




               The Graphics Engine version 1.30 Documentation
                              05 January 1994

                The Graphics Engine software and manual are
               Copyright (c) 1993-1994 by Matthew Hildebrand.
                            All rights reserved.




Topics covered in this document:


     INTRODUCTION
     WHY USE TGE?
     TERMS OF USAGE AND DISTRIBUTION
     SYSTEM REQUIREMENTS
     PACKING LIST
     RELEASE NOTES FOR VERSION 1.30
     A CRASH COURSE IN GRAPHICS PROGRAMMING
     USING TGE IN A PROGRAM
     TGE'S GRAPHICAL FUNCTION SET
     VIEWPORTS AND CLIPPING
     VIRTUAL COORDINATES
     VIRTUAL SCREENS
     GRAPHICAL OUTPUT MODES
     USING FONTS
     BITMAP MANIPULATION
     PALETTE MANIPULATION
     USING THE MOUSE
     TGE'S MOUSE FUNCTION SET
     CREATING FONTS
     USING PCX2RAW AND GRAPHICS FILES
     CONTACTING THE AUTHOR
     OBTAINING THE NEWEST VERSION OF TGE
     KNOWN PROBLEMS USING TGE
     ACKNOWLEDGEMENT
     LEGAL MUMBO JUMBO




INTRODUCTION


     The Graphics Engine is the result of my efforts to construct a library
     of routines designed to make writing C/C++ graphics applications
     easier.  I have used it in my own programs with excellent results.
 
     TGE allows the DOS programmer to easily access many graphics modes,
     without having to do special coding for each; the complications
     involved with supporting more than one graphics mode are removed.  TGE
     also provides remarkable flexibility and expandability through its
     modular design.



WHY USE TGE?


     TGE provides a simple, standard interface with which programs may
     access a powerful library of graphical functions.  TGE supports
     device-independence through the use of loadable drivers; loadable
     fonts; viewports; virtual screens of definable sizes; graphics output
     using COPY, AND, NOT, OR, and XOR, even to virtual screens; bitmap
     scaling; interrupt-driven, definable mouse pointer services; direct
     manipulation of PCX, RAW, and PAL files; and a virtual coordinate
     system to make device-independence easier.

     TGE's use of loadable graphics drivers means that all code and data
     necessary to handle any given graphics mode is stored in a disk file.
     When a program runs, this file will be loaded into memory and the code
     and data it contains will be made available.  Consequently:
          - Support for more graphics modes may be added simply by creating
            more drivers; programs need not be recompiled.
          - Since the code to manage the specifics of each mode is
            contained in the drivers, the main program needs not concern
            itself with what mode it is operating in.  The same code can
            work in any graphics mode.
          - Memory is saved for programs which support many graphics modes.
            Instead of keeping the code and data necessary for each in
            memory at all times, only the memory required for one driver is
            used.

     The names of the graphical functions, such as "putImage" and
     "filledRect" may easily be changed to suit individual preferences.

     TGE is powerful, fast, and cheap.  Upgrades are free.



TERMS OF USAGE AND DISTRIBUTION


     TGE is not free; it is distributed on a "try before you buy" basis.
     Permission is granted to use TGE, for evaluation purposes only, for a
     trial period of up to 30 days.  In order to use TGE after the trial
     period, you MUST REGISTER; registration entitles you free upgrades,
     technical support, a copy of TGE's source code, and royalty-free
     distribution rights for all software written using TGE.  Failure to
     register constitutes theft and is punishable by law.

     By purchasing a copy of TGE, you signify that you have read and
     understood the terms of usage and distribution as laid out in this
     document, and that you agree to be bound by these terms; you also
     signify that you agree to release the Author (Matthew Hildebrand) from
     all liability associated with the use of TGE.

     In order to register a copy of TGE, send $30 US funds or $40 Canadian
     funds to Matthew Hildebrand at the address listed in the CONTACTING
     THE AUTHOR section of this document.  Corporate users, send an
     additional $100 per software package built using TGE.  Payment by
     money order, check, or cash is acceptable; currency must be US or
     Canadian funds.  Also, be sure to send a filled out copy of
     REGISTER.FRM with your payment.  Thank you in advance for registering
     TGE; your support is what makes its continued growth possible.

     Upon receipt of your registration, I will mail you a copy of the
     registered version of TGE, which includes complete source code; this
     copy of TGE may not be distributed in any way.  Once I have mailed you
     a copy of the registered version, you will be considered a registered
     user.  If you are interested in receiving new versions as they are
     released, refer to paragraph two of the OBTAINING THE NEWEST VERSION
     OF TGE section.

     The privileges granted by purchasing TGE may be retracted if any of
     the copyright notices in TGE's source files is modified or removed, if
     any or all of the registered version of TGE is distributed in any way,
     or if any or all of TGE's source code is distributed as part of a
     software package.

     The shareware version of TGE may be distributed freely as long as the
     distributed package is complete and its contents are not modified in
     any way, and the distributed package is not sold for profit.



SYSTEM REQUIREMENTS


     TGE is a C/C++ programmer's library.  As such, it requires a C or C++
     compiler of some sort to work with it.  TGE was written and tested
     with Borland C++ 2.0 and Turbo C 2.0; it should work with other C/C++
     compilers as well.

     The drivers that come with TGE are written using 80386 instructions;
     they therefore cannot be used on a processor older than the 386 unless
     they are modified first.

     The font and virtual coordinate systems are written in C++, not C.  In
     order to use loadable fonts or VCOORD.H, a C++ compiler will be
     required.



PACKING LIST


     The current version of TGE consists of the following files:

     \TGE\               <DIR>
         TGE.DOC                   TGE documentation.
         REVISION.HST              Revision history.
         REGISTER.FRM              Registration form (shareware version
                                     only).
         UNIVESA.DOC               Universal VESA TSR documentation.
         UNIVESA.EXE               Universal VESA TSR executable.
         README.NOW                Important information.
         FILE_ID.DIZ               Archive description file used by some
                                     bulletin board systems (shareware
                                     version only).
     \TGE\INCLUDE\       <DIR> TGE include files.
         TGE.H                     TGE main header file.
         TGEFONT.H                 TGE font system header file.
         TGEMOUSE.H                Mouse header file.
         VCOORD.H                  Virtual coordinate system (C++ only).
     \TGE\SOURCE\        <DIR> TGE's source code (registered version only).
         TGE.C                     TGE main C file.
         TGESETUP.C                TGE setup file.
         CLIP.C                    Clipping routines.
         TGEFONT.CPP               TGE font system (C++ only).
         TGEMOUSE.ASM              Various mouse routines.
         MOUSEPTR.C                Definable mouse pointer support.
         NEWMOUSE.ASM              More definable pointer support.
         SCALE.C                   Bitmap scaling routine.
         PALETTE.C                 Palette fading and rotation.
         RAWFILE.C                 RAW file routines.
         PCXFILE.C                 PCX file routines.
         320X200.ASM               320x200x256 source.
         320X240.ASM               320x240x256 source.
         320X400.ASM               320x400x256 source.
         360X480.ASM               360x480x256 source.
         640X480.ASM               640x480x256 source.
         800X600.ASM               800x600x256 source.
         1024X768.ASM              1024x768x256 source.
         SHELL.ASM                 Skeleton driver source; use this file
                                     as a basis in making custom drivers.
         CDRV.BAT                  Batch file to make a .DRV from .ASM.
       \TGE\LIB\         <DIR> Library directory.
         BCL.MAK                   Makefile for Borland C++ large model
                                     library.
         BCH.MAK                   Makefile for Borland C++ huge model
                                     library.
         TGELIB.LST                Listfile used by library makefiles.
         BCL.LIB                   Borland C++ large model library.
         BCH.LIB                   Borland C++ huge model library.
       \TGE\UTIL\        <DIR> PCX2RAW and MAKEFONT utilitites.
         PCX2RAW.C                 Source for PCX2RAW.
         PCX2RAW.EXE               Convert PCX files to RAW and PAL files.
         MAKEFONT.C                Source for MAKEFONT.
         MAKEFONT.EXE              Make a font from individual bitmaps.
       \TGE\DRIVERS\     <DIR> Loadable drivers.
         320X200.DRV               Driver for VGA 320x200x256.
         320X240.DRV               Driver for VGA 320x240x256.
         320X400.DRV               Driver for VGA 320x400x256.
         360X480.DRV               Driver for VGA 360x480x256.
         640X480.DRV               Driver for SuperVGA 640x480x256.
         800X600.DRV               Driver for SuperVGA 800x600x256.
         1024X768.DRV              Driver for SuperVGA 1024x768x256.
       \TGE\FONTS\       <DIR> Loadable fonts.
         BIGTEXT.FNT               Big letters (variable-sized).
         8X8.FNT                   8x8 font (fixed-size).
         8X14.FNT                  8x14 font (fixed-size).
         8X16.FNT                  8x16 font (fixed-size).
       \TGE\DEMO\        <DIR> Demo programs.
         TGEDEMO.DOC               Documentation for demo program.
         TGEDEMO.CPP               Source code for demo program.
         MAKEFILE                  Makefile for the demo program.
         TGEDEMO.EXE               TGE demo program executable.
         TGELOGO.RAW               Data file used by the TGE demo program.
         SIMPLE.CPP                A skeleton TGE program showing interface
                                     basics.

     If you did not receive all of these files, you have an illegal copy of
     The Graphics Engine.



RELEASE NOTES FOR VERSION 1.30


     **IMPORTANT**  Changes follow:
        - TGE will no longer save and restore the palette during
          text/graphics switches.
        - For clarity, some of the member functions of the Font class have
          been renamed; the changes are listed below, with the old names
          on the left and the new names on the right.  The Font class
          itself has been renamed to FixedFont.
                    wide                width
                    maxWide             maxWidth
                    deep                height
                    maxDeep             maxHeight
        - setBlockPalette() and getBlockPalette() now have a slightly
          different argument list; refer to these functions' documentation
          for details.
        - MAKELIB.BAT and TGE.LIB have been replaced by BCL.LIB (Borland
          C++ large model), BCL.MAK (makefile for BCL.LIB), BCH.LIB
          (Borland C++ huge model), and BCH.MAK (makefile for BCH.LIB).
          Rather than using MAKELIB.BAT, these libraries may now be
          generated by running 'MAKE -fbcl.mak' or 'MAKE -fbch.mak'.

     Now for all the nifty new stuff since 1.20:
        - Added support for virtual screens of varying sizes.
        - Added a virtual coordinate system to ease the task of dealing
          with multiple resolutions.
        - TGE can now output using COPY, AND, NOT, OR, and XOR (even to
          virtual screens).
        - There is now an input viewport and an output viewport, which
          operate independently; ie. the input viewport is used for input
          operations such as getImage(), while the output viewport is used
          for output operations such as drawRect().
        - The functions imageSizeDim(), putLineInv(), and vertLine() have
          been added.
        - There is now a bitmap scaling feature, via scaleBitmap().
        - The PCX2RAW utility and the fixed-size monochrome font file
          structure are now documented.  (Oops...)
        - TGE now supports 256-colour fonts with variable-sized characters.
          The MAKEFONT utility is included to create a font file from
          individual character bitmap files.
        - Drivers now use 32-bit assembler code for extra speed.
        - Reduced memory requirements for fixed-size monochrome fonts.
        - Added support for palette fading and rotation.
        - Added native support for RAW, PAL, and PCX files.
        - Many optimizations, bug fixes, and documentation touch-ups.
        - Added the UNIVESA TSR to the TGE package so that more SVGAs can
          be supported.
        - The demo program has been updated.
     For a complete list of changes since TGE 1.20, refer to the
     REVISION.HST file.

     The drivers used with this release are not compatible with those from
     version 1.20 or older, since many changes have been made to the driver
     structure in order to allow for these new features.



A CRASH COURSE IN GRAPHICS PROGRAMMING


     A graphics screen is composed of thousands or even hundreds of
     thousands of coloured dots called "pixels".  Each pixel is referenced
     according to its offset, in coordinate form, from the upper-left of
     the screen:  (0,0), or the "origin".  The 'x' of a pixel's (x,y)
     location signifies the column number, and the 'y' signifies the row
     number; for example, a 640x480 screen would have (0,0) in the upper-
     left and (639,479) in the lower-right.

     Each of these pixels has a colour which is recorded as a number,
     ranging from 0..255 in 256-colour modes.  Each of these numbers is an
     index into a table of colours which the video card maintains:  the
     "palette".  The palette is what determines which colour is represented
     by certain numbers; for instance, what colour is colour number 196?
     Blue?  Green?  Purple?  It depends on the current setting of the
     palette register for colour number 196.

     Each of these palette registers consists of three components:  the
     red, green, and blue values, each of which is in the range 0..255.
     All the displayable colours are composed of these three primary
     colours in some proportion.  For instance, a purple would have lots of
     red and blue, but little or no green.

     The palette can be a powerful tool, as changing palette register, say,
     48, causes all pixels on-screen with the value of 48 to instantly
     change to the new colour.  It is important to keep in mind that the
     palette is a global palette; ie. it affects the entire screen.

     That's all there is to it!  <grin>



