home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 099 / TGE101.ZIP / TGE.DOC < prev    next >
Text File  |  1993-02-04  |  28KB  |  640 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.              The Graphics Engine v1.01 Documentation
  7.                         February 4, 1993
  8.  
  9.  The Graphics Engine software and manual are copyright (c) 1993
  10.           by Matthew Hildebrand.  All rights reserved.
  11.  
  12.  
  13.  
  14.  
  15. Topics covered in this document:
  16. -------------------------------
  17.  
  18.      INTRODUCTION
  19.      MAJOR FEATURES OF THE GRAPHICS ENGINE
  20.      SYSTEM REQUIREMENTS
  21.      PACKING LIST
  22.      RELEASE NOTES FOR v1.01
  23.      INCORPORATING THE GRAPHICS ENGINE
  24.      THE GRAPHICS ENGINE'S FUNCTION SET
  25.           initGraphics()
  26.           deInitGraphics()
  27.           putImage()
  28.           getImage()
  29.           putLine()
  30.           getLine()
  31.           imageSize()
  32.           putPixel()
  33.           getPixel()
  34.           line()
  35.           horizLine()
  36.           drawRect()
  37.           filledRect()
  38.           setPaletteReg()
  39.           getPaletteReg()
  40.           setBlockPalette()
  41.           getBlockPalette()
  42.           clearGraphics()
  43.      WRITING GRAPHICS DRIVERS
  44.      TERMS OF USAGE AND DISTRIBUTION
  45.      CONTACTING THE AUTHOR
  46.      OBTAINING THE GRAPHICS ENGINE
  47.      REVISION HISTORY
  48.      ACKNOWLEDGEMENT
  49.      LEGAL MUMBO JUMBO
  50.  
  51.  
  52.  
  53. INTRODUCTION
  54.  
  55.      The Graphics Engine is the result of my efforts to construct
  56.      a library of C/C++ routines designed to make writing
  57.      graphics applications easier.  I have used it in my own
  58.      programs with excellent results.
  59.  
  60.      The Graphics Engine allows the DOS programmer to easily
  61.      access any graphics mode, without having to do special
  62.      coding for each.  The complications involved with supporting
  63.      more than one graphics mode are essentially removed!  The
  64.      Graphics Engine also provides remarkable flexibility and
  65.      expandability through its modular design.
  66.  
  67.  
  68. MAJOR FEATURES OF THE GRAPHICS ENGINE
  69.  
  70.      The Graphics Engine provides a simple, standard interface
  71.      with which programs may access a powerful library of
  72.      graphical functions.  As an added bonus, this library
  73.      occupies much less memory than other popular commercial
  74.      packages do, such as Borland's BGI.
  75.  
  76.      The Graphics Engine uses loadable graphics drivers.  This
  77.      design means that all code and data necessary to handle a
  78.      certain graphics mode is stored in a disk file.  When a
  79.      program runs, this file will be loaded into memory and the
  80.      code it contains will be made available.  Consequently:
  81.         - Support for more graphics modes may be added simply by
  82.           creating more drivers; programs need not be recompiled.
  83.         - Since the code to manage the specifics of each mode is
  84.           contained in the drivers, the main program needs not
  85.           concern itself with what mode it is operating in.  The
  86.           same code can work in any graphics mode.
  87.         - Memory is saved for programs which support many
  88.           graphics modes.  Instead of keeping the code and data
  89.           necessary for each in memory at all times, only the
  90.           memory required for one driver is used.
  91.  
  92.      When writing drivers, it is not necessary to write assembly
  93.      code for every graphical function that The Graphics Engine
  94.      supports.  For instance, if a certain driver does not
  95.      contain a line-drawing routine, The Graphics Engine will use
  96.      its own.  Therefore, the programmer needs not waste time
  97.      writing assembly code which will seldom or never be used,
  98.      thus slashing development time.  Essentially, no matter what
  99.      a particular driver contains, the entire set of The Graphics
  100.      Engine's graphical functions will be available.
  101.  
  102.  
  103. SYSTEM REQUIREMENTS
  104.  
  105.      The Graphics Engine is a C/C++ programmer's library.  As
  106.      such, it requires a C or C++ compiler of some sort to work
  107.      with it.  The Graphics Engine was written and tested with
  108.      Borland C++ 2.0 and Turbo C 2.0, and also tested with Mix
  109.      Power C 2.1.2.  It should work with other C/C++ compilers as
  110.      well.
  111.  
  112.      The loadable drivers are written in assembly language.  In
  113.      order to write drivers, an assembler will be required.
  114.  
  115.      The drivers that come with The Graphics Engine are written
  116.      using 80286 instructions.  They therefore cannot be used on
  117.      a processor older than the 286.  Naturally, this restriction
  118.      does not apply to all drivers; drivers created using only
  119.      8088 instructions, for instance, would run on an 8088.
  120.  
  121.  
  122. PACKING LIST
  123.  
  124.      The current version of The Graphics Engine consists of the
  125.      following files:
  126.  
  127.           TGE.DOC        The Graphics Engine documentation
  128.           TGE.H          Header file
  129.           TGE.C          Main program module
  130.           TGE.OBJ        TGE.C compiled by Borland C++ 2.0.
  131.           TGEDEMO.C      Source code of The Graphics Engine
  132.                          demonstration program
  133.           TGEDEMO.EXE    The executable version of The Graphics
  134.                          Engine demonstration program
  135.           320x200.ASM    320x200x256 source code
  136.           320X200.DRV    Driver for VGA 320x200x256
  137.           320X240.ASM    320x240x256 source code
  138.           320X240.DRV    Driver for VGA 320x240x256
  139.           320X400.ASM    320x400x256 source code
  140.           320X400.DRV    Driver for VGA 320x400x256
  141.           640X480.ASM    640x480x256 source code
  142.           640X480.DRV    Driver for SuperVGA/VESA 640x480x256
  143.                          (autodetect)
  144.           800X600.ASM    800x600x256 source code
  145.           800X600.DRV    Driver for SuperVGA/VESA 800x600x256
  146.                          (autodetect)
  147.           SHELL.ASM      The source code of the skeleton graphics
  148.                          driver, which is designed as a basis for
  149.                          other graphics drivers
  150.           SHELL.DRV      Skeleton graphics driver
  151.           CDRV.BAT       Batch file to create a .DRV from .ASM
  152.  
  153.      If you did not receive all of these files, you have an
  154.      illegal copy of The Graphics Engine.
  155.  
  156.  
  157. RELEASE NOTES FOR v1.01
  158.  
  159.      The Graphics Engine has not been tested with any compilers
  160.      other than Borland C++ 2.0, Turbo C 2.0, and Mix Power C
  161.      2.1.2.  Although provisions have been made in the code which
  162.      aid portability, it may not work with other compilers in
  163.      spite of these efforts.
  164.  
  165.  
  166. INCORPORATING THE GRAPHICS ENGINE
  167.  
  168.      Incorporating The Graphics Engine into a program is a simple
  169.      process involving four simple steps.
  170.  
  171.      First, the header file TGE.H must be #included into any
  172.      source file which accesses any of The Graphics Engine's
  173.      routines.  TGE.C must be compiled and linked into the .EXE
  174.      file.
  175.  
  176.      Second, a graphics driver MUST be loaded before any
  177.      graphical functions are accessed; results are undefined if
  178.      this step is not followed.  Code to load a driver might look
  179.      like this:
  180.           if (!loadGraphDriver(drvFileName))
  181.           {
  182.             printf("Error loading \"%s\".\n\n", drvFileName);
  183.             exit(1);
  184.           }
  185.           else
  186.             atexit(unloadGraphDriver);
  187.      Obviously, the function loadGraphDriver() MUST be called. 
  188.      As its only parameter, it takes a string consisting of the
  189.      file name (which may include any valid DOS path) of the
  190.      driver to be loaded.  As its return value, it returns a
  191.      success code.  If loadGraphDriver() returns 1, the loading
  192.      was successful; if it returns 0, an error occurred.
  193.  
  194.      Third, information about the graphics mode should be
  195.      obtained from the graphics driver.  The following code will
  196.      store the maximum X-coordinate, Y-coordinate, and colour
  197.      number in the variables maxx, maxy, and colours
  198.      respectively:
  199.           maxx = _grSystemDrv->maxx;         // set up variables
  200.           maxy = _grSystemDrv->maxy;
  201.           colours = _grSystemDrv->colours;
  202.  
  203.      Fourth, after The Graphics Engine's graphical functions are
  204.      no longer needed (usually just before a program exit), the
  205.      function unloadGraphDriver() must be called.  It takes no
  206.      parameters, and returns nothing.  It simply frees the memory
  207.      taken up by a driver after it has been loaded.
  208.  
  209.      Note that the initGraphics() function must be called to
  210.      enter graphics mode; for more information, see the next
  211.      section.
  212.  
  213.  
  214. THE GRAPHICS ENGINE'S FUNCTION SET
  215.  
  216.      After a driver has been loaded, all of The Graphics Engine's
  217.      graphical functions can be accessed.  To call a function,
  218.      simply execute
  219.           functionName(parameter list);
  220.      where functionName is the name of the desired function (eg.
  221.      line, filledRect) and parameter list is all parameters to
  222.      that function, if any.
  223.  
  224.      A complete list of The Graphics Engine's functions follows.
  225.  
  226.  *** Function:      initGraphics
  227.      Syntax:        void far initGraphics(void);
  228.      Purpose:       Initialize graphics mode.
  229.      Parameters:    None.
  230.      Return value:  1 on success, or 0 on error.
  231.      Remarks:       On any call other than its first,
  232.                     initGraphics will also restore the colour
  233.                     palette which was active at the time
  234.                     deInitGraphics was last called.
  235.      See also:      deInitGraphics
  236.  
  237.  *** Function:      deInitGraphics
  238.      Syntax:        void far deInitGraphics(void);
  239.      Purpose:       Revert to 80x25 colour text mode.
  240.      Parameters:    None.
  241.      Return value:  None.
  242.      Remarks:       deInitGraphics will keep a copy of the active
  243.                     colour palette before shutting off graphics. 
  244.                     This palette will be restored by any future
  245.                     call to initGraphics.
  246.      See also:      initGraphics
  247.  
  248.  *** Function:      putImage
  249.      Syntax:        void far putImage(int x, int y, void far
  250.                     *image);
  251.      Purpose:       Place a bitmap, or image, onto the screen.
  252.      Parameters:    The bitmap starting at image will be placed
  253.                     onto the screen with its upper-left
  254.                     coordinate at (x,y).
  255.      Return value:  None.
  256.      Remarks:       Clipping is performed; the image may be
  257.                     placed entirely on-screen, partially on-
  258.                     screen, or entirely off-screen.
  259.      See also:      getImage, imageSize, putLine, getLine
  260.  
  261.  *** Function:      putImageInv
  262.      Syntax:        void far putImageInv(int x, int y, void far
  263.                     *image);
  264.      Purpose:       Place a bitmap, or image, on the screen.
  265.      Parameters:    The bitmap starting at image will be placed
  266.                     onto the screen with its upper-left
  267.                     coordinate at (x,y).
  268.      Return value:  None.
  269.      Remarks:       putImageInv() differs from putImage() only in
  270.                     that it allows for transparent, or invisible,
  271.                     colours.  If any pixel in the image buffer
  272.                     has a value of zero, the corresponding pixel
  273.                     on-screen will not be modified.  Using
  274.                     putImageInv() can avoid having black borders
  275.                     around non-rectangular shapes.
  276.  
  277.  *** Function:      getImage
  278.      Syntax:        void far getImage(int ulx, int uly, int lrx,
  279.                     int lry, void far *image);
  280.      Purpose:       Copy the specified rectangular portion of the
  281.                     screen to memory.
  282.      Parameters:    The portion of the screen with its upper-left
  283.                     coordinate at (ulx,uly) and its lower-left
  284.                     coordinate at (lrx,lry) will be copied into
  285.                     the previously allocated memory region at
  286.                     image (see imageSize).
  287.      Return value:  None.
  288.      Remarks:       Coordinates may be off-screen; getImage will
  289.                     still function reliably.
  290.      See also:      putImage, imageSize, putLine, getLine
  291.  
  292.  *** Function:      putLine
  293.      Syntax:        void far putLine(int lineNum, int xOff, int
  294.                     lineLen, void far *buf);
  295.      Purpose:       Place one horizontal line of image data on
  296.                     the screen.
  297.      Parameters:    The one-line bitmap contained at buf, of
  298.                     lineLen pixels, will be placed on-screen
  299.                     starting at (lineNum,xOff).
  300.      Return value:  None.
  301.      Remarks:       No clipping is performed.  Results are
  302.                     undefined if any coordinate on the line is
  303.                     off-screen.
  304.      See also:      getLine, putImage, getImage
  305.  
  306.  *** Function:      getLine
  307.      Syntax:        void far getLine(int lineNum, int xOff, int
  308.                     lineLen, void far *buf);
  309.      Purpose:       Copy one horizontal line from the screen to
  310.                     memory.
  311.      Parameters:    The horizontal line whose left coordinate is
  312.                     (xOff,lineNum) and whose length is lineLen
  313.                     pixels will be copied into the previously
  314.                     allocated memory region at buf.
  315.      Return value:  None.
  316.      Remarks:       No clipping is performed.  Results are
  317.                     undefined if any coordinate on the line is
  318.                     off-screen.
  319.      See also:      putLine, putImage, getImage
  320.  
  321.  *** Function:      imageSize
  322.      Syntax:        unsigned long far imageSize(int ulx, int uly,
  323.                     int lrx, int lry);
  324.      Purpose:       Determine the amount of memory required to
  325.                     hold a rectangular portion of the screen.
  326.      Parameters:    imageSize will calculate the amount of memory
  327.                     required to hold the porion of the screen
  328.                     whose upper-left coordinate is (ulx,uly) and
  329.                     whose lower-left coordinate is (lrx,lry).
  330.      Return value:  imageSize returns an unsigned long containing
  331.                     the size of the area in bytes.
  332.      Remarks:       Clipping is performed.  imageSize is designed
  333.                     for use with putImage and getImage.  To use
  334.                     it with putLine and getLine, subtract 4 from
  335.                     the value it returns.  (Image buffers have
  336.                     four bytes of dimension information in them;
  337.                     line buffers do not.)
  338.      See also:      putImage, getImage, putLine, getLine
  339.  
  340.  *** Function:      putPixel
  341.      Syntax:        void far putPixel(int x, int y, unsigned
  342.                     colour);
  343.      Purpose:       Place a single pixel on-screen.
  344.      Parameters:    The pixel located at (x,y) will be set to the
  345.                     colour contained in colour.
  346.      Return value:  None.
  347.      Remarks:       Clipping is not performed.
  348.      See also:      getPixel
  349.  
  350.  *** Function:      getPixel
  351.      Syntax:        unsigned far getPixel(int x, int y);
  352.      Purpose:       Return the value of a pixel.
  353.      Parameters:    getPixel will return the value of the pixel
  354.                     at (x,y).
  355.      Return value:  The value of the pixel at (x,y) is returned.
  356.      Remarks:       Clipping is not performed.
  357.      See also:      putPixel
  358.  
  359.  *** Function:      line
  360.      Syntax:        void far line(int x1, int y1, int x2, int y2,
  361.                     unsigned colour);
  362.      Purpose:       Draw a line between two points.
  363.      Parameters:    The line will be drawn joining (x1,y1) and
  364.                     (x2,y2) in the colour contained in colour.
  365.      Return value:  None.
  366.      Remarks:       Clipping is not performed.
  367.      See also:      horizLine
  368.  
  369.  *** Function:      horizLine
  370.      Syntax:        void far horizLine(int y, int x1, int x2,
  371.                     unsigned colour);
  372.      Purpose:       Draw a horizontal line between two points.
  373.      Parameters:    The line will be drawn between (x1,y) and
  374.                     (x2,y) in the colour contained in colour.
  375.      Return value:  None.
  376.      Remarks:       Clipping is not performed.
  377.      See also:      line
  378.  
  379.  *** Function:      drawRect
  380.      Syntax:        void far drawRect(int ulx, int uly, int lrx,
  381.                     int lry, unsigned colour);
  382.      Purpose:       Draw a rectangle.
  383.      Parameters:    The rectangle will be drawn with its upper-
  384.                     left coordinates at (ulx,uly) and its lower-
  385.                     left coordinates at (lrx,lry), in the colour
  386.                     contained in colour.
  387.      Return value:  None.
  388.      Remarks:       Clipping is not performed.
  389.      See also:      filledRect
  390.  
  391.  *** Function:      filledRect
  392.      Syntax:        void far filledRect(int ulx, int uly, int
  393.                     lrx, int lry, unsigned colour);
  394.      Purpose:       Draw a filled rectangle.
  395.      Parameters:    The rectangle will be drawn with its upper-
  396.                     left coordinates at (ulx,uly) and its lower-
  397.                     left coordinates at (lrx,lry), in the colour
  398.                     contained in colour.
  399.      Return value:  None.
  400.      Remarks:       Clipping is not performed.
  401.      See also:      drawRect
  402.  
  403.  *** Function:      setPaletteReg
  404.      Syntax:        void far setPaletteReg(unsigned palReg,
  405.                     unsigned char red, unsigned char green,
  406.                     unsigned char blue);
  407.      Purpose:       Set a palette register.
  408.      Parameters:    The red, green, and blue components of the
  409.                     palette register palReg will be set to red,
  410.                     green, and blue respectively.
  411.      Return value:  None.
  412.      Remarks:       None.
  413.      See also:      getPaletteReg, setBlockPalette,
  414.                     getBlockPalette
  415.  
  416.  *** Function:      getPaletteReg
  417.      Syntax:        void far getPaletteReg(unsigned palReg,
  418.                     unsigned char far *red, unsigned char far
  419.                     *green, unsigned char far *blue);
  420.      Purpose:       Return the current settings of a palette
  421.                     register.
  422.      Parameters:    The red, green, and blue contents of the
  423.                     palette register palReg will be stored in
  424.                     red, green, and blue respectively.
  425.      Return value:  The red, green, and blue components of the
  426.                     palette register are returned in red, green,
  427.                     and blue.
  428.      Remarks:       None.
  429.      See also:      setPaletteReg, setBlockPalette,
  430.                     getBlockPalette
  431.  
  432.  *** Function:      setBlockPalette
  433.      Syntax:        void far setBlockPalette(unsigned firstReg,
  434.                     unsigned numRegs, void far *data);
  435.      Purpose:       Set a block of palette registers.
  436.      Parameters:    numRegs palette registers, starting at
  437.                     firstReg, will be set to the values contained
  438.                     in data.
  439.      Return value:  None.
  440.      Remarks:       The memory region at data is organised in
  441.                     groups of three bytes; each group corresponds
  442.                     to one palette register, and each group is
  443.                     made up of, in order, the red, green, and
  444.                     blue components.  The first group is for the
  445.                     first register, the second for the second,
  446.                     and so on.
  447.      See also:      getBlockPalette, setPaletteReg, getPaletteReg
  448.  
  449.  *** Function:      getBlockPalette
  450.      Syntax:        void far getBlockPalette(unsigned firstReg,
  451.                     unsigned numRegs, void far *data);
  452.      Purpose:       Get the values of a block of palette
  453.                     registers.
  454.      Parameters:    The values of numRegs palette registers,
  455.                     starting at firstReg, will be stored in the
  456.                     previously allocated data.
  457.      Return value:  The values are returned in data.
  458.  
  459.      Remarks:       The memory region at data is organised in
  460.                     groups of three bytes; each group corresponds
  461.                     to one palette register, and each group is
  462.                     made up of, in order, the red, green, and
  463.                     blue components.  The first group is for the
  464.                     first register, the second for the second,
  465.                     and so on.
  466.      See also:      setBlockPalette, setPaletteReg, getPaletteReg
  467.  
  468.  *** Function:      clearGraphics
  469.      Syntax:        void far clearGraphics(unsigned colour);
  470.      Purpose:       Clear the screen.
  471.      Parameters:    The screen will be cleared to the colour
  472.                     contained in colour.
  473.      Return value:  None.
  474.      Remarks:       None.
  475.      See also:      filledRect
  476.  
  477.  
  478. WRITING GRAPHICS DRIVERS
  479.  
  480.      To build a new graphics driver, follow these steps:
  481.  
  482.      1.  Copy the file SHELL.ASM to another file, for example,
  483.      MYDRV.ASM.
  484.  
  485.      2.  Change the maximum X-coordinate, Y-coordinate, and
  486.      colour number to the appropriate values.  (They are clearly
  487.      identified with comments.)
  488.  
  489.      3.  A graphics driver must always contain the initGraphics
  490.      routine.  Replace the default one from SHELL.ASM with
  491.      whatever the appropriate code is.  (Be sure to add return
  492.      value logic, described in the initGraphics() description
  493.      above.)
  494.  
  495.      4.  If the new video mode is not supported by the video
  496.      BIOS, custom putPixel and getPixel routines must be written
  497.      and placed in the driver.  Doing so is advised anyway, as
  498.      the BIOS is notoriously slow.
  499.  
  500.      5.  The default palette management routines assume that the
  501.      video mode's palette registers have a resolution of six
  502.      bits.  The standard VGA has only 18-bit resolution (six bits
  503.      for each of red, green, and blue), but some SuperVGAs
  504.      support 24-bit resolution (8 bits each).  If the video mode
  505.      for which the driver is being written supports a true eight-
  506.      bit palette, the four palette management routines should be
  507.      written and placed in the driver.
  508.  
  509.      6.  Many routines assume that each pixel has a size of
  510.      exactly one byte, as 256-colour modes are so common. 
  511.      (Namely, these routines are putImage, getImage, putLine,
  512.      getLine, imageSize, putPixel, and getPixel.)  If the new
  513.      video mode does not have one-byte pixels, these routines
  514.      should be written and placed in the driver.
  515.  
  516.      7.  If speed is important, write any routines that have not
  517.      already been written.
  518.  
  519.      8.  For every routine that has been written, a change must
  520.      be made in the header of the driver's source code.  As an
  521.      example, assume that horizLine has been written.  Find the
  522.      "; horizLine" comment near the top of the source file. 
  523.      Change the "0" to the left of it to the exact name of the
  524.      new horizLine routine.  Repeat this procedure if necessary,
  525.      until the change has been made for every routine contained
  526.      in the driver.
  527.  
  528.      9.  A usable driver must be created from the source code. 
  529.      This process involves three steps.  First, assemble the .ASM
  530.      source file to an .OBJ object file.  Then, link the .OBJ so
  531.      it becomes an .EXE file.  Third, run EXE2BIN, which comes
  532.      with DOS.  Assuming the driver's source code was called
  533.      MYDRV, EXE2BIN's command line would be "EXE2BIN MYDRV.EXE
  534.      MYDRV.DRV".  When this last step is completed, there will be
  535.      a newly created driver, ready to be loaded and used with The
  536.      Graphics Engine.  The file CDRV.BAT is included to automate
  537.      this chore; it assumes the use of TASM and TLINK.  Note
  538.      that, since 16-bit offsets are used, the final driver may
  539.      not be larger than 64 Kb (not a likely problem).
  540.  
  541. TERMS OF USAGE AND DISTRIBUTION
  542.  
  543.      The Graphics Engine source code and associated documentation
  544.      are copyright (c) 1993 by Matthew Hildebrand.
  545.  
  546.      The Graphics Engine, consisting of the files listed in the
  547.      PACKING LIST section, may be distributed freely, so long as:
  548.           1.   The distributed package is complete, and its
  549.                contents are not modified in any way.
  550.           2.   The distributed package is not sold for profit.
  551.  
  552.      The Graphics Engine is not free; no part of it may be used
  553.      in any program without first purchasing it.  After an
  554.      individual or organization ("the Purchaser") has purchased a
  555.      copy of The Graphics Engine, the Purchaser is granted
  556.      permission to:
  557.           1.   Use any or all of The Graphics Engine in as many
  558.                software packages as the Purchaser likes.
  559.           2.   Distribute any software packages built using The
  560.                Graphics Engine without royalties.
  561.           3.   Modify any of the program code, and use the
  562.                modified code as described in 1 and 2 above.
  563.      Note that the Purchaser is granted permission to use any
  564.      version of The Graphics Engine, including any new ones when
  565.      they are released; ie., upgrades are free.
  566.  
  567.      The privileges granted to the Purchaser by purchasing The
  568.      Graphics Engine may be retracted if either or both of the
  569.      following conditions is broken:
  570.           1.   The copyright notice, which reads "The Graphics
  571.                Engine -- Copyright (c) 1993 by Matthew
  572.                Hildebrand" must be included in the executable
  573.                portion of any software package built using it, as
  574.                well as in any driver files (designed to work with
  575.                The Graphics Engine) which are part of that
  576.                software package.  The file TGE.C, as it is
  577.                shipped, contains this notice, as do the sources
  578.                for the drivers.
  579.           2.   Any program code derived or directly obtained from
  580.                The Graphics Engine may not be distributed in any
  581.                way, unless the recipient has also purchased a
  582.                copy of The Graphics Engine.
  583.  
  584.      In order to purchase a copy of The Graphics Engine, send $20
  585.      (US or Canadian) to Matthew Hildebrand at the address listed
  586.      in CONTACTING THE AUTHOR below.  Payment by money order,
  587.      check, or cash is acceptable.  Thank you in advance.
  588.  
  589.  
  590. CONTACTING THE AUTHOR
  591.  
  592.      I would appreciate hearing any questions, comments, bug
  593.      reports, or suggestions for improvement.  If you have any,
  594.      feel free to contact me.  I can be reached at either of the
  595.      following addresses.  Contributions of any kind to help
  596.      improve this project are welcome.
  597.  
  598.      Snail mail:
  599.           Matthew Hildebrand
  600.           4 College St.
  601.           St. Catharines, ON
  602.           Canada
  603.           L2R 2W7 
  604.  
  605.      Fido NetMail:
  606.           1:247/128.2
  607.  
  608.  
  609. OBTAINING THE GRAPHICS ENGINE
  610.  
  611.      The most recent copy of The Graphics Engine may be obtained
  612.      via File Request from 1:247/128 (14400 bps V.32bis) using
  613.      the magic file name "TGE"; unlisted nodes and points are
  614.      welcome.  The Graphics Engine is also available via first-
  615.      call download from 1:247/128 at (416)-935-6628.
  616.  
  617.  
  618. REVISION HISTORY
  619.  
  620.      1.01      First public release.
  621.  
  622.  
  623. ACKNOWLEDGEMENT
  624.  
  625.      There are people whom I would like to thank for their
  626.      suggestions, beta-testing, patience, and help with
  627.      distribution.  You know who you are.
  628.  
  629.  
  630. LEGAL MUMBO JUMBO
  631.  
  632.      All software and documentation associated with The Graphics
  633.      Engine is provided "as is", and without warranty of any
  634.      kind.  The author may not be held liable for any damage or
  635.      misfortune that the usage of this software may cause. 
  636.      Although the software has undergone extensive testing, there
  637.      is a chance that it may crash anyway.
  638.  
  639.      All registered trademarks in this document belong to
  640.      whomever it is that owns them.