ReC98/libs/master.lib/grc_clip_polygon_n.asm

476 lines
8.3 KiB
NASM
Raw Normal View History

2014-08-31 06:55:51 +00:00
; 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のままでです。
; 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