USING TGE IN A PROGRAM


     TGE now uses two environment variables:  TGEDRIVERS and TGEFONTS.
     Though these environement variables are not necessary, it is
     recommended that you add the following lines to your AUTOEXEC.BAT
     file:
          set TGEDRIVERS=drive:\tge\drivers\
          set TGEFONTS=drive:\tge\fonts\
     where 'drive:' is the drive on which you installed TGE.  The trailing
     backslash is required.


     Incorporating TGE into a program is an easy process involving three
     simple steps.  First, you must be sure that TGE is recognized by the
     program; to do so, #include the header file TGE.H into any source file
     which accesses any of TGE's routines; you may also need to #include
     other header files, such as TGEMOUSE.H if you use TGE's mouse code.
     Also, ensure that the appropriate library file is linked in with the
     program's OBJ files to make the EXE file; available library files are
     BCL.LIB (Borland C++ large model) and BCH.LIB (Borland C++ huge
     model).

     Second, a graphics driver MUST be loaded before any code or data
     contained in the driver is accessed; results are undefined (though
     almost certainly bad) if this step is not taken.  Code to load a
     driver might look like this:

          if (loadGraphDriver(drvFileName) != TGE_SUCCESS)
          {
            printf("Error loading driver %s; aborting.\n\n", drvFileName);
            exit(EXIT_FAILURE);
          }
          else
            atexit(unloadGraphDriver);

     The function loadGraphDriver() must be called.  As its only parameter,
     it takes a string consisting of the file name (which may include any
     valid DOS path) of the driver to be loaded; note that if the specified
     filename cannot be found, TGE will attempt to load it from the
     directory specified by the TGEDRIVERS environment variable.
     loadGraphDriver() returns the success code TGE_SUCCESS if the loading
     was successful, or one of TGE_OPEN_ERR (file not found),
     TGE_FORMAT_ERR (file is not a valid TGE driver), TGE_ALLOC_ERR (out of
     memory), and TGE_FILE_ERR (general file I/O error) if an error
     occurred.  These macros are defined in TGE.H.

     Third, after TGE's graphical functions are no longer needed (usually
     just before a program exit), the function unloadGraphDriver() should
     be called.  It takes no parameters, and returns nothing.  It simply
     frees the memory taken up by a driver after it has been loaded.  (With
     some compilers it is not necessary to call this function, but it's
     safer to call it just to be sure.)  It is generally a good idea to
     place unloadGraphDriver() in the atexit() queue, as was done in the
     above code fragment.


     Note that the initGraphics() function must be called to enter graphics
     mode; for more information, see the next section.  For more
     information on how to use any particular feature, refer to the
     appropriate section of this document.



TGE'S GRAPHICAL FUNCTION SET


     After a driver has been loaded, all of TGE's graphical functions can
     be accessed.  To call a function, simply execute

          functionName(parameter_list);

     where "functionName" is the name of the desired function (eg.
     "ellipse" or "filledRect") and "parameter_list" is all parameters to
     that function, if any.

     A complete list of TGE's graphical functions follows.


 *** Function:      initGraphics()
     Syntax:        void initGraphics(void);
     Purpose:       Initialize graphics mode.
     Parameters:    None.
     Return value:  1 on success or 0 on error.
     Remarks:       None.
     See also:      deInitGraphics()

 *** Function:      deInitGraphics()
     Syntax:        void deInitGraphics(void);
     Purpose:       Revert to 80x25 colour text mode.
     Parameters:    None.
     Return value:  None.
     Remarks:       None.
     See also:      initGraphics()

 *** Function:      putImage()
     Syntax:        void huge putImage(int x, int y, void far *image);
     Purpose:       Place a bitmap, or image, onto the screen.
     Parameters:    The bitmap contained in 'image' will be placed onto the
                    screen with its upper-left coordinate at ('x','y').
     Return value:  None.
     Remarks:            Clipping is performed; the image may be placed
                    entirely on-screen, partially on-screen, or entirely
                    off-screen.
                         This function is declared as huge so that it will
                    work properly when called from within an interrupt
                    service routine.
     See also:      putImageInv(), getImage(), imageSize(), imageSizeDim(),
                    putLine(), putLineInv(), getLine()

 *** Function:      putImageInv()
     Syntax:        void huge putImageInv(int x, int y, void far *image);
     Purpose:       Place a bitmap, or image, on the screen.
     Parameters:    The bitmap contained in 'image' will be placed onto the
                    screen with its upper-left coordinate at ('x','y').
     Return value:  None.
     Remarks:            Clipping is performed; the image may be placed
                    entirely on-screen, partially on-screen, or entirely
                    off-screen.    putImageInv() differs from putImage()
                    only in that it allows for transparent, or invisible,
                    colours.  If any pixel in the image buffer has a value
                    of zero, the corresponding pixel on-screen will not be
                    modified.  Using putImageInv() can avoid having black
                    borders around non-rectangular shapes.
                         This function is declared as huge so that it will
                    work properly when called from within an interrupt
                    service routine.
     See also:      putImage(), getImage(), imageSize(), imageSizeDim(),
                    putLineInv(), putLine(), getLine()

 *** Function:      getImage()
     Syntax:        void huge getImage(int ulx, int uly, int lrx, int lry,
                    void far *image);
     Purpose:       Copy the specified rectangular portion of the screen to
                    memory.
     Parameters:    The portion of the screen with its upper-left
                    coordinate at ('ulx','uly') and its lower-left
                    coordinate at ('lrx','lry') will be copied into the
                    previously allocated memory region at 'image' (see
                    imageSize()).
     Return value:  None.
     Remarks:            Clipping is performed.  Note that only the portion
                    of the specified region which lies within the current
                    viewport will be placed in the image buffer by
                    getImage().  Be careful not to assume that a getImage()
                    image has off-screen data in it.
                         This function is declared as huge so that it will
                    work properly when called from within an interrupt
                    service routine.
     See also:      putImage(), putImageInv(), imageSize(), imageSizeDim(),
                    getLine(), putLine(), putLineInv()

 *** Function:      imageSize()
     Syntax:        unsigned long imageSize(int ulx, int uly, int lrx, int
                    lry);
     Purpose:       Determine the amount of memory required to hold a
                    rectangular portion of the screen.
     Parameters:    imageSize() will calculate the amount of memory
                    required to hold the porion of the screen whose upper-
                    left coordinate is ('ulx','uly') and whose lower-left
                    coordinate is ('lrx','lry').
     Return value:  imageSize returns an unsigned long containing the size
                    of the area in bytes.
     Remarks:            Clipping is performed.
                         imageSize() is designed for use with putImage(),
                    putImageInv(), and getImage().  To use it with
                    putLine() and getLine(), subtract 4 from the value it
                    returns.  (Image buffers have four bytes of dimension
                    information in them; line buffers do not.)
     See also:      imageSizeDim(), putImage(), putImageInv(), getImage(),
                    putLine(), getLine()

 *** Function:      imageSizeDim()
     Syntax:        unsigned long imageSizeDim(unsigned wide, unsigned
                    deep);
     Purpose:       Determine the amount of memory required to hold a
                    rectangular portion of the screen.
     Parameters:    imageSize() will calculate the amount of memory
                    required to hold the porion of the screen with width
                    'wide' and depth 'deep'.
     Return value:  imageSize returns an unsigned long containing the size
                    of the area in bytes.
     Remarks:            Clipping is not performed.
                         imageSizeDim() is designed for use with
                    putImage(), putImageInv(), and getImage().  To use it
                    with putLine() and getLine(), subtract 4 from the value
                    it returns.  (Image buffers have four bytes of
                    dimension information in them; line buffers do not.)
     See also:      imageSize(), putImage(), putImageInv(), getImage(),
                    putLine(), getLine()

 *** Function:      putLine()
     Syntax:        void putLine(int lineNum, int xOff, int lineLen, void
                    far *buf);
     Purpose:       Place one horizontal line of image data on the screen.
     Parameters:    The one-line bitmap contained in 'buf', of 'lineLen'
                    pixels, will be placed on-screen starting at
                    ('xOff','lineNum').
     Return value:  None.
     Remarks:       No clipping is performed.  Results are undefined if any
                    coordinate on the line is off-screen.
     See also:      putLineInv(), getLine(), putImage(), putImageInv(),
                    getImage()

 *** Function:      putLineInv()
     Syntax:        void putLineInv(int lineNum, int xOff, int lineLen,
                    void far *buf);
     Purpose:       Place one horizontal line of image data on the screen,
                    leaving a pixel unchanged if the corresponding pixel in
                    the source buffer has a value of zero.  This function
                    is the single-line equivalent to putImageInv().
     Parameters:    The one-line bitmap contained in 'buf', of 'lineLen'
                    pixels, will be placed on-screen starting at
                    ('xOff','lineNum').
     Return value:  None.
     Remarks:       No clipping is performed.  Results are undefined if any
                    coordinate on the line is off-screen.
     See also:      putLine(), getLine(), putImage(), putImageInv(),
                    getImage()

 *** Function:      getLine()
     Syntax:        void getLine(int lineNum, int xOff, int lineLen, void
                    far *buf);
     Purpose:       Copy one horizontal line from the screen to memory.
     Parameters:    The horizontal line whose left coordinate is
                    ('xOff','lineNum') and whose length is 'lineLen' pixels
                    will be copied into the previously allocated memory
                    region at 'buf'.
     Return value:  None.
     Remarks:       No clipping is performed.  Results are undefined if any
                    coordinate on the line is off-screen.
     See also:      putLine(), putLineInv(), putImage(), putImageInv(),
                    getImage()

 *** Function:      putPixel()
     Syntax:        void putPixel(int x, int y, unsigned colour);
     Purpose:       Place a single pixel on-screen.
     Parameters:    The pixel located at ('x','y') will be set to the
                    colour 'colour'.
     Return value:  None.
     Remarks:       Clipping is not performed; see clipPoint() and
                    pointOnScreen() for details on clipping pixels.
     See also:      getPixel()

 *** Function:      getPixel()
     Syntax:        unsigned getPixel(int x, int y);
     Purpose:       Return the value of a pixel.
     Parameters:    The value of the pixel at ('x','y') is returned.
     Return value:  The value of the pixel at ('x','y') is returned.
     Remarks:       Clipping is not performed; see clipPoint() and
                    pointOnScreen() for details on clipping pixels.
     See also:      putPixel()

 *** Function:      line()
     Syntax:        void line(int x1, int y1, int x2, int y2, unsigned
                    colour);
     Purpose:       Draw a line between two points.
     Parameters:    The line will be drawn joining ('x1','y1') and
                    ('x2','y2') in the colour 'colour'.
     Return value:  None.
     Remarks:       Clipping is not performed; see clipLine() for details
                    on clipping lines.
     See also:      horizLine(), vertLine()

 *** Function:      horizLine()
     Syntax:        void horizLine(int y, int x1, int x2, unsigned colour);
     Purpose:       Draw a horizontal line between two points.
     Parameters:    The line will be drawn between ('x1','y') and
                    ('x2','y') in the colour contained in colour.
     Return value:  None.
     Remarks:            Clipping is not performed.
                         'x1' must be less than or equal to 'x2'.
     See also:      vertLine(), line()

 *** Function:      vertLine()
     Syntax:        void vertLine(int x, int y1, int y2, unsigned colour);
     Purpose:       Draw a vertical line between two points.
     Parameters:    The line will be drawn between ('x','y1') and
                    ('x','y2') in the colour contained in colour.
     Return value:  None.
     Remarks:            Clipping is not performed.
                         'y1' must be less than or equal to 'y2'.
     See also:      horizLine(), line()

 *** Function:      drawRect()
     Syntax:        void drawRect(int ulx, int uly, int lrx, int lry,
                    unsigned colour);
     Purpose:       Draw a rectangle.
     Parameters:    The rectangle will be drawn with its upper-left
                    coordinates at ('ulx','uly') and its lower-left
                    coordinates at ('lrx','lry'), in the colour 'colour'.
     Return value:  None.
     Remarks:       Clipping is performed.
     See also:      filledRect()

 *** Function:      filledRect()
     Syntax:        void filledRect(int ulx, int uly, int lrx, int lry,
                    unsigned colour);
     Purpose:       Draw a filled rectangle.
     Parameters:    The rectangle will be drawn with its upper-left
                    coordinates at ('ulx','uly') and its lower-left
                    coordinates at ('lrx','lry'), in the colour 'colour'.
     Return value:  None.
     Remarks:       Clipping is not performed; see clipFilledRect() for
                    details on clipping filledRects.
     See also:      drawRect()

 *** Function:      setPaletteReg()
     Syntax:        void setPaletteReg(unsigned palReg, unsigned char red,
                    unsigned char green, unsigned char blue);
     Purpose:       Set a palette register.
     Parameters:    The red, green, and blue components of the palette
                    register palReg will be set to 'red', 'green', and
                    'blue' respectively.
     Return value:  None.
     Remarks:       Each of the colour components ('red', 'green', 'blue')
                    should be in the range 0..255, not 0..63 as would be
                    the case using a stock VGA.  The drivers will take care
                    of converting 8-bit to 6-bit palette resolution if
                    necessary.
     See also:      getPaletteReg(), setBlockPalette(), getBlockPalette()

 *** Function:      getPaletteReg()
     Syntax:        void getPaletteReg(unsigned palReg, unsigned char far
                    *red, unsigned char far *green, unsigned char far
                    *blue);
     Purpose:       Return the current settings of a palette register.
     Parameters:    The red, green, and blue contents of the palette
                    register palReg will be stored in 'red', 'green', and
                    'blue' respectively.
     Return value:  The red, green, and blue components of the palette
                    register are returned in 'red', 'green', and 'blue'.
     Remarks:       Each of the colour components ('red', 'green', 'blue')
                    are in the range 0..255, not 0..63 as would be the case
                    using a stock VGA card.  The drivers will take care of
                    converting 8-bit to 6-bit palette resolution if
                    necessary.
     See also:      setPaletteReg(), setBlockPalette(), getBlockPalette()

 *** Function:      setBlockPalette()
     Syntax:        void setBlockPalette(unsigned firstReg, unsigned
                    lastReg, void far *data);
     Purpose:       Set a block of palette registers.
     Parameters:    The palette registers starting at 'firstReg' and ending
                    at 'lastReg' will be set to the values contained in
                    'data'.
     Return value:  None.
     Remarks:            The memory region at 'data' is organised in groups
                    of three bytes; each group corresponds to one palette
                    register, and each group is made up of, in order, the
                    red, green, and blue components.  The first group is
                    for the first register, the second for the second, and
                    so on.
                         Each of the colour components (red, green, blue)
                    should be in the range 0..255, not 0..63 as would be
                    the case using a stock VGA.  The drivers will take care
                    of converting 8-bit to 6-bit palette resolution if
                    necessary.
                         Results are undefined if 'lastReg' is less than
                    'firstReg'.
     See also:      getBlockPalette(), setPaletteReg(), getPaletteReg()

 *** Function:      getBlockPalette()
     Syntax:        void getBlockPalette(unsigned firstReg, unsigned
                    lastReg, void far *data);
     Purpose:       Get the values of a block of palette registers.
     Parameters:    The values of the palette registers starting at
                    'firstReg' and ending at 'lastReg' will be stored in
                    the previously allocated 'data'.
     Return value:  The values are returned in 'data'.
     Remarks:            The memory region at 'data' is organised in groups
                    of three bytes; each group corresponds to one palette
                    register, and each group is made up of, in order, the
                    red, green, and blue components.  The first group is
                    for the first register, the second for the second, and
                    so on.
                         Each of the colour components (red, green, blue)
                    is in the range 0..255, not 0..63 as would be the case
                    using a stock VGA.  The drivers will take care of
                    converting 8-bit to 6-bit palette resolution if
                    necessary.
                         Results are undefined if 'lastReg' is less than
                    'firstReg'.
     See also:      setBlockPalette(), setPaletteReg(), getPaletteReg()

 *** Function:      clearGraphics()
     Syntax:        void clearGraphics(unsigned colour);
     Purpose:       Clear the screen.
     Parameters:    The screen will be cleared to the colour 'colour'.
     Return value:  None.
     Remarks:       This function clears the entire screen, not just the
                    current viewport.
     See also:      filledRect()

 *** Function:      ellipse()
     Syntax:        void ellipse(int x, int y, int wide, int deep, unsigned
                    colour);
     Purpose:       Draw the outline of an ellipse.
     Parameters:    An ellipse centered at ('x','y') and having width
                    'wide' and depth 'deep' will be drawn in the colour
                    'colour'.
     Return value:  None.
     Remarks:       Clipping is performed.
     See also:      filledEllipse(), circle(), filledCircle()

 *** Function:      filledEllipse()
     Syntax:        void filledEllipse(x, int y, int wide, int deep,
                    unsigned colour);
     Purpose:       Draw a filled ellipse.
     Parameters:    An ellipse centered at ('x','y') and having width
                    'wide' and depth 'deep' will be drawn in the colour
                    'colour'.
     Return value:  None.
     Remarks:       Clipping is performed.
     See also:      ellipse(), filledCircle(), circle()

 *** Function:      circle()
     Syntax:        void circle(int x, int y, int radius, unsigned colour);
     Purpose:       Draw the outline of a circle.
     Parameters:    A circle centered at ('x','y') and having radius
                    'radius' will be drawn in the colour 'colour'.
     Return value:  None.
     Remarks:            Clipping is performed.
                         The 'radius' parameter is the radius in pixels
                    measured horizontally.  Although there will be no
                    difference in modes with square pixels, it will make a
                    difference in other modes; to ensure accurate drawing
                    of the circle with the given radius, make certain that
                    the radius is measured horizontally.
                         TGE uses an all-integer approach to coordinate
                    scaling to ensure that the drawn shape will be circular
                    in modes without square pixels.
     See also:      filledCircle(), filledEllipse(), ellipse()

 *** Function:      filledCircle()
     Syntax:        void filledCircle(int x, int y, int radius, unsigned
                    colour);
     Purpose:       Draw a filled circle.
     Parameters:    A circle centered at ('x','y') and having radius
                    'radius' will be drawn in the colour 'colour'.
     Return value:  None.
     Remarks:            Clipping is performed.
                         The 'radius' parameter is the radius in pixels
                    measured horizontally.  Although there will be no
                    difference in modes with square pixels, it will make a
                    difference in other modes; to ensure accurate drawing
                    of the circle with the given radius, make certain that
                    the radius is measured horizontally.
                         TGE uses an all-integer approach to coordinate
                    scaling to ensure that the drawn shape will be circular
                    in modes without square pixels.
     See also:      circle(), ellipse(), filledEllipse()

 *** Function:      fillRegion()
     Syntax:        void fillRegion(int x, int y, unsigned colour);
     Purpose:       Floods a region of the screen with the specified
                    colour.
     Parameters:    The fill will begin at the seed point ('x','y'), and
                    will fill with the colour 'colour'.
     Return value:  None.
     Remarks:            The region to be filled is bounded by any colour
                    not equal to the colour at ('x','y'); ie., the region
                    to be filled consists of one colour only.
                         Clipping is performed.
     See also:      None.

 *** Function:      colourCloseTo()
     Syntax:        unsigned colourCloseTo(unsigned char red, unsigned char
                    green, unsigned char blue);
     Purpose:       Given a 24-bit colour, find the colour from the current
                    palette which most closely matches it.
     Parameters:    The 24-bit colour is defined by the 'red', 'green', and
                    'blue' parameters.
     Return value:  Returns the colour which most closely matches the
                    specified 24-bit colour.
     Remarks:       None.
     See also:      colourCloseToX()

 *** Function:      colourCloseToX()
     Syntax:        unsigned colourCloseToX(unsigned char red, unsigned
                    char green, unsigned char blue, unsigned
                    colourExclude);
     Purpose:       Given a 24-bit colour, find the colour from the current
                    palette which most closely matches it, with the
                    specified colour disallowed from the search.
     Parameters:    The 24-bit colour is defined by the 'red', 'green', and
                    'blue' parameters.  The colour 'colourExclude' is
                    excluded from the search, and so will never be
                    returned.
     Return value:  Returns the colour which most closely matches the
                    specified 24-bit colour.
     Remarks:       Excluding zero from a search will ensure that the
                    returned colour will be visible when it is used as part
                    of a bitmap displayed using putImageInv().
     See also:      colourCloseTo()


     Note that since these function names are actually macros, they may
     easily be changed to suit individual preferences by editing TGE.H.



