mirror of https://github.com/nmlgc/ReC98.git
394 lines
8.1 KiB
NASM
394 lines
8.1 KiB
NASM
PAGE 98,120
|
||
; grcg - polygon - convex - Point
|
||
;
|
||
; DESCRIPTION:
|
||
; 凸多角形描画(青プレーンのみ)
|
||
;
|
||
; FUNCTION:
|
||
; void far _pascal grcg_polygon_c( Point far pts[], int npoint ) ;
|
||
;
|
||
; PARAMETERS:
|
||
; Point pts[] 座標リスト
|
||
; int npoint 座標数( 2〜 )
|
||
;
|
||
; Binding Target:
|
||
; Microsoft-C / Turbo-C / Turbo Pascal
|
||
;
|
||
; Running Target:
|
||
; NEC PC-9801 Normal mode
|
||
;
|
||
; REQUIRING RESOURCES:
|
||
; CPU: V30
|
||
; GRAPHICS ACCELARATOR: GRAPHIC CHARGER
|
||
; ・上記は、すべて draw_trapezoid に依ります。
|
||
;
|
||
; NOTES:
|
||
; ・色指定は、グラフィックチャージャーを使用してください。
|
||
; ・クリッピング枠によって描画を制限できます。( grc_setclip()参照 )
|
||
; ・左右の境界クリップは、台形描画ルーチンに依存しています。
|
||
; ・データが下記の条件に当てはまる場合、正しく描画しません。
|
||
; ○同じy座標を経由する辺が2つを超える場所がある場合。
|
||
; →条件により、ゼロ除算が発生したり、おかしな図形になります。
|
||
; (凸多角形でなくても、上記以外なら正しく描画します)
|
||
;
|
||
; COMPILER/ASSEMBLER:
|
||
; TASM 3.0
|
||
; OPTASM 1.6
|
||
;
|
||
; 関連関数:
|
||
; grc_setclip()
|
||
; make_linework
|
||
; draw_trapezoid
|
||
;
|
||
; AUTHOR:
|
||
; 恋塚昭彦
|
||
;
|
||
; HISTORY:
|
||
; 92/5/18 Initial(C版)
|
||
; 92/5/19 bugfix
|
||
; 92/5/20 とりあえず、左右と下端のクリップをやった。
|
||
; 92/5/21 左右の先判定と、上もクリップしたぞ。(あーのんびり。)
|
||
; 92/6/4 Initial(asm版 gc_4corn.asm)
|
||
; 92/6/5 gc_polyg.asm
|
||
; 92/6/6 ClipYT_seg対応
|
||
; 92/6/16 TASM対応
|
||
; 92/6/19 gc_polgc.asm
|
||
; 92/6/21 Pascal対応
|
||
|
||
IF datasize EQ 2
|
||
MOVPTS macro to, from
|
||
mov to,ES:from
|
||
endm
|
||
CMPPTS macro pts, dat
|
||
cmp ES:pts,dat
|
||
endm
|
||
SUBPTS macro reg,pts
|
||
sub reg,ES:pts
|
||
endm
|
||
LODPTS macro reg
|
||
les reg,[BP+@@pts]
|
||
endm
|
||
ELSE
|
||
MOVPTS macro to, from
|
||
mov to,from
|
||
endm
|
||
CMPPTS macro pts, dat
|
||
cmp pts,dat
|
||
endm
|
||
SUBPTS macro reg,pts
|
||
sub reg,pts
|
||
endm
|
||
LODPTS macro reg
|
||
mov reg,[BP+@@pts]
|
||
endm
|
||
ENDIF
|
||
|
||
MRETURN macro
|
||
pop SI
|
||
pop DI
|
||
leave
|
||
ret (datasize+1)*2
|
||
EVEN
|
||
endm
|
||
|
||
; void _pascal grcg_polygon_c( Point pts[], int npoint ) ;
|
||
;
|
||
func GRCG_POLYGON_C
|
||
push BP
|
||
mov BP,SP
|
||
sub SP,12 ; ローカル変数のサイズ
|
||
push DI
|
||
push SI
|
||
|
||
; パラメータ
|
||
@@pts = (RETSIZE+2)*2
|
||
@@npoint = (RETSIZE+1)*2
|
||
|
||
; ローカル変数
|
||
@@ry = -2 ; 左のy
|
||
@@ty = -4 ; 上端のy
|
||
@@ly = -6 ; 右のy
|
||
@@nl = -8 ; 左の点の添え字(byte単位)
|
||
@@nr = -10 ; 右の点の添え字(byte単位)
|
||
@@by = -12 ; 下端のy
|
||
|
||
mov AX,[BP+@@npoint]
|
||
dec AX
|
||
mov CX,AX ; CX = 本来の npoint
|
||
shl AX,2
|
||
mov [BP+@@npoint],AX ; npoint = (npoint-1)*4
|
||
|
||
; 頂上を探す〜 ----------------
|
||
|
||
LODPTS SI ; SI = pts
|
||
xor AX,AX
|
||
mov [BP+@@nl],AX ; nl = 0
|
||
mov [BP+@@nr],AX ; nr = 0
|
||
MOVPTS AX,[SI+2]
|
||
mov [BP+@@ty],AX ; ty = pts[0].y
|
||
mov [BP+@@by],AX ; by = pts[0].y
|
||
MOVPTS AX,[SI] ; AX = pts[0].x (AX=lx)
|
||
mov DI,AX ; DI = pts[0].x (DI=rx)
|
||
mov BX,4 ; BX = 1*4
|
||
|
||
@@LOOP1: ; x,y の各最大値と最小値を得るループ
|
||
MOVPTS DX,[BX+SI+2] ; pts[i].y
|
||
cmp DX,[BP+@@ty]
|
||
jge short @@S10
|
||
mov [BP+@@nl],BX ; nlは、頂上の最初にみつけた点
|
||
mov [BP+@@nr],BX ; nrは、頂上の最後に見つけた点
|
||
mov [BP+@@ty],DX
|
||
jmp short @@S30
|
||
EVEN
|
||
@@S10:
|
||
cmp [BP+@@ty],DX
|
||
jne short @@S20
|
||
mov [BP+@@nr],BX
|
||
jmp short @@S30
|
||
EVEN
|
||
@@S20:
|
||
cmp [BP+@@by],DX
|
||
jge short @@S30
|
||
mov [BP+@@by],DX
|
||
@@S30:
|
||
MOVPTS DX,[BX+SI] ; pts[].x
|
||
cmp AX,DX
|
||
jl short @@S40
|
||
mov AX,DX
|
||
jmp short @@S50
|
||
EVEN
|
||
|
||
; へんなところに潜ってるが、クリップの近場にreturn処理が
|
||
; いるのだ〜
|
||
@@RETURN1:
|
||
MRETURN
|
||
EVEN
|
||
@@S40: ; else
|
||
cmp DI,DX
|
||
jge short @@S50
|
||
mov DI,DX
|
||
@@S50:
|
||
add BX,4
|
||
loop short @@LOOP1
|
||
; ループ終り ----------------
|
||
|
||
; 範囲検査
|
||
cmp ClipXR,AX
|
||
jl short @@RETURN1 ; 完全に右に外れてる
|
||
|
||
cmp ClipXL,DI
|
||
jg short @@RETURN1 ; 完全に左に外れてる
|
||
|
||
mov AX,[BP+@@ty]
|
||
cmp ClipYB,AX
|
||
jl short @@RETURN1 ; 完全に下に外れてる
|
||
|
||
mov DX,[BP+@@by]
|
||
cmp ClipYT,DX
|
||
jg short @@RETURN1 ; 完全に上に外れてる
|
||
|
||
; **** さあ、ここに来たからには、かならず描画できるんだぞ。 ****
|
||
; (台形による最後のクリップを宛てにしてるから)
|
||
|
||
; 描画セグメント設定
|
||
IF datasize NE 2
|
||
mov ES,ClipYT_seg
|
||
ENDIF
|
||
|
||
; 下のy座標を先にクリップ枠で切断する
|
||
mov AX,ClipYB
|
||
cmp AX,DX
|
||
jge short @@S100
|
||
mov DX,AX
|
||
@@S100:
|
||
mov [BP+@@by],DX
|
||
|
||
; nlが最初、nr最後ならば、入れ換え。(わかりにくい〜)
|
||
; (凸多角形ならば、ある点の他に同じy座標の点は1つ以下にしか
|
||
; ならない。従って、頂上を共有する点は2つ以内なので、座標列の
|
||
; 端をまたがるのはこのパターンのみとなる)
|
||
mov AX,[BP+@@npoint]
|
||
cmp WORD PTR [BP+@@nl],0
|
||
jne short @@S110
|
||
cmp [BP+@@nr],AX
|
||
jne short @@S110
|
||
mov [BP+@@nl],AX
|
||
mov WORD PTR [BP+@@nr],0
|
||
@@S110:
|
||
|
||
; 左側辺の、上にはみ出ている部分を飛ばし ***
|
||
mov BX,[BP+@@nl] ; BX = nl
|
||
mov DX,[BP+@@npoint]
|
||
mov AX,ClipYT
|
||
@@LOOPL:
|
||
mov CX,BX
|
||
sub BX,4
|
||
jns short @@SKIPL
|
||
mov BX,DX
|
||
@@SKIPL:
|
||
CMPPTS [BX+SI+2],AX
|
||
jl short @@LOOPL
|
||
MOVPTS AX,[BX+SI+2]
|
||
mov [BP+@@ly],AX ; ly = pts[nl].y
|
||
mov [BP+@@nl],BX
|
||
|
||
; 最初の左側辺データを作成
|
||
|
||
mov BX,CX ; BX = i
|
||
MOVPTS DX,[SI+BX+2] ; DX = ty = pts[i].y
|
||
MOVPTS DI,[SI+BX] ; DI = wx = pts[i].x
|
||
mov BX,[BP+@@nl]
|
||
cmp DX,ClipYT
|
||
jge short @@S200
|
||
mov AX,DX
|
||
sub AX,[BP+@@ly] ; push (ty-ly)
|
||
PUSH AX
|
||
mov AX,DI ; AX = ((DI=wx) - pts[nl].x)
|
||
SUBPTS AX,[SI+BX]
|
||
mov CX,ClipYT
|
||
sub CX,DX ; CX = (ClipYT - (DX=ty))
|
||
imul CX
|
||
POP CX
|
||
idiv CX ; DI = (wx-pts[nl].x) * (ClipYT-ty)
|
||
add DI,AX ; / (ty-ly) + wx
|
||
mov DX,ClipYT ; ty = ClipYT
|
||
@@S200:
|
||
mov [BP+@@ty],DX
|
||
|
||
xchg DI,DX
|
||
MOVPTS AX,[SI+BX] ; pts[nl].x
|
||
mov CX,[BP+@@ly]
|
||
sub CX,DI ; CX = (ly-ty)
|
||
mov BX,offset trapez_a
|
||
call make_linework
|
||
|
||
|
||
; 右側辺の、上にはみ出ている部分を飛ばし ***
|
||
|
||
mov BX,[BP+@@nr] ; BX = nr
|
||
mov CX,[BP+@@npoint]
|
||
mov AX,ClipYT
|
||
@@LOOPR:
|
||
mov DI,BX ; DI = i
|
||
add BX,4 ; BX = nr
|
||
cmp BX,CX
|
||
jle short @@SKIPR
|
||
xor BX,BX
|
||
@@SKIPR:
|
||
CMPPTS [SI+BX+2],AX
|
||
jl short @@LOOPR
|
||
|
||
MOVPTS AX,[SI+BX+2]
|
||
mov [BP+@@ry],AX
|
||
mov [BP+@@nr],BX
|
||
|
||
; 最初の右側辺データを作成
|
||
add DI,SI
|
||
MOVPTS CX,[DI+2] ; CX = pts[i].y
|
||
MOVPTS DI,[DI] ; DI = wx = pts[i].x
|
||
MOVPTS BX,[SI+BX] ; BX = pts[nr].x
|
||
|
||
cmp CX,[BP+@@ty]
|
||
jge short @@S300
|
||
mov AX,ClipYT ; (ClipYT - pts[i].y)
|
||
sub AX,CX
|
||
push CX
|
||
mov CX,DI ; (wx - pts[nr].x)
|
||
sub CX,BX
|
||
imul CX
|
||
pop CX
|
||
sub CX,[BP+@@ry] ; (pts[i].y - ry)
|
||
idiv CX
|
||
add DI,AX ; + wx
|
||
@@S300:
|
||
mov DX,DI
|
||
mov AX,BX ; pts[nr].x
|
||
mov CX,[BP+@@ry]
|
||
sub CX,[BP+@@ty]
|
||
mov BX,offset trapez_b
|
||
call make_linework
|
||
|
||
; 実際に描画していくんだ[よーん] ========================
|
||
|
||
mov SI,[BP+@@ty] ; SI = ty
|
||
|
||
@@DRAWLOOP:
|
||
mov DI,[BP+@@ly] ; DI = y2
|
||
cmp DI,[BP+@@ry]
|
||
jle short @@S400
|
||
mov DI,[BP+@@ry]
|
||
@@S400:
|
||
cmp [BP+@@by],DI ; 下クリップ
|
||
jle short @@S500
|
||
|
||
PUSH DI
|
||
lea DX,[DI-1]
|
||
sub DX,SI ; DX = y2-1 - ty
|
||
sub SI,ClipYT
|
||
mov AX,SI ; SI = ty*80
|
||
shl SI,2
|
||
add SI,AX
|
||
shl SI,4
|
||
IF datasize EQ 2
|
||
mov ES,ClipYT_seg
|
||
ENDIF
|
||
call draw_trapezoid ; **** DRAW ****
|
||
POP SI
|
||
|
||
LODPTS DI ; DI = pts
|
||
cmp SI,[BP+@@ly] ; if ( ty == ly )
|
||
jne short @@S410
|
||
|
||
mov BX,[BP+@@nl]
|
||
MOVPTS DX,[BX+DI] ; DX = pts[nl].x
|
||
sub BX,4
|
||
jns short @@S405
|
||
mov BX,[BP+@@npoint]
|
||
@@S405:
|
||
mov [BP+@@nl],BX
|
||
MOVPTS AX,[DI+BX] ; AX = pts[nl].x
|
||
MOVPTS CX,[DI+BX+2] ; CX = (ly = pts[nl].y) - ty
|
||
mov [BP+@@ly],CX
|
||
sub CX,SI
|
||
mov BX,offset trapez_a
|
||
; DX = last pts[nl].x
|
||
call make_linework
|
||
|
||
@@S410: ; if ( ty == ry )
|
||
cmp [BP+@@ry],SI
|
||
jne short @@DRAWLOOP
|
||
|
||
mov BX,[BP+@@nr] ; BX = nr
|
||
MOVPTS DX,[BX+DI]
|
||
add BX,4
|
||
cmp BX,[BP+@@npoint]
|
||
jle short @@S420
|
||
xor BX,BX
|
||
@@S420:
|
||
mov [BP+@@nr],BX
|
||
MOVPTS AX,[DI+BX] ; AX = pts[nr].x
|
||
MOVPTS CX,[DI+BX+2] ; CX = pts[nr].y
|
||
mov [BP+@@ry],CX ; ry = CX
|
||
sub CX,SI ; CX -= SI
|
||
mov BX,offset trapez_b
|
||
push offset @@DRAWLOOP
|
||
jmp make_linework ; まさか!!
|
||
EVEN
|
||
|
||
; 一番下の台形
|
||
@@S500:
|
||
|
||
IF datasize EQ 2
|
||
mov ES,ClipYT_seg
|
||
ENDIF
|
||
mov DX,[BP+@@by]
|
||
sub DX,SI ; DX = by - ty
|
||
sub SI,ClipYT
|
||
mov AX,SI ; SI = ty*80
|
||
shl SI,2
|
||
add SI,AX
|
||
shl SI,4
|
||
call draw_trapezoid
|
||
MRETURN
|
||
endfunc
|