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

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  4.  *
  5.  *  File: rm.cpp
  6.  *
  7.  ***************************************************************************/
  8.  
  9. // Includes....
  10. #include "rm.h"
  11. #include "directx.h"
  12. #include "mmsystem.h"
  13. #include "stdio.h"
  14. #include "control.h"
  15.  
  16. // Globals....
  17. LPDIRECT3DRMFRAME               g_lpScene = NULL;       // Scene frame
  18. LPDIRECT3DRMFRAME               g_lpCamera = NULL;      // Camera frame
  19. LPDIRECT3DRMFRAME               g_lpArena = NULL;       // Arena frame
  20. LPDIRECT3DRMFRAME               g_lpBackground = NULL;  // Background frame
  21.  
  22. LPDIRECT3DRMFRAME               g_lpPlayers = NULL;     // Encapsulating frame
  23. LPDIRECT3DRMFRAME               g_lpPlayer1 = NULL;     // Human player
  24. LPDIRECT3DRMFRAME               g_lpPlayer1HeadFrame = NULL;// Human player head frame
  25. LPDIRECT3DRMANIMATIONSET        g_lpPlayer1AnimSet = NULL;// Human player animation set
  26. LPDIRECT3DRMFRAME               g_lpPlayer2 = NULL;     // Computer player
  27. LPDIRECT3DRMFRAME               g_lpPlayer2HeadFrame = NULL;// Computer player head frame
  28. LPDIRECT3DRMANIMATIONSET        g_lpPlayer2AnimSet = NULL;// Computer player animation set
  29.  
  30. LPDIRECT3DRMFRAME               g_lpTmp = NULL;         // Temporary frame
  31.  
  32. LPDIRECT3DRMLIGHT               g_lpDir;                // Global light frame
  33.  
  34. LPDIRECT3DRMMESHBUILDER         g_lpRedDebris = NULL;   // Red debris model
  35. LPDIRECT3DRMMESHBUILDER         g_lpBlueDebris = NULL;  // Blue debris model
  36. Debris                          g_debris[NUM_DEBRIS];   // Debris
  37.  
  38. LPDIRECT3DRMANIMATION           g_lpAnim = NULL;        // Intro anim
  39.  
  40. // Timing stuff
  41. D3DVALUE                        g_timingDelta = D3DVAL(0.0f);
  42.  
  43. // Frame rate stuff
  44. DWORD                           g_dwLastTime = 0;
  45. DWORD                           g_dwCurTime = 0;
  46. DWORD                           g_dwFpsTime = 0;
  47. DWORD                           g_dwDeltaTime = 0;
  48. DWORD                           g_dwFramesRendered = 0;
  49. DWORD                           g_dwFps = 0;
  50.  
  51. // Externals....
  52. extern BOOL                     g_bShowStats;           // Defined in WINMAIN.CPP
  53. extern BOOL                     g_bHardware3D;          // Defined in DIRECTX.CPP
  54. extern LPDIRECT3DRM             g_lpD3DRM;              // Defined in DIRECTX.CPP
  55. extern LPDIRECT3DRMVIEWPORT     g_lpD3DRMViewport;      // Defined in DIRECTX.CPP
  56. extern LPDIRECT3DRMDEVICE       g_lpD3DRMDevice;        // Defined in DIRECTX.CPP
  57. extern LPDIRECTDRAWSURFACE      g_lpPrimary;            // Defined in DIRECTX.CPP
  58. extern LPDIRECTDRAWSURFACE      g_lpBackBuffer;         // Defined in DIRECTX.CPP
  59. extern LPDIRECTDRAWSURFACE      g_lpZBuffer;            // Defined in DIRECTX.CPP
  60. extern DWORD                    g_vidModeX;             // Defined in DIRECTX.CPP
  61. extern DWORD                    g_vidModeY;             // Defined in DIRECTX.CPP
  62. extern DWORD                    g_vidModeBIT;           // Defined in DIRECTX.CPP
  63. extern DWORD                    g_dwFontHeight;         // Defined in DIRECTX.CPP
  64. extern DWORD                    g_dwAveCharWidth;       // Defined in DIRECTX.CPP
  65.  
  66. extern DWORD                    g_player1health;        // Defined in CONTROL.CPP
  67. extern DWORD                    g_player2health;        // Defined in CONTROL.CPP
  68.  
  69. extern DWORD                    g_lbar1;                // Defined in DIRECTX.CPP
  70. extern DWORD                    g_wbar1;                // Defined in DIRECTX.CPP
  71. extern DWORD                    g_lbar2;                // Defined in DIRECTX.CPP
  72. extern DWORD                    g_wbar2;                // Defined in DIRECTX.CPP
  73. extern DWORD                    g_hbar1;                // Defined in DIRECTX.CPP
  74. extern DWORD                    g_hbar2;                // Defined in DIRECTX.CPP
  75.  
  76. extern AnimArgs                 g_player1AnimArgs;
  77. extern AnimArgs                 g_player2AnimArgs;
  78.  
  79. //----------------------------------------------------------------------
  80. // 
  81. // Function     : InitScene
  82. //
  83. // Purpose      : Initialises Direct3D RM objects and loads scene for demo
  84. //
  85. //----------------------------------------------------------------------
  86.  
  87. BOOL InitScene()
  88. {
  89.     LPDIRECT3DRMLIGHT           pAmb;
  90.     LPDIRECT3DRMFRAME           pLight;
  91.     LPDIRECT3DRMMESHBUILDER pMeshBuilder;
  92.  
  93.     // Create the scene (parent) frame
  94.     TRY_D3DRM(g_lpD3DRM->CreateFrame(NULL, &g_lpScene))
  95.  
  96.     // Create the camera (child of g_lpScene)
  97.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &g_lpCamera))
  98.  
  99.     // Create the arena frame
  100.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &g_lpArena))
  101.  
  102.     // Create the frame that encapsulates both players
  103.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &g_lpPlayers))
  104.     
  105.     // Create player frames
  106.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpPlayers, &g_lpPlayer1))
  107.  
  108.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpPlayers, &g_lpPlayer2))
  109.     
  110.     // Create temporary frame
  111.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &g_lpTmp))
  112.     
  113.     // Create lights and position in world
  114.     TRY_D3DRM(g_lpD3DRM->CreateLightRGB(D3DRMLIGHT_AMBIENT, D3DVAL(0.2), D3DVAL(0.2), D3DVAL(0.2), &pAmb))
  115.     
  116.     TRY_D3DRM(g_lpD3DRM->CreateLightRGB(D3DRMLIGHT_DIRECTIONAL, D3DVAL(0.7), D3DVAL(0.7), D3DVAL(0.7), &g_lpDir))
  117.  
  118.     // Create ambient light frame
  119.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &pLight))
  120.     
  121.     // Add the light to the frame
  122.     TRY_D3DRM(pLight->AddLight(pAmb))
  123.     
  124.     // Release the light frame
  125.     pLight->Release();  
  126.  
  127.     // Create directional light frame
  128.     TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpScene, &pLight))
  129.     
  130.     // Set position and orientation of directional light
  131.     pLight->SetPosition(g_lpScene, D3DVAL(1000), D3DVAL(1000), D3DVAL(1000));
  132.     pLight->SetOrientation(g_lpScene, D3DVAL(-1.0), D3DVAL(-1.0), D3DVAL(1.0), D3DVAL(0.0), D3DVAL(1.0), D3DVAL(0.0));
  133.     
  134.     // Add the light to the frame
  135.     TRY_D3DRM(pLight->AddLight(g_lpDir))
  136.     
  137.     // Enable lights only for any object that is a child of g_lpPlayers
  138.     TRY_D3DRM(g_lpDir->SetEnableFrame(g_lpPlayers))
  139.  
  140.     // Release the light frame
  141.     pLight->Release();
  142.  
  143.     // Create mesh builder for arena
  144.     TRY_D3DRM(g_lpD3DRM->CreateMeshBuilder(&pMeshBuilder))
  145.     
  146.     // Load the arena
  147.     TRY_D3DRM(pMeshBuilder->Load("ARENA.X", NULL, D3DRMLOAD_FROMFILE, LoadTextures, NULL))
  148.     
  149.     // Make sure we use perspective correct!
  150.     pMeshBuilder->SetPerspective(TRUE);
  151.     
  152.     // Add the mesh to the scene
  153.     TRY_D3DRM(g_lpArena->AddVisual(pMeshBuilder))
  154.     
  155.     g_lpArena->SetZbufferMode(D3DRMZBUFFER_DISABLE);
  156.  
  157.     // Release the mesh builder
  158.     pMeshBuilder->Release();
  159.  
  160.     // Load player 1's model    
  161.     TRY_D3DRM(g_lpD3DRM->CreateAnimationSet(&g_lpPlayer1AnimSet))
  162.  
  163.     // Load the model and animation
  164.     TRY_D3DRM(g_lpPlayer1AnimSet->Load("SKMECH.X", NULL, D3DRMLOAD_FROMFILE, LoadTextures, NULL, g_lpPlayer1))
  165.  
  166.     // Add animation callback for player 1
  167.     g_player1AnimArgs.lpAnimSet = g_lpPlayer1AnimSet;
  168.     g_player1AnimArgs.time              = D3DVAL(0);
  169.     TRY_D3DRM(g_lpPlayer1->AddMoveCallback(Player1AnimationCallback, NULL))
  170.  
  171.     // Setup the initial position of player 1
  172.     g_lpPlayer1->SetPosition(g_lpScene, D3DVAL(0), D3DVAL(0), D3DVAL(-200));
  173.  
  174.     // Load player 2's model
  175.     TRY_D3DRM(g_lpD3DRM->CreateAnimationSet(&g_lpPlayer2AnimSet))
  176.  
  177.     // Load the model and animation
  178.     TRY_D3DRM(g_lpPlayer2AnimSet->Load("DEMECH.X", NULL, D3DRMLOAD_FROMFILE, LoadTextures, NULL, g_lpPlayer2))
  179.     
  180.     // Add animation callback for player 2
  181.     g_player2AnimArgs.lpAnimSet = g_lpPlayer2AnimSet;
  182.     g_player2AnimArgs.time              = D3DVAL(0);
  183.     TRY_D3DRM(g_lpPlayer2->AddMoveCallback(Player2AnimationCallback, NULL))     
  184.  
  185.     for (int i = 0; i < NUM_DEBRIS; i ++)
  186.     {
  187.         TRY_D3DRM(g_lpD3DRM->CreateFrame(g_lpPlayers, &g_debris[i].m_pFrame))
  188.         
  189.         g_debris[i].m_bInUse = FALSE;
  190.     }
  191.  
  192.     // Load the red debris
  193.     TRY_D3DRM(g_lpD3DRM->CreateMeshBuilder(&g_lpRedDebris))
  194.  
  195.     TRY_D3DRM(g_lpRedDebris->Load("debris_r.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL))
  196.     
  197.     // Load the blue debris
  198.     TRY_D3DRM(g_lpD3DRM->CreateMeshBuilder(&g_lpBlueDebris))
  199.  
  200.     TRY_D3DRM(g_lpBlueDebris->Load("debris_b.x", NULL, D3DRMLOAD_FROMFILE, NULL, NULL))
  201.  
  202.     // Setup the initial position of player 2
  203.     g_lpPlayer2->SetPosition(g_lpScene, D3DVAL(0), D3DVAL(0), D3DVAL(200));
  204.  
  205.     // Create the intro path
  206.     TRY_D3DRM(g_lpD3DRM->CreateAnimation(&g_lpAnim))
  207.  
  208.     // Setup the animation options
  209.     g_lpAnim->SetOptions(D3DRMANIMATION_OPEN | 
  210.                          D3DRMANIMATION_LINEARPOSITION | 
  211.                          D3DRMANIMATION_POSITION);
  212.     
  213.     // Add the starting position (as a keyframe)
  214.     g_lpAnim->AddPositionKey(D3DVAL(0), D3DVAL(200), D3DVAL(2000), D3DVAL(0));
  215.     
  216.     // Add the ending position (as a keyframe)
  217.     g_lpAnim->AddPositionKey(D3DVAL(1), D3DVAL(700), D3DVAL(100), D3DVAL(0));
  218.     
  219.     // Make the camera follow this animation
  220.     g_lpAnim->SetFrame(g_lpCamera);     
  221.  
  222.     // Retrieve player 1 and player 2's head frames     
  223.     LPDIRECT3DRMOBJECT tmp;
  224.             
  225.     TRY_D3DRM(g_lpD3DRM->GetNamedObject("x3ds_Head", &tmp))
  226.     g_lpPlayer1HeadFrame = (LPDIRECT3DRMFRAME)tmp;
  227.  
  228.     TRY_D3DRM(g_lpD3DRM->GetNamedObject("x3ds_xHead", &tmp))
  229.     g_lpPlayer2HeadFrame = (LPDIRECT3DRMFRAME)tmp;
  230.  
  231.     // Yahoo!
  232.     return TRUE;
  233. }
  234.  
  235. //----------------------------------------------------------------------
  236. // 
  237. // Function     : TermScene
  238. //
  239. // Purpose      : Destroys scene
  240. //
  241. //----------------------------------------------------------------------
  242.  
  243. void TermScene()
  244. {       
  245.     // Destroy the scene frame
  246.     if (g_lpScene)
  247.     {
  248.         g_lpScene->Release();
  249.         g_lpScene = NULL;
  250.     }
  251.  
  252.     // Destroy the animation sets
  253.     if (g_lpPlayer1AnimSet)
  254.     {
  255.         g_lpPlayer1AnimSet->Release();
  256.         g_lpPlayer1AnimSet = NULL;
  257.     }
  258.  
  259.     if (g_lpPlayer2AnimSet)
  260.     {
  261.         g_lpPlayer2AnimSet->Release();
  262.         g_lpPlayer2AnimSet = NULL;
  263.     }
  264. }
  265.  
  266. //----------------------------------------------------------------------
  267. // 
  268. // Function     : RenderScene
  269. //
  270. // Purpose      : Renders scene
  271. //
  272. //----------------------------------------------------------------------
  273.  
  274. BOOL RenderScene()
  275. {
  276.     static BOOL b = FALSE;
  277.  
  278.     // Verify both surfaces
  279.     if (!g_lpPrimary) return FALSE;
  280.  
  281.     if (!g_lpZBuffer) return FALSE;
  282.  
  283.     // Perform some timing stuff        
  284.     g_dwCurTime   = timeGetTime();
  285.     g_dwDeltaTime = g_dwCurTime - g_dwLastTime;
  286.     g_dwLastTime  = g_dwCurTime;
  287.     g_dwFpsTime  += g_dwDeltaTime;
  288.  
  289.     // Move the scene
  290.     g_lpScene->Move(D3DVAL(g_dwDeltaTime));
  291.  
  292.     if (b) {
  293.         b = FALSE;
  294.         TRY_D3DRM(g_lpD3DRMViewport->ForceUpdate(0, 0, g_vidModeX, g_vidModeY))
  295.     }
  296.  
  297.     // Restore the primary surface if it has been lost
  298.     if (g_lpPrimary->IsLost())
  299.     {
  300.             HRESULT rval = g_lpPrimary->Restore();
  301.             if (rval != DD_OK) return TRUE;
  302.             TRY_D3DRM(g_lpD3DRMViewport->ForceUpdate(0, 0, g_vidModeX, g_vidModeY))
  303.             b = TRUE;
  304.     }
  305.     
  306.     // Restore the ZBuffer if it has been lost
  307.     if (g_lpZBuffer->IsLost())
  308.     {
  309.             HRESULT rval = g_lpZBuffer->Restore();
  310.             if (rval != DD_OK) return TRUE;
  311.             TRY_D3DRM(g_lpD3DRMViewport->ForceUpdate(0, 0, g_vidModeX, g_vidModeY))
  312.     }
  313.  
  314.     // Clear the viewport ready for rendering
  315.     TRY_D3DRM(g_lpD3DRMViewport->Clear())
  316.     
  317.     // Render the scene
  318.     TRY_D3DRM(g_lpD3DRMViewport->Render(g_lpScene))
  319.  
  320.     g_dwFramesRendered ++;
  321.  
  322.     // Show stats if necessary
  323.     if (g_bShowStats)
  324.     {
  325.         // String to hold stats
  326.         char sStats[256];               
  327.  
  328.         // If 2 seconds have elapsed, calculate the frame rate
  329.         if (g_dwFpsTime > 2000)
  330.         {
  331.             g_dwFps             = g_dwFramesRendered / 2;
  332.             g_dwFramesRendered  = 0;
  333.             g_dwFpsTime         = 0;
  334.         }
  335.  
  336.         // Copy info into stat string
  337.         sprintf(sStats, "SX:%d, SY:%d, SBD:%d FPS:%d, %s", g_vidModeX, g_vidModeY, g_vidModeBIT, g_dwFps, g_bHardware3D ? "(H)" : "(S)");
  338.  
  339.         // Get a DC to the backbuffer (very useful!)
  340.         HDC hDC;
  341.         g_lpBackBuffer->GetDC(&hDC);
  342.         if (!hDC) return FALSE;
  343.  
  344.         // Use TextOut to draw the text onto the surface
  345.         DWORD dwStringPixelWidth = strlen(sStats) * g_dwAveCharWidth;
  346.  
  347.         SetBkMode( hDC, TRANSPARENT );
  348.         SetTextColor( hDC, RGB(255,255,255) );
  349.         TextOut(hDC, (g_vidModeX >> 1) - (dwStringPixelWidth >> 1), g_vidModeY - g_dwFontHeight, sStats, strlen(sStats));
  350.  
  351.         // Must release DC before calling Flip()
  352.         g_lpBackBuffer->ReleaseDC(hDC);
  353.     }
  354.  
  355.     // Draw the power bars
  356.     DDBLTFX ddBltFx;
  357.     memset(&ddBltFx, 0, sizeof(DDBLTFX));
  358.     ddBltFx.dwSize = sizeof(DDBLTFX);
  359.  
  360.     RECT rcBar1 = { g_lbar1, g_hbar1, g_lbar1 + g_wbar1, g_hbar1 + g_hbar2 };
  361.     RECT rcBar2 = { g_lbar2, g_hbar1, g_lbar2 + g_wbar2, g_hbar1 + g_hbar2 };
  362.  
  363.     switch (g_vidModeBIT)
  364.     {
  365.         case 8  : ddBltFx.dwFillColor = 253; break;
  366.         case 16 : ddBltFx.dwFillColor = 1 << 4; break;
  367.         case 24 : ddBltFx.dwFillColor = 1 << 7; break;
  368.     }
  369.     if (g_player1health > 0) {
  370.         TRY_DD(g_lpBackBuffer->Blt(&rcBar1, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx))
  371.         TRY_D3DRM(g_lpD3DRMViewport->ForceUpdate(rcBar1.left, rcBar1.top, rcBar1.right, rcBar1.bottom))
  372.     }
  373.  
  374.     switch (g_vidModeBIT)
  375.     {
  376.         case 8  : ddBltFx.dwFillColor = 254; break;
  377.         case 16 : ddBltFx.dwFillColor = 1 << 5 << 5 << 4; break;
  378.         case 24 : ddBltFx.dwFillColor = 1 << 8 << 8 << 7; break;
  379.     }   
  380.     if (g_player2health > 0) {
  381.         TRY_DD(g_lpBackBuffer->Blt(&rcBar2, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddBltFx))
  382.         TRY_D3DRM(g_lpD3DRMViewport->ForceUpdate(rcBar2.left, rcBar2.top, rcBar2.right, rcBar2.bottom))
  383.     }
  384.  
  385.     // And update the device
  386.     TRY_D3DRM(g_lpD3DRMDevice->Update())
  387.  
  388.     // Finally, flip the back buffer onto the primary surface, displaying
  389.     // the last rendered frame
  390.     TRY_DD(g_lpPrimary->Flip(NULL, DDFLIP_WAIT))
  391.  
  392.     // Yahoo!
  393.     return TRUE;
  394. }
  395.  
  396. //------------------------------------------------------------------
  397. // 
  398. // Function     : LoadTextures
  399. //
  400. // Purpose      : Loads an individual texture
  401. //
  402. // NOTE         : Textures must have a size divisible by 2 (e.g. 128x64, 256x256)
  403. //
  404. //------------------------------------------------------------------
  405.  
  406. HRESULT LoadTextures(char *sName, void *pArg, LPDIRECT3DRMTEXTURE *hTexture)
  407. {    
  408.     char *sTmpName = sName;
  409.             
  410.     // Find the extension
  411.     while(sTmpName[0] != '.') sTmpName ++;
  412.  
  413.     // Add .ppm to the picture file used by 3D Studio (.TGA, .GIF, .CEL etc)
  414.     strcpy(sTmpName, ".ppm");
  415.     
  416.     // Load the texture
  417.     if (FAILED(g_lpD3DRM->LoadTexture(sName, hTexture))) return -1;
  418.  
  419.     if (!strcmp(sName, "gdk_fill.ppm"))
  420.     {
  421.         (*hTexture)->SetShades(1);
  422.     }
  423.  
  424.     return 0;
  425. }
  426.  
  427.