VIEWPORTS AND CLIPPING


     A viewport is a rectangular region on the screen to which output is
     clipped, so that graphics output will appear only within that region.
     By default, this region is the entire screen; however, it can be set
     to any rectangular portion of the screen.  (Note that when a viewport
     is in use, coordinates are absolute, not relative to the viewport.)

     TGE now supports two viewports simultaneously:  an input viewport and
     an output viewport.  This feature was added primarily so that virtual
     screens (see the VIRTUAL SCREENS section) and the real screen could be
     used simultaneously, though it may have other uses as well.  The
     following functions are used to get and set the current input and
     output viewports:

 *** Function:      setInputViewport()
     Syntax:        void setInputViewport(int ulx, int uly, int lrx, int lry);
     Purpose:       Set the defining coordinates of the current input
                    viewport.
     Parameters:    The upper-left corner of the input viewport will be set to
                    ('ulx','uly'), and the lower-right corner to
                    ('lrx','lry').
     Return value:  None.
     Remarks:       It is assumed that 'ulx'<'lrx' and that 'uly'<'lry'.
     See also:      setOutputViewport(), setViewport(), getInputViewport(),
                    getOutputViewport()

 *** Function:      setOutputViewport()
     Syntax:        void setOutputViewport(int ulx, int uly, int lrx, int lry);
     Purpose:       Set the defining coordinates of the current output
                    viewport.
     Parameters:    The upper-left corner of the output viewport will be set
                    to ('ulx','uly'), and the lower-right corner to
                    ('lrx','lry').
     Return value:  None.
     Remarks:       It is assumed that 'ulx'<'lrx' and that 'uly'<'lry'.
     See also:      setInputViewport(), setViewport(), getOutputViewport(),
                    getInputViewport()

 *** Function:      setViewport()
     Syntax:        void setViewport(int ulx, int uly, int lrx, int lry);
     Purpose:       Set the defining coordinates of the current input and
                    output viewports.
     Parameters:    The upper-left corner of the viewports will be set to
                    ('ulx','uly'), and the lower-right corner to
                    ('lrx','lry').
     Return value:  None.
     Remarks:       It is assumed that 'ulx'<'lrx' and that 'uly'<'lry'.
     See also:      setInputViewport(), setOutputViewport(),
                    getInputViewport(), getOutputViewport()

 *** Function:      getInputViewport()
     Syntax:        void getInputViewport(int *ulx, int *uly, int *lrx, int
                    *lry);
     Purpose:       Get the defining coordinates of the current input
                    viewport.
     Parameters:    The upper-left corner of the input viewport will be stored
                    in ('ulx','uly'), and the lower-right corner in
                    ('lrx','lry').
     Return value:  None.
     Remarks:       It is assumed that 'ulx'<'lrx' and that 'uly'<'lry'.
     See also:      getOutputViewport(), getViewport(), setInputViewport(),
                    setOutputViewport()

 *** Function:      getOutputViewport()
     Syntax:        void getOutputViewport(int *ulx, int *uly, int *lrx, int
                    *lry);
     Purpose:       Get the defining coordinates of the current output
                    viewport.
     Parameters:    The upper-left corner of the output viewport will be
                    stored in ('ulx','uly'), and the lower-right corner in
                    ('lrx','lry').
     Return value:  None.
     Remarks:       It is assumed that 'ulx'<'lrx' and that 'uly'<'lry'.
     See also:      setOutputViewport(), getViewport(), getInputViewport(),
                    getOutputViewport()


     Note that not all of TGE's functions will clip to within the current
     output viewport.  Some of the time-critical graphics primitives, such
     as putPixel() and line(), do not clip in order to improve execution
     time.  If it is necessary for such functions to have their output
     clipped, the following routines may be used:

 *** Function:      clipFilledRect()
     Syntax:        int clipFilledRect(int *x1, int *y1, int *x2, int *y2);
     Purpose:       Clip the given filled rectangle to within the current
                    output viewport.
     Parameters:    The upper-left and lower-right corners of the rectangle
                    are passed in ('x1','y1') and ('x2','y2').  If clipping
                    is done, these points will be modified.
     Return value:  Returns true if the rectangle lies entirely or
                    partially within the current output viewport, or false
                    if it is entirely outside the current output viewport.
     Remarks:            It does not matter which of the corner coordinates
                    is passed first; they will be swapped if necessary.
                         This function is contained in CLIP.C.

 *** Function:      clipLine()
     Syntax:        int clipLine(int *x1, int *y1, int *x2, int *y2);
     Purpose:       Clip the given line to within the current output
                    viewport.
     Parameters:    The endpoints of the line are passed in ('x1','y1') and
                    ('x2','y2').  If clipping is done, these endpoints will
                    be modified.
     Return value:  Returns true if the line lies entirely or partially
                    within the current output viewport, or false if it is
                    entirely outside the current output viewport.
     Remarks:       This function is contained in CLIP.C.
     See also:      None.

 *** Function:      clipPoint()
     Syntax:        int clipPoint(int x, int y);
     Purpose:       Return a flag indicating whether or not the specified
                    coordinates lie within the current viewport.
     Parameters:    The point ('x','y') is tested.
     Return value:  Returns true if ('x','y') is within the current
                    viewport, or 0 if it isn't.
     Remarks:       This function is really a macro defined in TGE.H.
     See also:      None.

 *** Function:      clipInputPoint()
     Syntax:        int clipInputPoint(int x, int y);
     Purpose:       Return a flag indicating whether or not the specified
                    coordinates lie within the current input viewport.
     Parameters:    The point ('x','y') is tested.
     Return value:  Returns true if ('x','y') is within the current
                    input viewport, or 0 if it isn't.
     Remarks:       This function is really a macro defined in TGE.H.
     See also:      None.

 *** Function:      clipOutputPoint()
     Syntax:        int clipOutputPoint(int x, int y);
     Purpose:       Return a flag indicating whether or not the specified
                    coordinates lie within the current output viewport.
     Parameters:    The point ('x','y') is tested.
     Return value:  Returns true if ('x','y') is within the current
                    output viewport, or 0 if it isn't.
     Remarks:       This function is really a macro defined in TGE.H.
     See also:      None.

 *** Function:      pointOnScreen()
     Syntax:        int pointOnScreen(int x, int y);
     Purpose:       Return a flag indicating whether or not the specified
                    coordinates lie on-screen.
     Parameters:    The point ('x','y') is tested.
     Return value:  Returns true if ('x','y') is on-screen, or 0 if it is
                    off-screen.
     Remarks:       This function is really a macro defined in TGE.H.
     See also:      None.


     Note that since these function names are actually macros, they may
     easily be changed to suit individual preferences by editing TGE.H.



