
Specifying the Device
---------------------

If XShm is compiled into your binary, but you don't want to use it, try:

	R_DEVICE=XImageDevice ./testobj

or if you want to force the use of X-SHM

	R_DEVICE=XShmDevice ./testobj

This is for existing compiled binaries.  If for some reason, you
cannot compile XShm (ie not supported/installed on your system), just
remove the entry 'XShmDevice.C' from the Makefile.  Don't forget to
remove the backslash on the line before, if necessary.


Devices and Viewports register themselves automatically, and are
implemented as private, hidden classes, with no .H file.  This means
that no user code has direct access to the actual device/viewport
drivers, except through the abstract classes Device and Viewport.  Thus
we can add or remove new drivers, both for X and for other systems
without even recompiling the clients (assuming lib3d is used as a
dynamic library).

Specifying the Viewport
---------------------

If, say, you want to use the viewport Viewport8Ci (not distributed), but
lib3d automatically chooses DitherViewport, you can say:

	R_VIEWPORT=Viewport8Ci ./testobj

The list of viewports distributed with lib3d-0.1.2 is:

	DitherViewport	(8Bpp, dithered)
	Viewport8Ci       (8Bpp, colour-index, i386 asm (disabled), incomplete)
	Viewport16Bpp	(565 RGB, 16Bpp)
	Viewport32Bpp	(0888 RGB, sparse 32bpp (8+24))


What if my xterm uses another pixel layout?
-------------------------------------------

This is your chance to contribute to lib3d!

What you'll need to do is determine the actual pixel layout and size -
is it 32bpp sparse, or actually packed 24bpp?  16Bpp?  How are the
colours specified in the bit layout of the pixel?

If you are running X, which is all lib3d supports at the moment,
xdpyinfo can give you this information.

Once you know this, you will have a good idea which Viewport you want to
subclass.  Choose the one which has the same size pixels as your
display.  If you have a packed 24Bpp display, you'll have to create a
whole new one.

If not, you are lucky, and your task is really just to add a new
class, for now at the bottom of the appropriate ViewportXxx.C file,
overriding a two functions:

	uint getColour( uint r, uint g, uint b ) const   
		The inputs are in the range 0..255 - convert these into your
		native pixel format.

	const char *getName() const
		Return the name of the new class as a static string.  This
		is for debugging and so that the R_VIEWPORT thing can work.

This should be enough to get things working for you for now.  You'll
still have to say:

	R_VIEWPORT=Viewport32BppYUYV ./testobj   (or whatever)

because we haven't written the code to probe for the new viewport.  This
is the task of the clone() method.  You can write one of these, too,
if you want a bit more challenge.

This will probably mean making some XLib calls in the new class.
Don't worry about this too much - when you submit the new class back
to me, I'll expand the info passed around to include whatever you
need, so we can retain the potential for platform independance.

Now, if you really do have a packed 24Bpp or some other odd pixel-size
viewport, you will have to do all of the above, plus override and patch
the flatPolygonZb() method in your new class.  This is a more
significant task, but largely a cut and paste operation.  I'll leave
you to your own devices on this one.


How are Devices and Viewports registered?  How are they auto-selected?
--------------------------------------------------------------------

Look at the exemplar/virtual constructor mechanism (see James
Coplien's C++ text for background) to figure out how viewports register
themselves.  The auto-selection process is based on the 'speed'
parameter in the exemplar constructor, and the results of Viewport
*clone() method.

This is pretty much the same for Devices.  Devices should probe to see
if they are supported for the current execution envirionment - eg an
SVGA device shouldn't try to start up when executed from X, or vice
versa.  Viewports should verify that they are suitable for the device
that has already been created.

Porting
-------

With ports to other systems, (eg dos, windows, SVGA) the only code you
should need to write is a new Device.  All a device does is provide
and manage a memory mapped back buffer for the Viewport to draw into.

There are really four system-dependent methods in this class:

	clone() - probe for support for this device and possibly create.
		  (X devices actually pass this functionality off to the 
	           constructor...).  
		- Shouldn't do anything visible if at all possible.
	initialize() 
		- actually start up the new device - throws up a window in 
		  the X devices.
		- initialize Device::frameBuf to point to the back buffer.
		  (allocate some memory if there isn't one in hardware)
	allocateColour()
		- only meaningful for clut type devices (eg 8bpp VGA).
	swapBuffers()
		- the true purpose of the Device class.

This shouldn't be too difficult.  To register a properly constructed
device, just include it in the Makefile.  There is a good chance that
future devices will be restricted to a multiple of 4 bytes per span
line, so bear this in mind.


Debugging
---------

Lib3d has a builtin debugging facility, which can be enabled by
recompiling with the appropriate options (see the top of the
makefile).

Once compiled in, debugging can be enabled or disabled on a per-class
basis, by adding substrings of the names of classes to be debugged to
the file 'debug.conf'.

Thus, you can turn on debugging for all Viewports by adding the line:

-----------------<snip>---------------
Viewport
-----------------<snip>---------------

to debug.conf.  You can alter this to 

-----------------<snip>---------------
DitherViewport
-----------------<snip>---------------

to restrict debugging to just the DitherViewport class.  If you want to
'comment out' a line in debug.conf, you can use just about any
character you like as a comment char.  Eg, all of the following are
commented out:

-----------------<snip>----------------
# DitherViewport
xDitherViewport
 DitherViewport
DitherViewport  ...not!
-----------------<snip>----------------

If you want to turn on debugging for *all* classes, just add an empty
(ie no spaces or anything) line to debug.conf.  This is a substring of
every string, so will turn on debugging for all classes.


