
This is a fast framebuffer-level graphics library for linear 1, 2, 3 and 4
byte-per-pixel modes (256-color, hicolor, truecolor). It uses a limited
number of functions from svgalib (libvga) for low-level hardware
communication (the library is included in the svgalib shared image).
In particular, svgalib maps the 64K VGA frame buffer window, and this library
directly addresses the buffer. For SVGA modes that use more than 64K of
screen memory, SVGA paging is required when writing to the physical screen;
this is done automatically for most functions (at a certain cost).
Alternatively, any number of virtual screens of any type in system memory can
be used, which can then be copied to the physical screen. There is also
support for 4 bytes per pixel framebuffers (and copying them to a 3 bytes per
pixel context), and limited planar 256 color mode support (copyscreen,
aligned putbox).

The planar 256 color modes (available on all VGA cards) can now be used
with a virtual screen, which is copied to the physical screen (with optional
page-flipping).

Bitmaps are raw, with one (or more) bytes per pixel (like pixmaps in X),
stored in row-major order. They are usually manipulated with the getbox
and putbox functions.

A graphics context is just a structure that holds the size of the associated
graphics screen, how it is organized, clipping status etc. You can define a
custom virtual (system memory) graphics context of any size with the
setcontextvirtual function. All operations work on the current context.

Any questions, bug-reports, additions, suggestions etc. are welcome.


