cx16: graphics module y resolution corrected from 200 to 240. added 'cx16/circles' example.

This commit is contained in:
Irmen de Jong 2022-07-17 15:04:15 +02:00
parent 5189eaca36
commit 7d4695c5b2
5 changed files with 125 additions and 17 deletions

View File

@ -2,15 +2,20 @@
%import textio
; Bitmap pixel graphics module for the CommanderX16
; wraps the graphics functions that are in ROM.
; only black/white monochrome 320x200 for now. (i.e. truncated at the bottom)
; For full-screen 640x480 or 320x240 graphics, use the "gfx2" module instead. (but that is Cx16-specific)
; Wraps the graphics functions that are in ROM.
; Only lo-res 320x240 256 color mode for now.
; Unlike graphics module on the C64, you can use colors() to set new drawing colors for every draw operation.
; For other resolutions or other color modes, use the "gfx2" module instead. (which is Cx16-specific)
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
graphics {
const uword WIDTH = 320
const ubyte HEIGHT = 200
const ubyte HEIGHT = 240
ubyte stroke_color = 1
ubyte background_color = 0
sub enable_bitmap_mode() {
; enable bitmap screen, erase it and set colors to black/white.
@ -27,10 +32,18 @@ graphics {
sub clear_screen(ubyte pixelcolor, ubyte bgcolor) {
stroke_color = pixelcolor
background_color = bgcolor
cx16.GRAPH_set_colors(pixelcolor, pixelcolor, bgcolor)
cx16.GRAPH_clear()
}
sub colors(ubyte stroke, ubyte fill) {
; this routine is only available on the cx16, other targets can't change colors on the fly
cx16.GRAPH_set_colors(stroke, fill, background_color)
stroke_color = stroke
}
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
cx16.GRAPH_draw_line(x1, y1, x2, y2)
}
@ -71,31 +84,31 @@ graphics {
cx16.r0 = xcenter + xx
cx16.r1 = ycenter + yy
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter - xx
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter + xx
cx16.r1 = ycenter - yy
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter - xx
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter + yy
cx16.r1 = ycenter + xx
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter - yy
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter + yy
cx16.r1 = ycenter - xx
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
cx16.r0 = xcenter - yy
cx16.FB_cursor_position2()
cx16.FB_set_pixel(1)
cx16.FB_set_pixel(stroke_color)
yy++
if decisionOver2<=0 {
decisionOver2 += (yy as word)*2+1

View File

@ -94,6 +94,7 @@ class TestCompilerOnExamplesCx16: FunSpec({
"amiga",
"bdmusic",
"bobs",
"circles",
"cobramk3-gfx",
"colorbars",
"datetime",

View File

@ -3,6 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- uword x, ubyte radius; (x as word - radius) > 0 is ok , but (x as word - radius) >=0 is incorrect?
- add item to XZeropage that enables an option that if zeropage=FULL or KERNALSAFE, moves the cx16 virtual registers to ZP, same location as on x16
(can be done on C64 only for now) Remove those addresses from the ZP free pool = allocate them in ZP like Cx16Zeropage does
Adapt the code in AstPreprocessor that relocates the registers as well.

89
examples/cx16/circles.p8 Normal file
View File

@ -0,0 +1,89 @@
%import floats
%import graphics
; note: this program is tuned for the CX16, but with some minor modifications can run on other systems too.
main {
const ubyte MAX_NUM_CIRCLES = 80
const ubyte GROWTH_RATE = 2
uword[MAX_NUM_CIRCLES] circle_x
uword[MAX_NUM_CIRCLES] circle_y
ubyte[MAX_NUM_CIRCLES] circle_radius
ubyte num_circles = 0
sub start() {
graphics.enable_bitmap_mode()
repeat {
graphics.clear_screen(1, 0)
num_circles = 0
draw_circles()
}
}
sub draw_circles() {
uword @zp x
uword @zp y
ubyte @zp radius
while num_circles<MAX_NUM_CIRCLES {
x = rndw() % graphics.WIDTH
y = rndw() % graphics.HEIGHT
color = 0
radius = GROWTH_RATE * 2 ; use a bit of a buffer between circles.
if not_colliding() {
radius -= GROWTH_RATE
ubyte color = 0
while not color
color = rnd()
graphics.colors(color, 0)
while not_edge() and not_colliding() {
graphics.disc(x, y as ubyte, radius)
sys.waitvsync()
radius += GROWTH_RATE
}
circle_x[num_circles] = x
circle_y[num_circles] = y
circle_radius[num_circles] = radius - GROWTH_RATE
num_circles++
}
}
sub not_colliding() -> bool {
if num_circles==0
return true
ubyte @zp c
for c in 0 to num_circles-1 {
if distance(c) < (radius as uword) + circle_radius[c]
return false
}
return true
}
sub distance(ubyte cix) -> uword {
word dx = x as word - circle_x[cix]
word dy = y as word - circle_y[cix]
uword sqx = dx*dx as uword
uword sqy = dy*dy as uword
return sqrt16(sqx + sqy)
}
; sub distance(ubyte cix) -> uword {
; float dx = x as float - circle_x[cix]
; float dy = y as float - circle_y[cix]
; return floats.sqrt(dx*dx + dy*dy) as uword
; }
sub not_edge() -> bool {
if x as word - radius < 0
return false
if x + radius >= graphics.WIDTH
return false
if y as word - radius < 0
return false
if y + radius >= graphics.HEIGHT
return false
return true
}
}
}

View File

@ -2,11 +2,15 @@
%zeropage basicsafe
main {
sub func(ubyte bb) {
bb++
}
sub start() {
func("abc")
ubyte ci
ubyte from=10
ubyte end=1
for ci in from to end {
txt.print_ub(ci)
txt.spc()
}
txt.nl()
}
}