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

Windows编程

开发平台:

Visual C++

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