home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / 3DSCAPE.ZIP / 3D.C next >
C/C++ Source or Header  |  1993-10-13  |  9KB  |  511 lines

  1.  
  2. /* 3d landscape program by D.Hedley 7/4/93 */
  3.  
  4.  
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #include <dos.h>
  8. #include <conio.h>
  9. #include <math.h>
  10. #include <malloc.h>
  11.  
  12. #define GRIDSIZE 80  /* Must be bigger than VIEWSIZE */
  13. #define VIEWSIZE 61  /* MUST be odd */
  14.  
  15. #define DIFF (GRIDSIZE-VIEWSIZE)
  16.  
  17. #define DEF_DIST -1100
  18. #define DEF_PITCH 122
  19. #define DEF_HEIGHT 120
  20. #define DEF_ROLL 315
  21.  
  22. #define sine(X) ((long)(sn_tbl[X]))
  23. #define cosine(X) ((long)(sn_tbl[((X)+90) % 360]))
  24.  
  25. #define C_Plot(X,Y,C) pokeb(0xa000, (X) + 320U*(Y), C)
  26.  
  27. #define SHIFT 14
  28. #define MASK (GRIDSIZE*GRIDSIZE)
  29.  
  30. /*
  31. #define GetGrid(X,Y) ((unsigned)grid[((X) + GRIDSIZE*(Y) +idx) % MASK])
  32. #define PutGrid(X,Y,C) grid[((X) + GRIDSIZE*(Y) +idx) % MASK] = (unsigned char)(C)
  33. */
  34.  
  35. #define CalcAddress(X,Y) (&grid[((X) + GRIDSIZE*(Y) + idx) % MASK])
  36.  
  37. extern void far *view_screen;
  38. extern void far *screen;
  39. extern int sn_tbl[360];
  40. extern unsigned char grid[GRIDSIZE*GRIDSIZE];
  41. extern unsigned rand_seed;
  42. unsigned idx = 0;
  43.  
  44. extern long pitch_sine;
  45. extern long pitch_cosine;
  46. extern long roll_sine;
  47. extern long roll_cosine;
  48.  
  49. int num_points = GRIDSIZE*GRIDSIZE;
  50.  
  51. #define START (DIFF/2)
  52.  
  53. int gx = START,gy = START;
  54. unsigned char *gp;
  55.  
  56. int cz = DEF_DIST;
  57. int cy = DEF_HEIGHT;
  58. int roll = DEF_ROLL;
  59. int cpitch = DEF_PITCH;
  60.  
  61. extern void SetMyMode(void);
  62. extern void ClearMyScreen(void);
  63. extern void Project(void);
  64. extern void SwapScreens(void);
  65. extern void DoPlasma(int,int,int,int);
  66. extern int GetRand(void);
  67. extern unsigned GetGrid(void);
  68. extern void PutGrid(void);
  69.  
  70. #define _GetGrid(X,Y) (_AX = (X), _BX = (Y), GetGrid())
  71. #define _PutGrid(X,Y,C) { _CX = (C); _AX = (X); _BX = (Y); PutGrid(); }
  72.  
  73.  
  74. void SetMode(void)
  75. {
  76.     struct REGPACK regs;
  77.  
  78.     regs.r_ax = 0x13;
  79.     intr(0x10, ®s);
  80. }
  81.  
  82.  
  83. void SetTextMode(void)
  84. {
  85.     struct REGPACK regs;
  86.  
  87.     regs.r_ax = 0x3;
  88.     intr(0x10, ®s);
  89. }
  90.  
  91. void SetPalette(void)
  92. {
  93.     register int i;
  94.     register int j;
  95.  
  96.  
  97. #define DEPTH(X) max((((X)*(3-j))/3), 3)
  98.  
  99.     for (j = 0; j<4; j++)
  100.         for (i = 0; i<64; i+=4)
  101.         {
  102.             if (i+j > 0)
  103.             {
  104.                 disable();
  105.                 outportb(0x3c8, (i >> 2)+64*j);
  106.                 outportb(0x3c9, 0);
  107.                 outportb(0x3c9, 0);
  108.                 outportb(0x3c9, DEPTH(2*i/3));
  109.                 enable();
  110.             }
  111.  
  112.             disable();
  113.             outportb(0x3c8, (i >> 2)+64*j+16);
  114.             outportb(0x3c9, DEPTH(i/2+10));
  115.             outportb(0x3c9, DEPTH(i/4+10));
  116.             outportb(0x3c9, DEPTH(i/6+10));
  117.             enable();
  118.  
  119.             disable();
  120.             outportb(0x3c8, (i >> 2)+64*j+32);
  121.             outportb(0x3c9, DEPTH(max(63/2+10-i,0)));
  122.             outportb(0x3c9, DEPTH(min(64/4+10+3*i/4,63)));
  123.             outportb(0x3c9, DEPTH(max(63/6+10-i,0)));
  124.             enable();
  125.  
  126.             disable();
  127.             outportb(0x3c8, (i >> 2)+64*j+48);
  128.             outportb(0x3c9, DEPTH(i));
  129.             outportb(0x3c9, DEPTH(63));
  130.             outportb(0x3c9, DEPTH(i));
  131.             enable();
  132.         }
  133. }
  134.  
  135. /*
  136. int RandPixel(int x,int y,int x1,int y1,int x2,int y2)
  137. {
  138.     int col;
  139.  
  140.     col = (GetRand()%200 - 100) * (abs(x-x1)+abs(y-y1)) / (GRIDSIZE/6)
  141.             +((_GetGrid(x1,y1)+_GetGrid(x2,y2)) >> 1);
  142.  
  143.     if (col < 1) col = 1;
  144.     if (col > 255) col = 255;
  145.  
  146.     _PutGrid(x,y,col);
  147.  
  148.     return col;
  149. }
  150. */
  151. /*
  152. void DoPlasma(int x1, int y1, int x2, int y2)
  153. {
  154.     int x,y,s,p;
  155.  
  156.  
  157.     if (x2-x1 <= 1 && y2-y1 <= 1)
  158.         return;
  159.  
  160.     x = (x1+x2) >> 1;
  161.     y = (y1+y2) >> 1;
  162.  
  163.     if ((p = _GetGrid(x, y1)) == 0)
  164.         p = RandPixel(x,y1,x1,y1,x2,y1);
  165.     s = p;
  166.  
  167.     if ((p = _GetGrid(x2,y)) == 0)
  168.         p = RandPixel(x2,y,x2,y1,x2,y2);
  169.     s += p;
  170.  
  171.     if ((p = _GetGrid(x,y2)) == 0)
  172.         p = RandPixel(x,y2,x1,y2,x2,y2);
  173.     s += p;
  174.  
  175.     if ((p = _GetGrid(x1,y)) == 0)
  176.         p = RandPixel(x1,y,x1,y1,x1,y2);
  177.     s += p;
  178.  
  179.     if (_GetGrid(x,y) == 0)
  180.         _PutGrid(x,y,s >> 2);
  181.  
  182.     DoPlasma(x1,y1,x,y);
  183.     DoPlasma(x,y1,x2,y);
  184.     DoPlasma(x1,y,x,y2);
  185.     DoPlasma(x,y,x2,y2);
  186. }
  187. */
  188.  
  189. void BlankGrid(int x1,int y1,int x2,int y2)
  190. {
  191.     register int x,y;
  192.  
  193.     for (y = y1; y <= y2; y++)
  194.         for (x = x1; x <= x2; x++)
  195.             _PutGrid(x,y,0);
  196. }
  197.  
  198.  
  199. void NewLand(int x1,int y1,int x2,int y2)
  200. {
  201.     unsigned av = 0;
  202.     int val;
  203.     int num = 0;
  204.  
  205.     if ((val = _GetGrid(x1,y1)) > 0)
  206.     {
  207.         av += val;
  208.         num++;
  209.     }
  210.  
  211.     if ((val = _GetGrid(x2,y1)) > 0)
  212.     {
  213.         av += val;
  214.         num++;
  215.     }
  216.  
  217.     if ((val = _GetGrid(x2,y2)) > 0)
  218.     {
  219.         av += val;
  220.         num++;
  221.     }
  222.  
  223.     if ((val = _GetGrid(x1,y2)) > 0)
  224.     {
  225.         av += val;
  226.         num++;
  227.     }
  228.  
  229.     if (!av || GetRand() % 32 == 0)
  230.         av = GetRand() % 256;
  231.     else
  232.         av /= num;
  233.  
  234.     if (_GetGrid(x1,y1) == 0)
  235.         _PutGrid(x1,y1, av + (GetRand() % 80 -40));
  236.  
  237.     if (_GetGrid(x2,y1) == 0)
  238.         _PutGrid(x2,y1, av + (GetRand() % 80 -40));
  239.  
  240.     if (_GetGrid(x2,y2) == 0)
  241.         _PutGrid(x2,y2, av + (GetRand() % 80 -40));
  242.  
  243.     if (_GetGrid(x1,y2) == 0)
  244.         _PutGrid(x1,y2, av + (GetRand() % 80 -40));
  245.  
  246.     DoPlasma(x1,y1,x2,y2);
  247. }
  248.  
  249.  
  250. void Test(void)
  251. {
  252.     register int p;
  253.     register int x;
  254.     int y;
  255.  
  256.  
  257.     for (y = 0,p = idx; y < GRIDSIZE; y++)
  258.         for (x = 0; x < GRIDSIZE; x++, p = (p+1) % MASK)
  259.             C_Plot(x,y,max(grid[p],63) >> 2);
  260.  
  261.  
  262.     for (x = 0; x < VIEWSIZE; x++)
  263.     {
  264.         C_Plot(gx+x, gy, 0);
  265.         C_Plot(gx+x, gy+VIEWSIZE, 0);
  266.         C_Plot(gx, gy+x, 0);
  267.         C_Plot(gx+VIEWSIZE, gy+x, 0);
  268.     }
  269.  
  270. /*
  271.     for (y = 0, p = gp; y < VIEWSIZE; y++, p += DIFF)
  272.         for (x = 0; x < VIEWSIZE; x++,p++)
  273.             C_Plot(gx+x,gy+y,*p >> 3);
  274. */
  275. }
  276.  
  277.  
  278. void ClearScr(void)
  279. {
  280.     register unsigned i;
  281.  
  282.     for (i = 0; i < (320U*150); i++)
  283.         pokeb(0xa000,i,0);
  284. }
  285.  
  286.  
  287. void check_gx(void)
  288. {
  289.     if (gx < 0)
  290.     {
  291.         idx = (idx-DIFF/2 + MASK) % MASK;
  292.         gx = START-1;
  293.  
  294.         BlankGrid(0,0, DIFF/2-1, GRIDSIZE-1);
  295.  
  296.         NewLand(0,0,DIFF/2,GRIDSIZE/4);
  297.         NewLand(0,GRIDSIZE/4,DIFF/2,2*GRIDSIZE/4);
  298.         NewLand(0,2*GRIDSIZE/4,DIFF/2,3*GRIDSIZE/4);
  299.         NewLand(0,3*GRIDSIZE/4,DIFF/2,GRIDSIZE-1);
  300.     }
  301.     else if (gx >= DIFF)
  302.     {
  303.         idx = (idx+DIFF/2) % MASK;
  304.         gx = START+1;
  305.  
  306.         BlankGrid(GRIDSIZE-DIFF/2,0, GRIDSIZE-1, GRIDSIZE-1);
  307.  
  308.         NewLand(GRIDSIZE-DIFF/2-1,0,GRIDSIZE-1,GRIDSIZE/4);
  309.         NewLand(GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1,
  310.                                                 2*GRIDSIZE/4);
  311.         NewLand(GRIDSIZE-DIFF/2-1,2*GRIDSIZE/4,GRIDSIZE-1,
  312.                                                 3*GRIDSIZE/4);
  313.         NewLand(GRIDSIZE-DIFF/2-1,3*GRIDSIZE/4,GRIDSIZE-1,
  314.                                                 GRIDSIZE-1);
  315.     }
  316. }
  317.  
  318.  
  319. void check_gy(void)
  320. {
  321.     if (gy < 0)
  322.     {
  323.         idx = (idx-DIFF/2*GRIDSIZE + MASK) % MASK;
  324.         gy = START-1;
  325.  
  326.         BlankGrid(0,0, GRIDSIZE-1, DIFF/2-1);
  327.  
  328.         NewLand(0,0,GRIDSIZE/4,DIFF/2);
  329.         NewLand(GRIDSIZE/4,0,2*GRIDSIZE/4,DIFF/2);
  330.         NewLand(2*GRIDSIZE/4,0,3*GRIDSIZE/4,DIFF/2);
  331.         NewLand(3*GRIDSIZE/4,0,GRIDSIZE-1,DIFF/2);
  332.     }
  333.     else if (gy >= DIFF)
  334.     {
  335.         idx = (idx+DIFF/2*GRIDSIZE) % MASK;
  336.         gy = START+1;
  337.  
  338.         BlankGrid(0,GRIDSIZE-DIFF/2,GRIDSIZE-1, GRIDSIZE-1);
  339.  
  340.         NewLand(0,GRIDSIZE-DIFF/2-1,GRIDSIZE/4,GRIDSIZE-1);
  341.         NewLand(GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
  342.                                 2*GRIDSIZE/4,GRIDSIZE-1);
  343.         NewLand(2*GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
  344.                                 3*GRIDSIZE/4, GRIDSIZE-1);
  345.         NewLand(3*GRIDSIZE/4,GRIDSIZE-DIFF/2-1,
  346.                                 GRIDSIZE-1,GRIDSIZE-1);
  347.     }
  348. }
  349.  
  350.  
  351. void main(void)
  352. {
  353.     int rollspeed = 0;
  354.     int xspeed = 0, yspeed = 0;
  355.     int i;
  356.  
  357.     rand_seed = (unsigned) time(NULL);
  358.  
  359. /*    rand_seed = 2; */
  360.  
  361.     for (i = 0; i<(360+90); i++)
  362.         sn_tbl[i]=(int)(sin((double)i / 180.0*3.14159265) * (double)(1<<SHIFT));
  363.  
  364.  
  365.     NewLand(0,0,GRIDSIZE-1,GRIDSIZE-1);
  366.  
  367.     SetMode();
  368.     SetPalette();
  369.  
  370. //    goto skip;
  371.  
  372.     for (;;)
  373.     {
  374.         Test();
  375.  
  376.         switch(getch())
  377.         {
  378.             case 27:
  379.                 SetTextMode();
  380.                 exit(0);
  381.             case 'e':
  382.                 gx--;
  383.                 check_gx();
  384.                 break;
  385.             case 'r':
  386.                 gx++;
  387.                 check_gx();
  388.                 break;
  389.             case 'w':
  390.                 gy--;
  391.                 check_gy();
  392.                 break;
  393.             case 's':
  394.                 gy++;
  395.                 check_gy();
  396.                 break;
  397.             case ' ':
  398.                 goto skip;
  399.         }
  400.         gp = CalcAddress(gx,gy);
  401.         while (kbhit())
  402.             getch();
  403.  
  404.     }
  405. skip:
  406.     ;
  407.  
  408.     SetMyMode();
  409.     SetPalette();
  410.  
  411.     gp = CalcAddress(gx,gy);
  412.  
  413. //    yspeed = -1;
  414. //    rollspeed = (rollspeed+358) % 360;
  415.  
  416.     for (;;)
  417.     {
  418.         if (kbhit())
  419.         {
  420.             switch(getch())
  421.             {
  422.             case 27:
  423.                 SetTextMode();
  424.                 exit(0);
  425.             case 'q':
  426.                 cz += 50;
  427.                 break;
  428.             case 'a':
  429.                 cz -= 50;
  430.                 break;
  431.             case 'u':
  432.                 cy -= 50;
  433.                 break;
  434.             case 'j':
  435.                 cy += 50;
  436.                 break;
  437.             case 'Q':
  438.                 cpitch = (cpitch+1) % 360;
  439.                 break;
  440.             case 'A':
  441.                 cpitch = (cpitch+359) % 360;
  442.                 break;
  443.             case 'E':
  444.                 if (xspeed > -1) xspeed--;
  445.                 break;
  446.             case 'R':
  447.                 if (xspeed < 1) xspeed++;
  448.                 break;
  449.             case 'e':
  450.                 gx--;
  451.                 break;
  452.             case 'r':
  453.                 gx++;
  454.                 break;
  455.             case 'W':
  456.                 if (yspeed > -1) yspeed--;
  457.                 break;
  458.             case 'S':
  459.                 if (yspeed < 1) yspeed++;
  460.                 break;
  461.             case 'w':
  462.                 gy--;
  463.                 break;
  464.             case 's':
  465.                 gy++;
  466.                 break;
  467.             case 'i':
  468.                 roll = (roll+1) % 360;
  469.                 break;
  470.             case 'o':
  471.                 roll = (roll+359) % 360;
  472.                 break;
  473.             case 'I':
  474.                 rollspeed = (rollspeed+1) % 360;
  475.                 break;
  476.             case 'O':
  477.                 rollspeed = (rollspeed+359) % 360;
  478.                 break;
  479.             case ' ':
  480.                 rollspeed = 0;
  481.                 xspeed = yspeed = 0;
  482.                 cz = DEF_DIST;
  483.                 cy = DEF_HEIGHT;
  484.                 roll = DEF_ROLL;
  485.                 cpitch = DEF_PITCH;
  486.                 break;
  487.             }
  488.             while (kbhit())
  489.                 getch();
  490.         }
  491.         gy += yspeed;
  492.         gx += xspeed;
  493.  
  494.         check_gx();
  495.         check_gy();
  496.  
  497.         gp = CalcAddress(gx,gy);
  498.         roll = (roll+rollspeed) % 360;
  499.  
  500.         roll_sine = sine(roll);
  501.         roll_cosine = cosine(roll);
  502.         pitch_sine = sine(cpitch);
  503.         pitch_cosine = cosine(cpitch);
  504.  
  505.         ClearMyScreen();
  506.         Project();
  507.         SwapScreens();
  508.     }
  509.  
  510. }
  511.