mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
The FMOD include files are now assumed to be located outside of the Torque 3D directory structure. See Tools/projectGenerator/modules/fmod.inc for the various methods to tell the Project Generator how to find FMOD. If FMOD is installed in its default location then nothing special is required.
346 lines
9.6 KiB
C++
346 lines
9.6 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#ifndef _SFXFMODDEVICE_H_
|
|
#define _SFXFMODDEVICE_H_
|
|
|
|
#ifndef _SFXDEVICE_H_
|
|
#include "sfx/sfxDevice.h"
|
|
#endif
|
|
#ifndef _SFXFMODVOICE_H_
|
|
#include "sfx/fmod/sfxFMODVoice.h"
|
|
#endif
|
|
#ifndef _SFXFMODBUFFER_H_
|
|
#include "sfx/fmod/sfxFMODBuffer.h"
|
|
#endif
|
|
#ifndef _SFXFMODPLUGIN_H_
|
|
#include "sfx/fmod/sfxFMODPlugin.h"
|
|
#endif
|
|
|
|
#include "core/util/tDictionary.h"
|
|
|
|
|
|
// Disable warning for unused static functions.
|
|
#ifdef TORQUE_COMPILER_VISUALC
|
|
#pragma warning( disable : 4505 )
|
|
#endif
|
|
|
|
#if defined( TORQUE_OS_XENON ) || defined( TORQUE_OS_PS3 )
|
|
#define TORQUE_FMOD_STATIC
|
|
#define TORQUE_FMOD_NO_EVENTS //TEMP
|
|
#endif
|
|
|
|
|
|
#include "fmod.h"
|
|
#include "fmod_errors.h"
|
|
#include "fmod_event.h"
|
|
|
|
#include "platform/platformDlibrary.h"
|
|
#include "platform/threads/mutex.h"
|
|
|
|
|
|
// This doesn't appear to exist in some contexts, so let's just add it.
|
|
#if defined(TORQUE_OS_WIN32) || defined(TORQUE_OS_XENON)
|
|
#ifndef WINAPI
|
|
#define WINAPI __stdcall
|
|
#endif
|
|
#else
|
|
#define WINAPI
|
|
#endif
|
|
|
|
|
|
#define FModAssert(x, msg) \
|
|
{ FMOD_RESULT result = ( x ); \
|
|
AssertISV( result == FMOD_OK, String::ToString( "%s: %s", msg, FMOD_ErrorString( result ) ) ); }
|
|
|
|
#define FMOD_FN_FILE "sfx/fmod/fmodFunctions.h"
|
|
|
|
|
|
// Typedefs
|
|
#define FMOD_FUNCTION(fn_name, fn_args) \
|
|
typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
|
|
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
|
|
typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
|
|
#include FMOD_FN_FILE
|
|
#undef FMOD_FUNCTION
|
|
#undef FMOD_EVENT_FUNCTION
|
|
|
|
|
|
/// FMOD API function table.
|
|
///
|
|
/// FMOD doesn't want to be called concurrently so in order to
|
|
/// not force everything to the main thread (where sound updates
|
|
/// would just stall during loading), we thunk all the API
|
|
/// calls and lock all API entry points to a single mutex.
|
|
struct FModFNTable
|
|
{
|
|
FModFNTable()
|
|
: isLoaded( false ),
|
|
eventIsLoaded( false ),
|
|
dllRef( NULL ),
|
|
eventDllRef( NULL )
|
|
{
|
|
AssertFatal( mutex == NULL,
|
|
"FModFNTable::FModFNTable() - this should be a singleton" );
|
|
mutex = new Mutex;
|
|
}
|
|
~FModFNTable()
|
|
{
|
|
eventDllRef = NULL;
|
|
dllRef = NULL;
|
|
delete mutex;
|
|
}
|
|
|
|
bool isLoaded;
|
|
bool eventIsLoaded;
|
|
DLibraryRef dllRef;
|
|
DLibraryRef eventDllRef;
|
|
static Mutex* mutex;
|
|
|
|
template< typename FN >
|
|
struct Thunk
|
|
{
|
|
FN fn;
|
|
|
|
template< typename A >
|
|
FMOD_RESULT operator()( A a )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B >
|
|
FMOD_RESULT operator()( A a, B b )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C >
|
|
FMOD_RESULT operator()( A a, B b, C c )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C, typename D >
|
|
FMOD_RESULT operator()( A a, B b, C c, D d )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c, d );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C, typename D, typename E >
|
|
FMOD_RESULT operator()( A a, B b, C c, D d, E e )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c, d, e );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C, typename D, typename E, typename F >
|
|
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c, d, e, f );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C, typename D, typename E, typename F, typename G >
|
|
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c, d, e, f, g );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
|
|
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g, H h )
|
|
{
|
|
mutex->lock();
|
|
FMOD_RESULT result = fn( a, b, c, d, e, f, g, h );
|
|
mutex->unlock();
|
|
return result;
|
|
}
|
|
};
|
|
|
|
#define FMOD_FUNCTION(fn_name, fn_args) \
|
|
Thunk< FMODFNPTR##fn_name > fn_name;
|
|
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
|
|
Thunk< FMODFNPTR##fn_name > fn_name;
|
|
#include FMOD_FN_FILE
|
|
#undef FMOD_FUNCTION
|
|
#undef FMOD_EVENT_FUNCTION
|
|
};
|
|
|
|
|
|
inline void TorqueVectorToFMODVector( const Point3F& torque, FMOD_VECTOR& fmod )
|
|
{
|
|
fmod.x = torque.x;
|
|
fmod.y = torque.z;
|
|
fmod.z = torque.y;
|
|
}
|
|
|
|
inline void TorqueTransformToFMODVectors( const MatrixF& transform, FMOD_VECTOR& position, FMOD_VECTOR& forward, FMOD_VECTOR& up )
|
|
{
|
|
Point3F _pos, _fwd, _up;
|
|
|
|
transform.getColumn( 3, &_pos );
|
|
transform.getColumn( 1, &_fwd );
|
|
transform.getColumn( 2, &_up );
|
|
|
|
TorqueVectorToFMODVector( _pos, position );
|
|
TorqueVectorToFMODVector( _fwd, forward );
|
|
TorqueVectorToFMODVector( _up, up );
|
|
}
|
|
|
|
inline int TorquePriorityToFMODPriority( F32 priority )
|
|
{
|
|
// Map [-2,2] to [256,0].
|
|
|
|
F32 n = mClampF( priority, -2.0f, 2.0f ) + 2.0f;
|
|
return ( n * 256.0f / 4.0f );
|
|
}
|
|
|
|
inline String FMODEventPathToTorqueName( const String& path )
|
|
{
|
|
String p = path;
|
|
p.replace( '/', '_' );
|
|
p.replace( '-', '_' );
|
|
p.replace( ' ', '_' );
|
|
p.replace( '(', '_' );
|
|
p.replace( ')', '_' );
|
|
p.replace( '%', '_' );
|
|
p.replace( '$', '_' );
|
|
return p;
|
|
}
|
|
|
|
inline String FMODEventPathToTorqueName( const String& projectName, const String& path )
|
|
{
|
|
return String::ToString( "%s_%s", projectName.c_str(), FMODEventPathToTorqueName( path ).c_str() );
|
|
}
|
|
|
|
extern String FMODResultToString( FMOD_RESULT result );
|
|
|
|
|
|
class SFXProvider;
|
|
class SFXFMODPlugin;
|
|
|
|
|
|
|
|
class SFXFMODDevice : public SFXDevice
|
|
{
|
|
public:
|
|
|
|
typedef SFXDevice Parent;
|
|
friend class SFXFMODProvider; // _init
|
|
friend class SFXFMODEventSource; // smStatNumEventSources
|
|
|
|
explicit SFXFMODDevice();
|
|
|
|
SFXFMODDevice( SFXProvider* provider, FModFNTable *fmodFnTbl, int deviceIdx, String name );
|
|
|
|
virtual ~SFXFMODDevice();
|
|
|
|
protected:
|
|
|
|
FMOD_MODE m3drolloffmode;
|
|
int mDeviceIndex;
|
|
|
|
/// The FMOD SFXSystemPlugin instance.
|
|
SFXFMODPlugin mPlugin;
|
|
|
|
/// @name Console Variables
|
|
/// @{
|
|
|
|
/// Current core FMOD memory usage in bytes.
|
|
static U32 smStatMemUsageCore;
|
|
|
|
/// Current FMOD Event DLL memory usage in bytes.
|
|
static U32 smStatMemUsageEvents;
|
|
|
|
/// Current number of SFXFMODEventSource instances.
|
|
static U32 smStatNumEventSources;
|
|
|
|
///
|
|
static bool smPrefDisableSoftware;
|
|
|
|
///
|
|
static bool smPrefUseSoftwareOcclusion;
|
|
|
|
///
|
|
static bool smPrefUseSoftwareHRTF;
|
|
|
|
///
|
|
static bool smPrefUseSoftwareReverbLowmem;
|
|
|
|
///
|
|
static bool smPrefEnableProfile;
|
|
|
|
///
|
|
static bool smPrefGeometryUseClosest;
|
|
|
|
///
|
|
static const char* smPrefDSoundHRTF;
|
|
|
|
///
|
|
static const char* smPrefPluginPath;
|
|
|
|
/// @}
|
|
|
|
bool _init();
|
|
|
|
static SFXFMODDevice* smInstance;
|
|
|
|
public:
|
|
|
|
static SFXFMODDevice* instance() { return smInstance; }
|
|
|
|
FMOD_MODE get3dRollOffMode() { return m3drolloffmode; }
|
|
|
|
static FMOD_SYSTEM* smSystem;
|
|
static FMOD_EVENTSYSTEM* smEventSystem;
|
|
static FModFNTable* smFunc;
|
|
|
|
// Update memory usage stats for metrics display.
|
|
void updateMemUsageStats();
|
|
|
|
// SFXDevice.
|
|
virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
|
|
virtual SFXBuffer* createBuffer( const String& filename, SFXDescription* description );
|
|
virtual SFXVoice* createVoice( bool is3D, SFXBuffer* buffer );
|
|
virtual void update();
|
|
virtual void setNumListeners( U32 num );
|
|
virtual void setListener( U32 index, const SFXListenerProperties& listener );
|
|
virtual void setDistanceModel( SFXDistanceModel model );
|
|
virtual void setDopplerFactor( F32 factor );
|
|
virtual void setRolloffFactor( F32 factor );
|
|
virtual void setReverb( const SFXReverbProperties& reverb );
|
|
virtual void resetReverb();
|
|
};
|
|
|
|
#endif // _SFXFMODDEVICE_H_
|