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

  1. /* 
  2.   tut9.c
  3.   10/30/94
  4.   from tutprog9.pas
  5.   Adapted from Denthor's tutprog9.pas
  6.   Translated into C, from Denthor's VGA Trainer, by
  7.   Steve Pinault, scp@ohm.att.com
  8.   Compiled with Microsoft Visual C++ 1.5 (Microsoft C 8.0)
  9.   To compile:
  10.   First compile the subroutines in tutsubs.c with the batch file 
  11.   cltutsub.bat
  12.   Then compile any of the tutor programs with the batch file
  13.   cltut.bat
  14.   Example: C:>cltutsub
  15.            C:>cltut tut9.c
  16.            to compile this program.
  17. */
  18.  
  19. #include "tutheadr.h"
  20. #define maxpolys 5
  21. int A[maxpolys][4][3] = 
  22.         {
  23.          {{-10,10,0},{-2,-10,0},{0,-10,0},{-5,10,0}},
  24.          {{10,10,0},{2,-10,0},{0,-10,0},{5,10,0}},
  25.          {{-2,-10,0},{2,-10,0},{2,-5,0},{-2,-5,0}},
  26.          {{-6,0,0},{6,0,0},{7,5,0},{-7,5,0}},
  27.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  28.         }; // { The 3-D coordinates of our object ... stored as (X1,Y1,Z1}, }
  29.            // { (X2,Y2,Z2} ... for the 4 points of a poly }
  30. int S[maxpolys][4][3] = 
  31.         {
  32.          {{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}},
  33.          {{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}},
  34.          {{-10,1,0},{10,1,0},{10,-2,0},{-10,-2,0}},
  35.          {{-10,-8,0},{-7,-8,0},{-7,0,0},{-10,0,0}},
  36.          {{10,8,0},{7,8,0},{7,0,0},{10,0,0}}
  37.         }; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
  38.            //{ {X2,Y2,Z2} ... for the 4 points of a poly }
  39. int P[maxpolys][4][3] = 
  40.         {
  41.          {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
  42.          {{10,-10,0},{7,-10,0},{7,0,0},{10,0,0}},
  43.          {{-9,-10,0},{9,-10,0},{9,-7,0},{-9,-7,0}},
  44.          {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
  45.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  46.         }; // { The 3-D coordinates of our object ... stored as (X1,Y1,Z1}, }
  47.            // { (X2,Y2,Z2} ... for the 4 points of a poly }
  48. int H[maxpolys][4][3] = 
  49.         {
  50.          {{-10,-10,0},{-7,-10,0},{-7,10,0},{-10,10,0}},
  51.          {{10,-10,0},{7,-10,0},{7,10,0},{10,10,0}},
  52.          {{-9,-1,0},{9,-1,0},{9,2,0},{-9,2,0}},
  53.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  54.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  55.         }; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
  56.            // { (X2,Y2,Z2} ... for the 4 points of a poly }
  57. int Y[maxpolys][4][3] = 
  58.         {
  59.          {{-7,-10,0},{0,-3,0},{0,0,0},{-10,-7,0}},
  60.          {{7,-10,0},{0,-3,0},{0,0,0},{10,-7,0}},
  61.          {{-2,-3,0},{2,-3,0},{2,10,0},{-2,10,0}},
  62.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  63.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  64.         }; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
  65.            // { {X2,Y2,Z2} ... for the 4 points of a poly }
  66. int X[maxpolys][4][3] = 
  67.         {
  68.          {{-7,-10,0},{10,7,0},{7,10,0},{-10,-7,0}},
  69.          {{7,-10,0},{-10,7,0},{-7,10,0},{10,-7,0}},
  70.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  71.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  72.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  73.         }; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
  74.            // { {X2,Y2,Z2} ... for the 4 points of a poly }
  75. int I[maxpolys][4][3] = 
  76.         {
  77.          {{-10,-10,0},{10,-10,0},{10,-7,0},{-10,-7,0}},
  78.          {{-10,10,0},{10,10,0},{10,7,0},{-10,7,0}},
  79.          {{-2,-9,0},{2,-9,0},{2,9,0},{-2,9,0}},
  80.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}},
  81.          {{0,0,0},{0,0,0},{0,0,0},{0,0,0}}
  82.         }; // { The 3-D coordinates of our object ... stored as {X1,Y1,Z1}, }
  83.            // { {X2,Y2,Z2) ... for the 4 points of a poly }
  84.  
  85.  
  86.  
  87. struct Point Lines[maxpolys][4];
  88. struct Point translated[maxpolys][4];
  89. int xoff,yoff,zoff;
  90. float lookup[360][2];
  91.  
  92.  
  93.  
  94.  
  95. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  96. // Procedure DrawPoly(x1,y1,x2,y2,x3,y3,x4,y4:integer;color:byte;where:word);
  97. //   { This draw a polygon with 4 points at x1,y1 , x2,y2 , x3,y3 , x4,y4
  98. //    in color col }
  99. void DrawPoly(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, char color, int where)
  100. {
  101.   int x;
  102.   int mny,mxy;
  103.   int mnx,mxx,yc;
  104.   int mul1,div1,mul2,div2,mul3,div3,mul4,div4;
  105.  
  106.   mny=y1; mxy=y1;
  107.   if (y2<mny) mny=y2;
  108.   if (y2>mxy) mxy=y2;
  109.   if (y3<mny) mny=y3;
  110.   if (y3>mxy) mxy=y3;  //  { Choose the min y mny and max y mxy }
  111.   if (y4<mny) mny=y4;
  112.   if (y4>mxy) mxy=y4;
  113.  
  114.   if (mny<0)   mny=0;
  115.   if (mxy>199) mxy=199;
  116.   if (mny>199) return;
  117.   if (mxy<0)   return;  //      { Verticle range checking }
  118.  
  119.   mul1=x1-x4; div1=y1-y4;
  120.   mul2=x2-x1; div2=y2-y1;
  121.   mul3=x3-x2; div3=y3-y2;
  122.   mul4=x4-x3; div4=y4-y3; // { Constants needed for intersection calc }
  123.  
  124.   for (yc=mny;yc<=mxy;yc++)
  125.   {
  126.       mnx=320;
  127.       mxx=-1;
  128.       if ((y4>=yc) || (y1>=yc))
  129.         if ((y4<=yc)|| (y1<=yc)) // { Check that yc is between y1 and y4 }
  130.           if (!(y4==y1))
  131.             {
  132.               x=(yc-y4)*mul1/div1+x4; // { Point of intersection on x axis }
  133.               if (x<mnx)
  134.                 mnx=x;
  135.               if (x>mxx)
  136.                 mxx=x;    // { Set point as start or end of horiz line }
  137.             }
  138.       if ((y1>=yc) || (y2>=yc))
  139.         if ((y1<=yc) || (y2<=yc))// { Check that yc is between y1 and y2 }
  140.           if (!(y1==y2)) 
  141.           {
  142.               x=(yc-y1)*mul2 / div2+x1; // { Point of intersection on x axis }
  143.               if (x<mnx)
  144.                 mnx=x;
  145.               if (x>mxx)
  146.                 mxx=x;    //   { Set point as start or end of horiz line }
  147.            }
  148.       if ((y2>=yc) || (y3>=yc)) 
  149.         if ((y2<=yc) || (y3<=yc)) //  { Check that yc is between y2 and y3 }
  150.           if (!(y2==y3))
  151.             {
  152.               x=(yc-y2)*mul3 / div3+x2; //{ Point of intersection on x axis }
  153.               if (x<mnx)
  154.                 mnx=x;
  155.               if (x>mxx)
  156.                 mxx=x;  //     { Set point as start or end of horiz line }
  157.             }
  158.       if ((y3>=yc) || (y4>=yc))
  159.         if ((y3<=yc) || (y4<=yc)) //  { Check that yc is between y3 and y4 }
  160.           if (!(y3==y4))
  161.             {
  162.               x=(yc-y3)*mul4 / div4+x3; // { Point of intersection on x axis }
  163.               if (x<mnx)
  164.                 mnx=x;
  165.               if (x>mxx)
  166.                 mxx=x; //       { Set point as start or end of horiz line }
  167.             }
  168.       if (mnx<0)
  169.         mnx=0;
  170.       if (mxx>319)
  171.         mxx=319;   //       { Range checking on horizontal line }
  172.       if (mnx<=mxx)
  173.          Hline (mnx,mxx,yc,color,where);
  174.          //  { Draw the horizontal line }
  175.     }
  176. }
  177.  
  178.  
  179.  
  180. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  181. // Procedure SetUpPoints;
  182. //   { This creates the lookup table }
  183. void SetUpPoints()
  184. {
  185.   int loop1;
  186.   for(loop1=0;loop1<360;loop1++)
  187.   {
  188.     lookup [loop1][0]=(float)sin((double)rad((float)loop1));
  189.     lookup [loop1][1]=(float)cos((double)rad((float)loop1));
  190.   } 
  191. }  
  192.  
  193.  
  194. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  195. // Procedure RotatePoints (X,Y,Z:Integer);
  196. //   { This rotates object lines by X,Y and Z; then places the result in
  197. //     TRANSLATED }
  198. // rotate about x: newy = cos*y-sin*z (cos*cos-sin*sin)
  199. //                 newz = sin*y+cos*z (sin*cos+cos*sin)
  200. //           i.e:  newy+i*newz=e^(i*theta)*(y+i*z) (theta=int x)
  201. //                            =(cos+i*sin)*(y+i*z)
  202. // translated[loop1][0] and translated[loop1][1] are the two endpoints
  203. // of line segment loop1.
  204. //
  205. void RotatePoints(int x, int y, int z)
  206. {
  207.   int loop1,loop2;
  208.   struct Point temp;
  209.   for(loop1=0;loop1<maxpolys;loop1++)
  210.     for(loop2=0;loop2<4;loop2++)
  211.     {
  212. temp.x=Lines[loop1][loop2].x;
  213. temp.y=lookup[x][1]*Lines[loop1][loop2].y - lookup[x][0]*Lines[loop1][loop2].z;
  214. temp.z=lookup[x][0]*Lines[loop1][loop2].y + lookup[x][1]*Lines[loop1][loop2].z;
  215. translated[loop1][loop2]=temp;
  216.  
  217. temp.x=lookup[y][1]*translated[loop1][loop2].x-lookup[y][0]*translated[loop1][loop2].y;
  218. temp.y=lookup[y][0]*translated[loop1][loop2].x+lookup[y][1]*translated[loop1][loop2].y;
  219. temp.z=translated[loop1][loop2].z;
  220. translated[loop1][loop2]=temp;
  221.  
  222. temp.z=lookup[z][1]*translated[loop1][loop2].z-lookup[z][0]*translated[loop1][loop2].x;
  223. temp.x=lookup[z][0]*translated[loop1][loop2].z+lookup[z][1]*translated[loop1][loop2].x;
  224. temp.y=translated[loop1][loop2].y;
  225. translated[loop1][loop2]=temp;
  226.   }
  227. }
  228.  
  229. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  230. // Procedure DrawPoints;
  231. //   { This draws the translated object to the virtual screen }
  232. void DrawPoints()
  233. {
  234.   int loop1;
  235.   int nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3;
  236.   int temp0,temp1,temp2,temp3;
  237.   for(loop1=0;loop1<maxpolys;loop1++)
  238.   {
  239.     temp0=round (translated[loop1][0].z+zoff);
  240.     temp1=round (translated[loop1][1].z+zoff);
  241.     temp2=round (translated[loop1][2].z+zoff);
  242.     temp3=round (translated[loop1][3].z+zoff);
  243.     if((temp0<0)&&(temp1<0)&&(temp2<0)&&(temp3<0))
  244.     {
  245.       nx0 =round (256*translated[loop1][0].x) / temp0 + xoff;
  246.       ny0 =round (256*translated[loop1][0].y) / temp0 + yoff;
  247.       nx1 =round (256*translated[loop1][1].x) / temp1 + xoff;
  248.       ny1 =round (256*translated[loop1][1].y) / temp1 + yoff;
  249.       nx2 =round (256*translated[loop1][2].x) / temp2 + xoff;
  250.       ny2 =round (256*translated[loop1][2].y) / temp2 + yoff;
  251.       nx3 =round (256*translated[loop1][3].x) / temp3 + xoff;
  252.       ny3 =round (256*translated[loop1][3].y) / temp3 + yoff;
  253.       DrawPoly(nx0,ny0,nx1,ny1,nx2,ny2,nx3,ny3,13,Vaddr);
  254.     }
  255.   }
  256. }
  257.  
  258. //  Procedure Whizz (sub:boolean);
  259. void Whizz(int sub, int* deg)
  260. {
  261.   int loop1;
  262.   
  263.   for(loop1=-64;loop1<=-5;loop1++)
  264.   {
  265.       zoff=loop1*8;
  266.       if(sub) xoff-=7; else xoff+=7;
  267.       RotatePoints(*deg,*deg,*deg);
  268.       DrawPoints();
  269.       WaitRetrace();
  270.       Flip2(Vaddr,VGA);
  271.       Cls(0,Vaddr);
  272.       (*deg)++; if(*deg==360)*deg=0;
  273.   }
  274. }  
  275.  
  276.  
  277.  
  278. // {DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD}
  279. // Procedure MoveAround;
  280. //  {  This is the main display procedure. Firstly it brings the object towards
  281. //    the viewer by increasing the Zoff, then passes control to the user }
  282. void MoveAround()
  283. {
  284.   int loop1,loop2;
  285.   int deg;
  286.   char ch;
  287.   
  288.   deg=0;
  289.   ch=0x0;
  290.   yoff=100;
  291.   xoff=350;
  292.   Cls(0,Vaddr);
  293.   for(loop1=0;loop1<maxpolys;loop1++)
  294.     for(loop2=0;loop2<4;loop2++)
  295.     {
  296.       Lines[loop1][loop2].x=A[loop1][loop2][0];
  297.       Lines[loop1][loop2].y=A[loop1][loop2][1];
  298.       Lines[loop1][loop2].z=A[loop1][loop2][2];
  299.     }
  300.   Whizz (1, °);
  301.  
  302.   for(loop1=0;loop1<maxpolys;loop1++)
  303.     for(loop2=0;loop2<4;loop2++)
  304.     {
  305.       Lines[loop1][loop2].x=S[loop1][loop2][0];
  306.       Lines[loop1][loop2].y=S[loop1][loop2][1];
  307.       Lines[loop1][loop2].z=S[loop1][loop2][2];
  308.     }
  309.   Whizz (0, °);
  310.  
  311.   for(loop1=0;loop1<maxpolys;loop1++)
  312.     for(loop2=0;loop2<4;loop2++)
  313.     {
  314.       Lines[loop1][loop2].x=P[loop1][loop2][0];
  315.       Lines[loop1][loop2].y=P[loop1][loop2][1];
  316.       Lines[loop1][loop2].z=P[loop1][loop2][2];
  317.     }
  318.   Whizz (1, °);
  319.  
  320.   for(loop1=0;loop1<maxpolys;loop1++)
  321.     for(loop2=0;loop2<4;loop2++)
  322.     {
  323.       Lines[loop1][loop2].x=H[loop1][loop2][0];
  324.       Lines[loop1][loop2].y=H[loop1][loop2][1];
  325.       Lines[loop1][loop2].z=H[loop1][loop2][2];
  326.     }
  327.   Whizz (0, °);
  328.  
  329.   for(loop1=0;loop1<maxpolys;loop1++)
  330.     for(loop2=0;loop2<4;loop2++)
  331.     {
  332.       Lines[loop1][loop2].x=Y[loop1][loop2][0];
  333.       Lines[loop1][loop2].y=Y[loop1][loop2][1];
  334.       Lines[loop1][loop2].z=Y[loop1][loop2][2];
  335.     }
  336.   Whizz (1, °);
  337.  
  338.   for(loop1=0;loop1<maxpolys;loop1++)
  339.     for(loop2=0;loop2<4;loop2++)
  340.     {
  341.       Lines[loop1][loop2].x=X[loop1][loop2][0];
  342.       Lines[loop1][loop2].y=X[loop1][loop2][1];
  343.       Lines[loop1][loop2].z=X[loop1][loop2][2];
  344.     }
  345.   Whizz (0, °);
  346.  
  347.   for(loop1=0;loop1<maxpolys;loop1++)
  348.     for(loop2=0;loop2<4;loop2++)
  349.     {
  350.       Lines[loop1][loop2].x=I[loop1][loop2][0];
  351.       Lines[loop1][loop2].y=I[loop1][loop2][1];
  352.       Lines[loop1][loop2].z=I[loop1][loop2][2];
  353.     }
  354.   Whizz (1, °);
  355.  
  356.   for(loop1=0;loop1<maxpolys;loop1++)
  357.     for(loop2=0;loop2<4;loop2++)
  358.     {
  359.       Lines[loop1][loop2].x=A[loop1][loop2][0];
  360.       Lines[loop1][loop2].y=A[loop1][loop2][1];
  361.       Lines[loop1][loop2].z=A[loop1][loop2][2];
  362.     }
  363.   Whizz (0, °);
  364.  
  365.  
  366.   Cls (0,Vaddr);
  367.   Cls (0,VGA);
  368.   xoff = 160;
  369.  
  370.   while(ch!=0x1b)  // escape
  371.   {
  372.     if(_bios_keybrd(_KEYBRD_READY))
  373.     {
  374.       ch=(getch()&0x00ff);
  375.       if(ch==0x71)break; // 'q'
  376.       if(ch==0x51)break; // 'Q'
  377.       if(ch==0x1b)break; // ESC
  378.       if(ch=='Z')zoff+=5;
  379.       if(ch=='z')zoff-=5;
  380.       if(ch=='X')xoff+=5;
  381.       if(ch=='x')xoff-=5;
  382.       if(ch=='Y')yoff+=5;
  383.       if(ch=='y')yoff-=5;
  384.     }
  385.     DrawPoints();
  386.     WaitRetrace();
  387.     Flip2(Vaddr,VGA);
  388.     Cls(0,Vaddr);
  389.     RotatePoints(deg,deg,deg);
  390.     deg++; if(deg==360)deg=0;
  391.   }
  392. }  
  393.  
  394. void main()
  395. {
  396.   SetUpVirtual();
  397.   _clearscreen(_GCLEARSCREEN);
  398.   SetMCGA();
  399.   SetUpPoints();
  400.   MoveAround();
  401.   SetText();
  402. }          
  403.  
  404. /*  
  405.   Sorry, I got too lazy to convert these to printf's!
  406.   Writeln ('Hello there! Varsity has begun once again, so it is once again');
  407.   Writeln ('back to the grindstone ;-) ... anyway, this tutorial is, by');
  408.   Writeln ('popular demand, on poly-filling, in relation to 3-D solids.');
  409.   Writeln;
  410.   Writeln ('In this program, the letters of ASPHYXIA will fly past you. As you');
  411.   Writeln ('will see, they are solid, not wireframe. After the last letter has');
  412.   Writeln ('flown by, a large A will be left in the middle of the screen.');
  413.   Writeln;
  414.   Writeln ('You will be able to move it around the screen, and you will notice');
  415.   Writeln ('that it may have bits only half on the screen, i.e. clipping is');
  416.   Writeln ('perfomed. To control it use the following : "A" and "Z" control the Z');
  417.   Writeln ('movement, "," and "." control the X movement, and "S" and "X"');
  418.   Writeln ('control the Y movement. I have not included rotation control, but');
  419.   Writeln ('it should be easy enough to put in yourself ... if you have any');
  420.   Writeln ('hassles, leave me mail.');
  421.   Writeln;
  422.   Writeln ('I hope this is what you wanted...leave me mail for new ideas.');
  423.   writeln;
  424.   writeln;
  425.   Write ('  Hit any key to contine ...');
  426.   Readkey;
  427.   SetMCGA;
  428.   SetUpPoints;
  429.   MoveAround;
  430.   SetText;
  431.   ShutDown;
  432.   Writeln ('All done. This concludes the ninth sample program in the ASPHYXIA');
  433.   Writeln ('Training series. You may reach DENTHOR under the names of GRANT');
  434.   Writeln ('SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid');
  435.   Writeln ('Connectix BBS user, and occasionally read RSAProg.');
  436.   Writeln ('The numbers are available in the main text. You may also write to me at:');
  437.   Writeln ('             Grant Smith');
  438.   Writeln ('             P.O. Box 270');
  439.   Writeln ('             Kloof');
  440.   Writeln ('             3640');
  441.   Writeln ('I hope to hear from you soon!');
  442.   Writeln; Writeln;
  443.   Write   ('Hit any key to exit ...');
  444.   Readkey;
  445. END.
  446. */
  447.