mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
fix bresenham line
This commit is contained in:
parent
fac2a2d7cb
commit
fffe36e358
@ -14,6 +14,12 @@ import kotlin.math.pow
|
|||||||
/*
|
/*
|
||||||
todo add more expression optimizations
|
todo add more expression optimizations
|
||||||
|
|
||||||
|
x + x -> x << 1 (for words... for bytes too?)
|
||||||
|
x + x + x + x -> x << 2 (for words... for bytes too?)
|
||||||
|
x + x + x -> ???? x*3 ??? words/bytes?
|
||||||
|
x - x -> 0
|
||||||
|
|
||||||
|
|
||||||
Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html
|
Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@ -1,61 +1,53 @@
|
|||||||
%import c64lib
|
%import c64lib
|
||||||
%import c64utils
|
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
|
; bitmap pixel graphics module for the C64
|
||||||
|
; only black/white monchrome for now
|
||||||
|
|
||||||
main {
|
; you could put this code at $4000 which is after the bitmap screen in memory ($2000-$3fff),
|
||||||
|
; this leaves more space for user program code.
|
||||||
|
|
||||||
|
graphics {
|
||||||
const uword bitmap_address = $2000
|
const uword bitmap_address = $2000
|
||||||
|
|
||||||
|
sub enable_bitmap_mode() {
|
||||||
sub start() {
|
|
||||||
|
|
||||||
; enable bitmap screen, erase it and set colors to black/white.
|
; enable bitmap screen, erase it and set colors to black/white.
|
||||||
c64.SCROLY |= %00100000
|
c64.SCROLY |= %00100000
|
||||||
c64.VMCSB = (c64.VMCSB & %11110000) | %00001000 ; $2000-$3fff
|
c64.VMCSB = (c64.VMCSB & %11110000) | %00001000 ; $2000-$3fff
|
||||||
memset(bitmap_address, 320*200/8, 0)
|
memset(bitmap_address, 320*200/8, 0)
|
||||||
c64scr.clear_screen($10, 0)
|
c64scr.clear_screen($10, 0) ; pixel color $1 (white) backround $0 (black)
|
||||||
|
|
||||||
lines()
|
|
||||||
circles()
|
|
||||||
forever {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub line(uword x1, ubyte y1, uword x2, ubyte y2) {
|
||||||
sub circles() {
|
|
||||||
ubyte 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() {
|
|
||||||
ubyte ix
|
|
||||||
for ix in 1 to 15 {
|
|
||||||
line(10, 10, ix*4, 50) ; TODO fix lines of lenghts > 128
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
|
|
||||||
; Bresenham algorithm
|
; Bresenham algorithm
|
||||||
byte d = 0
|
word dx
|
||||||
ubyte dx = abs(x2 - x1)
|
word dy
|
||||||
ubyte dy = abs(y2 - y1)
|
byte ix = 1
|
||||||
ubyte dx2 = 2 * dx
|
byte iy = 1
|
||||||
ubyte dy2 = 2 * dy
|
if x2>x1 {
|
||||||
word ix = sgn(x2 as byte - x1 as byte)
|
dx = x2-x1
|
||||||
word iy = sgn(y2 as byte - y1 as byte)
|
} else {
|
||||||
|
ix = -1
|
||||||
|
dx = x1-x2
|
||||||
|
}
|
||||||
|
if y2>y1 {
|
||||||
|
dy = y2-y1
|
||||||
|
} else {
|
||||||
|
iy = -1
|
||||||
|
dy = y1-y2
|
||||||
|
}
|
||||||
|
word dx2 = 2 * dx
|
||||||
|
word dy2 = 2 * dy
|
||||||
|
word d = 0
|
||||||
plotx = x1
|
plotx = x1
|
||||||
|
|
||||||
if dx >= dy {
|
if dx >= dy {
|
||||||
|
if ix<0 {
|
||||||
forever {
|
forever {
|
||||||
plot(y1)
|
graphics.plot(y1)
|
||||||
if plotx==x2
|
if plotx==x2
|
||||||
return
|
return
|
||||||
plotx += ix
|
plotx--
|
||||||
d += dy2
|
d += dy2
|
||||||
if d > dx {
|
if d > dx {
|
||||||
y1 += iy
|
y1 += iy
|
||||||
@ -63,17 +55,44 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
forever {
|
||||||
|
graphics.plot(y1)
|
||||||
|
if plotx==x2
|
||||||
|
return
|
||||||
|
plotx++
|
||||||
|
d += dy2
|
||||||
|
if d > dx {
|
||||||
|
y1 += iy
|
||||||
|
d -= dx2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if iy<0 {
|
||||||
forever {
|
forever {
|
||||||
plot(y1)
|
plot(y1)
|
||||||
if y1 == y2
|
if y1 == y2
|
||||||
return
|
return
|
||||||
y1 += iy
|
y1--
|
||||||
d += dx2
|
d += dx2
|
||||||
if d > dy {
|
if d > dy {
|
||||||
plotx += ix
|
plotx += ix as word
|
||||||
d -= dy2
|
d -= dy2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
forever {
|
||||||
|
plot(y1)
|
||||||
|
if y1 == y2
|
||||||
|
return
|
||||||
|
y1++
|
||||||
|
d += dx2
|
||||||
|
if d > dy {
|
||||||
|
plotx += ix as word
|
||||||
|
d -= dy2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,6 +168,13 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; here is the non-asm code for the plot routine below:
|
||||||
|
; sub plot_nonasm(uword px, ubyte py) {
|
||||||
|
; ubyte[] ormask = [128, 64, 32, 16, 8, 4, 2, 1]
|
||||||
|
; uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000000111111000)
|
||||||
|
; @(addr) |= ormask[lsb(px) & 7]
|
||||||
|
; }
|
||||||
|
|
||||||
uword plotx ; 0..319
|
uword plotx ; 0..319
|
||||||
|
|
||||||
asmsub plot(ubyte ploty @A) { ; plotx is 16 bits 0 to 319... doesn't fit in a register
|
asmsub plot(ubyte ploty @A) { ; plotx is 16 bits 0 to 319... doesn't fit in a register
|
||||||
@ -219,13 +245,6 @@ _y_lookup_lo
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
; here is the non-asm code for the same plot routine:
|
|
||||||
; sub plot_nonasm(uword px, ubyte py) {
|
|
||||||
; ubyte[] ormask = [128, 64, 32, 16, 8, 4, 2, 1]
|
|
||||||
; uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000000111111000)
|
|
||||||
; @(addr) |= ormask[lsb(px) & 7]
|
|
||||||
; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
35
examples/line-circle-gfx.p8
Normal file
35
examples/line-circle-gfx.p8
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
%import c64lib
|
||||||
|
%import c64graphics
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
|
||||||
|
main {
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
graphics.enable_bitmap_mode()
|
||||||
|
draw_lines()
|
||||||
|
draw_circles()
|
||||||
|
forever {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub draw_circles() {
|
||||||
|
ubyte xx
|
||||||
|
for xx in 3 to 7 {
|
||||||
|
graphics.circle(xx*50-100, 10+xx*16, (xx+6)*4)
|
||||||
|
graphics.disc(xx*50-100, 10+xx*16, (xx+6)*2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub draw_lines() {
|
||||||
|
ubyte i
|
||||||
|
for i in 0 to 255 step 4 {
|
||||||
|
; uword x1 = (320-256)/2 + sin8u(i)
|
||||||
|
uword x1 = ((320-256)/2 as uword) + sin8u(i) ; TODO fix the need for a cast here
|
||||||
|
uword y1 = (200-128)/2 + cos8u(i)/2
|
||||||
|
uword x2 = ((320-64)/2 as uword) + sin8u(i)/4 ; TODO fix the need for a cast here
|
||||||
|
uword y2 = (200-64)/2 + cos8u(i)/4
|
||||||
|
graphics.line(x1, lsb(y1), x2, lsb(y2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -64,7 +64,8 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
|
sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
|
||||||
; Bresenham algorithm
|
; Bresenham algorithm, not very optimized to keep clear code.
|
||||||
|
; For a better optimized version have a look in the graphics.p8 module.
|
||||||
byte d = 0
|
byte d = 0
|
||||||
ubyte dx = abs(x2 - x1)
|
ubyte dx = abs(x2 - x1)
|
||||||
ubyte dy = abs(y2 - y1)
|
ubyte dy = abs(y2 - y1)
|
Loading…
Reference in New Issue
Block a user