diff --git a/compiler/res/prog8lib/c64/graphics.p8 b/compiler/res/prog8lib/c64/graphics.p8 index 9a2be5ce6..8921fecef 100644 --- a/compiler/res/prog8lib/c64/graphics.p8 +++ b/compiler/res/prog8lib/c64/graphics.p8 @@ -288,17 +288,30 @@ hline_zero2 sub disc(uword xcenter, ubyte ycenter, ubyte radius) { ; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen. - ; Midpoint algorithm, filled + ; Midpoint algorithm, filled. if radius==0 return ubyte @zp yy = 0 word decisionOver2 = (1 as word)-radius + ubyte last_y3 = ycenter+radius + ubyte last_y4 = ycenter-radius + ubyte new_y3, new_y4 while radius>=yy { horizontal_line(xcenter-radius, ycenter+yy, radius*2+1) horizontal_line(xcenter-radius, ycenter-yy, radius*2+1) - horizontal_line(xcenter-yy, ycenter+radius, yy*2+1) - horizontal_line(xcenter-yy, ycenter-radius, yy*2+1) + + new_y3 = ycenter+radius + if new_y3 != last_y3 { + horizontal_line(xcenter-yy, last_y3, yy*2+1) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + horizontal_line(xcenter-yy, last_y4, yy*2+1) + last_y4 = new_y4 + } + yy++ if decisionOver2>=0 { radius-- @@ -307,6 +320,10 @@ hline_zero2 decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + horizontal_line(xcenter-yy, last_y3, yy*2+1) + horizontal_line(xcenter-yy, last_y4, yy*2+1) } diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index 448d5624a..bb567566c 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -485,12 +485,25 @@ gfx2 { return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, color) horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, color) - horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, color) - horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, color) + + new_y3 = ycenter+radius + if new_y3 != last_y3 { + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color) + last_y4 = new_y4 + } + yy++ if decisionOver2>=0 { radius-- @@ -499,6 +512,11 @@ gfx2 { decisionOver2 += yy*$0002 decisionOver2++ } + + ; draw the final two spans + yy-- + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color) + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color) } sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, ubyte color) { @@ -508,12 +526,23 @@ gfx2 { return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { safe_horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, color) safe_horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, color) - safe_horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, color) - safe_horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, color) + new_y3 = ycenter+radius + if new_y3 != last_y3 { + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color) + last_y4 = new_y4 + } yy++ if decisionOver2>=0 { radius-- @@ -522,6 +551,10 @@ gfx2 { decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, color) + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, color) } sub plot(uword @zp xx, uword @zp yy, ubyte @zp color) { diff --git a/compiler/res/prog8lib/cx16/monogfx.p8 b/compiler/res/prog8lib/cx16/monogfx.p8 index 5b84c44b6..321d72e04 100644 --- a/compiler/res/prog8lib/cx16/monogfx.p8 +++ b/compiler/res/prog8lib/cx16/monogfx.p8 @@ -563,12 +563,23 @@ drawmode: ora cx16.r15L return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, draw) horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, draw) - horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw) - horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw) + new_y3 = ycenter+radius + if new_y3 != last_y3 { + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) + last_y4 = new_y4 + } yy++ if decisionOver2>=0 { radius-- @@ -577,6 +588,10 @@ drawmode: ora cx16.r15L decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) } sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) { @@ -586,12 +601,23 @@ drawmode: ora cx16.r15L return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { safe_horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, draw) safe_horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, draw) - safe_horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw) - safe_horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw) + new_y3 = ycenter+radius + if new_y3 != last_y3 { + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) + last_y4 = new_y4 + } yy++ if decisionOver2>=0 { radius-- @@ -600,6 +626,10 @@ drawmode: ora cx16.r15L decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) } sub plot(uword @zp xx, uword @zp yy, bool @zp draw) { diff --git a/compiler/res/prog8lib/virtual/monogfx.p8 b/compiler/res/prog8lib/virtual/monogfx.p8 index 60bb6f5be..00fc6f118 100644 --- a/compiler/res/prog8lib/virtual/monogfx.p8 +++ b/compiler/res/prog8lib/virtual/monogfx.p8 @@ -300,12 +300,23 @@ monogfx { return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, draw) horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, draw) - horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw) - horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw) + new_y3 = ycenter+radius + if new_y3 != last_y3 { + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) + last_y4 = new_y4 + } yy++ if decisionOver2>=0 { radius-- @@ -314,6 +325,10 @@ monogfx { decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) } sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) { @@ -323,12 +338,23 @@ monogfx { return ubyte @zp yy = 0 word @zp decisionOver2 = (1 as word)-radius + uword last_y3 = ycenter+radius + uword last_y4 = ycenter-radius + uword new_y3, new_y4 while radius>=yy { safe_horizontal_line(xcenter-radius, ycenter+yy, radius*$0002+1, draw) safe_horizontal_line(xcenter-radius, ycenter-yy, radius*$0002+1, draw) - safe_horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw) - safe_horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw) + new_y3 = ycenter+radius + if new_y3 != last_y3 { + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + last_y3 = new_y3 + } + new_y4 = ycenter-radius + if new_y4 != last_y4 { + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) + last_y4 = new_y4 + } yy++ if decisionOver2>=0 { radius-- @@ -337,6 +363,10 @@ monogfx { decisionOver2 += yy*$0002 decisionOver2++ } + ; draw the final two spans + yy-- + safe_horizontal_line(xcenter-yy, last_y3, yy*$0002+1, draw) + safe_horizontal_line(xcenter-yy, last_y4, yy*$0002+1, draw) } sub plot(uword @zp xx, uword @zp yy, bool @zp draw) { diff --git a/examples/line-circle-txt.p8 b/examples/line-circle-txt.p8 index ad5e50d21..27f3e7fbb 100644 --- a/examples/line-circle-txt.p8 +++ b/examples/line-circle-txt.p8 @@ -81,6 +81,8 @@ main { sub disc(ubyte cx, ubyte cy, ubyte radius) { ; Midpoint algorithm, filled + ; NOTE: because of the symmetry drawing, some horizontal spans will be drawn multiple times. + ; because this is only a very low res (text tiles) disc, it's not worth optimizing that. ubyte x = radius ubyte y = 0 byte decisionOver2 = 1-x as byte diff --git a/examples/test.p8 b/examples/test.p8 index 29ab761e5..aeb1f29ce 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,18 +1,19 @@ -%import conv +%import monogfx %option no_sysinit +%zeropage basicsafe main { sub start() { - read4hex() - } + monogfx.hires() + monogfx.circle(320, 240, 200, true) + sys.wait(60) + monogfx.drawmode(monogfx.MODE_STIPPLE) + monogfx.disc(320, 240, 200, true) + sys.wait(60) + monogfx.drawmode(monogfx.MODE_NORMAL) + monogfx.safe_disc(320, 240, 200, true) - sub read4hex() -> uword { - str hex = "0000" - hex[0] = cbm.CHRIN() - hex[1] = cbm.CHRIN() - hex[2] = cbm.CHRIN() - hex[3] = cbm.CHRIN() - return conv.hex2uword(hex) + repeat { + } } - }