mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +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
34 changed files with 13 additions and 5317 deletions
|
|
@ -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 "
|
"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 "
|
"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"
|
"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" );
|
"@note Generally, it is preferable to let sounds be mixed in software.\n\n" );
|
||||||
addField( "parameters", TypeSFXParameterName, Offset( mParameters, SFXDescription ), MaxNumParameters,
|
addField( "parameters", TypeSFXParameterName, Offset( mParameters, SFXDescription ), MaxNumParameters,
|
||||||
"Names of the parameters to which sources using this description will automatically be linked.\n\n"
|
"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" );
|
"@ref SFXSource_cones" );
|
||||||
addField( "rolloffFactor", TypeF32, Offset( mRolloffFactor, SFXDescription ),
|
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"
|
"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"
|
"is used for all sounds.\n"
|
||||||
"@see LevelInfo::soundDistanceModel" );
|
"@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 "
|
"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"
|
"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. "
|
"@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" );
|
"@ref SFX_streaming" );
|
||||||
addField( "streamReadAhead", TypeS32, Offset( mStreamReadAhead, SFXDescription ),
|
addField( "streamReadAhead", TypeS32, Offset( mStreamReadAhead, SFXDescription ),
|
||||||
"Number of sample packets to read and buffer in advance.\n"
|
"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 "
|
"device before the playback queue is running dry. Greater values thus allow for more lag "
|
||||||
"in the streaming pipeline.\n\n"
|
"in the streaming pipeline.\n\n"
|
||||||
"@note This field only takes effect when Torque's own sound system performs the streaming. "
|
"@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" );
|
"@ref SFX_streaming" );
|
||||||
|
|
||||||
endGroup( "Streaming" );
|
endGroup( "Streaming" );
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ class SFXDevice
|
||||||
CAPS_Occlusion = BIT( 2 ), ///< Device has its own sound occlusion handling (SFXOcclusionManager).
|
CAPS_Occlusion = BIT( 2 ), ///< Device has its own sound occlusion handling (SFXOcclusionManager).
|
||||||
CAPS_DSPEffects = BIT( 3 ), ///< Device implements DSP effects (SFXDSPManager).
|
CAPS_DSPEffects = BIT( 3 ), ///< Device implements DSP effects (SFXDSPManager).
|
||||||
CAPS_MultiListener = BIT( 4 ), ///< Device supports multiple listeners.
|
CAPS_MultiListener = BIT( 4 ), ///< Device supports multiple listeners.
|
||||||
CAPS_FMODDesigner = BIT( 5 ), ///< FMOD Designer support.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ ConsoleDocClass( SFXProfile,
|
||||||
"for it to be created. However, several of the SFX functions (sfxPlayOnce(), sfxCreateSource()) perform "
|
"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"
|
"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"
|
"See @ref SFX_formats.\n\n"
|
||||||
|
|
||||||
"@section SFXProfile_loading Profile Loading\n\n"
|
"@section SFXProfile_loading Profile Loading\n\n"
|
||||||
|
|
|
||||||
|
|
@ -158,8 +158,6 @@ ImplementEnumType( SFXChannel,
|
||||||
"- 3: Pause\n\n" },
|
"- 3: Pause\n\n" },
|
||||||
{ SFXChannelUser0, "User0",
|
{ SFXChannelUser0, "User0",
|
||||||
"Channel available for custom use. By default ignored by sources.\n\n"
|
"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" },
|
"@see SFXSource::onParameterValueChange" },
|
||||||
{ SFXChannelUser1, "User1",
|
{ SFXChannelUser1, "User1",
|
||||||
"Channel available for custom use. By default ignored by sources.\n\n"
|
"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 sDeviceCapsOcclusion = SFXDevice::CAPS_Occlusion;
|
||||||
static const U32 sDeviceCapsDSPEffects = SFXDevice::CAPS_DSPEffects;
|
static const U32 sDeviceCapsDSPEffects = SFXDevice::CAPS_DSPEffects;
|
||||||
static const U32 sDeviceCapsMultiListener = SFXDevice::CAPS_MultiListener;
|
static const U32 sDeviceCapsMultiListener = SFXDevice::CAPS_MultiListener;
|
||||||
static const U32 sDeviceCapsFMODDesigner = SFXDevice::CAPS_FMODDesigner;
|
|
||||||
|
|
||||||
static const U32 sDeviceInfoProvider = 0;
|
static const U32 sDeviceInfoProvider = 0;
|
||||||
static const U32 sDeviceInfoName = 1;
|
static const U32 sDeviceInfoName = 1;
|
||||||
|
|
@ -253,7 +250,6 @@ SFXSystem::SFXSystem()
|
||||||
|
|
||||||
Con::addConstant( "$SFX::DEVICE_CAPS_REVERB", TypeS32, &sDeviceCapsReverb,
|
Con::addConstant( "$SFX::DEVICE_CAPS_REVERB", TypeS32, &sDeviceCapsReverb,
|
||||||
"Sound device capability flag indicating that the sound device supports reverb.\n\n"
|
"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"
|
"@see sfxGetDeviceInfo\n\n"
|
||||||
"@ref SFX_reverb\n\n"
|
"@ref SFX_reverb\n\n"
|
||||||
"@ingroup SFX" );
|
"@ingroup SFX" );
|
||||||
|
|
@ -261,7 +257,6 @@ SFXSystem::SFXSystem()
|
||||||
"Sound device capability flag indicating that the sound device implements its own voice virtualization.\n\n"
|
"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 "
|
"For these devices, the sound system will deactivate its own voice management and leave voice "
|
||||||
"virtualization entirely to the device.\n\n"
|
"virtualization entirely to the device.\n\n"
|
||||||
"@note Currently only FMOD implements this.\n\n"
|
|
||||||
"@see sfxGetDeviceInfo\n\n"
|
"@see sfxGetDeviceInfo\n\n"
|
||||||
"@ref SFXSound_virtualization\n\n"
|
"@ref SFXSound_virtualization\n\n"
|
||||||
"@ingroup SFX" );
|
"@ingroup SFX" );
|
||||||
|
|
@ -278,16 +273,8 @@ SFXSystem::SFXSystem()
|
||||||
"@ingroup SFX" );
|
"@ingroup SFX" );
|
||||||
Con::addConstant( "$SFX::DEVICE_CAPS_MULTILISTENER", TypeS32, &sDeviceCapsMultiListener,
|
Con::addConstant( "$SFX::DEVICE_CAPS_MULTILISTENER", TypeS32, &sDeviceCapsMultiListener,
|
||||||
"Sound device capability flag indicating that the sound device supports multiple concurrent listeners.\n\n"
|
"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"
|
"@see sfxGetDeviceInfo\n\n"
|
||||||
"@ingroup SFX" );
|
"@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,
|
Con::addConstant( "$SFX::DEVICE_INFO_PROVIDER", TypeS32, &sDeviceInfoProvider,
|
||||||
"Index of sound provider field in device info string.\n\n"
|
"Index of sound provider field in device info string.\n\n"
|
||||||
|
|
@ -1241,7 +1228,7 @@ DefineEngineFunction( sfxGetAvailableDevices, const char*, (),,
|
||||||
"@verbatim\n"
|
"@verbatim\n"
|
||||||
"provider TAB device TAB hasHardware TAB numMaxBuffers\n"
|
"provider TAB device TAB hasHardware TAB numMaxBuffers\n"
|
||||||
"@endverbatim\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"
|
"- device: The name of the device as returned by the device layer.\n"
|
||||||
"- hasHardware: Whether the device supports hardware mixing or not.\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 "
|
"- 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"
|
"@verbatim\n"
|
||||||
"provider TAB device TAB hasHardware TAB numMaxBuffers TAB caps\n"
|
"provider TAB device TAB hasHardware TAB numMaxBuffers TAB caps\n"
|
||||||
"@endverbatim\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"
|
"- device: The name of the device as returned by the device layer.\n"
|
||||||
"- hasHardware: Whether the device supports hardware mixing or not.\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 "
|
"- 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_OCCLUSION\n\n"
|
||||||
"@see $SFX::DEVICE_CAPS_DSPEFFECTS\n\n"
|
"@see $SFX::DEVICE_CAPS_DSPEFFECTS\n\n"
|
||||||
"@see $SFX::DEVICE_CAPS_MULTILISTENER\n\n"
|
"@see $SFX::DEVICE_CAPS_MULTILISTENER\n\n"
|
||||||
"@see $SFX::DEVICE_CAPS_FMODDESIGNER\n\n"
|
|
||||||
"@ref SFX_devices\n"
|
"@ref SFX_devices\n"
|
||||||
"@ingroup SFX" )
|
"@ingroup SFX" )
|
||||||
{
|
{
|
||||||
|
|
@ -1379,7 +1365,7 @@ static ConsoleDocFragment _sfxCreateSource1(
|
||||||
"@param track The track the source should play.\n"
|
"@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"
|
"@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 "
|
"@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"
|
"@tsexample\n"
|
||||||
"// Create and play a source from a pre-existing profile:\n"
|
"// Create and play a source from a pre-existing profile:\n"
|
||||||
"%source = sfxCreateSource( SoundFileProfile );\n"
|
"%source = sfxCreateSource( SoundFileProfile );\n"
|
||||||
|
|
@ -1400,7 +1386,7 @@ static ConsoleDocFragment _sfxCreateSource2(
|
||||||
"@param z The Z coordinate of the 3D sound position.\n"
|
"@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"
|
"@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 "
|
"@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"
|
"@tsexample\n"
|
||||||
"// Create and play a source from a pre-existing profile and position it at (100, 200, 300):\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"
|
"%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 "
|
"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 "
|
"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 "
|
"Any track must be paired with a SFXDescription that tells the sound system how to set up "
|
||||||
"playback for the track.\n\n"
|
"playback for the track.\n\n"
|
||||||
|
|
|
||||||
|
|
@ -216,26 +216,18 @@ function sfxCompareProvider( %providerA, %providerB )
|
||||||
|
|
||||||
switch$( %providerA )
|
switch$( %providerA )
|
||||||
{
|
{
|
||||||
// Always prefer FMOD over anything else.
|
|
||||||
case "FMOD":
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// Prefer OpenAL over anything but FMOD.
|
|
||||||
case "OpenAL":
|
case "OpenAL":
|
||||||
if( %providerB $= "FMOD" )
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// choose XAudio over DirectSound
|
// choose XAudio over DirectSound
|
||||||
case "XAudio":
|
case "XAudio":
|
||||||
if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
|
if( %providerB $= "OpenAL" )
|
||||||
return -1;
|
return -1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case "DirectSound":
|
case "DirectSound":
|
||||||
if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "XAudio" )
|
if( %providerB !$= "OpenAL" && %providerB !$= "XAudio" )
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@
|
||||||
// Preferences.
|
// Preferences.
|
||||||
|
|
||||||
$pref::GuiMusicPlayer::filePattern = "*.ogg\t*.wav";
|
$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";
|
$pref::GuiMusicPlayer::fadeTime = "3.0";
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -192,8 +192,7 @@ function sfxMetricsCallback()
|
||||||
{
|
{
|
||||||
return " | SFX |" @
|
return " | SFX |" @
|
||||||
" Sounds: " @ $SFX::numSounds @
|
" Sounds: " @ $SFX::numSounds @
|
||||||
" Lists: " @ ( $SFX::numSources - $SFX::numSounds - $SFX::Device::fmodNumEventSource ) @
|
" Lists: " @ ( $SFX::numSources - $SFX::numSounds ) @
|
||||||
" Events: " @ $SFX::fmodNumEventSources @
|
|
||||||
" Playing: " @ $SFX::numPlaying @
|
" Playing: " @ $SFX::numPlaying @
|
||||||
" Culled: " @ $SFX::numCulled @
|
" Culled: " @ $SFX::numCulled @
|
||||||
" Voices: " @ $SFX::numVoices @
|
" Voices: " @ $SFX::numVoices @
|
||||||
|
|
|
||||||
|
|
@ -223,11 +223,7 @@ function DatablockEditorPlugin::isExcludedDatablockType( %this, %className )
|
||||||
case "SimDatablock":
|
case "SimDatablock":
|
||||||
return true;
|
return true;
|
||||||
case "SFXTrack": // Abstract.
|
case "SFXTrack": // Abstract.
|
||||||
return true;
|
return true;
|
||||||
case "SFXFMODEvent": // Internally created.
|
|
||||||
return true;
|
|
||||||
case "SFXFMODEventGroup": // Internally created.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -754,8 +750,7 @@ function DatablockEditorPlugin::canBeClientSideDatablock( %className )
|
||||||
"SFXAmbience" or
|
"SFXAmbience" or
|
||||||
"SFXEnvironment" or
|
"SFXEnvironment" or
|
||||||
"SFXState" or
|
"SFXState" or
|
||||||
"SFXDescription" or
|
"SFXDescription":
|
||||||
"SFXFMODProject":
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
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/ManageBookmarksWindow.ed.gui");
|
||||||
exec("./gui/ManageSFXParametersWindow.ed.gui" );
|
exec("./gui/ManageSFXParametersWindow.ed.gui" );
|
||||||
exec("./gui/TimeAdjustGui.ed.gui");
|
exec("./gui/TimeAdjustGui.ed.gui");
|
||||||
exec("./gui/AddFMODProjectDlg.ed.gui");
|
|
||||||
exec("./gui/SelectObjectsWindow.ed.gui");
|
exec("./gui/SelectObjectsWindow.ed.gui");
|
||||||
exec("./gui/ProceduralTerrainPainterGui.gui" );
|
exec("./gui/ProceduralTerrainPainterGui.gui" );
|
||||||
exec("tools/gui/renderTargetVisualizer.ed.gui");
|
exec("tools/gui/renderTargetVisualizer.ed.gui");
|
||||||
|
|
@ -65,7 +64,6 @@ function initializeWorldEditor()
|
||||||
exec("./scripts/EditorChooseLevelGui.ed." @ $TorqueScriptFileExtension);
|
exec("./scripts/EditorChooseLevelGui.ed." @ $TorqueScriptFileExtension);
|
||||||
exec("./scripts/cameraBookmarks.ed." @ $TorqueScriptFileExtension);
|
exec("./scripts/cameraBookmarks.ed." @ $TorqueScriptFileExtension);
|
||||||
exec("./scripts/ManageSFXParametersWindow.ed." @ $TorqueScriptFileExtension);
|
exec("./scripts/ManageSFXParametersWindow.ed." @ $TorqueScriptFileExtension);
|
||||||
exec("./scripts/AddFMODProjectDlg.ed." @ $TorqueScriptFileExtension);
|
|
||||||
exec("./scripts/SelectObjectsWindow.ed." @ $TorqueScriptFileExtension);
|
exec("./scripts/SelectObjectsWindow.ed." @ $TorqueScriptFileExtension);
|
||||||
exec("./scripts/cameraCommands.ed." @ $TorqueScriptFileExtension);
|
exec("./scripts/cameraCommands.ed." @ $TorqueScriptFileExtension);
|
||||||
exec("./scripts/probeBake.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[6] = "Import Texture Data..." TAB "" TAB "Texture::import();";
|
||||||
//item[7] = "-";
|
//item[7] = "-";
|
||||||
//item[8] = "Export Terraform Data..." TAB "" TAB "Heightfield::saveBitmap(\"\");";
|
//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("-");
|
||||||
%fileMenu.appendItem("Play Level" TAB "F11" TAB "Editor.close(ProjectSettings.value(\"UI/playGUIName\"));");
|
%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")
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: fmod support
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# modules
|
# modules
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue