home *** CD-ROM | disk | FTP | other *** search
/ Learn 3D Graphics Programming on the PC / Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso / rwdos / dosexp.c < prev    next >
C/C++ Source or Header  |  1995-02-15  |  42KB  |  1,803 lines

  1. /**********************************************************************
  2.  *
  3.  * File :     dosexp.c
  4.  *
  5.  * Abstract : A very simple, sample RenderWare application for
  6.  *            MS-Dos/PC Dos. This application has very little
  7.  *            functionality, but is simply intended as a demonstration
  8.  *            of how to use the RenderWare API.
  9.  *
  10.  *            This application had been written to be compatible with
  11.  *            both the fixed and floating-point versions of the
  12.  *            RenderWare library, i.e., it uses the macros CREAL,
  13.  *            INT2REAL, RAdd, RDiv, RSub etc. If your application is
  14.  *            intended for the floating-point version of the library
  15.  *            only these macros are not necessary.
  16.  *
  17.  *            Please note that this application is intended for
  18.  *            demonstration purposes only. No support will be
  19.  *            provided for this code and it comes with no warranty.
  20.  *
  21.  * This file is a product of Criterion Software Ltd.
  22.  *
  23.  * This file is provided as is with no warranties of any kind and is
  24.  * provided without any obligation on Criterion Software Ltd. or
  25.  * Canon Inc. to assist in its use or modification.
  26.  *
  27.  * Criterion Software Ltd. and Canon Inc. will not, under any
  28.  * circumstances, be liable for any lost revenue or other damages arising
  29.  * from the use of this file.
  30.  *
  31.  * Copyright (c) 1991, 1992, 1993. Canon Inc.
  32.  * All Rights Reserved.
  33.  *
  34.  **********************************************************************/
  35.  
  36. /**********************************************************************
  37.  *
  38.  * Header files.
  39.  *
  40.  **********************************************************************/
  41.  
  42. #include <i86.h>
  43. #include <stdlib.h>
  44. #include <stdio.h>
  45. #include <string.h>
  46. #include <math.h>    /* Required for floating point */
  47.  
  48. #include "rwlib.h"
  49. #include "rwdos.h"
  50. #include "doswrap.h"
  51.  
  52. /****************************************************************************
  53.  Defines
  54.  */
  55.  
  56. /* Key code for delete key */
  57.  
  58. #define DELETE 8
  59.  
  60. /*
  61.  * MS Windows compatible defines for dos keys CTRL and SHIFT
  62.  */
  63.  
  64. #define MK_CONTROL 0x4
  65. #define MK_SHIFT 0x2
  66.  
  67. /*
  68.  * Maximum amount of different launch objects
  69.  */
  70.  
  71. #define MAX_OBJECT_TYPES 20
  72. #define MAX_OBJECTS 5
  73. #define MAX_BITS 80
  74.  
  75. /* How high off the platform an object needs to be before it bounces */
  76.  
  77. #define OBJ_SIZE CREAL(0.5)
  78.  
  79. /* The accelleration due to gravity on an object */
  80.  
  81. #define FORCE_OF_GRAVITY 0.002
  82.  
  83. /* A bit is part of an explosion, an object is something to blow up */
  84.  
  85. #define TYPE_OBJECT 0
  86. #define TYPE_BIT 1
  87.  
  88. /* Amount of frames after button down that fire its taken into account */
  89.  
  90. #define FIRE_FRAMES 4
  91.  
  92. /****************************************************************************
  93.  Types
  94.  */
  95.  
  96. /*
  97.  Defines how things are launched, speeds types etc
  98.  */
  99.  
  100. typedef struct LaunchTag
  101. {
  102.     RwReal nMaxVel;
  103.     RwReal nMinVel;
  104.     RwReal nZOff;       /* Spread */
  105.     RwReal nXOff;
  106.     RwReal nExpVel;
  107.     int nAmoLaunch;
  108.     int nMinLaunchTime;
  109.     int nMaxLaunchTime;
  110.     int nMinSetTime;
  111.     int nMaxSetTime;
  112.     RwClump *cpaObjects[MAX_OBJECT_TYPES];
  113.     int nLaunchObject;
  114.     int nAmoObjects;
  115.     int nMaxBounce;
  116.     int nSetCountDown;
  117.     int nLaunchCountDown;
  118.     int nLaunchObjCount;
  119. } Launch;
  120.  
  121. /*
  122.  Defines a launched object either something to blow up or a bit
  123.  */
  124.  
  125. typedef struct LaunchObjectTag
  126. {
  127.     int nUsed;
  128.     int nType;
  129.     RwClump *cpGeo;
  130.     RwV3d vPos,vVel;
  131.     RwMatrix4d *mpRot,*mpPos;
  132.     RwV3d vAxis;
  133.     RwReal nRotAngle;
  134. } LaunchObject;
  135.  
  136. /****************************************************************************
  137.  Globals
  138.  */
  139.  
  140. /* Globals for handling objects and object launching */
  141.  
  142. static Launch lGLaunch;
  143. static LaunchObject loaGLObjects[MAX_OBJECTS];
  144. static LaunchObject loaGLBits[MAX_BITS];
  145.  
  146. /*  3d globals */
  147.  
  148. static RwScene    *Scene;
  149. static RwCamera  *Camera;
  150. static RwLight    *Light;
  151.  
  152. static ThreeDInitialized = FALSE;
  153.  
  154. static unsigned long frames = 0;
  155.  
  156. /* Current button status */
  157.  
  158. static int bButtonDown = 0;
  159.  
  160. /* String for clearing */
  161.  
  162. static char sGClear[]="                                  ";
  163.  
  164. /*
  165.  * Global variables used to remember the last mouse X and Y coordinates
  166.  * when involved in a pan, zoom, drag or spin.
  167.  */
  168. static int         LastX;
  169. static int         LastY;
  170.  
  171.  
  172. /*
  173.  Screen size
  174.  */
  175.  
  176. static int nGScrWidth;
  177. static int nGScrHeight;
  178.  
  179. /*
  180.  Colour Codes
  181.  */
  182.  
  183. static int nGTextCol;
  184.  
  185. /* Pick info */
  186.  
  187. static RwPickRecord pGPick;
  188. static int nGPickStatus;
  189.  
  190. /* Fire Counter */
  191.  
  192. static int nGFireCount;
  193.  
  194. /* "Score" */
  195.  
  196. static int nGTargets;
  197. static int nGHits;
  198. static int nGShots;
  199.  
  200. /****************************************************************************
  201.  Cursor Images
  202.  */
  203.  
  204. /* 16 by 16 image */
  205.  
  206. #define MOUSE_ARROW_X 0
  207. #define MOUSE_ARROW_Y 0
  208.  
  209. #define MOUSE_ARROW_W 16
  210. #define MOUSE_ARROW_H 16
  211.  
  212. static void *pGMouseArrow;
  213. static char sGMouseArrow[]="\
  214. aaaa            \
  215. abbbaaa         \
  216. abbbbbbaaa      \
  217. abbbbbbbbba     \
  218.  abbbbbbba      \
  219.  abbbbbba       \
  220.  abbbbbba       \
  221.   abbbbbba      \
  222.   abbaabbba     \
  223.   aba  abbba    \
  224.    a    abbba   \
  225.          abbba  \
  226.           abbba \
  227.            abba \
  228.             aa  \
  229.                 ";
  230.  
  231. /* 28 x 20 */
  232.  
  233. #define MOUSE_FIRE_X 14
  234. #define MOUSE_FIRE_Y 15
  235.  
  236. #define MOUSE_FIRE_W 28
  237. #define MOUSE_FIRE_H 20
  238.  
  239. static void *pGMouseFire;
  240. static char sGMouseFire[]="\
  241. aaaaaa   a   aaaaa    aaaaa \
  242. abbbbba aba abbbbba  abbbbba\
  243. abaaaa  aba abaaaaba abaaaa \
  244. abaa    aba abaaaaba abaa   \
  245. abbba   aba abbbbba  abbba  \
  246. abaa    aba abaaaba  abaa   \
  247. aba     aba aba  aba abaaaa \
  248. aba     aba aba  aba abbbbba\
  249.  a       a   a    a   aaaaa \
  250.                             \
  251.            aaaaaaa          \
  252.           abbbbbbba         \
  253.          ab       ba        \
  254.          ab       ba        \
  255.          ab       ba        \
  256.          ab       ba        \
  257.          ab       ba        \
  258.          ab       ba        \
  259.           abbbbbbba         \
  260.            aaaaaaa          ";
  261.  
  262. /* 12 x 10 */
  263.  
  264. #define MOUSE_SIGHT_X 6
  265. #define MOUSE_SIGHT_Y 5
  266.  
  267. #define MOUSE_SIGHT_W 11
  268. #define MOUSE_SIGHT_H 10
  269.  
  270. static void *pGMouseSight;
  271. static char sGMouseSight[]="\
  272.   aaaaaaa  \
  273.  abbbbbbba \
  274. ab       ba\
  275. ab       ba\
  276. ab       ba\
  277. ab       ba\
  278. ab       ba\
  279. ab       ba\
  280.  abbbbbbba \
  281.   aaaaaaa  ";
  282.  
  283.  
  284.  
  285.  
  286. /*************************************************************************
  287.  MakeZippy - Sets polygon to a random colour
  288.              (called from RwForAllPolygonsInClump)
  289.  
  290.  On entry    : Polygon
  291.  On exit    :
  292.  */
  293.  
  294. static void MakeZippy(RwPolygon3d *p)
  295. {
  296.   static int zippy = 0;
  297.  
  298.   switch (zippy % 7)
  299.     {
  300.     case 0: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.0)); break;
  301.     case 1: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.0)); break;
  302.     case 2: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.0), CREAL(0.7)); break;
  303.     case 3: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.0)); break;
  304.     case 4: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.0), CREAL(0.7)); break;
  305.     case 5: RwSetPolygonColor(p, CREAL(0.0), CREAL(0.7), CREAL(0.7)); break;
  306.     case 6: RwSetPolygonColor(p, CREAL(0.7), CREAL(0.7), CREAL(0.7)); break;
  307.     }
  308.   zippy++;
  309. }
  310.  
  311. /****************************************************************************
  312.  MakeMaterial - Sets a polygons material to the current material
  313.                                 ( Called from RwForAllPolygonsInClump)
  314.  
  315.  On entry    : Polygon
  316.  On exit    :
  317.  */
  318.  
  319. static void MakeMaterial(RwPolygon3d *p)
  320. {
  321.     RwSetPolygonMaterial(p,RwCurrentMaterial());
  322. }
  323.  
  324.  
  325. /****************************************************************************
  326.  SetCountdown - return a random value between max and min value
  327.  
  328.  On entry    : Max value
  329.                     : Min value
  330.  On exit    : value
  331.  */
  332.  
  333. int SetCountDown(int nMax,int nMin)
  334. {
  335.     int nVal;
  336.  
  337.     nVal = rand()%(nMax-nMin);
  338.  
  339.     return nMin+nVal;
  340. }
  341.  
  342. /****************************************************************************
  343.  SetupLaunch - Setup the launch structure (loading objects etc)
  344.  
  345.  On entry    : Launch structure to be set up
  346.  On exit    :
  347.  */
  348.  
  349. void SetupLaunch(Launch *plLaunch)
  350. {
  351.     RwClump *cpDefault,*cpLoad;
  352.     char saFiles[][14]={"banana.rwx",
  353.                                         "ball.rwx",
  354.                                         "c.rwx",
  355.                                         "table.rwx",
  356.                                         "slab.rwx",
  357.                                         "torus.rwx",
  358.                                         "banana.rwx",
  359.                                         "lampshad.rwx",
  360.                                         "dummy.rwx"};
  361.     int nCount;
  362.     RwMatrix4d *mpScale;
  363.  
  364.     /* Create a scale matrix */
  365.  
  366.     mpScale = RwCreateMatrix();
  367.     RwScaleMatrix(mpScale,CREAL(0.05),CREAL(0.05),CREAL(0.05),rwREPLACE);
  368.  
  369.     /* Amount of different objects that can be thrown up */
  370.  
  371.     plLaunch->nAmoObjects = 9;
  372.  
  373.     plLaunch->nMaxVel = CREAL(0.15);
  374.     plLaunch->nMinVel = CREAL(0.04);
  375.     plLaunch->nZOff = CREAL(0.01);    /* Uniform distribution */
  376.     plLaunch->nXOff = CREAL(0.01);
  377.  
  378.     plLaunch->nExpVel = CREAL(0.05);
  379.  
  380.     plLaunch->nAmoLaunch = 2;
  381.     plLaunch->nMinLaunchTime = 20;
  382.     plLaunch->nMaxLaunchTime = 40;
  383.     plLaunch->nMinSetTime = 100;
  384.     plLaunch->nMaxSetTime = 150;
  385.  
  386.     plLaunch->nLaunchObject=0;
  387.  
  388.     plLaunch->nMaxBounce = 4;
  389.  
  390.     /* Create a default image if the shape cannot be loaded */
  391.  
  392.   RwClumpBegin();
  393.   RwSetSurface(CREAL(0.4), CREAL(0.7), CREAL(0.0));
  394.   RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
  395.             RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
  396.             RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
  397.  
  398.   RwSphere(CREAL(0.1),3);
  399.     RwClumpEnd(&cpDefault);
  400.  
  401.     /* Put the clumps in the structure */
  402.  
  403.     /* Save the current material */
  404.     RwPushCurrentMaterial();
  405.     /* Create a default surface type */
  406.     RwSetMaterialSurface(RwCurrentMaterial(),CREAL(0.4),CREAL(7.0),CREAL(3.0));
  407.  
  408.     for (nCount=0;nCount<plLaunch->nAmoObjects;nCount++) {
  409.  
  410.         /* Read in shapes - if not found use the default shape */
  411.  
  412.         cpLoad = RwReadShape(saFiles[nCount]);
  413.         if (!cpLoad) {
  414.             plLaunch->cpaObjects[nCount] = RwDuplicateClump(cpDefault);
  415.         } else {
  416.             plLaunch->cpaObjects[nCount] = cpLoad;
  417.             if (nCount>=5) {
  418.                 /* Give material and zippify some of the objects */
  419.                 RwForAllPolygonsInClump(cpLoad, MakeMaterial);
  420.                 RwForAllPolygonsInClump(cpLoad, MakeZippy);
  421.             };
  422.         };
  423.  
  424.  
  425.  
  426.         /* Make objectunit size */
  427.         RwNormalizeClump(plLaunch->cpaObjects[nCount]);
  428.         RwTransformClump(plLaunch->cpaObjects[nCount],mpScale,rwREPLACE);
  429.     };
  430.  
  431.     /* Restore material */
  432.     RwPopCurrentMaterial();
  433.  
  434.     /* Destroy the scale matrix */
  435.  
  436.     RwDestroyMatrix(mpScale);
  437.  
  438.     /* Destroy the unwanted default clump */
  439.  
  440.     RwDestroyClump(cpDefault);
  441.  
  442.     /* Set random launch times */
  443.  
  444.     plLaunch->nLaunchCountDown =
  445.         SetCountDown(plLaunch->nMaxLaunchTime,plLaunch->nMinLaunchTime);
  446.     plLaunch->nSetCountDown =
  447.         SetCountDown(plLaunch->nMaxSetTime,plLaunch->nMinSetTime);
  448.     plLaunch->nLaunchObjCount = 0;
  449.  
  450.     for (nCount=0;nCount<MAX_OBJECTS;nCount++) {
  451.         /* Make the position (in rotation) and rotation matrixes the identity*/
  452.  
  453.         RwIdentityMatrix(loaGLObjects[nCount].mpRot = RwCreateMatrix());
  454.     RwIdentityMatrix(loaGLObjects[nCount].mpPos = RwCreateMatrix());
  455.     };
  456.  
  457. }
  458.  
  459. /****************************************************************************
  460.  CreateBits - Create the explosion bits
  461.  
  462.  On entry    : Bits array
  463.                     : Amount of bits
  464.  On exit    :
  465.  */
  466.  
  467. void CreateBits(LaunchObject *loaObject,int nAmo)
  468. {
  469.     int nCount;
  470.     RwClump *cpBit;
  471.     RwClump *cpGeo;
  472.     RwV3d vTmp;
  473.     RwReal nSize;
  474.  
  475.     /* Create the clump which is an explosion bit */
  476.  
  477.     nSize = CREAL(0.05);
  478.  
  479.   RwClumpBegin();
  480.   RwSetSurface(CREAL(0.4), CREAL(0.7), CREAL(0.0));
  481.   RwSetSurfaceColor(RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
  482.             RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))),
  483.             RDiv(CREAL(1.0), INT2REAL(1 + (rand() % 4))));
  484.  
  485.     RwVertex(CREAL(0.0),nSize,CREAL(0.0));
  486.     RwVertex(RMul(nSize,CREAL(-0.866)),
  487.                         RMul(nSize,CREAL(-0.5)),
  488.                         CREAL(0.0));
  489.     RwVertex(RMul(nSize,CREAL(0.866)),
  490.                         RMul(nSize,CREAL(-0.5)),
  491.                         CREAL(0.0));
  492.     RwVertex(CREAL(0.0),CREAL(0.0),nSize);
  493.     RwTriangle(1,4,3);
  494.     RwTriangle(2,4,1);
  495.     RwTriangle(4,2,3);
  496.     RwTriangle(3,2,1);
  497.     RwClumpEnd(&cpBit);
  498.  
  499.  
  500.     /* For all explosion bits */
  501.  
  502.     for (nCount=0;nCount<nAmo;nCount++) {
  503.         /* Make a copy of the bit clump */
  504.  
  505.             cpGeo = RwDuplicateClump(cpBit);
  506.  
  507.             if (!cpGeo) {
  508.                 RwClose();
  509.                 printf("Unable to duplicate bit clump.\n");
  510.                 exit(-1);
  511.             };
  512.  
  513.             /* Zippify the bit */
  514.  
  515.             RwForAllPolygonsInClump(cpGeo, MakeZippy);
  516.  
  517.             /* Mark as bit and unused */
  518.  
  519.             loaObject[nCount].nUsed=0;
  520.             loaObject[nCount].nType=TYPE_BIT;
  521.             loaObject[nCount].cpGeo = cpGeo;
  522.  
  523.             RwSetClumpData(cpGeo,NULL);        /* Mark with Null pointer */
  524.  
  525.             RwIdentityMatrix(loaObject[nCount].mpRot = RwCreateMatrix());
  526.         RwIdentityMatrix(loaObject[nCount].mpPos = RwCreateMatrix());
  527.  
  528.             /* Give it a random rotation */
  529.  
  530.             RandomVec(&vTmp);
  531.  
  532.       RwRotateMatrix(loaObject[nCount].mpRot,vTmp.x,vTmp.y,vTmp.z,
  533.           RMul(RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0)),CREAL(10.0)),
  534.                            rwREPLACE);
  535.     };
  536.  
  537.     /* Destroy the default clump */
  538.  
  539.     RwDestroyClump(cpBit);
  540. }
  541.  
  542. /****************************************************************************
  543.  DisplayTargets - display the amount of targets sent up
  544.  
  545.  On entry    :
  546.  On exit
  547.  */
  548.  
  549. void DisplayTargets(void)
  550. {
  551.     char buffer[10];
  552.  
  553.     sprintf(buffer,"%i ",nGTargets);
  554.     DosPrintString(9*8,nGScrHeight-16,buffer,nGTextCol);
  555. }
  556.  
  557. /****************************************************************************
  558.  DisplayShots - display the amount of shots fired
  559.  
  560.  On entry    :
  561.  On exit
  562.  */
  563.  
  564. void DisplayShots(void)
  565. {
  566.     char buffer[10];
  567.  
  568.     sprintf(buffer,"%i ",nGShots);
  569.     DosPrintString(30*8,nGScrHeight-16,buffer,nGTextCol);
  570. }
  571.  
  572. /****************************************************************************
  573.  LaunchObject - Launch an object
  574.  
  575.  On entry    : Launch Structure
  576.                     : Geometry to Launch
  577.  On exit    :
  578.  */
  579.  
  580. void DoLaunchObject(Launch *plLaunch,
  581.                                     RwClump *cpGeo)
  582. {
  583.         int nCount;
  584.         LaunchObject *lopObject=NULL;
  585.         RwV3d vTmp;
  586.         RwReal nRand;
  587.  
  588.         /* Find a free object */
  589.  
  590.         for (nCount=0;nCount<MAX_OBJECTS;nCount++) {
  591.             if (!loaGLObjects[nCount].nUsed) {
  592.                 lopObject = &(loaGLObjects[nCount]);
  593.                 break;
  594.             };
  595.         };
  596.  
  597.         /* Check that the object was actually found */
  598.  
  599.         if (!lopObject) {
  600.             return;
  601.         };
  602.  
  603.         /* Set up the object */
  604.  
  605.         lopObject->nUsed = 1;    /* Mark as used */
  606.         lopObject->nType = TYPE_OBJECT;
  607.  
  608.         lopObject->cpGeo = cpGeo;
  609.  
  610.         /* Point the data to this launch object */
  611.  
  612.         RwSetClumpData(cpGeo,(void *)lopObject);
  613.  
  614.         /* Stick it in the scene */
  615.  
  616.         RwAddClumpToScene(Scene,lopObject->cpGeo);
  617.  
  618.         /* place it in the centre of the launch pad */
  619.  
  620.         lopObject->vPos.x = CREAL(0.0);
  621.         lopObject->vPos.y = OBJ_SIZE;
  622.         lopObject->vPos.z = CREAL(0.0);
  623.  
  624.         /* Give it a random velocity */
  625.  
  626.         nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  627.  
  628.         lopObject->vVel.x = RSub(RMul(RAdd(plLaunch->nXOff,
  629.                                            plLaunch->nXOff),nRand),
  630.                                                                              plLaunch->nXOff);
  631.  
  632.         nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  633.  
  634.         lopObject->vVel.y =
  635.                                                                 RAdd(RMul(RSub(plLaunch->nMaxVel,
  636.                                            plLaunch->nMinVel),nRand),
  637.                                                                              plLaunch->nMinVel);
  638.  
  639.         nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  640.  
  641.         lopObject->vVel.z = RSub(RMul(RAdd(plLaunch->nZOff,
  642.                                            plLaunch->nZOff),nRand),
  643.                                                                              plLaunch->nZOff);
  644.  
  645.         /* Give it a random rotation */
  646.  
  647.         RandomVec(&vTmp);
  648.  
  649.     RwRotateMatrix(lopObject->mpRot,vTmp.x,vTmp.y,vTmp.z,
  650.       RMul(RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0)),CREAL(20.0)),
  651.                           rwREPLACE);
  652.  
  653.  
  654.         /* Increase the target counter */
  655.  
  656.         nGTargets++;
  657.         DisplayTargets();
  658. }
  659.  
  660. /****************************************************************************
  661.  DestroyObject - If it is used remove it from the scene
  662.  
  663.  On entry    : Object to destroy
  664.  On exit    :
  665.  */
  666.  
  667. void DestroyObject(LaunchObject *lopObject)
  668. {
  669.     if (lopObject->nUsed) {
  670.         lopObject->nUsed =0;
  671.  
  672.         RwRemoveClumpFromScene(lopObject->cpGeo);
  673.     };
  674. }
  675.  
  676. /****************************************************************************
  677.  Handle Launch - handle the launching of objects
  678.  
  679.  On entry    : Launch structure
  680.  On exit    : 0 if no launch
  681.  */
  682.  
  683. int HandleLaunch(Launch *plLaunch)
  684. {
  685.     int nLaunch=0;
  686.  
  687.     if (!(plLaunch->nSetCountDown--)) {
  688.         /* Start a set launch sequence */
  689.  
  690.         plLaunch->nLaunchObjCount = plLaunch->nAmoLaunch;
  691.         plLaunch->nSetCountDown =
  692.             SetCountDown(plLaunch->nMaxSetTime,plLaunch->nMinSetTime);
  693.  
  694.         plLaunch->nLaunchCountDown =
  695.             SetCountDown(plLaunch->nMaxLaunchTime,plLaunch->nMinLaunchTime);
  696.     };
  697.  
  698.     /* Check the launch sequence in a set */
  699.  
  700.     if ((plLaunch->nLaunchObjCount)&&(!(plLaunch->nLaunchCountDown--))) {
  701.  
  702.         /* Restet the object counters */
  703.  
  704.         plLaunch->nLaunchCountDown =
  705.             SetCountDown(plLaunch->nMaxLaunchTime,plLaunch->nMinLaunchTime);
  706.         plLaunch->nLaunchObjCount--;
  707.  
  708.         /* Initiate a launch */
  709.  
  710.         DoLaunchObject(plLaunch,plLaunch->cpaObjects[plLaunch->nLaunchObject]);
  711.  
  712.         nLaunch=1;
  713.  
  714.         /* Change the object */
  715.  
  716.         plLaunch->nLaunchObject++;
  717.         if (plLaunch->nLaunchObject>=plLaunch->nAmoObjects) {
  718.             plLaunch->nLaunchObject=0;
  719.         };
  720.     };
  721.  
  722.     return nLaunch;
  723. }
  724.  
  725.  
  726. /****************************************************************************
  727.  CreateExplosion
  728.  
  729.  On entry    : Vector position of explosion
  730.                     : Amount of Bits
  731.  On exit    :
  732.  */
  733.  
  734. void CreateExplosion(RwV3d *vpPos,RwV3d *vpVel,int nAmo)
  735. {
  736.     int nCount;
  737.     LaunchObject *lopBit;
  738.     RwReal nRand;
  739.  
  740.     lopBit = loaGLBits;
  741.  
  742.   RwPushScratchMatrix();
  743.  
  744.     for (nCount=0;nCount<MAX_BITS;nCount++) {
  745.         if (!lopBit->nUsed) {
  746.             /* Create an explosion bit */
  747.  
  748.             /* Mark as used */
  749.  
  750.             lopBit->nUsed = 2;
  751.  
  752.             /* Give it a velocity and position */
  753.  
  754.             lopBit->vPos = (*vpPos);
  755.             lopBit->vVel = (*vpVel);
  756.  
  757.             /* Offset the velocity by a random vector */
  758.  
  759.             nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  760.             lopBit->vVel.x += RSub(RMul(RAdd(lGLaunch.nExpVel,
  761.                                                lGLaunch.nExpVel),nRand),
  762.                                                                                  lGLaunch.nExpVel);
  763.  
  764.             nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  765.             lopBit->vVel.y += RSub(RMul(RAdd(lGLaunch.nExpVel,
  766.                                                lGLaunch.nExpVel),nRand),
  767.                                                                                  lGLaunch.nExpVel);
  768.  
  769.  
  770.             nRand = RDiv(INT2REAL(rand()>>1),CREAL(16384.0));
  771.             lopBit->vVel.z += RSub(RMul(RAdd(lGLaunch.nExpVel,
  772.                                                lGLaunch.nExpVel),nRand),
  773.                                                                                  lGLaunch.nExpVel);
  774.  
  775.             /* Make the pos the identity matrix */
  776.  
  777.         RwIdentityMatrix(lopBit->mpPos);
  778.  
  779.             /* Stick it in the scene */
  780.  
  781.             RwAddClumpToScene(Scene,lopBit->cpGeo);
  782.  
  783.             /* Check if can create any more */
  784.  
  785.             if (!(--nAmo)) {
  786.                 /* Exit -> all used up */
  787.  
  788.               RwPopScratchMatrix();
  789.                 return;
  790.             };
  791.         };
  792.  
  793.         /* Next Bit */
  794.  
  795.         lopBit++;
  796.     };
  797.  
  798.   RwPopScratchMatrix();
  799. }
  800.  
  801. /****************************************************************************
  802.  MoveObjects
  803.  
  804.  On entry    : pointer to launch objects
  805.                     : amount of objects
  806.  */
  807.  
  808. void MoveObjects(LaunchObject *loaObject, int nAmo,Launch *lpLaunch)
  809. {
  810.   int i;
  811.   RwV3d p;
  812.     LaunchObject *lopObject;
  813.  
  814.     /* Save current matrix */
  815.  
  816.   RwPushScratchMatrix();
  817.  
  818.     /* For all launch objects in list */
  819.  
  820.   for (i=0; i<nAmo; i++)
  821.   {
  822.         lopObject = &loaObject[i];
  823.  
  824.         if (lopObject->nUsed) {
  825.  
  826.             /* Apply rotation to rotation position matrix */
  827.  
  828.         RwMultiplyMatrix(lopObject->mpPos,lopObject->mpRot,RwScratchMatrix());
  829.  
  830.             /* Normalize matrix if its time to */
  831.  
  832.         if ((frames)%(nAmo<<3) ==(i<<3))  {
  833.                 RwOrthoNormalizeMatrix(RwScratchMatrix(), RwScratchMatrix());
  834.             };
  835.  
  836.             /* Save rotation pos */
  837.  
  838.         RwCopyMatrix(RwScratchMatrix(), lopObject->mpPos);
  839.  
  840.             /* Position clump */
  841.  
  842.             p = lopObject->vPos;
  843.         RwTranslateMatrix(RwScratchMatrix(), p.x,p.y,p.z, rwPOSTCONCAT);
  844.         RwTransformClump(lopObject->cpGeo, RwScratchMatrix(), rwREPLACE);
  845.  
  846.             /* Take into account gravity */
  847.  
  848.             lopObject->vVel.y -= CREAL(FORCE_OF_GRAVITY);
  849.  
  850.             /* Apply velocity */
  851.  
  852.             lopObject->vPos.x += lopObject->vVel.x;
  853.             lopObject->vPos.y += lopObject->vVel.y;
  854.             lopObject->vPos.z += lopObject->vVel.z;
  855.  
  856.             /* Has it hit the platform */
  857.  
  858.             if ((lopObject->vVel.y<CREAL(0.0))&&
  859.                (RAbs(lopObject->vPos.x)<CREAL(1.0)) &&
  860.                  (RAbs(lopObject->vPos.z)<CREAL(1.0))) {
  861.                 if (lopObject->nType==TYPE_BIT) {
  862.                     /* has it hit ?*/
  863.                     if (lopObject->vPos.y<CREAL(0.1)) {
  864.                         if (lopObject->nUsed<=lpLaunch->nMaxBounce) {
  865.                             /* Make it bounce */
  866.                             lopObject->vVel.y = RDiv(-(lopObject->vVel.y),CREAL(1.5));
  867.                             lopObject->nUsed++;
  868.                         } else {
  869.                             /* Destroy the object */
  870.                             DestroyObject(lopObject);
  871.                         };
  872.                     };
  873.                 } else {
  874.                     if (lopObject->vPos.y<OBJ_SIZE) {
  875.                         if (lopObject->nUsed<=lpLaunch->nMaxBounce) {
  876.                             /* Make it bounce */
  877.                             lopObject->vVel.y = RDiv(-(lopObject->vVel.y),CREAL(1.5));
  878.                             lopObject->nUsed++;
  879.                         } else {
  880.                             /* Create explosion */
  881.                             CreateExplosion(&lopObject->vPos,&lopObject->vVel,15);
  882.                             /* Destroy object */
  883.                             DestroyObject(lopObject);
  884.                         };
  885.                     };
  886.                 };
  887.             };
  888.  
  889.             /* If fallen out of scene destroy anyway */
  890.  
  891.             if (lopObject->vPos.y<CREAL(-8.0)) {
  892.                 DestroyObject(lopObject);
  893.             };
  894.         };
  895.     };
  896.  
  897.  
  898.   RwPopScratchMatrix( );
  899. }
  900.  
  901.  
  902. /****************************************************************************
  903.  DosPrintString
  904.  
  905.  On entry     : xcord
  906.                         : ycord
  907.                         : string
  908.                         : colour
  909.  On exit        :
  910.  */
  911.  
  912. void DosPrintString(int nX,int nY,char *sString,int nCol)
  913. {
  914.     RwPrintChar pcPrint;
  915.  
  916.     pcPrint.x = nX;
  917.     pcPrint.y = nY;
  918.     pcPrint.color = nCol;
  919.  
  920.     for (;(*sString);sString++)  {
  921.         pcPrint.c = (*sString);
  922.     RwDeviceControl(rwPRINTCHAR,0,&pcPrint,sizeof(pcPrint));
  923.         pcPrint.x+=8;
  924.     };
  925. }
  926.  
  927.  
  928. /****************************************************************************
  929.  DosTimer
  930.  
  931.  On entry    :
  932.  On exit    : Timer (in milliseconds)
  933.  */
  934.  
  935. int DosTimer(void)
  936. {
  937.     union REGS r;
  938.     int nTime;
  939.  
  940.     r.h.ah=0;
  941.  
  942.     int386(0x1a,&r,&r);
  943.  
  944.     nTime = ((r.w.cx)<<16)|(r.w.dx);
  945.  
  946.     return (nTime*55);
  947. }
  948.  
  949. /****************************************************************************
  950.  DosGetKey
  951.  
  952.  On entry    :
  953.  On exit     : Key pressed in ascii (or 0 if no key pressed)
  954.  */
  955.  
  956. int DosGetKey(void)
  957. {
  958.     union REGPACK rp;
  959.  
  960.     memset(&rp,0,sizeof(rp));
  961.     rp.h.ah = 0x06;
  962.     rp.h.dl = 0xff;
  963.  
  964.     intr(0x21,&rp);
  965.  
  966.     if (!(rp.w.flags & 0x40 )) {       /* Check Z flag */
  967.         /* Got key */
  968.  
  969.         if (rp.h.al) {
  970.             return ((int)rp.h.al);
  971.         };
  972.  
  973.         memset(&rp,0,sizeof(rp));
  974.         rp.h.ah = 0x06;
  975.         rp.h.dl = 0xff;
  976.         intr(0x21,&rp);
  977.  
  978.         if (!(rp.w.flags & 0x40)) {
  979.             return ((int)rp.h.al);
  980.         };
  981.  
  982.         return (rp.h.al|0x80);
  983.     };
  984.  
  985.     return 0;
  986. }
  987.  
  988. /****************************************************************************
  989.  DosShiftCtrl
  990.  
  991.  On entry    :
  992.  On exit    : Bit         Meaning
  993.                         0                Right Shift
  994.                         1                Left Shift
  995.                         2                Ctrl
  996.                         3                Alt
  997.                         4       Scroll Lock
  998.                         5                Num Lock
  999.                         6             Caps Lock
  1000.                         7                Insert on
  1001.  */
  1002.  
  1003. int DosShiftCtrl(void)
  1004. {
  1005.     union REGPACK rp;
  1006.  
  1007.     memset(&rp,0,sizeof(rp));
  1008.  
  1009.     rp.h.ah=0x02;
  1010.     intr(0x16,&rp);
  1011.  
  1012.     return ((int)rp.h.al);
  1013. }
  1014.  
  1015.  
  1016. /***************************************************************************
  1017.  RandomVec - create a random vector
  1018.  
  1019.  On entry    : Random vector to create
  1020.  On exit    :
  1021.  */
  1022.  
  1023. static void RandomVec(RwV3d *vec)
  1024. {
  1025.   vec->x = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
  1026.   vec->y = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
  1027.   vec->z = RSub(RDiv(INT2REAL(rand()),CREAL(16384.0)), CREAL(1.0));
  1028. }
  1029.  
  1030. /****************************************************************************
  1031.  Init3D
  1032.  
  1033.  * This function initializes the 3D (i.e. RenderWare) components of the
  1034.  * application. This function opens the RenderWare library, creates a
  1035.  * camera, a scene, a light and a matrix for spinning. A user-draw may
  1036.  * also be created if USERDRAW_LABELS is defined.
  1037.  
  1038.  On entry    : Filename (hopefully including path) of executable
  1039.  On exit    : TRUE if all ok
  1040.  */
  1041.  
  1042. static int
  1043. Init3D(char *sFilename)
  1044. {
  1045.   int     i;
  1046.   int fixed, debugging;
  1047.   char *title;
  1048.   RwClump *temp;
  1049.     RwReal naTextCol[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
  1050.   char     buffer[128];
  1051.     long nError;
  1052.  
  1053.  
  1054.     if (!RwOpen("DOSMOUSE", &nError))
  1055.     {
  1056.         printf("Unable to access renderware!!\n");
  1057.         switch (nError) {
  1058.             case E_RW_DOS_MODE_UNAVAILABLE: {
  1059.                printf("The installed VESA card is unable to switch to the resolution");
  1060.                 printf(" requested.\n");
  1061.                 printf("Either install a different video adapter or use a ");
  1062.                 printf("supported video mode.");
  1063.                 break;
  1064.             };
  1065.             case E_RW_DOS_NO_VESA_BIOS: {
  1066.                 printf("A VESA bios is unavailable on this machine.\n");
  1067.                 printf("Either use a VESA compatible Video Adapter or install a ");
  1068.                 printf("VESA bios emulation TSR.\n");
  1069.                 break;
  1070.             };
  1071.             case E_RW_DOS_INCOMPATIBLE_BIOS: {
  1072.                 printf("The VESA bios on this machine is not of high enough version ");
  1073.                 printf("to function\ncorrectly with RenderWare. Use a version 1.0 or");
  1074.                 printf(" higher VESA bios or TSR.\n");
  1075.                 break;
  1076.             };
  1077.             case E_RW_DOS_NO_MOUSE: {
  1078.                 printf("No Microsoft compatible mouse driver present.\n");
  1079.                 printf("Install a microsoft compatible mouse driver and try again.\n");
  1080.                 break;
  1081.             };
  1082.             default: {
  1083.                 printf("Unknown Error !!!!!!!!!!!!!!!\n");
  1084.                 break;
  1085.             };
  1086.         };
  1087.         return FALSE;
  1088.     }
  1089.  
  1090.     /* Set up the DOS Character Set */
  1091.  
  1092.   RwGetDeviceInfo(rwSCRHEIGHT,&nGScrHeight,sizeof(nGScrHeight));
  1093.   RwGetDeviceInfo(rwSCRWIDTH,&nGScrWidth,sizeof(nGScrWidth));
  1094.  
  1095.   nGTextCol = RwDeviceControl(rwSCRGETCOLOR,0,naTextCol,sizeof(naTextCol));
  1096.  
  1097.     RwSetShapePath(".",rwPRECONCAT);
  1098.  
  1099.     strcpy(buffer,sFilename);
  1100.  
  1101.     i = strlen(buffer);
  1102.     while((buffer[i] != '\\')&&(i>=0)) {
  1103.         i--;
  1104.     };
  1105.  
  1106.  
  1107.     if (i>=0) {
  1108.         buffer[i+1] = 0;
  1109.         strcat(buffer, "TEXTURES");
  1110.         RwSetShapePath(buffer, rwPOSTCONCAT);
  1111.  
  1112.         buffer[i+1] = 0;
  1113.         strcat(buffer, "SCRIPTS");
  1114.         RwSetShapePath(buffer, rwPOSTCONCAT);
  1115.     };
  1116.  
  1117.     RwSetShapePath("SCRIPTS", rwPRECONCAT);
  1118.     RwSetShapePath("TEXTURES", rwPRECONCAT);
  1119.  
  1120.  
  1121.     /*
  1122.     * Label the window with information about the version of
  1123.     * RenderWare being used. Its rather unlikely that
  1124.     * RwGetSystemInfo() will fail so we ignore its return value.
  1125.     */
  1126.  
  1127.     DosPrintString(0,nGScrHeight-16,"Targets:",nGTextCol);
  1128.     DosPrintString(13*8,nGScrHeight-16,"Hits:",nGTextCol);
  1129.     DosPrintString(24*8,nGScrHeight-16,"Shots:",nGTextCol);
  1130.  
  1131.   RwGetSystemInfo(rwFIXEDPOINTLIB, &fixed,sizeof(fixed));
  1132.   RwGetSystemInfo(rwDEBUGGINGLIB, &debugging,sizeof(debugging));
  1133.     if ((fixed) && (debugging))
  1134.     title = "DosExp (Fixed & Debugging)";
  1135.     else if (fixed)
  1136.     title = "DosExp (Fixed Point)";
  1137.     else if (debugging)
  1138.     title = "DosExp (Debugging)";
  1139.     else
  1140.     title = "DosExp (Floating Point)";
  1141.  
  1142.     /* Temporary message !!*/
  1143.  
  1144.     DosPrintString(0,nGScrHeight-24,title,nGTextCol);
  1145.  
  1146.     /*
  1147.     * Create the camera which will be used for rendering. The initial window
  1148.     * size the application will create is given by nGScrWidth and
  1149.     * nGScrHeight-17 which depends on the screen res used.
  1150.     */
  1151.  
  1152.     Camera = RwCreateCamera(nGScrWidth,nGScrHeight-17, NULL);
  1153.     if (!Camera)
  1154.     {
  1155.     /*
  1156.     * As with RwOpen(), the most common cause for a failure to create
  1157.     * a camera is insufficient memory so we will explicitly check for
  1158.     * this condition and report it. Otherwise a general error is issued.
  1159.     */
  1160.         if (RwGetError() == E_RW_NOMEM)
  1161.         {
  1162.             RwClose();
  1163.             printf("Insufficient memory to create the RenderWare(tm) camera\n");
  1164.         }
  1165.         else
  1166.         {
  1167.             RwClose();
  1168.             printf("Error creating the RenderWare(tm) camera\n");
  1169.         }
  1170.         exit(-1);
  1171.     }
  1172.  
  1173.  
  1174.   /*
  1175.     * The window has been resized. Therefore, it is necessary to
  1176.     * to modify the camera's viewport to be the same size as the
  1177.     * client area of the window.
  1178.     */
  1179.   RwSetCameraViewport(Camera, 0, 0, nGScrWidth, nGScrHeight-24);
  1180.  
  1181.   RwSetCameraBackdropViewportRect(Camera, 0,0,nGScrWidth,nGScrHeight-24);
  1182.  
  1183.   /* aspect ratio of 1:1 */
  1184.  
  1185.     if (nGScrWidth >= (nGScrHeight-24)) {
  1186.     RwSetCameraViewwindow(Camera,
  1187.         CREAL(1.0),
  1188.         RMul(CREAL(1.0), RDiv(INT2REAL(nGScrHeight-24), INT2REAL(nGScrWidth))));
  1189.     } else {
  1190.         RwSetCameraViewwindow(Camera,
  1191.         RMul(CREAL(1.0), RDiv(INT2REAL(nGScrWidth), INT2REAL(nGScrHeight-24))),
  1192.         CREAL(1.0));
  1193.     };
  1194.  
  1195.   /*
  1196.     * Set the camera's background color to cyan.
  1197.     */
  1198.   RwSetCameraBackColor(Camera, CREAL(0.0), CREAL(0.8), CREAL(0.8));
  1199.  
  1200.  
  1201.   RwVCMoveCamera( Camera, CREAL(0.0), CREAL(0.1), CREAL(-6.0) );
  1202.  
  1203.     /*
  1204.      * Create a scene which will contain the clumps to be rendered and the
  1205.      * light or lights illuminating those clumps . In this very simple
  1206.      * application it would be perfectly acceptable to use the default scene
  1207.      * (as returned by RwDefaultScene()) for rendering. However, it is good
  1208.      * practice to always create a scene which will be used for your rendering
  1209.      * and only use the default scene as a bag for currently unused clumps and
  1210.      * lights.
  1211.      */
  1212.  
  1213.  
  1214.     Scene = RwCreateScene();
  1215.     if (!Scene)
  1216.     {
  1217.         RwDestroyCamera(Camera);
  1218.         RwClose();
  1219.         printf("Error creating the RenderWare(tm) scene\n");
  1220.         exit(-1);
  1221.     }
  1222.  
  1223.   /*
  1224.     * Our scene will be illuminated by a directional light. The illumination
  1225.     * vector of the light is (-0.5, -1.0, -1.0) and its brightness will be 1.0.
  1226.     */
  1227.  
  1228.  
  1229.     Light = RwCreateLight( rwDIRECTIONAL, CREAL(-0.5), CREAL(-1.0), CREAL(-1.0),
  1230.              CREAL(1.2) );
  1231.  
  1232.     if (!Light)
  1233.     {
  1234.         RwDestroyScene(Scene);
  1235.         RwDestroyCamera(Camera);
  1236.         RwClose();
  1237.         printf("Error creating the RenderWare(tm) light\n");
  1238.         exit(-1);
  1239.     }
  1240.  
  1241.   /*
  1242.     * Add the new light to our scene.
  1243.     */
  1244.  
  1245.   RwAddLightToScene(Scene, Light);
  1246.  
  1247.     /*
  1248.      * Make the launch pad in the simulation
  1249.      */
  1250.  
  1251.     RwClumpBegin();
  1252.     RwVertex(CREAL(-1.0),CREAL(0.0),CREAL(-1.0));
  1253.     RwVertex(CREAL(1.0),CREAL(0.0),CREAL(-1.0));
  1254.     RwVertex(CREAL(1.0),CREAL(0.0),CREAL(1.0));
  1255.     RwVertex(CREAL(-1.0),CREAL(0.0),CREAL(1.0));
  1256.  
  1257.     RwVertex(CREAL(-0.8),CREAL(-0.1),CREAL(-0.8));
  1258.     RwVertex(CREAL(0.8),CREAL(-0.1),CREAL(-0.8));
  1259.     RwVertex(CREAL(0.8),CREAL(-0.1),CREAL(0.8));
  1260.     RwVertex(CREAL(-0.8),CREAL(-0.1),CREAL(0.8));
  1261.  
  1262.   RwSetSurface(CREAL(0.4), CREAL(0.6), CREAL(0.0));
  1263.   RwSetSurfaceColor(CREAL(0.5), CREAL(0.5), CREAL(0.5));
  1264.   RwQuad(4,3,2,1);
  1265.   RwSetSurfaceColor(CREAL(0.0), CREAL(0.5), CREAL(0.5));
  1266.  
  1267.  
  1268.   RwQuad(5,6,7,8);
  1269.   RwSetSurfaceColor(CREAL(0.4), CREAL(0.0), CREAL(0.0));
  1270.     RwQuad(4,8,7,3);
  1271.     RwQuad(1,2,6,5);
  1272.   RwSetSurfaceColor(CREAL(0.2), CREAL(0.0), CREAL(0.0));
  1273.     RwQuad(2,3,7,6);
  1274.     RwQuad(4,1,5,8);
  1275.  
  1276.     RwClumpEnd(&temp);
  1277.   RwAddHintToClump(temp, 0);
  1278.  
  1279.     RwSetClumpData(temp,(void *)(&Scene));    /* Mark as hit scene */
  1280.  
  1281.     RwAddClumpToScene(Scene, temp);
  1282.  
  1283.     ThreeDInitialized = TRUE;
  1284.   return( TRUE );
  1285. }
  1286.  
  1287.  
  1288. /****************************************************************************
  1289.  Tidy3D
  1290.  * This function shuts down the 3D (i.e. RenderWare) components of the
  1291.  * application in a polite fashion.
  1292.  
  1293.  On entry    :
  1294.  On exit    :
  1295.  */
  1296.  
  1297. static void
  1298. TidyUp3D()
  1299. {
  1300.     /*
  1301.     * Destroy the scene. This will destroy the contents of the scene,
  1302.     * i.e. any clumps and lights in that scene. In this case destroying
  1303.     * the scene will destroy the light we created in Init3D, and any
  1304.     * clumps we have loaded and not already destroyed.
  1305.     */
  1306.     RwDestroyScene(Scene);
  1307.  
  1308.     /*
  1309.     * Destroy the camera.
  1310.     */
  1311.     RwDestroyCamera(Camera);
  1312.  
  1313.     /*
  1314.     * Close the library. This will free up any internal resources and
  1315.     * textures loaded.
  1316.     */
  1317.     RwClose();
  1318. }
  1319.  
  1320.  
  1321.  
  1322. /****************************************************************************
  1323.  HandleLeftButtonDown
  1324.  
  1325.  On entry    : Mouse X
  1326.                         Mouse Y
  1327.                         Virtual Keys
  1328.  On exit    :
  1329.  */
  1330.  
  1331. static void
  1332. HandleLeftButtonDown(int x, int y, int vKeys)
  1333. {
  1334.     RwClump *cpHit;
  1335.     LaunchObject *lopObject;
  1336.  
  1337.   /* Stop warnings */
  1338.   vKeys=vKeys;
  1339.   x=x;
  1340.   y=y;
  1341.   /* Stop warnings */
  1342.  
  1343.     nGFireCount=FIRE_FRAMES;
  1344.  
  1345.     if ((nGPickStatus) &&(pGPick.type == rwPICKCLUMP)) {
  1346.         cpHit = pGPick.object.clump.clump;
  1347.         lopObject =(LaunchObject *)RwGetClumpData(cpHit);
  1348.  
  1349.         if ((lopObject)&&(lopObject == ((LaunchObject *)(&Scene))) ) {
  1350.  
  1351.         if (!bButtonDown)
  1352.         {
  1353.                  DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1354.                 DosPrintString(0,nGScrHeight-8, "Pan and Tilt Camera",nGTextCol);
  1355.         }
  1356.         else /* both must be down */
  1357.         {
  1358.                  DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1359.                 DosPrintString(0,nGScrHeight-8, "Zoom Camera",nGTextCol);
  1360.         }
  1361.  
  1362.             bButtonDown |=1;
  1363.             return;
  1364.         };
  1365.     };
  1366.  
  1367.     nGShots++;
  1368.     DisplayShots();
  1369. }
  1370.  
  1371. /****************************************************************************
  1372.  HandleRightButtonDown
  1373.  
  1374.  On entry    : Mouse X
  1375.                         Mouse Y
  1376.                         Virtual Keys
  1377.  On exit    :
  1378.  */
  1379.  
  1380. static void
  1381. HandleRightButtonDown(int x, int y, int vKeys)
  1382. {
  1383.   /* Stop warnings */
  1384.   vKeys=vKeys;
  1385.   x=x;
  1386.   y=y;
  1387.   /* Stop warnings */
  1388.  
  1389.     if (!bButtonDown)
  1390.     {
  1391.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1392.         DosPrintString(0,nGScrHeight-8, "Pan and Zoom Camera",nGTextCol);
  1393.     }
  1394.     else
  1395.     {
  1396.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1397.         DosPrintString(0,nGScrHeight-8, "Zoom Camera",nGTextCol);
  1398.     }
  1399.     bButtonDown |= 2;
  1400. }
  1401.  
  1402. /**********************************************************************/
  1403.  
  1404. /*
  1405.  * Handle the left mouse button comming back up. The basic action is
  1406.  * to turn of mouse move actions and release mouse capture.
  1407.  */
  1408.  
  1409. static void
  1410. HandleLeftButtonUp()
  1411. {
  1412.   bButtonDown &= ~1;
  1413.   if (!bButtonDown)
  1414.   {
  1415.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1416.   } else {
  1417.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1418.         DosPrintString(0,nGScrHeight-8, "Pan and Zoom Camera",nGTextCol);
  1419.     };
  1420. }
  1421.  
  1422. /**********************************************************************/
  1423.  
  1424. /*
  1425.  * Handle the right mouse button comming back up. The basic action is
  1426.  * to turn of mouse move actions and release mouse capture.
  1427.  */
  1428.  
  1429. static void
  1430. HandleRightButtonUp()
  1431. {
  1432.     bButtonDown &= ~2;
  1433.     if (!bButtonDown)
  1434.     {
  1435.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1436.     }
  1437.     else
  1438.     {
  1439.          DosPrintString(0,nGScrHeight-8,sGClear,nGTextCol);
  1440.         DosPrintString(0,nGScrHeight-8, "Pan and Tilt Camera",nGTextCol);
  1441.     };
  1442. }
  1443.  
  1444.  
  1445. /****************************************************************************
  1446.  HandleTimer
  1447.  
  1448.  On entry    :
  1449.  On exit    :
  1450.  */
  1451.  
  1452. void HandleTimer(void)
  1453. {
  1454.     /*
  1455.     * See the description of HandlePaint() for a description of this common
  1456.     * RenderWare cliche for rendering a scene and copying it to the display.
  1457.     */
  1458.  
  1459.   RwBeginCameraUpdate(Camera,NULL);
  1460.     RwClearCameraViewport(Camera);
  1461.     RwRenderScene(Scene);
  1462.     RwEndCameraUpdate(Camera);
  1463.     RwShowCameraImage(Camera, NULL);
  1464. }
  1465.  
  1466. /****************************************************************************
  1467.  HandleMouseMove
  1468.  
  1469.  * Handle a movement of the mouse. If a previous left or right mouse
  1470.  * button down event has set a mouse move mode then this function will
  1471.  * take the necessary actions. For example, pan and zooming the camera,
  1472.  * panning the light, dragging or spinning a clump etc.
  1473.  
  1474.  On entry    : Mouse x
  1475.                     : Mouse y
  1476.  On exit    :
  1477.  
  1478.  */
  1479. static void
  1480. HandleMouseMove(int x, int y)
  1481. {
  1482.     if ( bButtonDown)
  1483.     {
  1484.       int dx,dy;
  1485.       dx = x - LastX;
  1486.       dy = y - LastY;
  1487.       switch ( bButtonDown )
  1488.       {
  1489.       case 1:
  1490.         {
  1491.         RwV3d at,up;
  1492.           RwPushScratchMatrix();
  1493.           RwGetCameraLookUp(Camera, &up);
  1494.           RwRotateMatrix(RwScratchMatrix(), up.x, up.y, up.z, INT2REAL(-dx),
  1495.         rwREPLACE);
  1496.           RwGetCameraLookRight(Camera, &at);
  1497.           RwRotateMatrix(RwScratchMatrix(), at.x, at.y, at.z, INT2REAL(-dy),
  1498.         rwPOSTCONCAT);
  1499.         RwTransformCamera(Camera, RwScratchMatrix(),rwPOSTCONCAT);
  1500.           RwPopScratchMatrix();
  1501.         }
  1502.         break;
  1503.       case 2:
  1504.         RwVCMoveCamera(Camera, CREAL(0.0),CREAL(0.0), RDiv(INT2REAL(-dy),
  1505.                                 CREAL(50.0)));
  1506.         RwRotateMatrix(RwScratchMatrix(), CREAL(0.0),CREAL(1.0),CREAL(0.0),
  1507.         INT2REAL(-dx), rwREPLACE);
  1508.       RwTransformCamera(Camera, RwScratchMatrix(),rwPOSTCONCAT);
  1509.         break;
  1510.       case 3:
  1511.         RwVCMoveCamera(Camera, CREAL(0.0),CREAL(0.0), RDiv(INT2REAL(-dy),
  1512.                                 CREAL(50.0)));
  1513.         break;
  1514.       }
  1515.     }
  1516. }
  1517.  
  1518. /****************************************************************************
  1519.  DisplayHits
  1520.  
  1521.  On entry :
  1522.  On exit  :
  1523.  */
  1524.  
  1525. void DisplayHits()
  1526. {
  1527.     char buffer[10];
  1528.  
  1529.     sprintf(buffer,"%i ",nGHits);
  1530.     DosPrintString(18*8,nGScrHeight-16,buffer,nGTextCol);
  1531. }
  1532.  
  1533. /****************************************************************************
  1534.  Main Function
  1535.  */
  1536.  
  1537. void main(int nArgc,char *saArgv[])
  1538. {
  1539.     int nKey;
  1540.     int nOldMouseBut;
  1541.     int nDX,nDY;
  1542.     int nChange;
  1543.     int nCtrlShift;
  1544.     RwReal naWhite[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
  1545.     RwReal naBlack[]={CREAL(0.0),CREAL(0.0),CREAL(0.0)};
  1546.     RwMousePointer mMouse;
  1547.     RwImageConvert ciConvert;
  1548.     int nBlack,nWhite;
  1549.     RwClump *cpHit;
  1550.     LaunchObject *lopObject;
  1551.     RwPointerImage piImage;
  1552.  
  1553.   /* Stop warnings */
  1554.  
  1555.   nArgc = nArgc;
  1556.  
  1557.   /* Stop warnings */
  1558.  
  1559.     nGFireCount=0;
  1560.  
  1561.     nGHits = 0;
  1562.     nGTargets = 0;
  1563.     nGShots = 0;
  1564.  
  1565.     if (!Init3D(saArgv[0]))
  1566.     {
  1567.         exit(-1);
  1568.     };
  1569.  
  1570.   nBlack = RwDeviceControl(rwSCRGETCOLOR,0,naBlack,sizeof(naBlack));
  1571.   nWhite = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
  1572.  
  1573.     /* Create the mouse pointers */
  1574.  
  1575.     ciConvert.inimage = sGMouseArrow;
  1576.     ciConvert.w = MOUSE_ARROW_W;
  1577.     ciConvert.h = MOUSE_ARROW_H;
  1578.     ciConvert.colora = nBlack;
  1579.     ciConvert.colorb = nWhite;
  1580.     ciConvert.outstorage = NULL;
  1581.  
  1582.   RwDeviceControl(rwCHARMAPTORAW,0,&ciConvert,sizeof(ciConvert));
  1583.     pGMouseArrow = ciConvert.outstorage;
  1584.  
  1585.     ciConvert.inimage = sGMouseFire;
  1586.     ciConvert.w = MOUSE_FIRE_W;
  1587.     ciConvert.h = MOUSE_FIRE_H;
  1588.     ciConvert.outstorage = NULL;
  1589.  
  1590.   RwDeviceControl(rwCHARMAPTORAW,0,&ciConvert,sizeof(ciConvert));
  1591.     pGMouseFire = ciConvert.outstorage;
  1592.  
  1593.     ciConvert.inimage = sGMouseSight;
  1594.     ciConvert.w = MOUSE_SIGHT_W;
  1595.     ciConvert.h = MOUSE_SIGHT_H;
  1596.     ciConvert.outstorage = NULL;
  1597.  
  1598.   RwDeviceControl(rwCHARMAPTORAW,0,&ciConvert,sizeof(ciConvert));
  1599.     pGMouseSight = ciConvert.outstorage;
  1600.  
  1601.     /* Setup the launch structure */
  1602.  
  1603.     SetupLaunch(&lGLaunch);
  1604.  
  1605.     CreateBits(loaGLBits,MAX_BITS);
  1606.  
  1607.     /* Create a Black outlined White pointer */
  1608.  
  1609.   RwDeviceControl(rwPOINTERDISPLAY,0,&mMouse,sizeof(mMouse));
  1610.     LastX = mMouse.x;
  1611.     LastY = mMouse.y;
  1612.     nOldMouseBut = mMouse.buttons;
  1613.  
  1614.     nKey = DosGetKey();
  1615.  
  1616.     DisplayHits();
  1617.     DisplayTargets();
  1618.     DisplayShots();
  1619.  
  1620.     while (nKey!=27) {        /* ESC quits */
  1621.  
  1622.         if (nGFireCount) {
  1623.             nGFireCount--;
  1624.         };
  1625.  
  1626.     RwDeviceControl(rwPOINTERDISPLAY,0,&mMouse,sizeof(mMouse));
  1627.         nKey = DosGetKey();
  1628.  
  1629.         nCtrlShift = DosShiftCtrl();
  1630.  
  1631.         nGPickStatus = 0;
  1632.         if (mMouse.y<nGScrHeight-24) {
  1633.             if (RwPickScene(Scene, mMouse.x, mMouse.y, Camera, &pGPick)) {
  1634.                 if (pGPick.type==rwPICKCLUMP) {
  1635.                     cpHit = pGPick.object.clump.clump;
  1636.                     lopObject =(LaunchObject *)RwGetClumpData(cpHit);
  1637.  
  1638.                     if (lopObject) {
  1639.                         nGPickStatus = 1;
  1640.  
  1641.                         if (lopObject == ((LaunchObject *)(&Scene))) {
  1642.                             /* Its the platform */
  1643.  
  1644.                             piImage.hotx = MOUSE_ARROW_X;
  1645.                             piImage.hoty = MOUSE_ARROW_Y;
  1646.                             piImage.w = MOUSE_ARROW_W;
  1647.                             piImage.h = MOUSE_ARROW_H;
  1648.                             piImage.image= pGMouseArrow;
  1649.  
  1650.               RwDeviceControl(rwPOINTERSETIMAGE,0,&piImage,sizeof(piImage));
  1651.                         } else {
  1652.                         /* Explode the object */
  1653.                             piImage.hotx = MOUSE_FIRE_X;
  1654.                             piImage.hoty = MOUSE_FIRE_Y;
  1655.                             piImage.w = MOUSE_FIRE_W;
  1656.                             piImage.h = MOUSE_FIRE_H;
  1657.                             piImage.image= pGMouseFire;
  1658.  
  1659.               RwDeviceControl(rwPOINTERSETIMAGE,0,&piImage,sizeof(piImage));
  1660.  
  1661.                             if (nGFireCount) {
  1662.                                 /* Explode the object */
  1663.                                 CreateExplosion(&lopObject->vPos,&lopObject->vVel,20);
  1664.                                 DestroyObject(lopObject);
  1665.  
  1666.                                 nGHits++;
  1667.                                 DisplayHits();
  1668.                             };
  1669.                         };
  1670.                     };
  1671.                 };
  1672.             };
  1673.         };
  1674.  
  1675.         if (!nGPickStatus) {
  1676.             piImage.hotx = MOUSE_SIGHT_X;
  1677.             piImage.hoty = MOUSE_SIGHT_Y;
  1678.             piImage.w = MOUSE_SIGHT_W;
  1679.             piImage.h = MOUSE_SIGHT_H;
  1680.             piImage.image= pGMouseSight;
  1681.  
  1682.       RwDeviceControl(rwPOINTERSETIMAGE,0,&piImage,sizeof(piImage));
  1683.         };
  1684.  
  1685.         nDX =(mMouse.x-LastX);
  1686.         nDY =(mMouse.y-LastY);
  1687.  
  1688.         nChange = (mMouse.buttons&(2+8)) | ( (nOldMouseBut&(2+8)) >>1 );
  1689.  
  1690.         switch (nChange) {
  1691.             case 0+0:
  1692.             case 2+1:
  1693.             case 8+4:
  1694.             case 8+2+4+1: {
  1695.                 /* No change */
  1696.                 break;
  1697.             };
  1698.             case 2:
  1699.             case 8+2+4: {
  1700.  
  1701.                 /* Left Button Down */
  1702.  
  1703.                 HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1704.  
  1705.                 break;
  1706.             };
  1707.             case 8:
  1708.             case 8+2+1: {
  1709.                 /* Right Button Down */
  1710.  
  1711.  
  1712.                 HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1713.  
  1714.                 break;
  1715.             };
  1716.             case 8+1: {
  1717.                 /* Right down left Up */
  1718.  
  1719.                 HandleLeftButtonUp();
  1720.                 HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1721.  
  1722.                 break;
  1723.             };
  1724.             case 2+4: {
  1725.                 /* Right up left Down */
  1726.  
  1727.  
  1728.                 HandleRightButtonUp();
  1729.                 HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1730.  
  1731.  
  1732.                 break;
  1733.             };
  1734.             case 8+2: {
  1735.                 /* Left down RIght Down */
  1736.  
  1737.  
  1738.                 HandleRightButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1739.                 HandleLeftButtonDown(mMouse.x,mMouse.y,nCtrlShift);
  1740.  
  1741.  
  1742.                 break;
  1743.             };
  1744.             case 1+4: {
  1745.                 /* Left up Right Up */
  1746.  
  1747.  
  1748.                 HandleRightButtonUp();
  1749.                 HandleLeftButtonUp();
  1750.  
  1751.  
  1752.                 break;
  1753.             };
  1754.             case 1:
  1755.             case 8+4+1: {
  1756.                 /* Left up */
  1757.  
  1758.  
  1759.                 HandleLeftButtonUp();
  1760.  
  1761.  
  1762.                 break;
  1763.             };
  1764.             case 4:
  1765.             case 2+4+1: {
  1766.                 /* Right up */
  1767.  
  1768.  
  1769.                 HandleRightButtonUp();
  1770.  
  1771.  
  1772.                 break;
  1773.             };
  1774.         };
  1775.  
  1776.         if (nDX||nDY) {
  1777.             /* Mouse Move  */
  1778.             HandleMouseMove(mMouse.x,mMouse.y);
  1779.         };
  1780.  
  1781.         HandleLaunch(&lGLaunch);
  1782.         MoveObjects(loaGLObjects, MAX_OBJECTS, &lGLaunch);
  1783.         MoveObjects(loaGLBits, MAX_BITS, &lGLaunch);
  1784.  
  1785.         HandleTimer();
  1786.  
  1787.         LastX = mMouse.x;
  1788.         LastY = mMouse.y;
  1789.         nOldMouseBut = mMouse.buttons;
  1790.  
  1791.       frames++;
  1792.     };
  1793.  
  1794.     /*
  1795.     * Tidy up the 3D (RenderWare) components of the application.
  1796.     */
  1797.  
  1798.     TidyUp3D();
  1799.  
  1800.     exit(0);
  1801. }
  1802.  
  1803.