DS4/DualSense/SDL: add touchpad support

This commit is contained in:
Megamouse 2024-07-30 22:51:17 +02:00
parent 12fbff22b2
commit 30f49a61df
8 changed files with 216 additions and 6 deletions

View file

@ -143,6 +143,10 @@ sdl_pad_handler::sdl_pad_handler() : PadHandlerBase(pad_handler::sdl)
{ SDLKeyCodes::Paddle3, "Paddle 3" },
{ SDLKeyCodes::Paddle4, "Paddle 4" },
{ SDLKeyCodes::Touchpad, "Touchpad" },
{ SDLKeyCodes::Touch_L, "Touch Left" },
{ SDLKeyCodes::Touch_R, "Touch Right" },
{ SDLKeyCodes::Touch_U, "Touch Up" },
{ SDLKeyCodes::Touch_D, "Touch Down" },
{ SDLKeyCodes::LT, "LT" },
{ SDLKeyCodes::RT, "RT" },
{ SDLKeyCodes::LSXNeg, "LS X-" },
@ -342,6 +346,27 @@ SDLDevice::sdl_info sdl_pad_handler::get_sdl_info(int i)
info.has_accel = SDL_GameControllerHasSensor(info.game_controller, SDL_SENSOR_ACCEL);
info.has_gyro = SDL_GameControllerHasSensor(info.game_controller, SDL_SENSOR_GYRO);
if (const int num_touchpads = SDL_GameControllerGetNumTouchpads(info.game_controller); num_touchpads > 0)
{
info.touchpads.resize(num_touchpads);
for (int i = 0; i < num_touchpads; i++)
{
SDLDevice::touchpad& touchpad = ::at32(info.touchpads, i);
touchpad.index = i;
if (const int num_fingers = SDL_GameControllerGetNumTouchpadFingers(info.game_controller, touchpad.index); num_fingers > 0)
{
touchpad.fingers.resize(num_fingers);
for (int f = 0; f < num_fingers; f++)
{
::at32(touchpad.fingers, f).index = f;
}
}
}
}
sdl_log.notice("Found game controller %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_rumble=%d, has_rumble_triggers=%d, has_accel=%d, has_gyro=%d",
i, 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_rumble, info.has_rumble_triggers, info.has_accel, info.has_gyro);
@ -913,6 +938,20 @@ bool sdl_pad_handler::get_is_right_stick(const std::shared_ptr<PadDevice>& /*dev
}
}
bool sdl_pad_handler::get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& /*device*/, u64 keyCode)
{
switch (keyCode)
{
case SDLKeyCodes::Touch_L:
case SDLKeyCodes::Touch_R:
case SDLKeyCodes::Touch_U:
case SDLKeyCodes::Touch_D:
return true;
default:
return false;
}
}
std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::shared_ptr<PadDevice>& device)
{
std::unordered_map<u64, u16> values;
@ -962,6 +1001,40 @@ std::unordered_map<u64, u16> sdl_pad_handler::get_button_values(const std::share
}
}
for (const SDLDevice::touchpad& touchpad : dev->sdl.touchpads)
{
for (const SDLDevice::touch_point& finger : touchpad.fingers)
{
u8 state = 0; // 1 means the finger is touching the pad
f32 x = 0.0f; // 0 = left, 1 = right
f32 y = 0.0f; // 0 = top, 1 = bottom
f32 pressure = 0.0f; // In the current SDL version the pressure is always 1 if the state is 1
if (SDL_GameControllerGetTouchpadFinger(dev->sdl.game_controller, touchpad.index, finger.index, &state, &x, &y, &pressure) != 0)
{
sdl_log.error("Could not get touchpad %d finger %d data of device %d! SDL Error: %s", touchpad.index, finger.index, dev->player_id, SDL_GetError());
}
else
{
sdl_log.trace("touchpad=%d, finger=%d, state=%d, x=%f, y=%f, pressure=%f", touchpad.index, finger.index, state, x, y, pressure);
if (state == 0)
{
continue;
}
const f32 x_scaled = ScaledInput(x, 0.0f, 1.0f, 0.0f, 255.0f);
const f32 y_scaled = ScaledInput(y, 0.0f, 1.0f, 0.0f, 255.0f);
values[SDLKeyCodes::Touch_L] = Clamp0To255((127.5f - x_scaled) * 2.0f);
values[SDLKeyCodes::Touch_R] = Clamp0To255((x_scaled - 127.5f) * 2.0f);
values[SDLKeyCodes::Touch_U] = Clamp0To255((127.5f - y_scaled) * 2.0f);
values[SDLKeyCodes::Touch_D] = Clamp0To255((y_scaled - 127.5f) * 2.0f);
}
}
}
return values;
}