From f98efc542c5ed3e09bae5df8e8d2c69d0efdf28f Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 10 Apr 2025 19:43:59 +0200 Subject: [PATCH 1/3] Update SDL to 3.2.12 --- 3rdparty/libsdl-org/SDL | 2 +- 3rdparty/libsdl-org/SDL.vcxproj | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/3rdparty/libsdl-org/SDL b/3rdparty/libsdl-org/SDL index 877399b2b2..f705e2f9f7 160000 --- a/3rdparty/libsdl-org/SDL +++ b/3rdparty/libsdl-org/SDL @@ -1 +1 @@ -Subproject commit 877399b2b2cf21e67554ed9046410f268ce1d1b2 +Subproject commit f705e2f9f71fe0d329f773a699083f5ef4ad7590 diff --git a/3rdparty/libsdl-org/SDL.vcxproj b/3rdparty/libsdl-org/SDL.vcxproj index e062060fab..81b7d853a5 100644 --- a/3rdparty/libsdl-org/SDL.vcxproj +++ b/3rdparty/libsdl-org/SDL.vcxproj @@ -532,8 +532,6 @@ SDL\include;SDL\include\build_config;%(AdditionalIncludeDirectories) ProgramDatabase MaxSpeed - SDL_HIDAPI_DISABLED;%(PreprocessorDefinitions) - SDL_HIDAPI_DISABLED;%(PreprocessorDefinitions) From bf761e2ff3b8b548602f9f2d80b6b54b05ad27ec Mon Sep 17 00:00:00 2001 From: Megamouse Date: Mon, 10 Mar 2025 23:53:15 +0100 Subject: [PATCH 2/3] SDL/Input: add new misc buttons --- rpcs3/Input/sdl_pad_handler.cpp | 13 +++++++++++++ rpcs3/Input/sdl_pad_handler.h | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/rpcs3/Input/sdl_pad_handler.cpp b/rpcs3/Input/sdl_pad_handler.cpp index 38bd6bc1bd..db1790757a 100644 --- a/rpcs3/Input/sdl_pad_handler.cpp +++ b/rpcs3/Input/sdl_pad_handler.cpp @@ -85,6 +85,9 @@ public: case SDL_LOG_CATEGORY_TEST: category_name = "test"; break; + case SDL_LOG_CATEGORY_GPU: + category_name = "gpu"; + break; default: category_name = fmt::format("unknown(%d)", category); break; @@ -142,6 +145,11 @@ sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl) { SDLKeyCodes::RS, "RS" }, { SDLKeyCodes::Guide, "Guide" }, { SDLKeyCodes::Misc1, "Misc 1" }, + { SDLKeyCodes::Misc2, "Misc 2" }, + { SDLKeyCodes::Misc3, "Misc 3" }, + { SDLKeyCodes::Misc4, "Misc 4" }, + { SDLKeyCodes::Misc5, "Misc 5" }, + { SDLKeyCodes::Misc6, "Misc 6" }, { SDLKeyCodes::RPaddle1, "R Paddle 1" }, { SDLKeyCodes::LPaddle1, "L Paddle 1" }, { SDLKeyCodes::RPaddle2, "R Paddle 2" }, @@ -1116,6 +1124,11 @@ sdl_pad_handler::SDLKeyCodes sdl_pad_handler::get_button_code(SDL_GamepadButton case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_STICK: return SDLKeyCodes::RS; case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_GUIDE: return SDLKeyCodes::Guide; case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC1: return SDLKeyCodes::Misc1; + case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC2: return SDLKeyCodes::Misc2; + case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC3: return SDLKeyCodes::Misc3; + case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC4: return SDLKeyCodes::Misc4; + case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC5: return SDLKeyCodes::Misc5; + case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_MISC6: return SDLKeyCodes::Misc6; case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_PADDLE1: return SDLKeyCodes::RPaddle1; case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_LEFT_PADDLE1: return SDLKeyCodes::LPaddle1; case SDL_GamepadButton::SDL_GAMEPAD_BUTTON_RIGHT_PADDLE2: return SDLKeyCodes::RPaddle2; diff --git a/rpcs3/Input/sdl_pad_handler.h b/rpcs3/Input/sdl_pad_handler.h index 1e8dff73f2..408c4a2fae 100644 --- a/rpcs3/Input/sdl_pad_handler.h +++ b/rpcs3/Input/sdl_pad_handler.h @@ -98,6 +98,11 @@ class sdl_pad_handler : public PadHandlerBase Back, Guide, Misc1, + Misc2, + Misc3, + Misc4, + Misc5, + Misc6, RPaddle1, LPaddle1, RPaddle2, From 5f58c1781b6f07fa88f0a2b04a3a49c72649a03f Mon Sep 17 00:00:00 2001 From: Megamouse Date: Tue, 11 Mar 2025 01:13:31 +0100 Subject: [PATCH 3/3] SDL/Input: add DS3 pressure intensity --- rpcs3/Input/sdl_pad_handler.cpp | 137 +++++++++++++++++++++++++++++--- rpcs3/Input/sdl_pad_handler.h | 18 ++++- 2 files changed, 144 insertions(+), 11 deletions(-) diff --git a/rpcs3/Input/sdl_pad_handler.cpp b/rpcs3/Input/sdl_pad_handler.cpp index db1790757a..aa63143eb0 100644 --- a/rpcs3/Input/sdl_pad_handler.cpp +++ b/rpcs3/Input/sdl_pad_handler.cpp @@ -30,6 +30,14 @@ public: return instance; } + void set_hint(const char* name, const char* value) + { + if (!SDL_SetHint(name, value)) + { + sdl_log.error("Could not set hint '%s' to '%s': %s", name, value, SDL_GetError()); + } + } + bool initialize() { // Only init SDL once. SDL uses a global state internally... @@ -41,10 +49,14 @@ public: sdl_log.notice("Initializing SDL ..."); // Set non-dynamic hints before SDL_Init - if (!SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1")) - { - sdl_log.error("Could not set SDL_HINT_JOYSTICK_THREAD: %s", SDL_GetError()); - } + set_hint(SDL_HINT_JOYSTICK_THREAD, "1"); + + // DS3 pressure sensitive buttons +#ifdef _WIN32 + set_hint(SDL_HINT_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER, "1"); +#else + set_hint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1"); +#endif if (!SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { @@ -169,6 +181,16 @@ sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl) { SDLKeyCodes::RSXPos, "RS X+" }, { SDLKeyCodes::RSYPos, "RS Y+" }, { SDLKeyCodes::RSYNeg, "RS Y-" }, + { SDLKeyCodes::PressureCross, "South" }, // Same name as non-pressure button + { SDLKeyCodes::PressureCircle, "East" }, // Same name as non-pressure button + { SDLKeyCodes::PressureSquare, "West" }, // Same name as non-pressure button + { SDLKeyCodes::PressureTriangle, "North" }, // Same name as non-pressure button + { SDLKeyCodes::PressureL1, "LB" }, // Same name as non-pressure button + { SDLKeyCodes::PressureR1, "RB" }, // Same name as non-pressure button + { SDLKeyCodes::PressureUp, "Up" }, // Same name as non-pressure button + { SDLKeyCodes::PressureDown, "Down" }, // Same name as non-pressure button + { SDLKeyCodes::PressureLeft, "Left" }, // Same name as non-pressure button + { SDLKeyCodes::PressureRight, "Right" }, // Same name as non-pressure button }; init_configs(); @@ -360,6 +382,7 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id) } info.type = SDL_GetGamepadType(info.gamepad); + info.real_type = SDL_GetRealGamepadType(info.gamepad); info.vid = SDL_GetGamepadVendor(info.gamepad); info.pid = SDL_GetGamepadProduct(info.gamepad); info.product_version = SDL_GetGamepadProductVersion(info.gamepad); @@ -393,8 +416,8 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id) } } - sdl_log.notice("Found game pad %d: type=%d, name='%s', path='%s', serial='%s', vid=0x%x, pid=0x%x, product_version=0x%x, firmware_version=0x%x, has_led=%d, has_player_led=%d, has_mono_led=%d, has_rumble=%d, has_rumble_triggers=%d, has_accel=%d, has_gyro=%d", - id, static_cast(info.type), info.name, info.path, info.serial, info.vid, info.pid, info.product_version, info.firmware_version, info.has_led, info.has_player_led, info.has_mono_led, info.has_rumble, info.has_rumble_triggers, info.has_accel, info.has_gyro); + sdl_log.notice("Found game pad %d: type=%d, real_type=%d, name='%s', path='%s', serial='%s', vid=0x%x, pid=0x%x, product_version=0x%x, firmware_version=0x%x, has_led=%d, has_player_led=%d, has_mono_led=%d, has_rumble=%d, has_rumble_triggers=%d, has_accel=%d, has_gyro=%d", + id, static_cast(info.type), static_cast(info.real_type), info.name, info.path, info.serial, info.vid, info.pid, info.product_version, info.firmware_version, info.has_led, info.has_player_led, info.has_mono_led, info.has_rumble, info.has_rumble_triggers, info.has_accel, info.has_gyro); if (info.has_accel) { @@ -444,6 +467,33 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id) } } + // The DS3 may have extra pressure sensitive buttons as axis + if (info.real_type == SDL_GamepadType::SDL_GAMEPAD_TYPE_PS3) + { + if (SDL_Joystick* joystick = SDL_GetGamepadJoystick(info.gamepad)) + { + const int num_axes = SDL_GetNumJoystickAxes(joystick); + const int num_buttons = SDL_GetNumJoystickButtons(joystick); + + info.is_ds3_with_pressure_buttons = num_axes == 16 && num_buttons == 11; + + sdl_log.notice("DS3 device %d has %d axis and %d buttons (has_pressure_buttons=%d)", id, num_axes, num_buttons, info.is_ds3_with_pressure_buttons); + + if (info.is_ds3_with_pressure_buttons) + { + // Add pressure buttons + for (int i = SDL_GAMEPAD_AXIS_COUNT; i < num_axes; i++) + { + const SDL_GamepadAxis axis_id = static_cast(i); + //if (SDL_GamepadHasAxis(info.gamepad, axis_id)) // Always returns false for axis >= SDL_GAMEPAD_AXIS_COUNT + { + info.axis_ids.insert(axis_id); + } + } + } + } + } + return info; } @@ -741,7 +791,7 @@ void sdl_pad_handler::get_extended_info(const pad_ensemble& binding) { const f32 accel_x = dev->values_accel[0]; // Angular speed around the x axis (pitch) const f32 accel_y = dev->values_accel[1]; // Angular speed around the y axis (yaw) - const f32 accel_z = dev->values_accel[2]; // Angular speed around the z axis (roll + const f32 accel_z = dev->values_accel[2]; // Angular speed around the z axis (roll) // Convert to ds3. The ds3 resolution is 113/G. pad->m_sensors[0].m_value = Clamp0To1023((accel_x / SDL_STANDARD_GRAVITY) * -1 * MOTION_ONE_G + 512); @@ -991,18 +1041,61 @@ std::unordered_map sdl_pad_handler::get_button_values(const std::share if (!dev || !dev->sdl.gamepad) return values; + std::set pressed_pressure_buttons; + for (SDL_GamepadButton button_id : dev->sdl.button_ids) { - const u8 value = SDL_GetGamepadButton(dev->sdl.gamepad, button_id); + const bool value = SDL_GetGamepadButton(dev->sdl.gamepad, button_id); const SDLKeyCodes key_code = get_button_code(button_id); - // TODO: SDL does not support DS3 button intensity in the current version + // NOTE: SDL does not simply support DS3 button intensity in the current version + // So we have to skip the normal buttons if a DS3 with pressure buttons was detected + if (dev->sdl.is_ds3_with_pressure_buttons) + { + switch (key_code) + { + case SDLKeyCodes::North: + case SDLKeyCodes::South: + case SDLKeyCodes::West: + case SDLKeyCodes::East: + case SDLKeyCodes::Left: + case SDLKeyCodes::Right: + case SDLKeyCodes::Up: + case SDLKeyCodes::Down: + case SDLKeyCodes::LB: + case SDLKeyCodes::RB: + { + static const std::map button_to_pressure = + { + { SDLKeyCodes::South, SDLKeyCodes::PressureCross }, + { SDLKeyCodes::East, SDLKeyCodes::PressureCircle }, + { SDLKeyCodes::West, SDLKeyCodes::PressureSquare }, + { SDLKeyCodes::North, SDLKeyCodes::PressureTriangle }, + { SDLKeyCodes::LB, SDLKeyCodes::PressureL1 }, + { SDLKeyCodes::RB, SDLKeyCodes::PressureR1 }, + { SDLKeyCodes::Up, SDLKeyCodes::PressureUp }, + { SDLKeyCodes::Down, SDLKeyCodes::PressureDown }, + { SDLKeyCodes::Left, SDLKeyCodes::PressureLeft }, + { SDLKeyCodes::Right, SDLKeyCodes::PressureRight } + }; + + if (value) + { + pressed_pressure_buttons.insert(::at32(button_to_pressure, key_code)); + } + continue; + } + default: + break; + } + } + values[key_code] = value ? 255 : 0; } for (SDL_GamepadAxis axis_id : dev->sdl.axis_ids) { - const s16 value = SDL_GetGamepadAxis(dev->sdl.gamepad, axis_id); + s16 value = SDL_GetGamepadAxis(dev->sdl.gamepad, axis_id); switch (axis_id) { @@ -1029,8 +1122,32 @@ std::unordered_map sdl_pad_handler::get_button_values(const std::share values[SDLKeyCodes::RSYPos] = value < 0 ? std::abs(value) - 1 : 0; break; default: + { + if (dev->sdl.is_ds3_with_pressure_buttons) + { + // Get pressure button value from axis + if (const int key_code = SDLKeyCodes::PressureBegin + 1 + axis_id - SDL_GAMEPAD_AXIS_COUNT; + key_code > SDLKeyCodes::PressureBegin && key_code < SDLKeyCodes::PressureEnd) + { + // We need to get the joystick value directly for axis >= SDL_GAMEPAD_AXIS_COUNT + if (SDL_Joystick* joystick = SDL_GetGamepadJoystick(dev->sdl.gamepad)) + { + value = SDL_GetJoystickAxis(joystick, axis_id); + } + + value = static_cast(ScaledInput(value, SDL_JOYSTICK_AXIS_MIN, SDL_JOYSTICK_AXIS_MAX, 0.0f, 255.0f)); + + if (value <= 0 && pressed_pressure_buttons.contains(static_cast(key_code))) + { + value = 1; + } + + values[key_code] = Clamp0To255(value); + } + } break; } + } } for (const SDLDevice::touchpad& touchpad : dev->sdl.touchpads) diff --git a/rpcs3/Input/sdl_pad_handler.h b/rpcs3/Input/sdl_pad_handler.h index 408c4a2fae..58ddcfda63 100644 --- a/rpcs3/Input/sdl_pad_handler.h +++ b/rpcs3/Input/sdl_pad_handler.h @@ -35,6 +35,7 @@ public: { SDL_Gamepad* gamepad = nullptr; SDL_GamepadType type = SDL_GamepadType::SDL_GAMEPAD_TYPE_UNKNOWN; + SDL_GamepadType real_type = SDL_GamepadType::SDL_GAMEPAD_TYPE_UNKNOWN; int power_level = 0; int last_power_level = 0; @@ -47,6 +48,7 @@ public: u16 firmware_version = 0; bool is_virtual_device = false; + bool is_ds3_with_pressure_buttons = false; bool has_led = false; bool has_mono_led = false; @@ -124,7 +126,21 @@ class sdl_pad_handler : public PadHandlerBase RSXNeg, RSXPos, RSYNeg, - RSYPos + RSYPos, + + // DS3 Pressure sensitive buttons (reported as axis) + PressureBegin, + PressureCross, // Cross axis 6 + PressureCircle, // Circle axis 7 + PressureSquare, // Square axis 8 + PressureTriangle, // Triangle axis 9 + PressureL1, // L1 axis 10 + PressureR1, // R1 axis 11 + PressureUp, // D-Pad Up axis 12 + PressureDown, // D-Pad Down axis 13 + PressureLeft, // D-Pad Left axis 14 + PressureRight, // D-Pad Right axis 15 + PressureEnd, }; public: