better lines and circles

This commit is contained in:
Irmen de Jong 2020-03-26 23:33:55 +01:00
parent 4108a528e1
commit 582d31263c
2 changed files with 89 additions and 64 deletions

View File

@ -16,53 +16,81 @@ main {
memset(bitmap_address, 320*200/8, 0) memset(bitmap_address, 320*200/8, 0)
c64scr.clear_screen($10, 0) c64scr.clear_screen($10, 0)
circles()
lines() lines()
circles()
} }
sub circles() { sub circles() {
ubyte xx ubyte xx
for xx in 1 to 5 { for xx in 3 to 7 {
circle(50 + xx*40, 50+xx*15, (xx+10)*4, xx) circle(xx*50-100, 10+xx*16, (xx+6)*4)
disc(50 + xx*40, 50+xx*15, (xx+10)*2, xx) disc(xx*50-100, 10+xx*16, (xx+6)*2)
} }
} }
sub lines() { sub lines() {
uword xx ubyte ix
ubyte yy for ix in 1 to 15 {
ubyte color line(10, 10, ix*4, 50) ; TODO fix lines of lenghts > 128
ubyte iter }
}
for color in 1 to 15 { sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
xx = color * 16 ; Bresenham algorithm
yy = color + 20 byte d = 0
for iter in 0 to 80 { ubyte dx = abs(x2 - x1)
plot(xx, yy, color) ubyte dy = abs(y2 - y1)
xx++ ubyte dx2 = 2 * dx
yy+=2 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) {
sub circle(uword xcenter, ubyte ycenter, ubyte radius, ubyte color) {
; Midpoint algorithm ; Midpoint algorithm
ubyte x = radius ubyte x = radius
ubyte y = 0 ubyte y = 0
byte decisionOver2 = 1-x byte decisionOver2 = 1-x
while x>=y { while x>=y {
plot(xcenter + x, ycenter + y as ubyte, color) plot(xcenter + x, ycenter + y as ubyte)
plot(xcenter - x, ycenter + y as ubyte, color) plot(xcenter - x, ycenter + y as ubyte)
plot(xcenter + x, ycenter - y as ubyte, color) plot(xcenter + x, ycenter - y as ubyte)
plot(xcenter - x, ycenter - y as ubyte, color) plot(xcenter - x, ycenter - y as ubyte)
plot(xcenter + y, ycenter + x as ubyte, color) plot(xcenter + y, ycenter + x as ubyte)
plot(xcenter - y, ycenter + x as ubyte, color) plot(xcenter - y, ycenter + x as ubyte)
plot(xcenter + y, ycenter - x as ubyte, color) plot(xcenter + y, ycenter - x as ubyte)
plot(xcenter - y, ycenter - x as ubyte, color) plot(xcenter - y, ycenter - x as ubyte)
y++ y++
if decisionOver2<=0 if decisionOver2<=0
decisionOver2 += 2*y+1 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 ; Midpoint algorithm, filled
ubyte x = radius ubyte x = radius
ubyte y = 0 ubyte y = 0
@ -82,20 +110,20 @@ main {
while x>=y { while x>=y {
for xx in cx to cx+x { for xx in cx to cx+x {
plot(xx, cy + y as ubyte, color) plot(xx, cy + y as ubyte)
plot(xx, cy - y as ubyte, color) plot(xx, cy - y as ubyte)
} }
for xx in cx-x to cx-1 { for xx in cx-x to cx-1 {
plot(xx, cy + y as ubyte, color) plot(xx, cy + y as ubyte)
plot(xx, cy - y as ubyte, color) plot(xx, cy - y as ubyte)
} }
for xx in cx to cx+y { for xx in cx to cx+y {
plot(xx, cy + x as ubyte, color) plot(xx, cy + x as ubyte)
plot(xx, cy - x as ubyte, color) plot(xx, cy - x as ubyte)
} }
for xx in cx-y to cx { for xx in cx-y to cx {
plot(xx, cy + x as ubyte, color) plot(xx, cy + x as ubyte)
plot(xx, cy - x as ubyte, color) plot(xx, cy - x as ubyte)
} }
y++ y++
if decisionOver2<=0 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 ; 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] ubyte[] ormask = [128, 64, 32, 16, 8, 4, 2, 1]
uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000001111111000) uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000001111111000)
@(addr) |= ormask[lsb(px) & 7] @(addr) |= ormask[lsb(px) & 7]
ubyte sx = px >> 3
ubyte sy = py >> 3
c64.SCRATCH_ZPB1 = color << 4
c64scr.setchr(sx, sy)
} }
} }

View File

@ -80,10 +80,10 @@ main {
c64scr.setcc(x, y, 42, 5) c64scr.setcc(x, y, 42, 5)
if x==x2 if x==x2
return return
x += ix as ubyte x += ix
d += dy2 d += dy2
if d > dx { if d > dx {
y += iy as ubyte y += iy
d -= dx2 d -= dx2
} }
} }
@ -92,10 +92,10 @@ main {
c64scr.setcc(x, y, 42, 5) c64scr.setcc(x, y, 42, 5)
if y == y2 if y == y2
return return
y += iy as ubyte y += iy
d += dx2 d += dx2
if d > dy { if d > dy {
x += ix as ubyte x += ix
d -= dy2 d -= dy2
} }
} }
@ -104,19 +104,19 @@ main {
sub circle(ubyte xcenter, ubyte ycenter, ubyte radius) { sub circle(ubyte xcenter, ubyte ycenter, ubyte radius) {
; Midpoint algorithm ; Midpoint algorithm
byte x = radius as byte ubyte x = radius
byte y = 0 ubyte y = 0
byte decisionOver2 = 1-x byte decisionOver2 = 1-x
while x>=y { while x>=y {
c64scr.setcc(xcenter + x as ubyte, ycenter + y as ubyte, 81, 1) c64scr.setcc(xcenter + x, ycenter + y as ubyte, 81, 1)
c64scr.setcc(xcenter - x as ubyte, ycenter + y as ubyte, 81, 2) c64scr.setcc(xcenter - x, ycenter + y as ubyte, 81, 2)
c64scr.setcc(xcenter + x as ubyte, ycenter - y as ubyte, 81, 3) c64scr.setcc(xcenter + x, ycenter - y as ubyte, 81, 3)
c64scr.setcc(xcenter - x as ubyte, ycenter - y as ubyte, 81, 4) c64scr.setcc(xcenter - x, ycenter - y as ubyte, 81, 4)
c64scr.setcc(xcenter + y as ubyte, ycenter + x as ubyte, 81, 5) c64scr.setcc(xcenter + y, ycenter + x as ubyte, 81, 5)
c64scr.setcc(xcenter - y as ubyte, ycenter + x as ubyte, 81, 6) c64scr.setcc(xcenter - y, ycenter + x as ubyte, 81, 6)
c64scr.setcc(xcenter + y as ubyte, ycenter - x as ubyte, 81, 7) c64scr.setcc(xcenter + y, ycenter - x as ubyte, 81, 7)
c64scr.setcc(xcenter - y as ubyte, ycenter - x as ubyte, 81, 8) c64scr.setcc(xcenter - y, ycenter - x as ubyte, 81, 8)
y++ y++
if decisionOver2<=0 if decisionOver2<=0
decisionOver2 += 2*y+1 decisionOver2 += 2*y+1
@ -129,27 +129,27 @@ main {
sub disc(ubyte cx, ubyte cy, ubyte radius) { sub disc(ubyte cx, ubyte cy, ubyte radius) {
; Midpoint algorithm, filled ; Midpoint algorithm, filled
byte x = radius as byte ubyte x = radius
byte y = 0 ubyte y = 0
byte decisionOver2 = 1-x byte decisionOver2 = 1-x
byte xx ubyte xx
while x>=y { while x>=y {
for xx in cx to cx+x { for xx in cx to cx+x {
c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 1) c64scr.setcc(xx, 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, 2)
} }
for xx in cx-x to cx-1 { for xx in cx-x to cx-1 {
c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 3) c64scr.setcc(xx, 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, 4)
} }
for xx in cx to cx+y { for xx in cx to cx+y {
c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 5) c64scr.setcc(xx, 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, 6)
} }
for xx in cx-y to cx { for xx in cx-y to cx {
c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 7) c64scr.setcc(xx, 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, 8)
} }
y++ y++
if decisionOver2<=0 if decisionOver2<=0