home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_PAS
/
XLIB_TP5.ZIP
/
UNITS
/
X_POLYGO.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-12-28
|
31KB
|
934 lines
unit X_Polygon;
(*----------------------------------------------------------------------- *)
(* MODULE XPOLYGON *)
(* *)
(* Filled Triangle function for all MODE X 256 Color resolutions *)
(* *)
(* *)
(* ****** XLIB - Mode X graphics library **************** *)
(* ****** **************** *)
(* ****** Written By Themie Gouthas **************** *)
(* ****** Converted by Christian Harms **************** *)
(* *)
(* This module is based on code developed by Steve Dollind for his *)
(* XSPACE game. *)
(* Copyright (C) 1992 Steven Dollins -- sdollins@uiuc.edu *)
(* *)
(* *)
(* egg@dstos3.dsto.gov.au or teg@bart.dsto.gov.au *)
(* harms@mickey.informatik.uni-stuttgart.de *)
(*----------------------------------------------------------------------- *)
interface
type Point = record x,y:Word; end;
(*----------------------------------------------------------------------- *)
(* procedure x_triangle(X0,Y0,X1,Y1,X2,Y2:Word;Color:Byte); *)
(* *)
(* *)
(* Written by S. Dollins *)
procedure x_triangle(X0,Y0,X1,Y1,X2,Y2,Color:Word);
(* You can draw a triangle with different colors in every line. The colors *)
(* are in a ColorTable:Array[Y0..GetMaxY] of Byte. *)
procedure x_triangleCol(X0,Y0,X1,Y1,X2,Y2:Word;var ColorTable);
procedure x_poly(Var P:Array of Point;num,Color:Word);
procedure x_polyCol(Var P:Array of Point;num:Word;Var Color);
implementation
uses X_Const;
(*----------------------------------------------------------------------- *)
(* HLineClipR *)
(* *)
(* Draws a horizontal line from (X1, Y) to (X2, Y). *)
(* Uses Watcom Parameter passing convention in registers *)
(* *)
(* X1 in AX *)
(* X2 in DX *)
(* Y in CX *)
(* Color in BX *)
(* PageOffset in DI *)
(* *)
(* By Themie Gouthas - Adapted from x_fill_rect. *)
(*----------------------------------------------------------------------- *)
procedure HLineClipR; assembler;
(* Plane masks for clipping left and right edges of rectangle. *)
const LeftClipPlaneMask : Array[0..3] of Byte = ($0f,$0e,$0c,$08);
RightClipPlaneMask : Array[0..3] of Byte = ($0f,$01,$03,$07);
asm
push di
cmp dx,ax (* if (X2 < X1) then assume no line *)
jl @@Invisible (* is visible *)
cmp cx,[TopClip] (* if (Y < TopClip) then no line *)
jl @@Invisible
cmp cx,[BottomClip] (*if (Y > BottomClip) then no line *)
jg @@Invisible
mov di,[RightClip] (*convert RightClip to pixel coords *)
sal di,1
sal di,1
cmp ax,di (* if (X1 > RightClip) then no line *)
jg @@Invisible
cmp dx,di (* if (X2 > RightClip) then *)
jle @@ClipLeft (* X2:=RightClip *)
mov dx,di
@@ClipLeft:
mov di,[LeftClip] (*convert LeftClip to pixel coords *)
sal di,1
sal di,1
cmp dx,di (* if (X2 < LeftClip) then no line *)
jl @@Invisible
cmp ax,di (*if (X1 > LeftClip) then were ready to plot *)
jge @@DoLine
mov ax,di (* X1:=LeftClip *)
jmp @@DoLine
@@Invisible:
pop di
ret
@@DoLine:
pop di (* di = PageOffset *)
xchg cx,ax (* AX = Y, CX = X1 *)
mov si,dx (* SI = DX = X2 *)
mul [ScrnLogicalByteWidth]
mov dx,si (* Reset DX to X1 since mul erases DX *)
add ax,di
mov di,cx
sar di,1 (* Convert to bytes *)
sar di,1
add di,ax (* DI->First byte *)
and si,03h (* look up right edge plane mask *)
mov ah,[offset RightClipPlaneMask+si]
mov si,cx (* look up left edge plane mask *)
and si,03h
mov al,[offset LeftClipPlaneMask+si]
cmp dx,cx (* No harm in being paranoid.. *)
jle @@Invisible2
xchg cx,dx (*CX=X2, DX=X1 *)
dec cx
and dx,not 03h
sub cx,dx
js @@Invisible2
shr cx,1
shr cx,1
jnz @@MasksSet
and al,ah
@@MasksSet:
mov dl,bl (* set BX=Plane Masks, AH=Color *)
mov bx,ax
mov ah,dl
mov dx,SC_INDEX+1 (*set the Sequence Controller Index to *)
mov al,bl
out dx,al
mov al,ah
stosb (* Plot left byte *)
dec cx
js @@Invisible2
jz @@RightEnd
mov al,0fh (* plot middle bytes *)
out dx,al
mov al,ah
shr cx,1
rep stosw
adc cx,cx
rep stosb
@@RightEnd:
mov al,bh (* Plot right byte *)
out dx,al
mov al,ah
stosb
@@Invisible2:
end;
procedure x_triangle(X0,Y0,X1,Y1,X2,Y2,Color:Word); assembler;
var DX01,DY01,DX02,DY02,DX12,DY12,DP01,DP02,DP12,XA01,XA02,XA12:Word;
asm
push ds
push es
push si
push di (* Save es for polygon routine *)
mov ax,X0
mov bx,Y0
mov cx,X1
mov dx,Y1
cmp bx,dx (* Y0,Y1 *)
jl @tri_Y0lY1
je @tri_Y0eY1
xchg ax,cx (* X0,X1 *)
xchg bx,dx (* Y0,Y1 *)
@tri_Y0lY1:
cmp dx,Y2 (* Y1,Y2 *)
jg @tri_a
jmp @tri_sorted
@tri_a: xchg cx,X2 (* X1,X2 *)
xchg dx,Y2 (* Y1,Y2 *)
cmp bx,dx (* Y0,Y1 *)
jge @tri_b
jmp @tri_sorted
@tri_b: je @tri_bot
xchg ax,cx (* X0,X1 *)
xchg bx,dx (* Y0,Y1 *)
jmp @tri_sorted
@tri_Y0eY1:
cmp bx,Y2 (* Y0,Y2 *)
jl @tri_bot
jg @tri_c
jmp @tri_done
@tri_c: xchg ax,X2 (* X0,X2 *)
xchg bx,Y2 (* Y0,Y2 *)
jmp @tri_sorted
@tri_bot:
cmp ax,cx (* X0,X1 *)
jl @tri_bot_sorted
jg @tri_bot_a
jmp @tri_done
@tri_bot_a:
xchg ax,cx (* X0,X1 *)
@tri_bot_sorted:
cmp bx,[BottomClip]
jle @tri_bot_y0ok
jmp @tri_done
@tri_bot_y0ok:
mov si,Y2
cmp si,[TopClip]
jge @tri_bot_y2ok
jmp @tri_done
@tri_bot_y2ok:
mov X0,ax
mov Y0,bx
mov X1,cx
mov Y1,dx
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y0 (* bx <- Y2 - Y0 *)
mov DY02,bx (* DY02 <- Y2 - Y0 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X0 (* ax <- X2 - X0 *)
mov DX02,ax (* DX02 <- X2 - X0 *)
mov cx,ax (* cx <- DX02 *)
cwd (* dx:ax <- DX02 *)
idiv bx (* ax <- DX02 / DY02 *)
cmp cx,0
jge @tri_bot02
dec ax (* ax <- DX02 / DY02 - 1 *)
@tri_bot02:
mov XA02,ax (* XA02 <- DX02 / DY02 *)
imul bx (* ax <- XA02 * DY02 *)
sub cx,ax (* cx <- DX02 - XA02 * DY02*)
mov DP02,cx (* DP02 <- DX02 - XA02 * DY02*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y1 (* bx <- Y2 - Y1 *)
mov DY12,bx (* DY02 <- Y2 - Y1 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X1 (* ax <- X2 - X1 *)
mov DX12,ax (* DX12 <- X2 - X1 *)
mov cx,ax (* cx <- DX12 *)
cwd (* dx:ax <- DX12 *)
idiv bx (* ax <- DX12 / DY12 *)
cmp cx,0
jge @tri_bot12
dec ax (* ax <- DX12 / DY12 - 1 *)
@tri_bot12:
mov XA12,ax (* XA12 <- DX12 / DY12 *)
imul bx (* ax <- XA12 * DY12 *)
sub cx,ax (* cx <- DX12 - XA12 * DY12*)
mov DP12,cx (* DP12 <- DX12 - XA12 * DY12*)
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,X1
dec di
@tri_bot_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_bot_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_bot_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_bot_shortr
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_bot_shortr:
add di,XA12 (* XS,XA12 *)
push di (* XS *)
push si (* XL *)
cmp cx,Y2 (* Y,Y2 *)
jl @tri_bot_loop
jmp @tri_draw_lines
@tri_sorted:
cmp bx,[BottomClip]
jle @tri_y0ok
jmp @tri_done
@tri_y0ok:
mov si,Y2
cmp si,[TopClip]
jge @tri_y2ok
jmp @tri_done
@tri_y2ok:
mov X0,ax
mov Y0,bx
mov X1,cx
mov Y1,dx
mov bx,dx (* bx <- Y1 *)
sub bx,Y0 (* bx <- Y1 - Y0 *)
mov DY01,bx (* DY01 <- Y1 - Y0 *)
mov ax,X1 (* ax <- X1 *)
sub ax,X0 (* ax <- X1 - X0 *)
mov DX01,ax (* DX01 <- X1 - X0 *)
mov cx,ax (* cx <- DX01 *)
cwd (* dx:ax <- DX01 *)
idiv bx (* ax <- DX01 / DY01 *)
cmp cx,0 (* DX01 ? 0 *)
jge @tri_psl01
dec ax (* ax <- DX01 / DY01 - 1 *)
@tri_psl01:
mov XA01,ax (* XA01 <- DX01 / DY01 *)
imul bx (* ax <- XA01 * DY01 *)
sub cx,ax (* cx <- DX01 - XA01 * DY01*)
mov DP01,cx (* DP01 <- DX01 - XA01 * DY01*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y0 (* bx <- Y2 - Y0 *)
mov DY02,bx (* DY02 <- Y2 - Y0 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X0 (* ax <- X2 - X0 *)
mov DX02,ax (* DX02 <- X2 - X0 *)
mov cx,ax (* cx <- DX02 *)
cwd (* dx:ax <- DX02 *)
idiv bx (* ax <- DX02 / DY02 *)
cmp cx,0
jge @tri_psl02
dec ax (* ax <- DX02 / DY02 - 1 *)
@tri_psl02:
mov XA02,ax (* XA02 <- DX02 / DY02 *)
imul bx (* ax <- XA02 * DY02 *)
sub cx,ax (* cx <- DX02 - XA02 * DY02*)
mov DP02,cx (* DP02 <- DX02 - XA02 * DY02*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y1 (* bx <- Y2 - Y1 *)
jle @tri_const_computed
mov DY12,bx (* DY12 <- Y2 - Y1 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X1 (* ax <- X2 - X1 *)
mov DX12,ax (* DX12 <- X2 - X1 *)
mov cx,ax (* cx <- DX12 *)
cwd (* dx:ax <- DX12 *)
idiv bx (* ax <- DX12 / DY12 *)
cmp cx,0
jge @tri_psl12
dec ax (* ax <- DX12 / DY12 - 1 *)
@tri_psl12:
mov XA12,ax (* XA12 <- DX12 / DY12 *)
imul bx (* ax <- XA12 * DY12 *)
sub cx,ax (* cx <- DX12 - XA12 * DY12*)
mov DP12,cx (* DP12 <- DX12 - XA12 * DY12*)
@tri_const_computed:
mov ax,DX01
imul word ptr DY02
mov bx,ax
mov cx,dx (* DX01 * DY02 in cx:bx *)
mov ax,DX02
imul word ptr DY01 (* DX02 * DY01 in dx:ax *)
cmp cx,dx
jg @tri_pt1rt
jl @tri_pt1lt
cmp bx,ax
ja @tri_pt1rt
jb @tri_pt1lt
jmp @tri_done
(*------------------------------------ *)
(* Short sides are on the left *)
(* *)
@tri_pt1lt:
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,si
dec si
@tri_lt_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_lt_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_lt_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP01 (* PS,DP01 *)
jle @tri_lt_shortr
sub bx,DY01 (* PS,DY01 *)
inc di (* XS *)
@tri_lt_shortr:
add di,XA01 (* XS,XA01 *)
push si (* XL *)
push di (* XS *)
cmp cx,Y1 (* Y,Y1 *)
jl @tri_lt_loop
jmp @tri_lb_start
@tri_lb_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_lb_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_lb_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_lb_shortr
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_lb_shortr:
add di,XA12 (* XS,XA12 *)
push si (* XL *)
push di (* XS *)
@tri_lb_start:
cmp cx,Y2 (* Y,Y2 *)
jl @tri_lb_loop
jmp @tri_draw_lines
(*------------------------------------ *)
(* short sides are on the right *)
(* *)
@tri_pt1rt:
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,si
dec di
@tri_rt_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_rt_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_rt_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP01 (* PS,DP01 *)
jle @tri_rt_shortr
sub bx,DY01 (* PS,DY01 *)
inc di (* XS *)
@tri_rt_shortr:
add di,XA01 (* XS,XA01 *)
push di (* XS *)
push si (* XL *)
cmp cx,Y1 (* Y,Y1 *)
jl @tri_rt_loop
jmp @tri_rb_start
@tri_rb_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_rb_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_rb_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_rb_shorts
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_rb_shorts:
add di,XA12 (* XS,XA12 *)
push di (* XS *)
push si (* XL *)
@tri_rb_start:
cmp cx,Y2 (* Y,Y2 *)
jl @tri_rb_loop
(*------------------------------------ *)
(* Draw the horizontal lines *)
(* *)
@tri_draw_lines:
mov cx,SCREEN_SEG (*point ES to video segment *)
mov es,cx
mov dx,SC_INDEX (*set the Sequence Controller Index to *)
mov al,MAP_MASK (* point to the Map Mask register *)
out dx,al
@line_loop:
pop ax
pop dx
cmp ax,dx
jg @tri_draw_next
mov bx,Color
mov cx,Y2
add dx,2
mov di,ScreenOfs
call HLineClipR
@tri_draw_next:
dec word ptr Y2
dec word ptr DY02
jnz @line_loop
@tri_done:
pop di
pop si
pop es
pop ds
end;
procedure x_triangleCol(X0,Y0,X1,Y1,X2,Y2:Word;var ColorTable); assembler;
var DX01,DY01,DX02,DY02,DX12,DY12,DP01,DP02,DP12,XA01,XA02,XA12:Word;
asm
push ds
push es
push si
push di (* Save es for polygon routine *)
mov ax,X0
mov bx,Y0
mov cx,X1
mov dx,Y1
cmp bx,dx (* Y0,Y1 *)
jl @tri_Y0lY1
je @tri_Y0eY1
xchg ax,cx (* X0,X1 *)
xchg bx,dx (* Y0,Y1 *)
@tri_Y0lY1:
cmp dx,Y2 (* Y1,Y2 *)
jg @tri_a
jmp @tri_sorted
@tri_a: xchg cx,X2 (* X1,X2 *)
xchg dx,Y2 (* Y1,Y2 *)
cmp bx,dx (* Y0,Y1 *)
jge @tri_b
jmp @tri_sorted
@tri_b: je @tri_bot
xchg ax,cx (* X0,X1 *)
xchg bx,dx (* Y0,Y1 *)
jmp @tri_sorted
@tri_Y0eY1:
cmp bx,Y2 (* Y0,Y2 *)
jl @tri_bot
jg @tri_c
jmp @tri_done
@tri_c: xchg ax,X2 (* X0,X2 *)
xchg bx,Y2 (* Y0,Y2 *)
jmp @tri_sorted
@tri_bot:
cmp ax,cx (* X0,X1 *)
jl @tri_bot_sorted
jg @tri_bot_a
jmp @tri_done
@tri_bot_a:
xchg ax,cx (* X0,X1 *)
@tri_bot_sorted:
cmp bx,[BottomClip]
jle @tri_bot_y0ok
jmp @tri_done
@tri_bot_y0ok:
mov si,Y2
cmp si,[TopClip]
jge @tri_bot_y2ok
jmp @tri_done
@tri_bot_y2ok:
mov X0,ax
mov Y0,bx
mov X1,cx
mov Y1,dx
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y0 (* bx <- Y2 - Y0 *)
mov DY02,bx (* DY02 <- Y2 - Y0 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X0 (* ax <- X2 - X0 *)
mov DX02,ax (* DX02 <- X2 - X0 *)
mov cx,ax (* cx <- DX02 *)
cwd (* dx:ax <- DX02 *)
idiv bx (* ax <- DX02 / DY02 *)
cmp cx,0
jge @tri_bot02
dec ax (* ax <- DX02 / DY02 - 1 *)
@tri_bot02:
mov XA02,ax (* XA02 <- DX02 / DY02 *)
imul bx (* ax <- XA02 * DY02 *)
sub cx,ax (* cx <- DX02 - XA02 * DY02*)
mov DP02,cx (* DP02 <- DX02 - XA02 * DY02*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y1 (* bx <- Y2 - Y1 *)
mov DY12,bx (* DY02 <- Y2 - Y1 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X1 (* ax <- X2 - X1 *)
mov DX12,ax (* DX12 <- X2 - X1 *)
mov cx,ax (* cx <- DX12 *)
cwd (* dx:ax <- DX12 *)
idiv bx (* ax <- DX12 / DY12 *)
cmp cx,0
jge @tri_bot12
dec ax (* ax <- DX12 / DY12 - 1 *)
@tri_bot12:
mov XA12,ax (* XA12 <- DX12 / DY12 *)
imul bx (* ax <- XA12 * DY12 *)
sub cx,ax (* cx <- DX12 - XA12 * DY12*)
mov DP12,cx (* DP12 <- DX12 - XA12 * DY12*)
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,X1
dec di
@tri_bot_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_bot_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_bot_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_bot_shortr
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_bot_shortr:
add di,XA12 (* XS,XA12 *)
push di (* XS *)
push si (* XL *)
cmp cx,Y2 (* Y,Y2 *)
jl @tri_bot_loop
jmp @tri_draw_lines
@tri_sorted:
cmp bx,[BottomClip]
jle @tri_y0ok
jmp @tri_done
@tri_y0ok:
mov si,Y2
cmp si,[TopClip]
jge @tri_y2ok
jmp @tri_done
@tri_y2ok:
mov X0,ax
mov Y0,bx
mov X1,cx
mov Y1,dx
mov bx,dx (* bx <- Y1 *)
sub bx,Y0 (* bx <- Y1 - Y0 *)
mov DY01,bx (* DY01 <- Y1 - Y0 *)
mov ax,X1 (* ax <- X1 *)
sub ax,X0 (* ax <- X1 - X0 *)
mov DX01,ax (* DX01 <- X1 - X0 *)
mov cx,ax (* cx <- DX01 *)
cwd (* dx:ax <- DX01 *)
idiv bx (* ax <- DX01 / DY01 *)
cmp cx,0 (* DX01 ? 0 *)
jge @tri_psl01
dec ax (* ax <- DX01 / DY01 - 1 *)
@tri_psl01:
mov XA01,ax (* XA01 <- DX01 / DY01 *)
imul bx (* ax <- XA01 * DY01 *)
sub cx,ax (* cx <- DX01 - XA01 * DY01*)
mov DP01,cx (* DP01 <- DX01 - XA01 * DY01*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y0 (* bx <- Y2 - Y0 *)
mov DY02,bx (* DY02 <- Y2 - Y0 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X0 (* ax <- X2 - X0 *)
mov DX02,ax (* DX02 <- X2 - X0 *)
mov cx,ax (* cx <- DX02 *)
cwd (* dx:ax <- DX02 *)
idiv bx (* ax <- DX02 / DY02 *)
cmp cx,0
jge @tri_psl02
dec ax (* ax <- DX02 / DY02 - 1 *)
@tri_psl02:
mov XA02,ax (* XA02 <- DX02 / DY02 *)
imul bx (* ax <- XA02 * DY02 *)
sub cx,ax (* cx <- DX02 - XA02 * DY02*)
mov DP02,cx (* DP02 <- DX02 - XA02 * DY02*)
mov bx,Y2 (* bx <- Y2 *)
sub bx,Y1 (* bx <- Y2 - Y1 *)
jle @tri_const_computed
mov DY12,bx (* DY12 <- Y2 - Y1 *)
mov ax,X2 (* ax <- X2 *)
sub ax,X1 (* ax <- X2 - X1 *)
mov DX12,ax (* DX12 <- X2 - X1 *)
mov cx,ax (* cx <- DX12 *)
cwd (* dx:ax <- DX12 *)
idiv bx (* ax <- DX12 / DY12 *)
cmp cx,0
jge @tri_psl12
dec ax (* ax <- DX12 / DY12 - 1 *)
@tri_psl12:
mov XA12,ax (* XA12 <- DX12 / DY12 *)
imul bx (* ax <- XA12 * DY12 *)
sub cx,ax (* cx <- DX12 - XA12 * DY12*)
mov DP12,cx (* DP12 <- DX12 - XA12 * DY12*)
@tri_const_computed:
mov ax,DX01
imul word ptr DY02
mov bx,ax
mov cx,dx (* DX01 * DY02 in cx:bx *)
mov ax,DX02
imul word ptr DY01 (* DX02 * DY01 in dx:ax *)
cmp cx,dx
jg @tri_pt1rt
jl @tri_pt1lt
cmp bx,ax
ja @tri_pt1rt
jb @tri_pt1lt
jmp @tri_done
(*------------------------------------ *)
(* Short sides are on the left *)
(* *)
@tri_pt1lt:
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,si
dec si
@tri_lt_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_lt_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_lt_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP01 (* PS,DP01 *)
jle @tri_lt_shortr
sub bx,DY01 (* PS,DY01 *)
inc di (* XS *)
@tri_lt_shortr:
add di,XA01 (* XS,XA01 *)
push si (* XL *)
push di (* XS *)
cmp cx,Y1 (* Y,Y1 *)
jl @tri_lt_loop
jmp @tri_lb_start
@tri_lb_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_lb_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_lb_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_lb_shortr
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_lb_shortr:
add di,XA12 (* XS,XA12 *)
push si (* XL *)
push di (* XS *)
@tri_lb_start:
cmp cx,Y2 (* Y,Y2 *)
jl @tri_lb_loop
jmp @tri_draw_lines
(*------------------------------------ *)
(* short sides are on the right *)
(* *)
@tri_pt1rt:
mov ax,0 (* PL <- 0 *)
mov bx,0 (* PS <- 0 *)
mov cx,Y0 (* Y <- Y0 *)
mov si,X0
mov di,si
dec di
@tri_rt_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_rt_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_rt_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP01 (* PS,DP01 *)
jle @tri_rt_shortr
sub bx,DY01 (* PS,DY01 *)
inc di (* XS *)
@tri_rt_shortr:
add di,XA01 (* XS,XA01 *)
push di (* XS *)
push si (* XL *)
cmp cx,Y1 (* Y,Y1 *)
jl @tri_rt_loop
jmp @tri_rb_start
@tri_rb_loop:
inc cx (* Y *)
add ax,DP02 (* PL,DP02 *)
jle @tri_rb_shortl
sub ax,DY02 (* PL,DY02 *)
inc si (* XL *)
@tri_rb_shortl:
add si,XA02 (* XL,XA02 *)
add bx,DP12 (* PS,DP12 *)
jle @tri_rb_shorts
sub bx,DY12 (* PS,DY12 *)
inc di (* XS *)
@tri_rb_shorts:
add di,XA12 (* XS,XA12 *)
push di (* XS *)
push si (* XL *)
@tri_rb_start:
cmp cx,Y2 (* Y,Y2 *)
jl @tri_rb_loop
(*------------------------------------ *)
(* Draw the horizontal lines *)
(* *)
@tri_draw_lines:
mov cx,SCREEN_SEG (*point ES to video segment *)
mov es,cx
mov dx,SC_INDEX (*set the Sequence Controller Index to *)
mov al,MAP_MASK (* point to the Map Mask register *)
out dx,al
@line_loop:
pop ax
pop dx
cmp ax,dx
jg @tri_draw_next
mov cx,Y2
add dx,2
push ds
lds di,dword ptr [ColorTable]
add di,cx
mov bx,ds:[di]
pop ds
mov di,ScreenOfs
call HLineClipR
@tri_draw_next:
dec word ptr Y2
dec word ptr DY02
jnz @line_loop
@tri_done:
pop di
pop si
pop es
pop ds
end;
(*----------------------------------------------------------------------- *)
(* *)
(* Written by T. Gouthas *)
(* *)
(* Note: This is just a quick hack of a generalized polygon routine. *)
(* The way it works is by splitting up polygons into triangles and *)
(* drawing each individual triangle. *)
(* *)
(* Obviously this is not as fast as it could be, but for polygons of *)
(* 4 vertices it should perform quite respectably. *)
(* *)
(* Warning: Only works for convex polygons (convex polygons are such *)
(* that if you draw a line from any two vertices, every point on that *)
(* line will be within the polygon) *)
(* *)
(* Type Point see at the begin of this file. *)
procedure x_poly(Var P:Array of Point;num,Color:Word);
var i:Word;
begin;
for i:=1 to num-1 do
x_triangle(P[0].x,P[0].y,P[i].x,P[i].y,P[i+1].x,P[i+1].y,Color);
end;
procedure x_polyCol(Var P:Array of Point;num:Word;Var Color);
var i:Word;
begin;
for i:=1 to num-1 do
x_triangleCol(P[0].x,P[0].y,P[i].x,P[i].y,P[i+1].x,P[i+1].y,Color);
end;
end.