home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / directx2 / sdk / samples / rockem / control.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-28  |  41.4 KB  |  1,185 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: control.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9. // Includes....
  10. #include "rm.h"
  11. #include "control.h"
  12. #include "directx.h"
  13.  
  14. // Defines....
  15. #define MOVE_NORMAL                     D3DVAL(10)
  16. #define MOVE_FAST                       D3DVAL(20)
  17.  
  18. #define MIN_DIST_TO_OPPONENT            D3DVAL(100)
  19.  
  20. #define PLAYER_MOVE_FORWARD             VK_UP
  21. #define PLAYER_MOVE_BACKWARD            VK_DOWN
  22. #define PLAYER_BLOCK                    VK_CONTROL
  23. #define PLAYER_ATTACK                   VK_SPACE
  24.  
  25. #define CAM_BOTH_IN_VIEW                VK_F1
  26. #define CAM_OVER_THE_SHOULDER           VK_F2
  27. #define CAM_PILOT                       VK_F3
  28.  
  29. #define NUM_BOB_FRAMES                  D3DVAL(30)
  30. #define NUM_DEAD_FRAMES                 D3DVAL(66)
  31. #define NUM_PUNCH_FRAMES                D3DVAL(29)
  32. #define NUM_BEEN_HIT_FRAMES             D3DVAL(14)
  33. #define NUM_BLOCKING_FRAMES             D3DVAL(16)
  34. #define NUM_VICTORY_FRAMES              D3DVAL(55)
  35.  
  36. #define BOB_START                       D3DVAL(1)
  37. #define DEAD_START                      D3DVAL(94)
  38. #define DEAD_HIT_GROUND                 D3DVAL(115)
  39. #define PUNCH_START                     D3DVAL(31)
  40. #define PUNCH_ARM_COCKED                D3DVAL(50)
  41. #define BLOCK_START                     D3DVAL(77)
  42. #define BEEN_HIT_START                  D3DVAL(62)
  43. #define HEAD_RETURNING                  D3DVAL(68)
  44. #define VICTORY_START                   D3DVAL(161)
  45.  
  46. #define EDGE_LEFT                       D3DVAL(-600)
  47. #define EDGE_RIGHT                      D3DVAL(600)
  48.  
  49. // Globals....
  50.  
  51. // States
  52. AppState                g_appState = DOING_INTRO;
  53. PlayerState             g_oppState = CAUTIOUS;
  54. CameraState             g_camState = BOTH_IN_VIEW;
  55.  
  56. PlayerActionState       g_player1State = BOBBING;
  57. PlayerActionState       g_player2State = BOBBING;
  58.  
  59. AnimArgs                g_player1AnimArgs;
  60. AnimArgs                g_player2AnimArgs;
  61.  
  62. BOOL                    g_bPlayer1Attacking = FALSE;
  63. BOOL                    g_bPlayer1Blocking  = FALSE;
  64.  
  65. DWORD                   g_player1health = 100;
  66. DWORD                   g_player2health = 100;
  67.  
  68. // Timed lengths for each animation in milliseconds
  69. #define BOB_TIME_MS     D3DVAL(500)
  70. #define PUNCH_TIME_MS   D3DVAL(600)
  71. #define BLOCK_TIME_MS   D3DVAL(500)
  72. #define HIT_TIME_MS     D3DVAL(500)
  73. #define DEAD_TIME_MS    D3DVAL(4000)
  74. #define VICTORY_TIME_MS D3DVAL(3000)
  75.  
  76. // Timing deltas, used for scaling animation to frame rate
  77. D3DVALUE                g_bobDelta     = NUM_BOB_FRAMES / BOB_TIME_MS;
  78. D3DVALUE                g_attackDelta  = NUM_PUNCH_FRAMES / PUNCH_TIME_MS;
  79. D3DVALUE                g_blockDelta   = NUM_BLOCKING_FRAMES / BLOCK_TIME_MS;
  80. D3DVALUE                g_hitDelta     = NUM_BEEN_HIT_FRAMES / HIT_TIME_MS;
  81. D3DVALUE                g_deadDelta    = NUM_DEAD_FRAMES / DEAD_TIME_MS;
  82. D3DVALUE                g_victoryDelta = NUM_DEAD_FRAMES / DEAD_TIME_MS;
  83.  
  84. // Externals....
  85. extern LPDIRECT3DRM             g_lpD3DRM;
  86. extern LPDIRECT3DRMFRAME        g_lpScene;
  87. extern LPDIRECT3DRMFRAME        g_lpCamera;
  88. extern LPDIRECT3DRMFRAME        g_lpPlayer1;
  89. extern LPDIRECT3DRMFRAME        g_lpPlayer1HeadFrame;
  90. extern LPDIRECT3DRMFRAME        g_lpPlayer2;
  91. extern LPDIRECT3DRMFRAME        g_lpPlayer2HeadFrame;
  92. extern LPDIRECT3DRMFRAME        g_lpTmp;
  93. extern LPDIRECT3DRMANIMATION    g_lpAnim;
  94. extern LPDIRECT3DRMMESHBUILDER  g_lpRedDebris;
  95. extern LPDIRECT3DRMMESHBUILDER  g_lpBlueDebris;
  96. extern Debris                   g_debris[NUM_DEBRIS];
  97.  
  98. //----------------------------------------------------------------------
  99. // 
  100. // Function     : IsKeyDown()
  101. //
  102. // Purpose      : Returns TRUE if specified key is being pressed
  103. //
  104. //----------------------------------------------------------------------
  105.  
  106. BOOL IsKeyDown(int virtKeyCode)
  107. {
  108.     if (GetAsyncKeyState(virtKeyCode) & 0x8000) return TRUE;
  109.  
  110.     return FALSE;
  111. }
  112.  
  113. //----------------------------------------------------------------------
  114. // 
  115. // Function     : Player1AnimationCallback()
  116. //
  117. // Purpose      : Animation call back for player 1
  118. //
  119. //----------------------------------------------------------------------
  120.  
  121. void Player1AnimationCallback(LPDIRECT3DRMFRAME obj, void* arg, D3DVALUE delta)
  122. {       
  123.     D3DVALUE time = g_player1AnimArgs.time;
  124.     D3DVECTOR player1pos;
  125.     D3DVECTOR player2pos;
  126.     
  127.     // Booleans to help with sound playing
  128.     static BOOL bHitGround              = FALSE;
  129.     static BOOL bPlayedWhoosh   = FALSE;
  130.  
  131.     // Get the players positions
  132.     g_lpPlayer1->GetPosition(g_lpScene, &player1pos);   
  133.     g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
  134.     
  135.     // Compute distance between players
  136.     D3DVALUE curDist = player2pos.z - player1pos.z;
  137.  
  138.     // Do something based upon the state of player 1
  139.     switch (g_player1State)
  140.     {
  141.         case BOBBING :
  142.         {       
  143.             // Forward the bobbing animation time
  144.             g_player1AnimArgs.lpAnimSet->SetTime(time);                 
  145.             time += (g_bobDelta * delta);
  146.             
  147.             // Reset if animation has ended
  148.             if (time > BOB_START + NUM_BOB_FRAMES) time = BOB_START;
  149.             
  150.             // Record the new time
  151.             g_player1AnimArgs.time = time;
  152.         }
  153.         break;
  154.  
  155.         case PUNCHING :
  156.         {
  157.             // Forward the punching animation time
  158.             g_player1AnimArgs.lpAnimSet->SetTime(time);
  159.             time += (g_attackDelta * delta);
  160.  
  161.             // Play a whoosh sound if player 1's arm has gone back and is about to punch
  162.             if ((time > PUNCH_ARM_COCKED) && (!bPlayedWhoosh))
  163.             {
  164.                 // Play the whoosh
  165.                 PlaySoundDS(rand() % 2 == 0 ? WHOOSH1 : WHOOSH2);                               
  166.                 bPlayedWhoosh = TRUE;
  167.             }
  168.  
  169.             // If the punch has played, see if we hit the opponent
  170.             if (time > PUNCH_START + NUM_PUNCH_FRAMES) 
  171.             {
  172.                 // Reset player 1's state to BOBBING
  173.                 time               = BOB_START;
  174.                 g_player1State = BOBBING;
  175.                 bPlayedWhoosh  = FALSE;
  176.  
  177.                 // Play a servo sound
  178.                 PlaySoundDS(SERVO_DOWN_1);
  179.  
  180.                 // Now, decide whether we have hit the other player
  181.                 if (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(20))
  182.                 {               
  183.                     // The opponent may be blocking
  184.                     if ((g_player2State == BLOCKING) && 
  185.                         (g_player2AnimArgs.time > BLOCK_START + (NUM_BLOCKING_FRAMES / D3DVAL(2)))) 
  186.                     {
  187.                         // The opponent blocked the punch, so play the block sound
  188.                         PlaySoundDS(BLOCK1 + (rand() % 3));
  189.                         break;
  190.                     }
  191.  
  192.                     // We're within the striking distance
  193.                     if (g_player2health == 0) return;
  194.  
  195.                     // Add some debris into the scene to register a hit and play a sound        
  196.                     D3DVECTOR debrisOrg = player1pos;
  197.                     D3DVECTOR debrisVel = { D3DVAL(0), D3DVAL(0), D3DVAL(-10) };
  198.                     
  199.                     debrisOrg.x += D3DVAL(40);
  200.                     debrisOrg.y += D3DVAL(40);
  201.                     debrisOrg.z += D3DVAL(90);
  202.                     
  203.                     // Add some debris
  204.                     AddDebris(debrisOrg, debrisVel, g_lpRedDebris);
  205.  
  206.                     // Decrease the opponents health
  207.                     if (g_player2health > 0) g_player2health -= 10;
  208.                                             
  209.                     if (g_player2health == 0)
  210.                     {
  211.                         // The opponent has died!
  212.                         g_player2State = DEAD;
  213.                         g_player2AnimArgs.time = DEAD_START;
  214.                         g_player2AnimArgs.lpAnimSet->SetTime(DEAD_START);
  215.                         PlaySoundDS(HEAD_SPRING);
  216.                         
  217.                         // And the player has victory!
  218.                         g_player1State = VICTORY;
  219.                         g_player1AnimArgs.time = VICTORY_START;
  220.                         g_player1AnimArgs.lpAnimSet->SetTime(VICTORY_START);
  221.  
  222.                         PlaySoundDS(VICTORY_YEAH);
  223.  
  224.                         return;
  225.                     }
  226.  
  227.                     // Play a punch sound
  228.                     PlaySoundDS(rand() % 2 == 0 ? PLAYER1_PUNCH1 : PLAYER1_PUNCH2);
  229.  
  230.                     // Recalculate the power bars
  231.                     RecalcPowerBars(g_player1health, g_player2health);
  232.                     
  233.                     // Make sure we force the camera to the correct place
  234.                     PositionCamera();
  235.  
  236.                     // Setup the opponents animation and state
  237.                     g_player2State = BEEN_HIT;
  238.                     g_player2AnimArgs.time = BEEN_HIT_START;
  239.                     g_player2AnimArgs.lpAnimSet->SetTime(BEEN_HIT_START);
  240.                     
  241.                     // What should the opponent do?
  242.                     if (rand() % 10 < 2)
  243.                     {
  244.                         // Make the opponent defensive
  245.                         g_oppState = DEFENSIVE;
  246.                     }
  247.  
  248.                     // Play the ouch sound
  249.                     PlaySoundDS(PLAYER2_OUCH);
  250.                 }
  251.             }
  252.  
  253.             // Record the new animation time
  254.             g_player1AnimArgs.time = time;
  255.         }
  256.         break;
  257.         
  258.         case BLOCKING : 
  259.         {
  260.             // Forward the blocking animation time
  261.             g_player1AnimArgs.lpAnimSet->SetTime(time);
  262.             
  263.             // Hold the block up if CTRL is held down
  264.             if (GetAsyncKeyState(PLAYER_BLOCK) & 0x8000)
  265.             {
  266.                 if (time < BLOCK_START + (NUM_BLOCKING_FRAMES / 2)) time += (g_blockDelta * delta);
  267.             }
  268.             else
  269.             {
  270.                 time += (g_blockDelta * delta);
  271.             }
  272.  
  273.             // Reset player 1's state to BOBBING if the animation has ended
  274.             if (time > BLOCK_START + NUM_BLOCKING_FRAMES) 
  275.             {
  276.                 time            = BOB_START;
  277.                 g_player1State  = BOBBING;
  278.             }
  279.  
  280.             // Record the new animation time
  281.             g_player1AnimArgs.time = time;
  282.         }
  283.         break;
  284.  
  285.         case BEEN_HIT :
  286.         {
  287.             // Forward the been hit animation time
  288.             g_player1AnimArgs.lpAnimSet->SetTime(time);
  289.             time += (g_hitDelta * delta);
  290.  
  291.             if (player1pos.z > EDGE_LEFT) g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z - D3DVAL(5));
  292.             PositionCamera();
  293.  
  294.             // Reset player 1's state to BOBBING if the animation has ended
  295.             if (time > BEEN_HIT_START + NUM_BEEN_HIT_FRAMES) 
  296.             {
  297.                 time            = BOB_START;
  298.                 g_player1State  = BOBBING;
  299.             }
  300.             
  301.             // Record the new animation time
  302.             g_player1AnimArgs.time = time;
  303.         }
  304.         break;
  305.         
  306.         case DEAD :
  307.         {
  308.             // Forward the death animation time
  309.             g_player1AnimArgs.lpAnimSet->SetTime(time);
  310.             time += (g_deadDelta * delta);
  311.  
  312.             // Play a crash sound if the animation has passes the DEAD_HIT_GROUND frame
  313.             if ((time > DEAD_HIT_GROUND) && (!bHitGround))
  314.             {
  315.                 bHitGround = TRUE;
  316.                 PlaySoundDS(BLOCK3);
  317.             }
  318.  
  319.             // Reset player 1's state to BOBBING if the animation has ended
  320.             if (time > DEAD_START + NUM_DEAD_FRAMES) 
  321.             {
  322.                 time            = BOB_START;
  323.                 g_player1State  = BOBBING;
  324.                 g_player1health = 100;
  325.                 bHitGround      = FALSE;
  326.  
  327.                 RecalcPowerBars(g_player1health, g_player2health);
  328.             }
  329.             
  330.             // Record the new animation time
  331.             g_player1AnimArgs.time = time;
  332.  
  333.             // Position the camera correctly
  334.             PositionCamera();
  335.         }
  336.         break;
  337.  
  338.         case VICTORY :
  339.         {
  340.             // Forward the victory animation time
  341.             g_player1AnimArgs.lpAnimSet->SetTime(time);
  342.             time += (g_victoryDelta * delta);
  343.  
  344.             if (time > VICTORY_START + NUM_VICTORY_FRAMES) 
  345.             {
  346.                 time            = BOB_START;
  347.                 g_player1State  = BOBBING;
  348.             }
  349.             g_player1AnimArgs.time = time;
  350.  
  351.             PositionCamera();
  352.         }
  353.         break;
  354.     }
  355. }
  356.  
  357. //----------------------------------------------------------------------
  358. // 
  359. // Function     : Player2AnimationCallback()
  360. //
  361. // Purpose      : Animation call back for player 2
  362. //
  363. //----------------------------------------------------------------------
  364.  
  365. void Player2AnimationCallback(LPDIRECT3DRMFRAME obj, void* arg, D3DVALUE delta)
  366. {
  367.     D3DVALUE time = g_player2AnimArgs.time;
  368.     D3DVECTOR player1pos;
  369.     D3DVECTOR player2pos;
  370.  
  371.     // Booleans to help with sound playing
  372.     static BOOL bHitGround              = FALSE;
  373.     static BOOL bPlayedWhoosh   = FALSE;
  374.  
  375.     // Get the players positions
  376.     g_lpPlayer1->GetPosition(g_lpScene, &player1pos);   
  377.     g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
  378.  
  379.     // Compute distance between players
  380.     D3DVALUE curDist = player2pos.z - player1pos.z;
  381.  
  382.     // Do something based upon the state of player 1
  383.     switch (g_player2State)
  384.     {
  385.         case BOBBING :
  386.         {       
  387.             // Forward the bobbing animation time
  388.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  389.             time += (g_bobDelta * delta);
  390.  
  391.             // Reset if animation has ended
  392.             if (time > BOB_START + NUM_BOB_FRAMES) time = BOB_START;
  393.  
  394.             // Record the new time
  395.             g_player2AnimArgs.time = time;
  396.         }
  397.         break;
  398.  
  399.         case PUNCHING :
  400.         {
  401.             // Forward the punching animation time
  402.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  403.             time += (g_attackDelta * delta);
  404.  
  405.             // Play a whoosh sound if player 2's arm has gone back and is about to punch
  406.             if ((time > PUNCH_ARM_COCKED) && (!bPlayedWhoosh))
  407.             {
  408.                 // Play the whoosh
  409.                 PlaySoundDS(rand() % 2 == 0 ? WHOOSH1 : WHOOSH2);                               
  410.                 bPlayedWhoosh = TRUE;
  411.             }
  412.     
  413.             // If the punch has played, see if we hit the opponent
  414.             if (time > PUNCH_START + NUM_PUNCH_FRAMES) 
  415.             {
  416.                 time = BOB_START;
  417.                 g_player2State = BOBBING;
  418.                 bPlayedWhoosh  = FALSE;
  419.                 
  420.                 // Play a servo sound
  421.                 PlaySoundDS(SERVO_DOWN_2);
  422.  
  423.                 // Now, decide whether we have hit the other player
  424.                 if (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(20))
  425.                 {               
  426.                     // The opponent may be blocking
  427.                     if ((g_player1State == BLOCKING) && 
  428.                         (g_player1AnimArgs.time > BLOCK_START + (NUM_BLOCKING_FRAMES / D3DVAL(2)))) 
  429.                     {
  430.                         // The opponent blocked the punch, so play the block sound
  431.                         PlaySoundDS(BLOCK1 + (rand() % 3));
  432.                         break;
  433.                     }
  434.  
  435.                     // We're within the striking distance
  436.                     if (g_player1health <= 0) return;
  437.  
  438.                     // We're within the striking distance
  439.                     // Add some debris into the scene to register a hit and play a sound        
  440.                     D3DVECTOR debrisOrg = player1pos;
  441.                     D3DVECTOR debrisVel = { D3DVAL(0), D3DVAL(0), D3DVAL(10) };
  442.                     
  443.                     debrisOrg.x += D3DVAL(-40);
  444.                     debrisOrg.y += D3DVAL(40);
  445.                     debrisOrg.z += D3DVAL(-10);
  446.                     
  447.                     // Add some debris
  448.                     AddDebris(debrisOrg, debrisVel, g_lpBlueDebris);
  449.  
  450.                     // Play a punch sound
  451.                     PlaySoundDS(rand() % 2 == 0 ? PLAYER2_PUNCH1 : PLAYER2_PUNCH2);
  452.  
  453.                     // Decrease the opponents health
  454.                     if (g_player1health > 0) g_player1health -= 10;
  455.  
  456.                     if (g_player1health == 0)
  457.                     {
  458.                         // The player has died!
  459.                         g_player1State = DEAD;
  460.                         g_player1AnimArgs.time = DEAD_START;
  461.                         g_player1AnimArgs.lpAnimSet->SetTime(DEAD_START);
  462.                         PlaySoundDS(HEAD_SPRING);
  463.  
  464.                         // And the opponent has victory!
  465.                         g_player2State = VICTORY;
  466.                         g_player2AnimArgs.time = VICTORY_START;
  467.                         g_player2AnimArgs.lpAnimSet->SetTime(VICTORY_START);
  468.  
  469.                         // The crowd is not happy....
  470.                         PlaySoundDS(VICTORY_BOO);
  471.  
  472.                         return;
  473.                     }
  474.  
  475.                     // Recalculate the power bars
  476.                     RecalcPowerBars(g_player1health, g_player2health);
  477.                     
  478.                     // Force a camera positional update
  479.                     PositionCamera();
  480.                     
  481.                     if (g_player1State != BEEN_HIT)
  482.                     {
  483.                         // Change player 1's state to BEEN_HIT,
  484.                         g_player1State = BEEN_HIT;
  485.  
  486.                         // And set the animation time
  487.                         g_player1AnimArgs.time = BEEN_HIT_START;
  488.                         g_player1AnimArgs.lpAnimSet->SetTime(BEEN_HIT_START);                                           
  489.                     }
  490.  
  491.                     // Play the ouch sound
  492.                     PlaySoundDS(PLAYER1_OUCH);
  493.                 }
  494.             }
  495.  
  496.             // Record the new animation time
  497.             g_player2AnimArgs.time = time;
  498.         }
  499.         break;
  500.  
  501.         case BEEN_HIT :
  502.         {
  503.             // Forward the been hit animation time
  504.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  505.             time += (g_hitDelta * delta);
  506.             
  507.             // Move the player
  508.             if (player2pos.z < EDGE_RIGHT) g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + D3DVAL(5));
  509.             
  510.             // Force a camera position update
  511.             PositionCamera();
  512.  
  513.             // Reset to BOBBING if animation has ended
  514.             if (time > BEEN_HIT_START + NUM_BEEN_HIT_FRAMES) 
  515.             {
  516.                 time = BOB_START;
  517.                 g_player2State = BOBBING;
  518.             }
  519.             
  520.             // Record the new animation time
  521.             g_player2AnimArgs.time = time;
  522.         }
  523.         break;
  524.  
  525.         case BLOCKING : 
  526.         {
  527.             // Forward the blocking animation time
  528.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  529.             time += (g_blockDelta * delta);
  530.  
  531.             // Reset to BOBBING if animation has ended
  532.             if (time > BLOCK_START + NUM_BLOCKING_FRAMES) 
  533.             {
  534.                 time            = BOB_START;
  535.                 g_player2State  = BOBBING;
  536.                 g_oppState      = AGGRESSIVE;
  537.             }
  538.             
  539.             // Record the new animation time
  540.             g_player2AnimArgs.time = time;
  541.         }
  542.         break;
  543.  
  544.         case DEAD :
  545.         {
  546.             // Forward the death animation time
  547.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  548.             time += (g_deadDelta * delta);
  549.  
  550.             // Play the BLOCK3 sound when the opponent hits the ground
  551.             if ((time > DEAD_HIT_GROUND) && (!bHitGround))
  552.             {
  553.                 bHitGround = TRUE;
  554.                 PlaySoundDS(BLOCK3);
  555.             }
  556.  
  557.             // Reset to BOBBING if the animation has ended
  558.             if (time > DEAD_START + NUM_DEAD_FRAMES) 
  559.             {
  560.                 time            = BOB_START;
  561.                 g_player2State  = BOBBING;
  562.                 g_player2health = 100;
  563.                 bHitGround      = FALSE;
  564.  
  565.                 // Recalculate the power bars
  566.                 RecalcPowerBars(g_player1health, g_player2health);
  567.             }
  568.             // Record the new animation time
  569.             g_player2AnimArgs.time = time;
  570.  
  571.             // Force a camera position update
  572.             PositionCamera();
  573.         }
  574.         break;
  575.  
  576.         case VICTORY :
  577.         {
  578.             // Forward the victory animation time
  579.             g_player2AnimArgs.lpAnimSet->SetTime(time);
  580.             time += (g_victoryDelta * delta);
  581.  
  582.             if (time > VICTORY_START + NUM_VICTORY_FRAMES) 
  583.             {
  584.                 time            = BOB_START;
  585.                 g_player2State  = BOBBING;
  586.             }
  587.             
  588.             // Record the new animation time
  589.             g_player2AnimArgs.time = time;
  590.  
  591.             // Force a camera position update
  592.             PositionCamera();
  593.         }
  594.         break;
  595.     }
  596. }
  597.  
  598. //----------------------------------------------------------------------
  599. // 
  600. // Function     : CheckInputAndUpdate()
  601. //
  602. // Purpose      : Checks input, updates scene, moves player(s)
  603. //
  604. //----------------------------------------------------------------------
  605.  
  606. void CheckInputAndUpdate()
  607. {               
  608.     D3DVECTOR player1pos;
  609.     D3DVECTOR player2pos;
  610.     D3DVECTOR camPos;
  611.  
  612.     // Run intro
  613.     if (g_appState == DOING_INTRO)
  614.     {
  615.             RunIntro();
  616.             return;
  617.     }
  618.  
  619.     // Transition camera
  620.     if (g_appState == BETWEEN_CAM_VIEWS)
  621.     {
  622.             TransitionCamera();
  623.             return;
  624.     }
  625.  
  626.     // Get the players positions
  627.     g_lpPlayer1->GetPosition(g_lpScene, &player1pos);   
  628.     g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
  629.  
  630.     // Get the camera's position
  631.     g_lpCamera->GetPosition(g_lpScene, &camPos);
  632.  
  633.     // Calculate distance between players
  634.     D3DVALUE curDist = player2pos.z - player1pos.z;
  635.  
  636.     // Move player forward
  637.     if ((IsKeyDown(PLAYER_MOVE_FORWARD)) && (g_player1State != VICTORY) && (g_player1State != DEAD))
  638.     {
  639.             // Make sure the player can only move so close to the opponent
  640.             if (curDist > MIN_DIST_TO_OPPONENT)
  641.             {
  642.                     // Move the player
  643.                     g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z + MOVE_NORMAL);
  644.  
  645.                     // Force a camera position update
  646.                     PositionCamera();
  647.  
  648.                     // Play a servo sound
  649.                     PlaySoundDS(SERVO_UP_3);
  650.                     
  651.                     // Play a walk sound
  652.                     PlaySoundDS(PLAYER1_WALK);
  653.             }
  654.     }
  655.  
  656.     // Move player backward
  657.     if ((IsKeyDown(PLAYER_MOVE_BACKWARD)) && (g_player1State != VICTORY) && (g_player1State != DEAD))
  658.     {
  659.             // Make sure the player can't run off the arena
  660.             if (player1pos.z > EDGE_LEFT)
  661.             {
  662.                     // Move the player
  663.                     g_lpPlayer1->SetPosition(g_lpScene, player1pos.x, player1pos.y, player1pos.z - MOVE_NORMAL);
  664.                     
  665.                     // Force a camera position update
  666.                     PositionCamera();
  667.  
  668.                     // Play a servo sound
  669.                     PlaySoundDS(SERVO_UP_3);
  670.  
  671.                     // Play a walk sound
  672.                     PlaySoundDS(PLAYER1_WALK);
  673.             }
  674.     }
  675.  
  676.     // Initiate a player attack
  677.     if ((!g_bPlayer1Attacking) && (!g_bPlayer1Blocking) && (IsKeyDown(PLAYER_ATTACK)))
  678.     {
  679.             if ((g_player1State != PUNCHING) && (g_player1State != DEAD) && (g_player1State != VICTORY))
  680.             {
  681.                     // Set the player state to punching
  682.                     g_player1State = PUNCHING;
  683.                     
  684.                     // Set up the correct time for the animation
  685.                     g_player1AnimArgs.time = D3DVAL(PUNCH_START);
  686.                     g_player1AnimArgs.lpAnimSet->SetTime(D3DVAL(PUNCH_START));
  687.                                     
  688.                     g_bPlayer1Attacking = TRUE;
  689.                     
  690.                     // Play a servo sound
  691.                     PlaySoundDS(SERVO_UP_1);
  692.             }
  693.     }
  694.  
  695.     // Reset the attacking flag if the PLAYER_ATTACK key is not pressed anymore
  696.     if ((g_bPlayer1Attacking) && (!IsKeyDown(PLAYER_ATTACK)))
  697.     {
  698.             g_bPlayer1Attacking = FALSE;
  699.     }
  700.  
  701.     // Initiate a player block
  702.     if ((!g_bPlayer1Blocking) && (!g_bPlayer1Attacking) && (IsKeyDown(PLAYER_BLOCK)))
  703.     {
  704.             if ((g_player1State != BLOCKING) && (g_player1State != DEAD) && (g_player1State != VICTORY))
  705.             {
  706.                     // Set the player state to blocking
  707.                     g_player1State = BLOCKING;
  708.                     
  709.                     // Set up the correct time for the animation
  710.                     g_player1AnimArgs.time = D3DVAL(BLOCK_START);
  711.                     g_player1AnimArgs.lpAnimSet->SetTime(D3DVAL(BLOCK_START));
  712.                             
  713.                     // Don't allow any more blocking
  714.                     g_bPlayer1Blocking = TRUE;
  715.                     
  716.                     // Play a servo sound
  717.                     PlaySoundDS(SERVO_UP_1);
  718.             }   
  719.     }
  720.  
  721.     // Reset the blocking flag if the PLAYER_BLOCK key is no longer held down
  722.     if ((g_bPlayer1Blocking) && (!IsKeyDown(PLAYER_BLOCK)))
  723.     {
  724.             g_bPlayer1Blocking = FALSE;
  725.     }
  726.  
  727.     // Transition to the BOTH_IN_VIEW camera view
  728.     if ((IsKeyDown(CAM_BOTH_IN_VIEW)) && (g_camState != BOTH_IN_VIEW))
  729.     {
  730.             // Create transition animation
  731.             if (!FAILED(g_lpD3DRM->CreateAnimation(&g_lpAnim)))
  732.             {
  733.                     // Setup the animation options
  734.                     g_lpAnim->SetOptions(D3DRMANIMATION_OPEN | 
  735.                                                              D3DRMANIMATION_LINEARPOSITION | 
  736.                                                              D3DRMANIMATION_POSITION);
  737.  
  738.                     // Make midway vector between both players, this is what the camera will focus on
  739.                     D3DVECTOR vMidPoint;
  740.                     vMidPoint.x = 0.0f;
  741.                     vMidPoint.y = 0.0f;
  742.                     vMidPoint.z = (player1pos.z + player2pos.z) / D3DVAL(2);
  743.                     
  744.                     // Calculate vector that will keep both players in sight
  745.                     D3DVECTOR vNewCam;
  746.                     vNewCam.x = (float)abs((int)player2pos.z - (int)player1pos.z) + D3DVAL(300);
  747.                     vNewCam.y = camPos.y;
  748.                     vNewCam.z = vMidPoint.z;
  749.                     
  750.                     // Add the keyframes to the animation
  751.                     g_lpAnim->AddPositionKey(D3DVAL(0), camPos.x, camPos.y, camPos.z);
  752.                     g_lpAnim->AddPositionKey(D3DVAL(1), vNewCam.x, vNewCam.y, vNewCam.z);
  753.                     
  754.                     // Setup the initial position
  755.                     g_lpTmp->SetPosition(g_lpScene, vMidPoint.x, vMidPoint.y, vMidPoint.z);
  756.                     
  757.                     // And attach the camera to the animation
  758.                     g_lpAnim->SetFrame(g_lpCamera);
  759.  
  760.                     g_appState = BETWEEN_CAM_VIEWS;
  761.             }
  762.             else
  763.             {
  764.                     // Create animation failed so just set the camera position
  765.                     g_lpCamera->SetPosition(g_lpScene, D3DVAL(200), D3DVAL(100), player1pos.z + MOVE_NORMAL - D3DVAL(400));
  766.                     g_lpCamera->LookAt(g_lpPlayer2, g_lpScene, D3DRMCONSTRAIN_Z);               
  767.                     PositionCamera();                   
  768.             }
  769.  
  770.             g_camState = BOTH_IN_VIEW;
  771.     }
  772.     
  773.     // Transition to the OVER_SHOULDER camera view
  774.     if ((IsKeyDown(CAM_OVER_THE_SHOULDER)) && (g_camState != OVER_SHOULDER))
  775.     {
  776.         if (!FAILED(g_lpD3DRM->CreateAnimation(&g_lpAnim)))
  777.         {
  778.             // Setup the animation options
  779.             g_lpAnim->SetOptions(D3DRMANIMATION_OPEN | 
  780.                                  D3DRMANIMATION_LINEARPOSITION | 
  781.                                  D3DRMANIMATION_POSITION);
  782.  
  783.             // Add the keyframes to the animation                       
  784.             g_lpAnim->AddPositionKey(D3DVAL(0), camPos.x, camPos.y, camPos.z);
  785.             g_lpAnim->AddPositionKey(D3DVAL(1), D3DVAL(200), D3DVAL(100), player1pos.z - D3DVAL(300));
  786.             
  787.             // Setup the initial position
  788.             g_lpTmp->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z);
  789.             
  790.             // And attach the camera to the animation
  791.             g_lpAnim->SetFrame(g_lpCamera);
  792.  
  793.             g_appState = BETWEEN_CAM_VIEWS;
  794.         }
  795.         else
  796.         {
  797.             // Create animation failed so just set the camera position
  798.             PositionCamera();
  799.         }
  800.                                 
  801.         g_camState = OVER_SHOULDER;
  802.     }
  803.  
  804.     // Transition to the PILOT_VIEW camera view
  805.     if ((IsKeyDown(CAM_PILOT)) && (g_camState != PILOT_VIEW))
  806.     {
  807.         PositionCamera();
  808.         g_camState = PILOT_VIEW;
  809.     }
  810.  
  811.     // Update the opponent
  812.     UpdateOpponent();
  813.  
  814.     // Update any debris in the world
  815.     UpdateDebris();
  816. }
  817.  
  818. //----------------------------------------------------------------------
  819. // 
  820. // Function     : UpdateOpponent()
  821. //
  822. // Purpose      : Updates opponent
  823. //
  824. //----------------------------------------------------------------------
  825.  
  826. void UpdateOpponent()
  827. {
  828.     D3DVECTOR player1pos;
  829.     D3DVECTOR player2pos;       
  830.  
  831.     if (g_player2State != BOBBING) return;
  832.  
  833.     // Random value to determine what the opponent should do based upon its state
  834.     int r = rand() % 100;
  835.  
  836.     // Get the players positions
  837.     g_lpPlayer1->GetPosition(g_lpScene, &player1pos);   
  838.     g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
  839.  
  840.     // Calculate distance betweens players
  841.     D3DVALUE curDist = player2pos.z - player1pos.z;
  842.     
  843.     // There is always a chance to block the player
  844.     if ((r < 15) && (g_player1State == PUNCHING) && (g_player2State == BOBBING))
  845.     {
  846.         // Set the opponents state to BLOCKING ans start the animation
  847.         g_player2State = BLOCKING;
  848.         g_player2AnimArgs.time = BLOCK_START;
  849.         g_player2AnimArgs.lpAnimSet->SetTime(BLOCK_START);
  850.         
  851.         // Play a servo sound
  852.         PlaySoundDS(SERVO_UP_2);
  853.         return;
  854.     }
  855.  
  856.     switch (g_oppState)
  857.     {
  858.         case DEFENSIVE:
  859.         {                       
  860.             // Decide whether to move opponent backwards
  861.             if (r < 25)
  862.             {
  863.                 // Move the opponent backwards
  864.                 g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + MOVE_NORMAL);
  865.                 
  866.                 // Play a walk sound
  867.                 PlaySoundDS(PLAYER2_WALK);
  868.                 
  869.                 // Play a servo sound
  870.                 PlaySoundDS(SERVO_DOWN_3);
  871.             }
  872.             PositionCamera();                   
  873.  
  874.             // Decide whether to go from DEFENSIVE to cautious
  875.             if (r < 10) g_oppState = CAUTIOUS;
  876.         }
  877.         break;
  878.  
  879.         case CAUTIOUS:
  880.         {
  881.             // Decide whether to go from CAUTIOUS to AGGRESSIVE
  882.             if (r < 5)
  883.             {
  884.                 // Make the opponent become aggresive
  885.                 g_oppState = AGGRESSIVE;
  886.             }
  887.         }
  888.         break;
  889.  
  890.         case AGGRESSIVE:
  891.         {                       
  892.             // Decide whether to move the opponent towards the player
  893.             if (r < 50)
  894.             {
  895.                 // Move the opponent towards the player
  896.                 if (curDist > MIN_DIST_TO_OPPONENT)
  897.                 {
  898.                     g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z - MOVE_NORMAL);
  899.                     PositionCamera();
  900.  
  901.                     // Play a walk sound
  902.                     PlaySoundDS(PLAYER2_WALK);
  903.                     
  904.                     // Play a servo sound
  905.                     PlaySoundDS(SERVO_DOWN_3);                          
  906.                 }
  907.             }
  908.  
  909.             // Decide whether or not to attack the player
  910.             if ((r < 15) && (g_player2State == BOBBING) && 
  911.                 (g_player1State != DEAD) && (curDist < MIN_DIST_TO_OPPONENT + D3DVAL(50)))
  912.             {
  913.                 // Set the opponent's state to PUNCHING
  914.                 g_player2State = PUNCHING;
  915.                 g_player2AnimArgs.time = PUNCH_START;
  916.                 g_player2AnimArgs.lpAnimSet->SetTime(PUNCH_START);
  917.                 
  918.                 // Play a servo sound
  919.                 PlaySoundDS(SERVO_UP_2);
  920.             }
  921.  
  922.             // Decide whether or not to move the opponent backwards out of the way if the player
  923.             // is punching
  924.             if ((g_player1State == PUNCHING) && (r > 50) && (g_player2State == BOBBING) && (curDist < MIN_DIST_TO_OPPONENT + 50))
  925.             {
  926.                 // Move the opponent out of the way, making sure its still in the arena
  927.                 if (player2pos.z < EDGE_RIGHT) 
  928.                 {
  929.                     g_lpPlayer2->SetPosition(g_lpScene, player2pos.x, player2pos.y, player2pos.z + D3DVAL(5));
  930.                     
  931.                     // Play a servo sound
  932.                     PlaySoundDS(SERVO_DOWN_3);
  933.                 }
  934.             }
  935.         }
  936.         break;
  937.     }
  938. }
  939.  
  940. //----------------------------------------------------------------------
  941. // 
  942. // Function     : RunIntro()
  943. //
  944. // Purpose      : Moves camera along path
  945. //
  946. //----------------------------------------------------------------------
  947.  
  948. void RunIntro()
  949. {
  950.     static D3DVALUE time = D3DVAL(0.0f);
  951.  
  952.     // Play the intro sound
  953.     if (time == D3DVAL(0.0f))
  954.     {
  955.         PlaySoundDS(INTRO);
  956.         PlaySoundDS(CROWD_LOOP, DSBPLAY_LOOPING);
  957.     }
  958.     
  959.     // Foward the intro animation
  960.     time += D3DVAL(0.04);
  961.  
  962.     // Set the animation time
  963.     g_lpAnim->SetTime(time);
  964.     
  965.     // Always look at the origin of the g_lpScene frame
  966.     g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
  967.     
  968.     // If time has exceeded 1.0 the intro is done, and we can start the demo
  969.     if (time >= D3DVAL(1.0f))
  970.     {
  971.         g_appState = PLAYING_DEMO;
  972.         g_lpAnim->Release();
  973.         g_lpAnim = NULL;
  974.         PositionCamera();
  975.     }
  976. }
  977.  
  978. //----------------------------------------------------------------------
  979. // 
  980. // Function     : PostionCamera()
  981. //
  982. // Purpose      : Positions camera based upon camera state
  983. //
  984. //----------------------------------------------------------------------
  985.  
  986. void PositionCamera()
  987. {       
  988.     D3DVECTOR player1pos;
  989.     D3DVECTOR player2pos;
  990.     D3DVECTOR camPos;
  991.  
  992.     // Don't position the camera if we are transitioning between camera views
  993.     if (g_appState == BETWEEN_CAM_VIEWS) return;
  994.  
  995.     // Get the players positions
  996.     g_lpPlayer1->GetPosition(g_lpScene, &player1pos);   
  997.     g_lpPlayer2->GetPosition(g_lpScene, &player2pos);
  998.  
  999.     // Get the camera's position
  1000.     g_lpCamera->GetPosition(g_lpScene, &camPos);
  1001.  
  1002.     switch (g_camState)
  1003.     {
  1004.         case OVER_SHOULDER:
  1005.         {
  1006.             // Position the camera such that it looks over the shoulder of the player and
  1007.             // keeps the opponent in view
  1008.             g_lpCamera->SetPosition(g_lpScene, camPos.x, camPos.y, D3DVAL(player1pos.z) + MOVE_NORMAL - 300);                   
  1009.             g_lpCamera->LookAt(g_lpPlayer2, g_lpScene, D3DRMCONSTRAIN_Z);
  1010.         }
  1011.         break;
  1012.  
  1013.         case BOTH_IN_VIEW:
  1014.         {
  1015.             // Position the camera such that it looks at both players all the time
  1016.  
  1017.             // Make midway point, this is what the camera will focus on
  1018.             D3DVECTOR vMidPoint;
  1019.             vMidPoint.x = 0.0f;
  1020.             vMidPoint.y = 0.0f;
  1021.             vMidPoint.z = (player1pos.z + player2pos.z) / D3DVAL(2);
  1022.             
  1023.             // Calculate vector that will keep both players in sight
  1024.             D3DVECTOR vNewCam;
  1025.             vNewCam.x = (float)abs((int)player2pos.z - (int)player1pos.z) + D3DVAL(300);
  1026.             vNewCam.y = camPos.y;
  1027.             vNewCam.z = vMidPoint.z;
  1028.  
  1029.             g_lpCamera->SetPosition(g_lpScene, vNewCam.x, vNewCam.y, vNewCam.z);
  1030.                             
  1031.             g_lpTmp->SetPosition(g_lpScene, vMidPoint.x, vMidPoint.y, vMidPoint.z);
  1032.             g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
  1033.         }
  1034.         break;
  1035.  
  1036.         case PILOT_VIEW:
  1037.         {                                               
  1038.             // Position the camera such that it looks through the eyes of the player
  1039.             // and fixes on the origin of the head frame of the opponent
  1040.  
  1041.             g_lpCamera->SetPosition(g_lpPlayer1HeadFrame, D3DVAL(0), D3DVAL(-10), D3DVAL(0));
  1042.             g_lpTmp->SetPosition(g_lpPlayer2HeadFrame, D3DVAL(0), D3DVAL(-10), D3DVAL(0));
  1043.             g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
  1044.         }
  1045.         break;
  1046.     }
  1047. }
  1048.  
  1049. //----------------------------------------------------------------------
  1050. // 
  1051. // Function     : TransitionCamera()
  1052. //
  1053. // Purpose      : Positions camera based upon camera state
  1054. //
  1055. //----------------------------------------------------------------------
  1056.  
  1057. void TransitionCamera()
  1058. {
  1059.     static D3DVALUE time = D3DVAL(0.0f);
  1060.  
  1061.     // Forward the transition animation time
  1062.     time += D3DVAL(0.04);
  1063.  
  1064.     // Set the time for the transitional animation
  1065.     g_lpAnim->SetTime(time);
  1066.  
  1067.     // Look at the g_lpScene frame
  1068.     g_lpCamera->LookAt(g_lpTmp, g_lpScene, D3DRMCONSTRAIN_Z);
  1069.  
  1070.     // If the animation has ended, run the demo
  1071.     if (time >= D3DVAL(1.0f))
  1072.     {
  1073.         g_appState = PLAYING_DEMO;
  1074.         g_lpAnim->Release();
  1075.         g_lpAnim = NULL;
  1076.         time = D3DVAL(0);
  1077.         PositionCamera();               
  1078.     }
  1079.  
  1080.     // Update debris so any debris in the scene doesn't just sit there doing nothing
  1081.     UpdateDebris();
  1082. }
  1083.  
  1084. //----------------------------------------------------------------------
  1085. // 
  1086. // Function     : AddDebris()
  1087. //
  1088. // Purpose      : Adds some debris to the scene
  1089. //
  1090. //----------------------------------------------------------------------
  1091.  
  1092. void AddDebris(D3DVECTOR vOrg, D3DVECTOR vVel, LPDIRECT3DRMMESHBUILDER pDebris)
  1093. {
  1094.     // vOrg is the origin of the debris, find first open spot and add 5 bits of debris
  1095.     int count = 0;
  1096.  
  1097.     for (int i = 0; i < NUM_DEBRIS; i ++)
  1098.     {
  1099.         // Find some debris that is not in use yet
  1100.         if (!g_debris[i].m_bInUse)
  1101.         {
  1102.             // Add some debris 
  1103.             g_debris[i].m_pFrame->AddVisual(pDebris);
  1104.             g_debris[i].m_pFrame->SetPosition(g_lpScene, vOrg.x, vOrg.y, vOrg.z);
  1105.             g_debris[i].m_pFrame->SetRotation(g_lpScene, D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5), D3DVAL(0.5));
  1106.             g_debris[i].m_life = 0;
  1107.  
  1108.             // Setup velocity and acceleration
  1109.             g_debris[i].m_vel.x = D3DVAL(-10 + (rand() % 20)) + vVel.x;
  1110.             g_debris[i].m_vel.y = D3DVAL(8) + D3DVAL(rand() % 10) + vVel.y;
  1111.             g_debris[i].m_vel.z = D3DVAL(-10 + (rand() % 20)) + vVel.z;
  1112.  
  1113.             g_debris[i].m_acc.x = D3DVAL(0);
  1114.             g_debris[i].m_acc.y = D3DVAL(-2);
  1115.             g_debris[i].m_acc.z = D3DVAL(0);                    
  1116.  
  1117.             // This piece of debris is now in use
  1118.             g_debris[i].m_bInUse = TRUE;
  1119.             g_debris[i].m_pMeshBuilder = pDebris;
  1120.             
  1121.             count ++;                   
  1122.         }
  1123.  
  1124.         // Return if we've added NUM_HIT_DEBRIS bits of debris
  1125.         if (count == NUM_HIT_DEBRIS) return;
  1126.     }   
  1127. }
  1128.  
  1129. //----------------------------------------------------------------------
  1130. // 
  1131. // Function     : UpdateDebris()
  1132. //
  1133. // Purpose      : Updates debris
  1134. //
  1135. //----------------------------------------------------------------------
  1136.  
  1137. void UpdateDebris()
  1138. {
  1139.     D3DVECTOR vPos;
  1140.  
  1141.     // Go through the array of debris and update any debris that is in use
  1142.  
  1143.     for (int i = 0; i < NUM_DEBRIS; i ++)
  1144.     {
  1145.         if (g_debris[i].m_bInUse)
  1146.         {
  1147.             // If the debris's life has not yet expired
  1148.             if (g_debris[i].m_life < DEBRIS_LIFE)
  1149.             {
  1150.                 // Move the debris
  1151.                 g_debris[i].m_pFrame->GetPosition(g_lpScene, &vPos);
  1152.                 
  1153.                 g_debris[i].m_vel.x += g_debris[i].m_acc.x;
  1154.                 g_debris[i].m_vel.y += g_debris[i].m_acc.y;
  1155.                 g_debris[i].m_vel.z += g_debris[i].m_acc.z;
  1156.  
  1157.                 vPos.x += g_debris[i].m_vel.x;
  1158.                 vPos.y += g_debris[i].m_vel.y;
  1159.                 vPos.z += g_debris[i].m_vel.z;
  1160.  
  1161.                 // Check to see whether the debris is below the floor
  1162.                 if (vPos.y < D3DVAL(-60))
  1163.                 {
  1164.                         // Bounce the debris
  1165.                         vPos.y = D3DVAL(-60);
  1166.                         g_debris[i].m_vel.y = -g_debris[i].m_vel.y / D3DVAL(1.5);
  1167.                 }
  1168.  
  1169.                 // Update the position of the debris
  1170.                 g_debris[i].m_pFrame->SetPosition(g_lpScene, vPos.x, vPos.y, vPos.z);
  1171.             }
  1172.             else
  1173.             {
  1174.                 // Remove the debris from the world
  1175.                 g_debris[i].m_pFrame->DeleteVisual(g_debris[i].m_pMeshBuilder);
  1176.                 g_debris[i].m_bInUse = FALSE;
  1177.             }
  1178.  
  1179.             // Age the debris
  1180.             g_debris[i].m_life ++;
  1181.         }
  1182.     }
  1183. }
  1184.  
  1185.