From 582d31263cdcc58096d3276e793e291459aeff36 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 26 Mar 2020 23:33:55 +0100 Subject: [PATCH] better lines and circles --- examples/lines-circles-gfx.p8 | 103 +++++++++++++++++++++------------- examples/lines-circles.p8 | 50 ++++++++--------- 2 files changed, 89 insertions(+), 64 deletions(-) diff --git a/examples/lines-circles-gfx.p8 b/examples/lines-circles-gfx.p8 index e147fdc97..0a94e49e0 100644 --- a/examples/lines-circles-gfx.p8 +++ b/examples/lines-circles-gfx.p8 @@ -16,53 +16,81 @@ main { memset(bitmap_address, 320*200/8, 0) c64scr.clear_screen($10, 0) - circles() lines() + circles() } sub circles() { ubyte xx - for xx in 1 to 5 { - circle(50 + xx*40, 50+xx*15, (xx+10)*4, xx) - disc(50 + xx*40, 50+xx*15, (xx+10)*2, xx) + for xx in 3 to 7 { + circle(xx*50-100, 10+xx*16, (xx+6)*4) + disc(xx*50-100, 10+xx*16, (xx+6)*2) } } sub lines() { - uword xx - ubyte yy - ubyte color - ubyte iter + ubyte ix + for ix in 1 to 15 { + line(10, 10, ix*4, 50) ; TODO fix lines of lenghts > 128 + } + } - for color in 1 to 15 { - xx = color * 16 - yy = color + 20 - for iter in 0 to 80 { - plot(xx, yy, color) - xx++ - yy+=2 + sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) { + ; Bresenham algorithm + byte d = 0 + ubyte dx = abs(x2 - x1) + ubyte dy = abs(y2 - y1) + ubyte dx2 = 2 * dx + ubyte dy2 = 2 * dy + byte ix = sgn(x2 as byte - x1 as byte) + byte iy = sgn(y2 as byte - y1 as byte) + ubyte x = x1 + ubyte y = y1 + + if dx >= dy { + forever { + plot(x, y) + if x==x2 + return + x += ix + d += dy2 + if d > dx { + y += iy + d -= dx2 + } + } + } else { + forever { + plot(x, y) + if y == y2 + return + y += iy + d += dx2 + if d > dy { + x += ix + d -= dy2 + } } } } - - sub circle(uword xcenter, ubyte ycenter, ubyte radius, ubyte color) { + sub circle(uword xcenter, ubyte ycenter, ubyte radius) { ; Midpoint algorithm ubyte x = radius ubyte y = 0 byte decisionOver2 = 1-x while x>=y { - plot(xcenter + x, ycenter + y as ubyte, color) - plot(xcenter - x, ycenter + y as ubyte, color) - plot(xcenter + x, ycenter - y as ubyte, color) - plot(xcenter - x, ycenter - y as ubyte, color) - plot(xcenter + y, ycenter + x as ubyte, color) - plot(xcenter - y, ycenter + x as ubyte, color) - plot(xcenter + y, ycenter - x as ubyte, color) - plot(xcenter - y, ycenter - x as ubyte, color) + plot(xcenter + x, ycenter + y as ubyte) + plot(xcenter - x, ycenter + y as ubyte) + plot(xcenter + x, ycenter - y as ubyte) + plot(xcenter - x, ycenter - y as ubyte) + plot(xcenter + y, ycenter + x as ubyte) + plot(xcenter - y, ycenter + x as ubyte) + plot(xcenter + y, ycenter - x as ubyte) + plot(xcenter - y, ycenter - x as ubyte) y++ if decisionOver2<=0 decisionOver2 += 2*y+1 @@ -73,7 +101,7 @@ main { } } - sub disc(uword cx, ubyte cy, ubyte radius, ubyte color) { + sub disc(uword cx, ubyte cy, ubyte radius) { ; Midpoint algorithm, filled ubyte x = radius ubyte y = 0 @@ -82,20 +110,20 @@ main { while x>=y { for xx in cx to cx+x { - plot(xx, cy + y as ubyte, color) - plot(xx, cy - y as ubyte, color) + plot(xx, cy + y as ubyte) + plot(xx, cy - y as ubyte) } for xx in cx-x to cx-1 { - plot(xx, cy + y as ubyte, color) - plot(xx, cy - y as ubyte, color) + plot(xx, cy + y as ubyte) + plot(xx, cy - y as ubyte) } for xx in cx to cx+y { - plot(xx, cy + x as ubyte, color) - plot(xx, cy - x as ubyte, color) + plot(xx, cy + x as ubyte) + plot(xx, cy - x as ubyte) } for xx in cx-y to cx { - plot(xx, cy + x as ubyte, color) - plot(xx, cy - x as ubyte, color) + plot(xx, cy + x as ubyte) + plot(xx, cy - x as ubyte) } y++ if decisionOver2<=0 @@ -107,15 +135,12 @@ main { } } - sub plot(uword px, ubyte py, ubyte color) { + sub plot(uword px, ubyte py) { + ; TODO put this in a tuned asm plot routine ; fast asm plot via lookup tables http://codebase64.org/doku.php?id=base:various_techniques_to_calculate_adresses_fast_common_screen_formats_for_pixel_graphics ubyte[] ormask = [128, 64, 32, 16, 8, 4, 2, 1] uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000001111111000) @(addr) |= ormask[lsb(px) & 7] - ubyte sx = px >> 3 - ubyte sy = py >> 3 - c64.SCRATCH_ZPB1 = color << 4 - c64scr.setchr(sx, sy) } } diff --git a/examples/lines-circles.p8 b/examples/lines-circles.p8 index 5dc0f3999..3bc0e72b2 100644 --- a/examples/lines-circles.p8 +++ b/examples/lines-circles.p8 @@ -80,10 +80,10 @@ main { c64scr.setcc(x, y, 42, 5) if x==x2 return - x += ix as ubyte + x += ix d += dy2 if d > dx { - y += iy as ubyte + y += iy d -= dx2 } } @@ -92,10 +92,10 @@ main { c64scr.setcc(x, y, 42, 5) if y == y2 return - y += iy as ubyte + y += iy d += dx2 if d > dy { - x += ix as ubyte + x += ix d -= dy2 } } @@ -104,19 +104,19 @@ main { sub circle(ubyte xcenter, ubyte ycenter, ubyte radius) { ; Midpoint algorithm - byte x = radius as byte - byte y = 0 + ubyte x = radius + ubyte y = 0 byte decisionOver2 = 1-x while x>=y { - c64scr.setcc(xcenter + x as ubyte, ycenter + y as ubyte, 81, 1) - c64scr.setcc(xcenter - x as ubyte, ycenter + y as ubyte, 81, 2) - c64scr.setcc(xcenter + x as ubyte, ycenter - y as ubyte, 81, 3) - c64scr.setcc(xcenter - x as ubyte, ycenter - y as ubyte, 81, 4) - c64scr.setcc(xcenter + y as ubyte, ycenter + x as ubyte, 81, 5) - c64scr.setcc(xcenter - y as ubyte, ycenter + x as ubyte, 81, 6) - c64scr.setcc(xcenter + y as ubyte, ycenter - x as ubyte, 81, 7) - c64scr.setcc(xcenter - y as ubyte, ycenter - x as ubyte, 81, 8) + c64scr.setcc(xcenter + x, ycenter + y as ubyte, 81, 1) + c64scr.setcc(xcenter - x, ycenter + y as ubyte, 81, 2) + c64scr.setcc(xcenter + x, ycenter - y as ubyte, 81, 3) + c64scr.setcc(xcenter - x, ycenter - y as ubyte, 81, 4) + c64scr.setcc(xcenter + y, ycenter + x as ubyte, 81, 5) + c64scr.setcc(xcenter - y, ycenter + x as ubyte, 81, 6) + c64scr.setcc(xcenter + y, ycenter - x as ubyte, 81, 7) + c64scr.setcc(xcenter - y, ycenter - x as ubyte, 81, 8) y++ if decisionOver2<=0 decisionOver2 += 2*y+1 @@ -129,27 +129,27 @@ main { sub disc(ubyte cx, ubyte cy, ubyte radius) { ; Midpoint algorithm, filled - byte x = radius as byte - byte y = 0 + ubyte x = radius + ubyte y = 0 byte decisionOver2 = 1-x - byte xx + ubyte xx while x>=y { for xx in cx to cx+x { - c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 1) - c64scr.setcc(xx as ubyte, cy - y as ubyte, 81, 2) + c64scr.setcc(xx, cy + y as ubyte, 81, 1) + c64scr.setcc(xx, cy - y as ubyte, 81, 2) } for xx in cx-x to cx-1 { - c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 3) - c64scr.setcc(xx as ubyte, cy - y as ubyte, 81, 4) + c64scr.setcc(xx, cy + y as ubyte, 81, 3) + c64scr.setcc(xx, cy - y as ubyte, 81, 4) } for xx in cx to cx+y { - c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 5) - c64scr.setcc(xx as ubyte, cy - x as ubyte, 81, 6) + c64scr.setcc(xx, cy + x as ubyte, 81, 5) + c64scr.setcc(xx, cy - x as ubyte, 81, 6) } for xx in cx-y to cx { - c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 7) - c64scr.setcc(xx as ubyte, cy - x as ubyte, 81, 8) + c64scr.setcc(xx, cy + x as ubyte, 81, 7) + c64scr.setcc(xx, cy - x as ubyte, 81, 8) } y++ if decisionOver2<=0