From cf3d627327e6acdf0ead9ecff9d35d6589e77d45 Mon Sep 17 00:00:00 2001 From: bookmist Date: Thu, 15 May 2025 13:54:35 +0300 Subject: [PATCH] vita3k: Migration from SDL2 to SDL3 --- .github/workflows/c-cpp.yml | 18 - .gitmodules | 5 +- CMakeLists.txt | 7 + external/CMakeLists.txt | 14 +- external/sdl | 2 +- external/sdl2-cmake-scripts | 1 - lang/system/en-gb.xml | 2 +- lang/system/en.xml | 2 +- lang/system/fr.xml | 2 +- lang/system/ja.xml | 2 +- lang/system/pl.xml | 2 +- lang/system/pt-br.xml | 2 +- lang/system/ru.xml | 2 +- lang/system/zh-s.xml | 2 +- lang/system/zh-t.xml | 2 +- lang/user/id.xml | 2 +- lang/user/ms.xml | 2 +- lang/user/ua.xml | 2 +- vita3k/CMakeLists.txt | 8 +- vita3k/app/CMakeLists.txt | 2 +- vita3k/app/src/app.cpp | 5 +- vita3k/app/src/app_init.cpp | 109 +----- vita3k/audio/CMakeLists.txt | 4 +- vita3k/audio/include/audio/impl/sdl_audio.h | 24 +- vita3k/audio/include/audio/state.h | 40 +-- vita3k/audio/src/audio.cpp | 125 +------ vita3k/audio/src/impl/cubeb_audio.cpp | 6 +- vita3k/audio/src/impl/sdl_audio.cpp | 111 ++++-- vita3k/ctrl/CMakeLists.txt | 2 +- vita3k/ctrl/include/ctrl/state.h | 23 +- vita3k/ctrl/src/ctrl.cpp | 176 ++++----- vita3k/gui/CMakeLists.txt | 2 +- vita3k/gui/include/gui/imgui_impl_sdl.h | 1 - vita3k/gui/src/app_context_menu.cpp | 4 +- vita3k/gui/src/common_dialog.cpp | 2 +- vita3k/gui/src/controllers_dialog.cpp | 229 ++++++------ vita3k/gui/src/imgui_impl_sdl.cpp | 335 +++++++++--------- vita3k/gui/src/imgui_impl_sdl_gl3.cpp | 5 - vita3k/gui/src/imgui_impl_sdl_vulkan.cpp | 2 - vita3k/gui/src/information_bar.cpp | 2 +- vita3k/gui/src/settings_dialog.cpp | 4 +- vita3k/gui/src/vita3k_update.cpp | 4 +- vita3k/interface.cpp | 85 +++-- vita3k/kernel/CMakeLists.txt | 2 +- vita3k/kernel/src/kernel.cpp | 10 +- vita3k/lang/include/lang/state.h | 2 +- vita3k/main.cpp | 13 +- vita3k/modules/CMakeLists.txt | 2 +- vita3k/modules/SceAudio/SceAudio.cpp | 16 +- vita3k/modules/SceAudioIn/SceAudioIn.cpp | 36 +- .../SceCommonDialog/SceCommonDialog.cpp | 2 +- vita3k/modules/SceCtrl/SceCtrl.cpp | 4 +- vita3k/modules/SceGxm/SceGxm.cpp | 1 - vita3k/modules/ScePower/ScePower.cpp | 2 +- vita3k/motion/CMakeLists.txt | 2 +- vita3k/motion/include/motion/event_handler.h | 22 ++ vita3k/motion/src/motion.cpp | 112 +++--- vita3k/renderer/CMakeLists.txt | 2 +- vita3k/renderer/include/renderer/gl/state.h | 2 - vita3k/renderer/include/renderer/gl/types.h | 4 +- vita3k/renderer/src/gl/renderer.cpp | 5 +- vita3k/renderer/src/vulkan/pipeline_cache.cpp | 4 +- vita3k/renderer/src/vulkan/renderer.cpp | 14 +- .../renderer/src/vulkan/screen_renderer.cpp | 10 +- vita3k/touch/CMakeLists.txt | 2 +- vita3k/touch/include/touch/functions.h | 2 +- vita3k/touch/include/touch/touch.h | 2 +- vita3k/touch/src/touch.cpp | 32 +- 68 files changed, 740 insertions(+), 946 deletions(-) delete mode 160000 external/sdl2-cmake-scripts create mode 100644 vita3k/motion/include/motion/event_handler.h diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index 3746f75c5..ef8dbb736 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -88,24 +88,6 @@ jobs: choco install ccache if: matrix.os == 'windows-latest' - - name: Set up SDL 2.30.11 (ubuntu-22.04) - run: | - SDL2VER=2.30.11 - if [[ ! -e ~/.ccache ]]; then - mkdir ~/.ccache - fi - cd ~/.ccache - if [[ ! -e SDL2-${SDL2VER} ]]; then - curl -sLO https://libsdl.org/release/SDL2-${SDL2VER}.tar.gz - tar -xzf SDL2-${SDL2VER}.tar.gz - cd SDL2-${SDL2VER} - ./configure --prefix=/usr/local - make && cd ../ - rm SDL2-${SDL2VER}.tar.gz - fi - sudo make -C SDL2-${SDL2VER} install - if: matrix.os == 'ubuntu-22.04' - - name: Set up linuxdeploy (ubuntu-22.04, appimage) run: | if [[ ! -e linuxdeploy-x86_64.AppImage ]]; then diff --git a/.gitmodules b/.gitmodules index bbade4f76..85b8fcf54 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,10 +40,7 @@ url = https://github.com/zeux/pugixml [submodule "external/sdl"] path = external/sdl - url = https://github.com/Vita3K/sdl -[submodule "external/sdl2-cmake-scripts"] - path = external/sdl2-cmake-scripts - url = https://github.com/tcbrindle/sdl2-cmake-scripts + url = https://github.com/libsdl-org/SDL.git [submodule "external/spdlog"] path = external/spdlog url = https://github.com/gabime/spdlog diff --git a/CMakeLists.txt b/CMakeLists.txt index 704002b87..7540b56cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,13 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0) +# workaround for SDL due to cmake bug +# https://github.com/libsdl-org/SDL/issues/6454 +# https://gitlab.kitware.com/cmake/cmake/-/issues/24104 +if(APPLE) + enable_language(OBJC) +endif() + option(USE_DISCORD_RICH_PRESENCE "Build Vita3K with Discord Rich Presence" ON) option(USE_VITA3K_UPDATE "Build Vita3K with updater." ON) option(BUILD_APPIMAGE "Build an AppImage." OFF) diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index a7052457b..12e72a94d 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -91,19 +91,7 @@ target_include_directories(imgui PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/imgui" add_library(miniz STATIC miniz/miniz.c miniz/miniz.h) target_include_directories(miniz PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/miniz") -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/sdl2-cmake-scripts") - -if(APPLE) - set(SDL2_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sdl/macos" CACHE PATH "Where SDL2 is located" FORCE) -elseif(WIN32) - set(SDL2_PATH "${CMAKE_CURRENT_SOURCE_DIR}/sdl/windows" CACHE PATH "Where SDL2 is located" FORCE) - set(SDL2_INCLUDE_DIR "${SDL2_PATH}/include" CACHE PATH "Where the SDL2 include files can be found" FORCE) -endif() - -find_package(SDL2 REQUIRED) -add_library(sdl2 INTERFACE) -target_include_directories(sdl2 INTERFACE "${SDL2_INCLUDE_DIR}") -target_link_libraries(sdl2 INTERFACE "${SDL2_LIBRARY}") +add_subdirectory(sdl) # Cubeb setup, from https://github.com/RPCS3/rpcs3/blob/master/3rdparty/cubeb/CMakeLists.txt set(BUILD_SHARED_LIBS FALSE CACHE BOOL "Don't build shared libs") diff --git a/external/sdl b/external/sdl index 6d973c851..17656d051 160000 --- a/external/sdl +++ b/external/sdl @@ -1 +1 @@ -Subproject commit 6d973c85105c8e4a9e5458e4504e712cecec6aa9 +Subproject commit 17656d051b750b945fdd8b4608f9524c7879bc1b diff --git a/external/sdl2-cmake-scripts b/external/sdl2-cmake-scripts deleted file mode 160000 index e037fb54f..000000000 --- a/external/sdl2-cmake-scripts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e037fb54f32973343fada6a051d3a3f8adf3a4a0 diff --git a/lang/system/en-gb.xml b/lang/system/en-gb.xml index 6b1b20d25..a82506ea3 100644 --- a/lang/system/en-gb.xml +++ b/lang/system/en-gb.xml @@ -294,7 +294,7 @@ Error code: {} Green Blue No compatible controllers connected. -Connect a controller that is compatible with SDL2. +Connect a controller that is compatible with SDL3. Disable Motion Reset Controller Binding diff --git a/lang/system/en.xml b/lang/system/en.xml index 4ef23af76..d979d46a0 100644 --- a/lang/system/en.xml +++ b/lang/system/en.xml @@ -294,7 +294,7 @@ Error code: {} Green Blue No compatible controllers connected. -Connect a controller that is compatible with SDL2. +Connect a controller that is compatible with SDL3. Disable Motion Reset Controller Binding diff --git a/lang/system/fr.xml b/lang/system/fr.xml index 7810947ef..4bed59ce2 100644 --- a/lang/system/fr.xml +++ b/lang/system/fr.xml @@ -242,7 +242,7 @@ Code d'erreur: {} {} contrôleurs connectés Num Aucun contrôleur compatible n'est connecté. -Connecter un contrôleur compatible avec SDL2. +Connecter un contrôleur compatible avec SDL3. diff --git a/lang/system/ja.xml b/lang/system/ja.xml index 28ef9c716..d58cba7ba 100644 --- a/lang/system/ja.xml +++ b/lang/system/ja.xml @@ -273,7 +273,7 @@ 利用可能なコントローラーが接続されていません。 -SDL2に対応したコントローラーを接続してください。 +SDL3に対応したコントローラーを接続してください。 ボタン割り当てをリセット diff --git a/lang/system/pl.xml b/lang/system/pl.xml index 431a0f060..6ce484d16 100644 --- a/lang/system/pl.xml +++ b/lang/system/pl.xml @@ -291,7 +291,7 @@ Kod błędu: {} Zielony Niebieski Niepodłączono żadnego ze wspieranych kontrolerów. -Proszę, podłącz kontroler, który jest kompatybilny z SDL2. +Proszę, podłącz kontroler, który jest kompatybilny z SDL3. Restuj przypisanie przycisków kontrollera diff --git a/lang/system/pt-br.xml b/lang/system/pt-br.xml index da3b8c25f..57c9b7ea7 100644 --- a/lang/system/pt-br.xml +++ b/lang/system/pt-br.xml @@ -238,7 +238,7 @@ Código de erro: {} {} controles conectados Núm Nenhum controle compatível conectado. -Conecte um controle que seja compatível com SDL2. +Conecte um controle que seja compatível com SDL3. diff --git a/lang/system/ru.xml b/lang/system/ru.xml index ce544ec98..5aec9b174 100644 --- a/lang/system/ru.xml +++ b/lang/system/ru.xml @@ -274,7 +274,7 @@ Зеленый Синий Не подключены совместимые контроллеры. -Подключите контроллер, совместимый с SDL2. +Подключите контроллер, совместимый с SDL3. Сброс привязки элементов управления diff --git a/lang/system/zh-s.xml b/lang/system/zh-s.xml index 9dc889e57..8057a1502 100644 --- a/lang/system/zh-s.xml +++ b/lang/system/zh-s.xml @@ -293,7 +293,7 @@ 绿 未连接兼容的控制器。 -请连接与SDL2兼容的控制器。 +请连接与SDL3兼容的控制器。 禁用体感 重置控制器绑定 diff --git a/lang/system/zh-t.xml b/lang/system/zh-t.xml index d3ed601b8..58d28405f 100644 --- a/lang/system/zh-t.xml +++ b/lang/system/zh-t.xml @@ -293,7 +293,7 @@ 未接入相容的控制器。 -請接入與SDL2相容的控制器。 +請接入與SDL3相容的控制器。 停用體感 重設控制器繫結 diff --git a/lang/user/id.xml b/lang/user/id.xml index 3a467bc4d..e4c682c66 100644 --- a/lang/user/id.xml +++ b/lang/user/id.xml @@ -284,7 +284,7 @@ Kode kesalahan: {} Hijau Biru Gak ada kontroler kompatibel yang tersambung. -Sambungkan Kontroleryang kompatibel dengan SDL2. +Sambungkan Kontroleryang kompatibel dengan SDL3. Reset Ulang Pengikatan Kontroller diff --git a/lang/user/ms.xml b/lang/user/ms.xml index 0ccdcae73..9ca348d94 100644 --- a/lang/user/ms.xml +++ b/lang/user/ms.xml @@ -287,7 +287,7 @@ Kod ralat: {} Hijau Biru Tiada Kontroler serasi disambungkan. -Sila sambungkan Kontroler yang serasi dengan SDL2. +Sila sambungkan Kontroler yang serasi dengan SDL3. Tetapkan Semula Pengikat Kontroler diff --git a/lang/user/ua.xml b/lang/user/ua.xml index 8e7ac75db..a1a0cf156 100644 --- a/lang/user/ua.xml +++ b/lang/user/ua.xml @@ -292,7 +292,7 @@ Зелений Синій Сумісні контролери не підключені. -Будь ласка, підключіть контролер, сумісний з SDL2. +Будь ласка, підключіть контролер, сумісний з SDL3. Скинути налаштування елементів керування контролера diff --git a/vita3k/CMakeLists.txt b/vita3k/CMakeLists.txt index e254b4820..af53a1515 100644 --- a/vita3k/CMakeLists.txt +++ b/vita3k/CMakeLists.txt @@ -137,7 +137,7 @@ if(WIN32) target_sources(vita3k PRIVATE util/src/vc_runtime_checker.cpp) endif() -target_link_libraries(vita3k PRIVATE app config cppcommon ctrl display gdbstub gui gxm io miniz modules packages patch renderer shader touch util) +target_link_libraries(vita3k PRIVATE app config cppcommon ctrl display gdbstub gui gxm io miniz modules motion packages patch renderer shader touch util) if(USE_DISCORD_RICH_PRESENCE) target_link_libraries(vita3k PRIVATE discord-rpc) endif() @@ -175,8 +175,7 @@ if(APPLE) POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/../data" "$/../Resources/data" COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/../lang" "$/../Resources/lang" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/shaders-builtin/" "$/../Resources/shaders-builtin" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/external/sdl/macos/SDL2.framework" "$/../Frameworks/SDL2.framework") + COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/shaders-builtin/" "$/../Resources/shaders-builtin") if(USE_VITA3K_UPDATE) add_custom_command( TARGET vita3k @@ -257,8 +256,7 @@ elseif(WIN32) POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/../data" "$/data" COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/../lang" "$/lang" - COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/shaders-builtin" "$/shaders-builtin" - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${PROJECT_SOURCE_DIR}/external/sdl/windows/lib/x64/SDL2.dll" "$") + COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/shaders-builtin" "$/shaders-builtin") if(USE_VITA3K_UPDATE) add_custom_command( TARGET vita3k diff --git a/vita3k/app/CMakeLists.txt b/vita3k/app/CMakeLists.txt index c8910a7d8..f3d4cf6eb 100644 --- a/vita3k/app/CMakeLists.txt +++ b/vita3k/app/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(app PUBLIC emuenv mem) if(USE_DISCORD_RICH_PRESENCE) target_link_libraries(app PUBLIC discord-rpc) endif() -target_link_libraries(app PRIVATE audio config display gdbstub gui io ngs renderer) +target_link_libraries(app PRIVATE audio config display gdbstub gui io ngs renderer SDL3::SDL3) if(WIN32) target_link_libraries(app PRIVATE dwmapi) endif() diff --git a/vita3k/app/src/app.cpp b/vita3k/app/src/app.cpp index 32202e151..d8bf119e8 100644 --- a/vita3k/app/src/app.cpp +++ b/vita3k/app/src/app.cpp @@ -24,12 +24,13 @@ #include #include -#include +#include +#include namespace app { void error_dialog(const std::string &message, SDL_Window *window) { - if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", message.c_str(), window) < 0) { + if (!SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", message.c_str(), window)) { LOG_ERROR("SDL Error: {}", message); } } diff --git a/vita3k/app/src/app_init.cpp b/vita3k/app/src/app_init.cpp index 06d95da4b..1fe1560ee 100644 --- a/vita3k/app/src/app_init.cpp +++ b/vita3k/app/src/app_init.cpp @@ -41,20 +41,13 @@ #include -#include -#include -#include +#include +#include #ifdef _WIN32 -#include #include #endif -#ifdef __LINUX__ -#include -#include -#endif - namespace app { void update_viewport(EmuEnvState &state) { int w = 0; @@ -64,24 +57,12 @@ void update_viewport(EmuEnvState &state) { state.window_size.x = w; state.window_size.y = h; - switch (state.renderer->current_backend) { - case renderer::Backend::OpenGL: - SDL_GL_GetDrawableSize(state.window.get(), &w, &h); - break; - - case renderer::Backend::Vulkan: - SDL_Vulkan_GetDrawableSize(state.window.get(), &w, &h); - break; - - default: - LOG_ERROR("Unimplemented backend renderer: {}.", static_cast(state.renderer->current_backend)); - break; - } - + SDL_GetWindowSizeInPixels(state.window.get(), &w, &h); state.drawable_size.x = w; state.drawable_size.y = h; - state.system_dpi_scale = static_cast(state.drawable_size.x) / state.window_size.x; + state.system_dpi_scale = SDL_GetWindowPixelDensity(state.window.get()); + state.manual_dpi_scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindow(state.window.get())); ImGui::GetIO().FontGlobalScale = 1.f * state.manual_dpi_scale; if (h > 0) { @@ -155,7 +136,6 @@ void update_viewport(EmuEnvState &state) { void init_paths(Root &root_paths) { auto sdl_base_path = SDL_GetBasePath(); auto base_path = fs_utils::utf8_to_path(sdl_base_path); - SDL_free(sdl_base_path); root_paths.set_base_path(base_path); root_paths.set_static_assets_path(base_path); @@ -279,63 +259,6 @@ void init_paths(Root &root_paths) { fs::create_directories(root_paths.get_patch_path()); } -#ifdef __LINUX__ -static float fetch_x11_display_dpi() { - int dpi = 96; - - Display *display; - char *resourceString; - XrmDatabase db; - XrmValue value; - char *type; - - // Xrm initialization - XrmInitialize(); - - // Open the display - display = XOpenDisplay(NULL); - if (!display) { - LOG_INFO("Unable to open X display"); - return 1.0; - } - - // Get the resource manager string from the X server - resourceString = XResourceManagerString(display); - if (!resourceString) { - LOG_INFO("No resource manager string found"); - XCloseDisplay(display); - return 1.0; - } - - db = XrmGetStringDatabase(resourceString); - - // Search for the Xft.dpi value - if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value)) { - if (type && strcmp(type, "String") == 0) { - dpi = std::stoi(value.addr); - } else { - LOG_INFO("Xft.dpi found but not a string"); - } - } else { - LOG_INFO("Xft.dpi not found in X resources"); - } - - XCloseDisplay(display); - - // If that failed, try the GDK_SCALE environment variable - if (dpi <= 0) { - const char *gdk_scale = getenv("GDK_SCALE"); - if (gdk_scale) { - dpi = std::stoi(gdk_scale) * 96; - } else { - LOG_INFO("GDK_SCALE not found in environment"); - } - } - - return dpi > 96 ? (float)dpi / 96 : 1.0; -} -#endif - bool init(EmuEnvState &state, Config &cfg, const Root &root_paths) { state.cfg = std::move(cfg); @@ -402,33 +325,25 @@ bool init(EmuEnvState &state, Config &cfg, const Root &root_paths) { if (state.cfg.fullscreen) { state.display.fullscreen = true; - window_type |= SDL_WINDOW_FULLSCREEN_DESKTOP; + window_type |= SDL_WINDOW_FULLSCREEN; } -#ifdef __LINUX__ - if (SDL_GetCurrentVideoDriver() && std::string(SDL_GetCurrentVideoDriver()) == "x11") { - // X11 does not provide High DPI support, so manually set the High DPI scale - state.manual_dpi_scale = fetch_x11_display_dpi(); - if (state.manual_dpi_scale < 1.0) { - state.manual_dpi_scale = 1.0; - } - } -#endif + state.manual_dpi_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); - state.window = WindowPtr(SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DEFAULT_RES_WIDTH * state.manual_dpi_scale, DEFAULT_RES_HEIGHT * state.manual_dpi_scale, window_type | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI), SDL_DestroyWindow); + state.window = WindowPtr(SDL_CreateWindow(window_title, DEFAULT_RES_WIDTH * state.manual_dpi_scale, DEFAULT_RES_HEIGHT * state.manual_dpi_scale, window_type | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY), SDL_DestroyWindow); if (!state.window) { LOG_ERROR("SDL failed to create window!"); return false; } + state.manual_dpi_scale = SDL_GetDisplayContentScale(SDL_GetDisplayForWindow(state.window.get())); #ifdef _WIN32 // Disable round corners for the game window - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - SDL_GetWindowWMInfo(state.window.get(), &wm_info); const auto window_preference = DWMWCP_DONOTROUND; - DwmSetWindowAttribute(wm_info.info.win.window, DWMWA_WINDOW_CORNER_PREFERENCE, &window_preference, sizeof(window_preference)); + HWND hwnd = (HWND)SDL_GetPointerProperty(SDL_GetWindowProperties(state.window.get()), SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); + if (hwnd) + DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, &window_preference, sizeof(window_preference)); #endif // initialize the renderer first because we need to know if we need a page table diff --git a/vita3k/audio/CMakeLists.txt b/vita3k/audio/CMakeLists.txt index 8f6947ae0..d40563aef 100644 --- a/vita3k/audio/CMakeLists.txt +++ b/vita3k/audio/CMakeLists.txt @@ -6,5 +6,5 @@ add_library( src/impl/cubeb_audio.cpp) target_include_directories(audio PUBLIC include) -target_link_libraries(audio PUBLIC sdl2) -target_link_libraries(audio PRIVATE tracy util cubeb kernel) +target_link_libraries(audio PUBLIC SDL3::SDL3) +target_link_libraries(audio PRIVATE util cubeb kernel) diff --git a/vita3k/audio/include/audio/impl/sdl_audio.h b/vita3k/audio/include/audio/impl/sdl_audio.h index 0b5773571..1900b8a5b 100644 --- a/vita3k/audio/include/audio/impl/sdl_audio.h +++ b/vita3k/audio/include/audio/impl/sdl_audio.h @@ -19,9 +19,14 @@ #include "../state.h" +#include + class SDLAudioAdapter : public AudioAdapter { +private: SDL_AudioDeviceID device_id = 0; - SDL_AudioSpec spec{}; + int device_buffer_samples = 0; + SDL_AudioSpec dst_spec; + static void SDLCALL thread_wakeup_callback(void *userdata, SDL_AudioStream *stream, int additional_amount, int total_amount); public: SDLAudioAdapter(AudioState &audio_state); @@ -29,4 +34,21 @@ public: bool init() override; void switch_state(const bool pause) override; + AudioOutPortPtr open_port(int nb_channels, int freq, int nb_sample) override; + void audio_output(ThreadState &thread, AudioOutPort &out_port, const void *buffer) override; + void set_volume(AudioOutPort &out_port, float volume) override; + int get_rest_sample(AudioOutPort &out_port) override; +}; + +typedef std::shared_ptr AudioStreamPtr; + +struct SDLAudioOutPort : public AudioOutPort { + // thread currently waiting for the audio to be processed + SceUID thread = -1; + int channels = 2; + AudioStreamPtr stream; + SDLAudioAdapter &adapter; + SDLAudioOutPort(AudioStreamPtr stream, AudioAdapter &adapter) + : stream(std::move(stream)) + , adapter(dynamic_cast(adapter)) {} }; diff --git a/vita3k/audio/include/audio/state.h b/vita3k/audio/include/audio/state.h index eb603c04c..d1b6ccbc4 100644 --- a/vita3k/audio/include/audio/state.h +++ b/vita3k/audio/include/audio/state.h @@ -19,8 +19,6 @@ #include -#include - #include #include #include @@ -30,7 +28,6 @@ #define SCE_AUDIO_OUT_MAX_VOL 32768 //!< Maximum output port volume #define SCE_AUDIO_VOLUME_0DB SCE_AUDIO_OUT_MAX_VOL //!< Maximum output port volume -typedef std::shared_ptr AudioStreamPtr; typedef std::function ResumeAudioThread; struct AudioOutPort { @@ -51,49 +48,24 @@ struct AudioOutPort { int len = 0; int freq = 0; int mode = 0; - - std::mutex mutex; - // stream to get the data - AudioStreamPtr stream; - // thread currently waiting for the audio to be processed - SceUID thread = -1; }; typedef std::shared_ptr AudioOutPortPtr; typedef std::map AudioOutPortPtrs; struct AudioInPort { - SDL_AudioDeviceID id; + void *id = nullptr; bool running = false; int len_bytes = 0; }; -struct AudioSpec { - int freq; - // number of samples to be processed per callback per channel - int nb_samples = 0; - // value for silence - uint8_t silence; -}; - struct ThreadState; struct AudioState; // abstract class that need to be overloaded with an audio implementation class AudioAdapter { -private: - // buffer used to mix audio - std::vector temp_buffer; - -protected: - AudioState &state; - // are we using a single stream and mixing everything inside or multiple streams? - bool single_stream = true; - public: - // called by subclasses once they get called by their implementation callback - // stream points to the location where we need to write state.ro.len_bytes bytes - void audio_callback(uint8_t *stream, int len_bytes); + AudioState &state; AudioAdapter(AudioState &audio_state) : state(audio_state) {} @@ -104,13 +76,12 @@ public: virtual void audio_output(ThreadState &thread, AudioOutPort &out_port, const void *buffer) {} virtual void set_volume(AudioOutPort &out_port, float volume) {} virtual void switch_state(const bool pause) {} - + virtual int get_rest_sample(AudioOutPort &out_port) { return 0; }; friend struct AudioState; }; struct AudioState { - AudioSpec spec; - // the adapter must be before out_ports for the destructors to work correctly + // the adapter must be before out_ports for the destructors to work correctly std::unique_ptr adapter; std::mutex mutex; int next_port_id = 1; @@ -118,7 +89,7 @@ struct AudioState { AudioInPort in_port; ResumeAudioThread resume_thread; std::string audio_backend; - float global_volume; + float global_volume = 1; bool init(const ResumeAudioThread &resume_thread, const std::string &adapter_name); void set_backend(const std::string &adapter_name); @@ -127,4 +98,5 @@ struct AudioState { void set_volume(AudioOutPort &out_port, float volume); void set_global_volume(float volume); void switch_state(const bool pause); + int get_rest_sample(AudioOutPort &out_port); }; diff --git a/vita3k/audio/src/audio.cpp b/vita3k/audio/src/audio.cpp index c67c25ab4..ff59af373 100644 --- a/vita3k/audio/src/audio.cpp +++ b/vita3k/audio/src/audio.cpp @@ -17,8 +17,6 @@ #include