Functions (all have a "gl_" prefix):

	- simple line drawing 

	setpixel( int x, int y, int c )
		Draw a single pixel at position (x, y) in color c. The lower
		8, 15, 16 or 24 bits of the color are significant, depending
		on the number of colors the current mode supports. 

	setpixelrgb( int x, int y, int r, int g, int b )
		Draw a single pixel at (x, y) with color components r, g,
		and b, ranging from 0 to 255. In 256 color mode, only
		meaningful if the RGB palette is set (setrgbpalette).

	int getpixel( int x, int y )
		Returns color of pixel at position (x, y).

	getpixelrgb( int x, int y, int *r, int *g, int *b )
		Store color components from pixel at (x, y) ranging from 0
		to 255, into integers pointed to by r, g and b.

	int rgbcolor( int r, int g, int b )
		Returns pixel value that corresponds with the given color
		components. Used by setpixelrgb.

	line( int x1, int y1, int x2, int y2, int c )
		Draw a line from (x1, y1) to (x2, y2) inclusive in 
		color c.

	hline( int x1, int y, int x2, int c )
		Draw a horizontal line from (x1, y) to (x2, y) in color c.

	circle( int x, int y, int r, int c )
		Draw a circle of radius r in color c.


	- box (bitmap) functions 

	fillbox( int x, int y, int w, int h, int c )
		Screen position (x, y), box size (w, h).
		Fill a rectangular area of the screen with a single color.

	getbox( int x, int y, int w, int h, void *dp )
		Bitmap data pointer dp. Bitmaps are in row-major order.
		Copy a rectangular bitmap from the screen to a buffer.

	putbox(	int x, int y, int w, int h, void *dp )
		Bitmap data pointer dp.
		Copy a bitmap to a rectangular area of the screen.

	putboxpart( int x, int y, int w, int h, int bw, int bh, void *bp,
	int xo, int yo )
		Copy a partial bitmap to the screen. (w, h) is the size
		of the partial bitmap, (bw, bh) that of the source bitmap,
		and (xo, yo) is the offset in pixels into the source bitmap.

	putboxmask( int x, int y, int w, int h, void *dp )
		As putbox, but do not write bitmap pixels of color zero.

	copybox( int x1, int y1, int w, int h, int x2, int y2 )
		Copy the rectangular area at (x1, y1) of size (w, h),
		to (x2, y2) (bitblit).

	copyboxtocontext( int x1, int y1, int w, int h, GraphicsContext *gc,
	int x2, int y2 )
		Copy the rectangular area at (x1, y1) of size (w, h), to
		position (x2, y2) in the context gc. If possible use
		copyboxfromcontext.

	copyboxfromtocontext( GraphicsContext *gc, int x1, int y1, int w,
	int h, int x2, int y2 )
		Copy the rectangular area at (x1, y1) in the context gc, of
		size (w, h), to position (x2, y2) in the current context.
		This is more efficient than copyboxtocontext.


	- compiled bitmaps (linear 256 color mode only)

	compileboxmask( int w, int h, void *sdp, void *ddp )
		Convert rectangular masked bitmap of size (w, h) at sdp to
		a compressed format that allows faster drawing, which is
		stored at ddp. Allocating w * h bytes for the compiled
		version is usually enough; an upper limit should be 
		(w + 2) * h.

	int compiledboxmasksize( int w, int h, void *sdp )
		Returns the size of the compiled version of the masked
		bitmap of size (w, h) at sdp that will be generated by
		compileboxmask.

	putboxmaskcompiled( int x, int y, int w, int h, void *dp )
		Write compiled bitmap to screen. This is significantly
		faster than non-compiled masked bitmaps, especially for
		sparse bitmaps.


	- clipping
	
	enableclipping()
		Enable automatic clipping in most functions.

	disableclipping()
		Disable clipping.

	setclippingwindow( int x1, int y1, int x2, int y2 )
		Set the clipping window to the rectangle with top-left
		corner (x1, y1) and bottom-right corner (x2, y2) (incl.).


	- graphics contexts and virtual screens

	GraphicsContext *allocatecontext()
		Allocate a graphics context. This is preferred to
		hardcoding a context variable in a program since the
		latter is incompatible with a future vgagl version that
		has additional context fields.

	setcontextvga( int mode )
		Set the graphics context to the physical screen of a
		vga mode (as defined in svgalib). The mode must be set
		first. The only thing you can do with a planar (mode X-like)
		256 color mode is aligned putbox, and use it as a target for
		copyscreen.

	setcontextvgavirtual( int mode )
		Allocate a virtual screen in system memory identical to
		the graphics mode, and make that the current graphics
		context.

	setcontextvirtual( int w, int h, int bpp, int bitspp, void *vbuf )
		Define the current graphics context to have a width of w
		pixels, height h, bpp bytes per pixel, bitspp significant
		color bits per pixel (8, 15, 16 or 24), with the framebuffer
		at vbuf. A 4 bytes per pixel context, with 24 significant
		color bits is also valid.

	getcontext( GraphicsContext *gc )
		Save the current context in a structure variable.

	setcontext( GraphicsContext *gc )
		Restore a previously saved context (make it the current
		context).

	freecontext( GraphicsContext *gc )
		Free the space allocated for the virtual screen in the
		given context.

	copyscreen( GraphicsContext *gc )
		Copy the current graphics context contents (screen data) to
		the specified graphics context (the physical screen, for
		example). Contexts are assumed to be identical in size.

	setscreenoffset( int o )
		Set the offset in pixels into video memory for copyscreen
		and copyboxtoscreen, allows for page-flipping. Must be a
		multiple of the scanline width in bytes. It is reset to
		zero after completion of copyscreen.

	int enablepageflipping( GraphicsContext *gc )
		Enable page flipping or triple buffering in copyscreen if
		the physical context gc can do it. Returns 3 if triple
		buffering will be used, 2 for page flipping, 0 if page
		flipping is not possible (due to video memory/mode
		limitations). When pageflipping is enabled, the screenoffset
		is ignored in copyscreen.


	- text writing, font handling

	setfont( int fw, int fh, void *fp )
		Use the font stored as character bitmaps at fp, with 
		characters of size (fw, fh), as the basic font for write
		operations. Note that the font included in the library must
		be expanded first, because it is stored bit-per-pixel;
		this is not required if the FONT_COMPRESSED writemode
		flag is set.

	setwritemode( int m )
		Sets writemode flags. If WRITEMODE_MASKED is set (as opposed
		to WRITEMODE_OVERWRITE), only foreground pixels of the font
		are used for write operations; the screen background is not
		erased. If FONT_COMPRESSED is set (as opposed to
		FONT_EXPANDED), text writes will use the compressed
		bit-per-pixel font rather than the expanded font.

	write( int x, int y, char *s )
		Write string s at (x, y) using currently selected font.

	writen( int x, int y, int n, char *s )
		Write n character string s at (x, y).

	expandfont( int fw, int fh, int c, void *sfp, void *dfp )
		Convert bit-per-pixel font at sfp, with characters of size
		(fw, fh), to an expanded font of character bitmaps, stored at
		dfp (size will be 256 * fw * fw * BYTESPERPIXEL). All
		non-zero pixels are set to color c.

	colorfont( int fw, int fh, int c, void *fp )
		Set all nonzero pixels in the expanded font to color c.

	setfontcolors( int bg, int fg )
		Set the background and foreground colors for the compressed
		font write mode.


	- VGA 256-color palette handling

	These functions are only valid in 256-color modes.

	getpalettecolor( int c, int *r, int *g, int *b )
		Get red, green and blue values (in the range 0-63) of 
		color c from the color-lookup-table, and store them as
		integers in the memory locations pointed to by r, g and b.  

	setpalettecolor( int c, int r, int g, int b )
		Set RGB values (0-63) for color c.

	getpalettecolors( int s, int n, void *dp )
		Get RGB values of n colors starting at s, which are stored
		as a table of groups of three bytes at dp. 

	setpalettecolors( int s, int n, void *dp )
		Set RGB values of n colors starting at color s.

	getpalette( void *p )
		Equivalent to getpalettecolors(0, 256, p).

	setpalette( void *p )
		Equivalent to setpalettecolors(0, 256, p).

	setrgbpalette()
		Set 256-color RGB palette (bits 0-2 blue, 3-5 green,
		6-7 red). Use with setpixelrgb.


	- miscellaneous

	clearscreen( int c )
		Fill the entire screen with color c.

	scalebox( int w1, int h1, void *sdp, int w2, int h2, void *ddp )
		Scale the bitmap of size (w1, h1) at sdp to size (w2, h2)
		and store it at ddp, which must be a large enough buffer.
		The pixel size of the current graphics context is used.

	setdisplaystart(int x, int y)
		Set the physical display start address to the pixel at (x,
		y). Can be used for hardware scrolling, or for page flipping
		(e.g. setdisplaystart(0, HEIGHT) displays from the second
		page). Make sure the scanline width (BYTEWIDTH) in bytes
		of the current context corresponds with the physical
		screen.


