XAudio2Sound3D.cpp
上传用户:May-22
上传日期:2015-07-19
资源大小:7113k
文件大小:38k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // File: XAudio2Sound3D.cpp
  3. //
  4. // XNA Developer Connection
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //--------------------------------------------------------------------------------------
  7. #include "DXUT.h"
  8. #include "DXUTgui.h"
  9. #include "DXUTmisc.h"
  10. #include "DXUTSettingsDlg.h"
  11. #include "SDKmisc.h"
  12. #include "SDKmesh.h"
  13. #include "resource.h"
  14. #include "audio.h"
  15. //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
  16. //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
  17. //--------------------------------------------------------------------------------------
  18. // Global variables
  19. //--------------------------------------------------------------------------------------
  20. CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
  21. CD3DSettingsDlg         g_SettingsDlg;          // Device settings dialog
  22. CDXUTTextHelper* g_pTxtHelper = NULL;
  23. CDXUTDialog             g_HUD;                  // dialog for standard controls
  24. CDXUTDialog             g_SampleUI;             // dialog for sample specific controls
  25. // Direct3D 9 resources
  26. ID3DXFont*                      g_pFont9 = NULL;        
  27. ID3DXSprite*                    g_pSprite9 = NULL;      
  28. ID3DXEffect*                    g_pEffect9 = NULL;
  29. IDirect3DVertexDeclaration9*    g_pVertexDecl = NULL;
  30. LPDIRECT3DVERTEXBUFFER9         g_pvbFloor = NULL;
  31. LPDIRECT3DVERTEXBUFFER9         g_pvbSource = NULL;
  32. LPDIRECT3DVERTEXBUFFER9         g_pvbListener = NULL;
  33. LPDIRECT3DVERTEXBUFFER9         g_pvbGrid = NULL;
  34. struct D3DVERTEX
  35. {
  36.     D3DXVECTOR3 p;
  37.     D3DCOLOR c;
  38. };
  39. const LPWSTR g_SOUND_NAMES[] =
  40. {
  41.      L"Heli.wav",
  42.      L"MusicMono.wav",
  43. };
  44. enum CONTROL_MODE
  45. {
  46.     CONTROL_LISTENER=0,
  47.     CONTROL_SOURCE
  48. } g_eControlMode = (CONTROL_MODE)0;
  49. // Must match order of g_PRESET_PARAMS
  50. const LPWSTR g_PRESET_NAMES[ NUM_PRESETS ] =
  51. {
  52.     L"Default",
  53.     L"Generic",
  54.     L"Padded cell",
  55.     L"Room",
  56.     L"Bathroom",
  57.     L"Living room",
  58.     L"Stone room",
  59.     L"Auditorium",
  60.     L"Concert hall",
  61.     L"Cave",
  62.     L"Arena",
  63.     L"Hangar",
  64.     L"Carpeted hallway",
  65.     L"Hallway",
  66.     L"Stone Corridor",
  67.     L"Alley",
  68.     L"Forest",
  69.     L"City",
  70.     L"Mountains",
  71.     L"Quarry",
  72.     L"Plain",
  73.     L"Parking lot",
  74.     L"Sewer pipe",
  75.     L"Underwater",
  76.     L"Small room",
  77.     L"Medium room",
  78.     L"Large room",
  79.     L"Medium hall",
  80.     L"Large hall",
  81.     L"Plate",
  82. };
  83. #define FLAG_MOVE_UP        0x1
  84. #define FLAG_MOVE_LEFT      0x2
  85. #define FLAG_MOVE_RIGHT     0x4
  86. #define FLAG_MOVE_DOWN      0x8
  87. int g_moveFlags = 0;
  88. const float MOTION_SCALE = 10.0f;
  89. //--------------------------------------------------------------------------------------
  90. // Constants
  91. //--------------------------------------------------------------------------------------
  92. // UI control IDs
  93. #define IDC_STATIC              -1
  94. #define IDC_TOGGLEFULLSCREEN    1
  95. #define IDC_TOGGLEREF           2
  96. #define IDC_CHANGEDEVICE        3
  97. #define IDC_SOUND               4
  98. #define IDC_CONTROL_MODE        5
  99. #define IDC_PRESET              6
  100. #define IDC_UP                  7
  101. #define IDC_LEFT                8
  102. #define IDC_RIGHT               9
  103. #define IDC_DOWN                10
  104. // Constants for colors
  105. static const DWORD SOURCE_COLOR   = 0xffea1b1b;
  106. static const DWORD LISTENER_COLOR = 0xff1b1bea;
  107. static const DWORD FLOOR_COLOR    = 0xff101010;
  108. static const DWORD GRID_COLOR     = 0xff00a000;
  109. //--------------------------------------------------------------------------------------
  110. // Forward declarations 
  111. //--------------------------------------------------------------------------------------
  112. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
  113. void    CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
  114. void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
  115. void    CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );
  116. bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );
  117. bool    CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
  118. HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  119. HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
  120. void    CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
  121. void    CALLBACK OnD3D9LostDevice( void* pUserContext );
  122. void    CALLBACK OnD3D9DestroyDevice( void* pUserContext );
  123. void    InitApp();
  124. void    RenderText();
  125. //--------------------------------------------------------------------------------------
  126. // Entry point to the program. Initializes everything and goes into a message processing 
  127. // loop. Idle time is used to render the scene.
  128. //--------------------------------------------------------------------------------------
  129. int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
  130. {
  131.     // Enable run-time memory check for debug builds.
  132. #if defined(DEBUG) | defined(_DEBUG)
  133.     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
  134. #endif
  135.     // DXUT will create and use the best device (either D3D9 or D3D10) 
  136.     // that is available on the system depending on which D3D callbacks are set below
  137.     // Set DXUT callbacks
  138.     DXUTSetCallbackMsgProc( MsgProc );
  139.     DXUTSetCallbackKeyboard( OnKeyboard );
  140.     DXUTSetCallbackFrameMove( OnFrameMove );
  141.     DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
  142.     DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
  143.     DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
  144.     DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
  145.     DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
  146.     DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
  147.     DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
  148.     InitApp();
  149.     HRESULT hr = InitAudio();
  150.     if( FAILED( hr ) ) 
  151.     {
  152.         OutputDebugString( L"InitAudio() failed.  Disabling audio supportn" );
  153.     }
  154.     DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params
  155.     DXUTSetCursorSettings( true, true );
  156.     DXUTCreateWindow( L"XAudio2Sound3D" );
  157.     DXUTCreateDevice( true, 640, 480 );
  158.     hr = PrepareAudio( g_SOUND_NAMES[0] );
  159.     if( FAILED( hr ) )
  160.     {
  161.         OutputDebugString( L"PrepareAudio() failedn" );
  162.     }
  163.     DXUTMainLoop(); // Enter into the DXUT render loop
  164.     CleanupAudio();
  165.     return DXUTGetExitCode();
  166. }
  167. //--------------------------------------------------------------------------------------
  168. // Initialize the app 
  169. //--------------------------------------------------------------------------------------
  170. void InitApp()
  171. {
  172.     g_SettingsDlg.Init( &g_DialogResourceManager );
  173.     g_HUD.Init( &g_DialogResourceManager );
  174.     g_SampleUI.Init( &g_DialogResourceManager );
  175.     g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
  176.     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
  177.     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22, VK_F3 );
  178.     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
  179.     g_SampleUI.SetCallback( OnGUIEvent );
  180.     //
  181.     // Sound control
  182.     //
  183.     CDXUTComboBox* pComboBox = NULL;
  184.     g_SampleUI.AddStatic( IDC_STATIC, L"S(o)und", 0, 0, 105, 25 );
  185.     g_SampleUI.AddComboBox( IDC_SOUND, 0, 25, 140, 24, 'O', false, &pComboBox );
  186.     if( pComboBox )
  187.         pComboBox->SetDropHeight( 50 );
  188.     for( int i=0; i < sizeof(g_SOUND_NAMES)/sizeof(WCHAR*); i++ )
  189.     {
  190.         pComboBox->AddItem( g_SOUND_NAMES[i], IntToPtr(i) );
  191.     }
  192.     //
  193.     // Control mode
  194.     //
  195.     g_SampleUI.AddStatic( IDC_STATIC, L"(C)ontrol mode", 0, 45, 105, 25 );
  196.     g_SampleUI.AddComboBox( IDC_CONTROL_MODE, 0, 70, 140, 24, 'C', false, &pComboBox );
  197.     if( pComboBox )
  198.         pComboBox->SetDropHeight( 30 );
  199.     pComboBox->AddItem( L"Listener", IntToPtr(CONTROL_LISTENER) );
  200.     pComboBox->AddItem( L"Source", IntToPtr(CONTROL_SOURCE) );
  201.     //
  202.     // I3DL2 reverb preset control
  203.     //
  204.     g_SampleUI.AddStatic( IDC_STATIC, L"(R)everb", 0, 90, 105, 25 );
  205.     g_SampleUI.AddComboBox( IDC_PRESET, 0, 115, 140, 24, 'R', false, &pComboBox );
  206.     if( pComboBox )
  207.         pComboBox->SetDropHeight( 50 );
  208.     for( int i=0; i < sizeof(g_PRESET_NAMES)/sizeof(WCHAR*); i++ )
  209.     {
  210.         pComboBox->AddItem( g_PRESET_NAMES[i], IntToPtr(i) );
  211.     }
  212.     //
  213.     // Movement buttons
  214.     //
  215.     iY = 160;
  216.     g_SampleUI.AddButton( IDC_UP, L"(W)", 40, iY, 70, 24 );
  217.     g_SampleUI.AddButton( IDC_LEFT, L"(A)", 5, iY += 30, 70, 24 );
  218.     g_SampleUI.AddButton( IDC_RIGHT, L"(D)", 75, iY, 70, 24 );
  219.     g_SampleUI.AddButton( IDC_DOWN, L"(S)", 40, iY += 30, 70, 24 );
  220. }
  221. //--------------------------------------------------------------------------------------
  222. // Render the help and statistics text. This function uses the ID3DXFont interface for 
  223. // efficient text rendering.
  224. //--------------------------------------------------------------------------------------
  225. void RenderText()
  226. {
  227.     g_pTxtHelper->Begin();
  228.     g_pTxtHelper->SetInsertionPos( 5, 5 );
  229.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
  230.     g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );  
  231.     g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );
  232.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.0f, 0.0f, 1.0f ) );
  233.     g_pTxtHelper->DrawFormattedTextLine( L"Source: %.1f, %.1f, %.1f",
  234.             g_audioState.emitter.Position.x, g_audioState.emitter.Position.y, g_audioState.emitter.Position.z );
  235.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.0f, 0.0f, 0.5f, 1.0f ) );
  236.     g_pTxtHelper->DrawFormattedTextLine( L"Listener: %.1f, %.1f, %.1f",
  237.     g_audioState.listener.Position.x, g_audioState.listener.Position.y, g_audioState.listener.Position.z );
  238.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
  239.     g_pTxtHelper->DrawTextLine( L"Coefficients:" );
  240.     // Interpretation of channels depends on channel mask
  241.     switch( g_audioState.dwChannelMask )
  242.     {
  243.     case SPEAKER_MONO:
  244.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  245.         break;
  246.     case SPEAKER_STEREO:
  247.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  248.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  249.         break;
  250.     case SPEAKER_2POINT1:
  251.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  252.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  253.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  254.         break;
  255.     case SPEAKER_SURROUND:
  256.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  257.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  258.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  259.         g_pTxtHelper->DrawFormattedTextLine( L" B: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  260.         break;
  261.     case SPEAKER_QUAD:
  262.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  263.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  264.         g_pTxtHelper->DrawFormattedTextLine( L" Lb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  265.         g_pTxtHelper->DrawFormattedTextLine( L" Rb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  266.         break;
  267.     case SPEAKER_4POINT1:
  268.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  269.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  270.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  271.         g_pTxtHelper->DrawFormattedTextLine( L" Lb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  272.         g_pTxtHelper->DrawFormattedTextLine( L" Rb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  273.         break;
  274.     case SPEAKER_5POINT1:
  275.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  276.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  277.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  278.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  279.         g_pTxtHelper->DrawFormattedTextLine( L" Lb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  280.         g_pTxtHelper->DrawFormattedTextLine( L" Rb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[5] );
  281.         break;
  282.     
  283.     case SPEAKER_7POINT1:
  284.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  285.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  286.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  287.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  288.         g_pTxtHelper->DrawFormattedTextLine( L" Lb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  289.         g_pTxtHelper->DrawFormattedTextLine( L" Rb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[5] );
  290.         g_pTxtHelper->DrawFormattedTextLine( L" Lfc: %.3f", g_audioState.dspSettings.pMatrixCoefficients[6] );
  291.         g_pTxtHelper->DrawFormattedTextLine( L" Rfc: %.3f", g_audioState.dspSettings.pMatrixCoefficients[7] );
  292.         break;
  293.     case SPEAKER_5POINT1_SURROUND:
  294.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  295.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  296.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  297.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  298.         g_pTxtHelper->DrawFormattedTextLine( L" Ls: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  299.         g_pTxtHelper->DrawFormattedTextLine( L" Rs: %.3f", g_audioState.dspSettings.pMatrixCoefficients[5] );
  300.         break;
  301.     case SPEAKER_7POINT1_SURROUND:
  302.         g_pTxtHelper->DrawFormattedTextLine( L" L: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  303.         g_pTxtHelper->DrawFormattedTextLine( L" R: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  304.         g_pTxtHelper->DrawFormattedTextLine( L" C: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  305.         g_pTxtHelper->DrawFormattedTextLine( L" LFE: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  306.         g_pTxtHelper->DrawFormattedTextLine( L" Lb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  307.         g_pTxtHelper->DrawFormattedTextLine( L" Rb: %.3f", g_audioState.dspSettings.pMatrixCoefficients[5] );
  308.         g_pTxtHelper->DrawFormattedTextLine( L" Ls: %.3f", g_audioState.dspSettings.pMatrixCoefficients[6] );
  309.         g_pTxtHelper->DrawFormattedTextLine( L" Rs: %.3f", g_audioState.dspSettings.pMatrixCoefficients[7] );
  310.         break;
  311.     default:
  312.         // Generic channel output for non-standard channel masks
  313.         g_pTxtHelper->DrawFormattedTextLine( L" [0]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[0] );
  314.         g_pTxtHelper->DrawFormattedTextLine( L" [1]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[1] );
  315.         g_pTxtHelper->DrawFormattedTextLine( L" [2]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[2] );
  316.         g_pTxtHelper->DrawFormattedTextLine( L" [3]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[3] );
  317.         g_pTxtHelper->DrawFormattedTextLine( L" [4]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[4] );
  318.         g_pTxtHelper->DrawFormattedTextLine( L" [5]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[5] );
  319.         g_pTxtHelper->DrawFormattedTextLine( L" [6]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[6] );
  320.         g_pTxtHelper->DrawFormattedTextLine( L" [7]: %.3f", g_audioState.dspSettings.pMatrixCoefficients[7] );
  321.         break;
  322.     }
  323.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.5f, 0.5f, 0.5f, 1.0f ) );
  324.     g_pTxtHelper->DrawFormattedTextLine( L"Distance: %.3f", g_audioState.dspSettings.EmitterToListenerDistance );
  325.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
  326.     g_pTxtHelper->DrawFormattedTextLine( L"Doppler factor: %.3f", g_audioState.dspSettings.DopplerFactor );
  327.     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 0.5f, 0.5f, 0.5f, 1.0f ) );
  328.     g_pTxtHelper->DrawFormattedTextLine( L"LPF Direct: %.3f", g_audioState.dspSettings.LPFDirectCoefficient );
  329.     g_pTxtHelper->DrawFormattedTextLine( L"LPF Reverb: %.3f", g_audioState.dspSettings.LPFReverbCoefficient );
  330.     g_pTxtHelper->DrawFormattedTextLine( L"Reverb: %.3f", g_audioState.dspSettings.ReverbLevel );
  331.     g_pTxtHelper->End();
  332. }
  333. //--------------------------------------------------------------------------------------
  334. // Rejects any D3D9 devices that aren't acceptable to the app by returning false
  335. //--------------------------------------------------------------------------------------
  336. bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
  337.                                       D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
  338. {
  339.     // Skip backbuffer formats that don't support alpha blending
  340.     IDirect3D9* pD3D = DXUTGetD3D9Object(); 
  341.     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
  342.                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
  343.                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
  344.         return false;
  345.     // No fallback defined by this app, so reject any device that 
  346.     // doesn't support at least ps2.0
  347.     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
  348.         return false;
  349.     return true;
  350. }
  351. //--------------------------------------------------------------------------------------
  352. // Called right before creating a D3D9 or D3D10 device, allowing the app to modify the device settings as needed
  353. //--------------------------------------------------------------------------------------
  354. bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
  355. {
  356.     if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )
  357.     {
  358.         IDirect3D9 *pD3D = DXUTGetD3D9Object();
  359.         D3DCAPS9 Caps;
  360.         pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &Caps );
  361.         // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
  362.         // then switch to SWVP.
  363.         if( (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
  364.             Caps.VertexShaderVersion < D3DVS_VERSION(1,1) )
  365.         {
  366.             pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  367.         }
  368.         // Debugging vertex shaders requires either REF or software vertex processing 
  369.         // and debugging pixel shaders requires REF.  
  370. #ifdef DEBUG_VS
  371.         if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF )
  372.         {
  373.             pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
  374.             pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                            
  375.             pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  376.         }
  377. #endif
  378. #ifdef DEBUG_PS
  379.         pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF;
  380. #endif
  381.     }
  382.     // For the first device created if its a REF device, optionally display a warning dialog box
  383.     static bool s_bFirstTime = true;
  384.     if( s_bFirstTime )
  385.     {
  386.         s_bFirstTime = false;
  387.         if( (DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF) ||
  388.             (DXUT_D3D10_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d10.DriverType == D3D10_DRIVER_TYPE_REFERENCE) )
  389.             DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver );
  390.     }
  391.     return true;
  392. }
  393. //--------------------------------------------------------------------------------------
  394. // Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
  395. // and aren't tied to the back buffer size
  396. //--------------------------------------------------------------------------------------
  397. HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
  398. {
  399.     HRESULT hr;
  400.     V_RETURN( g_DialogResourceManager.OnD3D9CreateDevice( pd3dDevice ) );
  401.     V_RETURN( g_SettingsDlg.OnD3D9CreateDevice( pd3dDevice ) );
  402.     
  403.     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
  404.                               OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
  405.                               L"Arial", &g_pFont9 ) );
  406.     // Read the D3DX effect file
  407.     WCHAR str[MAX_PATH];
  408.     DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
  409.     #ifdef DEBUG_VS
  410.         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
  411.     #endif
  412.     #ifdef DEBUG_PS
  413.         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
  414.     #endif
  415.     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"XAudio2Sound3D.fx" ) );
  416.     V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, 
  417.                                         NULL, &g_pEffect9, NULL ) );
  418.     //
  419.     // Create render elements
  420.     //
  421.     // Define the vertex elements.
  422.     D3DVERTEXELEMENT9 VertexElements[ 3 ] =
  423.     {
  424.         { 0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
  425.         { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0 },
  426.         D3DDECL_END()
  427.     };
  428.     // Create a vertex declaration from the element descriptions.
  429.     V_RETURN( pd3dDevice->CreateVertexDeclaration( VertexElements, &g_pVertexDecl ) );
  430.     // Create our vertex buffers
  431.     V_RETURN( pd3dDevice->CreateVertexBuffer( 4 * sizeof(D3DVERTEX), 0, 0, D3DPOOL_MANAGED, &g_pvbFloor, NULL) );
  432.     V_RETURN( pd3dDevice->CreateVertexBuffer( 4 * sizeof(D3DVERTEX), 0, 0, D3DPOOL_MANAGED, &g_pvbSource, NULL ) );
  433.     V_RETURN( pd3dDevice->CreateVertexBuffer( 3 * sizeof(D3DVERTEX), 0, 0, D3DPOOL_MANAGED, &g_pvbListener, NULL ) );
  434.     const UINT lcount = 2 * ( (ZMAX-ZMIN+1) + (XMAX-XMIN+1 ) );
  435.     V_RETURN( pd3dDevice->CreateVertexBuffer( 2 * sizeof(D3DVERTEX) * lcount, 0, 0, D3DPOOL_MANAGED, &g_pvbGrid, NULL ) );
  436.     D3DVERTEX *pVertices;
  437.     // Fill the VB for the listener
  438.     V_RETURN( g_pvbListener->Lock( 0, 0, (VOID**)&pVertices, 0 ) );
  439.     pVertices[0].p = D3DXVECTOR3( -0.5f, -1.f, 0 );
  440.     pVertices[0].c = LISTENER_COLOR;
  441.     pVertices[1].p = D3DXVECTOR3(  0, 1.f, 0 );
  442.     pVertices[1].c = LISTENER_COLOR;
  443.     pVertices[2].p = D3DXVECTOR3(  0.5f, -1.f, 0 );
  444.     pVertices[2].c = LISTENER_COLOR;
  445.     g_pvbListener->Unlock();
  446.     // Fill the VB for the source
  447.     V_RETURN( g_pvbSource->Lock( 0, 0, (VOID**)&pVertices, 0 ) );
  448.     pVertices[0].p = D3DXVECTOR3( -0.5f, -0.5f, 0 );
  449.     pVertices[0].c = SOURCE_COLOR;
  450.     pVertices[1].p = D3DXVECTOR3( -0.5f, 0.5f, 0 );
  451.     pVertices[1].c = SOURCE_COLOR;
  452.     pVertices[2].p = D3DXVECTOR3(  0.5f, -0.5f, 0 );
  453.     pVertices[2].c = SOURCE_COLOR;
  454.     pVertices[3].p = D3DXVECTOR3(  0.5f, 0.5f, 0 );
  455.     pVertices[3].c = SOURCE_COLOR;
  456.     g_pvbSource->Unlock();
  457.     // Fill the VB for the floor
  458.     V_RETURN( g_pvbFloor->Lock( 0, 0, (VOID**)&pVertices, 0 ) );
  459.     pVertices[0].p = D3DXVECTOR3( (FLOAT)XMIN, (FLOAT)ZMIN, 0 );
  460.     pVertices[0].c = FLOOR_COLOR;
  461.     pVertices[1].p = D3DXVECTOR3( (FLOAT)XMIN, (FLOAT)ZMAX, 0 );
  462.     pVertices[1].c = FLOOR_COLOR;
  463.     pVertices[2].p = D3DXVECTOR3( (FLOAT)XMAX, (FLOAT)ZMIN, 0 );
  464.     pVertices[2].c = FLOOR_COLOR;
  465.     pVertices[3].p = D3DXVECTOR3( (FLOAT)XMAX, (FLOAT)ZMAX, 0 );
  466.     pVertices[3].c = FLOOR_COLOR;
  467.     g_pvbFloor->Unlock();
  468.     // Fill the VB for the grid
  469.     INT i, j;
  470.     V_RETURN( g_pvbGrid->Lock( 0, 0, (VOID**)&pVertices, 0 ) );
  471.     for( i = ZMIN, j = 0; i <= ZMAX; ++i, ++j )
  472.     {
  473.         pVertices[ j * 2 + 0 ].p = D3DXVECTOR3( (FLOAT)XMIN, (FLOAT)i, 0 );
  474.         pVertices[ j * 2 + 0 ].c = GRID_COLOR;
  475.         pVertices[ j * 2 + 1 ].p = D3DXVECTOR3( (FLOAT)XMAX, (FLOAT)i, 0 );
  476.         pVertices[ j * 2 + 1 ].c = GRID_COLOR;
  477.     }
  478.     for( i = XMIN; i <= XMAX; ++i, ++j )
  479.     {
  480.         pVertices[ j * 2 + 0 ].p = D3DXVECTOR3( (FLOAT)i, (FLOAT)ZMIN, 0 );
  481.         pVertices[ j * 2 + 0 ].c = GRID_COLOR;
  482.         pVertices[ j * 2 + 1 ].p = D3DXVECTOR3( (FLOAT)i, (FLOAT)ZMAX, 0 );
  483.         pVertices[ j * 2 + 1 ].c = GRID_COLOR;
  484.     }
  485.     g_pvbGrid->Unlock();
  486.     
  487.     return S_OK;
  488. }
  489. //--------------------------------------------------------------------------------------
  490. // Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT) 
  491. // or that are tied to the back buffer size 
  492. //--------------------------------------------------------------------------------------
  493. HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, 
  494.                                     const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
  495. {
  496.     HRESULT hr;
  497.     V_RETURN( g_DialogResourceManager.OnD3D9ResetDevice() );
  498.     V_RETURN( g_SettingsDlg.OnD3D9ResetDevice() );
  499.     if( g_pFont9 ) V_RETURN( g_pFont9->OnResetDevice() );
  500.     if( g_pEffect9 ) V_RETURN( g_pEffect9->OnResetDevice() );
  501.     V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pSprite9 ) );
  502.     g_pTxtHelper = new CDXUTTextHelper( g_pFont9, g_pSprite9, NULL, NULL, 15 );
  503.     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
  504.     g_HUD.SetSize( 170, 170 );
  505.     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-350 );
  506.     g_SampleUI.SetSize( 170, 300 );
  507.  
  508.     return S_OK;
  509. }
  510. //--------------------------------------------------------------------------------------
  511. // Handle updates to the scene.  This is called regardless of which D3D API is used
  512. //--------------------------------------------------------------------------------------
  513. void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
  514. {
  515.     if ( fElapsedTime > 0 )
  516.     {
  517.         D3DXVECTOR3* vec = (g_eControlMode == CONTROL_LISTENER) ? &g_audioState.vListenerPos : &g_audioState.vEmitterPos;
  518.         if ( g_moveFlags & FLAG_MOVE_UP )
  519.         {
  520.             vec->z += fElapsedTime * MOTION_SCALE;
  521.             vec->z = min( float(ZMAX), vec->z );
  522.         }
  523.         if ( g_moveFlags & FLAG_MOVE_LEFT )
  524.         {
  525.             vec->x -= fElapsedTime * MOTION_SCALE;
  526.             vec->x = max( float(XMIN), vec->x );
  527.         }
  528.         if ( g_moveFlags & FLAG_MOVE_RIGHT )
  529.         {
  530.             vec->x += fElapsedTime * MOTION_SCALE;
  531.             vec->x = min( float(XMAX), vec->x );
  532.         }
  533.         if ( g_moveFlags & FLAG_MOVE_DOWN )
  534.         {
  535.             vec->z -= fElapsedTime * MOTION_SCALE;
  536.             vec->z = max( float(ZMIN), vec->z );
  537.         }
  538.     }
  539.     UpdateAudio( fElapsedTime );
  540. }
  541. //--------------------------------------------------------------------------------------
  542. // Render the scene using the D3D9 device
  543. //--------------------------------------------------------------------------------------
  544. void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
  545. {
  546.     HRESULT hr;
  547.     
  548.     // If the settings dialog is being shown, then render it instead of rendering the app's scene
  549.     if( g_SettingsDlg.IsActive() )
  550.     {
  551.         g_SettingsDlg.OnRender( fElapsedTime );
  552.         return;
  553.     }
  554.     // Clear the render target and the zbuffer 
  555.     V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
  556.     // Render the scene
  557.     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
  558.     {
  559.         V( g_pEffect9->SetTechnique( "RenderScene" ) ); 
  560.         D3DXMATRIXA16 mScale; 
  561.         D3DXMatrixScaling( &mScale, 1.f / (XMAX - XMIN), 1.f / (ZMAX - ZMIN), 1 );
  562.         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"World" ); // These events are to help PIX identify what the code is doing
  563.         UINT iPass, cPasses;
  564.         V( g_pEffect9->Begin( &cPasses, 0 ) );
  565.         V( pd3dDevice->SetVertexDeclaration( g_pVertexDecl ) );
  566.         for( iPass = 0; iPass < cPasses; ++iPass )
  567.         {
  568.             V( g_pEffect9->BeginPass( iPass ) );
  569.             V( g_pEffect9->SetMatrix( "g_mTransform", &mScale ) );
  570.             V( g_pEffect9->CommitChanges() );
  571.             // Draw the floor
  572.             V( pd3dDevice->SetStreamSource( 0, g_pvbFloor, 0, sizeof(D3DVERTEX) ) );
  573.             V( pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ) );
  574.             // Draw the grid
  575.             V( pd3dDevice->SetStreamSource( 0, g_pvbGrid, 0, sizeof(D3DVERTEX) ) );
  576.             const UINT lcount = ( ( ZMAX - ZMIN + 1) + ( XMAX - XMIN + 1) );
  577.             V( pd3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, lcount ) );
  578.             // Draw the source
  579.             {
  580.                 D3DXMATRIXA16 mTrans;
  581.                 D3DXMatrixTranslation( &mTrans, g_audioState.vEmitterPos.x, g_audioState.vEmitterPos.z, 0 );
  582.                 D3DXMATRIXA16 mat = mTrans * mScale;
  583.                 V( g_pEffect9->SetMatrix( "g_mTransform", &mat ) );
  584.                 V( g_pEffect9->CommitChanges() );
  585.                 pd3dDevice->SetStreamSource( 0, g_pvbSource, 0, sizeof(D3DVERTEX) );
  586.                 pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
  587.             }
  588.             // Draw the listener
  589.             {
  590.                 D3DXMATRIXA16 mTrans;
  591.                 D3DXMatrixTranslation( &mTrans, g_audioState.vListenerPos.x, g_audioState.vListenerPos.z, 0 );
  592.                 D3DXMATRIXA16 mRot;
  593.                 D3DXMatrixRotationZ( &mRot, -g_audioState.fListenerAngle );
  594.                 D3DXMATRIXA16 mat = mRot * mTrans * mScale;
  595.                 V( g_pEffect9->SetMatrix( "g_mTransform", &mat ) );
  596.                 V( g_pEffect9->CommitChanges() );
  597.                 pd3dDevice->SetStreamSource( 0, g_pvbListener, 0, sizeof(D3DVERTEX) );
  598.                 pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 1 );
  599.             }
  600.             V( g_pEffect9->EndPass() );
  601.         }
  602.         V( g_pEffect9->End() );
  603.         DXUT_EndPerfEvent();
  604.         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
  605.         RenderText();
  606.         V( g_HUD.OnRender( fElapsedTime ) );
  607.         V( g_SampleUI.OnRender( fElapsedTime ) );
  608.         DXUT_EndPerfEvent();
  609.         V( pd3dDevice->EndScene() );
  610.     }
  611. }
  612. //--------------------------------------------------------------------------------------
  613. // Handle messages to the application
  614. //--------------------------------------------------------------------------------------
  615. LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
  616. {
  617.     // We use a simple sound focus model of not hearing the sound if the application is full-screen and minimized
  618.     if ( uMsg == WM_ACTIVATEAPP )
  619.     {
  620.         if( wParam == TRUE && !DXUTIsActive() ) // Handle only if previously not active 
  621.         {
  622.             if( !DXUTIsWindowed() )
  623.                 PauseAudio( true );
  624.         }
  625.         else if( wParam == FALSE && DXUTIsActive() ) // Handle only if previously active 
  626.         {
  627.             if( !DXUTIsWindowed() )
  628.                 PauseAudio( false );
  629.         }
  630.     }
  631.     // Pass messages to dialog resource manager calls so GUI state is updated correctly
  632.     *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
  633.     if( *pbNoFurtherProcessing )
  634.         return 0;
  635.     // Pass messages to settings dialog if its active
  636.     if( g_SettingsDlg.IsActive() )
  637.     {
  638.         g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
  639.         return 0;
  640.     }
  641.     // Give the dialogs a chance to handle the message first
  642.     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
  643.     if( *pbNoFurtherProcessing )
  644.         return 0;
  645.     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
  646.     if( *pbNoFurtherProcessing )
  647.         return 0;
  648.     return 0;
  649. }
  650. //--------------------------------------------------------------------------------------
  651. // Handle key presses
  652. //--------------------------------------------------------------------------------------
  653. void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
  654. {
  655.     switch (nChar)
  656.     {
  657.     case 'W':
  658.     case 'w':
  659.         if (bKeyDown)
  660.             g_moveFlags |= FLAG_MOVE_UP;
  661.         else
  662.             g_moveFlags &= ~FLAG_MOVE_UP;
  663.         break;
  664.     case 'A':
  665.     case 'a':
  666.         if (bKeyDown)
  667.             g_moveFlags |= FLAG_MOVE_LEFT;
  668.         else
  669.             g_moveFlags &= ~FLAG_MOVE_LEFT;
  670.         break;
  671.     case 'D':
  672.     case 'd':
  673.         if (bKeyDown)
  674.             g_moveFlags |= FLAG_MOVE_RIGHT;
  675.         else
  676.             g_moveFlags &= ~FLAG_MOVE_RIGHT;
  677.         break;
  678.     case 'S':
  679.     case 's':
  680.         if (bKeyDown)
  681.             g_moveFlags |= FLAG_MOVE_DOWN;
  682.         else
  683.             g_moveFlags &= ~FLAG_MOVE_DOWN;
  684.         break;
  685.     }
  686. }
  687. //--------------------------------------------------------------------------------------
  688. // Handles the GUI events
  689. //--------------------------------------------------------------------------------------
  690. void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
  691. {
  692.     CDXUTComboBox* pComboBox = NULL;
  693.     switch( nControlID )
  694.     {
  695.         case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
  696.         case IDC_TOGGLEREF:        DXUTToggleREF(); break;
  697.         case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
  698.         case IDC_SOUND:
  699.             pComboBox = (CDXUTComboBox*) pControl;  
  700.             PrepareAudio( g_SOUND_NAMES[ PtrToInt(pComboBox->GetSelectedData()) ] );
  701.             break;
  702.         case IDC_CONTROL_MODE:
  703.             pComboBox = (CDXUTComboBox*) pControl;  
  704.             g_eControlMode  = (CONTROL_MODE) (int) PtrToInt(pComboBox->GetSelectedData());
  705.             break;
  706.         case IDC_PRESET:
  707.             pComboBox = (CDXUTComboBox*) pControl;
  708.             SetReverb( (int) PtrToInt(pComboBox->GetSelectedData()) );
  709.             break;
  710.         case IDC_UP:
  711.             {
  712.                 D3DXVECTOR3* vec = (g_eControlMode == CONTROL_LISTENER) ? &g_audioState.vListenerPos : &g_audioState.vEmitterPos;
  713.                 vec->z += 0.5f;
  714.                 vec->z = min( float(ZMAX), vec->z );
  715.             }
  716.             break;
  717.         case IDC_LEFT:
  718.             {
  719.                 D3DXVECTOR3* vec = (g_eControlMode == CONTROL_LISTENER) ? &g_audioState.vListenerPos : &g_audioState.vEmitterPos;
  720.                 vec->x -= 0.5f;
  721.                 vec->x = max( float(XMIN), vec->x );
  722.             }
  723.             break;
  724.         case IDC_RIGHT:
  725.             {
  726.                 D3DXVECTOR3* vec = (g_eControlMode == CONTROL_LISTENER) ? &g_audioState.vListenerPos : &g_audioState.vEmitterPos;
  727.                 vec->x += 0.5f;
  728.                 vec->x = min( float(XMAX), vec->x );
  729.             }
  730.             break;
  731.         case IDC_DOWN:
  732.             {
  733.                 D3DXVECTOR3* vec = (g_eControlMode == CONTROL_LISTENER) ? &g_audioState.vListenerPos : &g_audioState.vEmitterPos;
  734.                 vec->z -= 0.5f;
  735.                 vec->z = max( float(ZMIN), vec->z );
  736.             }
  737.             break;
  738.     }
  739. }
  740. //--------------------------------------------------------------------------------------
  741. // Release D3D9 resources created in the OnD3D9ResetDevice callback 
  742. //--------------------------------------------------------------------------------------
  743. void CALLBACK OnD3D9LostDevice( void* pUserContext )
  744. {
  745.     g_moveFlags = 0;
  746.     g_DialogResourceManager.OnD3D9LostDevice();
  747.     g_SettingsDlg.OnD3D9LostDevice();
  748.     if( g_pFont9 ) g_pFont9->OnLostDevice();
  749.     if( g_pEffect9 ) g_pEffect9->OnLostDevice();
  750.     SAFE_RELEASE( g_pSprite9 );
  751.     SAFE_DELETE( g_pTxtHelper );
  752. }
  753. //--------------------------------------------------------------------------------------
  754. // Release D3D9 resources created in the OnD3D9CreateDevice callback 
  755. //--------------------------------------------------------------------------------------
  756. void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
  757. {
  758.     g_DialogResourceManager.OnD3D9DestroyDevice();
  759.     g_SettingsDlg.OnD3D9DestroyDevice();
  760.     SAFE_RELEASE( g_pEffect9 );
  761.     SAFE_RELEASE( g_pFont9 );
  762.     SAFE_RELEASE( g_pVertexDecl );
  763.     SAFE_RELEASE( g_pvbFloor );
  764.     SAFE_RELEASE( g_pvbSource );
  765.     SAFE_RELEASE( g_pvbListener );
  766.     SAFE_RELEASE( g_pvbGrid );
  767. }