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
|