Musique de fond (#44)
All checks were successful
Linux arm64 / Build (push) Successful in 5m30s

Fix #7

Reviewed-on: #44
Co-authored-by: Persson-dev <sim16.prib@gmail.com>
Co-committed-by: Persson-dev <sim16.prib@gmail.com>
This commit was merged in pull request #44.
This commit is contained in:
2024-04-11 16:59:07 +02:00
committed by Simon Pribylski
parent 747fa13d3a
commit 07d09332dd
19 changed files with 414 additions and 5 deletions

BIN
assets/sessionD.wav Normal file

Binary file not shown.

View File

@@ -158,6 +158,14 @@ class DataBuffer {
return m_Buffer.data();
}
std::vector<std::uint8_t>& GetVector() {
return m_Buffer;
}
const std::vector<std::uint8_t>& GetVector() const {
return m_Buffer;
}
std::size_t GetReadOffset() const {
return m_ReadOffset;
}

View File

@@ -28,6 +28,8 @@ class ClientListener {
virtual void OnSpectatorChange(game::PlayerID player) {}
virtual void OnPlayerShoot(PlayerID player, const Vec3f& position, float yaw, float pitch) {}
virtual void OnGameConfigUpdate() {}
virtual void OnGameJoin() {}
virtual void OnGameLeave() {}
};
} // namespace game

View File

