duskos

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

commit 4a14081337b37338ed78f5f44582fa0008b8e2cb
parent bc37867cd095f942b7f204c41e2ab24d1ad48a53
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 31 Dec 2022 20:32:44 -0500

gr/plane: new unit

see doc/gr/plane

Diffstat:
Mfs/doc/gr/color.txt | 4++++
Afs/doc/gr/plane.txt | 41+++++++++++++++++++++++++++++++++++++++++
Rfs/doc/gr/rect.fs -> fs/doc/gr/rect.txt | 0
Dfs/doc/sys/screen.fs | 42------------------------------------------
Afs/doc/sys/screen.txt | 29+++++++++++++++++++++++++++++
Mfs/drv/pc/vesa.fs | 11++++-------
Mfs/emul/uxn/gui.fs | 6++++--
Mfs/gr/color.fs | 2++
Mfs/gr/draw.fs | 11++++++-----
Afs/gr/plane.fs | 33+++++++++++++++++++++++++++++++++
Mfs/sys/screen.fs | 18++++--------------
Mfs/xcomp/i386/pc/init.fs | 1+
Mfs/xcomp/init.fs | 8++++----
13 files changed, 132 insertions(+), 74 deletions(-)

diff --git a/fs/doc/gr/color.txt b/fs/doc/gr/color.txt @@ -37,3 +37,7 @@ COLOR_RGB24 = $01 r8g8b8>rgb24 ( r8 g8 b8 -- n ) Convert 3 8-bit RGB components into a COLOR_RGB24 encoding. + +colorbpp ( id -- bpp ) + Returns the bpp (bits per plane) value, that is, the number of bits that each + pixel of that encoding takes, for the specified encoding ID. diff --git a/fs/doc/gr/plane.txt b/fs/doc/gr/plane.txt @@ -0,0 +1,41 @@ +# Plane + +A plane is a filled Rect (gr/rect). It extends Rect and adds a color buffer to +it, one color per pixel. The size of the buffer depends on its color encoding +(see gr/color). + +The buffer is a sequence of horizontal lines with each line being "pitch" bytes +in size, beginning with the top line. Each line is a sequence of pixels, with +the size in bytes of each pixel depending on the color encoding, beginning with +the leftmost pixel. + +Drawing on a plane is stateful. You set "tx" and "ty" (your target point), set +the active color with the "color" field and then call the appropriate drawing +method. + +## API + +Fields: + +encoding A color encoding ID from gr/color +pitch Size in bytes of each line +tx Target point X +ty Target point Y +color Color that is currently drawn +buffer Pointer to the pixel buffer + +Methods: + +:new ( width height encoding -- plane ) + Create a new plane and calculate pitch from color encoding. Does not allocate + a buffer and initializes it to 0. + +:allotbuf ( self -- ) + Allocate a new buffer of the proper size (considering height and pitch) and + set "buffer" to it. + +:pixel! ( self -- ) + Set a pixel at tx,ty to the value of field "color". + +:fill ( width height self -- ) \ TODO + Fill the area in the rect tx,ty,width,height with field "color". diff --git a/fs/doc/gr/rect.fs b/fs/doc/gr/rect.txt diff --git a/fs/doc/sys/screen.fs b/fs/doc/sys/screen.fs @@ -1,42 +0,0 @@ -# Screen subsystem - -The screen subsystem represents a matrix of pixels on a screen, which allows us -to draw graphics. The screen can be activated and deactivated to switch between -graphical and text modes, if the underlying hardware supports this. - -This subsystem rests on a hardware specific driver that takes care of the gory -details. The screen subsystem doesn't handle configuration of the display, which -has to be done directly through the driver. - -The screen subsystem defines the Screen structure as well as a "screen" -structbind to it. During initialization, what you'll want to do is create an -instance of the Screen from the driver and bind it to "screen". - -## Driver implementation - -To implement the screen, we need an underlying driver to extend it and implement -its methods, namely: - -:activate ( self -- ) - Enable the graphics mode. We expect this word to set appropriate fields such - as "width" and "height". - -:deactivate ( self -- ) - If the hardware supports it, bring back the display to text mode. - -:pixel' ( x y self -- a ) - Yield the address corresponding to the specified x and y coordinates. - -## API - -Fields: - -width Screen width -height Screen height -bpp Screen bits per plane -color Color (from gr/color) that will be drawn - -Methods: - -:pixel! ( x y self -- ) - Set a pixel at x,y to the value of field "color". diff --git a/fs/doc/sys/screen.txt b/fs/doc/sys/screen.txt @@ -0,0 +1,29 @@ +# Screen subsystem + +The screen subsystem represents a Plane (gr/plane) drawn on a physical screen +device. The screen can be activated and deactivated to switch between graphical +and text modes, if the underlying hardware supports this. + +This subsystem rests on a hardware specific driver that takes care of the gory +details. The screen subsystem doesn't handle configuration of the display, which +has to be done directly through the driver. + +The screen subsystem defines the Screen structure as well as a "screen" +structbind to it. During initialization, what you'll want to do is create an +instance of the Screen from the driver and bind it to "screen". + +## Driver implementation + +To implement the screen, we need an underlying driver to extend it and implement +its methods, namely: + +:activate ( self -- ) + Enable the graphics mode. We expect this word to set appropriate Plane fields + such as width, height, encoding, pitch and buffer. + +:deactivate ( self -- ) + If the hardware supports it, bring back the display to text mode. + +## API + +The Screen, except for driver method, has no additional API compared to Plane. diff --git a/fs/drv/pc/vesa.fs b/fs/drv/pc/vesa.fs @@ -99,8 +99,6 @@ here VBEModeInfo SZ allot structbind VBEModeInfo _curmode $112 value vesamode -: pixelbytes _curmode bpp >> >> >> ; - extends Screen struct[ VESAScreen : _activate ( self -- ) vesamode _modeinfo _curmode :self VBEModeInfo SZ move @@ -108,13 +106,12 @@ extends Screen struct[ VESAScreen $4f = _assert 2drop ( self ) _curmode width over to width _curmode height over to height - _curmode bpp swap to bpp ; + _curmode pitch over to pitch + _curmode framebuffer swap to buffer ; : _deactivate ( self -- ) drop vgatext! ; - : _pixel' ( x y self -- a ) drop - _curmode pitch * swap pixelbytes * + _curmode framebuffer + ; - : :new ( -- screen ) - :newbase ['] _activate , ['] _deactivate , ['] _pixel' , ; + 0 0 COLOR_RGB24 Screen :new + ['] _activate , ['] _deactivate , ; ]struct diff --git a/fs/emul/uxn/gui.fs b/fs/emul/uxn/gui.fs @@ -29,7 +29,8 @@ create _fgmask FGMASKSZ allot swap 1+ 1+ dup short@ r@ _extract ( r8 'g g8 ) swap 1+ 1+ short@ r> _extract ( r8 g8 b8 ) r8g8b8>rgb24 ; : _drawpixel ( x y pixel -- ) - 3 and screencolor to screen color ( x y ) screen :pixel! ; + 3 and screencolor to screen color ( x y ) + to screen ty to screen tx 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 ; @@ -100,7 +101,8 @@ create _fgmask FGMASKSZ allot : screendeo ( dev port -- ) 0 to@! rgbchanged if \ we need to fill the screen with the new color - 0 screencolor screen width screen height 0 0 drawrect then + 0 screencolor to screen color + screen width screen height 0 0 drawrect then case ( dev ) \ V1=case $e of = _pixel endof $f of = _sprite endof diff --git a/fs/gr/color.fs b/fs/gr/color.fs @@ -1,3 +1,5 @@ $01 const COLOR_RGB24 : r8g8b8>rgb24 ( r8 g8 b8 -- n ) swap 8 lshift or swap 16 lshift or ; + +: colorbpp ( id -- bpp ) drop 24 ; diff --git a/fs/gr/draw.fs b/fs/gr/draw.fs @@ -2,11 +2,12 @@ require /sys/screen.fs ?f<< /gr/color.fs : drawrect ( w h x y -- ) - >r >r \ V1=y V2=x - ( h ) >r begin ( w ) dup >r begin ( w ) - V2 r@ + 1- V1 screen :pixel! next - 1 to+ V1 next ( w ) - drop rfree ; + to screen ty ( w h x ) + swap >r begin ( w x ) + dup to screen tx over >r begin ( w x ) + screen :pixel! 1 to+ screen tx next + 1 to+ screen ty next ( w x ) + 2drop ; : recttest 255 0 0 r8g8b8>rgb24 to screen color diff --git a/fs/gr/plane.fs b/fs/gr/plane.fs @@ -0,0 +1,33 @@ +\ This code is currently used to write directly to the memory buffer of +\ graphical cards. Maybe that at some point, this scheme will break, but we'll +\ adjust then. + +?f<< /gr/rect.fs +?f<< /gr/color.fs + +\ TODO: support more than 24bpp +extends Rect struct[ Plane + sfield encoding + sfield pitch + sfield tx + sfield ty + sfield color + sfield buffer + + : _colorbytes ( id -- nbytes ) colorbpp >> >> >> ; + + : :new ( width height encoding -- plane ) + >r >r >r 0 0 r> r> Rect :new ( rect ) + r> ( encoding ) dup , _colorbytes over Rect width * ( pitch ) , + 0 ( tx ) , 0 ( ty ) , 0 ( color ) , 0 ( buffer ) , ; + + : :allotbuf ( self -- ) >r \ V1=self + here r@ pitch r@ height * allot r> to buffer ; + + : _addr ( self -- a ) >r \ V1=self + r@ ty r@ pitch * r@ encoding _colorbytes r@ tx * + r> buffer + ; + + : :pixel! ( self -- ) >r \ V1=self + r@ color r@ _addr 16b !+ r> color 16 rshift swap c! ; + +]struct diff --git a/fs/sys/screen.fs b/fs/sys/screen.fs @@ -1,19 +1,9 @@ -struct[ Screen - sfield width - sfield height - sfield bpp - \ TODO: support more than 24bpp - sfield color +?f<< /gr/plane.fs +?f<< /gr/color.fs + +extends Plane struct[ Screen smethod :activate ( self -- ) smethod :deactivate ( self -- ) - smethod :pixel' ( x y self -- a ) - - \ Creates the first part of the screen structure, but leaves the method fields - \ to the caller. - : :newbase ( -- partial-screen ) here 0 , 0 , 0 , 0 , ; - - : :pixel! ( x y self -- ) >r \ V1=self - r@ :pixel' r@ color swap 16b !+ r> color 16 rshift swap c! ; ]struct 0 structbind Screen screen diff --git a/fs/xcomp/i386/pc/init.fs b/fs/xcomp/i386/pc/init.fs @@ -59,6 +59,7 @@ f<< /sys/loop.fs f<< /drv/pc/a20.fs a20$ +f<< /sys/scratch.fs f<< /sys/screen.fs f<< /drv/pc/vesa.fs VESAScreen :new ' screen rebind diff --git a/fs/xcomp/init.fs b/fs/xcomp/init.fs @@ -1,7 +1,7 @@ \ Common part of init.fs. Machine-independent \ As a user, you'll want to adapt this to your needs. -f<< sys/scratch.fs -f<< lib/fmt.fs -f<< lib/diag.fs -f<< sys/rdln.fs +?f<< /sys/scratch.fs +f<< /lib/fmt.fs +f<< /lib/diag.fs +f<< /sys/rdln.fs : init S" Dusk OS\n" stype .free rdln$ stdio$ quit ;