; Bresenham Lines ; by Vince `deater` Weaver ; based on pseudo-code from ; https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm .include "zp.inc" .include "hardware.inc" ; 174 -- initial ; 170 -- inline init ; 166 -- inline step ; 161 -- merge absolute_value/negative code ; 159 -- merging init X/Y paths ; 156 -- more merging X/Y init ; 154 -- note PLOT doesn't touch Y ; 152 -- merge into common_inc ; 151 -- share an RTS ; 150 -- use X when plotting ; 148 -- re-arrange do abs (thanks to 42BS) B_X1 = $F0 B_Y1 = $F1 B_X2 = $F2 B_Y2 = $F3 B_DX = $F4 B_DY = $F5 B_SX = $F6 B_SY = $F7 B_ERR = $F8 COUNT = $F9 lines: jsr SETGR ; set lo-res 40x40 mode ; A=$D0 afterward restart: lda #0 sta COUNT lines_loop: jsr NEXTCOL lda #0 sta B_X1 lda #36 sta B_Y2 lda COUNT cmp #10 ;end: beq restart asl asl sta B_Y1 sta B_X2 jsr draw_line inc COUNT jmp lines_loop ;============================ ; draw line ; from x1,y1 to x2,y2 ;============================ draw_line: ; from wikipedia ; dx = abs(x2 - x1) ; sx = x1 < x2 ? 1 : -1 ; dy = -abs(y2 - y1) ; sy = y1 < y2 ? 1 : -1 ; err = dx+dy init_bresenham: ; dx = abs(x2-x1) ; sx = x1= dy: ; err = err + dy ; x1 = x1 + sx ; B_ERR already in A cmp B_DY ; check equal first beq do_x clc ; signed compare sbc B_DY bvc blah2 eor #$80 blah2: bmi skip_x ; ble do_x: lda B_DY jsr common_inc skip_x: inx ; setup common inc ; if err2 <= dx: ; err = err + dx ; y1 = y1 + sy pla ; restore err2 clc ; signed compare sbc B_DX bvc blah eor #$80 blah: bpl skip_y do_y: lda B_DX jsr common_inc skip_y: jmp line_loop ;===================================== ; common increment ;===================================== common_inc: clc adc B_ERR sta B_ERR lda B_X1,X clc adc B_SX,X sta B_X1,X done_line: rts ;===================================== ; init, do the abs and sx calculations ; x=0, for X ; x=1, for Y ;===================================== do_abs: ldy #$ff sec lda B_X1,X sbc B_X2,X ; A = x1 - x2 bpl is_pos ldy #$1 neg: eor #$ff clc adc #1 is_pos: sty B_SX,X sta B_DX,X rts