Torque3D Documentation / _generateds / sfxFMODEvent.cpp

sfxFMODEvent.cpp

Engine/source/sfx/fmod/sfxFMODEvent.cpp

More...

Public Functions

ConsoleDocClass(SFXFMODEvent , "@brief A playable sound event in an FMOD Designer audio <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">project.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXFMOD\n</a>" "@ingroup Datablocks" )

Detailed Description

Public Functions

ConsoleDocClass(SFXFMODEvent , "@brief A playable sound event in an FMOD Designer audio <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">project.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">SFXFMOD\n</a>" "@ingroup Datablocks" )

IMPLEMENT_CO_DATABLOCK_V1(SFXFMODEvent )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#include "platform/platform.h"
 25#include "sfx/fmod/sfxFMODEvent.h"
 26#include "sfx/fmod/sfxFMODEventGroup.h"
 27#include "sfx/fmod/sfxFMODProject.h"
 28#include "sfx/fmod/sfxFMODDevice.h"
 29#include "sfx/sfxParameter.h"
 30#include "sfx/sfxDescription.h"
 31#include "core/stream/bitStream.h"
 32
 33
 34IMPLEMENT_CO_DATABLOCK_V1( SFXFMODEvent );
 35
 36
 37ConsoleDocClass( SFXFMODEvent,
 38   "@brief A playable sound event in an FMOD Designer audio project.\n\n"
 39   
 40   "@ingroup SFXFMOD\n"
 41   "@ingroup Datablocks"
 42);
 43
 44
 45//-----------------------------------------------------------------------------
 46
 47SFXFMODEvent::SFXFMODEvent()
 48   : mGroup( NULL ),
 49     mHandle( NULL ),
 50     mGroupId( 0 ),
 51     mSibling( NULL )
 52{
 53   dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
 54   dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
 55}
 56
 57//-----------------------------------------------------------------------------
 58
 59SFXFMODEvent::SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle )
 60   : mGroup( group ),
 61     mHandle( handle ),
 62     mGroupId( 0 ),
 63     mSibling( NULL )
 64{
 65   dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
 66   dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
 67   
 68   // Fetch name.
 69   
 70   int index;
 71   char* name = NULL;
 72   
 73   SFXFMODDevice::smFunc->FMOD_Event_GetInfo( mHandle, &index, &name, ( FMOD_EVENT_INFO* ) 0 );
 74   
 75   mName = name;
 76   
 77   // Read out the parameter info so we can immediately create
 78   // the events on the client-side without having to open and
 79   // read all the project info there.
 80   
 81   int numParameters;
 82   SFXFMODDevice::smFunc->FMOD_Event_GetNumParameters( mHandle, &numParameters );
 83   if( numParameters > MaxNumParameters )
 84   {
 85      Con::errorf( "SFXFMODEvent::SFXFMODEvent - event '%s' has more parameters (%i) than supported per SFXTrack (%i)",
 86         getQualifiedName().c_str(),
 87         numParameters,
 88         MaxNumParameters );
 89      numParameters = MaxNumParameters;
 90   }
 91   
 92   for( U32 i = 0; i < numParameters; ++ i )
 93   {
 94      FMOD_EVENTPARAMETER* parameter;
 95      SFXFMODDevice::smFunc->FMOD_Event_GetParameterByIndex( mHandle, i, &parameter );
 96      
 97      SFXFMODDevice::smFunc->FMOD_EventParameter_GetInfo( parameter, &index, &name );
 98      setParameter( i, name );
 99         
100      // Get value and range of parameter.
101      
102      SFXFMODDevice::smFunc->FMOD_EventParameter_GetValue( parameter, &mParameterValues[ i ] );
103      SFXFMODDevice::smFunc->FMOD_EventParameter_GetRange( parameter, &mParameterRanges[ i ].x, &mParameterRanges[ i ].y );
104   }
105   
106   // Read out the properties and create a custom SFXDescription for the event.
107   
108   mDescription = new SFXDescription;
109   if( !group->isClientOnly() )
110      mDescription->assignId();
111      
112   mDescription->registerObject(
113      String::ToString( "%s_%s_Description",
114         group->getName(),
115         FMODEventPathToTorqueName( mName ).c_str()
116      )
117   );
118   if( group->isClientOnly() )
119      Sim::getRootGroup()->addObject( mDescription );
120   
121   FMOD_MODE modeValue;
122   float floatValue;
123   
124   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_MODE, &modeValue, true ) == FMOD_OK )
125      mDescription->mIs3D = ( modeValue == FMOD_3D );
126   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_VOLUME, &floatValue, true ) == FMOD_OK )
127      mDescription->mVolume = floatValue;
128   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_PITCH, &floatValue, true ) == FMOD_OK )
129      mDescription->mPitch = floatValue;
130   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MINDISTANCE, &floatValue, true ) == FMOD_OK )
131      mDescription->mMinDistance = floatValue;
132   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MAXDISTANCE, &floatValue, true ) == FMOD_OK )
133      mDescription->mMaxDistance = floatValue;
134   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEINSIDEANGLE, &floatValue, true ) == FMOD_OK )
135      mDescription->mConeInsideAngle = floatValue;
136   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEANGLE, &floatValue, true ) == FMOD_OK )
137      mDescription->mConeOutsideAngle = floatValue;
138   if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEVOLUME, &floatValue, true ) == FMOD_OK )
139      mDescription->mConeOutsideVolume = floatValue;
140      
141   // Don't read out fade values as we want to leave fade-effects to
142   // FMOD rather than having the fading system built into SFX pick
143   // these values up.
144}
145
146//-----------------------------------------------------------------------------
147
148SFXFMODEvent::~SFXFMODEvent()
149{
150}
151
152//-----------------------------------------------------------------------------
153
154void SFXFMODEvent::initPersistFields()
155{
156   addGroup( "DO NOT MODIFY!!" );
157   addField( "fmodGroup", TYPEID< SFXFMODEventGroup >(), Offset( mGroup, SFXFMODEvent ), "DO NOT MODIFY!!" );
158   addField( "fmodName", TypeRealString, Offset( mName, SFXFMODEvent ), "DO NOT MODIFY!!" );
159   addField( "fmodParameterRanges", TypePoint2F, Offset( mParameterRanges, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
160   addField( "fmodParameterValues", TypeF32, Offset( mParameterValues, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
161   endGroup( "DO NOT MODIFY!!" );
162   
163   Parent::initPersistFields();
164}
165
166//-----------------------------------------------------------------------------
167
168bool SFXFMODEvent::onAdd()
169{
170   if( !Parent::onAdd() )
171      return false;
172      
173   if( !mGroup )
174   {
175      Con::errorf( "SFXFMODEvent::onAdd - no group set; this event was not properly constructed" );
176      return false;
177   }
178   
179   mGroup->_addEvent( this );
180   mGroup->mProject->_addEvent( this );
181   
182   // For non-networked event datablocks, create the parameter
183   // instances now.
184   
185   if( isClientOnly() )
186      _createParameters();
187      
188   return true;
189}
190
191//-----------------------------------------------------------------------------
192
193void SFXFMODEvent::onRemove()
194{
195   Parent::onRemove();
196   
197   if( !mGroup )
198      return;
199   
200   release();
201   mGroup->_removeEvent( this );
202}
203
204//-----------------------------------------------------------------------------
205
206bool SFXFMODEvent::preload( bool server, String& errorStr )
207{
208   if( !Parent::preload( server, errorStr ) )
209      return false;
210      
211   if( !server )
212   {
213      if( !Sim::findObject( mGroupId, mGroup ) )
214      {
215         errorStr = String::ToString( "SFXFMODEvent - group '%i' does not exist", mGroupId );
216         return false;
217      }
218
219      // Create parameters.
220
221      _createParameters();
222   }
223      
224   return true;
225}
226
227//-----------------------------------------------------------------------------
228
229void SFXFMODEvent::packData( BitStream* stream )
230{
231   Parent::packData( stream );
232   
233   stream->write( mName );
234   stream->writeRangedS32( mGroup->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
235   
236   for( U32 i = 0; i < MaxNumParameters; ++ i )
237      if( stream->writeFlag( mParameters[ i ] ) )
238      {
239         stream->write( mParameterValues[ i ] );
240         stream->write( mParameterRanges[ i ].x );
241         stream->write( mParameterRanges[ i ].y );
242      }
243}
244
245//-----------------------------------------------------------------------------
246
247void SFXFMODEvent::unpackData( BitStream* stream )
248{
249   Parent::unpackData( stream );
250
251   stream->read( &mName );
252   mGroupId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
253   
254   for( U32 i = 0; i < MaxNumParameters; ++ i )
255      if( stream->readFlag() )
256      {
257         stream->read( &mParameterValues[ i ] );
258         stream->read( &mParameterRanges[ i ].x );
259         stream->read( &mParameterRanges[ i ].y );
260      }
261      else
262      {
263         mParameterValues[ i ] = 0.f;
264         mParameterRanges[ i ].x = 0.f;
265         mParameterRanges[ i ].y = 0.f;
266      }
267}
268
269//-----------------------------------------------------------------------------
270
271void SFXFMODEvent::acquire()
272{
273   if( mHandle )
274      return;
275      
276   mGroup->acquire();
277   if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
278         mGroup->mHandle, mName.c_str(), FMOD_EVENT_INFOONLY, &mHandle ) != FMOD_OK )
279   {
280      Con::errorf( "SFXFMODEvent::acquire() - failed to acquire event '%s'", getQualifiedName().c_str() );
281      return;
282   }
283}
284
285//-----------------------------------------------------------------------------
286
287void SFXFMODEvent::release()
288{
289   if( !mHandle )
290      return;
291      
292   SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, false );
293   mHandle = NULL;
294}
295
296//-----------------------------------------------------------------------------
297
298String SFXFMODEvent::getQualifiedName() const
299{
300   return String::ToString( "%s/%s", getEventGroup()->getQualifiedName().c_str(), mName.c_str() );
301}
302
303//-----------------------------------------------------------------------------
304
305void SFXFMODEvent::_createParameters()
306{
307   const String& projectFileName = getEventGroup()->getProject()->getFileName();
308   const String qualifiedGroupName = getEventGroup()->getQualifiedName();
309   const String description = String::ToString( "FMOD Event Parameter (%s)", projectFileName.c_str() );
310   
311   for( U32 i = 0; i < MaxNumParameters; ++ i )
312   {
313      StringTableEntry name = getParameter( i );
314      if( !name )
315         continue;
316         
317      SFXParameter* parameter = SFXParameter::find( name );
318      if( !parameter )
319      {
320         parameter = new SFXParameter();
321         parameter->setInternalName( name );
322         parameter->registerObject();
323         
324         // Set up parameter.
325         
326         parameter->setChannel( SFXChannelUser0 );
327         parameter->setRange( mParameterRanges[ i ] );
328         parameter->setDefaultValue( mParameterValues[ i ] );
329         parameter->setValue( mParameterValues[ i ] );
330         parameter->setDescription( description );
331         
332         // Set categories for easy filtering.
333         
334         static StringTableEntry sCategories = StringTable->insert( "categories" );
335         parameter->setDataField( sCategories, "0", "FMOD" );
336         parameter->setDataField( sCategories, "1", avar( "FMOD Project: %s", projectFileName.c_str() ) );
337         parameter->setDataField( sCategories, "2", avar( "FMOD Group: %s", qualifiedGroupName.c_str() ) );
338      }
339   }
340}
341