From: uz Date: Fri, 6 Nov 2009 15:26:46 +0000 (+0000) Subject: Added clipping for lines. X-Git-Tag: V2.13.1~77 X-Git-Url: https://git.sur5r.net/?p=cc65;a=commitdiff_plain;h=e12bd13e1616111e36acfc82be2f5e6430cce6da Added clipping for lines. git-svn-id: svn://svn.cc65.org/cc65/trunk@4452 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/libsrc/tgi/Makefile b/libsrc/tgi/Makefile index f0721b0ea..1e0dc2bf9 100644 --- a/libsrc/tgi/Makefile +++ b/libsrc/tgi/Makefile @@ -33,13 +33,13 @@ C_OBJS = tgi_arc.o \ tgi_load.o \ tgi_load_driver.o \ tgi_load_vectorfont.o \ - tgi_pieslice.o + tgi_pieslice.o S_OBJS = tgi-kernel.o \ tgi_bar.o \ tgi_circle.o \ tgi_clear.o \ - tgi_clipline.o \ + tgi_clippedline.o \ tgi_curtoxy.o \ tgi_done.o \ tgi_ellipse.o \ diff --git a/libsrc/tgi/tgi_clipline.s b/libsrc/tgi/tgi_clipline.s deleted file mode 100644 index 96ef5b860..000000000 --- a/libsrc/tgi/tgi_clipline.s +++ /dev/null @@ -1,494 +0,0 @@ -; -; Ullrich von Bassewitz, 2009-10-25 -; -; Clips the line in ptr1/ptr2/ptr3/ptr4 to the screen coordinates -; - - - .export _tgi_clipline - .export _tgi_clip_x1, _tgi_clip_y1, _tgi_clip_x2, _tgi_clip_y2 - .export _tgi_clip_o1, _tgi_clip_o2 ; Debugging! - .export _tgi_clip_dx, _tgi_clip_dy - .export _tgi_xmax, _tgi_ymax - - .import negax, pushax - .import imul16x16r32, idiv32by16r16 - .import return0, return1 - - .include "tgi-kernel.inc" - .include "zeropage.inc" - - .macpack longbranch - -.code - -;---------------------------------------------------------------------------- -; outcode constants. These aren't really used because most stuff is done by -; shifting the values, but they're here for documentation. - -CLIP_NONE = $00 -CLIP_LEFT = $01 -CLIP_RIGHT = $02 -CLIP_BOTTOM = $04 -CLIP_TOP = $08 - - - -;---------------------------------------------------------------------------- -; Generate a Cohen Sutherland outcode for tgi_clip_x1/tgi_clip_y1 in _tgi_clip_o1 -; -; void outcode1 () -; { -; _tgi_clip_o1 = 0; -; if (Y1 < 0) { -; _tgi_clip_o1 = CLIP_BOTTOM; -; } else if (Y1 >= yres) { -; _tgi_clip_o1 = CLIP_TOP; -; } -; if (X1 < 0) { -; _tgi_clip_o1 |= CLIP_LEFT; -; } else if (X1 >= xres) { -; _tgi_clip_o1 |= CLIP_RIGHT; -; } -; } - -.proc outcode1 - - ldy #CLIP_BOTTOM ; Assume line needs bottom clip - -; Check Y coordinate - - lda _tgi_clip_y1+1 ; High byte of Y1 - bmi L2 ; Jump if bottom clip - - ldy #CLIP_TOP ; Assume line needs top clip - ldx _tgi_clip_y1 ; Low byte of Y1 - cpx _tgi_yres - sbc _tgi_yres+1 - bvs L1 - eor #$80 -L1: bmi L2 - - ldy #CLIP_NONE ; No clipping actually - -L2: sty _tgi_clip_o1 - - -; Check X coordinate - - ldy #CLIP_LEFT ; Assume line needs left clip - - lda _tgi_clip_x1+1 ; High byte of X1 - bmi L4 ; Jump if left clip - - ldy #CLIP_RIGHT ; Assume line needs right clip - - ldx _tgi_clip_x1 ; Low byte of X1 - cpx _tgi_xres - sbc _tgi_xres+1 - bvs L3 - eor #$80 -L3: bmi L4 - - ldy #CLIP_NONE ; No clipping actually - -L4: tya - ora _tgi_clip_o1 - sta _tgi_clip_o1 - - rts - -.endproc - - -;---------------------------------------------------------------------------- -; Generate a Cohen Sutherland outcode for tgi_clip_x2/tgi_clip_y2 in _tgi_clip_o2 -; -; void outcode2 () -; { -; _tgi_clip_o2 = 0; -; if (Y2 < 0) { -; _tgi_clip_o2 = CLIP_BOTTOM; -; } else if (Y2 >= yres) { -; _tgi_clip_o2 = CLIP_TOP; -; } -; if (X2 < 0) { -; _tgi_clip_o2 |= CLIP_LEFT; -; } else if (X2 >= xres) { -; _tgi_clip_o2 |= CLIP_RIGHT; -; } -; } - -.proc outcode2 - - ldy #CLIP_BOTTOM ; Assume line needs bottom clip - -; Check Y coordinate - - lda _tgi_clip_y2+1 ; High byte of Y2 - bmi L2 ; Jump if bottom clip - - ldy #CLIP_TOP ; Assume line needs top clip - ldx _tgi_clip_y2 ; Low byte of Y4 - cpx _tgi_yres - sbc _tgi_yres+1 - bvs L1 - eor #$80 -L1: bmi L2 - - ldy #CLIP_NONE ; No clipping actually - -L2: sty _tgi_clip_o2 - - -; Check X coordinate - - ldy #CLIP_LEFT ; Assume line needs left clip - - lda _tgi_clip_x2+1 ; High byte of X2 - bmi L4 ; Jump if left clip - - ldy #CLIP_RIGHT ; Assume line needs right clip - - ldx _tgi_clip_x2 ; Low byte of X2 - cpx _tgi_xres - sbc _tgi_xres+1 - bvs L3 - eor #$80 -L3: bmi L4 - - ldy #CLIP_NONE ; No clipping actually - -L4: tya - ora _tgi_clip_o2 - sta _tgi_clip_o2 - - rts - -.endproc - - - -;---------------------------------------------------------------------------- -; Calculate dx and dy -; - -.proc calcdeltas - - lda _tgi_clip_x2 - sec - sbc _tgi_clip_x1 - sta _tgi_clip_dx - lda _tgi_clip_x2+1 - sbc _tgi_clip_x1+1 - sta _tgi_clip_dx+1 - - lda _tgi_clip_y2 - sec - sbc _tgi_clip_y1 - sta _tgi_clip_dy - lda _tgi_clip_y2+1 - sbc _tgi_clip_y1+1 - sta _tgi_clip_dy+1 - - rts - -.endproc - - - -;---------------------------------------------------------------------------- -; Multiplicate value in y/a by dy, then divide by dx. -; - -.proc muldiv_dydx - - sty ptr1 ; lhs - sta ptr1+1 - lda _tgi_clip_dy - ldx _tgi_clip_dy+1 ; rhs - jsr imul16x16r32 ; Multiplicate - -; Move the result of the multiplication into ptr1:ptr2 - - sta ptr1 - stx ptr1+1 - ldy sreg - sty ptr2 - ldy sreg+1 - sty ptr2+1 - -; Load divisor and divide - - lda _tgi_clip_dx - ldx _tgi_clip_dx+1 - jmp idiv32by16r16 - -.endproc - - - -;---------------------------------------------------------------------------- -; Multiplicate value in y/a by dx, then divide by dy. -; - -.proc muldiv_dxdy - - sty ptr1 ; lhs - sta ptr1+1 - lda _tgi_clip_dx - ldx _tgi_clip_dx+1 ; rhs - jsr imul16x16r32 ; Multiplicate - -; Move the result of the multiplication into ptr1:ptr2 - - sta ptr1 - stx ptr1+1 - ldy sreg - sty ptr2 - ldy sreg+1 - sty ptr2+1 - -; Load divisor and divide - - lda _tgi_clip_dy - ldx _tgi_clip_dy+1 - jmp idiv32by16r16 - -.endproc - - - -;---------------------------------------------------------------------------- -; Clip a line using Cohen Sutherland -; - -.proc _tgi_clipline - -; Generate outcodes - - jsr outcode1 - jsr outcode2 - jsr calcdeltas - -; if ((_tgi_clip_o1 | _tgi_clip_o2) == 0) accept; - -Loop: lda _tgi_clip_o1 - ora _tgi_clip_o2 - bne L1 - jmp return0 - -; if ((_tgi_clip_o1 & _tgi_clip_o2) != 0) reject; - -L1: lda _tgi_clip_o1 - and _tgi_clip_o2 - beq L2 - jmp return1 - -; Check if X1/Y1 needs clipping - -L2: lda _tgi_clip_o1 - jeq L10 - -; Need to clip X1/Y1 - - lsr a ; Check for CLIP_LEFT - bcc L3 - -; tgi_clip_y1 += (0 - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx; -; tgi_clip_x1 = 0; - - lda #$00 - tax - beq L4 - -L3: lsr a ; Check for CLIP_RIGHT - bcc L5 - -; tgi_clip_y1 += (tgi_xmax - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx; -; tgi_clip_x1 = tgi_xmax; - - lda _tgi_xmax - ldx _tgi_xmax+1 - -L4: tay - sec - sbc _tgi_clip_x1 - sty _tgi_clip_x1 - tay - txa - sbc _tgi_clip_x1+1 - stx _tgi_clip_x1+1 - - jsr muldiv_dydx - - clc - adc _tgi_clip_y1 - sta _tgi_clip_y1 - txa - adc _tgi_clip_y1+1 - sta _tgi_clip_y1+1 - -; - - lda _tgi_clip_o1 - lsr a - lsr a -L5: lsr a ; Check for CLIP_BOTTOM - bcc L6 - -; tgi_clip_x1 = (0 - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy; -; tgi_clip_y1 = 0; - - lda #$00 - tax - beq L7 - -L6: lsr a ; Check for CLIP_TOP - bcc L8 - -; tgi_clip_x1 += (tgi_ymax - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy; -; tgi_clip_y1 = ymax; - - lda _tgi_ymax - ldx _tgi_ymax+1 - -L7: tay - sec - sbc _tgi_clip_y1 - sty _tgi_clip_y1 - tay - txa - sbc _tgi_clip_y1+1 - stx _tgi_clip_y1+1 - - jsr muldiv_dxdy - - clc - adc _tgi_clip_x1 - sta _tgi_clip_x1 - txa - adc _tgi_clip_x1+1 - sta _tgi_clip_x1+1 - -; We need to recalculate outcode1 in this case - -L8: jsr outcode1 - -; Check if X2/Y2 needs clipping - -L10: lda _tgi_clip_o2 - jeq Loop - -; Need to clip X2/Y2 - - lsr a ; Check for CLIP_LEFT - bcc L11 - -; tgi_clip_y2 += (0 - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx; -; tgi_clip_x2 = 0; - - lda #$00 - tax - beq L12 - -L11: lsr a ; Check for CLIP_RIGHT - bcc L13 - -; tgi_clip_y2 += (tgi_xmax - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx; -; tgi_clip_x2 = tgi_xmax; - - lda _tgi_xmax - ldx _tgi_xmax+1 - -L12: tay - sec - sbc _tgi_clip_x2 - sty _tgi_clip_x2 - tay - txa - sbc _tgi_clip_x2+1 - stx _tgi_clip_x2+1 - - jsr muldiv_dydx - - clc - adc _tgi_clip_y2 - sta _tgi_clip_y2 - txa - adc _tgi_clip_y2+1 - sta _tgi_clip_y2+1 - -; - - lda _tgi_clip_o2 - lsr a - lsr a -L13: lsr a ; Check for CLIP_BOTTOM - bcc L14 - -; tgi_clip_x2 += (0 - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy; -; tgi_clip_y2 = 0; - - lda #$00 - tax - beq L15 - -L14: lsr a ; Check for CLIP_TOP - bcc L16 - -; tgi_clip_x2 += (tgi_ymax - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy; -; tgi_clip_y2 = tgi_ymax; - - lda _tgi_ymax - ldx _tgi_ymax+1 - -L15: tay - sec - sbc _tgi_clip_y2 - sty _tgi_clip_y2 - tay - txa - sbc _tgi_clip_y2+1 - stx _tgi_clip_y2+1 - - jsr muldiv_dxdy - - clc - adc _tgi_clip_x2 - sta _tgi_clip_x2 - txa - adc _tgi_clip_x2+1 - sta _tgi_clip_x2+1 - -; We need to recalculate outcode2 in this case - -L16: jsr outcode2 - -; Try again - - jmp Loop - -.endproc - - - - -;---------------------------------------------------------------------------- -; Data - -.bss - -_tgi_clip_x1: .res 2 -_tgi_clip_y1: .res 2 -_tgi_clip_x2: .res 2 -_tgi_clip_y2: .res 2 - -_tgi_clip_o1: .res 1 -_tgi_clip_o2: .res 1 - -_tgi_clip_dx: .res 2 -_tgi_clip_dy: .res 2 - -_tgi_xmax: .res 2 -_tgi_ymax: .res 2 diff --git a/libsrc/tgi/tgi_clippedline.s b/libsrc/tgi/tgi_clippedline.s new file mode 100644 index 000000000..c4085c019 --- /dev/null +++ b/libsrc/tgi/tgi_clippedline.s @@ -0,0 +1,565 @@ +; +; Ullrich von Bassewitz, 2009-10-25 +; +; Clips line coordinates to the screen coordinates and calls tgi_line +; + + + .import umul16x16r32, udiv32by16r16 + .import negax + + .include "tgi-kernel.inc" + .include "zeropage.inc" + + .macpack longbranch + +;---------------------------------------------------------------------------- +; Data + +.bss + +; Line coordinates. Must be set before calling tgi_clippedline +tgi_clip_x1: .res 2 +tgi_clip_y1: .res 2 +tgi_clip_x2: .res 2 +tgi_clip_y2: .res 2 + +tgi_clip_o1: .res 1 +tgi_clip_o2: .res 1 + +tgi_clip_d: .res 1 +tgi_clip_dx: .res 2 +tgi_clip_dy: .res 2 + +tgi_clip_sign: .res 1 + + +;---------------------------------------------------------------------------- +; outcode constants. + +CLIP_NONE = $00 +CLIP_LEFT = $01 +CLIP_RIGHT = $02 +CLIP_BOTTOM = $04 +CLIP_TOP = $08 + + + +;---------------------------------------------------------------------------- +; Generate a Cohen Sutherland outcode +; +; void outcode () +; { +; unsigned char o = 0; +; if (Y < 0) { +; o = CLIP_BOTTOM; +; } else if (Y >= yres) { +; o = CLIP_TOP; +; } +; if (X < 0) { +; o |= CLIP_LEFT; +; } else if (X >= xres) { +; o |= CLIP_RIGHT; +; } +; return o; +; } + +.code +.proc outcode + + lda #CLIP_NONE + sta tmp1 + +; Check Y coordinate + + lda tgi_clip_y1+1,y ; High byte of Y1 + bmi L2 ; Jump if bottom clip + + ldx tgi_clip_y1,y ; Low byte of Y1 + cpx _tgi_yres + sbc _tgi_yres+1 + bvs L1 + eor #$80 +L1: bpl L4 + lda #CLIP_TOP ; Top clipping necessary + bne L3 +L2: lda #CLIP_BOTTOM +L3: sta tmp1 ; Save temp outcode + + +; Check X coordinate + +L4: lda tgi_clip_x1+1,y ; High byte of X1 + bmi L7 ; Jump if left clip + + ldx tgi_clip_x1,y ; Low byte of X1 + cpx _tgi_xres + sbc _tgi_xres+1 + bvs L5 + eor #$80 +L5: bmi L6 + +; No right or left clipping necessary + + lda tmp1 + rts + +; Need right clipping + +L6: lda #CLIP_RIGHT + ora tmp1 + rts + +; Need left clipping + +L7: lda #CLIP_LEFT + ora tmp1 + rts + +.endproc + + +;---------------------------------------------------------------------------- +; Calculate outcodes for both ends of the line +; + +.code +.proc outcode1 + + ldy #0 + jsr outcode + sta tgi_clip_o1 + rts + +.endproc + +.code +.proc outcode2 + + ldy #(tgi_clip_y2 - tgi_clip_y1) + jsr outcode + sta tgi_clip_o2 + rts + +.endproc + + +;---------------------------------------------------------------------------- +; Negate tgi_clip_dxy +; + +.code +.proc negate + + lda tgi_clip_dx,y + eor #$FF + clc + adc #1 + sta tgi_clip_dx,y + lda tgi_clip_dx+1,y + eor #$FF + adc #$00 + sta tgi_clip_dx+1,y + rts + +.endproc + + +;---------------------------------------------------------------------------- +; Calculate the absolute values of dx and dy and store the combined sign in +; tgi_clip_sign +; + +.code +.proc calcdeltas + + lda tgi_clip_x2 + sec + sbc tgi_clip_x1 + sta tgi_clip_dx + lda tgi_clip_x2+1 + sbc tgi_clip_x1+1 + sta tgi_clip_dx+1 + sta tgi_clip_sign + bpl @L1 + ldy #0 + jsr negate + +@L1: lda tgi_clip_y2 + sec + sbc tgi_clip_y1 + sta tgi_clip_dy + lda tgi_clip_y2+1 + sbc tgi_clip_y1+1 + sta tgi_clip_dy+1 + + eor tgi_clip_sign + sta tgi_clip_sign + + bit tgi_clip_dy+1 + bpl @L9 + + ldy #(tgi_clip_dy - tgi_clip_dx) + jmp negate + +@L9: rts + +.endproc + + +;---------------------------------------------------------------------------- +; Helper routine. Generate the absolute value of y/a and calculate the sign +; of the final result +; + +.code +.proc prepare_coord + + tax ; Remember high byte + eor tgi_clip_sign + sta tmp1 ; Sign of result + tya + cpx #0 ; Check sign + bpl @L1 + jsr negax +@L1: sta ptr1 + stx ptr1+1 + rts + +.endproc + + +;---------------------------------------------------------------------------- +; Helper routine. Move the value in eax to ptr1:ptr2 +; + +.code +.proc move_intermediate_result + + sta ptr1 + stx ptr1+1 + ldy sreg + sty ptr2 + ldy sreg+1 + sty ptr2+1 + rts + +.endproc + + +;---------------------------------------------------------------------------- +; Multiplicate value in y/a by dy, then divide by dx. +; + +.code +.proc muldiv_dydx + +; Generate the absolute value of y/a and calculate the sign of the final +; result + + jsr prepare_coord + +; All values are positive now (dx/dy have been made positive in calcdeltas) +; and the sign of the final result is on tmp1, so we can use unsigned +; operations and apply the final result later, after rounding. + + lda tgi_clip_dy + ldx tgi_clip_dy+1 ; rhs + jsr umul16x16r32 ; Multiplicate + +; Move the result of the multiplication into ptr1:ptr2 + + jsr move_intermediate_result + +; Load divisor and divide + + lda tgi_clip_dx + ldx tgi_clip_dx+1 + jsr udiv32by16r16 + +; Check the sign of the final result and negate it if nessary + +done: bit tmp1 + jmi negax + rts + +.endproc + + + +;---------------------------------------------------------------------------- +; Multiplicate value in y/a by dx, then divide by dy. +; + +.code +.proc muldiv_dxdy + +; Generate the absolute value of y/a and calculate the sign of the final +; result + + jsr prepare_coord + +; All values are positive now (dx/dy have been made positive in calcdeltas) +; and the sign of the final result is on tmp1, so we can use unsigned +; operations and apply the final result later, after rounding. + + lda tgi_clip_dx + ldx tgi_clip_dx+1 ; rhs + jsr umul16x16r32 ; Multiplicate + +; Move the result of the multiplication into ptr1:ptr2 + + jsr move_intermediate_result + +; Load divisor and divide + + lda tgi_clip_dy + ldx tgi_clip_dy+1 + jsr udiv32by16r16 + +; Check the sign of the final result and negate it if nessary + + jmp muldiv_dydx::done + +.endproc + + + +;---------------------------------------------------------------------------- +; Clip a line using Cohen Sutherland +; + +.code +.proc tgi_clippedline + +; Set a flag that we have no deltas calculated + + lda #0 + sta tgi_clip_d + +; Generate outcodes + + jsr outcode1 + jsr outcode2 + +; if ((tgi_clip_o1 | tgi_clip_o2) == 0) { +; tgi_line (x1, y1, x2, y2); +; } + +Loop: lda tgi_clip_o1 + ora tgi_clip_o2 + bne L1 + +; Copy the coordinates into ptr1-4 and draw the line + + ldx #7 +L0: lda tgi_clip_x1,x + sta ptr1,x + dex + bpl L0 + jmp tgi_line + +; if ((tgi_clip_o1 & tgi_clip_o2) != 0) reject; + +L1: lda tgi_clip_o1 + and tgi_clip_o2 + beq L2 + rts ; Nothing to draw + +; We must clip. If we haven't already done so, calculate dx/dy. + +L2: lda tgi_clip_d ; Deltas alreay calculated? + bne HaveDeltas ; Jump if yes + inc tgi_clip_d + jsr calcdeltas + +; Check if X1/Y1 needs clipping + +HaveDeltas: + lda tgi_clip_o1 + jeq L10 + +; Need to clip X1/Y1 + + lsr a ; Check for CLIP_LEFT + bcc L3 + +; tgi_clip_y1 += (0 - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx; +; tgi_clip_x1 = 0; + + lda #$00 + tax + beq L4 + +L3: lsr a ; Check for CLIP_RIGHT + bcc L5 + +; tgi_clip_y1 += (tgi_xmax - tgi_clip_x1) * tgi_clip_dy / tgi_clip_dx; +; tgi_clip_x1 = tgi_xmax; + + lda _tgi_xmax + ldx _tgi_xmax+1 + +L4: tay + sec + sbc tgi_clip_x1 + sty tgi_clip_x1 + tay + txa + sbc tgi_clip_x1+1 + stx tgi_clip_x1+1 + + jsr muldiv_dydx + + clc + adc tgi_clip_y1 + sta tgi_clip_y1 + txa + adc tgi_clip_y1+1 + sta tgi_clip_y1+1 + +; + + lda tgi_clip_o1 + lsr a + lsr a +L5: lsr a ; Check for CLIP_BOTTOM + bcc L6 + +; tgi_clip_x1 = (0 - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy; +; tgi_clip_y1 = 0; + + lda #$00 + tax + beq L7 + +L6: lsr a ; Check for CLIP_TOP + bcc L8 + +; tgi_clip_x1 += (tgi_ymax - tgi_clip_y1) * tgi_clip_dx / tgi_clip_dy; +; tgi_clip_y1 = ymax; + + lda _tgi_ymax + ldx _tgi_ymax+1 + +L7: tay + sec + sbc tgi_clip_y1 + sty tgi_clip_y1 + tay + txa + sbc tgi_clip_y1+1 + stx tgi_clip_y1+1 + + jsr muldiv_dxdy + + clc + adc tgi_clip_x1 + sta tgi_clip_x1 + txa + adc tgi_clip_x1+1 + sta tgi_clip_x1+1 + +; We need to recalculate outcode1 in this case + +L8: jsr outcode1 + +; Check if X2/Y2 needs clipping + +L10: lda tgi_clip_o2 + jeq Loop + +; Need to clip X2/Y2 + + lsr a ; Check for CLIP_LEFT + bcc L11 + +; tgi_clip_y2 += (0 - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx; +; tgi_clip_x2 = 0; + + lda #$00 + tax + beq L12 + +L11: lsr a ; Check for CLIP_RIGHT + bcc L13 + +; tgi_clip_y2 += (tgi_xmax - tgi_clip_x2) * tgi_clip_dy / tgi_clip_dx; +; tgi_clip_x2 = tgi_xmax; + + lda _tgi_xmax + ldx _tgi_xmax+1 + +L12: tay + sec + sbc tgi_clip_x2 + sty tgi_clip_x2 + tay + txa + sbc tgi_clip_x2+1 + stx tgi_clip_x2+1 + + jsr muldiv_dydx + + clc + adc tgi_clip_y2 + sta tgi_clip_y2 + txa + adc tgi_clip_y2+1 + sta tgi_clip_y2+1 + +; + + lda tgi_clip_o2 + lsr a + lsr a +L13: lsr a ; Check for CLIP_BOTTOM + bcc L14 + +; tgi_clip_x2 += (0 - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy; +; tgi_clip_y2 = 0; + + lda #$00 + tax + beq L15 + +L14: lsr a ; Check for CLIP_TOP + bcc L16 + +; tgi_clip_x2 += (tgi_ymax - tgi_clip_y2) * tgi_clip_dx / tgi_clip_dy; +; tgi_clip_y2 = tgi_ymax; + + lda _tgi_ymax + ldx _tgi_ymax+1 + +L15: tay + sec + sbc tgi_clip_y2 + sty tgi_clip_y2 + tay + txa + sbc tgi_clip_y2+1 + stx tgi_clip_y2+1 + + jsr muldiv_dxdy + + clc + adc tgi_clip_x2 + sta tgi_clip_x2 + txa + adc tgi_clip_x2+1 + sta tgi_clip_x2+1 + +; We need to recalculate outcode2 in this case + +L16: jsr outcode2 + +; Try again + + jmp Loop + +.endproc + + + + diff --git a/libsrc/tgi/tgi_line.s b/libsrc/tgi/tgi_line.s index d895dc533..36f63c8ff 100644 --- a/libsrc/tgi/tgi_line.s +++ b/libsrc/tgi/tgi_line.s @@ -11,10 +11,14 @@ .proc _tgi_line - jsr tgi_linepop ; Pop/store Y2/X2 - jsr popax - jsr tgi_popxy ; Pop/store X1/Y1 into ptr1/ptr2 - jmp tgi_line ; Call the driver + jsr tgi_linepop ; Pop/store Y2/X2 + jsr popax ; Y1 + sta tgi_clip_y1 + stx tgi_clip_y1+1 + jsr popax ; X1 + sta tgi_clip_x1 + stx tgi_clip_x1+1 + jmp tgi_clippedline ; Call the line clipper .endproc diff --git a/libsrc/tgi/tgi_linepop.s b/libsrc/tgi/tgi_linepop.s index 8cc3dff89..bbd147c99 100644 --- a/libsrc/tgi/tgi_linepop.s +++ b/libsrc/tgi/tgi_linepop.s @@ -7,17 +7,18 @@ .include "tgi-kernel.inc" .import popax - .importzp ptr3, ptr4 .proc tgi_linepop - sta ptr4 ; Y2 - stx ptr4+1 + sta tgi_clip_y2 ; Y2 + stx tgi_clip_y2+1 sta _tgi_cury stx _tgi_cury+1 + jsr popax - sta ptr3 ; X2 - stx ptr3+1 + + sta tgi_clip_x2 ; X2 + stx tgi_clip_x2+1 sta _tgi_curx stx _tgi_curx+1 rts diff --git a/libsrc/tgi/tgi_lineto.s b/libsrc/tgi/tgi_lineto.s index 2cf4a9a1d..868f4cf42 100644 --- a/libsrc/tgi/tgi_lineto.s +++ b/libsrc/tgi/tgi_lineto.s @@ -12,9 +12,15 @@ .proc _tgi_lineto - jsr tgi_curtoxy ; Copy curx/cury into ptr1/ptr2 - jsr tgi_linepop ; Pop x2/y2 into ptr3/ptr4 and curx/cury - jmp tgi_line ; Call the driver + pha + ldy #3 ; Copy curx/cury to tgi_clip_x1/tgi_clip_y1 +@L1: lda _tgi_curx,y + sta tgi_clip_x1,y + dey + bpl @L1 + pla + jsr tgi_linepop ; Pop x2/y2 + jmp tgi_clippedline ; Call the line clipper .endproc