2020-09-22 00:12:01 +00:00
|
|
|
%import syslib
|
2020-11-22 17:17:43 +00:00
|
|
|
%import textio
|
2020-09-22 00:12:01 +00:00
|
|
|
|
2020-12-25 01:59:19 +00:00
|
|
|
; Bitmap pixel graphics module for the CommanderX16
|
2022-07-17 13:04:15 +00:00
|
|
|
; 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)
|
2020-12-26 12:38:14 +00:00
|
|
|
; Note: there is no color palette manipulation here, you have to do that yourself or use the "palette" module.
|
|
|
|
|
2020-09-22 00:12:01 +00:00
|
|
|
|
|
|
|
graphics {
|
2023-06-29 22:29:50 +00:00
|
|
|
%option no_symbol_prefixing
|
|
|
|
|
2020-09-22 19:50:56 +00:00
|
|
|
const uword WIDTH = 320
|
2022-07-17 13:04:15 +00:00
|
|
|
const ubyte HEIGHT = 240
|
|
|
|
|
|
|
|
|
|
|
|
ubyte stroke_color = 1
|
|
|
|
ubyte background_color = 0
|
2020-09-22 00:12:01 +00:00
|
|
|
|
|
|
|
sub enable_bitmap_mode() {
|
|
|
|
; enable bitmap screen, erase it and set colors to black/white.
|
2022-03-31 16:17:28 +00:00
|
|
|
void cx16.screen_mode($80, false)
|
2020-12-21 19:38:00 +00:00
|
|
|
cx16.GRAPH_init(0)
|
2020-09-22 00:12:01 +00:00
|
|
|
clear_screen(1, 0)
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:17:43 +00:00
|
|
|
sub disable_bitmap_mode() {
|
|
|
|
; enables text mode, erase the text screen, color white
|
2022-03-31 16:17:28 +00:00
|
|
|
void cx16.screen_mode(0, false)
|
2020-12-05 23:01:19 +00:00
|
|
|
txt.fill_screen(' ', 1) ; doesn't seem to fully clear the text screen after returning from gfx mode
|
2020-11-22 17:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-22 00:12:01 +00:00
|
|
|
sub clear_screen(ubyte pixelcolor, ubyte bgcolor) {
|
2022-07-17 13:04:15 +00:00
|
|
|
stroke_color = pixelcolor
|
|
|
|
background_color = bgcolor
|
2020-09-22 00:12:01 +00:00
|
|
|
cx16.GRAPH_set_colors(pixelcolor, pixelcolor, bgcolor)
|
|
|
|
cx16.GRAPH_clear()
|
|
|
|
}
|
|
|
|
|
2022-07-17 13:04:15 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-09-22 00:12:01 +00:00
|
|
|
sub line(uword @zp x1, ubyte @zp y1, uword @zp x2, ubyte @zp y2) {
|
2020-12-21 19:38:00 +00:00
|
|
|
cx16.GRAPH_draw_line(x1, y1, x2, y2)
|
2020-09-22 00:12:01 +00:00
|
|
|
}
|
|
|
|
|
2020-12-29 22:46:48 +00:00
|
|
|
sub fillrect(uword x, uword y, uword width, uword height) {
|
|
|
|
cx16.GRAPH_draw_rect(x, y, width, height, 0, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
sub rect(uword x, uword y, uword width, uword height) {
|
|
|
|
cx16.GRAPH_draw_rect(x, y, width, height, 0, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
sub horizontal_line(uword x, uword y, uword length) {
|
|
|
|
if length
|
|
|
|
cx16.GRAPH_draw_line(x, y, x+length-1, y)
|
|
|
|
}
|
|
|
|
|
|
|
|
sub vertical_line(uword x, uword y, uword height) {
|
|
|
|
if height
|
|
|
|
cx16.GRAPH_draw_line(x, y, x, y+height-1)
|
|
|
|
}
|
|
|
|
|
2020-09-22 00:12:01 +00:00
|
|
|
sub circle(uword xcenter, ubyte ycenter, ubyte radius) {
|
2020-09-22 00:52:09 +00:00
|
|
|
;cx16.r0 = xcenter - radius/2
|
|
|
|
;cx16.r1 = ycenter - radius/2
|
|
|
|
;cx16.r2 = radius*2
|
|
|
|
;cx16.r3 = radius*2
|
2020-12-05 23:01:19 +00:00
|
|
|
;cx16.GRAPH_draw_oval(false) ; currently this call is not implemented on cx16, does a BRK
|
2020-09-22 00:52:09 +00:00
|
|
|
|
|
|
|
; Midpoint algorithm
|
2020-12-27 16:34:25 +00:00
|
|
|
if radius==0
|
|
|
|
return
|
2020-09-22 00:52:09 +00:00
|
|
|
ubyte @zp xx = radius
|
|
|
|
ubyte @zp yy = 0
|
2020-12-29 22:46:48 +00:00
|
|
|
word @zp decisionOver2 = (1 as word)-xx
|
2020-09-22 00:52:09 +00:00
|
|
|
|
|
|
|
while xx>=yy {
|
|
|
|
cx16.r0 = xcenter + xx
|
|
|
|
cx16.r1 = ycenter + yy
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter - xx
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter + xx
|
|
|
|
cx16.r1 = ycenter - yy
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter - xx
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter + yy
|
|
|
|
cx16.r1 = ycenter + xx
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter - yy
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter + yy
|
|
|
|
cx16.r1 = ycenter - xx
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
cx16.r0 = xcenter - yy
|
2020-12-21 20:04:29 +00:00
|
|
|
cx16.FB_cursor_position2()
|
2022-07-17 13:04:15 +00:00
|
|
|
cx16.FB_set_pixel(stroke_color)
|
2020-09-22 00:52:09 +00:00
|
|
|
yy++
|
|
|
|
if decisionOver2<=0 {
|
2020-12-29 22:46:48 +00:00
|
|
|
decisionOver2 += (yy as word)*2+1
|
2020-09-22 00:52:09 +00:00
|
|
|
} else {
|
|
|
|
xx--
|
2020-12-29 22:46:48 +00:00
|
|
|
decisionOver2 += (yy as word -xx)*2+1
|
2020-09-22 00:52:09 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-22 00:12:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub disc(uword xcenter, ubyte ycenter, ubyte radius) {
|
2020-12-27 16:34:25 +00:00
|
|
|
if radius==0
|
|
|
|
return
|
|
|
|
ubyte @zp yy = 0
|
2020-12-29 22:46:48 +00:00
|
|
|
word decisionOver2 = (1 as word)-radius
|
2020-09-22 00:52:09 +00:00
|
|
|
|
2020-12-29 22:46:48 +00:00
|
|
|
while radius>=yy {
|
2020-12-29 22:58:11 +00:00
|
|
|
horizontal_line(xcenter-radius, ycenter+yy, radius*2+1)
|
|
|
|
horizontal_line(xcenter-radius, ycenter-yy, radius*2+1)
|
|
|
|
horizontal_line(xcenter-yy, ycenter+radius, yy*2+1)
|
|
|
|
horizontal_line(xcenter-yy, ycenter-radius, yy*2+1)
|
2020-09-22 00:52:09 +00:00
|
|
|
yy++
|
|
|
|
if decisionOver2<=0
|
2020-12-29 22:46:48 +00:00
|
|
|
decisionOver2 += (yy as word)*2+1
|
2020-09-22 00:52:09 +00:00
|
|
|
else {
|
2020-12-29 22:46:48 +00:00
|
|
|
radius--
|
|
|
|
decisionOver2 += (yy as word -radius)*2+1
|
2020-09-22 00:52:09 +00:00
|
|
|
}
|
|
|
|
}
|
2020-09-22 00:12:01 +00:00
|
|
|
}
|
|
|
|
|
2020-12-30 15:59:31 +00:00
|
|
|
inline asmsub plot(uword plotx @R0, uword ploty @R1) clobbers(A, X, Y) {
|
2020-12-26 04:33:00 +00:00
|
|
|
%asm {{
|
|
|
|
jsr cx16.FB_cursor_position
|
2023-03-24 00:56:29 +00:00
|
|
|
lda graphics.stroke_color
|
2020-12-26 04:33:00 +00:00
|
|
|
jsr cx16.FB_set_pixel
|
|
|
|
}}
|
2020-09-22 00:12:01 +00:00
|
|
|
}
|
|
|
|
}
|