home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TUTORC.ZIP / TUT14B.C < prev    next >
C/C++ Source or Header  |  1994-10-30  |  15KB  |  616 lines

  1. /* 
  2.   tut14b.c
  3.   10/30/94
  4.   from tutprog14.pas
  5.   Adapted from Denthor's tutprog14.pas
  6.   Translated into C, from Denthor's VGA Trainer, by
  7.   Steve Pinault, scp@ohm.att.com  
  8.   Variation of tut14.c to do solid cube with face sorting and shading.
  9.   For each side of the cube, a normal vector is rotated along with the
  10.   corners of the face, to use for computing the shading.
  11.   Compiled with Microsoft Visual C++ 1.5 (Microsoft C 8.0)
  12.   To compile:
  13.   First compile the subroutines in tutsubs.c with the batch file 
  14.   cltutsub.bat
  15.   Then compile any of the tutor programs with the batch file
  16.   cltut.bat
  17.   Example: C:>cltutsub
  18.            C:>cltut tut14b.c
  19.            to compile this program.
  20. */
  21.  
  22. #include "tutheadr.h"
  23.  
  24. #define maxpolys 6
  25.  
  26. int a[maxpolys][5][3] = 
  27. {
  28.      // 6 sides of a cube, plus exterior normals:
  29.      {{-10,-10,10},{-10,10,10},{10,10,10},{10,-10,10},{0,0,8}},       //z= 10
  30.      {{-10,-10,-10},{-10,10,-10},{10,10,-10},{10,-10,-10},{0,0,-8}},  //z=-10
  31.      {{-10,-10,-10},{-10,10,-10},{-10,10,10},{-10,-10,10},{-8,0,0}},  //x=-10
  32.      {{10,-10,-10},{10,10,-10},{10,10,10},{10,-10,10},{8,0,0}},       //x= 10
  33.      {{10,-10,10},{10,-10,-10},{-10,-10,-10},{-10,-10,10},{0,-8,0}},  //y=-10
  34.      {{10,10,10},{10,10,-10},{-10,10,-10},{-10,10,10},{0,8,0}}        //y= 10
  35. };         
  36.         // The 3-D coordinates of our object ... stored as (X1,Y1,Z1), }
  37.         // (X2,Y2,Z2) ... for the 4 points of a poly }
  38.         // fifth point is exterior normal. Later gets multiplied by 8,
  39.         // so normal has length 64, giving right scale for color.
  40.  
  41. struct IPoint
  42. {
  43.   int x;
  44.   int y;
  45.   int z;
  46. };  
  47. struct IPoint lines[maxpolys][5],translated[maxpolys][5];
  48. int lookup[360][2];  // sin and cos table
  49. int poly[200][2];
  50. int ytopclip,ybotclip;
  51. int xoff,yoff,zoff;
  52.  
  53. ///////////////////////////////////////////////////////////////////////////
  54. //Procedure doside (x1,y1,x2,y2:integer);
  55. //  { This scans the side of a polygon and updates the poly variable }
  56. void doside(int x1,int y1,int x2,int y2)
  57. {
  58.   int temp,x,xinc,loop1;
  59.   
  60.   if(y1==y2)return;
  61.   if(y2<y1)
  62.   {
  63.     temp=y2;
  64.     y2=y1;
  65.     y1=temp;
  66.     temp=x2;
  67.     x2=x1;
  68.     x1=temp;
  69.   }
  70.   xinc=((x2-x1)<<7)/(y2-y1);
  71.   x=(x1<<7);
  72.   for(loop1=y1;loop1<=y2;loop1++)
  73.   {
  74.     if((loop1>ytopclip-1)&&(loop1<ybotclip+1))
  75.     {
  76.       if((x>>7)<poly[loop1][0]) poly[loop1][0]=(x>>7); // min
  77.       if((x>>7)>poly[loop1][1]) poly[loop1][1]=(x>>7); // max
  78.     }
  79.     x+=xinc;
  80.   }
  81. }
  82.  
  83. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  84. // Procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
  85. // This draw a polygon with 4 points at x1,y1 , x2,y2 , x3,y3 , x4,y4
  86. // in color col }
  87. void drawpoly(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,char color,int where)
  88. {
  89.   int miny,maxy,loop1;
  90.  
  91.   _asm
  92.   {
  93.     mov   si,offset poly
  94.     mov   cx,200
  95. Loop1:
  96.     mov   ax,32766
  97.     mov   ds:[si],ax
  98.     inc   si
  99.     inc   si
  100.     mov   ax,-32767
  101.     mov   ds:[si],ax
  102.     inc   si
  103.     inc   si
  104.     loop  Loop1
  105.    }       // { Setting the minx and maxx values to extremes }
  106.   miny=y1;
  107.   maxy=y1;
  108.   if (y2<miny)  miny=y2;
  109.   if (y3<miny)  miny=y3;
  110.   if (y4<miny)  miny=y4;
  111.   if (y2>maxy)  maxy=y2;
  112.   if (y3>maxy)  maxy=y3;
  113.   if (y4>maxy)  maxy=y4;
  114.   if (miny<ytopclip)  miny=ytopclip;
  115.   if (maxy>ybotclip)  maxy=ybotclip;
  116.   if ((miny>199) || (maxy<0)) return;
  117.  
  118.   doside (x1,y1,x2,y2);
  119.   doside (x2,y2,x3,y3);
  120.   doside (x3,y3,x4,y4);
  121.   doside (x4,y4,x1,y1);
  122.  
  123.   for( loop1= miny;loop1<=maxy;loop1++)
  124.     // Hline2 (poly[loop1][0],poly[loop1][1],loop1,color,where); //transparent
  125.     Hline (poly[loop1][0],poly[loop1][1],loop1,color,where);  //solid
  126. }
  127.  
  128. //{DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  129. //Procedure SetUpPoints;
  130. //  { This creates the lookup table }
  131. void SetUpPoints()
  132. {
  133.   int loop1;
  134.   for(loop1=0;loop1<360;loop1++)
  135.   {
  136.     lookup[loop1][0]=round((float)sin((double)rad(loop1))*(float)16384);
  137.     lookup[loop1][1]=round((float)cos((double)rad(loop1))*(float)16384);
  138.   }
  139. }
  140.  
  141.  
  142. //{DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  143. //Procedure RotatePoints (x,Y,z:Integer);
  144. //  { This rotates the objecct in lines to translated }
  145. void rotatepoints(int x, int y, int z)
  146. {
  147.   int loop1,loop2;
  148.   int a,b,c;
  149.   
  150.   for(loop1=0;loop1<maxpolys;loop1++)
  151.   {
  152.     for(loop2=0;loop2<5;loop2++) // rotate the normals also!
  153.     {
  154.       b=lookup[y][1];
  155.       c=lines[loop1][loop2].x;
  156.       _asm
  157.       {
  158.         mov   ax,b
  159.         imul  c
  160.         sal   ax,1
  161.         rcl   dx,1
  162.         sal   ax,1
  163.         rcl   dx,1
  164.         mov   a,dx
  165.       }
  166.       b=lookup[y][0];
  167.       c=lines[loop1][loop2].z;
  168.       _asm
  169.       {
  170.         mov   ax,b
  171.         imul  c
  172.         sal   ax,1
  173.         rcl   dx,1
  174.         sal   ax,1
  175.         rcl   dx,1
  176.         add   a,dx
  177.       }
  178.       translated[loop1][loop2].x=a;
  179.       translated[loop1][loop2].y=lines[loop1][loop2].y;
  180.       b=-lookup[y][0];
  181.       c=lines[loop1][loop2].x;
  182.       _asm
  183.       {
  184.         mov   ax,b
  185.         imul  c
  186.         sal   ax,1
  187.         rcl   dx,1
  188.         sal   ax,1
  189.         rcl   dx,1
  190.         mov   a,dx
  191.       }
  192.       b=lookup[y][1];
  193.       c=lines[loop1][loop2].z;
  194.       _asm
  195.       {
  196.         mov   ax,b
  197.         imul  c
  198.         sal   ax,1
  199.         rcl   dx,1
  200.         sal   ax,1
  201.         rcl   dx,1
  202.         add   a,dx
  203.       }
  204.       translated[loop1][loop2].z=a;
  205.  
  206.  
  207.       if(x!=0)
  208.       {
  209.         b=lookup[x][1];
  210.         c=translated[loop1][loop2].y;
  211.         _asm
  212.         {
  213.           mov   ax,b
  214.           imul  c
  215.           sal   ax,1
  216.           rcl   dx,1
  217.           sal   ax,1
  218.           rcl   dx,1
  219.           mov   a,dx
  220.         }
  221.         b=lookup[x][0];
  222.         c=translated[loop1][loop2].z;
  223.         _asm
  224.         {
  225.           mov   ax,b
  226.           imul  c
  227.           sal   ax,1
  228.           rcl   dx,1
  229.           sal   ax,1
  230.           rcl   dx,1
  231.           sub   a,dx
  232.         }
  233.         b=lookup[x][0];
  234.         c=translated[loop1][loop2].y;
  235.         translated[loop1][loop2].y=a;
  236.         _asm
  237.         {
  238.           mov   ax,b
  239.           imul  c
  240.           sal   ax,1
  241.           rcl   dx,1
  242.           sal   ax,1
  243.           rcl   dx,1
  244.           mov   a,dx
  245.         }
  246.         b=lookup[x][1];
  247.         c=translated[loop1][loop2].z;
  248.         _asm
  249.         {
  250.           mov   ax,b
  251.           imul  c
  252.           sal   ax,1
  253.           rcl   dx,1
  254.           sal   ax,1
  255.           rcl   dx,1
  256.           add   a,dx
  257.         }
  258.         translated[loop1][loop2].z=a;
  259.       }
  260.  
  261.  
  262.  
  263.       if(z!=0)
  264.       {
  265.         b=lookup[z][1];
  266.         c=translated[loop1][loop2].x;
  267.         _asm
  268.         {
  269.           mov   ax,b
  270.           imul  c
  271.           sal   ax,1
  272.           rcl   dx,1
  273.           sal   ax,1
  274.           rcl   dx,1
  275.           mov   a,dx
  276.         }
  277.         b=lookup[z][0];
  278.         c=translated[loop1][loop2].y;
  279.         _asm
  280.         {
  281.           mov   ax,b
  282.           imul  c
  283.           sal   ax,1
  284.           rcl   dx,1
  285.           sal   ax,1
  286.           rcl   dx,1
  287.           sub   a,dx
  288.         }
  289.         b=lookup[z][0];
  290.         c=translated[loop1][loop2].x;
  291.         translated[loop1][loop2].x=a;
  292.         _asm
  293.         {
  294.           mov   ax,b
  295.           imul  c
  296.           sal   ax,1
  297.           rcl   dx,1
  298.           sal   ax,1
  299.           rcl   dx,1
  300.           mov   a,dx
  301.         }
  302.         b=lookup[z][1];
  303.         c=translated[loop1][loop2].y;
  304.         _asm
  305.         {
  306.           mov   ax,b
  307.           imul  c
  308.           sal   ax,1
  309.           rcl   dx,1
  310.           sal   ax,1
  311.           rcl   dx,1
  312.           add   a,dx
  313.         }
  314.         translated[loop1][loop2].y=a;
  315.       }
  316.     }
  317.   }
  318. }
  319.  
  320.  
  321. /////////////////////////////////////////////////////////////////////////////
  322. // Sort in descending order.
  323. // There are probably better ways of doing this...
  324. void sort(int* x, int* index, int n)
  325. {
  326.   int i,j;
  327.   int temp;
  328.   for(i=0;i<n;i++)index[i]=i;
  329.   for(i=0;i<n-1;i++)
  330.     for(j=i+1;j<n;j++)
  331.       if(x[i]<x[j])
  332.       {
  333.         temp=x[i];
  334.         x[i]=x[j];
  335.         x[j]=temp;
  336.         temp=index[i];
  337.         index[i]=index[j];
  338.         index[j]=temp;
  339.       }
  340. }
  341.  
  342. //{DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  343. //  Procedure DrawPoints;
  344. //  { This draws the translated object to the virtual screen }
  345. void drawpoints()
  346. {
  347.   int loop1,loop2;
  348.   int temp;
  349.   int nx;
  350.   int tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4;
  351.   int zdist[maxpolys];
  352.   int index[maxpolys];
  353.   int zcolor;
  354.   
  355.   for(loop1=0;loop1<maxpolys;loop1++)
  356.   {
  357.     zdist[loop1]=translated[loop1][0].z+translated[loop1][1].z+
  358.           translated[loop1][2].z+translated[loop1][3].z;
  359.   }
  360.   sort(zdist,index,maxpolys);
  361.  
  362.   // Find the 3 nearest, and then draw the furthest first:
  363.   for(loop2=2;loop2>=0;loop2--)
  364.   {
  365.     loop1=index[loop2];
  366.     if((translated[loop1][0].z+zoff<0)&&(translated[loop1][1].z+zoff<0)
  367.      &&(translated[loop1][2].z+zoff<0)&&(translated[loop1][3].z+zoff<0))
  368.      {
  369.       zcolor=translated[loop1][4].z;
  370.       if(zcolor==64)zcolor=63;
  371.       if(zcolor<10)zcolor=10;
  372.       temp=(translated[loop1][0].z)+zoff;
  373.       nx=translated[loop1][0].x;
  374.       _asm
  375.       {
  376.         mov   ax,nx
  377.         mov   dx,ax
  378.         sal   ax,8
  379.         sar   dx,8
  380.         idiv  temp
  381.         add   ax,160
  382.         mov   nx,ax
  383.       }
  384.       tx1=nx;
  385.       nx=translated[loop1][0].y;
  386.       _asm
  387.       {
  388.         mov   ax,nx
  389.         mov   dx,ax
  390.         sal   ax,8
  391.         sar   dx,8
  392.         idiv  temp
  393.         add   ax,100
  394.         mov   nx,ax
  395.       }
  396.       ty1=nx;
  397.  
  398.  
  399.       temp=(translated[loop1][1].z)+zoff;
  400.       nx=translated[loop1][1].x;
  401.       _asm
  402.       {
  403.         mov   ax,nx
  404.         mov   dx,ax
  405.         sal   ax,8
  406.         sar   dx,8
  407.         idiv  temp
  408.         add   ax,160
  409.         mov   nx,ax
  410.       }
  411.       tx2=nx;
  412.       nx=translated[loop1][1].y;
  413.       _asm
  414.       {
  415.         mov   ax,nx
  416.         mov   dx,ax
  417.         sal   ax,8
  418.         sar   dx,8
  419.         idiv  temp
  420.         add   ax,100
  421.         mov   nx,ax
  422.       }
  423.       ty2=nx;
  424.  
  425.  
  426.       temp=(translated[loop1][2].z)+zoff;
  427.       nx=translated[loop1][2].x;
  428.       _asm
  429.       {
  430.         mov   ax,nx
  431.         mov   dx,ax
  432.         sal   ax,8
  433.         sar   dx,8
  434.         idiv  temp
  435.         add   ax,160
  436.         mov   nx,ax
  437.       }
  438.       tx3=nx;
  439.       nx=translated[loop1][2].y;
  440.       _asm
  441.       {
  442.         mov   ax,nx
  443.         mov   dx,ax
  444.         sal   ax,8
  445.         sar   dx,8
  446.         idiv  temp
  447.         add   ax,100
  448.         mov   nx,ax
  449.       }
  450.       ty3=nx;
  451.  
  452.  
  453.       temp=(translated[loop1][3].z)+zoff;
  454.       nx=translated[loop1][3].x;
  455.       _asm
  456.       {
  457.         mov   ax,nx
  458.         mov   dx,ax
  459.         sal   ax,8
  460.         sar   dx,8
  461.         idiv  temp
  462.         add   ax,160
  463.         mov   nx,ax
  464.       }
  465.       tx4=nx;
  466.       nx=translated[loop1][3].y;
  467.       _asm
  468.       {
  469.         mov   ax,nx
  470.         mov   dx,ax
  471.         sal   ax,8
  472.         sar   dx,8
  473.         idiv  temp
  474.         add   ax,100
  475.         mov   nx,ax
  476.       }
  477.       ty4=nx;
  478.  
  479.       drawpoly (tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4,(char)zcolor,Vaddr);
  480.     }
  481.   }
  482. }      
  483.  
  484. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  485. // Procedure MoveAround;
  486. //{ This is the main display procedure. }
  487. void movearound()
  488. {
  489.   int deg,loop1,loop2;
  490.   int degincr=1; // degincr must divide 360! (was 2)
  491.   int clipincr=1; // clipincr must divide 100;
  492.   int ch;
  493.  
  494.   for(loop1=0;loop1<64;loop1++)
  495.   {
  496.     Pal((char)loop1,(char)loop1,0,0);
  497.     Pal((char)(64+loop1),0,(char)loop1,0);
  498.     Pal((char)(128+loop1),0,0,(char)loop1);
  499.   }
  500.  
  501.   deg=0;    
  502.   Cls (0,Vaddr);
  503.   for(loop1=0;loop1<maxpolys;loop1++)
  504.     for(loop2=0;loop2<5;loop2++)  // 5th point is normal to face
  505.     {
  506.       lines[loop1][loop2].x=a[loop1][loop2][0]*8;
  507.       lines[loop1][loop2].y=a[loop1][loop2][1]*8;
  508.       lines[loop1][loop2].z=a[loop1][loop2][2]*8;
  509.     }
  510.      
  511.   Cls(0,Vaddr);
  512.   Cls(0,VGA);
  513.   xoff=160;
  514.   yoff=100;
  515.   zoff=-500;
  516.   
  517.   ytopclip=101;
  518.   ybotclip=100;
  519.   Line2(0,100,319,100,100,VGA);
  520.   delay (500);
  521.   for(loop1=0;loop1<100/clipincr;loop1++)
  522.   {
  523.     rotatepoints(deg,deg,deg);
  524.     drawpoints();
  525.     Line2(0,ytopclip,319,ytopclip,100,Vaddr);
  526.     Line2(0,ybotclip,319,ybotclip,100,Vaddr);
  527.     WaitRetrace();
  528.     Flip2(Vaddr,VGA);
  529.     Cls (0,Vaddr);
  530.     deg+=degincr; if(deg==360)deg=0; // Was deg+=5 mod 360.
  531.     ytopclip=ytopclip-clipincr;
  532.     ybotclip=ybotclip+clipincr;
  533.   }
  534.   while(1)
  535.   {
  536.     rotatepoints(deg,deg,deg);
  537.     drawpoints();
  538.     Line2(0,0,319,0,100,Vaddr);
  539.     Line2(0,199,319,199,100,Vaddr);
  540.     WaitRetrace();
  541.     Flip2(Vaddr,VGA);
  542.     Cls (0,Vaddr);
  543.     deg+=degincr; if(deg==360)deg=0; // Was deg+=5 mod 360.
  544.     if(_bios_keybrd(_KEYBRD_READY))
  545.     {
  546.       ch=(0x00ff&getch());
  547.       if(ch==0x1b)break;
  548.     }
  549.   }
  550.   for(loop1=0;loop1<100/clipincr;loop1++)
  551.   {
  552.     ytopclip=ytopclip+clipincr;
  553.     ybotclip=ybotclip-clipincr;
  554.     rotatepoints(deg,deg,deg);
  555.     drawpoints();
  556.     Line2(0,ytopclip,319,ytopclip,100,Vaddr);
  557.     Line2(0,ybotclip,319,ybotclip,100,Vaddr);
  558.     WaitRetrace();
  559.     Flip2(Vaddr,VGA);
  560.     Cls (0,Vaddr);
  561.     deg+=degincr; if(deg==360)deg=0; // Was deg+=5 mod 360.
  562.   }
  563. }
  564.  
  565. void main()
  566. {
  567.   SetUpVirtual();
  568.   SetMCGA();
  569.   SetUpPoints();
  570.   movearound();
  571.   SetText();
  572. }
  573.  
  574.   
  575. /*
  576. BEGIN
  577.   clrscr;
  578.   writeln ('Welcome to the fourteenth trainer! This one is on glenzing, and also');
  579.   writeln ('throws in a faster poly, fixed point math and a lot more assembler.');
  580.   writeln;
  581.   Writeln ('This isn''t very interactive ... hit any key to start, and then');
  582.   writeln ('hit the [ESC] key to exit. It is a glenzed cube spinning in the');
  583.   writeln ('middle of the screen. Read the text file for more information on');
  584.   writeln ('how the fixed point etc. works ... it will also help a lot if you');
  585.   writeln ('compare it with TUTPROG9.PAS, as this is the same 3D system, just');
  586.   writeln ('speeded up.');
  587.   writeln;
  588.   writeln;
  589.   writeln;
  590.   write ('Hit any key to continue ...');
  591.   readkey;
  592.   SetUpVirtual;
  593.   SetMCGA;
  594.   SetUpPoints;
  595.   MoveAround;
  596.   SetText;
  597.   ShutDown;
  598.   Writeln ('All done. This concludes the fourteenth sample program in the ASPHYXIA');
  599.   Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
  600.   Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS.I also occasinally');
  601.   Writeln ('RSAProg, comp.lang.pascal and comp.sys.ibm.pc.demos. E-mail me at :');
  602.   Writeln ('    smith9@batis.bis.und.ac.za');
  603.   Writeln ('The numbers are available in the main text. You may also write to me at:');
  604.   Writeln ('             Grant Smith');
  605.   Writeln ('             P.O. Box 270');
  606.   Writeln ('             Kloof');
  607.   Writeln ('             3640');
  608.   Writeln ('             Natal');
  609.   Writeln ('             South Africa');
  610.   Writeln ('I hope to hear from you soon!');
  611.   Writeln; Writeln;
  612.   Write   ('Hit any key to exit ...');
  613.   readkey;
  614. END.
  615. */
  616.