
*******************************************************************
GAME32 Graphics/Input Programming Library for Watcom C/C++ & DOS4GW
*******************************************************************

(c)Andrew McNab 1997
email: 101447.2365@compuserve.com or amcnab@easynet.co.uk

BETA test version 1.4 - please report bugs, problems, comments,
 suggestions etc.

Updates - beta 1.0 - 1.3:
 keyboard.h file of definitions for CheckKey().
 Vesa 640x400 support added through SetVesaMode().
 Improved speed of plain polygon function.
 Rotate works right way for screen coordinates.
 New polygon functions added.
 LoadPicS() function added to load a section of a PCX image.
 Perspective plane functions added.

1.4 beta update - SVGA init failure with VESA 2, fixed.

To check if you have the very latest version, go to this WWW page -
 http://easyweb.easynet.co.uk/~amcnab/game32.htm

Requirements: Watcom C/C++, 486+ (compiled for 486)


LICENSE

This program is neither freeware nor shareware, it is free, but only for
non-commercial use (well it's better than most :) ).
  You may freely use this library for as long as you wish, but you may not
sell any programs created with this version (see below).
You must also not release/distribute any kind of game design system or
graphics library created with GAME32.
  If you wish to sell a program created using this library, you must purchase
a special version of the library which will include a license to sell such a
program. This version will have no message on start up. Shareware authors may
get their own reduced price version. Email for more details (see addr. above).
 
This is not a cut-down version. Apart from the 'non-commercial' message that
appears after library initiation it is fully functioning. Use it well and
if you make something great that you want to sell, come back to me for a
commercial or shareware product version.

Prices:
 Commercial Version: 60 ($90)
 License to sell shareware products only: 30 ($45)

 Please email me for full ordering info (see address above).


*************************************
LIBRARY FUNCTIONS & HOW TO USE GAME32
*************************************


*BASICS


See the example C and .bat files for examples of how to write and compile
simple graphics programs.


General notes

Variables - Some of GAME32's internal variables are declared in the header
file, this is so that experienced programmers can add their own functions if
desired.

Filenames - When passing filename paths to a function you may need to use
two \\ instead of the normal one \ for splitting up directories.

Image sizes - note the size limitations with some functions - e.g. MBMs
are 255x255 max, polygon textures must be 64 pixels wide, plane textures
must be 128x128.

Clipping - note that the drawing functions - PutPixel(), Rectangle() and
Line() do not get clipped so they must not extend outside of the buffer when
drawn. The same applys to the CutOut() & PutBitmap() functions. And the
functions for displaying the buffer to the screen must not have source or
destination coordinates outside of the buffer or screen areas.

Rotating images - there is no specific function for rotating images, but you
can use the texture mapping functions as shown in the example. You will have
to scale your source image so it has a width of 64 though and adjust the
texture coordinates to be the perimeter of the source image.
If you just want to scale an image and not rotate at all, use the Scale()
function which should be a lot faster than texture mapping and works with any
size image.


Basics

The functions work by having a buffer in memory where all graphics are drawn
to. You can then display this buffer, or a section of it, to the VGA or SVGA
screen. The currently supported screen modes are VGA 13h (320x200 256col) and
SVGA VESA modes 101h (640x480 256col) and 100h (640x400 256col).

 char InitGameLib(int buffw,int buffh);

This function initiates the library, and creates a buffer (or virtual screen)
in memory. The input variables specifiy the dimensions of this buffer.
You might just have a screen-sized buffer (320x200 for VGA, 640x480 for SVGA)
or you might create a larger buffer for a scrolling game. Memory should be
your only limitation.
  This function, as with many others, returns 1 if an error occurs.

 void FreeMem(void);

FreeMem() is like a close library function. It frees up all memory allocated
by the GAME32 functions.

 char NewBuffer(int width,int height);

Changes the size of the buffer and reallocates memory accordingly.

 void Quit(char message[]);

Quits the library and program and displays a text message.

 void SetVGA(void);
 int SetSVGA(void);
 int SetVesaMode(int mode);
 void SetTXT(void);

SetVGA() and SetSVGA() set 320x200x256col (VGA mode 13h) and 640x480x256col
(VESA svga) screen modes respectively. SetVesaMode() initiates other SVGA
Vesa modes, currently only 0x100 (640x400) and 0x101 (640x480 again) can be
set with this function
  You can then start drawing and displaying graphics. SetTXT() puts you back
to text mode.  Note the SVGA modes are for Vesa-compatible graphics cards
only.  Make sure a driver is loaded, if necessary, for your videocard.
The SetSVGA() function will return 1 if there is an error initializing
SVGA, as will SetVesaMode().

 void SetClip(int x1,int y1,int x2,int y2);

Sets the area, outside of which, no graphics are drawn (unless the function
does not support clipping).  You may never need this, as the clipping area is
automatically set to be the perimeter of the Buffer whenever you use the
InitGameLib() or NewBuffer() functions (i.e. 0,0,319,199 for VGA).


*BASIC DRAWING AND DISPLAYING


  void ClearBuffer(unsigned char colour);

Clear the buffer to specified colour.

  void DisplayBuffer(int x,int y);

Display a screen-sized chunk of the buffer to the screen (320x200 for VGA).
The coordinates specify the top-left corner of the buffer area to be
displayed (Use 0,0 if the buffer is the same size as the current screen
mode).

  void DWinBuffer(int buffx,int buffy,int scrx,int scry,int width,int height);

Display a specified window of the buffer to the specified screen position
  If you are creating a single screen SVGA game you can get a fast frame-rate
by using this function to only display the areas of the screen which have
changed since the last update. When displaying multiple windows to an SVGA
screen each frame, try to draw the windows in order - from top left to bottom
right - to get the fastest updates.

  void PutPixel(int x,int y,unsigned char colour);
  void Rectangle(int x,int y,int width,int height,unsigned char colour
   ,char fill);
  void Line(int x1,int y1,int x2,int y2,unsigned char colour);

-Draw a single pixel/dot to the buffer.
-Draw a Rectangle to the buffer. if (fill==0) an outline only will be drawn.
-Draw a line in the buffer.
The above three functions do not support clipping, so make sure nothing
is drawn outside of the buffer (or you will crash).


*IMAGE LOADING FUNCTIONS


THE MBM FORMAT - MBMs are a custom masked bitmap format, created for this
library, which store lines of solid or transparent pixels in an image in
order to speed up drawing. Convert PCXs to the MBM format using the
PCX2MBM.EXE program. Only convert images with transparent (colour 0) areas,
as other images do not benefit from this format.
  Advantages: Faster for drawing large images with transparent areas.
  Disadvantages: MAX SIZE = 255*255. Slower for very complex images that mix
                 a lot of transparent and solid pixels.
There are seperate functions for PCX loading/drawing and MBMs. Do not try
mixing the two.

Before you can display any images you must load them in to memory and store
them as simple bitmaps or in the MBM format.
  PCX files (256 colour) are the only source images supported at present.  If
you want to draw images with transparent areas (colour 0), then you should
convert them to MBM's in most cases.
  To load a PCX or MBM image use one of the following functions:-

  //to load a PCX
  char LoadPic(char name[],int position);

  //to load a MBM
  char LoadMBM(char name[],int position);

  //to load a PCX and set the palette to it's
  char LoadPic1(char name[],int position);

  //to load a small section of a PCX image
  char LoadPicS(char name[],int position,int sx,int sy,
   int width,int height);

The position input variable must be a number from 0-299. There are 300 slots
in which to store images. Loading an image into a slot already filled will
result in the old image being overwritten.
  With LoadPicS() you specify the start position in the image (sx,sy) and
the width and height of the section to cut out and load.


*IMAGE DRAWING FUNCTIONS


Only the PutMBM function deals with MBM's. All the other functions must use
previously loaded normal PCX images.

  char PutPic(int no,int X,int Y);

Draws and clips the specified number image to the buffer at x,y.

  char PutPicM(int no,int X,int Y);

As above but does not draw colour 0 parts. Use MBMs for all large masked
images to get the best speed, this function is slow. This is only really
useful for very small images or very complex (e.g. alternate solid and
transparent pixel) images which may work slower in the MBM format.


  int PutPicScale(int no,int X,int Y,float scale);

Draws an image scaled by the specified fraction.
By the way, the coordinates specify where you want the centre of the
image to be, not the top-left, for this function.

  int PutPicScaleM(int no,int X,int Y,float scale);

As above but leaves colour 0 parts transparent.


  int PutPicScaleXY(int no,int X,int Y,int newW,int newH);
  int PutPicScaleXYM(int no,int X,int Y,int newW,int newH);

Alternative scaling functions. Specify new width and height for image,
allowing for independant X and Y scaling. The X,Y coordinates are for the
top-left this time.


  void PutPicVGA(int no,int X,int Y);

The only direct to screen function.  Draws an unclipped image to the VGA
screen directly. Use for title screens and/or quick image displaying.

  int PutMBM(int no,int X,int Y);

Puts a masked MBM image to the screen (previously loaded with LoadMBM() ).

All above Image functions, except for PutPicVGA(), automatically clip the
image being drawn if it extends out of the cipping area / buffer.


*TEXT FUNCTIONS


By first creating a font file in the PCX format, you can then easily draw
text on the screen. See the example 'text.pcx' for how to lay out your
alphabet - basically you must create a line of equally sized 1pixel boxes
which contain letters, numbers and ,.? characters.

 char LoadTXT(char name[],int position,int width,int height);

This loads in your PCX format font file. The position is the slot to load the
text into. There are five (0-4) slots for Text, these are sepearate to the
300 image slots. The width and height are not for the image, but the size of
each character in your font.

 void PutTXT(int pos,char string[],unsigned char col,int X,int Y);
 void PutTXTC(int pos,char string[],unsigned char col,int Y);

PutTXT() draws text at you desired position.
PutTXTC() draws text centred in the current buffer.
pos = the 0-4 position in whih your desired font was loaded.
col = desired colour. 0 = use the origional colours the text was created in.
      1-255 = draw the text in the single colour specified.
string contains the text to print - letters,numbers and .,? characters only.


*PALETTE functions


  void SetPal(void);
  void SetPalCol(int n,unsigned char red,unsigned char green
                 ,unsigned char blue);
  void SetColour(unsigned char colour,unsigned char red,unsigned char green
                 ,unsigned char blue);
  void PFadeDown(int spd);
  void PFadeUp(int spd);

There are two types of palette. 1.The actual palette currently set and used
on screen. 2.The palette stored in the 'palette[768]' array of GAME32.
  When you use the LoadPic1() function the palette array is first filled
with the image's palette and then the internal palette is set to this. The
palette is now stored in the array for future use, so that when you change
screen mode etc you can use the SetPal() function to restore the palette.
  You can change the palette array directly or by using the SetPalCol()
function.
  SetColour() sets the internal/actual palette (1), but does not adjust the
stored palette.
  The PFadeDown() function fades down the actual palette (1) to black.
  PFadeUp fades up the actual palette (1) from black to the stored palette
values (2).


*POLYGONS and texture mapping


 //draw a 4 sided textured polygon
 int dtpclip4(int ppts[4][2], int txtpts[4][2], char *txtr);

 //draw a 4 sided plain polygon
 int dpclip4(int ppts[4][2], unsigned char col);

 //draw a 3 sided textured polygon
 int dtpclip3(int ppts[3][2], int txtpts[3][2], char *txtr);

 //draw a 3 sided plain polygon
 int dpclip3(int ppts[3][2], unsigned char col);

 //draw a 4 sided textured polygon with transparent areas
 int dtpclip4m(int ppts[4][2], int txtpts[4][2], char *txtr);

 //draw a 3 sided textured polygon with transparent areas
 int dtpclip3m(int ppts[3][2], int txtpts[3][2], char *txtr);


All the above functions take an array of points for input, which define
the 2d points of the polygon you wish to draw. The texture functions
take a second point array describing the area to be used from your source
texturemap (a bitmap pointed to by the *txtr input variable).
Not that all points must be described in CLOCKWISE order.
Also the source texture must be 64 PIXELS IN WIDTH.
  To simply use a previously loaded PCX image for texturing, use the pcxptr
array defined in the header file. e.g. to use an image in slot 1 use
'pcxptr[1]' as your texture pointer.
  The texture-mapping functions work best if the target polygon is small and
not too distorted from the source shape.
  The one unique limitation of polygons is that they can not be drawn below
line 479 of the buffer (i.e beyond the bottom of an SVGA640x480 screen).

  //alternative polygon functions
  int dpclip4b(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4
   ,unsigned char col);
  int dpclip3b(int x1,int y1,int x2,int y2,int x3,int y3,unsigned char col);

  int dtpclip4b(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4
   ,char *txtr);
  int dtpclip3b(int x1,int y1,int x2,int y2,int x3,int y3,char *txtr);

  int dtpclip4mb(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4
   ,char *txtr);
  int dtpclip3mb(int x1,int y1,int x2,int y2,int x3,int y3,char *txtr);

Or you can use the above functions and specify each point seperately.
These functions also check if the points are in clockwise order, so you do
not have to - great for 3d stuff.
For the above four textured polygon functions the source texture coordinates
are done for you and are - 0,0, 63,0, 63,63, (0,63).


  TEXTURED PLANES

  void draw_ground(int xoffset,int zoffset,int height,char *src);
  void draw_sky(int xoffset,int zoffset,int height,char *src);
  
These two functions draw perspective-textured planes.
They only work in VGA 320x200 mode with a 320x200 size buffer. 
The planes are aligned with the horizon and can have an offset in the X and Z
directions. The height effects how far you appear to be above or below the
plane and must be at least 100. The functions take a pointer to a stored
image which must be 128 pixels square.


*BITMAP CUT AND PASTE FUNCTIONS


  void CutOut(int x,int y,int width,int height,unsigned char *ptr);
  void PutBitmap(int x,int y,unsigned char *ptr);

CutOut() saves an area of the buffer into memory, while PutBitmap() will
draw a bitmap into the buffer (no clipping).
  With CutOut() *ptr must be a pointer to a memory block with enough space
to store the bitmap - 2+(width*height) bytes. Max dimensions 255*255;
  With PutBitmap() *ptr points to an array of bytes the first two
characters of which should contain the width and height of the bitmap, the
rest the raw data.
  These functions are useful in creating a scrolling game where each level
is pre-drawn in a large buffer. You can save the areas under each foreground
object, then draw and display them, then cover them over again to restore the
background. Also good for SVGA games with a static background.


*CONTROL INPUT FUNCTIONS


KEYBOARD

 void InitKeyScan(void);
 void CloseKeyScan(void);

The above functions initiate and close the keyboard scanning routine.
You must close it down before exiting your program.

  char CheckKey(char kno);

This returns 1 if the specified key (0-128) is pressed.
Include the 'keycodes.h' header file and you will be able to use the key
definitions shown in it - e.g. CheckKey(_A) to check the 'a' key.

JOYSTCKS

All joystick functions take a number indicating which of the two possible
joystcks you are accessing (1 or 2).

 void CalJoy(int no);

Text-mode calibration routine

 int JoyBtn(int no);

Returns a value indicating which buttons are pressed on the specified
joystick (joy. 1 or 2).
Return values - 0 = none pressed.
                1 = button 1 pressed.
                2 = button 2 pressed.
                3 = both buttons pressed.

 int JoyX(int no,int timeout);
 int JoyY(int no,int timeout);

Returns a number from -10 to 10 indicating the joysticks position along
the X or Y axis. Try 2000 for the timeout value, or higher for v.fast
machines. These functions are SLOOWWW, because PC joystick position reading
is like that. Use them sparingly.

 int JoyPos(int no,int axis);

A general position indicator function for making your own joystick routines.


*MISCELANEOUS FUNCTIONS


  unsigned char TestBuffPix(int x,int y);

Returns the value of the specified buffer pixel.

  void WaitVR();

Wait for the start of the next 'vertical retrace'. Use this before displaying
the buffer to the screen if you want smooth updates. It will also limit the
maximum speed of your program to the refresh rate (around 60fps).

  void Rotate(int angle,int x,int y,int *xp,int *yp);

2d rotation function. Rotate the specified point around 0,0 and store the
values in xp and yp. Example: Rotate(90, 5,10, &xv,&yv);
Angle must be 0-359.


*VARIABLES


See the header file for some delclarations of useful internal variables used
by GAME32.


********************
IF YOU HAVE PROBLEMS
********************

Check everything carefully, then send email to one of the address's at the
top explaining the problem.




