duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 41f39e99993a73ca0c89bbfd68a01ae674170ebb
parent be12a3ff69e1946fa3e3084b057eb6177f3466a1
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Mon,  2 Jan 2023 22:27:19 -0500

emul/uxn: make varvara screen buffer

Instead of having only a "fg mask", fully buffer 2bit fg/bg colors. The previous
approach didn't work well in cases where the fg pixel was set to 0 and that a
previous bg was present: we didn't know what color that bg pixel was so we
couldn't restore it.

By buffering colors of both layers, this problem is solved.

Diffstat:
Mfs/emul/uxn/gui.fs | 28+++++++++++++---------------
Mfs/tests/manual/uxn/mouse.tal | 2--
2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/fs/emul/uxn/gui.fs b/fs/emul/uxn/gui.fs @@ -3,20 +3,19 @@ require /sys/screen.fs ?f<< /lib/bit.fs ?f<< /emul/uxn/varvara.fs -\ FG Mask: to properly handle FG/BG logic, we need to know which pixels are -\ "filled" on the FG layer, that is, have a non-zero color. When it is, a draw -\ operation on the BG layer will have no effect. +\ The screen buffer is an array of 8bit pixel, b1:0 being foreground, b3:2 being +\ background, b7:4 being wasted. \ Let's say, for now, that maximum supported resolution is 1024x768 -1024 768 * 8 / const FGMASKSZ -create _fgmask FGMASKSZ allot +1024 768 * const SCRBUFSZ +create _scrbuf SCRBUFSZ allot -: _fg' ( x y -- bit a ) - screen width * + 8 /mod ( bit a ) _fgmask + ; -: _fg! ( x y id -- ) - >r _fg' dup c@ ( bit a n ) - rot r> if bit1! else bit0! then ( a n ) - swap c! ; -: _fg? ( x y -- f ) _fg' c@ swap bit? ; +\ Blends the fg/bg color in the buffer and yield the actual pixel to draw. +: _scrblend ( x y pixel fg? -- pixel ) + >r >r screen width * + _scrbuf + dup c@ ( a n ) + r> r> ( a n pixel fg? ) + if swap $c and or else << << swap $3 and or then ( a n ) + tuck swap c! ( n ) + dup $3 and ?dup if nip else >> >> then ( n ) ; \ example: $5678 for "r" means ID0=5 ID1=6 ID2=7 ID3=8 : _extract ( systemrgb id -- rgb8 ) @@ -31,8 +30,7 @@ create _fgmask FGMASKSZ allot 3 and screencolor to screen color ( x y ) screen :pos! screen :pixel! ; : _drawlayer ( x y pixel fg? -- ) - if >r 2dup r@ _fg! r> _drawpixel - else >r 2dup _fg? if 2drop rdrop else r> _drawpixel then then ; + >r >r 2dup r> r> _scrblend _drawpixel ; :c void _drawlayer(ushort x, ushort y, uchar pixel, int fg); : screendei ( dev port -- c ) case @@ -137,7 +135,7 @@ create _buf $10 allot \ to check for value changes r@ Device dat _buf $10 []= if rdrop else r> _?execvector then ; : gui_init - _fgmask FGMASKSZ 0 fill + _scrbuf SCRBUFSZ 0 fill $2 ['] screendei ['] screendeo uxn_set_dev screen :activate ; diff --git a/fs/tests/manual/uxn/mouse.tal b/fs/tests/manual/uxn/mouse.tal @@ -47,8 +47,6 @@ BRK @on-mouse ( -> ) ;pointer-icn .Screen/addr DEO2 - ( TODO: clearing the cursor erases the doodling below. It doesn't do it on - the regular uxnemu. ) ( clear last cursor ) .pointer/x LDZ2 .Screen/x DEO2 .pointer/y LDZ2 .Screen/y DEO2