mirror of https://github.com/nmlgc/ReC98.git
476 lines
8.3 KiB
NASM
476 lines
8.3 KiB
NASM
|
; gc_poly library - clip - polygon - convex
|
|||
|
;
|
|||
|
; Description:
|
|||
|
; 凸/凹多角形のクリッピング
|
|||
|
;
|
|||
|
; Funciton/Procedures:
|
|||
|
; int grc_clip_polygon_n( Point * dest, int ndest,
|
|||
|
; const Point * src, int nsrc ) ;
|
|||
|
;
|
|||
|
; Parameters:
|
|||
|
; Point *dest クリップ結果格納先
|
|||
|
; int ndest destに確保してある要素数
|
|||
|
; Point *src クリップ元の多角形の頂点配列
|
|||
|
; int nsrc srcに含まれる点の数
|
|||
|
;
|
|||
|
; Returns:
|
|||
|
; -1: srcのままでOKです。
|
|||
|
; 0: 全く範囲外です。描画できません。
|
|||
|
; 1〜: destにデータを格納しました。点数を返します。
|
|||
|
;
|
|||
|
; 上記3種類、どの場合でも destの内容は変化します。
|
|||
|
;
|
|||
|
; Binding Target:
|
|||
|
; Microsoft-C / Turbo-C / Turbo Pascal
|
|||
|
;
|
|||
|
; Running Target:
|
|||
|
; MS-DOS
|
|||
|
;
|
|||
|
; Requiring Resources:
|
|||
|
; CPU: V30
|
|||
|
;
|
|||
|
; Notes:
|
|||
|
; ・destには、凸の場合nsrc+4個,凹の場合nsrc*2個以上を確保しておくこと。
|
|||
|
; 実行時に、この ndest 個全てを書き換えます。
|
|||
|
;
|
|||
|
; ・凹多角形が入力され、クリッピングの結果が複数の島になってしまう場合、
|
|||
|
; クリップ枠の周囲に沿って細く繋げた形になります。
|
|||
|
;
|
|||
|
; ・destとsrcの関係は、全く同じ場合と、全く重ならない場合の
|
|||
|
; どちらかでなくてはいけません。
|
|||
|
; dest=srcの場合、戻り値に -1 が返る事はありません。
|
|||
|
;
|
|||
|
; ・src または dest が NULL かどうかの検査は行っていません。
|
|||
|
;
|
|||
|
; Compiler/Assembler:
|
|||
|
; TASM 3.0
|
|||
|
; OPTASM 1.6
|
|||
|
;
|
|||
|
; Author:
|
|||
|
; 恋塚昭彦
|
|||
|
;
|
|||
|
; Revision History:
|
|||
|
; 92/ 7/11 Initial
|
|||
|
; 92/ 7/17 bugfix(y=ClipYT or YBの点を含むクリップの誤り)
|
|||
|
; 92/ 7/30 bugfix(FAR版、srcとdestの一致判定にセグメントが抜けていた)
|
|||
|
; 92/11/16 bugfix(FAR版、ret <popvalue>の値が間違っていた
|
|||
|
; 93/ 5/10 bugfix(FAR版、ひとつセグメントロードが足りなかった(^^;)
|
|||
|
;
|
|||
|
|
|||
|
; IN: x
|
|||
|
; OUT: ans
|
|||
|
; BREAK: ans, flag
|
|||
|
GETOUTCODE_X macro ans,x,xl,xr
|
|||
|
local OUTEND
|
|||
|
mov ans,LEFT_OUT
|
|||
|
cmp xl,x
|
|||
|
jg short OUTEND
|
|||
|
xor ans,YOKO_OUT
|
|||
|
cmp x,xr
|
|||
|
jg short OUTEND
|
|||
|
xor ans,ans
|
|||
|
OUTEND:
|
|||
|
ENDM
|
|||
|
|
|||
|
; IN: y
|
|||
|
; OUT: ans
|
|||
|
; BREAK: ans, flag
|
|||
|
GETOUTCODE_Y macro ans,y,yt,yb
|
|||
|
local OUTEND
|
|||
|
mov ans,BOTTOM_OUT
|
|||
|
cmp y,yb
|
|||
|
jg short OUTEND
|
|||
|
xor ans,TATE_OUT
|
|||
|
cmp y,yt
|
|||
|
jl short OUTEND
|
|||
|
xor ans,ans
|
|||
|
OUTEND:
|
|||
|
ENDM
|
|||
|
|
|||
|
MRETURN macro
|
|||
|
pop DI
|
|||
|
pop SI
|
|||
|
mov SP,BP
|
|||
|
pop BP
|
|||
|
ret (2+datasize*2)*2
|
|||
|
EVEN
|
|||
|
endm
|
|||
|
|
|||
|
if datasize EQ 2
|
|||
|
LODE macro dest,src
|
|||
|
mov dest,ES:src
|
|||
|
endm
|
|||
|
STOE macro dest,src
|
|||
|
mov ES:dest,src
|
|||
|
endm
|
|||
|
ESSRC macro
|
|||
|
mov ES,[BP+@@src+2]
|
|||
|
endm
|
|||
|
ESDEST macro
|
|||
|
mov ES,[BP+@@dest+2]
|
|||
|
endm
|
|||
|
else
|
|||
|
LODE macro dest,src
|
|||
|
mov dest,src
|
|||
|
endm
|
|||
|
STOE macro dest,src
|
|||
|
mov dest,src
|
|||
|
endm
|
|||
|
ESSRC macro
|
|||
|
endm
|
|||
|
ESDEST macro
|
|||
|
endm
|
|||
|
endif
|
|||
|
|
|||
|
;---------------------------------------
|
|||
|
; int grc_clip_polygon_n( Point * dest, int ndest,
|
|||
|
; const Point * src, int nsrc ) ;
|
|||
|
func GRC_CLIP_POLYGON_N
|
|||
|
ENTER 14,0
|
|||
|
push SI
|
|||
|
push DI
|
|||
|
|
|||
|
; 引数
|
|||
|
@@dest = (RETSIZE+3+DATASIZE)*2
|
|||
|
@@ndest = (RETSIZE+2+DATASIZE)*2
|
|||
|
@@src = (RETSIZE+2)*2
|
|||
|
@@nsrc = (RETSIZE+1)*2
|
|||
|
|
|||
|
; ローカル変数
|
|||
|
@@yb = -2 ; STEP 1 のみ
|
|||
|
|
|||
|
@@d = -2 ; dx,dy
|
|||
|
@@oc = -4
|
|||
|
@@y = -6
|
|||
|
@@x = -8
|
|||
|
@@radr = -10
|
|||
|
@@last_oc = -12
|
|||
|
@@i = -14
|
|||
|
|
|||
|
;---------------------------
|
|||
|
; 最初のステップ:
|
|||
|
; 完全判定(完全に中か、完全に外か)
|
|||
|
|
|||
|
; src
|
|||
|
; nsrc
|
|||
|
; (i,x,y)
|
|||
|
; (xl,xr,yt,yb)
|
|||
|
|
|||
|
mov BX,[BP+@@nsrc] ;
|
|||
|
dec BX
|
|||
|
shl BX,2 ;
|
|||
|
_les SI,[BP+@@src]
|
|||
|
|
|||
|
; xl,xr,yt,ybの初期設定
|
|||
|
LODE AX,[SI+BX]
|
|||
|
mov DX,AX ; DX = xl
|
|||
|
mov CX,AX ; CX = xr
|
|||
|
LODE AX,[SI+BX+2]
|
|||
|
mov DI,AX ; DI = yt
|
|||
|
mov [BP+@@yb],AX
|
|||
|
sub BX,4
|
|||
|
; ループ〜
|
|||
|
@@LOOP1:
|
|||
|
LODE AX,[SI+BX]
|
|||
|
cmp AX,DX
|
|||
|
jg short @@L1_010
|
|||
|
mov DX,AX
|
|||
|
@@L1_010: cmp AX,CX
|
|||
|
jl short @@L1_020
|
|||
|
mov CX,AX
|
|||
|
@@L1_020:
|
|||
|
LODE AX,[SI+BX+2]
|
|||
|
cmp AX,DI
|
|||
|
jg short @@L1_030
|
|||
|
mov DI,AX
|
|||
|
@@L1_030: cmp AX,[BP+@@yb]
|
|||
|
jle short @@L1_040
|
|||
|
mov [BP+@@yb],AX
|
|||
|
@@L1_040: sub BX,4
|
|||
|
jge short @@LOOP1
|
|||
|
|
|||
|
; 全点走査が終ったので、BBOXによる内外判定
|
|||
|
@@LOOP1E:
|
|||
|
; 外判定
|
|||
|
cmp ClipXL,CX ; CX=xr
|
|||
|
jg short @@RET_OUT
|
|||
|
cmp DX,ClipXR ; DX=xl
|
|||
|
jg short @@RET_OUT
|
|||
|
cmp ClipYB,DI ; DI=yt
|
|||
|
jl short @@RET_OUT
|
|||
|
mov AX,[BP+@@yb]
|
|||
|
cmp ClipYT,AX
|
|||
|
jg short @@RET_OUT
|
|||
|
|
|||
|
; 内判定
|
|||
|
cmp DX,ClipXL ; DX=xl
|
|||
|
jl short @@STEP2
|
|||
|
cmp CX,ClipXR ; CX=xr
|
|||
|
jg short @@STEP2
|
|||
|
cmp DI,ClipYT
|
|||
|
jl short @@STEP2
|
|||
|
mov AX,ClipYB
|
|||
|
cmp [BP+@@yb],AX
|
|||
|
jg short @@STEP2
|
|||
|
mov AX,[BP+@@dest]
|
|||
|
cmp SI,AX ; SI = src
|
|||
|
jne short @@RET_IN
|
|||
|
if datasize EQ 2
|
|||
|
mov AX,ES ; segment compare
|
|||
|
mov SI,[BP+@@dest+2]
|
|||
|
cmp SI,AX
|
|||
|
jne short @@RET_IN
|
|||
|
endif
|
|||
|
mov AX,[BP+@@nsrc]
|
|||
|
MRETURN
|
|||
|
|
|||
|
@@RET_IN: ; 完全に中だぜ
|
|||
|
mov AX,-1
|
|||
|
MRETURN
|
|||
|
|
|||
|
@@RET_OUT: ; 完全に外だぜ
|
|||
|
xor AX,AX
|
|||
|
MRETURN
|
|||
|
|
|||
|
;---------------------------
|
|||
|
; 第2ステップ:
|
|||
|
; 上下のカット
|
|||
|
@@STEP2:
|
|||
|
mov SI,[BP+@@ndest] ; SI=nans
|
|||
|
|
|||
|
_les BX,[BP+@@src]
|
|||
|
LODE AX,[BX]
|
|||
|
mov [BP+@@x],AX ; x = src[0].x
|
|||
|
LODE AX,[BX+2]
|
|||
|
mov [BP+@@y],AX ; y = src[0].y
|
|||
|
GETOUTCODE_Y BX,AX,ClipYT,ClipYB
|
|||
|
mov [BP+@@last_oc],BX ; last_oc = outcode_y(x,y)
|
|||
|
mov DI,[BP+@@nsrc]
|
|||
|
dec DI
|
|||
|
jns short @@STEP2_1
|
|||
|
jmp @@STEP3 ; ここを通るときはSI=nansでなきゃいかんよ
|
|||
|
; 変更するときは気を付けよう
|
|||
|
|
|||
|
@@STEP2_1:
|
|||
|
mov AX,DI
|
|||
|
shl AX,2
|
|||
|
add AX,[BP+@@src]
|
|||
|
mov [BP+@@radr],AX ; radr = &src[nsrc-1]
|
|||
|
mov [BP+@@i],DI ; i = nsrc-1
|
|||
|
mov DI,[BP+@@y] ; DI=y
|
|||
|
@@LOOP2:
|
|||
|
mov DX,[BP+@@x] ; DX=x
|
|||
|
mov CX,DI ; CX=y
|
|||
|
mov BX,[BP+@@radr]
|
|||
|
ESSRC
|
|||
|
LODE AX,[BX] ; AX = x = radr->x
|
|||
|
mov [BP+@@x],AX ;
|
|||
|
LODE DI,[BX+2] ; DI = radr->y
|
|||
|
cmp DX,AX
|
|||
|
jne short @@S2_010
|
|||
|
cmp CX,DI
|
|||
|
jne short @@S2_010
|
|||
|
jmp @@S2_090 ; (;_;)
|
|||
|
@@S2_010:
|
|||
|
sub DX,AX
|
|||
|
sub CX,DI
|
|||
|
GETOUTCODE_Y AX,DI,ClipYT,ClipYB
|
|||
|
mov [BP+@@oc],AX
|
|||
|
mov BX,[BP+@@last_oc]
|
|||
|
cmp AX,BX
|
|||
|
je short @@S2_070
|
|||
|
|
|||
|
mov [BP+@@d],DX ; dx
|
|||
|
|
|||
|
; 線分の始点側の切断
|
|||
|
or BX,BX
|
|||
|
je short @@S2_040
|
|||
|
|
|||
|
cmp BX,TOP_OUT
|
|||
|
jne short @@S2_020
|
|||
|
mov AX,ClipYT
|
|||
|
jmp short @@S2_030
|
|||
|
@@S2_020: mov AX,ClipYB
|
|||
|
@@S2_030: cmp AX,DI ;y
|
|||
|
je short @@S2_040
|
|||
|
|
|||
|
dec SI
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
ESDEST
|
|||
|
STOE [BX+2],AX ; wy
|
|||
|
sub AX,DI ; y
|
|||
|
imul DX ; dx
|
|||
|
idiv CX ; dy
|
|||
|
add AX,[BP+@@x]
|
|||
|
STOE [BX],AX
|
|||
|
|
|||
|
@@S2_040:
|
|||
|
; 線分の終点側の切断
|
|||
|
mov BX,[BP+@@oc]
|
|||
|
or BX,BX
|
|||
|
je short @@S2_070
|
|||
|
cmp BX,TOP_OUT
|
|||
|
jne short @@S2_050
|
|||
|
mov AX,ClipYT
|
|||
|
jmp short @@S2_060
|
|||
|
EVEN
|
|||
|
@@S2_050: mov AX,ClipYB
|
|||
|
@@S2_060:
|
|||
|
mov DX,CX ; dy
|
|||
|
add DX,DI ;y
|
|||
|
cmp DX,AX
|
|||
|
je short @@S2_070
|
|||
|
|
|||
|
dec SI
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
ESDEST
|
|||
|
STOE [BX+2],AX
|
|||
|
|
|||
|
sub AX,DI ;y
|
|||
|
imul WORD PTR [BP+@@d] ; dx
|
|||
|
idiv CX ; dy
|
|||
|
add AX,[BP+@@x]
|
|||
|
STOE [BX],AX
|
|||
|
@@S2_070:
|
|||
|
mov CX,[BP+@@oc]
|
|||
|
or CX,CX
|
|||
|
jne short @@S2_080
|
|||
|
dec SI
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
ESDEST
|
|||
|
mov AX,[BP+@@x]
|
|||
|
STOE [BX],AX
|
|||
|
STOE [BX+2],DI ;y
|
|||
|
@@S2_080:
|
|||
|
mov [BP+@@last_oc],CX
|
|||
|
@@S2_090:
|
|||
|
sub WORD PTR [BP+@@radr],4
|
|||
|
dec WORD PTR [BP+@@i]
|
|||
|
js short @@STEP3
|
|||
|
jmp @@LOOP2 ; (;_;)
|
|||
|
|
|||
|
;---------------------------
|
|||
|
; 第3ステップ:
|
|||
|
; 左右のカット
|
|||
|
; SI: nans
|
|||
|
@@STEP3:
|
|||
|
mov CX,[BP+@@ndest]
|
|||
|
mov BX,CX
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
ESDEST
|
|||
|
LODE AX,[BX-2]
|
|||
|
mov [BP+@@y],AX
|
|||
|
LODE DI,[BX-4]
|
|||
|
GETOUTCODE_X AX,DI,ClipXL,ClipXR
|
|||
|
mov [BP+@@last_oc],AX
|
|||
|
cmp SI,CX
|
|||
|
jl short @@S3_010
|
|||
|
xor AX,AX ; nans=0だから
|
|||
|
jmp @@RETURN
|
|||
|
EVEN
|
|||
|
@@S3_010:
|
|||
|
mov AX,SI
|
|||
|
shl AX,2
|
|||
|
add AX,[BP+@@dest]
|
|||
|
mov [BP+@@radr],AX
|
|||
|
mov AX,CX
|
|||
|
sub AX,SI
|
|||
|
mov [BP+@@i],AX
|
|||
|
mov SI,0 ; nans=0
|
|||
|
@@LOOP3:
|
|||
|
mov CX,DI ; CX:dx
|
|||
|
mov AX,[BP+@@y]
|
|||
|
mov DX,AX ; DX:dy
|
|||
|
mov BX,[BP+@@radr]
|
|||
|
LODE DI,[BX] ; DI:x
|
|||
|
LODE AX,[BX+2]
|
|||
|
mov [BP+@@y],AX
|
|||
|
sub CX,DI
|
|||
|
sub DX,AX
|
|||
|
|
|||
|
mov BX,DI
|
|||
|
GETOUTCODE_X AX,BX,ClipXL,ClipXR
|
|||
|
mov [BP+@@oc],AX
|
|||
|
mov BX,[BP+@@last_oc]
|
|||
|
cmp AX,BX
|
|||
|
je short @@S3_070
|
|||
|
|
|||
|
mov [BP+@@d],DX ; dy
|
|||
|
|
|||
|
or BX,BX
|
|||
|
je short @@S3_040
|
|||
|
cmp BX,LEFT_OUT
|
|||
|
jne short @@S3_020
|
|||
|
mov AX,ClipXL
|
|||
|
jmp short @@S3_030
|
|||
|
EVEN
|
|||
|
@@S3_020:
|
|||
|
mov AX,ClipXR
|
|||
|
@@S3_030:
|
|||
|
cmp AX,DI
|
|||
|
je short @@S3_040
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
STOE [BX],AX
|
|||
|
sub AX,DI ; x
|
|||
|
imul DX
|
|||
|
idiv CX
|
|||
|
add AX,[BP+@@y]
|
|||
|
STOE [BX+2],AX
|
|||
|
inc SI
|
|||
|
@@S3_040:
|
|||
|
mov BX,[BP+@@oc]
|
|||
|
or BX,BX
|
|||
|
je short @@S3_070
|
|||
|
cmp BX,LEFT_OUT
|
|||
|
jne short @@S3_050
|
|||
|
mov AX,ClipXL
|
|||
|
jmp SHORT @@S3_060
|
|||
|
@@S3_050:
|
|||
|
mov AX,ClipXR
|
|||
|
@@S3_060:
|
|||
|
mov BX,CX
|
|||
|
add BX,DI
|
|||
|
cmp BX,AX
|
|||
|
je short @@S3_070
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
STOE [BX],AX
|
|||
|
sub AX,DI ; x
|
|||
|
imul WORD PTR [BP+@@d] ; dy
|
|||
|
idiv CX ; dx
|
|||
|
add AX,[BP+@@y]
|
|||
|
STOE [BX+2],AX
|
|||
|
inc SI
|
|||
|
@@S3_070:
|
|||
|
mov CX,[BP+@@oc]
|
|||
|
or CX,CX
|
|||
|
jne short @@S3_080
|
|||
|
mov BX,SI
|
|||
|
shl BX,2
|
|||
|
add BX,[BP+@@dest]
|
|||
|
STOE [BX],DI
|
|||
|
mov AX,[BP+@@y]
|
|||
|
STOE [BX+2],AX
|
|||
|
inc SI
|
|||
|
@@S3_080:
|
|||
|
mov [BP+@@last_oc],CX
|
|||
|
add WORD PTR [BP+@@radr],4
|
|||
|
dec WORD PTR [BP+@@i]
|
|||
|
je short @@S3_090
|
|||
|
jmp @@LOOP3 ; (;_;)
|
|||
|
@@S3_090:
|
|||
|
mov AX,SI
|
|||
|
@@RETURN:
|
|||
|
MRETURN
|
|||
|
endfunc
|