Created
May 15, 2019 21:33
-
-
Save BalorPrice/bccdfdcc55a59e0bdbe8c9c2b50892ca to your computer and use it in GitHub Desktop.
Bresenham line drawing example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; BRESENHAM LINE DRAWING | |
; This assumes MODE 4 (SAM coupé) with screen in 0-24575. | |
;------------------------------------------- | |
line.plotHLC: | |
; Plot a point at (L,H) with colour C (0-15 only) | |
ex af,af' | |
push bc | |
push hl | |
@find_scr_address: | |
srl h | |
rr l | |
@plot_right: | |
ld b,&f0 ; Assume plotting right nibble | |
jp c,@+do_plot ; If not carried, prepare plotting left nibble | |
@plot_left: | |
ld b,&0f | |
for 4, sla c | |
@do_plot: | |
ld a,(hl) ; Get background | |
and b ; mask nibble | |
or c ; set colour | |
ld (hl),a ; plot | |
pop hl | |
pop bc | |
ex af,af' | |
ret | |
line.plotHLDEC: | |
; Plot a point at (D.E,H.L) with colour C (0-15 only) | |
ex af,af' | |
push bc | |
push de | |
push hl | |
@round: ; Round up/down H and L to natural coordinates | |
ld b,0 | |
ld a,h | |
rl l | |
adc b | |
ld h,a | |
ld a,d | |
rl e | |
adc b | |
ld l,a | |
@find_scrn_addr: | |
srl h | |
rr l | |
@plot_right: | |
ld b,&f0 | |
jp c,@+do_plot | |
@plot_left: | |
ld b,&0f | |
for 4,sla c | |
@do_plot: | |
ld a,(hl) | |
and b | |
or c | |
ld (hl),a | |
pop hl | |
pop de | |
pop bc | |
ex af,af' | |
ret | |
;------------------------------------------------- | |
line.drawDEBCA: | |
; Make Bresenham line drawer to plot from (E,D) to (C,B), colour A | |
push bc | |
push de | |
push hl | |
ld (@+h_colour+1),a | |
ld (@+v_colour+1),a | |
ex de,hl | |
@test_plot_vert: ; Test if line is more vertical or horizontal | |
ld a,c | |
sub l | |
jp nc,@+skip | |
neg | |
@skip: | |
ld e,a | |
ld a,b | |
sub h | |
jp nc,@+skip | |
neg | |
@skip: | |
sub e | |
jp c,@+plot_horiz | |
@plot_vert: ; Line is <=45 degrees from vertical | |
@test_order: ; HL should be top if mostly vertical line | |
ld a,b | |
sub h | |
jp nc,@+get_dx | |
@swap_HL_BC: | |
ld a,h | |
ld h,b | |
ld b,a | |
ld a,l | |
ld l,c | |
ld c,a | |
@get_dx: ; Get difference in X movement per line moved | |
ld a,c | |
sub l | |
jp nc,@move_right ; If -ve result, move left after overflows | |
@move_left: | |
neg | |
ld e,a | |
ld a,dec_l ; change code to move left when going down screen | |
ld (@+move_pix),a | |
jp @+get_dy | |
@move_right: ; If +ve, set to move right on overflows. | |
ld e,a | |
ld a,inc_l | |
ld (@+move_pix),a | |
@get_dy: | |
ld a,b ; Get difference in Y movement to test for | |
sub h | |
ld d,a | |
ld b,a ; Get loop counter | |
inc b | |
@v_colour: ld c,yellow | |
srl a ; Halve dy for starting point | |
@plot_loop: | |
@plot_pix: | |
call line.plotHLC ; Plot this position | |
@upd_pos: | |
add e ; Update dx and test for over dy | |
cp d | |
jp m,@+next_line | |
@carry_pixel: ; If over threshold, move pixel along and update dx | |
sub d | |
@move_pix: inc l | |
@next_line: | |
inc h | |
djnz @-plot_loop | |
pop hl | |
pop de | |
pop bc | |
ret | |
@plot_horiz: ; Line is <=45 degrees from horiztonal | |
@test_order: ; HL should be left if mostly horizontal line | |
ld a,c | |
sub l | |
jp nc,@+get_dy | |
@swap_HL_BC: | |
ld a,h | |
ld h,b | |
ld b,a | |
ld a,l | |
ld l,c | |
ld c,a | |
@get_dy: ; Get difference in y movement per pixel column moved | |
ld a,b | |
sub h | |
jp nc,@+move_up ; If -ve result, move up after overflows | |
@move_down: | |
neg | |
ld e,a | |
ld a,dec_h ; change code to move left when going down screen | |
ld (@+move_pix),a | |
jp @+get_dx | |
@move_up: ; If +ve, set to move right on overflows. | |
ld e,a | |
ld a,inc_h | |
ld (@+move_pix),a | |
@get_dx: | |
ld a,c ; Get difference in X movement to test for | |
sub l | |
ld d,a | |
ld b,a ; Get loop counter | |
inc b | |
@h_colour: ld c,yellow | |
srl a ; Halve dx for starting point | |
@plot_loop: | |
@plot_pix: | |
call line.plotHLC ; Plot this position | |
@upd_pos: | |
add e ; Update dx and test for over dy | |
cp d | |
jp m,@+next_line | |
@carry_pixel: ; If over threshold, move pixel along and update dx | |
sub d | |
@move_pix: inc h | |
@next_line: | |
inc l | |
djnz @-plot_loop | |
pop hl | |
pop de | |
pop bc | |
ret | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment