diff --git a/CMakeLists.txt b/CMakeLists.txt index c4fccfb..6f70968 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 + $ + $ + ) # build server set(ASIO_INCLUDE_DIR "external/asio/include") diff --git a/src/audio/master.hpp b/src/audio/master.hpp index 37dcd18..1c11d07 100644 --- a/src/audio/master.hpp +++ b/src/audio/master.hpp @@ -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_; } diff --git a/src/audio/sound.cpp b/src/audio/sound.cpp index 5244e34..bf97c84 100644 --- a/src/audio/sound.cpp +++ b/src/audio/sound.cpp @@ -31,12 +31,12 @@ std::shared_ptr audio::Sound::LoadFromFile(const std::string { auto sound = std::make_shared(); - 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 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; } diff --git a/src/audio/sound.hpp b/src/audio/sound.hpp index f48f929..7719736 100644 --- a/src/audio/sound.hpp +++ b/src/audio/sound.hpp @@ -9,11 +9,8 @@ namespace audio class Sound { -private: - Sound(); - friend std::shared_ptr std::make_shared(); - public: + Sound(); static std::shared_ptr LoadFromFile(const std::string& path); unsigned int GetBufferId() const { return buffer_; } diff --git a/src/audio/sound_source.cpp b/src/audio/sound_source.cpp index 941b9bd..515b82c 100644 --- a/src/audio/sound_source.cpp +++ b/src/audio/sound_source.cpp @@ -9,7 +9,7 @@ audio::SoundSource::SoundSource(Player* player, std::shared_ptr 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) diff --git a/src/client/app.cpp b/src/client/app.cpp index a018083..bacdbe5 100644 --- a/src/client/app.cpp +++ b/src/client/app.cpp @@ -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) diff --git a/src/client/app.hpp b/src/client/app.hpp index 9dcc40c..b678a7e 100644 --- a/src/client/app.hpp +++ b/src/client/app.hpp @@ -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 session_; }; diff --git a/src/client/main.cpp b/src/client/main.cpp index 766309e..92476ce 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -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; diff --git a/src/game/vehicle.cpp b/src/game/vehicle.cpp index 081bde9..54cb9d3 100644 --- a/src/game/vehicle.cpp +++ b/src/game/vehicle.cpp @@ -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 diff --git a/src/game/vehicle.hpp b/src/game/vehicle.hpp index 78a5761..3f230e0 100644 --- a/src/game/vehicle.hpp +++ b/src/game/vehicle.hpp @@ -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 wheels_; + + VehicleFlags flags_; }; } // namespace game \ No newline at end of file diff --git a/src/game/vehicleflags.hpp b/src/game/vehicleflags.hpp new file mode 100644 index 0000000..e292011 --- /dev/null +++ b/src/game/vehicleflags.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +namespace game +{ + +using VehicleFlags = uint8_t; + +enum VehicleFlag : VehicleFlags +{ + VF_NONE, + VF_ACCELERATING = 1, + VF_BREAKING = 2, +}; + +} \ No newline at end of file diff --git a/src/gameview/client_session.cpp b/src/gameview/client_session.cpp index e958242..e027f6b 100644 --- a/src/gameview/client_session.cpp +++ b/src/gameview/client_session.cpp @@ -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; diff --git a/src/gameview/client_session.hpp b/src/gameview/client_session.hpp index a27042a..81d1d2b 100644 --- a/src/gameview/client_session.hpp +++ b/src/gameview/client_session.hpp @@ -29,6 +29,8 @@ public: glm::mat4 GetViewMatrix() const; + audio::Master& GetAudioMaster() const; + private: // msg handlers bool ProcessWorldMsg(net::InMessage& msg); diff --git a/src/gameview/entityview.cpp b/src/gameview/entityview.cpp new file mode 100644 index 0000000..b091b46 --- /dev/null +++ b/src/gameview/entityview.cpp @@ -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) {} diff --git a/src/gameview/entityview.hpp b/src/gameview/entityview.hpp index dd8a4ee..5794d4a 100644 --- a/src/gameview/entityview.hpp +++ b/src/gameview/entityview.hpp @@ -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 \ No newline at end of file diff --git a/src/gameview/vehicleview.cpp b/src/gameview/vehicleview.cpp index 048b9ce..86bc8c2 100644 --- a/src/gameview/vehicleview.cpp +++ b/src/gameview/vehicleview.cpp @@ -16,6 +16,8 @@ game::view::VehicleView::VehicleView(WorldView& world, std::shared_ptr 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; diff --git a/src/gameview/vehicleview.hpp b/src/gameview/vehicleview.hpp index 8af613a..a047545 100644 --- a/src/gameview/vehicleview.hpp +++ b/src/gameview/vehicleview.hpp @@ -3,6 +3,7 @@ #include "entityview.hpp" #include "assets/vehiclemdl.hpp" +#include "game/vehicleflags.hpp" #include @@ -20,6 +21,7 @@ struct VehicleWheelViewInfo class VehicleView : public EntityView { + using Super = EntityView; public: VehicleView(WorldView& world, std::shared_ptr model); static std::unique_ptr 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 snd_accel_; + audio::SoundSource* snd_accel_src_ = nullptr; }; } \ No newline at end of file diff --git a/src/gameview/worldview.cpp b/src/gameview/worldview.cpp index 9118573..c9e1569 100644 --- a/src/gameview/worldview.cpp +++ b/src/gameview/worldview.cpp @@ -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"); } diff --git a/src/gameview/worldview.hpp b/src/gameview/worldview.hpp index 9cb4967..84dbd56 100644 --- a/src/gameview/worldview.hpp +++ b/src/gameview/worldview.hpp @@ -26,6 +26,8 @@ public: float GetTime() const { return time_; } + audio::Master& GetAudioMaster() const { return audiomaster_; } + private: // msg handlers bool ProcessEntSpawnMsg(net::InMessage& msg); @@ -34,12 +36,13 @@ private: private: ClientSession& session_; - + std::shared_ptr map_; std::map> ents_; - + float time_ = 0.0f; + audio::Master& audiomaster_; }; } // namespace game::view \ No newline at end of file