273 lines
4.9 KiB
NASM
273 lines
4.9 KiB
NASM
ALIGN 2
|
|
|
|
WMINY dw 0
|
|
WMAXY dw 199
|
|
WMINX dw 0
|
|
WMAXX dw 319
|
|
|
|
clip_x1 dw 0
|
|
clip_y1 dw 0
|
|
clip_x2 dw 0
|
|
clip_y2 dw 0
|
|
clipxy2 dw 32 dup(0,0) ;tmp storage for polyclip
|
|
|
|
clipanypoly PROC NEAR
|
|
;polyisides/polyixy =>polysides/polyxy
|
|
mov ax,cs
|
|
mov ds,ax
|
|
mov cx,ds:polyisides
|
|
cmp cx,2
|
|
jg cap3
|
|
cmp cx,1
|
|
je cap4
|
|
jcxz cap0
|
|
;line
|
|
mov eax,dword ptr ds:polyixy[0]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:polyixy[4]
|
|
mov dword ptr ds:clip_x2,eax
|
|
cap2r: call clipliney
|
|
cmp ax,0
|
|
jnz cap0
|
|
call cliplinex
|
|
cmp ax,0
|
|
jnz cap0
|
|
mov eax,dword ptr ds:clip_x1
|
|
mov dword ptr ds:polyxy[0],eax
|
|
mov edx,dword ptr ds:clip_x2
|
|
mov dword ptr ds:polyxy[4],edx
|
|
cmp eax,edx
|
|
je cap2
|
|
mov word ptr ds:polysides,2
|
|
ret
|
|
cap2: mov word ptr ds:polysides,1
|
|
ret
|
|
cap4: ;dot
|
|
mov eax,dword ptr ds:polyixy[0]
|
|
cmp ax,cs:WMINX
|
|
jl cap0
|
|
cmp ax,cs:WMAXX
|
|
jg cap0
|
|
ror eax,16
|
|
cmp ax,cs:WMINY
|
|
jl cap0
|
|
cmp ax,cs:WMAXY
|
|
jg cap0
|
|
ror eax,16
|
|
mov dword ptr ds:polyxy,eax
|
|
mov word ptr cs:polysides,1
|
|
ret
|
|
cap0: ;all clipped away
|
|
mov word ptr ds:polysides,0
|
|
ret
|
|
cap3: ;polygon, first clip y, then x
|
|
mov si,cx
|
|
shl si,2
|
|
sub si,4
|
|
mov di,0
|
|
mov eax,dword ptr ds:polyixy[si]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:polyixy[di]
|
|
mov dword ptr ds:clip_x2,eax
|
|
call clipliney
|
|
;
|
|
mov cx,ds:polyisides
|
|
xor di,di
|
|
xor bx,bx
|
|
mov edx,80008000h
|
|
jmp cap35
|
|
cap32: push di
|
|
push bx
|
|
push cx
|
|
push edx
|
|
mov si,di
|
|
sub si,4
|
|
mov eax,dword ptr ds:polyixy[si]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:polyixy[di]
|
|
mov dword ptr ds:clip_x2,eax
|
|
call clipliney
|
|
pop edx
|
|
pop cx
|
|
pop bx
|
|
pop di
|
|
cap35: cmp ax,0
|
|
jnz cap34
|
|
mov eax,dword ptr ds:clip_x1
|
|
cmp eax,edx
|
|
je cap33
|
|
mov dword ptr ds:clipxy2[bx],eax
|
|
mov edx,eax
|
|
add bx,4
|
|
cap33: mov eax,dword ptr ds:clip_x2
|
|
cmp eax,edx
|
|
je cap34
|
|
mov dword ptr ds:clipxy2[bx],eax
|
|
mov edx,eax
|
|
add bx,4
|
|
cap34: add di,4
|
|
loop cap32
|
|
;
|
|
mov cx,bx
|
|
shr cx,2
|
|
cmp dword ptr ds:clipxy2[0],edx
|
|
jne cap31
|
|
dec cx
|
|
cap31: mov ds:polysides,cx
|
|
|
|
cmp cx,2
|
|
jg cap39
|
|
cmp cx,0
|
|
je cap38
|
|
mov eax,dword ptr ds:clipxy2[0]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:clipxy2[4]
|
|
mov dword ptr ds:clip_x2,eax
|
|
jmp cap2r ;reclip the remaining line
|
|
cap38: ret
|
|
cap39:
|
|
mov si,cx
|
|
shl si,2
|
|
sub si,4
|
|
mov di,0
|
|
mov eax,dword ptr ds:clipxy2[si]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:clipxy2[di]
|
|
mov dword ptr ds:clip_x2,eax
|
|
call cliplinex
|
|
;
|
|
mov cx,ds:polysides
|
|
xor di,di
|
|
xor bx,bx
|
|
mov edx,80008000h
|
|
jmp cbp35
|
|
cbp32: push di
|
|
push bx
|
|
push cx
|
|
push edx
|
|
mov si,di
|
|
sub si,4
|
|
mov eax,dword ptr ds:clipxy2[si]
|
|
mov dword ptr ds:clip_x1,eax
|
|
mov eax,dword ptr ds:clipxy2[di]
|
|
mov dword ptr ds:clip_x2,eax
|
|
call cliplinex
|
|
pop edx
|
|
pop cx
|
|
pop bx
|
|
pop di
|
|
cbp35: cmp ax,0
|
|
jnz cbp34
|
|
mov eax,dword ptr ds:clip_x1
|
|
cmp eax,edx
|
|
je cbp33
|
|
mov dword ptr ds:polyxy[bx],eax
|
|
mov edx,eax
|
|
add bx,4
|
|
cbp33: mov eax,dword ptr ds:clip_x2
|
|
cmp eax,edx
|
|
je cbp34
|
|
mov dword ptr ds:polyxy[bx],eax
|
|
mov edx,eax
|
|
add bx,4
|
|
cbp34: add di,4
|
|
loop cbp32
|
|
;
|
|
mov cx,bx
|
|
shr cx,2
|
|
cmp dword ptr ds:polyxy[0],edx
|
|
jne cbp31
|
|
dec cx
|
|
cbp31: mov ds:polysides,cx
|
|
|
|
ret
|
|
clipanypoly ENDP
|
|
|
|
clipcheck MACRO reg,min,max,flagreg,flagmin,flagmax
|
|
local l1,l2
|
|
cmp reg,min
|
|
jge l1
|
|
or flagreg,flagmin
|
|
l1: cmp reg,max
|
|
jle l2
|
|
or flagreg,flagmax
|
|
l2: ENDM
|
|
clipmacro MACRO v1,v2,w1,w2,wl
|
|
local l1,l2
|
|
push bx
|
|
mov bx,wl
|
|
mov cx,w2
|
|
sub cx,w1
|
|
jcxz l1
|
|
mov bp,bx
|
|
sub bp,w1
|
|
mov ax,v2
|
|
sub ax,v1
|
|
imul bp
|
|
idiv cx
|
|
add ax,v1
|
|
mov v1,ax
|
|
mov word ptr w1,bx
|
|
jmp l2
|
|
l1: mov ax,v1
|
|
mov word ptr w1,bx
|
|
l2: pop bx
|
|
ENDM
|
|
cliplinex PROC NEAR
|
|
;input line polyxy[SI]=>polyxy[DI]
|
|
xor bx,bx
|
|
mov ax,ds:clip_x1
|
|
clipcheck ax,cs:WMINX,cs:WMAXX,bl,1,2
|
|
mov ax,ds:clip_x2
|
|
clipcheck ax,cs:WMINX,cs:WMAXX,bh,1,2
|
|
mov al,bl
|
|
and al,bh
|
|
jz clpx1
|
|
ret
|
|
clpx1:
|
|
test bl,1
|
|
jz clpx13
|
|
clipmacro ds:clip_y1,ds:clip_y2,ds:clip_x1,ds:clip_x2,cs:WMINX
|
|
clpx13: test bl,2
|
|
jz clpx14
|
|
clipmacro ds:clip_y1,ds:clip_y2,ds:clip_x1,ds:clip_x2,cs:WMAXX
|
|
clpx14:
|
|
test bh,1
|
|
jz clpx23
|
|
clipmacro ds:clip_y2,ds:clip_y1,ds:clip_x2,ds:clip_x1,cs:WMINX
|
|
clpx23: test bh,2
|
|
jz clpx24
|
|
clipmacro ds:clip_y2,ds:clip_y1,ds:clip_x2,ds:clip_x1,cs:WMAXX
|
|
clpx24:
|
|
xor ax,ax
|
|
ret
|
|
cliplinex ENDP
|
|
clipliney PROC NEAR
|
|
xor bx,bx
|
|
mov ax,ds:clip_y1
|
|
clipcheck ax,cs:WMINY,cs:WMAXY,bl,4,8
|
|
mov ax,ds:clip_y2
|
|
clipcheck ax,cs:WMINY,cs:WMAXY,bh,4,8
|
|
mov al,bl
|
|
and al,bh
|
|
jz clpy1
|
|
ret
|
|
clpy1:
|
|
test bl,4
|
|
jz clpy11
|
|
clipmacro ds:clip_x1,ds:clip_x2,ds:clip_y1,ds:clip_y2,cs:WMINY
|
|
clpy11: test bl,8
|
|
jz clpy12
|
|
clipmacro ds:clip_x1,ds:clip_x2,ds:clip_y1,ds:clip_y2,cs:WMAXY
|
|
clpy12:
|
|
test bh,4
|
|
jz clpy21
|
|
clipmacro ds:clip_x2,ds:clip_x1,ds:clip_y2,ds:clip_y1,cs:WMINY
|
|
clpy21: test bh,8
|
|
jz clpy22
|
|
clipmacro ds:clip_x2,ds:clip_x1,ds:clip_y2,ds:clip_y1,cs:WMAXY
|
|
clpy22:
|
|
xor ax,ax
|
|
ret
|
|
clipliney ENDP
|
|
|