home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 31 / CDASC_31_1996_juillet_aout.iso / vrac / 3dstars0.zip / 3DSTARS.PAS next >
Pascal/Delphi Source File  |  1994-10-30  |  6KB  |  228 lines

  1. Program PanzerBatallion_294;
  2.  
  3.  { Real-3D starfield. Code by Alan F.                                94-10-30
  4.  
  5.               This is just a cute little starfield routine
  6.               in Turbo Pascal. I am not into coding PC-software
  7.               and this is my first demo-ish routine for PC. Nothing
  8.               special indeed. Well, I consider PC-assembler being
  9.               far less efficient than the MC680x0 assembler so this
  10.               code features only a few assembler subroutines.
  11.  
  12.               Excuse the lack of real comments in the code.
  13.  
  14.    Contact at Vodka BBS - +46-(0)21-412076, 14.4kbps, 24h/day.
  15.  
  16.    You will need to adjust the number of them stars shown to fit your
  17.    system capatibilities.
  18.  
  19.    Note: If you have a math coprocessor, compile this using math-co option!
  20.  
  21.  }
  22.  
  23. uses crt;
  24.  
  25. const d:integer=300;                            {Distance from Screen}
  26.       stno:integer=100;                         {Number of stars to plot}
  27.       offscreen:integer=0;
  28.       my:integer=220;                           {The positin of the 'camera'}
  29.  
  30. var x,y,z,sx,sy,xa,ya,za:integer;               {Just a bunch of variabels}
  31.     xb,yb,zb,xab,yab,zab:byte;
  32.     sr1,sr2,sr3,cr1,cr2,cr3:longint;
  33.     fact:real;
  34.     xr,yr,zr,add:integer;
  35.     star:array[0..999,0..2] of integer;         {... and some arrays}
  36.     color:array[0..999,0..1] of byte;
  37.     adds:array[0..999,0..1] of integer;
  38.     trig:array[0..720,0..1] of integer;
  39.  
  40. procedure setcolors;                {Initialize gray-scales}
  41.      var  colreg:byte;
  42.      BEGIN
  43.      for colreg:=0 to 255 do begin
  44.  
  45.       asm
  46.       mov    dx,3c8h
  47.       mov   al,colreg
  48.       out   dx,al
  49.       inc   dx
  50.       mov   al,colreg
  51.       out   dx,al
  52.       mov   al,colreg
  53.       out   dx,al
  54.       mov   al,colreg
  55.       out   dx,al
  56.       end;
  57.     end;
  58.     END;
  59.  
  60. procedure setmode(mode:byte);            {Shift VGA-modes}
  61.      begin
  62.      asm
  63.        xor ah, ah
  64.        mov al, mode
  65.        int 10h
  66.      end;
  67.  end;
  68.  
  69. procedure synchronise;                   {Synchronize Vertical-Blank}
  70.        begin
  71.        asm
  72.         mov     dx,3dah
  73.        @preVRT:
  74.         in      al,dx
  75.         test    al,8
  76.         jnz     @preVRT
  77.        @postVRT:
  78.         in      al,dx
  79.         test    al,8
  80.         jz      @postVRT
  81.        end;
  82. end;
  83.  
  84. procedure trigonometrics;            {Precalculate SIN/COS}
  85.     var i:integer;
  86.     BEGIN
  87.     for i:=0 to 720 do begin
  88.        trig[i,0]:=round(sin(i/720*(pi*2))*1024);
  89.        trig[i,1]:=round(cos(i/720*(pi*2))*1024);
  90.     end;
  91.     END;
  92.  
  93. procedure rotate;                 {Rotate the view of the camera to the
  94.                    current values}
  95.       BEGIN
  96.            sr1:=trig[xr,0];   {Uses precalculated SIN/COS thus avoiding}
  97.            cr1:=trig[xr,1];   {slow floating-point variables}
  98.            sr2:=trig[yr,0];
  99.            cr2:=trig[yr,1];
  100.            sr3:=trig[zr,0];
  101.            cr3:=trig[zr,1];
  102.       END;
  103.  
  104. procedure plotstars(numb,f1 : integer);         {Plot them stars}
  105.  var      i:integer;
  106.       colr:byte;
  107.  begin
  108.    for i:=0 to numb do begin
  109.    add:=adds[i,f1];
  110.    colr:=color[i,f1];
  111.    asm
  112.      cmp add, 0                           {0 marks an off-screen star}
  113.      je  @noplot                          {If not visible, do nothing}
  114.      mov ax, 0A000h                       {Screenbase -> AX}
  115.      mov si, add                          {Screen position -> SI}
  116.      mov es, ax                           {AX -> ES}
  117.      mov al, colr                         {Get color}
  118.      mov es:[si],al                       {Plot the colored star}
  119.    @noplot:
  120.      end;
  121.    end;
  122.  end;
  123.  
  124. procedure erasestars(numb,field:integer); {Erase stars, (almost) the same as
  125.                        the procedure above}
  126.  var      i:integer;
  127.  begin
  128.    for i:=0 to numb do begin
  129.    add:=adds[i,field];
  130.    asm
  131.      cmp add, 0
  132.      je  @noerase
  133.      mov ax, 0A000h
  134.      mov si, add
  135.      mov es, ax
  136.      mov byte ptr es:[si],0                {Remove the star from screen}
  137.    @noerase:
  138.      end;
  139.      end;
  140.  end;
  141.  
  142. Procedure calculate(numb,field:integer);   {Calculate 3D stars}
  143.       var i:integer;
  144.       BEGIN
  145.            for i:=0 to numb do begin
  146.            xa:=(cr1*star[i,0]-sr1*star[i,1]) div 1024;
  147.            ya:=(sr1*star[i,0]+cr1*star[i,1]) div 1024;
  148.            za:=(cr2*star[i,2]-sr2*xa) div 1024;
  149.  
  150.            x:=(cr2*xa+sr2*star[i,2]) div 1024;
  151.            y:=(cr3*ya-sr3*za) div 1024;
  152.            z:=(sr3*ya+cr3*za) div 1024;
  153.  
  154.            color[i,field]:=255-(y+200) div 7;  {Calculate the shade of
  155.                             the current star}
  156.  
  157.            inc (y, my);                 {Reposition camera's position}
  158.  
  159.            if y<>0 then            {Make sure no division-by-zero occurs}
  160.            fact:=d/y
  161.            else
  162.            fact:=0;                      {The star is too close anyway}
  163.            sx:=round(160+fact*x);        {Finally, convert to 2D}
  164.            sy:=round(100+fact*z);
  165.  
  166.            if (sx>0) and (sx<320) and (sy>0) and (sy<200) then
  167.           adds[i,field]:=sx+sy*320     {Calculate star's offset}
  168.            else
  169.           adds[i,field]:=offscreen
  170.            end;
  171.       END;
  172.  
  173. procedure changeview;            {Change the ange of the camera}
  174.  
  175.     begin
  176.       xr:=xr+2;
  177.       yr:=yr+1;
  178.       yr:=yr+2;
  179.  
  180.       if xr>719 then
  181.          xr:=xr-(720*(xr div 720));
  182.       if yr>719 then
  183.          yr:=yr-(720*(yr div 720));
  184.       if zr>719 then
  185.          zr:=zr-(720*(zr div 720));
  186.     end;
  187.  
  188. procedure slump(numb:integer);     {Randomize the positions. (No kidding!?)}
  189.       var i:integer;
  190.       BEGIN
  191.            randomize;
  192.            for i:=0 to numb do begin
  193.            star[i,0]:=random(200)-100;
  194.            star[i,1]:=random(200)-100;
  195.            star[i,2]:=random(200)-100;
  196.            end;
  197.       END;
  198.  
  199. BEGIN                                   {Ahh, yeah, the loop itself...}
  200.  
  201.      trigonometrics;
  202.      slump(stno);
  203.  
  204.      setmode($13);
  205.      rotate;
  206.      calculate(stno,1);
  207.  
  208.      setcolors;
  209.  
  210.      repeat
  211.        rotate;
  212.        changeview;
  213.        calculate(stno,0);
  214.        synchronise;
  215.        erasestars(stno,1);
  216.        plotstars(stno,0);
  217.  
  218.        rotate;
  219.        changeview;
  220.        calculate(stno,1);
  221.        synchronise;
  222.        erasestars(stno,0);
  223.        plotstars(stno,1);
  224.  
  225.      until keypressed;
  226.      setmode($3);
  227. END.
  228.