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