fix cx16 bresenham line inaccuracy

This commit is contained in:
Irmen de Jong 2021-03-09 21:54:31 +01:00
parent 6c60ea9cac
commit 6995ee2d17
3 changed files with 27 additions and 29 deletions

View File

@ -433,7 +433,6 @@ _done
sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) { sub line(uword @zp x1, uword @zp y1, uword @zp x2, uword @zp y2, ubyte color) {
; 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.
; TODO there are some slight errors at the first/last pixels in certain slopes...
if y1>y2 { if y1>y2 {
; make sure dy is always positive to have only 4 instead of 8 special cases ; make sure dy is always positive to have only 4 instead of 8 special cases
swap(x1, x2) swap(x1, x2)
@ -455,26 +454,26 @@ _done
; TODO rewrite the rest in optimized assembly (or reuse GRAPH_draw_line if we can get the FB replacement vector layer working) ; TODO rewrite the rest in optimized assembly (or reuse GRAPH_draw_line if we can get the FB replacement vector layer working)
word @zp d = 0 word @zp d = 0
ubyte positive_ix = true cx16.r13 = true ; 'positive_ix'
if dx < 0 { if dx < 0 {
dx = -dx dx = -dx
positive_ix = false cx16.r13 = false
} }
dx *= 2 word @zp dx2 = dx*2
dy *= 2 word @zp dy2 = dy*2
cx16.r14 = x1 ; internal plot X cx16.r14 = x1 ; internal plot X
if dx >= dy { if dx >= dy {
if positive_ix { if cx16.r13 {
repeat { repeat {
plot(cx16.r14, y1, color) plot(cx16.r14, y1, color)
if cx16.r14==x2 if cx16.r14==x2
return return
cx16.r14++ cx16.r14++
d += dy d += dy2
if d > dx { if d > dx {
y1++ y1++
d -= dx d -= dx2
} }
} }
} else { } else {
@ -483,25 +482,25 @@ _done
if cx16.r14==x2 if cx16.r14==x2
return return
cx16.r14-- cx16.r14--
d += dy d += dy2
if d > dx { if d > dx {
y1++ y1++
d -= dx d -= dx2
} }
} }
} }
} }
else { else {
if positive_ix { if cx16.r13 {
repeat { repeat {
plot(cx16.r14, y1, color) plot(cx16.r14, y1, color)
if y1 == y2 if y1 == y2
return return
y1++ y1++
d += dx d += dx2
if d > dy { if d > dy {
cx16.r14++ cx16.r14++
d -= dy d -= dy2
} }
} }
} else { } else {
@ -510,10 +509,10 @@ _done
if y1 == y2 if y1 == y2
return return
y1++ y1++
d += dx d += dx2
if d > dy { if d > dy {
cx16.r14-- cx16.r14--
d -= dy d -= dy2
} }
} }
} }

View File

@ -191,7 +191,7 @@ class TestC64Zeropage {
val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, C64Target)) val zp1 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, C64Target))
assertEquals(18, zp1.available()) assertEquals(18, zp1.available())
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, C64Target)) val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), false, false, C64Target))
assertEquals(89, zp2.available()) assertEquals(85, zp2.available())
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, C64Target)) val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.KERNALSAFE, emptyList(), false, false, C64Target))
assertEquals(125, zp3.available()) assertEquals(125, zp3.available())
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target)) val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, C64Target))

View File

@ -1,32 +1,31 @@
%target c64
%import floats %import floats
%import graphics %import gfx2
%import test_stack %import test_stack
%zeropage floatsafe %zeropage floatsafe
main { main {
sub start() { sub start() {
gfx2.screen_mode(1)
graphics.enable_bitmap_mode() ;graphics.enable_bitmap_mode()
uword xx uword xx
ubyte yy ubyte yy
graphics.line(160,100,160,80) gfx2.line(160,100,160,80 ,1)
graphics.line(160,80,180,81) gfx2.line(160,80,180,81 ,1)
graphics.line(180,81,177,103) gfx2.line(180,81,177,103 ,1)
for yy in 0 to 199-60 step 16 { for yy in 0 to 199-60 step 16 {
for xx in 0 to 319-50 step 16 { for xx in 0 to 319-50 step 16 {
graphics.line(30+xx, 10+yy, 50+xx, 30+yy) gfx2.line(30+xx, 10+yy, 50+xx, 30+yy ,1)
graphics.line(49+xx, 30+yy, 10+xx, 30+yy) gfx2.line(49+xx, 30+yy, 10+xx, 30+yy ,1)
graphics.line(11+xx, 29+yy, 29+xx, 11+yy) gfx2.line(11+xx, 29+yy, 29+xx, 11+yy ,1)
; triangle 2, counter-clockwise ; triangle 2, counter-clockwise
graphics.line(30+xx, 40+yy, 10+xx, 60+yy) gfx2.line(30+xx, 40+yy, 10+xx, 60+yy ,1)
graphics.line(11+xx, 60+yy, 50+xx, 60+yy) gfx2.line(11+xx, 60+yy, 50+xx, 60+yy ,1)
graphics.line(49+xx, 59+yy, 31+xx,41+yy) gfx2.line(49+xx, 59+yy, 31+xx,41+yy ,1)
} }
} }