diff options
Diffstat (limited to 'game/code/sound/soundfx')
27 files changed, 4353 insertions, 0 deletions
diff --git a/game/code/sound/soundfx/allsoundfx.cpp b/game/code/sound/soundfx/allsoundfx.cpp new file mode 100644 index 0000000..4ee5e0b --- /dev/null +++ b/game/code/sound/soundfx/allsoundfx.cpp @@ -0,0 +1,14 @@ +#include <sound/soundfx/soundeffectplayer.cpp> +#include <sound/soundfx/soundfxfrontendlogic.cpp> +#include <sound/soundfx/soundfxgameplaylogic.cpp> +#include <sound/soundfx/soundfxlogic.cpp> +#include <sound/soundfx/soundfxpauselogic.cpp> +#include <sound/soundfx/reverbcontroller.cpp> +#include <sound/soundfx/reverbsettings.cpp> +#include <sound/soundfx/positionalsoundsettings.cpp> + +#ifdef RAD_PS2 +#include <sound/soundfx/ps2reverbcontroller.cpp> +#else +#include <sound/soundfx/gcreverbcontroller.cpp> +#endif
\ No newline at end of file diff --git a/game/code/sound/soundfx/gcreverbcontroller.cpp b/game/code/sound/soundfx/gcreverbcontroller.cpp new file mode 100644 index 0000000..4b6336a --- /dev/null +++ b/game/code/sound/soundfx/gcreverbcontroller.cpp @@ -0,0 +1,108 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: gcreverbcontroller.cpp +// +// Description: Implementation for the GCReverbController class, which provides +// the GC-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radsound_gcn.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/gcreverbcontroller.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// GCReverbController::GCReverbController +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +GCReverbController::GCReverbController() +{ + m_reverbInterface = ::radSoundEffectStdReverbGcnCreate( GMA_PERSISTENT ); + + registerReverbEffect( m_reverbInterface ); +} + +//============================================================================== +// GCReverbController::~GCReverbController +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +GCReverbController::~GCReverbController() +{ + m_reverbInterface->Release(); + m_reverbInterface = NULL; +} + +//============================================================================= +// GCReverbController::SetReverbOn +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void GCReverbController::SetReverbOn( reverbSettings* settings ) +{ + SetReverbGain( settings->GetGain() ); + m_reverbInterface->SetPreDelay( settings->GetGCPreDelay() ); + m_reverbInterface->SetReverbTime( settings->GetGCReverbTime() ); + m_reverbInterface->SetColoration( settings->GetGCColoration() ); + m_reverbInterface->SetDamping( settings->GetGCDamping() ); +} + +//============================================================================= +// GCReverbController::SetReverbOff +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void GCReverbController::SetReverbOff() +{ + SetReverbGain( 0.0f ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/sound/soundfx/gcreverbcontroller.h b/game/code/sound/soundfx/gcreverbcontroller.h new file mode 100644 index 0000000..3e1e101 --- /dev/null +++ b/game/code/sound/soundfx/gcreverbcontroller.h @@ -0,0 +1,54 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: gcreverbcontroller.h +// +// Description: Declaration for the GCReverbController class, which provides +// the GC-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +#ifndef GCREVERBCONTROLLER_H +#define GCREVERBCONTROLLER_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/reverbcontroller.h> + +//======================================== +// Forward References +//======================================== +struct IRadSoundEffectStdReverbGcn; + +//============================================================================= +// +// Synopsis: GCReverbController +// +//============================================================================= + +class GCReverbController : public ReverbController +{ + public: + GCReverbController(); + virtual ~GCReverbController(); + + void SetReverbOn( reverbSettings* settings ); + void SetReverbOff(); + + private: + //Prevent wasteful constructor creation. + GCReverbController( const GCReverbController& original ); + GCReverbController& operator=( const GCReverbController& rhs ); + + // + // Radsound's GC reverb interface + // + IRadSoundEffectStdReverbGcn* m_reverbInterface; +}; + + +#endif // GCREVERBCONTROLLER_H + diff --git a/game/code/sound/soundfx/ipositionalsoundsettings.h b/game/code/sound/soundfx/ipositionalsoundsettings.h new file mode 100644 index 0000000..3989621 --- /dev/null +++ b/game/code/sound/soundfx/ipositionalsoundsettings.h @@ -0,0 +1,59 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ipositionalsoundsettings.h +// +// Description: RadScript interface for positional sound settings +// +// History: 12/20/2002 + Created -- Darren +// +//============================================================================= + +#ifndef IPOSITIONALSOUNDSETTINGS_H +#define IPOSITIONALSOUNDSETTINGS_H + +//======================================== +// Nested Includes +//======================================== +#include <radobject.hpp> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: IPositionalSoundSettings +// +//============================================================================= + +class IPositionalSoundSettings : public IRefCount +{ + // + // Name of sound resource to play + // + virtual void SetClipName( const char* clipName ) = 0; + + // + // Distance at which volume is maxed + // + virtual void SetMinDistance( float min ) = 0; + + // + // Distance at which volume reaches zero + // + virtual void SetMaxDistance( float max ) = 0; + + // + // Probability of sound playing + // + virtual void SetPlaybackProbability( float prob ) = 0; +}; + +//***************************************************************************** +// +//Inline Public Member Functions +// +//***************************************************************************** + +#endif //IPOSITIONALSOUNDSETTINGS_H diff --git a/game/code/sound/soundfx/ireverbsettings.h b/game/code/sound/soundfx/ireverbsettings.h new file mode 100644 index 0000000..c1288f3 --- /dev/null +++ b/game/code/sound/soundfx/ireverbsettings.h @@ -0,0 +1,73 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ireverbsettings.h +// +// Description: Declaration for IReverbSettings class, which is the interface +// visible in RadTuner for creating and storing a set of reverb +// parameters. +// +// History: 11/3/2002 + Created -- Darren +// +//============================================================================= + +#ifndef IREVERBSETTINGS_H +#define IREVERBSETTINGS_H + +//======================================== +// Nested Includes +//======================================== +#include <radobject.hpp> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: IReverbSettings +// +//============================================================================= + +struct IReverbSettings : public IRefCount +{ + virtual void SetGain( float gain ) = 0; + virtual void SetFadeInTime( float milliseconds ) = 0; + virtual void SetFadeOutTime( float milliseconds ) = 0; + + // + // See radsound_<platform name>.hpp for details on this stuff + // + virtual void SetXboxRoom( int mBvalue ) = 0; + virtual void SetXboxRoomHF( int mBvalue ) = 0; + virtual void SetXboxRoomRolloffFactor( float value ) = 0; + virtual void SetXboxDecayTime( float value ) = 0; + virtual void SetXboxDecayHFRatio( float value ) = 0; + virtual void SetXboxReflections( int mBvalue ) = 0; + virtual void SetXboxReflectionsDelay( float value ) = 0; + virtual void SetXboxReverb( int mBvalue ) = 0; + virtual void SetXboxReverbDelay( float value ) = 0; + virtual void SetXboxDiffusion( float value ) = 0; + virtual void SetXboxDensity( float value ) = 0; + virtual void SetXboxHFReference( float value ) = 0; + + // No RadTuner interface for enumerations as far as I know, so + // we'll have to cast whatever integer we get here + virtual void SetPS2ReverbMode( int mode ) = 0; + + virtual void SetPS2Delay( float delayTime ) = 0; + virtual void SetPS2Feedback( float feedback ) = 0; + + virtual void SetGCPreDelay( float milliseconds ) = 0; + virtual void SetGCReverbTime( float milliseconds ) = 0; + virtual void SetGCColoration( float coloration ) = 0; + virtual void SetGCDamping( float damping ) = 0; + + // Must be defined for all platforms cause of the script. + virtual void SetWinEnvironmentDiffusion( float diffusion ) = 0; + virtual void SetWinAirAbsorptionHF( float value ) = 0; +}; + + +#endif // IREVERBSETTINGS_H + diff --git a/game/code/sound/soundfx/positionalsoundsettings.cpp b/game/code/sound/soundfx/positionalsoundsettings.cpp new file mode 100644 index 0000000..670bf9b --- /dev/null +++ b/game/code/sound/soundfx/positionalsoundsettings.cpp @@ -0,0 +1,180 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: positionalsoundsettings.cpp +// +// Description: Implement positionalSoundSettings +// +// History: 12/20/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <string.h> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/positionalsoundsettings.h> + +#include <memory/srrmemory.h> + + +//***************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//***************************************************************************** + +// +// Initialially the list is empty +// +positionalSoundSettings* radLinkedClass< positionalSoundSettings >::s_pLinkedClassHead = NULL; +positionalSoundSettings* radLinkedClass< positionalSoundSettings >::s_pLinkedClassTail = NULL; + +//***************************************************************************** +// +// Public Member Functions +// +//***************************************************************************** + +//============================================================================= +// positionalSoundSettings::positionalSoundSettings +//============================================================================= +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +positionalSoundSettings::positionalSoundSettings() : + radRefCount( 0 ), + m_clipName( NULL ), + m_minDist( 10.0f ), + m_maxDist( 100.0f ), + m_playProbability( 1.0f ) +{ +} + +//============================================================================= +// positionalSoundSettings::~positionalSoundSettings +//============================================================================= +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================= +positionalSoundSettings::~positionalSoundSettings() +{ + delete m_clipName; +} + +//============================================================================= +// positionalSoundSettings::SetClipName +//============================================================================= +// Description: Set name of the sound resource to be played at this position +// +// Parameters: clipName - name of sound resource +// +// Return: void +// +//============================================================================= +void positionalSoundSettings::SetClipName( const char* clipName ) +{ + rAssert( clipName != NULL ); + + m_clipName = new(GMA_PERSISTENT) char[strlen(clipName)+1]; + strcpy( m_clipName, clipName ); +} + +//============================================================================= +// positionalSoundSettings::SetMinDistance +//============================================================================= +// Description: Set distance at which volume is maxed (kinda counterintuitive, +// but that seems to be the convention) +// +// Parameters: min - distance to set +// +// Return: void +// +//============================================================================= +void positionalSoundSettings::SetMinDistance( float min ) +{ + rAssert( min >= 0.0f ); + + m_minDist = min; +} + +//============================================================================= +// positionalSoundSettings::SetMaxDistance +//============================================================================= +// Description: Set the distance at which the volume reaches zero +// +// Parameters: max - distance to set +// +// Return: void +// +//============================================================================= +void positionalSoundSettings::SetMaxDistance( float max ) +{ + rAssert( max >= 0.0f ); + + m_maxDist = max; +} + +//============================================================================= +// positionalSoundSettings::SetPlaybackProbability +//============================================================================= +// Description: Set probability that sound will be played when we enter +// the trigger volume +// +// Parameters: prob - probability on scale of 0.0 to 1.0 +// +// Return: void +// +//============================================================================= +void positionalSoundSettings::SetPlaybackProbability( float prob ) +{ + rAssert( prob >= 0.0f ); + rAssert( prob <= 1.0f ); + + m_playProbability = prob; +} + +//***************************************************************************** +// +// Private Member Functions +// +//***************************************************************************** + +//****************************************************************************** +// Factory functions +//****************************************************************************** + +//============================================================================== +// PositionalSettingsObjCreate +//============================================================================== +// Description: Factory function for creating positionalSoundSettings objects. +// Called by RadScript. +// +// Parameters: ppParametersObj - Address of ptr to new object +// allocator - FTT pool to allocate object within +// +// Return: N/A. +// +//============================================================================== +void PositionalSettingsObjCreate +( + IPositionalSoundSettings** ppParametersObj, + radMemoryAllocator allocator +) +{ + rAssert( ppParametersObj != NULL ); + (*ppParametersObj) = new ( allocator ) positionalSoundSettings( ); + (*ppParametersObj)->AddRef( ); +} diff --git a/game/code/sound/soundfx/positionalsoundsettings.h b/game/code/sound/soundfx/positionalsoundsettings.h new file mode 100644 index 0000000..8174598 --- /dev/null +++ b/game/code/sound/soundfx/positionalsoundsettings.h @@ -0,0 +1,80 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: positionalsoundsettings.h +// +// Description: Declaration of object encapsulating positional sound settings +// +// History: 12/20/2002 + Created -- Darren +// +//============================================================================= + +#ifndef POSITIONALSOUNDSETTINGS_H +#define POSITIONALSOUNDSETTINGS_H + +//======================================== +// Nested Includes +//======================================== +#include <radlinkedclass.hpp> + +#include <sound/soundfx/ipositionalsoundsettings.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: positionalSoundSettings +// +//============================================================================= + +class positionalSoundSettings: public IPositionalSoundSettings, + public radLinkedClass< positionalSoundSettings >, + public radRefCount +{ + public: + IMPLEMENT_REFCOUNTED( "positionalSoundSettings" ); + positionalSoundSettings(); + virtual ~positionalSoundSettings(); + + void SetClipName( const char* clipName ); + const char* GetClipName() { return( m_clipName ); } + + void SetMinDistance( float min ); + float GetMinDistance() { return( m_minDist ); } + + void SetMaxDistance( float max ); + float GetMaxDistance() { return( m_maxDist ); } + + void SetPlaybackProbability( float prob ); + float GetPlaybackProbability() { return( m_playProbability ); } + + private: + //Prevent wasteful constructor creation. + positionalSoundSettings( const positionalSoundSettings& positionalsoundsettings ); + positionalSoundSettings& operator=( const positionalSoundSettings& positionalsoundsettings ); + + // + // Settings + // + char* m_clipName; + float m_minDist; + float m_maxDist; + float m_playProbability; +}; + +//============================================================================= +// Factory Functions +//============================================================================= + +// +// Create a positionalSoundSettings object +// +void PositionalSettingsObjCreate +( + IPositionalSoundSettings** ppSettings, + radMemoryAllocator allocator +); + +#endif //POSITIONALSOUNDSETTINGS_H diff --git a/game/code/sound/soundfx/ps2reverbcontroller.cpp b/game/code/sound/soundfx/ps2reverbcontroller.cpp new file mode 100644 index 0000000..cf88160 --- /dev/null +++ b/game/code/sound/soundfx/ps2reverbcontroller.cpp @@ -0,0 +1,124 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ps2reverbcontroller.cpp +// +// Description: Implementation for the PS2ReverbController class, which provides +// the PS2-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radsound_ps2.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/ps2reverbcontroller.h> + +#include <sound/soundfx/reverbsettings.h> + +#include <memory/srrmemory.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// PS2ReverbController::PS2ReverbController +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PS2ReverbController::PS2ReverbController() +{ + m_reverbInterface = ::radSoundCreateEffectPs2( GMA_PERSISTENT ); + + // + // Wheee!!!! + // + m_reverbInterface->SetMode( IRadSoundEffectPs2::Off ); + + registerReverbEffect( m_reverbInterface ); +} + +//============================================================================== +// PS2ReverbController::~PS2ReverbController +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +PS2ReverbController::~PS2ReverbController() +{ + m_reverbInterface->Release(); + m_reverbInterface = NULL; +} + +//============================================================================= +// PS2ReverbController::SetReverbOn +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void PS2ReverbController::SetReverbOn( reverbSettings* settings ) +{ + if( settings != NULL ) + { + m_reverbInterface->SetMode( static_cast<IRadSoundEffectPs2::Mode>(settings->GetPS2ReverbMode()) ); + m_reverbInterface->SetGain( settings->GetGain() ); + m_reverbInterface->SetDelay( settings->GetPS2Delay() ); + m_reverbInterface->SetFeedback( settings->GetPS2Feedback() ); + + prepareFadeSettings( settings->GetGain(), settings->GetFadeInTime(), + settings->GetFadeOutTime() ); + } + else + { + rReleaseString( "Settings is NULL\n" ); + } +} + +//============================================================================= +// PS2ReverbController::SetReverbOff +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void PS2ReverbController::SetReverbOff() +{ + startFadeOut(); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/sound/soundfx/ps2reverbcontroller.h b/game/code/sound/soundfx/ps2reverbcontroller.h new file mode 100644 index 0000000..d756bc2 --- /dev/null +++ b/game/code/sound/soundfx/ps2reverbcontroller.h @@ -0,0 +1,54 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: ps2reverbcontroller.h +// +// Description: Declaration for the PS2ReverbController class, which provides +// the PS2-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +#ifndef PS2REVERBCONTROLLER_H +#define PS2REVERBCONTROLLER_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/reverbcontroller.h> + +//======================================== +// Forward References +//======================================== +struct IRadSoundEffectPs2; + +//============================================================================= +// +// Synopsis: PS2ReverbController +// +//============================================================================= + +class PS2ReverbController : public ReverbController +{ + public: + PS2ReverbController(); + virtual ~PS2ReverbController(); + + void SetReverbOn( reverbSettings* settings ); + void SetReverbOff(); + + private: + //Prevent wasteful constructor creation. + PS2ReverbController( const PS2ReverbController& original ); + PS2ReverbController& operator=( const PS2ReverbController& rhs ); + + // + // Radsound's PS2 reverb interface + // + IRadSoundEffectPs2* m_reverbInterface; +}; + + +#endif // PS2REVERBCONTROLLER_H + diff --git a/game/code/sound/soundfx/reverbcontroller.cpp b/game/code/sound/soundfx/reverbcontroller.cpp new file mode 100644 index 0000000..672d542 --- /dev/null +++ b/game/code/sound/soundfx/reverbcontroller.cpp @@ -0,0 +1,410 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: reverbcontroller.cpp +// +// Description: Implementation for ReverbController, which turns reverb on +// and off and sets control values. +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radsound_hal.hpp> +#include <radnamespace.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/reverbcontroller.h> + +#include <sound/soundfx/reverbsettings.h> +#include <sound/soundrenderer/soundrenderingmanager.h> + +#include <events/eventmanager.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// ReverbController::ReverbController +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ReverbController::ReverbController() : + m_targetGain( 0.0f ), + m_currentGain( 0.0f ), + m_fadeInMultiplier( 1.0f ), + m_fadeOutMultiplier( 1.0f ), + m_lastReverb( NULL ), + m_queuedReverb( NULL ) +{ + unsigned int event; + EventManager* eventMgr = GetEventManager(); + + rAssert( eventMgr != NULL ); + + // + // Register all of the ambience events + // + for( event = EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_CITY; + event < EVENT_LOCATOR + LocatorEvent::PARKED_BIRDS; + ++event ) + { + eventMgr->AddListener( this, static_cast<EventEnum>(event) ); + } + eventMgr->AddListener(this, EVENT_MISSION_RESET); + eventMgr->AddListener(this, EVENT_MISSION_CHARACTER_RESET); + + // bmc -- add registering of extra ambient sound events (placeholder and otherwise) + for( event = EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_COUNTRY_NIGHT; + event <= EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PLACEHOLDER9; + ++event ) + { + eventMgr->AddListener( this, static_cast<EventEnum>(event) ); + } + + for( event = EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_SEASIDE_NIGHT; + event <= EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PLACEHOLDER16; + ++event ) + { + eventMgr->AddListener( this, static_cast<EventEnum>(event) ); + } + // bmc + + +} + +//============================================================================== +// ReverbController::~ReverbController +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +ReverbController::~ReverbController() +{ + GetEventManager()->RemoveAll( this ); +} + +//============================================================================= +// ReverbController::SetReverbGain +//============================================================================= +// Description: Set the gain on the entire reverb system +// +// Parameters: gain - 0 to 1 gain value +// +// Return: None +// +//============================================================================= +void ReverbController::SetReverbGain( float gain ) +{ + ::radSoundHalSystemGet()->SetAuxGain( REVERB_AUX_EFFECT_NUMBER, gain ); +} + +//============================================================================= +// ReverbController::HandleEvent +//============================================================================= +// Description: Listen for events that will cause us to switch reverb modes +// on and off +// +// Parameters: id - event ID +// pEventData - user data, unused +// +// Return: void +// +//============================================================================= +void ReverbController::HandleEvent( EventEnum id, void* pEventData ) +{ + reverbSettings* settingsObj = NULL; + reverbSettings* oldSettings = m_lastReverb; + + switch( id ) + { + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PP_ROOM_1: + settingsObj = getReverbSettings( "pproom1" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PP_ROOM_2: + settingsObj = getReverbSettings( "pproom2" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PP_ROOM_3: + settingsObj = getReverbSettings( "pproom3" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PP_TUNNEL_1: + settingsObj = getReverbSettings( "PP_tunnel_01" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_PP_TUNNEL_2: + settingsObj = getReverbSettings( "PP_tunnel_02" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_BURNS_TUNNEL: + settingsObj = getReverbSettings( "burns_tunnel" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_MANSION_INTERIOR: + settingsObj = getReverbSettings( "mansion_interior" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_SEWERS: + settingsObj = getReverbSettings( "sewers" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_STONE_CUTTER_TUNNEL: + settingsObj = getReverbSettings( "stonecuttertunnel" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_STONE_CUTTER_HALL: + settingsObj = getReverbSettings( "stonecutterhall" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_STADIUM_TUNNEL: + settingsObj = getReverbSettings( "stadiumtunnel" ); + break; + + case EVENT_LOCATOR + LocatorEvent::AMBIENT_SOUND_KRUSTYLU_EXTERIOR: + settingsObj = getReverbSettings( "krustylu" ); + break; + + default: + // + // This should be triggered by any ambient sound trigger that + // isn't mapped to reverb above + // + SetReverbOff(); + m_lastReverb = NULL; + break; + } + + if( settingsObj != NULL ) + { + // + // No sense in switching to something we're already doing. That only + // seems to lead to unnecessary clicks on PS2 anyway. + // + if( settingsObj != oldSettings ) + { + if( m_currentGain > 0.0f ) + { + // + // We can't do a sudden switch without hearing popping. Queue up this + // switch to occur after we fade out + // + prepareFadeSettings( 0.0f, settingsObj->GetFadeInTime(), settingsObj->GetFadeOutTime() ); + m_queuedReverb = m_lastReverb; + } + else + { + SetReverbOn( settingsObj ); + } + } + } +} + +//============================================================================= +// ReverbController::ServiceOncePerFrame +//============================================================================= +// Description: Handle the fading in and fading out of reverb +// +// Parameters: elapsedTime - elapsed time since last update +// +// Return: void +// +//============================================================================= +void ReverbController::ServiceOncePerFrame( unsigned int elapsedTime ) +{ + if( m_currentGain == m_targetGain ) + { + if( ( m_targetGain == 0.0f ) + && ( m_queuedReverb != NULL ) ) + { + // + // We're done fading out, now we can make the switch and fade + // back in + // + SetReverbOn( m_queuedReverb ); + m_queuedReverb = NULL; + } + + return; + } + else if( m_currentGain < m_targetGain ) + { + m_currentGain += ( elapsedTime * m_fadeInMultiplier ); + if( m_currentGain > m_targetGain ) + { + m_currentGain = m_targetGain; + } + } + else + { + m_currentGain -= ( elapsedTime * m_fadeOutMultiplier ); + if( m_currentGain < m_targetGain ) + { + m_currentGain = m_targetGain; + } + } + + SetReverbGain( m_currentGain ); +} + +//============================================================================= +// ReverbController::PauseReverb +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void ReverbController::PauseReverb() +{ + if( m_lastReverb != NULL ) + { + SetReverbOff(); + } +} + +//============================================================================= +// ReverbController::UnpauseReverb +//============================================================================= +// Description: Comment +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void ReverbController::UnpauseReverb() +{ + if( m_lastReverb != NULL ) + { + SetReverbOn( m_lastReverb ); + } +} + +//****************************************************************************** +// +// Protected Member Functions +// +//****************************************************************************** + +void ReverbController::registerReverbEffect( IRadSoundHalEffect* reverbEffect ) +{ + ::radSoundHalSystemGet()->SetAuxEffect( REVERB_AUX_EFFECT_NUMBER, reverbEffect ); + ::radSoundHalSystemGet()->SetAuxGain( REVERB_AUX_EFFECT_NUMBER, 0.0f ); + + Sound::daSoundRenderingManagerGet()->GetTheListener()->SetEnvironmentAuxSend( REVERB_AUX_EFFECT_NUMBER ); + Sound::daSoundRenderingManagerGet()->GetTheListener()->SetEnvEffectsEnabled( true ); +} + +//============================================================================= +// ReverbController::prepareFadeSettings +//============================================================================= +// Description: Set up the member values for fading reverb in and out +// +// Parameters: targetGain - gain value to gradually move to +// fadeInTime - time in seconds for the fade, assuming we're +// going from 0.0 to 1.0 +// fadeOutTime - similar to fadeInTime +// +// Return: void +// +//============================================================================= +void ReverbController::prepareFadeSettings( float targetGain, float fadeInTime, float fadeOutTime ) +{ + m_targetGain = targetGain; + + m_fadeInMultiplier = fadeInTime; + if( m_fadeInMultiplier == 0.0f ) + { + m_fadeInMultiplier = 1.0f; + } + else + { + m_fadeInMultiplier = 1.0f / m_fadeInMultiplier; + } + m_fadeOutMultiplier = fadeOutTime; + if( m_fadeOutMultiplier == 0.0f ) + { + m_fadeOutMultiplier = 1.0f; + } + else + { + m_fadeOutMultiplier = 1.0f / m_fadeInMultiplier; + } +} + +//============================================================================= +// ReverbController::startFadeOut +//============================================================================= +// Description: Set up for the gradual reverb fadeout +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void ReverbController::startFadeOut() +{ + m_targetGain = 0.0f; +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// ReverbController::getReverbSettings +//============================================================================= +// Description: Retrieve the object containing a group of reverb settings +// +// Parameters: objName - name of reverbSettings object to find +// +// Return: void +// +//============================================================================= +reverbSettings* ReverbController::getReverbSettings( const char* objName ) +{ + IRadNameSpace* nameSpace; + + nameSpace = Sound::daSoundRenderingManagerGet()->GetTuningNamespace(); + rAssert( nameSpace != NULL ); + + if ( objName != NULL ) + { + rTunePrintf( "\n\nAUDIO: Reverb Settings: [%s]\n\n\n", objName ); + } + + m_lastReverb = static_cast<reverbSettings*>(nameSpace->GetInstance( objName )); + + return( m_lastReverb ); +}
\ No newline at end of file diff --git a/game/code/sound/soundfx/reverbcontroller.h b/game/code/sound/soundfx/reverbcontroller.h new file mode 100644 index 0000000..d3bc037 --- /dev/null +++ b/game/code/sound/soundfx/reverbcontroller.h @@ -0,0 +1,83 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: reverbcontroller.h +// +// Description: Declaration for the ReverbController class, which turns reverb +// on and off and applies the required control values. +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +#ifndef REVERBCONTROLLER_H +#define REVERBCONTROLLER_H + +//======================================== +// Nested Includes +//======================================== +#include <events/eventlistener.h> + +//======================================== +// Forward References +//======================================== + +struct IRadSoundHalEffect; +class reverbSettings; + +//============================================================================= +// +// Synopsis: ReverbController +// +//============================================================================= + +class ReverbController : public EventListener +{ + public: + ReverbController(); + virtual ~ReverbController(); + + void SetReverbGain( float gain ); + + virtual void SetReverbOn( reverbSettings* settings ) = 0; + virtual void SetReverbOff() = 0; + + virtual void PauseReverb(); + virtual void UnpauseReverb(); + + // + // EventListener interface + // + void HandleEvent( EventEnum id, void* pEventData ); + + void ServiceOncePerFrame( unsigned int elapsedTime ); + + protected: + static const int REVERB_AUX_EFFECT_NUMBER = 0; + + void registerReverbEffect( IRadSoundHalEffect* reverbEffect ); + void prepareFadeSettings( float targetGain, float fadeInTime, float fadeOutTime ); + void startFadeOut(); + + private: + //Prevent wasteful constructor creation. + ReverbController( const ReverbController& original ); + ReverbController& operator=( const ReverbController& rhs ); + + reverbSettings* getReverbSettings( const char* objName ); + + // + // Used for gradual changes in reverb + // + float m_targetGain; + float m_currentGain; + float m_fadeInMultiplier; + float m_fadeOutMultiplier; + + reverbSettings* m_lastReverb; + reverbSettings* m_queuedReverb; +}; + + +#endif // REVERBCONTROLLER_H + diff --git a/game/code/sound/soundfx/reverbsettings.cpp b/game/code/sound/soundfx/reverbsettings.cpp new file mode 100644 index 0000000..d44c200 --- /dev/null +++ b/game/code/sound/soundfx/reverbsettings.cpp @@ -0,0 +1,133 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: reverbsettings.cpp +// +// Description: Definition for the reverbSettings class, which stores sets +// of reverb parameters to be applied whenever we want that +// reverby sound thing happening. NOTE: lower-case "r" needed +// to make RadScript happy. +// +// History: 11/5/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/reverbsettings.h> + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +// +// Initialially the list is empty +// +reverbSettings* radLinkedClass< reverbSettings >::s_pLinkedClassHead = NULL; +reverbSettings* radLinkedClass< reverbSettings >::s_pLinkedClassTail = NULL; + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// reverbSettings::reverbSettings +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +reverbSettings::reverbSettings() : + radRefCount( 0 ), + + m_gain( 0.0f ), + m_fadeInTime( 0.0f ), + m_fadeOutTime( 0.0f ), + + m_xboxRoom( 0 ), + m_xboxRoomHF( 0 ), + m_xboxRoomRolloff( 0.0f ), + m_xboxDecay( 0.0f ), + m_xboxDecayHFRatio( 0.0f ), + m_xboxReflections( 0 ), + m_xboxReflectionsDelay( 0.0f ), + m_xboxReverb( 0 ), + m_xboxReverbDelay( 0.0f ), + m_xboxDiffusion( 0.0f ), + m_xboxDensity( 0.0f ), + m_xboxHFReference( 0.0f ), + + m_ps2ReverbMode( 0 ), + m_ps2Delay( 0.0f ), + m_ps2Feedback( 0.0f ), + + m_gcPreDelay( 0.0f ), + m_gcReverbTime( 0.0f ), + m_gcColoration( 0.0f ), + m_gcDamping( 0.0f ), + + m_winEnvironmentDiffusion( 1.0f ), + m_winAirAbsorptionHF( -5.0f ) +{ +} + +//============================================================================== +// reverbSettings::~reverbSettings +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +reverbSettings::~reverbSettings() +{ +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//****************************************************************************** +// Factory functions +//****************************************************************************** + +//============================================================================== +// ReverbSettingsObjCreate +//============================================================================== +// Description: Factory function for creating reverbSettings objects. +// Called by RadScript. +// +// Parameters: ppSettings - Address of ptr to new object +// allocator - FTT pool to allocate object within +// +// Return: N/A. +// +//============================================================================== +void ReverbSettingsObjCreate +( + IReverbSettings** ppSettings, + radMemoryAllocator allocator +) +{ + rAssert( ppSettings != NULL ); + (*ppSettings) = new ( allocator ) reverbSettings( ); + (*ppSettings)->AddRef( ); +} + diff --git a/game/code/sound/soundfx/reverbsettings.h b/game/code/sound/soundfx/reverbsettings.h new file mode 100644 index 0000000..8ea3bbe --- /dev/null +++ b/game/code/sound/soundfx/reverbsettings.h @@ -0,0 +1,158 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: reverbsettings.h +// +// Description: Declaration for the reverbSettings class, which stores sets +// of reverb parameters to be applied whenever we want that +// reverby sound thing happening. NOTE: lower-case "r" needed +// to make RadScript happy. +// +// History: 11/5/2002 + Created -- Darren +// +//============================================================================= + +#ifndef REVERBSETTINGS_H +#define REVERBSETTINGS_H + +//======================================== +// Nested Includes +//======================================== +#include <radobject.hpp> +#include <radlinkedclass.hpp> + +#include <sound/soundfx/ireverbsettings.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: reverbSettings +// +//============================================================================= + +class reverbSettings : public IReverbSettings, + public radLinkedClass< reverbSettings >, + public radRefCount +{ + public: + IMPLEMENT_REFCOUNTED( "reverbSettings" ); + + reverbSettings(); + virtual ~reverbSettings(); + + void SetGain( float gain ) { m_gain = gain; } + float GetGain() { return( m_gain ); } + void SetFadeInTime( float milliseconds ) { m_fadeInTime = milliseconds; } + float GetFadeInTime() { return( m_fadeInTime ); } + void SetFadeOutTime( float milliseconds ) { m_fadeOutTime = milliseconds; } + float GetFadeOutTime() { return( m_fadeOutTime ); } + + // + // See radsound_<platform name>.hpp for details on this stuff + // + void SetXboxRoom( int mBvalue ) { m_xboxRoom = mBvalue; } + int GetXboxRoom() { return( m_xboxRoom ); } + void SetXboxRoomHF( int mBvalue ) { m_xboxRoomHF = mBvalue; } + int GetXboxRoomHF() { return( m_xboxRoomHF ); } + void SetXboxRoomRolloffFactor( float value ) { m_xboxRoomRolloff = value; } + float GetXboxRoomRolloffFactor() { return( m_xboxRoomRolloff ); } + void SetXboxDecayTime( float value ) { m_xboxDecay = value; } + float GetXboxDecayTime() { return( m_xboxDecay ); } + void SetXboxDecayHFRatio( float value ) { m_xboxDecayHFRatio = value; } + float GetXboxDecayHFRatio() { return( m_xboxDecayHFRatio ); } + void SetXboxReflections( int mBvalue ) { m_xboxReflections = mBvalue; } + int GetXboxReflections() { return( m_xboxReflections ); } + void SetXboxReflectionsDelay( float value ) { m_xboxReflectionsDelay = value; } + float GetXboxReflectionsDelay() { return( m_xboxReflectionsDelay ); } + void SetXboxReverb( int mBvalue ) { m_xboxReverb = mBvalue; } + int GetXboxReverb() { return( m_xboxReverb ); } + void SetXboxReverbDelay( float value ) { m_xboxReverbDelay = value; } + float GetXboxReverbDelay() { return( m_xboxReverbDelay ); } + void SetXboxDiffusion( float value ) { m_xboxDiffusion = value; } + float GetXboxDiffusion() { return( m_xboxDiffusion ); } + void SetXboxDensity( float value ) { m_xboxDensity = value; } + float GetXboxDensity() { return( m_xboxDensity ); } + void SetXboxHFReference( float value ) { m_xboxHFReference = value; } + float GetXboxHFReference() { return( m_xboxHFReference ); } + + // No RadTuner interface for enumerations as far as I know, so + // we'll have to cast whatever integer we get here + void SetPS2ReverbMode( int mode ) { m_ps2ReverbMode = mode; } + int GetPS2ReverbMode() { return( m_ps2ReverbMode ); } + + void SetPS2Delay( float delayTime ) { m_ps2Delay = delayTime; } + float GetPS2Delay() { return( m_ps2Delay ); } + void SetPS2Feedback( float feedback ) { m_ps2Feedback = feedback; } + float GetPS2Feedback() { return( m_ps2Feedback ); } + + void SetGCPreDelay( float milliseconds ) { m_gcPreDelay = milliseconds; } + float GetGCPreDelay() { return( m_gcPreDelay ); } + void SetGCReverbTime( float milliseconds ) { m_gcReverbTime = milliseconds; } + float GetGCReverbTime() { return( m_gcReverbTime ); } + void SetGCColoration( float coloration ) { m_gcColoration = coloration; } + float GetGCColoration() { return( m_gcColoration ); } + void SetGCDamping( float damping ) { m_gcDamping = damping; } + float GetGCDamping() { return( m_gcDamping ); } + + // Must be defined for all platforms cause of the script. + void SetWinEnvironmentDiffusion( float diffusion ) { m_winEnvironmentDiffusion = diffusion; } + float GetWinEnvironmentDiffusion() const { return m_winEnvironmentDiffusion; } + void SetWinAirAbsorptionHF( float value ) { m_winAirAbsorptionHF = value; } + float GetWinAirAbsorptionHF() const { return m_winAirAbsorptionHF; } + + private: + //Prevent wasteful constructor creation. + reverbSettings( const reverbSettings& original ); + reverbSettings& operator=( const reverbSettings& rhs ); + + // + // Reverb parameters + // + float m_gain; + float m_fadeInTime; + float m_fadeOutTime; + + int m_xboxRoom; + int m_xboxRoomHF; + float m_xboxRoomRolloff; + float m_xboxDecay; + float m_xboxDecayHFRatio; + int m_xboxReflections; + float m_xboxReflectionsDelay; + int m_xboxReverb; + float m_xboxReverbDelay; + float m_xboxDiffusion; + float m_xboxDensity; + float m_xboxHFReference; + + int m_ps2ReverbMode; + float m_ps2Delay; + float m_ps2Feedback; + + float m_gcPreDelay; + float m_gcReverbTime; + float m_gcColoration; + float m_gcDamping; + + float m_winEnvironmentDiffusion; + float m_winAirAbsorptionHF; +}; + +//============================================================================= +// Factory Functions +//============================================================================= + +// +// Create a reverbSettings object +// +void ReverbSettingsObjCreate +( + IReverbSettings** ppSettings, + radMemoryAllocator allocator +); + +#endif // REVERBSETTINGS_H + diff --git a/game/code/sound/soundfx/soundeffectplayer.cpp b/game/code/sound/soundfx/soundeffectplayer.cpp new file mode 100644 index 0000000..5847956 --- /dev/null +++ b/game/code/sound/soundfx/soundeffectplayer.cpp @@ -0,0 +1,249 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundeffectplayer.cpp +// +// Description: Implement SoundEffectPlayer, which switches between +// the objects that direct the soundfx logic for various game +// states +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/soundeffectplayer.h> + +#include <sound/soundfx/soundfxfrontendlogic.h> +#include <sound/soundfx/soundfxgameplaylogic.h> +#include <sound/soundfx/soundfxpauselogic.h> + +#ifdef RAD_XBOX +#include <sound/soundfx/xboxreverbcontroller.h> +#elif RAD_WIN32 +#include <sound/soundfx/win32reverbcontroller.h> +#elif RAD_PS2 +#include <sound/soundfx/ps2reverbcontroller.h> +#else +#include <sound/soundfx/gcreverbcontroller.h> +#endif + +#include <memory/srrmemory.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SoundEffectPlayer::SoundEffectPlayer +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundEffectPlayer::SoundEffectPlayer() : + m_reverbController( NULL ), + m_currentState( FXSTATE_INVALID ) +{ + unsigned int i; + + for( i = 0; i < FXSTATE_MAX_STATES; i++ ) + { + m_logicObjects[i] = NULL; + } + + initialize(); +} + +//============================================================================== +// SoundEffectPlayer::~SoundEffectPlayer +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundEffectPlayer::~SoundEffectPlayer() +{ + unsigned int i; + + for( i = 0; i < FXSTATE_MAX_STATES; i++ ) + { + if( m_logicObjects[i] != NULL ) + { + delete m_logicObjects[i]; + } + } + + delete m_reverbController; +} + +//============================================================================= +// SoundEffectPlayer::ServiceOncePerFrame +//============================================================================= +// Description: Positional sound servicing +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::ServiceOncePerFrame( unsigned int elapsedTime ) +{ + if( m_currentState != FXSTATE_INVALID ) + { + m_logicObjects[m_currentState]->ServiceOncePerFrame( elapsedTime ); + } + + m_reverbController->ServiceOncePerFrame( elapsedTime ); +} + +void SoundEffectPlayer::OnPauseStart() +{ + m_reverbController->PauseReverb(); +} + +void SoundEffectPlayer::OnPauseEnd() +{ + m_reverbController->UnpauseReverb(); +} + +//============================================================================= +// SoundEffectPlayer::PlayCarOptionStinger +//============================================================================= +// Description: The following four functions play stinger sounds for the +// level settings in the options menu +// +// Parameters: trim - trim setting to play it at +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::PlayCarOptionStinger( float trim ) +{ + playStinger( "car_stinger", trim ); +} + +void SoundEffectPlayer::PlayDialogOptionStinger( float trim ) +{ + playStinger( "dialog_stinger", trim ); +} + +void SoundEffectPlayer::PlayMusicOptionStinger( float trim ) +{ + playStinger( "music_stinger", trim ); +} + +void SoundEffectPlayer::PlaySfxOptionStinger( float trim ) +{ + playStinger( "sfx_stinger", trim ); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// SoundEffectPlayer::initialize +//============================================================================= +// Description: Create the sound FX logic objects during initialization +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::initialize() +{ + m_logicObjects[FXSTATE_FRONTEND] = new(GMA_PERSISTENT) SoundFXFrontEndLogic(); + m_logicObjects[FXSTATE_GAMEPLAY] = new(GMA_PERSISTENT) SoundFXGameplayLogic(); + m_logicObjects[FXSTATE_PAUSED] = new(GMA_PERSISTENT) SoundFXPauseLogic(); + +#ifdef RAD_PS2 + m_reverbController = new(GMA_PERSISTENT) PS2ReverbController(); +#elif RAD_XBOX + m_reverbController = new(GMA_PERSISTENT) XboxReverbController(); +#elif RAD_WIN32 + m_reverbController = new(GMA_PERSISTENT) Win32ReverbController(); +#else + m_reverbController = new(GMA_PERSISTENT) GCReverbController(); +#endif +} + +//============================================================================= +// SoundEffectPlayer::setSFXState +//============================================================================= +// Description: Switch to a new sound FX state +// +// Parameters: newState - state to be switched to +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::setSFXState( SFXState newState ) +{ + rAssert( newState < FXSTATE_MAX_STATES ); + + if( m_currentState != FXSTATE_INVALID ) + { + m_logicObjects[m_currentState]->UnregisterEventListeners(); + } + + m_currentState = newState; + m_logicObjects[m_currentState]->RegisterEventListeners(); +} + +//============================================================================= +// SoundEffectPlayer::doCleanup +//============================================================================= +// Description: Shut down anything that might be playing +// +// Parameters: () +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::doCleanup() +{ + m_logicObjects[m_currentState]->Cleanup(); + + m_reverbController->SetReverbOff(); +} + +//============================================================================= +// SoundEffectPlayer::playStinger +//============================================================================= +// Description: Play the given stinger resource at the specified trim +// +// Parameters: stingerName - name of sound resource for stinger +// trim - volume to play it at +// +// Return: void +// +//============================================================================= +void SoundEffectPlayer::playStinger( const char* stingerName, float trim ) +{ + m_stingerPlayer.PlaySound( stingerName ); + m_stingerPlayer.SetTrim( trim ); +} diff --git a/game/code/sound/soundfx/soundeffectplayer.h b/game/code/sound/soundfx/soundeffectplayer.h new file mode 100644 index 0000000..3985a97 --- /dev/null +++ b/game/code/sound/soundfx/soundeffectplayer.h @@ -0,0 +1,122 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundeffectplayer.h +// +// Description: Declaration for SoundEffectPlayer class, which switches between +// the objects that direct the soundfx logic for various game +// states +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +#ifndef SOUNDEFFECTPLAYER_H +#define SOUNDEFFECTPLAYER_H + +//======================================== +// Nested Includes +//======================================== + +#include <sound/simpsonssoundplayer.h> + +//======================================== +// Forward References +//======================================== + +class SoundFXLogic; +class ReverbController; + +//============================================================================= +// +// Synopsis: SoundEffectPlayer +// +//============================================================================= + +class SoundEffectPlayer +{ + public: + SoundEffectPlayer(); + virtual ~SoundEffectPlayer(); + + // + // Start playing front end sounds + // + void OnFrontEndStart() { setSFXState( FXSTATE_FRONTEND ); } + + // + // Start playing gameplay sounds + // + void OnGameplayStart() { setSFXState( FXSTATE_GAMEPLAY ); } + void OnGameplayEnd() { doCleanup(); } + + void OnPauseStart(); + void OnPauseEnd(); + + void ServiceOncePerFrame( unsigned int elapsedTime ); + + void PlayCarOptionStinger( float trim ); + void PlayDialogOptionStinger( float trim ); + void PlayMusicOptionStinger( float trim ); + void PlaySfxOptionStinger( float trim ); + + private: + //Prevent wasteful constructor creation. + SoundEffectPlayer( const SoundEffectPlayer& original ); + SoundEffectPlayer& operator=( const SoundEffectPlayer& rhs ); + + void initialize(); + + // + // Game states in which sound effects are played + // + enum SFXState + { + FXSTATE_FRONTEND, + FXSTATE_GAMEPLAY, + FXSTATE_PAUSED, + + FXSTATE_MAX_STATES, + + FXSTATE_INVALID + }; + + // + // Set a new SFX state + // + void setSFXState( SFXState newState ); + + // + // Shut down anything that might still be playing + // + void doCleanup(); + + // + // Play a stinger (duh) + // + void playStinger( const char* stingerName, float trim ); + + // + // FX logic objects, one for each state + // + SoundFXLogic* m_logicObjects[FXSTATE_MAX_STATES]; + + // + // Reverb controller + // + ReverbController* m_reverbController; + + // + // Current SFX state + // + SFXState m_currentState; + + // + // Options menu stinger player + // + SimpsonsSoundPlayer m_stingerPlayer; +}; + + +#endif // SOUNDEFFECTPLAYER_H + diff --git a/game/code/sound/soundfx/soundfxfrontendlogic.cpp b/game/code/sound/soundfx/soundfxfrontendlogic.cpp new file mode 100644 index 0000000..d2a07aa --- /dev/null +++ b/game/code/sound/soundfx/soundfxfrontendlogic.cpp @@ -0,0 +1,137 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxfrontendlogic.cpp +// +// Description: Implements the SoundFXFrontEndLogic class, which handles +// the translation of events into sound effects for the front +// end. +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/soundfxfrontendlogic.h> + +#include <sound/soundmanager.h> + +#include <events/eventmanager.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SoundFXFrontEndLogic::SoundFXFrontEndLogic +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXFrontEndLogic::SoundFXFrontEndLogic() +{ +} + +//============================================================================== +// SoundFXFrontEndLogic::~SoundFXFrontEndLogic +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXFrontEndLogic::~SoundFXFrontEndLogic() +{ +} + +//============================================================================= +// SoundFXFrontEndLogic::RegisterEventListeners +//============================================================================= +// Description: Register as listener of sound effect events with Event Manager +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXFrontEndLogic::RegisterEventListeners() +{ + GetEventManager()->AddListener( this, EVENT_FE_MENU_SELECT ); + GetEventManager()->AddListener( this, EVENT_FE_MENU_BACK ); + GetEventManager()->AddListener( this, EVENT_FE_MENU_UPORDOWN ); + GetEventManager()->AddListener( this, EVENT_FE_CHEAT_SUCCESS ); + GetEventManager()->AddListener( this, EVENT_FE_CHEAT_FAILURE ); + GetEventManager()->AddListener( this, EVENT_FE_CREDITS_NEW_LINE ); +} + +//============================================================================= +// SoundFXFrontEndLogic::HandleEvent +//============================================================================= +// Description: Play sound effects in response to events +// +// Parameters: id - Sound effect event identifier +// pEventData - Currently unused +// +// Return: void +// +//============================================================================= +void SoundFXFrontEndLogic::HandleEvent( EventEnum id, void* pEventData ) +{ + switch( id ) + { + case EVENT_FE_MENU_SELECT: + playSFXSound( "accept", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_MENU_BACK: + playSFXSound( "back", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_MENU_UPORDOWN: + playSFXSound( "scroll", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CHEAT_SUCCESS: + playSFXSound( "cheat_success", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CHEAT_FAILURE: + playSFXSound( "cheat_fail", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CREDITS_NEW_LINE: + playCreditLine( reinterpret_cast<int>(pEventData) ); + break; + + default: + rAssertMsg( false, "Huh? Unexpected sound FX event\n" ); + break; + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + diff --git a/game/code/sound/soundfx/soundfxfrontendlogic.h b/game/code/sound/soundfx/soundfxfrontendlogic.h new file mode 100644 index 0000000..eebe139 --- /dev/null +++ b/game/code/sound/soundfx/soundfxfrontendlogic.h @@ -0,0 +1,50 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxfrontendlogic.h +// +// Description: Declaration for the SoundFXFrontEndLogic class, which handles +// the translation of events into sound effects for the front +// end. +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +#ifndef SOUNDFXFRONTENDLOGIC_H +#define SOUNDFXFRONTENDLOGIC_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/soundfxlogic.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: SoundFXFrontEndLogic +// +//============================================================================= + +class SoundFXFrontEndLogic : public SoundFXLogic +{ + public: + SoundFXFrontEndLogic(); + virtual ~SoundFXFrontEndLogic(); + + void RegisterEventListeners(); + + virtual void HandleEvent( EventEnum id, void* pEventData ); + + private: + //Prevent wasteful constructor creation. + SoundFXFrontEndLogic( const SoundFXFrontEndLogic& original ); + SoundFXFrontEndLogic& operator=( const SoundFXFrontEndLogic& rhs ); +}; + + +#endif // SOUNDFXFRONTENDLOGIC_H + diff --git a/game/code/sound/soundfx/soundfxgameplaylogic.cpp b/game/code/sound/soundfx/soundfxgameplaylogic.cpp new file mode 100644 index 0000000..20b995e --- /dev/null +++ b/game/code/sound/soundfx/soundfxgameplaylogic.cpp @@ -0,0 +1,1212 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxgameplaylogic.cpp +// +// Description: Implements the SoundFXGameplayLogic class, which handles +// the translation of events into sound effects for the game +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radnamespace.hpp> +#include <radtime.hpp> +#include <radsound_hal.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/soundfxgameplaylogic.h> + +#include <sound/soundmanager.h> +#include <sound/soundcollisiondata.h> +#include <sound/soundfx/positionalsoundsettings.h> +#include <sound/soundrenderer/soundrenderingmanager.h> +#include <sound/soundrenderer/soundallocatedresource.h> +#include <sound/avatar/carsoundparameters.h> +#include <sound/tuning/globalsettings.h> + +#include <events/eventmanager.h> +#include <meta/scriptlocator.h> +#include <worldsim/physicsairef.h> +#include <worldsim/character/character.h> +#include <worldsim/vehiclecentral.h> +#include <worldsim/avatarmanager.h> +#include <mission/gameplaymanager.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +// +// These are compared against the collision impulse value, which is 0 - 1. +// + +static const float ARBITRARY_IMPULSE_THRESHOLD = 0.01f; + +// Above this value, send big crash event to dialog system +static const float ARBITRARY_BIG_CRASH_THRESHOLD = 0.15f; + +// These values determine whether to play small, medium, or big crash +// sounds for vehicles +static const float ARBITRARY_VEHICLE_MEDIUM_CRASH_THRESHOLD = 0.15f; +static const float ARBITRARY_VEHICLE_BIG_CRASH_THRESHOLD = 0.25f; + +static const char* s_hydrantSprayName = "hydrant_spray"; + +// +// Arbitrary value. If a collision occurs between the avatar vehicle +// and an object, where the difference between their distances is greater +// than this, then the avatar hit a wall or something, so don't average +// the positions. +// +static const float POSITIONAL_COLLISION_MAX_DISTANCE_SQR = 100.0f; + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SoundFXGameplayLogic::SoundFXGameplayLogic +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXGameplayLogic::SoundFXGameplayLogic() : + m_collisionMinMax( NULL ), + m_coinCounter( 0 ), + m_lastRonkTime( 0 ), + m_globalSettings( NULL ) +{ +} + +//============================================================================== +// SoundFXGameplayLogic::~SoundFXGameplayLogic +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXGameplayLogic::~SoundFXGameplayLogic() +{ +} + +//============================================================================= +// SoundFXGameplayLogic::RegisterEventListeners +//============================================================================= +// Description: Register as listener of sound effect events with Event Manager +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::RegisterEventListeners() +{ + EventManager* eventMgr = GetEventManager(); + + eventMgr->AddListener( this, EVENT_COLLISION ); + eventMgr->AddListener( this, EVENT_FOOTSTEP ); + eventMgr->AddListener( this, EVENT_BIG_RED_SWITCH_PRESSED ); + eventMgr->AddListener( this, EVENT_JUMP_TAKEOFF ); + eventMgr->AddListener( this, EVENT_JUMP_LANDING ); + eventMgr->AddListener( this, EVENT_POSITIONAL_SOUND_TRIGGER_HIT ); + eventMgr->AddListener( this, EVENT_GETINTOVEHICLE_START ); + eventMgr->AddListener( this, EVENT_GETOUTOFVEHICLE_END ); + eventMgr->AddListener( this, EVENT_FE_MENU_SELECT ); + eventMgr->AddListener( this, EVENT_FE_MENU_UPORDOWN ); + eventMgr->AddListener( this, EVENT_FE_MENU_BACK ); + eventMgr->AddListener( this, EVENT_COLLECTED_COINS ); + eventMgr->AddListener( this, EVENT_LOST_COINS ); + eventMgr->AddListener( this, EVENT_SPAWNED_COINS ); + eventMgr->AddListener( this, EVENT_PHONE_BOOTH_BUSY ); + eventMgr->AddListener( this, EVENT_PLAYER_CAR_HIT_NPC ); + eventMgr->AddListener( this, EVENT_BIG_BOOM_SOUND ); + eventMgr->AddListener( this, EVENT_CARD_COLLECTED ); + eventMgr->AddListener( this, EVENT_COLLECTED_WRENCH ); + eventMgr->AddListener( this, EVENT_VEHICLE_SUSPENSION_BOTTOMED_OUT ); + eventMgr->AddListener( this, EVENT_MISSION_COLLECTIBLE_PICKED_UP ); + eventMgr->AddListener( this, EVENT_KICK_NPC ); + eventMgr->AddListener( this, EVENT_OBJECT_KICKED ); + eventMgr->AddListener( this, EVENT_WASP_BULLET_FIRED ); + eventMgr->AddListener( this, EVENT_WASP_BULLET_MISSED ); + eventMgr->AddListener( this, EVENT_WASP_BULLET_HIT_CHARACTER_STYLIZED_VIOLENCE_FOLLOWS ); + eventMgr->AddListener( this, EVENT_START_ANIMATION_SOUND ); + eventMgr->AddListener( this, EVENT_MISSION_SUCCESS ); + eventMgr->AddListener( this, EVENT_STAGE_COMPLETE ); + eventMgr->AddListener( this, EVENT_HIT_AND_RUN_CAUGHT ); + eventMgr->AddListener( this, EVENT_HIT_AND_RUN_METER_THROB ); + eventMgr->AddListener( this, EVENT_SHOW_MISSION_OBJECTIVE ); + eventMgr->AddListener( this, EVENT_PLAY_BIRD_SOUND ); + eventMgr->AddListener( this, static_cast<EventEnum>(EVENT_LOCATOR + LocatorEvent::BOUNCEPAD) ); + eventMgr->AddListener( this, EVENT_FE_PAUSE_MENU_END ); + eventMgr->AddListener( this, EVENT_FE_PAUSE_MENU_START ); + eventMgr->AddListener( this, EVENT_FE_CANCEL ); + eventMgr->AddListener( this, EVENT_FE_CONTINUE ); + eventMgr->AddListener( this, EVENT_FE_LOCKED_OUT ); + eventMgr->AddListener( this, EVENT_BARREL_BLOWED_UP ); + eventMgr->AddListener( this, EVENT_FE_CREDITS_NEW_LINE ); +} + +//============================================================================= +// SoundFXGameplayLogic::HandleEvent +//============================================================================= +// Description: Play sound effects in response to events +// +// Parameters: id - Sound effect event identifier +// pEventData - Currently unused +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::HandleEvent( EventEnum id, void* pEventData ) +{ + Vehicle* vehiclePtr; + unsigned int ronkTime; + const char* soundName; + RenderEnums::LevelEnum level; + AnimSoundData* animData; + + switch( id ) + { + case EVENT_COLLISION: + handleCollisionEvent( static_cast<SoundCollisionData*>(pEventData) ); + break; + + case EVENT_FOOTSTEP: + handleFootstepEvent( static_cast<Character*>(pEventData) ); + break; + + case EVENT_JUMP_TAKEOFF: + playSFXSound( "jump", false ); + break; + + case EVENT_JUMP_LANDING: + // + // TEMPORARY: we need a surface-sensitive solution + // + playSFXSound( "feet_concrete_jump", false ); + break; + + case EVENT_BIG_RED_SWITCH_PRESSED: + handleSwitchEvent(); + break; + + case EVENT_POSITIONAL_SOUND_TRIGGER_HIT: + playPositionalSound( static_cast<ScriptLocator*>(pEventData) ); + break; + + case EVENT_GETINTOVEHICLE_START: + case EVENT_GETOUTOFVEHICLE_END: + playCarDoorSound( id, static_cast<Character*>(pEventData) ); + break; + + case EVENT_FE_MENU_SELECT: + playSFXSound( "accept", false, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + case EVENT_FE_MENU_UPORDOWN: + playSFXSound( "scroll", false, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + case EVENT_FE_MENU_BACK: + playSFXSound( "back", false, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + case EVENT_FE_LOCKED_OUT: + playSFXSound( "locked_out", false ); + break; + + case EVENT_COLLECTED_COINS: + playCoinCollectSound(); + break; + + case EVENT_SPAWNED_COINS: + // + // Should this do anything? + // + break; + + case EVENT_LOST_COINS: + playSFXSound( "coin_lose", true ); + break; + + case EVENT_PHONE_BOOTH_BUSY: + playSFXSound( "phonebusy", false ); + break; + + case EVENT_PLAYER_CAR_HIT_NPC: + { + // + // Set up special collision data for the collision code, because + // it won't be getting a collision event. I like saying "collision". + // + SoundCollisionData collData( 0.0f, static_cast<CollisionEntityDSG*>(pEventData), NULL ); + + handleCollisionEvent( &collData ); + } + break; + + case EVENT_KICK_NPC: + playSFXSound( "car_hit_pedestrian", true ); + break; + + case EVENT_OBJECT_KICKED: + handleObjectKick( static_cast<CollisionEntityDSG*>(pEventData) ); + break; + + case EVENT_BIG_BOOM_SOUND: + vehiclePtr = static_cast<Vehicle*>(pEventData); + rAssert( vehiclePtr != NULL ); + if( vehiclePtr->mVehicleType == VT_USER ) + { + playSFXSound( "generic_car_explode", false ); + } + break; + + case EVENT_BARREL_BLOWED_UP: + playSFXSound( "generic_car_explode", false ); + break; + + case EVENT_CARD_COLLECTED: + // + // Only play card sound effect in car, the music system + // handles it when on foot + // + if( GetAvatarManager()->GetAvatarForPlayer( 0 )->IsInCar() ) + { + playSFXSound( "card_collect", false ); + } + break; + + case EVENT_COLLECTED_WRENCH: + playSFXSound( "wrench_collect", false ); + break; + + case EVENT_VEHICLE_SUSPENSION_BOTTOMED_OUT: + // + // Play only if we haven't played the last one within a half-second. + // Use a simple timestamp to determine this. + // + ronkTime = ::radTimeGetMilliseconds(); + if( ( ronkTime < m_lastRonkTime ) + || ( ( ronkTime - m_lastRonkTime ) > 500 ) ) + { + m_lastRonkTime = ronkTime; + playSFXSound( "suspension_ronks", true ); + } + break; + + case EVENT_MISSION_COLLECTIBLE_PICKED_UP: + handleCollection(); + break; + + case EVENT_WASP_BULLET_FIRED: + playSFXSound( "wasp_lasers", true ); + break; + + case EVENT_WASP_BULLET_MISSED: + playSFXSound( "laser_miss", true ); + break; + + case EVENT_WASP_BULLET_HIT_CHARACTER_STYLIZED_VIOLENCE_FOLLOWS: + playSFXSound( "character_zapped", true ); + break; + + case EVENT_START_ANIMATION_SOUND: + animData = static_cast<AnimSoundData*>( pEventData ); + soundName = animData->soundName; + if( ( soundName != NULL ) && ( animData->animJoint == NULL ) ) + { + playSFXSound( soundName, false ); + } + break; + + case EVENT_MISSION_SUCCESS: + playSFXSound( "mission_complete", false ); + break; + + case EVENT_STAGE_COMPLETE: + playSFXSound( "stage_complete", false ); + break; + + case EVENT_HIT_AND_RUN_CAUGHT: + playSFXSound( "busted", false ); + break; + + case EVENT_HIT_AND_RUN_METER_THROB: + playSFXSound( "rage_warning", false ); + break; + + case EVENT_SHOW_MISSION_OBJECTIVE: + playSFXSound( "pop_up", true ); + break; + + case EVENT_PLAY_BIRD_SOUND: + // + // Pick the correct bird effect for the level + // + level = GetGameplayManager()->GetCurrentLevelIndex(); + if( ( level == RenderEnums::L2 ) + || ( level == RenderEnums::L5 ) ) + { + playSFXSound( "pigeon_takeoff", false ); + } + else if( ( level == RenderEnums::L3 ) + || ( level == RenderEnums::L6 ) ) + { + playSFXSound( "gull_takeoff", false ); + } + break; + + case EVENT_LOCATOR + LocatorEvent::BOUNCEPAD : + playSFXSound( "trampoline", true ); + break; + + case EVENT_FE_PAUSE_MENU_START: + playSFXSound( "pause_on", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_PAUSE_MENU_END: + playSFXSound( "pause_off", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CONTINUE: + playSFXSound( "continue", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CANCEL: + playSFXSound( "cancel", true, false, NULL, GetSoundManager()->GetSfxVolume() ); + break; + + case EVENT_FE_CREDITS_NEW_LINE: + playCreditLine( reinterpret_cast<int>(pEventData) ); + break; + + default: + rAssertMsg( false, "Unexpected event received in SoundFXGameplayLogic\n" ); + break; + } +} + +//============================================================================= +// SoundFXGameplayLogic::OnPlaybackComplete +//============================================================================= +// Description: No longer used, now that tutorial lines are played through +// the dialog system +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::OnPlaybackComplete() +{ +} + +//============================================================================= +// SoundFXGameplayLogic::Cleanup +//============================================================================= +// Description: Called on gameplay exit. Use this to shut down any +// positional sounds that might be playing. +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::Cleanup() +{ + int i; + + for( i = 0; i < s_numPositionalSounds; i++ ) + { + if( m_positionalSounds[i].IsInUse() ) + { + m_positionalSounds[i].Stop(); + } + } +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** + +//============================================================================= +// SoundFXGameplayLogic::getGlobalSettings +//============================================================================= +// Description: Initialize the member pointer to the global settings object +// if not done yet, and return it +// +// Parameters: None +// +// Return: pointer to globalSettings object +// +//============================================================================= +globalSettings* SoundFXGameplayLogic::getGlobalSettings() +{ + IRadNameSpace* nameSpace; + + if( m_globalSettings == NULL ) + { + nameSpace = Sound::daSoundRenderingManagerGet()->GetTuningNamespace(); + rAssert( nameSpace != NULL ); + m_globalSettings = static_cast<globalSettings*>(nameSpace->GetInstance( "tuner" )); + rAssert( m_globalSettings != NULL ); + } + + return( m_globalSettings ); +} + +//============================================================================= +// SoundFXGameplayLogic::handleCollisionEvent +//============================================================================= +// Description: Play a collision sound appropriate for this event, unless we've +// already received an event for this collision. A typical collision +// throws a lot of duplicate events, apparently, so we gotta screen +// 'em out. +// +// Parameters: collisionData - data we need pertaining to the collision, passed +// through the event mechanism +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::handleCollisionEvent( SoundCollisionData* collisionData ) +{ + int i; + + // + // FOR NOW: filter out collisions that don't involve the user's car. Later, + // we might want to do AI-car collisions within a certain radius or + // something + // + + //TODO (Cary): I think that this should search the avatar manager for each vehicle in the + //collision pair (or always take A so that vehicles don't get doubled events) and test to + //see if the vehicle is user controlled. The code as it is only sends events for player 0 + //and won't work for multiplayer. + Vehicle* pVehicle = GetAvatarManager()->GetAvatarForPlayer( 0 )->GetVehicle(); + + if( !pVehicle ) + { + return; + } + + // + // See if we're already playing a sound for this collision, or if all collision + // players are in use. If so, exit + // + for( i = 0; i < s_numCollisionSounds; i++ ) + { + if( m_collisionSounds[i].soundPlayer.IsInUse() ) + { + if( collisionPairMatches( i, collisionData->collObjA, collisionData->collObjB ) ) + { + // Collision sound already being played, do nothing + return; + } + } + else + { + break; + } + } + + if( i == s_numCollisionSounds ) + { + // + // All players are being used + // + return; + } + + CollisionAttributes* attributes; + CollisionEntityDSG* collEntities[2]; + const char* vehicleCrashName = NULL; + const char* nonVehicleCrashName = NULL; + CollisionEntityDSG* hydrantObject = NULL; + bool hydrantHit = false; + EventEnum minorCrash = EVENT_MINOR_VEHICLE_CRASH; + EventEnum bigCrash = EVENT_BIG_VEHICLE_CRASH; + Vehicle* collisionVehicle = NULL; + CollisionEntityDSG* otherEntity = NULL; + rmt::Vector diffVector; + rmt::Vector avatarPosition; + rmt::Vector* vectorPtr = NULL; + bool avatarVehicleInvolved = false; + + collEntities[0] = collisionData->collObjA; + collEntities[1] = collisionData->collObjB; + + // + // NOTE: this code assumes that we have at most one vehicle and one non-vehicle + // in the collision pair. If we have two non-vehicles, one is lost. Eh. + // + for( i = 0; i < 2; i++ ) + { + // + // If the DSG object is NULL, one of the objects is a fence or something. + // Ignore and move on. + // + if( collEntities[i] != NULL ) + { + if( collEntities[i]->GetAIRef() == PhysicsAIRef::redBrickVehicle ) + { + // + // Vehicle, play smashy sound + // + if( collisionData->mIntensity > ARBITRARY_VEHICLE_BIG_CRASH_THRESHOLD ) + { + vehicleCrashName = "large_car_crash"; + } + else if( collisionData->mIntensity > ARBITRARY_VEHICLE_MEDIUM_CRASH_THRESHOLD ) + { + vehicleCrashName = "medium_car_crash"; + } + else + { + vehicleCrashName = "small_car_crash"; + } + + collisionVehicle = static_cast<Vehicle*>( collEntities[i] ); + + if( collEntities[i] == pVehicle ) + { + // + // Collision involves the user vehicle, store the other + // entity + // + if( i == 0 ) + { + otherEntity = collEntities[1]; + } + else + { + otherEntity = collEntities[0]; + } + + avatarVehicleInvolved = true; + } + } + else + { + // + // Non-vehicle, get attributes + // + attributes = collEntities[i]->GetCollisionAttributes(); + if( attributes == NULL ) + { + // + // No attributes. Character, I assume? It'd be nice if the + // Character class filled this in. Something to try. + // + nonVehicleCrashName = "car_hit_pedestrian"; + } + else + { + nonVehicleCrashName = attributes->GetSound(); + + // + // Stinky special case + // + if( attributes->GetBreakable() == BreakablesEnum::eHydrantBreaking ) + { + hydrantHit = true; + hydrantObject = collEntities[i]; + } + } + + // + // This eliminates vehicle-on-vehicle collision, so don't use that + // type of event for the dialog system + // + minorCrash = EVENT_MINOR_CRASH; + bigCrash = EVENT_BIG_CRASH; + } + } + else + { + // + // This eliminates vehicle-on-vehicle collision, so don't use that + // type of event for the dialog system + // + minorCrash = EVENT_MINOR_CRASH; + bigCrash = EVENT_BIG_CRASH; + } + } + + + // + // Based on how hard the crash is, pass on an event that the dialog + // system can use (Q: is this the best place for this? If other + // game components start using it, this should be moved). + // + if( avatarVehicleInvolved ) + { + if( collisionData->mIntensity < ARBITRARY_BIG_CRASH_THRESHOLD ) + { + if( collisionData->mIntensity >= ARBITRARY_IMPULSE_THRESHOLD ) + { + if( minorCrash == EVENT_MINOR_CRASH ) + { + // + // Can't be vehicle-on-vehicle + // + collisionVehicle = NULL; + } + GetEventManager()->TriggerEvent( minorCrash, collisionVehicle ); + } + } + else + { + if( bigCrash == EVENT_BIG_CRASH ) + { + // + // Isn't vehicle-on-vehicle + // + collisionVehicle = NULL; + } + GetEventManager()->TriggerEvent( bigCrash, collisionVehicle ); + } + } + + // + // Play the collision sound if we've got a player free + // + rAssert( collisionData->mIntensity >= 0.0f ); + rAssert( collisionData->mIntensity <= 1.0f ); + + // + // Check whether the colliding entities are really far apart. If so, + // then the player has hit a wall or something, so don't bother averaging + // the distances between them, just play at the avatar position + // + if( otherEntity != NULL ) + { + pVehicle->GetPosition( &avatarPosition ); + otherEntity->GetPosition( &diffVector ); + diffVector -= avatarPosition; + + if( diffVector.MagnitudeSqr() > POSITIONAL_COLLISION_MAX_DISTANCE_SQR ) + { + vectorPtr = &avatarPosition; + } + } + + // + // Play the sounds in free players (or kill something + // if they're all in use) + // + if( vehicleCrashName != NULL ) + { + startCollisionPlayer( vehicleCrashName, collisionData->collObjA, collisionData->collObjB, vectorPtr ); + } + if( nonVehicleCrashName != NULL ) + { + startCollisionPlayer( nonVehicleCrashName, collisionData->collObjA, collisionData->collObjB, vectorPtr ); + + // + // Stinky fire hydrant hack. + // + if( hydrantHit ) + { + rAssert( hydrantObject != NULL ); + startCollisionPlayer( s_hydrantSprayName, hydrantObject, NULL, NULL ); + } + } +} + +//============================================================================= +// SoundFXGameplayLogic::handleObjectKick +//============================================================================= +// Description: Play a sound for an object that gets kicked +// +// Parameters: collObject - kicked object +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::handleObjectKick( CollisionEntityDSG* collObject ) +{ + CollisionAttributes* attributes; + const char* soundName; + + attributes = collObject->GetCollisionAttributes(); + if( attributes != NULL ) + { + soundName = attributes->GetSound(); + + // + // Cheat: don't play this positionally because I'd have to work around + // the double-play filter because of the stinky fire hydrant. Hope + // that's okay + // + playSFXSound( soundName, true ); + + // + // More hydrant hack + // + if( attributes->GetBreakable() == BreakablesEnum::eHydrantBreaking ) + { + startCollisionPlayer( s_hydrantSprayName, collObject, NULL, NULL ); + } + } +} + +//============================================================================= +// SoundFXGameplayLogic::collisionPairMatches +//============================================================================= +// Description: Check for match between parameters and collision pair at +// given index +// +// Parameters: index - index into m_collisionSource that we're matching against +// firstObj, secondObj - collision objects to match with +// +// Return: true if matching, false otherwise +// +//============================================================================= +bool SoundFXGameplayLogic::collisionPairMatches( int index, void* firstObj, void* secondObj ) +{ + PositionalSFXPlayer* storedPair; + + rAssert( index < s_numCollisionSounds ); + + storedPair = &(m_collisionSounds[index]); + + return( ( ( storedPair->collObjA == firstObj ) && + ( storedPair->collObjB == secondObj ) ) + + || + + ( ( storedPair->collObjA == secondObj ) && + ( storedPair->collObjB == firstObj ) ) ); +} + +//============================================================================= +// SoundFXGameplayLogic::startCollisionPlayer +//============================================================================= +// Description: Find a free positional sound player (or stop one if necessary) +// and play the sound and store the collision pair +// +// Parameters: soundName - name of sound resource to play +// objA - first colliding object +// objB - second colliding object +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::startCollisionPlayer( const char* soundName, + CollisionEntityDSG* objA, + CollisionEntityDSG* objB, + rmt::Vector* positionPtr ) +{ + int index; + rmt::Vector posnA; + rmt::Vector posnB; + rmt::Vector average; + rmt::Vector vectorToListener; + radSoundVector rsListenerPosition; + rmt::Vector listenerPosition; + IRadNameSpace* nameSpace; + IRefCount* nameSpaceObj; + IRadSoundHalListener* theListener; + + + // + // Look for a free player first + // + for( index = 0; index < s_numCollisionSounds; index++ ) + { + if( !(m_collisionSounds[index].soundPlayer.IsInUse()) ) + { + break; + } + } + + // + // If all are in use, stop one. Arbitrarily, use the one + // at the start of the list, since it's most likely to have + // been playing the longest. No need to get cute. + // + if( index >= s_numCollisionSounds ) + { + index = 0; + m_collisionSounds[0].soundPlayer.Stop(); + + rWarningMsg( false, "Collision sound dropped for lack of players\n" ); + } + + // + // Store the collision pair + // + m_collisionSounds[index].collObjA = objA; + m_collisionSounds[index].collObjB = objB; + + // + // Play the sound halfway between the positions of the + // colliding objects (if two objects are used) + // + if( positionPtr != NULL ) + { + average = *positionPtr; + } + else if( objA == NULL ) + { + objB->GetPosition( &average ); + } + else if( objB == NULL ) + { + objA->GetPosition( &average ); + } + else + { + objA->GetPosition( &posnA ); + objB->GetPosition( &posnB ); + average.Add( posnA, posnB ); + average *= 0.5f; + } + + if( GetGameplayManager()->IsSuperSprint() ) + { + // + // Hoo boy. Big stinky hack coming up. The problem is that sounds are + // positional, and the camera is a very long ways away in the bonus game. + // Fudge the position to make the collisions suitably close. + // + theListener = ::radSoundHalListenerGet( ); + rAssert( theListener != NULL ); + + theListener->GetPosition( &rsListenerPosition ); + listenerPosition.Set( rsListenerPosition.m_x, rsListenerPosition.m_y, rsListenerPosition.m_z ); + vectorToListener = average - listenerPosition; + vectorToListener.Scale( 0.01f, 0.01f, 0.01f ); + average = listenerPosition + vectorToListener; + } + + if( m_collisionMinMax == NULL ) + { + // + // Lazy initialization. Grab the positional characteristics for collision sounds + // + nameSpace = Sound::daSoundRenderingManagerGet()->GetTuningNamespace(); + rAssert( nameSpace != NULL ); + nameSpaceObj = nameSpace->GetInstance( "collision_sounds" ); + rAssert( nameSpaceObj != NULL ); + m_collisionMinMax = reinterpret_cast<positionalSoundSettings*>(nameSpaceObj); + } + + m_collisionSounds[index].soundPlayer.SetPosition( average.x, average.y, average.z ); + m_collisionSounds[index].soundPlayer.SetParameters( m_collisionMinMax ); + m_collisionSounds[index].soundPlayer.PlaySound( soundName ); + m_collisionSounds[index].soundPlayer.SetTrim( 1.0f ); +} + +//============================================================================= +// SoundFXGameplayLogic::handleFootstepEvent +//============================================================================= +// Description: Plays appropriate footstep sound +// +// Parameters: walkingCharacter - character doing the walking +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::handleFootstepEvent( Character* walkingCharacter ) +{ + eTerrainType terrain; + bool isInterior; + globalSettings* clipNameObj; + const char* name = NULL; + + rAssert( walkingCharacter != NULL ); + walkingCharacter->GetTerrainType( terrain, isInterior ); + + // + // Get the parameter object for this positional sound. + // + clipNameObj = getGlobalSettings(); + + if( isInterior ) + { + // + // Use the road clip indoors + // + name = clipNameObj->GetFootstepRoadClipName(); + } + else if( terrain == TT_Metal ) + { + name = clipNameObj->GetFootstepMetalClipName(); + } + else if( terrain == TT_Wood ) + { + name = clipNameObj->GetFootstepWoodClipName(); + } + else + { + name = clipNameObj->GetFootstepRoadClipName(); + } + + rAssert( name != NULL ); + + playSFXSound( name, true ); +} + +//============================================================================= +// SoundFXGameplayLogic::handleSwitchEvent +//============================================================================= +// Description: Play clicking sound for big red switches +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::handleSwitchEvent() +{ + playSFXSound( "switch", false ); +} + +//============================================================================= +// SoundFXGameplayLogic::handleCollection +//============================================================================= +// Description: Play the appropriate sound for picking up a collectible +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::handleCollection() +{ + RenderEnums::LevelEnum level; + int mission; + const char* soundName = NULL; + + // + // We don't have a way to identify collectible types, so select a + // sound resource based on our level/mission + // + level = GetGameplayManager()->GetCurrentLevelIndex(); + mission = GetGameplayManager()->GetCurrentMissionIndex(); + switch( level ) + { + case RenderEnums::L1 : + soundName = "level_1_pickup_sfx"; + break; + case RenderEnums::L2 : + if( mission == 6 ) + { + soundName = "monkey_collect"; + } + else + { + soundName = "level_2_pickup_sfx"; + } + break; + case RenderEnums::L3 : + soundName = "level_3_pickup_sfx"; + break; + case RenderEnums::L4 : + soundName = "level_4_pickup_sfx"; + break; + case RenderEnums::L5 : + soundName = "level_5_pickup_sfx"; + break; + case RenderEnums::L6 : + soundName = "level_6_pickup_sfx"; + break; + case RenderEnums::L7 : + soundName = "nuclear_waste_collect"; + break; + default: + break; + } + + rAssertMsg( ( soundName != NULL ), "Collection without sound effect, tell Esan\n" ); + + playSFXSound( soundName, true ); +} + +//============================================================================= +// SoundFXGameplayLogic::playPositionalSound +//============================================================================= +// Description: Plays a positional sound in the world when a positional +// (a.k.a. script) trigger is hit +// +// Parameters: locator - locator for the sound +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::playPositionalSound( ScriptLocator* locator ) +{ + IRadNameSpace* nameSpace; + IRefCount* nameSpaceObj; + positionalSoundSettings* parameters; + float diceRoll; + float probability; + int i; + rmt::Vector locatorPosition; + + rAssert( locator != NULL ); + + // + // Get the parameter object for this positional sound. + // + nameSpace = Sound::daSoundRenderingManagerGet()->GetTuningNamespace(); + rAssert( nameSpace != NULL ); + nameSpaceObj = nameSpace->GetInstance( locator->GetKey() ); + if( nameSpaceObj != NULL ) + { + parameters = reinterpret_cast<positionalSoundSettings*>( nameSpaceObj ); + + if( !(locator->GetPlayerEntered()) ) + { + // + // Player is exiting volume, not entering. If we're playing a sound + // already, stop it + // + for( i = 0; i < s_numPositionalSounds; i++ ) + { + if( m_positionalSounds[i].IsInUse() + && ( m_positionalSounds[i].GetParameters() == parameters ) ) + { + m_positionalSounds[i].Stop(); + break; + } + } + } + else + { + probability = parameters->GetPlaybackProbability(); + if( probability < 1.0f ) + { + // + // Random play + // + diceRoll = (static_cast<float>( rand() % 100 )) / 100.0f; + if( diceRoll >= probability ) + { + return; + } + } + + // + // Find a player and play + // + for( i = 0; i < s_numPositionalSounds; i++ ) + { + if( !(m_positionalSounds[i].IsInUse()) ) + { + locator->GetLocation( &locatorPosition ); + m_positionalSounds[i].SetPosition( locatorPosition.x, + locatorPosition.y, + locatorPosition.z ); + m_positionalSounds[i].SetParameters( parameters ); + + // + // Don't buffer, to save IOP + // + + m_positionalSounds[i].PlaySound( parameters->GetClipName(), NULL ); + break; + } + } + } + } + else + { + rDebugString( "Couldn't play missing positional sound" ); + } +} + +void SoundFXGameplayLogic::playCarDoorSound( EventEnum eventType, Character* playerCharacter ) +{ + Vehicle* car; + carSoundParameters* parameters; + IRadNameSpace* nameSpace; + IRefCount* nameSpaceObj; + const char* clipName; + + // + // Get name of clip + // + car = playerCharacter->GetTargetVehicle(); + if( car != NULL ) + { + // + // Get the car sound parameter object for this vehicle. + // + // IMPORTANT: We assume that the object in the namespace has the same + // name as the one in the vehicle object, which comes from the loading + // script for that car, I think. + // + nameSpace = Sound::daSoundRenderingManagerGet()->GetTuningNamespace(); + rAssert( nameSpace != NULL ); + + nameSpaceObj = nameSpace->GetInstance( car->GetName() ); + if( nameSpaceObj != NULL ) + { + parameters = reinterpret_cast<carSoundParameters*>( nameSpaceObj ); + + if( eventType == EVENT_GETINTOVEHICLE_START ) + { + clipName = parameters->GetCarDoorOpenClipName(); + } + else + { + clipName = parameters->GetCarDoorCloseClipName(); + } + + if( clipName != NULL ) + { + playSFXSound( clipName, false ); + } + } + else + { + rDebugString( "Couldn't find car door sound\n" ); + } + } +} + +//============================================================================= +// SoundFXGameplayLogic::playCoinCollectSound +//============================================================================= +// Description: Play next coin collect sound in sequence +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXGameplayLogic::playCoinCollectSound() +{ + float pitch; + unsigned int numPitches; + globalSettings* pitchSequence = getGlobalSettings(); + + pitch = pitchSequence->GetCoinPitch( m_coinCounter ); + playSFXSound( "coin_collect_01", true, false, NULL, 1.0f, pitch ); + + numPitches = pitchSequence->GetNumCoinPitches(); + if( numPitches > 0 ) + { + m_coinCounter = ( m_coinCounter + 1 ) % numPitches; + } +} diff --git a/game/code/sound/soundfx/soundfxgameplaylogic.h b/game/code/sound/soundfx/soundfxgameplaylogic.h new file mode 100644 index 0000000..cb1e5f9 --- /dev/null +++ b/game/code/sound/soundfx/soundfxgameplaylogic.h @@ -0,0 +1,130 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxgameplaylogic.h +// +// Description: Declaration for the SoundFXGameplayLogic class, which handles +// the translation of events into sound effects for the game +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +#ifndef SOUNDFXGAMEPLAYLOGIC_H +#define SOUNDFXGAMEPLAYLOGIC_H + +//======================================== +// Nested Includes +//======================================== +#include <radmath/radmath.hpp> + +#include <sound/soundfx/soundfxlogic.h> +#include <sound/positionalsoundplayer.h> +#include <events/eventenum.h> + +//======================================== +// Forward References +//======================================== + +class SoundCollisionData; +class Character; +class ScriptLocator; +class CollisionEntityDSG; +class globalSettings; + +//============================================================================= +// +// Synopsis: PositionalSFXPlayer +// +// Associated stuff required to play a positional collision sound +// +//============================================================================= +struct PositionalSFXPlayer +{ + PositionalSoundPlayer soundPlayer; + void* collObjA; + void* collObjB; +}; + +//============================================================================= +// +// Synopsis: SoundFXGameplayLogic +// +//============================================================================= + +class SoundFXGameplayLogic : public SoundFXLogic +{ + public: + SoundFXGameplayLogic(); + virtual ~SoundFXGameplayLogic(); + + void RegisterEventListeners(); + + virtual void HandleEvent( EventEnum id, void* pEventData ); + + // + // Override callback to trigger tutorial events + // + void OnPlaybackComplete(); + + // + // Virtual function to clean up positional sounds + // + void Cleanup(); + + private: + //Prevent wasteful constructor creation. + SoundFXGameplayLogic( const SoundFXGameplayLogic& original ); + SoundFXGameplayLogic& operator=( const SoundFXGameplayLogic& rhs ); + + globalSettings* getGlobalSettings(); + + void handleCollisionEvent( SoundCollisionData* collisionData ); + void handleFootstepEvent( Character* walkingCharacter ); + void handleSwitchEvent(); + void handleCollection(); + void handleObjectKick( CollisionEntityDSG* collObject ); + void playPositionalSound( ScriptLocator* locator ); + void playCarDoorSound( EventEnum eventType, Character* playerCharacter ); + void playCoinCollectSound(); + void startCollisionPlayer( const char* soundName, + CollisionEntityDSG* objA, + CollisionEntityDSG* objB, + rmt::Vector* positionPtr ); + + bool collisionPairMatches( int index, void* firstObj, void* secondObj ); + + // Number of simultaneous positional sounds + static const int s_numPositionalSounds = 3; + + // + // Positional sound objects + // + PositionalSoundPlayer m_positionalSounds[s_numPositionalSounds]; + + // Number of simultaneous collision sounds + static const int s_numCollisionSounds = 6; + + // + // Positional collision sounds + // + PositionalSFXPlayer m_collisionSounds[s_numCollisionSounds]; + + positionalSoundSettings* m_collisionMinMax; + + // + // Counter for cycling through ka-ching sounds + // + unsigned int m_coinCounter; + + // + // Timing for suspension ronks + // + unsigned int m_lastRonkTime; + + globalSettings* m_globalSettings; +}; + + +#endif // SOUNDFXGAMEPLAYLOGIC_H + diff --git a/game/code/sound/soundfx/soundfxlogic.cpp b/game/code/sound/soundfx/soundfxlogic.cpp new file mode 100644 index 0000000..798d061 --- /dev/null +++ b/game/code/sound/soundfx/soundfxlogic.cpp @@ -0,0 +1,322 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxlogic.cpp +// +// Description: Implement the SoundFXLogic class, which is an abstract +// base class for objects that translate events into sound effects +// in the different game states +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/soundfxlogic.h> + +#include <events/eventmanager.h> +#include <events/eventdata.h> + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +struct CreditInfo +{ + int lineNumber; + radKey32 dialogName; +}; + +#ifdef PAL + const int PAL_OFFSET = +16; // due to additional VUG localization team +#else + const int PAL_OFFSET = 0; +#endif + +static CreditInfo s_creditDialogTable[] = +{ + { 7, ::radMakeKey32( "pubcredits" ) }, + { 55, ::radMakeKey32( "foxcredits" ) }, + { 178 + PAL_OFFSET, ::radMakeKey32( "radproducer" ) }, + { 190 + PAL_OFFSET, ::radMakeKey32( "radlead" ) }, + { 204 + PAL_OFFSET, ::radMakeKey32( "raddesign" ) }, + { 221 + PAL_OFFSET, ::radMakeKey32( "radworld" ) }, + { 230 + PAL_OFFSET, ::radMakeKey32( "radmodel" ) }, + { 235 + PAL_OFFSET, ::radMakeKey32( "radfx" ) }, + { 242 + PAL_OFFSET, ::radMakeKey32( "radfmvart" ) }, + { 251 + PAL_OFFSET, ::radMakeKey32( "radfeart" ) }, + { 260 + PAL_OFFSET, ::radMakeKey32( "radprog" ) }, + { 279 + PAL_OFFSET, ::radMakeKey32( "radtest" ) }, + { 289 + PAL_OFFSET, ::radMakeKey32( "radsound" ) } +}; + +static int s_creditDialogTableSize = sizeof( s_creditDialogTable ) / sizeof( CreditInfo ); + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SoundFXLogic::SoundFXLogic +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXLogic::SoundFXLogic() +{ + unsigned int i; + + for( i = 0; i < s_numSFXPlayers; i++ ) + { + m_soundPlayers[i].isKillable = true; + } +} + +//============================================================================== +// SoundFXLogic::~SoundFXLogic +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXLogic::~SoundFXLogic() +{ +} + +//============================================================================= +// SoundFXLogic::UnregisterEventListeners +//============================================================================= +// Description: Unregister all events with the Event Manager +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXLogic::UnregisterEventListeners() +{ + GetEventManager()->RemoveAll( this ); +} + +//============================================================================= +// SoundFXLogic::GetAvailableSFXPlayer +//============================================================================= +// Description: Find an unused SFXPlayer. Failing that, find a killable +// SFXPlayer. Failing that, well, just fail. +// +// Parameters: index - Address of unsigned int, filled in with index of +// SFXPlayer if one is available and address is non-NULL, +// untouched otherwise +// +// Return: SFXPlayer pointer if one available, NULL otherwise +// +//============================================================================= +SFXPlayer* SoundFXLogic::GetAvailableSFXPlayer( unsigned int* index ) +{ + unsigned int i; + int lastKillable = -1; + + // + // First, look for free players + // + for( i = 0; i < s_numSFXPlayers; i++ ) + { + if( !m_soundPlayers[i].soundPlayer.IsInUse() ) + { + if( index != NULL ) + { + *index = i; + } + return( &(m_soundPlayers[i]) ); + } + else if( m_soundPlayers[i].isKillable ) + { + lastKillable = i; + } + } + + // + // If we get this far, all players are in use. Kill a player if we can + // + if( lastKillable != -1 ) + { + if( index != NULL ) + { + *index = lastKillable; + } + return( &(m_soundPlayers[lastKillable]) ); + } + else + { + return( NULL ); + } +} + +//============================================================================= +// SoundFXLogic::playSFXSound +//============================================================================= +// Description: Searches through the list of SFXPlayers for one that's free. +// If one isn't found, find one that's killable. If none of them +// are killable, eh, no sound. +// +// Parameters: resource - name of sound resource to play +// killable - true if sound can be killed prematurely, false otherwise +// useCallback - true if we set callback on playback completion, +// false otherwise +// index - to be filled in with index of SFXPlayer used if sound +// played and index is non-NULL +// trim - volume to play sound at +// pitch - pitch to play sound at +// +// Return: true if sound played, false otherwise +// +//============================================================================= +bool SoundFXLogic::playSFXSound( const char* resource, bool killable, + bool useCallback, unsigned int* index, + float trim, float pitch ) +{ + SFXPlayer* player; + bool success = false; + SimpsonsSoundPlayerCallback* callbackObj = NULL; + + // + // Get a player if possible + // + player = GetAvailableSFXPlayer( index ); + + if( player != NULL ) + { + if( player->soundPlayer.IsInUse() ) + { + player->soundPlayer.Stop(); + } + + if( useCallback ) + { + callbackObj = this; + } + player->soundPlayer.PlaySound( resource, callbackObj ); + player->soundPlayer.SetTrim( trim ); + player->soundPlayer.SetPitch( pitch ); + player->isKillable = killable; + + success = true; + } + else + { + rDebugString( "Dropped sound effect, no player available\n" ); + } + + return( success ); +} + +//============================================================================= +// SoundFXLogic::ServiceOncePerFrame +//============================================================================= +// Description: Does nothing. Subclasses with servicing requirements need +// to override this function +// +// Parameters: elapsedTime - time elapsed since last frame +// +// Return: void +// +//============================================================================= +void SoundFXLogic::ServiceOncePerFrame( unsigned int elapsedTime ) +{ +} + +//============================================================================= +// SoundFXLogic::OnSoundReady +//============================================================================= +// Description: Does nothing. Needed to pull this in to get OnPlaybackComplete +// from SimpsonsSoundPlayer. +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXLogic::OnSoundReady() +{ +} + +//============================================================================= +// SoundFXLogic::OnPlaybackComplete +//============================================================================= +// Description: Does nothing. Subclasses with callback requirements need +// to override this virtual function. +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXLogic::OnPlaybackComplete() +{ +} + +//============================================================================= +// SoundFXLogic::Cleanup +//============================================================================= +// Description: Does nothing. Subclasses with stuff to clean up override +// this virtual function. +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXLogic::Cleanup() +{ +} + +//****************************************************************************** +// +// Protected Member Functions +// +//****************************************************************************** + +//============================================================================= +// SoundFXLogic::playCreditLine +//============================================================================= +// Description: Play a credits conversation +// +// Parameters: lineNumber - last scrolled line number in credits text +// +// Return: void +// +//============================================================================= +void SoundFXLogic::playCreditLine( int lineNumber ) +{ + int i; + DialogEventData data; + + for( i = 0; i < s_creditDialogTableSize; i++ ) + { + if( lineNumber == s_creditDialogTable[i].lineNumber ) + { + data.charUID1 = tEntity::MakeUID( "kang" ); + data.charUID2 = tEntity::MakeUID( "kodos" ); + data.dialogName = s_creditDialogTable[i].dialogName; + + GetEventManager()->TriggerEvent( EVENT_IN_GAMEPLAY_CONVERSATION, static_cast<void*>(&data) ); + } + } +} diff --git a/game/code/sound/soundfx/soundfxlogic.h b/game/code/sound/soundfx/soundfxlogic.h new file mode 100644 index 0000000..f5735f6 --- /dev/null +++ b/game/code/sound/soundfx/soundfxlogic.h @@ -0,0 +1,91 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxlogic.h +// +// Description: Declaration for the SoundFXLogic class, which is an abstract +// base class for objects that translate events into sound effects +// in the different game states +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +#ifndef SOUNDFXLOGIC_H +#define SOUNDFXLOGIC_H + +//======================================== +// Nested Includes +//======================================== +#include <events/eventlistener.h> +#include <sound/simpsonssoundplayer.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: SFXPlayer +// +// Structure that maps the sound player to a flag indicating whether +// we can kill the sound effect for something higher priority +// +//============================================================================= +struct SFXPlayer +{ + SimpsonsSoundPlayer soundPlayer; + bool isKillable; +}; + +//============================================================================= +// +// Synopsis: SoundFXLogic +// +//============================================================================= + +class SoundFXLogic : public EventListener, + public SimpsonsSoundPlayerCallback +{ + public: + SoundFXLogic(); + virtual ~SoundFXLogic(); + + virtual void RegisterEventListeners() = 0; + void UnregisterEventListeners(); + + SFXPlayer* GetAvailableSFXPlayer( unsigned int* index = NULL ); + + virtual void ServiceOncePerFrame( unsigned int elapsedTime ); + + virtual void Cleanup(); + + // + // SimpsonsSoundPlayerCallback functions + // + void OnSoundReady(); + virtual void OnPlaybackComplete(); + + protected: + // Number of SFXPlayers + static const unsigned int s_numSFXPlayers = 6; + + // + // Sound players + // + SFXPlayer m_soundPlayers[s_numSFXPlayers]; + + bool playSFXSound( const char* resource, bool killable, bool useCallback = false, + unsigned int* index = NULL, float trim = 1.0f, float pitch = 1.0f ); + + void playCreditLine( int lineNumber ); + + private: + //Prevent wasteful constructor creation. + SoundFXLogic( const SoundFXLogic& original ); + SoundFXLogic& operator=( const SoundFXLogic& rhs ); +}; + + +#endif // SOUNDFXLOGIC_H + diff --git a/game/code/sound/soundfx/soundfxpauselogic.cpp b/game/code/sound/soundfx/soundfxpauselogic.cpp new file mode 100644 index 0000000..961996a --- /dev/null +++ b/game/code/sound/soundfx/soundfxpauselogic.cpp @@ -0,0 +1,98 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxpauselogic.cpp +// +// Description: Implements the SoundFXPauseLogic class, which handles +// the translation of events into sound effects for the pause +// menu. +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/soundfxpauselogic.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// SoundFXPauseLogic::SoundFXPauseLogic +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXPauseLogic::SoundFXPauseLogic() +{ +} + +//============================================================================== +// SoundFXPauseLogic::~SoundFXPauseLogic +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +SoundFXPauseLogic::~SoundFXPauseLogic() +{ +} + +//============================================================================= +// SoundFXPauseLogic::RegisterEventListeners +//============================================================================= +// Description: Register as listener of sound effect events with Event Manager +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void SoundFXPauseLogic::RegisterEventListeners() +{ +} + +//============================================================================= +// SoundFXPauseLogic::HandleEvent +//============================================================================= +// Description: Play sound effects in response to events +// +// Parameters: id - Sound effect event identifier +// pEventData - Currently unused +// +// Return: void +// +//============================================================================= +void SoundFXPauseLogic::HandleEvent( EventEnum id, void* pEventData ) +{ +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/sound/soundfx/soundfxpauselogic.h b/game/code/sound/soundfx/soundfxpauselogic.h new file mode 100644 index 0000000..5cc861f --- /dev/null +++ b/game/code/sound/soundfx/soundfxpauselogic.h @@ -0,0 +1,50 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: soundfxpauselogic.h +// +// Description: Declaration for the SoundFXPauseLogic class, which handles +// the translation of events into sound effects for the pause +// menu. +// +// History: 31/07/2002 + Created -- Darren +// +//============================================================================= + +#ifndef SOUNDFXPAUSELOGIC_H +#define SOUNDFXPAUSELOGIC_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/soundfxlogic.h> + +//======================================== +// Forward References +//======================================== + +//============================================================================= +// +// Synopsis: SoundFXPauseLogic +// +//============================================================================= + +class SoundFXPauseLogic : public SoundFXLogic +{ + public: + SoundFXPauseLogic(); + virtual ~SoundFXPauseLogic(); + + void RegisterEventListeners(); + + void HandleEvent( EventEnum id, void* pEventData ); + + private: + //Prevent wasteful constructor creation. + SoundFXPauseLogic( const SoundFXPauseLogic& original ); + SoundFXPauseLogic& operator=( const SoundFXPauseLogic& rhs ); +}; + + +#endif // SOUNDFXPAUSELOGIC_H + diff --git a/game/code/sound/soundfx/win32reverbcontroller.cpp b/game/code/sound/soundfx/win32reverbcontroller.cpp new file mode 100644 index 0000000..8876d0d --- /dev/null +++ b/game/code/sound/soundfx/win32reverbcontroller.cpp @@ -0,0 +1,127 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: win32reverbcontroller.cpp +// +// Description: Implementation for the Win32ReverbController class, which provides +// the Windows-specific reverb control +// +// History: 03/25/2003 + Created -- Ziemek +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radsound_win32.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/win32reverbcontroller.h> + +#include <sound/soundfx/reverbsettings.h> + +#include <memory/srrmemory.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// Win32ReverbController::Win32ReverbController +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Win32ReverbController::Win32ReverbController() +{ + m_reverbInterface = ::radSoundHalEffectEAX2ReverbCreate( GMA_PERSISTENT ); + m_reverbInterface->AddRef(); + + registerReverbEffect( m_reverbInterface ); +} + +//============================================================================== +// Win32ReverbController::~Win32ReverbController +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +Win32ReverbController::~Win32ReverbController() +{ + m_reverbInterface->Release(); + m_reverbInterface = NULL; +} + +//============================================================================= +// Win32ReverbController::SetReverbOn +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void Win32ReverbController::SetReverbOn( reverbSettings* settings ) +{ + if( settings != NULL ) + { + rReleaseString( "Settings not null\n" ); + SetReverbGain( settings->GetGain() ); + m_reverbInterface->SetRoom( settings->GetXboxRoom() ); + m_reverbInterface->SetRoomHF( settings->GetXboxRoomHF() ); + m_reverbInterface->SetRoomRolloffFactor( settings->GetXboxRoomRolloffFactor() ); + m_reverbInterface->SetDecayTime( settings->GetXboxDecayTime() ); + m_reverbInterface->SetDecayHFRatio( settings->GetXboxDecayHFRatio() ); + m_reverbInterface->SetReflections( settings->GetXboxReflections() ); + m_reverbInterface->SetReflectionsDelay( settings->GetXboxReflectionsDelay() ); + m_reverbInterface->SetReverb( settings->GetXboxReverb() ); + m_reverbInterface->SetReverbDelay( settings->GetXboxReverbDelay() ); + m_reverbInterface->SetEnvironmentDiffusion( settings->GetWinEnvironmentDiffusion() ); + m_reverbInterface->SetAirAbsorptionHF( settings->GetWinAirAbsorptionHF() ); + + prepareFadeSettings( settings->GetGain(), settings->GetFadeInTime(), + settings->GetFadeOutTime() ); + } +} + +//============================================================================= +// Win32ReverbController::SetReverbOff +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void Win32ReverbController::SetReverbOff() +{ + startFadeOut(); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/sound/soundfx/win32reverbcontroller.h b/game/code/sound/soundfx/win32reverbcontroller.h new file mode 100644 index 0000000..055ae84 --- /dev/null +++ b/game/code/sound/soundfx/win32reverbcontroller.h @@ -0,0 +1,54 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: win32reverbcontroller.h +// +// Description: Declaration for the Win32ReverbController class, which provides +// the Windows-specific reverb control +// +// History: 03/25/2003 + Created -- Ziemek +// +//============================================================================= + +#ifndef WIN32REVERBCONTROLLER_H +#define WIN32REVERBCONTROLLER_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/reverbcontroller.h> + +//======================================== +// Forward References +//======================================== +struct IRadSoundHalEffectEAX2Reverb; + +//============================================================================= +// +// Synopsis: Win32ReverbController +// +//============================================================================= + +class Win32ReverbController : public ReverbController +{ +public: + Win32ReverbController(); + virtual ~Win32ReverbController(); + + void SetReverbOn( reverbSettings* settings ); + void SetReverbOff(); + +private: + //Prevent wasteful constructor creation. + Win32ReverbController( const Win32ReverbController& original ); + Win32ReverbController& operator=( const Win32ReverbController& rhs ); + + // + // Radsound's Win32 reverb interface + // + IRadSoundHalEffectEAX2Reverb* m_reverbInterface; +}; + + +#endif // WIN32REVERBCONTROLLER_H + diff --git a/game/code/sound/soundfx/xboxreverbcontroller.cpp b/game/code/sound/soundfx/xboxreverbcontroller.cpp new file mode 100644 index 0000000..599aeee --- /dev/null +++ b/game/code/sound/soundfx/xboxreverbcontroller.cpp @@ -0,0 +1,127 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: xboxreverbcontroller.cpp +// +// Description: Implementation for the XboxReverbController class, which provides +// the Xbox-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +//======================================== +// System Includes +//======================================== +#include <radsound_xbox.hpp> + +//======================================== +// Project Includes +//======================================== +#include <sound/soundfx/xboxreverbcontroller.h> + +#include <sound/soundfx/reverbsettings.h> + +#include <memory/srrmemory.h> + + + +//****************************************************************************** +// +// Global Data, Local Data, Local Classes +// +//****************************************************************************** + +//****************************************************************************** +// +// Public Member Functions +// +//****************************************************************************** + +//============================================================================== +// XboxReverbController::XboxReverbController +//============================================================================== +// Description: Constructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +XboxReverbController::XboxReverbController() +{ + m_reverbInterface = ::radSoundHalEffectI3DL2ReverbXBoxCreate( GMA_PERSISTENT ); + + registerReverbEffect( m_reverbInterface ); +} + +//============================================================================== +// XboxReverbController::~XboxReverbController +//============================================================================== +// Description: Destructor. +// +// Parameters: None. +// +// Return: N/A. +// +//============================================================================== +XboxReverbController::~XboxReverbController() +{ + m_reverbInterface->Release(); + m_reverbInterface = NULL; +} + +//============================================================================= +// XboxReverbController::SetReverbOn +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void XboxReverbController::SetReverbOn( reverbSettings* settings ) +{ + if( settings != NULL ) + { + rReleaseString( "Settings not null\n" ); + SetReverbGain( settings->GetGain() ); + m_reverbInterface->SetRoom( settings->GetXboxRoom() ); + m_reverbInterface->SetRoomHF( settings->GetXboxRoomHF() ); + m_reverbInterface->SetRoomRolloffFactor( settings->GetXboxRoomRolloffFactor() ); + m_reverbInterface->SetDecayTime( settings->GetXboxDecayTime() ); + m_reverbInterface->SetDecayHFRatio( settings->GetXboxDecayHFRatio() ); + m_reverbInterface->SetReflections( settings->GetXboxReflections() ); + m_reverbInterface->SetReflectionsDelay( settings->GetXboxReflectionsDelay() ); + m_reverbInterface->SetReverb( settings->GetXboxReverb() ); + m_reverbInterface->SetReverbDelay( settings->GetXboxReverbDelay() ); + m_reverbInterface->SetDiffusion( settings->GetXboxDiffusion() ); + m_reverbInterface->SetDensity( settings->GetXboxDensity() ); + m_reverbInterface->SetHFReference( settings->GetXboxHFReference() ); + + prepareFadeSettings( settings->GetGain(), settings->GetFadeInTime(), + settings->GetFadeOutTime() ); + } +} + +//============================================================================= +// XboxReverbController::SetReverbOff +//============================================================================= +// Description: Self-explanatory +// +// Parameters: None +// +// Return: void +// +//============================================================================= +void XboxReverbController::SetReverbOff() +{ + startFadeOut(); +} + +//****************************************************************************** +// +// Private Member Functions +// +//****************************************************************************** diff --git a/game/code/sound/soundfx/xboxreverbcontroller.h b/game/code/sound/soundfx/xboxreverbcontroller.h new file mode 100644 index 0000000..5ef87f3 --- /dev/null +++ b/game/code/sound/soundfx/xboxreverbcontroller.h @@ -0,0 +1,54 @@ +//============================================================================= +// Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. +// +// File: xboxreverbcontroller.h +// +// Description: Declaration for the XboxReverbController class, which provides +// the Xbox-specific reverb control +// +// History: 10/28/2002 + Created -- Darren +// +//============================================================================= + +#ifndef XBOXREVERBCONTROLLER_H +#define XBOXREVERBCONTROLLER_H + +//======================================== +// Nested Includes +//======================================== +#include <sound/soundfx/reverbcontroller.h> + +//======================================== +// Forward References +//======================================== +struct IRadSoundHalEffectI3DL2ReverbXBox; + +//============================================================================= +// +// Synopsis: XboxReverbController +// +//============================================================================= + +class XboxReverbController : public ReverbController +{ + public: + XboxReverbController(); + virtual ~XboxReverbController(); + + void SetReverbOn( reverbSettings* settings ); + void SetReverbOff(); + + private: + //Prevent wasteful constructor creation. + XboxReverbController( const XboxReverbController& original ); + XboxReverbController& operator=( const XboxReverbController& rhs ); + + // + // Radsound's Xbox reverb interface + // + IRadSoundHalEffectI3DL2ReverbXBox* m_reverbInterface; +}; + + +#endif // XBOXREVERBCONTROLLER_H + |