Add vehicle sound sjeta

This commit is contained in:
tovjemam 2026-01-09 23:13:35 +01:00
parent 8f59d76cf9
commit 421fbdd710
19 changed files with 128 additions and 22 deletions

View File

@ -67,6 +67,7 @@ set(CLIENT_ONLY_SOURCES
"src/gameview/client_session.hpp"
"src/gameview/client_session.cpp"
"src/gameview/entityview.hpp"
"src/gameview/entityview.cpp"
"src/gameview/vehicleview.hpp"
"src/gameview/vehicleview.cpp"
"src/gameview/worldview.hpp"
@ -219,9 +220,15 @@ endif()
target_link_libraries(${MAIN_NAME} PRIVATE easywsclient)
# add openal
set(ALSOFT_EXAMPLES OFF)
set(ALSOFT_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory(external/openal-soft)
target_link_libraries(${MAIN_NAME} PRIVATE OpenAL)
target_link_libraries(${MAIN_NAME} PRIVATE OpenAL::OpenAL)
add_custom_command(TARGET ${MAIN_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:OpenAL>
$<TARGET_FILE_DIR:${MAIN_NAME}>
)
# build server
set(ASIO_INCLUDE_DIR "external/asio/include")

View File

@ -19,7 +19,7 @@ class Category
{
public:
Category(const std::string& name);
DELETE_COPY_MOVE(Category)
// DELETE_COPY_MOVE(Category) // HACK: make it possible to push into reserved vector
const std::string& GetName() const { return name_; }

View File

@ -31,12 +31,12 @@ std::shared_ptr<const audio::Sound> audio::Sound::LoadFromFile(const std::string
{
auto sound = std::make_shared<Sound>();
std::string ogg_path;
std::string ogg_name;
assets::LoadCMDFile(path, [&](const std::string& cmd, std::istringstream& iss) {
if (cmd == "ogg")
{
iss >> ogg_path;
iss >> ogg_name;
}
else if (cmd == "category")
{
@ -55,7 +55,8 @@ std::shared_ptr<const audio::Sound> audio::Sound::LoadFromFile(const std::string
if (sound->category_name_.empty())
sound->category_name_ = "default";
LoadBufferOGG(sound->GetBufferId(), ogg_path.c_str());
ogg_name = "data/" + ogg_name + ".ogg";
LoadBufferOGG(sound->GetBufferId(), ogg_name.c_str());
return sound;
}

View File

@ -9,11 +9,8 @@ namespace audio
class Sound
{
private:
Sound();
friend std::shared_ptr<Sound> std::make_shared<Sound>();
public:
Sound();
static std::shared_ptr<const Sound> LoadFromFile(const std::string& path);
unsigned int GetBufferId() const { return buffer_; }

View File

@ -9,7 +9,7 @@ audio::SoundSource::SoundSource(Player* player, std::shared_ptr<const Sound> sou
SetVolume(1.0f);
SetPitch(1.0f);
alSourcei(source_, AL_BUFFER, sound->GetBufferId());
alSourcei(source_, AL_BUFFER, sound_->GetBufferId());
}
void audio::SoundSource::SetLooping(bool looping)

View File

@ -11,7 +11,7 @@ App::App()
{
std::cout << "Initializing App..." << std::endl;
audiomaster_.SetMasterVolume(0.2f);
}
void App::Frame()
@ -55,11 +55,15 @@ void App::Frame()
// glm::mat4 view = glm::lookAt(glm::vec3(15.0f, 0.0f, 1.0f), glm::vec3(0.0f, 0.0f, -13.0f), glm::vec3(0.0f, 0.0f, 1.0f));
glm::mat4 proj = glm::perspective(glm::radians(45.0f), aspect, 0.1f, 3000.0f);
glm::mat4 view = session_->GetViewMatrix();
gfx::DrawListParams params;
params.view_proj = proj * session_->GetViewMatrix();
params.view_proj = proj * view;
renderer_.DrawList(dlist_, params);
glm::mat4 camera_world = glm::inverse(view);
audiomaster_.SetListenerOrientation(camera_world);
}
if (time_ - last_send_time_ > 0.040f)

View File

@ -4,6 +4,7 @@
#include "game/player_input.hpp"
#include "gfx/renderer.hpp"
#include "audio/master.hpp"
#include "net/msg_producer.hpp"
#include "net/inmessage.hpp"
@ -29,6 +30,8 @@ public:
float GetTime() const { return delta_time_; }
float GetDeltaTime() const { return delta_time_; }
audio::Master& GetAudioMaster() { return audiomaster_; }
~App();
private:
@ -47,5 +50,7 @@ private:
gfx::Renderer renderer_;
gfx::DrawList dlist_;
audio::Master audiomaster_;
std::unique_ptr<game::view::ClientSession> session_;
};

View File

@ -153,7 +153,12 @@ static void PollEvents()
}
}
#ifdef NDEBUG
#define WS_URL "ws://deadfish.cz:11200/ws"
#else
#define WS_URL "ws://127.0.0.1:11200/ws"
#endif
static bool s_ws_connected = false;

View File

@ -105,6 +105,7 @@ void game::Vehicle::Update()
{
Super::Update();
flags_ = 0;
ProcessInput();
UpdateWheels();
@ -216,6 +217,12 @@ void game::Vehicle::ProcessInput()
vehicle_->setSteeringValue(steering_, 0);
vehicle_->setSteeringValue(steering_, 1);
if (glm::abs(engineForce) > 0)
flags_ |= VF_ACCELERATING;
if (glm::abs(breakingForce) > 0)
flags_ |= VF_BREAKING;
}
void game::Vehicle::UpdateWheels()
@ -232,6 +239,7 @@ void game::Vehicle::UpdateWheels()
void game::Vehicle::SendUpdateMsg()
{
auto msg = BeginEntMsg(net::EMSG_UPDATE);
msg.Write(flags_);
net::WriteTransform(msg, root_.local);
// send wheel info

View File

@ -8,6 +8,7 @@
#include "controllable.hpp"
#include "entity.hpp"
#include "world.hpp"
#include "vehicleflags.hpp"
namespace game
{
@ -54,6 +55,8 @@ private:
size_t num_wheels_ = 0;
std::array<VehicleWheelState, MAX_WHEELS> wheels_;
VehicleFlags flags_;
};
} // namespace game

17
src/game/vehicleflags.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
namespace game
{
using VehicleFlags = uint8_t;
enum VehicleFlag : VehicleFlags
{
VF_NONE,
VF_ACCELERATING = 1,
VF_BREAKING = 2,
};
}

View File

@ -86,6 +86,11 @@ glm::mat4 game::view::ClientSession::GetViewMatrix() const
return glm::lookAt(eye, center, glm::vec3(0, 0, 1));
}
audio::Master& game::view::ClientSession::GetAudioMaster() const
{
return app_.GetAudioMaster();
}
bool game::view::ClientSession::ProcessWorldMsg(net::InMessage& msg)
{
net::MapName mapname;

View File

@ -29,6 +29,8 @@ public:
glm::mat4 GetViewMatrix() const;
audio::Master& GetAudioMaster() const;
private:
// msg handlers
bool ProcessWorldMsg(net::InMessage& msg);

View File

@ -0,0 +1,17 @@
#include "entityview.hpp"
#include "worldview.hpp"
game::view::EntityView::EntityView(WorldView& world) : world_(world), audioplayer_(world_.GetAudioMaster()) {}
bool game::view::EntityView::ProcessMsg(net::EntMsgType type, net::InMessage& msg)
{
return false;
}
void game::view::EntityView::Update(const UpdateInfo& info)
{
audioplayer_.Update();
}
void game::view::EntityView::Draw(gfx::DrawList& dlist) {}

View File

@ -4,6 +4,7 @@
#include "game/transform_node.hpp"
#include "gfx/draw_list.hpp"
#include "audio/player.hpp"
#include "net/defs.hpp"
#include "net/inmessage.hpp"
@ -24,12 +25,12 @@ struct UpdateInfo
class EntityView
{
public:
EntityView(WorldView& world) : world_(world) {}
EntityView(WorldView& world);
DELETE_COPY_MOVE(EntityView)
virtual bool ProcessMsg(net::EntMsgType type, net::InMessage& msg) { return false; }
virtual void Update(const UpdateInfo& info) {}
virtual void Draw(gfx::DrawList& dlist) {}
virtual bool ProcessMsg(net::EntMsgType type, net::InMessage& msg);
virtual void Update(const UpdateInfo& info);
virtual void Draw(gfx::DrawList& dlist);
const TransformNode& GetRoot() const { return root_; }
@ -37,9 +38,11 @@ public:
protected:
WorldView& world_;
TransformNode root_;
bool visible_ = false;
audio::Player audioplayer_;
};
} // namespace game::view

View File

@ -16,6 +16,8 @@ game::view::VehicleView::VehicleView(WorldView& world, std::shared_ptr<const ass
{
wheels_[i].node.parent = &root_;
}
snd_accel_ = assets::CacheManager::GetSound("data/auto.snd");
}
std::unique_ptr<game::view::VehicleView> game::view::VehicleView::InitFromMsg(WorldView& world, net::InMessage& msg)
@ -43,6 +45,8 @@ bool game::view::VehicleView::ProcessMsg(net::EntMsgType type, net::InMessage& m
void game::view::VehicleView::Update(const UpdateInfo& info)
{
Super::Update(info);
float tps = 25.0f;
float t = (info.time - update_time_) * tps * 0.8f; // assume some jitter, interpolate for longer
t = glm::clamp(t, 0.0f, 2.0f);
@ -68,6 +72,20 @@ void game::view::VehicleView::Update(const UpdateInfo& info)
wheels_[i].node.UpdateMatrix();
}
// update snds
bool accel = flags_ & VF_ACCELERATING;
if (accel && !snd_accel_src_)
{
snd_accel_src_ = audioplayer_.PlaySound(snd_accel_, &root_.local.position);
snd_accel_src_->SetLooping(true);
}
else if (!accel && snd_accel_src_)
{
snd_accel_src_->Delete();
snd_accel_src_ = nullptr;
}
}
void game::view::VehicleView::Draw(gfx::DrawList& dlist)
@ -105,6 +123,9 @@ bool game::view::VehicleView::ProcessUpdateMsg(net::InMessage& msg)
auto& root_trans = root_trans_[1];
update_time_ = world_.GetTime();
if (!msg.Read(flags_))
return false;
if (!net::ReadTransform(msg, root_trans))
return false;

View File

@ -3,6 +3,7 @@
#include "entityview.hpp"
#include "assets/vehiclemdl.hpp"
#include "game/vehicleflags.hpp"
#include <chrono>
@ -20,6 +21,7 @@ struct VehicleWheelViewInfo
class VehicleView : public EntityView
{
using Super = EntityView;
public:
VehicleView(WorldView& world, std::shared_ptr<const assets::VehicleModel> model);
static std::unique_ptr<VehicleView> InitFromMsg(WorldView& world, net::InMessage& msg);
@ -39,6 +41,10 @@ private:
float update_time_ = 0.0f;
Transform root_trans_[2];
VehicleFlags flags_ = 0;
std::shared_ptr<const audio::Sound> snd_accel_;
audio::SoundSource* snd_accel_src_ = nullptr;
};
}

View File

@ -5,7 +5,9 @@
#include "vehicleview.hpp"
#include "client_session.hpp"
game::view::WorldView::WorldView(ClientSession& session) : session_(session)
game::view::WorldView::WorldView(ClientSession& session) :
session_(session),
audiomaster_(session_.GetAudioMaster())
{
map_ = assets::CacheManager::GetMap("data/openworld.map");
}

View File

@ -26,6 +26,8 @@ public:
float GetTime() const { return time_; }
audio::Master& GetAudioMaster() const { return audiomaster_; }
private:
// msg handlers
bool ProcessEntSpawnMsg(net::InMessage& msg);
@ -40,6 +42,7 @@ private:
float time_ = 0.0f;
audio::Master& audiomaster_;
};
} // namespace game::view