diff --git a/libs/master.lib/grc_clip_polygon_n.asm b/libs/master.lib/grc_clip_polygon_n.asm new file mode 100644 index 00000000..57e227ad --- /dev/null +++ b/libs/master.lib/grc_clip_polygon_n.asm @@ -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のままで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 の値が間違っていた +; 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 diff --git a/th05_main.asm b/th05_main.asm index 5c54c9cb..cb656f9a 100644 --- a/th05_main.asm +++ b/th05_main.asm @@ -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