added rect functions

This commit is contained in:
Irmen de Jong 2020-12-30 00:14:35 +01:00
parent df6698c98f
commit ee12236d53
3 changed files with 53 additions and 27 deletions

View File

@ -31,7 +31,6 @@ graphics {
txt.fill_screen(pixelcolor << 4 | bgcolor, 0) txt.fill_screen(pixelcolor << 4 | bgcolor, 0)
} }
; TODO optimize if horizontal or vertical:
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) { sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
; Bresenham algorithm. ; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations. ; This code special-cases various quadrant loops to allow simple ++ and -- operations.
@ -41,10 +40,22 @@ graphics {
swap(x1, x2) swap(x1, x2)
swap(y1, y2) swap(y1, y2)
} }
word @zp d = 0
ubyte positive_ix = true
word @zp dx = x2-x1 as word word @zp dx = x2-x1 as word
word @zp dy = y2-y1 word @zp dy = y2-y1
if dx==0 {
vertical_line(x1, y1, abs(dy)+1 as ubyte)
return
}
if dy==0 {
if x1>x2
x1=x2
horizontal_line(x1, y1, abs(dx)+1 as uword)
return
}
word @zp d = 0
ubyte positive_ix = true
if dx < 0 { if dx < 0 {
dx = -dx dx = -dx
positive_ix = false positive_ix = false
@ -109,18 +120,33 @@ graphics {
} }
} }
sub fillrect(uword x, uword y, uword width, uword height) { sub rect(uword x, ubyte y, uword width, ubyte height) {
; TODO cx16.GRAPH_draw_rect(x, y, width, height, 0, 1) if width==0 or height==0
return
horizontal_line(x, y, width)
if height==1
return
horizontal_line(x, y+height-1, width)
vertical_line(x, y+1, height-2)
if width==1
return
vertical_line(x+width-1, y+1, height-2)
} }
sub rect(uword x, uword y, uword width, uword height) { sub fillrect(uword x, ubyte y, uword width, ubyte height) {
; TODO cx16.GRAPH_draw_rect(x, y, width, height, 0, 0) if width==0
return
repeat height {
horizontal_line(x, y, width)
y++
}
} }
sub horizontal_line(uword x, ubyte y, uword length) { sub horizontal_line(uword x, ubyte y, uword length) {
if not length if not length
return return
; TODO optimized drawing 8 pixels at a time (+edges) should use get_y_lookup(y) in this
internal_plotx = x internal_plotx = x
repeat length { repeat length {
internal_plot(y) internal_plot(y)
@ -129,9 +155,6 @@ graphics {
} }
sub vertical_line(uword x, ubyte y, ubyte height) { sub vertical_line(uword x, ubyte y, ubyte height) {
if not height
return
internal_plotx = x internal_plotx = x
repeat height { repeat height {
internal_plot(y) internal_plot(y)
@ -186,23 +209,10 @@ graphics {
word decisionOver2 = (1 as word)-radius word decisionOver2 = (1 as word)-radius
while radius>=yy { while radius>=yy {
ubyte ycenter_plus_yy = ycenter + yy horizontal_line(xcenter-radius, ycenter+yy, radius*2+1)
ubyte ycenter_min_yy = ycenter - yy horizontal_line(xcenter-radius, ycenter-yy, radius*2+1)
ubyte ycenter_plus_radius = ycenter + radius horizontal_line(xcenter-yy, ycenter+radius, yy*2+1)
ubyte ycenter_min_radius = ycenter - radius horizontal_line(xcenter-yy, ycenter-radius, yy*2+1)
internal_plotx = xcenter-radius
repeat radius*2+1 {
internal_plot(ycenter_plus_yy)
internal_plot(ycenter_min_yy)
internal_plotx++
}
internal_plotx = xcenter-yy
repeat yy*2+1 {
internal_plot(ycenter_plus_radius)
internal_plot(ycenter_min_radius)
internal_plotx++
}
yy++ yy++
if decisionOver2<=0 if decisionOver2<=0
decisionOver2 += (yy as word)*2+1 decisionOver2 += (yy as word)*2+1
@ -277,6 +287,17 @@ _y_lookup_hi .byte >_plot_y_values
}} }}
} }
asmsub get_y_lookup(ubyte y @Y) -> uword @AY {
%asm {{
lda _y_lookup_lo,y
pha
lda _y_lookup_hi,y
tay
pla
rts
}}
}
} }

View File

@ -546,6 +546,7 @@ _done
}} }}
} }
; TODO CLOBBERS
asmsub next_pixels(uword pixels @AY, uword amount @R0) { asmsub next_pixels(uword pixels @AY, uword amount @R0) {
; -- sets the next bunch of pixels from a prepared array of bytes. ; -- sets the next bunch of pixels from a prepared array of bytes.
; for 8 bpp screens this will plot 1 pixel per byte. ; for 8 bpp screens this will plot 1 pixel per byte.
@ -577,6 +578,7 @@ _done
}} }}
} }
; TODO CLOBBERS
asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) { asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) {
; this is only useful in 256 color mode where one pixel equals one byte value. ; this is only useful in 256 color mode where one pixel equals one byte value.
%asm {{ %asm {{
@ -692,6 +694,7 @@ _done
} }
} }
; TODO CLOBBERS
asmsub cs_innerloop640() { asmsub cs_innerloop640() {
%asm {{ %asm {{
ldy #80 ldy #80
@ -709,6 +712,7 @@ _done
}} }}
} }
; TODO CLOBBERS
asmsub addr_mul_320_add_24(uword address @R0, uword value @AY) -> uword @R0, ubyte @R1 { asmsub addr_mul_320_add_24(uword address @R0, uword value @AY) -> uword @R0, ubyte @R1 {
%asm {{ %asm {{
sta P8ZP_SCRATCH_W1 sta P8ZP_SCRATCH_W1

View File

@ -128,6 +128,7 @@ graphics {
} }
} }
; TODO CLOBBERS
inline asmsub plot(uword plotx @R0, uword ploty @R1) { inline asmsub plot(uword plotx @R0, uword ploty @R1) {
%asm {{ %asm {{
jsr cx16.FB_cursor_position jsr cx16.FB_cursor_position