VIRTUAL COORDINATES


     One of the problems associated with device-independence is that
     different display modes have different resolutions.  TGE provides a
     simple way to ease this problem, simply by #including VCOORD.H.  Doing
     so provides access to a simple yet powerful object-oriented virtual
     coordinate system.

     For the sake of illustration, assume that you are writing an
     application which ideally will be run in resolutions as high as
     1024x768, but can also be run in 320x200.  You want a way to have
     objects (eg., windows) retain the same sizes and positions on-screen
     in any graphics mode.  TGE's virtual coordinate system makes it easy.
     First, create an instance of the virtual coordinate object (I'll call
     the object virtScreen):

          VirtualCoord virtScreen;

     Then, virtScreen must be configured; I'll assume that the virtual
     screen is to be 1024x768, and that OUTMAXX and OUTMAXY have been
     initialized by loading a driver.  (Note that these parameters may be
     set during the class instantiation by using a different constructor.)

          virtScreen.virtParams(1023, 767);
          virtScreen.realParams(OUTMAXX, OUTMAXY);

     As an example, assume that you want to draw a light gray rectangle
     with upper-left coordinate (50,50) and lower-right coordinate
     (600,600) on the virtual screen.  On, say, a 360x480 screen these
     values will be quite different; to keep the proportion the same,
     execute a line like the following:

          drawRect(virtScreen.realX(50), virtScreen.realY(50),
                   virtScreen.realX(600), virtScreen.realY(600),
                   colourCloseTo(200,200,200));

     That's all there is to it!  Keep in mind that there are other
     applications of the VirtualCoord class, aside from a virtual screen;
     it can also be useful when dealing with portions of the screen, scaled
     bitmaps, etc..

     A complete list of the VirtualCoord member functions follows.


 *** Function:      VirtualCoord::VirtualCoord()
     Syntax:        VirtualCoord::VirtualCoord(void);
     Purpose:       Create an instance of the VirtualCoord class.
     Parameters:    None.
     Return value:  None.
     Remarks:       After an instantiation of a VirtualCoord using this
                    constructor, ensure that the screen dimensions, both
                    virtual and real, are initialized using the method
                    illustrated above.
     See also:      VirtualCoord::VirtualCoord(unsigned, unsigned,
                    unsigned, unsigned), VirtualCoord::virtParams(unsigned,
                    unsigned), VirtualCoord::realParams(unsigned, unsigned)

 *** Function:      VirtualCoord::VirtualCoord(unsigned, unsigned,
                    unsigned, unsigned)
     Syntax:        VirtualCoord::VirtualCoord(unsigned virtMaxX, unsigned
                    virtMaxY, unsigned realMaxX, unsigned realMaxY);
     Purpose:       Create an instance of the VirtualCoord class, and
                    initialize it.
     Parameters:    The maximum virtual x-coordinate is set to 'virtMaxX',
                    and the y-coordinate to 'virtMaxY'.  The maximum real
                    x-coordinate is set to 'realMaxX', and the y-coordinate
                    to 'realMaxY'.
     Return value:  None.
     Remarks:       Be sure that a driver has been loaded before passing
                    OUTMAXX and OUTMAXY to this constructor.
     See also:      VirtualCoord::VirtualCoord(unsigned, unsigned,
                    unsigned, unsigned), VirtualCoord::virtParams(unsigned,
                    unsigned), VirtualCoord::realParams(unsigned, unsigned)

 *** Function:      VirtualCoord::virtParams(unsigned, unsigned)
     Syntax:        void VirtualCoord::virtParams(unsigned virtMaxX,
                    unsigned virtMaxY);
     Purpose:       Set the maximum virtual x- and y-coordinates.
     Parameters:    The maximum virtual x-coordinate is set to 'virtMaxX',
                    and the maximum y-coordinate to 'virtMaxY'.
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::realParams(unsigned, unsigned),
                    VirtualCoord::virtParams(unsigned*, unsigned*),
                    VirtualCoord::realParams(unsigned*, unsigned*)

 *** Function:      VirtualCoord::realParams(unsigned, unsigned)
     Syntax:        void VirtualCoord::realParams(unsigned virtMaxX,
                    unsigned virtMaxY);
     Purpose:       Set the maximum real x- and y-coordinates.
     Parameters:    The maximum real x-coordinate is set to 'realMaxX', and
                    the maximum y-coordinate to 'realMaxY'.
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::virtParams(unsigned, unsigned),
                    VirtualCoord::realParams(unsigned*, unsigned*),
                    VirtualCoord::virtParams(unsigned*, unsigned*)

 *** Function:      VirtualCoord::virtParams(unsigned*, unsigned*)
     Syntax:        void VirtualCoord::virtParams(unsigned *virtMaxX,
                    unsigned *virtMaxY);
     Purpose:       Get the maximum virtual x- and y-coordinates.
     Parameters:    The maximum virtual x-coordinate is stored in
                    'virtMaxX', and the maximum y-coordinate in 'virtMaxY'.
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::realParams(unsigned*, unsigned*),
                    VirtualCoord::virtParams(unsigned, unsigned),
                    VirtualCoord::realParams(unsigned, unsigned)

 *** Function:      VirtualCoord::realParams(unsigned*, unsigned*)
     Syntax:        void VirtualCoord::realParams(unsigned *virtMaxX,
                    unsigned *virtMaxY);
     Purpose:       Get the maximum real x- and y-coordinates.
     Parameters:    The maximum real x-coordinate is stored in 'realMaxX',
                    and the maximum y-coordinate in 'realMaxY'.
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::virtParams(unsigned*, unsigned*),
                    VirtualCoord::realParams(unsigned, unsigned),
                    VirtualCoord::virtParams(unsigned, unsigned)

 *** Function:      VirtualCoord::realCoords()
     Syntax:        void VirtualCoord::realCoords(unsigned virtX, unsigned
                    virtY, unsigned *realX, unsigned *realY);
     Purpose:       Calculate the real (x,y) coordinates given the virtual
                    coordinates.
     Parameters:    The real (x,y) coordinates are returned in
                    ('realX','realY'), and are calculated based on the
                    virtual (x,y) coordinates ('virtX','virtY').
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::realX(), VirtualCoord::realY(),
                    VirtualCoord::virtCoords(), VirtualCoord::virtX(),
                    VirtualCoord::virtY()

 *** Function:      VirtualCoord::realX()
     Syntax:        unsigned VirtualCoord::realX(unsigned virtX);
     Purpose:       Calculate the real x-coordinate given the virtual x-
                    coordinate.
     Parameters:    The real x-coordinate is returned, calculated based on
                    the virtual x-coordinate 'virtX'.
     Return value:  Returns the real x-coordinate.
     Remarks:       None.
     See also:      VirtualCoord::realY(), VirtualCoord::realCoords(),
                    VirtualCoord::virtX(), VirtualCoord::virtY(),
                    VirtualCoord::virtCoords()

 *** Function:      VirtualCoord::realY()
     Syntax:        unsigned VirtualCoord::realY(unsigned virtY);
     Purpose:       Calculate the real y-coordinate given the virtual y-
                    coordinate.
     Parameters:    The real y-coordinate is returned, calculated based on
                    the virtual y-coordinate 'virtY'.
     Return value:  Returns the real y-coordinate.
     Remarks:       None.
     See also:      VirtualCoord::realX(), VirtualCoord::realCoords(),
                    VirtualCoord::virtY(), VirtualCoord::virtX(),
                    VirtualCoord::virtCoords()

 *** Function:      VirtualCoord::virtCoords()
     Syntax:        void VirtualCoord::virtCoords(unsigned realX, unsigned
                    realY, unsigned *virtX, unsigned *virtY);
     Purpose:       Calculate the virtual (x,y) coordinates given the real
                    coordinates.
     Parameters:    The virtual (x,y) coordinates are returned in
                    ('virtX','virtY'), and are calculated based on the real
                    (x,y) coordinate ('realX','realY').
     Return value:  None.
     Remarks:       None.
     See also:      VirtualCoord::virtX(), VirtualCoord::virtY(),
                    VirtualCoord::realCoords(), VirtualCoord::realX(),
                    VirtualCoord::realY()

 *** Function:      VirtualCoord::virtX()
     Syntax:        unsigned VirtualCoord::virtX(unsigned realX);
     Purpose:       Calculate the virtual x-coordinate given the real x-
                    coordinate.
     Parameters:    The virtual x-coordinate is returned, calculated based
                    on the real x-coordinate 'realX'.
     Return value:  Returns the virtual x-coordinate.
     Remarks:       None.
     See also:      VirtualCoord::virtY(), VirtualCoord::virtCoords(),
                    VirtualCoord::realX(), VirtualCoord::realY(),
                    VirtualCoord::realCoords()

 *** Function:      VirtualCoord::virtY()
     Syntax:        unsigned VirtualCoord::virtY(unsigned realY);
     Purpose:       Calculate the virtual y-coordinate given the real y-
                    coordinate.
     Parameters:    The virtual y-coordinate is returned, calculated based
                    on the real y-coordinate 'realY'.
     Return value:  Returns the virtual y-coordinate.
     Remarks:       None.
     See also:      VirtualCoord::virtX(), VirtualCoord::virtCoords(),
                    VirtualCoord::realY(), VirtualCoord::realX(),
                    VirtualCoord::realCoords()



