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

  1. /**********************************************************************
  2.  *
  3.  * File :     dosrobot.c
  4.  *
  5.  * Abstract : A very simple, sample RenderWare application for
  6.  *            Microsoft Windows 3.1. 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 calls 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 waranty.
  20.  *
  21.  * This application supports the following controls with the mouse button
  22.  * down:
  23.  *
  24.  * Control Key Depressed:
  25.  *     Pan and zoom the camera.
  26.  * No Object Picked, No Virtual Keys Depressed:
  27.  *     Pan and zoom the camera.
  28.  * No Object Picked, Shift Key Depressed:
  29.  *     Pan the light.
  30.  * Object Picked, No Virtual Keys Depressed:
  31.  *     Spin the clump or decal picked.
  32.  * Object Picked, Shift Key Depressed:
  33.  *     Drag the clump or decal pciked.
  34.  * Object Picked, Shift and Control Key Depressed:
  35.  *     Destroy the clump or decal picked.
  36.  *
  37.  * This file is a product of The Canon Research Centre Europe Ltd.
  38.  *
  39.  * This file is provided as is with no warranties of any kind and is
  40.  * provided without any obligiation on Canon Research Centre Europe Ltd.
  41.  * or Canon Inc. to assist in its use or modifiation.
  42.  *
  43.  * Canon Research Centre Europe Ltd. and Canon Inc. will not, under any
  44.  * circumstances, be liable for any lost revenue or other damages arising
  45.  * from the use of this file.
  46.  *
  47.  * Copyright (c) 1991, 1992, 1993. Canon Inc.
  48.  * All Rights Reserved.
  49.  *
  50.  **********************************************************************/
  51.  
  52. /**********************************************************************
  53.  *
  54.  * Header files.
  55.  *
  56.  **********************************************************************/
  57.  
  58. /****************************************************************************
  59.  Includes
  60.  */
  61.  
  62. #include <stdlib.h>
  63. #include <math.h>
  64. #include <string.h>
  65.  
  66. #include <i86.h>
  67.  
  68.  
  69. #include "rwlib.h"
  70. #include "rwtypes.h"
  71.  
  72. #include "rwdos.h"
  73. #include "doswrap.h"
  74.  
  75.  
  76. /**********************************************************************
  77.  *
  78.  * Application constants.
  79.  *
  80.  **********************************************************************/
  81.  
  82. #define DELETE 8
  83.  
  84. #define BOOL int
  85.  
  86. /*
  87.  * MS Windows compatible defines
  88.  */
  89.  
  90. #define MK_CONTROL 0x4
  91. #define MK_SHIFT 0x2
  92.  
  93. /*
  94.  * Other defines
  95.  */
  96.  
  97. #define DEFAULT_CAMERA_DISTANCE CREAL(-9.0)
  98.  
  99. #define M_PI CREAL(3.14159265358979323846)
  100.  
  101. /*--- Ansi Declarations */
  102. /*
  103. void LoadDemoMenu();
  104. int CheckCommandLine(LPSTR Command);
  105.  
  106. static void HandleDrop(HWND Window, HDROP Drop, char *name);
  107.  */
  108.  
  109. /**********************************************************************
  110.  *
  111.  * Type definitions.
  112.  *
  113.  **********************************************************************/
  114.  
  115. /*
  116.  * This enumerated type tells us what kind of action should be taken
  117.  * on mouse events.
  118.  */
  119. typedef enum
  120. {
  121.     MMNoAction,
  122.     MMPanAndZoomCamera,
  123.     MMPanAndLiftCamera,
  124.     MMPanLight
  125. }
  126. MMMode;
  127.  
  128. typedef enum
  129. {
  130.     APRest,
  131.     APAlert,
  132.     APLeftScan,
  133.     APRightScan,
  134.     APReach,
  135.     APGrab,
  136.     APPickUp,
  137.     APDiscard,
  138.     APOverBox,
  139.     APInBox,
  140.     APRelease
  141.  
  142. }
  143. ArmPositionType;
  144.  
  145. /*
  146.  * This enumerated type tells us what kind of animated action should
  147.  * be taken on timer messages. It is used to allow us to spin clumps
  148.  * and decals for a momentum effect.
  149.  */
  150. typedef enum
  151. {
  152.     ANoAction,
  153.     AAction
  154. }
  155. AMode;
  156.  
  157. /*
  158.  * The current camera mode.
  159.  */
  160. typedef enum
  161. {
  162.     CMTrackMouse,
  163.     CMDroppedObject,
  164.     CMDiscardObject,
  165.     CMRobotHand
  166. }
  167. CameraModeType;
  168.  
  169. /*
  170.  * This structure holds the parameters necessary for the current
  171.  * parameteric motion of a joint.
  172.  */
  173. typedef struct
  174. {
  175.     RwReal currentX;
  176.     RwReal lastX;
  177.     RwReal targetX;
  178.     RwReal currentY;
  179.     RwReal lastY;
  180.     RwReal targetY;
  181.     RwReal currentZ;
  182.     RwReal lastZ;
  183.     RwReal targetZ;
  184. }
  185. JointParams;
  186.  
  187. typedef struct _likedObjectNode
  188. {
  189.     char name[64];
  190.     int like;
  191.     struct _likedObjectNode *next;
  192. }
  193. LikedObjectNode;
  194.  
  195. /**********************************************************************
  196.  *
  197.  * Application global variables.
  198.  *
  199.  **********************************************************************/
  200.  
  201. static RwScene *Scene = NULL;
  202. static RwCamera *Camera = NULL;
  203.  
  204. /*#if 0
  205. static RwCamera *ObjectCamera = NULL;
  206. static RwCamera *HandCamera = NULL;
  207. #endif */
  208.  
  209. static RwLight *Light = NULL;
  210. static RwClump *DroppingObject = NULL;
  211. static RwClump *DeformingObject = NULL;
  212. static RwClump *DroppedObject = NULL;
  213. static RwClump *DiscardObject = NULL;
  214.  
  215. static RwClump *Robot = NULL;
  216. static RwClump *UpperArm = NULL;
  217. static RwClump *ForeArm = NULL;
  218. static RwClump *Hand = NULL;
  219. static RwClump *FirstFinger = NULL;
  220. static RwClump *SecondFinger = NULL;
  221. static RwClump *FirstFingerTip = NULL;
  222. static RwClump *SecondFingerTip = NULL;
  223.  
  224. static MMMode MouseMoveMode = MMNoAction;
  225.  
  226. static AMode AnimMode = ANoAction;
  227.  
  228. static int LastX;
  229. static int LastY;
  230.  
  231. static RwReal CameraDistance = DEFAULT_CAMERA_DISTANCE;
  232. static RwReal CamTilt = CREAL(0.0);
  233.  
  234. static RwReal JointParam;
  235.  
  236. static RwReal JointParamDelta;
  237.  
  238. static ArmPositionType ArmPosition = APRest;
  239.  
  240. static RwReal DropHeight = CREAL(10.0);
  241. static RwReal DropAcceleration;
  242. static RwReal DropX;
  243. static RwReal DropY;
  244. static RwReal DropZ;
  245. static RwReal DropTime;
  246.  
  247. static RwReal DeformingStep;
  248.  
  249. static RwReal DiscardXSpin;
  250. static RwReal DiscardYSpin;
  251. static RwReal DiscardZSpin;
  252. static RwV3d  DiscardVector;
  253. static int    DiscardStep;
  254.  
  255. static int LikeDroppedObject = 0;
  256.  
  257. static LikedObjectNode *LikedObjects = NULL;
  258.  
  259. static CameraModeType CMMode = CMTrackMouse;
  260.  
  261. static BOOL   RenderWareOpen = FALSE;
  262. static char   DropString[16] = "";
  263.  
  264. /*
  265.  * Dos globals
  266.  */
  267.  
  268. static int nGScrWidth;
  269. static int nGScrHeight;
  270.  
  271. static int nGTextColour;
  272.  
  273. static char sGClear[]="                                        ";
  274.  
  275.  
  276. /**********************************************************************
  277.  *
  278.  * Functions.
  279.  *
  280.  **********************************************************************/
  281.  
  282.  
  283. /****************************************************************************
  284.  DosPrintString
  285.  
  286.  On entry     : xcord
  287.                         : ycord
  288.                         : string
  289.                         : colour
  290.  On exit        :
  291.  */
  292.  
  293. void DosPrintString(int nX,int nY,char *sString,int nCol)
  294. {
  295.     RwPrintChar pcPrint;
  296.  
  297.     pcPrint.x = nX;
  298.     pcPrint.y = nY;
  299.     pcPrint.color = nCol;
  300.  
  301.     for (;(*sString);sString++)  {
  302.         pcPrint.c = (*sString);
  303.     RwDeviceControl(rwPRINTCHAR,0,&pcPrint,sizeof(pcPrint));
  304.         pcPrint.x+=8;
  305.     };
  306. }
  307.  
  308.  
  309. /****************************************************************************
  310.  DosTimer
  311.  
  312.  On entry    :
  313.  On exit    : Timer (in milliseconds)
  314.  */
  315.  
  316. int DosTimer(void)
  317. {
  318.     union REGS r;
  319.     int nTime;
  320.  
  321.     r.h.ah=0;
  322.  
  323.     int386(0x1a,&r,&r);
  324.  
  325.     nTime = ((r.w.cx)<<16)|(r.w.dx);
  326.  
  327.     return (nTime*55);
  328. }
  329.  
  330. /****************************************************************************
  331.  DosGetKey
  332.  
  333.  On entry    :
  334.  On exit     : Key pressed in ascii (or 0 if no key pressed)
  335.  */
  336.  
  337. int DosGetKey(void)
  338. {
  339.     union REGPACK rp;
  340.  
  341.     memset(&rp,0,sizeof(rp));
  342.     rp.h.ah = 0x06;
  343.     rp.h.dl = 0xff;
  344.  
  345.     intr(0x21,&rp);
  346.  
  347.     if (!(rp.w.flags & 0x40 )) {       /* Check Z flag */
  348.         /* Got key */
  349.  
  350.         if (rp.h.al) {
  351.             return ((int)rp.h.al);
  352.         };
  353.  
  354.         memset(&rp,0,sizeof(rp));
  355.         rp.h.ah = 0x06;
  356.         rp.h.dl = 0xff;
  357.         intr(0x21,&rp);
  358.  
  359.         if (!(rp.w.flags & 0x40)) {
  360.             return ((int)rp.h.al);
  361.         };
  362.  
  363.         return (rp.h.al|0x80);
  364.     };
  365.  
  366.     return 0;
  367. }
  368.  
  369. /****************************************************************************
  370.  DosShiftCtrl
  371.  
  372.  On entry    :
  373.  On exit    : Bit         Meaning
  374.                         0                Right Shift
  375.                         1                Left Shift
  376.                         2                Ctrl
  377.                         3                Alt
  378.                         4       Scroll Lock
  379.                         5                Num Lock
  380.                         6             Caps Lock
  381.                         7                Insert on
  382.  */
  383.  
  384. int DosShiftCtrl(void)
  385. {
  386.     union REGPACK rp;
  387.  
  388.     memset(&rp,0,sizeof(rp));
  389.  
  390.     rp.h.ah=0x02;
  391.     intr(0x16,&rp);
  392.  
  393.     return ((int)rp.h.al);
  394. }
  395.  
  396.  
  397.  
  398. /**********************************************************************/
  399.  
  400. void
  401. BeginDiscard(RwClump *clump)
  402. {
  403.     RwPushScratchMatrix();
  404.     RwGetClumpLTM(clump, RwScratchMatrix());
  405.     RwRemoveChildFromClump(clump);
  406.     RwTransformClump(clump, RwScratchMatrix(), rwREPLACE);
  407.     RwIdentityMatrix(RwScratchMatrix());
  408.     RwTransformClumpJoint(clump, RwScratchMatrix(), rwREPLACE);
  409.     DiscardObject = clump;
  410.     DiscardXSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
  411.             CREAL(30.0)), CREAL(15.0));
  412.     DiscardYSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
  413.             CREAL(30.0)), CREAL(15.0));
  414.     DiscardZSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
  415.             CREAL(30.0)), CREAL(15.0));
  416.     DiscardStep = 0;
  417.     DiscardVector.x = CREAL(0.0);
  418.     DiscardVector.y = CREAL(1.0);
  419.     DiscardVector.z = CREAL(0.0);
  420.     RwTransformVector(&DiscardVector, RwGetClumpLTM(Hand, RwScratchMatrix()));
  421.     RwNormalize(&DiscardVector);
  422.     DiscardVector.x = RDiv(DiscardVector.x, CREAL(3.0));
  423.     DiscardVector.y = RDiv(DiscardVector.y, CREAL(3.0));
  424.     DiscardVector.z = RDiv(DiscardVector.z, CREAL(3.0));
  425.     RwPopScratchMatrix();
  426. }
  427.  
  428. /**********************************************************************/
  429.  
  430. void
  431. DoDiscard()
  432. {
  433.     if (DiscardObject)
  434.     {
  435.     RwPushScratchMatrix();
  436.     RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0), CREAL(0.0),
  437.                (DiscardXSpin), rwREPLACE);
  438.     RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
  439.                (DiscardYSpin), rwPOSTCONCAT);
  440.     RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.0), CREAL(1.0),
  441.                (DiscardZSpin), rwPOSTCONCAT);
  442.     RwTransformClump(DiscardObject, RwScratchMatrix(), rwPRECONCAT);
  443.     RwTranslateMatrix(RwScratchMatrix(), DiscardVector.x, DiscardVector.y,
  444.               DiscardVector.z, rwREPLACE);
  445.     RwTransformClump(DiscardObject, RwScratchMatrix(), rwPOSTCONCAT);
  446.     RwPopScratchMatrix();
  447.     DiscardStep++;
  448.     }
  449. }
  450.  
  451. /**********************************************************************/
  452.  
  453. void
  454. EndDiscard()
  455. {
  456.     if (DiscardObject)
  457.     {
  458.     RwDestroyClump(DiscardObject);
  459.     DiscardObject = NULL;
  460.     DiscardStep = 0;
  461.     }
  462. }
  463.  
  464. /**********************************************************************/
  465.  
  466. void
  467. DoDrop()
  468. {
  469.     RwReal height;
  470.  
  471.     if (DroppingObject)
  472.     {
  473.         height = RAdd(RSub(DropHeight,
  474.                            RDiv(RMul(RMul(DropTime,
  475.                                           DropTime),
  476.                                      DropAcceleration),
  477.                                 CREAL(2.0))),
  478.                       DropY);
  479.         RwPushScratchMatrix();
  480.             RwTranslateMatrix(RwScratchMatrix(), DropX, height, DropZ, rwREPLACE);
  481.             RwTransformClump(DroppingObject, RwScratchMatrix(), rwREPLACE);
  482.         RwPopScratchMatrix();
  483.         DropTime = RAdd(DropTime, CREAL(0.1));
  484.         if (DropTime > CREAL(2.0))
  485.         {
  486.             DropTime = CREAL(0.0);
  487.             DeformingStep = CREAL(0.0);
  488.             DeformingObject = DroppingObject;
  489.             DroppingObject = NULL;
  490.         }
  491.     }
  492. }
  493.  
  494. /**********************************************************************/
  495.  
  496. void
  497. DoDeform()
  498. {
  499.     RwReal scale;
  500.     RwV3d  FUR;
  501.     RwV3d  BLL;
  502.  
  503.     if (DeformingObject)
  504.     {
  505.         scale = RMul(RSub(DeformingStep, CREAL(0.5)), CREAL(2.0));
  506.         scale = RDiv(RMul(scale, scale), CREAL(2.0));
  507.         scale = RAdd(scale, CREAL(0.5));
  508.         RwPushScratchMatrix();
  509.             RwScaleMatrix(RwScratchMatrix(), RAdd(RSub(CREAL(1.0), scale), CREAL(1.0)),
  510.                                              scale,
  511.                                              RAdd(RSub(CREAL(1.0), scale), CREAL(1.0)),
  512.                           rwREPLACE);
  513.             RwTransformClump(DeformingObject, RwScratchMatrix(), rwREPLACE);
  514.             RwGetClumpBBox(DeformingObject, &FUR, &BLL);
  515.             RwTranslateMatrix(RwScratchMatrix(), DropX, BLL.y, DropZ, rwREPLACE);
  516.             RwTransformClump(DeformingObject, RwScratchMatrix(), rwPOSTCONCAT);
  517.         RwPopScratchMatrix();
  518.         DeformingStep = RAdd(DeformingStep, CREAL(0.1));
  519.         if (DeformingStep > CREAL(1.0))
  520.         {
  521.             DeformingStep = CREAL(0.0);
  522.             DroppedObject = DeformingObject;
  523.             DeformingObject = NULL;
  524.         }
  525.     }
  526. }
  527.  
  528. /**********************************************************************/
  529.  
  530. /*
  531.  * Convert the given parameter (in range 0.0-1.0) to an output parameter
  532.  * in the range (0.0-1.0) where the curve is non-linear at the start and
  533.  * and to give an effect of acceleration, constant motion and decleration.
  534.  */
  535. RwReal
  536. VelocityMapping(RwReal p)
  537. {
  538.     int stage;
  539.     RwReal stagerange;
  540.  
  541.     /*
  542.      * The processing has three distinct stages, so identify which of the
  543.      * stages we are in.
  544.      */
  545.     stage = REAL2INT(RMul(p, CREAL(2.0)));
  546.     switch (stage)
  547.     {
  548.     case 0:
  549.     /* Acceleration. */
  550.     stagerange = RMul(CREAL(2.0), p);
  551.     return RMul(RDiv(CREAL(1.0), CREAL(2.0)), RMul(stagerange, stagerange));
  552.  
  553.     default:
  554.     /* Deceleration. */
  555.     stagerange = RSub(CREAL(1.0), RMul(RSub(p, CREAL(0.5)), CREAL(2.0)));
  556.     stagerange = RSub(CREAL(1.0), RMul(stagerange, stagerange));
  557.     return RAdd(CREAL(0.5), RMul(CREAL(0.5), stagerange));
  558.     }
  559. }
  560.  
  561. /**********************************************************************/
  562.  
  563. /*
  564.  * From the given clump, identify all the different bits of the robot
  565.  * arm and stash them away in global variables for later access.
  566.  */
  567. RwClump *
  568. FindRobotArmBits(RwClump *clump)
  569. {
  570.  
  571.     if (!(Robot = RwFindTaggedClump(clump, 1)))
  572.     {
  573.     return NULL;
  574.     }
  575.  
  576.     if (!(UpperArm = RwFindTaggedClump(Robot, 2)))
  577.     {
  578.     return NULL;
  579.     }
  580.  
  581.     if (!(ForeArm = RwFindTaggedClump(UpperArm, 3)))
  582.     {
  583.     return NULL;
  584.     }
  585.  
  586.     if (!(Hand = RwFindTaggedClump(ForeArm, 4)))
  587.     {
  588.     return NULL;
  589.     }
  590.  
  591.     if (!(FirstFinger = RwFindTaggedClump(Hand, 5)))
  592.     {
  593.     return NULL;
  594.     }
  595.  
  596.     if (!(FirstFingerTip = RwFindTaggedClump(FirstFinger, 7)))
  597.     {
  598.     return NULL;
  599.     }
  600.  
  601.     if (!(SecondFinger = RwFindTaggedClump(Hand, 6)))
  602.     {
  603.     return NULL;
  604.     }
  605.  
  606.     if (!(SecondFingerTip = RwFindTaggedClump(SecondFinger, 7)))
  607.     {
  608.     return NULL;
  609.     }
  610.  
  611.     return Robot;
  612. }
  613.  
  614. /**********************************************************************/
  615.  
  616. /*
  617.  * Initialize the joints of the robot arm for parametric motion.
  618.  */
  619. static int
  620. InitJoints()
  621. {
  622.     JointParams *params;
  623.  
  624.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  625.     {
  626.     return FALSE;
  627.     }
  628.     params->currentX = CREAL(0.0);
  629.     params->lastX = CREAL(0.0);
  630.     params->targetX = CREAL(0.0);
  631.     params->currentY = CREAL(0.0);
  632.     params->lastY = CREAL(0.0);
  633.     params->targetY = CREAL(0.0);
  634.     params->currentZ = CREAL(0.0);
  635.     params->lastZ = CREAL(0.0);
  636.     params->targetZ = CREAL(0.0);
  637.     RwSetClumpData(UpperArm, params);
  638.  
  639.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  640.     {
  641.     return FALSE;
  642.     }
  643.     params->currentX = CREAL(0.0);
  644.     params->lastX = CREAL(0.0);
  645.     params->targetX = CREAL(0.0);
  646.     params->currentY = CREAL(0.0);
  647.     params->lastY = CREAL(0.0);
  648.     params->targetY = CREAL(0.0);
  649.     params->currentZ = CREAL(0.0);
  650.     params->lastZ = CREAL(0.0);
  651.     params->targetZ = CREAL(0.0);
  652.     RwSetClumpData(ForeArm, params);
  653.  
  654.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  655.     {
  656.     return FALSE;
  657.     }
  658.     params->currentX = CREAL(0.0);
  659.     params->lastX = CREAL(0.0);
  660.     params->targetX = CREAL(0.0);
  661.     params->currentY = CREAL(0.0);
  662.     params->lastY = CREAL(0.0);
  663.     params->targetY = CREAL(0.0);
  664.     params->currentZ = CREAL(0.0);
  665.     params->lastZ = CREAL(0.0);
  666.     params->targetZ = CREAL(0.0);
  667.     RwSetClumpData(Hand, params);
  668.  
  669.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  670.     {
  671.     return FALSE;
  672.     }
  673.     params->currentX = CREAL(0.0);
  674.     params->lastX = CREAL(0.0);
  675.     params->targetX = CREAL(0.0);
  676.     params->currentY = CREAL(0.0);
  677.     params->lastY = CREAL(0.0);
  678.     params->targetY = CREAL(0.0);
  679.     params->currentZ = CREAL(0.0);
  680.     params->lastZ = CREAL(0.0);
  681.     params->targetZ = CREAL(0.0);
  682.     RwSetClumpData(FirstFinger, params);
  683.  
  684.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  685.     {
  686.     return FALSE;
  687.     }
  688.     params->currentX = CREAL(0.0);
  689.     params->lastX = CREAL(0.0);
  690.     params->targetX = CREAL(0.0);
  691.     params->currentY = CREAL(0.0);
  692.     params->lastY = CREAL(0.0);
  693.     params->targetY = CREAL(0.0);
  694.     params->currentZ = CREAL(0.0);
  695.     params->lastZ = CREAL(0.0);
  696.     params->targetZ = CREAL(0.0);
  697.     RwSetClumpData(FirstFingerTip, params);
  698.  
  699.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  700.     {
  701.     return FALSE;
  702.     }
  703.     params->currentX = CREAL(0.0);
  704.     params->lastX = CREAL(0.0);
  705.     params->targetX = CREAL(0.0);
  706.     params->currentY = CREAL(0.0);
  707.     params->lastY = CREAL(0.0);
  708.     params->targetY = CREAL(0.0);
  709.     params->currentZ = CREAL(0.0);
  710.     params->lastZ = CREAL(0.0);
  711.     params->targetZ = CREAL(0.0);
  712.     RwSetClumpData(SecondFinger, params);
  713.  
  714.     if (!(params = (JointParams *) malloc(sizeof(JointParams))))
  715.     {
  716.     return FALSE;
  717.     }
  718.     params->currentX = CREAL(0.0);
  719.     params->lastX = CREAL(0.0);
  720.     params->targetX = CREAL(0.0);
  721.     params->currentY = CREAL(0.0);
  722.     params->lastY = CREAL(0.0);
  723.     params->targetY = CREAL(0.0);
  724.     params->currentZ = CREAL(0.0);
  725.     params->lastZ = CREAL(0.0);
  726.     params->targetZ = CREAL(0.0);
  727.     RwSetClumpData(SecondFingerTip, params);
  728.  
  729.     return TRUE;
  730. }
  731.  
  732. /**********************************************************************/
  733.  
  734. static void
  735. SetClumpTargetAngleX(RwClump *clump, RwReal targetX)
  736. {
  737.     JointParams *params;
  738.  
  739.     params = (JointParams *) RwGetClumpData(clump);
  740.     params->lastX = params->currentX;
  741.     params->targetX = targetX;
  742. }
  743.  
  744. /**********************************************************************/
  745.  
  746. static void
  747. SetClumpTargetAngleY(RwClump *clump, RwReal targetY)
  748. {
  749.     JointParams *params;
  750.  
  751.     params = (JointParams *) RwGetClumpData(clump);
  752.     params->lastY = params->currentY;
  753.     params->targetY = targetY;
  754. }
  755.  
  756. /**********************************************************************/
  757.  
  758. static void
  759. SetClumpTargetAngleZ(RwClump *clump, RwReal targetZ)
  760. {
  761.     JointParams *params;
  762.  
  763.     params = (JointParams *) RwGetClumpData(clump);
  764.     params->lastZ = params->currentZ;
  765.     params->targetZ = targetZ;
  766. }
  767.  
  768. /**********************************************************************/
  769.  
  770. static void
  771. SetClumpTargetAngleXYZ(RwClump *clump, RwReal targetX, RwReal targetY,
  772.                RwReal targetZ)
  773. {
  774.     JointParams *params;
  775.  
  776.     params = (JointParams *) RwGetClumpData(clump);
  777.     params->lastX = params->currentX;
  778.     params->lastY = params->currentY;
  779.     params->lastZ = params->currentZ;
  780.     params->targetX = targetX;
  781.     params->targetY = targetY;
  782.     params->targetZ = targetZ;
  783. }
  784.  
  785. /**********************************************************************/
  786.  
  787. static void
  788. UpdateClumpTargetAngle(RwClump *clump)
  789. {
  790.     JointParams *params;
  791.  
  792.     params = (JointParams *) RwGetClumpData(clump);
  793.     params->lastX = params->currentX = params->targetX;
  794.     params->lastY = params->currentY = params->targetY;
  795.     params->lastZ = params->currentZ = params->targetZ;
  796. }
  797.  
  798. /**********************************************************************/
  799.  
  800. static void
  801. AnimateJoint(RwClump *Clump, RwReal p)
  802. {
  803.     JointParams *params;
  804.  
  805.     params = (JointParams *) RwGetClumpData(Clump);
  806.     params->currentX = RAdd(RMul(RSub(params->targetX, params->lastX),
  807.                 VelocityMapping(p)), params->lastX);
  808.     params->currentY = RAdd(RMul(RSub(params->targetY, params->lastY),
  809.                 VelocityMapping(p)), params->lastY);
  810.     params->currentZ = RAdd(RMul(RSub(params->targetZ, params->lastZ),
  811.                 VelocityMapping(p)), params->lastZ);
  812.     RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0), CREAL(0.0),
  813.            params->currentX, rwREPLACE);
  814.     RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
  815.            params->currentY, rwPOSTCONCAT);
  816.     RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.0), CREAL(1.0),
  817.            params->currentZ, rwPOSTCONCAT);
  818.     RwTransformClumpJoint(Clump, RwScratchMatrix(), rwREPLACE);
  819. }
  820.  
  821. /**********************************************************************/
  822.  
  823. static void
  824. AnimateJoints(RwReal p)
  825. {
  826.     RwPushScratchMatrix();
  827.     AnimateJoint(UpperArm, p);
  828.     AnimateJoint(ForeArm, p);
  829.     AnimateJoint(Hand, p);
  830.     AnimateJoint(FirstFinger, p);
  831.     AnimateJoint(FirstFingerTip, p);
  832.     AnimateJoint(SecondFinger, p);
  833.     AnimateJoint(SecondFingerTip, p);
  834.     RwPopScratchMatrix();
  835. }
  836.  
  837. /**********************************************************************/
  838.  
  839. static void
  840. ArmToRestPosition()
  841. {
  842.     SetClumpTargetAngleX(UpperArm, CREAL(-60.0));
  843.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  844.     SetClumpTargetAngleXYZ(ForeArm, CREAL(140.0), CREAL(0.0), CREAL(0.0));
  845.     SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  846.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
  847.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  848.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  849.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-10.0), CREAL(0.0),
  850.                CREAL(0.0));
  851. }
  852.  
  853. /**********************************************************************/
  854.  
  855. static void
  856. ArmToAlertPosition()
  857. {
  858.     SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
  859.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  860.     SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
  861.     SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(0.0), CREAL(0.0));
  862.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
  863.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(20.0), CREAL(0.0), CREAL(0.0));
  864.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  865.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-20.0), CREAL(0.0),
  866.                CREAL(0.0));
  867. }
  868.  
  869. /**********************************************************************/
  870.  
  871. static void
  872. ArmToLeftScanPosition()
  873. {
  874.     SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
  875.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  876.     SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
  877.     SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(45.0), CREAL(0.0));
  878.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
  879.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
  880.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
  881.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
  882.                CREAL(0.0));
  883. }
  884.  
  885. /**********************************************************************/
  886.  
  887. static void
  888. ArmToRightScanPosition()
  889. {
  890.     SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
  891.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  892.     SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
  893.     SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(-45.0), CREAL(0.0));
  894.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
  895.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
  896.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
  897.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
  898.                CREAL(0.0));
  899. }
  900.  
  901. /**********************************************************************/
  902.  
  903. static void
  904. ArmRotatePosition()
  905. {
  906.     SetClumpTargetAngleX(UpperArm, CREAL(-60.0));
  907.     SetClumpTargetAngleY(UpperArm, RAdd(RMul(RDiv(INT2REAL(rand()),
  908.                           INT2REAL(RAND_MAX)),
  909.                     CREAL(315.0)), CREAL(45.0)));
  910.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  911.     SetClumpTargetAngleXYZ(ForeArm, CREAL(140.0), CREAL(0.0), CREAL(0.0));
  912.     SetClumpTargetAngleXYZ(Hand, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  913.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
  914.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  915.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
  916.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-10.0), CREAL(0.0),
  917.                CREAL(0.0));
  918. }
  919.  
  920. /**********************************************************************/
  921.  
  922. static void
  923. ArmRotateUpPosition()
  924. {
  925.     SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
  926.     SetClumpTargetAngleY(UpperArm, RAdd(RMul(RDiv(INT2REAL(rand()),
  927.                           INT2REAL(RAND_MAX)),
  928.                     CREAL(315.0)), CREAL(45.0)));
  929.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  930.     SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
  931.     SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(0.0), CREAL(0.0));
  932.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
  933.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
  934.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
  935.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
  936.                CREAL(0.0));
  937. }
  938.  
  939. /**********************************************************************/
  940.  
  941. static RwReal
  942. XZToAngle(RwReal x, RwReal z)
  943. {
  944.     RwReal Temp;
  945.  
  946.     /* **** use table for atn() in real life **** */
  947.  
  948.     Temp = RMul(RDiv(FL2REAL(atan(REAL2FL(RDiv(z, x)))), RMul(M_PI,
  949.                                   CREAL(2.0))),
  950.         CREAL(360));
  951.     if (x < CREAL(0.0))
  952.     {
  953.     return RAdd(Temp, CREAL(180.0));
  954.     }
  955.     else if (z < CREAL(0.0))
  956.     {
  957.     return RAdd(Temp, CREAL(360.0));
  958.     }
  959.     else
  960.     {
  961.     return Temp;
  962.     }
  963. }
  964.  
  965. /**********************************************************************/
  966.  
  967. static void
  968. ArmReachForPosition(RwReal x, RwReal y, RwReal z)
  969. {
  970.     RwReal angle;
  971.     RwReal shoulderangle;
  972.     RwReal elbowangle;
  973.     RwReal wristangle;
  974.     RwReal hyp;
  975.  
  976.     /* Stop warnings */
  977.     y=y;
  978.  
  979.     angle = RSub(CREAL(450.0), XZToAngle(x, z));
  980.     if (angle < CREAL(0.0))
  981.     angle = RAdd(angle, CREAL(360.0));
  982.     if (angle >= CREAL(360.0))
  983.     angle = RSub(angle, CREAL(360.0));
  984.  
  985.     hyp = RSqrt(RAdd(RMul(x, x), RMul(z, z)));
  986.  
  987.     /* ***** use table for acos() ****** */
  988.     shoulderangle = RMul(CREAL(360.0),
  989.              RDiv(FL2REAL(acos REAL2FL(RDiv(RDiv(hyp, CREAL(2.0)),
  990.                             CREAL(2.5)))),
  991.                   RMul(M_PI, CREAL(2.0))));
  992.  
  993.     elbowangle = RSub(CREAL(180.0), RMul(CREAL(2.0), RSub(CREAL(90.0),
  994.                               shoulderangle)));
  995.     wristangle = RSub(CREAL(90.0), shoulderangle);
  996.  
  997.     SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
  998.                CREAL(0.0));
  999.     SetClumpTargetAngleXYZ(ForeArm, elbowangle, CREAL(0.0), CREAL(0.0));
  1000.     SetClumpTargetAngleXYZ(Hand, wristangle, CREAL(0.0), CREAL(0.0));
  1001.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-80.0), CREAL(0.0), CREAL(0.0));
  1002.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1003.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(80.0), CREAL(0.0), CREAL(0.0));
  1004.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1005. }
  1006.  
  1007. /**********************************************************************/
  1008.  
  1009. static void
  1010. ArmGrab()
  1011. {
  1012.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-45.0), CREAL(0.0), CREAL(0.0));
  1013.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  1014.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(45.0), CREAL(0.0), CREAL(0.0));
  1015.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-90.0), CREAL(0.0),
  1016.                CREAL(0.0));
  1017. }
  1018.  
  1019. /**********************************************************************/
  1020.  
  1021. static void
  1022. ArmPickUp()
  1023. {
  1024.     SetClumpTargetAngleX(UpperArm, CREAL(0.0));
  1025.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  1026.     SetClumpTargetAngleXYZ(ForeArm, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  1027.     SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  1028. }
  1029.  
  1030. /**********************************************************************/
  1031.  
  1032. static void
  1033. ArmRelease()
  1034. {
  1035.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-55.0), CREAL(0.0), CREAL(0.0));
  1036.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(45.0), CREAL(0.0), CREAL(0.0));
  1037.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(55.0), CREAL(0.0), CREAL(0.0));
  1038.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-45.0), CREAL(0.0),
  1039.                CREAL(0.0));
  1040. }
  1041.  
  1042. /**********************************************************************/
  1043.  
  1044. static void
  1045. ArmDiscard()
  1046. {
  1047.     SetClumpTargetAngleX(UpperArm, CREAL(-55.0));
  1048.     SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
  1049.     SetClumpTargetAngleXYZ(ForeArm, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1050.     SetClumpTargetAngleXYZ(Hand, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1051.     SetClumpTargetAngleXYZ(FirstFinger, CREAL(-90.0), CREAL(0.0), CREAL(0.0));
  1052.     SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1053.     SetClumpTargetAngleXYZ(SecondFinger, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  1054.     SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
  1055. }
  1056.  
  1057. /**********************************************************************/
  1058.  
  1059. static void
  1060. ArmOverBox()
  1061. {
  1062.     RwReal angle;
  1063.     RwReal shoulderangle;
  1064.     RwReal hyp;
  1065.  
  1066.     angle = RSub(CREAL(450.0), XZToAngle(CREAL(-2.0), CREAL(-2.0)));
  1067.     if (angle < CREAL(0.0))
  1068.     angle = RAdd(angle, CREAL(360.0));
  1069.     if (angle >= CREAL(360.0))
  1070.     angle = RSub(angle, CREAL(360.0));
  1071.  
  1072.     hyp = RSub(RSqrt(CREAL(8.0)), CREAL(2.5));
  1073.     shoulderangle = RMul(RDiv(FL2REAL(acos REAL2FL(RDiv(hyp, CREAL(2.5)))),
  1074.                   RMul(M_PI, CREAL(2.0))), CREAL(360));
  1075.  
  1076.     SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
  1077.                CREAL(0.0));
  1078.     SetClumpTargetAngleXYZ(ForeArm, shoulderangle, CREAL(0.0), CREAL(0.0));
  1079.     SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
  1080. }
  1081.  
  1082. /**********************************************************************/
  1083.  
  1084. static void
  1085. ArmPutInBox()
  1086. {
  1087.     RwReal angle;
  1088.     RwReal shoulderangle;
  1089.     RwReal elbowangle;
  1090.     RwReal wristangle;
  1091.     RwReal hyp;
  1092.  
  1093.     angle = RSub(CREAL(450.0), XZToAngle(CREAL(-2.0), CREAL(-2.0)));
  1094.     if (angle < CREAL(0.0))
  1095.     angle = RAdd(angle, CREAL(360.0));
  1096.     if (angle >= CREAL(360.0))
  1097.     angle = RSub(angle, CREAL(360.0));
  1098.  
  1099.     hyp = RSqrt(CREAL(8.0));
  1100.  
  1101.     shoulderangle = RMul(RDiv(FL2REAL(acos REAL2FL(RDiv(RDiv(hyp, CREAL(2.0)),
  1102.                             CREAL(2.5)))),
  1103.                   RMul(M_PI, CREAL(2.0))), CREAL(360));
  1104.  
  1105.     elbowangle = RSub(CREAL(180.0), RMul(CREAL(2.0), RSub(CREAL(90.0),
  1106.                               shoulderangle)));
  1107.  
  1108.     wristangle = RSub(CREAL(90.0), shoulderangle);
  1109.  
  1110.     SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
  1111.                CREAL(0.0));
  1112.     SetClumpTargetAngleXYZ(ForeArm, elbowangle, CREAL(0.0), CREAL(0.0));
  1113.     SetClumpTargetAngleXYZ(Hand, wristangle, CREAL(0.0), CREAL(0.0));
  1114. }
  1115.  
  1116. /**********************************************************************/
  1117.  
  1118. static void
  1119. UpdateArmPosition()
  1120. {
  1121.     UpdateClumpTargetAngle(UpperArm);
  1122.     UpdateClumpTargetAngle(ForeArm);
  1123.     UpdateClumpTargetAngle(Hand);
  1124.     UpdateClumpTargetAngle(FirstFinger);
  1125.     UpdateClumpTargetAngle(FirstFingerTip);
  1126.     UpdateClumpTargetAngle(SecondFinger);
  1127.     UpdateClumpTargetAngle(SecondFingerTip);
  1128. }
  1129.  
  1130. /**********************************************************************/
  1131.  
  1132. /*
  1133.  * This function initializes the 3D (i.e. RenderWare) components of the
  1134.  * application. This function opens the RenderWare library, creates a camera,
  1135.  * a scene, a light and loads an initial clump.
  1136.  */
  1137. static BOOL
  1138. Init3D(void)
  1139. {
  1140.     RwClump *Clump;
  1141.     char *title;
  1142.     int fixed, debugging;
  1143.         long nError;
  1144.     RwReal naWhite[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
  1145.  
  1146.     if (!RwOpen("DOSMOUSE", &nError))
  1147.     {
  1148.         printf("Unable to access renderware!!\n");
  1149.         switch (nError) {
  1150.             case E_RW_DOS_MODE_UNAVAILABLE: {
  1151.                printf("The installed VESA card is unable to switch to the resolution");
  1152.                 printf(" requested.\n");
  1153.                 printf("Either install a different video adapter or use a ");
  1154.                 printf("supported video mode.");
  1155.                 break;
  1156.             };
  1157.             case E_RW_DOS_NO_VESA_BIOS: {
  1158.                 printf("A VESA bios is unavailable on this machine.\n");
  1159.                 printf("Either use a VESA compatible Video Adapter or install a ");
  1160.                 printf("VESA bios emulation TSR.\n");
  1161.                 break;
  1162.             };
  1163.             case E_RW_DOS_INCOMPATIBLE_BIOS: {
  1164.                 printf("The VESA bios on this machine is not of high enough version ");
  1165.                 printf("to function\ncorrectly with RenderWare. Use a version 1.0 or");
  1166.                 printf(" higher VESA bios or TSR.\n");
  1167.                 break;
  1168.             };
  1169.             case E_RW_DOS_NO_MOUSE: {
  1170.                 printf("No Microsoft compatible mouse driver present.\n");
  1171.                 printf("Install a microsoft compatible mouse driver and try again.\n");
  1172.                 break;
  1173.             };
  1174.             default: {
  1175.                 printf("Unknown Error !!!!!!!!!!!!!!!\n");
  1176.                 break;
  1177.             };
  1178.         };
  1179.         return FALSE;
  1180.     }
  1181.  
  1182.     /* Set up display parametere */
  1183.  
  1184.   RwGetDeviceInfo(rwSCRHEIGHT,&nGScrHeight,sizeof(nGScrHeight));
  1185.   RwGetDeviceInfo(rwSCRWIDTH,&nGScrWidth,sizeof(nGScrWidth));
  1186.   nGTextColour = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
  1187.  
  1188.     /* Set the path */
  1189.  
  1190.     RwSetShapePath("SCRIPTS", rwPRECONCAT);
  1191.     RwSetShapePath("TEXTURES", rwPRECONCAT);
  1192.  
  1193.     /* Display status message */
  1194.  
  1195.     RwGetSystemInfo(rwFIXEDPOINTLIB, &fixed,sizeof(fixed));
  1196.     RwGetSystemInfo(rwDEBUGGINGLIB, &debugging,sizeof(debugging));
  1197.     if ((fixed) && (debugging))
  1198.     title = "Robot (Fixed & Debugging)";
  1199.     else if (fixed)
  1200.     title = "Robot (Fixed Point)";
  1201.     else if (debugging)
  1202.     title = "Robot (Debugging)";
  1203.     else
  1204.     title = "Robot (Floating Point)";
  1205.  
  1206.     DosPrintString(0,nGScrHeight-16,title,nGTextColour);
  1207.  
  1208.         /* Create camera */
  1209.  
  1210.     Camera = RwCreateCamera(nGScrWidth,nGScrHeight-24, NULL);
  1211.     if (!Camera)
  1212.     {
  1213.         /*
  1214.           * As with RwOpen(), the most common cause for a failure to create
  1215.           * a camera is insufficient memory so we will explicitly check for
  1216.           * this condition and report it. Otherwise a general error is issued.
  1217.           */
  1218.         if (RwGetError() == E_RW_NOMEM)
  1219.         {
  1220.             RwClose();
  1221.             printf("Insufficient memory to create the RenderWare(tm) camera\n");
  1222.         }
  1223.         else
  1224.         {
  1225.             RwClose();
  1226.             printf("Error creating the RenderWare(tm) camera\n");
  1227.         }
  1228.         exit(-1);
  1229.     }
  1230.  
  1231.   RwSetCameraViewport(Camera, 0, 0, nGScrWidth, nGScrHeight);
  1232.  
  1233.  
  1234.  
  1235.     RwSetCameraBackColor(Camera, CREAL(0.3), CREAL(0.0), CREAL(0.0));
  1236.  
  1237.         RwPanCamera(Camera, CREAL(45.0));
  1238.     RwVCMoveCamera(Camera, CREAL(0.0), CREAL(3.0), CameraDistance);
  1239.  
  1240.     /*
  1241.     * Another change from previous versions of RenderWare is the amount of
  1242.     * prespective generated by the default viewwindow size. When converting
  1243.     * applications from previous versions of RenderWare the simple rule is
  1244.     * to divide the viewwindow size by five to get the same prespective effect
  1245.     * as given under previous versions.
  1246.     */
  1247.     if (nGScrWidth >= nGScrHeight) {
  1248.         RwSetCameraViewwindow(Camera,
  1249.                               CREAL(1.0),
  1250.                               RMul(CREAL(1.0),
  1251.                                                     RDiv(INT2REAL(nGScrHeight),
  1252.                                                     INT2REAL(nGScrWidth))));
  1253.     } else {
  1254.         RwSetCameraViewwindow(Camera,
  1255.                               RMul(CREAL(1.0),
  1256.                                                     RDiv(INT2REAL(nGScrWidth),
  1257.                                                     INT2REAL(nGScrHeight))),
  1258.                               CREAL(1.0));
  1259.     };
  1260.  
  1261.     /*
  1262.     * Create a scene which will contain the clumps to be rendered and the
  1263.     * light or lights illuminating those clumps . In this very simple
  1264.     * application it would be perfectly acceptable to use the default scene
  1265.     * (as returned by RwDefaultScene()) for rendering. However, it is good
  1266.     * practice to always create a scene which will be used for your rendering
  1267.     * and only use the default scene as a bag for currently unused clumps and
  1268.     * lights.
  1269.     */
  1270.  
  1271.     Scene = RwCreateScene();
  1272.     if (!Scene)
  1273.     {
  1274.         RwDestroyCamera(Camera);
  1275.         RwClose();
  1276.         printf("Error creating the RenderWare(tm) scene\n");
  1277.         exit(-1);
  1278.     }
  1279.  
  1280.  
  1281.   Light = RwCreateLight(rwDIRECTIONAL, CREAL(0.1), CREAL(-1.0), CREAL(-0.3),
  1282.               CREAL(1.0));
  1283.     if (!Light)
  1284.     {
  1285.         RwDestroyScene(Scene);
  1286.         RwDestroyCamera(Camera);
  1287.         RwClose();
  1288.         printf("Error creating the RenderWare(tm) light\n");
  1289.         exit(-1);
  1290.     }
  1291.  
  1292.      RwAddLightToScene(Scene, Light);
  1293.  
  1294.  
  1295.     Clump = RwReadShape("roandfl.rwx");
  1296.     if (!Clump)
  1297.     {
  1298.         RwDestroyScene(Scene);
  1299.         if (RwGetError() == E_RW_NOMEM)
  1300.         {
  1301.                     RwClose();
  1302.                     printf("Could not read script file roandfl.rwx\n");
  1303.         }
  1304.         else
  1305.         {
  1306.                     RwClose();
  1307.                 printf("Could not read script file roandfl.rwx\n");
  1308.         }
  1309.                 return FALSE;
  1310.     }
  1311.  
  1312.     RwAddClumpToScene(Scene, Clump);
  1313.  
  1314.     if (!FindRobotArmBits(Clump))
  1315.     {
  1316.         RwDestroyScene(Scene);
  1317.         RwClose();
  1318.  
  1319.                 printf("Internal error in structure of Robot\n");
  1320.     return FALSE;
  1321.     }
  1322.  
  1323.     if (!InitJoints())
  1324.     {
  1325.         RwDestroyScene(Scene);
  1326.         RwClose();
  1327.                 printf("Internal error initializing Robot Arm\n");
  1328.     return FALSE;
  1329.     }
  1330.  
  1331.     AnimMode = AAction;
  1332.     ArmPosition = APRest;
  1333.     ArmToRestPosition();
  1334.     JointParam = CREAL(0.0);
  1335.     JointParamDelta = CREAL(0.03);
  1336.  
  1337.         /* Display Menu */
  1338.  
  1339.         DosPrintString(0,nGScrHeight-24,"Ball    Eggs    Torus   Banana",nGTextColour);
  1340.  
  1341.  
  1342.     RenderWareOpen = TRUE;
  1343.  
  1344.     return TRUE;
  1345. }
  1346.  
  1347. /**********************************************************************/
  1348.  
  1349. /*
  1350.  * This function shuts the 3D (i.e. RenderWare) components of the library
  1351.  * down in a polite fashion.
  1352.  */
  1353. static void
  1354. TidyUp3D()
  1355. {
  1356.     if (Scene)
  1357.     RwDestroyScene(Scene);
  1358.     if (Camera)
  1359.     RwDestroyCamera(Camera);
  1360.  
  1361.         RwClose();
  1362. }
  1363.  
  1364. /*************************************************************************/
  1365.  
  1366. static void
  1367. HandleRightButtonDown(int x, int y, int VKeys)
  1368. {
  1369.   /* Stop warnings */
  1370.   x=x;
  1371.   y=y;
  1372.   VKeys=VKeys;
  1373.  
  1374. }
  1375.  
  1376. static void
  1377. HandleRightButtonUp(void)
  1378. {
  1379. }
  1380.  
  1381.  
  1382. /**********************************************************************/
  1383.  
  1384. /*
  1385.  * This functions handles the left mouse button going down. Its main
  1386.  * job is to determine the kind of action to be taken when the mouse
  1387.  * moves, such as spinning a clump, or panning the camera. This involves
  1388.  * examining the virtual keys that were depressed when the mouse button
  1389.  * went down and attempting to pick a clump or decal under the the
  1390.  * mouse pointer position when the mouse went down.
  1391.  */
  1392. static void
  1393. HandleLeftButtonDown(int x, int y, int VKeys)
  1394. {
  1395.         if ((y>nGScrHeight-24)&&(y<nGScrHeight-16)) {
  1396.             switch(x>>6) {
  1397.                 case 0:
  1398.                 HandleDrop("ball.rwx");
  1399.                 break;
  1400.                 case 1:
  1401.                 HandleDrop("eggs.rwx");
  1402.                 break;
  1403.                 case 2:
  1404.                 HandleDrop("torus.rwx");
  1405.                 break;
  1406.                 case 3:
  1407.                 HandleDrop("banana.rwx");
  1408.                 break;
  1409.                 default:
  1410.                 break;
  1411.             };
  1412.             return;
  1413.         };
  1414.  
  1415.         if (VKeys & MK_SHIFT)
  1416.     {
  1417.     MouseMoveMode = MMPanAndLiftCamera;
  1418.             RwDPointerRemove();
  1419.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1420.             DosPrintString(0,nGScrHeight-8,"Pan and Tilt Camera",nGTextColour);
  1421.     }
  1422.     else if (VKeys & MK_CONTROL)
  1423.     {
  1424.     MouseMoveMode = MMPanLight;
  1425.             RwDPointerRemove();
  1426.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1427.             DosPrintString(0,nGScrHeight-8,"Rotate Light",nGTextColour);
  1428.     }
  1429.     else
  1430.     {
  1431.     MouseMoveMode = MMPanAndZoomCamera;
  1432.             RwDPointerRemove();
  1433.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1434.             DosPrintString(0,nGScrHeight-8,"Pan and Zoom Camera",nGTextColour);
  1435.     }
  1436.  
  1437.     if (MouseMoveMode != MMNoAction)
  1438.     {
  1439.         LastX = x;
  1440.         LastY = y;
  1441.     }
  1442.  
  1443. }
  1444.  
  1445. /**********************************************************************/
  1446.  
  1447. /*
  1448.  * Handle a movement of the mouse. If a previous left mouse button
  1449.  * down event has set a mouse move mode then this function will take
  1450.  * the necessary actions. For example, pan and zooming the camera,
  1451.  * panning the light, dragging or spinning a clump etc.
  1452.  */
  1453. static void
  1454. HandleMouseMove(int x, int y)
  1455. {
  1456.  
  1457.     switch (MouseMoveMode)
  1458.     {
  1459.     case MMNoAction:
  1460.     break;
  1461.  
  1462.     case MMPanAndZoomCamera:
  1463.     RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), -CameraDistance);
  1464.     RwTiltCamera(Camera, -CamTilt);
  1465.     RwPanCamera(Camera, INT2REAL(LastX - x));
  1466.     CameraDistance = RAdd(CameraDistance, RDiv(INT2REAL(LastY - y),
  1467.                            CREAL(10.0)));
  1468.     RwTiltCamera(Camera, CamTilt);
  1469.     RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CameraDistance);
  1470.     break;
  1471.  
  1472.     case MMPanAndLiftCamera:
  1473.     RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), -CameraDistance);
  1474.     RwTiltCamera(Camera, -CamTilt);
  1475.     RwPanCamera(Camera, INT2REAL(LastX - x));
  1476.     CamTilt += INT2REAL(LastY - y);
  1477.     RwTiltCamera(Camera, CamTilt);
  1478.     RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CameraDistance);
  1479.     break;
  1480.  
  1481.     case MMPanLight:
  1482.     RwPushScratchMatrix();
  1483.     RwRotateMatrix(RwScratchMatrix(),
  1484.                CREAL(0.0), CREAL(1.0), CREAL(0.0),
  1485.                INT2REAL(x - LastX), rwREPLACE);
  1486.     RwRotateMatrix(RwScratchMatrix(),
  1487.                CREAL(1.0), CREAL(0.0), CREAL(0.0),
  1488.                INT2REAL(y - LastY), rwPOSTCONCAT);
  1489.   RwTransformLight(Light, RwScratchMatrix(),rwPOSTCONCAT);
  1490.     RwPopScratchMatrix();
  1491.     break;
  1492.     }
  1493.  
  1494.     LastX = x;
  1495.     LastY = y;
  1496. }
  1497.  
  1498. /**********************************************************************/
  1499.  
  1500. /*
  1501.  * Handle the left mouse button comming back up. The basic action is
  1502.  * to turn of mouse move actions, and release mouse capture. Also,
  1503.  * if the previous mouse move action was a spin then this function will
  1504.  * turn on animation to continue the spin (and the objects "momentum").
  1505.  */
  1506. static void
  1507. HandleLeftButtonUp(void)
  1508. {
  1509.     if (MouseMoveMode != MMNoAction)
  1510.     {
  1511.             RwDPointerRemove();
  1512.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1513.     MouseMoveMode = MMNoAction;
  1514.     }
  1515. }
  1516.  
  1517. /**********************************************************************/
  1518.  
  1519. static void
  1520. HandleDrop(char *name)
  1521. {
  1522.     char Path[_MAX_PATH];
  1523.     RwV3d BLL, FUR;
  1524.     RwReal Angle;
  1525.     RwReal Radius;
  1526.     LikedObjectNode *Node;
  1527.     char buffer[256];
  1528.     int i;
  1529.  
  1530.     strcpy(Path, name);         /* else use supplied filename */
  1531.  
  1532.     if ((!DroppedObject) && (!DroppingObject))
  1533.     {
  1534.     if (DroppingObject = RwReadShape(Path))
  1535.     {
  1536.             for (i = strlen(Path); i && (Path[i-1] != '\\'); i--)
  1537.                 ;
  1538.             strcpy (DropString, &Path[i]);
  1539.  
  1540.  
  1541.             RwDPointerRemove();
  1542.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1543.  
  1544.         for (Node = LikedObjects; Node; Node = Node ->next)
  1545.         {
  1546.         if (strcmp(Node ->name, Path) == 0)
  1547.               break;
  1548.         }
  1549.  
  1550.         if (Node)
  1551.         {
  1552.         LikeDroppedObject = Node ->like;
  1553.         }
  1554.         else
  1555.         {
  1556.         if ((rand() & 0x0003)<2)
  1557.         {
  1558.             LikeDroppedObject = 0;
  1559.         }
  1560.         else
  1561.         {
  1562.             LikeDroppedObject = 1;
  1563.         }
  1564.         if (Node = (LikedObjectNode *) malloc(sizeof(LikedObjectNode)))
  1565.         {
  1566.             strcpy(Node ->name, Path);
  1567.             Node ->like = LikeDroppedObject;
  1568.             Node ->next = LikedObjects;
  1569.             LikedObjects = Node;
  1570.         }
  1571.         }
  1572.  
  1573.         Angle = RSub(RMul(CREAL(180.0), RDiv(INT2REAL(rand()),
  1574.                          INT2REAL(RAND_MAX))),
  1575.              CREAL(90));
  1576.  
  1577.         Radius = RAdd(RMul(CREAL(3), RDiv(INT2REAL(rand()),
  1578.                           INT2REAL(RAND_MAX))), CREAL(1));
  1579.  
  1580.         DropX = RMul(Radius, FL2REAL(cos REAL2FL(RMul(RDiv(Angle,
  1581.                                    CREAL(360)),
  1582.                               RMul(M_PI,
  1583.                                    CREAL(2))))));
  1584.  
  1585.         DropZ = RMul(Radius, FL2REAL(sin REAL2FL(RMul(RDiv(Angle,
  1586.                                    CREAL(360)),
  1587.                               RMul(M_PI,
  1588.                                    CREAL(2))))));
  1589.  
  1590.         RwNormalizeClump(DroppingObject);
  1591.         RwPushScratchMatrix();
  1592.         RwGetClumpBBox(DroppingObject, &BLL, &FUR);
  1593.             DropAcceleration = RDiv(DropHeight, CREAL(2.0));
  1594.             DropY      = -BLL.y;
  1595.             DropTime   = CREAL(0.0);
  1596.         RwTranslateMatrix(RwScratchMatrix(), DropX, RAdd(DropHeight, DropY), DropZ,
  1597.                   rwREPLACE);
  1598.         RwTransformClump(DroppingObject, RwScratchMatrix(), rwPOSTCONCAT);
  1599.         RwPopScratchMatrix();
  1600.  
  1601.         RwAddClumpToScene(Scene, DroppingObject);
  1602.     }
  1603.     else
  1604.     {
  1605.             if (RwGetError() == E_RW_NOMEM)
  1606.             {
  1607.                 sprintf(buffer, "Insufficient memory for %s",
  1608.                         Path);
  1609.             RwDPointerRemove();
  1610.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1611.             DosPrintString(0,nGScrHeight-8,buffer,nGTextColour);
  1612.  
  1613.             }
  1614.             else
  1615.             {
  1616.                 sprintf(buffer, "Error reading %s", Path);
  1617.             RwDPointerRemove();
  1618.             DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
  1619.             DosPrintString(0,nGScrHeight-8,buffer,nGTextColour);
  1620.             }
  1621.  
  1622.     }
  1623.     }
  1624. }
  1625.  
  1626. /**********************************************************************/
  1627.  
  1628. static void
  1629. HandleChar(int WParam)
  1630. {
  1631.     RwCamera *Cam;
  1632.  
  1633.     switch (WParam)
  1634.     {
  1635.     case '0':
  1636.     CMMode = CMTrackMouse;
  1637.     Cam = Camera;
  1638.     break;
  1639.     case '1':
  1640.     if (DroppedObject)
  1641.     {
  1642.         CMMode = CMDroppedObject;
  1643.     }
  1644.     else if (DiscardObject)
  1645.     {
  1646.         CMMode = CMDiscardObject;
  1647.     }
  1648.     else
  1649.     {
  1650.         CMMode = CMTrackMouse;
  1651.         Cam = Camera;
  1652.     }
  1653.     break;
  1654.     case '2':
  1655.     CMMode = CMRobotHand;
  1656.     break;
  1657.     default:
  1658.     CMMode = CMTrackMouse;
  1659.     Cam = Camera;
  1660.     break;
  1661.     }
  1662.     RwInvalidateCameraViewport(Cam);
  1663. }
  1664.  
  1665. /**********************************************************************/
  1666.  
  1667. static void
  1668. HandleTimer(void)
  1669. {
  1670.  
  1671.  
  1672.         RwV3d Origin;
  1673.     RwV3d BLL, FUR;
  1674.     RwCamera *Cam;
  1675.  
  1676.     if (DiscardObject)
  1677.     {
  1678.     DoDiscard();
  1679.     if (DiscardStep > 150)
  1680.     {
  1681.         if (CMMode == CMDiscardObject)
  1682.         {
  1683.         CMMode = CMTrackMouse;
  1684.         RwInvalidateCameraViewport(Camera);
  1685.         }
  1686.         EndDiscard();
  1687.     }
  1688.     }
  1689.  
  1690.     if (DroppingObject)
  1691.         DoDrop();
  1692.  
  1693.     if (DeformingObject)
  1694.         DoDeform();
  1695.  
  1696.     if (AnimMode != ANoAction)
  1697.     {
  1698.     AnimateJoints(JointParam);
  1699.  
  1700.     JointParam = RAdd(JointParam, JointParamDelta);
  1701.  
  1702.     if (JointParam > CREAL(1.0))
  1703.     {
  1704.         UpdateArmPosition();
  1705.         switch (ArmPosition)
  1706.         {
  1707.         case APRest:
  1708.         if (DroppedObject)
  1709.         {
  1710.             AnimMode = AAction;
  1711.             ArmPosition = APReach;
  1712.             ArmReachForPosition(DropX, CREAL(0.0), DropZ);
  1713.             JointParam = CREAL(0.0);
  1714.             JointParamDelta = CREAL(0.05);
  1715.         }
  1716.         else
  1717.         {
  1718.             AnimMode = ANoAction;
  1719.         }
  1720.         break;
  1721.         case APAlert:
  1722.         if (DroppedObject)
  1723.         {
  1724.             AnimMode = AAction;
  1725.             ArmPosition = APReach;
  1726.             ArmReachForPosition(DropX, CREAL(0.0), DropZ);
  1727.             JointParam = CREAL(0.0);
  1728.             JointParamDelta = CREAL(0.05);
  1729.         }
  1730.         else
  1731.         {
  1732.             AnimMode = AAction;
  1733.             ArmPosition = APLeftScan;
  1734.             JointParamDelta = CREAL(0.04);
  1735.             ArmToLeftScanPosition();
  1736.         }
  1737.         break;
  1738.         case APLeftScan:
  1739.         if (DroppedObject)
  1740.         {
  1741.             AnimMode = AAction;
  1742.             ArmPosition = APReach;
  1743.             ArmReachForPosition(DropX, CREAL(0.0), DropZ);
  1744.             JointParam = CREAL(0.0);
  1745.             JointParamDelta = CREAL(0.05);
  1746.         }
  1747.         else if ((rand() & 0x03) != 0x03)
  1748.         {
  1749.             AnimMode = AAction;
  1750.             JointParamDelta = CREAL(0.06);
  1751.             ArmPosition = APRightScan;
  1752.             ArmToRightScanPosition();
  1753.         }
  1754.         else if ((rand() & 0x03) != 0x03)
  1755.         {
  1756.             AnimMode = AAction;
  1757.             JointParamDelta = CREAL(0.05);
  1758.             ArmRotateUpPosition();
  1759.         }
  1760.         else
  1761.         {
  1762.             AnimMode = AAction;
  1763. /*            JointParamDelta = CREAL(0.03); */
  1764.             JointParamDelta = CREAL(0.07);
  1765.             ArmPosition = APRest;
  1766.             ArmToRestPosition();
  1767.         }
  1768.         break;
  1769.         case APRightScan:
  1770.         if (DroppedObject)
  1771.         {
  1772.             AnimMode = AAction;
  1773.             ArmPosition = APReach;
  1774.             ArmReachForPosition(DropX, CREAL(0.0), DropZ);
  1775.             JointParam = CREAL(0.0);
  1776.             JointParamDelta = CREAL(0.05);
  1777.         }
  1778.         else if ((rand() & 0x03) != 0x03)
  1779.         {
  1780.             AnimMode = AAction;
  1781.             JointParamDelta = CREAL(0.06);
  1782.             ArmPosition = APLeftScan;
  1783.             ArmToLeftScanPosition();
  1784.         }
  1785.         else if ((rand() & 0x03) != 0x03)
  1786.         {
  1787.             AnimMode = AAction;
  1788.             JointParamDelta = CREAL(0.05);
  1789.             ArmRotateUpPosition();
  1790.         }
  1791.         else
  1792.         {
  1793.             AnimMode = AAction;
  1794. /*            JointParamDelta = CREAL(0.03); */
  1795.             JointParamDelta = CREAL(0.07);
  1796.             ArmPosition = APRest;
  1797.             ArmToRestPosition();
  1798.         }
  1799.         break;
  1800.         case APReach:
  1801.         AnimMode = AAction;
  1802.         JointParamDelta = CREAL(0.05);
  1803.         ArmPosition = APGrab;
  1804.         ArmGrab();
  1805.         break;
  1806.         case APGrab:
  1807.         RwPushScratchMatrix();
  1808.         RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0),
  1809.                    CREAL(0.0), CREAL(180.0), rwREPLACE);
  1810.         RwTranslateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.7),
  1811.                   CREAL(0.0), rwPOSTCONCAT);
  1812.         RwTransformClump(DroppedObject, RwScratchMatrix(), rwREPLACE);
  1813.         RwPopScratchMatrix();
  1814.         RwAddChildToClump(Hand, DroppedObject);
  1815.         AnimMode = AAction;
  1816.         JointParamDelta = CREAL(0.03);
  1817.         ArmPosition = APPickUp;
  1818.         ArmPickUp();
  1819.         break;
  1820.         case APPickUp:
  1821.         if (LikeDroppedObject)
  1822.         {
  1823.             AnimMode = AAction;
  1824.             ArmPosition = APOverBox;
  1825.             JointParamDelta = CREAL(0.05);
  1826.             ArmOverBox();
  1827.         }
  1828.         else
  1829.         {
  1830.             AnimMode = AAction;
  1831.             JointParamDelta = CREAL(0.1);
  1832.             ArmPosition = APDiscard;
  1833.             ArmDiscard();
  1834.         }
  1835.         break;
  1836.         case APDiscard:
  1837.         AnimMode = AAction;
  1838.         JointParamDelta = CREAL(0.03);
  1839.         ArmPosition = APRest;
  1840.         ArmToRestPosition();
  1841.         if (DroppedObject)
  1842.         {
  1843.             BeginDiscard(DroppedObject);
  1844.             DroppedObject = NULL;
  1845.              /*       strcpy(DropString, "");
  1846.                     ShowAppRightStatus(Window, Camera, DropString);    */
  1847.             if (CMMode == CMDroppedObject)
  1848.             {
  1849.             CMMode = CMDiscardObject;
  1850.             }
  1851.         }
  1852.         break;
  1853.         case APOverBox:
  1854.         AnimMode = AAction;
  1855.         ArmPosition = APInBox;
  1856.         JointParamDelta = CREAL(0.05);
  1857.         ArmPutInBox();
  1858.         break;
  1859.         case APInBox:
  1860.         AnimMode = AAction;
  1861.         ArmPosition = APRelease;
  1862.         JointParamDelta = CREAL(0.08);
  1863.         ArmRelease();
  1864.         break;
  1865.         case APRelease:
  1866.         AnimMode = AAction;
  1867.         JointParamDelta = CREAL(0.03);
  1868.         ArmPosition = APRest;
  1869.         ArmToRestPosition();
  1870.         if (DroppedObject)
  1871.         {
  1872.             RwDestroyClump(DroppedObject);
  1873.             DroppedObject = NULL;
  1874.                 /*
  1875.                     strcpy(DropString, "");
  1876.                     ShowAppRightStatus(Window, Camera, DropString);
  1877.                  */
  1878.             if (CMMode == CMDroppedObject)
  1879.             {
  1880.             CMMode = CMTrackMouse;
  1881.             RwInvalidateCameraViewport(Camera);
  1882.             }
  1883.         }
  1884.         break;
  1885.         }
  1886.         JointParam = CREAL(0.0);
  1887.     }
  1888.     }
  1889.     else
  1890.     {
  1891.     if (DroppedObject)
  1892.     {
  1893.         AnimMode = AAction;
  1894.         ArmPosition = APReach;
  1895.         ArmReachForPosition(DropX, CREAL(0.0), DropZ);
  1896.         JointParam = CREAL(0.0);
  1897.         JointParamDelta = CREAL(0.05);
  1898.     }
  1899.     else if ((rand() & 0x3f) == 0x3f)
  1900.     {
  1901.         AnimMode = AAction;
  1902.         ArmPosition = APAlert;
  1903.         ArmToAlertPosition();
  1904.         JointParam = CREAL(0.0);
  1905. /*        JointParamDelta = CREAL(0.08); */
  1906.             JointParamDelta = CREAL(0.10);
  1907.     }
  1908.     else if ((rand() & 0x1f) == 0x1f)
  1909.     {
  1910.         AnimMode = AAction;
  1911.         ArmRotatePosition();
  1912.         JointParam = CREAL(0.0);
  1913. /*        JointParamDelta = CREAL(0.05); */
  1914.             JointParamDelta = CREAL(0.10);
  1915.     }
  1916.     }
  1917.  
  1918.     if ((CMMode == CMDroppedObject) && DroppedObject)
  1919.     {
  1920.     RwGetClumpOrigin(DroppedObject, &Origin);
  1921.     RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
  1922.     Origin.x = CREAL(-1.0);
  1923.     Origin.y = CREAL(0.0);
  1924.     Origin.z = CREAL(0.0);
  1925.     RwPushScratchMatrix();
  1926.     RwGetClumpLTM(DroppedObject, RwScratchMatrix());
  1927.     RwTransformVector(&Origin, RwScratchMatrix());
  1928.     RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
  1929.     RwPopScratchMatrix();
  1930.     }
  1931.     else if ((CMMode == CMDiscardObject) && DiscardObject)
  1932.     {
  1933.     RwGetClumpOrigin(DiscardObject, &Origin);
  1934.     RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
  1935.     RwPushScratchMatrix();
  1936.     RwGetClumpLTM(DiscardObject, RwScratchMatrix());
  1937.     Origin.x = CREAL(0.0);
  1938.     Origin.y = CREAL(0.0);
  1939.     Origin.z = CREAL(1.0);
  1940.     RwTransformVector(&Origin, RwScratchMatrix());
  1941.     RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
  1942.     Origin.x = CREAL(0.0);
  1943.     Origin.y = CREAL(1.0);
  1944.     Origin.z = CREAL(0.0);
  1945.     RwTransformVector(&Origin, RwScratchMatrix());
  1946.     RwSetCameraLookUp(Cam, Origin.x, Origin.y, Origin.z);
  1947.     RwPopScratchMatrix();
  1948.     }
  1949.     else if (CMMode == CMRobotHand)
  1950.     {
  1951.     RwPushScratchMatrix();
  1952.     RwGetClumpOrigin(FirstFingerTip, &Origin);
  1953.     RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
  1954.     RwGetClumpLTM(FirstFingerTip, RwScratchMatrix());
  1955.     Origin.x = CREAL(0.0);
  1956.     Origin.y = CREAL(1.0);
  1957.     Origin.z = CREAL(0.0);
  1958.     RwTransformVector(&Origin, RwScratchMatrix());
  1959.     RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
  1960.     RwGetClumpBBox(FirstFingerTip, &BLL, &FUR);
  1961.     RwVCMoveCamera(Cam, FUR.x, BLL.y, CREAL(0.0));
  1962.     RwPopScratchMatrix();
  1963.     }
  1964.     else
  1965.     {
  1966.     Cam = Camera;
  1967.     }
  1968.  
  1969.     RwBeginCameraUpdate(Cam,NULL);
  1970.     RwClearCameraViewport(Cam);
  1971.     RwRenderScene(Scene);
  1972.     RwEndCameraUpdate(Cam);
  1973.     RwShowCameraImage(Cam,NULL);
  1974. }
  1975.  
  1976. /****************************************************************************
  1977.  Main
  1978.  */
  1979.  
  1980. void main(int nArgc,char *saArgv[])
  1981. {
  1982.     int nKey;
  1983.     int nMouseX,nMouseY,nMouseBut,nOldMouseBut,nOldMouseX,nOldMouseY;
  1984.     int nDX,nDY;
  1985.     int nChange;
  1986.     int nStatus;
  1987.     int nCtrlShift;
  1988.     RwReal naWhite[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
  1989.     RwReal naBlack[]={CREAL(0.0),CREAL(0.0),CREAL(0.0)};
  1990.     int nWhite;
  1991.     int nBlack;
  1992.  
  1993.   /* Stop warnings */
  1994.  
  1995.   nArgc = nArgc;
  1996.   saArgv = saArgv;
  1997.  
  1998.   if (!Init3D())
  1999.     {
  2000.         exit(-1);
  2001.     };
  2002.  
  2003.     /*
  2004.     * Parse any command line parameters.
  2005.  
  2006.     if (!ReadFromCommandLine(nArgc, saArgv))
  2007.     {
  2008.         TidyUp3D();
  2009.         exit(-1);
  2010.     };
  2011.      */
  2012.  
  2013.   nWhite = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
  2014.   nBlack =  RwDeviceControl(rwSCRGETCOLOR,0,naBlack,sizeof(naBlack)),
  2015.  
  2016.     RwDPointerDisplay(&nOldMouseX,&nOldMouseY,&nOldMouseBut);
  2017.  
  2018.  
  2019.     /* Create pointer */
  2020.  
  2021.     nKey = DosGetKey();
  2022.     nStatus =0;
  2023.  
  2024.     while (nKey!=27) {        /* ESC quits */
  2025.  
  2026.         RwDPointerDisplay(&nMouseX,&nMouseY,&nMouseBut);
  2027.  
  2028.         nKey = DosGetKey();
  2029.  
  2030.         nCtrlShift = DosShiftCtrl();
  2031.  
  2032.         nDX =(nMouseX-nOldMouseX);
  2033.         nDY =(nMouseY-nOldMouseY);
  2034.  
  2035.         nChange = (nMouseBut&(2+8)) | ( (nOldMouseBut&(2+8)) >>1 );
  2036.  
  2037.         switch (nChange) {
  2038.             case 0+0:
  2039.             case 2+1:
  2040.             case 8+4:
  2041.             case 8+2+4+1: {
  2042.                 /* No change */
  2043.                 break;
  2044.             };
  2045.             case 2:
  2046.             case 8+2+4: {
  2047.  
  2048.                 /* Left Button Down */
  2049.  
  2050.                 HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
  2051.  
  2052.  
  2053.                 break;
  2054.             };
  2055.             case 8:
  2056.             case 8+2+1: {
  2057.                 /* Right Button Down */
  2058.  
  2059.  
  2060.                 HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
  2061.  
  2062.  
  2063.                 break;
  2064.             };
  2065.             case 8+1: {
  2066.                 /* Right down left Up */
  2067.  
  2068.  
  2069.                 HandleLeftButtonUp();
  2070.                 HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
  2071.  
  2072.  
  2073.                 break;
  2074.             };
  2075.             case 2+4: {
  2076.                 /* Right up left Down */
  2077.  
  2078.  
  2079.                 HandleRightButtonUp();
  2080.                 HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
  2081.  
  2082.  
  2083.                 break;
  2084.             };
  2085.             case 8+2: {
  2086.                 /* Left down RIght Down */
  2087.  
  2088.  
  2089.                 HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
  2090.                 HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
  2091.  
  2092.  
  2093.                 break;
  2094.             };
  2095.             case 1+4: {
  2096.                 /* Left up Right Up */
  2097.  
  2098.  
  2099.                 HandleRightButtonUp();
  2100.                 HandleLeftButtonUp();
  2101.  
  2102.  
  2103.                 break;
  2104.             };
  2105.             case 1:
  2106.             case 8+4+1: {
  2107.                 /* Left up */
  2108.  
  2109.  
  2110.                 HandleLeftButtonUp();
  2111.  
  2112.  
  2113.                 break;
  2114.             };
  2115.             case 4:
  2116.             case 2+4+1: {
  2117.                 /* Right up */
  2118.  
  2119.  
  2120.                 HandleRightButtonUp();
  2121.  
  2122.  
  2123.                 break;
  2124.             };
  2125.         };
  2126.  
  2127.         if (nDX||nDY) {
  2128.             /* Mouse Move  */
  2129.             if (!nStatus) HandleMouseMove(nMouseX,nMouseY);
  2130.         };
  2131.  
  2132.  
  2133.         if (nKey) {
  2134.              HandleChar(nKey);
  2135.         };
  2136.  
  2137.  
  2138.         HandleTimer();
  2139.  
  2140.         nOldMouseX = nMouseX;
  2141.         nOldMouseY = nMouseY;
  2142.         nOldMouseBut = nMouseBut;
  2143.     };
  2144.  
  2145.  
  2146.     /*
  2147.     * Tidy up the 3D (RenderWare) components of the application.
  2148.     */
  2149.  
  2150.     TidyUp3D();
  2151.  
  2152.     exit(0);
  2153. }
  2154.  
  2155.  
  2156.