/* 3d landscape program by D.Hedley 7/4/93 */ #include #include #include #include #include #include #define GRIDSIZE 80 /* Must be bigger than VIEWSIZE */ #define VIEWSIZE 61 /* MUST be odd */ #define DIFF (GRIDSIZE-VIEWSIZE) #define DEF_DIST -1100 #define DEF_PITCH 122 #define DEF_HEIGHT 120 #define DEF_ROLL 315 #define sine(X) ((long)(sn_tbl[X])) #define cosine(X) ((long)(sn_tbl[((X)+90) % 360])) #define C_Plot(X,Y,C) pokeb(0xa000, (X) + 320U*(Y), C) #define SHIFT 14 #define MASK (GRIDSIZE*GRIDSIZE) /* #define GetGrid(X,Y) ((unsigned)grid[((X) + GRIDSIZE*(Y) +idx) % MASK]) #define PutGrid(X,Y,C) grid[((X) + GRIDSIZE*(Y) +idx) % MASK] = (unsigned char)(C) */ #define CalcAddress(X,Y) (&grid[((X) + GRIDSIZE*(Y) + idx) % MASK]) extern void far *view_screen; extern void far *screen; extern int sn_tbl[360]; extern unsigned char grid[GRIDSIZE*GRIDSIZE]; extern unsigned rand_seed; unsigned idx = 0; extern long pitch_sine; extern long pitch_cosine; extern long roll_sine; extern long roll_cosine; int num_points = GRIDSIZE*GRIDSIZE; #define START (DIFF/2) int gx = START,gy = START; unsigned char *gp; int cz = DEF_DIST; int cy = DEF_HEIGHT; int roll = DEF_ROLL; int cpitch = DEF_PITCH; extern void SetMyMode(void); extern void ClearMyScreen(void); extern void Project(void); extern void SwapScreens(void); extern void DoPlasma(int,int,int,int); extern int GetRand(void); extern unsigned GetGrid(void); extern void PutGrid(void); #define _GetGrid(X,Y) (_AX = (X), _BX = (Y), GetGrid()) #define _PutGrid(X,Y,C) { _CX = (C); _AX = (X); _BX = (Y); PutGrid(); } void SetMode(void) { struct REGPACK regs; regs.r_ax = 0x13; intr(0x10, ®s); } void SetTextMode(void) { struct REGPACK regs; regs.r_ax = 0x3; intr(0x10, ®s); } void SetPalette(void) { register int i; register int j; #define DEPTH(X) max((((X)*(3-j))/3), 3) for (j = 0; j<4; j++) for (i = 0; i<64; i+=4) { if (i+j > 0) { disable(); outportb(0x3c8, (i >> 2)+64*j); outportb(0x3c9, 0); outportb(0x3c9, 0); outportb(0x3c9, DEPTH(2*i/3)); enable(); } disable(); outportb(0x3c8, (i >> 2)+64*j+16); outportb(0x3c9, DEPTH(i/2+10)); outportb(0x3c9, DEPTH(i/4+10)); outportb(0x3c9, DEPTH(i/6+10)); enable(); disable(); outportb(0x3c8, (i >> 2)+64*j+32); outportb(0x3c9, DEPTH(max(63/2+10-i,0))); outportb(0x3c9, DEPTH(min(64/4+10+3*i/4,63))); outportb(0x3c9, DEPTH(max(63/6+10-i,0))); enable(); disable(); outportb(0x3c8, (i >> 2)+64*j+48); outportb(0x3c9, DEPTH(i)); outportb(0x3c9, DEPTH(63)); outportb(0x3c9, DEPTH(i)); enable(); } } /* int RandPixel(int x,int y,int x1,int y1,int x2,int y2) { int col; col = (GetRand()%200 - 100) * (abs(x-x1)+abs(y-y1)) / (GRIDSIZE/6) +((_GetGrid(x1,y1)+_GetGrid(x2,y2)) >> 1); if (col < 1) col = 1; if (col > 255) col = 255; _PutGrid(x,y,col); return col; } */ /* void DoPlasma(int x1, int y1, int x2, int y2) { int x,y,s,p; if (x2-x1 <= 1 && y2-y1 <= 1) return; x = (x1+x2) >> 1; y = (y1+y2) >> 1; if ((p = _GetGrid(x, y1)) == 0) p = RandPixel(x,y1,x1,y1,x2,y1); s = p; if ((p = _GetGrid(x2,y)) == 0) p = RandPixel(x2,y,x2,y1,x2,y2); s += p; if ((p = _GetGrid(x,y2)) == 0) p = RandPixel(x,y2,x1,y2,x2,y2); s += p; if ((p = _GetGrid(x1,y)) == 0) p = RandPixel(x1,y,x1,y1,x1,y2); s += p; if (_GetGrid(x,y) == 0) _PutGrid(x,y,s >> 2); DoPlasma(x1,y1,x,y); DoPlasma(x,y1,x2,y); DoPlasma(x1,y,x,y2); DoPlasma(x,y,x2,y2); } */ void BlankGrid(int x1,int y1,int x2,int y2) { register int x,y; for (y = y1; y <= y2; y++) for (x = x1; x <= x2; x++) _PutGrid(x,y,0); } void NewLand(int x1,int y1,int x2,int y2) { unsigned av = 0; int val; int num = 0; if ((val = _GetGrid(x1,y1)) > 0) { av += val; num++; } if ((val = _GetGrid(x2,y1)) > 0) { av += val; num++; } if ((val = _GetGrid(x2,y2)) > 0) { av += val; num++; } if ((val = _GetGrid(x1,y2)) > 0) { av += val; num++; } if (!av || GetRand() % 32 == 0) av = GetRand() % 256; else av /= num; if (_GetGrid(x1,y1) == 0) _PutGrid(x1,y1, av + (GetRand() % 80 -40)); if (_GetGrid(x2,y1) == 0) _PutGrid(x2,y1, av + (GetRand() % 80 -40)); if (_GetGrid(x2,y2) == 0) _PutGrid(x2,y2, av + (GetRand() % 80 -40)); if (_GetGrid(x1,y2) == 0) _PutGrid(x1,y2, av + (GetRand() % 80 -40)); DoPlasma(x1,y1,x2,y2); } void Test(void) { register int p; register int x; int y; for (y = 0,p = idx; y < GRIDSIZE; y++) for (x = 0; x < GRIDSIZE; x++, p = (p+1) % MASK) C_Plot(x,y,max(grid[p],63) >> 2); for (x = 0; x < VIEWSIZE; x++) { C_Plot(gx+x, gy, 0); C_Plot(gx+x, gy+VIEWSIZE, 0); C_Plot(gx, gy+x, 0); C_Plot(gx+VIEWSIZE, gy+x, 0); } /* for (y = 0, p = gp; y < VIEWSIZE; y++, p += DIFF) for (x = 0; x < VIEWSIZE; x++,p++) C_Plot(gx+x,gy+y,*p >> 3); */ } void ClearScr(void) { register unsigned i; for (i = 0; i < (320U*150); i++) pokeb(0xa000,i,0); } void check_gx(void) { if (gx < 0) { idx = (idx-DIFF/2 + MASK) % MASK; gx = START-1; BlankGrid(0,0, DIFF/2-1, GRIDSIZE-1); NewLand(0,0,DIFF/2,GRIDSIZE/4); NewLand(0,GRIDSIZE/4,DIFF/2,2*GRIDSIZE/4); NewLand(0,2*GRIDSIZE/4,DIFF/2,3*GRIDSIZE/4); NewLand(0,3*GRIDSIZE/4,DIFF/2,GRIDSIZE-1); } else if (gx >= DIFF) { idx = (idx+DIFF/2) % MASK; gx = START+1; BlankGrid(GRIDSIZE-DIFF/2,0, GRIDSIZE-1, GRIDSIZE-1); NewLand(GRIDSIZE-DIFF/2-1,0,GRIDSIZE-1,GRIDSIZE/4); NewLand(GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1, 2*GRIDSIZE/4); NewLand(GRIDSIZE-DIFF/2-1,2*GRIDSIZE/4,GRIDSIZE-1, 3*GRIDSIZE/4); NewLand(GRIDSIZE-DIFF/2-1,3*GRIDSIZE/4,GRIDSIZE-1, GRIDSIZE-1); } } void check_gy(void) { if (gy < 0) { idx = (idx-DIFF/2*GRIDSIZE + MASK) % MASK; gy = START-1; BlankGrid(0,0, GRIDSIZE-1, DIFF/2-1); NewLand(0,0,GRIDSIZE/4,DIFF/2); NewLand(GRIDSIZE/4,0,2*GRIDSIZE/4,DIFF/2); NewLand(2*GRIDSIZE/4,0,3*GRIDSIZE/4,DIFF/2); NewLand(3*GRIDSIZE/4,0,GRIDSIZE-1,DIFF/2); } else if (gy >= DIFF) { idx = (idx+DIFF/2*GRIDSIZE) % MASK; gy = START+1; BlankGrid(0,GRIDSIZE-DIFF/2,GRIDSIZE-1, GRIDSIZE-1); NewLand(0,GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1); NewLand(GRIDSIZE/4,GRIDSIZE-DIFF/2-1, 2*GRIDSIZE/4,GRIDSIZE-1); NewLand(2*GRIDSIZE/4,GRIDSIZE-DIFF/2-1, 3*GRIDSIZE/4, GRIDSIZE-1); NewLand(3*GRIDSIZE/4,GRIDSIZE-DIFF/2-1, GRIDSIZE-1,GRIDSIZE-1); } } void main(void) { int rollspeed = 0; int xspeed = 0, yspeed = 0; int i; rand_seed = (unsigned) time(NULL); /* rand_seed = 2; */ for (i = 0; i<(360+90); i++) sn_tbl[i]=(int)(sin((double)i / 180.0*3.14159265) * (double)(1< -1) xspeed--; break; case 'R': if (xspeed < 1) xspeed++; break; case 'e': gx--; break; case 'r': gx++; break; case 'W': if (yspeed > -1) yspeed--; break; case 'S': if (yspeed < 1) yspeed++; break; case 'w': gy--; break; case 's': gy++; break; case 'i': roll = (roll+1) % 360; break; case 'o': roll = (roll+359) % 360; break; case 'I': rollspeed = (rollspeed+1) % 360; break; case 'O': rollspeed = (rollspeed+359) % 360; break; case ' ': rollspeed = 0; xspeed = yspeed = 0; cz = DEF_DIST; cy = DEF_HEIGHT; roll = DEF_ROLL; cpitch = DEF_PITCH; break; } while (kbhit()) getch(); } gy += yspeed; gx += xspeed; check_gx(); check_gy(); gp = CalcAddress(gx,gy); roll = (roll+rollspeed) % 360; roll_sine = sine(roll); roll_cosine = cosine(roll); pitch_sine = sine(cpitch); pitch_cosine = cosine(cpitch); ClearMyScreen(); Project(); SwapScreens(); } }