VIRTUAL SCREENS


     In early releases of TGE, all graphics input and output operations
     were done on the screen.  Now four different I/O arrangements are
     available:
        - Input and output on the real screen.
        - Input and output on a virtual screen (ie. in memory).
        - Input from the real screen, and output to a virtual screen.
        - Input from a virtual screen, and output to the real screen.
     As well, it is possible to switch between these four I/O modes at any
     time with one or two simple function calls.

     Virtual screens are useful for such tasks as building complex images
     off-screen, then displaying them quickly.  Since a virtual screen has
     exactly the same format as the images used by getImage() and its
     associated functions, they can be displayed using a putImage() or
     putImageInv() call, simply by passing the address of the virtual
     screen as the address of the image to be displayed.


     A virtual screen (or any bitmap, for that matter) may be created using
     the following function:

 *** Function:      makeVirtScreen()
     Syntax:        void far *makeVirtScreen(unsigned wide, unsigned deep);
     Purpose:       Allocate enough RAM to store a virtual screen with the
                    specified dimensions, then initialize it.
     Parameters:    A virtual screen with width 'wide' and depth 'deep' (in
                    pixels) will be created.
     Return value:  Returns the address of the newly allocated virtual
                    screen, or NULL if there is not enough memory to create
                    it.
     Remarks:            Memory for the virtual screen is alloated from
                    available conventional memory; don't forget to
                    de-allocate (using farfree()) the memory occupied by a
                    virtual screen when the screen is no longer needed.
                         After it is allocated, a virtual screen will
                    likely be filled with random pixels.  Clearing it using
                    clearGraphics() is often a good idea (after graphics
                    output has been set to the virtual screen).
     See also:      None.
     

     The functions used to establish input and output to and from real and
     virtual screens are:

 *** Function:      setGraphicsAddr()
     Syntax:        void setGraphicsAddr(void far *addr);
     Purpose:       Set the location upon which graphics input and output
                    will both be performed.
     Parameters:    If 'addr' is equal to NULL, input and output will be
                    performed on the real screen; if 'addr' is non-NULL,
                    input and output will be performed on the virtual
                    screen pointed to by 'addr'.
     Return value:  None.
     Remarks:       This function sets the currently active input and
                    output viewports to cover the entirety of the virtual
                    screen.  INMAXX, INMAXY, OUTMAXX, and OUTMAXY are also
                    changed appropriately.
     See also:      setGraphicsInputAddr(), setGraphicsOutputAddr()

 *** Function:      setGraphicsInputAddr()
     Syntax:        void setGraphicsInputAddr(void far *addr);
     Purpose:       Set the location upon which graphics input will be
                    performed.
     Parameters:    If 'addr' is equal to NULL, input will be performed on
                    the real screen; if 'addr' is non-NULL, input will be
                    performed on the virtual screen pointed to by 'addr'.
     Return value:  None.
     Remarks:       This function sets the currently active input viewport
                    to cover the entirety of the virtual screen.  INMAXX
                    and INMAXY are also changed appropriately.
     See also:      setGraphicsOutputAddr(), setGraphicsAddr()

 *** Function:      setGraphicsOutputAddr()
     Syntax:        void setGraphicsOutputAddr(void far *addr);
     Purpose:       Set the location upon which graphics output will be
                    performed.
     Parameters:    If 'addr' is equal to NULL, output will be performed on
                    the real screen; if 'addr' is non-NULL, output will be
                    performed on the virtual screen pointed to by 'addr'.
     Return value:  None.
     Remarks:       This function sets the currently active output viewport
                    to cover the entirety of the virtual screen.  OUTMAXX
                    and OUTMAXY are also changed appropriately.
     See also:      setGraphicsInputAddr(), setGraphicsAddr()

 *** Function:      getGraphicsInputAddr()
     Syntax:        void far *getGraphicsInputAddr(void);
     Purpose:       Get the location upon which graphics input is currently
                    being performed.
     Parameters:    None.
     Return value:  Returns NULL if graphics input is currently being
                    performed on the physical screen, or the address of the
                    virtual screen upon which input is being performed
                    otherwise.
     Remarks:       None.
     See also:      getGraphicsOutputAddr()

 *** Function:      getGraphicsOutputAddr()
     Syntax:        void far *getGraphicsOutputAddr(void);
     Purpose:       Get the location upon which graphics output is currently
                    being performed.
     Parameters:    None.
     Return value:  Returns NULL if graphics output is currently being
                    performed on the physical screen, or the address of the
                    virtual screen upon which output is being performed
                    otherwise.
     Remarks:       None.
     See also:      getGraphicsInputAddr()



GRAPHICAL OUTPUT MODES


     In early releases of TGE, all graphics output was copied to the
     screen.  Now output can be copied, ANDed, NOTed, ORed, or XORed, even
     to virtual screens.  A description of each of these output modes
     follows:
        - COPY:  This mode is the one which will likely be used most
          frequently.  In this mode, any output is copied directly,
          overwriting anything which was previously there.
        - AND:  In this mode, each pixel output is ANDed with the pixel
          already at the same location.
        - NOT:  In this mode, each pixel output is NOTed before being
          output.
        - OR:  In this mode, each pixel output is ORed with the pixel
          already at the same location.
        - XOR:  In this mode, each pixel output is XORed with the pixel
          already at the same location.


     The following function allows selection of the output mode:

 *** Function:      setGraphicsOutputMode()
     Syntax:        void setGraphicsOutputMode(int mode);
     Purpose:       Select the currently used output mode.
     Parameters:    The output mode will be set to COPY if 'mode' is
                    TGE_COPY_PUT, AND if it is TGE_AND_PUT, NOT if it is
                    TGE_NOT_PUT, OR if it is TGE_OR_PUT, or XOR if it is
                    TGE_XOR_PUT.  These macros are defined in TGE.H.
     Return value:  None.
     Remarks:       These output modes affect output to physical and
                    virtual screens.
     See also:      None.



USING FONTS


     TGE supports two types of loadable fonts:  fixed-size monochrome fonts
     (implemented with the FixedFont class), and variable-size 256-colour
     fonts (implemented with the VariableFont class).  Both high- and
     low-ASCII characters are supported.  As well, multiple fonts may be
     resident in memory simultaneously.

     For variable-size 256-colour fonts:
     
          In order to use a variable-size 256-colour font, an instance of
          the VariableFont class is necessary.  Font initialization will
          look something like this:

               VariableFont systemFont;
               char systemFontName[] = "BIGTEXT";
                    .
                    .
                    .
               if (!systemFont.load(systemFontName))
               {
                 printf("Error loading %s; aborting.\n\n", systemFontName);
                 exit(1);
               }

          Once a font has been loaded, it may be manipulated via its
          VariableFont class instance.  A complete list of the VariableFont
          member functions follows.


      *** Function:      VariableFont::VariableFont()
          Syntax:        VariableFont::VariableFont(void);
          Purpose:       Initialize a VariableFont class for use with a
                         font before loading.
          Parameters:    None.
          Return value:  None.
          Remarks:       None.
          See also:      VariableFont::~VariableFont()

      *** Function:      VariableFont::~VariableFont()
          Syntax:        VariableFont::~VariableFont(void);
          Purpose:       Unload a font from memory.
          Parameters:    None.
          Return value:  None.
          Remarks:       None.
          See also:      VariableFont::VariableFont()

      *** Function:      VariableFont::load()
          Syntax:        int VariableFont::load(char *filename);
          Purpose:       Load a font from disk.
          Parameters:    The font file 'filename' will be loaded.
          Return value:  Returns 0 on error.
          Remarks:       None.
          See also:      None.

      *** Function:      VariableFont::put()
          Syntax:        void VariableFont::put(int x, int y, char
                         ch);
          Purpose:       Write a character on screen.
          Parameters:    The character 'ch' will be displayed with its
                         upper-left corner at ('x','y').
          Return value:  None.
          Remarks:       None.
          See also:      VariableFont::put(int, int, char*)

      *** Function:      VariableFont::put()
          Syntax:        void VariableFont::put(int x, int y, char
                         *string);
          Purpose:       Write a string on screen.
          Parameters:    The string 'string' will be displayed with its
                         upper-left corner at ('x','y').
          Return value:  None.
          Remarks:       None.
          See also:      VariableFont::put(int, int, char)

      *** Function:      VariableFont::width()
          Syntax:        unsigned VariableFont::width(char *string);
          Purpose:       Determine the width of a string.
          Parameters:    The width of the string 'string' will be
                         determined.
          Return value:  The width of the string, in pixels, will be
                         returned.
          Remarks:       None.
          See also:      VariableFont::width(char),
                         VariableFont::height(char*),
                         VariableFont::height(char)

      *** Function:      VariableFont::height()
          Syntax:        unsigned VariableFont::height(char *string);
          Purpose:       Determine the height of a string.
          Parameters:    The height of the string 'string' will be
                         determined.
          Return value:  The height of the string, in pixels, will be
                         returned.
          Remarks:       None.
          See also:      VariableFont::height(char),
                         VariableFont::width(char*),
                         VariableFont::width(char),
                         VariableFont::maxHeight()

      *** Function:      VariableFont::width()
          Syntax:        unsigned short VariableFont::width(char ch);
          Purpose:       Determine the width of a character.
          Parameters:    The width of the character 'ch' will be
                         determined.
          Return value:  The width of the string, in pixels, will be
                         returned.
          Remarks:       None.
          See also:      VariableFont::width(char*),
                         VariableFont::height(char),
                         VariableFont::width(char*)

      *** Function:      VariableFont::height()
          Syntax:        unsigned short VariableFont::height(char ch);
          Purpose:       Determine the height of a character.
          Parameters:    The height of the character 'ch' will be
                         determined.
          Return value:  The height of the string, in pixels, will be
                         returned.
          Remarks:       None.
          See also:      VariableFont::height(char*),
                         VariableFont::width(char),
                         VariableFont::height(char*),
                         VariableFont::maxHeight()

      *** Function:      VariableFont::maxHeight()
          Syntax:        unsigned short VariableFont::maxHeight(void);
          Purpose:       Determine the height of the tallest character.
          Parameters:    None.
          Return value:  The height of the tallest character, in pixels,
                         will be returned.
          Remarks:       None.
          See also:      VariableFont::height(char*),
                         VariableFont::height(char)

      *** Function:      VariableFont::matchColours()
          Syntax:        void VariableFont::matchColours(void);
          Purpose:       Match the font colours as closely as possible to
                         the currently selected font palette.
          Parameters:    None.
          Return value:  None.
          Remarks:       This function is really only useful after the
                         colour palette has been changed.
          See also:      VariableFont::palette(void*)

      *** Function:      VariableFont::palette(void*)
          Syntax:        void VariableFont::palette(void *palette);
          Purpose:       Change the currently active font palette.
          Parameters:    The currently active font palette will be set to
                         the palette at 'palette'.
          Return value:  None.
          Remarks:       VariableFont::matchColours() is autmatically
                         called by this function.
          See also:      VariableFont::palette(void),
                         VariableFont::palette(unsigned char, unsigned
                         char, unsigned char, unsigned char),
                         VariableFont::matchColours()

      *** Function:      VariableFont::palette(void)
          Syntax:        void *VariableFont::palette(void);
          Purpose:       Get the address of the currently active font
                         palette.
          Parameters:    None.
          Return value:  Returns the address of the font palette.
          Remarks:       If a change is made to this data directly, you
                         must call VariableFont::palette(void*) if the
                         changes are to take effect.
          See also:      VariableFont::palette(void),
                         VariableFont::palette(unsigned char, unsigned
                         char*, unsigned char*, unsigned char*)

      *** Function:      VariableFont::palette(unsigned char, unsigned
                         char, unsigned char, unsigned char)
          Syntax:        void *VariableFont::palette(unsigned char palReg,
                         unsigned char red, unsigned char green, unsigned
                         char blue);
          Purpose:       Change one of the colours of the font palette.
          Parameters:    Colour number 'palReg' of the font palette will be
                         set to match the values passed in 'red', 'green',
                         and 'blue'.
          Return value:  None.
          Remarks:       The change will take effect immediately; there is
                         no need to explicitly update the palette.
          See also:      VariableFont::palette(void*)

      *** Function:      VariableFont::palette(unsigned char, unsigned
                         char*, unsigned char*, unsigned char*)
          Syntax:        void *VariableFont::palette(unsigned char palReg,
                         unsigned char *red, unsigned char *green, unsigned
                         char *blue);
          Purpose:       Determine the contents of one of the colours of
                         the font palette.
          Parameters:    Colour number 'palReg' of the font palette will be
                         passed to the caller in 'red', 'green', and
                         'blue'.
          Return value:  None.  On return, however, the colour's components
                         will be present at the 'red', 'green', and 'blue'
                         buffers.
          Remarks:       None.
          See also:      VariableFont::palette(void)

      *** Function:      VariableFont::spacing()
          Syntax:        void VariableFont::spacing(unsigned numPixels);
          Purpose:       Change the spacing between characters.
          Parameters:    After calling this function, the number of pixels
                         left between characters output with
                         VariableFont::put(char*) will be set to
                         'numPixels'.
          Return value:  None.
          Remarks:       The spacing defaults to one pixel between each
                         character.
          See also:      None.



     For fixed-size monochrome fonts:
     
          In order to use a fixed-size monochrome font, an instance of the
          FixedFont class is necessary.  Assuming instantiation of a
          FixedFont pointer, font initialization will look something like
          this:

               FixedFont *fixedFont;
               char fixedFontName[] = "8X16";
                         .
                         .
                         .
               fixedFont = new Font(fixedFontName);      // load font
               if (fixedFont==NULL || !fixedFont->status())
               {
                 printf("Error loading %s; aborting.\n\n", fixedFontName);
                 exit(1);
               }

          Once a font has been loaded, it may be manipulated via its
          FixedFont class instance.  A complete list of the FixedFont
          member functions follows.

      *** Function:      FixedFont::FixedFont()
          Syntax:        FixedFont::FixedFont(char *filename, unsigned char
                         fg=1, unsigned char bg=0);
          Purpose:       Load a font, and initiate a FixedFont class for
                         use with it.
          Parameters:    'filename' is the name of the font data file. 'fg'
                         (which defaults to 1) is the colour to be used as
                         the foreground colour.  'bg' (which defaults to 0)
                         is the colour to be used as the background colour.
          Return value:  None.
          Remarks:       After an instantiation of a FixedFont, ensure that
                         the loading and initialization was successful
                         using the method illustrated above.
          See also:      FixedFont::~FixedFont()

      *** Function:      FixedFont::~FixedFont()
          Syntax:        FixedFont::~FixedFont()
          Purpose:       Free the memory used by a font, and perform any
                         other clean-up actions when a FixedFont is no
                         longer needed.
          Parameters:    None.
          Return value:  None.
          Remarks:       None.
          See also:      FixedFont::FixedFont()

      *** Function:      FixedFont::status()
          Syntax:        inline int FixedFont::status(void);
          Purpose:       Return a flag indicating whether or not the font
                         loading and initialization were successful.
          Parameters:    None.
          Return value:  Returns 1 if the initialization was successful, or
                         0 if it wasn't.
          Remarks:       None.
          See also:      None.

      *** Function:      FixedFont::width(char*)
          Syntax:        unsigned FixedFont::width(char *str);
          Purpose:       Return the width, in pixels, of a string.
          Parameters:    The string 'str' is analyzed.
          Return value:  Returns the width of 'str', in pixels.
          Remarks:       None.
          See also:      FixedFont::width(char), FixedFont::height(char*),
                         FixedFont::height(char), FixedFont::maxWidth(),
                         FixedFont::maxHeight()

      *** Function:      FixedFont::width(char)
          Syntax:        inline unsigned FixedFont::width(char ch);
          Purpose:       Return the width, in pixels, of a single
                         character.
          Parameters:    The character 'ch' is analyzed.
          Return value:  Returns the width of 'ch', in pixels.
          Remarks:       None.
          See also:      FixedFont::width(char*), FixedFont::height(char),
                         FixedFont::height(char*), FixedFont::maxWidth(),
                         FixedFont::maxHeight()

      *** Function:      FixedFont::maxWidth()
          Syntax:        inline unsigned maxWidth(void);
          Purpose:       Return the width of the widest character.
          Parameters:    None.
          Return value:  Returns the width of the widest character.
          Remarks:       None.
          See also:      FixedFont::maxHeight(void),
                         FixedFont::width(char*), FixedFont::width(char),
                         FixedFont::height(char*), FixedFont::height(char)

      *** Function:      FixedFont::height(char*)
          Syntax:        unsigned FixedFont::height(char *str);
          Purpose:       Return the height, in pixels, of a string.
          Parameters:    The string 'str' is analyzed.
          Return value:  Returns the depth of 'str', in pixels.
          Remarks:       None.
          See also:      FixedFont::height(char), FixedFont::width(char*),
                         FixedFont::height(char), FixedFont::maxHeight(),
                         FixedFont::maxWidth()

      *** Function:      FixedFont::height(char)
          Syntax:        unsigned FixedFont::height(char ch);
          Purpose:       Return the height, in pixels, of a single
                         character.
          Parameters:    The character 'ch' is analyzed.
          Return value:  Returns the height of 'ch', in pixels.
          Remarks:       None.
          See also:      FixedFont::height(char*), FixedFont::width(char),
                         FixedFont::width(char*), FixedFont::maxWidth(),
                         FixedFont::maxHeight()

      *** Function:      FixedFont::maxHeight()
          Syntax:        inline unsigned maxHeight(void);
          Purpose:       Return the height of the tallest character.
          Parameters:    None.
          Return value:  Returns the height of the tallest character.
          Remarks:       None.
          See also:      FixedFont::maxWidth(void),
                         FixedFont::height(char*), FixedFont::height(char),
                         FixedFont::width(char*), FixedFont::width(char)

      *** Function:      FixedFont::put(int, int, char*)
          Syntax:        void FixedFont::put(int x, int y, char *str);
          Purpose:       Write a string to the screen.
          Parameters:    The string 'str' will be written starting at
                         ('x','y').
          Return value:  None.
          Remarks:       The coordinate passed to this function specifies
                         the upper-left coordinate of the string.
          See also:      FixedFont::put(char);

      *** Function:      FixedFont::put(int, int, char)
          Syntax:        void FixedFont::put(int x, int y, char ch);
          Purpose:       Write a single character to the screen.
          Parameters:    The character 'ch' will be written at
                         ('x','y').
          Return value:  None.
          Remarks:       The coordinate passed to this function specifies
                         the upper-left coordinate of the character.
          See also:      FixedFont::put(char*);

      *** Function:      FixedFont::foreground(unsigned)
          Syntax:        inline void FixedFont::foreground(unsigned
                         colour);
          Purpose:       Set the current foreground colour.
          Parameters:    The foreground colour will be set to 'colour'.
          Return value:  None.
          Remarks:       None.
          See also:      FixedFont::background(unsigned),
                         FixedFont::foreground(void),
                         FixedFont::background(void)

      *** Function:      FixedFont::foreground(void)
          Syntax:        inline unsigned FixedFont::foreground(void);
          Purpose:       Return the current foreground colour.
          Parameters:    None.
          Return value:  Returns the current foreground colour.
          Remarks:       None.
          See also:      FixedFont::background(void),
                         FixedFont::foreground(unsigned),
                         FixedFont::foreground(unsigned)

      *** Function:      FixedFont::background(unsigned)
          Syntax:        inline void FixedFont::background(unsigned
                         colour);
          Purpose:       Set the current background colour.
          Parameters:    The background colour will be set to 'colour'.
          Return value:  None.
          Remarks:       None.
          See also:      FixedFont::foreground(unsigned),
                         FixedFont::background(void),
                         FixedFont::foreground(void)

      *** Function:      FixedFont::background(void)
          Syntax:        inline unsigned FixedFont::background(void);
          Purpose:       Return the current background colour.
          Parameters:    None.
          Return value:  Returns the current background colour.
          Remarks:       None.
          See also:      FixedFont::foreground(void),
                         FixedFont::background(unsigned),
                         FixedFont::foreground(unsigned)


     Note that, at present, TGE's fonts are designed for use in 256-colour
     modes only.



