1 /*
2  * BB: The portable demo
3  *
4  * (C) 1997 by AA-group (e-mail: aa@horac.ta.jcu.cz)
5  *
6  * 3rd August 1997
7  * version: 1.2 [final3]
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public Licences as by published
11  * by the Free Software Foundation; either version 2; or (at your option)
12  * any later version
13  *
14  * This program is distributed in the hope that it will entertaining,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Publis License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.
21  * 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23 
24 #include <math.h>
25 #include <limits.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <stdlib.h>
29 #include "bb.h"
30 #define STAR 1
31 #define SLOWDOWN 2
32 #define NORMAL 3
33 #define WIND 4
34 
35 
36 #define MAXSTARS	450
37 
38 #if 1
39 #define MAXFAR		1000
40 #define MAXFAR1		100000
41 #define GFARCOR		256
42 #define MAXNEAR		1
43 #define MAXLEFT		-(MAXFAR*255)
44 #define MAXRIGHT	(MAXFAR*255)
45 #define MAXTOP		-(MAXFAR*255)
46 #define MAXBOTTOM	(MAXFAR*255)
47 #endif
48 #if 0
49 #define G 1000
50 #define SSPEED 10
51 #define SSPEED1 20
52 #else
53 #define G 600
54 #define SSPEED 40
55 #define SSPEED1 50
56 #endif
57 
58 #define DWIDTH aa_imgwidth(context)
59 #define DHEIGHT aa_imgheight(context)
60 
61 #define NCREDITS 6
62 #define CTIME 3000000
63 #define CTIME1 (CTIME/NCREDITS)
64 #define TOTAL (CTIME1*CSIZE+CTIME)
65 #define STATE (TIME-starttime)
66 #define TABSIZE (60*2)
67 
68 #define CSIZE (sizeof(text)/sizeof(char *))
69 #define RANDOM(x) (rand()%x)
70 #define RANDOM2(x,y) (((rand()/(float)RAND_MAX)*(2*(y)))+(x))
71 #define MAX(x,y) ((x)>(y)?(x):(y))
72 #define MIN(x,y) ((x)<(y)?(x):(y))
73 static int windx = 0;
74 static int windz = -30;
75 static int mode = STAR;
76 static float windspeed = 0, tospeed = 0;
77 static float windangle = 0, toangle = 0;
78 
79 static char *text[] =
80 {
81     "Thank you",
82     "For",
83     "watching",
84     "BB",
85     ".",
86     "...",
87     ".",
88     "CREDITS:",
89     " ",
90     "FK:",
91     "Music",
92     " ",
93     " ",
94     "MS:",
95     "3d engine",
96     "tyre",
97     " ",
98     " ",
99     "KT:",
100     "Sound",
101     "engine",
102     "Sound",
103     "synchro",
104     "Intro",
105     "Plasma",
106     "Guard",
107     "stone",
108     "Texts",
109     "Titles",
110     "Stars",
111     "Snowing",
112     " ",
113     " ",
114     "HH:",
115     "AAlib",
116     "Intro",
117     "Invaders",
118     "Fire",
119     "Greetings",
120     "Photos",
121     "XaoS",
122     "Zebra",
123     "Titeling",
124     "Texts",
125     "Snowing",
126     "Timing",
127     "system",
128     "Outro",
129     "Pc speaker",
130     "driver",
131     " ",
132     ".",
133     "...",
134     ".",
135     "Special",
136     "Thanks",
137     "to",
138     ":",
139     "Eva",
140     "Hubickova",
141     "for photos",
142     " ",
143     "Texas",
144     "Linux",
145     "users",
146     "group",
147     "Their",
148     "logo",
149     "- great",
150     "inspiration",
151     " ",
152     "Thomas",
153     "Marsh",
154     "For help",
155     "with",
156     "fractal",
157     "zooming",
158     " ",
159     "IBM",
160     "for MDA",
161     "the",
162     "primary",
163     "gfx",
164     "target",
165     " ",
166     "Jiri",
167     "Matousek",
168     "for help",
169     "with",
170     "searching",
171     "algorithm",
172     " ",
173     "0rfelyus",
174     "for help",
175     "with",
176     "dithering",
177     " ",
178     "DJ",
179     "for DJGPP",
180     " ",
181     "MikMak",
182     "for MikMod",
183     " ",
184     "Richard",
185     "Stallman",
186     "for GNU",
187     " ",
188     "Linus",
189     "for linux",
190     ".",
191     "...",
192     ".",
193     "This demo",
194     "and",
195     "ascii art",
196     "library",
197     "is free",
198     "software",
199     "...",
200     "you can",
201     "redistribute",
202     "it",
203     "and/or",
204     "modify",
205     "under",
206     "terms",
207     "of GNU",
208     "General",
209     "Public",
210     "Licence",
211     "as",
212     "published",
213     "by the",
214     "Free",
215     "Software",
216     "Foundation",
217     " ",
218     ".",
219     "...",
220     ".",
221     "see",
222     "COPYING",
223     "for",
224     "details",
225     "or",
226     "README",
227     "for",
228     "pointer",
229     "to",
230     "sources",
231     " ",
232     " ",
233     "! WARNING !",
234     "Do NOT",
235     "read",
236     "the sources",
237     "unless",
238     "you really",
239     "know",
240     "what you",
241     "are doing",
242     ".",
243     "...",
244     ".",
245     "(C)1997",
246     "AA",
247 };
248 struct starTYPE {
249     int x, y, z;
250     int x2, y2;
251 };
252 
253 static int *horiztab;
254 static int *verttab;
255 
256 typedef struct starTYPE starTYPE;
257 typedef starTYPE starfieldTYPE[MAXSTARS];
258 
259 static starfieldTYPE s;
260 
precalculate()261 static void precalculate()
262 {
263     int i, p, p1;
264     horiztab = malloc(TABSIZE * sizeof(*horiztab));
265     verttab = malloc(TABSIZE * sizeof(*verttab));
266     p1 = MAXLEFT / SSPEED;
267     for (i = 0; i < TABSIZE; i++) {
268 	p = cos((double) i * 2.0 * M_PI / (TABSIZE - 1)) * MAXLEFT / SSPEED;
269 	horiztab[i] = p - p1;
270 	p1 = p;
271     }
272     p1 = 0;
273     for (i = 0; i < TABSIZE; i++) {
274 	p = fabs(sin((double) i * 2 * M_PI / TABSIZE) * MAXLEFT / SSPEED1) + i * G;
275 	verttab[i] = p - p1;
276 	p1 = p;
277     }
278 }
279 
280 
281 
create_star(int i)282 static void create_star(int i)
283 {
284     s[i].x = RANDOM2(MAXLEFT, MAXRIGHT);
285     s[i].y = RANDOM2(MAXTOP, MAXBOTTOM);
286     s[i].x2 = DWIDTH / 2;
287     s[i].y2 = DHEIGHT / 2;
288     s[i].z = RANDOM2(0, MAXFAR) + 1;
289 }
290 
draw_starfield(void)291 static void draw_starfield(void)
292 {
293     int i;
294 
295     clrscr();
296     for (i = 0; i < MAXSTARS; i++) {
297 	if (s[i].x2 > 0 && s[i].x2 < DWIDTH && s[i].y2 > 0 && s[i].y2 < DHEIGHT)
298 	    aa_putpixel(context, s[i].x2, s[i].y2, MIN(MAXFAR1 / MAX(s[i].z - GFARCOR, 1), 255));
299     }
300     aa_putpixel(context, aa_imgwidth(context) / 2, aa_imgheight(context) / 2, 0);
301 }
302 
move_starfield(int step)303 static void move_starfield(int step)
304 {
305     int i;
306     static int counter;
307     for (; step; step--) {
308 	if (mode == SLOWDOWN)
309 	    windz = -30 * (endtime - TIME) / (endtime - starttime);
310 	if (mode == WIND) {
311 	    if (windspeed >= tospeed) {
312 		windspeed -= 0.05;
313 		if (windspeed <= tospeed)
314 		    tospeed = rand() % 40 - 10;
315 		if (tospeed < 0)
316 		    tospeed = 0;
317 	    }
318 	    if (windspeed < tospeed)
319 		windspeed += 0.05;
320 	    if (windangle <= toangle) {
321 		windangle += 1.0 / 200.0;
322 		if (windangle >= toangle)
323 		    toangle = -M_PI * 2 / 3 + (rand() % 1000) * M_PI / 1000.0 * 4 / 3;
324 	    }
325 	    if (windangle >= toangle)
326 		windangle -= 1.0 / 200.0;
327 	    windx = sin(windangle) * windspeed * 100;
328 	    windz = -cos(windangle) * windspeed;
329 	}
330 	counter++;
331 	for (i = 0; i < MAXSTARS; i++) {
332 	    if (step == 1) {
333 		if (s[i].z) {
334 		    s[i].x2 = ((((s[i].x - 256) / s[i].z) * aa_imgwidth(context)) >> 8) + aa_imgwidth(context) / 2;
335 		    s[i].y2 = ((((s[i].y - 256) / s[i].z) * aa_imgwidth(context) * aa_mmheight(context) / aa_mmwidth(context)) >> 8) + aa_imgheight(context) / 2;
336 		}
337 		while (!(s[i].x2 > -DWIDTH / 3 && s[i].x2 < 4 * DWIDTH / 3 && s[i].y2 > -DHEIGHT / 3 && s[i].y2 < 4 * DHEIGHT / 3 && s[i].z > 0 && s[i].z <= MAXFAR)) {
338 		    create_star(i);
339 		    s[i].x2 = ((((s[i].x - 256) / s[i].z) * aa_imgwidth(context)) >> 8) + aa_imgwidth(context) / 2;
340 		    s[i].y2 = ((((s[i].y - 256) / s[i].z) * aa_imgwidth(context) * aa_mmheight(context) / aa_mmwidth(context)) >> 8) + aa_imgheight(context) / 2;
341 		}
342 	    }
343 	    if (mode != STAR) {
344 		s[i].x += horiztab[(counter + i) % TABSIZE] + windx;
345 		s[i].y += verttab[(counter + i) % TABSIZE];
346 	    }
347 	    s[i].z += windz;
348 	}
349     }
350 }
351 
drawcredits()352 static void drawcredits()
353 {
354     int state = STATE;
355     double pos = sin(state * M_PI / 900000);
356     int xpos1 = aa_imgwidth(context) / 2 + pos * 0.16 * aa_imgwidth(context);
357     int xpos2 = aa_imgwidth(context) / 2 - pos * 0.16 * aa_imgwidth(context);
358     int i, time = 0;
359     int height = aa_imgheight(context) / NCREDITS;
360     draw_starfield();
361     for (i = 0; i < CSIZE; i++) {
362 	if (state > time && state < time + CTIME) {
363 	    centerprint((i & 1) ? xpos1 : xpos2, -height + (aa_imgheight(context) + 2 * height) * (CTIME + time - state) / CTIME, NCREDITS - 2, 255, text[i], 0);
364 	}
365 	time += CTIME1;
366     }
367     if (state > TOTAL - CTIME)
368 	params->randomval = (state - TOTAL + CTIME) * 800 / CTIME;
369 }
mydraw1()370 static void mydraw1()
371 {
372     if (mode == STAR) {
373 	if (TIME < endtime) {
374 	    params->bright = -255 + (TIME - starttime) * 255 / (endtime - starttime);
375 	}
376 	else
377 	    params->bright = 0;
378     }
379     else
380 	params->bright = 0;
381     draw_starfield();
382 }
credits(void)383 void credits(void)
384 {
385     windx = 0;
386     windz = -30;
387     mode = STAR;
388     windspeed = 0, tospeed = 0;
389     windangle = 0, toangle = 0;
390     textclrscr();
391     aa_flush(context);
392     load_song("bb2.s3m");
393     precalculate();
394     bbupdate();
395     starttime = endtime = TIME;
396     play();
397     params->bright = -255;
398     drawptr = mydraw1;
399     params->dither = AA_NONE;
400     mode = STAR;
401     timestuff(-60, move_starfield, draw, 6000000);
402     mode = SLOWDOWN;
403     timestuff(-60, move_starfield, draw, 4000000);
404     mode = NORMAL;
405     timestuff(-60, move_starfield, draw, 8000000);
406     mode = WIND;
407     params->bright = 0;
408     drawptr = drawcredits;
409     timestuff(-60, move_starfield, draw, TOTAL);
410     free(horiztab);
411     free(verttab);
412 }
413