home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Zone
/
VRZONE.ISO
/
mac
/
PC
/
REND386
/
POLYBLIT
/
FTRIBLT.ASM
< prev
next >
Wrap
Assembly Source File
|
1992-02-05
|
8KB
|
415 lines
TITLE FASTRI - Fast triangle poly filling blitter
NAME FTRIBLT
COMMENT $
Name: FTRIBLT
Written and (c) by Dave Stampe 9/11/91
Not for commercial use, so get permission
before marketing code using this stuff!
For private PD use only.
$
.MODEL large
.CODE
; big table more eff. than masking
; start byte lookup table
stmask: REPT 40
db 0ffh,07fh,03fh,01fh,00fh,007h,003h,001h
ENDM
; end byte lookup table
fnmask: REPT 40
db 080h,0c0h,0e0h,0f0h,0f8h,0fch,0feh,0ffh
ENDM
extrn _dpaddr ; page base address
x1 equ [bp+6] ; arguments to _tpoly
y1 equ [bp+8]
x2 equ [bp+10]
y2 equ [bp+12]
x3 equ [bp+14]
y3 equ [bp+16]
vline equ [bp-2] ; video base addr. of line
lines equ [bp-4] ; number of lines to fill
l_incr equ [bp-8]
r_incr equ [bp-12]
;
; fastri(int x1,int y1, int x2, int y2, int x3, int y3)
; vertices must be in CCW order!
PUBLIC _fastri
_fastri proc far
.386
push bp
mov bp,sp
sub sp,16
push si
push di
mov eax,x1 ; consider as 32-bit hash: look for top, then left
mov ebx,x2
mov ecx,x3
cmp ebx,eax
jae nrot1
xchg eax,ebx ; rotate till top-left is at head of list
xchg ebx,ecx
cmp ebx,eax
jae donerot
xchg eax,ebx
xchg ebx,ecx
jmp donerot
nrot1: cmp ecx,eax
jae donerot
xchg eax,ecx
xchg ebx,ecx
donerot:
mov x1,eax
mov x2,ebx
mov x3,ecx
cld
mov ax,0a000h ; set video segment
mov es,ax
mov al,y1
mov bl,40 ; compute starting line adr
mul bl
add ax,WORD PTR ds:_dpaddr
mov vline,ax
mov ax,y1 ; determine config. of vertices: one of:
cmp ax,y3
jz flattop
mov ax,y2 ; 1 3 1 1 1
cmp ax,y3 ; 2 3
jz flatbot ; 2 2 3 3 2
jb onleft
jmp onright
flatbot:
movzx ecx,word ptr y2 ; check for sliver poly
sub cx,y1
jz finished
mov lines,cx
mov ax,x2
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl1 ; zero slope
cmp cx,1
je roundpl1
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl1
inc eax
roundpl1:
mov l_incr,eax
mov ax,x3
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl2 ; zero slope
cmp cx,1
je roundpl2
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl2
inc eax
roundpl2:
mov r_incr,eax
cmp eax,l_incr
jz finished ; sliver: don't bother
mov dx,x1 ; compute L,R start
mov cx,dx
shl edx,16
mov bx,cx
mov esi,edx
add edx,08000h ; force left side to round up
call near ptr trapezoid
jmp finished
flattop:
movzx ecx,word ptr y2 ; check for sliver poly
sub cx,y1
jz finished
mov lines,cx
mov ax,x2
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl3 ; zero slope
cmp cx,1
je roundpl3 ; no slope needed if 1 line only
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl3
inc eax
roundpl3:
mov l_incr,eax
mov ax,x2
sub ax,x3
movsx eax,ax ; conv. to double prec. << 16
je roundpl4 ; zero slope
cmp cx,1
je roundpl4 ; no slope needed if 1 line only
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl4
inc eax
roundpl4:
mov r_incr,eax
cmp eax,l_incr
jz finished ; sliver: don't bother
movzx edx,word ptr x1 ; compute L,R start
mov bx,dx
shl edx,16
add edx,08000h ; force left side to round up
movzx esi,word ptr x3
mov cx,si
shl esi,16
call near ptr trapezoid
jmp finished
onleft:
movzx ecx,word ptr y2 ; compute first slice height
sub cx,y1
je finished ; sliver poly
mov lines,cx
mov ax,x2
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl5 ; zero slope
cmp cx,1
je roundpl5
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl5
inc eax
roundpl5:
mov l_incr,eax
movzx ecx,word ptr y3
sub cx,y1
mov ax,x3
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl6 ; zero slope
cmp cx,1
je roundpl6
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl6
inc eax
roundpl6:
mov r_incr,eax
cmp eax,l_incr
jz finished ; sliver: don't bother
mov dx,x1 ; compute L,R start
mov cx,dx
shl edx,16
mov bx,cx
mov esi,edx
add edx,08000h ; force left side to round up
call near ptr trapezoid
push esi ; save full precison right side
movzx ecx,word ptr y3 ; compute second slice height
sub cx,y2
mov lines,cx
mov ax,x3
sub ax,x2
movsx eax,ax ; conv. to double prec. << 16
je roundpl7 ; zero slope
cmp cx,1
je roundpl7
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl7
inc eax
roundpl7:
mov l_incr,eax ; change left increment
pop esi
mov ecx,esi ; restore right side
shr ecx,16
movzx edx,word ptr x2 ; compute L start
mov bx,dx
shl edx,16
add edx,08000h ; force left side to round up
call near ptr trapezoid
jmp finished
onright:
movzx ecx,word ptr y2 ; compute first slice height
sub cx,y1
je finished
mov ax,x2
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl8 ; zero slope
cmp cx,1
je roundpl8
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl8
inc eax
roundpl8:
mov l_incr,eax
movzx ecx,word ptr y3 ; compute first slice height
sub cx,y1
mov lines,cx
mov ax,x3
sub ax,x1
movsx eax,ax ; conv. to double prec. << 16
je roundpl9 ; zero slope
cmp cx,1
je roundpl9
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpl9
inc eax
roundpl9:
mov r_incr,eax
cmp eax,l_incr
jz finished ; sliver: don't bother
mov dx,x1 ; compute L,R start
mov cx,dx
shl edx,16
mov bx,cx
mov esi,edx
add edx,08000h ; force left side to round up
call near ptr trapezoid
push edx ; save full precison left side
movzx ecx,word ptr y2 ; compute second slice height
sub cx,y3
mov lines,cx
mov ax,x2
sub ax,x3
movsx eax,ax ; conv. to double prec. << 16
je roundpla ; zero slope
cmp cx,1
je roundpla
cdq
shl eax,16 ; (x2-x1)/(y2-y1)
idiv ecx
cmp eax,0 ; round up if pos (neg already rounded up)
jle roundpla
inc eax
roundpla:
mov r_incr,eax ; change left increment
pop edx
mov ebx,edx ; restore left side
shr ebx,16
movzx esi,word ptr x3 ; compute R start
mov cx,si
shl esi,16
call near ptr trapezoid
jmp finished
finished:
pop di ; exit code
pop si
mov sp,bp
pop bp
ret
_fastri endp
trapezoid: ; call with bx = left, cx = right
; edx = (left+0.5)>>16, esi = right<<16
; vline, lines, l_incr, r_incr all set up
nextline:
; start of fast h line blitter:
; bx=left side, cx=right side, vline=line start
mov al,BYTE PTR cs:[bx+stmask] ; left mask
shr bx,3 ; left address
mov di,cx
mov ah,BYTE PTR cs:[di+fnmask] ; right mask
shr cx,3 ; right address
mov di,vline ; start address
add di,bx
sub cx,bx ; number of bytes-1
je short onebyte
jc short doneline ; clip trap
and es:[di],al ; mask first byte
inc di
dec cx ; mask rest
mov al,0ffh ; rep faster than test and jmp
rep stosb ; for zero byte case
and es:[di],ah ; mask last byte
jmp short doneline
onebyte:
and al,ah
and es:[di],al ; single byte mask
doneline:
mov ax,40 ; next line address
add vline,ax
add edx,DWORD PTR l_incr ; step left, right edges
add esi,DWORD PTR r_incr
mov ebx,edx ; convert fixed pt to integer
sar ebx,16
mov ecx,esi
sar ecx,16
dec WORD PTR lines ; done lines?
jg short nextline
donetri: ; finished all drawing
exit:
retn
end