
This is a fast framebuffer-level graphics library for linear 1, 2 and 3
byte-per-pixel modes (256-color, hicolor, truecolor). It utilizes svgalib,
an extension of VGAlib, for low-level hardware communication.
In particular, VGAlib maps the 64K VGA frame buffer window, and this library
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.


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.

	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).


	- 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

	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.

	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 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.

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

	setcontext( GraphicsContext *gc )
		Restore a previously saved context.

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

	copyscreen( GraphicsContext *gc )
		Copy the current graphics context (screen) to the
		specified graphics context (the physical screen,
		for example).


	- 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.

	setwritemode( int m )
		Either WRITEMODE_OVERWRITE or WRITEMODE_MASKED. If the latter
		is selected, only foreground pixels of the font are used for
		write operations; the screen background is not erased.

	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. All non-zero pixels are set to color c.

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


	- 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 integers 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 dpp, 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).


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 or 3).
	BYTEWIDTH	Width of a scanline in bytes.
	COLORS		Number of colors.
	BITSPERPIXEL	Number of significant color bits.
	VBUF		Address of the framebuffer.


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

It may be interesting to compare the framebuffer video speeds for certain
modes, especially among Vesa Local Bus cards. If you want, you can mail them
to me (hhanemaa@cs.ruu.nl) and I'll collect the results at this place.
Please state CPU, card type/chipset, and bus type (of the card).

The speedtest program is using aligned REP STOSL (memset), which is
relatively slow on a 486 (4 cycles); unrolled MOV's may be faster. It does show
that some VLB cards are in fact only 16-bits (like my Cirrus 5426 based card).
The maximum throughput using STOSL on a 386 (5 cycles) is about 15K/s at
16-bit VLB 40MHz, 30K/s with 32 bits.

					256-color		hicolor	truec.
card			system		320x200	640x480	800x600 640x480 640x480
AVGA3, CLGD5426, VLB	386DX/40	12.5	13.7	12.8	 7.6	 4.6
  same, high MCLK	386DX/40	15.5	15.5	15.5	11.7	 8.4
Trident 9000, 512K ISA  386DX/40	 2.1     2.2     2.2	   -       -


Bugs

	For three bytes per pixel (true color) modes, in some functions
	(e.g. fillbox),	pixels are assumed to never be split between two
	segments. This effectively means that writing directly to 320x200
	and 640x480 truecolor modes with those functions produces errors
	(like stripes in another color). This can be solved 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.
