@@ -46,6 +46,19 @@ struct sdl_instance
46
46
sdl_log.error (" Could not set SDL_HINT_JOYSTICK_THREAD: %s" , SDL_GetError ());
47
47
}
48
48
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
+
49
62
if (!SDL_Init (SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD))
50
63
{
51
64
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)
169
182
{ SDLKeyCodes::RSXPos, " RS X+" },
170
183
{ SDLKeyCodes::RSYPos, " RS Y+" },
171
184
{ 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
172
195
};
173
196
174
197
init_configs ();
@@ -360,6 +383,7 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
360
383
}
361
384
362
385
info.type = SDL_GetGamepadType (info.gamepad );
386
+ info.real_type = SDL_GetRealGamepadType (info.gamepad );
363
387
info.vid = SDL_GetGamepadVendor (info.gamepad );
364
388
info.pid = SDL_GetGamepadProduct (info.gamepad );
365
389
info.product_version = SDL_GetGamepadProductVersion (info.gamepad );
@@ -393,8 +417,8 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
393
417
}
394
418
}
395
419
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 );
398
422
399
423
if (info.has_accel )
400
424
{
@@ -444,6 +468,33 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(SDL_JoystickID id)
444
468
}
445
469
}
446
470
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
+
447
498
return info;
448
499
}
449
500
@@ -991,18 +1042,61 @@ std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::share
991
1042
if (!dev || !dev->sdl .gamepad )
992
1043
return values;
993
1044
1045
+ std::set<SDLKeyCodes> pressed_pressure_buttons;
1046
+
994
1047
for (SDL_GamepadButton button_id : dev->sdl .button_ids )
995
1048
{
996
- const u8 value = SDL_GetGamepadButton (dev->sdl .gamepad , button_id);
1049
+ const bool value = SDL_GetGamepadButton (dev->sdl .gamepad , button_id);
997
1050
const SDLKeyCodes key_code = get_button_code (button_id);
998
1051
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
+
1000
1094
values[key_code] = value ? 255 : 0 ;
1001
1095
}
1002
1096
1003
1097
for (SDL_GamepadAxis axis_id : dev->sdl .axis_ids )
1004
1098
{
1005
- const s16 value = SDL_GetGamepadAxis (dev->sdl .gamepad , axis_id);
1099
+ s16 value = SDL_GetGamepadAxis (dev->sdl .gamepad , axis_id);
1006
1100
1007
1101
switch (axis_id)
1008
1102
{
@@ -1029,8 +1123,32 @@ std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::share
1029
1123
values[SDLKeyCodes::RSYPos] = value < 0 ? std::abs (value) - 1 : 0 ;
1030
1124
break ;
1031
1125
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
+ }
1032
1149
break ;
1033
1150
}
1151
+ }
1034
1152
}
1035
1153
1036
1154
for (const SDLDevice::touchpad& touchpad : dev->sdl .touchpads )
0 commit comments