BITMAP MANIPULATION


     Bitmaps can get boring when all you can do is display them.  TGE can
     scale bitmaps to different sizes, using the following function:

 *** Function:      scaleBitmap()
     Syntax:        void far *scaleBitmap(void *srcImage, unsigned newWide,
                    unsigned newDeep, void *destImage)
     Purpose:       Scale the given bitmap to the specified size
     Parameters:    The image in 'srcImage' will be scaled to 'newWide'
                    pixels wide and 'newDeep' pixels deep.  The resulting
                    scaled image will be placed in 'destImage' if
                    'destImage' is non-NULL, or in a newly allocated block
                    of memory if 'destImage' is NULL.
     Return value:  Returns the address of the scaled image on success, or
                    NULL on error.  Note that NULL will never be returned
                    if 'destImage' is non-NULL.
     Remarks:       Results are undefined if either 'newWide' or 'newDeep'
                    is equal to zero.
     See also:      None.


     TGE also provides routines for determining an image's dimensions given
     its address:

 *** Function:      imageWidth
     Syntax:        unsigned imageWidth(void *image);
     Purpose:       Determine an image's width.
     Parameters:    This routine will determine the width of 'image'.
     Return value:  Returns the width, in pixels, of 'image'.
     Remarks:       This routine is implemented as a macro in TGE.H.
     See also:      imageHeight

 *** Function:      imageHeight
     Syntax:        unsigned imageHeight(void *image);
     Purpose:       Determine an image's height.
     Parameters:    This routine will determine the height of 'image'.
     Return value:  Returns the height, in pixels, of 'image'.
     Remarks:       This routine is implemented as a macro in TGE.H.
     See also:      imageWidth



PALETTE MANIPULATION


     TGE provides some palette manipulation routines, described below:


 *** Function:      fadePalette
     Syntax:        int fadePalette(unsigned step, void *inPal, void
                    *outPal, void *targetPal);
     Purpose:       Fade one palette into another.
     Parameters:    The palette at 'inPal' will be faded closer to the
                    palette at 'targetPal'.  The resulting palette will be
                    stored at 'outPal'.  Each of the colour components
                    which compose a palette colour will be incremented or
                    decremented by no more than the value in 'step'; thus,
                    higher 'step' values produce more rapid fading.
     Return value:  Returns 0 if fading is complete, or 1 if it isn't.
     Remarks:       Note that this function does not always complete the
                    fading with one call.  Code like this could be used:
                         while (fadePalette(1, in, out, target))
                         {
                           delay(10);
                           setBlockPalette(0, 255, out);
                           swap(in, out);
                           doSomeOtherProcessing();
                         }
     See also:      None.

 *** Function:      greyPalette
     Syntax:        void TGE_greyPalette(void *inPal, void *outPal);
     Purpose:       Produce a greyscale version of a palette.
     Parameters:    A greyscale version of the palette at 'inPal' will be
                    calculated, and stored at 'outPal'.
     Return value:  None, but the calculated greyscale palette will be at
                    'outPal' on return.
     Remarks:       Images designed with the input palette in mind will
                    look the same under the output greyscale palette,
                    except that they will be composed entirely of greys,
                    black, and white.
     See also:      None.

 *** Function:      rotatePalette
     Syntax:        void TGE_rotatePalette(int howMuch, void *inPal, void
                    *outPal)
     Purpose:       Rotate a palette.
     Parameters:    The palette at 'inPal' will be rotated by the value
                    'howMuch', and the resulting palette will be placed at
                    'outPal'.  'howMuch' can be negative or positive,
                    depending on which direction rotation will be
                    performed; for instance, a 'howMuch' value of 1 would
                    cause the value of colour 0 to move to colour 1, while
                    a 'howMuch' value of -1 would have the opposite effect.
     Return value:  None, but the rotated palette will be at 'outPal' on
                    return.
     Remarks:       This function will still operate correctly with
                    'howMuch' values which are greater than 255 or less
                    than -255.
     See also:      None.



USING THE MOUSE


     TGE now provides support for interrupt-driven, definable mouse
     pointers.  In order to make use of this feature, some simple steps
     must be taken.

     The new mouse handler is designed to work in tandem with TGE's
     graphical functions.  Programs using the new mouse handler must first
     have successfully initialized graphics mode using TGE.  Both TGE.H and
     TGEMOUSE.H must be #included into a program using the mouse services.

     The mouse handler has to be initialized.  To do so, one function call
     is required:

          initNewMouse();

     For more information on initNewMouse(), refer to the mouse functions
     reference section.

     Next, the mouse driver must be informed of the screen dimensions, like
     this:

          setHorizLimitsMouse(0, OUTMAXX);
          setVertLimitsMouse(0, OUTMAXY);

     If desired, the pointer may then be positioned.  To center it on the
     screen, do this:

          setPosMouse(OUTMAXX/2, OUTMAXY/2);

     A pointer shape must then be selected.  TGE, as shipped, includes two
     arrow pointers and two target pointers; the file MOUSEPTR.C may easily
     be modified to allow more.  To select, for instance, the big arrow
     pointer, do this:

          setupMousePointer(BIG_ARROW_POINTER);

     The macro BIG_ARROW_POINTER is defined in TGEMOUSE.H; it expands to a
     number which is used by MOUSEPTR.C to identify which bitmap to use. 
     Note that if exceptionally large (ie. larger than 512 bytes) pointers
     are used, a change must be made in NEWMOUSE.ASM; see that file for
     details.  If you would like to directly set a bitmap as the mouse
     pointer, you may use the setPointerShapeMouse() routine, described
     in the next section.

     Once things have been initialized, the use of the new mouse handler
     over the standard mouse driver can essentially be ignored; mouse
     driver services are obtained in exactly the same way.  The mouse
     interface functions are prototyped in TGEMOUSE.H, also using the macro
     method which allows function names to be changed simply by editing
     TGEMOUSE.H.

     Before exiting the program, the function deInitNewMouse() _must_ be
     called.  It is usually a very good idea to place deInitNewMouse() in
     the atexit() queue immediately after calling initNewMouse().

     Note that, since the pointer is drawn using TGE's putImageInv()
     function, the pointer will only appear when it is within the current
     viewport.



