CONTROL.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:43k
源码类别:

Windows编程

开发平台:

Visual C++

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