[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]


{This is my procedure for drawing DOOM-like floors for the game I am working
on. It uses the similar triangle method, but does not work as fast as I
would like. The problem is probably that I am using Turbo Pascal.  I tried to 
optimize using assembler, but have never used it before.   If anyone could 
help me speed it up, I would really appreciate it. I think this procedure runs 
at about 11-12 fps without my wall,objects procedures, at about 8 fps with 
them.  The wall,objects procedures run at about 20 fps without the floor 
procedure.  My goal is for a nice 15 fps with everything.  All speeds are on a 
486 DX2/66.



Sorry for the sloppy code. I'll try to explain.}



procedure floorcast(var player1:player);
var
   xp,yp:integer;       {some of these variables might not be needed}
   z:word;
   i:byte;
   dd:longint;
   xstep,ystep:longint;
   scrd:integer;
   finx1,finy1:longint;
   finx2,finy2:integer;
   finxd,finyd:longint;
   distance:longint;
   cc,colour:byte;
   ssofs:word;
   s3,o3,o4,s4:word;
   mapx,mapy,bmapx,bmapy:byte;
   ang:integer;
   v1,v2:longint;
   lookm:integer;
   flm:byte;
   loop:integer;
   ssinc:byte;
   zinc:word;
   hh:word;
   shade:byte;
   cos2,sin2,cos1,sin1:longint;
   sf:byte;
begin
v1:=viewcos^[0];                {to fix the fishbowl effect}
v2:=viewcos^[319];
lookm:=(player1.look-100); {to find out if the player is looking up or down}
loop:=(player1.look+1);    {number of h-lines to draw}
hh:=(vdis)*player1.height;  {viewer distance * player height}
ang:=dangle(0,-dangle(player1.angle,(-160)));  {angle for left most pixel}
cos1:=cost^[ang]; {trig values for angle}
sin1:=sint^[ang];
ang:=dangle(0,-dangle(player1.angle,(160)));  {angle for right most pixel}
cos2:=cost^[ang]; {trig values for angle}
sin2:=sint^[ang];
ssofs:=320*loop+o1+xmin;  {screen offset at start of loop}
ssinc:=xmin+320-xmax;     {screen offset increment to start each h-line}
zinc:=xmax-xmin;          {size of h-viewport}
emsmap(handle,0,0);       {ems routines for graphics}
emsmap(handle,1,1);
emsmap(handle,2,2);
emsmap(handle,3,3);
for i:=loop to toomax do  {loop from horizon to bottom of screen}
begin
     dd:=(hh div (i-player1.look)); {temp distance variable used twice}
     distance:=(dd*v1) shr 16;      {fishbowl adjust}
     distance:=(distance*5) shr 2;  {This fixes a strange floor shift for me}
     distance:=distance-lookm;      {adjust for looking up or down}
     finx1:=((distance*cos1)) shr 16; {rotate to player angle}
     finy1:=(-(distance*sin1)) shr 16;

     distance:=(dd*v2) shr 16;         {same as above for right most pixel}
     distance:=(distance*5) shr 2;
     distance:=distance-lookm;
     finx2:=((distance*cos2)) shr 16;
     finy2:=(-(distance*sin2)) shr 16;

     finxd:=(finx2-finx1);  {x-distance}
     finyd:=(finy2-finy1);  {y-distance}
     finx1:=finx1+player1.x; {translate to player position}
     finy1:=finy1+player1.y;
     xstep:=(finxd shl 16) div 320;  {x-step along map for each pixel}
     ystep:=(finyd shl 16) div 320;  {x-step along map for each pixel}
     finx1:=finx1 shl 16;
     finy1:=finy1 shl 16;
     z:=ssofs+zinc;  {value for end of loop}
     finx1:=(finx1+xstep*xmin); { adjust for variable screen size}
     finy1:=(finy1+ystep*xmin);
     repeat
          if mem[s1:o1+ssofs]=0 then {if a wall or object has not been drawn}
          begin
          xp:=finx1 shr 16;  {fixed point shift}
          yp:=finy1 shr 16;
          asm
             mov ax,xp       {map position}
             shr ax,6
             mov mapx,al
             mov ax,yp
             shr ax,6
             mov mapy,al
             mov ax,xp       {bitmap position}
             and ax,3Fh
             mov bmapx,al
             mov ax,yp
             and ax,3Fh
             mov bmapy,al
          end;
          if (mapx>25) or (mapx<=0) or (mapy>25) or (mapy<=0) then
          colour:=8   {check if out of bounds, I have a small map}
          else
          begin
          colour:=floormap^[mapx,mapy]; {else find colour in map}
          flm:=flipmap^[mapx,mapy];     {check if I should flip the bitmap}
          if flm=0 then
          begin
          end
          else if flm=1 then bmapx:=63-bmapx
          else if flm=2 then bmapy:=63-bmapy
          else if flm=3 then
          begin
               bmapx:=63-bmapx;
               bmapy:=63-bmapy;
          end;
          end;
          if bmapy>62 then bmapy:=62;
          o4:=bmapx+((bmapy) shl 6)+ctable[colour];  {find the offset of the}
          asm                                        {pixel in the bitmap}
             mov es,[segment]
             mov bx,[o4]
             mov dl,byte ptr [es:bx]                {put it on the screen}
             mov es,[s1]
             mov bx,[ssofs]
             mov byte ptr [es:bx],dl
          end;
          end;
          ssofs:=ssofs+1;                     {increment screen offset}
          finx1:=finx1+xstep;                 {step along map}
          finy1:=finy1+ystep;
     until ssofs=z;                             {until end of h-line}
     ssofs:=ssofs+ssinc;                        {move down one h-line}
     end;
end;

[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]