Skip to content

Commit f88ef45

Browse files
committed
SDL/Input: add DS3 pressure intensity
1 parent bf761e2 commit f88ef45

File tree

2 files changed

+140
-6
lines changed

2 files changed

+140
-6
lines changed

rpcs3/Input/sdl_pad_handler.cpp

Lines changed: 123 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ struct sdl_instance
4646
sdl_log.error("Could not set SDL_HINT_JOYSTICK_THREAD: %s", SDL_GetError());
4747
}
4848

49+
// DS3 pressure sensitive buttons
50+
#ifdef _WIN32
51+
if (!SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER, "1"))
52+
{
53+
sdl_log.error("Could not set SDL_HINT_JOYSTICK_HIDAPI_PS3_SIXAXIS_DRIVER: %s", SDL_GetError());
54+
}
55+
#else
56+
if (!SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_PS3, "1"))
57+
{
58+
sdl_log.error("Could not set SDL_HINT_JOYSTICK_HIDAPI_PS3: %s", SDL_GetError());
59+
}
60+
#endif
61+
4962
if (!SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD))
5063
{
5164
sdl_log.error("Could not initialize! SDL Error: %s", SDL_GetError());
@@ -169,6 +182,16 @@ sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl)
169182
{ SDLKeyCodes::RSXPos, "RS X+" },
170183
{ SDLKeyCodes::RSYPos, "RS Y+" },
171184
{ SDLKeyCodes::RSYNeg, "RS Y-" },
185+
{ SDLKeyCodes::PressureCross, "South" }, // Same name as non-pressure button
186+
{ SDLKeyCodes::PressureCircle, "East" }, // Same name as non-pressure button
187+
{ SDLKeyCodes::PressureSquare, "West" }, // Same name as non-pressure button
188+
{ SDLKeyCodes::PressureTriangle, "North" }, // Same name as non-pressure button
189+
{ SDLKeyCodes::PressureL1, "LB" }, // Same name as non-pressure button
190+
{ SDLKeyCodes::PressureR1, "RB" }, // Same name as non-pressure button
191+
{ SDLKeyCodes::PressureUp, "Up" }, // Same name as non-pressure button
192+
{ SDLKeyCodes::PressureDown, "Down" }, // Same name as non-pressure button
193+
{ SDLKeyCodes::PressureLeft, "Left" }, // Same name as non-pressure button
194+
{ SDLKeyCodes::PressureRight, "Right" }, // Same name as non-pressure button
172195
};
173196

174197
init_configs();
@@ -360,6 +383,7 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
360383
}
361384

362385
info.type = SDL_GetGamepadType(info.gamepad);
386+
info.real_type = SDL_GetRealGamepadType(info.gamepad);
363387
info.vid = SDL_GetGamepadVendor(info.gamepad);
364388
info.pid = SDL_GetGamepadProduct(info.gamepad);
365389
info.product_version = SDL_GetGamepadProductVersion(info.gamepad);
@@ -393,8 +417,8 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
393417
}
394418
}
395419

396-
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",
397-
id, static_cast<int>(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);
420+
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",
421+
id, static_cast<int>(info.type), static_cast<int>(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);
398422

399423
if (info.has_accel)
400424
{
@@ -444,6 +468,33 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
444468
}
445469
}
446470

471+
// The DS3 may have extra pressure sensitive buttons as axis
472+
if (info.real_type == SDL_GamepadType::SDL_GAMEPAD_TYPE_PS3)
473+
{
474+
if (SDL_Joystick* joystick = SDL_GetGamepadJoystick(info.gamepad))
475+
{
476+
const int num_axes = SDL_GetNumJoystickAxes(joystick);
477+
const int num_buttons = SDL_GetNumJoystickButtons(joystick);
478+
479+
info.is_ds3_with_pressure_buttons = num_axes == 16 && num_buttons == 11;
480+
481+
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);
482+
483+
if (info.is_ds3_with_pressure_buttons)
484+
{
485+
// Add pressure buttons
486+
for (int i = SDL_GAMEPAD_AXIS_COUNT; i < num_axes; i++)
487+
{
488+
const SDL_GamepadAxis axis_id = static_cast<SDL_GamepadAxis>(i);
489+
//if (SDL_GamepadHasAxis(info.gamepad, axis_id)) // Always returns false for axis >= SDL_GAMEPAD_AXIS_COUNT
490+
{
491+
info.axis_ids.insert(axis_id);
492+
}
493+
}
494+
}
495+
}
496+
}
497+
447498
return info;
448499
}
449500

@@ -991,18 +1042,61 @@ std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::share
9911042
if (!dev || !dev->sdl.gamepad)
9921043
return values;
9931044

