mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
added Cx16 highresbitmap example. added stippled drawing to gfx2 monochrome mode
This commit is contained in:
parent
6cb0e6a936
commit
9e2c52e1ec
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 '_'
|
||||
|
87
examples/cx16/highresbitmap.p8
Normal file
87
examples/cx16/highresbitmap.p8
Normal 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)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user