mirror of
https://github.com/irmen/prog8.git
synced 2024-11-23 07:32:10 +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) {
|
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) {
|
sub rect(uword x, uword y, uword width, uword height, ubyte color) {
|
||||||
@ -132,23 +132,95 @@ gfx2 {
|
|||||||
when active_mode {
|
when active_mode {
|
||||||
1 -> {
|
1 -> {
|
||||||
; 8bpp mode
|
; 8bpp mode
|
||||||
gfx2.plot(x, y, color)
|
position(x, y)
|
||||||
repeat length-1
|
%asm {{
|
||||||
gfx2.next_pixel(color)
|
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 -> {
|
0, 128 -> {
|
||||||
; 1 bpp mode
|
; 1 bpp mode
|
||||||
; TODO optimize this to plot 8 pixels at once while possible, note: do mind the stipple setting and color 0 black
|
ubyte separate_pixels = (8-lsb(x)) & 7
|
||||||
repeat length {
|
if separate_pixels as uword > length
|
||||||
gfx2.plot(x, y, color)
|
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++
|
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) {
|
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 {
|
repeat height {
|
||||||
plot(x, y, color)
|
plot(x, y, color)
|
||||||
y++
|
y++
|
||||||
@ -297,8 +369,8 @@ gfx2 {
|
|||||||
while radius>=yy {
|
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-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*$0002+1, color)
|
||||||
horizontal_line(xcenter-yy, ycenter-radius, yy*2+1, color)
|
horizontal_line(xcenter-yy, ycenter-radius, yy*$0002+1, color)
|
||||||
yy++
|
yy++
|
||||||
if decisionOver2<=0
|
if decisionOver2<=0
|
||||||
decisionOver2 += (yy as word)*2+1
|
decisionOver2 += (yy as word)*2+1
|
||||||
@ -382,26 +454,42 @@ gfx2 {
|
|||||||
|
|
||||||
inline asmsub next_pixel(ubyte color @A) {
|
inline asmsub next_pixel(ubyte color @A) {
|
||||||
; -- sets the next pixel byte to the graphics chip.
|
; -- 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 8 bpp screens this will plot 1 pixel.
|
||||||
; For super fast pixel plotting, don't call this subroutine but instead just use the assignment: cx16.VERA_DATA0 = color
|
; for 1 bpp screens it will plot 8 pixels at once (color = bit pattern).
|
||||||
%asm {{
|
%asm {{
|
||||||
sta cx16.VERA_DATA0
|
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.
|
; -- 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.
|
; for 8 bpp screens this will plot 1 pixel per byte.
|
||||||
repeat msb(amount) {
|
; for 1 bpp screens it will plot 8 pixels at once (colors are the bit patterns per byte).
|
||||||
repeat 256 {
|
%asm {{
|
||||||
cx16.VERA_DATA0 = @(pixels)
|
phx
|
||||||
pixels++
|
sta P8ZP_SCRATCH_W1
|
||||||
}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
}
|
ldx cx16.r0+1
|
||||||
repeat lsb(amount) {
|
beq +
|
||||||
cx16.VERA_DATA0 = @(pixels)
|
ldy #0
|
||||||
pixels++
|
- 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) {
|
asmsub set_8_pixels_from_bits(ubyte bits @R0, ubyte oncolor @A, ubyte offcolor @Y) {
|
||||||
|
@ -1,11 +1,133 @@
|
|||||||
%target cx16
|
%target cx16
|
||||||
%import gfx2
|
%import gfx2
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%import test_stack
|
||||||
|
%zeropage dontuse
|
||||||
|
|
||||||
main {
|
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)
|
gfx2.text_charset(3)
|
||||||
|
|
||||||
ubyte[] modes = [1, 0, 128]
|
ubyte[] modes = [1, 0, 128]
|
||||||
@ -18,6 +140,7 @@ main {
|
|||||||
|
|
||||||
gfx2.screen_mode(255)
|
gfx2.screen_mode(255)
|
||||||
txt.print("done!\n")
|
txt.print("done!\n")
|
||||||
|
test_stack.test()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub draw() {
|
sub draw() {
|
||||||
|
@ -9,6 +9,16 @@ main {
|
|||||||
|
|
||||||
sub start () {
|
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()
|
test_stack.test()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user