optimized all circle routines a little more. Added gfx2/monogfx safe_circle and safe_disc. Warning for when on const value.

This commit is contained in:
Irmen de Jong 2023-11-05 16:39:36 +01:00
parent d9389afc66
commit 723ab54f97
9 changed files with 452 additions and 102 deletions

View File

@ -1,6 +1,9 @@
; bitmap pixel graphics module for the C64
; only black/white monochrome 320x200 for now
;
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
; Sets character matrix and bitmap screen memory at a higher memory location $5c00-$7fff
; so that the program itself can be larger without starting to overwrite the graphics memory.
@ -244,7 +247,8 @@ hline_zero2
}
sub circle(uword xcenter, ubyte ycenter, ubyte radius) {
; Midpoint algorithm
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm.
if radius==0
return
ubyte @zp ploty
@ -273,16 +277,17 @@ hline_zero2
internal_plotx = xcenter - yy
internal_plot(ploty)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
sub disc(uword xcenter, ubyte ycenter, ubyte radius) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
@ -295,12 +300,12 @@ hline_zero2
horizontal_line(xcenter-yy, ycenter+radius, yy*2+1)
horizontal_line(xcenter-yy, ycenter-radius, yy*2+1)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}

View File

@ -10,6 +10,9 @@
; If you're memory constrained you should probably not use this built-in library,
; but make a copy in your project only containing the code for the required resolution.
;
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
;
; SCREEN MODE LIST:
; mode 0 = reset back to default text mode
@ -203,6 +206,24 @@ gfx2 {
}
}
sub safe_horizontal_line(uword xx, uword yy, uword length, bool draw) {
; does bounds checking and clipping
if msb(yy)&$80!=0 or yy>=height
return
if msb(xx)&$80!=0 {
length += xx
xx = 0
}
if xx>=width
return
if xx+length>width
length = width-xx
if length>width
return
horizontal_line(xx, yy, length, draw)
}
sub vertical_line(uword xx, uword yy, uword lheight, ubyte color) {
when active_mode {
1 -> {
@ -350,6 +371,7 @@ gfx2 {
}
sub circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, ubyte color) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm.
if radius==0
return
@ -363,36 +385,91 @@ gfx2 {
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plot(cx16.r14, cx16.r15, color)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, color)
plotq()
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
xx--
decisionOver2 += (yy as word -xx)*2+1
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, color=color.
plot(cx16.r14, cx16.r15, color)
}
}
sub safe_circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, ubyte color) {
; This version does bounds checks and clipping, but is a lot slower.
; Midpoint algorithm.
if radius==0
return
ubyte @zp xx = radius
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-xx
; R14 = internal plot X
; R15 = internal plot Y
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plotq()
cx16.r14 = xcenter - yy
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plotq()
cx16.r14 = xcenter - yy
plotq()
yy++
if decisionOver2>=0 {
xx--
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, color=color.
safe_plot(cx16.r14, cx16.r15, color)
}
}
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, ubyte color) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
@ -405,12 +482,35 @@ gfx2 {
horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, color)
horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, color)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, ubyte color) {
; This version does bounds checks and clipping, but is a lot slower.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-radius
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)
yy++
if decisionOver2>=0 {
radius--
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
@ -467,6 +567,15 @@ gfx2 {
}
}
sub safe_plot(uword xx, uword yy, ubyte color) {
; A plot that does bounds checks to see if the pixel is inside the screen.
if msb(xx)&$80!=0 or msb(yy)&$80!=0
return
if xx >= width or yy >= height
return
plot(xx, yy, color)
}
sub pget(uword @zp xx, uword yy) -> ubyte {
when active_mode {
1 -> {

View File

@ -7,6 +7,10 @@
; Unlike graphics module on the C64, you can use colors() to set new drawing colors for every draw operation.
; For other resolutions or other color modes, use the "gfx2" or "monogfx" module instead. (which is Cx16-specific)
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
;
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
graphics {
@ -69,6 +73,8 @@ graphics {
}
sub circle(uword xcenter, ubyte ycenter, ubyte radius) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
;cx16.r0 = xcenter - radius/2
;cx16.r1 = ycenter - radius/2
;cx16.r2 = radius*2
@ -111,17 +117,21 @@ graphics {
cx16.r0 = xcenter - yy
cx16.FB_cursor_position2()
cx16.FB_set_pixel(stroke_color)
yy++
if decisionOver2<=0 {
decisionOver2 += (yy as word)*2+1
} else {
if decisionOver2>=0 {
xx--
decisionOver2 += (yy as word -xx)*2+1
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
sub disc(uword xcenter, ubyte ycenter, ubyte radius) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
@ -132,13 +142,14 @@ graphics {
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)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}

View File

@ -5,6 +5,9 @@
; For color bitmap graphics, see the gfx2 library.
;
; NOTE: a lot of the code here is similar or the same to that in gfx2
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
monogfx {
@ -229,6 +232,24 @@ _done
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off again
}
sub safe_horizontal_line(uword xx, uword yy, uword length, bool draw) {
; does bounds checking and clipping
if msb(yy)&$80!=0 or yy>=height
return
if msb(xx)&$80!=0 {
length += xx
xx = 0
}
if xx>=width
return
if xx+length>width
length = width-xx
if length>width
return
horizontal_line(xx, yy, length, draw)
}
sub vertical_line(uword xx, uword yy, uword lheight, bool draw) {
cx16.r15L = monogfx.plot.maskbits[xx as ubyte & 7] ; bitmask
if draw {
@ -385,6 +406,7 @@ _done
}
sub circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm.
if radius==0
return
@ -398,36 +420,91 @@ _done
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
xx--
decisionOver2 += (yy as word -xx)*2+1
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, draw=draw
plot(cx16.r14, cx16.r15, draw)
}
}
sub safe_circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, bool draw) {
; Does bounds checking and clipping.
; Midpoint algorithm.
if radius==0
return
ubyte @zp xx = radius
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-xx
; R14 = internal plot X
; R15 = internal plot Y
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plotq()
cx16.r14 = xcenter - yy
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plotq()
cx16.r14 = xcenter - yy
plotq()
yy++
if decisionOver2>=0 {
xx--
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, draw=draw
safe_plot(cx16.r14, cx16.r15, draw)
}
}
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
@ -440,12 +517,35 @@ _done
horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw)
horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Does bounds checking and clipping.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-radius
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)
yy++
if decisionOver2>=0 {
radius--
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
@ -497,6 +597,15 @@ _done
}
}
sub safe_plot(uword xx, uword yy, bool draw) {
; A plot that does bounds checks to see if the pixel is inside the screen.
if msb(xx)&$80!=0 or msb(yy)&$80!=0
return
if xx >= width or yy >= height
return
plot(xx, yy, draw)
}
sub pget(uword @zp xx, uword yy) -> ubyte {
%asm {{
lda xx

View File

@ -1,5 +1,9 @@
; Monochrome Bitmap pixel graphics routines for the Virtual Machine
; Using the full-screen 640x480 and 320x240 screen modes, but just black/white.
;
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
monogfx {
@ -74,6 +78,24 @@ monogfx {
plot(xpos, yy, color)
}
sub safe_horizontal_line(uword xx, uword yy, uword length, bool draw) {
; does bounds checking and clipping
if msb(yy)&$80!=0 or yy>=height
return
if msb(xx)&$80!=0 {
length += xx
xx = 0
}
if xx>=width
return
if xx+length>width
length = width-xx
if length>width
return
horizontal_line(xx, yy, length, draw)
}
sub vertical_line(uword xx, uword yy, uword lheight, bool draw) {
ubyte color = 0
if draw
@ -176,6 +198,7 @@ monogfx {
}
sub circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm.
if radius==0
return
@ -189,36 +212,91 @@ monogfx {
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plot(cx16.r14, cx16.r15, draw)
plotq()
cx16.r14 = xcenter - yy
plot(cx16.r14, cx16.r15, draw)
plotq()
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
xx--
decisionOver2 += (yy as word -xx)*2+1
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, draw=draw
plot(cx16.r14, cx16.r15, draw)
}
}
sub safe_circle(uword @zp xcenter, uword @zp ycenter, ubyte radius, bool draw) {
; Does bounds checking and clipping.
; Midpoint algorithm.
if radius==0
return
ubyte @zp xx = radius
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-xx
; R14 = internal plot X
; R15 = internal plot Y
while xx>=yy {
cx16.r14 = xcenter + xx
cx16.r15 = ycenter + yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + xx
cx16.r15 = ycenter - yy
plotq()
cx16.r14 = xcenter - xx
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter + xx
plotq()
cx16.r14 = xcenter - yy
plotq()
cx16.r14 = xcenter + yy
cx16.r15 = ycenter - xx
plotq()
cx16.r14 = xcenter - yy
plotq()
yy++
if decisionOver2>=0 {
xx--
decisionOver2 -= xx*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
sub plotq() {
; cx16.r14 = x, cx16.r15 = y, draw=draw
safe_plot(cx16.r14, cx16.r15, draw)
}
}
sub disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
@ -231,12 +309,35 @@ monogfx {
horizontal_line(xcenter-yy, ycenter+radius, yy*$0002+1, draw)
horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, draw)
yy++
if decisionOver2<=0
decisionOver2 += (yy as word)*2+1
else {
if decisionOver2>=0 {
radius--
decisionOver2 += (yy as word -radius)*2+1
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
sub safe_disc(uword @zp xcenter, uword @zp ycenter, ubyte @zp radius, bool draw) {
; Warning: NO BOUNDS CHECKS. Make sure circle fits in the screen.
; Midpoint algorithm, filled
if radius==0
return
ubyte @zp yy = 0
word @zp decisionOver2 = (1 as word)-radius
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)
yy++
if decisionOver2>=0 {
radius--
decisionOver2 -= radius*$0002
}
decisionOver2 += yy*$0002
decisionOver2++
}
}
@ -255,6 +356,15 @@ monogfx {
sys.gfx_plot(xx, yy, 0)
}
sub safe_plot(uword xx, uword yy, bool draw) {
; A plot that does bounds checks to see if the pixel is inside the screen.
if msb(xx)&$80!=0 or msb(yy)&$80!=0
return
if xx >= width or yy >= height
return
plot(xx, yy, draw)
}
sub pget(uword @zp xx, uword yy) -> ubyte {
return sys.gfx_getpixel(xx, yy)
}

View File

@ -1348,6 +1348,9 @@ internal class AstChecker(private val program: Program,
if(whenStmt.choices.isEmpty())
errors.err("empty when statement", whenStmt.position)
if(whenStmt.condition.constValue(program)!=null)
errors.warn("when-value is a constant and will always result in the same choice", whenStmt.condition.position)
super.visit(whenStmt)
}

View File

@ -1,10 +1,8 @@
TODO
====
- is Jesko's circle algorithm faster than what we have now? https://en.wikipedia.org/wiki/Midpoint_circle_algorithm#Jesko's_Method
is it Correct??? Or better to use Casey's algorithm?
- optimize when in case of constant value (only keep choice that matches)
- revisit the seek example to see if write-seeking now works?
- remove unused interned strings in the resulting code (for example from removed if/else blocks)
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
- [on branch: ir-less-branch-opcodes] IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction

View File

@ -61,21 +61,21 @@ main {
byte decisionOver2 = 1-x as byte
while x>=y {
txt.setcc(xcenter + x, ycenter + y as ubyte, 81, 1)
txt.setcc(xcenter - x, ycenter + y as ubyte, 81, 2)
txt.setcc(xcenter + x, ycenter - y as ubyte, 81, 3)
txt.setcc(xcenter - x, ycenter - y as ubyte, 81, 4)
txt.setcc(xcenter + y, ycenter + x as ubyte, 81, 5)
txt.setcc(xcenter - y, ycenter + x as ubyte, 81, 6)
txt.setcc(xcenter + y, ycenter - x as ubyte, 81, 7)
txt.setcc(xcenter - y, ycenter - x as ubyte, 81, 8)
txt.setcc(xcenter + x, ycenter + y, 81, 1)
txt.setcc(xcenter - x, ycenter + y, 81, 2)
txt.setcc(xcenter + x, ycenter - y, 81, 3)
txt.setcc(xcenter - x, ycenter - y, 81, 4)
txt.setcc(xcenter + y, ycenter + x, 81, 5)
txt.setcc(xcenter - y, ycenter + x, 81, 6)
txt.setcc(xcenter + y, ycenter - x, 81, 7)
txt.setcc(xcenter - y, ycenter - x, 81, 8)
y++
if decisionOver2<=0
decisionOver2 += 2*y+1
else {
if decisionOver2>=0 {
x--
decisionOver2 += 2*(y-x)+1
decisionOver2 -= 2*x
}
decisionOver2 += 2*y
decisionOver2++
}
}
@ -89,23 +89,23 @@ main {
while x>=y {
xx = cx-x
repeat 2*x+1 {
txt.setcc(xx, cy + y as ubyte, 81, 11)
txt.setcc(xx, cy - y as ubyte, 81, 12)
txt.setcc(xx, cy + y, 81, 11)
txt.setcc(xx, cy - y, 81, 12)
xx++
}
xx = cx-y
repeat 2*y+1 {
txt.setcc(xx, cy + x as ubyte, 81, 13)
txt.setcc(xx, cy - x as ubyte, 81, 14)
txt.setcc(xx, cy + x, 81, 13)
txt.setcc(xx, cy - x, 81, 14)
xx++
}
y++
if decisionOver2<=0
decisionOver2 += 2*y+1
else {
if decisionOver2>=0 {
x--
decisionOver2 += 2*(y-x)+1
decisionOver2 -= 2*x
}
decisionOver2 += 2*y
decisionOver2++
}
}
}

View File

@ -1,22 +1,27 @@
%zeropage basicsafe
%import gfx2
main {
sub pget(uword x, uword y) -> ubyte {
return lsb(x+y)
}
sub start() {
gfx2.screen_mode(2)
word xx
word x2
word yy
gfx2.safe_circle(120, 140, 200, 1)
sys.wait(30)
gfx2.safe_circle(520, 140, 200, 1)
sys.wait(30)
gfx2.safe_circle(120, 340, 200, 1)
sys.wait(30)
gfx2.safe_circle(520, 340, 200, 1)
sys.wait(30)
if xx <= x2 and pget(xx as uword, yy as uword) == cx16.r11L
xx++
gfx2.safe_disc(120, 140, 200, 1)
sys.wait(30)
gfx2.safe_disc(520, 140, 200, 1)
sys.wait(30)
gfx2.safe_disc(120, 340, 200, 1)
sys.wait(30)
gfx2.safe_disc(520, 340, 200, 1)
; if xx <= x2
; if pget(xx as uword, yy as uword) == cx16.r11L
; xx++
repeat {
}
}
}