Macros defined in vgagl.h:

	WIDTH		The width in pixels of the current graphics context.
	HEIGHT 		Height in pixels.
	BYTESPERPIXEL	Number of bytes per pixel (1, 2, 3 or 4).
	BYTEWIDTH	Width of a scanline in bytes.
	COLORS		Number of colors.
	BITSPERPIXEL	Number of significant color bits.
	VBUF		Address of the framebuffer.
	__clip		Clipping flag.
	__clipx1	Top-left corner of clipping window.
	__clipy1
	__clipx2	Bottom-right corner of clipping window.
	__clipy2


Use the environment variable GSVGAMODE to select the graphics mode used by
the testgl program (e.g. export GSVGAMODE=G640x480x256).

Note

	For three bytes per pixel (true color) modes, it is possible that
	pixels cross a SVGA segment boundary. This should be correctly
	handled	by most functions. It can be avoided by using a logical
	scanline length that is a divisor of 65536 (a power of 2), like 1024
	(as opposed to 960) for 320x200 and 2048 (1920) for 640x480. For
	800x600, this is impractical (4096 as opposed to 2400 doesn't fit in
	2MB). Alternatively, avoid those functions by using a virtual screen.


Question: How do I poll the keyboard without waiting and handle multiple
	  keypresses?

You can have complete keyboard control by using RAW mode. An example should
be in the kbd-08? package (nic.funet.fi, /pub/Linux/PEOPLE/Linus or similar).

There is now a low-level keyboard interface in svgalib.
There is also a seperate 'rawkey' library for use with svgalib, by Russell
Marks.


Q: What's the fuss about a DLL library?
A: The building of a DLL library includes a conversion, at the assembler
   level, of all references in the library code of exported global variables
   into indirect references with some overhead added to preserve register
   values. This is not very efficient if the global variables are used all
   over the place (e.g. currentcontext and its fields). The testgl program
   ran 20% slower because of this. Therefore, the library internally uses a
   copy of currentcontext that is not exported. This means that the current
   context may only be changed with vgagl functions.
