From a250c20d8425e13e2f409e9d803e3012700652a8 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Mon, 23 Feb 2026 07:51:10 -0800 Subject: [PATCH] Fix audio volume double/triple-scaling and add About tab Audio was being scaled by master volume multiple times: once via ma_engine_set_volume, again per-sound in AudioEngine, and again via pre-multiplication in the UI. Removed redundant master volume multiplications so each channel volume is independent and master applies once through the engine. Added About tab to settings with developer info and GitHub link. --- src/audio/audio_engine.cpp | 8 +-- src/ui/game_screen.cpp | 118 +++++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/audio/audio_engine.cpp b/src/audio/audio_engine.cpp index 92065709..b08d10eb 100644 --- a/src/audio/audio_engine.cpp +++ b/src/audio/audio_engine.cpp @@ -273,7 +273,7 @@ bool AudioEngine::playSound2D(const std::vector& wavData, float volume, } // Set volume (pitch not supported with NO_PITCH flag) - ma_sound_set_volume(sound, volume * masterVolume_); + ma_sound_set_volume(sound, volume); // Start playback result = ma_sound_start(sound); @@ -361,7 +361,7 @@ bool AudioEngine::playSound3D(const std::vector& wavData, const glm::ve // Set 3D position and attenuation ma_sound_set_position(sound, position.x, position.y, position.z); - ma_sound_set_volume(sound, volume * masterVolume_); + ma_sound_set_volume(sound, volume); ma_sound_set_pitch(sound, pitch); // Enable pitch variation ma_sound_set_attenuation_model(sound, ma_attenuation_model_inverse); ma_sound_set_min_gain(sound, 0.0f); @@ -462,7 +462,7 @@ bool AudioEngine::playMusic(const std::vector& musicData, float volume, } // Set volume and looping - ma_sound_set_volume(musicSound_, volume * masterVolume_); + ma_sound_set_volume(musicSound_, volume); ma_sound_set_looping(musicSound_, loop ? MA_TRUE : MA_FALSE); // Start playback @@ -510,7 +510,7 @@ bool AudioEngine::isMusicPlaying() const { void AudioEngine::setMusicVolume(float volume) { musicVolume_ = glm::clamp(volume, 0.0f, 1.0f); if (musicSound_) { - ma_sound_set_volume(musicSound_, musicVolume_ * masterVolume_); + ma_sound_set_volume(musicSound_, musicVolume_); } } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index a3ebf71a..d68739d7 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -228,36 +228,36 @@ void GameScreen::render(game::GameHandler& gameHandler) { auto* renderer = core::Application::getInstance().getRenderer(); if (renderer && renderer->getUiSoundManager()) { float masterScale = soundMuted_ ? 0.0f : static_cast(pendingMasterVolume) / 100.0f; - audio::AudioEngine::instance().setMasterVolume(soundMuted_ ? 0.0f : masterScale); + audio::AudioEngine::instance().setMasterVolume(masterScale); if (auto* music = renderer->getMusicManager()) { - music->setVolume(static_cast(pendingMusicVolume * masterScale)); + music->setVolume(pendingMusicVolume); } if (auto* ambient = renderer->getAmbientSoundManager()) { - ambient->setVolumeScale(pendingAmbientVolume / 100.0f * masterScale); + ambient->setVolumeScale(pendingAmbientVolume / 100.0f); } if (auto* ui = renderer->getUiSoundManager()) { - ui->setVolumeScale(pendingUiVolume / 100.0f * masterScale); + ui->setVolumeScale(pendingUiVolume / 100.0f); } if (auto* combat = renderer->getCombatSoundManager()) { - combat->setVolumeScale(pendingCombatVolume / 100.0f * masterScale); + combat->setVolumeScale(pendingCombatVolume / 100.0f); } if (auto* spell = renderer->getSpellSoundManager()) { - spell->setVolumeScale(pendingSpellVolume / 100.0f * masterScale); + spell->setVolumeScale(pendingSpellVolume / 100.0f); } if (auto* movement = renderer->getMovementSoundManager()) { - movement->setVolumeScale(pendingMovementVolume / 100.0f * masterScale); + movement->setVolumeScale(pendingMovementVolume / 100.0f); } if (auto* footstep = renderer->getFootstepManager()) { - footstep->setVolumeScale(pendingFootstepVolume / 100.0f * masterScale); + footstep->setVolumeScale(pendingFootstepVolume / 100.0f); } if (auto* npcVoice = renderer->getNpcVoiceManager()) { - npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f * masterScale); + npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f); } if (auto* mount = renderer->getMountSoundManager()) { - mount->setVolumeScale(pendingMountVolume / 100.0f * masterScale); + mount->setVolumeScale(pendingMountVolume / 100.0f); } if (auto* activity = renderer->getActivitySoundManager()) { - activity->setVolumeScale(pendingActivityVolume / 100.0f * masterScale); + activity->setVolumeScale(pendingActivityVolume / 100.0f); } volumeSettingsApplied_ = true; } @@ -6104,36 +6104,36 @@ void GameScreen::renderSettingsWindow() { auto applyAudioSettings = [&]() { if (!renderer) return; float masterScale = soundMuted_ ? 0.0f : static_cast(pendingMasterVolume) / 100.0f; - audio::AudioEngine::instance().setMasterVolume(soundMuted_ ? 0.0f : masterScale); + audio::AudioEngine::instance().setMasterVolume(masterScale); if (auto* music = renderer->getMusicManager()) { - music->setVolume(static_cast(pendingMusicVolume * masterScale)); + music->setVolume(pendingMusicVolume); } if (auto* ambient = renderer->getAmbientSoundManager()) { - ambient->setVolumeScale(pendingAmbientVolume / 100.0f * masterScale); + ambient->setVolumeScale(pendingAmbientVolume / 100.0f); } if (auto* ui = renderer->getUiSoundManager()) { - ui->setVolumeScale(pendingUiVolume / 100.0f * masterScale); + ui->setVolumeScale(pendingUiVolume / 100.0f); } if (auto* combat = renderer->getCombatSoundManager()) { - combat->setVolumeScale(pendingCombatVolume / 100.0f * masterScale); + combat->setVolumeScale(pendingCombatVolume / 100.0f); } if (auto* spell = renderer->getSpellSoundManager()) { - spell->setVolumeScale(pendingSpellVolume / 100.0f * masterScale); + spell->setVolumeScale(pendingSpellVolume / 100.0f); } if (auto* movement = renderer->getMovementSoundManager()) { - movement->setVolumeScale(pendingMovementVolume / 100.0f * masterScale); + movement->setVolumeScale(pendingMovementVolume / 100.0f); } if (auto* footstep = renderer->getFootstepManager()) { - footstep->setVolumeScale(pendingFootstepVolume / 100.0f * masterScale); + footstep->setVolumeScale(pendingFootstepVolume / 100.0f); } if (auto* npcVoice = renderer->getNpcVoiceManager()) { - npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f * masterScale); + npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f); } if (auto* mount = renderer->getMountSoundManager()) { - mount->setVolumeScale(pendingMountVolume / 100.0f * masterScale); + mount->setVolumeScale(pendingMountVolume / 100.0f); } if (auto* activity = renderer->getActivitySoundManager()) { - activity->setVolumeScale(pendingActivityVolume / 100.0f * masterScale); + activity->setVolumeScale(pendingActivityVolume / 100.0f); } saveSettings(); }; @@ -6425,6 +6425,60 @@ void GameScreen::renderSettingsWindow() { ImGui::EndTabItem(); } + // ============================================================ + // ABOUT TAB + // ============================================================ + if (ImGui::BeginTabItem("About")) { + ImGui::Spacing(); + ImGui::Spacing(); + + ImGui::TextWrapped("WoWee - World of Warcraft Client Emulator"); + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::Text("Developer"); + ImGui::Indent(); + ImGui::Text("Kelsi Davis"); + ImGui::Unindent(); + ImGui::Spacing(); + + ImGui::Text("GitHub"); + ImGui::Indent(); + ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "https://github.com/Kelsidavis/WoWee"); + if (ImGui::IsItemHovered()) { + ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); + ImGui::SetTooltip("Click to copy"); + } + if (ImGui::IsItemClicked()) { + ImGui::SetClipboardText("https://github.com/Kelsidavis/WoWee"); + } + ImGui::Unindent(); + ImGui::Spacing(); + + ImGui::Text("Contact"); + ImGui::Indent(); + ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "github.com/Kelsidavis"); + if (ImGui::IsItemHovered()) { + ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); + ImGui::SetTooltip("Click to copy"); + } + if (ImGui::IsItemClicked()) { + ImGui::SetClipboardText("https://github.com/Kelsidavis"); + } + ImGui::Unindent(); + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::TextWrapped("A multi-expansion WoW client supporting Classic, TBC, and WotLK (3.3.5a)."); + ImGui::Spacing(); + ImGui::TextDisabled("Built with Vulkan, SDL2, and ImGui"); + + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); } @@ -6639,34 +6693,34 @@ void GameScreen::renderMinimapMarkers(game::GameHandler& gameHandler) { audio::AudioEngine::instance().setMasterVolume(masterScale); if (!activeRenderer) return; if (auto* music = activeRenderer->getMusicManager()) { - music->setVolume(static_cast(pendingMusicVolume * masterScale)); + music->setVolume(pendingMusicVolume); } if (auto* ambient = activeRenderer->getAmbientSoundManager()) { - ambient->setVolumeScale(pendingAmbientVolume / 100.0f * masterScale); + ambient->setVolumeScale(pendingAmbientVolume / 100.0f); } if (auto* ui = activeRenderer->getUiSoundManager()) { - ui->setVolumeScale(pendingUiVolume / 100.0f * masterScale); + ui->setVolumeScale(pendingUiVolume / 100.0f); } if (auto* combat = activeRenderer->getCombatSoundManager()) { - combat->setVolumeScale(pendingCombatVolume / 100.0f * masterScale); + combat->setVolumeScale(pendingCombatVolume / 100.0f); } if (auto* spell = activeRenderer->getSpellSoundManager()) { - spell->setVolumeScale(pendingSpellVolume / 100.0f * masterScale); + spell->setVolumeScale(pendingSpellVolume / 100.0f); } if (auto* movement = activeRenderer->getMovementSoundManager()) { - movement->setVolumeScale(pendingMovementVolume / 100.0f * masterScale); + movement->setVolumeScale(pendingMovementVolume / 100.0f); } if (auto* footstep = activeRenderer->getFootstepManager()) { - footstep->setVolumeScale(pendingFootstepVolume / 100.0f * masterScale); + footstep->setVolumeScale(pendingFootstepVolume / 100.0f); } if (auto* npcVoice = activeRenderer->getNpcVoiceManager()) { - npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f * masterScale); + npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f); } if (auto* mount = activeRenderer->getMountSoundManager()) { - mount->setVolumeScale(pendingMountVolume / 100.0f * masterScale); + mount->setVolumeScale(pendingMountVolume / 100.0f); } if (auto* activity = activeRenderer->getActivitySoundManager()) { - activity->setVolumeScale(pendingActivityVolume / 100.0f * masterScale); + activity->setVolumeScale(pendingActivityVolume / 100.0f); } };