mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
gfx2 optimizations for horizontal lines, fix bug in disc drawing
This commit is contained in:
parent
4b366358c4
commit
51f32677b7
@ -101,7 +101,7 @@ gfx2 {
|
||||
}
|
||||
|
||||
sub monochrome_stipple(ubyte enable) {
|
||||
monochrome_dont_stipple_flag = ~enable
|
||||
monochrome_dont_stipple_flag = not enable
|
||||
}
|
||||
|
||||
sub rect(uword x, uword y, uword width, uword height, ubyte color) {
|
||||
@ -132,23 +132,95 @@ gfx2 {
|
||||
when active_mode {
|
||||
1 -> {
|
||||
; 8bpp mode
|
||||
gfx2.plot(x, y, color)
|
||||
repeat length-1
|
||||
gfx2.next_pixel(color)
|
||||
position(x, y)
|
||||
%asm {{
|
||||
lda color
|
||||
phx
|
||||
ldx length+1
|
||||
beq +
|
||||
ldy #0
|
||||
- sta cx16.VERA_DATA0
|
||||
iny
|
||||
bne -
|
||||
dex
|
||||
bne -
|
||||
+ ldy length ; remaining
|
||||
beq +
|
||||
- sta cx16.VERA_DATA0
|
||||
dey
|
||||
bne -
|
||||
+ plx
|
||||
}}
|
||||
}
|
||||
0, 128 -> {
|
||||
; 1 bpp mode
|
||||
; TODO optimize this to plot 8 pixels at once while possible, note: do mind the stipple setting and color 0 black
|
||||
repeat length {
|
||||
gfx2.plot(x, y, color)
|
||||
ubyte separate_pixels = (8-lsb(x)) & 7
|
||||
if separate_pixels as uword > length
|
||||
separate_pixels = lsb(length)
|
||||
repeat separate_pixels {
|
||||
; this could be optimized by setting this byte in 1 go but probably not worth it due to code size
|
||||
plot(x, y, color)
|
||||
x++
|
||||
}
|
||||
length -= separate_pixels
|
||||
if length {
|
||||
position(x, y)
|
||||
separate_pixels = lsb(length) & 7
|
||||
x += length & $fff8
|
||||
%asm {{
|
||||
lsr length+1
|
||||
ror length
|
||||
lsr length+1
|
||||
ror length
|
||||
lsr length+1
|
||||
ror length
|
||||
lda color
|
||||
bne +
|
||||
ldy #0 ; black
|
||||
bra _loop
|
||||
+ lda monochrome_dont_stipple_flag
|
||||
beq _stipple
|
||||
ldy #255 ; don't stipple
|
||||
bra _loop
|
||||
_stipple lda y
|
||||
and #1 ; determine stipple pattern to use
|
||||
bne +
|
||||
ldy #%01010101
|
||||
bra _loop
|
||||
+ ldy #%10101010
|
||||
_loop lda length
|
||||
ora length+1
|
||||
beq _done
|
||||
sty cx16.VERA_DATA0
|
||||
lda length
|
||||
bne +
|
||||
dec length+1
|
||||
+ dec length
|
||||
bra _loop
|
||||
_done
|
||||
}}
|
||||
repeat separate_pixels {
|
||||
; this could be optimized by setting this byte in 1 go but probably not worth it due to code size
|
||||
plot(x, y, color)
|
||||
x++
|
||||
}
|
||||
}
|
||||
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) ; vera auto-increment off again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub vertical_line(uword x, uword y, uword height, ubyte color) {
|
||||
; TODO optimize this to use vera special increment mode, note: do mind the stipple setting and color 0 black
|
||||
if active_mode==1 {
|
||||
; TODO for the 320x256 8bbp mode use vera auto increment
|
||||
repeat lsb(height) {
|
||||
plot(x, y, color)
|
||||
y++
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
; note for the 1 bpp modes we can't use vera's auto increment mode because we have to 'or' the pixel data in place.
|
||||
repeat height {
|
||||
plot(x, y, color)
|
||||
y++
|
||||
@ -297,8 +369,8 @@ gfx2 {
|
||||
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*2+1, color)
|
||||
horizontal_line(xcenter-yy, ycenter-radius, yy*2+1, color)
|
||||
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
|
||||
@ -382,26 +454,42 @@ gfx2 {
|
||||
|
||||
inline asmsub next_pixel(ubyte color @A) {
|
||||
; -- sets the next pixel byte to the graphics chip.
|
||||
; for 8 bpp screens this will plot 1 pixel. for 1 bpp screens it will actually plot 8 pixels at once (bitmask).
|
||||
; For super fast pixel plotting, don't call this subroutine but instead just use the assignment: cx16.VERA_DATA0 = color
|
||||
; for 8 bpp screens this will plot 1 pixel.
|
||||
; for 1 bpp screens it will plot 8 pixels at once (color = bit pattern).
|
||||
%asm {{
|
||||
sta cx16.VERA_DATA0
|
||||
}}
|
||||
}
|
||||
|
||||
sub next_pixels(uword pixels, uword amount) {
|
||||
asmsub next_pixels(uword pixels @AY, uword amount @R0) {
|
||||
; -- sets the next bunch of pixels from a prepared array of bytes.
|
||||
; for 8 bpp screens this will plot 1 pixel per byte, but for 1 bpp screens the bytes contain 8 pixels each.
|
||||
repeat msb(amount) {
|
||||
repeat 256 {
|
||||
cx16.VERA_DATA0 = @(pixels)
|
||||
pixels++
|
||||
}
|
||||
}
|
||||
repeat lsb(amount) {
|
||||
cx16.VERA_DATA0 = @(pixels)
|
||||
pixels++
|
||||
}
|
||||
; for 8 bpp screens this will plot 1 pixel per byte.
|
||||
; for 1 bpp screens it will plot 8 pixels at once (colors are the bit patterns per byte).
|
||||
%asm {{
|
||||
phx
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldx cx16.r0+1
|
||||
beq +
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.VERA_DATA0
|
||||
iny
|
||||
bne -
|
||||
inc P8ZP_SCRATCH_W1+1 ; next page of 256 pixels
|
||||
dex
|
||||
bne -
|
||||
|
||||
+ ldx cx16.r0 ; remaining pixels
|
||||
beq +
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta cx16.VERA_DATA0
|
||||
iny
|
||||
dex
|
||||
bne -
|
||||
+ plx
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) {
|
||||
|
@ -1,11 +1,133 @@
|
||||
%target cx16
|
||||
%import gfx2
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%import test_stack
|
||||
%zeropage dontuse
|
||||
|
||||
main {
|
||||
|
||||
sub start () {
|
||||
sub start() {
|
||||
gfx2.screen_mode(1)
|
||||
|
||||
uword pixels = memory("pixels", 320)
|
||||
uword yy = 10
|
||||
uword xx = gfx2.width/2
|
||||
uword pp
|
||||
uword cnt
|
||||
pp=pixels
|
||||
|
||||
for xx in 10 to 300 {
|
||||
gfx2.vertical_line(xx, 10, 220, 1)
|
||||
}
|
||||
gfx2.screen_mode(255)
|
||||
txt.print("done!\n")
|
||||
return
|
||||
|
||||
|
||||
for cnt in 0 to 319 {
|
||||
@(pp) = 255
|
||||
pp++
|
||||
}
|
||||
|
||||
gfx2.monochrome_stipple(false)
|
||||
linesy()
|
||||
linesx()
|
||||
gfx2.monochrome_stipple(true)
|
||||
linesy()
|
||||
linesx()
|
||||
|
||||
sub linesx() {
|
||||
repeat 8 {
|
||||
gfx2.horizontal_line(10,yy,300,3)
|
||||
yy++
|
||||
}
|
||||
yy+=4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.line(10,yy,309,yy,4)
|
||||
yy++
|
||||
}
|
||||
yy+=4
|
||||
|
||||
repeat 8 {
|
||||
for cnt in 10 to 309 {
|
||||
gfx2.plot(cnt, yy, 1)
|
||||
}
|
||||
yy+=1
|
||||
}
|
||||
yy += 4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.horizontal_line(10,yy,100,3)
|
||||
yy++
|
||||
}
|
||||
yy+=4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.line(10,yy,109,yy,4)
|
||||
yy++
|
||||
}
|
||||
yy+=4
|
||||
|
||||
repeat 8 {
|
||||
for cnt in 10 to 109 {
|
||||
gfx2.plot(cnt, yy, 1)
|
||||
}
|
||||
yy++
|
||||
}
|
||||
yy+=4
|
||||
}
|
||||
|
||||
sub linesy() {
|
||||
repeat 8 {
|
||||
gfx2.vertical_line(xx,10,300,3)
|
||||
xx++
|
||||
}
|
||||
xx+=4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.line(xx,10, xx, 309, 4)
|
||||
xx++
|
||||
}
|
||||
xx+=4
|
||||
|
||||
repeat 8 {
|
||||
for cnt in 10 to 309 {
|
||||
gfx2.plot(xx, cnt, 1)
|
||||
}
|
||||
xx+=1
|
||||
}
|
||||
xx += 4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.vertical_line(xx,10,100,3)
|
||||
xx++
|
||||
}
|
||||
xx+=4
|
||||
|
||||
repeat 8 {
|
||||
gfx2.line(xx,10,xx,109,4)
|
||||
xx++
|
||||
}
|
||||
xx+=4
|
||||
|
||||
repeat 8 {
|
||||
for cnt in 10 to 109 {
|
||||
gfx2.plot(xx, cnt, 1)
|
||||
}
|
||||
xx++
|
||||
}
|
||||
xx+=4
|
||||
}
|
||||
|
||||
; cx16.wait(3*60)
|
||||
gfx2.screen_mode(255)
|
||||
txt.print("done!\n")
|
||||
|
||||
test_stack.test()
|
||||
}
|
||||
|
||||
sub start2 () {
|
||||
gfx2.text_charset(3)
|
||||
|
||||
ubyte[] modes = [1, 0, 128]
|
||||
@ -18,6 +140,7 @@ main {
|
||||
|
||||
gfx2.screen_mode(255)
|
||||
txt.print("done!\n")
|
||||
test_stack.test()
|
||||
}
|
||||
|
||||
sub draw() {
|
||||
|
@ -9,6 +9,16 @@ main {
|
||||
|
||||
sub start () {
|
||||
|
||||
; differences between:
|
||||
; @(pp) = cnt as ubyte
|
||||
; @(pp) = lsb(cnt)
|
||||
; @(pp) = msb(cnt)
|
||||
; repeat w as ubyte / repeat lsb(w)
|
||||
|
||||
; stack based evaluation for this function call even when it's inlined:
|
||||
; gfx2.next_pixel((cnt as ubyte) + 30)
|
||||
|
||||
|
||||
test_stack.test()
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user