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 \
+++ /dev/null
-;
-; 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
--- /dev/null
+;
+; 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
+
+
+
+
.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
.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
.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