add monogfx inverted (eor) draw mode

This commit is contained in:
Irmen de Jong
2024-03-03 22:35:54 +01:00
parent 449461e412
commit 4d7e96d423
8 changed files with 124 additions and 68 deletions

View File

@@ -8,6 +8,7 @@
; NOTE: For sake of speed, NO BOUNDS CHECKING is performed in most routines!
; You'll have to make sure yourself that you're not writing outside of bitmap boundaries!
;
; TODO: implement invert mode for horizontal lines (will fix disc and fillrect as well)
monogfx {
@@ -16,7 +17,10 @@ monogfx {
; read-only control variables:
uword width = 0
uword height = 0
bool dont_stipple_flag = true ; set to false to enable stippling mode
ubyte mode
const ubyte MODE_NORMAL = %00000000
const ubyte MODE_STIPPLE = %00000001
const ubyte MODE_INVERT = %00000010
sub lores() {
; enable 320*240 bitmap mode
@@ -29,6 +33,7 @@ monogfx {
cx16.VERA_L1_TILEBASE = 0
width = 320
height = 240
mode = MODE_NORMAL
clear_screen(0)
}
@@ -43,6 +48,7 @@ monogfx {
cx16.VERA_L1_TILEBASE = %00000001
width = 640
height = 480
mode = MODE_NORMAL
clear_screen(0)
}
@@ -53,8 +59,11 @@ monogfx {
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11111000) | cx16.r15L
}
sub drawmode(ubyte dm) {
mode = dm
}
sub clear_screen(ubyte color) {
stipple(false)
position(0, 0)
when width {
320 -> {
@@ -69,10 +78,6 @@ monogfx {
position(0, 0)
}
sub stipple(bool enable) {
dont_stipple_flag = not enable
}
sub rect(uword xx, uword yy, uword rwidth, uword rheight, bool draw) {
if rwidth==0 or rheight==0
return
@@ -122,8 +127,9 @@ monogfx {
bne -
sta cx16.r0L ; new left byte
+
lda p8v_dont_stipple_flag
bne _dontstipple
lda p8v_mode
lsr a
bcc _dontstipple
; determine stipple pattern
lda p8v_yy
and #1
@@ -163,7 +169,7 @@ _clear
ubyte separate_pixels = (8-lsb(xx)) & 7
if separate_pixels {
if dont_stipple_flag {
if mode!=MODE_STIPPLE {
position(xx,yy)
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
if draw
@@ -194,8 +200,9 @@ _clear
bne +
ldy #0 ; black
bra _loop
+ lda p8v_dont_stipple_flag
beq _stipple
+ lda p8v_mode
lsr a
bcs _stipple
ldy #255 ; don't stipple
bra _loop
_stipple lda p8v_yy
@@ -216,7 +223,7 @@ _loop lda p8v_length
_done
}}
if dont_stipple_flag {
if mode!=MODE_STIPPLE {
cx16.VERA_ADDR_H &= %00000111 ; vera auto-increment off
if draw
cx16.VERA_DATA0 |= masked_ends[separate_pixels]
@@ -253,7 +260,18 @@ _done
sub vertical_line(uword xx, uword yy, uword lheight, bool draw) {
cx16.r15L = monogfx.plot.maskbits[xx as ubyte & 7] ; bitmask
if draw {
if dont_stipple_flag {
%asm {{
lda p8v_mode
and #p8c_MODE_INVERT
beq +
lda #$45 ; eor ZP
sta drawmode
bra ++
+ lda #$05 ; ora ZP
sta drawmode
+
}}
if mode!=MODE_STIPPLE {
; draw continuous line.
position2(xx,yy,true)
if width==320
@@ -263,7 +281,7 @@ _done
repeat lheight {
%asm {{
lda cx16.VERA_DATA0
ora cx16.r15L
drawmode: ora cx16.r15L
sta cx16.VERA_DATA1
}}
}
@@ -554,8 +572,13 @@ _done
if draw {
; solid color or perhaps stipple
%asm {{
lda p8v_dont_stipple_flag
bne p8l_nostipple
lda p8v_mode
lsr a
bcs +
lsr a
bcs p8l_invert
bra p8l_nostipple
+ ; stipple mode
lda p8v_xx
eor p8v_yy
and #1
@@ -574,6 +597,16 @@ nostipple:
trb cx16.VERA_DATA0
}}
}
return
invert:
prepare()
%asm {{
lda cx16.VERA_DATA0
eor p8v_maskbits,y
sta cx16.VERA_DATA0
}}
return
sub prepare() {
%asm {{

View File

@@ -12,13 +12,17 @@ monogfx {
; read-only control variables:
uword width = 0
uword height = 0
bool dont_stipple_flag = true ; set to false to enable stippling mode
ubyte mode
const ubyte MODE_NORMAL = %00000000
const ubyte MODE_STIPPLE = %00000001
const ubyte MODE_INVERT = %00000010
sub lores() {
; enable 320*240 bitmap mode
sys.gfx_enable(0)
width = 320
height = 240
mode = MODE_NORMAL
clear_screen(0)
}
@@ -27,6 +31,7 @@ monogfx {
sys.gfx_enable(1)
width = 640
height = 480
mode = MODE_NORMAL
clear_screen(0)
}
@@ -34,17 +39,16 @@ monogfx {
; back to normal text mode
}
sub drawmode(ubyte dm) {
mode = dm
}
sub clear_screen(ubyte color) {
stipple(false)
if color
color=255
sys.gfx_clear(color)
}
sub stipple(bool enable) {
dont_stipple_flag = not enable
}
sub rect(uword xx, uword yy, uword rwidth, uword rheight, bool draw) {
if rwidth==0 or rheight==0
return
@@ -337,13 +341,19 @@ monogfx {
sub plot(uword @zp xx, uword @zp yy, bool @zp draw) {
if draw {
if dont_stipple_flag
sys.gfx_plot(xx, yy, 255)
else {
if (xx ^ yy)&1
when mode {
MODE_NORMAL -> {
sys.gfx_plot(xx, yy, 255)
else
sys.gfx_plot(xx, yy, 0)
}
MODE_STIPPLE -> {
if (xx ^ yy)&1
sys.gfx_plot(xx, yy, 255)
else
sys.gfx_plot(xx, yy, 0)
}
MODE_INVERT -> {
sys.gfx_plot(xx, yy, 255 ^ sys.gfx_getpixel(xx, yy))
}
}
}
else

View File

@@ -6,10 +6,10 @@ package prog8.buildversion
const val MAVEN_GROUP = "prog8"
const val MAVEN_NAME = "compiler"
const val VERSION = "10.2-SNAPSHOT"
const val GIT_REVISION = 4459
const val GIT_SHA = "a1f197d2ff2e23c84cac26efbda75ef3efb1f0aa"
const val GIT_DATE = "2024-02-10T00:33:26Z"
const val GIT_REVISION = 4491
const val GIT_SHA = "9fbc7bc5ad12fe3ee233eae40f710c244c998473"
const val GIT_DATE = "2024-03-03T22:15:47Z"
const val GIT_BRANCH = "master"
const val BUILD_DATE = "2024-02-10T00:33:30Z"
const val BUILD_UNIX_TIME = 1707525210318L
const val DIRTY = 0
const val BUILD_DATE = "2024-03-03T22:27:16Z"
const val BUILD_UNIX_TIME = 1709504836383L
const val DIRTY = 1

View File

@@ -612,7 +612,7 @@ Same interface as gfx2, but is optimized for monochrome (1 bpp) screens.
- drawing lines, rectangles, filled rectangles, circles, discs
- flood fill
- drawing text inside the bitmap
- can draw using a stipple pattern (alternate black/white pixels)
- can draw using a stipple pattern (alternate black/white pixels) and in invert mode (toggle pixels)
Read the `monogfx source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/cx16/monogfx.p8>`_
to see what's in there.

View File

@@ -1,17 +1,7 @@
TODO
====
larger programs:
dirlist
bobs
cobramk3-gfx
automatons
mandelbrot (quite a bit larger)
mandelbrot-gfx
maze
textelite
rockrunner is quite a bit larger
cx16.monogfx: add invert mode support to horizontal line routine, and text routine
replace Takes by Http4k in httpCompilerService project. https://github.com/http4k/examples/blob/master/hello-world/README.md
@@ -64,7 +54,7 @@ Compiler:
Libraries:
- monogfx: add EOR mode support next to Stipple. See PAINT for inspiration. Can this also be added to gfx2? Self modifying code to keep it optimized?
- gfx2: add EOR mode support line in monogfx and see PAINT for inspiration. Self modifying code to keep it optimized?
- conv: the routines could return the address of conv.string_out, and/or there could be versions that take the address of a different buffer and use it instead.
- once kernal rom v47 is released, remove most of the workarounds in cx16 floats.parse_f() . Prototype parse routine in examples/cx16/floatparse.p8
- fix the problems in atari target, and flesh out its libraries.

View File

@@ -23,17 +23,17 @@ main {
yy = 20
xx = 20
monogfx.stipple(false)
monogfx.drawmode(monogfx.MODE_NORMAL)
monogfx.rect(xx, yy, 250, 80, 1)
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.fillrect(xx+2, yy+2, 250-4, 80-4, 1)
monogfx.stipple(false)
monogfx.drawmode(monogfx.MODE_NORMAL)
monogfx.fillrect(xx+20, yy+20, 200, 30, 1)
monogfx.rect(xx+21, yy+21, 200-2, 30-2, 0)
monogfx.text(xx+30, yy+32, 0, sc:"High Res Bitmap Example")
; monogfx.stipple(true)
; monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.horizontal_line(10, 240, 620, 1)
monogfx.vertical_line(320, 10, 460, 1)
monogfx.text(320, 242, 1, sc:"0,0")
@@ -48,7 +48,7 @@ main {
monogfx.horizontal_line(319, yy, 3, 1)
}
monogfx.stipple(false)
monogfx.drawmode(monogfx.MODE_NORMAL)
float y_f
for ww in -600 to 600 {
y_f = floats.sin(ww as float / 60.0)*150
@@ -68,14 +68,15 @@ main {
monogfx.circle(320, 240, 210, 1)
monogfx.circle(320, 240, 200, 1)
monogfx.circle(320, 240, 190, 1)
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.disc(320, 240, 140, 1)
monogfx.stipple(false)
monogfx.drawmode(monogfx.MODE_NORMAL)
monogfx.disc(320, 240, 90, 1)
monogfx.disc(320, 240, 40, 0)
sys.wait(2*60)
monogfx.drawmode(monogfx.MODE_INVERT)
repeat 255
monogfx.line(math.rndw() % 640, math.rndw() % 480, math.rndw() % 640, math.rndw() % 480, 1)

View File

@@ -9,12 +9,12 @@
main {
sub start() {
monogfx.lores()
demofill()
sys.wait(2*60)
monogfx.hires()
demo1()
sys.wait(2*60)
; monogfx.lores()
; demofill()
; sys.wait(2*60)
; monogfx.hires()
; demo1()
; sys.wait(2*60)
demo2()
monogfx.textmode()
@@ -26,7 +26,7 @@ main {
monogfx.rect(180, 5, 25, 190, true)
monogfx.line(100, 150, 240, 10, true)
monogfx.line(101, 150, 241, 10, true)
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
sys.wait(60)
monogfx.fill(100,100,true)
}
@@ -36,7 +36,7 @@ main {
uword xx
uword cnt
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.disc(320,240,200,true)
for xx in 0 to 639 {
monogfx.vertical_line(xx, 0, 480, true)
@@ -47,10 +47,10 @@ main {
xx=monogfx.width/2
yy=10
monogfx.stipple(false)
monogfx.drawmode(monogfx.MODE_NORMAL)
linesy()
linesx()
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
linesy()
linesx()
@@ -145,10 +145,16 @@ main {
monogfx.text_charset(3)
monogfx.lores()
draw()
sys.wait(200)
sys.wait(100)
monogfx.hires()
draw()
sys.wait(200)
sys.wait(100)
monogfx.drawmode(monogfx.MODE_INVERT)
repeat 7 {
for cx16.r8 in 100 to 400 {
monogfx.vertical_line(cx16.r8, 0, 400, true)
}
}
}
sub draw() {

View File

@@ -1,19 +1,35 @@
%import math
%import monogfx
main {
sub start() {
monogfx.lores()
monogfx.stipple(true)
monogfx.drawmode(monogfx.MODE_INVERT)
uword x1, x2
uword y1, y2
repeat {
repeat 200 {
x1 = math.rnd()
y1 = math.rnd() % 240
x2 = math.rnd()
y2 = math.rnd() % 240
monogfx.line(x1, y1, x2, y2, true)
}
repeat 5 {
for cx16.r9L in 0 to 200 {
monogfx.vertical_line(cx16.r9L, 10, 200, true)
}
}
monogfx.disc(160, 120, 100, true)
monogfx.fillrect(20, 100, 280, 50, true)
monogfx.drawmode(monogfx.MODE_STIPPLE)
monogfx.fillrect(80, 10, 50, 220, true)
repeat {
}
}
}