Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

636 lines
20 KiB

  1. //-----------------------------------------------------------------------------
  2. // File: DXUtil.cpp
  3. //
  4. // Desc: Shortcut macros and functions for using DX objects
  5. //
  6. //@@BEGIN_MSINTERNAL
  7. //
  8. // Hist: 11.16.98 - mwetzel - New for DirectX 7
  9. // 12.10.98 - mwetzel - Changes to InitLight and axed InitViewport
  10. // 04.12.99 - mwetzelf - Changed some helper funcs
  11. // 07.06.99 - mwetzel - Mods for UNICODE support
  12. // 03.20.00 - mwetzel - Added timer support
  13. //
  14. //@@END_MSINTERNAL
  15. //
  16. // Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved
  17. //-----------------------------------------------------------------------------
  18. #define STRICT
  19. #include <windows.h>
  20. #include <mmsystem.h>
  21. #include <tchar.h>
  22. #include <stdio.h>
  23. #include <stdarg.h>
  24. #include "DXUtil.h"
  25. //-----------------------------------------------------------------------------
  26. // Name: DXUtil_GetDXSDKMediaPath()
  27. // Desc: Returns the DirectX SDK media path
  28. //-----------------------------------------------------------------------------
  29. const TCHAR* DXUtil_GetDXSDKMediaPath()
  30. {
  31. static TCHAR strNull[2] = _T("");
  32. static TCHAR strPath[MAX_PATH];
  33. DWORD dwType;
  34. DWORD dwSize = MAX_PATH;
  35. HKEY hKey;
  36. // Open the appropriate registry key
  37. LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  38. _T("Software\\Microsoft\\DirectX"),
  39. 0, KEY_READ, &hKey );
  40. if( ERROR_SUCCESS != lResult )
  41. return strNull;
  42. lResult = RegQueryValueEx( hKey, _T("DX8SDK Samples Path"), NULL,
  43. &dwType, (BYTE*)strPath, &dwSize );
  44. RegCloseKey( hKey );
  45. if( ERROR_SUCCESS != lResult )
  46. return strNull;
  47. _tcscat( strPath, _T("\\Media\\") );
  48. return strPath;
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Name: DXUtil_FindMediaFile()
  52. // Desc: Returns a valid path to a DXSDK media file
  53. //-----------------------------------------------------------------------------
  54. HRESULT DXUtil_FindMediaFile( TCHAR* strPath, TCHAR* strFilename )
  55. {
  56. HANDLE file;
  57. if( NULL==strFilename || NULL==strPath )
  58. return E_INVALIDARG;
  59. // Check if the file exists in the current directory
  60. _tcscpy( strPath, strFilename );
  61. file = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL,
  62. OPEN_EXISTING, 0, NULL );
  63. if( INVALID_HANDLE_VALUE != file )
  64. {
  65. CloseHandle( file );
  66. return S_OK;
  67. }
  68. // Check if the file exists in the current directory
  69. _stprintf( strPath, _T("%s%s"), DXUtil_GetDXSDKMediaPath(), strFilename );
  70. file = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL,
  71. OPEN_EXISTING, 0, NULL );
  72. if( INVALID_HANDLE_VALUE != file )
  73. {
  74. CloseHandle( file );
  75. return S_OK;
  76. }
  77. // On failure, just return the file as the path
  78. _tcscpy( strPath, strFilename );
  79. return E_FAIL;
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Name: DXUtil_ReadStringRegKey()
  83. // Desc: Helper function to read a registry key string
  84. //-----------------------------------------------------------------------------
  85. HRESULT DXUtil_ReadStringRegKey( HKEY hKey, TCHAR* strRegName, TCHAR* strValue,
  86. DWORD dwLength, TCHAR* strDefault )
  87. {
  88. DWORD dwType;
  89. if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
  90. (BYTE*)strValue, &dwLength ) )
  91. {
  92. _tcscpy( strValue, strDefault );
  93. }
  94. return S_OK;
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Name: DXUtil_WriteStringRegKey()
  98. // Desc: Helper function to write a registry key string
  99. //-----------------------------------------------------------------------------
  100. HRESULT DXUtil_WriteStringRegKey( HKEY hKey, TCHAR* strRegName,
  101. TCHAR* strValue )
  102. {
  103. if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_SZ,
  104. (BYTE*)strValue,
  105. (_tcslen(strValue)+1)*sizeof(TCHAR) ) )
  106. return E_FAIL;
  107. return S_OK;
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Name: DXUtil_ReadIntRegKey()
  111. // Desc: Helper function to read a registry key int
  112. //-----------------------------------------------------------------------------
  113. HRESULT DXUtil_ReadIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD* pdwValue,
  114. DWORD dwDefault )
  115. {
  116. DWORD dwType;
  117. DWORD dwLength = sizeof(DWORD);
  118. if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
  119. (BYTE*)pdwValue, &dwLength ) )
  120. {
  121. *pdwValue = dwDefault;
  122. }
  123. return S_OK;
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Name: DXUtil_WriteIntRegKey()
  127. // Desc: Helper function to write a registry key int
  128. //-----------------------------------------------------------------------------
  129. HRESULT DXUtil_WriteIntRegKey( HKEY hKey, TCHAR* strRegName, DWORD dwValue )
  130. {
  131. if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD,
  132. (BYTE*)&dwValue, sizeof(DWORD) ) )
  133. return E_FAIL;
  134. return S_OK;
  135. }
  136. //-----------------------------------------------------------------------------
  137. // Name: DXUtil_ReadBoolRegKey()
  138. // Desc: Helper function to read a registry key BOOL
  139. //-----------------------------------------------------------------------------
  140. HRESULT DXUtil_ReadBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL* pbValue,
  141. BOOL bDefault )
  142. {
  143. DWORD dwType;
  144. DWORD dwLength = sizeof(BOOL);
  145. if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
  146. (BYTE*)pbValue, &dwLength ) )
  147. {
  148. *pbValue = bDefault;
  149. }
  150. return S_OK;
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Name: DXUtil_WriteBoolRegKey()
  154. // Desc: Helper function to write a registry key BOOL
  155. //-----------------------------------------------------------------------------
  156. HRESULT DXUtil_WriteBoolRegKey( HKEY hKey, TCHAR* strRegName, BOOL bValue )
  157. {
  158. if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD,
  159. (BYTE*)&bValue, sizeof(BOOL) ) )
  160. return E_FAIL;
  161. return S_OK;
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Name: DXUtil_ReadGuidRegKey()
  165. // Desc: Helper function to read a registry key guid
  166. //-----------------------------------------------------------------------------
  167. HRESULT DXUtil_ReadGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID* pGuidValue,
  168. GUID& guidDefault )
  169. {
  170. DWORD dwType;
  171. DWORD dwLength = sizeof(GUID);
  172. if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType,
  173. (LPBYTE) pGuidValue, &dwLength ) )
  174. {
  175. *pGuidValue = guidDefault;
  176. }
  177. return S_OK;
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Name: DXUtil_WriteGuidRegKey()
  181. // Desc: Helper function to write a registry key guid
  182. //-----------------------------------------------------------------------------
  183. HRESULT DXUtil_WriteGuidRegKey( HKEY hKey, TCHAR* strRegName, GUID guidValue )
  184. {
  185. if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_BINARY,
  186. (BYTE*)&guidValue, sizeof(GUID) ) )
  187. return E_FAIL;
  188. return S_OK;
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Name: DXUtil_Timer()
  192. // Desc: Performs timer opertations. Use the following commands:
  193. // TIMER_RESET - to reset the timer
  194. // TIMER_START - to start the timer
  195. // TIMER_STOP - to stop (or pause) the timer
  196. // TIMER_ADVANCE - to advance the timer by 0.1 seconds
  197. // TIMER_GETABSOLUTETIME - to get the absolute system time
  198. // TIMER_GETAPPTIME - to get the current time
  199. // TIMER_GETELAPSEDTIME - to get the time that elapsed between
  200. // TIMER_GETELAPSEDTIME calls
  201. //-----------------------------------------------------------------------------
  202. FLOAT __stdcall DXUtil_Timer( TIMER_COMMAND command )
  203. {
  204. static BOOL m_bTimerInitialized = FALSE;
  205. static BOOL m_bUsingQPF = FALSE;
  206. static BOOL m_bTimerStopped = TRUE;
  207. static LONGLONG m_llQPFTicksPerSec = 0;
  208. // Initialize the timer
  209. if( FALSE == m_bTimerInitialized )
  210. {
  211. m_bTimerInitialized = TRUE;
  212. // Use QueryPerformanceFrequency() to get frequency of timer. If QPF is
  213. // not supported, we will timeGetTime() which returns milliseconds.
  214. LARGE_INTEGER qwTicksPerSec;
  215. m_bUsingQPF = QueryPerformanceFrequency( &qwTicksPerSec );
  216. if( m_bUsingQPF )
  217. m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
  218. }
  219. if( m_bUsingQPF )
  220. {
  221. static LONGLONG m_llStopTime = 0;
  222. static LONGLONG m_llLastElapsedTime = 0;
  223. static LONGLONG m_llBaseTime = 0;
  224. double fTime;
  225. double fElapsedTime;
  226. LARGE_INTEGER qwTime;
  227. // Get either the current time or the stop time, depending
  228. // on whether we're stopped and what command was sent
  229. if( m_llStopTime != 0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  230. qwTime.QuadPart = m_llStopTime;
  231. else
  232. QueryPerformanceCounter( &qwTime );
  233. // Return the elapsed time
  234. if( command == TIMER_GETELAPSEDTIME )
  235. {
  236. fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
  237. m_llLastElapsedTime = qwTime.QuadPart;
  238. return (FLOAT) fElapsedTime;
  239. }
  240. // Return the current time
  241. if( command == TIMER_GETAPPTIME )
  242. {
  243. double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
  244. return (FLOAT) fAppTime;
  245. }
  246. // Reset the timer
  247. if( command == TIMER_RESET )
  248. {
  249. m_llBaseTime = qwTime.QuadPart;
  250. m_llLastElapsedTime = qwTime.QuadPart;
  251. m_llStopTime = 0;
  252. m_bTimerStopped = FALSE;
  253. return 0.0f;
  254. }
  255. // Start the timer
  256. if( command == TIMER_START )
  257. {
  258. if( m_bTimerStopped )
  259. m_llBaseTime += qwTime.QuadPart - m_llStopTime;
  260. m_llStopTime = 0;
  261. m_llLastElapsedTime = qwTime.QuadPart;
  262. m_bTimerStopped = FALSE;
  263. return 0.0f;
  264. }
  265. // Stop the timer
  266. if( command == TIMER_STOP )
  267. {
  268. m_llStopTime = qwTime.QuadPart;
  269. m_llLastElapsedTime = qwTime.QuadPart;
  270. m_bTimerStopped = TRUE;
  271. return 0.0f;
  272. }
  273. // Advance the timer by 1/10th second
  274. if( command == TIMER_ADVANCE )
  275. {
  276. m_llStopTime += m_llQPFTicksPerSec/10;
  277. return 0.0f;
  278. }
  279. if( command == TIMER_GETABSOLUTETIME )
  280. {
  281. fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
  282. return (FLOAT) fTime;
  283. }
  284. return -1.0f; // Invalid command specified
  285. }
  286. else
  287. {
  288. // Get the time using timeGetTime()
  289. static double m_fLastElapsedTime = 0.0;
  290. static double m_fBaseTime = 0.0;
  291. static double m_fStopTime = 0.0;
  292. double fTime;
  293. double fElapsedTime;
  294. // Get either the current time or the stop time, depending
  295. // on whether we're stopped and what command was sent
  296. if( m_fStopTime != 0.0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  297. fTime = m_fStopTime;
  298. else
  299. fTime = timeGetTime() * 0.001;
  300. // Return the elapsed time
  301. if( command == TIMER_GETELAPSEDTIME )
  302. {
  303. fElapsedTime = (double) (fTime - m_fLastElapsedTime);
  304. m_fLastElapsedTime = fTime;
  305. return (FLOAT) fElapsedTime;
  306. }
  307. // Return the current time
  308. if( command == TIMER_GETAPPTIME )
  309. {
  310. return (FLOAT) (fTime - m_fBaseTime);
  311. }
  312. // Reset the timer
  313. if( command == TIMER_RESET )
  314. {
  315. m_fBaseTime = fTime;
  316. m_fLastElapsedTime = fTime;
  317. m_fStopTime = 0;
  318. m_bTimerStopped = FALSE;
  319. return 0.0f;
  320. }
  321. // Start the timer
  322. if( command == TIMER_START )
  323. {
  324. if( m_bTimerStopped )
  325. m_fBaseTime += fTime - m_fStopTime;
  326. m_fStopTime = 0.0f;
  327. m_fLastElapsedTime = fTime;
  328. m_bTimerStopped = FALSE;
  329. return 0.0f;
  330. }
  331. // Stop the timer
  332. if( command == TIMER_STOP )
  333. {
  334. m_fStopTime = fTime;
  335. m_bTimerStopped = TRUE;
  336. return 0.0f;
  337. }
  338. // Advance the timer by 1/10th second
  339. if( command == TIMER_ADVANCE )
  340. {
  341. m_fStopTime += 0.1f;
  342. return 0.0f;
  343. }
  344. if( command == TIMER_GETABSOLUTETIME )
  345. {
  346. return (FLOAT) fTime;
  347. }
  348. return -1.0f; // Invalid command specified
  349. }
  350. }
  351. //-----------------------------------------------------------------------------
  352. // Name: DXUtil_ConvertAnsiStringToWide()
  353. // Desc: This is a UNICODE conversion utility to convert a CHAR string into a
  354. // WCHAR string. cchDestChar defaults -1 which means it
  355. // assumes strDest is large enough to store strSource
  356. //-----------------------------------------------------------------------------
  357. VOID DXUtil_ConvertAnsiStringToWide( WCHAR* wstrDestination, const CHAR* strSource,
  358. int cchDestChar )
  359. {
  360. if( wstrDestination==NULL || strSource==NULL )
  361. return;
  362. if( cchDestChar == -1 )
  363. cchDestChar = strlen(strSource)+1;
  364. MultiByteToWideChar( CP_ACP, 0, strSource, -1,
  365. wstrDestination, cchDestChar-1 );
  366. wstrDestination[cchDestChar-1] = 0;
  367. }
  368. //-----------------------------------------------------------------------------
  369. // Name: DXUtil_ConvertWideStringToAnsi()
  370. // Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
  371. // CHAR string. cchDestChar defaults -1 which means it
  372. // assumes strDest is large enough to store strSource
  373. //-----------------------------------------------------------------------------
  374. VOID DXUtil_ConvertWideStringToAnsi( CHAR* strDestination, const WCHAR* wstrSource,
  375. int cchDestChar )
  376. {
  377. if( strDestination==NULL || wstrSource==NULL )
  378. return;
  379. if( cchDestChar == -1 )
  380. cchDestChar = wcslen(wstrSource)+1;
  381. WideCharToMultiByte( CP_ACP, 0, wstrSource, -1, strDestination,
  382. cchDestChar-1, NULL, NULL );
  383. strDestination[cchDestChar-1] = 0;
  384. }
  385. //-----------------------------------------------------------------------------
  386. // Name: DXUtil_ConvertGenericStringToAnsi()
  387. // Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
  388. // CHAR string. cchDestChar defaults -1 which means it
  389. // assumes strDest is large enough to store strSource
  390. //-----------------------------------------------------------------------------
  391. VOID DXUtil_ConvertGenericStringToAnsi( CHAR* strDestination, const TCHAR* tstrSource,
  392. int cchDestChar )
  393. {
  394. if( strDestination==NULL || tstrSource==NULL )
  395. return;
  396. #ifdef _UNICODE
  397. DXUtil_ConvertWideStringToAnsi( strDestination, tstrSource, cchDestChar );
  398. #else
  399. if( cchDestChar == -1 )
  400. strcpy( strDestination, tstrSource );
  401. else
  402. strncpy( strDestination, tstrSource, cchDestChar );
  403. #endif
  404. }
  405. //-----------------------------------------------------------------------------
  406. // Name: DXUtil_ConvertGenericStringToWide()
  407. // Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
  408. // WCHAR string. cchDestChar defaults -1 which means it
  409. // assumes strDest is large enough to store strSource
  410. //-----------------------------------------------------------------------------
  411. VOID DXUtil_ConvertGenericStringToWide( WCHAR* wstrDestination, const TCHAR* tstrSource,
  412. int cchDestChar )
  413. {
  414. if( wstrDestination==NULL || tstrSource==NULL )
  415. return;
  416. #ifdef _UNICODE
  417. if( cchDestChar == -1 )
  418. wcscpy( wstrDestination, tstrSource );
  419. else
  420. wcsncpy( wstrDestination, tstrSource, cchDestChar );
  421. #else
  422. DXUtil_ConvertAnsiStringToWide( wstrDestination, tstrSource, cchDestChar );
  423. #endif
  424. }
  425. //-----------------------------------------------------------------------------
  426. // Name: DXUtil_ConvertAnsiStringToGeneric()
  427. // Desc: This is a UNICODE conversion utility to convert a CHAR string into a
  428. // TCHAR string. cchDestChar defaults -1 which means it
  429. // assumes strDest is large enough to store strSource
  430. //-----------------------------------------------------------------------------
  431. VOID DXUtil_ConvertAnsiStringToGeneric( TCHAR* tstrDestination, const CHAR* strSource,
  432. int cchDestChar )
  433. {
  434. if( tstrDestination==NULL || strSource==NULL )
  435. return;
  436. #ifdef _UNICODE
  437. DXUtil_ConvertAnsiStringToWide( tstrDestination, strSource, cchDestChar );
  438. #else
  439. if( cchDestChar == -1 )
  440. strcpy( tstrDestination, strSource );
  441. else
  442. strncpy( tstrDestination, strSource, cchDestChar );
  443. #endif
  444. }
  445. //-----------------------------------------------------------------------------
  446. // Name: DXUtil_ConvertAnsiStringToGeneric()
  447. // Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
  448. // TCHAR string. cchDestChar defaults -1 which means it
  449. // assumes strDest is large enough to store strSource
  450. //-----------------------------------------------------------------------------
  451. VOID DXUtil_ConvertWideStringToGeneric( TCHAR* tstrDestination, const WCHAR* wstrSource,
  452. int cchDestChar )
  453. {
  454. if( tstrDestination==NULL || wstrSource==NULL )
  455. return;
  456. #ifdef _UNICODE
  457. if( cchDestChar == -1 )
  458. wcscpy( tstrDestination, wstrSource );
  459. else
  460. wcsncpy( tstrDestination, wstrSource, cchDestChar );
  461. #else
  462. DXUtil_ConvertWideStringToAnsi( tstrDestination, wstrSource, cchDestChar );
  463. #endif
  464. }
  465. //-----------------------------------------------------------------------------
  466. // Name: _DbgOut()
  467. // Desc: Outputs a message to the debug stream
  468. //-----------------------------------------------------------------------------
  469. HRESULT _DbgOut( TCHAR* strFile, DWORD dwLine, HRESULT hr, TCHAR* strMsg )
  470. {
  471. TCHAR buffer[256];
  472. wsprintf( buffer, _T("%s(%ld): "), strFile, dwLine );
  473. OutputDebugString( buffer );
  474. OutputDebugString( strMsg );
  475. if( hr != S_OK )
  476. {
  477. wsprintf( buffer, _T("(hr=%08lx)\n"), hr );
  478. OutputDebugString( buffer );
  479. }
  480. OutputDebugString( _T("\n") );
  481. return hr;
  482. }
  483. //-----------------------------------------------------------------------------
  484. // Name: DXUtil_Trace()
  485. // Desc: Outputs to the debug stream a formatted string with a variable-
  486. // argument list.
  487. //-----------------------------------------------------------------------------
  488. VOID DXUtil_Trace( TCHAR* strMsg, ... )
  489. {
  490. #if defined(DEBUG) | defined(_DEBUG)
  491. TCHAR strBuffer[512];
  492. va_list args;
  493. va_start(args, strMsg);
  494. _vsntprintf( strBuffer, 512, strMsg, args );
  495. va_end(args);
  496. OutputDebugString( strBuffer );
  497. #endif
  498. }