Last modified 14th January 2006 occam-pi SDL Raster Graphics |
This page documents the "SDLRaster" library in KRoC, for providing basic framebuffer-oriented graphics using the SDL (simple direct-media layer) library.
[ SDLRaster | events | control | examples ]
The SDLRaster library included with the latest versions of KRoC (1.4.0-final and above) provides a simple frame-buffer for occam-pi programs, represented as a 2D mobile array of INTs. The library does not yet support the whole wealth of SDL operations -- only basic framebuffers.
The following basic routines are provided:
Creates a new graphics raster on the default display (usually from the "DISPLAY" environment variable for X11). A meaningful identifier may be given using dpyid. The size of the raster is given in width and height. The number of buffers is specified in nbuffers (must be >= 1) -- more buffers mean more memory, but sometimes smoother graphics (and other interesting effects). Before the raster terminates, all its buffers must be returned. Furthermore, a RASTER that is produced by SDLRaster must ultimately be returned to the raster process (and not allowed to die in the application).
Interaction with the created raster is through its four channels; out! produces fresh rasters, that the application can then draw on. To update the on-screen copy, SDLRasterUpdate or SDLRasterUpdateBuf can be called, or the raster can be returned through the in? channel. Events are sent down the events! channel (described below). The raster can be controlled at run-time (very limited!) through its control! channel.
CHAN RASTER r.in, r.out: CHAN SDLEVENT events: CHAN INT control: PAR SDLRaster ("wibble", 320, 240, 1, r.in?, r.out!, events!, control?) ... do raster stuff
PROC SDLRasterClear ([][]INT r)
Clears the given raster (by r) to #00000000 (black). Although this could be done in occam-pi the routine used here is likely to be faster.
PROC SDLRasterUpdate ([][]INT r)
Renders the raster buffer (given by r). This should be one of the rasters acquired from SDLRaster's out! channel.
PROC SDLRasterUpdateBuf (VAL INT bufnum)
Renders the given buffer number on the display (first buffer is numbered 0). If there are multiple rasters, this only redraws the most recently created raster.
PROC SDLRasterAutoClose (CHAN [2]INT events?, CHAN INT control!)
This can be used to connect up the event and control channels for SDLRaster, responding only to the 'quit' event by sending a 'shutdown' control message (and throwing all other events away).
The provided RASTER type is defined as:
DATA TYPE RASTER IS MOBILE [][]INT:
The buffers communicated and represented using this type are 2D arrays of integers, with each integer representing a single pixel. Since both SDLRaster and DXRaster are intended for 24 or 32-bit displays (that most are these days), the integers that make up the pixels have 8-bits of red, green and blue. If specifying hexidecimal constants for pixel values, the makeup is: #00ggrrbb (on my system anyway -- it should be fairly obvious if your system does things differently). If an integer is treated as a [4]BYTE array, the bytes will be in reverse (e.g. red in pixel[1], green in pixel[2] and blue in pixel[0]).
Because the RASTER type uses dynamic mobile arrays, when a process outputs one, it is gone from that process (i.e. may not be referenced again). The mobiles communicated by the SDLRaster process must not intermix with application data of the same type; neither should an application attempt to create these rasters or free them. The rasters come out of the SDLRaster process and should go back there :-).
The various events delivered from SDLRaster are sent as SDLEVENT records, defined as:
DATA TYPE SDLEVENT RECORD INT type: INT data: :
The type field contains the event (constants defined in sdlraster.inc), the data field contains any event-specific data. These are defined as:
event number | description | event data |
---|---|---|
EVENT.UNKNOWN | unknown or unsupported event | undefined |
EVENT.EXPOSE | expose event (raster obscured and redrawn) | undefined |
EVENT.BUTTON.PRESS | mouse button pressed | button data: ((x /\ #FFF) << 20) \/ ((y /\ #FFF) << 8) \/ ((key.state /\ #F) << 4) \/ (button /\ #F) |
EVENT.BUTTON.RELEASE | mouse button released | button data: ((x /\ #FFF) << 20) \/ ((y /\ #FFF) << 8) \/ ((key.state /\ #F) << 4) \/ (button /\ #F) |
EVENT.KEY.PRESS | key pressed | key data: (unicode-char /\ #FFFF) |
EVENT.KEY.RELEASE | key released | key data: (unicode-char /\ #FFFF) |
EVENT.QUIT | user closing window | undefined |
EVENT.MOTION | mouse motion | motion data: ((x /\ #FFF) << 20) \/ ((y /\ #FFF) << 8) \/ ((key.state /\ #F) << 4) \/ (button-state /\ #F) |
EVENT.CKEY.PRESS | control-key pressed | control-key (see below) |
EVENT.CKEY.RELEASE | control-key released | control-key (see below) |
The various control keys currently recognised are:
control-key | description |
---|---|
CKEY.UNKNOWN | unknown control key |
CKEY.BACKSPACE | backspace |
CKEY.NUMLOCK | num-lock |
CKEY.CAPSLOCK | caps-lock |
CKEY.SCROLLOCK | scroll-lock |
CKEY.RSHIFT | right-shift |
CKEY.LSHIFT | left-shift |
CKEY.RCTRL | right-control |
CKEY.LCTRL | left-control |
CKEY.RALT | right-alt |
CKEY.LALT | left-alt |
CKEY.RMETA | right-meta |
CKEY.LMETA | left-meta |
CKEY.RSUPER | right-super (windows key) |
CKEY.LSUPER | left-super (windows key) |
CKEY.SYSREQ | sys-rq key |
CKEY.MENU | menu key (windows key) |
CKEY.MODE | mode switch (alt-gr) |
CKEY.UP | up |
CKEY.DOWN | down |
CKEY.LEFT | left |
CKEY.RIGHT | right |
CKEY.HOME | home |
CKEY.END | end |
CKEY.PAGEUP | page-up |
CKEY.PAGEDOWN | page-down |
CKEY.INSERT | insert |
CKEY.DELETE | delete |
To extract the X/Y/button-state/key-state data from events the following functions are provided:
INT FUNCTION SDLEVENT.XPOS (VAL SDLEVENT ev)
This extracts the X position of the pointer (mouse) from the event ev. The event must be one of EVENT.BUTTON.PRESS, EVENT.BUTTON.RELEASE or EVENT.MOTION.
INT FUNCTION SDLEVENT.YPOS (VAL SDLEVENT ev)
This extracts the Y position of the pointer (mouse) from the event ev. The event must be one of EVENT.BUTTON.PRESS, EVENT.BUTTON.RELEASE or EVENT.MOTION.
INT FUNCTION SDLEVENT.BUTTON (VAL SDLEVENT ev)
This extracts the button number from event ev, which must be one of EVENT.BUTTON.PRESS or EVENT.BUTTON.RELEASE.
INT FUNCTION SDLEVENT.BSTATE (VAL SDLEVENT ev)
This extracts the button state/mask from event ev, which must be of type EVENT.MOTION.
INT FUNCTION SDLEVENT.KSTATE (VAL SDLEVENT ev)
This extracts the keyboard modifier-key state/mask from event ev, which must be one of EVENT.BUTTON.PRESS, EVENT.BUTTON.RELEASE or EVENT.MOTION.
The control messages currently supported (sent as a single integer) are:
control constant | description |
---|---|
CTL.SHUTDOWN | shut-down the raster |
A number of basic example programs are provided in the KRoC distribution, in the "sdlraster/examples/" sub-directory. To build these, use "./build examples" in the KRoC source tree (or from 1.4.0-pre2 onwards, "./build sdlraster_examples"). In a binary distribution, pre-built SDLRaster examples (if supported) will be installed in PREFIX/share/kroc/examples/sdlraster.
The SDLRaster code no longer uses user-defined channels (it uses CIF instead). As such, the 'gridlink' process has been removed, making SDLRaster somewhat nicer to work with. The following shows a basic application outline for using SDLRaster:
#INCLUDE "sdlraster.inc" #USE "sdlraster" #USE "course.lib" PROC test (CHAN BYTE screen!) CHAN RASTER c, d: CHAN SDLEVENT events: CHAN INT control: PAR SDLRaster ("test", 320, 200, 1, d?, c!, events!, control?) SDLRasterAutoClose (events?, control!) RASTER r: SEQ out.string ("hello from SDLRaster test :)*n", 0, screen!) c ? r -- get raster WHILE TRUE SEQ ... scribble on r SDLRasterUpdate (r) ... do suitable delay d ! r -- return raster (bit redundant here) :
Which would be compiled with:
bash$ kroc mytest.occ -lcourse -lsdlraster -lSDL -lcif
Copyright © 2005-2006, Fred Barnes, Department of Computer Science, University of Kent. |