123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- #include "sfx/sfxProvider.h"
- #include "sfx/dsound/sfxDSDevice.h"
- #include "core/util/safeRelease.h"
- #include "console/console.h"
- #include "core/strings/unicode.h"
- #include "core/util/safeDelete.h"
- #include "core/module.h"
- class SFXDSProvider : public SFXProvider
- {
- public:
- SFXDSProvider()
- : SFXProvider( "DirectSound" ) {}
- virtual ~SFXDSProvider();
- void init();
- protected:
- DSoundFNTable mDSound;
- struct DSDeviceInfo : SFXDeviceInfo
- {
- GUID* guid;
- DSCAPS caps;
- };
- static BOOL CALLBACK dsEnumProc(
- LPGUID lpGUID,
- LPCTSTR lpszDesc,
- LPCTSTR lpszDrvName,
- LPVOID lpContext );
- void addDeviceDesc( GUID* guid, const String& name, const String& desc );
- public:
- SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers );
- };
- MODULE_BEGIN( DirectSound )
- MODULE_INIT_BEFORE( SFX )
- MODULE_SHUTDOWN_AFTER( SFX )
-
- SFXDSProvider* mProvider;
-
- MODULE_INIT
- {
- mProvider = new SFXDSProvider;
- }
-
- MODULE_SHUTDOWN
- {
- delete mProvider;
- }
- MODULE_END;
- //------------------------------------------------------------------------------
- // Helper
- bool dsBindFunction( DLibrary *dll, void *&fnAddress, const char *name )
- {
- fnAddress = dll->bind( name );
- if (!fnAddress)
- Con::warnf( "DSound Loader: DLL bind failed for %s", name );
- return fnAddress != 0;
- }
- //------------------------------------------------------------------------------
- SFXDSProvider::~SFXDSProvider()
- {
- }
- void SFXDSProvider::init()
- {
- // Grab the functions we'll want from the dsound DLL.
- mDSound.dllRef = OsLoadLibrary( "dsound.dll" );
- mDSound.isLoaded = true;
- #define DS_FUNCTION(fn_name, fn_return, fn_args) \
- mDSound.isLoaded &= dsBindFunction(mDSound.dllRef, *(void**)&mDSound.fn_name, #fn_name);
- #include "sfx/dsound/dsFunctions.h"
- #undef DS_FUNCTION
- AssertISV( mDSound.isLoaded, "DirectSound failed to load." );
- // All we need to do to init is enumerate the
- // devices... if this fails then don't register
- // the provider as it's broken in some way.
- if ( FAILED( mDSound.DirectSoundEnumerate( dsEnumProc, (VOID*)this ) ) )
- {
- Con::errorf( "SFXDSProvider - Device enumeration failed!" );
- return;
- }
- // Did we get any devices?
- if ( mDeviceInfo.empty() )
- {
- Con::errorf( "SFXDSProvider - No valid devices found!" );
- return;
- }
- // Wow, we made it - register the provider.
- regProvider( this );
- }
- BOOL CALLBACK SFXDSProvider::dsEnumProc(
- LPGUID lpGUID,
- LPCTSTR lpszDesc,
- LPCTSTR lpszDrvName,
- LPVOID lpContext )
- {
- SFXDSProvider* provider = (SFXDSProvider*)lpContext;
- provider->addDeviceDesc( lpGUID, lpszDrvName, lpszDesc );
- return TRUE;
- }
- void SFXDSProvider::addDeviceDesc( GUID* guid, const String& name, const String& desc )
- {
- // Create a dummy device to get the caps.
- IDirectSound8* dsound;
- HRESULT hr = mDSound.DirectSoundCreate8( guid, &dsound, NULL );
- if ( FAILED( hr ) || !dsound )
- return;
- // Init the caps structure and have the device fill it out.
- DSCAPS caps;
- dMemset( &caps, 0, sizeof( caps ) );
- caps.dwSize = sizeof( caps );
- hr = dsound->GetCaps( &caps );
- // Clean up and handle errors.
- SAFE_RELEASE( dsound );
- if ( FAILED( hr ) )
- return;
- // Now, record the desc info into our own internal list.
- DSDeviceInfo* info = new DSDeviceInfo;
- info->name = desc;
- info->driver = name;
- info->hasHardware = caps.dwMaxHw3DAllBuffers > 0;
- info->maxBuffers = caps.dwMaxHw3DAllBuffers;
- info->guid = guid;
- info->caps = caps;
- mDeviceInfo.push_back( info );
- }
- SFXDevice* SFXDSProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers )
- {
- DSDeviceInfo* info = dynamic_cast< DSDeviceInfo* >
- ( _findDeviceInfo( deviceName ) );
- if( !info )
- return NULL;
- SFXDSDevice* device = new SFXDSDevice( this,
- &mDSound,
- info->guid,
- info->name,
- useHardware,
- maxBuffers );
- if( !device->_init() )
- SAFE_DELETE( device );
- return device;
- }
|