home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Supreme Volume 6 #1
/
swsii.zip
/
swsii
/
099
/
TGE101.ZIP
/
TGE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-04
|
16KB
|
664 lines
/*****************************************************************************
* The Graphics Engine v1.01 *
* *
* All program code and documentation associated with The Graphics *
* Engine is Copyright (c) 1993 by Matthew Hildebrand. *
* *
* Unauthorised usage or modification of any or all of The Graphics *
* Engine is strictly prohibited. *
*****************************************************************************/
/* This notice may NOT be removed and MUST remain intact */
static char copyright[] = "The Graphics Engine -- Copyright (c) 1993 by Matthew Hildebrand";
/* Guess what... this file must be compiled with the large or huge model. */
#ifdef __TINY__
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef __SMALL__
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef M_I86SM
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef __MEDIUM__
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef M_I86MM
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef __COMPACT__
#error This module MUST be compiled with the large or huge model.
#endif
#ifdef M_I86CM
#error This module MUST be compiled with the large or huge model.
#endif
#include <alloc.h>
#include <dos.h>
#include <math.h>
#include <mem.h>
#include <stdio.h>
#include "tge.h"
#define MAXX (_grSystemDrv->maxx)
#define MAXY (_grSystemDrv->maxy)
static void *forceOffset(void far *p);
static void setupInfo(struct GraphDrv far *grDrv);
static void huge GE_deInitGraphics(void);
static void huge GE_putImage(int x, int y, void far *image);
static void huge GE_putImageInv(int x, int y, void far *image);
static void huge GE_getImage(int ulx, int uly, int lrx, int lry, void far
*image);
static void huge GE_putLine(int lineNum, int xOff, int lineLen, void far *buf);
static void huge GE_getLine(int lineNum, int xOff, int lineLen, void far *buf);
static unsigned long huge GE_imageSize(int ulx, int uly, int lrx, int lry);
static void huge GE_putPixel(int x, int y, unsigned colour);
static unsigned huge GE_getPixel(int x, int y);
static void huge GE_line(int x1, int y1, int x2, int y2, unsigned colour);
static void huge GE_horizLine(int y, int x1, int x2, unsigned colour);
static void huge GE_drawRect(int ulx, int uly, int lrx, int lry, unsigned
colour);
static void huge GE_filledRect(int ulx, int uly, int lrx, int lry, unsigned
colour);
static void huge GE_setPaletteReg(unsigned palReg, unsigned char red,
unsigned char blue, unsigned char green);
static void huge GE_getPaletteReg(unsigned palReg, unsigned char *red,
unsigned char *blue, unsigned char *green);
static void huge GE_setBlockPalette(unsigned firstReg, unsigned numRegs,
void far *data);
static void huge GE_getBlockPalette(unsigned firstReg, unsigned numRegs,
void far *data);
static void huge GE_clearGraphics(unsigned colour);
static struct GraphDrv far *drvAddr = NULL;
struct GraphDrv far *_grSystemDrv = NULL;
/******
******* Routines to load a graphics driver from disk.
******/
/* Call this function to load a driver */
int loadGraphDriver(char *filename)
{
struct GraphDrv far *grDrv = NULL;
FILE *fp;
long l;
char signature[4];
if ((fp=fopen(filename,"rb")) != NULL) {
fseek(fp, 0L, SEEK_END);
l = ftell(fp);
rewind(fp);
fread(signature, 1, 4, fp);
if (!memcmp(signature, "GRAP", 4))
{
l -= 4;
if (l < 0xFFFFl && (grDrv=(struct GraphDrv far *)farmalloc(l+15)) != NULL)
{
drvAddr = grDrv;
(void *)grDrv = forceOffset(drvAddr); /* force to XXXX:0004 */
_grSystemDrv = grDrv;
/* initialize the function pointers */
if (fread(grDrv, 1, (unsigned)l, fp) == (unsigned)l)
{
setupInfo(grDrv);
}
else
{
farfree(grDrv);
drvAddr = _grSystemDrv = grDrv = NULL;
}
}
}
fclose(fp);
}
return (grDrv ? 1 : 0);
}
/* Force a pointer to the form XXXX:0004 */
static void *forceOffset(void far *p)
{
void huge *temp = (void huge *)p;
if (FP_OFF(temp) == 4)
return ((void far *)temp);
else if (FP_OFF(temp) > 4)
return (MK_FP(FP_SEG(temp)+1, 4));
else
return (MK_FP(FP_SEG(temp), 4));
}
/* Set up function pointers once a driver has been loaded */
static void setupInfo(struct GraphDrv far *grDrv)
{
register unsigned seg = FP_SEG(grDrv);
/* initGraphics must always be present */
(void *)grDrv->_initGraphics = MK_FP(seg, FP_OFF(grDrv->_initGraphics));
/* These functions are optional; fill in the default ones if the
driver doesn't contain them. It's tedious, but somebody has
to do it... */
if (FP_OFF(grDrv->_deInitGraphics)) /* deInitGraphics */
(void *)grDrv->_deInitGraphics = MK_FP(seg, FP_OFF(grDrv->_deInitGraphics));
else
grDrv->_deInitGraphics = GE_deInitGraphics;
if (FP_OFF(grDrv->_putImage)) /* putImage */
(void *)grDrv->_putImage = MK_FP(seg, FP_OFF(grDrv->_putImage));
else
grDrv->_putImage = GE_putImage;
if (FP_OFF(grDrv->_putImageInv)) /* putImageInv */
(void *)grDrv->_putImageInv = MK_FP(seg, FP_OFF(grDrv->_putImageInv));
else
grDrv->_putImageInv = GE_putImageInv;
if (FP_OFF(grDrv->_getImage)) /* getImage */
(void *)grDrv->_getImage = MK_FP(seg, FP_OFF(grDrv->_getImage));
else
grDrv->_getImage = GE_getImage;
if (FP_OFF(grDrv->_putLine)) /* putLine */
(void *)grDrv->_putLine = MK_FP(seg, FP_OFF(grDrv->_putLine));
else
grDrv->_putLine = GE_putLine;
if (FP_OFF(grDrv->_getLine)) /* getLine */
(void *)grDrv->_getLine = MK_FP(seg, FP_OFF(grDrv->_getLine));
else
grDrv->_getLine = GE_getLine;
if (FP_OFF(grDrv->_imageSize)) /* imageSize */
(void *)grDrv->_imageSize = MK_FP(seg, FP_OFF(grDrv->_imageSize));
else
grDrv->_imageSize = GE_imageSize;
if (FP_OFF(grDrv->_putPixel)) /* putPixel */
(void *)grDrv->_putPixel = MK_FP(seg, FP_OFF(grDrv->_putPixel));
else
grDrv->_putPixel = GE_putPixel;
if (FP_OFF(grDrv->_getPixel)) /* getPixel */
(void *)grDrv->_getPixel = MK_FP(seg, FP_OFF(grDrv->_getPixel));
else
grDrv->_getPixel = GE_getPixel;
if (FP_OFF(grDrv->_line)) /* line */
(void *)grDrv->_line = MK_FP(seg, FP_OFF(grDrv->_line));
else
grDrv->_line = GE_line;
if (FP_OFF(grDrv->_horizLine)) /* horizLine */
(void *)grDrv->_horizLine = MK_FP(seg, FP_OFF(grDrv->_horizLine));
else
grDrv->_horizLine = GE_horizLine;
if (FP_OFF(grDrv->_drawRect)) /* drawRect */
(void *)grDrv->_drawRect = MK_FP(seg, FP_OFF(grDrv->_drawRect));
else
grDrv->_drawRect = GE_drawRect;
if (FP_OFF(grDrv->_filledRect)) /* filledRect */
(void *)grDrv->_filledRect = MK_FP(seg, FP_OFF(grDrv->_filledRect));
else
grDrv->_filledRect = GE_filledRect;
if (FP_OFF(grDrv->_setPaletteReg)) /* setPaletteReg */
(void *)grDrv->_setPaletteReg = MK_FP(seg, FP_OFF(grDrv->_setPaletteReg));
else
grDrv->_setPaletteReg = GE_setPaletteReg;
if (FP_OFF(grDrv->_getPaletteReg)) /* getPaletteReg */
(void *)grDrv->_getPaletteReg = MK_FP(seg, FP_OFF(grDrv->_getPaletteReg));
else
grDrv->_getPaletteReg = GE_getPaletteReg;
if (FP_OFF(grDrv->_setBlockPalette)) /* setBlockPalette */
(void *)grDrv->_setBlockPalette = MK_FP(seg, FP_OFF(grDrv->_setBlockPalette));
else
grDrv->_setBlockPalette = GE_setBlockPalette;
if (FP_OFF(grDrv->_getBlockPalette)) /* getBlockPalette */
(void *)grDrv->_getBlockPalette = MK_FP(seg, FP_OFF(grDrv->_getBlockPalette));
else
grDrv->_getBlockPalette = GE_getBlockPalette;
if (FP_OFF(grDrv->_clearGraphics)) /* clearGraphics */
(void *)grDrv->_clearGraphics = MK_FP(seg, FP_OFF(grDrv->_clearGraphics));
else
grDrv->_clearGraphics = GE_clearGraphics;
}
/******
******* Free graphics driver memory
******/
void unloadGraphDriver(void)
{
if (drvAddr)
farfree(drvAddr);
}
/******
******* High-level driver routines to be used if they aren't in a driver
******/
static void huge GE_deInitGraphics(void)
{
_AX = 0x0003;
geninterrupt(0x10);
}
static void huge GE_putImage(int x, int y, void far *image)
{
register unsigned ycount;
unsigned wide, deep;
register unsigned sadd = 0;
unsigned char huge *p = (unsigned char *)image;
wide = *(unsigned *)image;
deep = *((unsigned *)image+1);
p += 4;
if (y < 0) /* clip y coordinate */
{
if (y+deep)
{
p += wide * abs(y);
deep -= abs(y);
y = 0;
}
else
return;
}
else if (y > MAXY)
return;
else if (y+deep > MAXY)
deep = MAXY-y+1;
if (x < 0) /* clip x coordinate */
{
if (x+wide)
{
sadd += abs(x);
p += abs(x);
wide -= abs(x);
x = 0;
}
else
return;
}
else if (x > MAXX)
return;
else if (x+wide > MAXX)
{
sadd += wide-1 - (MAXX-x);
wide = MAXX-x+1;
}
sadd += wide;
for (ycount=0; ycount<deep; ycount++)
{
putLine(y+ycount, x, wide, (void *)p);
p += sadd;
}
}
static void huge GE_putImageInv(int x, int y, void far *image)
{
register unsigned xcount, ycount;
unsigned wide, deep;
register unsigned sadd = 0;
unsigned char huge *p = (unsigned char *)image;
wide = *(unsigned *)image;
deep = *((unsigned *)image+1);
p += 4;
if (y < 0) /* clip y coordinate */
{
if (y+deep)
{
p += wide * abs(y);
deep -= abs(y);
y = 0;
}
else
return;
}
else if (y > MAXY)
return;
else if (y+deep > MAXY)
deep = MAXY-y+1;
if (x < 0) /* clip x coordinate */
{
if (x+wide)
{
sadd += abs(x);
p += abs(x);
wide -= abs(x);
x = 0;
}
else
return;
}
else if (x > MAXX)
return;
else if (x+wide > MAXX)
{
sadd += wide-1 - (MAXX-x);
wide = MAXX-x+1;
}
for (ycount=0; ycount<deep; ycount++)
{
for (xcount=0; xcount<wide; xcount++)
{
if (*p)
putPixel(x+xcount, y+ycount, *p);
p++;
}
p += sadd;
}
}
static void huge GE_getImage(int ulx, int uly, int lrx, int lry, void far
*image)
{
register unsigned ycount, wide;
int temp;
unsigned char huge *p = (unsigned char *)image;
if (lrx < ulx) /* swap coordinates if necessary */
{
temp = ulx;
lrx = ulx;
lrx = temp;
}
if (lry < uly)
{
temp = uly;
lry = uly;
lry = temp;
}
if (ulx < 0) /* ensure coords are in bounds */
ulx = 0;
else if (ulx > MAXX)
ulx = MAXX;
if (uly < 0)
uly = 0;
else if (uly > MAXY)
uly = MAXY;
if (lrx < 0)
lrx = 0;
else if (lrx > MAXX)
lrx = MAXX;
if (lry < 0)
lry = 0;
else if (lry > MAXY)
lry = MAXY;
*(unsigned *)image = lrx-ulx+1;
*((unsigned *)image+1) = lry-uly+1;
p += 4;
wide = lrx-ulx+1;
for (ycount=uly; ycount<=lry; ycount++)
{
getLine(ycount, ulx, wide, (void *)p);
p += wide;
}
}
static void huge GE_putLine(int lineNum, int xOff, int lineLen, void far *buf)
{
register unsigned count, y;
for (count=0,y=lineNum; count<lineLen; count++)
putPixel(xOff+count, y, *((unsigned char huge *)buf+count));
}
static void huge GE_getLine(int lineNum, int xOff, int lineLen, void far *buf)
{
register unsigned count, y;
for (count=0,y=lineNum; count<lineLen; count++)
*((unsigned char huge *)buf+count) = getPixel(xOff+count, y);
}
static unsigned long huge GE_imageSize(int ulx, int uly, int lrx, int lry)
{
unsigned long size;
int temp;
if (lrx < ulx) /* swap coordinates if necessary */
{
temp = ulx;
lrx = ulx;
lrx = temp;
}
if (lry < uly)
{
temp = uly;
lry = uly;
lry = temp;
}
if (ulx < 0) /* ensure coords are in bounds */
ulx = 0;
else if (ulx > MAXX)
ulx = MAXX;
if (uly < 0)
uly = 0;
else if (uly > MAXY)
uly = MAXY;
if (lrx < 0)
lrx = 0;
else if (lrx > MAXX)
lrx = MAXX;
if (lry < 0)
lry = 0;
else if (lry > MAXY)
lry = MAXY;
size = (unsigned long)(lrx-ulx+1);
size *= (unsigned long)(lry-uly+1);
return (size+4); /* +4 for dimension information */
}
static void huge GE_putPixel(int x, int y, unsigned colour)
{
_AH = 0x0C;
_AL = (unsigned char)colour;
_BH = 0;
_CX = x;
_DX = y;
geninterrupt(0x10);
}
static unsigned huge GE_getPixel(int x, int y)
{
_AH = 0x0D;
_BH = 0;
_CX = x;
_DX = y;
geninterrupt(0x10);
_AH = 0;
return (_AX);
}
static void huge GE_line(int x1, int y1, int x2, int y2, unsigned colour)
{
register int t, distance;
int xerr=0, yerr=0, deltax, deltay;
int incx, incy;
deltax = x2 - x1; /* compute both distances */
deltay = y2 - y1;
if (deltax > 0) /* compute increments */
incx = 1;
else if (deltax == 0)
incx = 0;
else
incx = -1;
if (deltay > 0)
incy = 1;
else if (deltay == 0)
incy = 0;
else
incy = -1;
deltax = abs(deltax); /* determine greater distance */
deltay = abs(deltay);
if (deltax > deltay)
distance = deltax;
else
distance = deltay;
for (t=0; t<=distance+1; t++) /* draw the line */
{
putPixel(x1, y1, colour);
xerr += deltax;
yerr += deltay;
if (xerr > distance)
{
xerr -= distance;
x1 += incx;
}
if (yerr > distance)
{
yerr -= distance;
y1 += incy;
}
}
}
static void huge GE_horizLine(int y, int x1, int x2, unsigned colour)
{
register unsigned count, max;
max = x2;
for (count=x1; count<=max; count++)
putPixel(count, y, colour);
}
static void huge GE_drawRect(int ulx, int uly, int lrx, int lry, unsigned
colour)
{
register int t;
if (ulx > lrx) /* swap coords if necessary */
{
t = ulx;
ulx = lrx;
lrx = t;
}
if (uly > lry)
{
t = uly;
uly = lry;
lry = t;
}
horizLine(uly, ulx, lrx, colour); /* top */
horizLine(lry, ulx, lrx, colour); /* bottom */
line(ulx, uly, ulx, lry, colour); /* left */
line(lrx, uly, lrx, lry, colour); /* bottom */
}
static void huge GE_filledRect(int ulx, int uly, int lrx, int lry, unsigned
colour)
{
register unsigned count, max;
int t;
if (ulx > lrx) /* swap coords if necessary */
{
t = ulx;
ulx = lrx;
lrx = t;
}
if (uly > lry)
{
t = uly;
uly = lry;
lry = t;
}
max = lry;
for (count=uly; count<=max; count++)
horizLine(count, ulx, lrx, colour);
}
static void huge GE_setPaletteReg(unsigned palReg, unsigned char red, unsigned
char blue, unsigned char green)
{
_AX = 0x1010;
_BX = palReg;
_DH = red;
_CH = green;
_CL = blue;
geninterrupt(0x10);
}
static void huge GE_getPaletteReg(unsigned palReg, unsigned char *red, unsigned
char *blue, unsigned char *green)
{
_AX = 0x1015;
_BX = palReg;
geninterrupt(0x10);
*red = _DH;
*green = _CH;
*blue = _CL;
}
static void huge GE_setBlockPalette(unsigned firstReg, unsigned numRegs, void
far *data)
{
_ES = FP_SEG(data);
_DX = FP_OFF(data);
_AX = 0x1012;
_BX = firstReg;
_CX = numRegs;
geninterrupt(0x10);
}
static void huge GE_getBlockPalette(unsigned firstReg, unsigned numRegs, void
far *data)
{
_ES = FP_SEG(data);
_DX = FP_OFF(data);
_AX = 0x1017;
_BX = firstReg;
_CX = numRegs;
geninterrupt(0x10);
}
static void huge GE_clearGraphics(unsigned colour)
{
register unsigned count;
for (count=0; count<=MAXY; count++)
horizLine(count, 0, MAXX, colour);
}