TGE'S MOUSE FUNCTION SET


 *** Function:      initNewMouse()
     Syntax:        void initNewMouse(void);
     Purpose:       Initializes the new mouse handler.
     Parameters:    The new mouse handler will be configured for use with
                    TGE.
     Return value:  None.
     Remarks:            A graphics driver must have been loaded prior to a
                    call to initNewMouse().
                         The new mouse handler requires that a Microsoft or
                    compatible mouse driver already be resident.  It
                    assumes that a mouse driver's presence will have been
                    tested beforehand.
                         initNewMouse() is really a simple macro; refer to
                    TGEMOUSE.H for the expansion of initNewMouse(void);
     See also:      deInitNewMouse(), enableNewMouse(), disableNewMouse()

 *** Function:      deInitNewMouse()
     Syntax:        void deInitNewMouse(void);
     Purpose:       Deactivate the new mouse handler, and leave all the
                    work up to the old driver.
     Parameters:    None.
     Return value:  None.
     Remarks:       This function must be called prior to program exit if
                    initNewMouse() had previously been called.
     See also:      initNewMouse(), enableNewMouse(), disableNewMouse()

 *** Function:      enableNewMouse()
     Syntax:        void enableNewMouse(void);
     Purpose:       Reactivate the new mouse handler following a call to
                    disableNewMouse().
     Parameters:    None.
     Return value:  None.
     Remarks:       None.
     See also:      disableNewMouse(), initNewMouse(), deInitNewMouse()

 *** Function:      disableNewMouse()
     Syntax:        void disableNewMouse(void);
     Purpose:       Temporarily deactivate the new mouse handler, to be
                    reactivated later by a call to enableNewMouse().
     Parameters:    None.
     Return value:  None.
     Remarks:       Following a call to this function, the new mouse
                    handler will cease trapping mouse driver interrupts and
                    moving the pointer.
     See also:      enableNewMouse(), initNewMouse(), deInitNewMouse()

 *** Function:      resetMouse()
     Syntax:        int resetMouse(void);
     Purpose:       Reset the mouse driver and hardware.
     Parameters:    None.
     Return value:  1 if mouse driver available, 0 otherwise.
     Remarks:       Following a call to this function, the mouse pointer is
                    hidden and positioned at the center of the screen.
     See also:      softResetMouse(), initNewMouse()

 *** Function:      getButtonsMouse()
     Syntax:        int getButtonsMouse(void);
     Purpose:       Return the number of buttons on the mouse.
     Parameters:    None.
     Return value:  Returns the number of buttons on the mouse.
     Remarks:       This function calls resetMouse(), and so the mouse
                    driver and hardware are re-initialized.
     See also:      resetMouse()

 *** Function:      showMouse()
     Syntax:        void showMouse(void);
     Purpose:       Show the mouse pointer.
     Parameters:    None.
     Return value:  None.
     Remarks:       Calls to showMouse() and hideMouse() are cumulative;
                    ie., if showMouse() is called twice, hideMouse() must
                    be called twice to hide the pointer again.
     See also:      hideMouse()

 *** Function:      hideMouse()
     Syntax:        void hideMouse(void);
     Purpose:       Hide the mouse pointer.
     Parameters:    None.
     Return value:  None.
     Remarks:       Calls to showMouse() and hideMouse() are cumulative;
                    ie., if showMouse() is called twice, hideMouse() must
                    be called twice to hide the pointer again.
     See also:      showMouse()

 *** Function:      getPosMouse()
     Syntax:        void getPosMouse(int far *x, int far *y);
     Purpose:       Get the current pointer coordinates.
     Parameters:    The current pointer x- and y-coordinates will be stored
                    in 'x' and 'y', respectively.
     Return value:  None.
     Remarks:       None.
     See also:      setPosMouse()

 *** Function:      setPosMouse()
     Syntax:        void setPosMouse(unsigned x, unsigned y);
     Purpose:       Set the current pointer coordinates.
     Parameters:    The pointer will be positioned at ('x','y').
     Return value:  None.
     Remarks:       None.
     See also:      getPosMouse()

 *** Function:      buttonMouse()
     Syntax:        int buttonMouse(void);
     Purpose:       Return whether or not any of the mouse buttons is down.
     Parameters:    None.
     Return value:  Returns true if at least one button is down, or zero if
                    none of them is down.
     Remarks:       None.
     See also:      leftButtonMouse(), rightButtonMouse(),
                    centerButtonMouse(), waitReleaseMouse()

 *** Function:      leftButtonMouse()
     Syntax:        int leftButtonMouse(void);
     Purpose:       Return the status of the left mouse button.
     Parameters:    None.
     Return value:  Returns true if the button is down, or zero if it is
                    up.
     Remarks:       None.
     See also:      buttonMouse(), rightButtonMouse(), centerButtonMouse(),
                    waitReleaseMouse()

 *** Function:      rightButtonMouse()
     Syntax:        int rightButtonMouse(void);
     Purpose:       Return the status of the right mouse button.
     Parameters:    None.
     Return value:  Returns true if the button is down, or zero if it is
                    up.
     Remarks:       None.
     See also:      buttonMouse(), leftButtonMouse(), centerButtonMouse(),
                    waitReleaseMouse()

 *** Function:      centerButtonMouse()
     Syntax:        int centerButtonMouse(void);
     Purpose:       Return the status of the center mouse button.
     Parameters:    None.
     Return value:  Returns true if the button is down, or zero if it is
                    up.
     Remarks:       None.
     See also:      buttonMouse(), leftButtonMouse(), rightButtonMouse(),
                    waitReleaseMouse()

 *** Function:      buttonPressMouse()
     Syntax:        unsigned buttonPressMouse(unsigned button, int far *x,
                    int far *y);
     Purpose:       Return the number of times the specified button has
                    been pressed since the last call to this function (with
                    the same button parameter), and store the coordinates
                    of the last press.
     Parameters:    The button 'button' is checked, and may be any of
                    LEFTBUTTON, RIGHTBUTTON, and CENTERBUTTON, which are
                    defined in TGEMOUSE.H.  The position of the last press
                    will be stored in ('x','y').
     Return value:  Returns the number of times the specified button has
                    been pressed since the last call to this function (with
                    the same button parameter).
     Remarks:       None.
     See also:      buttonReleaseMouse()

 *** Function:      buttonReleaseMouse()
     Syntax:        unsigned buttonReleaseMouse(unsigned button, int far
                    *x, int far *y);
     Purpose:       Return the number of times the specified button has
                    been released since the last call to this function
                    (with the same button parameter), and store the
                    coordinates of the last press.
     Parameters:    The button 'button' is checked, and may be any of
                    LEFTBUTTON, RIGHTBUTTON, and CENTERBUTTON, which are
                    defined in TGEMOUSE.H.  The position of the last
                    release will be stored in ('x','y').
     Return value:  Returns the number of times the specified button has
                    been released since the last call to this function
                    (with the same button parameter).
     Remarks:       None.
     See also:      buttonPressMouse()

 *** Function:      setHorizLimitsMouse()
     Syntax:        void setHorizLimitsMouse(unsigned min, unsigned max);
     Purpose:       Set the minimum and maximum horizontal coordinates for
                    the pointer.
     Parameters:    The minimum horizontal coordinate will be set to 'min',
                    and the maximum to 'max'.
     Return value:  None.
     Remarks:       None.
     See also:      setVertLimitsMouse()

 *** Function:      setVertLimitsMouse()
     Syntax:        void setVertLimitsMouse(unsigned min, unsigned max);
     Purpose:       Set the minimum and maximum vertical coordinates for
                    the pointer.
     Parameters:    The minimum vertical coordinate will be set to 'min',
                    and the maximum to 'max'.
     Return value:  None.
     Remarks:       None.
     See also:      setHorizLimitsMouse()

 *** Function:      setPointerMouse()
     Syntax:        void setPointerMouse(int xOff, int yOff, void far *p);
     Purpose:       Set the shape of the pointer.
     Parameters:    The image pointed to by 'p' will be the pointer bitmap. 
                    ('xOff','yOff') is the offset, relative to the upper-
                    left corner of the bitmap, of the "hot spot" -- the
                    pixel where the pointer is actually registered as
                    being.  (For instance, the standard arrow pointer has
                    its hot spot in the upper-left, while a crosshairs
                    pointer would have it towards the middle.)
     Return value:  None.
     Remarks:       The mouse pointer should be hidden when a call to this
                    function is made.
     See also:      None.

 *** Function:      getSaveSizeMouse()
     Syntax:        unsigned getSaveSizeMouse(void);
     Purpose:       Return the size of the buffer necessary to store the
                    state of the mouse driver.
     Parameters:    None.
     Return value:  Returns the size of the buffer.
     Remarks:       If a program using TGE and the new mouse handling
                    routines is to run another program, for instance
                    shelling to DOS, the ensuing procedure should be
                    followed:  call disableNewMouse(), call
                    getSaveSizeMouse(), allocate a block of memory with the
                    size returned by getSaveSizeMouse(), call
                    saveStateMouse(), run the program, call
                    restoreStateMouse(), free the block of memory, then
                    call enableNewMouse().
     See also:      saveStateMouse(), restoreStateMouse()

 *** Function:      saveStateMouse()
     Syntax:        void saveStateMouse(void far *buf);
     Purpose:       Save the current state of the mouse driver.
     Parameters:    The block of memory pointed to by 'buf' will be used to
                    store the state data.  Its length should be obtained by
                    calling getSaveSizeMouse().
     Return value:  None.
     Remarks:       If a program using TGE and the new mouse handling
                    routines is to run another program, for instance
                    shelling to DOS, the ensuing procedure should be
                    followed:  call disableNewMouse(), call
                    getSaveSizeMouse(), allocate a block of memory with the
                    size returned by getSaveSizeMouse(), call
                    saveStateMouse(), run the program, call
                    restoreStateMouse(), free the block of memory, then
                    call enableNewMouse().
     See also:      getSaveSizeMouse(), restoreStateMouse()

 *** Function:      restoreStateMouse()
     Syntax:        void restoreStateMouse(void far *buf);
     Purpose:       Restore the state of the mouse driver from a buffer
                    previously filled by saveStateMouse().
     Parameters:    The block of memory pointed to by 'buf' stores the
                    state data.
     Return value:  None.
     Remarks:       If a program using TGE and the new mouse handling
                    routines is to run another program, for instance
                    shelling to DOS, the ensuing procedure should be
                    followed:  call disableNewMouse(), call
                    getSaveSizeMouse(), allocate a block of memory with the
                    size returned by getSaveSizeMouse(), call
                    saveStateMouse(), run the program, call
                    restoreStateMouse(), free the block of memory, then
                    call enableNewMouse().
     See also:      getSaveSizeMouse, saveStateMouse

 *** Function:      setRatioMouse()
     Syntax:        void setRatioMouse(unsigned horiz, unsigned vert);
     Purpose:       Set the mouse sensitivity, in units of mickeys per 8
                    pixels of pointer movement.  (A mickey is the unit used
                    to measure mouse movement.)
     Parameters:    The horizontal mickeys to pixels ratio will be set to
                    'horiz', and the vertical to 'vert'.
     Return value:  None.
     Remarks:       None.
     See also:      getSensitivityMouse()

 *** Function:      getSensitivityMouse()
     Syntax:        void getSensitivityMouse(unsigned *horiz, unsigned
                    *vert, unsigned *doubleSpeed);
     Purpose:       Get the mouse sensitivity, in units of mickeys per 8
                    pixels of pointer movement.  (A mickey is the unit used
                    to measure mouse movement.)  The mouse double speed
                    threshold (the minimum number of mickeys per second of
                    motion before pointer movement is doubled) is retrieved
                    as well.
     Parameters:    The horizontal mickeys to pixels ratio will be stored
                    in 'horiz', the vertical in 'vert', and the double
                    speed threshold in 'doubleSpeed'.
     Return value:  None.
     Remarks:       None.
     See also:      setRatioMouse()

 *** Function:      softResetMouse()
     Syntax:        void softResetMouse(void);
     Purpose:       Reset the mouse driver, but not the hardware.
     Parameters:    None.
     Return value:  None.
     Remarks:       This function is equivalent to resetMouse(), except in
                    that it performs no initialization of the mouse
                    hardware.
     See also:      resetMouse()

 *** Function:      waitReleaseMouse()
     Syntax:        void waitReleaseMouse(int button);
     Purpose:       If the specified button is not already up, wait until
                    it is released, then return.
     Parameters:    The button 'button' is checked, and may be any of
                    LEFTBUTTON, RIGHTBUTTON, and CENTERBUTTON, which are
                    defined in TGEMOUSE.H.
     Return value:  None.
     Remarks:       None.
     See also:      buttonMouse(), leftButtonMouse(), rightButtonMouse(),
                    centerButtonMouse()


     Note that since these function names are actually macros, they may
     easily be changed to suit individual preferences by editing
     TGEMOUSE.H.



