home *** CD-ROM | disk | FTP | other *** search
/ Isometric Game Programming with DirectX 7.0 / Isometric Game Programming.iso / directx / dxf / samples / multimedia / common / src / dxutil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  19.5 KB  |  617 lines

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