1045+
std::set<SDLKeyCodes> pressed_pressure_buttons;
1046+
9941047
for (SDL_GamepadButton button_id : dev->sdl.button_ids)
9951048
{
996-
const u8 value = SDL_GetGamepadButton(dev->sdl.gamepad, button_id);
1049+
const bool value = SDL_GetGamepadButton(dev->sdl.gamepad, button_id);
9971050
const SDLKeyCodes key_code = get_button_code(button_id);
9981051

999-
// TODO: SDL does not support DS3 button intensity in the current version
1052+
// NOTE: SDL does not simply support DS3 button intensity in the current version
1053+
// So we have to skip the normal buttons if a DS3 with pressure buttons was detected
1054+
if (dev->sdl.is_ds3_with_pressure_buttons)
1055+
{
1056+
switch (key_code)
1057+
{
1058+
case SDLKeyCodes::North:
1059+
case SDLKeyCodes::South:
1060+
case SDLKeyCodes::West:
1061+
case SDLKeyCodes::East:
1062+
case SDLKeyCodes::Left:
1063+
case SDLKeyCodes::Right:
1064+
case SDLKeyCodes::Up:
1065+
case SDLKeyCodes::Down:
1066+
case SDLKeyCodes::LB:
1067+
case SDLKeyCodes::RB:
1068+
{
1069+
static const std::map<SDLKeyCodes, SDLKeyCodes> button_to_pressure =
1070+
{
1071+
{ SDLKeyCodes::South, SDLKeyCodes::PressureCross },
1072+
{ SDLKeyCodes::East, SDLKeyCodes::PressureCircle },
1073+
{ SDLKeyCodes::West, SDLKeyCodes::PressureSquare },
1074+
{ SDLKeyCodes::North, SDLKeyCodes::PressureTriangle },
1075+
{ SDLKeyCodes::LB, SDLKeyCodes::PressureL1 },
1076+
{ SDLKeyCodes::RB, SDLKeyCodes::PressureR1 },
1077+
{ SDLKeyCodes::Up, SDLKeyCodes::PressureUp },
1078+
{ SDLKeyCodes::Down, SDLKeyCodes::PressureDown },
1079+
{ SDLKeyCodes::Left, SDLKeyCodes::PressureLeft },
1080+
{ SDLKeyCodes::Right, SDLKeyCodes::PressureRight }
1081+
};
1082+
1083+
if (value)
1084+
{
1085+
pressed_pressure_buttons.insert(::at32(button_to_pressure, key_code));
1086+
}
1087+
continue;
1088+
}
1089+
default:
1090+
break;
1091+
}
1092+
}
1093+
10001094
values[key_code] = value ? 255 : 0;
10011095
}
10021096

10031097
for (SDL_GamepadAxis axis_id : dev->sdl.axis_ids)
10041098
{
1005-
const s16 value = SDL_GetGamepadAxis(dev->sdl.gamepad, axis_id);
1099+
s16 value = SDL_GetGamepadAxis(dev->sdl.gamepad, axis_id);
10061100

10071101
switch (axis_id)
10081102
{
@@ -1029,8 +1123,32 @@ std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::share
10291123
values[SDLKeyCodes::RSYPos] = value < 0 ? std::abs(value) - 1 : 0;
10301124
break;
10311125
default:
1126+
{
1127+
if (dev->sdl.is_ds3_with_pressure_buttons)
1128+
{
1129+
// Get pressure button value from axis
1130+
if (const int key_code = SDLKeyCodes::PressureBegin + 1 + axis_id - SDL_GAMEPAD_AXIS_COUNT;
1131+
key_code > SDLKeyCodes::PressureBegin && key_code < SDLKeyCodes::PressureEnd)
1132+
{
1133+
// We need to get the joystick value directly for axis >= SDL_GAMEPAD_AXIS_COUNT
1134+
if (SDL_Joystick* joystick = SDL_GetGamepadJoystick(dev->sdl.gamepad))
1135+
{
1136+
value = SDL_GetJoystickAxis(joystick, axis_id);
1137+
}
1138+
1139+
value = static_cast<s16>(ScaledInput(value, SDL_JOYSTICK_AXIS_MIN, SDL_JOYSTICK_AXIS_MAX, 0.0f, 255.0f));
1140+
1141+
if (value <= 0 && pressed_pressure_buttons.contains(static_cast<SDLKeyCodes>(key_code)))
1142+
{
1143+
value = 1;
1144+
}
1145+
1146+
values[key_code] = Clamp0To255(value);
1147+
}
1148+
}
10321149
break;
10331150
}
1151+
}
10341152
}
10351153

10361154
for (const SDLDevice::touchpad& touchpad : dev->sdl.touchpads)

rpcs3/Input/sdl_pad_handler.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class SDLDevice : public PadDevice
3535
{
3636
SDL_Gamepad* gamepad = nullptr;
3737
SDL_GamepadType type = SDL_GamepadType::SDL_GAMEPAD_TYPE_UNKNOWN;
38+
SDL_GamepadType real_type = SDL_GamepadType::SDL_GAMEPAD_TYPE_UNKNOWN;
3839
int power_level = 0;
3940
int last_power_level = 0;
4041

@@ -47,6 +48,7 @@ class SDLDevice : public PadDevice
4748
u16 firmware_version = 0;
4849

4950
bool is_virtual_device = false;
51+
bool is_ds3_with_pressure_buttons = false;
5052

5153
bool has_led = false;
5254
bool has_mono_led = false;
@@ -124,7 +126,21 @@ class sdl_pad_handler : public PadHandlerBase
124126
RSXNeg,
125127
RSXPos,
126128
RSYNeg,
127-
RSYPos
129+
RSYPos,
130+
131+
// DS3 Pressure sensitive buttons (reported as axis)
132+
PressureBegin,
133+
PressureCross, // Cross axis 6
134+
PressureCircle, // Circle axis 7
135+
PressureSquare, // Square axis 8
136+
PressureTriangle, // Triangle axis 9
137+
PressureL1, // L1 axis 10
138+
PressureR1, // R1 axis 11
139+
PressureUp, // D-Pad Up axis 12
140+
PressureDown, // D-Pad Down axis 13
141+
PressureLeft, // D-Pad Left axis 14
142+
PressureRight, // D-Pad Right axis 15
143+
PressureEnd,
128144
};
129145

130146
public:

0 commit comments

Comments
 (0)