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