/* s_text.c (comment6.c) - Spherical scroller - Don Yang (uguu.org) DOS only. MSC 6.0: cl /FPi87 /G2rs /Ox /W4 s_text.c 04/08/99: main blit render */ /* Includes */ #include #include /* Constants */ #define SCREEN 0xb8000000 #define CLOCK 0x0040006c /*#define DISABLEVSYNC */ /* Data (all data are global) */ int far *video = (int far *)SCREEN; int OldScreen[2000]; char screen[4000]; int palette[16] = /* top << 2 | bottom */ {0x0000, 0x0adc, 0x07dc, 0x0fdc, /* 0 = black */ 0x0adf, 0x0adb, 0x7adf, 0x7adf, /* 1 = green */ 0x70dc, 0x7adc, 0x77dc, 0x7fdc, /* 2 = gray */ 0x0fdf, 0x7adc, 0x7fdf, 0x0fdb}; /* 3 = white */ char image[2][8][28] = { { {0,2,2,2,2,2,0,0,0, 0,0,0,0,2,2,0,0,0,0, 0,0,2,0,0,0,0,2,0}, {2,3,3,3,3,3,2,0,0, 0,0,0,2,3,3,2,0,0,0, 0,2,3,2,0,0,2,3,2}, {2,3,2,2,2,2,3,2,0, 0,0,2,3,2,2,3,2,0,0, 0,2,3,3,2,0,2,3,2}, {2,3,2,0,0,2,3,2,0, 0,2,3,2,0,0,2,3,2,0, 0,2,3,2,3,2,2,3,2}, {2,3,2,0,0,2,3,2,0, 0,2,3,2,0,0,2,3,2,0, 0,2,3,2,2,3,2,3,2}, {2,3,2,2,2,2,3,2,0, 0,0,2,3,2,2,3,2,0,0, 0,2,3,2,0,2,3,3,2}, {2,3,3,3,3,3,2,0,0, 0,0,0,2,3,3,2,0,0,0, 0,2,3,2,0,0,2,3,2}, {0,2,2,2,2,2,0,0,0, 0,0,0,0,2,2,0,0,0,0, 0,0,2,0,0,0,0,2,0} }, { {1,0,0,0,0,1,0, 0,0,1,1,0,0,0, 1,1,1,0,0,1,0, 0,0,1,1,1,1,0}, {1,0,0,0,0,1,0, 0,1,0,0,1,0,0, 1,0,0,1,0,1,0, 0,1,0,0,0,0,0}, {1,0,0,0,0,1,0, 1,0,0,0,0,1,0, 1,0,0,0,1,1,0, 1,0,0,0,0,0,0}, {0,1,1,1,1,1,0, 1,0,0,0,0,1,0, 1,0,0,0,0,1,0, 1,0,0,0,0,0,0}, {0,0,0,0,0,1,0, 1,1,1,1,1,1,0, 1,0,0,0,0,1,0, 1,0,0,1,1,0,0}, {0,0,0,0,0,1,0, 1,0,0,0,0,1,0, 1,0,0,0,0,1,0, 1,0,0,0,0,1,0}, {0,0,0,0,1,0,0, 1,0,0,0,0,1,0, 1,0,0,0,0,1,0, 0,1,0,0,0,1,0}, {0,1,1,1,0,0,0, 1,0,0,0,0,1,0, 1,0,0,0,0,1,0, 0,0,1,1,1,0,0} } }; volatile long far *clock = (long far *)CLOCK; long sync; int f = 112, d = 1; int u, v; char w; int i, j, k; double lon = 0, lat = 0; double x[8 * 28], y[8 * 28], z[8 * 28], r, s, t; double pi = 3.141592653589793; /******************************************************************** blit */ void blit(void) { /* Wait for clock (18.2fps) */ #ifdef DISABLEVSYNC while( sync == *clock ); sync = *clock; #else while(inp(986) & 8); while(!(inp(986) & 8)); #endif /* Write to video memory */ for(j = 0; j < 50; j += 2) { for(i = 0; i < 80; i++) { video[80 * (j / 2) + i] = palette[(screen[j * 80 + i] * 4) | screen[(j + 1) * 80 + i] ]; } } } /* blit() */ /****************************************************************** render */ void render(void) { /* Clear screen */ for(i = 0; i < 4000;) screen[i++] = 0; /* Calculate coordinates */ k = 0; for(i = 0; i < 8; i++) { r = sin((i - 3.5) * pi / 50 + pi / 4); for(j = 0; j < 28; j++) { x[k] = r * cos(lat + j * pi / 25); z[k] = r * sin(lat + j * pi / 25); y[k] = cos((i - 3.5) * pi / 50 + pi / 4); k++; } } r = sin(lon); s = cos(lon); for(i = 0; i < 8 * 28; i++) { t = y[i]; y[i] = s * y[i] - r * z[i]; z[i] = s * z[i] + r * t; } /* Draw points */ k = 0; for(i = 0; i < 8; i++) { for(j = 0; j < 28; j++) { if( (w = (f > 4 * j) ? image[0][i][j] : image[1][i][j]) > 0 ) { u = (int)(1900 * x[k] / (100 * z[k] + 115) + 40); v = (int)(1900 * y[k] / (100 * z[k] + 115) + 25); if( v >= 0 && v < 50 ) screen[v * 80 + u] = w; } k++; } } /* Animate */ lon = fmod(lon + pi / 61, 2 * pi); lat = fmod(lat + pi / 79, 2 * pi); f += d; if( d > 0 ) { if( f > 315 ) d = -1; } else { if( f < -285 ) d = 1; } /* Redraw screen */ blit(); } /* render() */ /******************************************************************** main */ void cdecl main(void) { /* Save screen */ for(i = 0; i < 2000;) OldScreen[i++] = video[i]; /* Loop until keypress */ while( !kbhit() ) render(); /* Restore screen */ for(i = 0; i < 2000;) video[i++] = OldScreen[i]; /* Clear keystroke */ if( !getch() ) getch(); } /* main() */