mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
remove FMODex from Torque3D
The current version of FMod in Torque3D uses the legacy ex plugin, which hasn't been around for a long time.
This commit is contained in:
parent
772c0ae25b
commit
41bd5ef6b6
|
|
@ -1,115 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FMOD_ERROR( FMOD_OK )
|
||||
FMOD_ERROR( FMOD_ERR_ALREADYLOCKED )
|
||||
FMOD_ERROR( FMOD_ERR_BADCOMMAND )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_DRIVERS )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_INIT )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_INVALID_DEVICE )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_NOAUDIO )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_NODEVICES )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_NODISC )
|
||||
FMOD_ERROR( FMOD_ERR_CDDA_READ )
|
||||
FMOD_ERROR( FMOD_ERR_CHANNEL_ALLOC )
|
||||
FMOD_ERROR( FMOD_ERR_CHANNEL_STOLEN )
|
||||
FMOD_ERROR( FMOD_ERR_COM )
|
||||
FMOD_ERROR( FMOD_ERR_DMA )
|
||||
FMOD_ERROR( FMOD_ERR_DSP_CONNECTION )
|
||||
FMOD_ERROR( FMOD_ERR_DSP_FORMAT )
|
||||
FMOD_ERROR( FMOD_ERR_DSP_NOTFOUND )
|
||||
FMOD_ERROR( FMOD_ERR_DSP_RUNNING )
|
||||
FMOD_ERROR( FMOD_ERR_DSP_TOOMANYCONNECTIONS )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_BAD )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_COULDNOTSEEK )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_DISKEJECTED )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_EOF )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_NOTFOUND )
|
||||
FMOD_ERROR( FMOD_ERR_FILE_UNWANTED )
|
||||
FMOD_ERROR( FMOD_ERR_FORMAT )
|
||||
FMOD_ERROR( FMOD_ERR_HTTP )
|
||||
FMOD_ERROR( FMOD_ERR_HTTP_ACCESS )
|
||||
FMOD_ERROR( FMOD_ERR_HTTP_PROXY_AUTH )
|
||||
FMOD_ERROR( FMOD_ERR_HTTP_SERVER_ERROR )
|
||||
FMOD_ERROR( FMOD_ERR_HTTP_TIMEOUT )
|
||||
FMOD_ERROR( FMOD_ERR_INITIALIZATION )
|
||||
FMOD_ERROR( FMOD_ERR_INITIALIZED )
|
||||
FMOD_ERROR( FMOD_ERR_INTERNAL )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_ADDRESS )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_FLOAT )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_HANDLE )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_PARAM )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_POSITION )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_SPEAKER )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_SYNCPOINT )
|
||||
FMOD_ERROR( FMOD_ERR_INVALID_VECTOR )
|
||||
FMOD_ERROR( FMOD_ERR_MAXAUDIBLE )
|
||||
FMOD_ERROR( FMOD_ERR_MEMORY )
|
||||
FMOD_ERROR( FMOD_ERR_MEMORY_CANTPOINT )
|
||||
FMOD_ERROR( FMOD_ERR_MEMORY_SRAM )
|
||||
FMOD_ERROR( FMOD_ERR_NEEDS2D )
|
||||
FMOD_ERROR( FMOD_ERR_NEEDS3D )
|
||||
FMOD_ERROR( FMOD_ERR_NEEDSHARDWARE )
|
||||
FMOD_ERROR( FMOD_ERR_NEEDSSOFTWARE )
|
||||
FMOD_ERROR( FMOD_ERR_NET_CONNECT )
|
||||
FMOD_ERROR( FMOD_ERR_NET_SOCKET_ERROR )
|
||||
FMOD_ERROR( FMOD_ERR_NET_URL )
|
||||
FMOD_ERROR( FMOD_ERR_NET_WOULD_BLOCK )
|
||||
FMOD_ERROR( FMOD_ERR_NOTREADY )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_ALLOCATED )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_CREATEBUFFER )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_DRIVERCALL )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_ENUMERATION )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_FORMAT )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_INIT )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_NOHARDWARE )
|
||||
FMOD_ERROR( FMOD_ERR_OUTPUT_NOSOFTWARE )
|
||||
FMOD_ERROR( FMOD_ERR_PAN )
|
||||
FMOD_ERROR( FMOD_ERR_PLUGIN )
|
||||
FMOD_ERROR( FMOD_ERR_PLUGIN_INSTANCES )
|
||||
FMOD_ERROR( FMOD_ERR_PLUGIN_MISSING )
|
||||
FMOD_ERROR( FMOD_ERR_PLUGIN_RESOURCE )
|
||||
FMOD_ERROR( FMOD_ERR_RECORD )
|
||||
FMOD_ERROR( FMOD_ERR_REVERB_INSTANCE )
|
||||
FMOD_ERROR( FMOD_ERR_SUBSOUND_ALLOCATED )
|
||||
FMOD_ERROR( FMOD_ERR_SUBSOUND_CANTMOVE )
|
||||
FMOD_ERROR( FMOD_ERR_SUBSOUND_MODE )
|
||||
FMOD_ERROR( FMOD_ERR_SUBSOUNDS )
|
||||
FMOD_ERROR( FMOD_ERR_TAGNOTFOUND )
|
||||
FMOD_ERROR( FMOD_ERR_TOOMANYCHANNELS )
|
||||
FMOD_ERROR( FMOD_ERR_UNIMPLEMENTED )
|
||||
FMOD_ERROR( FMOD_ERR_UNINITIALIZED )
|
||||
FMOD_ERROR( FMOD_ERR_UNSUPPORTED )
|
||||
FMOD_ERROR( FMOD_ERR_UPDATE )
|
||||
FMOD_ERROR( FMOD_ERR_VERSION )
|
||||
FMOD_ERROR( FMOD_ERR_PRELOADED )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_FAILED )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_INFOONLY )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_INTERNAL )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_MAXSTREAMS )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_MISMATCH )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_NAMECONFLICT )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_NOTFOUND )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_NEEDSSIMPLE )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_GUIDCONFLICT )
|
||||
FMOD_ERROR( FMOD_ERR_EVENT_ALREADY_LOADED )
|
||||
FMOD_ERROR( FMOD_ERR_MUSIC_UNINITIALIZED )
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Xcode has problems properly detecting the dependencies for this file.
|
||||
// If you change something here, manually recompile all the FMOD modules.
|
||||
|
||||
|
||||
// FMOD Ex API:
|
||||
|
||||
FMOD_FUNCTION( FMOD_Channel_GetPaused, (FMOD_CHANNEL *channel, FMOD_BOOL *paused))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetPaused, (FMOD_CHANNEL *channel, FMOD_BOOL paused));
|
||||
FMOD_FUNCTION( FMOD_Channel_IsPlaying, (FMOD_CHANNEL *channel, FMOD_BOOL *isplaying))
|
||||
FMOD_FUNCTION( FMOD_Channel_Set3DAttributes, (FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetFrequency, (FMOD_CHANNEL *channel, float frequency))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetLoopCount, (FMOD_CHANNEL *channel, int loopcount))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetPosition, (FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype))
|
||||
FMOD_FUNCTION( FMOD_Channel_GetPosition, (FMOD_CHANNEL* channel, unsigned int* position, FMOD_TIMEUNIT postype))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetVolume, (FMOD_CHANNEL *channel, float volume))
|
||||
FMOD_FUNCTION( FMOD_Channel_GetVolume, (FMOD_CHANNEL *channel, float *volume))
|
||||
FMOD_FUNCTION( FMOD_Channel_Stop, (FMOD_CHANNEL *channel))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetMode, (FMOD_CHANNEL *channel, FMOD_MODE mode))
|
||||
FMOD_FUNCTION( FMOD_Channel_Set3DMinMaxDistance, (FMOD_CHANNEL *channel, float mindistance, float maxdistance));
|
||||
FMOD_FUNCTION( FMOD_Channel_Set3DConeSettings, (FMOD_CHANNEL *channel, float insideconeangle, float outsideconeangle, float outsidevolume))
|
||||
FMOD_FUNCTION( FMOD_Channel_Set3DConeOrientation, (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation))
|
||||
FMOD_FUNCTION( FMOD_Channel_SetReverbProperties, ( FMOD_CHANNEL* channel, const FMOD_REVERB_CHANNELPROPERTIES* prop ) )
|
||||
FMOD_FUNCTION( FMOD_Channel_SetPriority, ( FMOD_CHANNEL* channel, int priority ) )
|
||||
FMOD_FUNCTION( FMOD_Channel_IsVirtual, ( FMOD_CHANNEL* channel, FMOD_BOOL* isvirtual ) )
|
||||
FMOD_FUNCTION( FMOD_Channel_AddDSP, ( FMOD_CHANNEL* channel, FMOD_DSP* dsp, FMOD_DSPCONNECTION** connection ) )
|
||||
|
||||
FMOD_FUNCTION( FMOD_Sound_Lock, (FMOD_SOUND *sound, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2))
|
||||
FMOD_FUNCTION( FMOD_Sound_Unlock, (FMOD_SOUND *sound, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2))
|
||||
FMOD_FUNCTION( FMOD_Sound_Release, (FMOD_SOUND *sound))
|
||||
FMOD_FUNCTION( FMOD_Sound_Set3DMinMaxDistance, (FMOD_SOUND *sound, float min, float max))
|
||||
FMOD_FUNCTION( FMOD_Sound_SetMode, (FMOD_SOUND *sound, FMOD_MODE mode))
|
||||
FMOD_FUNCTION( FMOD_Sound_GetMode, (FMOD_SOUND *sound, FMOD_MODE *mode))
|
||||
FMOD_FUNCTION( FMOD_Sound_SetLoopCount, (FMOD_SOUND *sound, int loopcount))
|
||||
FMOD_FUNCTION( FMOD_Sound_GetFormat, ( FMOD_SOUND* sound, FMOD_SOUND_TYPE* type, FMOD_SOUND_FORMAT* format, int* channels, int* bits ) )
|
||||
FMOD_FUNCTION( FMOD_Sound_GetLength, ( FMOD_SOUND* sound, unsigned int* length, FMOD_TIMEUNIT lengthtype ) )
|
||||
FMOD_FUNCTION( FMOD_Sound_GetDefaults, ( FMOD_SOUND* sound, float* frequency, float* volume, float* pan, int* priority ) )
|
||||
FMOD_FUNCTION( FMOD_Sound_GetMemoryInfo, ( FMOD_SOUND* sound, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) );
|
||||
|
||||
FMOD_FUNCTION( FMOD_Geometry_AddPolygon, ( FMOD_GEOMETRY* geometry, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided, int numvertices, const FMOD_VECTOR* vertices, int* polygonindex ) )
|
||||
FMOD_FUNCTION( FMOD_Geometry_SetPosition, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* position ) )
|
||||
FMOD_FUNCTION( FMOD_Geometry_SetRotation, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* forward, const FMOD_VECTOR* up ) )
|
||||
FMOD_FUNCTION( FMOD_Geometry_SetScale, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* scale ) )
|
||||
FMOD_FUNCTION( FMOD_Geometry_Release, ( FMOD_GEOMETRY* geometry ) )
|
||||
|
||||
FMOD_FUNCTION( FMOD_DSP_GetInfo, ( FMOD_DSP* dsp, char* name, unsigned int* version, int* channels, int* configwidth, int* configheight ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_Release, ( FMOD_DSP* dsp ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_GetParameterInfo, ( FMOD_DSP* dsp, int index, char* name, char* label, char* description, int descriptionlen, float* min, float* max ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_GetNumParameters, ( FMOD_DSP* dsp, int* numparams ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_GetParameter, ( FMOD_DSP* dsp, int index, float* value, char* valuestr, int valuestrlen ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_SetParameter, ( FMOD_DSP* dsp, int index, float value ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_GetNumInputs, ( FMOD_DSP* dsp, int* numinputs ) )
|
||||
FMOD_FUNCTION( FMOD_DSP_GetNumOutputs, ( FMOD_DSP* dsp, int* numoutputs ) )
|
||||
|
||||
FMOD_FUNCTION( FMOD_System_Close, (FMOD_SYSTEM *system))
|
||||
FMOD_FUNCTION( FMOD_System_Create, (FMOD_SYSTEM **system))
|
||||
FMOD_FUNCTION( FMOD_System_Release, (FMOD_SYSTEM *system))
|
||||
FMOD_FUNCTION( FMOD_System_CreateSound, (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound))
|
||||
FMOD_FUNCTION( FMOD_System_CreateGeometry, ( FMOD_SYSTEM* system, int maxpolygons, int maxvertices, FMOD_GEOMETRY** geometry ) )
|
||||
FMOD_FUNCTION( FMOD_System_SetDriver, (FMOD_SYSTEM *system, int driver))
|
||||
FMOD_FUNCTION( FMOD_System_GetDriverCaps, (FMOD_SYSTEM *system, int id, FMOD_CAPS *caps, int *controlpaneloutputrate, FMOD_SPEAKERMODE *controlpanelspeakermode))
|
||||
FMOD_FUNCTION( FMOD_System_GetDriverInfo, (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *GUID))
|
||||
FMOD_FUNCTION( FMOD_System_GetNumDrivers, (FMOD_SYSTEM *system, int *numdrivers))
|
||||
FMOD_FUNCTION( FMOD_System_GetVersion, (FMOD_SYSTEM *system, unsigned int *version))
|
||||
FMOD_FUNCTION( FMOD_System_Init, (FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata))
|
||||
FMOD_FUNCTION( FMOD_System_PlaySound, (FMOD_SYSTEM *system, FMOD_CHANNELINDEX channelid, FMOD_SOUND *sound, FMOD_BOOL paused, FMOD_CHANNEL **channel))
|
||||
FMOD_FUNCTION( FMOD_System_Set3DListenerAttributes, (FMOD_SYSTEM *system, int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up))
|
||||
FMOD_FUNCTION( FMOD_System_Set3DNumListeners, ( FMOD_SYSTEM* system, int numlisteners ) )
|
||||
FMOD_FUNCTION( FMOD_System_SetGeometrySettings, ( FMOD_SYSTEM* system, float maxworldsize ) )
|
||||
FMOD_FUNCTION( FMOD_System_Get3DSettings, (FMOD_SYSTEM* system, float* dopplerFactor, float* distanceFactor, float* rolloffFactor))
|
||||
FMOD_FUNCTION( FMOD_System_Set3DSettings, (FMOD_SYSTEM *system, float dopplerscale, float distancefactor, float rolloffscale))
|
||||
FMOD_FUNCTION( FMOD_System_SetDSPBufferSize, (FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers))
|
||||
FMOD_FUNCTION( FMOD_System_SetSpeakerMode, (FMOD_SYSTEM *system, FMOD_SPEAKERMODE speakermode))
|
||||
FMOD_FUNCTION( FMOD_System_SetReverbProperties, ( FMOD_SYSTEM* system, const FMOD_REVERB_PROPERTIES* prop ) )
|
||||
FMOD_FUNCTION( FMOD_System_SetReverbAmbientProperties, ( FMOD_SYSTEM* system, FMOD_REVERB_PROPERTIES* prop ) )
|
||||
FMOD_FUNCTION( FMOD_System_Update, ( FMOD_SYSTEM *system ) )
|
||||
FMOD_FUNCTION( FMOD_System_CreateDSPByType, ( FMOD_SYSTEM* system, FMOD_DSP_TYPE type, FMOD_DSP** dsp ) )
|
||||
FMOD_FUNCTION( FMOD_System_AddDSP, ( FMOD_SYSTEM* system, FMOD_DSP* dsp, FMOD_DSPCONNECTION** connection ) )
|
||||
FMOD_FUNCTION( FMOD_System_GetMemoryInfo, ( FMOD_SYSTEM* system, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) )
|
||||
FMOD_FUNCTION( FMOD_System_SetFileSystem, ( FMOD_SYSTEM* system, FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek, int blockalign ) )
|
||||
FMOD_FUNCTION( FMOD_System_SetPluginPath, ( FMOD_SYSTEM* system, const char* path ) )
|
||||
FMOD_FUNCTION( FMOD_System_GetHardwareChannels, ( FMOD_SYSTEM* system, int* num2d, int* num3d, int* total ) )
|
||||
|
||||
FMOD_FUNCTION( FMOD_Memory_GetStats, ( int*, int* ) )
|
||||
FMOD_FUNCTION( FMOD_Memory_Initialize, ( void *poolmem, int poollen, FMOD_MEMORY_ALLOCCALLBACK useralloc, FMOD_MEMORY_REALLOCCALLBACK userrealloc, FMOD_MEMORY_FREECALLBACK userfree ) )
|
||||
|
||||
// FMOD Designer API:
|
||||
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Create, ( FMOD_EVENTSYSTEM** eventsystem ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetSystemObject, ( FMOD_EVENTSYSTEM* eventsystem, FMOD_SYSTEM** system ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetVersion, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int* version ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Init, ( FMOD_EVENTSYSTEM* eventsystem, int maxchannels, FMOD_INITFLAGS flags, void* extradriverdata, FMOD_EVENT_INITFLAGS eventflags ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Release, ( FMOD_EVENTSYSTEM* eventsystem ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Load, ( FMOD_EVENTSYSTEM* eventsystem, const char* name_or_data, FMOD_EVENT_LOADINFO* loadinfo, FMOD_EVENTPROJECT** project ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Update, ( FMOD_EVENTSYSTEM* eventsystem ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetMemoryInfo, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventSystem_SetMediaPath, ( FMOD_EVENTSYSTEM* eventsystem, const char* path ) )
|
||||
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_Release, ( FMOD_EVENTPROJECT* eventproject ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetInfo, ( FMOD_EVENTPROJECT* eventproject, FMOD_EVENT_PROJECTINFO* info ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumEvents, ( FMOD_EVENTPROJECT* eventproject, int* numevents ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumGroups, ( FMOD_EVENTPROJECT* eventproject, int* numgroups ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroupByIndex, ( FMOD_EVENTPROJECT* eventproject, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroup, ( FMOD_EVENTPROJECT* eventproject, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
|
||||
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetInfo, ( FMOD_EVENTGROUP* eventgroup, int* index, char** name ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_LoadEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT_RESOURCE resource, FMOD_EVENT_MODE mode ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_FreeEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT* event, FMOD_BOOL waituntilready ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumEvents, ( FMOD_EVENTGROUP* eventgroup, int* numevents ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumGroups, ( FMOD_EVENTGROUP* eventgroup, int* numgroups ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEventByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEvent, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroupByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroup, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
|
||||
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetInfo, ( FMOD_EVENT* event, int* index, char** name, FMOD_EVENT_INFO* info ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_Release, ( FMOD_EVENT* event, FMOD_BOOL freeeventdata, FMOD_BOOL waituntilready ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_Start, ( FMOD_EVENT* event ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_Stop, ( FMOD_EVENT* event, FMOD_BOOL immediate ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_SetPaused, ( FMOD_EVENT* event, FMOD_BOOL paused ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_SetVolume, ( FMOD_EVENT* event, float volume ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_SetPitch, ( FMOD_EVENT* event, float pitch, FMOD_EVENT_PITCHUNITS units ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_Set3DAttributes, ( FMOD_EVENT* event, const FMOD_VECTOR* position, const FMOD_VECTOR* velocity, const FMOD_VECTOR* orientation ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetState, ( FMOD_EVENT* event, FMOD_EVENT_STATE* state ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetNumParameters, ( FMOD_EVENT* event, int* numparameters ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetParameter, ( FMOD_EVENT* event, const char* name, FMOD_EVENTPARAMETER** parameter ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetParameterByIndex, ( FMOD_EVENT* event, int index, FMOD_EVENTPARAMETER** parameter ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_SetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetProperty, ( FMOD_EVENT* event, const char* propertyname, void* value, FMOD_BOOL this_instance ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyInfo, ( FMOD_EVENT* event, int* propertyindex, char** propertyname, FMOD_EVENTPROPERTY_TYPE* type ) )
|
||||
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetInfo, ( FMOD_EVENTPARAMETER* eventparameter, int* index, char** name ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetValue, ( FMOD_EVENTPARAMETER* eventparameter, float* value ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventParameter_SetValue, ( FMOD_EVENTPARAMETER* eventparameter, float value ) )
|
||||
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetRange, ( FMOD_EVENTPARAMETER* eventparameter, float* rangemin, float* rangemax ) )
|
||||
|
|
@ -1,322 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/fmod/sfxFMODBuffer.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "core/volume.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char* sExtensions[] =
|
||||
{
|
||||
"", // First try without doing anything with the given path.
|
||||
"", // Then try it without an extension but by expanding it through Torque::FS.
|
||||
"aiff",
|
||||
"asf",
|
||||
"asx",
|
||||
"dls",
|
||||
"flac",
|
||||
"fsb",
|
||||
"it",
|
||||
"m3u",
|
||||
"mid",
|
||||
"mod",
|
||||
"mp2",
|
||||
"mp3",
|
||||
"ogg",
|
||||
"pls",
|
||||
"s3m",
|
||||
"vag",
|
||||
"wav",
|
||||
"wax",
|
||||
"wma",
|
||||
"xm",
|
||||
|
||||
#ifdef TORQUE_OS_XENON
|
||||
".xma",
|
||||
#endif
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODBuffer* SFXFMODBuffer::create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
|
||||
{
|
||||
SFXFMODBuffer *buffer = new SFXFMODBuffer( stream, description );
|
||||
if( !buffer->mSound )
|
||||
SAFE_DELETE( buffer );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODBuffer* SFXFMODBuffer::create( const String& filename, SFXDescription* description )
|
||||
{
|
||||
if( Con::getBoolVariable( "$pref::SFX::FMOD::noCustomFileLoading", false ) )
|
||||
return NULL;
|
||||
|
||||
SFXFMODBuffer *buffer = new SFXFMODBuffer( filename, description );
|
||||
if( !buffer->mSound )
|
||||
SAFE_DELETE( buffer );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODBuffer::SFXFMODBuffer( const String& filename, SFXDescription* description )
|
||||
: Parent( description ),
|
||||
mSound( NULL )
|
||||
{
|
||||
FMOD_MODE fMode = ( description->mUseHardware ? FMOD_HARDWARE : FMOD_SOFTWARE )
|
||||
| ( description->mIs3D ? FMOD_3D : FMOD_2D );
|
||||
|
||||
if( description->mIsStreaming )
|
||||
{
|
||||
fMode |= FMOD_CREATESTREAM;
|
||||
mIsUnique = true;
|
||||
}
|
||||
|
||||
// Go through the extensions and try each with the given path. The
|
||||
// first two are special. First we try without touching the filename at all
|
||||
// so FMOD gets a chance to handle URLs and whatever, and then second we
|
||||
// try by expanding the path but without adding an extension.
|
||||
|
||||
Torque::Path path = filename;
|
||||
for( U32 i = 0; sExtensions[ i ]; ++ i )
|
||||
{
|
||||
path.setExtension( sExtensions[ i ] );
|
||||
|
||||
if( !i || Torque::FS::IsFile( path ) )
|
||||
{
|
||||
// Translate to full path.
|
||||
//TODO: Remove this when hooking up the file system functions in sfxFMODDevice.cpp
|
||||
|
||||
String fullPath;
|
||||
if( !i )
|
||||
fullPath = filename;
|
||||
else
|
||||
{
|
||||
Torque::Path realPath;
|
||||
if( !Torque::FS::GetFSPath( path, realPath ) )
|
||||
continue;
|
||||
|
||||
fullPath = realPath.getFullPath().c_str();
|
||||
}
|
||||
|
||||
mSound = NULL;
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_System_CreateSound(
|
||||
SFXFMODDevice::smSystem,
|
||||
fullPath.c_str(),
|
||||
fMode,
|
||||
( FMOD_CREATESOUNDEXINFO* ) NULL,
|
||||
&mSound );
|
||||
|
||||
if( result == FMOD_OK )
|
||||
{
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetMode( mSound, &mMode );
|
||||
|
||||
// Read out format.
|
||||
|
||||
int numChannels;
|
||||
int bitsPerSample;
|
||||
unsigned int length;
|
||||
float frequency;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetFormat( mSound, ( FMOD_SOUND_TYPE* ) NULL, ( FMOD_SOUND_FORMAT* ) NULL, &numChannels, &bitsPerSample );
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetLength( mSound, &length, FMOD_TIMEUNIT_MS );
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetDefaults( mSound, &frequency, ( float* ) NULL, ( float* ) NULL, ( int* ) NULL );
|
||||
|
||||
mDuration = length;
|
||||
mFormat = SFXFormat( numChannels, numChannels * bitsPerSample, frequency );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( !mSound )
|
||||
Con::errorf( "SFXFMODBuffer::SFXFMODBuffer - failed to load '%s' through FMOD", filename.c_str() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODBuffer::SFXFMODBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
|
||||
: Parent( stream, description ),
|
||||
mSound( NULL )
|
||||
{
|
||||
FMOD_MODE fMode = ( description->mUseHardware ? FMOD_HARDWARE : FMOD_SOFTWARE )
|
||||
| ( description->mIs3D ? FMOD_3D : FMOD_2D );
|
||||
|
||||
FMOD_CREATESOUNDEXINFO* pCreatesoundexinfo = NULL;
|
||||
FMOD_CREATESOUNDEXINFO createsoundexinfo;
|
||||
|
||||
fMode |= FMOD_OPENUSER; // this tells fmod we are supplying the data directly
|
||||
if( isStreaming() )
|
||||
fMode |= FMOD_LOOP_NORMAL | FMOD_UNIQUE;
|
||||
|
||||
const SFXFormat& format = getFormat();
|
||||
U32 channels = format.getChannels();
|
||||
U32 frequency = format.getSamplesPerSecond();
|
||||
U32 bitsPerChannel = format.getBitsPerSample() / channels;
|
||||
U32 dataSize = mBufferSize;
|
||||
|
||||
FMOD_SOUND_FORMAT sfxFmt = FMOD_SOUND_FORMAT_NONE;
|
||||
switch(bitsPerChannel)
|
||||
{
|
||||
case 8:
|
||||
sfxFmt = FMOD_SOUND_FORMAT_PCM8;
|
||||
break;
|
||||
case 16:
|
||||
sfxFmt = FMOD_SOUND_FORMAT_PCM16;
|
||||
break;
|
||||
case 24:
|
||||
sfxFmt = FMOD_SOUND_FORMAT_PCM24;
|
||||
break;
|
||||
case 32:
|
||||
sfxFmt = FMOD_SOUND_FORMAT_PCM32;
|
||||
break;
|
||||
default:
|
||||
AssertISV(false, "SFXFMODBuffer::SFXFMODBuffer() - unsupported bits-per-sample (what format is it in, 15bit PCM?)");
|
||||
break;
|
||||
}
|
||||
|
||||
dMemset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
|
||||
createsoundexinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); /* required. */
|
||||
createsoundexinfo.decodebuffersize = frequency; /* Chunk size of stream update in samples. This will be the amount of data passed to the user callback. */
|
||||
createsoundexinfo.length = dataSize; /* Length of PCM data in bytes of whole sound (for Sound::getLength) */
|
||||
createsoundexinfo.numchannels = channels; /* Number of channels in the sound. */
|
||||
createsoundexinfo.defaultfrequency = frequency; /* Default playback rate of sound. */
|
||||
createsoundexinfo.format = sfxFmt; /* Data format of sound. */
|
||||
createsoundexinfo.pcmreadcallback = NULL; /* User callback for reading. */
|
||||
createsoundexinfo.pcmsetposcallback = NULL; /* User callback for seeking. */
|
||||
pCreatesoundexinfo = &createsoundexinfo;
|
||||
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_System_CreateSound(
|
||||
SFXFMODDevice::smSystem,
|
||||
( const char* ) NULL,
|
||||
fMode,
|
||||
pCreatesoundexinfo,
|
||||
&mSound );
|
||||
|
||||
if( result != FMOD_OK )
|
||||
{
|
||||
mSound = NULL;
|
||||
Con::errorf( "SFXFMODBuffer::SFXFMODBuffer - failed to create buffer (%i)", result );
|
||||
}
|
||||
else
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetMode( mSound, &mMode );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODBuffer::~SFXFMODBuffer()
|
||||
{
|
||||
if( mSound )
|
||||
FModAssert( SFXFMODDevice::smFunc->FMOD_Sound_Release( mSound ),
|
||||
"SFXFMODBuffer::~SFXFMODBuffer - Failed to release a sound!" );
|
||||
|
||||
mSound = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODBuffer::_flush()
|
||||
{
|
||||
AssertFatal( isStreaming(), "SFXFMODBuffer::_flush() - not a streaming buffer" );
|
||||
AssertFatal( SFXInternal::isSFXThread(), "SFXFMODBuffer::_flush() - not on SFX thread" );
|
||||
|
||||
Parent::_flush();
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPosition
|
||||
( ( ( SFXFMODVoice* ) mUniqueVoice.getPointer() )->mChannel, 0, FMOD_TIMEUNIT_PCM );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODBuffer::_copyData( U32 offset, const U8* data, U32 length )
|
||||
{
|
||||
AssertFatal( data != NULL && length > 0, "Must have data!" );
|
||||
|
||||
// Fill the buffer with the resource data.
|
||||
void* lpvWrite;
|
||||
U32 dwLength;
|
||||
void* lpvWrite2;
|
||||
U32 dwLength2;
|
||||
int res = SFXFMODDevice::smFunc->FMOD_Sound_Lock(
|
||||
mSound,
|
||||
offset, // Offset at which to start lock.
|
||||
length, // Size of lock.
|
||||
&lpvWrite, // Gets address of first part of lock.
|
||||
&lpvWrite2, // Address of wraparound not needed.
|
||||
&dwLength, // Gets size of first part of lock.
|
||||
&dwLength2 // Size of wraparound not needed.
|
||||
);
|
||||
|
||||
if ( res != FMOD_OK )
|
||||
{
|
||||
// You can remove this if it gets spammy. However since we can
|
||||
// safely fail in this case it doesn't seem right to assert...
|
||||
// at the same time it can be very annoying not to know why
|
||||
// an upload fails!
|
||||
Con::errorf("SFXFMODBuffer::_copyData - failed to lock a sound buffer! (%d)", this);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the first part.
|
||||
dMemcpy( lpvWrite, data, dwLength );
|
||||
|
||||
// Do we have a wrap?
|
||||
if ( lpvWrite2 )
|
||||
dMemcpy( lpvWrite2, data + dwLength, dwLength2 );
|
||||
|
||||
// And finally, unlock.
|
||||
FModAssert( SFXFMODDevice::smFunc->FMOD_Sound_Unlock(
|
||||
mSound,
|
||||
lpvWrite, // Address of lock start.
|
||||
lpvWrite2, // No wraparound portion.
|
||||
dwLength, // Size of lock.
|
||||
dwLength2 ), // No wraparound size.
|
||||
"Failed to unlock sound buffer!" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
U32 SFXFMODBuffer::getMemoryUsed() const
|
||||
{
|
||||
unsigned int memoryUsed;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Sound_GetMemoryInfo(
|
||||
mSound,
|
||||
FMOD_MEMBITS_ALL,
|
||||
FMOD_EVENT_MEMBITS_ALL,
|
||||
&memoryUsed,
|
||||
( unsigned int* ) NULL );
|
||||
|
||||
return memoryUsed;
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODBUFFER_H_
|
||||
#define _SFXFMODBUFFER_H_
|
||||
|
||||
#include "fmod.h"
|
||||
|
||||
#ifndef _SFXINTERNAL_H_
|
||||
# include "sfx/sfxInternal.h"
|
||||
#endif
|
||||
|
||||
|
||||
class SFXFMODBuffer : public SFXInternal::SFXWrapAroundBuffer
|
||||
{
|
||||
typedef SFXInternal::SFXWrapAroundBuffer Parent;
|
||||
|
||||
friend class SFXFMODDevice;
|
||||
friend class SFXFMODVoice;
|
||||
|
||||
protected:
|
||||
|
||||
FMOD_SOUND *mSound;
|
||||
FMOD_MODE mMode;
|
||||
|
||||
SFXFMODBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
|
||||
SFXFMODBuffer( const String& filename, SFXDescription* description );
|
||||
|
||||
// SFXWrapAroundBuffer.
|
||||
virtual bool _copyData( U32 offset, const U8* data, U32 length );
|
||||
virtual void _flush();
|
||||
|
||||
virtual ~SFXFMODBuffer();
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
static SFXFMODBuffer* create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
|
||||
static SFXFMODBuffer* create( const String& filename, SFXDescription* description );
|
||||
|
||||
virtual U32 getMemoryUsed() const;
|
||||
};
|
||||
|
||||
#endif // _SFXFMODBUFFER_H_
|
||||
|
|
@ -1,578 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "platform/platform.h"
|
||||
#include "platform/threads/mutex.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/fmod/sfxFMODBuffer.h"
|
||||
#include "sfx/sfxSystem.h"
|
||||
#include "platform/async/asyncUpdate.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "core/volume.h"
|
||||
|
||||
|
||||
bool SFXFMODDevice::smPrefDisableSoftware = false;
|
||||
bool SFXFMODDevice::smPrefUseSoftwareOcclusion = true;
|
||||
bool SFXFMODDevice::smPrefUseSoftwareHRTF = true;
|
||||
bool SFXFMODDevice::smPrefEnableProfile = false;
|
||||
bool SFXFMODDevice::smPrefGeometryUseClosest = false;
|
||||
const char* SFXFMODDevice::smPrefDSoundHRTF = "full";
|
||||
const char* SFXFMODDevice::smPrefPluginPath = "";
|
||||
U32 SFXFMODDevice::smStatMemUsageCore;
|
||||
U32 SFXFMODDevice::smStatMemUsageEvents;
|
||||
U32 SFXFMODDevice::smStatNumEventSources;
|
||||
SFXFMODDevice* SFXFMODDevice::smInstance;
|
||||
FMOD_SYSTEM* SFXFMODDevice::smSystem;
|
||||
FMOD_EVENTSYSTEM* SFXFMODDevice::smEventSystem;
|
||||
FModFNTable* SFXFMODDevice::smFunc;
|
||||
Mutex* FModFNTable::mutex;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
String FMODResultToString( FMOD_RESULT result )
|
||||
{
|
||||
switch( result )
|
||||
{
|
||||
#define FMOD_ERROR( n ) case n: return #n;
|
||||
#include "fmodErrors.h"
|
||||
#undef FMOD_ERROR
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return String();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// FMOD filesystem wrappers.
|
||||
//FIXME: these are not thread-safe and cannot be used as such
|
||||
|
||||
FMOD_RESULT F_CALLBACK fmodFileOpenCallback( const char* name, int unicode, unsigned int* filesize, void** handle, void** userdata )
|
||||
{
|
||||
String fileName;
|
||||
if( unicode )
|
||||
fileName = String( ( UTF16* ) name );
|
||||
else
|
||||
fileName = String( name );
|
||||
|
||||
Torque::FS::FileRef file = Torque::FS::OpenFile( fileName, Torque::FS::File::Read );
|
||||
if( !file )
|
||||
return FMOD_ERR_FILE_NOTFOUND;
|
||||
else if( file->getStatus() != Torque::FS::File::Open )
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
|
||||
// Add a reference so we can pass it into FMOD.
|
||||
file->incRefCount();
|
||||
|
||||
*filesize = U32( file->getSize() );
|
||||
*handle = file.getPointer();
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
FMOD_RESULT F_CALLBACK fmodFileCloseCallback( void* handle, void* userdata )
|
||||
{
|
||||
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
||||
file->decRefCount();
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
FMOD_RESULT F_CALLBACK fmodFileReadCallback( void* handle, void* buffer, unsigned int sizebytes, unsigned int* bytesread, void* userdata )
|
||||
{
|
||||
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
||||
|
||||
U32 numRead = file->read( buffer, sizebytes );
|
||||
*bytesread = numRead;
|
||||
|
||||
if( file->getStatus() == Torque::FS::File::EndOfFile )
|
||||
return FMOD_ERR_FILE_EOF;
|
||||
else if( file->getStatus() != Torque::FS::File::Open )
|
||||
return FMOD_ERR_FILE_BAD;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
FMOD_RESULT F_CALLBACK fmodFileSeekCallback( void* handle, unsigned int pos, void* userdata )
|
||||
{
|
||||
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
||||
|
||||
if( file->setPosition( pos, Torque::FS::File::Begin ) != pos )
|
||||
return FMOD_ERR_FILE_COULDNOTSEEK;
|
||||
|
||||
return FMOD_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODDevice::SFXFMODDevice( SFXProvider* provider,
|
||||
FModFNTable *fmodFnTbl,
|
||||
int deviceIdx,
|
||||
String name )
|
||||
: SFXDevice( name, provider, false, 32 ),
|
||||
m3drolloffmode( FMOD_3D_INVERSEROLLOFF ),
|
||||
mDeviceIndex( deviceIdx )
|
||||
{
|
||||
// Store off the function pointers for later use.
|
||||
smFunc = fmodFnTbl;
|
||||
|
||||
smStatMemUsageCore = 0;
|
||||
smStatMemUsageEvents = 0;
|
||||
smStatNumEventSources = 0;
|
||||
|
||||
// Register our SFXSystem plugin.
|
||||
|
||||
SFX->addPlugin( &mPlugin );
|
||||
|
||||
smInstance = this;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODDevice::~SFXFMODDevice()
|
||||
{
|
||||
_releaseAllResources();
|
||||
|
||||
SFX->removePlugin( &mPlugin );
|
||||
|
||||
if( smEventSystem )
|
||||
{
|
||||
smFunc->FMOD_EventSystem_Release( smEventSystem );
|
||||
smEventSystem = NULL;
|
||||
smSystem = NULL;
|
||||
}
|
||||
else
|
||||
smFunc->FMOD_System_Close( smSystem );
|
||||
|
||||
smInstance = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODDevice::_init()
|
||||
{
|
||||
#define FMOD_CHECK( message ) \
|
||||
if( result != FMOD_OK ) \
|
||||
{ \
|
||||
Con::errorf( "SFXFMODDevice::_init() - %s (%s)", \
|
||||
message, \
|
||||
FMOD_ErrorString( result ) ); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
AssertISV(smSystem,
|
||||
"SFXFMODDevice::_init() - can't init w/o an existing FMOD system handle!");
|
||||
|
||||
FMOD_RESULT result;
|
||||
|
||||
// Get some prefs.
|
||||
|
||||
if( smPrefPluginPath && smPrefPluginPath[ 0 ] )
|
||||
{
|
||||
char fullPath[ 4096 ];
|
||||
Platform::makeFullPathName( smPrefPluginPath, fullPath, sizeof( fullPath ) );
|
||||
|
||||
smFunc->FMOD_System_SetPluginPath( smSystem, fullPath );
|
||||
}
|
||||
else
|
||||
{
|
||||
smFunc->FMOD_System_SetPluginPath( smSystem, Platform::getExecutablePath() );
|
||||
}
|
||||
|
||||
// Initialize everything from fmod.
|
||||
FMOD_SPEAKERMODE speakermode;
|
||||
FMOD_CAPS caps;
|
||||
result = smFunc->FMOD_System_GetDriverCaps(smSystem, 0, &caps, ( int* ) 0, &speakermode);
|
||||
FMOD_CHECK( "SFXFMODDevice::init - Failed to get driver caps" );
|
||||
|
||||
result = smFunc->FMOD_System_SetDriver(smSystem, mDeviceIndex);
|
||||
FMOD_CHECK( "SFXFMODDevice::init - Failed to set driver" );
|
||||
|
||||
result = smFunc->FMOD_System_SetSpeakerMode(smSystem, speakermode);
|
||||
FMOD_CHECK( "SFXFMODDevice::init - Failed to set the user selected speaker mode" );
|
||||
|
||||
if (caps & FMOD_CAPS_HARDWARE_EMULATED) /* The user has the 'Acceleration' slider set to off! This is really bad for latency!. */
|
||||
{ /* You might want to warn the user about this. */
|
||||
result = smFunc->FMOD_System_SetDSPBufferSize(smSystem, 1024, 10);
|
||||
FMOD_CHECK( "SFXFMODDevice::init - Failed to set DSP buffer size" );
|
||||
}
|
||||
|
||||
Con::printf( "\nFMOD Device caps:" );
|
||||
#define PRINT_CAP( name ) \
|
||||
if( caps & FMOD_CAPS_ ## name ) \
|
||||
Con::printf( #name );
|
||||
|
||||
PRINT_CAP( HARDWARE );
|
||||
PRINT_CAP( HARDWARE_EMULATED );
|
||||
PRINT_CAP( OUTPUT_MULTICHANNEL );
|
||||
PRINT_CAP( OUTPUT_FORMAT_PCM8 );
|
||||
PRINT_CAP( OUTPUT_FORMAT_PCM16 );
|
||||
PRINT_CAP( OUTPUT_FORMAT_PCM24 );
|
||||
PRINT_CAP( OUTPUT_FORMAT_PCM32 );
|
||||
PRINT_CAP( OUTPUT_FORMAT_PCMFLOAT );
|
||||
PRINT_CAP( REVERB_LIMITED );
|
||||
|
||||
Con::printf( "" );
|
||||
|
||||
bool tryAgain;
|
||||
do
|
||||
{
|
||||
tryAgain = false;
|
||||
|
||||
FMOD_INITFLAGS flags = FMOD_INIT_NORMAL | FMOD_INIT_VOL0_BECOMES_VIRTUAL;
|
||||
|
||||
if( smPrefDisableSoftware )
|
||||
flags |= FMOD_INIT_SOFTWARE_DISABLE;
|
||||
if( smPrefUseSoftwareOcclusion )
|
||||
flags |= FMOD_INIT_OCCLUSION_LOWPASS;
|
||||
if( smPrefUseSoftwareHRTF )
|
||||
flags |= FMOD_INIT_HRTF_LOWPASS;
|
||||
if( smPrefEnableProfile )
|
||||
flags |= FMOD_INIT_ENABLE_PROFILE;
|
||||
if( smPrefGeometryUseClosest )
|
||||
flags |= FMOD_INIT_GEOMETRY_USECLOSEST;
|
||||
|
||||
if( smEventSystem )
|
||||
result = smFunc->FMOD_EventSystem_Init( smEventSystem, 100, flags, ( void* ) 0, FMOD_EVENT_INIT_NORMAL );
|
||||
else
|
||||
result = smFunc->FMOD_System_Init( smSystem, 100, flags, ( void* ) 0 );
|
||||
|
||||
if( result == FMOD_ERR_OUTPUT_CREATEBUFFER ) /* Ok, the speaker mode selected isn't supported by this soundcard. Switch it back to stereo... */
|
||||
{
|
||||
result = smFunc->FMOD_System_SetSpeakerMode( smSystem, FMOD_SPEAKERMODE_STEREO );
|
||||
FMOD_CHECK( "SFXFMODDevice::init - failed on fallback speaker mode setup" );
|
||||
tryAgain = true;
|
||||
}
|
||||
} while( tryAgain );
|
||||
FMOD_CHECK( "SFXFMODDevice::init - failed to init system" );
|
||||
|
||||
// Print hardware channel info.
|
||||
|
||||
if( caps & FMOD_CAPS_HARDWARE )
|
||||
{
|
||||
int num3D, num2D, numTotal;
|
||||
|
||||
if( smFunc->FMOD_System_GetHardwareChannels( smSystem, &num2D, &num3D, &numTotal ) == FMOD_OK )
|
||||
Con::printf( "FMOD Hardware channels: 2d=%i, 3d=%i, total=%i", num2D, num3D, numTotal );
|
||||
}
|
||||
|
||||
// Set up filesystem.
|
||||
|
||||
//FIXME: Don't do this for now. Crashes on Windows.
|
||||
#if 0
|
||||
smFunc->FMOD_System_SetFileSystem( smSystem, fmodFileOpenCallback, fmodFileCloseCallback, fmodFileReadCallback, fmodFileSeekCallback, -1 );
|
||||
#endif
|
||||
|
||||
// Set capabilities.
|
||||
|
||||
mCaps = CAPS_Reverb | CAPS_VoiceManagement;
|
||||
if( smEventSystem )
|
||||
mCaps |= CAPS_FMODDesigner;
|
||||
|
||||
// Start the update thread.
|
||||
|
||||
#ifndef TORQUE_DEDICATED // Avoid dependency on platform/async for Linx dedicated.
|
||||
|
||||
if( !Con::getBoolVariable( "$_forceAllMainThread" ) )
|
||||
{
|
||||
SFXInternal::gUpdateThread = new AsyncPeriodicUpdateThread
|
||||
( "FMOD Update Thread", SFXInternal::gBufferUpdateList,
|
||||
Con::getIntVariable( "$pref::SFX::updateInterval", SFXInternal::DEFAULT_UPDATE_INTERVAL ) );
|
||||
SFXInternal::gUpdateThread->start();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXBuffer* SFXFMODDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
|
||||
{
|
||||
AssertFatal( stream, "SFXFMODDevice::createBuffer() - Got a null stream!" );
|
||||
AssertFatal( description, "SFXFMODDevice::createBuffer() - Got null description!" );
|
||||
|
||||
SFXFMODBuffer *buffer = SFXFMODBuffer::create( stream, description );
|
||||
if ( buffer )
|
||||
_addBuffer( buffer );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXBuffer* SFXFMODDevice::createBuffer( const String& filename, SFXDescription* description )
|
||||
{
|
||||
AssertFatal( filename.isNotEmpty(), "SFXFMODDevice::createBuffer() - Got an empty filename!" );
|
||||
AssertFatal( description, "SFXFMODDevice::createBuffer() - Got null description!" );
|
||||
|
||||
SFXFMODBuffer* buffer = SFXFMODBuffer::create( filename, description );
|
||||
if( buffer )
|
||||
_addBuffer( buffer );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXVoice* SFXFMODDevice::createVoice( bool is3D, SFXBuffer* buffer )
|
||||
{
|
||||
AssertFatal( buffer, "SFXFMODDevice::createVoice() - Got null buffer!" );
|
||||
|
||||
SFXFMODBuffer* fmodBuffer = dynamic_cast<SFXFMODBuffer*>( buffer );
|
||||
AssertFatal( fmodBuffer, "SFXFMODDevice::createVoice() - Got bad buffer!" );
|
||||
|
||||
SFXFMODVoice* voice = SFXFMODVoice::create( this, fmodBuffer );
|
||||
if ( !voice )
|
||||
return NULL;
|
||||
|
||||
_addVoice( voice );
|
||||
return voice;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::update()
|
||||
{
|
||||
Parent::update();
|
||||
|
||||
if( smEventSystem )
|
||||
{
|
||||
FModAssert( smFunc->FMOD_EventSystem_Update( smEventSystem ), "Failed to update event system!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
FModAssert(smFunc->FMOD_System_Update(smSystem), "Failed to update system!");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setNumListeners( U32 num )
|
||||
{
|
||||
smFunc->FMOD_System_Set3DNumListeners( smSystem, num );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setListener( U32 index, const SFXListenerProperties& listener )
|
||||
{
|
||||
FMOD_VECTOR position, forward, up, velocity;
|
||||
|
||||
TorqueTransformToFMODVectors( listener.getTransform(), position, forward, up );
|
||||
TorqueVectorToFMODVector( listener.getVelocity(), velocity );
|
||||
|
||||
// Do the listener state update, then update!
|
||||
smFunc->FMOD_System_Set3DListenerAttributes( smSystem, index, &position, &velocity, &forward, &up );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setDistanceModel( SFXDistanceModel model )
|
||||
{
|
||||
switch( model )
|
||||
{
|
||||
case SFXDistanceModelLinear:
|
||||
m3drolloffmode = FMOD_3D_LINEARROLLOFF;
|
||||
break;
|
||||
|
||||
case SFXDistanceModelLogarithmic:
|
||||
m3drolloffmode = FMOD_3D_INVERSEROLLOFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertWarn( false, "SFXFMODDevice::setDistanceModel - model not implemented" );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setDopplerFactor( F32 factor )
|
||||
{
|
||||
F32 dopplerFactor;
|
||||
F32 distanceFactor;
|
||||
F32 rolloffFactor;
|
||||
|
||||
smFunc->FMOD_System_Get3DSettings( smSystem, &dopplerFactor, &distanceFactor, &rolloffFactor );
|
||||
dopplerFactor = factor;
|
||||
smFunc->FMOD_System_Set3DSettings( smSystem, dopplerFactor, distanceFactor, rolloffFactor );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setRolloffFactor( F32 factor )
|
||||
{
|
||||
F32 dopplerFactor;
|
||||
F32 distanceFactor;
|
||||
F32 rolloffFactor;
|
||||
|
||||
smFunc->FMOD_System_Get3DSettings( smSystem, &dopplerFactor, &distanceFactor, &rolloffFactor );
|
||||
rolloffFactor = factor;
|
||||
smFunc->FMOD_System_Set3DSettings( smSystem, dopplerFactor, distanceFactor, rolloffFactor );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::setReverb( const SFXReverbProperties& reverb )
|
||||
{
|
||||
FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC;
|
||||
|
||||
prop.Environment = 0;
|
||||
prop.EnvDiffusion = reverb.mEnvDiffusion;
|
||||
prop.Room = reverb.mRoom;
|
||||
prop.RoomHF = reverb.mRoomHF;
|
||||
prop.RoomLF = reverb.mRoomLF;
|
||||
prop.DecayTime = reverb.mDecayTime;
|
||||
prop.DecayLFRatio = reverb.mDecayLFRatio;
|
||||
prop.DecayHFRatio = reverb.mDecayHFRatio;
|
||||
prop.Reflections = reverb.mReflections;
|
||||
prop.ReflectionsDelay = reverb.mReflectionsDelay;
|
||||
prop.Reverb = reverb.mReverb;
|
||||
prop.ReverbDelay = reverb.mReverbDelay;
|
||||
prop.ModulationTime = reverb.mModulationTime;
|
||||
prop.ModulationDepth = reverb.mModulationDepth;
|
||||
prop.HFReference = reverb.mHFReference;
|
||||
prop.LFReference = reverb.mLFReference;
|
||||
prop.Diffusion = reverb.mDiffusion;
|
||||
prop.Density = reverb.mDensity;
|
||||
prop.Flags = reverb.mFlags;
|
||||
|
||||
// Here we only want to affect 3D sounds. While not quite obvious from the docs,
|
||||
// SetReverbProperties sets the global reverb environment for 2D sounds whereas
|
||||
// SetAmbientReverbProperties sets the global reverb environment for 3D sounds.
|
||||
|
||||
FMOD_RESULT result = smFunc->FMOD_System_SetReverbAmbientProperties( smSystem, &prop );
|
||||
if( result != FMOD_OK )
|
||||
Con::errorf( "SFXFMODDevice::setReverb - Failed to set reverb (%s)", FMODResultToString( result ).c_str() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::resetReverb()
|
||||
{
|
||||
FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_OFF;
|
||||
smFunc->FMOD_System_SetReverbProperties( smSystem, &prop );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODDevice::updateMemUsageStats()
|
||||
{
|
||||
smFunc->FMOD_System_GetMemoryInfo( smSystem, ( unsigned int ) FMOD_MEMBITS_ALL,
|
||||
( unsigned int ) 0, ( unsigned int* ) &smStatMemUsageCore, ( unsigned int* ) 0 );
|
||||
|
||||
if( smEventSystem )
|
||||
smFunc->FMOD_EventSystem_GetMemoryInfo( smEventSystem, ( unsigned int ) 0,
|
||||
( unsigned int ) FMOD_EVENT_MEMBITS_ALL, ( unsigned int* ) &smStatMemUsageEvents, ( unsigned int* ) 0 );
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Console Functions.
|
||||
//=============================================================================
|
||||
// MARK: ---- Console Functions ----
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( fmodDumpDSPInfo, void, 1, 1, "()"
|
||||
"@brief Dump information about the standard DSP effects.\n\n"
|
||||
"@ingroup SFXFMOD")
|
||||
{
|
||||
if( !SFXFMODDevice::smFunc )
|
||||
return;
|
||||
|
||||
const U32 firstDSPType = FMOD_DSP_TYPE_MIXER;
|
||||
const U32 lastDSPType = FMOD_DSP_TYPE_TREMOLO;
|
||||
|
||||
for( U32 i = firstDSPType; i <= lastDSPType; ++ i )
|
||||
{
|
||||
FMOD_DSP* dsp;
|
||||
if( SFXFMODDevice::smFunc->FMOD_System_CreateDSPByType( SFXFMODDevice::smSystem, ( FMOD_DSP_TYPE ) i, &dsp ) == FMOD_OK )
|
||||
{
|
||||
// Print general info.
|
||||
|
||||
char name[ 33 ];
|
||||
unsigned int version;
|
||||
int channels;
|
||||
int numParameters;
|
||||
|
||||
dMemset( name, 0, sizeof( name ) );
|
||||
SFXFMODDevice::smFunc->FMOD_DSP_GetInfo( dsp, name, &version, &channels, ( int* ) NULL, ( int* ) NULL );
|
||||
SFXFMODDevice::smFunc->FMOD_DSP_GetNumParameters( dsp, &numParameters );
|
||||
|
||||
Con::printf( "----------------------------------------------------------------" );
|
||||
Con::printf( "DSP: %s", name );
|
||||
Con::printf( "Version: %i.%i", ( version & 0xffff0000 ) >> 16, version & 0xffff );
|
||||
Con::printf( "Channels: %i", channels );
|
||||
Con::printf( "Parameters: %i", numParameters );
|
||||
Con::printf( "" );
|
||||
|
||||
// Print parameter info.
|
||||
|
||||
for( U32 n = 0; n < numParameters; ++ n )
|
||||
{
|
||||
char name[ 17 ];
|
||||
char label[ 17 ];
|
||||
char description[ 1024 ];
|
||||
float minValue, maxValue;
|
||||
float value;
|
||||
char valueString[ 256 ];
|
||||
|
||||
dMemset( name, 0, sizeof( name ) );
|
||||
dMemset( label, 0, sizeof( label ) );
|
||||
dMemset( description, 0, sizeof( description ) );
|
||||
dMemset( valueString, 0, sizeof( valueString ) );
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_DSP_GetParameterInfo( dsp, n, name, label, description, sizeof( description ) - 1, &minValue, &maxValue );
|
||||
SFXFMODDevice::smFunc->FMOD_DSP_GetParameter( dsp, n, &value, valueString, sizeof( valueString ) - 1 );
|
||||
|
||||
Con::printf( "* Parameter %i", n );
|
||||
Con::printf( "Name: %s", name );
|
||||
Con::printf( "Label: %s", label );
|
||||
Con::printf( "Description: %s", description );
|
||||
Con::printf( "Min: %f", minValue );
|
||||
Con::printf( "Max: %f", maxValue );
|
||||
Con::printf( "Value: %f (%s)", value, valueString );
|
||||
Con::printf( "" );
|
||||
}
|
||||
|
||||
// Release the DSP.
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_DSP_Release( dsp );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ConsoleFunction( fmodDumpMemoryStats, void, 1, 1, "()"
|
||||
"@return Prints the current memory consumption of the FMOD module\n\n"
|
||||
"@ingroup SFXFMOD")
|
||||
{
|
||||
int current = 0;
|
||||
int max = 0;
|
||||
|
||||
if (SFXFMODDevice::smFunc && SFXFMODDevice::smFunc->FMOD_Memory_GetStats.fn)
|
||||
SFXFMODDevice::smFunc->FMOD_Memory_GetStats(¤t, &max);
|
||||
Con::printf("Fmod current: %d, max: %d", current, max);
|
||||
}
|
||||
|
|
@ -1,342 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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_WIN) || 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()
|
||||
{
|
||||
dllRef = NULL;
|
||||
eventDllRef = 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 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_
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "platform/platform.h"
|
||||
#include "sfx/fmod/sfxFMODEvent.h"
|
||||
#include "sfx/fmod/sfxFMODEventGroup.h"
|
||||
#include "sfx/fmod/sfxFMODProject.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/sfxParameter.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODEvent );
|
||||
|
||||
|
||||
ConsoleDocClass( SFXFMODEvent,
|
||||
"@brief A playable sound event in an FMOD Designer audio project.\n\n"
|
||||
|
||||
"@ingroup SFXFMOD\n"
|
||||
"@ingroup Datablocks"
|
||||
);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEvent::SFXFMODEvent()
|
||||
: mGroup( NULL ),
|
||||
mHandle( NULL ),
|
||||
mGroupId( 0 ),
|
||||
mSibling( NULL )
|
||||
{
|
||||
dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
|
||||
dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEvent::SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle )
|
||||
: mGroup( group ),
|
||||
mHandle( handle ),
|
||||
mGroupId( 0 ),
|
||||
mSibling( NULL )
|
||||
{
|
||||
dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
|
||||
dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
|
||||
|
||||
// Fetch name.
|
||||
|
||||
int index;
|
||||
char* name = NULL;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Event_GetInfo( mHandle, &index, &name, ( FMOD_EVENT_INFO* ) 0 );
|
||||
|
||||
mName = name;
|
||||
|
||||
// Read out the parameter info so we can immediately create
|
||||
// the events on the client-side without having to open and
|
||||
// read all the project info there.
|
||||
|
||||
int numParameters;
|
||||
SFXFMODDevice::smFunc->FMOD_Event_GetNumParameters( mHandle, &numParameters );
|
||||
if( numParameters > MaxNumParameters )
|
||||
{
|
||||
Con::errorf( "SFXFMODEvent::SFXFMODEvent - event '%s' has more parameters (%i) than supported per SFXTrack (%i)",
|
||||
getQualifiedName().c_str(),
|
||||
numParameters,
|
||||
MaxNumParameters );
|
||||
numParameters = MaxNumParameters;
|
||||
}
|
||||
|
||||
for( U32 i = 0; i < numParameters; ++ i )
|
||||
{
|
||||
FMOD_EVENTPARAMETER* parameter;
|
||||
SFXFMODDevice::smFunc->FMOD_Event_GetParameterByIndex( mHandle, i, ¶meter );
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventParameter_GetInfo( parameter, &index, &name );
|
||||
setParameter( i, name );
|
||||
|
||||
// Get value and range of parameter.
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventParameter_GetValue( parameter, &mParameterValues[ i ] );
|
||||
SFXFMODDevice::smFunc->FMOD_EventParameter_GetRange( parameter, &mParameterRanges[ i ].x, &mParameterRanges[ i ].y );
|
||||
}
|
||||
|
||||
// Read out the properties and create a custom SFXDescription for the event.
|
||||
|
||||
mDescription = new SFXDescription;
|
||||
if( !group->isClientOnly() )
|
||||
mDescription->assignId();
|
||||
|
||||
mDescription->registerObject(
|
||||
String::ToString( "%s_%s_Description",
|
||||
group->getName(),
|
||||
FMODEventPathToTorqueName( mName ).c_str()
|
||||
)
|
||||
);
|
||||
if( group->isClientOnly() )
|
||||
Sim::getRootGroup()->addObject( mDescription );
|
||||
|
||||
FMOD_MODE modeValue;
|
||||
float floatValue;
|
||||
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_MODE, &modeValue, true ) == FMOD_OK )
|
||||
mDescription->mIs3D = ( modeValue == FMOD_3D );
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_VOLUME, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mVolume = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_PITCH, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mPitch = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MINDISTANCE, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mMinDistance = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MAXDISTANCE, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mMaxDistance = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEINSIDEANGLE, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mConeInsideAngle = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEANGLE, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mConeOutsideAngle = floatValue;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEVOLUME, &floatValue, true ) == FMOD_OK )
|
||||
mDescription->mConeOutsideVolume = floatValue;
|
||||
|
||||
// Don't read out fade values as we want to leave fade-effects to
|
||||
// FMOD rather than having the fading system built into SFX pick
|
||||
// these values up.
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEvent::~SFXFMODEvent()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::initPersistFields()
|
||||
{
|
||||
addGroup( "DO NOT MODIFY!!" );
|
||||
addField( "fmodGroup", TYPEID< SFXFMODEventGroup >(), Offset( mGroup, SFXFMODEvent ), "DO NOT MODIFY!!" );
|
||||
addField( "fmodName", TypeRealString, Offset( mName, SFXFMODEvent ), "DO NOT MODIFY!!" );
|
||||
addField( "fmodParameterRanges", TypePoint2F, Offset( mParameterRanges, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
|
||||
addField( "fmodParameterValues", TypeF32, Offset( mParameterValues, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
|
||||
endGroup( "DO NOT MODIFY!!" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEvent::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
if( !mGroup )
|
||||
{
|
||||
Con::errorf( "SFXFMODEvent::onAdd - no group set; this event was not properly constructed" );
|
||||
return false;
|
||||
}
|
||||
|
||||
mGroup->_addEvent( this );
|
||||
mGroup->mProject->_addEvent( this );
|
||||
|
||||
// For non-networked event datablocks, create the parameter
|
||||
// instances now.
|
||||
|
||||
if( isClientOnly() )
|
||||
_createParameters();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
|
||||
if( !mGroup )
|
||||
return;
|
||||
|
||||
release();
|
||||
mGroup->_removeEvent( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEvent::preload( bool server, String& errorStr )
|
||||
{
|
||||
if( !Parent::preload( server, errorStr ) )
|
||||
return false;
|
||||
|
||||
if( !server )
|
||||
{
|
||||
if( !Sim::findObject( mGroupId, mGroup ) )
|
||||
{
|
||||
errorStr = String::ToString( "SFXFMODEvent - group '%i' does not exist", mGroupId );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create parameters.
|
||||
|
||||
_createParameters();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::packData( BitStream* stream )
|
||||
{
|
||||
Parent::packData( stream );
|
||||
|
||||
stream->write( mName );
|
||||
stream->writeRangedS32( mGroup->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
|
||||
for( U32 i = 0; i < MaxNumParameters; ++ i )
|
||||
if( stream->writeFlag( mParameters[ i ] ) )
|
||||
{
|
||||
stream->write( mParameterValues[ i ] );
|
||||
stream->write( mParameterRanges[ i ].x );
|
||||
stream->write( mParameterRanges[ i ].y );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::unpackData( BitStream* stream )
|
||||
{
|
||||
Parent::unpackData( stream );
|
||||
|
||||
stream->read( &mName );
|
||||
mGroupId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
|
||||
for( U32 i = 0; i < MaxNumParameters; ++ i )
|
||||
if( stream->readFlag() )
|
||||
{
|
||||
stream->read( &mParameterValues[ i ] );
|
||||
stream->read( &mParameterRanges[ i ].x );
|
||||
stream->read( &mParameterRanges[ i ].y );
|
||||
}
|
||||
else
|
||||
{
|
||||
mParameterValues[ i ] = 0.f;
|
||||
mParameterRanges[ i ].x = 0.f;
|
||||
mParameterRanges[ i ].y = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::acquire()
|
||||
{
|
||||
if( mHandle )
|
||||
return;
|
||||
|
||||
mGroup->acquire();
|
||||
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
|
||||
mGroup->mHandle, mName.c_str(), FMOD_EVENT_INFOONLY, &mHandle ) != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODEvent::acquire() - failed to acquire event '%s'", getQualifiedName().c_str() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::release()
|
||||
{
|
||||
if( !mHandle )
|
||||
return;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, false );
|
||||
mHandle = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
String SFXFMODEvent::getQualifiedName() const
|
||||
{
|
||||
return String::ToString( "%s/%s", getEventGroup()->getQualifiedName().c_str(), mName.c_str() );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEvent::_createParameters()
|
||||
{
|
||||
const String& projectFileName = getEventGroup()->getProject()->getFileName();
|
||||
const String qualifiedGroupName = getEventGroup()->getQualifiedName();
|
||||
const String description = String::ToString( "FMOD Event Parameter (%s)", projectFileName.c_str() );
|
||||
|
||||
for( U32 i = 0; i < MaxNumParameters; ++ i )
|
||||
{
|
||||
StringTableEntry name = getParameter( i );
|
||||
if( !name )
|
||||
continue;
|
||||
|
||||
SFXParameter* parameter = SFXParameter::find( name );
|
||||
if( !parameter )
|
||||
{
|
||||
parameter = new SFXParameter();
|
||||
parameter->setInternalName( name );
|
||||
parameter->registerObject();
|
||||
|
||||
// Set up parameter.
|
||||
|
||||
parameter->setChannel( SFXChannelUser0 );
|
||||
parameter->setRange( mParameterRanges[ i ] );
|
||||
parameter->setDefaultValue( mParameterValues[ i ] );
|
||||
parameter->setValue( mParameterValues[ i ] );
|
||||
parameter->setDescription( description );
|
||||
|
||||
// Set categories for easy filtering.
|
||||
|
||||
static StringTableEntry sCategories = StringTable->insert( "categories" );
|
||||
parameter->setDataField( sCategories, "0", "FMOD" );
|
||||
parameter->setDataField( sCategories, "1", avar( "FMOD Project: %s", projectFileName.c_str() ) );
|
||||
parameter->setDataField( sCategories, "2", avar( "FMOD Group: %s", qualifiedGroupName.c_str() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODEVENT_H_
|
||||
#define _SFXFMODEVENT_H_
|
||||
|
||||
#ifndef _SFXTRACK_H_
|
||||
#include "sfx/sfxTrack.h"
|
||||
#endif
|
||||
#ifndef _CONSOLETYPES_H_
|
||||
#include "console/consoleTypes.h"
|
||||
#endif
|
||||
#ifndef _MPOINT2_H_
|
||||
#include "math/mPoint2.h"
|
||||
#endif
|
||||
|
||||
#include "fmod_event.h"
|
||||
|
||||
|
||||
class SFXFMODProject;
|
||||
class SFXFMODEventGroup;
|
||||
|
||||
|
||||
/// An event in an FMOD Designer project.
|
||||
///
|
||||
/// This class must not be manually instanced by the user. Instead, SFXFMODEvents
|
||||
/// are automatically created when an SFXFMODProject is loaded.
|
||||
///
|
||||
/// Be aware that as all the playback happens internally within FMOD's event system,
|
||||
/// this bypasses the SFX layer and will thus not work with features that rely the
|
||||
/// structures there. Namely, sound occlusion (except for FMOD's own occlusion) will
|
||||
/// not work with FMOD events.
|
||||
///
|
||||
/// The parameters of an FMOD event are automatically created and designed using the
|
||||
/// information in the project.
|
||||
///
|
||||
class SFXFMODEvent : public SFXTrack
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXTrack Parent;
|
||||
friend class SFXFMODEventGroup;
|
||||
friend class SFXFMODEventSource;
|
||||
|
||||
protected:
|
||||
|
||||
/// Name of the event in the Designer project.
|
||||
String mName;
|
||||
|
||||
/// Event group that this event belongs to.
|
||||
SFXFMODEventGroup* mGroup;
|
||||
|
||||
/// Next event in the group's event chain.
|
||||
SFXFMODEvent* mSibling;
|
||||
|
||||
/// FMOD event handle when event is open. Client-side only.
|
||||
FMOD_EVENT* mHandle;
|
||||
|
||||
///
|
||||
Point2F mParameterRanges[ MaxNumParameters ];
|
||||
|
||||
///
|
||||
F32 mParameterValues[ MaxNumParameters ];
|
||||
|
||||
/// Group ID for client net sync.
|
||||
S32 mGroupId;
|
||||
|
||||
///
|
||||
void _createParameters();
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SFXFMODEvent();
|
||||
|
||||
///
|
||||
SFXFMODEvent( SFXFMODEventGroup* group, const String& name );
|
||||
|
||||
///
|
||||
SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle );
|
||||
|
||||
~SFXFMODEvent();
|
||||
|
||||
/// Create the event object on the FMOD device.
|
||||
void acquire();
|
||||
|
||||
/// Release the event object on the FMOD device.
|
||||
void release();
|
||||
|
||||
///
|
||||
const String& getEventName() const { return mName; }
|
||||
|
||||
///
|
||||
SFXFMODEventGroup* getEventGroup() const { return mGroup; }
|
||||
|
||||
///
|
||||
String getQualifiedName() const;
|
||||
|
||||
///
|
||||
bool isDataLoaded() const;
|
||||
|
||||
// SFXTrack.
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual bool preload( bool server, String& errorStr );
|
||||
virtual void packData( BitStream* stream );
|
||||
virtual void unpackData( BitStream* stream );
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT( SFXFMODEvent );
|
||||
DECLARE_CATEGORY( "SFX FMOD" );
|
||||
DECLARE_DESCRIPTION( "An FMOD Designer event." );
|
||||
};
|
||||
|
||||
#endif // !_SFXFMODEVENT_H_
|
||||
|
|
@ -1,510 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/fmod/sfxFMODEventGroup.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/fmod/sfxFMODEvent.h"
|
||||
#include "sfx/fmod/sfxFMODProject.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODEventGroup );
|
||||
|
||||
ConsoleDocClass( SFXFMODEventGroup,
|
||||
"@brief A group of events in an imported FMOD Designer project.\n\n"
|
||||
|
||||
""
|
||||
|
||||
"@note Instances of this class \n\n"
|
||||
|
||||
"@ingroup SFXFMOD\n"
|
||||
"@ingroup Datablocks"
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventGroup::SFXFMODEventGroup()
|
||||
: mProject( NULL ),
|
||||
mHandle( NULL ),
|
||||
mParent( NULL ),
|
||||
mChildren( NULL ),
|
||||
mSibling( NULL ),
|
||||
mLoadCount( 0 ),
|
||||
mEvents( NULL ),
|
||||
mNumEvents( 0 ),
|
||||
mNumGroups( 0 ),
|
||||
mParentId( 0 ),
|
||||
mProjectId( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventGroup::SFXFMODEventGroup( SFXFMODProject* project, FMOD_EVENTGROUP* handle, SFXFMODEventGroup* parent )
|
||||
: mProject( project ),
|
||||
mHandle( handle ),
|
||||
mParent( parent ),
|
||||
mChildren( NULL ),
|
||||
mSibling( NULL ),
|
||||
mLoadCount( 0 ),
|
||||
mEvents( NULL ),
|
||||
mNumEvents( 0 ),
|
||||
mNumGroups( 0 ),
|
||||
mParentId( 0 ),
|
||||
mProjectId( 0 )
|
||||
{
|
||||
AssertFatal( project != NULL, "SFXFMODEventGroup::SFXFMODEventGroup - got a NULL project!" );
|
||||
AssertFatal( handle != NULL, "SFXFMODEventGroup::SFXFMODEventGroup - got a NULL group handle!" );
|
||||
|
||||
// Fetch the name.
|
||||
|
||||
int index;
|
||||
char* name = NULL;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventGroup_GetInfo( handle, &index, &name );
|
||||
|
||||
mName = name;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventGroup::~SFXFMODEventGroup()
|
||||
{
|
||||
AssertFatal( mEvents == NULL, "SFXFMODEventGroup::~SFXFMODEventGroup - group still has events attached" );
|
||||
AssertFatal( mChildren == NULL, "SFXFMODEventGroup::~SFXFMODEventGroup - group still has subgroups attached" );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::initPersistFields()
|
||||
{
|
||||
addGroup( "DO NOT MODIFY!!" );
|
||||
addField( "fmodProject", TYPEID< SFXFMODProject >(), Offset( mProject, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
|
||||
addField( "fmodGroup", TYPEID< SFXFMODEventGroup >(), Offset( mParent, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
|
||||
addField( "fmodName", TypeRealString, Offset( mName, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
|
||||
endGroup( "DO NOT MODIFY!!" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEventGroup::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
if( !mProject )
|
||||
{
|
||||
Con::errorf( "SFXFMODEventGroup - not part of a project" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( mParent )
|
||||
mParent->_addGroup( this );
|
||||
|
||||
mProject->_addGroup( this );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
|
||||
if( !mProject )
|
||||
return;
|
||||
|
||||
release();
|
||||
|
||||
while( mEvents )
|
||||
mEvents->deleteObject();
|
||||
while( mChildren )
|
||||
mChildren->deleteObject();
|
||||
|
||||
if( mParent )
|
||||
mParent->_removeGroup( this );
|
||||
|
||||
mProject->_removeGroup( this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEventGroup::preload( bool server, String& errorStr )
|
||||
{
|
||||
if( !Parent::preload( server, errorStr ) )
|
||||
return false;
|
||||
|
||||
if( !server )
|
||||
{
|
||||
if( mParentId != 0 && !Sim::findObject( mParentId, mParent ) )
|
||||
{
|
||||
errorStr = String::ToString( "SFXFMODEventGroup - parent group '%i' does not exist", mParentId );
|
||||
return false;
|
||||
}
|
||||
if( !Sim::findObject( mProjectId, mProject ) )
|
||||
{
|
||||
errorStr = String::ToString( "SFXFMODEventGroup - project '%i' does not exist", mProjectId );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::packData( BitStream* stream )
|
||||
{
|
||||
Parent::packData( stream );
|
||||
|
||||
stream->write( mName );
|
||||
stream->writeRangedS32( mProject->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
if( stream->writeFlag( mParent ) )
|
||||
stream->writeRangedS32( mParent->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::unpackData( BitStream* stream )
|
||||
{
|
||||
Parent::unpackData( stream );
|
||||
|
||||
stream->read( &mName );
|
||||
|
||||
mProjectId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
if( stream->readFlag() )
|
||||
mParentId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
|
||||
else
|
||||
mParentId = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
String SFXFMODEventGroup::getQualifiedName() const
|
||||
{
|
||||
if( mParent )
|
||||
return String::ToString( "%s/%s", mParent->getQualifiedName().c_str(), mName.c_str() );
|
||||
else
|
||||
return mName;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEventGroup::isDataLoaded() const
|
||||
{
|
||||
// Check whether we or any of our parents has triggered a load.
|
||||
|
||||
for( const SFXFMODEventGroup* group = this; group != NULL; group = group->mParent )
|
||||
if( group->mLoadCount > 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODEventGroup::loadData( bool samples, bool streams )
|
||||
{
|
||||
if( !mHandle )
|
||||
acquire();
|
||||
|
||||
if( !mLoadCount )
|
||||
{
|
||||
FMOD_EVENT_RESOURCE resource;
|
||||
if( samples && streams )
|
||||
resource = FMOD_EVENT_RESOURCE_STREAMS_AND_SAMPLES;
|
||||
else if( samples )
|
||||
resource = FMOD_EVENT_RESOURCE_SAMPLES;
|
||||
else if( streams )
|
||||
resource = FMOD_EVENT_RESOURCE_STREAMS;
|
||||
else
|
||||
return true;
|
||||
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventGroup_LoadEventData( mHandle, resource, FMOD_EVENT_DEFAULT );
|
||||
if( result != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODEventGroup::loadData - could not load data: %s", FMODResultToString( result ).c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
SFXFMODDevice::instance()->updateMemUsageStats();
|
||||
Con::printf( "SFXFMODProject - %s: Loaded data for group '%s'", mProject->getName(), getQualifiedName().c_str() );
|
||||
}
|
||||
|
||||
mLoadCount ++;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::freeData( bool force )
|
||||
{
|
||||
bool isLoaded = ( mLoadCount > 0 );
|
||||
|
||||
if( !isLoaded )
|
||||
isLoaded = ( mParent ? mParent->isDataLoaded() : false );
|
||||
else
|
||||
{
|
||||
if( force )
|
||||
mLoadCount = 0;
|
||||
else
|
||||
-- mLoadCount;
|
||||
}
|
||||
|
||||
if( !mLoadCount && isLoaded )
|
||||
{
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventGroup_FreeEventData( mHandle, ( FMOD_EVENT* ) NULL, false );
|
||||
if( result != FMOD_OK )
|
||||
Con::errorf( "SFXFMODEventGroup - failed freeing event data: %s", FMODResultToString( result ).c_str() );
|
||||
|
||||
SFXFMODDevice::instance()->updateMemUsageStats();
|
||||
Con::printf( "SFXFMODProject - %s: Cleared data for group '%s'", mProject->getName(), getQualifiedName().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::acquire( bool recursive )
|
||||
{
|
||||
// Make sure the project is acquired.
|
||||
|
||||
mProject->acquire();
|
||||
|
||||
// Acquire the group.
|
||||
|
||||
if( !mHandle )
|
||||
{
|
||||
if( mParent )
|
||||
{
|
||||
mParent->acquire();
|
||||
SFXFMODDevice::smFunc->FMOD_EventGroup_GetGroup( mParent->mHandle, mName, true, &mHandle );
|
||||
}
|
||||
else
|
||||
{
|
||||
mProject->acquire();
|
||||
SFXFMODDevice::smFunc->FMOD_EventProject_GetGroup( mProject->mHandle, mName, true, &mHandle );
|
||||
}
|
||||
}
|
||||
|
||||
// Acquite events and subgroups.
|
||||
|
||||
if( recursive )
|
||||
{
|
||||
for( SFXFMODEvent* event = mEvents; event != NULL; event = event->mSibling )
|
||||
event->acquire();
|
||||
|
||||
for( SFXFMODEventGroup* group = mChildren; group != NULL; group = group->mSibling )
|
||||
group->acquire( true );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::release()
|
||||
{
|
||||
if( !mHandle )
|
||||
return;
|
||||
|
||||
// Free the event data if we still have it loaded.
|
||||
|
||||
if( isDataLoaded() )
|
||||
freeData( true );
|
||||
|
||||
// Release events.
|
||||
|
||||
for( SFXFMODEvent* event = mEvents; event != NULL; event = event->mSibling )
|
||||
event->release();
|
||||
|
||||
// Release children.
|
||||
|
||||
for( SFXFMODEventGroup* child = mChildren; child != NULL; child = child->mSibling )
|
||||
child->release();
|
||||
|
||||
// Release our handle.
|
||||
|
||||
freeData();
|
||||
mHandle = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::_load()
|
||||
{
|
||||
// Make sure we have the group open.
|
||||
|
||||
if( !mHandle )
|
||||
acquire();
|
||||
|
||||
// Fetch info.
|
||||
|
||||
int numEvents;
|
||||
int numGroups;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventGroup_GetNumEvents( mHandle, &numEvents );
|
||||
SFXFMODDevice::smFunc->FMOD_EventGroup_GetNumGroups( mHandle, &numGroups );
|
||||
|
||||
// Load events.
|
||||
|
||||
for( U32 i = 0; i < numEvents; ++ i )
|
||||
{
|
||||
FMOD_EVENT* handle;
|
||||
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEventByIndex( mHandle, i, FMOD_EVENT_INFOONLY, &handle ) == FMOD_OK )
|
||||
{
|
||||
SFXFMODEvent* event = new SFXFMODEvent( this, handle );
|
||||
if( !isClientOnly() )
|
||||
event->assignId();
|
||||
|
||||
event->registerObject( String::ToString( "%s_%s", getName(), FMODEventPathToTorqueName( event->getEventName() ).c_str() ) );
|
||||
if( isClientOnly() )
|
||||
Sim::getRootGroup()->addObject( event );
|
||||
}
|
||||
}
|
||||
|
||||
// Load subgroups.
|
||||
|
||||
for( U32 i = 0; i < numGroups; ++ i )
|
||||
{
|
||||
FMOD_EVENTGROUP* handle;
|
||||
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetGroupByIndex( mHandle, i, true, &handle ) == FMOD_OK )
|
||||
{
|
||||
SFXFMODEventGroup* group = new SFXFMODEventGroup( mProject, handle, this );
|
||||
if( !isClientOnly() )
|
||||
group->assignId();
|
||||
|
||||
group->registerObject( String::ToString( "%s_%s", getName(), FMODEventPathToTorqueName( group->getGroupName() ).c_str() ) );
|
||||
if( isClientOnly() )
|
||||
Sim::getRootGroup()->addObject( group );
|
||||
|
||||
group->_load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::_addEvent( SFXFMODEvent* event )
|
||||
{
|
||||
event->mSibling = mEvents;
|
||||
mEvents = event;
|
||||
mNumEvents ++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::_removeEvent( SFXFMODEvent* event )
|
||||
{
|
||||
if( mEvents == event )
|
||||
{
|
||||
mEvents = event->mSibling;
|
||||
event->mSibling = NULL;
|
||||
mNumEvents --;
|
||||
}
|
||||
else
|
||||
{
|
||||
SFXFMODEvent* p = mEvents;
|
||||
while( p != NULL && p->mSibling != event )
|
||||
p = p->mSibling;
|
||||
|
||||
if( p )
|
||||
{
|
||||
p->mSibling = event->mSibling;
|
||||
event->mSibling = NULL;
|
||||
mNumEvents --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::_addGroup( SFXFMODEventGroup* group )
|
||||
{
|
||||
group->mSibling = mChildren;
|
||||
mChildren = group;
|
||||
mNumGroups ++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventGroup::_removeGroup( SFXFMODEventGroup* group )
|
||||
{
|
||||
if( mChildren == group )
|
||||
{
|
||||
mChildren = group->mSibling;
|
||||
group->mSibling = NULL;
|
||||
mNumGroups --;
|
||||
}
|
||||
else
|
||||
{
|
||||
SFXFMODEventGroup* p = mChildren;
|
||||
while( p != NULL && p->mSibling != group )
|
||||
p = p->mSibling;
|
||||
|
||||
if( p )
|
||||
{
|
||||
p->mSibling = group->mSibling;
|
||||
group->mSibling = NULL;
|
||||
mNumGroups --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Console Methods.
|
||||
//=============================================================================
|
||||
// MARK: ---- Console Methods ----
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineMethod( SFXFMODEventGroup, isDataLoaded, bool, (),,
|
||||
"Test whether the resource data for this group has been loaded.\n\n"
|
||||
"@return True if the resource data for this group is currently loaded.\n" )
|
||||
{
|
||||
return object->isDataLoaded();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineMethod( SFXFMODEventGroup, loadData, bool, ( bool loadStreams, bool loadSamples ), ( true, true ),
|
||||
"Load the resource data for this group, if it has not already been loaded (either directly "
|
||||
"or indirectly through a parent group).\n"
|
||||
"This method works recursively and thus data for direct and indirect child groups to this group will be "
|
||||
"loaded as well.\n\n"
|
||||
"@param loadStreams Whether to open streams.\n"
|
||||
"@param loadSamples Whether to load sample banks.\n"
|
||||
"@return True if the data has been successfully loaded; false otherwise.\n\n"
|
||||
"@see SFXFMODProject_resources" )
|
||||
{
|
||||
return object->loadData( loadSamples, loadStreams );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineMethod( SFXFMODEventGroup, freeData, void, (),,
|
||||
"Release the resource data for this group and its subgroups.\n\n"
|
||||
"@see SFXFMODProject_resources" )
|
||||
{
|
||||
object->freeData();
|
||||
}
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODEVENTGROUP_H_
|
||||
#define _SFXFMODEVENTGROUP_H_
|
||||
|
||||
#ifndef _SIMDATABLOCK_H_
|
||||
#include "console/simDatablock.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _CONSOLETYPES_H_
|
||||
#include "console/consoleTypes.h"
|
||||
#endif
|
||||
|
||||
#include "fmod_event.h"
|
||||
|
||||
|
||||
class SFXFMODProject;
|
||||
class SFXFMODEvent;
|
||||
|
||||
|
||||
///
|
||||
class SFXFMODEventGroup : public SimDataBlock
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SimDataBlock Parent;
|
||||
friend class SFXFMODProject;
|
||||
friend class SFXFMODEvent; // mHandle
|
||||
friend class SFXFMODEventSource; // mHandle
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
String mName;
|
||||
|
||||
///
|
||||
U32 mNumEvents;
|
||||
|
||||
///
|
||||
U32 mNumGroups;
|
||||
|
||||
///
|
||||
SFXFMODProject* mProject;
|
||||
|
||||
///
|
||||
SFXFMODEventGroup* mParent;
|
||||
|
||||
///
|
||||
SFXFMODEventGroup* mChildren;
|
||||
|
||||
///
|
||||
SFXFMODEventGroup* mSibling;
|
||||
|
||||
///
|
||||
SFXFMODEvent* mEvents;
|
||||
|
||||
///
|
||||
FMOD_EVENTGROUP* mHandle;
|
||||
|
||||
///
|
||||
U32 mLoadCount;
|
||||
|
||||
/// Project ID for client net sync.
|
||||
S32 mParentId;
|
||||
|
||||
/// Project ID for client net sync.
|
||||
S32 mProjectId;
|
||||
|
||||
///
|
||||
void _load();
|
||||
|
||||
///
|
||||
void _addEvent( SFXFMODEvent* event );
|
||||
|
||||
///
|
||||
void _addGroup( SFXFMODEventGroup* group );
|
||||
|
||||
///
|
||||
void _removeEvent( SFXFMODEvent* event );
|
||||
|
||||
///
|
||||
void _removeGroup( SFXFMODEventGroup* group );
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SFXFMODEventGroup();
|
||||
|
||||
///
|
||||
SFXFMODEventGroup( SFXFMODProject* project, const String& name, SFXFMODEventGroup* parent = NULL );
|
||||
|
||||
///
|
||||
SFXFMODEventGroup( SFXFMODProject* project, FMOD_EVENTGROUP* handle, SFXFMODEventGroup* parent = NULL );
|
||||
|
||||
~SFXFMODEventGroup();
|
||||
|
||||
/// Create the event group object on the FMOD device.
|
||||
void acquire( bool recursive = false );
|
||||
|
||||
/// Release the event group object on the FMOD device.
|
||||
void release();
|
||||
|
||||
///
|
||||
const String& getGroupName() const { return mName; }
|
||||
|
||||
///
|
||||
String getQualifiedName() const;
|
||||
|
||||
///
|
||||
SFXFMODProject* getProject() const { return mProject; }
|
||||
|
||||
/// Return true if the event data for this group has been loaded.
|
||||
bool isDataLoaded() const;
|
||||
|
||||
/// Load the event data for this group.
|
||||
///
|
||||
/// @note Loading is reference-counted.
|
||||
bool loadData( bool samples = true, bool streams = true );
|
||||
|
||||
///
|
||||
void freeData( bool force = false );
|
||||
|
||||
// SimDataBlock.
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual bool preload( bool server, String& errorStr );
|
||||
virtual void packData( BitStream* stream );
|
||||
virtual void unpackData( BitStream* stream );
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT( SFXFMODEventGroup );
|
||||
DECLARE_CATEGORY( "SFX FMOD" );
|
||||
DECLARE_DESCRIPTION( "An event group in an FMOD Designer project." );
|
||||
};
|
||||
|
||||
#endif // !_SFXFMODEVENTGROUP_H_
|
||||
|
|
@ -1,337 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "platform/platform.h"
|
||||
#include "sfx/fmod/sfxFMODEventSource.h"
|
||||
#include "sfx/fmod/sfxFMODEvent.h"
|
||||
#include "sfx/fmod/sfxFMODEventGroup.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( SFXFMODEventSource );
|
||||
|
||||
ConsoleDocClass( SFXFMODEventSource,
|
||||
"@brief A sound source controller playing an %FMOD Designer event (SFXFMODEvent).\n\n"
|
||||
|
||||
"%FMOD event sources are internally created by the sound system to play events from imported %FMOD Designer projects.\n\n"
|
||||
|
||||
"@note This class cannot be instantiated directly by the user. Instead, instances of SFXFMODEventSource will be "
|
||||
"implicitly created by the sound system when playing an SFXFMODEvent.\n\n"
|
||||
|
||||
"@ingroup SFXFMOD\n"
|
||||
);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventSource::SFXFMODEventSource()
|
||||
: mHandle( NULL )
|
||||
{
|
||||
SFXFMODDevice::instance()->smStatNumEventSources ++;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventSource::SFXFMODEventSource( SFXFMODEvent* event )
|
||||
: Parent( event ),
|
||||
mHandle( NULL )
|
||||
{
|
||||
SFXFMODDevice::instance()->smStatNumEventSources ++;
|
||||
|
||||
// Make sure the group has its data loaded.
|
||||
|
||||
SFXFMODEventGroup* group = event->getEventGroup();
|
||||
if( !group->loadData() )
|
||||
return;
|
||||
|
||||
// Create an event instance.
|
||||
|
||||
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
|
||||
event->getEventGroup()->mHandle,
|
||||
event->getEventName(),
|
||||
FMOD_EVENT_DEFAULT,
|
||||
&mHandle ) != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODEventSource::SFXFMODEventSource - failed to open event '%s'", event->getQualifiedName().c_str() );
|
||||
mHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventSource::~SFXFMODEventSource()
|
||||
{
|
||||
SFXFMODDevice::instance()->smStatNumEventSources --;
|
||||
|
||||
if( mHandle )
|
||||
SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, true );
|
||||
|
||||
if( getEvent() )
|
||||
getEvent()->getEventGroup()->freeData();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODEventSource* SFXFMODEventSource::create( SFXFMODEvent* event )
|
||||
{
|
||||
AssertFatal( event != NULL, "SFXFMODEventSource::create - got a NULL event!" );
|
||||
|
||||
// Create the source.
|
||||
|
||||
SFXFMODEventSource* source = new SFXFMODEventSource( event );
|
||||
if( source->mHandle )
|
||||
source->registerObject();
|
||||
else
|
||||
{
|
||||
delete source;
|
||||
source = NULL;
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::play( F32 fadeInTime )
|
||||
{
|
||||
if( getStatus() == SFXStatusPlaying )
|
||||
return;
|
||||
|
||||
if( isPaused() )
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, false );
|
||||
else
|
||||
{
|
||||
AssertFatal( getEvent()->getEventGroup()->isDataLoaded(), "SFXFMODEventSource::play() - event data for group not loaded" );
|
||||
|
||||
if( fadeInTime != -1.f )
|
||||
{
|
||||
U32 fade = U32( fadeInTime * 1000.f );
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
|
||||
mHandle, FMOD_EVENTPROPERTY_FADEIN,
|
||||
&fade, true
|
||||
);
|
||||
}
|
||||
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Start( mHandle );
|
||||
if( result != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODEventSoure::play() - failed to start event: %s", FMODResultToString( result ).c_str() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mPlayTimer.start();
|
||||
_setStatus( SFXStatusPlaying );
|
||||
|
||||
_play();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::stop( F32 fadeOutTime )
|
||||
{
|
||||
if( getStatus() == SFXStatusStopped )
|
||||
return;
|
||||
|
||||
AssertFatal( mHandle, "SFXFMODEvent::stop() - event not acquired" );
|
||||
|
||||
bool immediate = ( fadeOutTime == 0.f );
|
||||
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Stop( mHandle, immediate );
|
||||
if( result != FMOD_OK )
|
||||
Con::errorf( "SFXFMODEventSource::stop() - failed to stop event: %s", FMODResultToString( result ).c_str() );
|
||||
|
||||
mPlayTimer.stop();
|
||||
_setStatus( SFXStatusStopped );
|
||||
|
||||
// Reset fade-in to default in case it got overwritten
|
||||
// in play().
|
||||
|
||||
U32 fade = U32( mFadeInTime * 1000.f );
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
|
||||
mHandle, FMOD_EVENTPROPERTY_FADEIN,
|
||||
&fade, true
|
||||
);
|
||||
|
||||
_stop();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::pause( F32 fadeOutTime )
|
||||
{
|
||||
if( getStatus() != SFXStatusPlaying )
|
||||
return;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, true );
|
||||
|
||||
mPlayTimer.pause();
|
||||
_setStatus( SFXStatusPaused );
|
||||
|
||||
_pause();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::setTransform( const MatrixF& transform )
|
||||
{
|
||||
Parent::setTransform( transform );
|
||||
_update3DAttributes();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::setVelocity( const VectorF& velocity )
|
||||
{
|
||||
Parent::setVelocity( velocity );
|
||||
_update3DAttributes();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_update3DAttributes()
|
||||
{
|
||||
FMOD_VECTOR position;
|
||||
FMOD_VECTOR velocity;
|
||||
FMOD_VECTOR orientation;
|
||||
|
||||
Point3F direction;
|
||||
getTransform().getColumn( 1, &direction );
|
||||
|
||||
TorqueVectorToFMODVector( getTransform().getPosition(), position );
|
||||
TorqueVectorToFMODVector( getVelocity(), velocity );
|
||||
TorqueVectorToFMODVector( direction, orientation );
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Event_Set3DAttributes( mHandle, &position, &velocity, &orientation );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_updateStatus()
|
||||
{
|
||||
if( mStatus == SFXStatusPlaying )
|
||||
{
|
||||
if( !getEvent() )
|
||||
_setStatus( SFXStatusStopped );
|
||||
else
|
||||
{
|
||||
FMOD_EVENT_STATE state;
|
||||
SFXFMODDevice::smFunc->FMOD_Event_GetState( mHandle, &state );
|
||||
|
||||
if( !( state & FMOD_EVENT_STATE_PLAYING ) )
|
||||
_setStatus( SFXStatusStopped );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_updateVolume( const MatrixF& listener )
|
||||
{
|
||||
F32 oldPreAttenuatedVolume = mPreAttenuatedVolume;
|
||||
Parent::_updateVolume( listener );
|
||||
|
||||
if( oldPreAttenuatedVolume != mPreAttenuatedVolume )
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetVolume( mHandle, mPreAttenuatedVolume );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_updatePitch()
|
||||
{
|
||||
F32 oldEffectivePitch = mEffectivePitch;
|
||||
Parent::_updatePitch();
|
||||
|
||||
if( mEffectivePitch != oldEffectivePitch )
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPitch( mHandle, mEffectivePitch - 1.0f, FMOD_EVENT_PITCHUNITS_RAW );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_updatePriority()
|
||||
{
|
||||
//TODO
|
||||
Parent::_updatePriority();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_setMinMaxDistance( F32 min, F32 max )
|
||||
{
|
||||
Parent::_setMinMaxDistance( min, max );
|
||||
_update3DAttributes();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_setFadeTimes( F32 fadeInTime, F32 fadeOutTime )
|
||||
{
|
||||
Parent::_setFadeTimes( fadeInTime, fadeOutTime );
|
||||
|
||||
U32 fadeIn = U32( mFadeInTime * 1000.f );
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
|
||||
mHandle, FMOD_EVENTPROPERTY_FADEIN,
|
||||
&fadeIn, true
|
||||
);
|
||||
|
||||
U32 fadeOut = U32( mFadeOutTime * 1000.f );
|
||||
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
|
||||
mHandle, FMOD_EVENTPROPERTY_FADEOUT,
|
||||
&fadeOut, true
|
||||
);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
|
||||
{
|
||||
Parent::_setCone( innerAngle, outerAngle, outerVolume );
|
||||
_update3DAttributes();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODEventSource::_onParameterEvent( SFXParameter* parameter, SFXParameterEvent event )
|
||||
{
|
||||
Parent::_onParameterEvent( parameter, event );
|
||||
|
||||
// If it's a value-change on a custom parameter,
|
||||
// pass it along to FMOD.
|
||||
|
||||
if( getEvent()
|
||||
&& event == SFXParameterEvent_ValueChanged
|
||||
&& parameter->getChannel() == SFXChannelUser0 )
|
||||
{
|
||||
const char* name = parameter->getInternalName();
|
||||
|
||||
FMOD_EVENTPARAMETER* fmodParameter;
|
||||
if( SFXFMODDevice::smFunc->FMOD_Event_GetParameter( mHandle, name, &fmodParameter ) != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODEventSource::_onParameterEvent - could not access parameter '%s' of event '%s'",
|
||||
name, getEvent()->getQualifiedName().c_str() );
|
||||
return;
|
||||
}
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventParameter_SetValue( fmodParameter, parameter->getValue() );
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODEVENTSOURCE_H_
|
||||
#define _SFXFMODEVENTSOURCE_H_
|
||||
|
||||
#ifndef _SFXSOURCE_H_
|
||||
#include "sfx/sfxSource.h"
|
||||
#endif
|
||||
|
||||
#include "fmod_event.h"
|
||||
|
||||
|
||||
class SFXFMODEvent;
|
||||
|
||||
|
||||
/// An SFXSource that controls the playback of an SFXFMODEvent.
|
||||
///
|
||||
/// SFXFMODEvents can be played back directly through their console methods.
|
||||
/// However, this class integrates them with the remaining SFX system and makes
|
||||
/// events usable wherever SFX tracks are usable though with the important
|
||||
/// distinction that there can only ever be a single source for a given event.
|
||||
///
|
||||
/// Note that calling playback methods directly on an event will cause a source
|
||||
/// for the event to be created if there is not already one.
|
||||
///
|
||||
/// Be aware that using fade-outs in events in combination with play-once sources
|
||||
/// does not work well at the moment.
|
||||
///
|
||||
class SFXFMODEventSource : public SFXSource
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXSource Parent;
|
||||
|
||||
protected:
|
||||
|
||||
/// The event instance handle for this source.
|
||||
FMOD_EVENT* mHandle;
|
||||
|
||||
///
|
||||
SFXFMODEventSource( SFXFMODEvent* event );
|
||||
|
||||
/// Update 3D position, velocity, and orientation from current source transform.
|
||||
void _update3DAttributes();
|
||||
|
||||
// SFXSource.
|
||||
virtual void _updateStatus();
|
||||
virtual void _updateVolume( const MatrixF& listener );
|
||||
virtual void _updatePitch();
|
||||
virtual void _updatePriority();
|
||||
virtual void _onParameterEvent( SFXParameter* parameter, SFXParameterEvent event );
|
||||
virtual void _setMinMaxDistance( F32 min, F32 max );
|
||||
virtual void _setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
|
||||
virtual void _setFadeTimes( F32 fadeInTime, F32 fadeOutTime );
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SFXFMODEventSource();
|
||||
|
||||
virtual ~SFXFMODEventSource();
|
||||
|
||||
/// Return the FMOD event object that is being played back by this source.
|
||||
SFXFMODEvent* getEvent() const { return ( SFXFMODEvent* ) mTrack.getPointer(); }
|
||||
|
||||
/// Create a new source for the given event.
|
||||
static SFXFMODEventSource* create( SFXFMODEvent* event );
|
||||
|
||||
// SFXSource.
|
||||
virtual void play( F32 fadeInTime = -1.f ); // fadeInTime ignored when resuming from paused
|
||||
virtual void stop( F32 fadeOutTime = -1.f ); // fadeOutTime!=0 ignored
|
||||
virtual void pause( F32 fadeOutTime = -1.f ); // fadeOutTime currently ignored
|
||||
virtual void setTransform( const MatrixF& transform );
|
||||
virtual void setVelocity( const VectorF& velocity );
|
||||
|
||||
DECLARE_CONOBJECT( SFXFMODEventSource );
|
||||
DECLARE_CATEGORY( "SFX FMOD" );
|
||||
DECLARE_DESCRIPTION( "An SFX source controlling the playback of an FMOD Designer event." );
|
||||
};
|
||||
|
||||
#endif // !_SFXFMODEVENTSOURCE_H_
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/fmod/sfxFMODPlugin.h"
|
||||
#include "sfx/fmod/sfxFMODEvent.h"
|
||||
#include "sfx/fmod/sfxFMODEventSource.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXSource* SFXFMODPlugin::createSource( SFXTrack* track )
|
||||
{
|
||||
SFXFMODEvent* event = dynamic_cast< SFXFMODEvent* >( track );
|
||||
if( !event )
|
||||
return NULL;
|
||||
|
||||
return SFXFMODEventSource::create( event );
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODPLUGIN_H_
|
||||
#define _SFXFMODPLUGIN_H_
|
||||
|
||||
#ifndef _SFXSYSTEM_H_
|
||||
#include "sfx/sfxSystem.h"
|
||||
#endif
|
||||
|
||||
|
||||
/// SFXSystem plugin that adds the capability to create SFXSources for
|
||||
/// Designer SFXFMODEvents.
|
||||
///
|
||||
/// The plugin will only be installed if an FMOD device has been created.
|
||||
/// While SFXFMODEvents may be constructed without an FMOD device, trying
|
||||
/// to play such an event then will result in an error.
|
||||
///
|
||||
class SFXFMODPlugin : public SFXSystemPlugin
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SFXSystemPlugin Parent;
|
||||
|
||||
///
|
||||
virtual SFXSource* createSource( SFXTrack* track );
|
||||
};
|
||||
|
||||
#endif // !_SFXFMODPLUGIN_H_
|
||||
|
|
@ -1,493 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/fmod/sfxFMODProject.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "sfx/fmod/sfxFMODEvent.h"
|
||||
#include "sfx/fmod/sfxFMODEventGroup.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
#include "core/stringTable.h"
|
||||
#include "core/volume.h"
|
||||
#include "core/util/path.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODProject );
|
||||
|
||||
|
||||
ConsoleDocClass( SFXFMODProject,
|
||||
"@brief An FMOD Designer project loaded into Torque.\n\n"
|
||||
|
||||
"@section SFXFMODProject_resources Resource Loading\n\n"
|
||||
|
||||
"@ingroup SFXFMOD\n"
|
||||
"@ingroup Datablocks"
|
||||
);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODProject::SFXFMODProject()
|
||||
: mHandle( NULL ),
|
||||
mRootGroups( NULL )
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION( mGroups );
|
||||
VECTOR_SET_ASSOCIATION( mEvents );
|
||||
|
||||
SFX->getEventSignal().notify( this, &SFXFMODProject::_onSystemEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SFXFMODProject::~SFXFMODProject()
|
||||
{
|
||||
AssertFatal( mGroups.empty(), "SFXFMODProject::~SFXFMODProject - project still has groups attached" );
|
||||
AssertFatal( mEvents.empty(), "SFXFMODProject::~SFXFMODProject - project still has events attached" );
|
||||
|
||||
if( SFX )
|
||||
SFX->getEventSignal().remove( this, &SFXFMODProject::_onSystemEvent );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::initPersistFields()
|
||||
{
|
||||
addGroup( "FMOD" );
|
||||
|
||||
addField( "fileName", TypeStringFilename, Offset( mFileName, SFXFMODProject ), "The compiled .fev file from FMOD Designer." );
|
||||
addField( "mediaPath", TypeStringFilename, Offset( mMediaPath, SFXFMODProject ), "Path to the media files; if unset, defaults to project directory." );
|
||||
|
||||
endGroup( "FMOD" );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODProject::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
// If this is a non-networked datablock, load the
|
||||
// project data now.
|
||||
|
||||
if( isClientOnly() && !_load() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
|
||||
_clear();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODProject::preload( bool server, String& errorStr )
|
||||
{
|
||||
if( !Parent::preload( server, errorStr ) )
|
||||
return false;
|
||||
|
||||
if( server )
|
||||
{
|
||||
if( mFileName.isEmpty() )
|
||||
{
|
||||
errorStr = String::ToString( "SFXFMODProject::preload - no filename set on %i (%s)",
|
||||
getId(), getName() );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( mGroups.empty() || mEvents.empty() )
|
||||
_load();
|
||||
|
||||
release();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::packData( BitStream* stream )
|
||||
{
|
||||
Parent::packData( stream );
|
||||
|
||||
stream->write( mFileName );
|
||||
stream->write( mMediaPath );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::unpackData( BitStream* stream )
|
||||
{
|
||||
Parent::unpackData( stream );
|
||||
|
||||
stream->read( &mFileName );
|
||||
stream->read( &mMediaPath );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_onSystemEvent( SFXSystemEventType event )
|
||||
{
|
||||
switch( event )
|
||||
{
|
||||
case SFXSystemEvent_DestroyDevice:
|
||||
|
||||
// If the FMOD device is being destroyed,
|
||||
// release all our data.
|
||||
|
||||
if( SFXFMODDevice::instance() )
|
||||
release();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_clear()
|
||||
{
|
||||
release();
|
||||
|
||||
for( U32 i = 0; i < mGroups.size(); ++ i )
|
||||
if( !mGroups[ i ]->isRemoved() )
|
||||
mGroups[ i ]->deleteObject();
|
||||
|
||||
mGroups.clear();
|
||||
mEvents.clear();
|
||||
|
||||
mRootGroups = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool SFXFMODProject::_load()
|
||||
{
|
||||
const Torque::Path eventScriptFileName = mFileName + ".cs";
|
||||
const Torque::Path eventScriptFileNameDSO = eventScriptFileName + ".dso";
|
||||
const bool eventScriptFileExists = Torque::FS::IsFile( eventScriptFileName );
|
||||
const bool eventScriptFileDSOExists = Torque::FS::IsFile( eventScriptFileNameDSO );
|
||||
|
||||
// Check if we need to (re-)generate the event script file.
|
||||
|
||||
bool needToGenerateEventScriptFile = false;
|
||||
if( ( !eventScriptFileExists && !eventScriptFileDSOExists )
|
||||
|| ( Torque::FS::CompareModifiedTimes( mFileName, eventScriptFileName ) > 0
|
||||
|| Torque::FS::CompareModifiedTimes( mFileName, eventScriptFileNameDSO ) > 0 ) )
|
||||
needToGenerateEventScriptFile = true;
|
||||
|
||||
// If we need to generate, check if we can.
|
||||
|
||||
SFXFMODDevice* fmodDevice = SFXFMODDevice::instance();
|
||||
if( needToGenerateEventScriptFile && !fmodDevice )
|
||||
{
|
||||
// If we have neither FMOD nor the event scripts (even if outdated),
|
||||
// there's nothing we can do.
|
||||
|
||||
if( !eventScriptFileExists && !eventScriptFileDSOExists )
|
||||
{
|
||||
Con::errorf( "SFXFMODProject::_load() - event script for '%s' does not exist and device is not FMOD; load this project under FMOD first",
|
||||
mFileName.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use the oudated versions.
|
||||
|
||||
Con::warnf( "SFXMODProject::_load() - event script for '%s' is outdated and device is not FMOD; event data may not match .fev contents",
|
||||
mFileName.c_str() );
|
||||
needToGenerateEventScriptFile = false;
|
||||
}
|
||||
|
||||
// If we don't need to regenerate, try executing the event script now.
|
||||
|
||||
if( !needToGenerateEventScriptFile )
|
||||
{
|
||||
if( ( eventScriptFileExists || eventScriptFileDSOExists )
|
||||
&& !Con::evaluatef( "exec( \"%s\" );", eventScriptFileName.getFullPath().c_str() ) )
|
||||
{
|
||||
Con::errorf( "SFXFMODProject::_load() - failed to execute event script for '%s'%s",
|
||||
mFileName.c_str(),
|
||||
fmodDevice != NULL ? "; trying to regenerate" : ""
|
||||
);
|
||||
|
||||
if( !fmodDevice )
|
||||
return false;
|
||||
|
||||
needToGenerateEventScriptFile = true;
|
||||
}
|
||||
else
|
||||
Con::printf( "SFXFMODProject - %s: Loaded event script", getName() );
|
||||
}
|
||||
|
||||
// If we need to generate the event script file,
|
||||
// load the FMOD project now and then emit the file.
|
||||
|
||||
if( needToGenerateEventScriptFile )
|
||||
{
|
||||
// Try to load the project.
|
||||
|
||||
acquire();
|
||||
|
||||
if( !mHandle )
|
||||
return false;
|
||||
|
||||
// Get the project info.
|
||||
|
||||
FMOD_EVENT_PROJECTINFO info;
|
||||
|
||||
int numEvents;
|
||||
int numGroups;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventProject_GetInfo( mHandle, &info );
|
||||
SFXFMODDevice::smFunc->FMOD_EventProject_GetNumEvents( mHandle, &numEvents );
|
||||
SFXFMODDevice::smFunc->FMOD_EventProject_GetNumGroups( mHandle, &numGroups );
|
||||
|
||||
Con::printf( "SFXFMODProject - %s: Loading '%s' from '%s' (index: %i, events: %i, groups: %i)",
|
||||
getName(), info.name, mFileName.c_str(), info.index, numEvents, numGroups );
|
||||
|
||||
// Load the root groups.
|
||||
|
||||
for( U32 i = 0; i < numGroups; ++ i )
|
||||
{
|
||||
FMOD_EVENTGROUP* group;
|
||||
if( SFXFMODDevice::smFunc->FMOD_EventProject_GetGroupByIndex( mHandle, i, true, &group ) == FMOD_OK )
|
||||
{
|
||||
SFXFMODEventGroup* object = new SFXFMODEventGroup( this, group );
|
||||
|
||||
object->mSibling = mRootGroups;
|
||||
mRootGroups = object;
|
||||
|
||||
String qualifiedName = FMODEventPathToTorqueName( object->getQualifiedName() );
|
||||
|
||||
if( !isClientOnly() )
|
||||
object->assignId();
|
||||
|
||||
object->registerObject( String::ToString( "%s_%s", getName(), qualifiedName.c_str() ) );
|
||||
if( isClientOnly() )
|
||||
Sim::getRootGroup()->addObject( object );
|
||||
|
||||
object->_load();
|
||||
}
|
||||
}
|
||||
|
||||
// Create the event script file.
|
||||
|
||||
FileStream stream;
|
||||
if( !stream.open( eventScriptFileName.getFullPath(), Torque::FS::File::Write ) )
|
||||
{
|
||||
Con::errorf( "SFXFMODProject::_load - could not create event script file for '%s'", mFileName.c_str() );
|
||||
return true; // Don't treat as failure.
|
||||
}
|
||||
|
||||
// Write a header.
|
||||
|
||||
stream.writeText( String::ToString( "// This file has been auto-generated from '%s'\n", mFileName.c_str() ) );
|
||||
stream.writeText( "// Do not edit this file manually and do not move it away from the Designer file.\n\n" );
|
||||
|
||||
// Write the group objects.
|
||||
|
||||
for( U32 i = 0; i < mGroups.size(); ++ i )
|
||||
{
|
||||
mGroups[ i ]->write( stream, 0 );
|
||||
stream.writeText( "\n" );
|
||||
}
|
||||
|
||||
// Write the event objects along with their
|
||||
// SFXDescriptions.
|
||||
|
||||
for( U32 i = 0; i < mEvents.size(); ++ i )
|
||||
{
|
||||
mEvents[ i ]->getDescription()->write( stream, 0 );
|
||||
mEvents[ i ]->write( stream, 0 );
|
||||
stream.writeText( "\n" );
|
||||
}
|
||||
|
||||
Con::printf( "SFXFMODProject - %s: Generated event script '%s'", getName(), eventScriptFileName.getFullPath().c_str() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::acquire( bool recursive )
|
||||
{
|
||||
// Load the project file.
|
||||
|
||||
if( !mHandle )
|
||||
{
|
||||
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventSystem_Load(
|
||||
SFXFMODDevice::smEventSystem,
|
||||
mFileName.c_str(),
|
||||
( FMOD_EVENT_LOADINFO* ) 0,
|
||||
&mHandle
|
||||
);
|
||||
|
||||
if( result != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODProject::acquire - could not load '%s' (%s)",
|
||||
mFileName.c_str(), FMODResultToString( result ).c_str() );
|
||||
mHandle = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
Con::printf( "SFXFMODProject - %s: Opened project '%s'", getName(), mFileName.c_str() );
|
||||
|
||||
// Set the media path.
|
||||
|
||||
String mediaPath;
|
||||
if( !mMediaPath.isEmpty() )
|
||||
{
|
||||
mediaPath = mMediaPath;
|
||||
if( mediaPath[ mediaPath.length() - 1 ] != '/' )
|
||||
mediaPath += '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set to project directory.
|
||||
|
||||
Torque::Path path = mFileName;
|
||||
if( path.getRoot().isEmpty() )
|
||||
path.setRoot( "game" );
|
||||
path.setFileName( "" );
|
||||
path.setExtension( "" );
|
||||
|
||||
mediaPath = path.getFullPath() + '/';
|
||||
}
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventSystem_SetMediaPath(
|
||||
SFXFMODDevice::smEventSystem,
|
||||
mediaPath.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
// Acquire the root groups.
|
||||
|
||||
if( recursive )
|
||||
for( SFXFMODEventGroup* group = mRootGroups; group != NULL; group = group->mSibling )
|
||||
group->acquire( true );
|
||||
|
||||
SFXFMODDevice::instance()->updateMemUsageStats();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::release()
|
||||
{
|
||||
if( !mHandle )
|
||||
return;
|
||||
|
||||
Con::printf( "SFXFMODProject - %s: Closing project '%s'",
|
||||
getName(), mFileName.c_str() );
|
||||
|
||||
// Clear media path.
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventSystem_SetMediaPath(
|
||||
SFXFMODDevice::smEventSystem, "" );
|
||||
|
||||
// Release the root groups.
|
||||
|
||||
for( SFXFMODEventGroup* group = mRootGroups; group != NULL; group = group->mSibling )
|
||||
group->release();
|
||||
|
||||
// Release the project.
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_EventProject_Release( mHandle );
|
||||
mHandle = NULL;
|
||||
|
||||
SFXFMODDevice::instance()->updateMemUsageStats();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_addEvent( SFXFMODEvent* event )
|
||||
{
|
||||
mEvents.push_back( event );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_addGroup( SFXFMODEventGroup* group )
|
||||
{
|
||||
mGroups.push_back( group );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_removeEvent( SFXFMODEvent* event )
|
||||
{
|
||||
for( U32 i = 0; i < mEvents.size(); ++ i )
|
||||
if( mEvents[ i ] == event )
|
||||
{
|
||||
mEvents.erase( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProject::_removeGroup( SFXFMODEventGroup* group )
|
||||
{
|
||||
// Remove from group array.
|
||||
|
||||
for( U32 i = 0; i < mGroups.size(); ++ i )
|
||||
if( mGroups[ i ] == group )
|
||||
{
|
||||
mGroups.erase( i );
|
||||
break;;
|
||||
}
|
||||
|
||||
// Unlink if it's a root group.
|
||||
|
||||
if( !group->mParent )
|
||||
{
|
||||
if( group == mRootGroups )
|
||||
{
|
||||
mRootGroups = group->mSibling;
|
||||
group->mSibling = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SFXFMODEventGroup* p = mRootGroups;
|
||||
while( p && p->mSibling != group )
|
||||
p = p->mSibling;
|
||||
|
||||
if( p )
|
||||
{
|
||||
p->mSibling = group->mSibling;
|
||||
group->mSibling = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODPROJECT_H_
|
||||
#define _SFXFMODPROJECT_H_
|
||||
|
||||
#ifndef _SIMDATABLOCK_H_
|
||||
#include "console/simDatablock.h"
|
||||
#endif
|
||||
#ifndef _CONSOLETYPES_H_
|
||||
#include "console/consoleTypes.h"
|
||||
#endif
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
#endif
|
||||
#ifndef _SFXSYSTEM_H_
|
||||
#include "sfx/sfxSystem.h"
|
||||
#endif
|
||||
|
||||
#include "fmod_event.h"
|
||||
|
||||
|
||||
class SFXFMODEvent;
|
||||
class SFXFMODEventGroup;
|
||||
class SimGroup;
|
||||
|
||||
|
||||
|
||||
/// Datablock that loads an FMOD Designer project.
|
||||
///
|
||||
/// All events in the project are automatically made available as SFXFMODEvent track
|
||||
/// datablock instances. Each event object is automatically named by substituting
|
||||
/// the slashes in its fully qualified name with underscores and preprending the project
|
||||
/// name to this; event 'group1/group2/event' in the SFXFMODProject instance called
|
||||
/// 'project', for example, will be available as a TorqueScript object called
|
||||
/// 'project_group1_group2_event'.
|
||||
///
|
||||
/// This class also works in a client-server environment where the server is
|
||||
/// not running FMOD. The event objects are cached in an auto-generated TorqueScript
|
||||
/// file alongside the .fev project file (x/y.fev -> x/y.fev.cs) which, when available
|
||||
/// and up-to-date, does not require FMOD for the server-side objects to correctly
|
||||
/// initialize.
|
||||
///
|
||||
/// To establish good loading behavior and for good memory management, it is necessary to
|
||||
/// wisely distribute events to groups and to manually pre-load groups. The best solution
|
||||
/// probably is to have one group of common events that is loaded during game startup and
|
||||
/// then have one event group for each level in the game that is only loaded for the
|
||||
/// duration of its particular level.
|
||||
///
|
||||
/// SFXFMODProject will propagate it's networking model to all its contents. This means
|
||||
/// that if the project is a non-networked datablock, then all event groups, events, and
|
||||
/// descriptions contained in the project will also be non-networked datablocks.
|
||||
///
|
||||
/// It usually makes the most sense to use non-networked ("client-only") datablocks as
|
||||
/// otherwise the FMOD datablocks will be purged on each mission load.
|
||||
///
|
||||
/// @note Only one project's music data can ever be loaded at any one time.
|
||||
/// Usually you wouldn't want more than a single SFXFMODProject instance in your game
|
||||
/// data. Also, only a single media path can be set through the designer API so when
|
||||
/// loading multiple projects, note that each project will set the media path to its
|
||||
/// own directory. For data loading to work, all project thus need to be placed in
|
||||
/// the same directory.
|
||||
///
|
||||
class SFXFMODProject : public SimDataBlock
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SimDataBlock Parent;
|
||||
friend class SFXFMODEventGroup; // _addGroup
|
||||
friend class SFXFMODEvent; // _addEvent
|
||||
|
||||
protected:
|
||||
|
||||
///
|
||||
String mFileName;
|
||||
|
||||
///
|
||||
String mMediaPath;
|
||||
|
||||
///
|
||||
SFXFMODEventGroup* mRootGroups;
|
||||
|
||||
/// A flat list of all the groups in this projet.
|
||||
Vector< SFXFMODEventGroup* > mGroups;
|
||||
|
||||
/// A flat list of all the events in the project.
|
||||
Vector< SFXFMODEvent* > mEvents;
|
||||
|
||||
///
|
||||
FMOD_EVENTPROJECT* mHandle;
|
||||
|
||||
///
|
||||
void _onSystemEvent( SFXSystemEventType event );
|
||||
|
||||
///
|
||||
void _clear();
|
||||
|
||||
///
|
||||
bool _load();
|
||||
|
||||
///
|
||||
void _addEvent( SFXFMODEvent* event );
|
||||
|
||||
///
|
||||
void _addGroup( SFXFMODEventGroup* group );
|
||||
|
||||
///
|
||||
void _removeEvent( SFXFMODEvent* event );
|
||||
|
||||
///
|
||||
void _removeGroup( SFXFMODEventGroup* group );
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
SFXFMODProject();
|
||||
|
||||
virtual ~SFXFMODProject();
|
||||
|
||||
///
|
||||
void acquire( bool recursive = false );
|
||||
|
||||
///
|
||||
void release();
|
||||
|
||||
///
|
||||
const String& getFileName() const { return mFileName; }
|
||||
|
||||
// SimDataBlock.
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
virtual bool preload( bool server, String& errorStr );
|
||||
virtual void packData( BitStream* stream );
|
||||
virtual void unpackData( BitStream* stream );
|
||||
|
||||
static void initPersistFields();
|
||||
|
||||
DECLARE_CONOBJECT( SFXFMODProject );
|
||||
DECLARE_CATEGORY( "SFX FMOD" );
|
||||
DECLARE_DESCRIPTION( "An FMOD Designer project." );
|
||||
};
|
||||
|
||||
#endif // !_SFXFMODPROJECT_H_
|
||||
|
|
@ -1,398 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/fmod/sfxFMODDevice.h"
|
||||
#include "core/util/safeRelease.h"
|
||||
#include "console/console.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "core/module.h"
|
||||
#include "console/consoleTypes.h"
|
||||
|
||||
|
||||
class SFXFMODProvider : public SFXProvider
|
||||
{
|
||||
public:
|
||||
|
||||
SFXFMODProvider()
|
||||
: SFXProvider( "FMOD" )
|
||||
{
|
||||
Con::addVariable( "$SFX::Device::fmodNumEventSources", TypeS32, &SFXFMODDevice::smStatNumEventSources,
|
||||
"The current number of SFXFMODEventSource instances in the system.\n"
|
||||
"This tells the number of sounds in the system that are currently playing FMOD Designer events.\n\n"
|
||||
"@note Only relevant if an %FMOD sound device is used.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$SFX::Device::fmodCoreMem", TypeS32, &SFXFMODDevice::smStatMemUsageCore,
|
||||
"Current number of bytes allocated by the core %FMOD sound system.\n\n"
|
||||
"@note Only relevant if an %FMOD sound device is used.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$SFX::Device::fmodEventMem", TypeS32, &SFXFMODDevice::smStatMemUsageEvents,
|
||||
"Current number of bytes allocated by the %FMOD Designer event system.\n\n"
|
||||
"@note Only relevant if an %FMOD sound device is used and the FMOD event DLL is loaded.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
|
||||
Con::addVariable( "$pref::SFX::FMOD::disableSoftware", TypeBool, &SFXFMODDevice::smPrefDisableSoftware,
|
||||
"Whether to disable the %FMOD software mixer to conserve memory.\n"
|
||||
"All sounds not created with SFXDescription::useHardware or using DSP effects will fail to load.\n\n"
|
||||
"@note Only applies when using an %FMOD sound device.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$pref::SFX::FMOD::useSoftwareHRTF", TypeBool, &SFXFMODDevice::smPrefUseSoftwareHRTF,
|
||||
"Whether to enable HRTF in %FMOD's software mixer.\n"
|
||||
"This will add a lowpass filter effect to the DSP effect chain of all sounds mixed in software.\n\n"
|
||||
"@note Only applies when using an %FMOD sound device.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$pref::SFX::FMOD::enableProfile", TypeBool, &SFXFMODDevice::smPrefEnableProfile,
|
||||
"Whether to enable support for %FMOD's profiler.\n\n"
|
||||
"@note Only applies when using an %FMOD sound device.\n\n"
|
||||
"@ref FMOD_profiler\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$pref::SFX::FMOD::DSoundHRTF", TypeString, &SFXFMODDevice::smPrefDSoundHRTF,
|
||||
"The type of HRTF to use for hardware-mixed 3D sounds when %FMOD is using DirectSound for sound output "
|
||||
"and hardware-acceleration is not available.\n\n"
|
||||
"Options are\n"
|
||||
"- \"none\": simple stereo panning/doppler/attenuation\n"
|
||||
"- \"light\": slightly higher quality than \"none\"\n"
|
||||
"- \"full\": full quality 3D playback\n\n"
|
||||
"@note Only applies when using an %FMOD sound device.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
Con::addVariable( "$pref::SFX::FMOD::pluginPath", TypeString, &SFXFMODDevice::smPrefPluginPath,
|
||||
"%Path to additional %FMOD plugins.\n\n"
|
||||
"@note Only applies when using an %FMOD sound device.\n\n"
|
||||
"@ingroup SFXFMOD" );
|
||||
}
|
||||
virtual ~SFXFMODProvider();
|
||||
|
||||
protected:
|
||||
FModFNTable mFMod;
|
||||
|
||||
struct FModDeviceInfo : SFXDeviceInfo
|
||||
{
|
||||
FMOD_CAPS mCaps;
|
||||
FMOD_SPEAKERMODE mSpeakerMode;
|
||||
};
|
||||
|
||||
void init();
|
||||
|
||||
bool _createSystem();
|
||||
|
||||
public:
|
||||
|
||||
SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers );
|
||||
|
||||
};
|
||||
|
||||
MODULE_BEGIN( FMOD )
|
||||
|
||||
MODULE_INIT_BEFORE( SFX )
|
||||
MODULE_SHUTDOWN_AFTER( SFX )
|
||||
|
||||
SFXFMODProvider* mProvider;
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
mProvider = new SFXFMODProvider;
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
delete mProvider;
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helper
|
||||
|
||||
bool fmodBindFunction( DLibrary *dll, void *&fnAddress, const char* name )
|
||||
{
|
||||
if( !dll )
|
||||
return false;
|
||||
|
||||
fnAddress = dll->bind( name );
|
||||
|
||||
if (!fnAddress)
|
||||
Con::warnf( "FMOD Loader: DLL bind failed for %s", name );
|
||||
|
||||
return fnAddress != 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void SFXFMODProvider::init()
|
||||
{
|
||||
#ifdef TORQUE_FMOD_STATIC
|
||||
|
||||
// FMOD statically linked.
|
||||
|
||||
mFMod.isLoaded = true;
|
||||
#define FMOD_FUNCTION(fn_name, fn_args) \
|
||||
(*(void**)&mFMod.fn_name.fn) = &fn_name;
|
||||
|
||||
#ifndef TORQUE_FMOD_NO_EVENTS
|
||||
mFMod.eventIsLoaded = true;
|
||||
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
|
||||
(*(void**)&mFMod.fn_name.fn) = &fn_name;
|
||||
#else
|
||||
#define FMOD_EVENT_FUNCTION( fn_name, fn_args )
|
||||
#endif
|
||||
|
||||
#include FMOD_FN_FILE
|
||||
|
||||
#undef FMOD_FUNCTION
|
||||
#undef FMOD_EVENT_FUNCTION
|
||||
|
||||
#else
|
||||
|
||||
// FMOD dynamically linked.
|
||||
|
||||
const char* dllName;
|
||||
const char* pDllName; // plugin-based DLL
|
||||
const char* eventDllName;
|
||||
|
||||
#ifdef _WIN64
|
||||
dllName = "fmodex64.dll";
|
||||
pDllName = "fmodexp64.dll";
|
||||
eventDllName = "fmod_event64.dll";
|
||||
#elif defined(TORQUE_OS_WIN)
|
||||
dllName = "fmodex.dll";
|
||||
pDllName = "fmodexp.dll";
|
||||
eventDllName = "fmod_event.dll";
|
||||
#elif defined( TORQUE_OS_MAC )
|
||||
dllName = "libfmodex.dylib";
|
||||
pDllName = "libfmodexp.dylib";
|
||||
eventDllName = "libfmodevent.dylib";
|
||||
#else
|
||||
# warning Need to set FMOD DLL filename for platform.
|
||||
return;
|
||||
#endif
|
||||
|
||||
// Grab the functions we'll want from the fmod DLL.
|
||||
mFMod.dllRef = OsLoadLibrary( dllName );
|
||||
|
||||
// Try the plugin-based version.
|
||||
if( !mFMod.dllRef )
|
||||
mFMod.dllRef = OsLoadLibrary( pDllName );
|
||||
|
||||
if(!mFMod.dllRef)
|
||||
{
|
||||
Con::warnf( "SFXFMODProvider - Could not locate '%s' or '%s' - FMOD not available.", dllName, pDllName );
|
||||
return;
|
||||
}
|
||||
|
||||
mFMod.eventDllRef = OsLoadLibrary( eventDllName );
|
||||
if(!mFMod.eventDllRef)
|
||||
Con::warnf( "SFXFMODProvider - Could not locate %s - FMOD Designer integration not available.", eventDllName );
|
||||
|
||||
mFMod.isLoaded = true;
|
||||
mFMod.eventIsLoaded = true;
|
||||
|
||||
#define FMOD_FUNCTION(fn_name, fn_args) \
|
||||
mFMod.isLoaded &= fmodBindFunction(mFMod.dllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
|
||||
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
|
||||
mFMod.eventIsLoaded &= fmodBindFunction(mFMod.eventDllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
|
||||
|
||||
#include FMOD_FN_FILE
|
||||
|
||||
#undef FMOD_FUNCTION
|
||||
#undef FMOD_EVENT_FUNCTION
|
||||
|
||||
if(mFMod.isLoaded == false)
|
||||
{
|
||||
Con::warnf("SFXFMODProvider - Could not load %s - FMOD not available.", dllName);
|
||||
return;
|
||||
}
|
||||
if( !mFMod.eventIsLoaded && mFMod.eventDllRef )
|
||||
Con::warnf("SFXFMODProvider - Could not load %s - FMOD Designer integration not available.", eventDllName);
|
||||
|
||||
#endif
|
||||
|
||||
FMOD_RESULT res;
|
||||
|
||||
// Create the FMOD system object.
|
||||
|
||||
if( !_createSystem() )
|
||||
return;
|
||||
|
||||
// Check that the Ex API version is OK.
|
||||
|
||||
unsigned int version;
|
||||
res = mFMod.FMOD_System_GetVersion(SFXFMODDevice::smSystem, &version);
|
||||
FModAssert(res, "SFXFMODProvider - Failed to get FMOD version!");
|
||||
|
||||
Con::printf( "SFXFMODProvider - FMOD Ex API version: %x.%x.%x",
|
||||
( version & 0xffff0000 ) >> 16,
|
||||
( version & 0x0000ff00 ) >> 8,
|
||||
( version & 0x000000ff )
|
||||
);
|
||||
|
||||
if(version < FMOD_VERSION)
|
||||
{
|
||||
Con::warnf("SFXFMODProvider - FMOD Ex API version in DLL is too old - FMOD not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the Designer API version is ok.
|
||||
|
||||
if( mFMod.eventIsLoaded )
|
||||
{
|
||||
res = mFMod.FMOD_EventSystem_GetVersion( SFXFMODDevice::smEventSystem, &version );
|
||||
FModAssert(res, "SFXFMODProvider - Failed to get FMOD version!");
|
||||
|
||||
Con::printf( "SFXFMODProvider - FMOD Designer API version: %x.%x.%x",
|
||||
( version & 0xffff0000 ) >> 16,
|
||||
( version & 0x0000ff00 ) >> 8,
|
||||
( version & 0x000000ff )
|
||||
);
|
||||
|
||||
if( version < FMOD_EVENT_VERSION )
|
||||
{
|
||||
Con::errorf( "SFXFMODProvider - FMOD Designer API version in DLL is too old!" );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, enumerate our devices.
|
||||
int numDrivers;
|
||||
res = mFMod.FMOD_System_GetNumDrivers(SFXFMODDevice::smSystem, &numDrivers);
|
||||
FModAssert(res, "SFXFMODProvider - Failed to get driver count - FMOD not available.");
|
||||
|
||||
char nameBuff[256];
|
||||
|
||||
for(S32 i=0; i<numDrivers; i++)
|
||||
{
|
||||
res = mFMod.FMOD_System_GetDriverInfo(SFXFMODDevice::smSystem, i, nameBuff, 256, ( FMOD_GUID* ) NULL);
|
||||
if( res != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODProvider - Failed to get driver name (%s)", FMODResultToString( res ).c_str() );
|
||||
continue;
|
||||
}
|
||||
nameBuff[ 255 ] = '\0';
|
||||
|
||||
FMOD_CAPS caps;
|
||||
FMOD_SPEAKERMODE speakerMode;
|
||||
res = mFMod.FMOD_System_GetDriverCaps( SFXFMODDevice::smSystem, i, &caps, ( int* ) 0, &speakerMode );
|
||||
if( res != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODProvider - Failed to get driver caps (%s)", FMODResultToString( res ).c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Great - got something - so add it to the list of options.
|
||||
FModDeviceInfo *fmodInfo = new FModDeviceInfo();
|
||||
fmodInfo->name = String( nameBuff );
|
||||
fmodInfo->hasHardware = caps & FMOD_CAPS_HARDWARE;
|
||||
fmodInfo->maxBuffers = 32;
|
||||
fmodInfo->driver = String();
|
||||
fmodInfo->mCaps = caps;
|
||||
fmodInfo->mSpeakerMode = speakerMode;
|
||||
|
||||
mDeviceInfo.push_back(fmodInfo);
|
||||
}
|
||||
|
||||
// Did we get any devices?
|
||||
if ( mDeviceInfo.empty() )
|
||||
{
|
||||
Con::warnf( "SFXFMODProvider - No valid devices found - FMOD not available." );
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: FMOD_Memory_Initialize
|
||||
#ifdef TORQUE_OS_XENON
|
||||
const dsize_t memSz = 5 * 1024 * 1024;
|
||||
void *memBuffer = XPhysicalAlloc( memSz, MAXULONG_PTR, 0, PAGE_READWRITE );
|
||||
mFMod.FMOD_Memory_Initialize( memBuffer, memSz, FMOD_MEMORY_ALLOCCALLBACK(NULL), FMOD_MEMORY_REALLOCCALLBACK(NULL), FMOD_MEMORY_FREECALLBACK(NULL) );
|
||||
#endif
|
||||
|
||||
// Wow, we made it - register the provider.
|
||||
regProvider( this );
|
||||
}
|
||||
|
||||
SFXFMODProvider::~SFXFMODProvider()
|
||||
{
|
||||
if( SFXFMODDevice::smEventSystem )
|
||||
{
|
||||
mFMod.FMOD_EventSystem_Release( SFXFMODDevice::smEventSystem );
|
||||
SFXFMODDevice::smEventSystem = NULL;
|
||||
SFXFMODDevice::smSystem = NULL;
|
||||
}
|
||||
else if( SFXFMODDevice::smSystem )
|
||||
{
|
||||
mFMod.FMOD_System_Release( SFXFMODDevice::smSystem );
|
||||
SFXFMODDevice::smSystem = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SFXDevice* SFXFMODProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers )
|
||||
{
|
||||
FModDeviceInfo* info = dynamic_cast< FModDeviceInfo* >
|
||||
( _findDeviceInfo( deviceName ) );
|
||||
|
||||
if( !info )
|
||||
return NULL;
|
||||
|
||||
if( !SFXFMODDevice::smSystem && !_createSystem() )
|
||||
return false;
|
||||
|
||||
SFXFMODDevice* device = new SFXFMODDevice(this, &mFMod, 0, info->name );
|
||||
if( !device->_init() )
|
||||
SAFE_DELETE( device );
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
bool SFXFMODProvider::_createSystem()
|
||||
{
|
||||
AssertFatal( !SFXFMODDevice::smEventSystem, "SFXFMODProvider::_createSystem() - event system already created!" );
|
||||
AssertFatal( !SFXFMODDevice::smSystem, "SFXFMODProvider::_createSystem() - system already created!" );
|
||||
|
||||
if( mFMod.eventIsLoaded )
|
||||
{
|
||||
FMOD_RESULT res = mFMod.FMOD_EventSystem_Create( &SFXFMODDevice::smEventSystem );
|
||||
if( res != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODProvider - could not create the FMOD event system." );
|
||||
return false;
|
||||
}
|
||||
|
||||
res = mFMod.FMOD_EventSystem_GetSystemObject( SFXFMODDevice::smEventSystem, &SFXFMODDevice::smSystem );
|
||||
if( res != FMOD_OK )
|
||||
{
|
||||
Con::errorf( "SFXFMODProvider - could not retrieve the FMOD system object." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate the FMod system.
|
||||
|
||||
FMOD_RESULT res = mFMod.FMOD_System_Create( &SFXFMODDevice::smSystem );
|
||||
if( res != FMOD_OK )
|
||||
{
|
||||
// Failed - deal with it!
|
||||
Con::errorf("SFXFMODProvider - could not create the FMOD system.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,303 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 "platform/platform.h"
|
||||
#include "sfx/fmod/sfxFMODVoice.h"
|
||||
|
||||
#include "sfx/fmod/sfxFMODBuffer.h"
|
||||
#include "sfx/fmod/sfxFMODDevice.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
|
||||
|
||||
SFXFMODVoice* SFXFMODVoice::create( SFXFMODDevice *device,
|
||||
SFXFMODBuffer *buffer )
|
||||
{
|
||||
AssertFatal( device, "SFXFMODVoice::create() - Got null device!" );
|
||||
AssertFatal( buffer, "SFXFMODVoice::create() - Got null buffer!" );
|
||||
|
||||
return new SFXFMODVoice( device, buffer );
|
||||
}
|
||||
|
||||
SFXFMODVoice::SFXFMODVoice( SFXFMODDevice *device,
|
||||
SFXFMODBuffer *buffer )
|
||||
: Parent( buffer ),
|
||||
mDevice( device ),
|
||||
mChannel( NULL )
|
||||
{
|
||||
AssertFatal( device, "SFXFMODVoice::SFXFMODVoice() - No device assigned!" );
|
||||
AssertFatal( buffer, "SFXFMODVoice::SFXFMODVoice() - No buffer assigned!" );
|
||||
AssertFatal( _getBuffer()->mSound != NULL, "SFXFMODVoice::SFXFMODVoice() - No sound assigned!" );
|
||||
}
|
||||
|
||||
SFXFMODVoice::~SFXFMODVoice()
|
||||
{
|
||||
_stop();
|
||||
}
|
||||
|
||||
SFXStatus SFXFMODVoice::_status() const
|
||||
{
|
||||
if( mChannel )
|
||||
{
|
||||
FMOD_BOOL isTrue = false;
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_GetPaused( mChannel, &isTrue );
|
||||
if ( isTrue )
|
||||
return SFXStatusPaused;
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_IsPlaying( mChannel, &isTrue );
|
||||
if ( isTrue )
|
||||
return SFXStatusPlaying;
|
||||
}
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Stop( mChannel );
|
||||
mChannel = NULL;
|
||||
|
||||
return SFXStatusStopped;
|
||||
}
|
||||
|
||||
void SFXFMODVoice::_play()
|
||||
{
|
||||
if( !mChannel )
|
||||
_assignChannel();
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPaused( mChannel, false );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::_pause()
|
||||
{
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPaused( mChannel, true );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::_stop()
|
||||
{
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Stop(mChannel);
|
||||
|
||||
mChannel = NULL;
|
||||
}
|
||||
|
||||
void SFXFMODVoice::_seek( U32 sample )
|
||||
{
|
||||
if( !mChannel )
|
||||
_assignChannel();
|
||||
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPosition
|
||||
( mChannel, sample, FMOD_TIMEUNIT_PCM );
|
||||
}
|
||||
|
||||
bool SFXFMODVoice::_assignChannel()
|
||||
{
|
||||
AssertFatal( _getBuffer()->mSound != NULL, "SFXFMODVoice::_assignChannel() - No sound assigned!" );
|
||||
|
||||
// we start playing it now in the paused state, so that we can immediately set attributes that
|
||||
// depend on having a channel (position, volume, etc). According to the FMod docs
|
||||
// it is ok to do this.
|
||||
bool success = SFXFMODDevice::smFunc->FMOD_System_PlaySound(
|
||||
SFXFMODDevice::smSystem,
|
||||
FMOD_CHANNEL_FREE,
|
||||
_getBuffer()->mSound,
|
||||
true,
|
||||
&mChannel ) == FMOD_OK;
|
||||
|
||||
if( success )
|
||||
{
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetMode( mChannel, mMode );
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetLoopCount( mChannel, mMode & FMOD_LOOP_NORMAL ? -1 : 0 );
|
||||
|
||||
if( mSetFlags.test( SET_Velocity ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, ( const FMOD_VECTOR* ) NULL, &mVelocity );
|
||||
if( mSetFlags.test( SET_MinMaxDistance ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DMinMaxDistance(mChannel, mMinDistance, mMaxDistance);
|
||||
if( mSetFlags.test( SET_Transform ) )
|
||||
{
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, &mPosition, ( const FMOD_VECTOR* ) NULL );
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeOrientation( mChannel, &mDirection );
|
||||
}
|
||||
if( mSetFlags.test( SET_Volume ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetVolume(mChannel, mVolume);
|
||||
if( mSetFlags.test( SET_Pitch ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetFrequency( mChannel, mFrequency );
|
||||
if( mSetFlags.test( SET_Cone ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeSettings(
|
||||
mChannel,
|
||||
mConeInnerAngle,
|
||||
mConeOuterAngle,
|
||||
mConeOuterVolume );
|
||||
if( mSetFlags.test( SET_Priority ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPriority( mChannel, TorquePriorityToFMODPriority( mPriority ) );
|
||||
if( mSetFlags.test( SET_Reverb ) )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetReverbProperties( mChannel, &mReverb );
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
U32 SFXFMODVoice::_tell() const
|
||||
{
|
||||
if( !mChannel )
|
||||
return 0;
|
||||
|
||||
U32 pos;
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_GetPosition( mChannel, &pos, ( FMOD_TIMEUNIT ) FMOD_TIMEUNIT_PCMBYTES );
|
||||
return _getBuffer()->getSamplePos( pos );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setMinMaxDistance( F32 min, F32 max )
|
||||
{
|
||||
if ( !( _getBuffer()->mMode & FMOD_3D ) )
|
||||
return;
|
||||
|
||||
mMinDistance = min;
|
||||
mMaxDistance = max;
|
||||
|
||||
mSetFlags.set( SET_MinMaxDistance );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DMinMaxDistance(mChannel, mMinDistance, mMaxDistance);
|
||||
}
|
||||
|
||||
void SFXFMODVoice::play( bool looping )
|
||||
{
|
||||
if( mBuffer->isStreaming() )
|
||||
looping = true;
|
||||
|
||||
mMode = mDevice->get3dRollOffMode();
|
||||
mMode |= (looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||
|
||||
Parent::play( looping );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setVelocity( const VectorF& velocity )
|
||||
{
|
||||
if( !( _getBuffer()->mMode & FMOD_3D ) )
|
||||
return;
|
||||
|
||||
// Note we have to do a handedness swap; see the
|
||||
// listener update code in SFXFMODDevice for details.
|
||||
mVelocity.x = velocity.x;
|
||||
mVelocity.y = velocity.z;
|
||||
mVelocity.z = velocity.y;
|
||||
|
||||
mSetFlags.set( SET_Velocity );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, ( const FMOD_VECTOR* ) NULL, &mVelocity );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setTransform( const MatrixF& transform )
|
||||
{
|
||||
if ( !( _getBuffer()->mMode & FMOD_3D ) )
|
||||
return;
|
||||
|
||||
transform.getColumn( 3, (Point3F*)&mPosition );
|
||||
transform.getColumn( 1, (Point3F*)&mDirection );
|
||||
|
||||
// Note we have to do a handedness swap; see the
|
||||
// listener update code in SFXFMODDevice for details.
|
||||
swap( mPosition.y, mPosition.z );
|
||||
swap( mDirection.y, mDirection.z );
|
||||
|
||||
mSetFlags.set( SET_Transform );
|
||||
|
||||
if( mChannel )
|
||||
{
|
||||
// This can fail safe, so don't assert if it fails.
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, &mPosition, ( const FMOD_VECTOR* ) NULL );
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeOrientation( mChannel, &mDirection );
|
||||
}
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setVolume( F32 volume )
|
||||
{
|
||||
mVolume = volume;
|
||||
mSetFlags.set( SET_Volume );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetVolume( mChannel, volume );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setPriority( F32 priority )
|
||||
{
|
||||
mPriority = priority;
|
||||
mSetFlags.set( SET_Priority );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetPriority( mChannel, TorquePriorityToFMODPriority( priority ) );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setPitch( F32 pitch )
|
||||
{
|
||||
// if we do not know the frequency, we cannot change the pitch
|
||||
F32 frequency = _getBuffer()->getFormat().getSamplesPerSecond();
|
||||
if ( frequency == 0 )
|
||||
return;
|
||||
|
||||
mFrequency = frequency * pitch;
|
||||
|
||||
mSetFlags.set( SET_Pitch );
|
||||
|
||||
// Scale the original frequency by the pitch factor.
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetFrequency(mChannel, mFrequency);
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
|
||||
{
|
||||
mConeInnerAngle = innerAngle;
|
||||
mConeOuterAngle = outerAngle;
|
||||
mConeOuterVolume = outerVolume;
|
||||
|
||||
mSetFlags.set( SET_Cone );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeSettings(
|
||||
mChannel,
|
||||
mConeInnerAngle,
|
||||
mConeOuterAngle,
|
||||
mConeOuterVolume );
|
||||
}
|
||||
|
||||
void SFXFMODVoice::setReverb( const SFXSoundReverbProperties& reverb )
|
||||
{
|
||||
dMemset( &mReverb, 0, sizeof( mReverb ) );
|
||||
|
||||
mReverb.Direct = reverb.mDirect;
|
||||
mReverb.Room = reverb.mRoom;
|
||||
mReverb.Flags = reverb.mFlags;
|
||||
|
||||
mSetFlags.set( SET_Reverb );
|
||||
|
||||
if( mChannel )
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_SetReverbProperties( mChannel, &mReverb );
|
||||
}
|
||||
|
||||
bool SFXFMODVoice::isVirtual() const
|
||||
{
|
||||
if( mChannel )
|
||||
{
|
||||
FMOD_BOOL result;
|
||||
SFXFMODDevice::smFunc->FMOD_Channel_IsVirtual( mChannel, &result );
|
||||
return result;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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 _SFXFMODVOICE_H_
|
||||
#define _SFXFMODVOICE_H_
|
||||
|
||||
#ifndef _SFXDEVICE_H_
|
||||
#include "sfx/sfxDevice.h"
|
||||
#endif
|
||||
#ifndef _SFXVOICE_H_
|
||||
#include "sfx/sfxVoice.h"
|
||||
#endif
|
||||
#ifndef _BITSET_H_
|
||||
#include "core/bitSet.h"
|
||||
#endif
|
||||
|
||||
#include "fmod.h"
|
||||
|
||||
class SFXSource;
|
||||
class SFXFMODBuffer;
|
||||
class SFXFMODDevice;
|
||||
|
||||
|
||||
class SFXFMODVoice : public SFXVoice
|
||||
{
|
||||
typedef SFXVoice Parent;
|
||||
friend class SFXFMODBuffer;
|
||||
|
||||
protected:
|
||||
|
||||
SFXFMODDevice *mDevice;
|
||||
|
||||
mutable FMOD_CHANNEL *mChannel;
|
||||
|
||||
enum ESettings
|
||||
{
|
||||
SET_MinMaxDistance = BIT( 0 ),
|
||||
SET_Velocity = BIT( 1 ),
|
||||
SET_Transform = BIT( 2 ),
|
||||
SET_Volume = BIT( 3 ),
|
||||
SET_Pitch = BIT( 4 ),
|
||||
SET_Cone = BIT( 5 ),
|
||||
SET_Priority = BIT( 6 ),
|
||||
SET_Reverb = BIT( 7 ),
|
||||
};
|
||||
|
||||
BitSet32 mSetFlags;
|
||||
|
||||
FMOD_MODE mMode;
|
||||
F32 mMinDistance;
|
||||
F32 mMaxDistance;
|
||||
F32 mVolume;
|
||||
F32 mPriority;
|
||||
F32 mFrequency;
|
||||
F32 mConeInnerAngle;
|
||||
F32 mConeOuterAngle;
|
||||
F32 mConeOuterVolume;
|
||||
FMOD_VECTOR mVelocity;
|
||||
FMOD_VECTOR mPosition;
|
||||
FMOD_VECTOR mDirection;
|
||||
FMOD_REVERB_CHANNELPROPERTIES mReverb;
|
||||
|
||||
///
|
||||
SFXFMODVoice( SFXFMODDevice *device,
|
||||
SFXFMODBuffer *buffer );
|
||||
|
||||
// prep for playback
|
||||
bool _assignChannel();
|
||||
|
||||
SFXFMODBuffer* _getBuffer() const { return ( SFXFMODBuffer* ) mBuffer.getPointer(); }
|
||||
|
||||
// SFXVoice.
|
||||
virtual SFXStatus _status() const;
|
||||
virtual void _play();
|
||||
virtual void _pause();
|
||||
virtual void _stop();
|
||||
virtual void _seek( U32 sample );
|
||||
virtual U32 _tell() const;
|
||||
|
||||
public:
|
||||
|
||||
///
|
||||
static SFXFMODVoice* create( SFXFMODDevice *device,
|
||||
SFXFMODBuffer *buffer );
|
||||
|
||||
///
|
||||
virtual ~SFXFMODVoice();
|
||||
|
||||
/// SFXVoice
|
||||
void setMinMaxDistance( F32 min, F32 max );
|
||||
void play( bool looping );
|
||||
void setVelocity( const VectorF& velocity );
|
||||
void setTransform( const MatrixF& transform );
|
||||
void setVolume( F32 volume );
|
||||
void setPriority( F32 priority );
|
||||
void setPitch( F32 pitch );
|
||||
void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
|
||||
void setReverb( const SFXSoundReverbProperties& reverb );
|
||||
bool isVirtual() const;
|
||||
};
|
||||
|
||||
#endif // _SFXFMODBUFFER_H_
|
||||
|
|
@ -247,7 +247,6 @@ void SFXDescription::initPersistFields()
|
|||
"If true, the sound system will try to allocate the voice for the sound directly "
|
||||
"on the sound hardware for mixing by the hardware mixer. Be aware that a hardware mixer "
|
||||
"may not provide all features available to sounds mixed in software.\n\n"
|
||||
"@note This flag currently only takes effect when using FMOD.\n\n"
|
||||
"@note Generally, it is preferable to let sounds be mixed in software.\n\n" );
|
||||
addField( "parameters", TypeSFXParameterName, Offset( mParameters, SFXDescription ), MaxNumParameters,
|
||||
"Names of the parameters to which sources using this description will automatically be linked.\n\n"
|
||||
|
|
@ -355,7 +354,7 @@ void SFXDescription::initPersistFields()
|
|||
"@ref SFXSource_cones" );
|
||||
addField( "rolloffFactor", TypeF32, Offset( mRolloffFactor, SFXDescription ),
|
||||
"Scale factor to apply to logarithmic distance attenuation curve. If -1, the global rolloff setting is used.\n\n"
|
||||
"@note Per-sound rolloff is only supported on OpenAL and FMOD at the moment. With other divices, the global rolloff setting "
|
||||
"@note Per-sound rolloff is only supported on OpenAL at the moment. With other divices, the global rolloff setting "
|
||||
"is used for all sounds.\n"
|
||||
"@see LevelInfo::soundDistanceModel" );
|
||||
|
||||
|
|
@ -373,7 +372,6 @@ void SFXDescription::initPersistFields()
|
|||
"of sample data determined by this field. The greater its value, the more sample data each "
|
||||
"packet contains, the more work is done per packet.\n\n"
|
||||
"@note This field only takes effect when Torque's own sound system performs the streaming. "
|
||||
"When FMOD is used, this field is ignored and streaming is performed by FMOD.\n\n"
|
||||
"@ref SFX_streaming" );
|
||||
addField( "streamReadAhead", TypeS32, Offset( mStreamReadAhead, SFXDescription ),
|
||||
"Number of sample packets to read and buffer in advance.\n"
|
||||
|
|
@ -382,7 +380,6 @@ void SFXDescription::initPersistFields()
|
|||
"device before the playback queue is running dry. Greater values thus allow for more lag "
|
||||
"in the streaming pipeline.\n\n"
|
||||
"@note This field only takes effect when Torque's own sound system performs the streaming. "
|
||||
"When FMOD is used, this field is ignored and streaming is performed by FMOD.\n\n"
|
||||
"@ref SFX_streaming" );
|
||||
|
||||
endGroup( "Streaming" );
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ class SFXDevice
|
|||
CAPS_Occlusion = BIT( 2 ), ///< Device has its own sound occlusion handling (SFXOcclusionManager).
|
||||
CAPS_DSPEffects = BIT( 3 ), ///< Device implements DSP effects (SFXDSPManager).
|
||||
CAPS_MultiListener = BIT( 4 ), ///< Device supports multiple listeners.
|
||||
CAPS_FMODDesigner = BIT( 5 ), ///< FMOD Designer support.
|
||||
};
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ ConsoleDocClass( SFXProfile,
|
|||
"for it to be created. However, several of the SFX functions (sfxPlayOnce(), sfxCreateSource()) perform "
|
||||
"this creation internally for convenience using temporary profile objects.\n\n"
|
||||
|
||||
"Sound files can be in either OGG or WAV format. However, extended format support is available when using FMOD. "
|
||||
"Sound files can be in either OGG or WAV format. "
|
||||
"See @ref SFX_formats.\n\n"
|
||||
|
||||
"@section SFXProfile_loading Profile Loading\n\n"
|
||||
|
|
|
|||
|
|
@ -158,8 +158,6 @@ ImplementEnumType( SFXChannel,
|
|||
"- 3: Pause\n\n" },
|
||||
{ SFXChannelUser0, "User0",
|
||||
"Channel available for custom use. By default ignored by sources.\n\n"
|
||||
"@note For FMOD Designer event sources (SFXFMODEventSource), this channel is used for event parameters "
|
||||
"defined in FMOD Designer and should not be used otherwise.\n\n"
|
||||
"@see SFXSource::onParameterValueChange" },
|
||||
{ SFXChannelUser1, "User1",
|
||||
"Channel available for custom use. By default ignored by sources.\n\n"
|
||||
|
|
@ -179,7 +177,6 @@ static const U32 sDeviceCapsVoiceManagement = SFXDevice::CAPS_VoiceManagement;
|
|||
static const U32 sDeviceCapsOcclusion = SFXDevice::CAPS_Occlusion;
|
||||
static const U32 sDeviceCapsDSPEffects = SFXDevice::CAPS_DSPEffects;
|
||||
static const U32 sDeviceCapsMultiListener = SFXDevice::CAPS_MultiListener;
|
||||
static const U32 sDeviceCapsFMODDesigner = SFXDevice::CAPS_FMODDesigner;
|
||||
|
||||
static const U32 sDeviceInfoProvider = 0;
|
||||
static const U32 sDeviceInfoName = 1;
|
||||
|
|
@ -253,7 +250,6 @@ SFXSystem::SFXSystem()
|
|||
|
||||
Con::addConstant( "$SFX::DEVICE_CAPS_REVERB", TypeS32, &sDeviceCapsReverb,
|
||||
"Sound device capability flag indicating that the sound device supports reverb.\n\n"
|
||||
"@note Currently only FMOD implements this.\n\n"
|
||||
"@see sfxGetDeviceInfo\n\n"
|
||||
"@ref SFX_reverb\n\n"
|
||||
"@ingroup SFX" );
|
||||
|
|
@ -261,7 +257,6 @@ SFXSystem::SFXSystem()
|
|||
"Sound device capability flag indicating that the sound device implements its own voice virtualization.\n\n"
|
||||
"For these devices, the sound system will deactivate its own voice management and leave voice "
|
||||
"virtualization entirely to the device.\n\n"
|
||||
"@note Currently only FMOD implements this.\n\n"
|
||||
"@see sfxGetDeviceInfo\n\n"
|
||||
"@ref SFXSound_virtualization\n\n"
|
||||
"@ingroup SFX" );
|
||||
|
|
@ -278,16 +273,8 @@ SFXSystem::SFXSystem()
|
|||
"@ingroup SFX" );
|
||||
Con::addConstant( "$SFX::DEVICE_CAPS_MULTILISTENER", TypeS32, &sDeviceCapsMultiListener,
|
||||
"Sound device capability flag indicating that the sound device supports multiple concurrent listeners.\n\n"
|
||||
"@note Currently only FMOD implements this.\n\n"
|
||||
"@see sfxGetDeviceInfo\n\n"
|
||||
"@ingroup SFX" );
|
||||
Con::addConstant( "$SFX::DEVICE_CAPS_FMODDESIGNER", TypeS32, &sDeviceCapsFMODDesigner,
|
||||
"Sound device capability flag indicating that the sound device supports FMOD Designer audio projects.\n\n"
|
||||
"@note This is exclusive to FMOD. If the FMOD Event DLLs are in place and could be successfully loaded, this "
|
||||
"flag will be set after initializating an FMOD audio device.\n\n"
|
||||
"@see sfxGetDeviceInfo\n\n"
|
||||
"@ref FMOD_designer\n\n"
|
||||
"@ingroup SFX" );
|
||||
|
||||
Con::addConstant( "$SFX::DEVICE_INFO_PROVIDER", TypeS32, &sDeviceInfoProvider,
|
||||
"Index of sound provider field in device info string.\n\n"
|
||||
|
|
@ -1241,7 +1228,7 @@ DefineEngineFunction( sfxGetAvailableDevices, const char*, (),,
|
|||
"@verbatim\n"
|
||||
"provider TAB device TAB hasHardware TAB numMaxBuffers\n"
|
||||
"@endverbatim\n"
|
||||
"- provider: The name of the device provider (e.g. \"FMOD\").\n"
|
||||
"- provider: The name of the device provider (e.g. \"OpenAL\").\n"
|
||||
"- device: The name of the device as returned by the device layer.\n"
|
||||
"- hasHardware: Whether the device supports hardware mixing or not.\n"
|
||||
"- numMaxBuffers: The maximum number of concurrent voices supported by the device's mixer. If this limit "
|
||||
|
|
@ -1336,7 +1323,7 @@ DefineEngineFunction( sfxGetDeviceInfo, const char*, (),,
|
|||
"@verbatim\n"
|
||||
"provider TAB device TAB hasHardware TAB numMaxBuffers TAB caps\n"
|
||||
"@endverbatim\n"
|
||||
"- provider: The name of the device provider (e.g. \"FMOD\").\n"
|
||||
"- provider: The name of the device provider (e.g. \"OpenALD\").\n"
|
||||
"- device: The name of the device as returned by the device layer.\n"
|
||||
"- hasHardware: Whether the device supports hardware mixing or not.\n"
|
||||
"- numMaxBuffers: The maximum number of concurrent voices supported by the device's mixer. If this limit "
|
||||
|
|
@ -1357,7 +1344,6 @@ DefineEngineFunction( sfxGetDeviceInfo, const char*, (),,
|
|||
"@see $SFX::DEVICE_CAPS_OCCLUSION\n\n"
|
||||
"@see $SFX::DEVICE_CAPS_DSPEFFECTS\n\n"
|
||||
"@see $SFX::DEVICE_CAPS_MULTILISTENER\n\n"
|
||||
"@see $SFX::DEVICE_CAPS_FMODDESIGNER\n\n"
|
||||
"@ref SFX_devices\n"
|
||||
"@ingroup SFX" )
|
||||
{
|
||||
|
|
@ -1379,7 +1365,7 @@ static ConsoleDocFragment _sfxCreateSource1(
|
|||
"@param track The track the source should play.\n"
|
||||
"@return A new SFXSource for playback of the given track or 0 if no source could be created from the given track.\n\n"
|
||||
"@note Trying to create a source for a device-specific track type will fail if the currently selected device "
|
||||
"does not support the type. Example: trying to create a source for an FMOD Designer event when not running FMOD.\n\n"
|
||||
"does not support the type. \n\n"
|
||||
"@tsexample\n"
|
||||
"// Create and play a source from a pre-existing profile:\n"
|
||||
"%source = sfxCreateSource( SoundFileProfile );\n"
|
||||
|
|
@ -1400,7 +1386,7 @@ static ConsoleDocFragment _sfxCreateSource2(
|
|||
"@param z The Z coordinate of the 3D sound position.\n"
|
||||
"@return A new SFXSource for playback of the given track or 0 if no source could be created from the given track.\n\n"
|
||||
"@note Trying to create a source for a device-specific track type will fail if the currently selected device "
|
||||
"does not support the type. Example: trying to create a source for an FMOD Designer event when not running FMOD.\n\n"
|
||||
"does not support the type. \n\n"
|
||||
"@tsexample\n"
|
||||
"// Create and play a source from a pre-existing profile and position it at (100, 200, 300):\n"
|
||||
"%source = sfxCreateSource( SoundFileProfile, 100, 200, 300 );\n"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ ConsoleDocClass( SFXTrack,
|
|||
|
||||
"The term \"track\" is used in the sound system to refer to any entity that can be played "
|
||||
"back as a sound source. These can be individual files (SFXProfile), patterns of other tracks "
|
||||
"(SFXPlayList), or special sound data defined by a device layer (SFXFMODEvent).\n\n"
|
||||
"(SFXPlayList).\n\n"
|
||||
|
||||
"Any track must be paired with a SFXDescription that tells the sound system how to set up "
|
||||
"playback for the track.\n\n"
|
||||
|
|
|
|||
|
|
@ -216,26 +216,18 @@ function sfxCompareProvider( %providerA, %providerB )
|
|||
|
||||
switch$( %providerA )
|
||||
{
|
||||
// Always prefer FMOD over anything else.
|
||||
case "FMOD":
|
||||
return 1;
|
||||
|
||||
// Prefer OpenAL over anything but FMOD.
|
||||
case "OpenAL":
|
||||
if( %providerB $= "FMOD" )
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
|
||||
// choose XAudio over DirectSound
|
||||
case "XAudio":
|
||||
if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
|
||||
if( %providerB $= "OpenAL" )
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case "DirectSound":
|
||||
if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "XAudio" )
|
||||
if( %providerB !$= "OpenAL" && %providerB !$= "XAudio" )
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
// Preferences.
|
||||
|
||||
$pref::GuiMusicPlayer::filePattern = "*.ogg\t*.wav";
|
||||
$pref::GuiMusicPlayer::filePatternFMOD = "*.aiff\t*.asf\t*.flac\t*.it\t*.mid\t*.mod\t*.mp2\t*.mp3\t*.ogg\t*.s3m\t*.vag\t*.wav\t*.wma\t*.xm";
|
||||
$pref::GuiMusicPlayer::fadeTime = "3.0";
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -192,8 +192,7 @@ function sfxMetricsCallback()
|
|||
{
|
||||
return " | SFX |" @
|
||||
" Sounds: " @ $SFX::numSounds @
|
||||
" Lists: " @ ( $SFX::numSources - $SFX::numSounds - $SFX::Device::fmodNumEventSource ) @
|
||||
" Events: " @ $SFX::fmodNumEventSources @
|
||||
" Lists: " @ ( $SFX::numSources - $SFX::numSounds ) @
|
||||
" Playing: " @ $SFX::numPlaying @
|
||||
" Culled: " @ $SFX::numCulled @
|
||||
" Voices: " @ $SFX::numVoices @
|
||||
|
|
|
|||
|
|
@ -223,11 +223,7 @@ function DatablockEditorPlugin::isExcludedDatablockType( %this, %className )
|
|||
case "SimDatablock":
|
||||
return true;
|
||||
case "SFXTrack": // Abstract.
|
||||
return true;
|
||||
case "SFXFMODEvent": // Internally created.
|
||||
return true;
|
||||
case "SFXFMODEventGroup": // Internally created.
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -754,8 +750,7 @@ function DatablockEditorPlugin::canBeClientSideDatablock( %className )
|
|||
"SFXAmbience" or
|
||||
"SFXEnvironment" or
|
||||
"SFXState" or
|
||||
"SFXDescription" or
|
||||
"SFXFMODProject":
|
||||
"SFXDescription":
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
<GUIAsset
|
||||
canSave="true"
|
||||
canSaveDynamicFields="true"
|
||||
AssetName="AddFMODProjectDlg,EditorGuiGroup"
|
||||
scriptFile="@assetFile=AddFMODProjectDlg.ed.gui"
|
||||
GUIFile="@assetFile=AddFMODProjectDlg.ed.gui"
|
||||
VersionId="1" />
|
||||
|
|
@ -1,284 +0,0 @@
|
|||
//--- OBJECT WRITE BEGIN ---
|
||||
$guiContent = new GuiControl(AddFMODProjectDlg,EditorGuiGroup) {
|
||||
isContainer = "1";
|
||||
Profile = "ToolsGuiOverlayProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "0 0";
|
||||
Extent = "1024 768";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "1";
|
||||
|
||||
new GuiWindowCtrl() {
|
||||
resizeWidth = "0";
|
||||
resizeHeight = "0";
|
||||
canMove = "1";
|
||||
canClose = "1";
|
||||
canMinimize = "0";
|
||||
canMaximize = "0";
|
||||
minSize = "50 50";
|
||||
closeCommand = "AddFMODProjectDlg.onCancel();";
|
||||
EdgeSnap = "1";
|
||||
text = "Add FMOD Designer Audio";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "1";
|
||||
Profile = "ToolsGuiWindowProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "361 196";
|
||||
Extent = "303 236";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
internalName = "window";
|
||||
|
||||
new GuiBitmapBorderCtrl() {
|
||||
isContainer = "1";
|
||||
Profile = "ToolsGuiGroupBorderProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "5 26";
|
||||
Extent = "291 160";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
|
||||
new GuiTextCtrl() {
|
||||
text = "Path to the compiled event file (.fev):";
|
||||
maxLength = "1024";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiAutoSizeTextProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "8 51";
|
||||
Extent = "176 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiTextEditCtrl() {
|
||||
historySize = "0";
|
||||
password = "0";
|
||||
tabComplete = "0";
|
||||
sinkAllKeyEvents = "0";
|
||||
passwordMask = "•";
|
||||
maxLength = "1024";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiTextEditProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "7 72";
|
||||
Extent = "254 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
internalName = "fileNameField";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiTextEditCtrl() {
|
||||
historySize = "0";
|
||||
password = "0";
|
||||
tabComplete = "0";
|
||||
sinkAllKeyEvents = "0";
|
||||
passwordMask = "•";
|
||||
maxLength = "1024";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiTextEditProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "7 127";
|
||||
Extent = "254 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
internalName = "mediaPathField";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiTextCtrl() {
|
||||
text = "Name for the SFXFMODProject object:";
|
||||
maxLength = "1024";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiAutoSizeTextProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "8 10";
|
||||
Extent = "189 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiTextEditCtrl() {
|
||||
historySize = "0";
|
||||
password = "0";
|
||||
tabComplete = "0";
|
||||
sinkAllKeyEvents = "0";
|
||||
passwordMask = "•";
|
||||
maxLength = "1024";
|
||||
Margin = "0 0 0 0";
|
||||
Padding = "0 0 0 0";
|
||||
AnchorTop = "1";
|
||||
AnchorBottom = "0";
|
||||
AnchorLeft = "1";
|
||||
AnchorRight = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiTextEditProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "7 30";
|
||||
Extent = "277 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
internalName = "projectNameField";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiMLTextCtrl() {
|
||||
lineSpacing = "2";
|
||||
allowColorChars = "0";
|
||||
maxChars = "-1";
|
||||
text = "Path to the project\'s media files (leave empty if files are in same directory as the project file):";
|
||||
useURLMouseCursor = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiMLTextProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "8 96";
|
||||
Extent = "276 26";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiButtonCtrl() {
|
||||
text = "...";
|
||||
groupNum = "-1";
|
||||
buttonType = "PushButton";
|
||||
useMouseEvents = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiButtonProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "266 72";
|
||||
Extent = "18 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
command = "AddFMODProjectDlg.onSelectFile();";
|
||||
};
|
||||
new GuiButtonCtrl() {
|
||||
text = "...";
|
||||
groupNum = "-1";
|
||||
buttonType = "PushButton";
|
||||
useMouseEvents = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiButtonProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "266 127";
|
||||
Extent = "18 17";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
command = "AddFMODProjectDlg.onSelectMediaPath();";
|
||||
};
|
||||
};
|
||||
new GuiButtonCtrl() {
|
||||
text = "Cancel";
|
||||
groupNum = "-1";
|
||||
buttonType = "PushButton";
|
||||
useMouseEvents = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiButtonProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "206 196";
|
||||
Extent = "90 30";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
Command = "AddFMODProjectDlg.onCancel();";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
new GuiButtonCtrl() {
|
||||
text = "OK";
|
||||
groupNum = "-1";
|
||||
buttonType = "PushButton";
|
||||
useMouseEvents = "0";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiButtonProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
position = "112 196";
|
||||
Extent = "90 30";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
Command = "AddFMODProjectDlg.onOK();";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
hovertime = "1000";
|
||||
canSaveDynamicFields = "0";
|
||||
};
|
||||
};
|
||||
};
|
||||
//--- OBJECT WRITE END ---
|
||||
|
|
@ -40,7 +40,6 @@ function initializeWorldEditor()
|
|||
exec("./gui/ManageBookmarksWindow.ed.gui");
|
||||
exec("./gui/ManageSFXParametersWindow.ed.gui" );
|
||||
exec("./gui/TimeAdjustGui.ed.gui");
|
||||
exec("./gui/AddFMODProjectDlg.ed.gui");
|
||||
exec("./gui/SelectObjectsWindow.ed.gui");
|
||||
exec("./gui/ProceduralTerrainPainterGui.gui" );
|
||||
exec("tools/gui/renderTargetVisualizer.ed.gui");
|
||||
|
|
@ -65,7 +64,6 @@ function initializeWorldEditor()
|
|||
exec("./scripts/EditorChooseLevelGui.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/cameraBookmarks.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/ManageSFXParametersWindow.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/AddFMODProjectDlg.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/SelectObjectsWindow.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/cameraCommands.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/probeBake.ed." @ $TorqueScriptFileExtension);
|
||||
|
|
|
|||
|
|
@ -1,253 +0,0 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// AddFMODProjectDlg.
|
||||
//=============================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::show( %this )
|
||||
{
|
||||
if( $platform $= "macos" )
|
||||
{
|
||||
%fmodex = "libfmodex.dylib";
|
||||
%fmodevent = "libfmodevent.dylib";
|
||||
}
|
||||
else
|
||||
{
|
||||
%fmodex = "fmodex.dll";
|
||||
%fmodevent = "fmod_event.dll";
|
||||
}
|
||||
|
||||
// Make sure we have FMOD running.
|
||||
|
||||
if( getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_PROVIDER ) !$= "FMOD" )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"You do not currently have FMOD selected as your sound system." NL
|
||||
"" NL
|
||||
"To install FMOD, place the FMOD DLLs (" @ %fmodex @ " and " @ %fmodevent @ ")" SPC
|
||||
"in your game/ folder alongside your game executable" SPC
|
||||
"and restart Torque." NL
|
||||
"" NL
|
||||
"To select FMOD as your sound system, choose it as the sound provider in" SPC
|
||||
"the audio tab of the Game Options dialog."
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have the FMOD Event DLL loaded.
|
||||
|
||||
%deviceCaps = getField( sfxGetDeviceInfo(), $SFX::DEVICE_INFO_CAPS );
|
||||
if( !( %deviceCaps & $SFX::DEVICE_CAPS_FMODDESIGNER ) )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"You do not have the requisite FMOD Event DLL in place." NL
|
||||
"" NL
|
||||
"Please copy " @ %fmodevent @ " into your game/ folder and restart Torque."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show it.
|
||||
|
||||
Canvas.pushDialog( %this, 0, true );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onWake( %this )
|
||||
{
|
||||
%this.persistenceMgr = new PersistenceManager();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onSleep( %this )
|
||||
{
|
||||
%this.persistenceMgr.delete();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onCancel( %this )
|
||||
{
|
||||
Canvas.popDialog( %this );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onOK( %this )
|
||||
{
|
||||
%objName = %this-->projectNameField.getText();
|
||||
%fileName = %this-->fileNameField.getText();
|
||||
%mediaPath = %this-->mediaPathField.getText();
|
||||
|
||||
// Make sure the object name is valid.
|
||||
if( !Editor::validateObjectName( %objName, true ))
|
||||
return;
|
||||
|
||||
// Make sure the .fev file exists.
|
||||
|
||||
if( %fileName $= "" )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"Please enter a project file name."
|
||||
);
|
||||
return;
|
||||
}
|
||||
if( !isFile( %fileName ) )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"'" @ %fileName @ "' is not a valid file."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the media path exists.
|
||||
|
||||
if( !isDirectory( %mediaPath ) )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"'" @ %mediaPath @ "' is not a valid directory."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// If an event script exists from a previous instantiation,
|
||||
// delete it first.
|
||||
|
||||
%eventFileName = %fileName @ "." @ $TorqueScriptFileExtension;
|
||||
if( isFile( %eventFileName ) )
|
||||
fileDelete( %eventFileName );
|
||||
|
||||
// Create the FMOD project object.
|
||||
|
||||
pushInstantGroup();
|
||||
eval( "new SFXFMODProject( " @ %objName @ ") {" NL
|
||||
"fileName = \"" @ %fileName @ "\";" NL
|
||||
"mediaPath = \"" @ %mediaPath @ "\";" NL
|
||||
"};" );
|
||||
popInstantGroup();
|
||||
|
||||
if( !isObject( %objName ) )
|
||||
{
|
||||
toolsMessageBoxOK( "Error",
|
||||
"Failed to create the object. Please take a look at the log for details."
|
||||
);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save the object.
|
||||
|
||||
%objName.setFileName( "scripts/client/audioData." @ $TorqueScriptFileExtension );
|
||||
%this.persistenceMgr.setDirty( %objName );
|
||||
%this.persistenceMgr.saveDirty();
|
||||
}
|
||||
|
||||
Canvas.popDialog( %this );
|
||||
|
||||
// Trigger a reinit on the datablock editor, just in case.
|
||||
|
||||
if( isObject( DatablockEditorPlugin ) )
|
||||
DatablockEditorPlugin.populateTrees();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onSelectFile( %this )
|
||||
{
|
||||
if( $pref::WorldEditor::AddFMODProjectDlg::lastPath $= "" )
|
||||
$pref::WorldEditor::AddFMODProjectDlg::lastPath = getMainDotCsDir();
|
||||
|
||||
%dlg = new OpenFileDialog()
|
||||
{
|
||||
Title = "Select Compiled FMOD Designer Event File...";
|
||||
Filters = "Compiled Event Files (*.fev)|*.fev|All Files (*.*)|*.*|";
|
||||
DefaultPath = $pref::WorldEditor::AddFMODProjectDlg::lastPath;
|
||||
DefaultFile = fileName( %this-->fileNameField.getText() );
|
||||
MustExit = true;
|
||||
ChangePath = false;
|
||||
};
|
||||
|
||||
%ret = %dlg.execute();
|
||||
if( %ret )
|
||||
{
|
||||
%file = %dlg.fileName;
|
||||
$pref::WorldEditor::AddFMODProjectDlg::lastPath = filePath( %file );
|
||||
}
|
||||
|
||||
%dlg.delete();
|
||||
|
||||
if( !%ret )
|
||||
return;
|
||||
|
||||
%file = makeRelativePath( %file, getMainDotCsDir() );
|
||||
%this-->fileNameField.setText( %file );
|
||||
|
||||
if( %this-->projectNameField.getText() $= "" )
|
||||
{
|
||||
%projectName = "fmod" @ fileBase( %file );
|
||||
if( isValidObjectName( %projectName ) )
|
||||
%this-->projectNameField.setText( %projectName );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function AddFMODProjectDlg::onSelectMediaPath( %this )
|
||||
{
|
||||
%defaultPath = %this-->mediaPathField.getText();
|
||||
if( %defaultPath $= "" )
|
||||
{
|
||||
%defaultPath = filePath( %this-->fileNameField.getText() );
|
||||
if( %defaultPath $= "" )
|
||||
%defaultPath = getMainDotCsDir();
|
||||
else
|
||||
%defaultPath = makeFullPath( %defaultPath );
|
||||
}
|
||||
|
||||
%dlg = new OpenFolderDialog()
|
||||
{
|
||||
Title = "Select Media Path...";
|
||||
DefaultPath = %defaultPath;
|
||||
MustExit = true;
|
||||
ChangePath = false;
|
||||
};
|
||||
|
||||
%ret = %dlg.execute();
|
||||
if( %ret )
|
||||
%file = %dlg.fileName;
|
||||
|
||||
%dlg.delete();
|
||||
|
||||
if( !%ret )
|
||||
return;
|
||||
|
||||
%file = makeRelativePath( %file, getMainDotCsDir() );
|
||||
%this-->mediaPathField.setText( %file );
|
||||
}
|
||||
|
|
@ -167,10 +167,7 @@ function EditorGui::buildMenus(%this)
|
|||
//item[6] = "Import Texture Data..." TAB "" TAB "Texture::import();";
|
||||
//item[7] = "-";
|
||||
//item[8] = "Export Terraform Data..." TAB "" TAB "Heightfield::saveBitmap(\"\");";
|
||||
|
||||
%fileMenu.appendItem( "-" );
|
||||
%fileMenu.appendItem( "Add FMOD Designer Audio..." TAB "" TAB "AddFMODProjectDlg.show();" );
|
||||
|
||||
|
||||
%fileMenu.appendItem("-");
|
||||
%fileMenu.appendItem("Play Level" TAB "F11" TAB "Editor.close(ProjectSettings.value(\"UI/playGUIName\"));");
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,6 @@ if(UNIX)
|
|||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
endif()
|
||||
|
||||
# TODO: fmod support
|
||||
|
||||
###############################################################################
|
||||
# modules
|
||||
###############################################################################
|
||||
|
|
|
|||
Loading…
Reference in a new issue