[Reduction] #400: grc_clip_polygon_n

This commit is contained in:
nmlgc 2014-08-31 08:55:51 +02:00
parent 1546628658
commit c793095729
2 changed files with 477 additions and 412 deletions

View File

@ -0,0 +1,475 @@
; 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

View File

@ -63,417 +63,7 @@ include libs/master.lib/grcg_circlefill.asm
include libs/master.lib/grcg_circle.asm
include libs/master.lib/grcg_circle_x.asm
include libs/master.lib/grc_setclip.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_139E proc far
var_E = word ptr -0Eh
var_C = word ptr -0Ch
var_A = word ptr -0Ah
var_8 = word ptr -8
var_6 = word ptr -6
var_4 = word ptr -4
var_2 = word ptr -2
arg_0 = word ptr 6
arg_2 = dword ptr 8
arg_6 = word ptr 0Ch
arg_8 = word ptr 0Eh
arg_A = word ptr 10h
enter 0Eh, 0
push si
push di
mov bx, [bp+arg_0]
dec bx
shl bx, 2
les si, [bp+arg_2]
mov ax, es:[bx+si]
mov dx, ax
mov cx, ax
mov ax, es:[bx+si+2]
mov di, ax
mov [bp+var_2], ax
sub bx, 4
loc_13C1:
mov ax, es:[bx+si]
cmp ax, dx
jg short loc_13CA
mov dx, ax
loc_13CA:
cmp ax, cx
jl short loc_13D0
mov cx, ax
loc_13D0:
mov ax, es:[bx+si+2]
cmp ax, di
jg short loc_13DA
mov di, ax
loc_13DA:
cmp ax, [bp+var_2]
jle short loc_13E2
mov [bp+var_2], ax
loc_13E2:
sub bx, 4
jge short loc_13C1
cmp ClipXL, cx
jg short loc_1444
cmp dx, ClipXR
jg short loc_1444
cmp ClipYB, di
jl short loc_1444
mov ax, [bp+var_2]
cmp ClipYT, ax
jg short loc_1444
cmp dx, ClipXL
jl short loc_144E
cmp cx, ClipXR
jg short loc_144E
cmp di, ClipYT
jl short loc_144E
mov ax, ClipYB
cmp [bp+var_2], ax
jg short loc_144E
mov ax, [bp+arg_8]
cmp si, ax
jnz short loc_1438
mov ax, es
mov si, [bp+arg_A]
cmp si, ax
jnz short loc_1438
mov ax, [bp+arg_0]
pop di
pop si
mov sp, bp
pop bp
retf 0Ch
; ---------------------------------------------------------------------------
nop
loc_1438:
mov ax, 0FFFFh
pop di
pop si
mov sp, bp
pop bp
retf 0Ch
; ---------------------------------------------------------------------------
nop
loc_1444:
xor ax, ax
pop di
pop si
mov sp, bp
pop bp
retf 0Ch
; ---------------------------------------------------------------------------
loc_144E:
mov si, [bp+arg_6]
les bx, [bp+arg_2]
mov ax, es:[bx]
mov [bp+var_8], ax
mov ax, es:[bx+2]
mov [bp+var_6], ax
mov bx, 4
cmp ax, ClipYB
jg short loc_1475
xor bx, 0Ch
cmp ax, ClipYT
jl short loc_1475
xor bx, bx
loc_1475:
mov [bp+var_C], bx
mov di, [bp+arg_0]
dec di
jns short loc_1481
jmp loc_156E
; ---------------------------------------------------------------------------
loc_1481:
mov ax, di
shl ax, 2
add ax, word ptr [bp+arg_2]
mov [bp+var_A], ax
mov [bp+var_E], di
mov di, [bp+var_6]
loc_1492:
mov dx, [bp+var_8]
mov cx, di
mov bx, [bp+var_A]
mov es, word ptr [bp+arg_2+2]
mov ax, es:[bx]
mov [bp+var_8], ax
mov di, es:[bx+2]
cmp dx, ax
jnz short loc_14B2
cmp cx, di
jnz short loc_14B2
jmp loc_1562
; ---------------------------------------------------------------------------
loc_14B2:
; sub_139E+10Fj
sub dx, ax
sub cx, di
mov ax, 4
cmp di, ClipYB
jg short loc_14CA
xor ax, 0Ch
cmp di, ClipYT
jl short loc_14CA
xor ax, ax
loc_14CA:
; sub_139E+128j
mov [bp+var_4], ax
mov bx, [bp+var_C]
cmp ax, bx
jz short loc_1542
mov [bp+var_2], dx
or bx, bx
jz short loc_1508
cmp bx, 8
jnz short loc_14E5
mov ax, ClipYT
jmp short loc_14E8
; ---------------------------------------------------------------------------
loc_14E5:
mov ax, ClipYB
loc_14E8:
cmp ax, di
jz short loc_1508
dec si
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es, [bp+arg_A]
mov es:[bx+2], ax
sub ax, di
imul dx
idiv cx
add ax, [bp+var_8]
mov es:[bx], ax
loc_1508:
; sub_139E+14Cj
mov bx, [bp+var_4]
or bx, bx
jz short loc_1542
cmp bx, 8
jnz short loc_151A
mov ax, ClipYT
jmp short loc_151D
; ---------------------------------------------------------------------------
nop
loc_151A:
mov ax, ClipYB
loc_151D:
mov dx, cx
add dx, di
cmp dx, ax
jz short loc_1542
dec si
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es, [bp+arg_A]
mov es:[bx+2], ax
sub ax, di
imul [bp+var_2]
idiv cx
add ax, [bp+var_8]
mov es:[bx], ax
loc_1542:
; sub_139E+16Fj ...
mov cx, [bp+var_4]
or cx, cx
jnz short loc_155F
dec si
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es, [bp+arg_A]
mov ax, [bp+var_8]
mov es:[bx], ax
mov es:[bx+2], di
loc_155F:
mov [bp+var_C], cx
loc_1562:
sub [bp+var_A], 4
dec [bp+var_E]
js short loc_156E
jmp loc_1492
; ---------------------------------------------------------------------------
loc_156E:
; sub_139E+1CBj
mov cx, [bp+arg_6]
mov bx, cx
shl bx, 2
add bx, [bp+arg_8]
mov es, [bp+arg_A]
mov ax, es:[bx-2]
mov [bp+var_6], ax
mov di, es:[bx-4]
mov ax, 1
cmp ClipXL, di
jg short loc_159B
xor ax, 3
cmp di, ClipXR
jg short loc_159B
xor ax, ax
loc_159B:
; sub_139E+1F9j
mov [bp+var_C], ax
cmp si, cx
jl short loc_15A8
xor ax, ax
jmp loc_1687
; ---------------------------------------------------------------------------
nop
loc_15A8:
mov ax, si
shl ax, 2
add ax, [bp+arg_8]
mov [bp+var_A], ax
mov ax, cx
sub ax, si
mov [bp+var_E], ax
mov si, 0
loc_15BD:
mov cx, di
mov ax, [bp+var_6]
mov dx, ax
mov bx, [bp+var_A]
mov di, es:[bx]
mov ax, es:[bx+2]
mov [bp+var_6], ax
sub cx, di
sub dx, ax
mov bx, di
mov ax, 1
cmp ClipXL, bx
jg short loc_15EB
xor ax, 3
cmp bx, ClipXR
jg short loc_15EB
xor ax, ax
loc_15EB:
; sub_139E+249j
mov [bp+var_4], ax
mov bx, [bp+var_C]
cmp ax, bx
jz short loc_165C
mov [bp+var_2], dx
or bx, bx
jz short loc_1626
cmp bx, 1
jnz short loc_1606
mov ax, ClipXL
jmp short loc_1609
; ---------------------------------------------------------------------------
loc_1606:
mov ax, ClipXR
loc_1609:
cmp ax, di
jz short loc_1626
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es:[bx], ax
sub ax, di
imul dx
idiv cx
add ax, [bp+var_6]
mov es:[bx+2], ax
inc si
loc_1626:
; sub_139E+26Dj
mov bx, [bp+var_4]
or bx, bx
jz short loc_165C
cmp bx, 1
jnz short loc_1637
mov ax, ClipXL
jmp short loc_163A
; ---------------------------------------------------------------------------
loc_1637:
mov ax, ClipXR
loc_163A:
mov bx, cx
add bx, di
cmp bx, ax
jz short loc_165C
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es:[bx], ax
sub ax, di
imul [bp+var_2]
idiv cx
add ax, [bp+var_6]
mov es:[bx+2], ax
inc si
loc_165C:
; sub_139E+28Dj ...
mov cx, [bp+var_4]
or cx, cx
jnz short loc_1676
mov bx, si
shl bx, 2
add bx, [bp+arg_8]
mov es:[bx], di
mov ax, [bp+var_6]
mov es:[bx+2], ax
inc si
loc_1676:
mov [bp+var_C], cx
add [bp+var_A], 4
dec [bp+var_E]
jz short loc_1685
jmp loc_15BD
; ---------------------------------------------------------------------------
loc_1685:
mov ax, si
loc_1687:
pop di
pop si
mov sp, bp
pop bp
retf 0Ch
sub_139E endp
include libs/master.lib/grc_clip_polygon_n.asm
include libs/master.lib/grcg_hline.asm
; =============== S U B R O U T I N E =======================================
@ -13520,7 +13110,7 @@ arg_0 = word ptr 4
push ss
push di
push 4
call sub_139E
call grc_clip_polygon_n
or ax, ax
jz short loc_EA6D
jge short loc_EA61