--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXCC.ASM - Fast clip line function\r
+; Copyright (c) 1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC xsubClipLine\r
+\r
+MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN mx_BytesPerLine : WORD\r
+EXTRN mx_VideoSegment : WORD\r
+\r
+EXTRN mx_ClipX1 : WORD\r
+EXTRN mx_ClipY1 : WORD\r
+EXTRN mx_ClipX2 : WORD\r
+EXTRN mx_ClipY2 : WORD\r
+\r
+tblGroups LABEL WORD\r
+ DW 10, tbl00\r
+ DW 10, tbl10\r
+ DW 9, tbl20\r
+ DW -1, 0\r
+ DW 10, tbl40\r
+ DW 10, tbl50\r
+ DW 9, tbl60\r
+ DW -1, 0\r
+ DW 6, tbl80\r
+ DW 6, tbl90\r
+ DW 5, tblA0\r
+ DW -1, 0\r
+ DW -1, 0\r
+ DW -1, 0\r
+ DW -1, 0\r
+ DW -1, 0\r
+tbl00 DW cc00, cc01, cc02, ccFF, cc04, cc05, cc06, ccFF, cc08, cc09, cc0A\r
+tbl10 DW cc10, ccFF, cc12, ccFF, cc14, ccFF, cc16, ccFF, cc18, ccFF, cc1A\r
+tbl20 DW cc20, cc21, ccFF, ccFF, cc24, cc25, ccFF, ccFF, cc28, cc29\r
+tbl40 DW cc40, cc41, cc42, ccFF, ccFF, ccFF, ccFF, ccFF, cc48, cc49, cc4A\r
+tbl50 DW cc50, ccFF, cc52, ccFF, ccFF, ccFF, ccFF, ccFF, cc58, ccFF, cc5A\r
+tbl60 DW cc60, cc61, ccFF, ccFF, ccFF, ccFF, ccFF, ccFF, cc68, cc69\r
+tbl80 DW cc80, cc81, cc82, ccFF, cc84, cc85, cc86\r
+tbl90 DW cc90, ccFF, cc92, ccFF, cc94, ccFF, cc96\r
+tblA0 DW ccA0, ccA1, ccFF, ccFF, ccA4, ccA5\r
+\r
+ccTT: clc\r
+ ret\r
+ccFF: stc\r
+ ret\r
+\r
+; Group 00 -------------------------------------------------\r
+;\r
+cc00:\r
+ clc\r
+ ret\r
+cc01:\r
+ jmp ClipQLeft\r
+cc02:\r
+ jmp ClipQRight\r
+cc04:\r
+ jmp ClipQTop\r
+cc05:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY1]\r
+ jge ccTT\r
+ jmp ClipQTop\r
+cc06:\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY1]\r
+ jge ccTT\r
+ jmp ClipQTop\r
+cc08:\r
+ jmp ClipQBottom\r
+cc09:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY2]\r
+ jle ccTT\r
+ jmp ClipQBottom\r
+cc0A:\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY2]\r
+ jle ccTT\r
+ jmp ClipQBottom\r
+\r
+; Group 10 -------------------------------------------------\r
+;\r
+cc10FF:\r
+ stc\r
+ ret\r
+cc10TT:\r
+ clc\r
+ ret\r
+cc10:\r
+ jmp ClipPLeft\r
+cc12:\r
+ call ClipPLeft\r
+ jmp ClipQRight\r
+cc14:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc10FF\r
+ jmp ClipQTop\r
+cc16:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc10FF\r
+ call ClipQTop\r
+ cmp cx, [mx_ClipX2]\r
+ jle cc10TT\r
+ jmp ClipQRight\r
+cc18:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc10FF\r
+ jmp ClipQBottom\r
+cc1A:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc10FF\r
+ call ClipQBottom\r
+ cmp cx, [mx_ClipX2]\r
+ jle cc10TT\r
+ jmp ClipQRight\r
+\r
+; Group 20 -------------------------------------------------\r
+;\r
+cc20TT:\r
+ clc\r
+ ret\r
+cc20FF:\r
+ stc\r
+ ret\r
+cc20:\r
+ jmp ClipPRight\r
+cc21:\r
+ call ClipPRight\r
+ jmp ClipQLeft\r
+cc24:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc20FF\r
+ jmp ClipQTop\r
+cc25:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc20FF\r
+ call ClipQTop\r
+ cmp cx, [mx_ClipX1]\r
+ jge cc20TT\r
+ jmp ClipQLeft\r
+cc28:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc20FF\r
+ jmp ClipQBottom\r
+cc29:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc20FF\r
+ call ClipQBottom\r
+ cmp cx, [mx_ClipX1]\r
+ jge cc20TT\r
+ jmp ClipQLeft\r
+\r
+; Group 40 -------------------------------------------------\r
+;\r
+cc40TT:\r
+ clc\r
+ ret\r
+cc40FF:\r
+ stc\r
+ ret\r
+cc40:\r
+ jmp ClipPTop\r
+cc41:\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX1]\r
+ jl cc40FF\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY1]\r
+ jge cc40TT\r
+ jmp ClipQTop\r
+cc42:\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX2]\r
+ jg cc40FF\r
+ jmp ClipQRight\r
+cc48:\r
+ call ClipPTop\r
+ jmp ClipQBottom\r
+cc49:\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX1]\r
+ jl cc40FF\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY2]\r
+ jle cc40TT\r
+ jmp ClipQBottom\r
+cc4A:\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX2]\r
+ jg cc40FF\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY2]\r
+ jle cc40TT\r
+ jmp ClipQBottom\r
+\r
+\r
+; Group 50 -------------------------------------------------\r
+;\r
+cc50TT:\r
+ clc\r
+ ret\r
+cc50FF:\r
+ stc\r
+ ret\r
+cc50:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY1]\r
+ jge cc50TT\r
+ jmp ClipPTop\r
+cc52:\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY1]\r
+ jl cc50FF\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX1]\r
+ jge cc50TT\r
+ jmp ClipPLeft\r
+cc58:\r
+ call ClipQBottom\r
+ cmp cx, [mx_ClipX1]\r
+ jl cc50FF\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX1]\r
+ jge cc50TT\r
+ jmp ClipPLeft\r
+cc5A:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc50FF\r
+ call ClipQRight\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc50FF\r
+ cmp si, [mx_ClipY2]\r
+ jle cc50TT\r
+ jmp ClipQBottom\r
+\r
+; Group 60 -------------------------------------------------\r
+;\r
+cc60TT:\r
+ clc\r
+ ret\r
+cc60FF:\r
+ stc\r
+ ret\r
+cc60:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY1]\r
+ jge cc60TT\r
+ jmp ClipPTop\r
+cc61:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY2]\r
+ jl cc60FF\r
+ call ClipPTop\r
+ cmp di, [mx_ClipX2]\r
+ jle cc60TT\r
+ jmp ClipPRight\r
+cc68:\r
+ call ClipQBottom\r
+ cmp cx, [mx_ClipX2]\r
+ jg cc60FF\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY1]\r
+ jge cc60TT\r
+ jmp ClipPTop\r
+cc69:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY1]\r
+ jl cc60FF\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY2]\r
+ jg cc60FF\r
+ cmp si, [mx_ClipY2]\r
+ jle cc69_1\r
+ call ClipQBottom\r
+cc69_1:\r
+ cmp bx, [mx_ClipY1]\r
+ jge cc60TT\r
+ jmp ClipPTop\r
+\r
+; Group 80 -------------------------------------------------\r
+;\r
+cc80TT:\r
+ clc\r
+ ret\r
+cc80FF:\r
+ stc\r
+ ret\r
+cc80:\r
+ jmp ClipPBottom\r
+cc81:\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX1]\r
+ jl cc80FF\r
+ jmp ClipQLeft\r
+cc82:\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX2]\r
+ jg cc80FF\r
+ jmp ClipQRight\r
+cc84:\r
+ call ClipPBottom\r
+ jmp ClipQTop\r
+cc85:\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX1]\r
+ jl cc80FF\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY1]\r
+ jge cc80FF\r
+ jmp ClipQTop\r
+cc86:\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX2]\r
+ jg cc80FF\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY1]\r
+ jge cc80TT\r
+ jmp ClipQTop\r
+\r
+; Group 90 -------------------------------------------------\r
+;\r
+cc90TT:\r
+ clc\r
+ ret\r
+cc90FF:\r
+ stc\r
+ ret\r
+cc90:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY2]\r
+ jle cc90TT\r
+ jmp ClipPBottom\r
+cc92:\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY2]\r
+ jg cc90FF\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX1]\r
+ jge cc90TT\r
+ jmp ClipPLeft\r
+cc94:\r
+ call ClipQTop\r
+ cmp cx, [mx_ClipX1]\r
+ jl cc90FF\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY2]\r
+ jle cc90TT\r
+ jmp ClipPBottom\r
+cc96:\r
+ call ClipPLeft\r
+ cmp bx, [mx_ClipY1]\r
+ jl cc90FF\r
+ call ClipQRight\r
+ cmp si, [mx_ClipY2]\r
+ jg cc90FF\r
+ cmp bx, [mx_ClipY2]\r
+ jle cc96_1\r
+ call ClipPBottom\r
+cc96_1:\r
+ cmp si, [mx_ClipY1]\r
+ jge cc90TT\r
+ jmp ClipQTop\r
+\r
+; Group A0 -------------------------------------------------\r
+;\r
+ccA0TT:\r
+ clc\r
+ ret\r
+ccA0FF:\r
+ stc\r
+ ret\r
+ccA0:\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY2]\r
+ jle ccA0TT\r
+ jmp ClipPBottom\r
+ccA1:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY2]\r
+ jg ccA0FF\r
+ call ClipPBottom\r
+ cmp di, [mx_ClipX2]\r
+ jle ccA0TT\r
+ jmp ClipPRight\r
+ccA4:\r
+ call ClipQTop\r
+ cmp cx, [mx_ClipX2]\r
+ jg ccA0FF\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY2]\r
+ jle ccA0TT\r
+ jmp ClipPBottom\r
+ccA5:\r
+ call ClipQLeft\r
+ cmp si, [mx_ClipY2]\r
+ jg ccA0FF\r
+ call ClipPRight\r
+ cmp bx, [mx_ClipY1]\r
+ jl ccA0FF\r
+ cmp si, [mx_ClipY1]\r
+ jge ccA5_1\r
+ call ClipQTop\r
+ccA5_1:\r
+ cmp bx, [mx_ClipY2]\r
+ jle ccA0TT\r
+ jmp ClipPBottom\r
+\r
+; Y1 = (Y2-Y1)*(mx_ClipX1-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX1-DI)/(CX-DI)+BX\r
+; X1 = mx_ClipX1\r
+ClipPLeft:\r
+ mov ax, si\r
+ sub ax, bx\r
+ mov dx, [mx_ClipX1]\r
+ sub dx, di\r
+ imul dx\r
+ mov bp, cx\r
+ sub bp, di\r
+ idiv bp\r
+ add bx, ax\r
+ mov di, [mx_ClipX1]\r
+ clc\r
+ ret\r
+\r
+; Y1 = (Y2-Y1)*(mx_ClipX2-X1)/(X2-X1)+Y1 = (SI-BX)*(mx_ClipX2-DI)/(CX-DI)+BX\r
+; X1 = mx_ClipX2\r
+ClipPRight:\r
+ mov ax, si\r
+ sub ax, bx\r
+ mov dx, [mx_ClipX2]\r
+ sub dx, di\r
+ imul dx\r
+ mov bp, cx\r
+ sub bp, di\r
+ idiv bp\r
+ add bx, ax\r
+ mov di, [mx_ClipX2]\r
+ clc\r
+ ret\r
+\r
+; X1 = (X2-X1)*(mx_ClipY2-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY2-BX)/(SI-BX)+DI\r
+; Y1 = mx_ClipY2\r
+ClipPBottom:\r
+ mov ax, cx\r
+ sub ax, di\r
+ mov dx, [mx_ClipY2]\r
+ sub dx, bx\r
+ imul dx\r
+ mov bp, si\r
+ sub bp, bx\r
+ idiv bp\r
+ add di, ax\r
+ mov bx, [mx_ClipY2]\r
+ clc\r
+ ret\r
+\r
+; X1 = (X2-X1)*(mx_ClipY1-Y1)/(Y2-Y1)+X1 = (CX-DI)*(mx_ClipY1-BX)/(SI-BX)+DI\r
+; Y1 = mx_ClipY1\r
+ClipPTop:\r
+ mov ax, cx\r
+ sub ax, di\r
+ mov dx, [mx_ClipY1]\r
+ sub dx, bx\r
+ imul dx\r
+ mov bp, si\r
+ sub bp, bx\r
+ idiv bp\r
+ add di, ax\r
+ mov bx, [mx_ClipY1]\r
+ clc\r
+ ret\r
+\r
+; Y2 = (Y1-Y2)*(mx_ClipX1-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX1-CX)/(DI-CX)+SI\r
+; X2 = mx_ClipX1\r
+ClipQLeft:\r
+ mov ax, bx\r
+ sub ax, si\r
+ mov dx, [mx_ClipX1]\r
+ sub dx, cx\r
+ imul dx\r
+ mov bp, di\r
+ sub bp, cx\r
+ idiv bp\r
+ add si, ax\r
+ mov cx, [mx_ClipX1]\r
+ clc\r
+ ret\r
+\r
+; Y2 = (Y1-Y2)*(mx_ClipX2-X2)/(X1-X2)+Y2 = (BX-SI)*(mx_ClipX2-CX)/(DI-CX)+SI\r
+; X2 = mx_ClipX1\r
+ClipQRight:\r
+ mov ax, bx\r
+ sub ax, si\r
+ mov dx, [mx_ClipX2]\r
+ sub dx, cx\r
+ imul dx\r
+ mov bp, di\r
+ sub bp, cx\r
+ idiv bp\r
+ add si, ax\r
+ mov cx, [mx_ClipX2]\r
+ clc\r
+ ret\r
+\r
+; X2 = (X1-X2)*(mx_ClipY2-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY2-SI)/(BX-SI)+CX\r
+; Y2 = mx_ClipY1\r
+ClipQBottom:\r
+ mov ax, di\r
+ sub ax, cx\r
+ mov dx, [mx_ClipY2]\r
+ sub dx, si\r
+ imul dx\r
+ mov bp, bx\r
+ sub bp, si\r
+ idiv bp\r
+ add cx, ax\r
+ mov si, [mx_ClipY2]\r
+ clc\r
+ ret\r
+\r
+; X2 = (X1-X2)*(mx_ClipY1-Y2)/(Y1-Y2)+X2 = (DI-CX)*(mx_ClipY1-SI)/(BX-SI)+CX\r
+; Y2 = mx_ClipY1\r
+ClipQTop:\r
+ mov ax, di\r
+ sub ax, cx\r
+ mov dx, [mx_ClipY1]\r
+ sub dx, si\r
+ imul dx\r
+ mov bp, bx\r
+ sub bp, si\r
+ idiv bp\r
+ add cx, ax\r
+ mov si, [mx_ClipY1]\r
+ clc\r
+ ret\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Checks the coordinates of a line against the active\r
+; clip region.\r
+; Uses the Sobkow-Pospisil-Yang (SPY) algorithm: this was\r
+; supposed to be twice as fast as Cohen-Sutherland, but my\r
+; tests show only a very small increase in speed and a noticeable\r
+; increase of the program size! Maybe this is caused by the\r
+; slow speed of VGA cards, so probably a better test should\r
+; be performed with lines drawn in RAM.\r
+;\r
+; Input:\r
+; AX, BX = X1, Y1\r
+; CX, DX = X2, Y2\r
+; Output:\r
+; CF = set if line is full clipped\r
+; AX, BX = clipped X1, Y1\r
+; CX, DX = clipped X2, Y2\r
+; Note:\r
+; destroys SI, DI\r
+;\r
+xsubClipLine PROC NEAR\r
+ push bp\r
+ xor si, si ; SPY code\r
+\r
+ cmp dx, [mx_ClipY2]\r
+ jle @@1\r
+ or si, 08h\r
+ jmp @@2\r
+@@1:\r
+ cmp dx, [mx_ClipY1]\r
+ jge @@2\r
+ or si, 04h\r
+@@2:\r
+\r
+ cmp cx, [mx_ClipX2]\r
+ jle @@3\r
+ or si, 02h\r
+ jmp @@4\r
+@@3:\r
+ cmp cx, [mx_ClipX1]\r
+ jge @@4\r
+ or si, 01h\r
+@@4:\r
+\r
+ cmp bx, [mx_ClipY2]\r
+ jle @@5\r
+ or si, 80h\r
+ jmp @@6\r
+@@5:\r
+ cmp bx, [mx_ClipY1]\r
+ jge @@6\r
+ or si, 40h\r
+@@6:\r
+\r
+ cmp ax, [mx_ClipX2]\r
+ jle @@7\r
+ or si, 20h\r
+ jmp @@8\r
+@@7:\r
+ cmp ax, [mx_ClipX1]\r
+ jge @@8\r
+ or si, 10h\r
+@@8:\r
+\r
+ mov di, si\r
+ and di, 000Fh ; Index of procedure\r
+ and si, 00F0h\r
+ .shr si, 2 ; Index of group (times 4)\r
+ cmp di, cs:tblGroups[si] ; Is index within range?\r
+ jg @@Exit ; No, line is full clipped\r
+ mov si, cs:tblGroups[si+2] ; Get offset of group table\r
+ shl di, 1 ; We must index word elements\r
+ add si, di ; Make full offset\r
+ mov di, ax ; Move X1 to DI and free AX\r
+ mov si, cs:[si] ; Get subroutine address\r
+ xchg dx, si ; Move Y2 to SI and free DX\r
+ call dx ; Call the proper subroutine\r
+ mov ax, di ; Restore AX to X1\r
+ mov dx, si ; Restore DX to Y2\r
+ pop bp\r
+ ret\r
+\r
+@@Exit:\r
+ pop bp\r
+ stc\r
+ ret\r
+xsubClipLine ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r