dxutil.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:44k
源码类别:

游戏

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. // File: DXUtil.cpp
  3. //
  4. // Desc: Shortcut macros and functions for using DX objects
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved
  7. //-----------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #ifdef UNICODE
  10.     typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
  11. #else
  12.     typedef HINSTANCE (WINAPI* LPShellExecute)(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, INT nShowCmd);
  13. #endif
  14. #ifndef UNDER_CE
  15. //-----------------------------------------------------------------------------
  16. // Name: DXUtil_GetDXSDKMediaPathCch()
  17. // Desc: Returns the DirectX SDK media path
  18. //       cchDest is the size in TCHARs of strDest.  Be careful not to 
  19. //       pass in sizeof(strDest) on UNICODE builds.
  20. //-----------------------------------------------------------------------------
  21. HRESULT DXUtil_GetDXSDKMediaPathCch( TCHAR* strDest, int cchDest )
  22. {
  23.     if( strDest == NULL || cchDest < 1 )
  24.         return E_INVALIDARG;
  25.     lstrcpy( strDest, TEXT("") );
  26.     // Open the appropriate registry key
  27.     HKEY  hKey;
  28.     LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  29.                                 _T("Software\Microsoft\DirectX SDK"),
  30.                                 0, KEY_READ, &hKey );
  31.     if( ERROR_SUCCESS != lResult )
  32.         return E_FAIL;
  33.     DWORD dwType;
  34.     DWORD dwSize = cchDest * sizeof(TCHAR);
  35.     lResult = RegQueryValueEx( hKey, _T("DX9J3SDK Samples Path"), NULL,
  36.                               &dwType, (BYTE*)strDest, &dwSize );
  37.     strDest[cchDest-1] = 0; // RegQueryValueEx doesn't NULL term if buffer too small
  38.     RegCloseKey( hKey );
  39.     if( ERROR_SUCCESS != lResult )
  40.         return E_FAIL;
  41.     const TCHAR* strMedia = _T("\Media\");
  42.     if( lstrlen(strDest) + lstrlen(strMedia) < cchDest )
  43.         _tcscat( strDest, strMedia );
  44.     else
  45.         return E_INVALIDARG;
  46.     return S_OK;
  47. }
  48. #endif // !UNDER_CE
  49. #ifndef UNDER_CE
  50. //-----------------------------------------------------------------------------
  51. // Name: DXUtil_FindMediaFileCch()
  52. // Desc: Trys to find the location of a SDK media file
  53. //       cchDest is the size in TCHARs of strDestPath.  Be careful not to 
  54. //       pass in sizeof(strDest) on UNICODE builds.
  55. //-----------------------------------------------------------------------------
  56. HRESULT DXUtil_FindMediaFileCch( TCHAR* strDestPath, int cchDest, LPCTSTR strFilename )
  57. {
  58.     HRESULT hr;
  59.     TCHAR* strLeafNameTmp = NULL;
  60.     TCHAR strLeafName[MAX_PATH];
  61.     TCHAR strExePath[MAX_PATH];
  62.     TCHAR strExeName[MAX_PATH];
  63.     TCHAR strMediaDir[MAX_PATH];
  64.     TCHAR strSearchPath[MAX_PATH];
  65.     TCHAR* strLastSlash = NULL;
  66.     int cchPath;
  67.     BOOL bFound = FALSE;
  68.     if( NULL==strFilename || NULL==strDestPath || cchDest < 10 )
  69.         return E_INVALIDARG;
  70.     lstrcpy( strDestPath, TEXT("") );
  71.     lstrcpy( strLeafName, TEXT("") );
  72.     // Append current working directory to strFilename and extract the leaf filename 
  73.     cchPath = GetFullPathName(strFilename, MAX_PATH, strSearchPath, &strLeafNameTmp);
  74.     if ((cchPath == 0) || (MAX_PATH <= cchPath))
  75.         return E_FAIL;
  76.     if( strLeafNameTmp )
  77.         lstrcpyn( strLeafName, strLeafNameTmp, MAX_PATH );
  78.     // Search in . 
  79.     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  80.         bFound = true;
  81.     if( !bFound )
  82.     {
  83.         // Search in .. 
  84.         _sntprintf( strSearchPath, MAX_PATH, TEXT("..\%s"), strLeafName );
  85.         strSearchPath[MAX_PATH-1] = 0;
  86.         if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  87.             bFound = true;
  88.     }
  89.     if( !bFound )
  90.     {
  91.         // Search in ....  
  92.         _sntprintf( strSearchPath, MAX_PATH, TEXT("..\..\%s"), strLeafName );
  93.         strSearchPath[MAX_PATH-1] = 0;
  94.         if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  95.             bFound = true;
  96.     }
  97.     
  98.     if( !bFound )
  99.     {
  100.         // Get the exe name, and exe path
  101.         GetModuleFileName( NULL, strExePath, MAX_PATH );
  102.         strExePath[MAX_PATH-1]=0;
  103.         strLastSlash = _tcsrchr( strExePath, TEXT('\') );
  104.         if( strLastSlash )
  105.         {
  106.             lstrcpyn( strExeName, &strLastSlash[1], MAX_PATH );
  107.             // Chop the exe name from the exe path
  108.             *strLastSlash = 0;
  109.             // Chop the .exe from the exe name
  110.             strLastSlash = _tcsrchr( strExeName, TEXT('.') );
  111.             if( strLastSlash )
  112.                 *strLastSlash = 0;
  113.         }
  114.         // Search in the executable directory
  115.         _sntprintf( strSearchPath, MAX_PATH, _T("%s\%s"), strExePath, strLeafName );
  116.         strSearchPath[MAX_PATH-1] = 0;
  117.         if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  118.             bFound = TRUE;
  119.         if( !bFound )
  120.         {
  121.             // Search in "%EXE_DIR%.."
  122.             _sntprintf( strSearchPath, MAX_PATH, _T("%s\..\%s"), strExePath, strLeafName );
  123.             strSearchPath[MAX_PATH-1] = 0;
  124.             if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  125.                 bFound = TRUE;
  126.         }
  127.         if( !bFound )
  128.         {
  129.             // Search in "%EXE_DIR%...."
  130.             _sntprintf( strSearchPath, MAX_PATH, _T("%s\..\..\%s"), strExePath, strLeafName );
  131.             strSearchPath[MAX_PATH-1] = 0;
  132.             if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  133.                 bFound = TRUE;
  134.         }
  135.         if( !bFound )
  136.         {
  137.             // Search in "%EXE_DIR%..%EXE_NAME%".  This matches the DirectX SDK layout
  138.             _sntprintf( strSearchPath, MAX_PATH, TEXT("%s\..\%s\%s"), strExePath, strExeName, strLeafName );
  139.             strSearchPath[MAX_PATH-1] = 0;
  140.             if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  141.                 bFound = TRUE;
  142.         }
  143.     }
  144.     
  145.     if( !bFound )
  146.     {
  147.         // Get the media dir 
  148.         if( FAILED( hr = DXUtil_GetDXSDKMediaPathCch( strMediaDir, MAX_PATH ) ) )
  149.             return hr;
  150.         // Search in SDK's media dir 
  151.         _sntprintf( strSearchPath, MAX_PATH, TEXT("%s%s"), strMediaDir, strLeafName );
  152.         strSearchPath[MAX_PATH-1] = 0;
  153.         if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
  154.             bFound = TRUE;
  155.     }
  156.     if( bFound )
  157.     {
  158.         // Found the file, so copy the search path to the output buffer
  159.         // and return success
  160.         lstrcpyn( strDestPath, strSearchPath, cchDest );
  161.         return S_OK;
  162.     }
  163.     else
  164.     {
  165.         // On failure, return the file as the path but return an error code
  166.         lstrcpyn( strDestPath, strFilename, cchDest );
  167.         return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  168.     }
  169. }
  170. #endif // !UNDER_CE
  171. //-----------------------------------------------------------------------------
  172. // Name: DXUtil_ReadStringRegKeyCch()
  173. // Desc: Helper function to read a registry key string
  174. //       cchDest is the size in TCHARs of strDest.  Be careful not to 
  175. //       pass in sizeof(strDest) on UNICODE builds.
  176. //-----------------------------------------------------------------------------
  177. HRESULT DXUtil_ReadStringRegKeyCch( HKEY hKey, LPCTSTR strRegName, TCHAR* strDest, 
  178.                                     DWORD cchDest, LPCTSTR strDefault )
  179. {
  180.     DWORD dwType;
  181.     DWORD cbDest = cchDest * sizeof(TCHAR);
  182.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  183.                                           (BYTE*)strDest, &cbDest ) )
  184.     {
  185.         _tcsncpy( strDest, strDefault, cchDest );
  186.         strDest[cchDest-1] = 0;
  187.         return S_FALSE;
  188.     }
  189.     else
  190.     {     
  191.         if( dwType != REG_SZ )
  192.         {
  193.             _tcsncpy( strDest, strDefault, cchDest );
  194.             strDest[cchDest-1] = 0;
  195.             return S_FALSE;
  196.         }   
  197.     }
  198.     return S_OK;
  199. }
  200. //-----------------------------------------------------------------------------
  201. // Name: DXUtil_WriteStringRegKey()
  202. // Desc: Helper function to write a registry key string
  203. //-----------------------------------------------------------------------------
  204. HRESULT DXUtil_WriteStringRegKey( HKEY hKey, LPCTSTR strRegName,
  205.                                   LPCTSTR strValue )
  206. {
  207.     if( NULL == strValue )
  208.         return E_INVALIDARG;
  209.         
  210.     DWORD cbValue = ((DWORD)_tcslen(strValue)+1) * sizeof(TCHAR);
  211.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_SZ, 
  212.                                         (BYTE*)strValue, cbValue ) )
  213.         return E_FAIL;
  214.     return S_OK;
  215. }
  216. //-----------------------------------------------------------------------------
  217. // Name: DXUtil_ReadFloatRegKey()
  218. // Desc: Helper function to read a registry key string
  219. //-----------------------------------------------------------------------------
  220. HRESULT DXUtil_ReadFloatRegKey( HKEY hKey, LPCTSTR strRegName, FLOAT* pfDest, FLOAT fDefault )
  221. {
  222.     if( NULL == pfDest )
  223.         return E_INVALIDARG;
  224.     TCHAR sz[256];
  225.     float fResult;
  226.     TCHAR strDefault[256];
  227.     _sntprintf( strDefault, 256, TEXT("%f"), fDefault );
  228.     strDefault[255] = 0;
  229.    
  230.     if( SUCCEEDED( DXUtil_ReadStringRegKeyCch( hKey, strRegName, sz, 256, strDefault ) ) )
  231.     {
  232.         int nResult = _stscanf( sz, TEXT("%f"), &fResult );
  233.         if( nResult == 1 )
  234.         {
  235.             *pfDest = fResult;
  236.             return S_OK;           
  237.         }
  238.     }
  239.     *pfDest = fDefault;
  240.     return S_FALSE;
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Name: DXUtil_WriteFloatRegKey()
  244. // Desc: Helper function to write a registry key string
  245. //-----------------------------------------------------------------------------
  246. HRESULT DXUtil_WriteFloatRegKey( HKEY hKey, LPCTSTR strRegName, FLOAT fValue )
  247. {
  248.     TCHAR strValue[256];
  249.     _sntprintf( strValue, 256, TEXT("%f"), fValue );
  250.     strValue[255] = 0;
  251.     return DXUtil_WriteStringRegKey( hKey, strRegName, strValue );
  252. }
  253. //-----------------------------------------------------------------------------
  254. // Name: DXUtil_ReadIntRegKey()
  255. // Desc: Helper function to read a registry key int
  256. //-----------------------------------------------------------------------------
  257. HRESULT DXUtil_ReadIntRegKey( HKEY hKey, LPCTSTR strRegName, DWORD* pdwDest, 
  258.                               DWORD dwDefault )
  259. {
  260.     DWORD dwType;
  261.     DWORD dwLength = sizeof(DWORD);
  262.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  263.                                           (BYTE*)pdwDest, &dwLength ) )
  264.     {
  265.         *pdwDest = dwDefault;
  266.         return S_FALSE;
  267.     }
  268.     else
  269.     {
  270.         if( dwType != REG_DWORD )
  271.         {
  272.             *pdwDest = dwDefault;
  273.             return S_FALSE;
  274.         }
  275.     }
  276.     return S_OK;
  277. }
  278. //-----------------------------------------------------------------------------
  279. // Name: DXUtil_WriteIntRegKey()
  280. // Desc: Helper function to write a registry key int
  281. //-----------------------------------------------------------------------------
  282. HRESULT DXUtil_WriteIntRegKey( HKEY hKey, LPCTSTR strRegName, DWORD dwValue )
  283. {
  284.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD, 
  285.                                         (BYTE*)&dwValue, sizeof(DWORD) ) )
  286.         return E_FAIL;
  287.     return S_OK;
  288. }
  289. //-----------------------------------------------------------------------------
  290. // Name: DXUtil_ReadBoolRegKey()
  291. // Desc: Helper function to read a registry key BOOL
  292. //-----------------------------------------------------------------------------
  293. HRESULT DXUtil_ReadBoolRegKey( HKEY hKey, LPCTSTR strRegName, BOOL* pbDest, 
  294.                               BOOL bDefault )
  295. {
  296.     DWORD dwType;
  297.     DWORD dwLength = sizeof(BOOL);
  298.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  299.                                           (BYTE*)pbDest, &dwLength ) )
  300.     {
  301.         *pbDest = bDefault;
  302.         return S_FALSE;
  303.     }
  304.     else
  305.     {
  306.         if( dwType != REG_DWORD )
  307.         {
  308.             *pbDest = bDefault;
  309.             return S_FALSE;
  310.         }
  311.     }
  312.     return S_OK;
  313. }
  314. //-----------------------------------------------------------------------------
  315. // Name: DXUtil_WriteBoolRegKey()
  316. // Desc: Helper function to write a registry key BOOL
  317. //-----------------------------------------------------------------------------
  318. HRESULT DXUtil_WriteBoolRegKey( HKEY hKey, LPCTSTR strRegName, BOOL bValue )
  319. {
  320.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_DWORD, 
  321.                                         (BYTE*)&bValue, sizeof(BOOL) ) )
  322.         return E_FAIL;
  323.     return S_OK;
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Name: DXUtil_ReadGuidRegKey()
  327. // Desc: Helper function to read a registry key guid
  328. //-----------------------------------------------------------------------------
  329. HRESULT DXUtil_ReadGuidRegKey( HKEY hKey, LPCTSTR strRegName, GUID* pGuidDest, 
  330.                                GUID& guidDefault )
  331. {
  332.     DWORD dwType;
  333.     DWORD dwLength = sizeof(GUID);
  334.     if( ERROR_SUCCESS != RegQueryValueEx( hKey, strRegName, 0, &dwType, 
  335.                                           (LPBYTE) pGuidDest, &dwLength ) )
  336.     {
  337.         *pGuidDest = guidDefault;
  338.         return S_FALSE;
  339.     }
  340.     else
  341.     {
  342.         if( dwType != REG_BINARY )
  343.         {
  344.             *pGuidDest = guidDefault;
  345.             return S_FALSE;
  346.         }
  347.     }
  348.     return S_OK;
  349. }
  350. //-----------------------------------------------------------------------------
  351. // Name: DXUtil_WriteGuidRegKey()
  352. // Desc: Helper function to write a registry key guid
  353. //-----------------------------------------------------------------------------
  354. HRESULT DXUtil_WriteGuidRegKey( HKEY hKey, LPCTSTR strRegName, GUID guidValue )
  355. {
  356.     if( ERROR_SUCCESS != RegSetValueEx( hKey, strRegName, 0, REG_BINARY, 
  357.                                         (BYTE*)&guidValue, sizeof(GUID) ) )
  358.         return E_FAIL;
  359.     return S_OK;
  360. }
  361. //-----------------------------------------------------------------------------
  362. // Name: DXUtil_Timer()
  363. // Desc: Performs timer opertations. Use the following commands:
  364. //          TIMER_RESET           - to reset the timer
  365. //          TIMER_START           - to start the timer
  366. //          TIMER_STOP            - to stop (or pause) the timer
  367. //          TIMER_ADVANCE         - to advance the timer by 0.1 seconds
  368. //          TIMER_GETABSOLUTETIME - to get the absolute system time
  369. //          TIMER_GETAPPTIME      - to get the current time
  370. //          TIMER_GETELAPSEDTIME  - to get the time that elapsed between 
  371. //                                  TIMER_GETELAPSEDTIME calls
  372. //-----------------------------------------------------------------------------
  373. FLOAT __stdcall DXUtil_Timer( TIMER_COMMAND command )
  374. {
  375.     static BOOL     m_bTimerInitialized = FALSE;
  376.     static BOOL     m_bUsingQPF         = FALSE;
  377.     static BOOL     m_bTimerStopped     = TRUE;
  378.     static LONGLONG m_llQPFTicksPerSec  = 0;
  379.     // Initialize the timer
  380.     if( FALSE == m_bTimerInitialized )
  381.     {
  382.         m_bTimerInitialized = TRUE;
  383.         // Use QueryPerformanceFrequency() to get frequency of timer.  If QPF is
  384.         // not supported, we will timeGetTime() which returns milliseconds.
  385.         LARGE_INTEGER qwTicksPerSec;
  386.         m_bUsingQPF = QueryPerformanceFrequency( &qwTicksPerSec );
  387.         if( m_bUsingQPF )
  388.             m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
  389.     }
  390.     if( m_bUsingQPF )
  391.     {
  392.         static LONGLONG m_llStopTime        = 0;
  393.         static LONGLONG m_llLastElapsedTime = 0;
  394.         static LONGLONG m_llBaseTime        = 0;
  395.         double fTime;
  396.         double fElapsedTime;
  397.         LARGE_INTEGER qwTime;
  398.         
  399.         // Get either the current time or the stop time, depending
  400.         // on whether we're stopped and what command was sent
  401.         if( m_llStopTime != 0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  402.             qwTime.QuadPart = m_llStopTime;
  403.         else
  404.             QueryPerformanceCounter( &qwTime );
  405.         // Return the elapsed time
  406.         if( command == TIMER_GETELAPSEDTIME )
  407.         {
  408.             fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
  409.             m_llLastElapsedTime = qwTime.QuadPart;
  410.             return (FLOAT) fElapsedTime;
  411.         }
  412.     
  413.         // Return the current time
  414.         if( command == TIMER_GETAPPTIME )
  415.         {
  416.             double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
  417.             return (FLOAT) fAppTime;
  418.         }
  419.     
  420.         // Reset the timer
  421.         if( command == TIMER_RESET )
  422.         {
  423.             m_llBaseTime        = qwTime.QuadPart;
  424.             m_llLastElapsedTime = qwTime.QuadPart;
  425.             m_llStopTime        = 0;
  426.             m_bTimerStopped     = FALSE;
  427.             return 0.0f;
  428.         }
  429.     
  430.         // Start the timer
  431.         if( command == TIMER_START )
  432.         {
  433.             if( m_bTimerStopped )
  434.                 m_llBaseTime += qwTime.QuadPart - m_llStopTime;
  435.             m_llStopTime = 0;
  436.             m_llLastElapsedTime = qwTime.QuadPart;
  437.             m_bTimerStopped = FALSE;
  438.             return 0.0f;
  439.         }
  440.     
  441.         // Stop the timer
  442.         if( command == TIMER_STOP )
  443.         {
  444.             if( !m_bTimerStopped )
  445.             {
  446.                 m_llStopTime = qwTime.QuadPart;
  447.                 m_llLastElapsedTime = qwTime.QuadPart;
  448.                 m_bTimerStopped = TRUE;
  449.             }
  450.             return 0.0f;
  451.         }
  452.     
  453.         // Advance the timer by 1/10th second
  454.         if( command == TIMER_ADVANCE )
  455.         {
  456.             m_llStopTime += m_llQPFTicksPerSec/10;
  457.             return 0.0f;
  458.         }
  459.         if( command == TIMER_GETABSOLUTETIME )
  460.         {
  461.             fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
  462.             return (FLOAT) fTime;
  463.         }
  464.         return -1.0f; // Invalid command specified
  465.     }
  466.     else
  467.     {
  468.         // Get the time using timeGetTime()
  469.         static double m_fLastElapsedTime  = 0.0;
  470.         static double m_fBaseTime         = 0.0;
  471.         static double m_fStopTime         = 0.0;
  472.         double fTime;
  473.         double fElapsedTime;
  474.         
  475.         // Get either the current time or the stop time, depending
  476.         // on whether we're stopped and what command was sent
  477.         if( m_fStopTime != 0.0 && command != TIMER_START && command != TIMER_GETABSOLUTETIME)
  478.             fTime = m_fStopTime;
  479.         else
  480.             fTime = GETTIMESTAMP() * 0.001;
  481.     
  482.         // Return the elapsed time
  483.         if( command == TIMER_GETELAPSEDTIME )
  484.         {   
  485.             fElapsedTime = (double) (fTime - m_fLastElapsedTime);
  486.             m_fLastElapsedTime = fTime;
  487.             return (FLOAT) fElapsedTime;
  488.         }
  489.     
  490.         // Return the current time
  491.         if( command == TIMER_GETAPPTIME )
  492.         {
  493.             return (FLOAT) (fTime - m_fBaseTime);
  494.         }
  495.     
  496.         // Reset the timer
  497.         if( command == TIMER_RESET )
  498.         {
  499.             m_fBaseTime         = fTime;
  500.             m_fLastElapsedTime  = fTime;
  501.             m_fStopTime         = 0;
  502.             m_bTimerStopped     = FALSE;
  503.             return 0.0f;
  504.         }
  505.     
  506.         // Start the timer
  507.         if( command == TIMER_START )
  508.         {
  509.             if( m_bTimerStopped )
  510.                 m_fBaseTime += fTime - m_fStopTime;
  511.             m_fStopTime = 0.0f;
  512.             m_fLastElapsedTime  = fTime;
  513.             m_bTimerStopped = FALSE;
  514.             return 0.0f;
  515.         }
  516.     
  517.         // Stop the timer
  518.         if( command == TIMER_STOP )
  519.         {
  520.             if( !m_bTimerStopped )
  521.             {
  522.                 m_fStopTime = fTime;
  523.                 m_fLastElapsedTime  = fTime;
  524.                 m_bTimerStopped = TRUE;
  525.             }
  526.             return 0.0f;
  527.         }
  528.     
  529.         // Advance the timer by 1/10th second
  530.         if( command == TIMER_ADVANCE )
  531.         {
  532.             m_fStopTime += 0.1f;
  533.             return 0.0f;
  534.         }
  535.         if( command == TIMER_GETABSOLUTETIME )
  536.         {
  537.             return (FLOAT) fTime;
  538.         }
  539.         return -1.0f; // Invalid command specified
  540.     }
  541. }
  542. //-----------------------------------------------------------------------------
  543. // Name: DXUtil_ConvertAnsiStringToWideCch()
  544. // Desc: This is a UNICODE conversion utility to convert a CHAR string into a
  545. //       WCHAR string. 
  546. //       cchDestChar is the size in TCHARs of wstrDestination.  Be careful not to 
  547. //       pass in sizeof(strDest) 
  548. //-----------------------------------------------------------------------------
  549. HRESULT DXUtil_ConvertAnsiStringToWideCch( WCHAR* wstrDestination, const CHAR* strSource, 
  550.                                      int cchDestChar )
  551. {
  552.     if( wstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
  553.         return E_INVALIDARG;
  554.     int nResult = MultiByteToWideChar( CP_ACP, 0, strSource, -1, 
  555.                                        wstrDestination, cchDestChar );
  556.     wstrDestination[cchDestChar-1] = 0;
  557.     
  558.     if( nResult == 0 )
  559.         return E_FAIL;
  560.     return S_OK;
  561. }
  562. //-----------------------------------------------------------------------------
  563. // Name: DXUtil_ConvertWideStringToAnsi()
  564. // Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
  565. //       CHAR string. 
  566. //       cchDestChar is the size in TCHARs of strDestination
  567. //-----------------------------------------------------------------------------
  568. HRESULT DXUtil_ConvertWideStringToAnsiCch( CHAR* strDestination, const WCHAR* wstrSource, 
  569.                                      int cchDestChar )
  570. {
  571.     if( strDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
  572.         return E_INVALIDARG;
  573.     int nResult = WideCharToMultiByte( CP_ACP, 0, wstrSource, -1, strDestination, 
  574.                                        cchDestChar*sizeof(CHAR), NULL, NULL );
  575.     strDestination[cchDestChar-1] = 0;
  576.     
  577.     if( nResult == 0 )
  578.         return E_FAIL;
  579.     return S_OK;
  580. }
  581. //-----------------------------------------------------------------------------
  582. // Name: DXUtil_ConvertGenericStringToAnsi()
  583. // Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
  584. //       CHAR string. 
  585. //       cchDestChar is the size in TCHARs of strDestination
  586. //-----------------------------------------------------------------------------
  587. HRESULT DXUtil_ConvertGenericStringToAnsiCch( CHAR* strDestination, const TCHAR* tstrSource, 
  588.                                            int cchDestChar )
  589. {
  590.     if( strDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
  591.         return E_INVALIDARG;
  592. #ifdef _UNICODE
  593.     return DXUtil_ConvertWideStringToAnsiCch( strDestination, tstrSource, cchDestChar );
  594. #else
  595.     strncpy( strDestination, tstrSource, cchDestChar );
  596.     strDestination[cchDestChar-1] = '';
  597.     return S_OK;
  598. #endif   
  599. }
  600. //-----------------------------------------------------------------------------
  601. // Name: DXUtil_ConvertGenericStringToWide()
  602. // Desc: This is a UNICODE conversion utility to convert a TCHAR string into a
  603. //       WCHAR string. 
  604. //       cchDestChar is the size in TCHARs of wstrDestination.  Be careful not to 
  605. //       pass in sizeof(strDest) 
  606. //-----------------------------------------------------------------------------
  607. HRESULT DXUtil_ConvertGenericStringToWideCch( WCHAR* wstrDestination, const TCHAR* tstrSource, 
  608.                                            int cchDestChar )
  609. {
  610.     if( wstrDestination==NULL || tstrSource==NULL || cchDestChar < 1 )
  611.         return E_INVALIDARG;
  612. #ifdef _UNICODE
  613.     wcsncpy( wstrDestination, tstrSource, cchDestChar );
  614.     wstrDestination[cchDestChar-1] = L'';
  615.     return S_OK;
  616. #else
  617.     return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, tstrSource, cchDestChar );
  618. #endif    
  619. }
  620. //-----------------------------------------------------------------------------
  621. // Name: DXUtil_ConvertAnsiStringToGeneric()
  622. // Desc: This is a UNICODE conversion utility to convert a CHAR string into a
  623. //       TCHAR string. 
  624. //       cchDestChar is the size in TCHARs of tstrDestination.  Be careful not to 
  625. //       pass in sizeof(strDest) on UNICODE builds
  626. //-----------------------------------------------------------------------------
  627. HRESULT DXUtil_ConvertAnsiStringToGenericCch( TCHAR* tstrDestination, const CHAR* strSource, 
  628.                                            int cchDestChar )
  629. {
  630.     if( tstrDestination==NULL || strSource==NULL || cchDestChar < 1 )
  631.         return E_INVALIDARG;
  632.         
  633. #ifdef _UNICODE
  634.     return DXUtil_ConvertAnsiStringToWideCch( tstrDestination, strSource, cchDestChar );
  635. #else
  636.     strncpy( tstrDestination, strSource, cchDestChar );
  637.     tstrDestination[cchDestChar-1] = '';
  638.     return S_OK;
  639. #endif    
  640. }
  641. //-----------------------------------------------------------------------------
  642. // Name: DXUtil_ConvertAnsiStringToGeneric()
  643. // Desc: This is a UNICODE conversion utility to convert a WCHAR string into a
  644. //       TCHAR string. 
  645. //       cchDestChar is the size in TCHARs of tstrDestination.  Be careful not to 
  646. //       pass in sizeof(strDest) on UNICODE builds
  647. //-----------------------------------------------------------------------------
  648. HRESULT DXUtil_ConvertWideStringToGenericCch( TCHAR* tstrDestination, const WCHAR* wstrSource, 
  649.                                            int cchDestChar )
  650. {
  651.     if( tstrDestination==NULL || wstrSource==NULL || cchDestChar < 1 )
  652.         return E_INVALIDARG;
  653. #ifdef _UNICODE
  654.     wcsncpy( tstrDestination, wstrSource, cchDestChar );
  655.     tstrDestination[cchDestChar-1] = L'';    
  656.     return S_OK;
  657. #else
  658.     return DXUtil_ConvertWideStringToAnsiCch( tstrDestination, wstrSource, cchDestChar );
  659. #endif
  660. }
  661. //-----------------------------------------------------------------------------
  662. // Name: DXUtil_LaunchReadme()
  663. // Desc: Finds and opens the readme for this sample
  664. //-----------------------------------------------------------------------------
  665. VOID DXUtil_LaunchReadme( HWND hWnd, LPCTSTR strLoc )
  666. {
  667. #ifdef UNDER_CE
  668.     // This is not available on PocketPC
  669.     MessageBox( hWnd, TEXT("For operating instructions, please open the ")
  670.                       TEXT("readme.txt file included with the project."),
  671.                 TEXT("DirectX SDK Sample"), MB_ICONWARNING | MB_OK );
  672.     return;
  673. #endif
  674.     const int NUM_FILENAMES = 2;
  675.     LPCTSTR strFilenames[] = 
  676.     {
  677.         TEXT("readme.htm"),
  678.         TEXT("readme.txt")
  679.     };
  680.     TCHAR strReadmePath[1024];
  681.     TCHAR strExeName[MAX_PATH];
  682.     TCHAR strExePath[MAX_PATH];
  683.     TCHAR strSamplePath[MAX_PATH];
  684.     TCHAR* strLastSlash = NULL;
  685.     for( int i=0; i < NUM_FILENAMES; i++ )
  686.     {
  687.         LPCTSTR strFilename = strFilenames[i];
  688.         bool bSuccess = false;
  689.         bool bFound = false;
  690.         
  691.         lstrcpy( strReadmePath, TEXT("") );
  692.         lstrcpy( strExePath, TEXT("") );
  693.         lstrcpy( strExeName, TEXT("") );
  694.         lstrcpy( strSamplePath, TEXT("") );
  695.         // If the user provided a location for the readme, check there first.
  696.         if( strLoc )
  697.         {
  698.             HKEY  hKey;
  699.             LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  700.                                         _T("Software\Microsoft\DirectX SDK"),
  701.                                         0, KEY_READ, &hKey );
  702.             if( ERROR_SUCCESS == lResult )
  703.             {
  704.                 DWORD dwType;
  705.                 DWORD dwSize = MAX_PATH * sizeof(TCHAR);
  706.                 lResult = RegQueryValueEx( hKey, _T("DX9J3SDK Samples Path"), NULL,
  707.                                         &dwType, (BYTE*)strSamplePath, &dwSize );
  708.                 strSamplePath[MAX_PATH-1] = 0; // RegQueryValueEx doesn't NULL term if buffer too small
  709.                 
  710.                 if( ERROR_SUCCESS == lResult )
  711.                 {
  712.                     _sntprintf( strReadmePath, 1023, TEXT("%s\C++\%s\%s"), 
  713.                                 strSamplePath, strLoc, strFilename );
  714.                     strReadmePath[1023] = 0;
  715.                     if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  716.                         bFound = TRUE;
  717.                 }
  718.             }
  719.             RegCloseKey( hKey );
  720.         }
  721.         // Get the exe name, and exe path
  722.         GetModuleFileName( NULL, strExePath, MAX_PATH );
  723.         strExePath[MAX_PATH-1]=0;
  724.         strLastSlash = _tcsrchr( strExePath, TEXT('\') );
  725.         if( strLastSlash )
  726.         {
  727.             _tcsncpy( strExeName, &strLastSlash[1], MAX_PATH );
  728.             strExeName[MAX_PATH-1]=0;
  729.             // Chop the exe name from the exe path
  730.             *strLastSlash = 0;
  731.             // Chop the .exe from the exe name
  732.             strLastSlash = _tcsrchr( strExeName, TEXT('.') );
  733.             if( strLastSlash )
  734.                 *strLastSlash = 0;
  735.         }
  736.         if( !bFound )
  737.         {
  738.             // Search in "%EXE_DIR%..%EXE_NAME%".  This matches the DirectX SDK layout
  739.             _tcscpy( strReadmePath, strExePath );
  740.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  741.             if( strLastSlash )
  742.                 *strLastSlash = 0;
  743.             lstrcat( strReadmePath, TEXT("\") );
  744.             lstrcat( strReadmePath, strExeName );
  745.             lstrcat( strReadmePath, TEXT("\") );
  746.             lstrcat( strReadmePath, strFilename );
  747.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  748.                 bFound = TRUE;
  749.         }
  750.         if( !bFound )
  751.         {
  752.             // Search in "%EXE_DIR%..BumpMapping%EXE_NAME%".
  753.             _tcscpy( strReadmePath, strExePath );
  754.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  755.             if( strLastSlash )
  756.                 *strLastSlash = 0;
  757.             lstrcat( strReadmePath, TEXT("\BumpMapping\") );
  758.             lstrcat( strReadmePath, strExeName );
  759.             lstrcat( strReadmePath, TEXT("\") );
  760.             lstrcat( strReadmePath, strFilename );
  761.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  762.                 bFound = TRUE;
  763.         }
  764.         if( !bFound )
  765.         {
  766.             // Search in "%EXE_DIR%..EnvMapping%EXE_NAME%".
  767.             _tcscpy( strReadmePath, strExePath );
  768.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  769.             if( strLastSlash )
  770.                 *strLastSlash = 0;
  771.             lstrcat( strReadmePath, TEXT("\EnvMapping\") );
  772.             lstrcat( strReadmePath, strExeName );
  773.             lstrcat( strReadmePath, TEXT("\") );
  774.             lstrcat( strReadmePath, strFilename );
  775.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  776.                 bFound = TRUE;
  777.         }
  778.         if( !bFound )
  779.         {
  780.             // Search in "%EXE_DIR%..Meshes%EXE_NAME%".
  781.             _tcscpy( strReadmePath, strExePath );
  782.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  783.             if( strLastSlash )
  784.                 *strLastSlash = 0;
  785.             lstrcat( strReadmePath, TEXT("\Meshes\") );
  786.             lstrcat( strReadmePath, strExeName );
  787.             lstrcat( strReadmePath, TEXT("\") );
  788.             lstrcat( strReadmePath, strFilename );
  789.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  790.                 bFound = TRUE;
  791.         }
  792.         if( !bFound )
  793.         {
  794.             // Search in "%EXE_DIR%..StencilBuffer%EXE_NAME%".
  795.             _tcscpy( strReadmePath, strExePath );
  796.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  797.             if( strLastSlash )
  798.                 *strLastSlash = 0;
  799.             lstrcat( strReadmePath, TEXT("\StencilBuffer\") );
  800.             lstrcat( strReadmePath, strExeName );
  801.             lstrcat( strReadmePath, TEXT("\") );
  802.             lstrcat( strReadmePath, strFilename );
  803.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  804.                 bFound = TRUE;
  805.         }
  806.         if( !bFound )
  807.         {
  808.             // Search in "%EXE_DIR%"
  809.             _tcscpy( strReadmePath, strExePath );
  810.             lstrcat( strReadmePath, TEXT("\") );
  811.             lstrcat( strReadmePath, strFilename );
  812.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  813.                 bFound = TRUE;
  814.         }
  815.         if( !bFound )
  816.         {
  817.             // Search in "%EXE_DIR%.."
  818.             _tcscpy( strReadmePath, strExePath );
  819.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  820.             if( strLastSlash )
  821.                 *strLastSlash = 0;
  822.             lstrcat( strReadmePath, TEXT("\") );
  823.             lstrcat( strReadmePath, strFilename );
  824.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  825.                 bFound = TRUE;
  826.         }
  827.         if( !bFound )
  828.         {
  829.             // Search in "%EXE_DIR%...."
  830.             _tcscpy( strReadmePath, strExePath );
  831.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  832.             if( strLastSlash )
  833.                 *strLastSlash = 0;
  834.             strLastSlash = _tcsrchr( strReadmePath, TEXT('\') );
  835.             if( strLastSlash )
  836.                 *strLastSlash = 0;
  837.             lstrcat( strReadmePath, TEXT("\") );
  838.             lstrcat( strReadmePath, strFilename );
  839.             if( GetFileAttributes( strReadmePath ) != 0xFFFFFFFF )
  840.                 bFound = TRUE;
  841.         }
  842.         if( bFound )
  843.         {
  844.             // GetProcAddress for ShellExecute, so we don't have to include shell32.lib 
  845.             // in every project that uses dxutil.cpp
  846.             LPShellExecute pShellExecute = NULL;
  847.             HINSTANCE hInstShell32 = LoadLibrary(TEXT("shell32.dll"));
  848.             if (hInstShell32 != NULL)
  849.             {
  850.     #ifdef UNICODE
  851.                 pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteW"));
  852.     #else
  853.                 pShellExecute = (LPShellExecute)GetProcAddress(hInstShell32, _TWINCE("ShellExecuteA"));
  854.     #endif
  855.                 if( pShellExecute != NULL )
  856.                 {
  857.                     if( pShellExecute( hWnd, TEXT("open"), strReadmePath, NULL, NULL, SW_SHOW ) > (HINSTANCE) 32 )
  858.                         bSuccess = true;
  859.                 }
  860.                 FreeLibrary(hInstShell32);
  861.             }
  862.         }
  863.         if( bSuccess )
  864.             return;
  865.     }
  866.     // Tell the user that the readme couldn't be opened
  867.     MessageBox( hWnd, TEXT("Could not find readme"), 
  868.                 TEXT("DirectX SDK Sample"), MB_ICONWARNING | MB_OK );
  869. }
  870. //-----------------------------------------------------------------------------
  871. // Name: DXUtil_Trace()
  872. // Desc: Outputs to the debug stream a formatted string with a variable-
  873. //       argument list.
  874. //-----------------------------------------------------------------------------
  875. VOID DXUtil_Trace( LPCTSTR strMsg, ... )
  876. {
  877. #if defined(DEBUG) | defined(_DEBUG)
  878.     TCHAR strBuffer[512];
  879.     
  880.     va_list args;
  881.     va_start(args, strMsg);
  882.     _vsntprintf( strBuffer, 512, strMsg, args );
  883.     va_end(args);
  884.     OutputDebugString( strBuffer );
  885. #else
  886.     UNREFERENCED_PARAMETER(strMsg);
  887. #endif
  888. }
  889. //-----------------------------------------------------------------------------
  890. // Name: DXUtil_ConvertStringToGUID()
  891. // Desc: Converts a string to a GUID
  892. //-----------------------------------------------------------------------------
  893. HRESULT DXUtil_ConvertStringToGUID( const TCHAR* strSrc, GUID* pGuidDest )
  894. {
  895.     UINT aiTmp[10];
  896.     if( _stscanf( strSrc, TEXT("{%8X-%4X-%4X-%2X%2X-%2X%2X%2X%2X%2X%2X}"),
  897.                     &pGuidDest->Data1, 
  898.                     &aiTmp[0], &aiTmp[1], 
  899.                     &aiTmp[2], &aiTmp[3],
  900.                     &aiTmp[4], &aiTmp[5],
  901.                     &aiTmp[6], &aiTmp[7],
  902.                     &aiTmp[8], &aiTmp[9] ) != 11 )
  903.     {
  904.         ZeroMemory( pGuidDest, sizeof(GUID) );
  905.         return E_FAIL;
  906.     }
  907.     else
  908.     {
  909.         pGuidDest->Data2       = (USHORT) aiTmp[0];
  910.         pGuidDest->Data3       = (USHORT) aiTmp[1];
  911.         pGuidDest->Data4[0]    = (BYTE) aiTmp[2];
  912.         pGuidDest->Data4[1]    = (BYTE) aiTmp[3];
  913.         pGuidDest->Data4[2]    = (BYTE) aiTmp[4];
  914.         pGuidDest->Data4[3]    = (BYTE) aiTmp[5];
  915.         pGuidDest->Data4[4]    = (BYTE) aiTmp[6];
  916.         pGuidDest->Data4[5]    = (BYTE) aiTmp[7];
  917.         pGuidDest->Data4[6]    = (BYTE) aiTmp[8];
  918.         pGuidDest->Data4[7]    = (BYTE) aiTmp[9];
  919.         return S_OK;
  920.     }
  921. }
  922. //-----------------------------------------------------------------------------
  923. // Name: DXUtil_ConvertGUIDToStringCch()
  924. // Desc: Converts a GUID to a string 
  925. //       cchDestChar is the size in TCHARs of strDest.  Be careful not to 
  926. //       pass in sizeof(strDest) on UNICODE builds
  927. //-----------------------------------------------------------------------------
  928. HRESULT DXUtil_ConvertGUIDToStringCch( const GUID* pGuidSrc, TCHAR* strDest, int cchDestChar )
  929. {
  930.     int nResult = _sntprintf( strDest, cchDestChar, TEXT("{%0.8X-%0.4X-%0.4X-%0.2X%0.2X-%0.2X%0.2X%0.2X%0.2X%0.2X%0.2X}"),
  931.                pGuidSrc->Data1, pGuidSrc->Data2, pGuidSrc->Data3,
  932.                pGuidSrc->Data4[0], pGuidSrc->Data4[1],
  933.                pGuidSrc->Data4[2], pGuidSrc->Data4[3],
  934.                pGuidSrc->Data4[4], pGuidSrc->Data4[5],
  935.                pGuidSrc->Data4[6], pGuidSrc->Data4[7] );
  936.     if( nResult < 0 )
  937.         return E_FAIL;
  938.     return S_OK;
  939. }
  940. //-----------------------------------------------------------------------------
  941. // Name: CArrayList constructor
  942. // Desc: 
  943. //-----------------------------------------------------------------------------
  944. CArrayList::CArrayList( ArrayListType Type, UINT BytesPerEntry )
  945. {
  946.     if( Type == AL_REFERENCE )
  947.         BytesPerEntry = sizeof(void*);
  948.     m_ArrayListType = Type;
  949.     m_pData = NULL;
  950.     m_BytesPerEntry = BytesPerEntry;
  951.     m_NumEntries = 0;
  952.     m_NumEntriesAllocated = 0;
  953. }
  954. //-----------------------------------------------------------------------------
  955. // Name: CArrayList destructor
  956. // Desc: 
  957. //-----------------------------------------------------------------------------
  958. CArrayList::~CArrayList( void )
  959. {
  960.     if( m_pData != NULL )
  961.         delete[] m_pData;
  962. }
  963. //-----------------------------------------------------------------------------
  964. // Name: CArrayList::Add
  965. // Desc: Adds pEntry to the list.
  966. //-----------------------------------------------------------------------------
  967. HRESULT CArrayList::Add( void* pEntry )
  968. {
  969.     if( m_BytesPerEntry == 0 )
  970.         return E_FAIL;
  971.     if( m_pData == NULL || m_NumEntries + 1 > m_NumEntriesAllocated )
  972.     {
  973.         void* pDataNew;
  974.         UINT NumEntriesAllocatedNew;
  975.         if( m_NumEntriesAllocated == 0 )
  976.             NumEntriesAllocatedNew = 16;
  977.         else
  978.             NumEntriesAllocatedNew = m_NumEntriesAllocated * 2;
  979.         pDataNew = new BYTE[NumEntriesAllocatedNew * m_BytesPerEntry];
  980.         if( pDataNew == NULL )
  981.             return E_OUTOFMEMORY;
  982.         if( m_pData != NULL )
  983.         {
  984.             CopyMemory( pDataNew, m_pData, m_NumEntries * m_BytesPerEntry );
  985.             delete[] m_pData;
  986.         }
  987.         m_pData = pDataNew;
  988.         m_NumEntriesAllocated = NumEntriesAllocatedNew;
  989.     }
  990.     if( m_ArrayListType == AL_VALUE )
  991.         CopyMemory( (BYTE*)m_pData + (m_NumEntries * m_BytesPerEntry), pEntry, m_BytesPerEntry );
  992.     else
  993.         *(((void**)m_pData) + m_NumEntries) = pEntry;
  994.     m_NumEntries++;
  995.     return S_OK;
  996. }
  997. //-----------------------------------------------------------------------------
  998. // Name: CArrayList::Remove
  999. // Desc: Remove the item at Entry in the list, and collapse the array. 
  1000. //-----------------------------------------------------------------------------
  1001. void CArrayList::Remove( UINT Entry )
  1002. {
  1003.     // Decrement count
  1004.     m_NumEntries--;
  1005.     // Find the entry address
  1006.     BYTE* pData = (BYTE*)m_pData + (Entry * m_BytesPerEntry);
  1007.     // Collapse the array
  1008.     MoveMemory( pData, pData + m_BytesPerEntry, ( m_NumEntries - Entry ) * m_BytesPerEntry );
  1009. }
  1010. //-----------------------------------------------------------------------------
  1011. // Name: CArrayList::GetPtr
  1012. // Desc: Returns a pointer to the Entry'th entry in the list.
  1013. //-----------------------------------------------------------------------------
  1014. void* CArrayList::GetPtr( UINT Entry )
  1015. {
  1016.     if( m_ArrayListType == AL_VALUE )
  1017.         return (BYTE*)m_pData + (Entry * m_BytesPerEntry);
  1018.     else
  1019.         return *(((void**)m_pData) + Entry);
  1020. }
  1021. //-----------------------------------------------------------------------------
  1022. // Name: CArrayList::Contains
  1023. // Desc: Returns whether the list contains an entry identical to the 
  1024. //       specified entry data.
  1025. //-----------------------------------------------------------------------------
  1026. bool CArrayList::Contains( void* pEntryData )
  1027. {
  1028.     for( UINT iEntry = 0; iEntry < m_NumEntries; iEntry++ )
  1029.     {
  1030.         if( m_ArrayListType == AL_VALUE )
  1031.         {
  1032.             if( memcmp( GetPtr(iEntry), pEntryData, m_BytesPerEntry ) == 0 )
  1033.                 return true;
  1034.         }
  1035.         else
  1036.         {
  1037.             if( GetPtr(iEntry) == pEntryData )
  1038.                 return true;
  1039.         }
  1040.     }
  1041.     return false;
  1042. }
  1043. //-----------------------------------------------------------------------------
  1044. // Name: BYTE helper functions
  1045. // Desc: cchDestChar is the size in BYTEs of strDest.  Be careful not to 
  1046. //       pass use sizeof() if the strDest is a string pointer.  
  1047. //       eg.
  1048. //       TCHAR* sz = new TCHAR[100]; // sizeof(sz)  == 4
  1049. //       TCHAR sz2[100];             // sizeof(sz2) == 200
  1050. //-----------------------------------------------------------------------------
  1051. HRESULT DXUtil_ConvertAnsiStringToWideCb( WCHAR* wstrDestination, const CHAR* strSource, int cbDestChar )
  1052. {
  1053.     return DXUtil_ConvertAnsiStringToWideCch( wstrDestination, strSource, cbDestChar / sizeof(WCHAR) );
  1054. }
  1055. HRESULT DXUtil_ConvertWideStringToAnsiCb( CHAR* strDestination, const WCHAR* wstrSource, int cbDestChar )
  1056. {
  1057.     return DXUtil_ConvertWideStringToAnsiCch( strDestination, wstrSource, cbDestChar / sizeof(CHAR) );
  1058. }
  1059. HRESULT DXUtil_ConvertGenericStringToAnsiCb( CHAR* strDestination, const TCHAR* tstrSource, int cbDestChar )
  1060. {
  1061.     return DXUtil_ConvertGenericStringToAnsiCch( strDestination, tstrSource, cbDestChar / sizeof(CHAR) );
  1062. }
  1063. HRESULT DXUtil_ConvertGenericStringToWideCb( WCHAR* wstrDestination, const TCHAR* tstrSource, int cbDestChar )
  1064. {
  1065.     return DXUtil_ConvertGenericStringToWideCch( wstrDestination, tstrSource, cbDestChar / sizeof(WCHAR) );
  1066. }
  1067. HRESULT DXUtil_ConvertAnsiStringToGenericCb( TCHAR* tstrDestination, const CHAR* strSource, int cbDestChar )
  1068. {
  1069.     return DXUtil_ConvertAnsiStringToGenericCch( tstrDestination, strSource, cbDestChar / sizeof(TCHAR) );
  1070. }
  1071. HRESULT DXUtil_ConvertWideStringToGenericCb( TCHAR* tstrDestination, const WCHAR* wstrSource, int cbDestChar )
  1072. {
  1073.     return DXUtil_ConvertWideStringToGenericCch( tstrDestination, wstrSource, cbDestChar / sizeof(TCHAR) );
  1074. }
  1075. HRESULT DXUtil_ReadStringRegKeyCb( HKEY hKey, LPCTSTR strRegName, TCHAR* strDest, DWORD cbDest, LPCTSTR strDefault )
  1076. {
  1077.     return DXUtil_ReadStringRegKeyCch( hKey, strRegName, strDest, cbDest / sizeof(TCHAR), strDefault );
  1078. }
  1079. HRESULT DXUtil_ConvertGUIDToStringCb( const GUID* pGuidSrc, TCHAR* strDest, int cbDestChar )
  1080. {
  1081.     return DXUtil_ConvertGUIDToStringCch( pGuidSrc, strDest, cbDestChar / sizeof(TCHAR) );
  1082. }
  1083. #ifndef UNDER_CE
  1084. HRESULT DXUtil_GetDXSDKMediaPathCb( TCHAR* szDest, int cbDest )
  1085. {
  1086.     return DXUtil_GetDXSDKMediaPathCch( szDest, cbDest / sizeof(TCHAR) );
  1087. }
  1088. HRESULT DXUtil_FindMediaFileCb( TCHAR* szDestPath, int cbDest, LPCTSTR strFilename )
  1089. {
  1090.     return DXUtil_FindMediaFileCch( szDestPath, cbDest / sizeof(TCHAR), strFilename );
  1091. }
  1092. #endif // !UNDER_CE