home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TUT06NEW.ZIP / TUT6.PAS < prev    next >
Pascal/Delphi Source File  |  1995-01-04  |  9KB  |  259 lines

  1. (*****************************************************************************)
  2. (*                                                                           *)
  3. (* TUT6.PAS - VGA Trainer Program 6 (in Pascal)                              *)
  4. (*                                                                           *)
  5. (* "The VGA Trainer Program" is written by Denthor of Asphyxia.  However it  *)
  6. (* was limited to Pascal only in its first run.  All I have done is taken    *)
  7. (* his original release, translated it to C++, and touched up a few things.  *)
  8. (* I take absolutely no credit for the concepts presented in this code, and  *)
  9. (* am NOT the person to ask for help if you are having trouble.              *)
  10. (*                                                                           *)
  11. (* Program Notes : This program presents pregenerated arrays.                *)
  12. (*                                                                           *)
  13. (* Author        : Grant Smith (Denthor)  - denthor@beastie.cs.und.ac.za     *)
  14. (*                                                                           *)
  15. (*****************************************************************************)
  16.  
  17. {$X+}
  18. USES crt;
  19.  
  20. CONST VGA = $a000;
  21.  
  22. TYPE tbl = Array [1..8000] of real;
  23.              { This will be the shape of the 'table' where we look up
  24.                values, which is faster then calculating them }
  25.  
  26. VAR loop1:integer;
  27.     Pall : Array [1..20,1..3] of byte;
  28.       { This is our temporary pallette. We ony use colors 1 to 20, so we
  29.         only have variables for those ones. }
  30.  
  31. {──────────────────────────────────────────────────────────────────────────}
  32. Procedure SetMCGA;  { This procedure gets you into 320x200x256 mode. }
  33. BEGIN
  34.   asm
  35.      mov        ax,0013h
  36.      int        10h
  37.   end;
  38. END;
  39.  
  40.  
  41. {──────────────────────────────────────────────────────────────────────────}
  42. Procedure SetText;  { This procedure returns you to text mode.  }
  43. BEGIN
  44.   asm
  45.      mov        ax,0003h
  46.      int        10h
  47.   end;
  48. END;
  49.  
  50. {──────────────────────────────────────────────────────────────────────────}
  51. Procedure Cls (Col : Byte);
  52.    { This clears the screen to the specified color }
  53. BEGIN
  54.   Fillchar (Mem [VGA:0],64000,col);
  55. END;
  56.  
  57.  
  58. {──────────────────────────────────────────────────────────────────────────}
  59. Procedure Putpixel (X,Y : Integer; Col : Byte);
  60.   { This puts a pixel on the screen by writing directly to memory. }
  61. BEGIN
  62.   Mem [VGA:X+(Y*320)]:=Col;
  63. END;
  64.  
  65.  
  66. {──────────────────────────────────────────────────────────────────────────}
  67. procedure WaitRetrace; assembler;
  68.   {  This waits for a vertical retrace to reduce snow on the screen }
  69. label
  70.   l1, l2;
  71. asm
  72.     mov dx,3DAh
  73. l1:
  74.     in al,dx
  75.     and al,08h
  76.     jnz l1
  77. l2:
  78.     in al,dx
  79.     and al,08h
  80.     jz  l2
  81. end;
  82.  
  83.  
  84. {──────────────────────────────────────────────────────────────────────────}
  85. Procedure Pal(ColorNo : Byte; R,G,B : Byte);
  86.   { This sets the Red, Green and Blue values of a certain color }
  87. Begin
  88.    Port[$3c8] := ColorNo;
  89.    Port[$3c9] := R;
  90.    Port[$3c9] := G;
  91.    Port[$3c9] := B;
  92. End;
  93.  
  94.  
  95. {──────────────────────────────────────────────────────────────────────────}
  96. Function rad (theta : real) : real;
  97.   {  This calculates the degrees of an angle }
  98. BEGIN
  99.   rad := theta * pi / 180
  100. END;
  101.  
  102.  
  103.  
  104. {──────────────────────────────────────────────────────────────────────────}
  105. Procedure NormCirc;
  106.   { This generates a spireal without using a lookup table }
  107. VAR deg,radius:real;
  108.     x,y:integer;
  109.  
  110. BEGIN
  111.   gotoxy (1,1);
  112.   Writeln ('Without pregenerated arrays.');
  113.   for loop1:=60 downto 43 do BEGIN
  114.     deg:=0;
  115.     radius:=loop1;
  116.     repeat
  117.       X:=round(radius*COS (rad (deg)));
  118.       Y:=round(radius*sin (rad (deg)));
  119.       putpixel (x+160,y+100,61-loop1);
  120.       deg:=deg+0.4;           { Increase the degree so the circle is round }
  121.       radius:=radius-0.02;    { Decrease the radius for a spiral effect }
  122.     until radius<0; {  Continue till at the centre (the radius is zero) }
  123.   END;
  124. END;
  125.  
  126.  
  127. {──────────────────────────────────────────────────────────────────────────}
  128. Procedure LookupCirc;
  129.   {  This draws a spiral using a lookup table }
  130. VAR radius:real;
  131.     x,y,pos:integer;
  132.     costbl : ^tbl;
  133.     sintbl : ^tbl;
  134.  
  135.     Procedure Setupvars;
  136.       {  This is a nested procedure (a procedure in a procedure), and may
  137.          therefore only be used from within the main part of this procedure.
  138.          This section gets the memory for the table, then generates the
  139.          table. }
  140.     VAR deg:real;
  141.     BEGIN
  142.       getmem (costbl,sizeof(costbl^));
  143.       getmem (sintbl,sizeof(sintbl^));
  144.       deg:=0;
  145.       for loop1:=1 to 8000 do BEGIN         { There are 360 degrees in a    }
  146.         deg:=deg+0.4;                       { circle. If you increase the   }
  147.         costbl^[loop1]:=cos (rad(deg));     { degrees by 0.4, the number of }
  148.         sintbl^[loop1]:=sin (rad(deg));     { needed parts of the table is  }
  149.       END;                                  { 360/0.4=8000                  }
  150.     END;
  151.     { NB : For greater accuracy I increase the degrees by 0.4, because if I
  152.            increase them by one, holes are left in the final product as a
  153.            result of the rounding error margin. This means the pregen array
  154.            is bigger, takes up more memory and is slower to calculate, but
  155.            the finished product looks better.}
  156.  
  157. BEGIN
  158.   cls (0);
  159.   gotoxy (1,1);
  160.   Writeln ('Generating variables....');
  161.   setupvars;
  162.   gotoxy (1,1);
  163.   Writeln ('With pregenerated arrays.');
  164.   for loop1:=60 downto 43 do BEGIN
  165.     pos:=1;
  166.     radius:=loop1;
  167.     repeat
  168.       X:=round (radius*costbl^[pos]);   { Note how I am not recalculating sin}
  169.       Y:=round (radius*sintbl^[pos]);   { and cos for each point.            }
  170.       putpixel (x+160,y+100,61-loop1);
  171.       radius:=radius-0.02;
  172.       inc (pos);
  173.       if pos>8000 then pos:=1;    { I only made a table from 1 to 8000, so it}
  174.                                   { must never exceed that, or the program   }
  175.                                   { will probably crash.                     }
  176.     until radius<0;
  177.   END;
  178.   freemem (costbl,sizeof(costbl^));   { Freeing the memory taken up by the   }
  179.   freemem (sintbl,sizeof(sintbl^));   { tables. This is very important.      }
  180. END;
  181.  
  182.  
  183. {──────────────────────────────────────────────────────────────────────────}
  184. Procedure PalPlay;
  185.   { This procedure mucks about with our "virtual pallette", then shoves it
  186.     to screen. }
  187. Var Tmp : Array[1..3] of Byte;
  188.   { This is used as a "temporary color" in our pallette }
  189.     loop1 : Integer;
  190. BEGIN
  191.    Move(Pall[1],Tmp,3);
  192.      { This copies color 1 from our virtual pallette to the Tmp variable }
  193.    Move(Pall[2],Pall[1],18*3);
  194.      { This moves the entire virtual pallette down one color }
  195.    Move(Tmp,Pall[18],3);
  196.      { This copies the Tmp variable to no. 18 of the virtual pallette }
  197.    WaitRetrace;
  198.    For loop1:=1 to 18 do
  199.      pal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);
  200. END;
  201.  
  202.  
  203. BEGIN
  204.   ClrScr;
  205.   writeln ('Hi there! This program will demonstrate the usefullness of ');
  206.   writeln ('pregenerated arrays, also known as lookup tables. The program');
  207.   writeln ('will first draw a spiral without using a lookup table, rotate');
  208.   writeln ('the pallette until a key is pressed, the calculate the lookup');
  209.   writeln ('table, then draw the same spiral using the lookup table.');
  210.   writeln;
  211.   writeln ('This is merely one example for the wide range of uses of a ');
  212.   writeln ('lookup table.');
  213.   writeln;
  214.   writeln;
  215.   Write ('  Hit any key to contine ...');
  216.   Readkey;
  217.   setmcga;
  218.   directvideo:=FALSE;  { This handy trick allows you to use GOTOXY and }
  219.                        { Writeln in GFX mode. Hit CTRL-F1 on it for more }
  220.                        { info/help }
  221.   For Loop1 := 1 to 18 do BEGIN
  222.     Pall[Loop1,1] := (Loop1*3)+9;
  223.     Pall[Loop1,2] := 0;
  224.     Pall[Loop1,3] := 0;
  225.   END;
  226.        { This sets colors 1 to 18 to values between 12 to 63. }
  227.  
  228.    WaitRetrace;
  229.    For loop1:=1 to 18 do
  230.      pal (loop1,pall[loop1,1],pall[loop1,2],pall[loop1,3]);
  231.         { This sets the true pallette to variable Pall }
  232.  
  233.   normcirc;         { This draws a spiral without lookups }
  234.   Repeat
  235.     PalPlay;
  236.   Until keypressed;
  237.   readkey;
  238.   lookupcirc;       { This draws a spiral with lookups }
  239.   Repeat
  240.     PalPlay;
  241.   Until keypressed;
  242.   Readkey;
  243.  
  244.   SetText;
  245.   Writeln ('All done. This concludes the sixth sample program in the ASPHYXIA');
  246.   Writeln ('Training series. You may reach DENTHOR under the name of GRANT');
  247.   Writeln ('SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the');
  248.   Writeln ('ASPHYXIA BBS. I am also an avid Connectix BBS user.');
  249.   Writeln ('Get the numbers from Roblist, or write to :');
  250.   Writeln ('             Grant Smith');
  251.   Writeln ('             P.O. Box 270');
  252.   Writeln ('             Kloof');
  253.   Writeln ('             3640');
  254.   Writeln ('I hope to hear from you soon!');
  255.   Writeln; Writeln;
  256.   Write   ('Hit any key to exit ...');
  257.   Readkey;
  258. END.
  259.