/* * BB: The portable demo * * (C) 1997 by AA-group (e-mail: aa@horac.ta.jcu.cz) * * 3rd August 1997 * version: 1.2 [final3] * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public Licences as by published * by the Free Software Foundation; either version 2; or (at your option) * any later version * * This program is distributed in the hope that it will entertaining, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Publis License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc. * 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include "bb.h" #define STAR 1 #define SLOWDOWN 2 #define NORMAL 3 #define WIND 4 #define MAXSTARS 450 #if 1 #define MAXFAR 1000 #define MAXFAR1 100000 #define GFARCOR 256 #define MAXNEAR 1 #define MAXLEFT -(MAXFAR*255) #define MAXRIGHT (MAXFAR*255) #define MAXTOP -(MAXFAR*255) #define MAXBOTTOM (MAXFAR*255) #endif #if 0 #define G 1000 #define SSPEED 10 #define SSPEED1 20 #else #define G 600 #define SSPEED 40 #define SSPEED1 50 #endif #define DWIDTH aa_imgwidth(context) #define DHEIGHT aa_imgheight(context) #define NCREDITS 6 #define CTIME 3000000 #define CTIME1 (CTIME/NCREDITS) #define TOTAL (CTIME1*CSIZE+CTIME) #define STATE (TIME-starttime) #define TABSIZE (60*2) #define CSIZE (sizeof(text)/sizeof(char *)) #define RANDOM(x) (rand()%x) #define RANDOM2(x,y) (((rand()/(float)RAND_MAX)*(2*(y)))+(x)) #define MAX(x,y) ((x)>(y)?(x):(y)) #define MIN(x,y) ((x)<(y)?(x):(y)) static int windx = 0; static int windz = -30; static int mode = STAR; static float windspeed = 0, tospeed = 0; static float windangle = 0, toangle = 0; static char *text[] = { "Thank you", "For", "watching", "BB", ".", "...", ".", "CREDITS:", " ", "FK:", "Music", " ", " ", "MS:", "3d engine", "tyre", " ", " ", "KT:", "Sound", "engine", "Sound", "synchro", "Intro", "Plasma", "Guard", "stone", "Texts", "Titles", "Stars", "Snowing", " ", " ", "HH:", "AAlib", "Intro", "Invaders", "Fire", "Greetings", "Photos", "XaoS", "Zebra", "Titeling", "Texts", "Snowing", "Timing", "system", "Outro", "Pc speaker", "driver", " ", ".", "...", ".", "Special", "Thanks", "to", ":", "Eva", "Hubickova", "for photos", " ", "Texas", "Linux", "users", "group", "Their", "logo", "- great", "inspiration", " ", "Thomas", "Marsh", "For help", "with", "fractal", "zooming", " ", "IBM", "for MDA", "the", "primary", "gfx", "target", " ", "Jiri", "Matousek", "for help", "with", "searching", "algorithm", " ", "0rfelyus", "for help", "with", "dithering", " ", "DJ", "for DJGPP", " ", "MikMak", "for MikMod", " ", "Richard", "Stallman", "for GNU", " ", "Linus", "for linux", ".", "...", ".", "This demo", "and", "ascii art", "library", "is free", "software", "...", "you can", "redistribute", "it", "and/or", "modify", "under", "terms", "of GNU", "General", "Public", "Licence", "as", "published", "by the", "Free", "Software", "Foundation", " ", ".", "...", ".", "see", "COPYING", "for", "details", "or", "README", "for", "pointer", "to", "sources", " ", " ", "! WARNING !", "Do NOT", "read", "the sources", "unless", "you really", "know", "what you", "are doing", ".", "...", ".", "(C)1997", "AA", }; struct starTYPE { int x, y, z; int x2, y2; }; static int *horiztab; static int *verttab; typedef struct starTYPE starTYPE; typedef starTYPE starfieldTYPE[MAXSTARS]; static starfieldTYPE s; static void precalculate() { int i, p, p1; horiztab = malloc(TABSIZE * sizeof(*horiztab)); verttab = malloc(TABSIZE * sizeof(*verttab)); p1 = MAXLEFT / SSPEED; for (i = 0; i < TABSIZE; i++) { p = cos((double) i * 2.0 * M_PI / (TABSIZE - 1)) * MAXLEFT / SSPEED; horiztab[i] = p - p1; p1 = p; } p1 = 0; for (i = 0; i < TABSIZE; i++) { p = fabs(sin((double) i * 2 * M_PI / TABSIZE) * MAXLEFT / SSPEED1) + i * G; verttab[i] = p - p1; p1 = p; } } static void create_star(int i) { s[i].x = RANDOM2(MAXLEFT, MAXRIGHT); s[i].y = RANDOM2(MAXTOP, MAXBOTTOM); s[i].x2 = DWIDTH / 2; s[i].y2 = DHEIGHT / 2; s[i].z = RANDOM2(0, MAXFAR) + 1; } static void draw_starfield(void) { int i; clrscr(); for (i = 0; i < MAXSTARS; i++) { if (s[i].x2 > 0 && s[i].x2 < DWIDTH && s[i].y2 > 0 && s[i].y2 < DHEIGHT) aa_putpixel(context, s[i].x2, s[i].y2, MIN(MAXFAR1 / MAX(s[i].z - GFARCOR, 1), 255)); } aa_putpixel(context, aa_imgwidth(context) / 2, aa_imgheight(context) / 2, 0); } static void move_starfield(int step) { int i; static int counter; for (; step; step--) { if (mode == SLOWDOWN) windz = -30 * (endtime - TIME) / (endtime - starttime); if (mode == WIND) { if (windspeed >= tospeed) { windspeed -= 0.05; if (windspeed <= tospeed) tospeed = rand() % 40 - 10; if (tospeed < 0) tospeed = 0; } if (windspeed < tospeed) windspeed += 0.05; if (windangle <= toangle) { windangle += 1.0 / 200.0; if (windangle >= toangle) toangle = -M_PI * 2 / 3 + (rand() % 1000) * M_PI / 1000.0 * 4 / 3; } if (windangle >= toangle) windangle -= 1.0 / 200.0; windx = sin(windangle) * windspeed * 100; windz = -cos(windangle) * windspeed; } counter++; for (i = 0; i < MAXSTARS; i++) { if (step == 1) { if (s[i].z) { s[i].x2 = ((((s[i].x - 256) / s[i].z) * aa_imgwidth(context)) >> 8) + aa_imgwidth(context) / 2; s[i].y2 = ((((s[i].y - 256) / s[i].z) * aa_imgwidth(context) * aa_mmheight(context) / aa_mmwidth(context)) >> 8) + aa_imgheight(context) / 2; } 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)) { create_star(i); s[i].x2 = ((((s[i].x - 256) / s[i].z) * aa_imgwidth(context)) >> 8) + aa_imgwidth(context) / 2; s[i].y2 = ((((s[i].y - 256) / s[i].z) * aa_imgwidth(context) * aa_mmheight(context) / aa_mmwidth(context)) >> 8) + aa_imgheight(context) / 2; } } if (mode != STAR) { s[i].x += horiztab[(counter + i) % TABSIZE] + windx; s[i].y += verttab[(counter + i) % TABSIZE]; } s[i].z += windz; } } } static void drawcredits() { int state = STATE; double pos = sin(state * M_PI / 900000); int xpos1 = aa_imgwidth(context) / 2 + pos * 0.16 * aa_imgwidth(context); int xpos2 = aa_imgwidth(context) / 2 - pos * 0.16 * aa_imgwidth(context); int i, time = 0; int height = aa_imgheight(context) / NCREDITS; draw_starfield(); for (i = 0; i < CSIZE; i++) { if (state > time && state < time + CTIME) { centerprint((i & 1) ? xpos1 : xpos2, -height + (aa_imgheight(context) + 2 * height) * (CTIME + time - state) / CTIME, NCREDITS - 2, 255, text[i], 0); } time += CTIME1; } if (state > TOTAL - CTIME) params->randomval = (state - TOTAL + CTIME) * 800 / CTIME; } static void mydraw1() { if (mode == STAR) { if (TIME < endtime) { params->bright = -255 + (TIME - starttime) * 255 / (endtime - starttime); } else params->bright = 0; } else params->bright = 0; draw_starfield(); } void credits(void) { windx = 0; windz = -30; mode = STAR; windspeed = 0, tospeed = 0; windangle = 0, toangle = 0; textclrscr(); aa_flush(context); load_song("bb2.s3m"); precalculate(); bbupdate(); starttime = endtime = TIME; play(); params->bright = -255; drawptr = mydraw1; params->dither = AA_NONE; mode = STAR; timestuff(-60, move_starfield, draw, 6000000); mode = SLOWDOWN; timestuff(-60, move_starfield, draw, 4000000); mode = NORMAL; timestuff(-60, move_starfield, draw, 8000000); mode = WIND; params->bright = 0; drawptr = drawcredits; timestuff(-60, move_starfield, draw, TOTAL); free(horiztab); free(verttab); }