CREATING FONTS


     Creating fonts is by no means easy, but the necessary information is
     outlined below.

     For variable-size 256-colour fonts:
     
          First, you should make a working directory for your font's data
          files.  For the sake of example, I will assume that you are
          trying to create MYFONT.FNT.

          Second, draw a bitmap for each of the 256 ASCII characters which
          you would like to exist in the font; if you won't be using a
          character, feel free to not bother drawing a bitmap for it.  Each
          bitmap should be as small as possible, so be sure not to leave
          any extra space around the character.  Use colour zero as the
          background colour, or some other colour if you would like the
          font to have a coloured background.  Save each of these bitmaps
          as a PCX file in the working directory.  Note that all character
          bitmaps must use the same colour palette.

          Third, convert the PCX files to RAW files by using PCX2RAW; to do
          so, type 'PCX2RAW *'.

          Fourth, you must rename one of the PAL files produced by PCX2RAW
          to MYFONT.PAL (remember MYFONT.FNT is the font you're creating).
          If you wish, you may delete all the other PAL files, so long as
          you leave MYFONT.PAL intact.

          Fifth, you must create MYFONT.OFF, the character offset
          description file.  This text file consists of 256 lines, each
          containing a single integer (either positive or zero), followed
          by a newline.  Each line contains its corresponding character's
          "offset from top" value; the first line is for character 0, the
          second is for character 1, and so on.  Given the (x,y)
          coordinates at which to put a character from the font, the
          "offset from top" is the value to add to the y coordinate before
          putImageInv() is called to display the character's bitmap.  The
          "offset from top" is used to make character bitmaps be written
          lower down on the screen than other bitmaps; for instance, the
          period character's offset would be greater than an asterisk's
          offset, because a period is lower down than an asterisk.

          Finally, you must create the font file MYFONT.FNT; to do so, type
          'MAKEFONT myfont'.


     For fixed-size monochrome fonts:
     
          TGE's font definition files must have a certain format which will
          be outlined below.  (Note that a fixed font consists of 256
          monochrome characters, each with the same dimensions.)

          The font file header consists of three fields of defined length.
          The first of these fields is the eight-byte font definition file
          signature string, which must be "TGEFONT1", without quotes or
          terminating null character.  The next field is a two-byte
          unsigned integer which holds the width of a character in pixels.
          The last field is also a two-byte integer, holding the height of
          a character in pixels.

          The remainder of the file consists of font data.  (If you have
          done advanced text programming before, you may recognize this
          data organization as the format used by the video BIOS.)  The
          characters are stored starting at character 0, all the way up to
          255.  Each of the characters is stored starting with the
          uppermost row, all the way down to the bottom row.  Each row is
          stored left to right, with the leftmost pixel in the most
          significant bit of the first byte in the row, and the rightmost
          pixel in the least significant bit of the last byte in the row.
          A 1 bit represents a foreground pixel, while a 0 bit represents a
          background pixel.  Note that, at present, font row widths must be
          evenly divisible by 8; pad with 0 bits if necessary.

          Image data for all 256 of the ASCII characters must be present in
          the file; if you won't be needing some of them, feel free to
          store zero bytes (or random bytes, if you're imaginative) as
          their image data.



USING PCX2RAW AND GRAPHICS FILES


     The PCX2RAW utility provides a simple way to convert 256-colour images
     in PCX format into a format usable by TGE.  It is used like this:

          pcx2raw filename[.pcx]

     Given the PCX file FILENAME.PCX, PCX2RAW will create two new files in
     the same directory as FILENAME.PCX:  FILENAME.PAL which contains the
     colour palette from FILENAME.PCX, and FILENAME.RAW which is a TGE
     format bitmap of the image in FILENAME.PCX.  Following is a discussion
     of the PAL and RAW file formats, and how to use TGE's functions to
     access them.


     The PAL file is organized like this:

         Element size    Element description
         ------------    -------------------
           3 bytes           colour 0
           3 bytes           colour 1
                        .
                        .
                        .
           3 bytes           colour 254
           3 bytes           colour 255

     Each 3-byte element consists of the red, green, and blue colour
     components, in that order.  Each of these components is an unsigned
     char.  Code to load a PAL file is included in RAWFILE.C; the function
     description follows:

 *** Function:      loadPalFile()
     Syntax:        void far *loadPalFile(char *filename, void far *addr);
     Purpose:       Load a 768-byte palette file into memory.
     Parameters:    The palette data file 'filename' will be loaded into
                    the memory block at 'addr' (if 'addr' != NULL), or into
                    a newly allocated memory block (if 'addr' == NULL).
     Return value:  Returns the address of the loaded palette on success,
                    or NULL on error.
     Remarks:       If 'addr' is NULL, be sure to free() the allocated
                    memory block when the palette information is no longer
                    needed.
     See also:      loadPcxFilePal(), loadRawFile(), displayRawFile(),
                    loadPcxFile(), displayPcxFile()


     The RAW file is organized in exactly the same way as the bitmaps used
     by putImage() and its associated functions:

         Element size    Element description
         ------------    -------------------
           2 bytes           image width
           2 bytes           image depth
           variable     raw pixel information

     The image dimension fields are both unsigned ints, and are measured in
     pixels.  Code to load a RAW file is included in RAWFILE.C; the
     function descriptions follow:

 *** Function:      loadRawFile()
     Syntax:        void far *loadRawFile(char *filename);
     Purpose:       Load a RAW image file into memory.
     Parameters:    The RAW image file 'filename' will be loaded into a
                    newly allocated memory block.
     Return value:  Returns the address of the loaded image on success, or
                    NULL on error.
     Remarks:       Be sure to free() the allocated memory block when the
                    image information is no longer needed.
     See also:      displayRawFile(), loadPcxFile(), displayPcxFile(),
                    loadPalFile(), loadPcxFilePal()

 *** Function:      displayRawFile()
     Syntax:        int displayRawFile(int x, int y, char *filename);
     Purpose:       Display a RAW image file.
     Parameters:    The RAW image file 'filename' will be displayed with
                    its upper-left corner at ('x','y').  Clipping is
                    performed.
     Return value:  Returns the 1 on success, or 0 on error.
     Remarks:       Since this function uses standard TGE output routines,
                    it can display to virtual screens as well as the real
                    screen.
     See also:      loadRawFile(), displayPcxFile(), loadPcxFile(),
                    loadPalFile(), loadPcxFilePal()


     TGE also includes routines to deal directly with PCX files:

 *** Function:      loadPcxFilePal()
     Syntax:        void far *loadPcxFilePal(char *filename, void far *addr);
     Purpose:       Load a 768-byte palette from a PCX file into memory.
     Parameters:    The palette data 'filename' will be loaded into the
                    memory block at 'addr' (if 'addr' != NULL), or into a
                    newly allocated memory block (if 'addr' == NULL).
     Return value:  Returns the address of the loaded palette on success,
                    or NULL on error.
     Remarks:       If 'addr' is NULL, be sure to free() the allocated
                    memory block when the palette information is no longer
                    needed.
     See also:      loadPalFile(), loadPcxFile(), displayPcxFile(),
                    loadRawFile(), displayRawFile()

 *** Function:      loadPcxFile()
     Syntax:        void far *loadPalFile(char *filename, void *palette);
     Purpose:       Load a PCX image file, and its palette if requested,
                    into memory.
     Parameters:    The PCX image file 'filename' will be loaded into a
                    newly allocated memory block.  If 'palette' is
                    non-NULL, the 768 bytes of palette data from the PCX
                    file will be loaded into the memory area at 'palette'.
     Return value:  Returns the address of the loaded image on success, or
                    NULL on error.  If 'palette' was non-NULL, a copy of
                    the palette will be at the memory area pointed to by
                    'palette' on return.
     Remarks:       Be sure to free() the allocated memory block when the
                    image information is no longer needed.
     See also:      displayPcxFile(), loadPcxFilePal(), loadRawFile(),
                    displayRawFile(), loadPalFile()

 *** Function:      displayPcxFile()
     Syntax:        int displayPcxFile(int x, int y, char *filename);
     Purpose:       Display a PCX image file.
     Parameters:    The PCX image file 'filename' will be displayed with
                    its upper-left corner at ('x','y').  Clipping is
                    performed.
     Return value:  Returns the 1 on success, or 0 on error.
     Remarks:       Since this function uses standard TGE output routines,
                    it can display to virtual screens as well as the real
                    screen.
     See also:      loadPcxFile(), displayRawFile(), loadRawFile()



CONTACTING THE AUTHOR


     I would appreciate hearing any questions, comments, bug reports, or
     suggestions for improvement.  If you have any, feel free to contact
     me; I can be reached at any of the addresses below.  When reporting
     bugs, please be sure to mention the version of TGE to which you are
     referring; also, if possible, please include detailed descriptions of
     the problem and of your video hardware configuration.  If you have a
     video card which is not directly supported by TGE, I would appreciate
     it if you would send me programming information about your card and/or
     code to deal with it.

          Snail mail:      Matthew Hildebrand
                           4 College St.
                           St. Catharines, ON
                           Canada
                           L2R 2W7

          Fidonet mail:    1:247/128.2
               Please do not post personal messages to me in any of the
               Fidonet echos, such as C_ECHO or C_PLUSPLUS; such messages
               are off-topic and liable to annoy the moderator and other
               echo participants.  Use netmail instead.  If I find any such
               personal messages in Fidonet programming echos, I reply by
               netmail only.  If the matter being discussed is of interest
               to other echo participants, I will reply in that echo.

          Internet mail:   Matthew.Hildebrand@p2.f128.n247.z1.fidonet.org
               Internet-Fidonet mail routing sometimes goes awry; if you
               don't get a reply from me after a reasonable amount of time,
               send the message again.  If you still don't receive a reply,
               either persist until you do or contact me via snail mail or
               Fidonet mail.



OBTAINING THE NEWEST VERSION OF TGE


     The most recent distributed copy of TGE is available via first-call
     download from (905)-935-6628 (14400 bps V.32bis), or via file request
     from Fidonet node 1:247/128 (14400 bps V.32bis) using the magic file
     name "TGE"; unlisted nodes and points are welcome.  TGE is also
     distributed through the Fidonet file echo PDNCEE.

     If, after you have registered, you are interested in receiving new
     versions of TGE as they are released, an easy method is now available.
     For $3 per mailing (to cover the disk, envelope, and postage), I will
     mail copies of new versions as they are released, on either a 3.5" or
     a 5.25" disk.  The $3 per mailing may be included with the initial
     registration fee, with instructions to mail newer versions as they are
     released, or mailed later with a request for a copy of the newest
     version.  Please ensure that the $3 is paid in either US or Canadian
     funds; payment by check, cash, or money order is acceptable.



KNOWN PROBLEMS USING TGE


     At present, the following problems may be experienced when using TGE:

          1.   (Registered users only.)  When TGE.C is compiled by Turbo
               C++ 3.0, putImage() and putImageInv() do not work correctly.
               When informed of this bug, I stepped through the offending
               code at the assembly level, and discovered that this problem
               is caused by a bug in TC++, not TGE.  The miscompiled lines
               of TGE.C are perfectly legal C statements; when TGE.C is
               compiled by my compiler (Borland C++ 2.0), TGE works
               beautifully.  Using one of the TGE library files included in
               the TGE package, rather than OBJ files compiled by Turbo C++
               3.0, should solve the problem.
          2.   A very small number of users may experience an odd pattern
               of blue lines when TGE is run in an SVGA mode on some older
               ATI cards.  I have been informed that this problem is caused
               by a bug in the video card itself.  ATI has confirmed the
               presence of this bug, and has implemented a software patch
               in its Windows 3.1 SVGA driver, but ATI has not released
               information on how this bug was squashed.



ACKNOWLEDGEMENT


     There are many people whom I would like to thank for their
     suggestions, beta-testing, patience, registrations, and help with
     distribution.  You know who you are.



LEGAL MUMBO JUMBO


     The Graphics Engine and its documentation are Copyright (c) 1993-1994
     by Matthew Hildebrand.

     All software and documentation associated with The Graphics Engine is
     provided "as is":  ie., it is provided without warranty of any kind,
     not even an implied warranty of merchantability or fitness for any
     purpose.  The Author (Matthew Hildebrand) disclaims all warranties,
     both express and implied, including but not limited to warranties
     regarding The Graphics Engine's merchantability or fitness for any
     particular purpose.

     The author may not be held liable for any damage or misfortune related
     to the use of this software.  The usage of any or all of The Graphics
     Engine is done entirely at the user's risk.

     All registered trademarks in this document belong to whomever it is
     that owns them.



End of document.
