added Cx16 highresbitmap example. added stippled drawing to gfx2 monochrome mode

This commit is contained in:
Irmen de Jong 2020-12-27 23:57:13 +01:00
parent 6cb0e6a936
commit 9e2c52e1ec
5 changed files with 155 additions and 55 deletions

View File

@ -6,7 +6,6 @@
; Note: for compatible graphics code that words on C64 too, use the "graphics" module instead.
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
; TODO this is in development. Add line drawing, circles and discs (like the graphics module has)
gfx2 {
@ -15,6 +14,7 @@ gfx2 {
uword width = 0
uword height = 0
ubyte bpp = 0
ubyte monochrome_dont_stipple_flag = false ; set to false to enable stippling mode in monochrome displaymodes
sub screen_mode(ubyte mode) {
; mode 0 = bitmap 320 x 240 x 1c monochrome
@ -77,6 +77,7 @@ gfx2 {
}
sub clear_screen() {
monochrome_stipple(false)
position(0, 0)
when active_mode {
0 -> {
@ -98,6 +99,10 @@ gfx2 {
position(0, 0)
}
sub monochrome_stipple(ubyte enable) {
monochrome_dont_stipple_flag = ~enable
}
sub rect(uword x, uword y, uword width, uword height, ubyte color) {
if width==0 or height==0
return
@ -289,8 +294,8 @@ gfx2 {
word @zp decisionOver2 = (1 as word)-radius
while radius>=yy {
horizontal_line(xcenter-radius, ycenter+yy, radius*2+1, color)
horizontal_line(xcenter-radius, ycenter-yy, radius*2+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*2+1, color)
yy++
@ -307,27 +312,54 @@ gfx2 {
ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1]
uword addr
ubyte value
when active_mode {
0 -> {
%asm {{
lda x
eor y
ora monochrome_dont_stipple_flag
and #1
}}
if_nz {
addr = x/8 + y*(320/8)
value = bits[lsb(x)&7]
if color
cx16.vpoke_or(0, addr, value)
else {
value = ~value
cx16.vpoke_and(0, addr, value)
}
}
}
128 -> {
%asm {{
lda x
eor y
ora monochrome_dont_stipple_flag
and #1
}}
if_nz {
addr = x/8 + y*(640/8)
value = bits[lsb(x)&7]
if color
cx16.vpoke_or(0, addr, value)
else {
value = ~value
cx16.vpoke_and(0, addr, value)
}
}
}
1 -> {
void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L
value = lsb(cx16.r1)
cx16.vpoke(value, cx16.r0, color)
}
}
; activate vera auto-increment mode so next_pixel() can be used after this
cx16.VERA_ADDR_H = (cx16.VERA_ADDR_H & %00000111) | %00010000
color = cx16.VERA_DATA0
}
}
}
sub position(uword @zp x, uword y) {
when active_mode {
@ -424,10 +456,18 @@ gfx2 {
lda cx16.VERA_ADDR_H
and #%111 ; don't auto-increment, we have to do that manually because of the ora
sta cx16.VERA_ADDR_H
lda color
sta P8ZP_SCRATCH_B1
ldy #8
- lda cx16.VERA_DATA0
- lda P8ZP_SCRATCH_B1
bne + ; white color, plot normally
lda cx16.VERA_DATA1
eor #255 ; black color, keep only the other pixels
and cx16.VERA_DATA0
bra ++
+ lda cx16.VERA_DATA0
ora cx16.VERA_DATA1
sta cx16.VERA_DATA0
+ sta cx16.VERA_DATA0
lda cx16.VERA_ADDR_L
clc
adc cx16.r2

View File

@ -91,10 +91,11 @@ gfx2 (cx16 only)
Full-screen multicolor bitmap graphics routines, available on the Cx16 machine only.
- multiple full-screen resolutions: 640 * 480 monochrome, and 320 * 240 monochrome and 256 colors
- clearing screen, switching screen mode
- drawing pixels
- clearing screen, switching screen mode, also back to text mode is possible.
- drawing individual pixels
- drawing lines, rectangles, filled rectangles, circles, discs
- drawing text inside the bitmap
- lines, rectangles, circles, discs.
- in monochrome mode, it's possible to use a stippled drawing pattern to simulate a shade of gray.
palette (cx16 only)

View File

@ -2,7 +2,8 @@
TODO
====
- implement gfx2's rect, fillrect, horizontal_line and vertical_line in graphics modules as well.
- nice error msg for float as for loop var
- implement gfx2's rect, fillrect, horizontal_line and vertical_line in graphics modules as well. (and optimize bresenham line to use vert/horiz line if possible)
- detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation
- hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine)
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_'

View File

@ -0,0 +1,87 @@
%target cx16
%import gfx2
%import floats
%import textio
%zeropage basicsafe
main {
sub start () {
gfx2.text_charset(3)
test_monochrome()
gfx2.screen_mode(255)
txt.print("done!\n")
}
sub test_monochrome() {
gfx2.screen_mode(128)
uword yy
uword xx
word ww
yy = 20
xx = 20
gfx2.monochrome_stipple(false)
gfx2.rect(xx, yy, 250, 80, 1)
gfx2.monochrome_stipple(true)
gfx2.fillrect(xx+2, yy+2, 250-4, 80-4, 1)
gfx2.monochrome_stipple(false)
gfx2.fillrect(xx+20, yy+20, 200, 30, 1)
gfx2.rect(xx+21, yy+21, 200-2, 30-2, 0)
gfx2.text(xx+30, yy+32, 0, @"High Res Bitmap Example")
; gfx2.monochrome_stipple(true)
gfx2.horizontal_line(10, 240, 620, 1)
gfx2.vertical_line(320, 10, 460, 1)
gfx2.text(320, 242, 1, @"0,0")
gfx2.text(322, 10, 1, @"Y-axis")
gfx2.text(590, 242, 1, @"X-axis")
for ww in -10 to 10 {
xx = (ww*30) + 320 as uword
gfx2.vertical_line(xx, 239, 3, 1)
}
for ww in -7 to 7 {
yy = (ww*30) + 240 as uword
gfx2.horizontal_line(319, yy, 3, 1)
}
gfx2.monochrome_stipple(false)
float y_f
for ww in -600 to 600 {
y_f = sin(ww as float / 60.0)*150
gfx2.plot(ww/2 + 320 as uword, (y_f + 240) as uword, 1)
}
gfx2.text(480, 100, 1, @"sin(x)")
for ww in -300 to 300 {
y_f = cos(ww as float/30.0)*60 - (ww as float)/1.7
gfx2.plot(ww + 320 as uword, (y_f + 240) as uword, 1)
}
gfx2.text(80, 420, 1, @"cos(x)+x")
cx16.wait(3*60)
gfx2.circle(320, 240, 220, 1)
gfx2.circle(320, 240, 210, 1)
gfx2.circle(320, 240, 200, 1)
gfx2.circle(320, 240, 190, 1)
gfx2.monochrome_stipple(true)
gfx2.disc(320, 240, 140, 1)
gfx2.monochrome_stipple(false)
gfx2.disc(320, 240, 90, 1)
gfx2.disc(320, 240, 40, 0)
cx16.wait(2*60)
repeat 255 {
xx=rndw() % 640 ; TODO doesn't work correctly, truncates
yy=rndw() % 480 ; TODO doesn't work correctly, truncates
gfx2.line(xx, yy, rndw() % 640, rndw() % 480, 1)
}
cx16.wait(1*60)
}
}

View File

@ -7,46 +7,17 @@ main {
sub start () {
uword length
uword total = 0
length=200
count()
txt.print_uw(total)
txt.chrout('\n')
length=255
count()
txt.print_uw(total)
txt.chrout('\n')
length=256
count()
txt.print_uw(total)
txt.chrout('\n')
length=257
count()
txt.print_uw(total)
txt.chrout('\n')
length=9999
count()
txt.print_uw(total)
txt.chrout('\n')
; TODO uword var = rndw() % 640 doesn't work??? works if its in an expression.
test_stack.test()
sub count() {
total = 0
if length>256 {
repeat length-1
total++
} else {
uword total2
repeat lsb(length-1)
total++
; repeat (length-1) as ubyte ; TODO lsb(length-1) doesn't work!?!?!?
; total++
}
x_f = -300.0
for ww in -300 to 300 {
;fl = ww as float / 10.0 ; TODO doesn't work???
y_f = cos(x_f/30)*60 - x_f/1.7
gfx2.plot(ww + 320 as uword, (y_f + 240) as uword, 1)
x_f += 1.0
}
}