home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * File : dossim.c
- *
- * Abstract : A very simple, sample RenderWare application for
- * MS-Dos/PC Dos. This application has very little
- * functionality, but is simply intended as a demonstration
- * of how to use the RenderWare API.
- *
- * This application had been written to be compatible with
- * both the fixed and floating-point versions of the
- * RenderWare library, i.e., it uses the macros CREAL,
- * INT2REAL, RAdd, RDiv, RSub etc. If your application is
- * intended for the floating-point version of the library
- * only these macros are not necessary.
- *
- * Please note that this application is intended for
- * demonstration purposes only. No support will be
- * provided for this code and it comes with no warranty.
- *
- * 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. and Canon Inc. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1991, 1992, 1993. Canon Inc.
- * All Rights Reserved.
- *
- **********************************************************************/
-
- /**********************************************************************
- *
- * Header files.
- *
- **********************************************************************/
-
- #include <stdlib.h>
- #include <i86.h>
- #include <string.h>
- #include <stdio.h>
- #include <math.h> /* Required for floating point */
-
- #include "rwlib.h"
- #include "rwtypes.h"
-
- #include "rwdos.h"
- #include "doswrap.h"
-
- /****************************************************************************
- Defines
- */
-
- /* Key code for delete key */
-
- #define DELETE 8
- #define BOOL int
-
- /*
- * MS Windows compatible defines
- */
-
- #define MK_CONTROL 0x4
- #define MK_SHIFT 0x2
-
- /*
- * Motion parameters
- */
-
- #define DAMPING CREAL(0.95)
- #define MAXTHINGS 25
-
- /****************************************************************************
- Types
- */
-
- typedef struct
- {
- RwClump *geometry;
- int canmove;
- RwReal size;
- RwV3d pos,vel;
- RwMatrix4d *tumble,*rot,*antirot;
- RwReal rotangle, antiangle;
- RwV3d axis;
- int damprot;
- } Thing;
-
- /****************************************************************************
- Globals
- */
-
- static Thing things[MAXTHINGS];
- static int follow,numthings;
-
- static RwScene *Scene;
- static RwCamera *Camera;
- static RwLight *Light;
-
- static ThreeDInitialized = FALSE;
-
- static unsigned long frames = 0;
-
- static int bButtonDown = 0;
-
- static char sGClear[]=" ";
-
- /*
- * Global variables used to remember the last mouse X and Y coordinates
- * when involved in a pan, zoom, drag or spin.
- */
- static int LastX;
- static int LastY;
-
-
- /*
- Screen size
- */
-
- static int nGScrWidth;
- static int nGScrHeight;
-
- /*
- Colour Codes
- */
-
- static int nGTextCol;
-
- /****************************************************************************
- DosPrintString
-
- On entry : xcord
- : ycord
- : string
- : colour
- On exit :
- */
-
- void DosPrintString(int nX,int nY,char *sString,int nCol)
- {
- RwPrintChar pcPrint;
-
- pcPrint.x = nX;
- pcPrint.y = nY;
- pcPrint.color = nCol;
-
- for (;(*sString);sString++) {
- pcPrint.c = (*sString);
- RwDeviceControl(rwPRINTCHAR,0,&pcPrint,sizeof(pcPrint));
- pcPrint.x+=8;
- };
- }
-
-
- /****************************************************************************
- DosTimer
-
- On entry :
- On exit : Timer (in milliseconds)
- */
-
- int DosTimer(void)
- {
- union REGS r;
- int nTime;
-
- r.h.ah=0;
-
- int386(0x1a,&r,&r);
-
- nTime = ((r.w.cx)<<16)|(r.w.dx);
-
- return (nTime*55);
- }
-
- /****************************************************************************
- DosGetKey
-
- On entry :
- On exit : Key pressed in ascii (or 0 if no key pressed)
- */
-
- 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;
- }
-
- /****************************************************************************
- DosShiftCtrl
-
- On entry :
- On exit : Bit Meaning
- 0 Right Shift
- 1 Left Shift
- 2 Ctrl
- 3 Alt
- 4 Scroll Lock
- 5 Num Lock
- 6 Caps Lock
- 7 Insert on
- */
-
- int DosShiftCtrl(void)
- {
- union REGPACK rp;
-
- memset(&rp,0,sizeof(rp));
-
- rp.h.ah=0x02;
- intr(0x16,&rp);
-
- return ((int)rp.h.al);
- }
-
-
- /*********************************************************************/
- static void randomvec(RwV3d *vec)
- {
- vec->x = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
- vec->y = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
- vec->z = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
- }
-
- /*********************************************************************/
- static void assignvec(RwV3d *vec,RwReal x,RwReal y,RwReal z)
- {
- vec->x = x;
- vec->y = y;
- vec->z = z;
- }
-
- /*********************************************************************/
- static void makezippy(RwPolygon3d *p)
- {
- static int zippy = 0;
-
- switch (zippy % 7)
- {
- case 0: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.0)); break;
- case 1: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.0)); break;
- case 2: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.0), CREAL(0.7)); break;
- case 3: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.0)); break;
- case 4: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.7)); break;
- case 5: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.7)); break;
- case 6: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.7)); break;
- }
- zippy++;
- }
-
- /*********************************************************************/
- static void makethings(RwScene *scene,Thing *things, int num)
- {
- RwClump *clump,*prototypes[4];
- RwV3d p;
- int i,which;
-
- srand(0);
-
- for (i=0; i<4; i++)
- {
- RwClumpBegin();
- RwSetSurface(CREAL(0.4), CREAL(0.7), CREAL(0.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
- switch(i)
- {
- case 0:
- RwTranslateCTM(CREAL(0.0), CREAL(-0.15/2), CREAL(0.0));
- RwCone(CREAL(0.15), CREAL(0.1), 12);
- RwRotateCTM(CREAL(1.0), CREAL(0.0), CREAL(0.0), CREAL(180.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
- RwDisc(CREAL(0.0), CREAL(0.1), 12);
- break;
- case 1:
- RwSphere(CREAL(0.1),3);
- break;
- case 2:
- RwTranslateCTM(CREAL(0.0), CREAL(-0.15/2), CREAL(0.0));
- RwCylinder(CREAL(0.15), CREAL(0.1), CREAL(0.1), 12);
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
- RwDisc(CREAL(0.15), CREAL(0.1), 12);
- RwRotateCTM(CREAL(1.0), CREAL(0.0), CREAL(0.0), CREAL(180.0));
- RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
- RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
- RwDisc(CREAL(0.0), CREAL(0.1), 12);
- break;
- default:
- RwBlock(CREAL(0.1), CREAL(0.2), CREAL(0.15));
- break;
- }
- RwClumpEnd(&prototypes[i]);
- }
-
- for (i=0; i<num ; i++)
- {
- which = rand() % 4;
- clump = RwDuplicateClump(prototypes[which]);
- if ((rand() & 7) < 2)
- RwForAllPolygonsInClump(clump, makezippy);
- RwAddClumpToScene(scene, clump);
- things[i].geometry = clump;
- things[i].size = CREAL(0.1);
- RwIdentityMatrix(things[i].tumble = RwCreateMatrix());
- RwIdentityMatrix(things[i].rot = RwCreateMatrix());
-
- things[i].damprot = 0;
- randomvec(&p);
- things[i].pos.x = RMul(p.x, RSub(CREAL(1.0), things[i].size));
- things[i].pos.y = RMul(p.y, RSub(CREAL(1.0), things[i].size));
- things[i].pos.z = RMul(p.z, RSub(CREAL(1.0), things[i].size));
- things[i].canmove = 7;
- assignvec(&things[i].vel, CREAL(0.0),CREAL(0.0),CREAL(0.0));
- }
- for (i=0; i<4; i++)
- RwDestroyClump(prototypes[i]);
- }
-
- /*********************************************************************/
- static twobody(Thing *things, int i, int j)
- {
- RwReal length,adjust,doti,dotj,speedi,speedj;
- RwV3d hit,axis,xferi,xferj;
- RwV3d veli,velj;
-
- hit.x = RSub(things[j].pos.x, things[i].pos.x);
- hit.y = RSub(things[j].pos.y, things[i].pos.y);
- hit.z = RSub(things[j].pos.z, things[i].pos.z);
- length = RAdd(RAdd(RMul(hit.x, hit.x), RMul(hit.y, hit.y)),
- RMul(hit.z, hit.z));
-
- if ((length > CREAL(0.0)) && (length < CREAL(0.2*0.2)))
- {
- length = RSqrt(length);
-
- hit.x = RDiv(hit.x, length);
- hit.y = RDiv(hit.y, length);
- hit.z = RDiv(hit.z, length);
- adjust = RDiv(RSub(CREAL(0.2), length), CREAL(2.0));
-
- veli = things[i].vel;
- speedi = RAdd(RAdd(RMul(veli.x, veli.x), RMul(veli.y, veli.y)),
- RMul(veli.z, veli.z));
-
- if (speedi > CREAL(0.0)) {
- speedi = RSqrt(speedi);
- veli.x = RDiv(veli.x, speedi);
- veli.y = RDiv(veli.y, speedi);
- veli.z = RDiv(veli.z, speedi);
-
- doti = RwDotProduct(&hit, &veli);
-
- if (doti > CREAL(0.0)) {
- speedi = RMul(speedi, RMul(doti, DAMPING));
-
- xferi.x = RMul(hit.x, speedi);
- xferi.y = RMul(hit.y, speedi);
- xferi.z = RMul(hit.z, speedi);
- RwCrossProduct(&veli, &hit, &axis);
-
- things[i].rotangle = RMul(speedi,
- RMul(RSub(CREAL(1.0),doti),CREAL(720.0)));
-
-
- things[i].axis.x = axis.x;
- things[i].axis.y = axis.y;
- things[i].axis.z = axis.z;
-
-
- things[i].antiangle = RMul(speedi, RMul(RSub(CREAL(1.0),doti),CREAL(-4.0)));
- things[i].damprot = (int)(720.0 / 4.0);
- } else {
- xferi.x = xferi.y = xferi.z = CREAL(0.0);
- };
- } else {
- xferi.x = xferi.y = xferi.z = CREAL(0.0);
- };
-
- if (things[i].canmove & 1) {
- things[i].pos.x = RSub(things[i].pos.x,RMul(hit.x, adjust));
- };
- if (!things[j].canmove & 1) {
- things[i].pos.x = RSub(things[i].pos.x,RMul(hit.x, adjust));
- };
-
- if (things[i].canmove & 2) {
- things[i].pos.y = RSub(things[i].pos.y,RMul(hit.y, adjust));
- };
- if (!things[j].canmove & 2) {
- things[i].pos.y = RSub(things[i].pos.y,RMul(hit.y, adjust));
- };
-
- if (things[i].canmove & 4) {
- things[i].pos.z = RSub(things[i].pos.z,RMul(hit.z, adjust));
- };
- if (!things[j].canmove & 4) {
- things[i].pos.z = RSub(things[i].pos.z,RMul(hit.z, adjust));
- };
-
- /*
- hit.x = -hit.x;
- hit.y = -hit.y;
- hit.z = -hit.z;
- */
-
- hit.x = CREAL(0.0);
- hit.y = CREAL(0.0);
- hit.z = CREAL(0.0);
-
- velj = things[j].vel;
- speedj = RAdd(RAdd(RMul(velj.x, velj.x), RMul(velj.y, velj.y)),
- RMul(velj.z, velj.z));
- if (speedj > CREAL(0.0)) {
- speedj = RSqrt(speedj);
- velj.x = RDiv(velj.x, speedj);
- velj.y = RDiv(velj.y, speedj);
- velj.z = RDiv(velj.z, speedj);
- dotj = RwDotProduct(&hit, &velj);
- if (dotj > CREAL(0.0)) {
- speedj = RMul(speedj, RMul(dotj, DAMPING));
- xferj.x = RMul(hit.x, speedj);
- xferj.y = RMul(hit.y, speedj);
- xferj.z = RMul(hit.z, speedj);
- RwCrossProduct(&velj, &hit, &axis);
-
- things[j].rotangle = RMul(speedj, RMul(RSub(CREAL(1.0),dotj),CREAL(720.0)));
-
- things[j].axis.x = axis.x;
- things[j].axis.y = axis.y;
- things[j].axis.z = axis.z;
-
- things[j].antiangle = RMul(speedj, RMul(RSub(CREAL(1.0),dotj),CREAL(-4.0)));
- things[j].damprot=(int)(720.0 / 4.0);
- } else {
- xferj.x = xferj.y = xferj.z = CREAL(0.0);
- };
- } else {
- xferj.x = xferj.y = xferj.z = CREAL(0.0);
- };
-
- if (things[j].canmove & 1) {
- things[j].pos.x = RSub(things[j].pos.x,RMul(hit.x, adjust));
- };
-
- if (!things[i].canmove & 1) {
- things[j].pos.x = RSub(things[j].pos.x,RMul(hit.x, adjust));
- };
-
- if (things[j].canmove & 2) {
- things[j].pos.y = RSub(things[j].pos.y,RMul(hit.y, adjust));
- };
- if (!things[i].canmove & 2) {
- things[j].pos.y = RSub(things[j].pos.y,RMul(hit.y, adjust));
- };
-
- if (things[j].canmove & 4) {
- things[j].pos.z = RSub(things[j].pos.z,RMul(hit.z, adjust));
- };
- if (!things[i].canmove & 4) {
- things[j].pos.z = RSub(things[j].pos.z,RMul(hit.z, adjust));
- };
-
- things[i].vel.x = RAdd(things[i].vel.x,RSub(xferj.x, xferi.x));
- things[i].vel.y = RAdd(things[i].vel.y,RSub(xferj.y, xferi.y));
- things[i].vel.z = RAdd(things[i].vel.z,RSub(xferj.z, xferi.z));
-
- things[j].vel.x = RAdd(things[i].vel.x,RSub(xferi.x, xferj.x));
- things[j].vel.y = RAdd(things[i].vel.y,RSub(xferi.y, xferj.y));
- things[j].vel.z = RAdd(things[i].vel.z,RSub(xferi.z, xferj.z));
-
- return(1);
- }
- return(0);
- }
-
- /*********************************************************************/
- collisions(Thing *things, int num)
- {
- int i,j;
-
- for (i=0; i<num; i++)
- {
- for (j=i+1; j<num; j++)
- {
- if (twobody(things,i,j)) break;
- }
- }
- }
-
- /*********************************************************************/
- static void gravitatethings(Thing *things, int num, RwV3d *acc)
- {
- int i;
- RwV3d p;
- RwReal val;
- RwReal limit;
-
- RwPushScratchMatrix();
- limit = CREAL(1.0 - 0.1);
- for (i=0; i<num; i++)
- {
- if (things[i].damprot > 0)
- {
- /* Below is the original version of the damping code. This accumulates
- a new .rot matrix by repeated multiplication with .antirot. This
- causes the .rot matrix to drift causing shearing of the object.
- RwMultiplyMatrix(things[i].rot, things[i].antirot, RwScratchMatrix());
- RwCopyMatrix(RwScratchMatrix(), things[i].rot);
- */
- RwRotateMatrix(things[i].rot, things[i].axis.x, things[i].axis.y,
- things[i].axis.z,
- RSub(things[i].rotangle, things[i].antiangle), rwREPLACE);
- things[i].damprot--;
- }
- RwMultiplyMatrix(things[i].tumble, things[i].rot, RwScratchMatrix());
- if ((frames)%(num<<3) ==(i<<3))
- RwOrthoNormalizeMatrix(RwScratchMatrix(), RwScratchMatrix());
- RwCopyMatrix(RwScratchMatrix(), things[i].tumble);
- p = things[i].pos;
- RwTranslateMatrix(RwScratchMatrix(), p.x,p.y,p.z, rwPOSTCONCAT);
- RwTransformClump(things[i].geometry, RwScratchMatrix(), rwREPLACE);
-
- things[i].canmove = 0;
- /* += */
- things[i].vel.x = RAdd(things[i].vel.x,acc->x);
- /* things[i].vel.x += acc->x; */
- val = things[i].pos.x = RAdd(things[i].pos.x,things[i].vel.x);
- /* val = things[i].pos.x += things[i].vel.x; */
- if (val < - limit || val > limit)
- {
- things[i].vel.x = RSub(things[i].vel.x,acc->x);
- /* things[i].vel.x -= acc->x; */
- things[i].vel.x = RMul(-things[i].vel.x, DAMPING);
- things[i].pos.x = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 1;
-
- /* things[i].vel.y += acc->y; */
- things[i].vel.y = RAdd(things[i].vel.y,acc->y);
- /* val = things[i].pos.y += things[i].vel.y; */
- val = things[i].pos.y = RAdd(things[i].pos.y,things[i].vel.y);
-
- if (val < -limit || val > limit)
- {
- /* things[i].vel.y -= acc->y; */
- things[i].vel.y = RSub(things[i].vel.y,acc->y);
- things[i].vel.y = RMul(-things[i].vel.y, DAMPING);
- things[i].pos.y = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 2;
-
- /* things[i].vel.z += acc->z; */
- things[i].vel.z = RAdd(things[i].vel.z,acc->z);
- /* val = things[i].pos.z += things[i].vel.z; */
- val = things[i].pos.z = RAdd(things[i].pos.z,things[i].vel.z);
- if (val < -limit || val > limit)
- {
- things[i].vel.z -= acc->z;
- things[i].vel.z = RMul(-things[i].vel.z, DAMPING);
- things[i].pos.z = val < CREAL(0.0) ? -limit : limit;
- }
- else
- things[i].canmove |= 4;
- }
- RwPopScratchMatrix();
- frames++;
- }
-
- /***************************************************************************/
- /*
- * This function initializes the 3D (i.e. RenderWare) components of the
- * application. This function opens the RenderWare library, creates a
- * camera, a scene, a light and a matrix for spinning. A user-draw may
- * also be created if USERDRAW_LABELS is defined.
- */
-
- static BOOL
- Init3D(char *sFilename)
- {
- int i,j;
- int fixed, debugging;
- char *title;
- RwClump *temp;
- RwReal naTextCol[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
- char version[30];
- char buffer[128];
- int param;
- long nError;
-
- if (!RwOpen("DOSMOUSE", &nError))
- {
- 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 <%i> !!!!!!!!!!!!!!!\n",nError);
- break;
- };
- };
- return FALSE;
- }
-
- /* Set up the DOS Character Set */
-
- RwGetDeviceInfo(rwSCRHEIGHT,&nGScrHeight,sizeof(nGScrHeight));
- RwGetDeviceInfo(rwSCRWIDTH,&nGScrWidth,sizeof(nGScrWidth));
-
- nGTextCol = RwDeviceControl(rwSCRGETCOLOR,0,naTextCol,sizeof(naTextCol));
-
- RwSetShapePath(".",rwPRECONCAT);
-
- strcpy(buffer,sFilename);
-
- i = strlen(buffer);
- while((buffer[i] != '\\')&&(i>=0)) {
- i--;
- };
-
-
- if (i>=0) {
- buffer[i+1] = 0;
- strcat(buffer, "TEXTURES");
- RwSetShapePath(buffer, rwPOSTCONCAT);
-
- buffer[i+1] = 0;
- strcat(buffer, "SCRIPTS");
- RwSetShapePath(buffer, rwPOSTCONCAT);
- };
-
- RwSetShapePath("SCRIPTS", rwPRECONCAT);
- RwSetShapePath("TEXTURES", rwPRECONCAT);
-
- /*
- * Label the window with information about the version of
- * RenderWare being used. Its rather unlikely that
- * RwGetSystemInfo() will fail so we ignore its return value.
- */
-
- RwGetSystemInfo(rwVERSIONSTRING, &version,sizeof(version));
- RwGetSystemInfo(rwFIXEDPOINTLIB, ¶m,sizeof(param));
- sprintf(buffer, "RenderSim(tm) V%s %s",
- version, (param ? "Fixed" : "Float"));
- DosPrintString(0,nGScrHeight-16,buffer,nGTextCol);
-
- RwGetSystemInfo(rwFIXEDPOINTLIB, &fixed,sizeof(fixed));
- RwGetSystemInfo(rwDEBUGGINGLIB, &debugging,sizeof(debugging));
- if ((fixed) && (debugging))
- title = "n-Body (Fixed & Debugging)";
- else if (fixed)
- title = "n-Body (Fixed Point)";
- else if (debugging)
- title = "n-Body (Debugging)";
- else
- title = "n-Body (Floating Point)";
-
- /* Temporary message !!*/
-
- DosPrintString(0,nGScrHeight-24,title,nGTextCol);
-
- /*
- * Create the camera which will be used for rendering. The initial window
- * size the application will create is given by nGScrWidth and
- * nGScrHeight-17 which depends on the screen res used.
- */
-
- Camera = RwCreateCamera(nGScrWidth,nGScrHeight-17, NULL);
- if (!Camera)
- {
- /*
- * As with RwOpen(), the most common cause for a failure to create
- * a camera is insufficient memory so we will explicitly check for
- * this condition and report it. Otherwise a general error is issued.
- */
- if (RwGetError() == E_RW_NOMEM)
- {
- RwClose();
- printf("Insufficient memory to create the RenderWare(tm) camera\n");
- }
- else
- {
- RwClose();
- printf("Error creating the RenderWare(tm) camera\n");
- }
- exit(-1);
- }
-
-
- /*
- * The window has been resized. Therefore, it is necessary to
- * to modify the camera's viewport to be the same size as the
- * client area of the window.
- */
- RwSetCameraViewport(Camera, 0, 0, nGScrWidth, nGScrHeight-24);
-
- RwSetCameraBackdropViewportRect(Camera, 0,0,nGScrWidth,nGScrHeight-24);
-
- /* aspect ratio of 1:1 */
-
- if (nGScrWidth >= (nGScrHeight-24)) {
- RwSetCameraViewwindow(Camera,
- CREAL(1.0),
- RMul(CREAL(1.0), RDiv(INT2REAL(nGScrHeight-24), INT2REAL(nGScrWidth))));
- } else {
- RwSetCameraViewwindow(Camera,
- RMul(CREAL(1.0), RDiv(INT2REAL(nGScrWidth), INT2REAL(nGScrHeight-24))),
- CREAL(1.0));
- };
-
- /*
- * Set the camera's background color to cyan.
- */
- RwSetCameraBackColor(Camera, CREAL(0.0), CREAL(0.8), CREAL(0.8));
-
-
- RwVCMoveCamera( Camera, CREAL(0.0), CREAL(0.0), CREAL(-7.0) );
-
- /*
- * Create a scene which will contain the clumps to be rendered and the
- * light or lights illuminating those clumps . In this very simple
- * application it would be perfectly acceptable to use the default scene
- * (as returned by RwDefaultScene()) for rendering. However, it is good
- * practice to always create a scene which will be used for your rendering
- * and only use the default scene as a bag for currently unused clumps and
- * lights.
- */
-
-
- Scene = RwCreateScene();
- if (!Scene)
- {
- RwDestroyCamera(Camera);
- RwClose();
- printf("Error creating the RenderWare(tm) scene\n");
- exit(-1);
- }
-
- /*
- * Our scene will be illuminated by a directional light. The illumination
- * vector of the light is (-0.5, -1.0, -1.0) and its brightness will be 1.0.
- */
-
-
- Light = RwCreateLight( rwDIRECTIONAL, CREAL(-0.5), CREAL(-1.0), CREAL(-1.0),
- CREAL(1.2) );
-
- if (!Light)
- {
- RwDestroyScene(Scene);
- RwDestroyCamera(Camera);
- RwClose();
- printf("Error creating the RenderWare(tm) light\n");
- exit(-1);
- }
-
- /*
- * Add the new light to our scene.
- */
-
- RwAddLightToScene(Scene, Light);
-
- /*
- * Make the room in the simulation
- */
-
- RwClumpBegin();
- RwVertex(CREAL(-1.0),CREAL(-1.005),CREAL(1.0));
- RwVertex( CREAL(1.0),CREAL(-1.005),CREAL(1.0));
- RwVertex( CREAL(1.0), CREAL(1.0),CREAL(1.0));
- RwVertex(CREAL(-1.0), CREAL(1.0),CREAL(1.0));
- RwVertex(CREAL(-1.0),CREAL(-1.005),CREAL(-1.0));
- RwVertex( CREAL(1.0),CREAL(-1.005),CREAL(-1.0));
- RwVertex( CREAL(1.0), CREAL(1.0),CREAL(-1.0));
- RwVertex(CREAL(-1.0), CREAL(1.0),CREAL(-1.0));
- RwSetSurface(CREAL(0.4), CREAL(0.6), CREAL(0.0));
- RwSetSurfaceColor(CREAL(0.5), CREAL(0.5), CREAL(0.5));
- RwQuad(2,1,4,3);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.0), CREAL(0.7));
- RwQuad(6,2,3,7);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.7), CREAL(0.0));
- RwQuad(5,6,7,8);
- RwSetSurfaceColor(CREAL(0.7), CREAL(0.0), CREAL(0.0));
- RwQuad(1,5,8,4);
- RwSetSurfaceColor(CREAL(0.0), CREAL(0.7), CREAL(0.0));
- RwQuad(8,7,3,4);
- RwTransformBegin();
- RwTranslateCTM(CREAL(0.0), CREAL(-1.0), CREAL(0.0));
- RwScaleCTM(CREAL(0.25),CREAL(0.0),CREAL(0.25));
- for (i=-4; i<=4; i++)
- for (j=-4; j<=4; j++)
- RwVertex(INT2REAL(i), CREAL(0.0), INT2REAL(j));
- for (i=0; i<8; i++)
- for (j=0; j<8; j++)
- {
- if ((i ^ j) & 1)
- {
- RwSetSurface(CREAL(0.5),CREAL(0.2),CREAL(0.0));
- RwSetSurfaceColor(CREAL(1.0), CREAL(0.0), CREAL(0.0));
- }
- else
- {
- RwSetSurface(CREAL(0.5),CREAL(0.5),CREAL(0.0));
- RwSetSurfaceColor(CREAL(0.5), CREAL(0.5), CREAL(0.0));
- }
- RwQuad(9+(i*9)+j, 9+(i*9)+j+1, 9+((i+1)*9)+j+1, 9+((i+1)*9)+j);
- }
- RwTransformEnd();
- RwClumpEnd(&temp);
- RwAddHintToClump(temp, rwCONTAINER);
- RwAddClumpToScene(Scene, temp);
-
- numthings = 10; /* number of objects */
- makethings(Scene, things, numthings);
-
- follow = 0;
-
- ThreeDInitialized = TRUE;
- return( TRUE );
- }
-
-
- /**********************************************************************/
-
- /*
- * This function shuts down the 3D (i.e. RenderWare) components of the
- * application in a polite fashion.
- */
-
- static void
- TidyUp3D()
- {
- /*
- * Destroy the scene. This will destroy the contents of the scene,
- * i.e. any clumps and lights in that scene. In this case destroying
- * the scene will destroy the light we created in Init3D, and any
- * clumps we have loaded and not already destroyed.
- */
- RwDestroyScene(Scene);
-
- /*
- * Destroy the camera.
- */
- RwDestroyCamera(Camera);
-
- /*
- * Close the library. This will free up any internal resources and
- * textures loaded.
- */
- RwClose();
- }
-
-
- /****************************************************************************
- HandleLeftButtonDown
-
- On entry : Mouse X
- Mouse Y
- Virtual Keys
- On exit :
- */
-
- static void
- HandleLeftButtonDown(int x, int y, int vKeys)
- {
- /* Stop warnings */
- x=x;
- y=y;
- vKeys=vKeys;
-
- if (!bButtonDown)
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Pan and Tilt Camera",nGTextCol);
- }
- else /* both must be down */
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Zoom Camera",nGTextCol);
- }
- bButtonDown |= 1;
- }
-
- /****************************************************************************
- HandleRightButtonDown
-
- On entry : Mouse X
- Mouse Y
- Virtual Keys
- On exit :
- */
-
- static void
- HandleRightButtonDown(int x, int y, int vKeys)
- {
- /* Stop warnings */
- x=x;
- y=y;
- vKeys=vKeys;
-
- if (!bButtonDown)
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Pan and Zoom Camera",nGTextCol);
- }
- else
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Zoom Camera",nGTextCol);
- }
- bButtonDown |= 2;
- }
-
- /**********************************************************************/
-
- /*
- * Handle the left mouse button comming back up. The basic action is
- * to turn of mouse move actions and release mouse capture.
- */
-
- static void
- HandleLeftButtonUp()
- {
- bButtonDown &= ~1;
- if (!bButtonDown)
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- } else {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Pan and Zoom Camera",nGTextCol);
- };
- }
-
- /**********************************************************************/
-
- /*
- * Handle the right mouse button comming back up. The basic action is
- * to turn of mouse move actions and release mouse capture.
- */
-
- static void
- HandleRightButtonUp()
- {
- bButtonDown &= ~2;
- if (!bButtonDown)
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- }
- else
- {
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8, "Pan and Tilt Camera",nGTextCol);
- };
- }
-
-
- /****************************************************************************
- HandleTimer
-
- On entry :
- On exit :
- */
-
- void HandleTimer(void)
- {
- RwV3d vec;
-
- collisions(things, numthings);
- RwGetCameraLookUp(Camera, &vec);
- vec.x = RDiv(vec.x, CREAL(-200));
- vec.y = RDiv(vec.y, CREAL(-200));
- vec.z = RDiv(vec.z, CREAL(-200));
- gravitatethings(things, numthings, &vec);
-
- if (! bButtonDown )
- {
- RwGetClumpOrigin(things[follow].geometry, &vec);
- RwPointCamera(Camera, vec.x,vec.y,vec.z);
- RwSetCameraLookUp(Camera, CREAL(0.0),CREAL(1.0),CREAL(0.0));
- }
-
- /*
- * See the description of HandlePaint() for a description of this common
- * RenderWare cliche for rendering a scene and copying it to the display.
- */
-
-
- RwBeginCameraUpdate(Camera,NULL);
- RwClearCameraViewport(Camera);
- RwRenderScene(Scene);
- RwEndCameraUpdate(Camera);
- RwShowCameraImage(Camera, NULL);
-
-
- }
-
- /****************************************************************************
- HandleMouseMove
-
- * Handle a movement of the mouse. If a previous left or right mouse
- * button down event has set a mouse move mode then this function will
- * take the necessary actions. For example, pan and zooming the camera,
- * panning the light, dragging or spinning a clump etc.
-
- On entry : Mouse x
- : Mouse y
- On exit :
-
- */
- static void
- HandleMouseMove(int x, int y)
- {
- if ( bButtonDown)
- {
- int dx,dy;
- dx = x - LastX;
- dy = y - LastY;
- switch ( bButtonDown )
- {
- case 1:
- {
- RwV3d at,up;
- RwPushScratchMatrix();
- RwGetCameraLookUp(Camera, &up);
- RwRotateMatrix(RwScratchMatrix(), up.x, up.y, up.z, INT2REAL(-dx),
- rwREPLACE);
- RwGetCameraLookRight(Camera, &at);
- RwRotateMatrix(RwScratchMatrix(), at.x, at.y, at.z, INT2REAL(-dy),
- rwPOSTCONCAT);
- RwTransformCamera(Camera, RwScratchMatrix(),rwPOSTCONCAT);
- RwPopScratchMatrix();
- }
- break;
- case 2:
- RwVCMoveCamera(Camera, CREAL(0.0),CREAL(0.0), RDiv(INT2REAL(-dy),
- CREAL(50.0)));
- RwRotateMatrix(RwScratchMatrix(), CREAL(0.0),CREAL(1.0),CREAL(0.0),
- INT2REAL(-dx), rwREPLACE);
- RwTransformCamera(Camera, RwScratchMatrix(),rwPOSTCONCAT);
- break;
- case 3:
- RwVCMoveCamera(Camera, CREAL(0.0),CREAL(0.0), RDiv(INT2REAL(-dy),
- CREAL(50.0)));
- break;
- }
- }
- }
-
- /****************************************************************************
- HandleKey
-
- On entry :
- On exit :
- */
-
- void HandleKey(nKey)
- {
- if (nKey >= '0' && nKey <= '9' && nKey < numthings + '0')
- {
- follow = nKey - '0';
- } else if ((nKey == 't') || (nKey == 'T'))
- {
- int t,u;
- int i;
- char szBuf[255];
-
- u = DosTimer();
- while (u == (t = DosTimer()));
- for (i=0; i<150; i++)
- {
- RwV3d vec;
-
- collisions(things, numthings);
- RwGetCameraLookUp(Camera, &vec);
- vec.x = RDiv(vec.x, CREAL(-200));
- vec.y = RDiv(vec.y, CREAL(-200));
- vec.z = RDiv(vec.z, CREAL(-200));
- gravitatethings(things, numthings, &vec);
- if (1)
- {
- RwGetClumpOrigin(things[follow].geometry, &vec);
- RwPointCamera(Camera, vec.x,vec.y,vec.z);
- RwSetCameraLookUp(Camera, CREAL(0.0),CREAL(1.0),CREAL(0.0));
- }
- RwBeginCameraUpdate(Camera,NULL);
- RwClearCameraViewport( Camera );
- RwRenderScene( Scene );
- RwEndCameraUpdate(Camera);
- RwShowCameraImage( Camera, NULL);
- }
- u = DosTimer();
- sprintf(szBuf, "DosSim took %lu ms for %d frames\n", u-t, i);
- DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
- DosPrintString(0,nGScrHeight-8,szBuf,nGTextCol);
- }
- }
-
- /****************************************************************************
- Main Function
- */
-
- void main(int nArgc,char *saArgv[])
- {
- int nKey;
- int nOldMouseBut;
- int nDX,nDY;
- int nChange;
- int nCtrlShift;
- RwMousePointer mMouse;
-
- /* Stop warnings */
-
- nArgc = nArgc;
-
- if (!Init3D(saArgv[0]))
- {
- exit(-1);
- };
-
- /* Create a Black outlined White pointer */
-
- RwDeviceControl(rwPOINTERDISPLAY,0,&mMouse,sizeof(mMouse));
- LastX = mMouse.x;
- LastY = mMouse.y;
- nOldMouseBut = mMouse.buttons;
-
- nKey = DosGetKey();
-
- while (nKey!=27) { /* ESC quits */
- RwDeviceControl(rwPOINTERDISPLAY,0,&mMouse,sizeof(mMouse));
- nKey = DosGetKey();
-
- nCtrlShift = DosShiftCtrl();
-
- nDX =(mMouse.x-LastX);
- nDY =(mMouse.y-LastY);
-
- nChange = (mMouse.buttons&(2+8)) | ( (nOldMouseBut&(2+8)) >>1 );
-
- switch (nChange) {
- case 0+0:
- case 2+1:
- case 8+4:
- case 8+2+4+1: {
- /* No change */
- break;
- };
- case 2:
- case 8+2+4: {
-
- /* Left Button Down */
-
- HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
-
- break;
- };
- case 8:
- case 8+2+1: {
- /* Right Button Down */
-
-
- HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
-
- break;
- };
- case 8+1: {
- /* Right down left Up */
-
- HandleLeftButtonUp();
- HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
-
- break;
- };
- case 2+4: {
- /* Right up left Down */
-
-
- HandleRightButtonUp();
- HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
-
-
- break;
- };
- case 8+2: {
- /* Left down RIght Down */
-
-
- HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
- HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
-
-
- 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(mMouse.x,mMouse.y);
- };
-
-
- if (nKey) {
- HandleKey(nKey);
- };
-
- HandleTimer();
-
- LastX = mMouse.x;
- LastY = mMouse.y;
- nOldMouseBut = mMouse.buttons;
-
- };
-
- /*
- * Tidy up the 3D (RenderWare) components of the application.
- */
-
- TidyUp3D();
-
- exit(0);
- }
-
-