From fbdaf92953569db374bbd96dccafaa1e036b5869 Mon Sep 17 00:00:00 2001 From: stiffly Date: Fri, 5 Feb 2016 16:39:23 +0100 Subject: [PATCH] Started refactoring. Put player walk logic in a designated sound system. --- .../Engine/Input/FirstPersonInputController.h | 4 + .../Sound/{SoundSystem.h => SoundManager.h} | 89 +++--- include/Game/Game.h | 5 +- include/Game/Systems/SoundSystem.h | 31 ++ .../{SoundSystem.cpp => SoundManager.cpp} | 287 +++++++----------- src/Game/Game.cpp | 8 +- src/Game/Systems/SoundSystem.cpp | 73 +++++ 7 files changed, 281 insertions(+), 216 deletions(-) rename include/Engine/Sound/{SoundSystem.h => SoundManager.h} (71%) create mode 100644 include/Game/Systems/SoundSystem.h rename src/Engine/Sound/{SoundSystem.cpp => SoundManager.cpp} (65%) create mode 100644 src/Game/Systems/SoundSystem.cpp diff --git a/include/Engine/Input/FirstPersonInputController.h b/include/Engine/Input/FirstPersonInputController.h index 2bbd768d..f3b0a17a 100644 --- a/include/Engine/Input/FirstPersonInputController.h +++ b/include/Engine/Input/FirstPersonInputController.h @@ -4,6 +4,7 @@ #include "../GLM.h" #include "../Core/InputController.h" #include "../Core/ELockMouse.h" +#include "../Game/Events/EDashAbility.h" #include "InputHandler.h" template @@ -230,6 +231,9 @@ void FirstPersonInputController::AssaultDashCheck(double dt, bool m_AssaultDashDoubleTapped = true; m_AssaultDashDoubleTapDeltaTime = 0.f; m_AssaultDashCoolDownTimer = assaultDashCoolDownMaxTimer; + + Events::DashAbility e; + m_EventBroker->Publish(e); } #endif \ No newline at end of file diff --git a/include/Engine/Sound/SoundSystem.h b/include/Engine/Sound/SoundManager.h similarity index 71% rename from include/Engine/Sound/SoundSystem.h rename to include/Engine/Sound/SoundManager.h index 51f80427..a9fb23a9 100644 --- a/include/Engine/Sound/SoundSystem.h +++ b/include/Engine/Sound/SoundManager.h @@ -1,5 +1,5 @@ -#ifndef SoundSystem_h__ -#define SoundSystem_h__ +#ifndef SoundManager_h__ +#define SoundManager_h__ #include #include @@ -34,6 +34,7 @@ #include "Collision/ETrigger.h" #include "Core/EPause.h" #include "Game/Events/EDoubleJump.h" +#include "Game/Events/EDashAbility.h" typedef std::pair> QueuedBuffers; @@ -51,14 +52,30 @@ struct Source SoundType Type; }; -class SoundSystem +class SoundManager { public: - SoundSystem() { } - SoundSystem(World* world, EventBroker* eventBroker, bool editorMode); - ~SoundSystem(); + SoundManager() { } + SoundManager(World* world, EventBroker* eventBroker, bool editorMode); + ~SoundManager(); // Update emitters / listener void Update(double dt); + +protected: + // Specific logic + void playSound(Source* source); + // Need to be the same format (sample rate etc) + void playQueue(QueuedBuffers qb); + void stopSound(Source* source); + void playerJumps(); + void playerStep(double dt); + EntityID createChildEmitter(); + + // Logic + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; + std::unordered_map m_Sources; + private: // Help functions for working with OpenaAL void setListenerPos(glm::vec3 pos) { alListener3f(AL_POSITION, pos.x, pos.y, pos.z); }; @@ -81,75 +98,63 @@ private: void setGain(Source* source, float gain); void setSoundProperties(Source* source, ComponentWrapper* soundComponent); - // Specific logic - void playSound(Source* source); - // Need to be the same format (sample rate etc) - void playQueue(QueuedBuffers qb); - void stopSound(Source* source); - void playerDamaged(); - void playerShot(); - void playerJumps(); - void playerStep(double dt); + // OpenAL system variables ALCdevice* m_ALCdevice = nullptr; ALCcontext* m_ALCcontext = nullptr; - // Logic - World* m_World = nullptr; - EventBroker* m_EventBroker = nullptr; - std::unordered_map m_Sources; + float m_BGMVolumeChannel = 1.0f; float m_SFXVolumeChannel = 1.0f; bool m_EditorEnabled = false; - const double m_PlayerFootstepInterval = 1.0; - double m_TimeSinceLastFootstep = 0; EntityID m_LocalPlayer = EntityID_Invalid; - bool m_LeftFoot = false; std::default_random_engine generator; // Events - EventRelay m_EPlaySoundOnEntity; + EventRelay m_EPlaySoundOnEntity; bool OnPlaySoundOnEntity(const Events::PlaySoundOnEntity &e); - EventRelay m_EPlaySoundOnPosition; + EventRelay m_EPlaySoundOnPosition; bool OnPlaySoundOnPosition(const Events::PlaySoundOnPosition &e); - EventRelay m_EPlayBackgroundMusic; + EventRelay m_EPlayBackgroundMusic; bool OnPlayBackgroundMusic(const Events::PlayBackgroundMusic &e); - EventRelay m_EPauseSound; + EventRelay m_EPauseSound; bool OnPauseSound(const Events::PauseSound &e); - EventRelay m_EStopSound; + EventRelay m_EStopSound; bool OnStopSound(const Events::StopSound &e); - EventRelay m_EContinueSound; + EventRelay m_EContinueSound; bool OnContinueSound(const Events::ContinueSound &e); - EventRelay m_ESetBGMGain; + EventRelay m_ESetBGMGain; bool OnSetBGMGain(const Events::SetBGMGain &e); - EventRelay m_ESetSFXGain; + EventRelay m_ESetSFXGain; bool OnSetSFXGain(const Events::SetSFXGain &e); - EventRelay m_EShoot; + EventRelay m_EShoot; bool OnShoot(const Events::Shoot &e); - EventRelay m_EPlayerSpawned; + EventRelay m_EPlayerSpawned; bool OnPlayerSpawned(const Events::PlayerSpawned &e); - EventRelay m_EInputCommand; + EventRelay m_EInputCommand; bool OnInputCommand(const Events::InputCommand &e); - EventRelay m_ECaptured; + EventRelay m_ECaptured; bool OnCaptured(const Events::Captured &e); - EventRelay m_EPlayerDamage; + EventRelay m_EPlayerDamage; bool OnPlayerDamage(const Events::PlayerDamage &e); - EventRelay m_EPlayerDeath; + EventRelay m_EPlayerDeath; bool OnPlayerDeath(const Events::PlayerDeath &e); - EventRelay m_EPlayerHealthPickup; + EventRelay m_EPlayerHealthPickup; bool OnPlayerHealthPickup(const Events::PlayerHealthPickup &e); - EventRelay m_EComponentAttached; + EventRelay m_EComponentAttached; bool OnComponentAttached(const Events::ComponentAttached &e); - EventRelay m_ETriggerTouch; + EventRelay m_ETriggerTouch; bool OnTriggerTouch(const Events::TriggerTouch &e); - EventRelay m_EPause; + EventRelay m_EPause; bool OnPause(const Events::Pause &e); - EventRelay m_EResume; + EventRelay m_EResume; bool OnResume(const Events::Resume &e); - EventRelay m_EDoubleJump; + EventRelay m_EDoubleJump; bool OnDoubleJump(const Events::DoubleJump &e); + EventRelay m_EDashAbility; + bool OnDashAbility(const Events::DashAbility &e); diff --git a/include/Game/Game.h b/include/Game/Game.h index 37267a68..b6a2c0d3 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -30,7 +30,8 @@ #include "Network/Client.h" // Sound -#include "Sound/SoundSystem.h" +//#include "Sound/SoundManager.h" +#include "Systems/SoundSystem.h" class Game { @@ -64,7 +65,7 @@ private: bool m_IsClientOrServer = false; // Sound - SoundSystem* m_SoundSystem; + SoundManager* m_SoundManager; //EventRelay m_EInputCommand; //bool debugOnInputCommand(const Events::InputCommand& e); diff --git a/include/Game/Systems/SoundSystem.h b/include/Game/Systems/SoundSystem.h new file mode 100644 index 00000000..33dbf1fc --- /dev/null +++ b/include/Game/Systems/SoundSystem.h @@ -0,0 +1,31 @@ +#ifndef Systems_SoundSystem_h__ +#define Systems_SoundSystem_h__ + +#include "../Engine/Core/System.h" +#include "../Engine/Sound/SoundManager.h" +#include "../Engine/Core/EPlayerSpawned.h" + + +class SoundSystem : public PureSystem, ImpureSystem, SoundManager +{ +public: + SoundSystem(World* world, EventBroker* eventbroker); + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; + virtual void Update(double dt) override; +private: + void playerStep(double dt); + EntityWrapper m_LocalPlayer = EntityWrapper(); + + World* m_World = nullptr; + EventBroker* m_EventBroker = nullptr; + + // TODO: WIP Update this + double m_TimeSinceLastFootstep = 0.0; + const double m_PlayerFootstepInterval = 1.0; + bool m_LeftFoot = false; + + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(const Events::PlayerSpawned &e); +}; + +#endif diff --git a/src/Engine/Sound/SoundSystem.cpp b/src/Engine/Sound/SoundManager.cpp similarity index 65% rename from src/Engine/Sound/SoundSystem.cpp rename to src/Engine/Sound/SoundManager.cpp index 3045b1f4..3cec4deb 100644 --- a/src/Engine/Sound/SoundSystem.cpp +++ b/src/Engine/Sound/SoundManager.cpp @@ -1,6 +1,6 @@ -#include "Sound/SoundSystem.h" +#include "Sound/SoundManager.h" -SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode) +SoundManager::SoundManager(World* world, EventBroker* eventBroker, bool editorMode) { m_EventBroker = eventBroker; m_World = world; @@ -12,27 +12,28 @@ SoundSystem::SoundSystem(World* world, EventBroker* eventBroker, bool editorMode alDistanceModel(AL_LINEAR_DISTANCE); alDopplerFactor(1); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundSystem::OnPlaySoundOnEntity); - EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundSystem::OnPlaySoundOnPosition); - EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundSystem::OnPlayBackgroundMusic); - EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); - EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundSystem::OnPauseSound); - EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundSystem::OnContinueSound); - EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundSystem::OnSetBGMGain); - EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundSystem::OnSetSFXGain); - EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundSystem::OnShoot); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); - EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundSystem::OnPlayerDamage); - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundSystem::OnInputCommand); - EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundSystem::OnCaptured); - EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundSystem::OnTriggerTouch); - EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundSystem::OnPause); - EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundSystem::OnResume); - EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundSystem::OnComponentAttached); - EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundSystem::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnEntity, &SoundManager::OnPlaySoundOnEntity); + EVENT_SUBSCRIBE_MEMBER(m_EPlaySoundOnPosition, &SoundManager::OnPlaySoundOnPosition); + EVENT_SUBSCRIBE_MEMBER(m_EPlayBackgroundMusic, &SoundManager::OnPlayBackgroundMusic); + EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundManager::OnStopSound); + EVENT_SUBSCRIBE_MEMBER(m_EPauseSound, &SoundManager::OnPauseSound); + EVENT_SUBSCRIBE_MEMBER(m_EContinueSound, &SoundManager::OnContinueSound); + EVENT_SUBSCRIBE_MEMBER(m_ESetBGMGain, &SoundManager::OnSetBGMGain); + EVENT_SUBSCRIBE_MEMBER(m_ESetSFXGain, &SoundManager::OnSetSFXGain); + EVENT_SUBSCRIBE_MEMBER(m_EShoot, &SoundManager::OnShoot); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundManager::OnPlayerSpawned); + EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &SoundManager::OnPlayerDamage); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SoundManager::OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &SoundManager::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &SoundManager::OnTriggerTouch); + EVENT_SUBSCRIBE_MEMBER(m_EPause, &SoundManager::OnPause); + EVENT_SUBSCRIBE_MEMBER(m_EResume, &SoundManager::OnResume); + EVENT_SUBSCRIBE_MEMBER(m_EComponentAttached, &SoundManager::OnComponentAttached); + EVENT_SUBSCRIBE_MEMBER(m_EDoubleJump, &SoundManager::OnDoubleJump); + EVENT_SUBSCRIBE_MEMBER(m_EDashAbility, &SoundManager::OnDashAbility); } -SoundSystem::~SoundSystem() +SoundManager::~SoundManager() { stopEmitters(); // Stopps emitters deleteInactiveEmitters(); // Deletes stopped emitters @@ -47,7 +48,7 @@ SoundSystem::~SoundSystem() alcCloseDevice(m_ALCdevice); } -void SoundSystem::stopEmitters() +void SoundManager::stopEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -57,10 +58,9 @@ void SoundSystem::stopEmitters() } } -void SoundSystem::Update(double dt) +void SoundManager::Update(double dt) { - m_EventBroker->Process(); - playerStep(dt); + m_EventBroker->Process(); deleteInactiveEmitters(); // can be optimized with "EEntityDeleted" updateEmitters(dt); updateListener(dt); @@ -70,7 +70,7 @@ void SoundSystem::Update(double dt) ImGui::SliderFloat("SFX", &m_SFXVolumeChannel, 0.0f, 1.0f, "%.3f", 1.0f); } -void SoundSystem::deleteInactiveEmitters() +void SoundManager::deleteInactiveEmitters() { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end();) { @@ -99,7 +99,7 @@ void SoundSystem::deleteInactiveEmitters() } } -void SoundSystem::updateEmitters(double dt) +void SoundManager::updateEmitters(double dt) { std::unordered_map::iterator it; for (it = m_Sources.begin(); it != m_Sources.end(); it++) { @@ -132,7 +132,7 @@ void SoundSystem::updateEmitters(double dt) } } -void SoundSystem::updateListener(double dt) +void SoundManager::updateListener(double dt) { // Should only be one listener. auto listenerComponents = m_World->GetComponents("Listener"); @@ -151,7 +151,7 @@ void SoundSystem::updateListener(double dt) } } -Source* SoundSystem::createSource(std::string filePath) +Source* SoundManager::createSource(std::string filePath) { ALuint alSource; alGenSources((ALuint)1, &alSource); @@ -163,13 +163,13 @@ Source* SoundSystem::createSource(std::string filePath) return source; } -void SoundSystem::playSound(Source* source) +void SoundManager::playSound(Source* source) { alSourcei(source->ALsource, AL_BUFFER, source->SoundResource->Buffer()); alSourcePlay(source->ALsource); } -void SoundSystem::playQueue(QueuedBuffers qb) +void SoundManager::playQueue(QueuedBuffers qb) { for (int i = 0; i < qb.second.size(); i++) { alSourceQueueBuffers(qb.first, 1, &qb.second[i]); @@ -177,69 +177,37 @@ void SoundSystem::playQueue(QueuedBuffers qb) alSourcePlay(qb.first); } -void SoundSystem::stopSound(Source* source) +void SoundManager::stopSound(Source* source) { alSourceStop(source->ALsource); } -void SoundSystem::playerDamaged() -{ - -} - -void SoundSystem::playerShot() -{ } - -void SoundSystem::playerJumps() +void SoundManager::playerJumps() { glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; if (vel.y == 0) { Source* source = createSource("Audio/jump/jump1.wav"); - auto emitterID = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(emitterID, "Transform"); - m_World->AttachComponent(emitterID, "SoundEmitter"); source->Type = SoundType::SFX; - m_Sources[emitterID] = source; + m_Sources[createChildEmitter()] = source; playSound(source); } } -void SoundSystem::playerStep(double dt) +void SoundManager::playerStep(double dt) { - if (!m_World->ValidEntity(m_LocalPlayer)) { - return; - } - if (m_LocalPlayer == EntityID_Invalid) { - return; - } - - m_TimeSinceLastFootstep += dt; - glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer, "Physics")["Velocity"]; - float playerSpeed = glm::length(vel); - bool isAirborne = vel.y != 0; - if (playerSpeed > 1 && !isAirborne) { - // Player is walking - if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { - // Create footstep sound - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - Events::PlaySoundOnEntity e; - e.EmitterID = child; - if (m_LeftFoot) { - e.FilePath = "Audio/footstep/footstep2.wav"; - } else { - e.FilePath = "Audio/footstep/footstep3.wav"; - } - m_LeftFoot = !m_LeftFoot; - m_EventBroker->Publish(e); - m_TimeSinceLastFootstep = 0; - } - } + } -bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) +EntityID SoundManager::createChildEmitter() +{ + EntityID child = m_World->CreateEntity(m_LocalPlayer); + m_World->AttachComponent(child, "Transform"); + m_World->AttachComponent(child, "SoundEmitter"); + return child; +} + +bool SoundManager::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) { Source* source = createSource(e.FilePath); source->Type = SoundType::SFX; @@ -248,7 +216,7 @@ bool SoundSystem::OnPlaySoundOnEntity(const Events::PlaySoundOnEntity & e) return false; } -bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) +bool SoundManager::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) { Source* source = createSource(e.FilePath); auto emitterID = m_World->CreateEntity(); @@ -267,25 +235,25 @@ bool SoundSystem::OnPlaySoundOnPosition(const Events::PlaySoundOnPosition & e) return true; } -bool SoundSystem::OnPauseSound(const Events::PauseSound & e) +bool SoundManager::OnPauseSound(const Events::PauseSound & e) { alSourcePause(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnStopSound(const Events::StopSound & e) +bool SoundManager::OnStopSound(const Events::StopSound & e) { alSourceStop(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnContinueSound(const Events::ContinueSound & e) +bool SoundManager::OnContinueSound(const Events::ContinueSound & e) { alSourcePlay(m_Sources[e.EmitterID]->ALsource); return true; } -bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) +bool SoundManager::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) { auto listenerComponents = m_World->GetComponents("Listener"); for (auto it = listenerComponents->begin(); it != listenerComponents->end(); it++) { @@ -303,53 +271,40 @@ bool SoundSystem::OnPlayBackgroundMusic(const Events::PlayBackgroundMusic & e) return true; } -bool SoundSystem::OnSetBGMGain(const Events::SetBGMGain & e) +bool SoundManager::OnSetBGMGain(const Events::SetBGMGain & e) { m_BGMVolumeChannel = e.Gain; return true; } -bool SoundSystem::OnSetSFXGain(const Events::SetSFXGain & e) +bool SoundManager::OnSetSFXGain(const Events::SetSFXGain & e) { m_SFXVolumeChannel = e.Gain; return true; } -bool SoundSystem::OnShoot(const Events::Shoot & e) +bool SoundManager::OnShoot(const Events::Shoot & e) { Source* source = createSource("Audio/laser/laser1.wav"); - auto emitterID = m_World->CreateEntity(e.Player.ID); - m_World->AttachComponent(emitterID, "Transform"); - auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); + //auto emitterID = m_World->CreateEntity(e.Player.ID); + //m_World->AttachComponent(emitterID, "Transform"); + //auto emitter = m_World->AttachComponent(emitterID, "SoundEmitter"); source->Type = SoundType::SFX; - m_Sources[emitterID] = source; + m_Sources[createChildEmitter()] = source; playSound(source); return true; } -bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned & e) +bool SoundManager::OnPlayerSpawned(const Events::PlayerSpawned & e) { if (e.PlayerID == -1) { // Local player m_World->AttachComponent(e.Player.ID, "Listener"); m_LocalPlayer = e.Player.ID; - EntityID child = m_World->CreateEntity(e.Player.ID); - m_World->AttachComponent(child, "SoundEmitter"); // Temp - m_World->AttachComponent(child, "Transform"); // Temp - Events::PlaySoundOnEntity event; - event.EmitterID = child; - event.FilePath = "Audio/announcer/go.wav"; - m_EventBroker->Publish(event); - // TEMP: starts bgm - { - Events::PlayBackgroundMusic ev; - ev.FilePath = "Audio/bgm/ambient.wav"; - m_EventBroker->Publish(ev); - } } return true; } -bool SoundSystem::OnInputCommand(const Events::InputCommand & e) +bool SoundManager::OnInputCommand(const Events::InputCommand & e) { if (e.Command == "Jump" && e.Value > 0) { if (e.PlayerID == -1) { // local player @@ -370,7 +325,7 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e) return false; } -bool SoundSystem::OnCaptured(const Events::Captured & e) +bool SoundManager::OnCaptured(const Events::Captured & e) { int homeTeam = (int)m_World->GetComponent(e.CapturePointID, "Team")["Team"]; int team = (int)m_World->GetComponent(m_LocalPlayer, "Team")["Team"]; @@ -380,26 +335,20 @@ bool SoundSystem::OnCaptured(const Events::Captured & e) } else { ev.FilePath = "Audio/announcer/objective_failed.wav"; // have not been tested } - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); m_EventBroker->Publish(ev); return false; } -bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) +bool SoundManager::OnPlayerDamage(const Events::PlayerDamage & e) { // Should check for only local players here... - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); std::uniform_int_distribution dist(1, 12); int rand = dist(generator); Source* source = createSource("Audio/hurt/hurt" + std::to_string(rand) + ".wav"); source->Type = SoundType::SFX; - m_Sources[child] = source; + m_Sources[createChildEmitter()] = source; // Breathe std::vector buffers; @@ -413,35 +362,29 @@ bool SoundSystem::OnPlayerDamage(const Events::PlayerDamage & e) return false; } -bool SoundSystem::OnPlayerDeath(const Events::PlayerDeath & e) +bool SoundManager::OnPlayerDeath(const Events::PlayerDeath & e) { if (e.PlayerID == m_LocalPlayer) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/die/die2.wav"; // should random between a bunch m_EventBroker->Publish(ev); } return false; } -bool SoundSystem::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) +bool SoundManager::OnPlayerHealthPickup(const Events::PlayerHealthPickup & e) { if (e.PlayerHealedID == m_LocalPlayer) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/pickup/pickup2.wav"; m_EventBroker->Publish(ev); } return false; } -bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) +bool SoundManager::OnComponentAttached(const Events::ComponentAttached & e) { if (e.Component.Info.Name == "SoundEmitter") { auto component = m_World->GetComponent(e.Entity.ID, "SoundEmitter"); @@ -451,7 +394,7 @@ bool SoundSystem::OnComponentAttached(const Events::ComponentAttached & e) return false; } -bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) +bool SoundManager::OnTriggerTouch(const Events::TriggerTouch & e) { if (m_World->HasComponent(e.Trigger.ID, "CapturePoint")) { Events::PlayBackgroundMusic ev; @@ -461,7 +404,7 @@ bool SoundSystem::OnTriggerTouch(const Events::TriggerTouch & e) return false; } -bool SoundSystem::OnPause(const Events::Pause & e) +bool SoundManager::OnPause(const Events::Pause & e) { for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { alSourcePause(it->second->ALsource); @@ -469,7 +412,7 @@ bool SoundSystem::OnPause(const Events::Pause & e) return false; } -bool SoundSystem::OnResume(const Events::Resume &e) +bool SoundManager::OnResume(const Events::Resume &e) { for (auto it = m_Sources.begin(); it != m_Sources.end(); it++) { alSourcePlay(it->second->ALsource); @@ -477,19 +420,60 @@ bool SoundSystem::OnResume(const Events::Resume &e) return false; } -bool SoundSystem::OnDoubleJump(const Events::DoubleJump & e) +bool SoundManager::OnDoubleJump(const Events::DoubleJump & e) { Events::PlaySoundOnEntity ev; - EntityID child = m_World->CreateEntity(m_LocalPlayer); - m_World->AttachComponent(child, "Transform"); - m_World->AttachComponent(child, "SoundEmitter"); - ev.EmitterID = child; + ev.EmitterID = createChildEmitter(); ev.FilePath = "Audio/jump/jump2.wav"; m_EventBroker->Publish(ev); return false; } -void SoundSystem::setListenerOri(glm::vec3 ori) +bool SoundManager::OnDashAbility(const Events::DashAbility &e) +{ + Events::PlaySoundOnEntity ev; + ev.EmitterID = createChildEmitter(); + ev.FilePath = "Audio/jump/dash1.wav"; + m_EventBroker->Publish(ev); + return false; +} + +ALenum SoundManager::getSourceState(ALuint source) +{ + ALenum state; + alGetSourcei(source, AL_SOURCE_STATE, &state); + return state; +} + +void SoundManager::setGain(Source * source, float gain) +{ + alSourcef(source->ALsource, AL_GAIN, gain); +} + +void SoundManager::setSoundProperties(Source* source, ComponentWrapper* soundComponent) +{ + float gain = (source->Type == SoundType::SFX) ? m_SFXVolumeChannel : m_BGMVolumeChannel; + alSourcef(source->ALsource, AL_GAIN, (float)(double)(*soundComponent)["Gain"] * gain); + alSourcef(source->ALsource, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); + alSourcei(source->ALsource, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO + alSourcef(source->ALsource, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); + alSourcef(source->ALsource, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); + alSourcef(source->ALsource, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); +} + +void SoundManager::initOpenAL() +{ + // Initialize OpenAL + m_ALCdevice = alcOpenDevice(nullptr); + if (m_ALCdevice != nullptr) { + m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); + alcMakeContextCurrent(m_ALCcontext); + } else { + LOG_ERROR("OpenAL failed to initialize."); + } +} + +void SoundManager::setListenerOri(glm::vec3 ori) { // Calculate forward and up vector. glm::vec3 forward = glm::vec3(0.0, 0.0, -1.0); @@ -504,39 +488,4 @@ void SoundSystem::setListenerOri(glm::vec3 ori) glm::normalize(up); ALfloat lOri[6] = { forward.x, forward.y, forward.z, up.x, up.y, up.z }; alListenerfv(AL_ORIENTATION, lOri); -} - -ALenum SoundSystem::getSourceState(ALuint source) -{ - ALenum state; - alGetSourcei(source, AL_SOURCE_STATE, &state); - return state; -} - -void SoundSystem::setGain(Source * source, float gain) -{ - alSourcef(source->ALsource, AL_GAIN, gain); -} - -void SoundSystem::setSoundProperties(Source* source, ComponentWrapper* soundComponent) -{ - float gain = (source->Type == SoundType::SFX) ? m_SFXVolumeChannel : m_BGMVolumeChannel; - alSourcef(source->ALsource, AL_GAIN, (float)(double)(*soundComponent)["Gain"] * gain); - alSourcef(source->ALsource, AL_PITCH, (float)(double)(*soundComponent)["Pitch"]); - alSourcei(source->ALsource, AL_LOOPING, (int)(bool)(*soundComponent)["Loop"]); // YOLO - alSourcef(source->ALsource, AL_MAX_DISTANCE, (float)(double)(*soundComponent)["MaxDistance"]); - alSourcef(source->ALsource, AL_ROLLOFF_FACTOR, (float)(double)(*soundComponent)["RollOffFactor"]); - alSourcef(source->ALsource, AL_REFERENCE_DISTANCE, (float)(double)(*soundComponent)["ReferenceDistance"]); -} - -void SoundSystem::initOpenAL() -{ - // Initialize OpenAL - m_ALCdevice = alcOpenDevice(nullptr); - if (m_ALCdevice != nullptr) { - m_ALCcontext = alcCreateContext(m_ALCdevice, nullptr); - alcMakeContextCurrent(m_ALCcontext); - } else { - LOG_ERROR("OpenAL failed to initialize."); - } } \ No newline at end of file diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 04542f11..204f425e 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -81,6 +81,7 @@ Game::Game(int argc, char* argv[]) // All systems with orderlevel 0 will be updated first. unsigned int updateOrderLevel = 0; + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -91,6 +92,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); @@ -114,7 +116,7 @@ Game::Game(int argc, char* argv[]) } // Invoke sound system - m_SoundSystem = new SoundSystem(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); + //m_SoundManager = new SoundManager(m_World, m_EventBroker, m_Config->Get("Debug.EditorEnabled", false)); m_LastTime = glfwGetTime(); } @@ -122,7 +124,7 @@ Game::Game(int argc, char* argv[]) Game::~Game() { delete m_SystemPipeline; - delete m_SoundSystem; + //delete m_SoundManager; delete m_OctreeFrustrumCulling; delete m_OctreeCollision; delete m_OctreeTrigger; @@ -157,7 +159,7 @@ void Game::Tick() if (m_IsClientOrServer) { m_ClientOrServer->Update(); } - m_SoundSystem->Update(dt); + //m_SoundManager->Update(dt); // Iterate through systems and update world! m_EventBroker->Process(); diff --git a/src/Game/Systems/SoundSystem.cpp b/src/Game/Systems/SoundSystem.cpp new file mode 100644 index 00000000..d51996ac --- /dev/null +++ b/src/Game/Systems/SoundSystem.cpp @@ -0,0 +1,73 @@ +#include "Game/Systems/SoundSystem.h" + +SoundSystem::SoundSystem(World* world, EventBroker* eventbroker) + : System(world, eventbroker) + , PureSystem("SoundEmitter") + , ImpureSystem() + , SoundManager(world, eventbroker, true) +{ + m_World = world; + m_EventBroker = eventbroker; + EVENT_SUBSCRIBE_MEMBER(m_EPlayerSpawned, &SoundSystem::OnPlayerSpawned); +} + +void SoundSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) +{ + +} + +void SoundSystem::Update(double dt) +{ + SoundManager::Update(dt); + playerStep(dt); +} + +void SoundSystem::playerStep(double dt) +{ + if (!m_LocalPlayer.Valid()) { + return; + } + if (m_LocalPlayer.ID == EntityID_Invalid) { + return; + } + + m_TimeSinceLastFootstep += dt; + glm::vec3 vel = (glm::vec3)m_World->GetComponent(m_LocalPlayer.ID, "Physics")["Velocity"]; + float playerSpeed = glm::length(vel); + bool isAirborne = vel.y != 0; + if (playerSpeed > 1 && !isAirborne) { + // Player is walking + if (m_TimeSinceLastFootstep * std::min(playerSpeed, 2) > m_PlayerFootstepInterval) { + // Create footstep sound + Events::PlaySoundOnEntity e; + e.EmitterID = createChildEmitter(); + if (m_LeftFoot) { + e.FilePath = "Audio/footstep/footstep2.wav"; + } else { + e.FilePath = "Audio/footstep/footstep3.wav"; + } + m_LeftFoot = !m_LeftFoot; + m_EventBroker->Publish(e); + m_TimeSinceLastFootstep = 0; + } + } +} + +bool SoundSystem::OnPlayerSpawned(const Events::PlayerSpawned &e) +{ + if (e.PlayerID == -1) { // Local player + m_World->AttachComponent(e.Player.ID, "Listener"); + m_LocalPlayer = e.Player; + Events::PlaySoundOnEntity event; + event.EmitterID = createChildEmitter(); + event.FilePath = "Audio/announcer/go.wav"; + m_EventBroker->Publish(event); + // TEMP: starts bgm +// { +// Events::PlayBackgroundMusic ev; +// ev.FilePath = "Audio/bgm/ambient.wav"; +// m_EventBroker->Publish(ev); +// } + } + return true; +}