home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Learn 3D Graphics Programming on the PC
/
Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso
/
rwdos
/
osdos.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-15
|
39KB
|
1,342 lines
/**********************************************************************
*
* File : osdos.c
*
* Abstract : DOS specific implementation of OS specific files. Note:
* the program entry point and top level control flow is
* also performed here.
*
**********************************************************************
*
* This file is a product of Criterion Software Ltd.
*
* This file is provided as is with no warranties of any kind and is
* provided without any obligation on Criterion Software Ltd. or
* Canon Inc. to assist in its use or modification.
*
* Criterion Software Ltd. will not, under any
* circumstances, be liable for any lost revenue or other damages arising
* from the use of this file.
*
* Copyright (c) 1995 Criterion Software Ltd.
* All Rights Reserved.
*
* RenderWare is a trademark of Canon Inc.
*
************************************************************************/
/*--- Include Files ---*/
#include "global.h" /* Application global includes */
/* Dos specific include files */
#include <i86.h>
#include "rwdos.h"
#include "doswrap.h"
/* Macro and Magic Number definitions */
#define KEY_RSHIFT 0x01
#define KEY_LSHIFT 0x02
#define KEY_CONTROL 0x04
#define KEY_ALT 0x08
#define KEY_SCRCLOCK 0x10
#define KEY_NUMLOCK 0x20
#define KEY_CAPLOCK 0x40
#define KEY_INSERT 0x80
#define LORES_SCREEN_WIDTH 320
#define LORES_SCREEN_HEIGHT 200
#define LORES_CAMERA_WIDTH LORES_SCREEN_WIDTH
#define LORES_CAMERA_HEIGHT LORES_SCREEN_HEIGHT
#define HIRES_SCREEN_WIDTH 640
#define HIRES_SCREEN_HEIGHT 480
#define HIRES_CAMERA_WIDTH PANEL_HOLE_WIDTH
#define HIRES_CAMERA_HEIGHT PANEL_HOLE_HEIGHT
#ifdef WITH_SCORE
#define SCORE_UP CREAL(0.2)
#define SCORE_RIGHT CREAL(0.5)
#define SCORE_FORWARD CREAL(2.5)
#define SCORE_STARTX CREAL(2.0)
#define SCORE_STARTY CREAL(1.4)
/*--- Structure Definitions ---*/
/* AllSprites: A single global variable of this type is defined and used to hold
* global sprite data
*/
typedef struct
{
RwRect rClip; /* The clip rectangle for the sprites */
int nDepth; /* The current display depth. Used when masking sprites */
} AllSprites;
AllSprites asGSprites;
/* Score definitions */
#define NUM_LEFT_IMAGES 4 /* The number of images used for the big rat */
/* Score: A single global variable of this type is declared and used to hold
* all of the global score data
*/
typedef struct
{
RwClump *cpRat; /* The clump for the small spinning rat */
RwMatrix4d *mpPos; /* The absolute position matrix for the
spinning rats */
RwMatrix4d *mpRot; /* The incremental rotation that is applied to the
rats each frame */
RwMatrix4d *mpOffset; /* The matrix used to determine the 3D location
that the score rats are drawn */
RwRaster *spaLeftImages[NUM_LEFT_IMAGES]; /* The rasters for the big rat
which changes dependant on
the number of rats in the street */
RwRaster *spTimesOne; /* The raster for the x1 overlay */
RwRaster *spTimesFive; /* The raster for the x5 overlay */
RwRaster *spTimesTwentyFive; /* The raster for the x25 overlay */
} Score;
Score sGScore;
/*--- Function Prototypes ---*/
static int AllSoundsAddSound(char *cpFilename, int nVolume, int nPeriod, int nChannel);
static int AllSpritesSetClip(RwInt32 nX, RwInt32 nY, RwInt32 nW, RwInt32 nH);
#endif /* WITH_SCORE */
/*--- Global Variables ---*/
static int nGLoRes; /* TRUE if lores display else false */
static int nGHiCol; /* TRUE if hi color display else false */
#ifdef WITH_SCORE
/************************************************************************
*
* Function: AllSpritesSetup()
*
* Description: Initialise the global sprite data
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
static int
AllSpritesSetup(void)
{
AllSpritesSetClip(0,0,0,0);
RwGetDeviceInfo(rwRENDERDEPTH,&asGSprites.nDepth,sizeof(asGSprites.nDepth));
return TRUE;
}
/************************************************************************
*
* Function: AllSpritesSetClip()
*
* Description: Set the clip rectangle for sprites
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
static int
AllSpritesSetClip(RwInt32 nX, RwInt32 nY, RwInt32 nW, RwInt32 nH)
{
asGSprites.rClip.x = nX;
asGSprites.rClip.y = nY;
asGSprites.rClip.w = nW;
asGSprites.rClip.h = nH;
return TRUE;
}
/************************************************************************
*
* Function: SpriteMask()
*
* Description: The supplied RwRaster is converted into a
* transparent one by overwriting all pixels of
* the specified color with the transparency value
*
* Parameters: rpSprite - the RwRaster to mask
* nX, nY - identifies the pixel in the RwRaster that
* contains the background color. All pixels in the
* raster that are this color will be made transparent
*
* Return Value: None
*
************************************************************************/
static void
SpriteMask(RwRaster *rpSprite,int nX,int nY)
{
short int *npData;
int nMask;
unsigned char *cpData;
unsigned char cMask;
int nW;
int nH;
int nStride;
if (asGSprites.nDepth==8)
{
/* its an 8 bit raster */
/* Get the background color */
cpData = (unsigned char *)RwGetRasterPixels(rpSprite);
cMask = cpData[(RwGetRasterStride(rpSprite)*nY)+nX];
nStride = (RwGetRasterStride(rpSprite))-
RwGetRasterWidth(rpSprite);
/* And replace it with the transparent color */
for (nH = RwGetRasterHeight(rpSprite); nH>0;nH--)
{
for (nW = RwGetRasterWidth(rpSprite);nW>0;nW--)
{
if ((*cpData)==cMask)
{
/* Its transparant really ! */
(*cpData) = 0x0;
}
cpData++;
}
cpData+=nStride;
}
}
else
{
/* It's a 16 bit raster */
/* Get the background color */
npData = (short int *)RwGetRasterPixels(rpSprite);
nMask = npData[((RwGetRasterStride(rpSprite)>>1)*nY)+nX];
nStride = (RwGetRasterStride(rpSprite)>>1)-
RwGetRasterWidth(rpSprite);
/* And replace it with the transparent color */
for (nH = RwGetRasterHeight(rpSprite); nH>0;nH--)
{
for (nW = RwGetRasterWidth(rpSprite);nW>0;nW--)
{
if ((*npData)==nMask)
{
/* Its transparant really ! */
(*npData) = 0x0;
}
npData++;
}
npData+=nStride;
}
}
}
/************************************************************************
*
* Function: SpriteWriteImage()
*
* Description:
*
* Parameters: cpCamera - the RenderWare camera to write into
* rpSpr - the RwRaster to write
* nIX, nIY - relative position in outpu camera for
* the centre of the sprite
* nX, nY - first sprite pixel to be drawn
* nW, nH - width and height of sprite area to be drawn
*
* Return Value: None
*
************************************************************************/
static void
SpriteWriteImage(RwCamera *cpCamera, RwRaster *rpSpr,
RwInt32 nIX, RwInt32 nIY,
RwInt32 nX, RwInt32 nY, RwInt32 nW, RwInt32 nH)
{
RwRaster *rpRas;
unsigned char *cpData;
unsigned char *cpSource;
unsigned short int *npData;
unsigned short *npSource;
int nCount;
int nSourceStride;
int nDataStride;
/* Get the camera's image buffer */
rpRas = (RwRaster *)RwGetCameraImage(cpCamera);
if (asGSprites.nDepth==8)
{
/* 8 bit transfer */
cpSource = ((unsigned char *)RwGetRasterPixels(rpSpr)) +
(RwGetRasterStride(rpSpr) * nY) + nX;
cpData = ((unsigned char *)RwGetRasterPixels(rpRas)) +
(RwGetRasterStride(rpRas) * nIY) + nIX;
nSourceStride = RwGetRasterStride(rpSpr) - nW;
nDataStride = RwGetRasterStride(rpRas) - nW;
for (;nH>0;nH--)
{
for (nCount=0; nCount < nW; nCount++)
{
if (*cpSource++)
{
(*cpData)=(*cpSource);
}
cpData++;
}
cpSource+=nSourceStride;
cpData+=nDataStride;
}
}
else
{
/* 16 bit transfer */
npSource = (unsigned short int *)
(((unsigned char *)RwGetRasterPixels(rpSpr)) +
(RwGetRasterStride(rpSpr) * nY) + (nX<<1));
npData = (unsigned short int *)
((unsigned char *)RwGetRasterPixels(rpRas))+
(nIY * RwGetRasterStride(rpRas))+ (nIX<<1);
nSourceStride = (RwGetRasterStride(rpSpr)>>1) - nW;
nDataStride = (RwGetRasterStride(rpRas)>>1) - nW;
for (;nH>0;nH--)
{
for (nCount=0; nCount < nW; nCount++)
{
if (*npSource++)
{
(*npData)=(*npSource);
}
npData++;
}
npSource += nSourceStride;
npData += nDataStride;
}
}
}
#endif /* WITH_SCORE */
/************************************************************************
*
* Function: SpriteRender()
*
* Description: Render the sprite at the specified position in
* the image buffer of the supplied camera. The sprite
* will be clipped to the current global clip region.
*
* Parameters: cpCamera - the camera to write the sprite into
* rwSprite - the RwRaster to write.
* nIX, nIY - relative normalized offsets into the camera
* image buffer
*
* Return Value: None
*
************************************************************************/
static void
SpriteRender(RwCamera *cpCamera, RwRaster *rpSprite, RwInt32 nIX, RwInt32 nIY)
{
RwInt32 nW, nH, nX, nY, nSW, nSH;
if (!rpSprite)
{
return;
}
nX = 0;
nY = 0;
nSW= nW = RwGetRasterWidth(rpSprite);
nSH= nH = RwGetRasterHeight(rpSprite);
/* Clip the display region to the clip region */
if ( (nIX > (asGSprites.rClip.x + asGSprites.rClip.w)) ||
((nIX+nSW) < asGSprites.rClip.x) ||
(nIY > (asGSprites.rClip.y + asGSprites.rClip.h)) ||
((nIY+nSH) < asGSprites.rClip.y) )
{
/* Its not on the screen */
return;
}
/* Clip to the region size */
if (nIX < asGSprites.rClip.x)
{
nX = asGSprites.rClip.x - nIX;
nW -= nX;
}
if ((nIX+nSW) > (asGSprites.rClip.x + asGSprites.rClip.w))
{
nW -= ((nIX+nSW) - (asGSprites.rClip.x + asGSprites.rClip.w));
}
if (nIY < asGSprites.rClip.y)
{
nY = asGSprites.rClip.y - nIY;
nH -= nY;
}
if ((nIY+nSH) > (asGSprites.rClip.y + asGSprites.rClip.h))
{
nH -= ((nIY+nSH) - (asGSprites.rClip.y+asGSprites.rClip.h));
}
/* Check if after clipping all is ok */
if ((nW <= 0) || (nH <= 0))
{
/* Nothing to display ! */
return;
}
SpriteWriteImage(cpCamera, rpSprite, nIX+nX, nIY+nY, nX, nY, nW, nH);
}
/************************************************************************
*
* Function: SpriteRenderRelative()
*
* Description: Draws a sprite at a relative normalized position.
* The position specified is where the CENTRE of the
* sprite will be located.
*
* Parameters: cpCam - the camera that the sprite will be rendered into
* rwSprite - the sprite to render
* nX, nY - relative X and Y offsets into camera viewport
* these are normalised so spepcifying (0.5, 0.5)
* for example will draw the sprite in the centre
* of the cameras viewport
*
* Return Value: None
*
************************************************************************/
static void
SpriteRenderRelative(RwCamera *cpCam, RwRaster *rpSprite, RwReal nX, RwReal nY)
{
RwInt32 nW,nH,nCX,nCY;
if (rpSprite)
{
RwGetCameraViewport(cpGCamera,&nCX,&nCY,&nW,&nH);
nCX = REAL2INT(RMul(INT2REAL(nW),nX));
nCY = REAL2INT(RMul(INT2REAL(nH),nY));
nCX -= RwGetRasterWidth(rpSprite) >> 1;
nCY -= RwGetRasterHeight(rpSprite) >> 1;
SpriteRender(cpCam, rpSprite, nCX, nCY);
}
}
/************************************************************************
*
* Function: OsBeginCameraUpdate()
*
* Description: Os specific version of RwBeginCameraUpdate().
* For MS Windows RwBeginCameraUpdate() is passed
* the handle to the window. We use the global
* handle that is setup in the main window handler.
*
* Parameters: Camera - the Camera to pass to RwBeginCameraUpdate()
*
* Return Value: None
*
************************************************************************/
void OsBeginCameraUpdate(RwCamera *Camera)
{
RwBeginCameraUpdate(Camera, NULL);
}
/************************************************************************
*
* Function: OsMaxScreenWidth()
*
* Description: The maximum screen width is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxScreenWidth(void)
{
if (nGLoRes)
{
return ((RwInt32)LORES_SCREEN_WIDTH);
}
else
{
return ((RwInt32)HIRES_SCREEN_WIDTH);
}
}
/************************************************************************
*
* Function: OsMaxScreenHeight()
*
* Description: The maximum screen height is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxScreenHeight(void)
{
if (nGLoRes)
{
return ((RwInt32)LORES_SCREEN_HEIGHT);
}
else
{
return ((RwInt32)HIRES_SCREEN_HEIGHT);
}
}
/************************************************************************
*
* Function: OsMaxCameraWidth()
*
* Description: The maximum camera width is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxCameraWidth(void)
{
if (nGLoRes)
{
return ((RwInt32)LORES_CAMERA_WIDTH);
}
else
{
return ((RwInt32)HIRES_CAMERA_WIDTH);
}
}
/************************************************************************
*
* Function: OsMaxCameraHeight()
*
* Description: The maximum camera height is an OS specific
* feature. This function returns this information to
* the main body of the application
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
RwInt32 OsMaxCameraHeight(void)
{
if (nGLoRes)
{
return ((RwInt32)LORES_CAMERA_HEIGHT);
}
else
{
return ((RwInt32)HIRES_CAMERA_HEIGHT);
}
}
/************************************************************************
*
* Function: OsShowCameraImage()
*
* Description: Os specific version of RwShowCameraImage().
* For DOS the device specific parameter is NULL
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsShowCameraImage()
{
RwShowCameraImage(cpGCamera, NULL);
}
/************************************************************************
*
* Function: OsError()
*
* Description: Os specific error handler. For DOS we just
* call printf
*
* Parameters: fmt - stdarg format string
*
* Return Value: None
*
************************************************************************/
void OsError(char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf (fmt, args);
va_end(args);
printf("\n");
}
/************************************************************************
*
* Function: OsOpen()
*
* Description: Os specific RwOpen(). This function opens
* RenderWare and sets the Shape Path
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
int OsOpen(void)
{
long nError;
RwOpenArgument arg[4];
if (nGHiCol)
{
arg[0].option = rwSCRDEPTH;
arg[0].value = (void *)16;
}
else
{
arg[0].option = rwSCRDEPTH;
arg[0].value = (void *)8;
}
arg[1].option = rwSCRWIDTH;
arg[1].value = (void *)OsMaxScreenWidth();
arg[2].option = rwSCRHEIGHT;
arg[2].value = (void *)OsMaxScreenHeight();
if (!RwOpenExt("DOSMOUSE", &nError, 3, &arg))
{
printf("Unable to access renderware!!\n");
switch (nError)
{
case E_RW_DOS_MODE_UNAVAILABLE:
printf("The installed VESA card is unable to switch to the resolution");
printf(" requested.\n");
printf("Either install a different video adapter or use a ");
printf("supported video mode.");
break;
case E_RW_DOS_NO_VESA_BIOS:
printf("A VESA bios is unavailable on this machine.\n");
printf("Either use a VESA compatible Video Adapter or install a ");
printf("VESA bios emulation TSR.\n");
break;
case E_RW_DOS_INCOMPATIBLE_BIOS:
printf("The VESA bios on this machine is not of high enough version ");
printf("to function\ncorrectly with RenderWare. Use a version 1.0 or");
printf(" higher VESA bios or TSR.\n");
break;
case E_RW_DOS_NO_MOUSE:
printf("No Microsoft compatible mouse driver present.\n");
printf("Install a microsoft compatible mouse driver and try again.\n");
break;
default:
printf("Unknown Error !!!!!!!!!!!!!!!\n");
break;
}
return FALSE;
}
RwSetShapePath("SCRIPTS", rwPRECONCAT);
RwSetShapePath("TEXTURES", rwPRECONCAT);
RwSetShapePath(".", rwPRECONCAT);
return TRUE;
}
/************************************************************************
*
* Function: OsSetCameraViewport()
*
* Description: Os specific RwSetCameraViewport(). For DOS, the
* viewport size is dependant on the screen resolution
* so we have to take account of this before calling
* RwSetCameraViewport
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsSetCameraViewport()
{
if (nGLoRes)
{
RwSetCameraViewport(cpGCamera, 0,0,
OsMaxCameraWidth(), OsMaxCameraHeight());
}
else
{
RwSetCameraViewport(cpGCamera, PANEL_HOLE_XOFFSET, PANEL_HOLE_YOFFSET,
PANEL_HOLE_WIDTH, PANEL_HOLE_HEIGHT);
}
}
/************************************************************************
*
* Function: OsInit()
*
* Description: Os specific application initialisation. This function
* is called once the palette has been set up and
* performs all of the device specific initialisation
* and object loading
*
* Parameters: None
*
* Return Value: TRUE if successful else FALSE
*
************************************************************************/
int OsInit()
{
#ifdef WITH_SCORE
RwRect rViewport;
#endif
RwRaster *rpTitle;
RwPointerImage piImage;
RwReal naWhite[3]={CREAL(1),CREAL(1),CREAL(1)};
RwReal naBlack[3]={CREAL(0),CREAL(0),CREAL(0)};
/* Rematch the pointer image */
piImage.image = NULL;
piImage.hotx=0;
piImage.hoty=0;
piImage.w = RwDeviceControl(rwSCRGETCOLOR,0,naBlack,sizeof(naBlack));
piImage.h = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
RwDeviceControl(rwPOINTERSETIMAGE,0,&piImage,sizeof(piImage));
/* Do the loading screen */
if (!(rpTitle = RwReadRaster("title.bmp", 0)))
{
return FALSE;
}
RwSetCameraBackdrop(cpGCamera, rpTitle);
RwSetCameraBackdropOffset(cpGCamera, 0,0);
RwSetCameraBackdropViewportRect(cpGCamera, 0,0,
RwGetRasterWidth(rpTitle),
RwGetRasterHeight(rpTitle));
/* Put the title in the centre of the screen */
RwSetCameraViewport(cpGCamera,
(OsMaxScreenWidth() - RwGetRasterWidth(rpTitle))/2,
(OsMaxScreenHeight() - RwGetRasterHeight(rpTitle))/2,
RwGetRasterWidth(rpTitle), RwGetRasterHeight(rpTitle));
OsBeginCameraUpdate(cpGCamera);
RwClearCameraViewport(cpGCamera);
RwEndCameraUpdate(cpGCamera);
OsShowCameraImage();
RwDestroyRaster(rpTitle);
OsSetCameraViewport();
#ifdef WITH_SCORE
/* Set up the sprites */
if (!(AllSpritesSetup()))
{
return FALSE;
}
/* Set up sprite structure */
RwGetCameraViewport(cpGCamera,
&rViewport.x,&rViewport.y,&rViewport.w,&rViewport.h);
AllSpritesSetClip(0,0,rViewport.w,rViewport.h);
#endif
rpGPanel = NULL;
if (!nGLoRes)
{
if (!(rpGPanel = RwReadRaster("panel", 0L)))
{
return FALSE;
}
}
#ifdef WITH_SCORE
if (!ScoreSetup())
{
return(FALSE);
}
#endif
return TRUE;
}
/************************************************************************
*
* Function: OsTidy()
*
* Description: Clean up all of the stuff initialised in OsInit()
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
void OsTidy(void)
{
#ifdef WITH_SCORE
ScoreDestroy();
#endif
if (!nGLoRes)
{
RwDestroyRaster(rpGPanel);
}
}
#ifdef WITH_SCORE
/************************************************************************
*
* Function: SpriteSetup()
*
* Description: Setup a single sprite
*
* Parameters: name - the name of the raster file to load
* x,y the offset into the raster to obtain the mask color
*
* Return Value: None
*
************************************************************************/
static RwRaster *SpriteSetup(char *name, int x, int y)
{
RwRaster *raster = RwReadRaster(name, 0L);
if (raster)
{
SpriteMask(raster, x, y);
}
return(raster);
}
/************************************************************************
*
* Function: ScoreSetup()
*
* Description: Initialise the score data structures
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
static int ScoreSetup(void)
{
if (!(sGScore.cpRat = DoRwReadShape("ratsimpl.rwx")))
{
return FALSE;
}
/* Load in the sprite images */
if (!(sGScore.spaLeftImages[0] = SpriteSetup("ratface4.bmp", 0, 0)) ||
!(sGScore.spaLeftImages[1] = SpriteSetup("ratface3.bmp", 0, 0)) ||
!(sGScore.spaLeftImages[2] = SpriteSetup("ratface2.bmp", 0, 0)) ||
!(sGScore.spaLeftImages[3] = SpriteSetup("ratface1.bmp", 0, 0)))
{
return FALSE;
}
if (!(sGScore.spTimesOne = SpriteSetup("t1.bmp", 2, 2)) ||
!(sGScore.spTimesFive = SpriteSetup("t5.bmp", 2, 2)) ||
!(sGScore.spTimesTwentyFive = SpriteSetup("t25.bmp", 2, 2)) )
{
return FALSE;
}
/* Screen position */
if (!(sGScore.mpPos = RwCreateMatrix()))
{
return FALSE;
}
RwIdentityMatrix(sGScore.mpPos);
if (!(sGScore.mpRot = RwCreateMatrix()))
{
return FALSE;
}
RwIdentityMatrix(sGScore.mpRot);
if (!(sGScore.mpOffset = RwCreateMatrix()))
{
return FALSE;
}
RwIdentityMatrix(sGScore.mpOffset);
RwRotateMatrix(sGScore.mpRot,
CREAL(0.01), CREAL(1), CREAL(0.1), CREAL(6), rwREPLACE);
RwRotateMatrix(sGScore.mpOffset,
CREAL(0.1), CREAL(-0.5), CREAL(2), CREAL(100), rwREPLACE);
return TRUE;
}
/************************************************************************
*
* Function: OsDisplayScore()
*
* Description: Overlay the score on top of the rendered image
*
* Parameters: dead - number of dead rats
* left - number of rats remaining
*
* Return Value: None
*
************************************************************************/
void OsDisplayScore(int dead, int left)
{
int nCount;
int nRats;
int nAmo;
int nTmp;
RwV3d vPos;
RwV3d vAt;
RwV3d vUp;
RwV3d vRight;
RwV3d vTmp;
RwV3d vLeft;
RwReal naPos[4][4];
int nImage;
RwMatrix4d *mpTmp;
RwTransformMatrix(sGScore.mpPos, sGScore.mpRot, rwPOSTCONCAT);
RwOrthoNormalizeMatrix(sGScore.mpPos, sGScore.mpPos);
mpTmp = RwScratchMatrix();
RwPushScratchMatrix();
RwIdentityMatrix(mpTmp);
RwGetCameraPosition(cpGCamera,&vPos);
RwGetCameraLookAt(cpGCamera, &vAt);
(*((RwV3d *)&naPos[2][0])) = vAt;
RwScaleVector(&vAt, SCORE_FORWARD, &vAt);
RwAddVector(&vPos,&vAt,&vPos);
RwGetCameraLookUp(cpGCamera, &vUp);
(*((RwV3d *)&naPos[1][0])) = vUp;
RwScaleVector(&vUp, SCORE_STARTY, &vTmp);
RwAddVector(&vPos,&vTmp,&vPos);
RwScaleVector(&vUp, SCORE_UP, &vUp);
vLeft = vPos;
RwGetCameraLookRight(cpGCamera, &vRight);
(*((RwV3d *)&naPos[0][0])) = vRight;
RwScaleVector(&vRight, SCORE_STARTX, &vTmp);
RwAddVector(&vPos,&vTmp,&vPos);
RwScaleVector(&vRight, SCORE_RIGHT, &vRight);
/* vPos points to the start position */
nRats = dead;
nCount = 0;
(*((RwV3d *)&naPos[3][0])) = vPos;
RwSetMatrixElements(RwScratchMatrix(),naPos);
while (nCount<3)
{
RwCopyMatrix(RwScratchMatrix(), mpTmp);
RwTransformMatrix(mpTmp, sGScore.mpPos, rwPRECONCAT);
nAmo = nRats%5;
nRats = nRats/5;
for (nTmp=0; nTmp < nAmo; nTmp++)
{
/* Draw a rat */
RwTransformClump(sGScore.cpRat, mpTmp, rwREPLACE);
RwRenderClump(sGScore.cpRat);
RwTranslateMatrix(mpTmp, -vUp.x, -vUp.y, -vUp.z,rwPOSTCONCAT);
RwTransformMatrix(mpTmp, sGScore.mpOffset, rwPRECONCAT);
}
nCount++;
/* Move one to the right */
RwTranslateMatrix(RwScratchMatrix(),
-vRight.x,-vRight.y,-vRight.z,rwPOSTCONCAT);
}
RwPopScratchMatrix();
/* Display the amount left */
nImage = (left * (NUM_LEFT_IMAGES-1))/RAT_MAXIMUM;
SpriteRenderRelative(cpGCamera,sGScore.spaLeftImages[nImage],CREAL(0.08),CREAL(0.08));
SpriteRenderRelative(cpGCamera,sGScore.spTimesOne,CREAL(0.9),CREAL(0.052));
SpriteRenderRelative(cpGCamera,sGScore.spTimesFive,CREAL(0.8),CREAL(0.052));
SpriteRenderRelative(cpGCamera,sGScore.spTimesTwentyFive,CREAL(0.7),CREAL(0.052));
}
/************************************************************************
*
* Function: ScoreDestroy()
*
* Description: Destroy the score data structures
*
* Parameters: None
*
* Return Value: None
*
************************************************************************/
static void ScoreDestroy(void)
{
RwDestroyClump(sGScore.cpRat);
RwDestroyMatrix(sGScore.mpPos);
RwDestroyMatrix(sGScore.mpRot);
RwDestroyMatrix(sGScore.mpOffset);
RwDestroyRaster(sGScore.spaLeftImages[0]);
RwDestroyRaster(sGScore.spaLeftImages[1]);
RwDestroyRaster(sGScore.spaLeftImages[2]);
RwDestroyRaster(sGScore.spaLeftImages[3]);
RwDestroyRaster(sGScore.spTimesOne);
RwDestroyRaster(sGScore.spTimesFive);
RwDestroyRaster(sGScore.spTimesTwentyFive);
}
#endif
/************************************************************************
*
* Function: DosGetKey()
*
* Description: Get the ascii key code of any depressed key.
*
* Parameters: None
*
* Return Value: 0 if no key pressed else ASCII value for key pressed
*
************************************************************************/
static int DosGetKey(void)
{
union REGPACK rp;
memset(&rp,0,sizeof(rp));
rp.h.ah = 0x06;
rp.h.dl = 0xff;
intr(0x21,&rp);
if (!(rp.w.flags & 0x40 )) { /* Check Z flag */
/* Got key */
if (rp.h.al) {
return ((int)rp.h.al);
};
memset(&rp,0,sizeof(rp));
rp.h.ah = 0x06;
rp.h.dl = 0xff;
intr(0x21,&rp);
if (!(rp.w.flags & 0x40)) {
return ((int)rp.h.al);
};
return (rp.h.al|0x80);
};
return 0;
}
/************************************************************************
*
* Function: DosShiftCtrl()
*
* Description: Get the status of the Shift Control keys.
*
* Parameters: None
*
* Return Value: Bit field indicating the key status
* Bit Meaning
* 0 Right Shift
* 1 Left Shift
* 2 Ctrl
* 3 Alt
* 4 Scroll Lock
* 5 Num Lock
* 6 Caps Lock
* 7 Insert on
*
************************************************************************/
static int
DosShiftCtrl(void)
{
union REGPACK rp;
memset(&rp,0,sizeof(rp));
rp.h.ah=0x02;
intr(0x16,&rp);
return ((int)rp.h.al);
}
/************************************************************************
*
* Function: ReadFromCommandLine()
*
* Description: Parse the arguments passed to the program. For this
* program the valid arguments are -hires for a high
* resolution display and -hicol for 16 bit color
*
* Parameters: argc, argv - standard C program arguments
*
* Return Value: None
*
************************************************************************/
static void ReadFromCommandLine(int argc, char *argv[])
{
int i;
nGLoRes = 1;
nGHiCol = 0;
for (i=1; i<argc; i++)
{
if (!strcmp(argv[i],"-hires"))
nGLoRes = 0;
if (!strcmp(argv[i],"-hicol"))
nGHiCol = 1;
}
}
/************************************************************************
*
* Function: main()
*
* Description: Main entry point, All of the top level control
* flow is handle directly here.
*
* Parameters: argc, argv - standard C parameters
*
* Return Value: None
*
************************************************************************/
void
main(int nArgc,char *saArgv[])
{
int nMouseX,nMouseY;
int nKey;
int nMouseBut, nOldMouseBut, nOldMouseX, nOldMouseY;
int nDX,nDY;
int nChange;
int nCtrlShift;
RwErrorCode eCode;
/* Initialise the Random Number Seed */
RwSRandom(time(0));
ReadFromCommandLine(nArgc, saArgv);
if (!Init3D())
{
eCode = RwGetError();
switch(eCode)
{
case E_RW_BADOPEN:
OsError("E_RW_BADOPEN");
break;
case E_RW_INTERNAL:
OsError("E_RW_INTERNAL: Contact RenderWare Support");
break;
}
exit(-1);
}
/* Load all of the sound effects */
#ifdef WITH_SOUND
AllSoundsAddSound("gun.sb",0x1f,150,0);
AllSoundsAddSound("ricochet.sb",0x2f,200,1);
AllSoundsAddSound("squish.sb",0x3f,400,2);
AllSoundsAddSound("squeak.sb",0x3f,200,2);
AllSoundsAddSound("ratty.sb",0x3f,50,2);
AllSoundsAddSound("boink.sb",0x3f,300,3);
AllSoundsAddSound("ratty2.sb",0x3f,50,2);
AllSoundsAddSound("clang.sb",0x3f,400,2);
#endif
/* paint display for the first time */
if (!nGLoRes)
{
HandlePaint();
}
RwDPointerDisplay(&nOldMouseX,&nOldMouseY,&nOldMouseBut);
nKey = DosGetKey();
while (nKey!=27)
{
/* ESC quits */
RwDPointerDisplay(&nMouseX,&nMouseY,&nMouseBut);
nKey = DosGetKey();
if ((nKey == 'g')||(nKey=='G'))
{
GunToggle();
}
if ((nKey == 'f')||(nKey=='F'))
{
ToggleFlyCamera();
}
nCtrlShift = DosShiftCtrl();
nDX =(nMouseX-nOldMouseX);
nDY =(nMouseY-nOldMouseY);
nChange = (nMouseBut&(2+8)) | ( (nOldMouseBut&(2+8)) >>1 );
switch (nChange)
{
case 0+0:
case 2+1:
case 8+4:
case 8+2+4+1:
break;
case 2:
case 8+2+4:
/* Left Button Down */
HandleLeftButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
break;
case 8:
case 8+2+1:
/* Right Button Down */
HandleRightButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
break;
case 8+1:
/* Right down left Up */
HandleLeftButtonUp();
HandleRightButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
break;
case 2+4:
/* Right up left Down */
HandleRightButtonUp();
HandleLeftButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
break;
case 8+2:
/* Left down RIght Down */
HandleRightButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
HandleLeftButtonDown(nMouseX, nMouseY,
nCtrlShift & KEY_CONTROL,
nCtrlShift & (KEY_RSHIFT|KEY_LSHIFT));
break;
case 1+4:
/* Left up Right Up */
HandleRightButtonUp();
HandleLeftButtonUp();
break;
case 1:
case 8+4+1:
/* Left up */
HandleLeftButtonUp();
break;
case 4:
case 2+4+1:
/* Right up */
HandleRightButtonUp();
break;
}
if (nDX||nDY)
{
/* Mouse Move */
HandleMouseMove(nMouseX,nMouseY);
}
HandleTimer();
nOldMouseX = nMouseX;
nOldMouseY = nMouseY;
nOldMouseBut = nMouseBut;
}
/*
* Tidy up the 3D (RenderWare) components of the application.
*/
TidyUp3D();
exit(0);
}