@@ -0,0 +1,25 @@
#pragma once
#include "blitz/common/DataBuffer.h"
#include "blitz/common/NonCopyable.h"
#include "blitz/maths/Vector.h"
#include "client/audio/AudioLoader.h"
namespace blitz {
namespace audio {
class AudioBuffer : private NonCopyable {
private:
unsigned int m_ID;
public:
AudioBuffer(AudioData&& audioData);
~AudioBuffer();
unsigned int GetID() const {
return m_ID;
}
};
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,21 @@
#pragma once
#include "blitz/common/NonCopyable.h"
#include "blitz/maths/Vector.h"
namespace blitz {
namespace audio {
class AudioListener : private NonCopyable {
public:
AudioListener();
~AudioListener();
void SetGain(float a_Gain);
void SetPosition(const Vec3f& a_Position);
void SetVelocity(const Vec3f& a_Velocity);
void SetOrientation(const Vec3f& a_Orientation, const Vec3f& a_Up);
};
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,24 @@
#pragma once
#include "blitz/common/DataBuffer.h"
namespace blitz {
namespace audio {
enum AudioFormat { afMono8 = 0, afMono16, afStereo8, afStereo16 };
struct AudioData {
DataBuffer m_Buffer;
AudioFormat m_Format;
std::uint32_t m_Frequency;
};
namespace AudioLoader {
// files should be 8 or 16 bits wav
AudioData LoadAudioFile(const std::string& filePath);
}; // namespace AudioLoader
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,33 @@
#pragma once
#include "blitz/game/Listeners.h"
#include "client/audio/AudioListener.h"
#include "client/audio/AudioSource.h"
namespace blitz {
class Client;
namespace audio {
class AudioManager : public game::ClientListener {
private:
Client* m_Client;
AudioListener m_Listener;
AudioSourcePtr m_MenuMusic;
std::vector<AudioSourcePtr> m_Sources;
public:
AudioManager(Client* client);
~AudioManager();
virtual void OnGameJoin() override;
virtual void OnGameLeave() override;
private:
void InitMainMenuMusic();
};
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,42 @@
#pragma once
#include "blitz/common/NonCopyable.h"
#include "blitz/maths/Vector.h"
#include "client/audio/AudioBuffer.h"
#include <memory>
namespace blitz {
namespace audio {
typedef std::unique_ptr<AudioBuffer> AudioBufferPtr;
class AudioSource : NonCopyable {
private:
unsigned int m_ID;
AudioBufferPtr m_Buffer;
public:
enum SourceState { ssInitial = 0, ssPlaying, ssPaused, ssStopped };
AudioSource();
~AudioSource();
void SetGain(float a_Gain);
void SetPitch(float a_Pitch);
void SetPosition(const Vec3f& a_Position);
void SetDirection(const Vec3f& a_Direction);
void SetVelocity(const Vec3f& a_Velocity);
void SetLooping(bool a_Looping);
void SetBuffer(AudioBufferPtr&& a_Buffer);
SourceState GetSourceState() const;
void Play();
void Pause();
void Stop();
};
typedef std::unique_ptr<AudioSource> AudioSourcePtr;
} // namespace audio
} // namespace blitz

View File

@@ -1,5 +1,6 @@
#include "blitz/network/Network.h"
#include "client/Client.h"
#include "client/audio/AudioManager.h"
#include "client/display/Display.h"
#include "client/render/MainRenderer.h"
@@ -12,6 +13,7 @@ int main(int argc, char** argv) {
return EXIT_FAILURE;
blitz::render::MainRenderer renderer(&client);
blitz::audio::AudioManager audioManager(&client);
blitz::network::NetworkInitializer network;
while (!display.IsCloseRequested()) {

View File

@@ -13,7 +13,7 @@ DataBuffer GetAsset(const std::string& fileName) {
SDL_RWops* io = SDL_RWFromFile(fileName.c_str(), "rb");
assert(io != nullptr);
assert(io != nullptr && "Can't find the requested file !");
std::int64_t bufferSize = SDL_RWsize(io);

View File

@@ -1,5 +1,6 @@
#include "client/Client.h"
#include "blitz/misc/Log.h"
#include "blitz/protocol/packets/ChatPacket.h"
#include "blitz/protocol/packets/DisconnectPacket.h"
#include "blitz/protocol/packets/PlayerPositionAndRotationPacket.h"
@@ -17,11 +18,13 @@ Client::Client() :
m_Game(std::make_unique<client::ClientGame>(this, m_Connexion->GetDispatcher())) {}
Client::~Client() {
protocol::DisconnectPacket packet("Client");
m_Connexion->SendPacket(&packet);
Disconnect();
}
void Client::Update() {
if (m_Connexion->GetSocketStatus() != network::TCPSocket::Status::Connected)
return;
if (m_Connexion->UpdateSocket()) {
static std::uint64_t lastTime = utils::GetTime();
@@ -29,6 +32,8 @@ void Client::Update() {
m_Game->Tick(utils::GetTime() - lastTime);
lastTime = utils::GetTime();
} else {
Disconnect();
}
}
@@ -57,11 +62,21 @@ bool Client::CreateGame(std::uint16_t port, const std::string& pseudo) {
}
void Client::Disconnect() {
if (m_Connexion->GetSocketStatus() != network::TCPSocket::Status::Connected)
return;
protocol::DisconnectPacket packet("Client wants to leave !");
m_Connexion->SendPacket(&packet);
utils::LOGD("[Client] Disconnected !");
if (m_Server) {
m_Server->Stop();
}
m_Connexion->CloseConnection();
Reset();
NotifyListeners(&game::ClientListener::OnGameLeave);
}
void Client::Reset() {

View File

@@ -53,6 +53,7 @@ void ClientConnexion::HandlePacket(const protocol::ChatPacket* packet) {
void ClientConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
utils::LOG("Disconnected !");
m_Client->NotifyListeners(&game::ClientListener::OnGameLeave);
}
void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
@@ -62,6 +63,7 @@ void ClientConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
void ClientConnexion::HandlePacket(const protocol::ConnexionInfoPacket* packet) {
m_PlayerID = packet->GetConnectionID();
utils::LOGD("[ClientConnexion] Logging in with pseudo " + m_PlayerName + " ...");
Login(m_PlayerName);
}

View File

@@ -0,0 +1,27 @@
#include "client/audio/AudioBuffer.h"
#include <AL/al.h>
namespace blitz {
namespace audio {
static const std::vector<unsigned int> AudioFormats = {
AL_FORMAT_MONO8,
AL_FORMAT_MONO16,
AL_FORMAT_STEREO8,
AL_FORMAT_STEREO16,
};
AudioBuffer::AudioBuffer(AudioData&& audioData) {
alGenBuffers(1, &m_ID);
alBufferData(m_ID, AudioFormats[audioData.m_Format], audioData.m_Buffer.data() + audioData.m_Buffer.GetReadOffset(),
audioData.m_Buffer.GetSize() - audioData.m_Buffer.GetReadOffset(), static_cast<ALsizei>(audioData.m_Frequency));
}
AudioBuffer::~AudioBuffer() {
alDeleteBuffers(1, &m_ID);
m_ID = 0;
}
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,47 @@
#include "client/audio/AudioListener.h"
#include "blitz/misc/Log.h"
#include <AL/al.h>
#include <AL/alc.h>
namespace blitz {
namespace audio {
AudioListener::AudioListener() {
ALCdevice* device = alcOpenDevice(nullptr);
if (device) {
ALCcontext* context = alcCreateContext(device, nullptr);
alcMakeContextCurrent(context);
} else {
utils::LOGE("[AudioListener] Can't initialize sound !");
}
}
AudioListener::~AudioListener() {
ALCcontext* context = alcGetCurrentContext();
ALCdevice* device = alcGetContextsDevice(context);
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
alcCloseDevice(device);
}
void AudioListener::SetGain(float a_Gain) {
alListenerf(AL_GAIN, a_Gain);
}
void AudioListener::SetPosition(const Vec3f& a_Position) {
alListener3f(AL_POSITION, a_Position.x, a_Position.y, a_Position.z);
}
void AudioListener::SetVelocity(const Vec3f& a_Velocity) {
alListener3f(AL_VELOCITY, a_Velocity.x, a_Velocity.y, a_Velocity.z);
}
void AudioListener::SetOrientation(const Vec3f& a_Orientation, const Vec3f& a_Up) {
Vec3f data[] = {a_Orientation, a_Up};
alListenerfv(AL_ORIENTATION, reinterpret_cast<float*>(data));
}
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,51 @@
#include "client/audio/AudioLoader.h"
#include "blitz/misc/Log.h"
#include "client/AssetsManager.h"
namespace blitz {
namespace audio {
namespace AudioLoader {
struct WavHeader {
/* RIFF Chunk Descriptor */
uint8_t RIFF[4]; // RIFF Header Magic header
uint32_t ChunkSize; // RIFF Chunk Size
uint8_t WAVE[4]; // WAVE Header
/* "fmt" sub-chunk */
uint8_t FMT[4]; // FMT header
uint32_t Subchunk1Size; // Size of the fmt chunk
uint16_t AudioFormat; // Audio format 1=PCM,6=mulaw,7=alaw, 257=IBM Mu-Law, 258=IBM A-Law, 259=ADPCM
uint16_t NumOfChan; // Number of channels 1=Mono 2=Sterio
uint32_t SamplesPerSec; // Sampling Frequency in Hz
uint32_t BytesPerSec; // bytes per second
uint16_t BlockAlign; // 2=16-bit mono, 4=16-bit stereo
uint16_t BitsPerSample; // Number of bits per sample
/* "data" sub-chunk */
uint8_t Subchunk2ID[4]; // "data" string
uint32_t Subchunk2Size; // Sampled data length
};
AudioData LoadAudioFile(const std::string& filePath) {
DataBuffer fileBuffer = utils::AssetsManager::GetAsset(filePath);
WavHeader wavHeader;
fileBuffer >> wavHeader;
if (wavHeader.Subchunk2Size == 0) {
utils::LOGE("[AudioLoader] Failed to load sound " + filePath + " !");
}
fileBuffer.Resize(fileBuffer.GetReadOffset() + wavHeader.Subchunk2Size);
int audioFormat = (wavHeader.NumOfChan - 1) * 2 + (wavHeader.BitsPerSample / 8) - 1;
return {fileBuffer, AudioFormat(audioFormat), wavHeader.SamplesPerSec};
}
}; // namespace AudioLoader
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,43 @@
#include "client/audio/AudioManager.h"
#include "client/Client.h"
#include "client/audio/AudioBuffer.h"
namespace blitz {
namespace audio {
AudioManager::AudioManager(Client* client) : m_Client(client) {
m_Listener.SetPosition({});
m_Listener.SetVelocity({});
m_Listener.SetGain(1.0f);
m_Listener.SetOrientation(blitz::Vec3f{0.0, 0.0, 0.0}, blitz::Vec3f{0.0, 1.0, 0.0});
InitMainMenuMusic();
m_MenuMusic->Play();
m_Client->BindListener(this);
}
void AudioManager::InitMainMenuMusic() {
AudioData audioData = AudioLoader::LoadAudioFile("sessionD.wav");
AudioBufferPtr audioBuffer = std::make_unique<AudioBuffer>(std::move(audioData));
m_MenuMusic = std::make_unique<AudioSource>();
m_MenuMusic->SetBuffer(std::move(audioBuffer));
m_MenuMusic->SetPosition({});
m_MenuMusic->SetVelocity({});
m_MenuMusic->SetPitch(1.0f);
m_MenuMusic->SetLooping(true);
}
void AudioManager::OnGameJoin() {
m_MenuMusic->Stop();
}
void AudioManager::OnGameLeave() {
m_MenuMusic->Play();
}
AudioManager::~AudioManager() {
m_Client->UnbindListener(this);
}
} // namespace audio
} // namespace blitz

View File

@@ -0,0 +1,66 @@
#include "client/audio/AudioSource.h"
#include <AL/al.h>
namespace blitz {
namespace audio {
AudioSource::AudioSource() {
alGenSources(1, &m_ID);
}
AudioSource::~AudioSource() {
alDeleteSources(1, &m_ID);
}
void AudioSource::SetGain(float a_Gain) {
alSourcef(m_ID, AL_GAIN, a_Gain);
}
void AudioSource::SetPitch(float a_Pitch) {
alSourcef(m_ID, AL_PITCH, a_Pitch);
}
void AudioSource::SetPosition(const Vec3f& a_Position) {
alSource3f(m_ID, AL_POSITION, a_Position.x, a_Position.y, a_Position.z);
}
void AudioSource::SetDirection(const Vec3f& a_Direction) {
alSource3f(m_ID, AL_DIRECTION, a_Direction.x, a_Direction.y, a_Direction.z);
}
void AudioSource::SetVelocity(const Vec3f& a_Velocity) {
alSource3f(m_ID, AL_VELOCITY, a_Velocity.x, a_Velocity.y, a_Velocity.z);
}
void AudioSource::SetLooping(bool a_Looping) {
alSourcei(m_ID, AL_LOOPING, a_Looping);
}
void AudioSource::SetBuffer(AudioBufferPtr&& a_Buffer) {
alSourcei(m_ID, AL_BUFFER, a_Buffer->GetID());
m_Buffer = std::move(a_Buffer);
}
AudioSource::SourceState AudioSource::GetSourceState() const {
int state;
alGetSourcei(m_ID, AL_SOURCE_STATE, &state);
return SourceState(state - AL_INITIAL);
}
void AudioSource::Play() {
alSourcePlay(m_ID);
}
void AudioSource::Pause() {
alSourcePause(m_ID);
}
void AudioSource::Stop() {
alSourceStop(m_ID);
}
} // namespace audio
} // namespace blitz

View File

@@ -53,6 +53,7 @@ void ClientGame::HandlePacket(const protocol::PlayerJoinPacket* packet) {
// Initialize camera
if (packet->GetPlayerID() == m_Client->GetPlayerID()) {
m_Client->NotifyListeners(&game::ClientListener::OnSpectatorChange, packet->GetPlayerID());
m_Client->NotifyListeners(&game::ClientListener::OnGameJoin);
}
}

View File

@@ -8,7 +8,7 @@ if is_plat("linux") and is_arch("arm64-v8a") then
end
add_requires("libsdl 2.28.3", {configs = {sdlmain = false}})
add_requires(opengl, "assimp 5.3.1", "nlohmann_json")
add_requires(opengl, "assimp 5.3.1", "nlohmann_json", "openal-soft")
-- Client binary (default)
@@ -26,7 +26,7 @@ target("BlitzClient")
-- Libraries
add_deps("Blitz")
add_packages("libsdl", opengl, "assimp", "nlohmann_json")
add_packages("libsdl", opengl, "assimp", "nlohmann_json", "openal-soft")
add_includedirs("../libs", "../libs/imgui")
add_files("../libs/imgui/**.cpp")