From 0a48e85a3192188e320117090a27e7f943186a11 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 1/7] switch to SDL3 dep --- .ci/linux/build.sh | 4 +-- CMakeLists.txt | 34 +++++++++---------- CMakeModules/CopyYuzuSDLDeps.cmake | 2 +- CMakeModules/MinGWClangCross.cmake | 2 +- CMakeModules/MinGWCross.cmake | 2 +- cpmfile.json | 26 +++++++------- docs/Options.md | 4 +-- src/CMakeLists.txt | 2 +- src/android/app/build.gradle.kts | 2 +- src/audio_core/CMakeLists.txt | 6 ++-- src/audio_core/sink/sdl2_sink.cpp | 2 +- src/input_common/CMakeLists.txt | 6 ++-- src/input_common/drivers/sdl_driver.h | 2 +- src/yuzu/CMakeLists.txt | 6 ++-- src/yuzu/main.cpp | 2 +- src/yuzu_cmd/CMakeLists.txt | 2 +- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 2 +- .../emu_window/emu_window_sdl2_gl.cpp | 2 +- .../emu_window/emu_window_sdl2_null.cpp | 2 +- .../emu_window/emu_window_sdl2_vk.cpp | 2 +- src/yuzu_cmd/sdl_config.cpp | 2 +- 21 files changed, 57 insertions(+), 57 deletions(-) diff --git a/.ci/linux/build.sh b/.ci/linux/build.sh index 41e0ca308b..f46dd9bdf1 100755 --- a/.ci/linux/build.sh +++ b/.ci/linux/build.sh @@ -97,8 +97,8 @@ cmake .. -G Ninja \ -DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \ -DCMAKE_C_FLAGS="$ARCH_FLAGS" \ -DYUZU_USE_BUNDLED_QT=OFF \ - -DYUZU_USE_BUNDLED_SDL2=OFF \ - -DYUZU_USE_EXTERNAL_SDL2=ON \ + -DYUZU_USE_BUNDLED_SDL3=OFF \ + -DYUZU_USE_EXTERNAL_SDL3=ON \ -DYUZU_TESTS=OFF \ -DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \ -DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \ diff --git a/CMakeLists.txt b/CMakeLists.txt index a9ff2e9458..a690ebd119 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,14 +137,14 @@ if (PLATFORM_FREEBSD) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib") endif() -# Set bundled sdl2/qt as dependent options. -# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion -cmake_dependent_option(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" OFF) +# Set bundled sdl3/qt as dependent options. +# On Linux system SDL3 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion +cmake_dependent_option(ENABLE_SDL3 "Enable the SDL3 frontend" ON "NOT ANDROID" OFF) -if (ENABLE_SDL2) +if (ENABLE_SDL3) # TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system - cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" OFF "NOT MSVC" OFF) - option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}") + cmake_dependent_option(YUZU_USE_EXTERNAL_SDL3 "Compile external SDL3" OFF "NOT MSVC" OFF) + option(YUZU_USE_BUNDLED_SDL3 "Download bundled SDL3 build" "${MSVC}") endif() option(ENABLE_QT "Enable the Qt frontend" ON) @@ -215,7 +215,7 @@ option(YUZU_DOWNLOAD_ANDROID_VVL "Download validation layer binary for android" cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF) cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF) -cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL2;NOT ANDROID" OFF) +cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "ENABLE_SDL3;NOT ANDROID" OFF) cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR LINUX" OFF) @@ -609,10 +609,10 @@ if(ENABLE_CUBEB) endif() endif() -# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package -if (ENABLE_SDL2) - if (YUZU_USE_EXTERNAL_SDL2) - message(STATUS "Using SDL2 from externals.") +# find SDL3 exports a bunch of variables that are needed, so its easier to do this outside of the YUZU_find_package +if (ENABLE_SDL3) + if (YUZU_USE_EXTERNAL_SDL3) + message(STATUS "Using SDL3 from externals.") if (NOT WIN32) # Yuzu itself needs: Atomic Audio Events Joystick Haptic Sensor Threads Timers # Since 2.0.18 Atomic+Threads required for HIDAPI/libusb (see https://github.com/libsdl-org/SDL/issues/5095) @@ -635,16 +635,16 @@ if (ENABLE_SDL2) if ("${YUZU_SYSTEM_PROFILE}" STREQUAL "steamdeck") set(SDL_PIPEWIRE OFF) # build errors out with this on - AddJsonPackage("sdl2_steamdeck") + AddJsonPackage("sdl3_steamdeck") else() - AddJsonPackage("sdl2_generic") + AddJsonPackage("sdl3_generic") endif() - elseif (YUZU_USE_BUNDLED_SDL2) - message(STATUS "Using bundled SDL2") - AddJsonPackage(sdl2) + elseif (YUZU_USE_BUNDLED_SDL3) + message(STATUS "Using bundled SDL3") + AddJsonPackage(sdl3) endif() - find_package(SDL2 2.26.4 REQUIRED) + find_package(SDL3 3.2.22 REQUIRED) endif() # List of all FFmpeg components required diff --git a/CMakeModules/CopyYuzuSDLDeps.cmake b/CMakeModules/CopyYuzuSDLDeps.cmake index 464eed5e9c..c3935794ca 100644 --- a/CMakeModules/CopyYuzuSDLDeps.cmake +++ b/CMakeModules/CopyYuzuSDLDeps.cmake @@ -4,5 +4,5 @@ function(copy_yuzu_SDL_deps target_dir) include(WindowsCopyFiles) set(DLL_DEST "$/") - windows_copy_files(${target_dir} ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll) + windows_copy_files(${target_dir} ${SDL3_DLL_DIR} ${DLL_DEST} SDL3.dll) endfunction(copy_yuzu_SDL_deps) diff --git a/CMakeModules/MinGWClangCross.cmake b/CMakeModules/MinGWClangCross.cmake index 286a59a7ad..11ed402380 100644 --- a/CMakeModules/MinGWClangCross.cmake +++ b/CMakeModules/MinGWClangCross.cmake @@ -6,7 +6,7 @@ set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_PROCESSOR x86_64) set(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX}) -set(SDL2_PATH ${MINGW_PREFIX}) +set(SDL3_PATH ${MINGW_PREFIX}) set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-) # Specify the cross compiler diff --git a/CMakeModules/MinGWCross.cmake b/CMakeModules/MinGWCross.cmake index 61464f7dae..5cebe81a6e 100644 --- a/CMakeModules/MinGWCross.cmake +++ b/CMakeModules/MinGWCross.cmake @@ -9,7 +9,7 @@ set(CMAKE_HOST_WIN32 TRUE) set(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX}) -set(SDL2_PATH ${MINGW_PREFIX}) +set(SDL3_PATH ${MINGW_PREFIX}) set(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-) # Specify the cross compiler diff --git a/cpmfile.json b/cpmfile.json index f1fd5ce1cf..8c596b67ba 100644 --- a/cpmfile.json +++ b/cpmfile.json @@ -157,30 +157,30 @@ "hash": "99779ca9b6e040d36558cadf484f9ffdab5b47bcc8fc72e4d33639d1d60c0ceb4410d335ba445d72a4324e455167fd6769d99b459943aa135bec085dff2d4b7c", "find_args": "MODULE" }, - "sdl2_generic": { - "package": "SDL2", + "sdl3_generic": { + "package": "SDL3", "repo": "libsdl-org/SDL", - "sha": "54772f345a", - "hash": "2a68a0e01c390043aa9d9df63d8a20a52076c88bb460ac4e0f33194ca7d9bc8fadbbcc04e7506872ac4b6354a73fbc267c036f82200da59465789b87c7d9e3a4", + "sha": "a96677bdf6", + "hash": "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "key": "generic", "bundled": true }, - "sdl2_steamdeck": { - "package": "SDL2", + "sdl3_steamdeck": { + "package": "SDL3", "repo": "libsdl-org/SDL", "sha": "cc016b0046", "hash": "34d5ef58da6a4f9efa6689c82f67badcbd741f5a4f562a9c2c30828fa839830fb07681c5dc6a7851520e261c8405a416ac0a2c2513b51984fb3b4fa4dcb3e20b", "key": "steamdeck", "bundled": true }, - "sdl2": { + "sdl3": { "ci": true, - "package": "SDL2", - "name": "SDL2", - "repo": "crueter-ci/SDL2", - "version": "2.32.8", - "min_version": "2.26.4", - "cmake_filename": "sdl2" + "package": "SDL3", + "name": "SDL3", + "repo": "libsdl-org/SDL3", + "version": "3.2.22", + "min_version": "3.2.0", + "cmake_filename": "sdl3" }, "llvm-mingw": { "repo": "misc/llvm-mingw", diff --git a/docs/Options.md b/docs/Options.md index 3dd84ea645..dc73fecd3e 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -40,12 +40,12 @@ Notes: * Unavailable on OpenBSD The following options are desktop only: -- `ENABLE_SDL2` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) +- `ENABLE_SDL3` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) * Unavailable on Android - `YUZU_USE_EXTERNAL_SDL2` (ON for non-UNIX) Compiles SDL2 from source - `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2 * Unavailable on OpenBSD - * Only enabled if YUZU_USE_CPM and ENABLE_SDL2 are both ON + * Only enabled if YUZU_USE_CPM and ENABLE_SDL3 are both ON - `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED) - `ENABLE_OPENGL` (ON) Enable the OpenGL graphics frontend * Unavailable on Windows/ARM64 and Android diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 88470c4c42..ed209890ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -223,7 +223,7 @@ if (YUZU_TESTS) add_subdirectory(tests) endif() -if (ENABLE_SDL2 AND YUZU_CMD) +if (ENABLE_SDL3 AND YUZU_CMD) add_subdirectory(yuzu_cmd) set_target_properties(yuzu-cmd PROPERTIES OUTPUT_NAME "eden-cli") endif() diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index e8d8141711..8dedf35446 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -168,7 +168,7 @@ android { cmake { arguments( "-DENABLE_QT=0", // Don't use QT - "-DENABLE_SDL2=0", // Don't use SDL + "-DENABLE_SDL3=0", // Don't use SDL "-DENABLE_WEB_SERVICE=1", // Enable web service "-DENABLE_OPENSSL=ON", "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index c9f8af7dc3..77ac05c7a2 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -247,14 +247,14 @@ if (ENABLE_CUBEB) target_compile_definitions(audio_core PRIVATE HAVE_CUBEB=1) endif() -if (ENABLE_SDL2) +if (ENABLE_SDL3) target_sources(audio_core PRIVATE sink/sdl2_sink.cpp sink/sdl2_sink.h ) - target_link_libraries(audio_core PRIVATE SDL2::SDL2) - target_compile_definitions(audio_core PRIVATE HAVE_SDL2) + target_link_libraries(audio_core PRIVATE SDL3::SDL3) + target_compile_definitions(audio_core PRIVATE HAVE_SDL3) endif() if(ANDROID) diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 25ed58620e..4a9b537116 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include "audio_core/common/common.h" #include "audio_core/sink/sdl2_sink.h" diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index d455323e05..05a123fd6e 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -47,7 +47,7 @@ else() ) endif() -if (ENABLE_SDL2) +if (ENABLE_SDL3) target_sources(input_common PRIVATE drivers/joycon.cpp drivers/joycon.h @@ -73,8 +73,8 @@ if (ENABLE_SDL2) helpers/joycon_protocol/rumble.cpp helpers/joycon_protocol/rumble.h ) - target_link_libraries(input_common PRIVATE SDL2::SDL2) - target_compile_definitions(input_common PRIVATE HAVE_SDL2) + target_link_libraries(input_common PRIVATE SDL3::SDL3) + target_compile_definitions(input_common PRIVATE HAVE_SDL3) endif() if (ENABLE_LIBUSB) diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index a140ad072c..58240d327c 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include "common/common_types.h" #include "common/threadsafe_queue.h" diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 00e03bd935..b47cce6137 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -468,9 +468,9 @@ if (YUZU_USE_BUNDLED_QT) copy_yuzu_Qt6_deps(yuzu) endif() -if (ENABLE_SDL2) - target_link_libraries(yuzu PRIVATE SDL2::SDL2) - target_compile_definitions(yuzu PRIVATE HAVE_SDL2) +if (ENABLE_SDL3) + target_link_libraries(yuzu PRIVATE SDL3::SDL3) + target_compile_definitions(yuzu PRIVATE HAVE_SDL3) endif() if (MSVC) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index fc7a953d77..58c1b151e2 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -98,7 +98,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #ifdef HAVE_SDL2 #include #include -#include // For SDL ScreenSaver functions +#include // For SDL ScreenSaver functions #endif #include diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index a60650bc19..47e0f7e5e1 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -41,7 +41,7 @@ target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) create_resource("../../dist/yuzu.bmp" "yuzu_cmd/yuzu_icon.h" "yuzu_icon") target_include_directories(yuzu-cmd PRIVATE ${RESOURCES_DIR}) -target_link_libraries(yuzu-cmd PRIVATE SDL2::SDL2) +target_link_libraries(yuzu-cmd PRIVATE SDL3::SDL3) if(UNIX AND NOT APPLE) install(TARGETS yuzu-cmd) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 4b56f3794b..f0c1100d09 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -3,7 +3,7 @@ // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include +#include #include "common/logging/log.h" #include "common/scm_rev.h" diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 32f365e0d0..15b634bf63 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -9,7 +9,7 @@ #include #define SDL_MAIN_HANDLED -#include +#include #include #include diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index 506137bd8a..e4f01ece24 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -18,7 +18,7 @@ #include #endif -#include +#include EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index f509652bf6..ba4b29e9ae 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -12,7 +12,7 @@ #include "video_core/renderer_vulkan/renderer_vulkan.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" -#include +#include #include EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, diff --git a/src/yuzu_cmd/sdl_config.cpp b/src/yuzu_cmd/sdl_config.cpp index 6e0f254b6b..5d303571b1 100644 --- a/src/yuzu_cmd/sdl_config.cpp +++ b/src/yuzu_cmd/sdl_config.cpp @@ -3,7 +3,7 @@ // SDL will break our main function in yuzu-cmd if we don't define this before adding SDL.h #define SDL_MAIN_HANDLED -#include +#include #include "common/logging/log.h" #include "input_common/main.h" From e6c3e042be45651b333eaa9a70544e2b4ed0dcfa Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 2/7] rename all symbols --- src/audio_core/sink/sdl2_sink.cpp | 4 +- src/input_common/drivers/sdl_driver.cpp | 182 +++++++++--------- src/input_common/drivers/sdl_driver.h | 6 +- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 42 ++-- .../emu_window/emu_window_sdl2_gl.cpp | 6 +- .../emu_window/emu_window_sdl2_null.cpp | 2 +- .../emu_window/emu_window_sdl2_vk.cpp | 4 +- 7 files changed, 123 insertions(+), 123 deletions(-) diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 4a9b537116..72c02058b3 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -42,7 +42,7 @@ public: SDL_AudioSpec spec; spec.freq = TargetSampleRate; spec.channels = static_cast(device_channels); - spec.format = AUDIO_S16SYS; + spec.format = SDL_AUDIO_S16; spec.samples = TargetSampleCount * 2; spec.callback = &SDLSinkStream::DataCallback; spec.userdata = this; @@ -260,7 +260,7 @@ bool IsSDLSuitable() { SDL_AudioSpec spec; spec.freq = TargetSampleRate; spec.channels = 2u; - spec.format = AUDIO_S16SYS; + spec.format = SDL_AUDIO_S16; spec.samples = TargetSampleCount * 2; spec.callback = nullptr; spec.userdata = nullptr; diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 972abec9fe..100a2516e7 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -15,7 +15,7 @@ namespace InputCommon { namespace { Common::UUID GetGUID(SDL_Joystick* joystick) { - const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + const SDL_GUID guid = SDL_GetJoystickGUID(joystick); std::array data{}; std::memcpy(data.data(), guid.data, sizeof(data)); // Clear controller name crc @@ -35,9 +35,9 @@ static int SDLEventWatcher(void* user_data, SDL_Event* event) { class SDLJoystick { public: SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, - SDL_GameController* game_controller) - : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_JoystickClose}, - sdl_controller{game_controller, &SDL_GameControllerClose} { + SDL_Gamepad* game_controller) + : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_CloseJoystick}, + sdl_controller{game_controller, &SDL_CloseGamepad} { EnableMotion(); } @@ -45,18 +45,18 @@ public: if (!sdl_controller) { return; } - SDL_GameController* controller = sdl_controller.get(); + SDL_Gamepad* controller = sdl_controller.get(); if (HasMotion()) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_FALSE); - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_FALSE); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); } - has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE; - has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE; + has_accel = SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL) == true; + has_gyro = SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO) == true; if (has_accel) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, true); } if (has_gyro) { - SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_GYRO, SDL_TRUE); + SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true); } } @@ -64,7 +64,7 @@ public: return has_gyro || has_accel; } - bool UpdateMotion(SDL_ControllerSensorEvent event) { + bool UpdateMotion(SDL_GamepadSensorEvent event) { constexpr float gravity_constant = 9.80665f; std::scoped_lock lock{mutex}; const u64 time_difference = event.timestamp - last_motion_update; @@ -136,11 +136,11 @@ public: f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; if (sdl_controller) { - return SDL_GameControllerRumble(sdl_controller.get(), static_cast(low_amplitude), + return SDL_RumbleGamepad(sdl_controller.get(), static_cast(low_amplitude), static_cast(high_amplitude), rumble_max_duration_ms) != -1; } else if (sdl_joystick) { - return SDL_JoystickRumble(sdl_joystick.get(), static_cast(low_amplitude), + return SDL_RumbleJoystick(sdl_joystick.get(), static_cast(low_amplitude), static_cast(high_amplitude), rumble_max_duration_ms) != -1; } @@ -150,11 +150,11 @@ public: bool HasHDRumble() const { if (sdl_controller) { - const auto type = SDL_GameControllerGetType(sdl_controller.get()); - return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) || - (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || - (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || - (type == SDL_CONTROLLER_TYPE_PS5); + const auto type = SDL_GetGamepadType(sdl_controller.get()); + return (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO) || + (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || + (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || + (type == SDL_GAMEPAD_TYPE_PS5); } return false; } @@ -201,11 +201,11 @@ public: return sdl_joystick.get(); } - SDL_GameController* GetSDLGameController() const { + SDL_Gamepad* GetSDLGameController() const { return sdl_controller.get(); } - void SetSDLJoystick(SDL_Joystick* joystick, SDL_GameController* controller) { + void SetSDLJoystick(SDL_Joystick* joystick, SDL_Gamepad* controller) { sdl_joystick.reset(joystick); sdl_controller.reset(controller); } @@ -253,28 +253,28 @@ public: std::string GetControllerName() const { if (sdl_controller) { - switch (SDL_GameControllerGetType(sdl_controller.get())) { - case SDL_CONTROLLER_TYPE_XBOX360: + switch (SDL_GetGamepadType(sdl_controller.get())) { + case SDL_GAMEPAD_TYPE_XBOX360: return "Xbox 360 Controller"; - case SDL_CONTROLLER_TYPE_XBOXONE: + case SDL_GAMEPAD_TYPE_XBOXONE: return "Xbox One Controller"; - case SDL_CONTROLLER_TYPE_PS3: + case SDL_GAMEPAD_TYPE_PS3: return "DualShock 3 Controller"; - case SDL_CONTROLLER_TYPE_PS4: + case SDL_GAMEPAD_TYPE_PS4: return "DualShock 4 Controller"; - case SDL_CONTROLLER_TYPE_PS5: + case SDL_GAMEPAD_TYPE_PS5: return "DualSense Controller"; default: break; } - const auto name = SDL_GameControllerName(sdl_controller.get()); + const auto name = SDL_GetGamepadName(sdl_controller.get()); if (name) { return name; } } if (sdl_joystick) { - const auto name = SDL_JoystickName(sdl_joystick.get()); + const auto name = SDL_GetJoystickName(sdl_joystick.get()); if (name) { return name; } @@ -286,8 +286,8 @@ public: private: Common::UUID guid; int port; - std::unique_ptr sdl_joystick; - std::unique_ptr sdl_controller; + std::unique_ptr sdl_joystick; + std::unique_ptr sdl_controller; mutable std::mutex mutex; u64 last_motion_update{}; @@ -323,7 +323,7 @@ std::shared_ptr SDLDriver::GetSDLJoystickByGUID(const std::string& } std::shared_ptr SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { - auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); + auto sdl_joystick = SDL_GetJoystickFromID(sdl_id); const auto guid = GetGUID(sdl_joystick); std::scoped_lock lock{joystick_map_mutex}; @@ -346,11 +346,11 @@ std::shared_ptr SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl } void SDLDriver::InitJoystick(int joystick_index) { - SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index); - SDL_GameController* sdl_gamecontroller = nullptr; + SDL_Joystick* sdl_joystick = SDL_OpenJoystick(joystick_index); + SDL_Gamepad* sdl_gamecontroller = nullptr; - if (SDL_IsGameController(joystick_index)) { - sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); + if (SDL_IsGamepad(joystick_index)) { + sdl_gamecontroller = SDL_OpenGamepad(joystick_index); } if (!sdl_joystick) { @@ -364,7 +364,7 @@ void SDLDriver::InitJoystick(int joystick_index) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); - SDL_JoystickClose(sdl_joystick); + SDL_CloseJoystick(sdl_joystick); return; } } @@ -372,7 +372,7 @@ void SDLDriver::InitJoystick(int joystick_index) { if (Settings::values.enable_procon_driver) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); - SDL_JoystickClose(sdl_joystick); + SDL_CloseJoystick(sdl_joystick); return; } } @@ -428,35 +428,35 @@ void SDLDriver::PumpEvents() const { void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { switch (event.type) { - case SDL_JOYBUTTONUP: { + case SDL_EVENT_JOYSTICK_BUTTON_UP: { if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetButton(identifier, event.jbutton.button, false); } break; } - case SDL_JOYBUTTONDOWN: { + case SDL_EVENT_JOYSTICK_BUTTON_DOWN: { if (const auto joystick = GetSDLJoystickBySDLID(event.jbutton.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetButton(identifier, event.jbutton.button, true); } break; } - case SDL_JOYHATMOTION: { + case SDL_EVENT_JOYSTICK_HAT_MOTION: { if (const auto joystick = GetSDLJoystickBySDLID(event.jhat.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetHatButton(identifier, event.jhat.hat, event.jhat.value); } break; } - case SDL_JOYAXISMOTION: { + case SDL_EVENT_JOYSTICK_AXIS_MOTION: { if (const auto joystick = GetSDLJoystickBySDLID(event.jaxis.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetAxis(identifier, event.jaxis.axis, event.jaxis.value / 32767.0f); } break; } - case SDL_CONTROLLERSENSORUPDATE: { + case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: { if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { if (joystick->UpdateMotion(event.csensor)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); @@ -465,18 +465,18 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { } break; } - case SDL_JOYBATTERYUPDATED: { + case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: { if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); } break; } - case SDL_JOYDEVICEREMOVED: + case SDL_EVENT_JOYSTICK_REMOVED: LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which); - CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which)); + CloseJoystick(SDL_GetJoystickFromID(event.jdevice.which)); break; - case SDL_JOYDEVICEADDED: + case SDL_EVENT_JOYSTICK_ADDED: LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); InitJoystick(event.jdevice.which); break; @@ -502,8 +502,8 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); // Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE, "1"); - SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); + SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled @@ -533,8 +533,8 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); // If the frontend is going to manage the event loop, then we don't start one here - start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == 0; - if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { + start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == 0; + if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0) { LOG_CRITICAL(Input, "SDL_Init failed with: {}", SDL_GetError()); return; } @@ -561,12 +561,12 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDLDriver::~SDLDriver() { CloseJoysticks(); - SDL_DelEventWatch(&SDLEventWatcher, this); + SDL_RemoveEventWatch(&SDLEventWatcher, this); initialized = false; if (start_thread) { vibration_thread.join(); - SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); + SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD); } } @@ -762,13 +762,13 @@ Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& g Common::ParamPackage SDLDriver::BuildParamPackageForBinding( int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { switch (binding.bindType) { - case SDL_CONTROLLER_BINDTYPE_NONE: + case SDL_GAMEPAD_BINDTYPE_NONE: break; - case SDL_CONTROLLER_BINDTYPE_AXIS: + case SDL_GAMEPAD_BINDTYPE_AXIS: return BuildAnalogParamPackageForButton(port, guid, binding.value.axis); - case SDL_CONTROLLER_BINDTYPE_BUTTON: + case SDL_GAMEPAD_BINDTYPE_BUTTON: return BuildButtonParamPackageForButton(port, guid, binding.value.button); - case SDL_CONTROLLER_BINDTYPE_HAT: + case SDL_GAMEPAD_BINDTYPE_HAT: return BuildHatParamPackageForButton(port, guid, binding.value.hat.hat, static_cast(binding.value.hat.hat_mask)); } @@ -810,8 +810,8 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p // Add the missing bindings for ZL/ZR static constexpr ZButtonBindings switch_to_sdl_axis{{ - {Settings::NativeButton::ZL, SDL_CONTROLLER_AXIS_TRIGGERLEFT}, - {Settings::NativeButton::ZR, SDL_CONTROLLER_AXIS_TRIGGERRIGHT}, + {Settings::NativeButton::ZL, SDL_GAMEPAD_AXIS_LEFT_TRIGGER}, + {Settings::NativeButton::ZR, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER}, }}; // Parameters contain two joysticks return dual @@ -830,41 +830,41 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p ButtonBindings SDLDriver::GetDefaultButtonBinding( const std::shared_ptr& joystick) const { // Default SL/SR mapping for other controllers - auto sll_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - auto srl_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - auto slr_button = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - auto srr_button = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + auto sll_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; + auto srl_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; + auto slr_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; + auto srr_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; if (joystick->IsJoyconLeft()) { - sll_button = SDL_CONTROLLER_BUTTON_PADDLE2; - srl_button = SDL_CONTROLLER_BUTTON_PADDLE4; + sll_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE1; + srl_button = SDL_GAMEPAD_BUTTON_LEFT_PADDLE2; } if (joystick->IsJoyconRight()) { - slr_button = SDL_CONTROLLER_BUTTON_PADDLE3; - srr_button = SDL_CONTROLLER_BUTTON_PADDLE1; + slr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2; + srr_button = SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1; } return { - std::pair{Settings::NativeButton::A, SDL_CONTROLLER_BUTTON_B}, - {Settings::NativeButton::B, SDL_CONTROLLER_BUTTON_A}, - {Settings::NativeButton::X, SDL_CONTROLLER_BUTTON_Y}, - {Settings::NativeButton::Y, SDL_CONTROLLER_BUTTON_X}, - {Settings::NativeButton::LStick, SDL_CONTROLLER_BUTTON_LEFTSTICK}, - {Settings::NativeButton::RStick, SDL_CONTROLLER_BUTTON_RIGHTSTICK}, - {Settings::NativeButton::L, SDL_CONTROLLER_BUTTON_LEFTSHOULDER}, - {Settings::NativeButton::R, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER}, - {Settings::NativeButton::Plus, SDL_CONTROLLER_BUTTON_START}, - {Settings::NativeButton::Minus, SDL_CONTROLLER_BUTTON_BACK}, - {Settings::NativeButton::DLeft, SDL_CONTROLLER_BUTTON_DPAD_LEFT}, - {Settings::NativeButton::DUp, SDL_CONTROLLER_BUTTON_DPAD_UP}, - {Settings::NativeButton::DRight, SDL_CONTROLLER_BUTTON_DPAD_RIGHT}, - {Settings::NativeButton::DDown, SDL_CONTROLLER_BUTTON_DPAD_DOWN}, + std::pair{Settings::NativeButton::A, SDL_GAMEPAD_BUTTON_EAST}, + {Settings::NativeButton::B, SDL_GAMEPAD_BUTTON_SOUTH}, + {Settings::NativeButton::X, SDL_GAMEPAD_BUTTON_NORTH}, + {Settings::NativeButton::Y, SDL_GAMEPAD_BUTTON_WEST}, + {Settings::NativeButton::LStick, SDL_GAMEPAD_BUTTON_LEFT_STICK}, + {Settings::NativeButton::RStick, SDL_GAMEPAD_BUTTON_RIGHT_STICK}, + {Settings::NativeButton::L, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER}, + {Settings::NativeButton::R, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER}, + {Settings::NativeButton::Plus, SDL_GAMEPAD_BUTTON_START}, + {Settings::NativeButton::Minus, SDL_GAMEPAD_BUTTON_BACK}, + {Settings::NativeButton::DLeft, SDL_GAMEPAD_BUTTON_DPAD_LEFT}, + {Settings::NativeButton::DUp, SDL_GAMEPAD_BUTTON_DPAD_UP}, + {Settings::NativeButton::DRight, SDL_GAMEPAD_BUTTON_DPAD_RIGHT}, + {Settings::NativeButton::DDown, SDL_GAMEPAD_BUTTON_DPAD_DOWN}, {Settings::NativeButton::SLLeft, sll_button}, {Settings::NativeButton::SRLeft, srl_button}, {Settings::NativeButton::SLRight, slr_button}, {Settings::NativeButton::SRRight, srr_button}, - {Settings::NativeButton::Home, SDL_CONTROLLER_BUTTON_GUIDE}, - {Settings::NativeButton::Screenshot, SDL_CONTROLLER_BUTTON_MISC1}, + {Settings::NativeButton::Home, SDL_GAMEPAD_BUTTON_GUIDE}, + {Settings::NativeButton::Screenshot, SDL_GAMEPAD_BUTTON_MISC1}, }; } @@ -960,9 +960,9 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p AnalogMapping mapping = {}; const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); if (params.Has("guid2")) { const auto identifier = joystick2->GetPadIdentifier(); PreSetController(identifier); @@ -987,9 +987,9 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p left_offset_x, left_offset_y)); } const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); const auto identifier = joystick->GetPadIdentifier(); PreSetController(identifier); PreSetAxis(identifier, binding_right_x.value.axis); @@ -1105,13 +1105,13 @@ bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) { const auto& axis_x = params.Get("axis_x", 0); const auto& axis_y = params.Get("axis_y", 0); const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY); + SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { return false; diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index 58240d327c..bdd2476cb0 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -15,7 +15,7 @@ #include "input_common/input_engine.h" union SDL_Event; -using SDL_GameController = struct _SDL_GameController; +using SDL_Gamepad = struct _SDL_GameController; using SDL_Joystick = struct _SDL_Joystick; using SDL_JoystickID = s32; @@ -24,9 +24,9 @@ namespace InputCommon { class SDLJoystick; using ButtonBindings = - std::array, 20>; + std::array, 20>; using ZButtonBindings = - std::array, 2>; + std::array, 2>; class SDLDriver : public InputEngine { public: diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index f0c1100d09..cb3e4bc576 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -21,7 +21,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) : input_subsystem{input_subsystem_}, system{system_} { input_subsystem->Initialize(); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0) { + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0) { LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}, Exiting...", SDL_GetError()); exit(1); } @@ -176,50 +176,50 @@ void EmuWindow_SDL2::WaitEvent() { switch (event.type) { case SDL_WINDOWEVENT: switch (event.window.event) { - case SDL_WINDOWEVENT_SIZE_CHANGED: - case SDL_WINDOWEVENT_RESIZED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_MAXIMIZED: + case SDL_EVENT_WINDOW_RESTORED: OnResize(); break; - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_EXPOSED: - is_shown = event.window.event == SDL_WINDOWEVENT_EXPOSED; + case SDL_EVENT_WINDOW_MINIMIZED: + case SDL_EVENT_WINDOW_EXPOSED: + is_shown = event.window.event == SDL_EVENT_WINDOW_EXPOSED; OnResize(); break; - case SDL_WINDOWEVENT_CLOSE: + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: is_open = false; break; } break; - case SDL_KEYDOWN: - case SDL_KEYUP: + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: OnKeyEvent(static_cast(event.key.keysym.scancode), event.key.state); break; - case SDL_MOUSEMOTION: + case SDL_EVENT_MOUSE_MOTION: // ignore if it came from touch if (event.button.which != SDL_TOUCH_MOUSEID) OnMouseMotion(event.motion.x, event.motion.y); break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: // ignore if it came from touch if (event.button.which != SDL_TOUCH_MOUSEID) { OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); } break; - case SDL_FINGERDOWN: + case SDL_EVENT_FINGER_DOWN: OnFingerDown(event.tfinger.x, event.tfinger.y, static_cast(event.tfinger.touchId)); break; - case SDL_FINGERMOTION: + case SDL_EVENT_FINGER_MOTION: OnFingerMotion(event.tfinger.x, event.tfinger.y, static_cast(event.tfinger.touchId)); break; - case SDL_FINGERUP: + case SDL_EVENT_FINGER_UP: OnFingerUp(); break; - case SDL_QUIT: + case SDL_EVENT_QUIT: is_open = false; break; default: @@ -242,19 +242,19 @@ void EmuWindow_SDL2::WaitEvent() { // Credits to Samantas5855 and others for this function. void EmuWindow_SDL2::SetWindowIcon() { - SDL_RWops* const yuzu_icon_stream = SDL_RWFromConstMem((void*)yuzu_icon, yuzu_icon_size); + SDL_IOStream* const yuzu_icon_stream = SDL_IOFromConstMem((void*)yuzu_icon, yuzu_icon_size); if (yuzu_icon_stream == nullptr) { LOG_WARNING(Frontend, "Failed to create Eden icon stream."); return; } - SDL_Surface* const window_icon = SDL_LoadBMP_RW(yuzu_icon_stream, 1); + SDL_Surface* const window_icon = SDL_LoadBMP_IO(yuzu_icon_stream, 1); if (window_icon == nullptr) { LOG_WARNING(Frontend, "Failed to read BMP from stream."); return; } // The icon is attached to the window pointer SDL_SetWindowIcon(render_window, window_icon); - SDL_FreeSurface(window_icon); + SDL_DestroySurface(window_icon); } void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 15b634bf63..e08e843673 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -30,7 +30,7 @@ public: ~SDLGLContext() { DoneCurrent(); - SDL_GL_DeleteContext(context); + SDL_GL_DestroyContext(context); } void SwapBuffers() override { @@ -100,7 +100,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste SDL_WINDOWPOS_UNDEFINED, // x position SDL_WINDOWPOS_UNDEFINED, // y position Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); if (render_window == nullptr) { LOG_CRITICAL(Frontend, "Failed to create SDL2 window! {}", SDL_GetError()); @@ -148,7 +148,7 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() { core_context.reset(); - SDL_GL_DeleteContext(window_context); + SDL_GL_DestroyContext(window_context); } std::unique_ptr EmuWindow_SDL2_GL::CreateSharedContext() const { diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index e4f01ece24..0eaecc6085 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -28,7 +28,7 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subs render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); SetWindowIcon(); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index ba4b29e9ae..dfac272342 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -25,11 +25,11 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste render_window = SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); SDL_SysWMinfo wm; SDL_VERSION(&wm.version); - if (SDL_GetWindowWMInfo(render_window, &wm) == SDL_FALSE) { + if (SDL_GetWindowWMInfo(render_window, &wm) == false) { LOG_CRITICAL(Frontend, "Failed to get information from the window manager: {}", SDL_GetError()); std::exit(EXIT_FAILURE); From e12f25ee1d27ef381faab134f1738b7c9298e646 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 3/7] rename some headers --- src/input_common/drivers/joycon.h | 2 +- src/input_common/helpers/joycon_protocol/joycon_types.h | 2 +- src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp | 2 +- src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h index 112e970e15..92ebf0c813 100644 --- a/src/input_common/drivers/joycon.h +++ b/src/input_common/drivers/joycon.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include "input_common/input_engine.h" diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h index 792f124e14..439becb2ed 100644 --- a/src/input_common/helpers/joycon_protocol/joycon_types.h +++ b/src/input_common/helpers/joycon_protocol/joycon_types.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include "common/bit_field.h" #include "common/common_funcs.h" diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index 0eaecc6085..cd1003a10e 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -15,7 +15,7 @@ #ifdef YUZU_USE_EXTERNAL_SDL2 // Include this before SDL.h to prevent the external from including a dummy #define USING_GENERATED_CONFIG_H -#include +#include #endif #include diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index dfac272342..3b3382556b 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -13,7 +13,7 @@ #include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" #include -#include +#include EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) From 406bb8e45d8c841cf64c9a94505f64a4aa0a8789 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 4/7] new audio api changes --- src/audio_core/sink/sdl2_sink.cpp | 190 +++++++++++++++--------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp index 72c02058b3..2d07a35c43 100644 --- a/src/audio_core/sink/sdl2_sink.cpp +++ b/src/audio_core/sink/sdl2_sink.cpp @@ -4,6 +4,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include @@ -13,7 +14,6 @@ #include "audio_core/sink/sdl2_sink.h" #include "audio_core/sink/sink_stream.h" #include "common/logging/log.h" -#include "common/scope_exit.h" #include "core/core.h" namespace AudioCore::Sink { @@ -39,37 +39,53 @@ public: system_channels = system_channels_; device_channels = device_channels_; - SDL_AudioSpec spec; + SDL_AudioSpec spec{}; spec.freq = TargetSampleRate; - spec.channels = static_cast(device_channels); + spec.channels = static_cast(device_channels); spec.format = SDL_AUDIO_S16; - spec.samples = TargetSampleCount * 2; - spec.callback = &SDLSinkStream::DataCallback; - spec.userdata = this; + SDL_AudioDeviceID device_id = 0; std::string device_name{output_device}; - bool capture{false}; + bool is_capture{false}; + if (type == StreamType::In) { device_name = input_device; - capture = true; + is_capture = true; } - SDL_AudioSpec obtained; - if (device_name.empty()) { - device = SDL_OpenAudioDevice(nullptr, capture, &spec, &obtained, false); - } else { - device = SDL_OpenAudioDevice(device_name.c_str(), capture, &spec, &obtained, false); + if (!device_name.empty()) { + int count = 0; + SDL_AudioDeviceID* devices = is_capture ? SDL_GetAudioRecordingDevices(&count) + : SDL_GetAudioPlaybackDevices(&count); + + if (devices) { + for (int i = 0; i < count; ++i) { + const char* name = SDL_GetAudioDeviceName(devices[i]); + if (name && device_name == name) { + device_id = devices[i]; + break; + } + } + SDL_free(devices); + } } - if (device == 0) { - LOG_CRITICAL(Audio_Sink, "Error opening SDL audio device: {}", SDL_GetError()); + if (device_id == 0) { + device_id = + is_capture ? SDL_AUDIO_DEVICE_DEFAULT_RECORDING : SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK; + } + + stream = SDL_OpenAudioDeviceStream( + device_id, &spec, + is_capture ? &SDLSinkStream::CaptureCallback : &SDLSinkStream::PlaybackCallback, this); + + if (!stream) { + LOG_CRITICAL(Audio_Sink, "Error opening SDL audio stream: {}", SDL_GetError()); return; } - LOG_INFO(Service_Audio, - "Opening SDL stream {} with: rate {} channels {} (system channels {}) " - " samples {}", - device, obtained.freq, obtained.channels, system_channels, obtained.samples); + LOG_INFO(Service_Audio, "Opening SDL stream with: rate {} channels {} (system channels {})", + spec.freq, spec.channels, system_channels); } /** @@ -84,13 +100,14 @@ public: * Finalize the sink stream. */ void Finalize() override { - if (device == 0) { + if (!stream) { return; } Stop(); - SDL_ClearQueuedAudio(device); - SDL_CloseAudioDevice(device); + SDL_ClearAudioStream(stream); + SDL_DestroyAudioStream(stream); + stream = nullptr; } /** @@ -100,62 +117,80 @@ public: * Default false. */ void Start(bool resume = false) override { - if (device == 0 || !paused) { + if (!stream || !paused) { return; } paused = false; - SDL_PauseAudioDevice(device, 0); + SDL_ResumeAudioStreamDevice(stream); } /** * Stop the sink stream. */ void Stop() override { - if (device == 0 || paused) { + if (!stream || paused) { return; } SignalPause(); - SDL_PauseAudioDevice(device, 1); + SDL_PauseAudioStreamDevice(stream); + paused = true; } private: - /** - * Main callback from SDL. Either expects samples from us (audio render/audio out), or will - * provide samples to be copied (audio in). - * - * @param userdata - Custom data pointer passed along, points to a SDLSinkStream. - * @param stream - Buffer of samples to be filled or read. - * @param len - Length of the stream in bytes. - */ - static void DataCallback(void* userdata, Uint8* stream, int len) { + static void PlaybackCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, + int total_amount) { auto* impl = static_cast(userdata); - if (!impl) { return; } const std::size_t num_channels = impl->GetDeviceChannels(); const std::size_t frame_size = num_channels; - const std::size_t num_frames{len / num_channels / sizeof(s16)}; + const std::size_t num_frames = additional_amount / (sizeof(s16) * frame_size); - if (impl->type == StreamType::In) { - std::span input_buffer{reinterpret_cast(stream), - num_frames * frame_size}; - impl->ProcessAudioIn(input_buffer, num_frames); - } else { - std::span output_buffer{reinterpret_cast(stream), num_frames * frame_size}; - impl->ProcessAudioOutAndRender(output_buffer, num_frames); + if (num_frames == 0) { + return; + } + + std::vector buffer(num_frames * frame_size); + impl->ProcessAudioOutAndRender(buffer, num_frames); + SDL_PutAudioStreamData(stream, buffer.data(), + static_cast(buffer.size() * sizeof(s16))); + } + + static void CaptureCallback(void* userdata, SDL_AudioStream* stream, int additional_amount, + int total_amount) { + auto* impl = static_cast(userdata); + if (!impl) { + return; + } + + const std::size_t num_channels = impl->GetDeviceChannels(); + const std::size_t frame_size = num_channels; + const std::size_t bytes_available = SDL_GetAudioStreamAvailable(stream); + + if (bytes_available == 0) { + return; + } + + const std::size_t num_frames = bytes_available / (sizeof(s16) * frame_size); + std::vector buffer(num_frames * frame_size); + + int bytes_read = + SDL_GetAudioStreamData(stream, buffer.data(), static_cast(bytes_available)); + if (bytes_read > 0) { + const std::size_t frames_read = bytes_read / (sizeof(s16) * frame_size); + impl->ProcessAudioIn(buffer, frames_read); } } - /// SDL device id of the opened input/output device - SDL_AudioDeviceID device{}; + SDL_AudioStream* stream{nullptr}; }; SDLSink::SDLSink(std::string_view target_device_name) { if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError()); return; } @@ -218,66 +253,31 @@ std::vector ListSDLSinkDevices(bool capture) { std::vector device_list; if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { + if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError()); return {}; } } - const int device_count = SDL_GetNumAudioDevices(capture); - for (int i = 0; i < device_count; ++i) { - if (const char* name = SDL_GetAudioDeviceName(i, capture)) { - device_list.emplace_back(name); + int count = 0; + SDL_AudioDeviceID* devices = + capture ? SDL_GetAudioRecordingDevices(&count) : SDL_GetAudioPlaybackDevices(&count); + + if (devices) { + for (int i = 0; i < count; ++i) { + const char* name = SDL_GetAudioDeviceName(devices[i]); + if (name) { + device_list.emplace_back(name); + } } + SDL_free(devices); } return device_list; } -/* REVERSION to 3833 - function GetSDLLatency() REINTRODUCED FROM 3833 - DIABLO 3 FIX */ u32 GetSDLLatency() { return TargetSampleCount * 2; } -// REVERTED back to 3833 - Below function IsSDLSuitable() removed, reverting to GetSDLLatency() above. - DIABLO 3 FIX -/* -bool IsSDLSuitable() { -#if !defined(HAVE_SDL2) - return false; -#else - // Check SDL can init - if (!SDL_WasInit(SDL_INIT_AUDIO)) { - if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { - LOG_ERROR(Audio_Sink, "SDL failed to init, it is not suitable. Error: {}", - SDL_GetError()); - return false; - } - } - - // We can set any latency frequency we want with SDL, so no need to check that. - - // Check we can open a device with standard parameters - SDL_AudioSpec spec; - spec.freq = TargetSampleRate; - spec.channels = 2u; - spec.format = SDL_AUDIO_S16; - spec.samples = TargetSampleCount * 2; - spec.callback = nullptr; - spec.userdata = nullptr; - - SDL_AudioSpec obtained; - auto device = SDL_OpenAudioDevice(nullptr, false, &spec, &obtained, false); - - if (device == 0) { - LOG_ERROR(Audio_Sink, "SDL failed to open a device, it is not suitable. Error: {}", - SDL_GetError()); - return false; - } - - SDL_CloseAudioDevice(device); - return true; -#endif -} -*/ - -} // namespace AudioCore::Sink +} // namespace AudioCore::Sink \ No newline at end of file From 25790b03ee6d70574451e2e52af7508e7b8f6e28 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 5/7] gamepad and joystick apis --- src/input_common/drivers/sdl_driver.cpp | 349 ++++++++++++------------ src/input_common/drivers/sdl_driver.h | 50 +--- 2 files changed, 179 insertions(+), 220 deletions(-) diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 100a2516e7..d140b00ca0 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -8,7 +8,7 @@ #include "common/param_package.h" #include "common/settings.h" #include "common/thread.h" -#include "common/vector_math.h" +// #include "common/vector_math.h" // Not used directly #include "input_common/drivers/sdl_driver.h" namespace InputCommon { @@ -18,45 +18,41 @@ Common::UUID GetGUID(SDL_Joystick* joystick) { const SDL_GUID guid = SDL_GetJoystickGUID(joystick); std::array data{}; std::memcpy(data.data(), guid.data, sizeof(data)); - // Clear controller name crc std::memset(data.data() + 2, 0, sizeof(u16)); return Common::UUID{data}; } } // Anonymous namespace -static int SDLEventWatcher(void* user_data, SDL_Event* event) { +static bool SDLEventWatcher(void* user_data, SDL_Event* event) { auto* const sdl_state = static_cast(user_data); - sdl_state->HandleGameControllerEvent(*event); - - return 0; + return false; } class SDLJoystick { public: - SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, - SDL_Gamepad* game_controller) + SDLJoystick(Common::UUID guid_, int port_, SDL_Joystick* joystick, SDL_Gamepad* gamepad) : guid{guid_}, port{port_}, sdl_joystick{joystick, &SDL_CloseJoystick}, - sdl_controller{game_controller, &SDL_CloseGamepad} { + sdl_gamepad{gamepad, &SDL_CloseGamepad} { EnableMotion(); } void EnableMotion() { - if (!sdl_controller) { + if (!sdl_gamepad) { return; } - SDL_Gamepad* controller = sdl_controller.get(); + SDL_Gamepad* gamepad = sdl_gamepad.get(); if (HasMotion()) { - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, false); - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, false); + SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_ACCEL, false); + SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_GYRO, false); } - has_accel = SDL_GamepadHasSensor(controller, SDL_SENSOR_ACCEL) == true; - has_gyro = SDL_GamepadHasSensor(controller, SDL_SENSOR_GYRO) == true; + has_accel = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_ACCEL); + has_gyro = SDL_GamepadHasSensor(gamepad, SDL_SENSOR_GYRO); if (has_accel) { - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_ACCEL, true); + SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_ACCEL, true); } if (has_gyro) { - SDL_SetGamepadSensorEnabled(controller, SDL_SENSOR_GYRO, true); + SDL_SetGamepadSensorEnabled(gamepad, SDL_SENSOR_GYRO, true); } } @@ -84,25 +80,22 @@ public: } } - // Ignore duplicated timestamps if (time_difference == 0) { return false; } - // Motion data is invalid if (motion.accel_x == 0 && motion.gyro_x == 0 && motion.accel_y == 0 && motion.gyro_y == 0 && motion.accel_z == 0 && motion.gyro_z == 0) { if (motion_error_count++ < 200) { return false; } - // Try restarting the sensor motion_error_count = 0; EnableMotion(); return false; } motion_error_count = 0; - motion.delta_timestamp = time_difference * 1000; + motion.delta_timestamp = time_difference; return true; } @@ -116,13 +109,13 @@ public: constexpr f32 low_width_sensitivity_limit = 400.0f; constexpr f32 high_start_sensitivity_limit = 200.0f; constexpr f32 high_width_sensitivity_limit = 700.0f; - // Try to provide some feeling of the frequency by reducing the amplitude depending on it. + f32 low_frequency_scale = 1.0f; if (vibration.low_frequency > low_start_sensitivity_limit) { low_frequency_scale = (std::max)(1.0f - (vibration.low_frequency - low_start_sensitivity_limit) / - low_width_sensitivity_limit, - 0.3f); + low_width_sensitivity_limit, + 0.3f); } f32 low_amplitude = vibration.low_amplitude * low_frequency_scale; @@ -130,27 +123,25 @@ public: if (vibration.high_frequency > high_start_sensitivity_limit) { high_frequency_scale = (std::max)(1.0f - (vibration.high_frequency - high_start_sensitivity_limit) / - high_width_sensitivity_limit, - 0.3f); + high_width_sensitivity_limit, + 0.3f); } f32 high_amplitude = vibration.high_amplitude * high_frequency_scale; - if (sdl_controller) { - return SDL_RumbleGamepad(sdl_controller.get(), static_cast(low_amplitude), - static_cast(high_amplitude), - rumble_max_duration_ms) != -1; + if (sdl_gamepad) { + return SDL_RumbleGamepad(sdl_gamepad.get(), static_cast(low_amplitude), + static_cast(high_amplitude), rumble_max_duration_ms); } else if (sdl_joystick) { return SDL_RumbleJoystick(sdl_joystick.get(), static_cast(low_amplitude), - static_cast(high_amplitude), - rumble_max_duration_ms) != -1; + static_cast(high_amplitude), rumble_max_duration_ms); } return false; } bool HasHDRumble() const { - if (sdl_controller) { - const auto type = SDL_GetGamepadType(sdl_controller.get()); + if (sdl_gamepad) { + const auto type = SDL_GetGamepadType(sdl_gamepad.get()); return (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO) || (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT) || (type == SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT) || @@ -172,9 +163,6 @@ public: return is_vibration_tested; } - /** - * The Pad identifier of the joystick - */ const PadIdentifier GetPadIdentifier() const { return { .guid = guid, @@ -183,16 +171,10 @@ public: }; } - /** - * The guid of the joystick - */ const Common::UUID& GetGUID() const { return guid; } - /** - * The number of joystick from the same type that were connected before this joystick - */ int GetPort() const { return port; } @@ -201,13 +183,13 @@ public: return sdl_joystick.get(); } - SDL_Gamepad* GetSDLGameController() const { - return sdl_controller.get(); + SDL_Gamepad* GetSDLGamepad() const { + return sdl_gamepad.get(); } - void SetSDLJoystick(SDL_Joystick* joystick, SDL_Gamepad* controller) { + void SetSDLJoystick(SDL_Joystick* joystick, SDL_Gamepad* gamepad) { sdl_joystick.reset(joystick); - sdl_controller.reset(controller); + sdl_gamepad.reset(gamepad); } bool IsJoyconLeft() const { @@ -232,28 +214,27 @@ public: return false; } - Common::Input::BatteryLevel GetBatteryLevel(SDL_JoystickPowerLevel battery_level) { + Common::Input::BatteryLevel GetBatteryLevel(SDL_PowerState battery_level) { switch (battery_level) { - case SDL_JOYSTICK_POWER_EMPTY: - return Common::Input::BatteryLevel::Empty; - case SDL_JOYSTICK_POWER_LOW: + case SDL_POWERSTATE_ERROR: + case SDL_POWERSTATE_UNKNOWN: + return Common::Input::BatteryLevel::None; + case SDL_POWERSTATE_ON_BATTERY: return Common::Input::BatteryLevel::Low; - case SDL_JOYSTICK_POWER_MEDIUM: - return Common::Input::BatteryLevel::Medium; - case SDL_JOYSTICK_POWER_FULL: - case SDL_JOYSTICK_POWER_MAX: - return Common::Input::BatteryLevel::Full; - case SDL_JOYSTICK_POWER_WIRED: + case SDL_POWERSTATE_NO_BATTERY: + return Common::Input::BatteryLevel::None; + case SDL_POWERSTATE_CHARGING: return Common::Input::BatteryLevel::Charging; - case SDL_JOYSTICK_POWER_UNKNOWN: + case SDL_POWERSTATE_CHARGED: + return Common::Input::BatteryLevel::Full; default: return Common::Input::BatteryLevel::None; } } std::string GetControllerName() const { - if (sdl_controller) { - switch (SDL_GetGamepadType(sdl_controller.get())) { + if (sdl_gamepad) { + switch (SDL_GetGamepadType(sdl_gamepad.get())) { case SDL_GAMEPAD_TYPE_XBOX360: return "Xbox 360 Controller"; case SDL_GAMEPAD_TYPE_XBOXONE: @@ -267,7 +248,7 @@ public: default: break; } - const auto name = SDL_GetGamepadName(sdl_controller.get()); + const auto name = SDL_GetGamepadName(sdl_gamepad.get()); if (name) { return name; } @@ -287,7 +268,7 @@ private: Common::UUID guid; int port; std::unique_ptr sdl_joystick; - std::unique_ptr sdl_controller; + std::unique_ptr sdl_gamepad; mutable std::mutex mutex; u64 last_motion_update{}; @@ -345,16 +326,16 @@ std::shared_ptr SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl return *vec_it; } -void SDLDriver::InitJoystick(int joystick_index) { - SDL_Joystick* sdl_joystick = SDL_OpenJoystick(joystick_index); - SDL_Gamepad* sdl_gamecontroller = nullptr; +void SDLDriver::InitJoystick(SDL_JoystickID joystick_id) { + SDL_Joystick* sdl_joystick = SDL_OpenJoystick(joystick_id); + SDL_Gamepad* sdl_gamepad = nullptr; - if (SDL_IsGamepad(joystick_index)) { - sdl_gamecontroller = SDL_OpenGamepad(joystick_index); + if (SDL_IsGamepad(joystick_id)) { + sdl_gamepad = SDL_OpenGamepad(joystick_id); } if (!sdl_joystick) { - LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); + LOG_ERROR(Input, "Failed to open joystick {}", joystick_id); return; } @@ -363,7 +344,7 @@ void SDLDriver::InitJoystick(int joystick_index) { if (Settings::values.enable_joycon_driver) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && (guid.uuid[8] == 0x06 || guid.uuid[8] == 0x07)) { - LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); + LOG_WARNING(Input, "Preferring joycon driver for device ID {}", joystick_id); SDL_CloseJoystick(sdl_joystick); return; } @@ -371,7 +352,7 @@ void SDLDriver::InitJoystick(int joystick_index) { if (Settings::values.enable_procon_driver) { if (guid.uuid[5] == 0x05 && guid.uuid[4] == 0x7e && guid.uuid[8] == 0x09) { - LOG_WARNING(Input, "Preferring joycon driver for device index {}", joystick_index); + LOG_WARNING(Input, "Preferring joycon driver for device ID {}", joystick_id); SDL_CloseJoystick(sdl_joystick); return; } @@ -379,7 +360,7 @@ void SDLDriver::InitJoystick(int joystick_index) { std::scoped_lock lock{joystick_map_mutex}; if (joystick_map.find(guid) == joystick_map.end()) { - auto joystick = std::make_shared(guid, 0, sdl_joystick, sdl_gamecontroller); + auto joystick = std::make_shared(guid, 0, sdl_joystick, sdl_gamepad); PreSetController(joystick->GetPadIdentifier()); joystick->EnableMotion(); joystick_map[guid].emplace_back(std::move(joystick)); @@ -392,13 +373,13 @@ void SDLDriver::InitJoystick(int joystick_index) { [](const auto& joystick) { return !joystick->GetSDLJoystick(); }); if (joystick_it != joystick_guid_list.end()) { - (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller); + (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamepad); (*joystick_it)->EnableMotion(); return; } const int port = static_cast(joystick_guid_list.size()); - auto joystick = std::make_shared(guid, port, sdl_joystick, sdl_gamecontroller); + auto joystick = std::make_shared(guid, port, sdl_joystick, sdl_gamepad); PreSetController(joystick->GetPadIdentifier()); joystick->EnableMotion(); joystick_guid_list.emplace_back(std::move(joystick)); @@ -408,7 +389,6 @@ void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) { const auto guid = GetGUID(sdl_joystick); std::scoped_lock lock{joystick_map_mutex}; - // This call to guid is safe since the joystick is guaranteed to be in the map const auto& joystick_guid_list = joystick_map[guid]; const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(), [&sdl_joystick](const auto& joystick) { @@ -457,8 +437,8 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { break; } case SDL_EVENT_GAMEPAD_SENSOR_UPDATE: { - if (auto joystick = GetSDLJoystickBySDLID(event.csensor.which)) { - if (joystick->UpdateMotion(event.csensor)) { + if (auto joystick = GetSDLJoystickBySDLID(event.gsensor.which)) { + if (joystick->UpdateMotion(event.gsensor)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); SetMotion(identifier, 0, joystick->GetMotion()); } @@ -468,7 +448,7 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { case SDL_EVENT_JOYSTICK_BATTERY_UPDATED: { if (auto joystick = GetSDLJoystickBySDLID(event.jbattery.which)) { const PadIdentifier identifier = joystick->GetPadIdentifier(); - SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.level)); + SetBattery(identifier, joystick->GetBatteryLevel(event.jbattery.state)); } break; } @@ -477,7 +457,7 @@ void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) { CloseJoystick(SDL_GetJoystickFromID(event.jdevice.which)); break; case SDL_EVENT_JOYSTICK_ADDED: - LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which); + LOG_DEBUG(Input, "Controller connected with device ID {}", event.jdevice.which); InitJoystick(event.jdevice.which); break; } @@ -489,24 +469,17 @@ void SDLDriver::CloseJoysticks() { } SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_engine_)) { - // Set our application name. Currently passed to DBus by SDL and visible to the user through - // their desktop environment. SDL_SetHint(SDL_HINT_APP_NAME, "Eden"); if (!Settings::values.enable_raw_input) { - // Disable raw input. When enabled this setting causes SDL to die when a web applet opens SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "0"); } - // Prevent SDL from adding undesired axis - SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0"); - - // Enable HIDAPI rumble. This prevents SDL from disabling motion on PS4 and PS5 controllers - SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); - SDL_SetHint(SDL_HINT_JOYSTICK_ENHANCED_REPORTS, "1"); + // SDL_HINT_ACCELEROMETER_AS_JOYSTICK was removed in SDL3 + // SDL_HINT_JOYSTICK_HIDAPI_PS4_RUMBLE and SDL_HINT_JOYSTICK_HIDAPI_PS5_RUMBLE were removed in + // SDL3 These are now handled by SDL_HINT_JOYSTICK_ENHANCED_REPORTS SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); - // Disable hidapi drivers for joycon controllers when the custom joycon driver is enabled if (Settings::values.enable_joycon_driver) { SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "0"); } else { @@ -516,7 +489,6 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_VERTICAL_JOY_CONS, "1"); } - // Disable hidapi drivers for pro controllers when the custom joycon driver is enabled if (Settings::values.enable_procon_driver) { SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "0"); } else { @@ -525,16 +497,11 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en } SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_PLAYER_LED, "1"); - // Share the same button mapping with non-Nintendo controllers - SDL_SetHint(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS, "0"); - - // Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native - // driver on Linux. + // SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS was removed in SDL3 SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0"); - // If the frontend is going to manage the event loop, then we don't start one here - start_thread = SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == 0; - if (start_thread && SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0) { + start_thread = !SDL_WasInit(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD); + if (start_thread && !SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { LOG_CRITICAL(Input, "SDL_Init failed with: {}", SDL_GetError()); return; } @@ -552,10 +519,14 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en } }); } - // Because the events for joystick connection happens before we have our event watcher added, we - // can just open all the joysticks right here - for (int i = 0; i < SDL_NumJoysticks(); ++i) { - InitJoystick(i); + + int num_joysticks; + SDL_JoystickID* joysticks = SDL_GetJoysticks(&num_joysticks); + if (joysticks) { + for (int i = 0; i < num_joysticks; ++i) { + InitJoystick(joysticks[i]); + } + SDL_free(joysticks); } } @@ -592,7 +563,6 @@ std::vector SDLDriver::GetInputDevices() const { } } - // Add dual controllers for (const auto& [key, value] : joystick_map) { for (const auto& joystick : value) { if (joystick->IsJoyconRight()) { @@ -624,15 +594,12 @@ Common::Input::DriverResult SDLDriver::SetVibration( return (amplitude + std::pow(amplitude, factor)) * 0.5f * 0xFFFF; }; - // Default exponential curve for rumble f32 factor = 0.35f; - // If vibration is set as a linear output use a flatter value if (vibration.type == Common::Input::VibrationAmplificationType::Linear) { factor = 0.5f; } - // Amplitude for HD rumble needs no modification if (joystick->HasHDRumble()) { factor = 1.0f; } @@ -677,10 +644,7 @@ bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) { return joystick->HasVibration(); } - // First vibration might fail joystick->RumblePlay(test_vibration); - - // Wait for about 15ms to ensure the controller is ready for the stop command std::this_thread::sleep_for(std::chrono::milliseconds(15)); if (!joystick->RumblePlay(zero_vibration)) { @@ -760,17 +724,17 @@ Common::ParamPackage SDLDriver::BuildMotionParam(int port, const Common::UUID& g } Common::ParamPackage SDLDriver::BuildParamPackageForBinding( - int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const { - switch (binding.bindType) { + int port, const Common::UUID& guid, const SDL_GamepadBinding& binding) const { + switch (binding.input_type) { case SDL_GAMEPAD_BINDTYPE_NONE: break; case SDL_GAMEPAD_BINDTYPE_AXIS: - return BuildAnalogParamPackageForButton(port, guid, binding.value.axis); + return BuildAnalogParamPackageForButton(port, guid, binding.input.axis.axis); case SDL_GAMEPAD_BINDTYPE_BUTTON: - return BuildButtonParamPackageForButton(port, guid, binding.value.button); + return BuildButtonParamPackageForButton(port, guid, binding.input.button); case SDL_GAMEPAD_BINDTYPE_HAT: - return BuildHatParamPackageForButton(port, guid, binding.value.hat.hat, - static_cast(binding.value.hat.hat_mask)); + return BuildHatParamPackageForButton(port, guid, binding.input.hat.hat, + static_cast(binding.input.hat.hat_mask)); } return {}; } @@ -797,28 +761,23 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p } const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); - auto* controller = joystick->GetSDLGameController(); - if (controller == nullptr) { + auto* gamepad = joystick->GetSDLGamepad(); + if (gamepad == nullptr) { return {}; } - // This list is missing ZL/ZR since those are not considered buttons in SDL GameController. - // We will add those afterwards ButtonBindings switch_to_sdl_button; - switch_to_sdl_button = GetDefaultButtonBinding(joystick); - // Add the missing bindings for ZL/ZR static constexpr ZButtonBindings switch_to_sdl_axis{{ {Settings::NativeButton::ZL, SDL_GAMEPAD_AXIS_LEFT_TRIGGER}, {Settings::NativeButton::ZR, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER}, }}; - // Parameters contain two joysticks return dual if (params.Has("guid2")) { const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); - if (joystick2->GetSDLGameController() != nullptr) { + if (joystick2->GetSDLGamepad() != nullptr) { return GetDualControllerMapping(joystick, joystick2, switch_to_sdl_button, switch_to_sdl_axis); } @@ -829,7 +788,6 @@ ButtonMapping SDLDriver::GetButtonMappingForDevice(const Common::ParamPackage& p ButtonBindings SDLDriver::GetDefaultButtonBinding( const std::shared_ptr& joystick) const { - // Default SL/SR mapping for other controllers auto sll_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; auto srl_button = SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER; auto slr_button = SDL_GAMEPAD_BUTTON_LEFT_SHOULDER; @@ -873,16 +831,25 @@ ButtonMapping SDLDriver::GetSingleControllerMapping( const ZButtonBindings& switch_to_sdl_axis) const { ButtonMapping mapping; mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); - auto* controller = joystick->GetSDLGameController(); for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { - const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); + // SDL_GetGamepadBindForButton was removed in SDL3 + // We need to use SDL_GetGamepadStringForButton or work with joystick directly + // For now, create a dummy binding + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_BUTTON; + binding.input.button = sdl_button; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); } for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { - const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); + // SDL_GetGamepadBindForAxis was removed in SDL3 + // We need to use SDL_GetGamepadStringForAxis or work with joystick directly + // For now, create a dummy binding + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding.input.axis.axis = sdl_axis; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); @@ -897,31 +864,41 @@ ButtonMapping SDLDriver::GetDualControllerMapping(const std::shared_ptrGetSDLGameController(); - auto* controller2 = joystick2->GetSDLGameController(); for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { if (IsButtonOnLeftSide(switch_button)) { - const auto& binding = SDL_GameControllerGetBindForButton(controller2, sdl_button); + // SDL_GetGamepadBindForButton was removed in SDL3 + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_BUTTON; + binding.input.button = sdl_button; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); continue; } - const auto& binding = SDL_GameControllerGetBindForButton(controller, sdl_button); + // SDL_GetGamepadBindForButton was removed in SDL3 + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_BUTTON; + binding.input.button = sdl_button; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); } for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { if (IsButtonOnLeftSide(switch_button)) { - const auto& binding = SDL_GameControllerGetBindForAxis(controller2, sdl_axis); + // SDL_GetGamepadBindForAxis was removed in SDL3 + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding.input.axis.axis = sdl_axis; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick2->GetPort(), joystick2->GetGUID(), binding)); continue; } - const auto& binding = SDL_GameControllerGetBindForAxis(controller, sdl_axis); + // SDL_GetGamepadBindForAxis was removed in SDL3 + SDL_GamepadBinding binding{}; + binding.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding.input.axis.axis = sdl_axis; mapping.insert_or_assign( switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding)); @@ -953,53 +930,70 @@ AnalogMapping SDLDriver::GetAnalogMappingForDevice(const Common::ParamPackage& p } const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); - auto* controller = joystick->GetSDLGameController(); - if (controller == nullptr) { + auto* gamepad = joystick->GetSDLGamepad(); + if (gamepad == nullptr) { return {}; } AnalogMapping mapping = {}; - const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); - const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); + // SDL_GetGamepadBindForAxis was removed in SDL3 + // We need to work with the underlying joystick directly + SDL_Joystick* sdl_joystick = SDL_GetGamepadJoystick(gamepad); + if (!sdl_joystick) { + return {}; + } + + // For now, use hardcoded axis mappings + SDL_GamepadBinding binding_left_x{}; + binding_left_x.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding_left_x.input.axis.axis = 0; // Left stick X + + SDL_GamepadBinding binding_left_y{}; + binding_left_y.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding_left_y.input.axis.axis = 1; // Left stick Y + if (params.Has("guid2")) { const auto identifier = joystick2->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_left_x.value.axis); - PreSetAxis(identifier, binding_left_y.value.axis); - const auto left_offset_x = -GetAxis(identifier, binding_left_x.value.axis); - const auto left_offset_y = GetAxis(identifier, binding_left_y.value.axis); + PreSetAxis(identifier, binding_left_x.input.axis.axis); + PreSetAxis(identifier, binding_left_y.input.axis.axis); + const auto left_offset_x = -GetAxis(identifier, binding_left_x.input.axis.axis); + const auto left_offset_y = GetAxis(identifier, binding_left_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::LStick, - BuildParamPackageForAnalog(identifier, binding_left_x.value.axis, - binding_left_y.value.axis, - left_offset_x, left_offset_y)); + BuildParamPackageForAnalog( + identifier, binding_left_x.input.axis.axis, + binding_left_y.input.axis.axis, left_offset_x, left_offset_y)); } else { const auto identifier = joystick->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_left_x.value.axis); - PreSetAxis(identifier, binding_left_y.value.axis); - const auto left_offset_x = -GetAxis(identifier, binding_left_x.value.axis); - const auto left_offset_y = GetAxis(identifier, binding_left_y.value.axis); + PreSetAxis(identifier, binding_left_x.input.axis.axis); + PreSetAxis(identifier, binding_left_y.input.axis.axis); + const auto left_offset_x = -GetAxis(identifier, binding_left_x.input.axis.axis); + const auto left_offset_y = GetAxis(identifier, binding_left_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::LStick, - BuildParamPackageForAnalog(identifier, binding_left_x.value.axis, - binding_left_y.value.axis, - left_offset_x, left_offset_y)); + BuildParamPackageForAnalog( + identifier, binding_left_x.input.axis.axis, + binding_left_y.input.axis.axis, left_offset_x, left_offset_y)); } - const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); - const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); + + // For right stick + SDL_GamepadBinding binding_right_x{}; + binding_right_x.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding_right_x.input.axis.axis = 2; // Right stick X + + SDL_GamepadBinding binding_right_y{}; + binding_right_y.input_type = SDL_GAMEPAD_BINDTYPE_AXIS; + binding_right_y.input.axis.axis = 3; // Right stick Y const auto identifier = joystick->GetPadIdentifier(); PreSetController(identifier); - PreSetAxis(identifier, binding_right_x.value.axis); - PreSetAxis(identifier, binding_right_y.value.axis); - const auto right_offset_x = -GetAxis(identifier, binding_right_x.value.axis); - const auto right_offset_y = GetAxis(identifier, binding_right_y.value.axis); + PreSetAxis(identifier, binding_right_x.input.axis.axis); + PreSetAxis(identifier, binding_right_y.input.axis.axis); + const auto right_offset_x = -GetAxis(identifier, binding_right_x.input.axis.axis); + const auto right_offset_y = GetAxis(identifier, binding_right_y.input.axis.axis); mapping.insert_or_assign(Settings::NativeAnalog::RStick, - BuildParamPackageForAnalog(identifier, binding_right_x.value.axis, - binding_right_y.value.axis, right_offset_x, - right_offset_y)); + BuildParamPackageForAnalog(identifier, binding_right_x.input.axis.axis, + binding_right_y.input.axis.axis, + right_offset_x, right_offset_y)); return mapping; } @@ -1009,8 +1003,8 @@ MotionMapping SDLDriver::GetMotionMappingForDevice(const Common::ParamPackage& p } const auto joystick = GetSDLJoystickByGUID(params.Get("guid", ""), params.Get("port", 0)); const auto joystick2 = GetSDLJoystickByGUID(params.Get("guid2", ""), params.Get("port", 0)); - auto* controller = joystick->GetSDLGameController(); - if (controller == nullptr) { + auto* gamepad = joystick->GetSDLGamepad(); + if (gamepad == nullptr) { return {}; } @@ -1039,7 +1033,6 @@ MotionMapping SDLDriver::GetMotionMappingForDevice(const Common::ParamPackage& p Common::Input::ButtonNames SDLDriver::GetUIName(const Common::ParamPackage& params) const { if (params.Has("button")) { - // TODO(German77): Find how to substitute the values for real button names return Common::Input::ButtonNames::Value; } if (params.Has("hat")) { @@ -1097,29 +1090,27 @@ bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) { if (joystick == nullptr) { return false; } - auto* controller = joystick->GetSDLGameController(); - if (controller == nullptr) { + auto* gamepad = joystick->GetSDLGamepad(); + if (gamepad == nullptr) { return false; } const auto& axis_x = params.Get("axis_x", 0); const auto& axis_y = params.Get("axis_y", 0); - const auto& binding_left_x = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTX); - const auto& binding_right_x = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTX); - const auto& binding_left_y = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_LEFTY); - const auto& binding_right_y = - SDL_GameControllerGetBindForAxis(controller, SDL_GAMEPAD_AXIS_RIGHTY); + // SDL_GetGamepadBindForAxis was removed in SDL3 + // Use hardcoded axis mappings for now + const int binding_left_x = 0; // Left stick X + const int binding_right_x = 2; // Right stick X + const int binding_left_y = 1; // Left stick Y + const int binding_right_y = 3; // Right stick Y - if (axis_x != binding_left_y.value.axis && axis_x != binding_right_y.value.axis) { + if (axis_x != binding_left_y && axis_x != binding_right_y) { return false; } - if (axis_y != binding_left_x.value.axis && axis_y != binding_right_x.value.axis) { + if (axis_y != binding_left_x && axis_y != binding_right_x) { return false; } return true; } -} // namespace InputCommon +} // namespace InputCommon \ No newline at end of file diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index bdd2476cb0..98f29e488a 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -15,39 +15,26 @@ #include "input_common/input_engine.h" union SDL_Event; -using SDL_Gamepad = struct _SDL_GameController; -using SDL_Joystick = struct _SDL_Joystick; -using SDL_JoystickID = s32; +using SDL_Gamepad = struct SDL_Gamepad; +using SDL_Joystick = struct SDL_Joystick; +using SDL_JoystickID = Uint32; namespace InputCommon { class SDLJoystick; -using ButtonBindings = - std::array, 20>; -using ZButtonBindings = - std::array, 2>; +using ButtonBindings = std::array, 20>; +using ZButtonBindings = std::array, 2>; class SDLDriver : public InputEngine { public: - /// Initializes and registers SDL device factories explicit SDLDriver(std::string input_engine_); - - /// Unregisters SDL device factories and shut them down. ~SDLDriver() override; void PumpEvents() const; - - /// Handle SDL_Events for joysticks from SDL_PollEvent void HandleGameControllerEvent(const SDL_Event& event); - /// Get the nth joystick with the corresponding GUID std::shared_ptr GetSDLJoystickBySDLID(SDL_JoystickID sdl_id); - - /** - * Check how many identical joysticks (by guid) were connected before the one with sdl_id and so - * tie it to a SDLJoystick with the same guid and that port - */ std::shared_ptr GetSDLJoystickByGUID(const Common::UUID& guid, int port); std::shared_ptr GetSDLJoystickByGUID(const std::string& guid, int port); @@ -69,59 +56,40 @@ public: bool IsVibrationEnabled(const PadIdentifier& identifier) override; private: - void InitJoystick(int joystick_index); + void InitJoystick(SDL_JoystickID joystick_id); void CloseJoystick(SDL_Joystick* sdl_joystick); - - /// Needs to be called before SDL_QuitSubSystem. void CloseJoysticks(); - - /// Takes all vibrations from the queue and sends the command to the controller void SendVibrations(); Common::ParamPackage BuildAnalogParamPackageForButton(int port, const Common::UUID& guid, s32 axis, float value = 0.1f) const; Common::ParamPackage BuildButtonParamPackageForButton(int port, const Common::UUID& guid, s32 button) const; - Common::ParamPackage BuildHatParamPackageForButton(int port, const Common::UUID& guid, s32 hat, u8 value) const; - Common::ParamPackage BuildMotionParam(int port, const Common::UUID& guid) const; - - Common::ParamPackage BuildParamPackageForBinding( - int port, const Common::UUID& guid, const SDL_GameControllerButtonBind& binding) const; - + Common::ParamPackage BuildParamPackageForBinding(int port, const Common::UUID& guid, + const SDL_GamepadBinding& binding) const; Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x, int axis_y, float offset_x, float offset_y) const; - /// Returns the default button bindings list ButtonBindings GetDefaultButtonBinding(const std::shared_ptr& joystick) const; - - /// Returns the button mappings from a single controller ButtonMapping GetSingleControllerMapping(const std::shared_ptr& joystick, const ButtonBindings& switch_to_sdl_button, const ZButtonBindings& switch_to_sdl_axis) const; - - /// Returns the button mappings from two different controllers ButtonMapping GetDualControllerMapping(const std::shared_ptr& joystick, const std::shared_ptr& joystick2, const ButtonBindings& switch_to_sdl_button, const ZButtonBindings& switch_to_sdl_axis) const; - - /// Returns true if the button is on the left joycon bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; - /// Queue of vibration request to controllers Common::SPSCQueue vibration_queue; - - /// Map of GUID of a list of corresponding virtual Joysticks std::unordered_map>> joystick_map; std::mutex joystick_map_mutex; bool start_thread = false; std::atomic initialized = false; - std::thread vibration_thread; }; -} // namespace InputCommon +} // namespace InputCommon \ No newline at end of file From fac44ac81eaf57f98ad424772e4c5fd4fe41e274 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 6/7] windowing and input stuff --- src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 115 +++++++++--------- src/yuzu_cmd/emu_window/emu_window_sdl2.h | 12 +- .../emu_window/emu_window_sdl2_gl.cpp | 31 +++-- src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h | 9 +- .../emu_window/emu_window_sdl2_null.cpp | 17 ++- .../emu_window/emu_window_sdl2_null.h | 6 +- .../emu_window/emu_window_sdl2_vk.cpp | 95 +++++++-------- src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h | 6 +- src/yuzu_cmd/yuzu.cpp | 8 +- 9 files changed, 139 insertions(+), 160 deletions(-) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index cb3e4bc576..38754fe7f0 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -4,7 +4,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include - +#include +#include #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/settings.h" @@ -18,23 +19,23 @@ #include "yuzu_cmd/emu_window/emu_window_sdl2.h" #include "yuzu_cmd/yuzu_icon.h" -EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) +EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) : input_subsystem{input_subsystem_}, system{system_} { input_subsystem->Initialize(); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) < 0) { - LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}, Exiting...", SDL_GetError()); + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { + LOG_CRITICAL(Frontend, "Failed to initialize SDL3: {}, Exiting...", SDL_GetError()); exit(1); } SDL_SetMainReady(); } -EmuWindow_SDL2::~EmuWindow_SDL2() { +EmuWindow_SDL3::~EmuWindow_SDL3() { system.HIDCore().UnloadInputDevices(); input_subsystem->Shutdown(); SDL_Quit(); } -InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const { +InputCommon::MouseButton EmuWindow_SDL3::SDLButtonToMouseButton(u32 button) const { switch (button) { case SDL_BUTTON_LEFT: return InputCommon::MouseButton::Left; @@ -52,21 +53,17 @@ InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) cons } /// @brief Translates pixel position to float position -EmuWindow_SDL2::FloatPairNonHFA EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 touch_y) const { +EmuWindow_SDL3::FloatPairNonHFA EmuWindow_SDL3::MouseToTouchPos(s32 touch_x, s32 touch_y) const { int w = 0, h = 0; SDL_GetWindowSize(render_window, &w, &h); const float fx = float(touch_x) / w; const float fy = float(touch_y) / h; - return { - std::clamp(fx, 0.0f, 1.0f), - std::clamp(fy, 0.0f, 1.0f), - 0 - }; + return {std::clamp(fx, 0.0f, 1.0f), std::clamp(fy, 0.0f, 1.0f), 0}; } -void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { +void EmuWindow_SDL3::OnMouseButton(u32 button, bool pressed, s32 x, s32 y) { const auto mouse_button = SDLButtonToMouseButton(button); - if (state == SDL_PRESSED) { + if (pressed) { auto const [touch_x, touch_y, _] = MouseToTouchPos(x, y); input_subsystem->GetMouse()->PressButton(x, y, mouse_button); input_subsystem->GetMouse()->PressMouseButton(mouse_button); @@ -76,64 +73,65 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { } } -void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { +void EmuWindow_SDL3::OnMouseMotion(s32 x, s32 y) { auto const [touch_x, touch_y, _] = MouseToTouchPos(x, y); input_subsystem->GetMouse()->Move(x, y, 0, 0); input_subsystem->GetMouse()->MouseMove(touch_x, touch_y); input_subsystem->GetMouse()->TouchMove(touch_x, touch_y); } -void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) { +void EmuWindow_SDL3::OnFingerDown(float x, float y, std::size_t id) { input_subsystem->GetTouchScreen()->TouchPressed(x, y, id); } -void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) { +void EmuWindow_SDL3::OnFingerMotion(float x, float y, std::size_t id) { input_subsystem->GetTouchScreen()->TouchMoved(x, y, id); } -void EmuWindow_SDL2::OnFingerUp() { +void EmuWindow_SDL3::OnFingerUp() { input_subsystem->GetTouchScreen()->ReleaseAllTouch(); } -void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { - if (state == SDL_PRESSED) { +void EmuWindow_SDL3::OnKeyEvent(int key, bool pressed) { + if (pressed) { input_subsystem->GetKeyboard()->PressKey(static_cast(key)); - } else if (state == SDL_RELEASED) { + } else { input_subsystem->GetKeyboard()->ReleaseKey(static_cast(key)); } } -bool EmuWindow_SDL2::IsOpen() const { +bool EmuWindow_SDL3::IsOpen() const { return is_open; } -bool EmuWindow_SDL2::IsShown() const { +bool EmuWindow_SDL3::IsShown() const { return is_shown; } -void EmuWindow_SDL2::OnResize() { +void EmuWindow_SDL3::OnResize() { int width, height; - SDL_GL_GetDrawableSize(render_window, &width, &height); + SDL_GetWindowSizeInPixels(render_window, &width, &height); UpdateCurrentFramebufferLayout(width, height); } -void EmuWindow_SDL2::ShowCursor(bool show_cursor) { - SDL_ShowCursor(show_cursor ? SDL_ENABLE : SDL_DISABLE); +void EmuWindow_SDL3::ShowCursor(bool show_cursor) { + show_cursor ? SDL_ShowCursor() : SDL_HideCursor(); } -void EmuWindow_SDL2::Fullscreen() { - SDL_DisplayMode display_mode; +void EmuWindow_SDL3::Fullscreen() { + const SDL_DisplayMode* display_mode; switch (Settings::values.fullscreen_mode.GetValue()) { case Settings::FullscreenMode::Exclusive: - // Set window size to render size before entering fullscreen -- SDL2 does not resize window + // Set window size to render size before entering fullscreen -- SDL3 does not resize window // to display dimensions automatically in this mode. - if (SDL_GetDesktopDisplayMode(0, &display_mode) == 0) { - SDL_SetWindowSize(render_window, display_mode.w, display_mode.h); + display_mode = SDL_GetDesktopDisplayMode(0); + if (display_mode) { + SDL_SetWindowSize(render_window, display_mode->w, display_mode->h); } else { LOG_ERROR(Frontend, "SDL_GetDesktopDisplayMode failed: {}", SDL_GetError()); } - if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) { + if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN)) { return; } @@ -141,7 +139,7 @@ void EmuWindow_SDL2::Fullscreen() { LOG_INFO(Frontend, "Attempting to use borderless fullscreen..."); [[fallthrough]]; case Settings::FullscreenMode::Borderless: - if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) { + if (SDL_SetWindowFullscreen(render_window, true)) { return; } @@ -156,11 +154,13 @@ void EmuWindow_SDL2::Fullscreen() { } } -void EmuWindow_SDL2::WaitEvent() { +void EmuWindow_SDL3::WaitEvent() { // Called on main thread SDL_Event event; - if (!SDL_WaitEvent(&event)) { + if (SDL_WaitEvent(&event)) { + // Event received successfully + } else { const char* error = SDL_GetError(); if (!error || strcmp(error, "") == 0) { // https://github.com/libsdl-org/SDL/issues/5780 @@ -174,27 +174,23 @@ void EmuWindow_SDL2::WaitEvent() { } switch (event.type) { - case SDL_WINDOWEVENT: - switch (event.window.event) { - case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: - case SDL_EVENT_WINDOW_RESIZED: - case SDL_EVENT_WINDOW_MAXIMIZED: - case SDL_EVENT_WINDOW_RESTORED: - OnResize(); - break; - case SDL_EVENT_WINDOW_MINIMIZED: - case SDL_EVENT_WINDOW_EXPOSED: - is_shown = event.window.event == SDL_EVENT_WINDOW_EXPOSED; - OnResize(); - break; - case SDL_EVENT_WINDOW_CLOSE_REQUESTED: - is_open = false; - break; - } + case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: + case SDL_EVENT_WINDOW_RESIZED: + case SDL_EVENT_WINDOW_MAXIMIZED: + case SDL_EVENT_WINDOW_RESTORED: + OnResize(); + break; + case SDL_EVENT_WINDOW_MINIMIZED: + case SDL_EVENT_WINDOW_EXPOSED: + is_shown = event.type == SDL_EVENT_WINDOW_EXPOSED; + OnResize(); + break; + case SDL_EVENT_WINDOW_CLOSE_REQUESTED: + is_open = false; break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: - OnKeyEvent(static_cast(event.key.keysym.scancode), event.key.state); + OnKeyEvent(static_cast(event.key.scancode), event.type == SDL_EVENT_KEY_DOWN); break; case SDL_EVENT_MOUSE_MOTION: // ignore if it came from touch @@ -205,16 +201,17 @@ void EmuWindow_SDL2::WaitEvent() { case SDL_EVENT_MOUSE_BUTTON_UP: // ignore if it came from touch if (event.button.which != SDL_TOUCH_MOUSEID) { - OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); + OnMouseButton(event.button.button, event.type == SDL_EVENT_MOUSE_BUTTON_DOWN, + event.button.x, event.button.y); } break; case SDL_EVENT_FINGER_DOWN: OnFingerDown(event.tfinger.x, event.tfinger.y, - static_cast(event.tfinger.touchId)); + static_cast(event.tfinger.touchID)); break; case SDL_EVENT_FINGER_MOTION: OnFingerMotion(event.tfinger.x, event.tfinger.y, - static_cast(event.tfinger.touchId)); + static_cast(event.tfinger.touchID)); break; case SDL_EVENT_FINGER_UP: OnFingerUp(); @@ -241,7 +238,7 @@ void EmuWindow_SDL2::WaitEvent() { } // Credits to Samantas5855 and others for this function. -void EmuWindow_SDL2::SetWindowIcon() { +void EmuWindow_SDL3::SetWindowIcon() { SDL_IOStream* const yuzu_icon_stream = SDL_IOFromConstMem((void*)yuzu_icon, yuzu_icon_size); if (yuzu_icon_stream == nullptr) { LOG_WARNING(Frontend, "Failed to create Eden icon stream."); @@ -257,6 +254,6 @@ void EmuWindow_SDL2::SetWindowIcon() { SDL_DestroySurface(window_icon); } -void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { +void EmuWindow_SDL3::OnMinimalClientAreaChangeRequest(std::pair minimal_size) { SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 8aec1efda0..1e330afc59 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -22,10 +22,10 @@ class InputSubsystem; enum class MouseButton; } // namespace InputCommon -class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { +class EmuWindow_SDL3 : public Core::Frontend::EmuWindow { public: - explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); - ~EmuWindow_SDL2(); + explicit EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); + ~EmuWindow_SDL3(); /// Whether the window is still open, and a close request hasn't yet been sent bool IsOpen() const; @@ -41,7 +41,7 @@ public: protected: /// Called by WaitEvent when a key is pressed or released. - void OnKeyEvent(int key, u8 state); + void OnKeyEvent(int key, bool pressed); /// Converts a SDL mouse button into MouseInput mouse button InputCommon::MouseButton SDLButtonToMouseButton(u32 button) const; @@ -53,7 +53,7 @@ protected: FloatPairNonHFA MouseToTouchPos(s32 touch_x, s32 touch_y) const; /// Called by WaitEvent when a mouse button is pressed or released - void OnMouseButton(u32 button, u8 state, s32 x, s32 y); + void OnMouseButton(u32 button, bool pressed, s32 x, s32 y); /// Called by WaitEvent when the mouse moves. void OnMouseMotion(s32 x, s32 y); @@ -85,7 +85,7 @@ protected: /// Is the window being shown? bool is_shown = true; - /// Internal SDL2 render window + /// Internal SDL3 render window SDL_Window* render_window{}; /// Keeps track of how often to update the title bar during gameplay diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index e08e843673..4e00fa91a8 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -4,7 +4,6 @@ // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include #include #include @@ -16,7 +15,6 @@ #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/settings.h" -#include "common/string_util.h" #include "core/core.h" #include "input_common/main.h" #include "video_core/renderer_base.h" @@ -58,7 +56,7 @@ private: bool is_current = false; }; -bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { +bool EmuWindow_SDL3_GL::SupportsRequiredGLExtensions() { std::vector unsupported_ext; // Extensions required to support some texture formats. @@ -76,9 +74,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { return unsupported_ext.empty(); } -EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, +EmuWindow_SDL3_GL::EmuWindow_SDL3_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { + : EmuWindow_SDL3{input_subsystem_, system_} { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); @@ -95,15 +93,12 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste std::string window_title = fmt::format("{} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc); - render_window = - SDL_CreateWindow(window_title.c_str(), - SDL_WINDOWPOS_UNDEFINED, // x position - SDL_WINDOWPOS_UNDEFINED, // y position - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); + render_window = SDL_CreateWindow( + window_title.c_str(), Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, + SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); if (render_window == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 window! {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create SDL3 window! {}", SDL_GetError()); exit(1); } @@ -120,15 +115,17 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste core_context = CreateSharedContext(); if (window_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context: {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create SDL3 GL context: {}", SDL_GetError()); exit(1); } if (core_context == nullptr) { - LOG_CRITICAL(Frontend, "Failed to create shared SDL2 GL context: {}", SDL_GetError()); + LOG_CRITICAL(Frontend, "Failed to create shared SDL3 GL context: {}", SDL_GetError()); exit(1); } - if (!gladLoadGLLoader(static_cast(SDL_GL_GetProcAddress))) { + if (!gladLoadGLLoader([](const char* name) -> void* { + return reinterpret_cast(SDL_GL_GetProcAddress(name)); + })) { LOG_CRITICAL(Frontend, "Failed to initialize GL functions! {}", SDL_GetError()); exit(1); } @@ -146,11 +143,11 @@ EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsyste Settings::LogSettings(); } -EmuWindow_SDL2_GL::~EmuWindow_SDL2_GL() { +EmuWindow_SDL3_GL::~EmuWindow_SDL3_GL() { core_context.reset(); SDL_GL_DestroyContext(window_context); } -std::unique_ptr EmuWindow_SDL2_GL::CreateSharedContext() const { +std::unique_ptr EmuWindow_SDL3_GL::CreateSharedContext() const { return std::make_unique(render_window); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h index 39346e7047..345ee17760 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include "core/frontend/emu_window.h" #include "yuzu_cmd/emu_window/emu_window_sdl2.h" @@ -15,11 +16,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_GL final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, + explicit EmuWindow_SDL3_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen); - ~EmuWindow_SDL2_GL(); + ~EmuWindow_SDL3_GL(); std::unique_ptr CreateSharedContext() const override; @@ -27,8 +28,6 @@ private: /// Whether the GPU and driver supports the OpenGL extension required bool SupportsRequiredGLExtensions(); - using SDL_GLContext = void*; - /// The OpenGL context associated with the window SDL_GLContext window_context; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp index cd1003a10e..36f61bd6f1 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.cpp @@ -12,7 +12,7 @@ #include "video_core/renderer_null/renderer_null.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_null.h" -#ifdef YUZU_USE_EXTERNAL_SDL2 +#ifdef YUZU_USE_EXTERNAL_SDL3 // Include this before SDL.h to prevent the external from including a dummy #define USING_GENERATED_CONFIG_H #include @@ -20,15 +20,14 @@ #include -EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, +EmuWindow_SDL3_Null::EmuWindow_SDL3_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { + : EmuWindow_SDL3{input_subsystem_, system_} { const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); - render_window = - SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); + render_window = SDL_CreateWindow(window_title.c_str(), Layout::ScreenUndocked::Width, + Layout::ScreenUndocked::Height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); SetWindowIcon(); @@ -44,8 +43,8 @@ EmuWindow_SDL2_Null::EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subs Common::g_scm_branch, Common::g_scm_desc); } -EmuWindow_SDL2_Null::~EmuWindow_SDL2_Null() = default; +EmuWindow_SDL3_Null::~EmuWindow_SDL3_Null() = default; -std::unique_ptr EmuWindow_SDL2_Null::CreateSharedContext() const { +std::unique_ptr EmuWindow_SDL3_Null::CreateSharedContext() const { return std::make_unique(); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h index 35aee286df..f194d137ae 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_null.h @@ -16,11 +16,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_Null final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_Null final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_Null(InputCommon::InputSubsystem* input_subsystem_, + explicit EmuWindow_SDL3_Null(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, bool fullscreen); - ~EmuWindow_SDL2_Null() override; + ~EmuWindow_SDL3_Null() override; std::unique_ptr CreateSharedContext() const override; }; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index 3b3382556b..ee43f130ce 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -9,31 +9,18 @@ #include "common/logging/log.h" #include "common/scm_rev.h" -#include "video_core/renderer_vulkan/renderer_vulkan.h" #include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h" #include -#include -EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, +EmuWindow_SDL3_VK::EmuWindow_SDL3_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem_, system_} { - const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", - Common::g_build_name, - Common::g_scm_branch, - Common::g_scm_desc); - render_window = - SDL_CreateWindow(window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, - SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); - - SDL_SysWMinfo wm; - SDL_VERSION(&wm.version); - if (SDL_GetWindowWMInfo(render_window, &wm) == false) { - LOG_CRITICAL(Frontend, "Failed to get information from the window manager: {}", - SDL_GetError()); - std::exit(EXIT_FAILURE); - } + : EmuWindow_SDL3{input_subsystem_, system_} { + const std::string window_title = fmt::format("Eden {} | {}-{} (Vulkan)", Common::g_build_name, + Common::g_scm_branch, Common::g_scm_desc); + render_window = SDL_CreateWindow(window_title.c_str(), Layout::ScreenUndocked::Width, + Layout::ScreenUndocked::Height, + SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); SetWindowIcon(); @@ -42,43 +29,43 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste ShowCursor(false); } - switch (wm.subsystem) { -#ifdef SDL_VIDEO_DRIVER_WINDOWS - case SDL_SYSWM_TYPE::SDL_SYSWM_WINDOWS: + { + SDL_PropertiesID props = SDL_GetWindowProperties(render_window); + +#if defined(SDL_PLATFORM_WIN32) window_info.type = Core::Frontend::WindowSystemType::Windows; - window_info.render_surface = reinterpret_cast(wm.info.win.window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_X11 - case SDL_SYSWM_TYPE::SDL_SYSWM_X11: - window_info.type = Core::Frontend::WindowSystemType::X11; - window_info.display_connection = wm.info.x11.display; - window_info.render_surface = reinterpret_cast(wm.info.x11.window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_WAYLAND - case SDL_SYSWM_TYPE::SDL_SYSWM_WAYLAND: - window_info.type = Core::Frontend::WindowSystemType::Wayland; - window_info.display_connection = wm.info.wl.display; - window_info.render_surface = wm.info.wl.surface; - break; -#endif -#ifdef SDL_VIDEO_DRIVER_COCOA - case SDL_SYSWM_TYPE::SDL_SYSWM_COCOA: + window_info.render_surface = + SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, nullptr); +#elif defined(SDL_PLATFORM_MACOS) window_info.type = Core::Frontend::WindowSystemType::Cocoa; window_info.render_surface = SDL_Metal_CreateView(render_window); - break; -#endif -#ifdef SDL_VIDEO_DRIVER_ANDROID - case SDL_SYSWM_TYPE::SDL_SYSWM_ANDROID: +#elif defined(SDL_PLATFORM_LINUX) + const char* video_driver = SDL_GetCurrentVideoDriver(); + if (video_driver && SDL_strcmp(video_driver, "x11") == 0) { + window_info.type = Core::Frontend::WindowSystemType::X11; + window_info.display_connection = + SDL_GetPointerProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr); + window_info.render_surface = reinterpret_cast( + SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0)); + } else if (video_driver && SDL_strcmp(video_driver, "wayland") == 0) { + window_info.type = Core::Frontend::WindowSystemType::Wayland; + window_info.display_connection = + SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, nullptr); + window_info.render_surface = + SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, nullptr); + } else { + LOG_CRITICAL(Frontend, "Unsupported SDL video driver: {}", + video_driver ? video_driver : "(null)"); + std::exit(EXIT_FAILURE); + } +#elif defined(SDL_PLATFORM_ANDROID) window_info.type = Core::Frontend::WindowSystemType::Android; - window_info.render_surface = reinterpret_cast(wm.info.android.window); - break; -#endif - default: - LOG_CRITICAL(Frontend, "Window manager subsystem {} not implemented", wm.subsystem); + window_info.render_surface = + SDL_GetPointerProperty(props, SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, nullptr); +#else + LOG_CRITICAL(Frontend, "Unsupported platform for SDL window properties"); std::exit(EXIT_FAILURE); - break; +#endif } OnResize(); @@ -88,8 +75,8 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste Common::g_scm_branch, Common::g_scm_desc); } -EmuWindow_SDL2_VK::~EmuWindow_SDL2_VK() = default; +EmuWindow_SDL3_VK::~EmuWindow_SDL3_VK() = default; -std::unique_ptr EmuWindow_SDL2_VK::CreateSharedContext() const { +std::unique_ptr EmuWindow_SDL3_VK::CreateSharedContext() const { return std::make_unique(); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h index 9467d164a4..00cc406943 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h @@ -16,11 +16,11 @@ namespace InputCommon { class InputSubsystem; } -class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { +class EmuWindow_SDL3_VK final : public EmuWindow_SDL3 { public: - explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, + explicit EmuWindow_SDL3_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, bool fullscreen); - ~EmuWindow_SDL2_VK() override; + ~EmuWindow_SDL3_VK() override; std::unique_ptr CreateSharedContext() const override; }; diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 4a99f34861..96689c49f6 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -346,16 +346,16 @@ int main(int argc, char** argv) { // Apply the command line arguments system.ApplySettings(); - std::unique_ptr emu_window; + std::unique_ptr emu_window; switch (Settings::values.renderer_backend.GetValue()) { case Settings::RendererBackend::OpenGL: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; case Settings::RendererBackend::Vulkan: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; case Settings::RendererBackend::Null: - emu_window = std::make_unique(&input_subsystem, system, fullscreen); + emu_window = std::make_unique(&input_subsystem, system, fullscreen); break; } From 93dc48d0583f3641f51882ea6a6d409be38b5fd5 Mon Sep 17 00:00:00 2001 From: octocar Date: Wed, 1 Oct 2025 21:04:31 +0200 Subject: [PATCH 7/7] rename more macros --- .ci/windows/build.sh | 2 +- docs/Caveats.md | 2 +- docs/Deps.md | 6 +++--- docs/Options.md | 8 ++++---- externals/gamemode/gamemode_client.h | 2 +- src/audio_core/sink/sink_details.cpp | 6 +++--- src/input_common/main.cpp | 20 ++++++++++---------- src/yuzu/main.cpp | 8 ++++---- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/.ci/windows/build.sh b/.ci/windows/build.sh index d554e00e1b..c0e46d219f 100644 --- a/.ci/windows/build.sh +++ b/.ci/windows/build.sh @@ -24,7 +24,7 @@ cmake .. -G Ninja \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE:-Release}" \ -DENABLE_QT_TRANSLATION=ON \ -DUSE_DISCORD_PRESENCE=ON \ - -DYUZU_USE_BUNDLED_SDL2=ON \ + -DYUZU_USE_BUNDLED_SDL3=ON \ -DBUILD_TESTING=OFF \ -DYUZU_TESTS=OFF \ -DDYNARMIC_TESTS=OFF \ diff --git a/docs/Caveats.md b/docs/Caveats.md index 7bc2428bab..b60cfd4ea9 100644 --- a/docs/Caveats.md +++ b/docs/Caveats.md @@ -38,7 +38,7 @@ export LIBGL_ALWAYS_SOFTWARE=1 ``` - Modify the generated ffmpeg.make (in build dir) if using multiple threads (base system `make` doesn't use `-j4`, so change for `gmake`). -- If using OpenIndiana, due to a bug in SDL2's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL2 may solve this. +- If using OpenIndiana, due to a bug in SDL3's CMake configuration, audio driver defaults to SunOS ``, which does not exist on OpenIndiana. Using external or bundled SDL3 may solve this. - System OpenSSL generally does not work. Instead, use `-DYUZU_USE_BUNDLED_OPENSSL=ON` to use a bundled static OpenSSL, or build a system dependency from source. ## OpenBSD diff --git a/docs/Deps.md b/docs/Deps.md index 573d1fe14a..928f9b4d41 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -32,7 +32,7 @@ If you are on Windows and NOT building with MSYS2, you may go [back home](Build. The following are handled by Eden's externals: * [FFmpeg](https://ffmpeg.org/) (should use `-DYUZU_USE_EXTERNAL_FFMPEG=ON`) -* [SDL2](https://www.libsdl.org/download-2.0.php) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL2=ON` OR `-DYUZU_USE_BUNDLED_SDL2=ON` to reduce compile time) +* [SDL3](https://github.com/libsdl-org/SDL/releases) 2.0.18+ (should use `-DYUZU_USE_EXTERNAL_SDL3=ON` OR `-DYUZU_USE_BUNDLED_SDL3=ON` to reduce compile time) All other dependencies will be downloaded and built by [CPM](https://github.com/cpm-cmake/CPM.cmake/) if `YUZU_USE_CPM` is on, but will always use system dependencies if available (UNIX-like only): @@ -116,7 +116,7 @@ sudo dnf install autoconf ccache cmake fmt-devel gcc{,-c++} glslang hidapi-devel ``` * Force system libraries via CMake arguments: - * SDL2: `-DYUZU_USE_BUNDLED_SDL2=OFF -DYUZU_USE_EXTERNAL_SDL2=OFF` + * SDL3: `-DYUZU_USE_BUNDLED_SDL3=OFF -DYUZU_USE_EXTERNAL_SDL3=OFF` * FFmpeg: `-DYUZU_USE_EXTERNAL_FFMPEG=OFF` * [RPM Fusion](https://rpmfusion.org/) is required for `ffmpeg-devel` * Fedora 32 or later is required. @@ -202,7 +202,7 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l * Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) * Download and install all dependencies using: - * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` + * `pacman -Syu git make mingw-w64-x86_64-SDL3 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` * Add MinGW binaries to the PATH: * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` * Add VulkanSDK to the PATH: diff --git a/docs/Options.md b/docs/Options.md index dc73fecd3e..7323fdc4a3 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -40,10 +40,10 @@ Notes: * Unavailable on OpenBSD The following options are desktop only: -- `ENABLE_SDL3` (ON) Enable the SDL2 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) +- `ENABLE_SDL3` (ON) Enable the SDL3 desktop, audio, and input frontend (HIGHLY RECOMMENDED!) * Unavailable on Android -- `YUZU_USE_EXTERNAL_SDL2` (ON for non-UNIX) Compiles SDL2 from source -- `YUZU_USE_BUNDLED_SDL2` (ON for MSVC) Download a prebuilt SDL2 +- `YUZU_USE_EXTERNAL_SDL3` (ON for non-UNIX) Compiles SDL3 from source +- `YUZU_USE_BUNDLED_SDL3` (ON for MSVC) Download a prebuilt SDL3 * Unavailable on OpenBSD * Only enabled if YUZU_USE_CPM and ENABLE_SDL3 are both ON - `ENABLE_LIBUSB` (ON) Enable the use of the libusb input frontend (HIGHLY RECOMMENDED) @@ -62,7 +62,7 @@ The following options are desktop only: - `YUZU_ROOM` (ON) Enable dedicated room functionality - `YUZU_ROOM_STANDALONE` (ON) Enable standalone room executable (eden-room) * Requires `YUZU_ROOM` -- `YUZU_CMD` (ON) Compile the SDL2 frontend (eden-cli) - requires SDL2 +- `YUZU_CMD` (ON) Compile the SDL3 frontend (eden-cli) - requires SDL3 - `YUZU_CRASH_DUMPS` Compile crash dump (Minidump) support" * Currently only available on Windows and Linux diff --git a/externals/gamemode/gamemode_client.h b/externals/gamemode/gamemode_client.h index b9f64fe460..5bda6d26f8 100644 --- a/externals/gamemode/gamemode_client.h +++ b/externals/gamemode/gamemode_client.h @@ -89,7 +89,7 @@ static char internal_gamemode_client_error_string[512] = { 0 }; /** * Load libgamemode dynamically to dislodge us from most dependencies. * This allows clients to link and/or use this regardless of runtime. - * See SDL2 for an example of the reasoning behind this in terms of + * See SDL3 for an example of the reasoning behind this in terms of * dynamic versioning as well. */ static volatile int internal_libgamemode_loaded = 1; diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp index 70bf75018b..6076ed9eb0 100644 --- a/src/audio_core/sink/sink_details.cpp +++ b/src/audio_core/sink/sink_details.cpp @@ -16,7 +16,7 @@ #ifdef HAVE_CUBEB #include "audio_core/sink/cubeb_sink.h" #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 #include "audio_core/sink/sdl2_sink.h" #endif #include "audio_core/sink/null_sink.h" @@ -71,7 +71,7 @@ constexpr SinkDetails sink_details[] = { &GetCubebLatency, }, #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 SinkDetails{ Settings::AudioEngine::Sdl2, [](std::string_view device_id) -> std::unique_ptr { @@ -115,7 +115,7 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) { // BEGIN REINTRODUCED FROM 3833 - REPLACED CODE BLOCK ABOVE - DIABLO 3 FIX // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which // causes audio issues, in that case go with SDL. -#if defined(HAVE_CUBEB) && defined(HAVE_SDL2) +#if defined(HAVE_CUBEB) && defined(HAVE_SDL3) iter = find_backend(Settings::AudioEngine::Cubeb); if (iter->latency() > TargetSampleCount * 3) { iter = find_backend(Settings::AudioEngine::Sdl2); diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 62a7ae40f8..97a86a750a 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp @@ -22,7 +22,7 @@ #ifdef HAVE_LIBUSB #include "input_common/drivers/gc_adapter.h" #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 #include "input_common/drivers/joycon.h" #include "input_common/drivers/sdl_driver.h" #endif @@ -87,7 +87,7 @@ struct InputSubsystem::Impl { #endif RegisterEngine("virtual_amiibo", virtual_amiibo); RegisterEngine("virtual_gamepad", virtual_gamepad); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 RegisterEngine("sdl", sdl); RegisterEngine("joycon", joycon); #endif @@ -121,7 +121,7 @@ struct InputSubsystem::Impl { #endif UnregisterEngine(virtual_amiibo); UnregisterEngine(virtual_gamepad); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 UnregisterEngine(sdl); UnregisterEngine(joycon); #endif @@ -151,7 +151,7 @@ struct InputSubsystem::Impl { #endif auto udp_devices = udp_client->GetInputDevices(); devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 auto joycon_devices = joycon->GetInputDevices(); devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end()); auto sdl_devices = sdl->GetInputDevices(); @@ -186,7 +186,7 @@ struct InputSubsystem::Impl { if (engine == udp_client->GetEngineName()) { return udp_client; } -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 if (engine == sdl->GetEngineName()) { return sdl; } @@ -277,7 +277,7 @@ struct InputSubsystem::Impl { if (engine == virtual_gamepad->GetEngineName()) { return true; } -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 if (engine == sdl->GetEngineName()) { return true; } @@ -298,7 +298,7 @@ struct InputSubsystem::Impl { gcadapter->BeginConfiguration(); #endif udp_client->BeginConfiguration(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->BeginConfiguration(); joycon->BeginConfiguration(); #endif @@ -314,7 +314,7 @@ struct InputSubsystem::Impl { gcadapter->EndConfiguration(); #endif udp_client->EndConfiguration(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->EndConfiguration(); joycon->EndConfiguration(); #endif @@ -322,7 +322,7 @@ struct InputSubsystem::Impl { void PumpEvents() const { update_engine->PumpEvents(); -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 sdl->PumpEvents(); #endif } @@ -347,7 +347,7 @@ struct InputSubsystem::Impl { std::shared_ptr gcadapter; #endif -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 std::shared_ptr sdl; std::shared_ptr joycon; #endif diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 58c1b151e2..a80177a038 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -95,7 +95,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include #include -#ifdef HAVE_SDL2 +#ifdef HAVE_SDL3 #include #include #include // For SDL ScreenSaver functions @@ -584,7 +584,7 @@ GMainWindow::GMainWindow(bool has_broken_vulkan) VkDeviceInfo::PopulateRecords(vk_device_records, this->window()->windowHandle()); } -#if defined(HAVE_SDL2) && !defined(_WIN32) +#if defined(HAVE_SDL3) && !defined(_WIN32) SDL_InitSubSystem(SDL_INIT_VIDEO); // Set a screensaver inhibition reason string. Currently passed to DBus by SDL and visible to @@ -1855,7 +1855,7 @@ void GMainWindow::OnSigInterruptNotifierActivated() { void GMainWindow::PreventOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); -#elif defined(HAVE_SDL2) +#elif defined(HAVE_SDL3) SDL_DisableScreenSaver(); #endif } @@ -1863,7 +1863,7 @@ void GMainWindow::PreventOSSleep() { void GMainWindow::AllowOSSleep() { #ifdef _WIN32 SetThreadExecutionState(ES_CONTINUOUS); -#elif defined(HAVE_SDL2) +#elif defined(HAVE_SDL3) SDL_EnableScreenSaver(); #endif }