optimize horzontal_line drawing

This commit is contained in:
Irmen de Jong 2020-12-30 18:02:46 +01:00
parent ddfcf45d40
commit b4931c9a1f
4 changed files with 81 additions and 14 deletions

View File

@ -34,7 +34,6 @@ graphics {
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations.
; TODO rewrite this in optimized assembly
if y1>y2 {
; make sure dy is always positive to have only 4 instead of 8 special cases
swap(x1, x2)
@ -54,6 +53,8 @@ graphics {
return
}
; TODO rewrite the rest in optimized assembly
word @zp d = 0
ubyte positive_ix = true
if dx < 0 {
@ -143,14 +144,82 @@ graphics {
}
sub horizontal_line(uword x, ubyte y, uword length) {
if not length
if length<8 {
internal_plotx=x
repeat lsb(length) {
internal_plot(y)
internal_plotx++
}
return
}
; TODO optimized drawing 8 pixels at a time (+edges) should use get_y_lookup(y) in this
internal_plotx = x
repeat length {
internal_plot(y)
internal_plotx++
ubyte separate_pixels = lsb(x) & 7
uword addr = get_y_lookup(y) + (x&$fff8)
if separate_pixels {
%asm {{
lda addr
sta P8ZP_SCRATCH_W1
lda addr+1
sta P8ZP_SCRATCH_W1+1
ldy separate_pixels
lda _filled_right,y
eor #255
ldy #0
ora (P8ZP_SCRATCH_W1),y
sta (P8ZP_SCRATCH_W1),y
}}
addr += 8
length += separate_pixels
length -= 8
}
if length {
%asm {{
lda length
and #7
sta separate_pixels
stx P8ZP_SCRATCH_REG
lsr length+1
ror length
lsr length+1
ror length
lsr length+1
ror length
lda addr
sta _modified+1
lda addr+1
sta _modified+2
lda length
ora length+1
beq _zero
ldy length
ldx #$ff
_modified stx $ffff ; modified
lda _modified+1
clc
adc #8
sta _modified+1
bcc +
inc _modified+2
+ dey
bne _modified
_zero ldx P8ZP_SCRATCH_REG
ldy separate_pixels
beq _zero2
lda _modified+1
sta P8ZP_SCRATCH_W1
lda _modified+2
sta P8ZP_SCRATCH_W1+1
lda _filled_right,y
ldy #0
ora (P8ZP_SCRATCH_W1),y
sta (P8ZP_SCRATCH_W1),y
jmp _zero2
_filled_right .byte 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110
_zero2
}}
}
}
@ -289,9 +358,9 @@ _y_lookup_hi .byte >_plot_y_values
asmsub get_y_lookup(ubyte y @Y) -> uword @AY {
%asm {{
lda _y_lookup_lo,y
lda internal_plot._y_lookup_lo,y
pha
lda _y_lookup_hi,y
lda internal_plot._y_lookup_hi,y
tay
pla
rts

View File

@ -315,7 +315,6 @@ _done
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
; Bresenham algorithm.
; This code special-cases various quadrant loops to allow simple ++ and -- operations.
; TODO rewrite this in optimized assembly
if y1>y2 {
; make sure dy is always positive to have only 4 instead of 8 special cases
swap(x1, x2)
@ -335,6 +334,7 @@ _done
return
}
; TODO rewrite the rest in optimized assembly
word @zp d = 0
ubyte positive_ix = true
if dx < 0 {

View File

@ -76,9 +76,8 @@ graphics
Monochrome bitmap graphics routines, fixed 320*200 resolution:
- clearing the screen
- drawing lines
- drawing circles and discs (filled circles)
- plotting individual pixels
- drawing individual pixels
- drawing lines, rectangles, filled rectangles, circles, discs
This library is available both on the C64 and the Cx16.
It uses the ROM based graphics routines on the latter, and it is a very small library because of that.

View File

@ -2,7 +2,6 @@
TODO
====
- implement gfx2's rect, fillrect, horizontal_line and vertical_line in graphics modules as well. (and optimize bresenham line to use vert/horiz line if possible)
- detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'