#include "AdeptHeaders.hpp" #include "ComponentHeaders.hpp" #include "Interface.hpp" #include "AudioFXComponent.hpp" #include "AudioRenderer.hpp" #include "Entity.hpp" #include "AudioComponentWeb.hpp" #include "Mover.hpp" #include "SpatializedCommand.hpp" // // Shared Data Support // //#define HUNT_BUG "daberger" Component::ClassData* AudioFXComponent::DefaultData = NULL; static Scalar g_RangeMultiplier; bool g_LowEndSound; static bool __stdcall Check50() {return g_RangeMultiplier == 0.5f;} static bool __stdcall Check33() {return g_RangeMultiplier == 0.33f;} static bool __stdcall Check25() {return g_RangeMultiplier == 0.25f;} static bool __stdcall CheckLowDetailSound() {return g_LowEndSound;} static void __stdcall Enable50() {g_RangeMultiplier = (g_RangeMultiplier == 0.5f) ? 1.0f : 0.5f;} static void __stdcall Enable33() {g_RangeMultiplier = (g_RangeMultiplier == 0.33f) ? 1.0f : 0.33f;} static void __stdcall Enable25() {g_RangeMultiplier = (g_RangeMultiplier == 0.25f) ? 1.0f : 0.25f;} static void __stdcall EnableLowDetailSound() {g_LowEndSound = !g_LowEndSound;} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // InitializeClass // void AudioFXComponent::InitializeClass(Stuff::NotationFile *startup_ini) { Verify(!DefaultData); DefaultData = new ClassData( AudioFXComponentClassID, "Adept::AudioFXComponent", BaseClass::DefaultData, 0, NULL ); Register_Object(DefaultData); g_RangeMultiplier = 1.0f; g_LowEndSound = false; AddDebuggerMenuItem("Libraries\\Sound\\50% sound range", Check50, Enable50, 0 ); AddDebuggerMenuItem("Libraries\\Sound\\33% sound range", Check33, Enable33, 0 ); AddDebuggerMenuItem("Libraries\\Sound\\25% sound range", Check25, Enable25, 0 ); AddDebuggerMenuItem("Libraries\\Sound\\Low Detail sounds", CheckLowDetailSound, EnableLowDetailSound, 0 ); if (startup_ini) { Check_Object(startup_ini); Stuff::Page *page = startup_ini->FindPage("Sound Options"); if (page) { Check_Object(page); page->GetEntry("LowEndSound", &g_LowEndSound); page->GetEntry("Radius", &g_RangeMultiplier); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AudioFXComponent::TerminateClass(Stuff::NotationFile *startup_ini) { if (startup_ini) { Check_Object(startup_ini); Stuff::Page *page = startup_ini->SetPage("Sound Options"); Check_Object(page); page->SetEntry("LowEndSound", g_LowEndSound); page->SetEntry("Radius", g_RangeMultiplier); } Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AudioFXComponent // AudioFXComponent::AudioFXComponent( ClassData *class_data, MemoryStream *stream, AudioComponentWeb *owning_web ): Component(class_data, stream, owning_web), m_command(NULL) { Check_Pointer(this); Check_Object(stream); Check_Object(owning_web); // //------------------------- // Read in the command data //------------------------- // int play_mode; *stream >> m_type >> m_handleResourceID >> m_lowEndHandleResourceID; *stream >> play_mode >> m_priority >> m_volume; m_playMode = static_cast(play_mode); *stream >> m_minRestartDelay >> m_minReplaceDelay; *stream >> m_minDeviation; *stream >> m_nearClip >> m_minRange >> m_maxRange >> m_farClip; // //------------------------------------------- // Make sure the sample is in the audio cache //------------------------------------------- // AudioRenderer::Instance->UseSample(m_handleResourceID); // //--------------------------- // Read in the component data //--------------------------- // int attribute_id; *stream >> attribute_id; m_entity = owning_web->GetEntity(); Check_Object(m_entity); if (attribute_id != -1) { m_status = m_entity->GetAttributeEntry(attribute_id); Check_Object(m_status); Verify(m_status->attributeType == IntClassID); } else m_status = NULL; // //---------------------------------------------------------- // If we are told to play on startup, issue the play command //---------------------------------------------------------- // bool execute_now; *stream >> execute_now >> m_executeDelay; if (execute_now) { PlaySound(); if (m_status) { bool result = true; m_status->SetValue(m_entity, &result); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AudioFXComponent* AudioFXComponent::Make( MemoryStream *stream, AudioComponentWeb *owning_web ) { AudioFXComponent *ear = new AudioFXComponent(DefaultData, stream, owning_web); return ear; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // AudioFXComponent::~AudioFXComponent() { Check_Object(this); AudioCommand *command = m_command.GetCurrent(); if (command) { Check_Object(command); command->Stop(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AudioFXComponent::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AudioFXComponent::Execute() { Check_Object(this); // //------------------------------------------------------------------------ // Set the status for the entity. If we are no longer executing, or if it // isn't our turn yet, don't do anything //------------------------------------------------------------------------ // SpatializedCommand *command = m_command.GetCurrent(); int result = command != NULL; if (m_status) m_status->SetValue(m_entity, &result); Time now = gos_GetElapsedTime(); if (!result || now < m_nextExecute) return; // //----------------------------------------------- // Update the position and velocity of the entity //----------------------------------------------- // Check_Object(m_entity); Point3D position(m_entity->GetLocalToWorld()); command->SetPosition(position); m_nextExecute = now + m_executeDelay; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AudioFXComponent::ChannelChanged(Channel *channel) { Check_Object(this); Check_Object(channel); switch (channel->GetCommand()) { case AudioRenderer::StartEffectCommandID: if (!m_command.GetCurrent()) PlaySound(); break; case AudioRenderer::KillEffectCommandID: case AudioRenderer::StopEffectCommandID: if (m_command.GetCurrent()) m_command.GetCurrent()->Stop(); break; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void AudioFXComponent::PlaySound() { Check_Object(this); // //------------------------------------------------------ // Find where the sound is, then launch the play command //------------------------------------------------------ // Check_Object(m_entity); Point3D position(m_entity->GetLocalToWorld()); Verify(m_executeDelay >= 0.0f); m_nextExecute = gos_GetElapsedTime() + m_executeDelay; SpatializedCommand *command = SpatializedCommand::Create( m_type, (g_LowEndSound) ? m_lowEndHandleResourceID : m_handleResourceID, m_priority, m_volume, m_minRestartDelay, m_minReplaceDelay, position, Vector3D(0.0f, 0.0f, 0.0f), m_minDeviation, #if defined(LAB_ONLY) m_nearClip * g_RangeMultiplier, m_minRange * g_RangeMultiplier, m_maxRange * g_RangeMultiplier, m_farClip * g_RangeMultiplier #else m_nearClip, m_minRange, m_maxRange, m_farClip #endif ); Check_Object(command); m_command.Add(command); command->Play(m_playMode); }