Game.cpp
上传用户:whgydz
上传日期:2007-01-12
资源大小:2259k
文件大小:23k
源码类别:

其他书籍

开发平台:

HTML/CSS

  1. // Game.cpp: implementation of the CGame class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "Game.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CGame::CGame()
  9. {
  10. m_pD3D = NULL;
  11. m_pD3DDevice = NULL;
  12. m_pDirectInput = NULL;
  13. m_pKeyboard = NULL;
  14. m_pMouse = NULL;
  15. m_pDirectAudioPerformance = NULL;
  16. m_pDirectAudioLoader = NULL;
  17. m_dwFrames = 0;
  18. m_dwStartTime = 0;
  19. m_dwEndTime = 0;
  20. m_dwTotalPolygons = 0;
  21. m_fQuit = false;
  22. //Initialise COM
  23. CoInitialize(NULL);
  24. m_nMouseLeft = 0;
  25. m_nMouseRight = 0;
  26. m_nMouseX = 0;
  27. m_nMouseY = 0;
  28. m_pFont = NULL;
  29. m_pSound1 = NULL;
  30. m_pSound2 = NULL;
  31. m_pSound3 = NULL;
  32. m_pSound4 = NULL;
  33. m_pSoundFailed = NULL;
  34. m_pSoundBG = NULL;
  35. m_pPanelMouse = NULL;
  36. m_pPanel1 = NULL;
  37. m_pPanel2 = NULL;
  38. m_pPanel3 = NULL;
  39. m_pPanel4 = NULL;
  40. }
  41. CGame::~CGame()
  42. {
  43. //Game finished, so destroy game objects
  44. LogInfo("<br>Finish Game:");
  45. //Clean up our objects and interfaces
  46. CleanUpGame();
  47. CleanUpDirectAudio();
  48. CleanUpDirectInput();
  49. CleanUpDirect3D();
  50. CoUninitialize();
  51. //Game finished, so save statistics to log
  52. DWORD dwDuration = (m_dwEndTime - m_dwStartTime) / 1000;
  53. if((dwDuration != 0)&&(m_dwFrames != 0))
  54. {
  55. //Log stats
  56. LogInfo("<br>Statistics:");
  57. LogInfo("<li>Start Time (ms): %d", m_dwStartTime);
  58. LogInfo("<li>End Time (ms): %d", m_dwEndTime);
  59. LogInfo("<li>Duration (s): %d", dwDuration);
  60. LogInfo("<li>Total Frame Count: %d", m_dwFrames);
  61. LogInfo("<li>Average FPS: %d", (m_dwFrames / dwDuration));
  62. LogInfo("<li>Total Polygons: %d", m_dwTotalPolygons);
  63. LogInfo("<li>Average Polygons per Frame: %d", (m_dwTotalPolygons / m_dwFrames));
  64. }
  65. else
  66. {
  67. LogInfo("<br>No statistics to report");
  68. }
  69. StopLogging();
  70. }
  71. void CGame::CleanUpGame()
  72. {
  73. SafeDelete(m_pFont);
  74. SafeDelete(m_pSound1);
  75. SafeDelete(m_pSound2);
  76. SafeDelete(m_pSound3);
  77. SafeDelete(m_pSound4);
  78. SafeDelete(m_pSoundFailed);
  79. SafeDelete(m_pSoundBG);
  80. SafeDelete(m_pPanelMouse);
  81. SafeDelete(m_pPanel1);
  82. SafeDelete(m_pPanel2);
  83. SafeDelete(m_pPanel3);
  84. SafeDelete(m_pPanel4);
  85. }
  86. void CGame::CleanUpDirectAudio()
  87. {
  88. //Stop all sounds.
  89. m_pDirectAudioPerformance->Stop(NULL, NULL, 0, 0);
  90.  
  91. //CleanUp
  92.     m_pDirectAudioPerformance->CloseDown();
  93.  
  94.     SafeRelease(m_pDirectAudioLoader);
  95.     SafeRelease(m_pDirectAudioPerformance);
  96. LogInfo("<li>CleanUpDirectAudio finished.");
  97. }
  98. void CGame::CleanUpDirectInput()
  99. {
  100. if(m_pKeyboard)
  101. {
  102. m_pKeyboard->Unacquire(); 
  103. }
  104. if(m_pMouse)
  105. {
  106. m_pMouse->Unacquire();
  107. }
  108. SafeRelease(m_pMouse);
  109. SafeRelease(m_pKeyboard);
  110. SafeRelease(m_pDirectInput);
  111. LogInfo("<li>CleanUpDirectInput finished.");
  112. }
  113. void CGame::CleanUpDirect3D()
  114. {
  115. SafeRelease(m_pD3DDevice);
  116. SafeRelease(m_pD3D);
  117. LogInfo("<li>CleanUpDirect3D finished.");
  118. }
  119. bool CGame::Initialise(HWND hWnd, HINSTANCE hInst, UINT nWidth, UINT nHeight)
  120. {
  121. //Initialise Direct3D
  122. if(!InitialiseDirect3D(hWnd, nWidth, nHeight))
  123. {
  124. return false;
  125. }
  126. //Initialise DirectInput
  127. if(!InitialiseDirectInput(hWnd, hInst))
  128. {
  129. return false;
  130. }
  131. if(!InitialiseDirectAudio(hWnd))
  132. {
  133. return false;
  134. }
  135. //Initialise Lighting
  136. if(!InitialiseLights()) 
  137. {
  138. return false;
  139. }
  140. //Initialise Game Objects
  141. if(!InitialiseGame())
  142. {
  143. return false;
  144. }
  145. return true;
  146. }
  147. bool CGame::InitialiseGame()
  148. {
  149. LogInfo("<br>Initialise Game:");
  150. //Setup games objects here
  151. //Setup fonts here
  152. m_pFont = new CFont(m_pD3DDevice, "Verdana", 12, false, false, false);
  153. //Setup panels for 2D
  154. m_pPanelMouse = new CPanel(m_pD3DDevice, 32, 32, m_nScreenWidth, m_nScreenHeight);
  155. m_pPanelMouse->SetTexture("Textures\Mouse.bmp", D3DCOLOR_XRGB(0, 0, 0));
  156. m_pPanel1 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
  157. m_pPanel1->SetTexture("Textures\1.bmp");
  158. m_pPanel2 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
  159. m_pPanel2->SetTexture("Textures\2.bmp");
  160. m_pPanel3 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
  161. m_pPanel3->SetTexture("Textures\3.bmp");
  162. m_pPanel4 = new CPanel(m_pD3DDevice, 128, 128, m_nScreenWidth, m_nScreenHeight);
  163. m_pPanel4->SetTexture("Textures\4.bmp");
  164. //Setup sounds
  165. m_pSound1 = new CSound();
  166. m_pSound1->InitialiseForWavMidi(m_pDirectAudioPerformance, m_pDirectAudioLoader);
  167. m_pSound1->LoadSound("notify.wav");
  168. m_pSound2 = new CSound();
  169. m_pSound2->InitialiseForWavMidi(m_pDirectAudioPerformance, m_pDirectAudioLoader);
  170. m_pSound2->LoadSound("chimes.wav");
  171. m_pSound3 = new CSound();
  172. m_pSound3->InitialiseForWavMidi(m_pDirectAudioPerformance, m_pDirectAudioLoader);
  173. m_pSound3->LoadSound("chord.wav");
  174. m_pSound4 = new CSound();
  175. m_pSound4->InitialiseForWavMidi(m_pDirectAudioPerformance, m_pDirectAudioLoader);
  176. m_pSound4->LoadSound("ding.wav");
  177. m_pSoundFailed = new CSound();
  178. m_pSoundFailed->InitialiseForWavMidi(m_pDirectAudioPerformance, m_pDirectAudioLoader);
  179. m_pSoundFailed->LoadSound("Fail.wav");
  180. m_pSoundBG = new CSound();
  181. m_pSoundBG->InitialiseForMP3();
  182. m_pSoundBG->LoadSound("Aai_Took-Needthew-3776_hifi.mp3");
  183. return true;
  184. }
  185. D3DFORMAT CGame::CheckDisplayMode(UINT nWidth, UINT nHeight, UINT nDepth)
  186. {
  187. UINT x;
  188. D3DDISPLAYMODE d3ddm;
  189. for(x = 0; x < m_pD3D->GetAdapterModeCount(0); x++)
  190. {
  191. m_pD3D->EnumAdapterModes(0, x, &d3ddm);
  192. if(d3ddm.Width == nWidth)
  193. {
  194. if(d3ddm.Height == nHeight)
  195. {
  196. if((d3ddm.Format == D3DFMT_R5G6B5) || (d3ddm.Format == D3DFMT_X1R5G5B5) || (d3ddm.Format == D3DFMT_X4R4G4B4))
  197. {
  198. if(nDepth == 16)
  199. {
  200. return d3ddm.Format;
  201. }
  202. }
  203. else if((d3ddm.Format == D3DFMT_R8G8B8) || (d3ddm.Format == D3DFMT_X8R8G8B8))
  204. {
  205. if(nDepth == 32)
  206. {
  207. return d3ddm.Format;
  208. }
  209. }
  210. }
  211. }
  212. }
  213. return D3DFMT_UNKNOWN;
  214. }
  215. bool CGame::InitialiseDirectAudio(HWND hWnd)
  216. {
  217. LogInfo("<br>Initialise DirectAudio:");
  218. //Create the DirectAudio performance object
  219. if(CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC, 
  220. IID_IDirectMusicPerformance8, (void**) &m_pDirectAudioPerformance) != S_OK)
  221. {
  222. LogError("<li>Failed to create the DirectAudio perfomance object.");
  223. return false;
  224. }
  225. else
  226. {
  227. LogInfo("<li>DirectAudio perfomance object created OK.");
  228. }
  229. //Create the DirectAudio loader object
  230. if(CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, 
  231. IID_IDirectMusicLoader8, (void**) &m_pDirectAudioLoader) != S_OK)
  232. {
  233. LogError("<li>Failed to create the DirectAudio loader object.");
  234. return false;
  235. }
  236. else
  237. {
  238. LogInfo("<li>DirectAudio loader object created OK.");
  239. }
  240. //Initialise the performance object
  241. if(FAILED(m_pDirectAudioPerformance->InitAudio(NULL, NULL, hWnd, DMUS_APATH_SHARED_STEREOPLUSREVERB,
  242.  64, DMUS_AUDIOF_ALL, NULL)))
  243. {
  244. LogError("<li>Failed to initialise the DirectAudio perfomance object.");
  245. return false;
  246. }
  247. else
  248. {
  249. LogInfo("<li>Initialised the DirectAudio perfomance object OK.");
  250. }
  251. //Get the our applications "sounds" directory.
  252.     CHAR strSoundPath[MAX_PATH];
  253.     GetCurrentDirectory(MAX_PATH, strSoundPath);
  254.     strcat(strSoundPath, "\Sounds");
  255.  
  256. //Convert the path to unicode.
  257.     WCHAR wstrSoundPath[MAX_PATH];
  258.     MultiByteToWideChar(CP_ACP, 0, strSoundPath, -1, wstrSoundPath, MAX_PATH);
  259.  
  260.     //Set the search directory.
  261.     if(FAILED(m_pDirectAudioLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, wstrSoundPath, FALSE)))
  262. {
  263. LogError("<li>Failed to set the search directory '%s'.", strSoundPath);
  264. return false;
  265. }
  266. else
  267. {
  268. LogInfo("<li>Search directory '%s' set OK.", strSoundPath);
  269. }
  270. return true;
  271. }
  272. bool CGame::InitialiseDirectInput(HWND hWnd, HINSTANCE hInst)
  273. {
  274. LogInfo("<br>Initialise DirectInput:");
  275. //Create the DirectInput object
  276. if(FAILED(DirectInput8Create(hInst, DIRECTINPUT_VERSION, 
  277.   IID_IDirectInput8, (void**)&m_pDirectInput, NULL))) 
  278. LogError("<li>Unable to create DirectInput interface.");
  279. return false;
  280. }
  281. else
  282. {
  283. LogInfo("<li>DirectInput interface created OK");
  284. }
  285. //KEYBOARD =======================================================================
  286. //Create the keyboard device object
  287. if(FAILED(m_pDirectInput->CreateDevice(GUID_SysKeyboard, &m_pKeyboard, NULL))) 
  288. CleanUpDirectInput();
  289. LogError("<li>Unable to create DirectInput keyboard device interface.");
  290. return false; 
  291. }
  292. else
  293. {
  294. LogInfo("<li>DirectInput keyboard device interface created OK.");
  295. }
  296. //Set the data format for the keyboard
  297. if(FAILED(m_pKeyboard->SetDataFormat(&c_dfDIKeyboard)))
  298. CleanUpDirectInput();
  299. LogError("<li>Unable to set the keyboard data format.");
  300. return false; 
  301. }
  302. else
  303. {
  304. LogInfo("<li>Set the keyboard data format OK.");
  305. }
  306. //Set the cooperative level for the keyboard
  307. if(FAILED(m_pKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
  308. CleanUpDirectInput();
  309. LogError("<li>Unable to set the keyboard cooperative level.");
  310. return false;
  311. }
  312. else
  313. {
  314. LogInfo("<li>Set the keyboard cooperative level OK.");
  315. }
  316. //Acquire the keyboard
  317. if(m_pKeyboard)
  318. {
  319. m_pKeyboard->Acquire(); 
  320. }
  321. //MOUSE =======================================================================
  322. //Create the mouse device object
  323. if(FAILED(m_pDirectInput->CreateDevice(GUID_SysMouse, &m_pMouse, NULL)))
  324. CleanUpDirectInput();
  325. LogError("<li>Unable to create DirectInput mouse device interface.");
  326. return false; 
  327. }
  328. else
  329. {
  330. LogInfo("<li>DirectInput mouse device interface created OK.");
  331. }
  332. //Set the data format for the mouse
  333. if(FAILED(m_pMouse->SetDataFormat(&c_dfDIMouse)))
  334. CleanUpDirectInput();
  335. LogError("<li>Unable to set the mouse data format.");
  336. return false; 
  337. }
  338. else
  339. {
  340. LogInfo("<li>Set the mouse data format OK.");
  341. }
  342. //Set the cooperative level for the mouse
  343. if(FAILED(m_pMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
  344. CleanUpDirectInput();
  345. LogError("<li>Unable to set the mouse cooperative level.");
  346. return false;
  347. }
  348. else
  349. {
  350. LogInfo("<li>Set the mouse cooperative level OK.");
  351. }
  352. //Acquire the mouse
  353. if(m_pMouse)
  354. {
  355. m_pMouse->Acquire(); 
  356. }
  357. return true;
  358. }
  359. bool CGame::InitialiseDirect3D(HWND hWnd, UINT nWidth, UINT nHeight)
  360. {
  361. LogInfo("<br>Initialise Direct3D:");
  362.     //First of all, create the main D3D object. If it is created successfully we 
  363.     //should get a pointer to an IDirect3D8 interface.
  364.     m_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
  365.     if(m_pD3D == NULL)
  366.     {
  367. LogError("<li>Unable to create DirectX8 interface.");
  368.         return false;
  369.     }
  370.     //Get the current display mode
  371.     D3DDISPLAYMODE d3ddm;
  372. d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 32);
  373. if(d3ddm.Format != D3DFMT_UNKNOWN)
  374. {
  375. //Width x Height x 32bit has been selected
  376. d3ddm.Width = nWidth;
  377. d3ddm.Height = nHeight;
  378. LogInfo("<li>%d x %d x 32bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
  379. }
  380. else
  381. {
  382. d3ddm.Format = CheckDisplayMode(nWidth, nHeight, 16);
  383. if(d3ddm.Format != D3DFMT_UNKNOWN)
  384. {
  385.             //Width x Height x 16bit has been selected
  386. d3ddm.Width = nWidth;
  387. d3ddm.Height = nHeight;
  388. LogInfo("<li>%d x %d x 16bit back buffer format selected. Format = %d.", nWidth, nHeight, d3ddm.Format);
  389. }
  390.         else
  391. {
  392. LogError("<li>Unable to select back buffer format for %d x %d.", nWidth, nHeight);
  393.             return false;
  394.         }
  395. }
  396.     //Create a structure to hold the settings for our device
  397.     D3DPRESENT_PARAMETERS d3dpp; 
  398.     ZeroMemory(&d3dpp, sizeof(d3dpp));
  399. d3dpp.Windowed = FALSE;
  400.     d3dpp.BackBufferCount = 1;
  401.     d3dpp.BackBufferFormat = d3ddm.Format;
  402.     d3dpp.BackBufferWidth = d3ddm.Width;
  403.     d3dpp.BackBufferHeight = d3ddm.Height;
  404.     d3dpp.hDeviceWindow = hWnd;
  405.     d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
  406. d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
  407.     d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE;
  408. m_nScreenWidth = d3ddm.Width;
  409. m_nScreenHeight = d3ddm.Height;
  410. //Select the best depth buffer, select 32, 24 or 16 bit
  411.     if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32) == D3D_OK)
  412. {
  413.         d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
  414.         d3dpp.EnableAutoDepthStencil = TRUE;
  415. LogInfo("<li>32bit depth buffer selected");
  416.     }
  417.     else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8) == D3D_OK)
  418.     {
  419. d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
  420.         d3dpp.EnableAutoDepthStencil = TRUE;
  421. LogInfo("<li>24bit depth buffer selected");
  422. }
  423.     else if(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) == D3D_OK)
  424.     {
  425. d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
  426.         d3dpp.EnableAutoDepthStencil = TRUE;
  427. LogInfo("<li>16bit depth buffer selected");
  428. }
  429.     else
  430. {
  431.         d3dpp.EnableAutoDepthStencil = FALSE;
  432. LogError("<li>Unable to select depth buffer.");
  433. }
  434.     //Create a Direct3D device.
  435.     if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, 
  436.                                    D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice)))
  437.     {
  438. LogError("<li>Unable to create device.");
  439.         return false;
  440.     }
  441.     
  442. //Turn on back face culling. This is becuase we want to hide the back of our polygons
  443. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW)))
  444. {
  445. LogError("<li>SetRenderState: D3DRS_CULLMODE Failed");
  446. return false;
  447. }
  448. else
  449. {
  450. LogInfo("<li>SetRenderState: D3DRS_CULLMODE OK");
  451. }
  452. //Turn on Depth Buffering
  453. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE)))
  454. {
  455. LogError("<li>SetRenderState: D3DRS_ZENABLE Failed");
  456. return false;
  457. }
  458. else
  459. {
  460. LogInfo("<li>SetRenderState: D3DRS_ZENABLE OK");
  461. }
  462. //Set fill state. Possible values: D3DFILL_POINT, D3DFILL_WIREFRAME, D3DFILL_SOLID
  463. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID)))
  464. {
  465. LogError("<li>SetRenderState: D3DRS_FILLMODE Failed");
  466. return false;
  467. }
  468. else
  469. {
  470. LogInfo("<li>SetRenderState: D3DRS_FILLMODE OK");
  471. }
  472. //Set the D3DRS_NORMALIZENORMALS render state to fix the problem when scaling the objects get darker
  473. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE)))
  474. {
  475. LogError("<li>SetRenderState: D3DRS_NORMALIZENORMALS Failed");
  476. return false;
  477. }
  478. else
  479. {
  480. LogInfo("<li>SetRenderState: D3DRS_NORMALIZENORMALS OK");
  481. }
  482. //Enable alpha blending so we can use transparent textures
  483. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  TRUE)))
  484. {
  485. LogError("<li>SetRenderState: D3DRS_ALPHABLENDENABLE Failed");
  486. return false;
  487. }
  488. else
  489. {
  490. //Set how the texture should be blended (use alpha)
  491. m_pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  492. m_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  493. LogInfo("<li>SetRenderState: D3DRS_ALPHABLENDENABLE OK");
  494. }
  495.     return true;
  496. }
  497. bool CGame::InitialiseLights()
  498. {
  499. LogInfo("<br>Initialise Lights:");
  500. D3DLIGHT8 d3dLight;
  501. //Initialize the light structure.
  502. ZeroMemory(&d3dLight, sizeof(D3DLIGHT8));
  503. d3dLight.Type = D3DLIGHT_POINT;
  504. d3dLight.Position.x = -30.0f;
  505. d3dLight.Position.y = 0.0f;
  506. d3dLight.Position.z = -15.0f;
  507. d3dLight.Attenuation0 = 1.0f; 
  508. d3dLight.Attenuation1 = 0.0f; 
  509. d3dLight.Attenuation2 = 0.0f; 
  510. d3dLight.Range = 1000.0f;
  511. d3dLight.Diffuse.r = 1.0f;
  512. d3dLight.Diffuse.g = 1.0f;
  513. d3dLight.Diffuse.b = 1.0f;
  514. d3dLight.Ambient.r = 0.0f;
  515. d3dLight.Ambient.g = 0.0f;
  516. d3dLight.Ambient.b = 0.0f;
  517. d3dLight.Specular.r = 0.0f;
  518. d3dLight.Specular.g = 0.0f;
  519. d3dLight.Specular.b = 0.0f;
  520. //Assign the point light to our device in poisition (index) 0
  521. if(FAILED(m_pD3DDevice->SetLight(0, &d3dLight)))
  522. {
  523. LogError("<li>SetLight Failed");
  524. return false;
  525. }
  526. else
  527. {
  528. LogInfo("<li>SetLight OK");
  529. }
  530. //Enable our point light in position (index) 0
  531. if(FAILED(m_pD3DDevice->LightEnable(0, TRUE)))
  532. {
  533. LogError("<li>LightEnable Failed");
  534. return false;
  535. }
  536. else
  537. {
  538. LogInfo("<li>LightEnable OK");
  539. }
  540. //Turn on lighting
  541.     if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE)))
  542. {
  543. LogError("<li>SetRenderState: D3DRS_LIGHTING Failed");
  544. return false;
  545. }
  546. else
  547. {
  548. LogInfo("<li>SetRenderState: D3DRS_LIGHTING OK");
  549. }
  550. //Set ambient light level
  551. if(FAILED(m_pD3DDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(100, 100, 100))))
  552. {
  553. LogError("<li>SetRenderState: D3DRS_AMBIENT Failed");
  554. return false;
  555. }
  556. else
  557. {
  558. LogInfo("<li>SetRenderState: D3DRS_AMBIENT OK");
  559. }
  560. return true;
  561. }
  562. LPDIRECT3DDEVICE8 CGame::GetDevice()
  563. {
  564. return m_pD3DDevice;
  565. }
  566. void CGame::GameLoop()
  567. {
  568.     //Enter the game loop
  569.     MSG msg; 
  570.     BOOL fMessage;
  571.     PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
  572. //Game started, so record time
  573. m_dwStartTime = timeGetTime();
  574.     while((msg.message != WM_QUIT) && (!m_fQuit))
  575.     {
  576.         fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
  577.         if(fMessage)
  578.         {
  579.             //Process message
  580.             TranslateMessage(&msg);
  581.             DispatchMessage(&msg);
  582.         }
  583.         else
  584.         {
  585.             //No message to process, so render the current scene
  586.             Render();
  587.         }
  588.     }
  589. //Game finished, so record time
  590. m_dwEndTime = timeGetTime();
  591. }
  592. void CGame::Render()
  593. {
  594. if(m_pD3DDevice == NULL)
  595.     {
  596.         return;
  597.     }
  598. //Process keyboard and mouse user input
  599. ProcessKeyboard();
  600. ProcessMouse();
  601. if(!m_fQuit)
  602. {
  603. //Clear the back buffer and depth buffer
  604. m_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
  605.     
  606. //Begin the scene
  607. m_pD3DDevice->BeginScene();
  608.     
  609. //Setup the camera ready for 3D elements
  610. Setup3DCamera();
  611. //Now that the 3D camera is setup, render the 3D objects
  612. Render3D();
  613. //Setup the camera ready for 2D elements
  614. Setup2DCamera();
  615. //Now that the 2D camera is setup, render the 2D objects
  616. Render2D();
  617. //Now render the text
  618. RenderText();
  619. //End the scene
  620. m_pD3DDevice->EndScene();
  621.     
  622. //Filp the back and front buffers so that whatever has been rendered on the back buffer
  623. //will now be visible on screen (front buffer).
  624. m_pD3DDevice->Present(NULL, NULL, NULL, NULL);
  625. //Count Frames
  626. m_dwFrames++;
  627. }
  628. }
  629. void CGame::Setup2DCamera()
  630. {
  631. D3DXMATRIX matOrtho;
  632. D3DXMATRIX matIdentity;
  633. //Setup the orthogonal projection matrix and the default world/view matrix
  634. D3DXMatrixOrthoLH(&matOrtho, (float)m_nScreenWidth, (float)m_nScreenHeight, 0.0f, 1.0f);
  635. D3DXMatrixIdentity(&matIdentity);
  636. m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matOrtho);
  637. m_pD3DDevice->SetTransform(D3DTS_WORLD, &matIdentity);
  638. m_pD3DDevice->SetTransform(D3DTS_VIEW, &matIdentity);
  639. //Make sure that the z-buffer and lighting are disabled
  640. m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
  641. m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
  642. }
  643. void CGame::Setup3DCamera()
  644. {
  645. //Here we will setup the camera.
  646. //The camera has three settings: "Camera Position", "Look at Position" and "Up Direction"
  647. //We have set the following:
  648. //Camera Position: (0, 15, -50)
  649. //Look at Position: (0, 0, 0)
  650. //Up direction: Y-Axis.
  651.     D3DXMATRIX matView;
  652.     D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 15.0f, -50.0f), //Camera Position
  653.                                  &D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
  654.                                  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
  655.     m_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
  656. //Here we specify the field of view, aspect ration and near and far clipping planes.
  657.     D3DXMATRIX matProj;
  658.     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.25f, 1.0f, 2000.0f);
  659.     m_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
  660. //Make sure that the z-buffer and lighting are enabled
  661. m_pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
  662. m_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
  663. }
  664. void CGame::Render2D()
  665. {
  666. //Render our 2D objects
  667. m_pPanel1->MoveTo(136, 86);
  668. m_dwTotalPolygons += m_pPanel1->Render();
  669. m_pPanel2->MoveTo(536, 86);
  670. m_dwTotalPolygons += m_pPanel2->Render();
  671. m_pPanel3->MoveTo(136, 386);
  672. m_dwTotalPolygons += m_pPanel3->Render();
  673. m_pPanel4->MoveTo(536, 386);
  674. m_dwTotalPolygons += m_pPanel4->Render();
  675. //Render mouse panel last so that it is on top
  676. m_pPanelMouse->MoveTo(m_nMouseX, m_nMouseY);
  677. m_dwTotalPolygons += m_pPanelMouse->Render();
  678. //Play sounds
  679. if(m_nMouseLeft == 1)
  680. {
  681. //Left mouse button is down, which sound do we play?
  682. if(m_pPanel1->IsPointInsidePanel(m_nMouseX, m_nMouseY))
  683. {
  684. m_pSound1->Play();
  685. }
  686. else if(m_pPanel2->IsPointInsidePanel(m_nMouseX, m_nMouseY))
  687. {
  688. m_pSound2->Play();
  689. }
  690. else if(m_pPanel3->IsPointInsidePanel(m_nMouseX, m_nMouseY))
  691. {
  692. m_pSound3->Play();
  693. }
  694. else if(m_pPanel4->IsPointInsidePanel(m_nMouseX, m_nMouseY))
  695. {
  696. m_pSound4->Play();
  697. }
  698. else
  699. {
  700. //Play "Error" sound
  701. m_pSoundFailed->Play();
  702. }
  703. }
  704. //Start background music on first frame
  705. if(m_dwFrames == 1)
  706. {
  707. m_pSoundBG->Play();
  708. }
  709. else if(m_dwFrames > 1)
  710. {
  711. //Make the background music loop
  712. if(!m_pSoundBG->IsPlaying())
  713. {
  714. m_pSoundBG->Play();
  715. }
  716. }
  717. }
  718. void CGame::Render3D()
  719. {
  720. //Render our 3D objects
  721. }
  722. void CGame::RenderText()
  723. {
  724. //Draw some text at the top of the screen showing stats
  725. char buffer[255];
  726. DWORD dwDuration = (timeGetTime() - m_dwStartTime) / 1000;
  727. if(dwDuration > 0)
  728. {
  729. sprintf(buffer, "Duration: %d seconds. Frames: %d. FPS: %d. Left: %d. Right: %d. X = %d. Y = %d.", dwDuration, m_dwFrames, (m_dwFrames / dwDuration), m_nMouseLeft, m_nMouseRight, m_nMouseX, m_nMouseY);
  730. }
  731. else
  732. {
  733. sprintf(buffer, "Calculating...");
  734. }
  735. m_pFont->DrawText(buffer, 0, 0, D3DCOLOR_XRGB(255, 255, 255));
  736. }
  737. void CGame::ProcessKeyboard()
  738. {
  739.     char KeyboardState[256]; 
  740.      
  741.     if(FAILED(m_pKeyboard->GetDeviceState(sizeof(KeyboardState),(LPVOID)&KeyboardState)))
  742.     { 
  743. return; 
  744.     } 
  745.  
  746. if(KEYDOWN(KeyboardState, DIK_ESCAPE))
  747. {
  748.         //Escape key pressed. Quit game.
  749. m_fQuit = true;
  750. }
  751. }
  752. void CGame::ProcessMouse()
  753. {
  754. DIMOUSESTATE MouseState;
  755. if(FAILED(m_pMouse->GetDeviceState(sizeof(MouseState),(LPVOID)&MouseState)))
  756.     { 
  757. return; 
  758.     } 
  759. //Is the left mouse button down?
  760. if(MOUSEBUTTONDOWN(MouseState.rgbButtons[MOUSEBUTTON_LEFT]))
  761. {
  762. m_nMouseLeft = 1;
  763. }
  764. else
  765. {
  766. m_nMouseLeft = 0;
  767. }
  768. //Is the right mouse button down?
  769. if(MOUSEBUTTONDOWN(MouseState.rgbButtons[MOUSEBUTTON_RIGHT]))
  770. {
  771. m_nMouseRight = 1;
  772. }
  773. else
  774. {
  775. m_nMouseRight = 0;
  776. }
  777.     
  778. m_nMouseX += MouseState.lX;
  779. m_nMouseY += MouseState.lY;
  780. }