prog8/examples/line-circle-txt.p8

166 lines
4.9 KiB
Plaintext
Raw Normal View History

2020-03-14 16:11:10 +00:00
%import c64lib
2020-08-27 16:10:22 +00:00
%import c64textio
2020-03-14 16:11:10 +00:00
%zeropage basicsafe
main {
sub start() {
2020-08-27 16:10:22 +00:00
txt.print("mid-point\ncircle\n and\nbresenham\nline\nalgorithms.\n")
2020-03-14 16:11:10 +00:00
2020-03-22 22:50:15 +00:00
ubyte r
for r in 3 to 12 step 3 {
circle(20, 12, r)
}
2020-08-27 16:10:22 +00:00
txt.print("enter for disc:")
void c64.CHRIN()
c64.CHROUT('\n')
2020-08-30 17:31:20 +00:00
txt.clear_screen()
disc(20, 12, 12)
2020-08-27 16:10:22 +00:00
txt.print("enter for lines:")
void c64.CHRIN()
c64.CHROUT('\n')
2020-08-30 17:31:20 +00:00
txt.clear_screen()
2020-03-14 16:11:10 +00:00
line(1, 10, 38, 24)
line(1, 20, 38, 2)
line(20, 4, 10, 24)
line(39, 16, 12, 0)
2020-08-27 16:10:22 +00:00
txt.print("enter for rectangles:")
void c64.CHRIN()
c64.CHROUT('\n')
2020-08-30 17:31:20 +00:00
txt.clear_screen()
rect(4, 8, 37, 23, false)
rect(20, 12, 30, 20, true)
rect(10, 10, 10, 10, false)
rect(6, 0, 16, 20, true)
sub rect(ubyte x1, ubyte y1, ubyte x2, ubyte y2, ubyte fill) {
ubyte x
ubyte y
if fill {
for y in y1 to y2 {
for x in x1 to x2 {
2020-08-27 16:10:22 +00:00
txt.setcc(x, y, 42, x+y)
}
}
} else {
for x in x1 to x2 {
2020-08-27 16:10:22 +00:00
txt.setcc(x, y1, 42, 8)
txt.setcc(x, y2, 42, 8)
}
if y2>y1 {
for y in y1+1 to y2-1 {
2020-08-27 16:10:22 +00:00
txt.setcc(x1, y, 42, 7)
txt.setcc(x2, y, 42, 7)
}
}
}
}
2020-03-14 16:11:10 +00:00
sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
2020-03-28 11:33:16 +00:00
; Bresenham algorithm, not very optimized to keep clear code.
; For a better optimized version have a look in the graphics.p8 module.
2020-03-14 16:11:10 +00:00
byte d = 0
ubyte dx = abs(x2 - x1)
ubyte dy = abs(y2 - y1)
ubyte dx2 = 2 * dx
ubyte dy2 = 2 * dy
ubyte ix = sgn(x2 as byte - x1 as byte) as ubyte
ubyte iy = sgn(y2 as byte - y1 as byte) as ubyte
2020-03-14 16:11:10 +00:00
ubyte x = x1
ubyte y = y1
if dx >= dy {
repeat {
2020-08-27 16:10:22 +00:00
txt.setcc(x, y, 42, 5)
2020-03-14 16:11:10 +00:00
if x==x2
return
2020-03-26 22:33:55 +00:00
x += ix
2020-03-14 16:11:10 +00:00
d += dy2
if d > dx {
2020-03-26 22:33:55 +00:00
y += iy
2020-03-14 16:11:10 +00:00
d -= dx2
}
}
} else {
repeat {
2020-08-27 16:10:22 +00:00
txt.setcc(x, y, 42, 5)
2020-03-14 16:11:10 +00:00
if y == y2
return
2020-03-26 22:33:55 +00:00
y += iy
2020-03-14 16:11:10 +00:00
d += dx2
if d > dy {
2020-03-26 22:33:55 +00:00
x += ix
2020-03-14 16:11:10 +00:00
d -= dy2
}
}
}
}
sub circle(ubyte xcenter, ubyte ycenter, ubyte radius) {
; Midpoint algorithm
2020-03-26 22:33:55 +00:00
ubyte x = radius
ubyte y = 0
byte decisionOver2 = 1-x as byte
2020-03-14 16:11:10 +00:00
while x>=y {
2020-08-27 16:10:22 +00:00
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)
y++
if decisionOver2<=0
decisionOver2 += 2*y+1
else {
x--
decisionOver2 += 2*(y-x)+1
}
}
}
sub disc(ubyte cx, ubyte cy, ubyte radius) {
; Midpoint algorithm, filled
2020-03-26 22:33:55 +00:00
ubyte x = radius
ubyte y = 0
byte decisionOver2 = 1-x as byte
2020-03-26 22:33:55 +00:00
ubyte xx
while x>=y {
for xx in cx to cx+x {
2020-08-27 16:10:22 +00:00
txt.setcc(xx, cy + y as ubyte, 81, 1)
txt.setcc(xx, cy - y as ubyte, 81, 2)
}
for xx in cx-x to cx-1 {
2020-08-27 16:10:22 +00:00
txt.setcc(xx, cy + y as ubyte, 81, 3)
txt.setcc(xx, cy - y as ubyte, 81, 4)
}
for xx in cx to cx+y {
2020-08-27 16:10:22 +00:00
txt.setcc(xx, cy + x as ubyte, 81, 5)
txt.setcc(xx, cy - x as ubyte, 81, 6)
}
for xx in cx-y to cx {
2020-08-27 16:10:22 +00:00
txt.setcc(xx, cy + x as ubyte, 81, 7)
txt.setcc(xx, cy - x as ubyte, 81, 8)
}
2020-03-14 16:11:10 +00:00
y++
if decisionOver2<=0
decisionOver2 += 2*y+1
else {
x--
decisionOver2 += 2*(y-x)+1
}
}
}
}
}