Merge branch 'FMOD'
Conflicts: src/GameWorld.cpp src/Renderer.cpp src/Systems/PhysicsSystem.cpp src/Systems/PhysicsSystem.h src/Systems/SoundSystem.cpp src/Systems/SoundSystem.h vs11/Returngeance/Returngeance.vcxproj vs11/Returngeance/Returngeance.vcxproj.filters
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
#ifndef Components_Listener_h__
|
||||
#define Components_Listener_h__
|
||||
|
||||
#include <string>
|
||||
#include <glm/common.hpp>
|
||||
#include "Component.h"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
|
||||
struct Listener : Component
|
||||
{
|
||||
Listener() {}
|
||||
|
||||
virtual Listener* Clone() const override { return new Listener(*this); }
|
||||
};
|
||||
|
||||
}
|
||||
#endif // !Components_Listener_h__
|
||||
@@ -7,16 +7,23 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
|
||||
|
||||
struct SoundEmitter : Component
|
||||
{
|
||||
SoundEmitter() : Gain(1.f), MaxDistance(1.f), ReferenceDistance(1.f), Pitch(1.f), Loop(false) {}
|
||||
enum class SoundType
|
||||
{
|
||||
SOUND_3D,
|
||||
SOUND_2D
|
||||
};
|
||||
|
||||
SoundEmitter() : Gain(1.f), MaxDistance(1.f), MinDistance(1.f), Pitch(1.f), Loop(false) {}
|
||||
float Gain;
|
||||
float MaxDistance;
|
||||
float ReferenceDistance;
|
||||
float MinDistance;
|
||||
float Pitch;
|
||||
bool Loop;
|
||||
std::string Path;
|
||||
SoundType type;
|
||||
|
||||
virtual SoundEmitter* Clone() const override { return new SoundEmitter(*this); }
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef Event_ComponentCreated_h__
|
||||
#define Event_ComponentCreated_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "Entity.h"
|
||||
#include "Component.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct ComponentCreated : Event
|
||||
{
|
||||
EntityID Entity;
|
||||
std::shared_ptr<::Component> Component;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // Event_ComponentCreated_h__
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef Event_PlayBGM_h__
|
||||
#define Event_PlayBGM_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct PlayBGM : Event
|
||||
{
|
||||
std::string Resource;
|
||||
bool Loop;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // Event_PlayBGM_h__
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef Event_PlaySFX_h__
|
||||
#define Event_PlaySFX_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct PlaySFX : Event
|
||||
{
|
||||
EntityID Emitter;
|
||||
std::string Resource;
|
||||
bool Loop;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // Event_PlaySFX_h__
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef Event_PlaySound_h__
|
||||
#define Event_PlaySound_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct PlaySound : Event
|
||||
{
|
||||
EntityID Emitter;
|
||||
std::string Resource;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // Event_PlaySound_h__
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef Event_StopSound_h__
|
||||
#define Event_StopSound_h__
|
||||
|
||||
#include "EventBroker.h"
|
||||
#include "Entity.h"
|
||||
|
||||
namespace Events
|
||||
{
|
||||
|
||||
struct StopSound : Event
|
||||
{
|
||||
EntityID Emitter;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // Event_StopSound_h__
|
||||
+13
-89
@@ -1,96 +1,20 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Sound.h"
|
||||
|
||||
Sound::Sound(std::string path)
|
||||
|
||||
Sound::Sound(std::string path, FMOD_SYSTEM* system, Components::SoundEmitter::SoundType type)
|
||||
{
|
||||
m_Buffer = 0;
|
||||
m_Buffer = LoadFile(path);
|
||||
if(type == Components::SoundEmitter::SoundType::SOUND_2D)
|
||||
{
|
||||
FMOD_System_CreateSound(system, path.c_str(), FMOD_2D, NULL, &m_Sound);
|
||||
}
|
||||
if(type == Components::SoundEmitter::SoundType::SOUND_3D)
|
||||
{
|
||||
FMOD_System_CreateSound(system, path.c_str(), FMOD_3D, NULL, &m_Sound);
|
||||
}
|
||||
}
|
||||
|
||||
ALuint Sound::LoadFile(std::string path)
|
||||
Sound::~Sound()
|
||||
{
|
||||
char type[4];
|
||||
unsigned long size, chunkSize;
|
||||
short formatType, channels;
|
||||
unsigned long sampleRate, avgBytesPerSec;
|
||||
short bytesPerSample, bitsPerSample;
|
||||
unsigned long dataSize;
|
||||
|
||||
FILE* fp = NULL;
|
||||
fp = fopen(path.c_str(), "rb");
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
LOG_ERROR("Failed to load sound file \"%s\"", path.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
//CHECK FOR VALID WAVE-FILE
|
||||
fread(type, sizeof(char), 4, fp);
|
||||
if (type[0] != 'R' || type[1] != 'I' || type[2] != 'F' || type[3] != 'F')
|
||||
{
|
||||
LOG_ERROR("ERROR: No RIFF in WAVE-file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread(&size, sizeof(unsigned long), 1, fp);
|
||||
fread(type, sizeof(char), 4, fp);
|
||||
if (type[0] != 'W' || type[1] != 'A' || type[2] != 'V' || type[3] != 'E')
|
||||
{
|
||||
LOG_ERROR("ERROR: Not WAVE-file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread(type, sizeof(char), 4, fp);
|
||||
if (type[0] != 'f' || type[1] != 'm' || type[2] != 't' || type[3] != ' ')
|
||||
{
|
||||
LOG_ERROR("ERROR: No fmt in WAVE-file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//READ THE DATA FROM WAVE-FILE
|
||||
fread(&chunkSize, sizeof(unsigned long), 1, fp);
|
||||
fread(&formatType, sizeof(short), 1, fp);
|
||||
fread(&channels, sizeof(short), 1, fp);
|
||||
fread(&sampleRate, sizeof(unsigned long), 1, fp);
|
||||
fread(&avgBytesPerSec, sizeof(unsigned long), 1, fp);
|
||||
fread(&bytesPerSample, sizeof(short), 1, fp);
|
||||
fread(&bitsPerSample, sizeof(short), 1, fp);
|
||||
|
||||
fread(type, sizeof(char), 4, fp);
|
||||
if (type[0] != 'd' || type[1] != 'a' || type[2] != 't' || type[3] != 'a')
|
||||
{
|
||||
LOG_ERROR("ERROR: WAVE-file Missing data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fread(&dataSize, sizeof(unsigned long), 1, fp);
|
||||
|
||||
unsigned char* buf = new unsigned char[dataSize];
|
||||
fread(buf, sizeof(unsigned char), dataSize, fp);
|
||||
fclose(fp);
|
||||
|
||||
// Create buffer
|
||||
ALuint format = 0;
|
||||
if (bitsPerSample == 8)
|
||||
{
|
||||
if (channels == 1)
|
||||
format = AL_FORMAT_MONO8;
|
||||
else if (channels == 2)
|
||||
format = AL_FORMAT_STEREO8;
|
||||
}
|
||||
if (bitsPerSample == 16)
|
||||
{
|
||||
if (channels == 1)
|
||||
format = AL_FORMAT_MONO16;
|
||||
else if (channels == 2)
|
||||
format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer);
|
||||
alBufferData(buffer, format, buf, dataSize, sampleRate);
|
||||
delete[] buf;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
FMOD_Sound_Release(m_Sound);
|
||||
}
|
||||
+7
-8
@@ -1,22 +1,21 @@
|
||||
#ifndef Sound_h__
|
||||
#define Sound_h__
|
||||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
|
||||
#include "ResourceManager.h"
|
||||
#include <fmod.h>
|
||||
#include <fmod_errors.h>
|
||||
#include <Components/SoundEmitter.h>
|
||||
|
||||
class Sound : public Resource
|
||||
{
|
||||
public:
|
||||
Sound(std::string path);
|
||||
Sound(std::string path, FMOD_SYSTEM* system, Components::SoundEmitter::SoundType type);
|
||||
~Sound();
|
||||
|
||||
ALuint LoadFile(std::string path);
|
||||
|
||||
operator ALuint() const { return m_Buffer; }
|
||||
operator FMOD_SOUND*() const { return m_Sound; }
|
||||
|
||||
private:
|
||||
ALuint m_Buffer;
|
||||
FMOD_SOUND* m_Sound;
|
||||
};
|
||||
|
||||
#endif // Sound_h__
|
||||
|
||||
@@ -29,8 +29,6 @@ public:
|
||||
// Called once for every entity in the world every tick
|
||||
virtual void UpdateEntity(double dt, EntityID entity, EntityID parent) { }
|
||||
|
||||
// Called when a component is created
|
||||
virtual void OnComponentCreated(std::string type, std::shared_ptr<Component> component) { }
|
||||
// Called when a component is removed
|
||||
virtual void OnComponentRemoved(EntityID entity, std::string type, Component* component) { }
|
||||
// Called when components are committed to an entity
|
||||
|
||||
@@ -19,10 +19,10 @@ bool Systems::DebugSystem::OnKeyDown(const Events::KeyDown &event)
|
||||
{
|
||||
if (event.KeyCode == GLFW_KEY_ENTER)
|
||||
{
|
||||
Events::PlaySound e;
|
||||
Events::PlaySFX e;
|
||||
e.Emitter = 0;
|
||||
e.Resource = "Sounds/korvring.wav";
|
||||
EventBroker->Publish<Events::PlaySound>(e);
|
||||
EventBroker->Publish<Events::PlaySFX>(e);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "System.h"
|
||||
#include "Components/Transform.h"
|
||||
#include "Events/KeyDown.h"
|
||||
#include "Events/PlaySound.h"
|
||||
#include "Events/PlaySFX.h"
|
||||
|
||||
namespace Systems
|
||||
{
|
||||
|
||||
@@ -159,7 +159,7 @@ bool Systems::InputSystem::OnBindKey(const Events::BindKey &event)
|
||||
else
|
||||
{
|
||||
m_KeyBindings[event.KeyCode] = std::make_tuple(event.Command, event.Value);
|
||||
LOG_DEBUG("Input: Bound key %c to %s", (char)event.KeyCode, event.Command.c_str());
|
||||
LOG_DEBUG("Input: Bound key %i:%c to %s", event.KeyCode, (char)event.KeyCode, event.Command.c_str());
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -673,11 +673,6 @@ void Systems::PhysicsSystem::TearDownPhysicsState(EntityID entity, EntityID pare
|
||||
|
||||
}
|
||||
|
||||
void Systems::PhysicsSystem::OnComponentCreated(std::string type, std::shared_ptr<Component> component)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Systems::PhysicsSystem::SetupVisualDebugger(hkpPhysicsContext* worlds)
|
||||
{
|
||||
// Setup the visual debugger
|
||||
|
||||
@@ -165,7 +165,6 @@ public:
|
||||
|
||||
void Update(double dt) override;
|
||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
||||
void OnComponentCreated(std::string type, std::shared_ptr<Component> component) override;
|
||||
void OnComponentRemoved(EntityID entity, std::string type, Component* component) override;
|
||||
void OnEntityCommit(EntityID entity) override;
|
||||
void OnEntityRemoved(EntityID entity) override;
|
||||
|
||||
+157
-111
@@ -4,157 +4,203 @@
|
||||
|
||||
void Systems::SoundSystem::Initialize()
|
||||
{
|
||||
//initialize OpenAL
|
||||
ALCdevice* Device = alcOpenDevice(NULL);
|
||||
ALCcontext* context;
|
||||
if(Device)
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EComponentCreated, &SoundSystem::OnComponentCreated);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::PlaySFX);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EPlayBGM, &SoundSystem::PlayBGM);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::StopSound);
|
||||
|
||||
m_TransformSystem = m_World->GetSystem<Systems::TransformSystem>();
|
||||
FMOD_System_Create(&m_System);
|
||||
FMOD_RESULT result = FMOD_System_Init(m_System, 32, FMOD_INIT_3D_RIGHTHANDED, 0);
|
||||
if(result != FMOD_OK)
|
||||
{
|
||||
context = alcCreateContext(Device, NULL);
|
||||
alcMakeContextCurrent(context);
|
||||
LOG_ERROR("Did initialized load FMOD correctly");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("OMG OPEN AL FAIL");
|
||||
LOG_INFO("FMOD initialized successfully");
|
||||
}
|
||||
|
||||
alGetError();
|
||||
|
||||
alSpeedOfSound(340.29f); // Speed of sound
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
|
||||
// Subscribe to events
|
||||
m_EPlaySound = decltype(m_EPlaySound)(std::bind(&Systems::SoundSystem::OnPlaySound, this, std::placeholders::_1));
|
||||
EventBroker->Subscribe(m_EPlaySound);
|
||||
FMOD_System_Set3DSettings(m_System, 1.f, 1.f, 1.f); //dopplerScale, distancefactor, rolloffscale
|
||||
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::RegisterComponents(ComponentFactory* cf)
|
||||
{
|
||||
cf->Register<Components::SoundEmitter>([]() { return new Components::SoundEmitter(); });
|
||||
cf->Register<Components::Listener>([]() { return new Components::Listener(); });
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::RegisterResourceTypes(std::shared_ptr<::ResourceManager> rm)
|
||||
{
|
||||
rm->RegisterType("Sound", [](std::string resourceName) { return new Sound(resourceName); });
|
||||
rm->RegisterType("Sound3D", [this](std::string resourceName) { return new Sound(resourceName, this->m_System, Components::SoundEmitter::SoundType::SOUND_3D); });
|
||||
rm->RegisterType("Sound2D", [this](std::string resourceName) { return new Sound(resourceName, this->m_System, Components::SoundEmitter::SoundType::SOUND_2D); });
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::Update(double dt)
|
||||
{
|
||||
FMOD_System_Update(m_System);
|
||||
|
||||
//Delete sounds. Not until it's done playing
|
||||
std::map<EntityID, FMOD_CHANNEL*>::iterator it;
|
||||
for(it = m_DeleteChannels.begin(); it != m_DeleteChannels.end();)
|
||||
{
|
||||
FMOD_BOOL *isPlaying = false;
|
||||
FMOD_Channel_IsPlaying(it->second, isPlaying);
|
||||
if(isPlaying)
|
||||
{
|
||||
it++;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMOD_Sound_Release(m_DeleteSounds[it->first]);
|
||||
m_DeleteSounds.erase(it->first);
|
||||
it = m_DeleteChannels.erase(it);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::UpdateEntity(double dt, EntityID entity, EntityID parent)
|
||||
{
|
||||
auto transformComponent = m_World->GetComponent<Components::Transform>(entity);
|
||||
if (transformComponent == nullptr)
|
||||
return;
|
||||
|
||||
auto entityName = m_World->GetProperty<std::string>(entity, "Name");
|
||||
if (entityName == "Camera")
|
||||
auto listener = m_World->GetComponent<Components::Listener>(entity);
|
||||
if(listener)
|
||||
{
|
||||
glm::vec3 playerPos = transformComponent->Position;
|
||||
ALfloat listenerPos[3] = { playerPos.x, playerPos.y, -playerPos.z };
|
||||
int lID = std::find(m_Listeners.begin(), m_Listeners.end(), entity) - m_Listeners.begin();
|
||||
auto lTransform = m_World->GetComponent<Components::Transform>(entity);
|
||||
|
||||
glm::vec3 tPos = m_TransformSystem->AbsolutePosition(entity);
|
||||
FMOD_VECTOR lPos = {tPos.x, tPos.y, tPos.z};
|
||||
|
||||
glm::vec3 playerVel = transformComponent->Velocity;
|
||||
ALfloat listenerVel[3] = { playerVel.x, playerVel.y, -playerVel.z };
|
||||
glm::vec3 tVel = (lTransform->Velocity * 1000.f) / (float)dt;
|
||||
FMOD_VECTOR lVel = {tVel.x, tVel.y, tVel.z};
|
||||
|
||||
glm::fquat playerQuatOri = transformComponent->Orientation;
|
||||
glm::vec3 playerOriFW = glm::rotate(playerQuatOri, glm::vec3(0, 0, -1));
|
||||
glm::vec3 playerOriUP = glm::rotate(playerQuatOri, glm::vec3(0, 1, 0));
|
||||
ALfloat listenerOri[6] = { playerOriFW.x, playerOriFW.y, playerOriFW.z, playerOriUP.x, playerOriUP.y, playerOriUP.z };
|
||||
glm::vec3 tUp = glm::normalize(lTransform->Orientation * glm::vec3(0,1,0));
|
||||
FMOD_VECTOR lUp = {tUp.x, tUp.y, tUp.z};
|
||||
glm::vec3 tForward = glm::normalize(lTransform->Orientation * glm::vec3(0,0,-1));
|
||||
FMOD_VECTOR lForward = {tForward.x, tForward.y, tForward.z};
|
||||
|
||||
//Listener
|
||||
alListenerfv(AL_POSITION, listenerPos);
|
||||
alListenerfv(AL_VELOCITY, listenerVel);
|
||||
alListenerfv(AL_ORIENTATION, listenerOri);
|
||||
FMOD_System_Set3DListenerAttributes(m_System, lID, (const FMOD_VECTOR*)&lPos, (const FMOD_VECTOR*)&lVel, (const FMOD_VECTOR*)&lForward, (const FMOD_VECTOR*)&lUp);
|
||||
}
|
||||
|
||||
auto soundEmitter = m_World->GetComponent<Components::SoundEmitter>(entity);
|
||||
if(soundEmitter != nullptr)
|
||||
auto emitter = m_World->GetComponent<Components::SoundEmitter>(entity);
|
||||
if(emitter)
|
||||
{
|
||||
ALuint source = m_Sources[soundEmitter];
|
||||
alSourcef(source, AL_GAIN, soundEmitter->Gain);
|
||||
//alSourcef(source, AL_MAX_DISTANCE, soundEmitter->MaxDistance);
|
||||
alSourcef(source, AL_REFERENCE_DISTANCE, soundEmitter->ReferenceDistance);
|
||||
alSourcef(source, AL_PITCH, soundEmitter->Pitch);
|
||||
alSourcei(source, AL_LOOPING, soundEmitter->Loop);
|
||||
FMOD_CHANNEL* channel = m_Channels[entity];
|
||||
FMOD_SOUND* sound = m_Sounds[entity];
|
||||
auto eTransform = m_World->GetComponent<Components::Transform>(entity);
|
||||
|
||||
glm::vec3 tPos = m_TransformSystem->AbsolutePosition(entity);
|
||||
FMOD_VECTOR ePos = {tPos.x, tPos.y, tPos.z};
|
||||
|
||||
glm::vec3 emitterPos = transformComponent->Position;
|
||||
ALfloat sourcePos[3] = { emitterPos.x, emitterPos.y, -emitterPos.z };
|
||||
|
||||
glm::vec3 emitterVel= transformComponent->Velocity;
|
||||
ALfloat sourceVel[3] = { emitterVel.x, emitterVel.y, -emitterVel.z };
|
||||
|
||||
alSourcefv(source, AL_POSITION, sourcePos);
|
||||
alSourcefv(source, AL_VELOCITY, sourceVel);
|
||||
glm::vec3 tVel = (eTransform->Velocity * 1000.f) / float(dt);
|
||||
FMOD_VECTOR eVel = {tVel.x, tVel.y, tVel.z};
|
||||
|
||||
FMOD_Channel_Set3DAttributes(channel, &ePos, &eVel);
|
||||
}
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::PlaySound(Components::SoundEmitter* emitter, std::string fileName)
|
||||
bool Systems::SoundSystem::OnComponentCreated(const Events::ComponentCreated &event)
|
||||
{
|
||||
if (m_Sources.find(emitter) == m_Sources.end())
|
||||
return;
|
||||
|
||||
ALuint buffer = *ResourceManager->Load<Sound>("Sound", fileName);
|
||||
if (buffer == 0)
|
||||
return;
|
||||
ALuint source = m_Sources[emitter];
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
alSourcePlay(m_Sources[emitter]);
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::PlaySound(std::shared_ptr<Components::SoundEmitter> emitter)
|
||||
{
|
||||
ALuint buffer = *ResourceManager->Load<Sound>("Sound", emitter->Path);
|
||||
ALuint source = m_Sources[emitter.get()];
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
alSourcePlay(m_Sources[emitter.get()]);
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::StopSound(std::shared_ptr<Components::SoundEmitter> emitter)
|
||||
{
|
||||
alSourceStop(m_Sources[emitter.get()]);
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::OnComponentCreated(std::string type, std::shared_ptr<Component> component)
|
||||
{
|
||||
if(type == "SoundEmitter")
|
||||
auto listener = std::dynamic_pointer_cast<Components::Listener>(event.Component);
|
||||
if(listener)
|
||||
{
|
||||
ALuint source = CreateSource();
|
||||
m_Sources[component.get()] = source;
|
||||
m_Listeners.push_back(listener->Entity);
|
||||
}
|
||||
|
||||
auto emitter = std::dynamic_pointer_cast<Components::SoundEmitter>(event.Component);
|
||||
if(emitter)
|
||||
{
|
||||
FMOD_CHANNEL* channel;
|
||||
FMOD_SOUND* sound;
|
||||
|
||||
std::string path = emitter->Path;
|
||||
float volume = emitter->Gain;
|
||||
bool loop = emitter->Loop;
|
||||
float maxDist = emitter->MaxDistance;
|
||||
float minDist = emitter->MinDistance;
|
||||
float pitch = emitter->Pitch;
|
||||
//LoadSound(sound, path, maxDist, minDist);
|
||||
m_Channels.insert(std::make_pair(emitter->Entity, channel));
|
||||
m_Sounds.insert(std::make_pair(emitter->Entity, sound));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Systems::SoundSystem::PlaySFX(const Events::PlaySFX &event)
|
||||
{
|
||||
auto emitter = m_World->GetComponent<Components::SoundEmitter>(event.Emitter);
|
||||
if(!emitter)
|
||||
{
|
||||
LOG_ERROR("FMOD: The Entity %i does not have a SoundEmitter-component, but is trying to play a sound", event.Emitter);FMOD_CHANNEL* channel = m_Channels[event.Emitter];
|
||||
return false;
|
||||
}
|
||||
|
||||
emitter->type = Components::SoundEmitter::SoundType::SOUND_3D;
|
||||
Sound* sound = ResourceManager->Load<Sound>("Sound3D", event.Resource);
|
||||
m_Sounds[event.Emitter] = *sound;
|
||||
FMOD_Sound_Set3DMinMaxDistance(*sound, emitter->MinDistance, emitter->MaxDistance);
|
||||
|
||||
PlaySound(&m_Channels[event.Emitter], m_Sounds[event.Emitter], 1.0, event.Loop);
|
||||
FMOD_System_Update(m_System);
|
||||
|
||||
FMOD_BOOL isPlaying = false;
|
||||
FMOD_Channel_IsPlaying(m_Channels[event.Emitter], &isPlaying);
|
||||
if(!isPlaying)
|
||||
LOG_ERROR("FMOD: File %s is not playing", event.Resource.c_str());
|
||||
else
|
||||
LOG_INFO("Now playing sound %s", event.Resource.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Systems::SoundSystem::PlayBGM(const Events::PlayBGM &event)
|
||||
{
|
||||
auto emitter = m_World->CreateEntity();
|
||||
auto eTransform = m_World->AddComponent<Components::Transform>(emitter);
|
||||
auto eComponent = m_World->AddComponent<Components::SoundEmitter>(emitter);
|
||||
m_Channels[emitter] = m_BGMChannel;
|
||||
eComponent->type = Components::SoundEmitter::SoundType::SOUND_3D;
|
||||
Sound* sound = ResourceManager->Load<Sound>("Sound2D", event.Resource);
|
||||
m_Sounds[emitter] = *sound;
|
||||
|
||||
FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, *sound, false, &m_Channels[emitter]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Systems::SoundSystem::StopSound(const Events::StopSound &event)
|
||||
{
|
||||
FMOD_Channel_Stop(m_Channels[event.Emitter]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::LoadSound(FMOD_SOUND* &sound, std::string filePath, float maxDist, float minDist)
|
||||
{
|
||||
FMOD_RESULT result = FMOD_System_CreateSound(m_System, filePath.c_str(), FMOD_3D | FMOD_HARDWARE , 0, &sound);
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
LOG_ERROR("FMOD did not load file: %s", filePath.c_str());
|
||||
}
|
||||
FMOD_Sound_Set3DMinMaxDistance(sound, minDist, maxDist);
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::PlaySound(FMOD_CHANNEL** channel, FMOD_SOUND* sound, float volume, bool loop)
|
||||
{
|
||||
FMOD_System_PlaySound(m_System, FMOD_CHANNEL_FREE, sound, false, channel);
|
||||
FMOD_Channel_SetVolume(*channel, volume);
|
||||
if(loop)
|
||||
{
|
||||
FMOD_Channel_SetMode(*channel, FMOD_LOOP_NORMAL);
|
||||
FMOD_Sound_SetLoopCount(sound, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void Systems::SoundSystem::OnComponentRemoved(EntityID entity, std::string type, Component* component)
|
||||
{
|
||||
if(type == "SoundEmitter")
|
||||
auto emitter = dynamic_cast<Components::SoundEmitter*>(component);
|
||||
if(emitter)
|
||||
{
|
||||
if (m_Sources.find(component) != m_Sources.end())
|
||||
{
|
||||
ALuint source = m_Sources[component];
|
||||
alDeleteSources(1, &source);
|
||||
}
|
||||
m_DeleteChannels.insert(std::make_pair(entity, m_Channels[entity]));
|
||||
m_DeleteSounds.insert(std::make_pair(entity, m_Sounds[entity]));
|
||||
m_Channels.erase(entity);
|
||||
m_Sounds.erase(entity);
|
||||
}
|
||||
}
|
||||
|
||||
ALuint Systems::SoundSystem::CreateSource()
|
||||
{
|
||||
ALuint source;
|
||||
alGenSources((ALuint)1, &source);
|
||||
|
||||
alDopplerFactor(1); // Numbers greater than 1 will increase Doppler effect, numbers lower than 1 will decrease the Doppler effect
|
||||
alDopplerVelocity(350.f); // Defines the velocity of the sound
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
bool Systems::SoundSystem::OnPlaySound(const Events::PlaySound &event)
|
||||
{
|
||||
LOG_DEBUG("Events::PlaySound.Resource = %s", event.Resource.c_str());
|
||||
|
||||
ALuint buffer = *ResourceManager->Load<Sound>("Sound", event.Resource);
|
||||
ALuint source = m_Sources.begin()->second;
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
alSourcePlay(source);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+30
-24
@@ -1,13 +1,18 @@
|
||||
#ifndef SoundEmitter_h__
|
||||
#define SoundEmitter_h__
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <fmod.hpp>
|
||||
#include <fmod_errors.h>
|
||||
#include <vector>
|
||||
|
||||
#include "System.h"
|
||||
#include "Systems/TransformSystem.h"
|
||||
#include "Components/Transform.h"
|
||||
#include "Components/SoundEmitter.h"
|
||||
#include "Events/PlaySound.h"
|
||||
#include "Components/Listener.h"
|
||||
#include "Events/ComponentCreated.h"
|
||||
#include "Events/PlaySFX.h"
|
||||
#include "Events/PlayBGM.h"
|
||||
#include "Events/StopSound.h"
|
||||
#include "Sound.h"
|
||||
|
||||
namespace Systems
|
||||
@@ -23,33 +28,34 @@ public:
|
||||
void RegisterComponents(ComponentFactory* cf) override;
|
||||
void RegisterResourceTypes(std::shared_ptr<::ResourceManager> rm) override;
|
||||
void Initialize() override;
|
||||
|
||||
void Update(double dt) override;
|
||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
||||
void OnComponentCreated(std::string type, std::shared_ptr<Component> component) override;
|
||||
//void OnComponentRemoved(std::string type, Component* component);
|
||||
void OnComponentRemoved(EntityID entity, std::string type, Component* component) override;
|
||||
void PlaySound(Components::SoundEmitter* emitter, std::string path); // Use if you want to play a temporary .wav file not from component
|
||||
void PlaySound(std::shared_ptr<Components::SoundEmitter> emitter); // Use if you want to play .wav file from component // imon no hate plx T.T
|
||||
void StopSound(std::shared_ptr<Components::SoundEmitter> emitter);
|
||||
|
||||
FMOD_SYSTEM* GetFMODSystem() const { return m_System; }
|
||||
private:
|
||||
ALuint LoadFile(std::string fileName);
|
||||
ALuint CreateSource();
|
||||
|
||||
//File-info
|
||||
//char type[4];
|
||||
//unsigned long size, chunkSize;
|
||||
//short formatType, channels;
|
||||
//unsigned long sampleRate, avgBytesPerSec;
|
||||
//short bytesPerSample, bitsPerSample;
|
||||
//unsigned long dataSize;
|
||||
|
||||
// Events
|
||||
EventRelay<SoundSystem, Events::PlaySound> m_EPlaySound;
|
||||
bool OnPlaySound(const Events::PlaySound &event);
|
||||
EventRelay<SoundSystem, Events::ComponentCreated> m_EComponentCreated;
|
||||
bool OnComponentCreated(const Events::ComponentCreated &event);
|
||||
EventRelay<SoundSystem, Events::PlaySFX> m_EPlaySFX;
|
||||
bool PlaySFX(const Events::PlaySFX &event);
|
||||
EventRelay<SoundSystem, Events::PlayBGM> m_EPlayBGM;
|
||||
bool PlayBGM(const Events::PlayBGM &event);
|
||||
EventRelay<SoundSystem, Events::StopSound> m_EStopSound;
|
||||
bool StopSound(const Events::StopSound &event);
|
||||
|
||||
std::map<Component*, ALuint> m_Sources;
|
||||
std::map<std::string, ALuint> m_BufferCache; // string = fileName
|
||||
void LoadSound(FMOD_SOUND*&, std::string, float, float);
|
||||
void PlaySound(FMOD_CHANNEL**, FMOD_SOUND*, float volume, bool loop);
|
||||
|
||||
FMOD_SYSTEM* m_System;
|
||||
FMOD_CHANNEL* m_BGMChannel;
|
||||
std::vector<EntityID> m_Listeners;
|
||||
std::map<EntityID, FMOD_CHANNEL*> m_Channels;
|
||||
std::map<EntityID, FMOD_CHANNEL*> m_DeleteChannels;
|
||||
std::map<EntityID, FMOD_SOUND*> m_Sounds;
|
||||
std::map<EntityID, FMOD_SOUND*> m_DeleteSounds;
|
||||
std::shared_ptr<Systems::TransformSystem> m_TransformSystem;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -26,10 +26,6 @@ void Systems::TriggerSystem::UpdateEntity( double dt, EntityID entity, EntityID
|
||||
|
||||
}
|
||||
|
||||
void Systems::TriggerSystem::OnComponentCreated( std::string type, std::shared_ptr<Component> component )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Systems::TriggerSystem::OnComponentRemoved(EntityID entity, std::string type, Component* component )
|
||||
{
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Systems
|
||||
void RegisterComponents(ComponentFactory* cf) override;
|
||||
void Update(double dt) override;
|
||||
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
|
||||
void OnComponentCreated(std::string type, std::shared_ptr<Component> component) override;
|
||||
//void OnComponentCreated(std::string type, std::shared_ptr<Component> component) override;
|
||||
void OnComponentRemoved(EntityID entity, std::string type, Component* component) override;
|
||||
void OnEntityCommit(EntityID entity) override;
|
||||
void OnEntityRemoved(EntityID entity) override;
|
||||
|
||||
+5
-5
@@ -155,11 +155,11 @@ void World::AddComponent(EntityID entity, std::string componentType, std::shared
|
||||
component->Entity = entity;
|
||||
m_ComponentsOfType[componentType].push_back(component);
|
||||
m_EntityComponents[entity][componentType] = component;
|
||||
for (auto pair : m_Systems)
|
||||
{
|
||||
auto system = pair.second;
|
||||
system->OnComponentCreated(componentType, component);
|
||||
}
|
||||
|
||||
Events::ComponentCreated e;
|
||||
e.Entity = entity;
|
||||
e.Component = component;
|
||||
EventBroker->Publish(e);
|
||||
}
|
||||
|
||||
EntityID World::CloneEntity(EntityID entity, EntityID parent /* = 0 */)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "Components/Template.h"
|
||||
#include "System.h"
|
||||
#include "EventBroker.h"
|
||||
#include "Events/ComponentCreated.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
class World
|
||||
|
||||
Reference in New Issue
Block a user