``````
{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;
cos2,sin2,cos1,sin1:longint;
sf:byte;
begin
v1:=viewcos^;                {to fix the fishbowl effect}
v2:=viewcos^;
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;

``````