diff --git a/.gitmodules b/.gitmodules index 59978ec3..6981e9f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,9 +16,6 @@ [submodule "thirdparty/msdf-atlas-gen"] path = thirdparty/msdf-atlas-gen url = https://github.com/Chlumsky/msdf-atlas-gen.git -[submodule "thirdparty/miniaudio"] - path = thirdparty/miniaudio - url = https://github.com/mackron/miniaudio [submodule "thirdparty/vcpkg"] path = thirdparty/vcpkg url = https://github.com/microsoft/vcpkg @@ -58,9 +55,6 @@ [submodule "thirdparty/unordered_dense"] path = thirdparty/unordered_dense url = https://github.com/martinus/unordered_dense.git -[submodule "thirdparty/vorbis"] - path = thirdparty/vorbis - url = https://gitlab.xiph.org/xiph/vorbis.git -[submodule "thirdparty/ogg"] - path = thirdparty/ogg - url = https://gitlab.xiph.org/xiph/ogg.git +[submodule "thirdparty/SDL_mixer"] + path = thirdparty/SDL_mixer + url = https://github.com/libsdl-org/SDL_mixer \ No newline at end of file diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 20753538..e45beef9 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -7,7 +7,7 @@ endif() if (CMAKE_SYSTEM_NAME MATCHES "Linux") option(SWA_FLATPAK "Configure the build for Flatpak compatibility." OFF) -endif() +endif() option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF) @@ -53,14 +53,14 @@ add_compile_options( -Wno-int-to-void-pointer-cast -Wno-invalid-offsetof -Wno-null-arithmetic - -Wno-null-conversion + -Wno-null-conversion -Wno-tautological-undefined-compare -) - -if (WIN32) - add_compile_options(/fp:strict) -else() - add_compile_options(-ffp-model=strict) +) + +if (WIN32) + add_compile_options(/fp:strict) +else() + add_compile_options(-ffp-model=strict) endif() add_compile_definitions( @@ -187,46 +187,46 @@ set(SWA_INSTALL_CXX_SOURCES "install/hashes/mazuri.cpp" "install/hashes/spagonia.cpp" "install/hashes/update.cpp" -) - +) + set(SWA_USER_CXX_SOURCES "user/achievement_data.cpp" "user/config.cpp" -) - -set(SWA_THIRDPARTY_SOURCES - "${SWA_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp" - "${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp" - "${SWA_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp" - "${SWA_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp" - "${SWA_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp" - "${SWA_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp" - "${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c" - "${SWA_THIRDPARTY_ROOT}/tiny-AES-c/aes.c" - "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source/smolv.cpp" -) - -set(SWA_THIRDPARTY_INCLUDES - "${SWA_THIRDPARTY_ROOT}/concurrentqueue" +) + +set(SWA_THIRDPARTY_SOURCES + "${SWA_THIRDPARTY_ROOT}/imgui/backends/imgui_impl_sdl2.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_demo.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_draw.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_tables.cpp" + "${SWA_THIRDPARTY_ROOT}/imgui/imgui_widgets.cpp" + "${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack/lzxd.c" + "${SWA_THIRDPARTY_ROOT}/tiny-AES-c/aes.c" + "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source/smolv.cpp" +) + +set(SWA_THIRDPARTY_INCLUDES + "${SWA_THIRDPARTY_ROOT}/concurrentqueue" "${SWA_THIRDPARTY_ROOT}/ddspp" - "${SWA_THIRDPARTY_ROOT}/imgui" + "${SWA_THIRDPARTY_ROOT}/imgui" "${SWA_THIRDPARTY_ROOT}/libmspack/libmspack/mspack" - "${SWA_THIRDPARTY_ROOT}/magic_enum/include" + "${SWA_THIRDPARTY_ROOT}/magic_enum/include" "${SWA_THIRDPARTY_ROOT}/miniaudio" - "${SWA_THIRDPARTY_ROOT}/stb" - "${SWA_THIRDPARTY_ROOT}/tiny-AES-c" + "${SWA_THIRDPARTY_ROOT}/stb" + "${SWA_THIRDPARTY_ROOT}/tiny-AES-c" "${SWA_THIRDPARTY_ROOT}/TinySHA1" "${SWA_THIRDPARTY_ROOT}/unordered_dense/include" - "${SWA_THIRDPARTY_ROOT}/volk" - "${SWA_THIRDPARTY_ROOT}/Vulkan-Headers/include" - "${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include" - "${SWA_TOOLS_ROOT}/bc_diff" + "${SWA_THIRDPARTY_ROOT}/volk" + "${SWA_THIRDPARTY_ROOT}/Vulkan-Headers/include" + "${SWA_THIRDPARTY_ROOT}/VulkanMemoryAllocator/include" + "${SWA_TOOLS_ROOT}/bc_diff" "${SWA_TOOLS_ROOT}/ShaderRecomp/thirdparty/smol-v/source" -) - -if (SWA_D3D12) - list(APPEND SWA_THIRDPARTY_INCLUDES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include") - list(APPEND SWA_THIRDPARTY_SOURCES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp") +) + +if (SWA_D3D12) + list(APPEND SWA_THIRDPARTY_INCLUDES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/include") + list(APPEND SWA_THIRDPARTY_SOURCES "${SWA_THIRDPARTY_ROOT}/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp") endif() set_source_files_properties(${SWA_THIRDPARTY_SOURCES} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) @@ -248,7 +248,7 @@ set(SWA_CXX_SOURCES ${SWA_PATCHES_CXX_SOURCES} ${SWA_UI_CXX_SOURCES} ${SWA_INSTALL_CXX_SOURCES} - ${SWA_USER_CXX_SOURCES} + ${SWA_USER_CXX_SOURCES} ${SWA_THIRDPARTY_SOURCES} ) @@ -261,7 +261,7 @@ else() add_executable(UnleashedRecomp ${SWA_CXX_SOURCES}) endif() -set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) +set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) if (SWA_FLATPAK) target_compile_definitions(UnleashedRecomp PRIVATE "GAME_INSTALL_DIRECTORY=\"/var/data\"") @@ -273,7 +273,7 @@ if (SWA_D3D12) target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12) endif() -find_package(directx-dxc REQUIRED) +find_package(directx-dxc REQUIRED) if (SWA_D3D12) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) @@ -289,7 +289,7 @@ if (SWA_D3D12) Microsoft::DirectX-Headers Microsoft::DirectX-Guids Microsoft::DirectX12-Agility - Microsoft::DirectXShaderCompiler + Microsoft::DirectXShaderCompiler Microsoft::DXIL dxgi ) @@ -307,21 +307,22 @@ if (WIN32) endif() target_link_libraries(UnleashedRecomp PRIVATE - fmt::fmt + fmt::fmt libzstd_static msdf-atlas-gen::msdf-atlas-gen nfd::nfd o1heap PowerUtils SDL2::SDL2-static + SDL2_mixer tomlplusplus::tomlplusplus UnleashedRecompLib - Vorbis::vorbisfile - xxHash::xxhash ) + xxHash::xxhash +) target_include_directories(UnleashedRecomp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - "${CMAKE_CURRENT_SOURCE_DIR}/api" + "${CMAKE_CURRENT_SOURCE_DIR}/api" ${SWA_THIRDPARTY_INCLUDES} ) diff --git a/UnleashedRecomp/apu/embedded_player.cpp b/UnleashedRecomp/apu/embedded_player.cpp index 2fb899d0..e72b7b6a 100644 --- a/UnleashedRecomp/apu/embedded_player.cpp +++ b/UnleashedRecomp/apu/embedded_player.cpp @@ -10,82 +10,6 @@ #include #include -#pragma region libvorbis -static ma_result ma_decoding_backend_init__libvorbis(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libvorbis* pVorbis; - - (void)pUserData; - - pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks); - if (pVorbis == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libvorbis_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pVorbis); - if (result != MA_SUCCESS) { - ma_free(pVorbis, pAllocationCallbacks); - return result; - } - - *ppBackend = pVorbis; - - return MA_SUCCESS; -} - -static ma_result ma_decoding_backend_init_file__libvorbis(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend) -{ - ma_result result; - ma_libvorbis* pVorbis; - - (void)pUserData; - - pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks); - if (pVorbis == NULL) { - return MA_OUT_OF_MEMORY; - } - - result = ma_libvorbis_init_file(pFilePath, pConfig, pAllocationCallbacks, pVorbis); - if (result != MA_SUCCESS) { - ma_free(pVorbis, pAllocationCallbacks); - return result; - } - - *ppBackend = pVorbis; - - return MA_SUCCESS; -} - -static void ma_decoding_backend_uninit__libvorbis(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks) -{ - ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend; - - (void)pUserData; - - ma_libvorbis_uninit(pVorbis, pAllocationCallbacks); - ma_free(pVorbis, pAllocationCallbacks); -} - -static ma_result ma_decoding_backend_get_channel_map__libvorbis(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap) -{ - ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend; - - (void)pUserData; - - return ma_libvorbis_get_data_format(pVorbis, NULL, NULL, NULL, pChannelMap, channelMapCap); -} - -static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis = -{ - ma_decoding_backend_init__libvorbis, - ma_decoding_backend_init_file__libvorbis, - NULL, /* onInitFileW() */ - NULL, /* onInitMemory() */ - ma_decoding_backend_uninit__libvorbis -}; -#pragma endregion - enum class EmbeddedSound { SysWorldMapCursor, @@ -101,12 +25,10 @@ enum class EmbeddedSound struct EmbeddedSoundData { static const int SimultaneousLimit = 4; - std::array, SimultaneousLimit> sounds; - std::array, SimultaneousLimit> decoders; - int oldestIndex = 0; + Mix_Chunk* chunk{}; + int channelIndex{}; }; -static ma_engine g_audioEngine = {}; static std::array g_embeddedSoundData = {}; static const std::unordered_map g_embeddedSoundMap = { @@ -122,111 +44,56 @@ static const std::unordered_map g_embeddedSound static void PlayEmbeddedSound(EmbeddedSound s) { EmbeddedSoundData &data = g_embeddedSoundData[size_t(s)]; - int pickedIndex = -1; - for (int i = 0; (i < EmbeddedSoundData::SimultaneousLimit) && (pickedIndex < 0); i++) + if (data.chunk == nullptr) { - if (data.sounds[i] == nullptr) + // The sound hasn't been created yet, create it and pick it. + const void *soundData = nullptr; + size_t soundDataSize = 0; + switch (s) { - // The sound hasn't been created yet, create it and pick it. - const void *soundData = nullptr; - size_t soundDataSize = 0; - switch (s) - { - case EmbeddedSound::SysWorldMapCursor: - soundData = g_sys_worldmap_cursor; - soundDataSize = sizeof(g_sys_worldmap_cursor); - break; - case EmbeddedSound::SysWorldMapFinalDecide: - soundData = g_sys_worldmap_finaldecide; - soundDataSize = sizeof(g_sys_worldmap_finaldecide); - break; - case EmbeddedSound::SysActStgPauseCansel: - soundData = g_sys_actstg_pausecansel; - soundDataSize = sizeof(g_sys_actstg_pausecansel); - break; - case EmbeddedSound::SysActStgPauseCursor: - soundData = g_sys_actstg_pausecursor; - soundDataSize = sizeof(g_sys_actstg_pausecursor); - break; - case EmbeddedSound::SysActStgPauseDecide: - soundData = g_sys_actstg_pausedecide; - soundDataSize = sizeof(g_sys_actstg_pausedecide); - break; - case EmbeddedSound::SysActStgPauseWinClose: - soundData = g_sys_actstg_pausewinclose; - soundDataSize = sizeof(g_sys_actstg_pausewinclose); - break; - case EmbeddedSound::SysActStgPauseWinOpen: - soundData = g_sys_actstg_pausewinopen; - soundDataSize = sizeof(g_sys_actstg_pausewinopen); - break; - default: - assert(false && "Unknown embedded sound."); - return; - } - - ma_decoding_backend_vtable* pCustomBackendVTables[] = - { - &g_ma_decoding_backend_vtable_libvorbis - }; - - ma_decoder_config decoderConfig = ma_decoder_config_init_default(); - decoderConfig.pCustomBackendUserData = NULL; - decoderConfig.ppCustomBackendVTables = pCustomBackendVTables; - decoderConfig.customBackendCount = std::size(pCustomBackendVTables); - - ma_result res; - data.decoders[i] = std::make_unique(); - res = ma_decoder_init_memory(soundData, soundDataSize, &decoderConfig, data.decoders[i].get()); - if (res != MA_SUCCESS) - { - fprintf(stderr, "ma_decoder_init_memory failed with error code %d.\n", res); - return; - } - - data.sounds[i] = std::make_unique(); - res = ma_sound_init_from_data_source(&g_audioEngine, data.decoders[i].get(), MA_SOUND_FLAG_DECODE, nullptr, data.sounds[i].get()); - if (res != MA_SUCCESS) - { - fprintf(stderr, "ma_sound_init_from_data_source failed with error code %d.\n", res); - return; - } - - pickedIndex = i; - } - else if (ma_sound_at_end(data.sounds[i].get())) - { - // A sound has reached the end, pick it. - pickedIndex = i; + case EmbeddedSound::SysWorldMapCursor: + soundData = g_sys_worldmap_cursor; + soundDataSize = sizeof(g_sys_worldmap_cursor); + break; + case EmbeddedSound::SysWorldMapFinalDecide: + soundData = g_sys_worldmap_finaldecide; + soundDataSize = sizeof(g_sys_worldmap_finaldecide); + break; + case EmbeddedSound::SysActStgPauseCansel: + soundData = g_sys_actstg_pausecansel; + soundDataSize = sizeof(g_sys_actstg_pausecansel); + break; + case EmbeddedSound::SysActStgPauseCursor: + soundData = g_sys_actstg_pausecursor; + soundDataSize = sizeof(g_sys_actstg_pausecursor); + break; + case EmbeddedSound::SysActStgPauseDecide: + soundData = g_sys_actstg_pausedecide; + soundDataSize = sizeof(g_sys_actstg_pausedecide); + break; + case EmbeddedSound::SysActStgPauseWinClose: + soundData = g_sys_actstg_pausewinclose; + soundDataSize = sizeof(g_sys_actstg_pausewinclose); + break; + case EmbeddedSound::SysActStgPauseWinOpen: + soundData = g_sys_actstg_pausewinopen; + soundDataSize = sizeof(g_sys_actstg_pausewinopen); + break; + default: + assert(false && "Unknown embedded sound."); + return; } + + data.chunk = Mix_LoadWAV_RW(SDL_RWFromConstMem(soundData, soundDataSize), 1); } - if (pickedIndex < 0) - { - // No free slots are available, pick the oldest one. - pickedIndex = data.oldestIndex; - data.oldestIndex = (data.oldestIndex + 1) % EmbeddedSoundData::SimultaneousLimit; - } - - if (data.sounds[pickedIndex] != nullptr) - { - ma_sound_set_volume(data.sounds[pickedIndex].get(), Config::EffectsVolume); - ma_sound_seek_to_pcm_frame(data.sounds[pickedIndex].get(), 0); - ma_sound_start(data.sounds[pickedIndex].get()); - } + Mix_PlayChannel(data.channelIndex % EmbeddedSoundData::SimultaneousLimit, data.chunk, 0); + ++data.channelIndex; } void EmbeddedPlayer::Init() { - ma_engine_config engineConfig = ma_engine_config_init(); - engineConfig.channels = XAUDIO_NUM_CHANNELS; - engineConfig.sampleRate = XAUDIO_SAMPLES_HZ; - - ma_result res = ma_engine_init(&engineConfig, &g_audioEngine); - if (res != MA_SUCCESS) - { - fprintf(stderr, "ma_engine_init failed with error code %d.\n", res); - } + Mix_OpenAudio(XAUDIO_SAMPLES_HZ, AUDIO_F32SYS, XAUDIO_NUM_CHANNELS, 256); s_isActive = true; } @@ -241,11 +108,6 @@ void EmbeddedPlayer::Play(const char *name) return; } - if (g_audioEngine.pDevice == nullptr) - { - return; - } - PlayEmbeddedSound(it->second); } @@ -253,37 +115,12 @@ void EmbeddedPlayer::Shutdown() { for (EmbeddedSoundData &data : g_embeddedSoundData) { - for (auto &sound : data.sounds) - { - if (sound != nullptr) - { - if (sound->pDataSource != nullptr) - { - ma_sound_uninit(sound.get()); - } - - sound.reset(); - } - } - - for (auto &decoder : data.decoders) - { - if (decoder != nullptr) - { - if (decoder->pBackend != nullptr) - { - ma_decoder_uninit(decoder.get()); - } - - decoder.reset(); - } - } + if (data.chunk != nullptr) + Mix_FreeChunk(data.chunk); } - if (g_audioEngine.pDevice != nullptr) - { - ma_engine_uninit(&g_audioEngine); - } + Mix_CloseAudio(); + Mix_Quit(); s_isActive = false; } diff --git a/UnleashedRecomp/stdafx.cpp b/UnleashedRecomp/stdafx.cpp index 90aaf593..7a2e063c 100644 --- a/UnleashedRecomp/stdafx.cpp +++ b/UnleashedRecomp/stdafx.cpp @@ -1,10 +1,4 @@ #define STB_IMAGE_IMPLEMENTATION #include -#define MINIAUDIO_IMPLEMENTATION -#include - -#define ma_offset_pcm_frames_ptr (char*)ma_offset_pcm_frames_ptr -#include - #include "stdafx.h" diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index a0b541ca..ec224344 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -36,6 +36,7 @@ using Microsoft::WRL::ComPtr; #include #include #include +#include #include #include #include @@ -43,8 +44,6 @@ using Microsoft::WRL::ComPtr; #include #include #include -#include -#include #include #include diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 28f000da..6430650e 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -3,9 +3,17 @@ set(MSDF_ATLAS_USE_SKIA OFF) set(MSDF_ATLAS_NO_ARTERY_FONT ON) set(MSDFGEN_DISABLE_PNG ON) +set(SDL2MIXER_VENDORED ON) +set(SDL2MIXER_FLAC OFF) +set(SDL2MIXER_MOD OFF) +set(SDL2MIXER_MP3 OFF) +set(SDL2MIXER_MIDI OFF) +set(SDL2MIXER_OPUS OFF) +set(SDL2MIXER_VORBIS "VORBISFILE") +set(SDL2MIXER_WAVPACK OFF) + add_subdirectory("${SWA_THIRDPARTY_ROOT}/msdf-atlas-gen") add_subdirectory("${SWA_THIRDPARTY_ROOT}/nativefiledialog-extended") -add_subdirectory("${SWA_THIRDPARTY_ROOT}/ogg") add_subdirectory("${SWA_THIRDPARTY_ROOT}/o1heap") add_subdirectory("${SWA_THIRDPARTY_ROOT}/SDL") -add_subdirectory("${SWA_THIRDPARTY_ROOT}/vorbis") +add_subdirectory("${SWA_THIRDPARTY_ROOT}/SDL_mixer") diff --git a/thirdparty/SDL_mixer b/thirdparty/SDL_mixer new file mode 160000 index 00000000..43799269 --- /dev/null +++ b/thirdparty/SDL_mixer @@ -0,0 +1 @@ +Subproject commit 437992692cf9300f2b2f04be35adc7445a9055bf diff --git a/thirdparty/miniaudio b/thirdparty/miniaudio deleted file mode 160000 index 12a8d4e4..00000000 --- a/thirdparty/miniaudio +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 12a8d4e4911c5ab4f4c089b4d039433975ed8a66 diff --git a/thirdparty/ogg b/thirdparty/ogg deleted file mode 160000 index 7cf42ea1..00000000 --- a/thirdparty/ogg +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7cf42ea17aef7bc1b7b21af70724840a96c2e7d0 diff --git a/thirdparty/vorbis b/thirdparty/vorbis deleted file mode 160000 index 84c02369..00000000 --- a/thirdparty/vorbis +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 84c023699cdf023a32fa4ded32019f194afcdad0