home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 18
/
CD_ASCQ_18_111294_W.iso
/
dos
/
prg
/
pas
/
gfxfx
/
threedee.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1994-05-28
|
5KB
|
192 lines
{$r-}
unit threedee;
interface
const
vidseg:word=$a000;
divd:word=128;
var
ctab:array[0..255] of integer;
stab:array[0..255] of integer;
virscr:pointer;
virseg:word;
minx,miny,maxx,maxy:integer;
border:boolean;
procedure setborder(col:byte);
procedure retrace;
procedure setpal(c,r,g,b:byte);
procedure cls(lvseg:word);
procedure flip(src,dst:word);
procedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte);
function sinus(i:byte):integer;
function cosinus(i:byte):integer;
implementation
{ -------------------------------------------------------------------------- }
procedure setborder(col:byte); assembler; asm
xor ch,ch; mov cl,border; jcxz @out; mov dx,3dah; in al,dx
mov dx,3c0h; mov al,11h+32; out dx,al; mov al,col; out dx,al; @out: end;
{ -------------------------------------------------------------------------- }
procedure retrace; assembler; asm
mov dx,3dah; @vert1: in al,dx; test al,8; jz @vert1
@vert2: in al,dx; test al,8; jnz @vert2; end;
{ -------------------------------------------------------------------------- }
procedure setpal(c,r,g,b:byte); assembler; asm
mov dx,3c8h; mov al,[c]; out dx,al; inc dx; mov al,[r]
out dx,al; mov al,[g]; out dx,al; mov al,[b]; out dx,al; end;
{ -------------------------------------------------------------------------- }
procedure cls(lvseg:word); assembler; asm
mov es,[lvseg]; xor di,di; xor ax,ax; mov cx,320*200/2; rep stosw; end;
procedure flip(src,dst:word); assembler; asm
push ds; mov ax,[dst]; mov es,ax; mov ax,[src]; mov ds,ax
xor si,si; xor di,di; mov cx,320*200/2; rep movsw; pop ds; end;
{ -------------------------------------------------------------------------- }
procedure horline(xb,xe,y:integer; c:byte); assembler;
asm
mov bx,xb
mov cx,xe
cmp bx,cx
jb @skip
xchg bx,cx
@skip:
inc cx
sub cx,bx
mov es,virseg
mov ax,y
shl ax,6
mov di,ax
shl ax,2
add di,ax
add di,bx
mov al,c
shr cx,1
jnc @skip2
stosb
@skip2:
mov ah,al
rep stosw
@out:
end;
function MaxI(A,B:Integer):Integer; inline(
$58/ { pop ax }
$5B/ { pop bx }
$3B/$C3/ { cmp ax,bx }
$7F/$01/ { jg +1 }
$93); { xchg ax,bx }
function MinI(A,B:Integer):Integer; inline(
$58/ { pop ax }
$5B/ { pop bx }
$3B/$C3/ { cmp ax,bx }
$7C/$01/ { jl +1 }
$93); { xchg ax,bx }
function InRangeI(value,min,max:integer):integer; inline(
$59/ { pop cx max }
$5B/ { pop bx min }
$58/ { pop ax val }
$3B/$C3/ { cmp ax,bx }
$7F/$03/ { jg +3 }
$93/ { xchg ax,bx }
$Eb/$05/ { jmp +5 }
$3B/$C1/ { cmp ax,cx }
$7C/$01/ { jl +1 }
$91); { xchg ax,cx }
procedure polygon( x1,y1, x2,y2, x3,y3, x4,y4 :integer; c:byte);
var pos:array[0..199,0..1] of integer;
xdiv1,xdiv2,xdiv3,xdiv4:integer;
ydiv1,ydiv2,ydiv3,ydiv4:integer;
dir1,dir2,dir3,dir4:byte;
ly,gy,y,tmp,step:integer;
begin
{ determine highest and lowest point + vertical window checking }
ly:=MaxI(MinI(MinI(MinI(y1,y2),y3),y4),miny);
gy:=MinI(MaxI(MaxI(MaxI(y1,y2),y3),y4),maxy);
if ly>maxy then exit;
if gy<miny then exit;
{ check directions (-1=down, 1=up) and calculate constants }
dir1:=byte(y1<y2); xdiv1:=x2-x1; ydiv1:=y2-y1;
dir2:=byte(y2<y3); xdiv2:=x3-x2; ydiv2:=y3-y2;
dir3:=byte(y3<y4); xdiv3:=x4-x3; ydiv3:=y4-y3;
dir4:=byte(y4<y1); xdiv4:=x1-x4; ydiv4:=y1-y4;
y:=y1;
step:=dir1*2-1;
if y1<>y2 then repeat
if InRangeI(y,ly,gy)=y then begin
tmp:=xdiv1*(y-y1) div ydiv1+x1;
pos[y,dir1]:=InRangeI(tmp,minx,maxx);
end;
inc(y,step);
until y=y2+step
else if (y>=ly) and (y<=gy) then pos[y,dir1]:=InRangeI(x1,minx,maxx);
y:=y2;
step:=dir2*2-1;
if y2<>y3 then repeat
if InRangeI(y,ly,gy)=y then begin
tmp:=xdiv2*(y-y2) div ydiv2+x2;
pos[y,dir2]:=InRangeI(tmp,minx,maxx);
end;
inc(y,step);
until y=y3+step
else if (y>=ly) and (y<=gy) then pos[y,dir2]:=InRangeI(x2,minx,maxx);
y:=y3;
step:=dir3*2-1;
if y3<>y4 then repeat
if InRangeI(y,ly,gy)=y then begin
tmp:=xdiv3*(y-y3) div ydiv3+x3;
pos[y,dir3]:=InRangeI(tmp,minx,maxx);
end;
inc(y,step);
until y=y4+step
else if (y>=ly) and (y<=gy) then pos[y,dir3]:=InRangeI(x3,minx,maxx);
y:=y4;
step:=dir4*2-1;
if y4<>y1 then repeat
if InRangeI(y,ly,gy)=y then begin
tmp:=xdiv4*(y-y4) div ydiv4+x4;
pos[y,dir4]:=InRangeI(tmp,minx,maxx);
end;
inc(y,step);
until y=y1+step
else if (y>=ly) and (y<=gy) then pos[y,dir4]:=InRangeI(x4,minx,maxx);
for y:=ly to gy do horline(pos[y,0],pos[y,1],y,c);
end;
{ -------------------------------------------------------------------------- }
function cosinus(i:byte):integer; begin cosinus:=ctab[i]; end;
function sinus(i:byte):integer; begin sinus:=stab[i]; end;
{ -------------------------------------------------------------------------- }
var i:byte;
begin
border:=false;
minx:=0; miny:=0; maxx:=319; maxy:=199;
for i:=0 to 255 do ctab[i]:=round(-cos(i*pi/128)*divd);
for i:=0 to 255 do stab[i]:=round(sin(i*pi/128)*divd);
end.