mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Implement comprehensive audio control panel with tabbed settings interface
Adds complete audio volume controls for all 11 audio systems with master volume. Reorganizes settings window into Video, Audio, and Gameplay tabs for better UX. Audio Features: - Master volume control affecting all audio systems - Individual volume sliders for: Music, Ambient, UI, Combat, Spell, Movement, Footsteps, NPC Voices, Mounts, Activity sounds - Real-time volume adjustment with master volume multiplier - Restore defaults button per tab Technical Changes: - Added getVolumeScale() getters to all audio managers - Integrated all 10 audio managers into renderer (UI, Combat, Spell, Movement added) - Expanded game_screen.hpp with 11 pending volume variables - Reorganized settings window using ImGui tab bars (Video/Audio/Gameplay) - Audio settings uses scrollable child window for 11 volume controls - Settings window expanded to 520x720px to accommodate comprehensive controls
This commit is contained in:
parent
1e23370c0e
commit
9741c8ee7c
12 changed files with 295 additions and 98 deletions
|
|
@ -208,6 +208,12 @@ set(WOWEE_HEADERS
|
||||||
include/audio/footstep_manager.hpp
|
include/audio/footstep_manager.hpp
|
||||||
include/audio/activity_sound_manager.hpp
|
include/audio/activity_sound_manager.hpp
|
||||||
include/audio/mount_sound_manager.hpp
|
include/audio/mount_sound_manager.hpp
|
||||||
|
include/audio/npc_voice_manager.hpp
|
||||||
|
include/audio/ambient_sound_manager.hpp
|
||||||
|
include/audio/ui_sound_manager.hpp
|
||||||
|
include/audio/combat_sound_manager.hpp
|
||||||
|
include/audio/spell_sound_manager.hpp
|
||||||
|
include/audio/movement_sound_manager.hpp
|
||||||
|
|
||||||
include/pipeline/mpq_manager.hpp
|
include/pipeline/mpq_manager.hpp
|
||||||
include/pipeline/blp_loader.hpp
|
include/pipeline/blp_loader.hpp
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ public:
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
void setVolumeScale(float scale);
|
void setVolumeScale(float scale);
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AmbientEmitter {
|
struct AmbientEmitter {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
void setVolumeScale(float scale);
|
void setVolumeScale(float scale);
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
// Weapon swing sounds (whoosh sounds before impact)
|
// Weapon swing sounds (whoosh sounds before impact)
|
||||||
enum class WeaponSize {
|
enum class WeaponSize {
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ public:
|
||||||
|
|
||||||
bool isMounted() const { return mounted_; }
|
bool isMounted() const { return mounted_; }
|
||||||
void setVolumeScale(float scale) { volumeScale_ = scale; }
|
void setVolumeScale(float scale) { volumeScale_ = scale; }
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MountType detectMountType(uint32_t creatureDisplayId) const;
|
MountType detectMountType(uint32_t creatureDisplayId) const;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
void setVolumeScale(float scale);
|
void setVolumeScale(float scale);
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
// Character size (for water splash intensity)
|
// Character size (for water splash intensity)
|
||||||
enum class CharacterSize {
|
enum class CharacterSize {
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
void setVolumeScale(float scale);
|
void setVolumeScale(float scale);
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
// Magic school types
|
// Magic school types
|
||||||
enum class MagicSchool {
|
enum class MagicSchool {
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ class AssetManager;
|
||||||
|
|
||||||
namespace audio {
|
namespace audio {
|
||||||
|
|
||||||
class UISoundManager {
|
class UiSoundManager {
|
||||||
public:
|
public:
|
||||||
UISoundManager() = default;
|
UiSoundManager() = default;
|
||||||
~UISoundManager() = default;
|
~UiSoundManager() = default;
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
bool initialize(pipeline::AssetManager* assets);
|
bool initialize(pipeline::AssetManager* assets);
|
||||||
|
|
@ -23,6 +23,7 @@ public:
|
||||||
|
|
||||||
// Volume control
|
// Volume control
|
||||||
void setVolumeScale(float scale);
|
void setVolumeScale(float scale);
|
||||||
|
float getVolumeScale() const { return volumeScale_; }
|
||||||
|
|
||||||
// Window sounds
|
// Window sounds
|
||||||
void playBagOpen();
|
void playBagOpen();
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
namespace wowee {
|
namespace wowee {
|
||||||
namespace core { class Window; }
|
namespace core { class Window; }
|
||||||
namespace game { class World; class ZoneManager; }
|
namespace game { class World; class ZoneManager; }
|
||||||
namespace audio { class MusicManager; class FootstepManager; class ActivitySoundManager; class MountSoundManager; class NpcVoiceManager; class AmbientSoundManager; enum class FootstepSurface : uint8_t; enum class VoiceType; }
|
namespace audio { class MusicManager; class FootstepManager; class ActivitySoundManager; class MountSoundManager; class NpcVoiceManager; class AmbientSoundManager; class UiSoundManager; class CombatSoundManager; class SpellSoundManager; class MovementSoundManager; enum class FootstepSurface : uint8_t; enum class VoiceType; }
|
||||||
namespace pipeline { class AssetManager; }
|
namespace pipeline { class AssetManager; }
|
||||||
|
|
||||||
namespace rendering {
|
namespace rendering {
|
||||||
|
|
@ -151,6 +151,10 @@ public:
|
||||||
audio::MountSoundManager* getMountSoundManager() { return mountSoundManager.get(); }
|
audio::MountSoundManager* getMountSoundManager() { return mountSoundManager.get(); }
|
||||||
audio::NpcVoiceManager* getNpcVoiceManager() { return npcVoiceManager.get(); }
|
audio::NpcVoiceManager* getNpcVoiceManager() { return npcVoiceManager.get(); }
|
||||||
audio::AmbientSoundManager* getAmbientSoundManager() { return ambientSoundManager.get(); }
|
audio::AmbientSoundManager* getAmbientSoundManager() { return ambientSoundManager.get(); }
|
||||||
|
audio::UiSoundManager* getUiSoundManager() { return uiSoundManager.get(); }
|
||||||
|
audio::CombatSoundManager* getCombatSoundManager() { return combatSoundManager.get(); }
|
||||||
|
audio::SpellSoundManager* getSpellSoundManager() { return spellSoundManager.get(); }
|
||||||
|
audio::MovementSoundManager* getMovementSoundManager() { return movementSoundManager.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
core::Window* window = nullptr;
|
core::Window* window = nullptr;
|
||||||
|
|
@ -179,6 +183,10 @@ private:
|
||||||
std::unique_ptr<audio::MountSoundManager> mountSoundManager;
|
std::unique_ptr<audio::MountSoundManager> mountSoundManager;
|
||||||
std::unique_ptr<audio::NpcVoiceManager> npcVoiceManager;
|
std::unique_ptr<audio::NpcVoiceManager> npcVoiceManager;
|
||||||
std::unique_ptr<audio::AmbientSoundManager> ambientSoundManager;
|
std::unique_ptr<audio::AmbientSoundManager> ambientSoundManager;
|
||||||
|
std::unique_ptr<audio::UiSoundManager> uiSoundManager;
|
||||||
|
std::unique_ptr<audio::CombatSoundManager> combatSoundManager;
|
||||||
|
std::unique_ptr<audio::SpellSoundManager> spellSoundManager;
|
||||||
|
std::unique_ptr<audio::MovementSoundManager> movementSoundManager;
|
||||||
std::unique_ptr<game::ZoneManager> zoneManager;
|
std::unique_ptr<game::ZoneManager> zoneManager;
|
||||||
std::unique_ptr<Shader> underwaterOverlayShader;
|
std::unique_ptr<Shader> underwaterOverlayShader;
|
||||||
uint32_t underwaterOverlayVAO = 0;
|
uint32_t underwaterOverlayVAO = 0;
|
||||||
|
|
|
||||||
|
|
@ -65,8 +65,17 @@ private:
|
||||||
bool pendingVsync = false;
|
bool pendingVsync = false;
|
||||||
int pendingResIndex = 0;
|
int pendingResIndex = 0;
|
||||||
bool pendingShadows = false;
|
bool pendingShadows = false;
|
||||||
|
int pendingMasterVolume = 100;
|
||||||
int pendingMusicVolume = 30;
|
int pendingMusicVolume = 30;
|
||||||
int pendingSfxVolume = 100;
|
int pendingAmbientVolume = 100;
|
||||||
|
int pendingUiVolume = 100;
|
||||||
|
int pendingCombatVolume = 100;
|
||||||
|
int pendingSpellVolume = 100;
|
||||||
|
int pendingMovementVolume = 100;
|
||||||
|
int pendingFootstepVolume = 100;
|
||||||
|
int pendingNpcVoiceVolume = 100;
|
||||||
|
int pendingMountVolume = 100;
|
||||||
|
int pendingActivityVolume = 100;
|
||||||
float pendingMouseSensitivity = 0.2f;
|
float pendingMouseSensitivity = 0.2f;
|
||||||
bool pendingInvertMouse = false;
|
bool pendingInvertMouse = false;
|
||||||
int pendingUiOpacity = 65;
|
int pendingUiOpacity = 65;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
namespace wowee {
|
namespace wowee {
|
||||||
namespace audio {
|
namespace audio {
|
||||||
|
|
||||||
bool UISoundManager::initialize(pipeline::AssetManager* assets) {
|
bool UiSoundManager::initialize(pipeline::AssetManager* assets) {
|
||||||
if (!assets) {
|
if (!assets) {
|
||||||
LOG_ERROR("UISoundManager: AssetManager is null");
|
LOG_ERROR("UISoundManager: AssetManager is null");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -136,11 +136,11 @@ bool UISoundManager::initialize(pipeline::AssetManager* assets) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UISoundManager::shutdown() {
|
void UiSoundManager::shutdown() {
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UISoundManager::loadSound(const std::string& path, UISample& sample, pipeline::AssetManager* assets) {
|
bool UiSoundManager::loadSound(const std::string& path, UISample& sample, pipeline::AssetManager* assets) {
|
||||||
sample.path = path;
|
sample.path = path;
|
||||||
sample.loaded = false;
|
sample.loaded = false;
|
||||||
|
|
||||||
|
|
@ -157,63 +157,63 @@ bool UISoundManager::loadSound(const std::string& path, UISample& sample, pipeli
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UISoundManager::playSound(const std::vector<UISample>& library) {
|
void UiSoundManager::playSound(const std::vector<UISample>& library) {
|
||||||
if (!initialized_ || library.empty() || !library[0].loaded) return;
|
if (!initialized_ || library.empty() || !library[0].loaded) return;
|
||||||
|
|
||||||
float volume = 0.7f * volumeScale_;
|
float volume = 0.7f * volumeScale_;
|
||||||
AudioEngine::instance().playSound2D(library[0].data, volume, 1.0f);
|
AudioEngine::instance().playSound2D(library[0].data, volume, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UISoundManager::setVolumeScale(float scale) {
|
void UiSoundManager::setVolumeScale(float scale) {
|
||||||
volumeScale_ = std::max(0.0f, std::min(1.0f, scale));
|
volumeScale_ = std::max(0.0f, std::min(1.0f, scale));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Window sounds
|
// Window sounds
|
||||||
void UISoundManager::playBagOpen() { playSound(bagOpenSounds_); }
|
void UiSoundManager::playBagOpen() { playSound(bagOpenSounds_); }
|
||||||
void UISoundManager::playBagClose() { playSound(bagCloseSounds_); }
|
void UiSoundManager::playBagClose() { playSound(bagCloseSounds_); }
|
||||||
void UISoundManager::playQuestLogOpen() { playSound(questLogOpenSounds_); }
|
void UiSoundManager::playQuestLogOpen() { playSound(questLogOpenSounds_); }
|
||||||
void UISoundManager::playQuestLogClose() { playSound(questLogCloseSounds_); }
|
void UiSoundManager::playQuestLogClose() { playSound(questLogCloseSounds_); }
|
||||||
void UISoundManager::playCharacterSheetOpen() { playSound(characterSheetOpenSounds_); }
|
void UiSoundManager::playCharacterSheetOpen() { playSound(characterSheetOpenSounds_); }
|
||||||
void UISoundManager::playCharacterSheetClose() { playSound(characterSheetCloseSounds_); }
|
void UiSoundManager::playCharacterSheetClose() { playSound(characterSheetCloseSounds_); }
|
||||||
void UISoundManager::playAuctionHouseOpen() { playSound(auctionOpenSounds_); }
|
void UiSoundManager::playAuctionHouseOpen() { playSound(auctionOpenSounds_); }
|
||||||
void UISoundManager::playAuctionHouseClose() { playSound(auctionCloseSounds_); }
|
void UiSoundManager::playAuctionHouseClose() { playSound(auctionCloseSounds_); }
|
||||||
void UISoundManager::playGuildBankOpen() { playSound(guildBankOpenSounds_); }
|
void UiSoundManager::playGuildBankOpen() { playSound(guildBankOpenSounds_); }
|
||||||
void UISoundManager::playGuildBankClose() { playSound(guildBankCloseSounds_); }
|
void UiSoundManager::playGuildBankClose() { playSound(guildBankCloseSounds_); }
|
||||||
|
|
||||||
// Button sounds
|
// Button sounds
|
||||||
void UISoundManager::playButtonClick() { playSound(buttonClickSounds_); }
|
void UiSoundManager::playButtonClick() { playSound(buttonClickSounds_); }
|
||||||
void UISoundManager::playMenuButtonClick() { playSound(menuButtonSounds_); }
|
void UiSoundManager::playMenuButtonClick() { playSound(menuButtonSounds_); }
|
||||||
|
|
||||||
// Quest sounds
|
// Quest sounds
|
||||||
void UISoundManager::playQuestActivate() { playSound(questActivateSounds_); }
|
void UiSoundManager::playQuestActivate() { playSound(questActivateSounds_); }
|
||||||
void UISoundManager::playQuestComplete() { playSound(questCompleteSounds_); }
|
void UiSoundManager::playQuestComplete() { playSound(questCompleteSounds_); }
|
||||||
void UISoundManager::playQuestFailed() { playSound(questFailedSounds_); }
|
void UiSoundManager::playQuestFailed() { playSound(questFailedSounds_); }
|
||||||
void UISoundManager::playQuestUpdate() { playSound(questUpdateSounds_); }
|
void UiSoundManager::playQuestUpdate() { playSound(questUpdateSounds_); }
|
||||||
|
|
||||||
// Loot sounds
|
// Loot sounds
|
||||||
void UISoundManager::playLootCoinSmall() { playSound(lootCoinSmallSounds_); }
|
void UiSoundManager::playLootCoinSmall() { playSound(lootCoinSmallSounds_); }
|
||||||
void UISoundManager::playLootCoinLarge() { playSound(lootCoinLargeSounds_); }
|
void UiSoundManager::playLootCoinLarge() { playSound(lootCoinLargeSounds_); }
|
||||||
void UISoundManager::playLootItem() { playSound(lootItemSounds_); }
|
void UiSoundManager::playLootItem() { playSound(lootItemSounds_); }
|
||||||
|
|
||||||
// Item sounds
|
// Item sounds
|
||||||
void UISoundManager::playDropOnGround() { playSound(dropSounds_); }
|
void UiSoundManager::playDropOnGround() { playSound(dropSounds_); }
|
||||||
void UISoundManager::playPickupBag() { playSound(pickupBagSounds_); }
|
void UiSoundManager::playPickupBag() { playSound(pickupBagSounds_); }
|
||||||
void UISoundManager::playPickupBook() { playSound(pickupBookSounds_); }
|
void UiSoundManager::playPickupBook() { playSound(pickupBookSounds_); }
|
||||||
void UISoundManager::playPickupCloth() { playSound(pickupClothSounds_); }
|
void UiSoundManager::playPickupCloth() { playSound(pickupClothSounds_); }
|
||||||
void UISoundManager::playPickupFood() { playSound(pickupFoodSounds_); }
|
void UiSoundManager::playPickupFood() { playSound(pickupFoodSounds_); }
|
||||||
void UISoundManager::playPickupGem() { playSound(pickupGemSounds_); }
|
void UiSoundManager::playPickupGem() { playSound(pickupGemSounds_); }
|
||||||
|
|
||||||
// Eating/drinking
|
// Eating/drinking
|
||||||
void UISoundManager::playEating() { playSound(eatingSounds_); }
|
void UiSoundManager::playEating() { playSound(eatingSounds_); }
|
||||||
void UISoundManager::playDrinking() { playSound(drinkingSounds_); }
|
void UiSoundManager::playDrinking() { playSound(drinkingSounds_); }
|
||||||
|
|
||||||
// Level up
|
// Level up
|
||||||
void UISoundManager::playLevelUp() { playSound(levelUpSounds_); }
|
void UiSoundManager::playLevelUp() { playSound(levelUpSounds_); }
|
||||||
|
|
||||||
// Error/feedback
|
// Error/feedback
|
||||||
void UISoundManager::playError() { playSound(errorSounds_); }
|
void UiSoundManager::playError() { playSound(errorSounds_); }
|
||||||
void UISoundManager::playTargetSelect() { playSound(selectTargetSounds_); }
|
void UiSoundManager::playTargetSelect() { playSound(selectTargetSounds_); }
|
||||||
void UISoundManager::playTargetDeselect() { playSound(deselectTargetSounds_); }
|
void UiSoundManager::playTargetDeselect() { playSound(deselectTargetSounds_); }
|
||||||
|
|
||||||
} // namespace audio
|
} // namespace audio
|
||||||
} // namespace wowee
|
} // namespace wowee
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,10 @@
|
||||||
#include "audio/mount_sound_manager.hpp"
|
#include "audio/mount_sound_manager.hpp"
|
||||||
#include "audio/npc_voice_manager.hpp"
|
#include "audio/npc_voice_manager.hpp"
|
||||||
#include "audio/ambient_sound_manager.hpp"
|
#include "audio/ambient_sound_manager.hpp"
|
||||||
|
#include "audio/ui_sound_manager.hpp"
|
||||||
|
#include "audio/combat_sound_manager.hpp"
|
||||||
|
#include "audio/spell_sound_manager.hpp"
|
||||||
|
#include "audio/movement_sound_manager.hpp"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtx/euler_angles.hpp>
|
#include <glm/gtx/euler_angles.hpp>
|
||||||
|
|
@ -346,6 +350,10 @@ bool Renderer::initialize(core::Window* win) {
|
||||||
mountSoundManager = std::make_unique<audio::MountSoundManager>();
|
mountSoundManager = std::make_unique<audio::MountSoundManager>();
|
||||||
npcVoiceManager = std::make_unique<audio::NpcVoiceManager>();
|
npcVoiceManager = std::make_unique<audio::NpcVoiceManager>();
|
||||||
ambientSoundManager = std::make_unique<audio::AmbientSoundManager>();
|
ambientSoundManager = std::make_unique<audio::AmbientSoundManager>();
|
||||||
|
uiSoundManager = std::make_unique<audio::UiSoundManager>();
|
||||||
|
combatSoundManager = std::make_unique<audio::CombatSoundManager>();
|
||||||
|
spellSoundManager = std::make_unique<audio::SpellSoundManager>();
|
||||||
|
movementSoundManager = std::make_unique<audio::MovementSoundManager>();
|
||||||
|
|
||||||
// Underwater full-screen tint overlay (applies to all world geometry).
|
// Underwater full-screen tint overlay (applies to all world geometry).
|
||||||
underwaterOverlayShader = std::make_unique<Shader>();
|
underwaterOverlayShader = std::make_unique<Shader>();
|
||||||
|
|
@ -2204,6 +2212,18 @@ bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::
|
||||||
if (ambientSoundManager) {
|
if (ambientSoundManager) {
|
||||||
ambientSoundManager->initialize(assetManager);
|
ambientSoundManager->initialize(assetManager);
|
||||||
}
|
}
|
||||||
|
if (uiSoundManager) {
|
||||||
|
uiSoundManager->initialize(assetManager);
|
||||||
|
}
|
||||||
|
if (combatSoundManager) {
|
||||||
|
combatSoundManager->initialize(assetManager);
|
||||||
|
}
|
||||||
|
if (spellSoundManager) {
|
||||||
|
spellSoundManager->initialize(assetManager);
|
||||||
|
}
|
||||||
|
if (movementSoundManager) {
|
||||||
|
movementSoundManager->initialize(assetManager);
|
||||||
|
}
|
||||||
cachedAssetManager = assetManager;
|
cachedAssetManager = assetManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2291,6 +2311,18 @@ bool Renderer::loadTerrainArea(const std::string& mapName, int centerX, int cent
|
||||||
if (ambientSoundManager && cachedAssetManager) {
|
if (ambientSoundManager && cachedAssetManager) {
|
||||||
ambientSoundManager->initialize(cachedAssetManager);
|
ambientSoundManager->initialize(cachedAssetManager);
|
||||||
}
|
}
|
||||||
|
if (uiSoundManager && cachedAssetManager) {
|
||||||
|
uiSoundManager->initialize(cachedAssetManager);
|
||||||
|
}
|
||||||
|
if (combatSoundManager && cachedAssetManager) {
|
||||||
|
combatSoundManager->initialize(cachedAssetManager);
|
||||||
|
}
|
||||||
|
if (spellSoundManager && cachedAssetManager) {
|
||||||
|
spellSoundManager->initialize(cachedAssetManager);
|
||||||
|
}
|
||||||
|
if (movementSoundManager && cachedAssetManager) {
|
||||||
|
movementSoundManager->initialize(cachedAssetManager);
|
||||||
|
}
|
||||||
|
|
||||||
// Wire ambient sound manager to terrain manager for emitter registration
|
// Wire ambient sound manager to terrain manager for emitter registration
|
||||||
if (terrainManager && ambientSoundManager) {
|
if (terrainManager && ambientSoundManager) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,13 @@
|
||||||
#include "audio/music_manager.hpp"
|
#include "audio/music_manager.hpp"
|
||||||
#include "audio/footstep_manager.hpp"
|
#include "audio/footstep_manager.hpp"
|
||||||
#include "audio/activity_sound_manager.hpp"
|
#include "audio/activity_sound_manager.hpp"
|
||||||
|
#include "audio/mount_sound_manager.hpp"
|
||||||
|
#include "audio/npc_voice_manager.hpp"
|
||||||
|
#include "audio/ambient_sound_manager.hpp"
|
||||||
|
#include "audio/ui_sound_manager.hpp"
|
||||||
|
#include "audio/combat_sound_manager.hpp"
|
||||||
|
#include "audio/spell_sound_manager.hpp"
|
||||||
|
#include "audio/movement_sound_manager.hpp"
|
||||||
#include "pipeline/asset_manager.hpp"
|
#include "pipeline/asset_manager.hpp"
|
||||||
#include "pipeline/dbc_loader.hpp"
|
#include "pipeline/dbc_loader.hpp"
|
||||||
#include "pipeline/blp_loader.hpp"
|
#include "pipeline/blp_loader.hpp"
|
||||||
|
|
@ -4039,19 +4046,36 @@ void GameScreen::renderSettingsWindow() {
|
||||||
pendingVsync = window->isVsyncEnabled();
|
pendingVsync = window->isVsyncEnabled();
|
||||||
pendingShadows = renderer ? renderer->areShadowsEnabled() : true;
|
pendingShadows = renderer ? renderer->areShadowsEnabled() : true;
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
|
// Load volumes from all audio managers
|
||||||
if (auto* music = renderer->getMusicManager()) {
|
if (auto* music = renderer->getMusicManager()) {
|
||||||
pendingMusicVolume = music->getVolume();
|
pendingMusicVolume = music->getVolume();
|
||||||
}
|
}
|
||||||
|
if (auto* ambient = renderer->getAmbientSoundManager()) {
|
||||||
|
pendingAmbientVolume = static_cast<int>(ambient->getVolumeScale() * 100.0f + 0.5f);
|
||||||
|
}
|
||||||
|
if (auto* ui = renderer->getUiSoundManager()) {
|
||||||
|
pendingUiVolume = static_cast<int>(ui->getVolumeScale() * 100.0f + 0.5f);
|
||||||
|
}
|
||||||
|
if (auto* combat = renderer->getCombatSoundManager()) {
|
||||||
|
pendingCombatVolume = static_cast<int>(combat->getVolumeScale() * 100.0f + 0.5f);
|
||||||
|
}
|
||||||
|
if (auto* spell = renderer->getSpellSoundManager()) {
|
||||||
|
pendingSpellVolume = static_cast<int>(spell->getVolumeScale() * 100.0f + 0.5f);
|
||||||
|
}
|
||||||
|
if (auto* movement = renderer->getMovementSoundManager()) {
|
||||||
|
pendingMovementVolume = static_cast<int>(movement->getVolumeScale() * 100.0f + 0.5f);
|
||||||
|
}
|
||||||
if (auto* footstep = renderer->getFootstepManager()) {
|
if (auto* footstep = renderer->getFootstepManager()) {
|
||||||
float scale = footstep->getVolumeScale();
|
pendingFootstepVolume = static_cast<int>(footstep->getVolumeScale() * 100.0f + 0.5f);
|
||||||
pendingSfxVolume = static_cast<int>(scale * 100.0f + 0.5f);
|
}
|
||||||
if (pendingSfxVolume < 0) pendingSfxVolume = 0;
|
if (auto* npcVoice = renderer->getNpcVoiceManager()) {
|
||||||
if (pendingSfxVolume > 100) pendingSfxVolume = 100;
|
pendingNpcVoiceVolume = static_cast<int>(npcVoice->getVolumeScale() * 100.0f + 0.5f);
|
||||||
} else if (auto* activity = renderer->getActivitySoundManager()) {
|
}
|
||||||
float scale = activity->getVolumeScale();
|
if (auto* mount = renderer->getMountSoundManager()) {
|
||||||
pendingSfxVolume = static_cast<int>(scale * 100.0f + 0.5f);
|
pendingMountVolume = static_cast<int>(mount->getVolumeScale() * 100.0f + 0.5f);
|
||||||
if (pendingSfxVolume < 0) pendingSfxVolume = 0;
|
}
|
||||||
if (pendingSfxVolume > 100) pendingSfxVolume = 100;
|
if (auto* activity = renderer->getActivitySoundManager()) {
|
||||||
|
pendingActivityVolume = static_cast<int>(activity->getVolumeScale() * 100.0f + 0.5f);
|
||||||
}
|
}
|
||||||
if (auto* cameraController = renderer->getCameraController()) {
|
if (auto* cameraController = renderer->getCameraController()) {
|
||||||
pendingMouseSensitivity = cameraController->getMouseSensitivity();
|
pendingMouseSensitivity = cameraController->getMouseSensitivity();
|
||||||
|
|
@ -4080,7 +4104,7 @@ void GameScreen::renderSettingsWindow() {
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
float screenW = io.DisplaySize.x;
|
float screenW = io.DisplaySize.x;
|
||||||
float screenH = io.DisplaySize.y;
|
float screenH = io.DisplaySize.y;
|
||||||
ImVec2 size(440.0f, 520.0f);
|
ImVec2 size(520.0f, std::min(screenH * 0.9f, 720.0f));
|
||||||
ImVec2 pos((screenW - size.x) * 0.5f, (screenH - size.y) * 0.5f);
|
ImVec2 pos((screenW - size.x) * 0.5f, (screenH - size.y) * 0.5f);
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(pos, ImGuiCond_Always);
|
ImGui::SetNextWindowPos(pos, ImGuiCond_Always);
|
||||||
|
|
@ -4092,60 +4116,148 @@ void GameScreen::renderSettingsWindow() {
|
||||||
ImGui::Text("Settings");
|
ImGui::Text("Settings");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::Text("Video");
|
if (ImGui::BeginTabBar("SettingsTabs", ImGuiTabBarFlags_None)) {
|
||||||
ImGui::Checkbox("Fullscreen", &pendingFullscreen);
|
// ============================================================
|
||||||
ImGui::Checkbox("VSync", &pendingVsync);
|
// VIDEO TAB
|
||||||
ImGui::Checkbox("Shadows", &pendingShadows);
|
// ============================================================
|
||||||
|
if (ImGui::BeginTabItem("Video")) {
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Checkbox("Fullscreen", &pendingFullscreen);
|
||||||
|
ImGui::Checkbox("VSync", &pendingVsync);
|
||||||
|
ImGui::Checkbox("Shadows", &pendingShadows);
|
||||||
|
|
||||||
const char* resLabel = "Resolution";
|
const char* resLabel = "Resolution";
|
||||||
const char* resItems[kResCount];
|
const char* resItems[kResCount];
|
||||||
char resBuf[kResCount][16];
|
char resBuf[kResCount][16];
|
||||||
for (int i = 0; i < kResCount; i++) {
|
for (int i = 0; i < kResCount; i++) {
|
||||||
snprintf(resBuf[i], sizeof(resBuf[i]), "%dx%d", kResolutions[i][0], kResolutions[i][1]);
|
snprintf(resBuf[i], sizeof(resBuf[i]), "%dx%d", kResolutions[i][0], kResolutions[i][1]);
|
||||||
resItems[i] = resBuf[i];
|
resItems[i] = resBuf[i];
|
||||||
}
|
}
|
||||||
ImGui::Combo(resLabel, &pendingResIndex, resItems, kResCount);
|
ImGui::Combo(resLabel, &pendingResIndex, resItems, kResCount);
|
||||||
if (ImGui::Button("Restore Video Defaults", ImVec2(-1, 0))) {
|
|
||||||
pendingFullscreen = kDefaultFullscreen;
|
|
||||||
pendingVsync = kDefaultVsync;
|
|
||||||
pendingShadows = kDefaultShadows;
|
|
||||||
pendingResIndex = defaultResIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
if (ImGui::Button("Restore Video Defaults", ImVec2(-1, 0))) {
|
||||||
|
pendingFullscreen = kDefaultFullscreen;
|
||||||
|
pendingVsync = kDefaultVsync;
|
||||||
|
pendingShadows = kDefaultShadows;
|
||||||
|
pendingResIndex = defaultResIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================
|
||||||
|
// AUDIO TAB
|
||||||
|
// ============================================================
|
||||||
|
if (ImGui::BeginTabItem("Audio")) {
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::BeginChild("AudioSettings", ImVec2(0, 360), true);
|
||||||
|
|
||||||
|
ImGui::Text("Master Volume");
|
||||||
|
ImGui::SliderInt("##MasterVolume", &pendingMasterVolume, 0, 100, "%d%%");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
ImGui::Text("Audio");
|
ImGui::Text("Music");
|
||||||
ImGui::SliderInt("Music Volume", &pendingMusicVolume, 0, 100, "%d");
|
ImGui::SliderInt("##MusicVolume", &pendingMusicVolume, 0, 100, "%d%%");
|
||||||
ImGui::SliderInt("SFX Volume", &pendingSfxVolume, 0, 100, "%d");
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Ambient Sounds");
|
||||||
|
ImGui::SliderInt("##AmbientVolume", &pendingAmbientVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Weather, zones, cities, emitters");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("UI Sounds");
|
||||||
|
ImGui::SliderInt("##UiVolume", &pendingUiVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Buttons, loot, quest complete");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Combat Sounds");
|
||||||
|
ImGui::SliderInt("##CombatVolume", &pendingCombatVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Weapon swings, impacts, grunts");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Spell Sounds");
|
||||||
|
ImGui::SliderInt("##SpellVolume", &pendingSpellVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Magic casting and impacts");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Movement Sounds");
|
||||||
|
ImGui::SliderInt("##MovementVolume", &pendingMovementVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Water splashes, jump/land");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Footsteps");
|
||||||
|
ImGui::SliderInt("##FootstepVolume", &pendingFootstepVolume, 0, 100, "%d%%");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("NPC Voices");
|
||||||
|
ImGui::SliderInt("##NpcVoiceVolume", &pendingNpcVoiceVolume, 0, 100, "%d%%");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Mount Sounds");
|
||||||
|
ImGui::SliderInt("##MountVolume", &pendingMountVolume, 0, 100, "%d%%");
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Text("Activity Sounds");
|
||||||
|
ImGui::SliderInt("##ActivityVolume", &pendingActivityVolume, 0, 100, "%d%%");
|
||||||
|
ImGui::TextWrapped("Swimming, eating, drinking");
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
|
||||||
if (ImGui::Button("Restore Audio Defaults", ImVec2(-1, 0))) {
|
if (ImGui::Button("Restore Audio Defaults", ImVec2(-1, 0))) {
|
||||||
|
pendingMasterVolume = 100;
|
||||||
pendingMusicVolume = kDefaultMusicVolume;
|
pendingMusicVolume = kDefaultMusicVolume;
|
||||||
pendingSfxVolume = kDefaultSfxVolume;
|
pendingAmbientVolume = 100;
|
||||||
|
pendingUiVolume = 100;
|
||||||
|
pendingCombatVolume = 100;
|
||||||
|
pendingSpellVolume = 100;
|
||||||
|
pendingMovementVolume = 100;
|
||||||
|
pendingFootstepVolume = 100;
|
||||||
|
pendingNpcVoiceVolume = 100;
|
||||||
|
pendingMountVolume = 100;
|
||||||
|
pendingActivityVolume = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::EndTabItem();
|
||||||
ImGui::Separator();
|
}
|
||||||
ImGui::Spacing();
|
|
||||||
|
|
||||||
ImGui::Text("Controls");
|
// ============================================================
|
||||||
ImGui::SliderFloat("Mouse Sensitivity", &pendingMouseSensitivity, 0.05f, 1.0f, "%.2f");
|
// GAMEPLAY TAB
|
||||||
ImGui::Checkbox("Invert Mouse", &pendingInvertMouse);
|
// ============================================================
|
||||||
if (ImGui::Button("Restore Control Defaults", ImVec2(-1, 0))) {
|
if (ImGui::BeginTabItem("Gameplay")) {
|
||||||
pendingMouseSensitivity = kDefaultMouseSensitivity;
|
ImGui::Spacing();
|
||||||
pendingInvertMouse = kDefaultInvertMouse;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Text("Controls");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Spacing();
|
ImGui::SliderFloat("Mouse Sensitivity", &pendingMouseSensitivity, 0.05f, 1.0f, "%.2f");
|
||||||
|
ImGui::Checkbox("Invert Mouse", &pendingInvertMouse);
|
||||||
|
|
||||||
ImGui::Text("Interface");
|
ImGui::Spacing();
|
||||||
ImGui::SliderInt("UI Opacity", &pendingUiOpacity, 20, 100, "%d%%");
|
ImGui::Spacing();
|
||||||
ImGui::Checkbox("Rotate Minimap", &pendingMinimapRotate);
|
|
||||||
if (ImGui::Button("Restore Interface Defaults", ImVec2(-1, 0))) {
|
ImGui::Text("Interface");
|
||||||
pendingUiOpacity = 65;
|
ImGui::Separator();
|
||||||
pendingMinimapRotate = false;
|
ImGui::SliderInt("UI Opacity", &pendingUiOpacity, 20, 100, "%d%%");
|
||||||
|
ImGui::Checkbox("Rotate Minimap", &pendingMinimapRotate);
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
if (ImGui::Button("Restore Gameplay Defaults", ImVec2(-1, 0))) {
|
||||||
|
pendingMouseSensitivity = kDefaultMouseSensitivity;
|
||||||
|
pendingInvertMouse = kDefaultInvertMouse;
|
||||||
|
pendingUiOpacity = 65;
|
||||||
|
pendingMinimapRotate = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|
@ -4164,16 +4276,40 @@ void GameScreen::renderSettingsWindow() {
|
||||||
if (auto* minimap = renderer->getMinimap()) {
|
if (auto* minimap = renderer->getMinimap()) {
|
||||||
minimap->setRotateWithCamera(minimapRotate_);
|
minimap->setRotateWithCamera(minimapRotate_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply all audio volume settings
|
||||||
|
float masterScale = static_cast<float>(pendingMasterVolume) / 100.0f;
|
||||||
if (auto* music = renderer->getMusicManager()) {
|
if (auto* music = renderer->getMusicManager()) {
|
||||||
music->setVolume(pendingMusicVolume);
|
music->setVolume(static_cast<int>(pendingMusicVolume * masterScale));
|
||||||
|
}
|
||||||
|
if (auto* ambient = renderer->getAmbientSoundManager()) {
|
||||||
|
ambient->setVolumeScale(pendingAmbientVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* ui = renderer->getUiSoundManager()) {
|
||||||
|
ui->setVolumeScale(pendingUiVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* combat = renderer->getCombatSoundManager()) {
|
||||||
|
combat->setVolumeScale(pendingCombatVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* spell = renderer->getSpellSoundManager()) {
|
||||||
|
spell->setVolumeScale(pendingSpellVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* movement = renderer->getMovementSoundManager()) {
|
||||||
|
movement->setVolumeScale(pendingMovementVolume / 100.0f * masterScale);
|
||||||
}
|
}
|
||||||
float sfxScale = static_cast<float>(pendingSfxVolume) / 100.0f;
|
|
||||||
if (auto* footstep = renderer->getFootstepManager()) {
|
if (auto* footstep = renderer->getFootstepManager()) {
|
||||||
footstep->setVolumeScale(sfxScale);
|
footstep->setVolumeScale(pendingFootstepVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* npcVoice = renderer->getNpcVoiceManager()) {
|
||||||
|
npcVoice->setVolumeScale(pendingNpcVoiceVolume / 100.0f * masterScale);
|
||||||
|
}
|
||||||
|
if (auto* mount = renderer->getMountSoundManager()) {
|
||||||
|
mount->setVolumeScale(pendingMountVolume / 100.0f * masterScale);
|
||||||
}
|
}
|
||||||
if (auto* activity = renderer->getActivitySoundManager()) {
|
if (auto* activity = renderer->getActivitySoundManager()) {
|
||||||
activity->setVolumeScale(sfxScale);
|
activity->setVolumeScale(pendingActivityVolume / 100.0f * masterScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto* cameraController = renderer->getCameraController()) {
|
if (auto* cameraController = renderer->getCameraController()) {
|
||||||
cameraController->setMouseSensitivity(pendingMouseSensitivity);
|
cameraController->setMouseSensitivity(pendingMouseSensitivity);
|
||||||
cameraController->setInvertMouse(pendingInvertMouse);
|
cameraController->setInvertMouse(pendingInvertMouse);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue