From ed14359c87bc6ed9781d151cbb1f34b9fe045f4c Mon Sep 17 00:00:00 2001 From: rainmakerv2 <30595646+rainmakerv3@users.noreply.github.com> Date: Sun, 16 Nov 2025 16:36:54 +0800 Subject: [PATCH] Re-implement custom trophy sounds using sdl3 mixer (#3805) * re-implement custom trophy sounds using sdl3 mixer * fix build vars * Don't change SDL version --- .gitmodules | 4 ++ CMakeLists.txt | 3 +- externals/CMakeLists.txt | 12 +++++ externals/sdl3_mixer | 1 + src/core/libraries/np/trophy_ui.cpp | 73 ++++++++++++----------------- src/core/libraries/np/trophy_ui.h | 4 ++ 6 files changed, 52 insertions(+), 45 deletions(-) create mode 160000 externals/sdl3_mixer diff --git a/.gitmodules b/.gitmodules index 43ba2a7c1..b8d1544e4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -113,3 +113,7 @@ [submodule "externals/json"] path = externals/json url = https://github.com/nlohmann/json.git +[submodule "externals/sdl3_mixer"] + path = externals/sdl3_mixer + url = https://github.com/libsdl-org/SDL_mixer + shallow = true diff --git a/CMakeLists.txt b/CMakeLists.txt index d26581790..1491a3e1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,6 +229,7 @@ find_package(magic_enum 0.9.7 CONFIG) find_package(PNG 1.6 MODULE) find_package(RenderDoc 1.6.0 MODULE) find_package(SDL3 3.1.2 CONFIG) +find_package(SDL3_mixer 2.8.1 CONFIG) find_package(stb MODULE) find_package(toml11 4.2.0 CONFIG) find_package(tsl-robin-map 1.3.0 CONFIG) @@ -1070,7 +1071,7 @@ add_executable(shadps4 create_target_directory_groups(shadps4) target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG) -target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json) +target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 SDL3_mixer::SDL3_mixer pugixml::pugixml stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json) target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h") target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h") diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index a26f58d69..a45a03bf6 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -63,6 +63,18 @@ if (NOT TARGET SDL3::SDL3) add_subdirectory(sdl3) endif() +# SDL3_mixer +if (NOT TARGET SDL3_Mixer::SDL3_Mixer) + set(SDLMIXER_FLAC OFF) + set(SDLMIXER_OGG OFF) + set(SDLMIXER_MOD OFF) + set(SDLMIXER_MIDI OFF) + set(SDLMIXER_OPUS OFF) + set(SDLMIXER_WAVPACK OFF) + set(BUILD_SHARED_LIBS OFF) + add_subdirectory(sdl3_mixer) +endif() + # vulkan-headers if (NOT TARGET Vulkan::Headers) set(VULKAN_HEADERS_ENABLE_MODULE OFF) diff --git a/externals/sdl3_mixer b/externals/sdl3_mixer new file mode 160000 index 000000000..4182794ea --- /dev/null +++ b/externals/sdl3_mixer @@ -0,0 +1 @@ +Subproject commit 4182794ea45fe28568728670c6f1583855d0e85c diff --git a/src/core/libraries/np/trophy_ui.cpp b/src/core/libraries/np/trophy_ui.cpp index 94e7eb5f2..b803403c4 100644 --- a/src/core/libraries/np/trophy_ui.cpp +++ b/src/core/libraries/np/trophy_ui.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -92,59 +91,45 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin AddLayer(this); - bool customsoundplayed = false; -#ifdef ENABLE_QT_GUI - QString musicPathWav = QString::fromStdString(CustomTrophy_Dir.string() + "/trophy.wav"); - QString musicPathMp3 = QString::fromStdString(CustomTrophy_Dir.string() + "/trophy.mp3"); - if (fs::exists(musicPathWav.toStdString())) { - BackgroundMusicPlayer::getInstance().setVolume(100); - BackgroundMusicPlayer::getInstance().playMusic(musicPathWav, false); - customsoundplayed = true; - } else if (fs::exists(musicPathMp3.toStdString())) { - BackgroundMusicPlayer::getInstance().setVolume(100); - BackgroundMusicPlayer::getInstance().playMusic(musicPathMp3, false); - customsoundplayed = true; + MIX_Init(); + mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL); + if (!mixer) { + LOG_ERROR(Lib_NpTrophy, "Could not initialize SDL Mixer, {}", SDL_GetError()); + return; } -#endif - if (!customsoundplayed) { + MIX_SetMasterGain(mixer, static_cast(Config::getVolumeSlider() / 100.f)); + auto musicPathMp3 = CustomTrophy_Dir / "trophy.mp3"; + auto musicPathWav = CustomTrophy_Dir / "trophy.wav"; + + if (std::filesystem::exists(musicPathMp3)) { + audio = MIX_LoadAudio(mixer, musicPathMp3.string().c_str(), false); + } else if (std::filesystem::exists(musicPathWav)) { + audio = MIX_LoadAudio(mixer, musicPathWav.string().c_str(), false); + } else { auto soundFile = resource.open("src/images/trophy.wav"); std::vector soundData = std::vector(soundFile.begin(), soundFile.end()); + audio = + MIX_LoadAudio_IO(mixer, SDL_IOFromMem(soundData.data(), soundData.size()), false, true); + // due to low volume of default sound file + MIX_SetMasterGain(mixer, MIX_GetMasterGain(mixer) * 1.3f); + } - SDL_AudioSpec spec; - Uint8* audioBuf; - Uint32 audioLen; + if (!audio) { + LOG_ERROR(Lib_NpTrophy, "Could not loud audio file, {}", SDL_GetError()); + return; + } - if (!SDL_LoadWAV_IO(SDL_IOFromMem(soundData.data(), soundData.size()), true, &spec, - &audioBuf, &audioLen)) { - LOG_ERROR(Lib_NpTrophy, "Cannot load trophy sound: {}", SDL_GetError()); - SDL_free(audioBuf); - return; - } - - SDL_AudioStream* stream = - SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, nullptr, nullptr); - if (!stream) { - LOG_ERROR(Lib_NpTrophy, "Cannot create audio stream for trophy sound: {}", - SDL_GetError()); - SDL_free(audioBuf); - return; - } - - if (!SDL_PutAudioStreamData(stream, audioBuf, audioLen)) { - LOG_ERROR(Lib_NpTrophy, "Cannot add trophy sound data to stream: {}", SDL_GetError()); - SDL_free(audioBuf); - return; - } - - // Set audio gain 20% higher since audio file itself is soft - SDL_SetAudioStreamGain(stream, Config::getVolumeSlider() / 100.0f * 1.2f); - SDL_ResumeAudioStreamDevice(stream); - SDL_free(audioBuf); + if (!MIX_PlayAudio(mixer, audio)) { + LOG_ERROR(Lib_NpTrophy, "Could not play audio file, {}", SDL_GetError()); } } TrophyUI::~TrophyUI() { + MIX_DestroyAudio(audio); + MIX_DestroyMixer(mixer); + MIX_Quit(); + Finish(); } diff --git a/src/core/libraries/np/trophy_ui.h b/src/core/libraries/np/trophy_ui.h index fbadac8f4..2734471b3 100644 --- a/src/core/libraries/np/trophy_ui.h +++ b/src/core/libraries/np/trophy_ui.h @@ -5,6 +5,7 @@ #include #include +#include #include #include "common/fixed_value.h" @@ -30,6 +31,9 @@ private: std::string_view trophy_type; ImGui::RefCountedTexture trophy_icon; ImGui::RefCountedTexture trophy_type_icon; + + MIX_Mixer* mixer; + MIX_Audio* audio; }; struct TrophyInfo {