sfxDSProvider.cpp
Engine/source/sfx/dsound/sfxDSProvider.cpp
Classes:
class
Public Defines
define
DS_FUNCTION(fn_name, fn_return, fn_args) mDSound.isLoaded &= (mDSound.dllRef, *(**)&mDSound.fn_name, #fn_name);
Public Variables
Public Functions
bool
dsBindFunction(DLibrary * dll, void *& fnAddress, const char * name)
Detailed Description
Public Defines
DS_FUNCTION(fn_name, fn_return, fn_args) mDSound.isLoaded &= (mDSound.dllRef, *(**)&mDSound.fn_name, #fn_name);
Public Variables
MODULE_END
MODULE_INIT
MODULE_SHUTDOWN
SFXDSProvider * mProvider
Public Functions
dsBindFunction(DLibrary * dll, void *& fnAddress, const char * name)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "sfx/sfxProvider.h" 25#include "sfx/dsound/sfxDSDevice.h" 26#include "core/util/safeRelease.h" 27#include "console/console.h" 28#include "core/strings/unicode.h" 29#include "core/util/safeDelete.h" 30#include "core/module.h" 31 32 33class SFXDSProvider : public SFXProvider 34{ 35public: 36 37 SFXDSProvider() 38 : SFXProvider( "DirectSound" ) {} 39 virtual ~SFXDSProvider(); 40 41 void init(); 42 43protected: 44 DSoundFNTable mDSound; 45 46 struct DSDeviceInfo : SFXDeviceInfo 47 { 48 GUID* guid; 49 DSCAPS caps; 50 }; 51 52 static BOOL CALLBACK dsEnumProc( 53 LPGUID lpGUID, 54 LPCTSTR lpszDesc, 55 LPCTSTR lpszDrvName, 56 LPVOID lpContext ); 57 58 void addDeviceDesc( GUID* guid, const String& name, const String& desc ); 59 60public: 61 62 SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ); 63 64}; 65 66MODULE_BEGIN( DirectSound ) 67 68 MODULE_INIT_BEFORE( SFX ) 69 MODULE_SHUTDOWN_AFTER( SFX ) 70 71 SFXDSProvider* mProvider; 72 73 MODULE_INIT 74 { 75 mProvider = new SFXDSProvider; 76 } 77 78 MODULE_SHUTDOWN 79 { 80 delete mProvider; 81 } 82 83MODULE_END; 84 85//------------------------------------------------------------------------------ 86// Helper 87 88bool dsBindFunction( DLibrary *dll, void *&fnAddress, const char *name ) 89{ 90 fnAddress = dll->bind( name ); 91 92 if (!fnAddress) 93 Con::warnf( "DSound Loader: DLL bind failed for %s", name ); 94 95 return fnAddress != 0; 96} 97 98//------------------------------------------------------------------------------ 99 100SFXDSProvider::~SFXDSProvider() 101{ 102} 103 104void SFXDSProvider::init() 105{ 106 // Grab the functions we'll want from the dsound DLL. 107 mDSound.dllRef = OsLoadLibrary( "dsound.dll" ); 108 mDSound.isLoaded = true; 109#define DS_FUNCTION(fn_name, fn_return, fn_args) \ 110 mDSound.isLoaded &= dsBindFunction(mDSound.dllRef, *(void**)&mDSound.fn_name, #fn_name); 111#include "sfx/dsound/dsFunctions.h" 112#undef DS_FUNCTION 113 114 AssertISV( mDSound.isLoaded, "DirectSound failed to load." ); 115 116 // All we need to do to init is enumerate the 117 // devices... if this fails then don't register 118 // the provider as it's broken in some way. 119 if ( FAILED( mDSound.DirectSoundEnumerate( dsEnumProc, (VOID*)this ) ) ) 120 { 121 Con::errorf( "SFXDSProvider - Device enumeration failed!" ); 122 return; 123 } 124 125 // Did we get any devices? 126 if ( mDeviceInfo.empty() ) 127 { 128 Con::errorf( "SFXDSProvider - No valid devices found!" ); 129 return; 130 } 131 132 // Wow, we made it - register the provider. 133 regProvider( this ); 134} 135 136 137BOOL CALLBACK SFXDSProvider::dsEnumProc( 138 LPGUID lpGUID, 139 LPCTSTR lpszDesc, 140 LPCTSTR lpszDrvName, 141 LPVOID lpContext ) 142{ 143 SFXDSProvider* provider = (SFXDSProvider*)lpContext; 144 provider->addDeviceDesc( lpGUID, lpszDrvName, lpszDesc ); 145 return TRUE; 146} 147 148void SFXDSProvider::addDeviceDesc( GUID* guid, const String& name, const String& desc ) 149{ 150 // Create a dummy device to get the caps. 151 IDirectSound8* dsound; 152 HRESULT hr = mDSound.DirectSoundCreate8( guid, &dsound, NULL ); 153 if ( FAILED( hr ) || !dsound ) 154 return; 155 156 // Init the caps structure and have the device fill it out. 157 DSCAPS caps; 158 dMemset( &caps, 0, sizeof( caps ) ); 159 caps.dwSize = sizeof( caps ); 160 hr = dsound->GetCaps( &caps ); 161 162 // Clean up and handle errors. 163 SAFE_RELEASE( dsound ); 164 165 if ( FAILED( hr ) ) 166 return; 167 168 // Now, record the desc info into our own internal list. 169 DSDeviceInfo* info = new DSDeviceInfo; 170 info->name = desc; 171 info->driver = name; 172 info->hasHardware = caps.dwMaxHw3DAllBuffers > 0; 173 info->maxBuffers = caps.dwMaxHw3DAllBuffers; 174 info->guid = guid; 175 info->caps = caps; 176 177 mDeviceInfo.push_back( info ); 178} 179 180SFXDevice* SFXDSProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) 181{ 182 DSDeviceInfo* info = dynamic_cast< DSDeviceInfo* > 183 ( _findDeviceInfo( deviceName ) ); 184 185 if( !info ) 186 return NULL; 187 188 SFXDSDevice* device = new SFXDSDevice( this, 189 &mDSound, 190 info->guid, 191 info->name, 192 useHardware, 193 maxBuffers ); 194 195 if( !device->_init() ) 196 SAFE_DELETE( device ); 197 198 return device; 199} 200