mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01:00
DS4/DualSense/SDL: add touchpad support
This commit is contained in:
parent
12fbff22b2
commit
30f49a61df
@ -261,9 +261,13 @@ PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::stri
|
||||
|
||||
const bool is_trigger = get_is_left_trigger(device, keycode) || get_is_right_trigger(device, keycode);
|
||||
const bool is_stick = !is_trigger && (get_is_left_stick(device, keycode) || get_is_right_stick(device, keycode));
|
||||
const bool is_button = !is_trigger && !is_stick;
|
||||
const bool is_touch_motion = !is_trigger && !is_stick && get_is_touch_pad_motion(device, keycode);
|
||||
const bool is_button = !is_trigger && !is_stick && !is_touch_motion;
|
||||
|
||||
if ((is_trigger && (value > m_trigger_threshold)) || (is_stick && (value > m_thumb_threshold)) || (is_button && (value > 0)))
|
||||
if ((is_trigger && (value > m_trigger_threshold)) ||
|
||||
(is_stick && (value > m_thumb_threshold)) ||
|
||||
(is_button && (value > 0)) ||
|
||||
(is_touch_motion && (value > 255 * 0.9)))
|
||||
{
|
||||
if (get_blacklist)
|
||||
{
|
||||
|
@ -290,6 +290,7 @@ private:
|
||||
virtual bool get_is_right_trigger(const std::shared_ptr<PadDevice>& /*device*/, u64 /*keyCode*/) { return false; }
|
||||
virtual bool get_is_left_stick(const std::shared_ptr<PadDevice>& /*device*/, u64 /*keyCode*/) { return false; }
|
||||
virtual bool get_is_right_stick(const std::shared_ptr<PadDevice>& /*device*/, u64 /*keyCode*/) { return false; }
|
||||
virtual bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& /*device*/, u64 /*keyCode*/) { return false; }
|
||||
virtual PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& /*device*/) { return connection::disconnected; }
|
||||
virtual void get_extended_info(const pad_ensemble& /*binding*/) {}
|
||||
virtual void apply_pad_data(const pad_ensemble& /*binding*/) {}
|
||||
|
@ -85,6 +85,10 @@ ds4_pad_handler::ds4_pad_handler()
|
||||
{ DS4KeyCodes::Share, "Share" },
|
||||
{ DS4KeyCodes::PSButton, "PS Button" },
|
||||
{ DS4KeyCodes::TouchPad, "Touch Pad" },
|
||||
{ DS4KeyCodes::Touch_L, "Touch Left" },
|
||||
{ DS4KeyCodes::Touch_R, "Touch Right" },
|
||||
{ DS4KeyCodes::Touch_U, "Touch Up" },
|
||||
{ DS4KeyCodes::Touch_D, "Touch Down" },
|
||||
{ DS4KeyCodes::L1, "L1" },
|
||||
{ DS4KeyCodes::L2, "L2" },
|
||||
{ DS4KeyCodes::L3, "L3" },
|
||||
@ -333,6 +337,47 @@ std::unordered_map<u64, u16> ds4_pad_handler::get_button_values(const std::share
|
||||
keyBuffer[DS4KeyCodes::L2] = input.z;
|
||||
keyBuffer[DS4KeyCodes::R2] = input.rz;
|
||||
|
||||
// Touch Pad
|
||||
const auto apply_touch = [&keyBuffer](const ds4_touch_report& touch)
|
||||
{
|
||||
for (const ds4_touch_point& point : touch.points)
|
||||
{
|
||||
if (!(point.contact & DS4_TOUCH_POINT_INACTIVE))
|
||||
{
|
||||
const s32 x = (point.x_hi << 8) | point.x_lo;
|
||||
const s32 y = (point.y_hi << 4) | point.y_lo;
|
||||
|
||||
const f32 x_scaled = ScaledInput(static_cast<float>(x), 0.0f, static_cast<float>(DS4_TOUCHPAD_WIDTH), 0.0f, 255.0f);
|
||||
const f32 y_scaled = ScaledInput(static_cast<float>(y), 0.0f, static_cast<float>(DS4_TOUCHPAD_HEIGHT), 0.0f, 255.0f);
|
||||
|
||||
keyBuffer[DS4KeyCodes::Touch_L] = Clamp0To255((127.5f - x_scaled) * 2.0f);
|
||||
keyBuffer[DS4KeyCodes::Touch_R] = Clamp0To255((x_scaled - 127.5f) * 2.0f);
|
||||
|
||||
keyBuffer[DS4KeyCodes::Touch_U] = Clamp0To255((127.5f - y_scaled) * 2.0f);
|
||||
keyBuffer[DS4KeyCodes::Touch_D] = Clamp0To255((y_scaled - 127.5f) * 2.0f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (ds4_dev->bt_controller)
|
||||
{
|
||||
const ds4_input_report_bt& report = ds4_dev->report_bt;
|
||||
|
||||
for (u32 i = 0; i < std::min<u32>(report.num_touch_reports, ::size32(report.touch_reports)); i++)
|
||||
{
|
||||
apply_touch(report.touch_reports[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const ds4_input_report_usb& report = ds4_dev->report_usb;
|
||||
|
||||
for (u32 i = 0; i < std::min<u32>(report.num_touch_reports, ::size32(report.touch_reports)); i++)
|
||||
{
|
||||
apply_touch(report.touch_reports[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return keyBuffer;
|
||||
}
|
||||
|
||||
@ -759,6 +804,20 @@ bool ds4_pad_handler::get_is_right_stick(const std::shared_ptr<PadDevice>& /*dev
|
||||
}
|
||||
}
|
||||
|
||||
bool ds4_pad_handler::get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& /*device*/, u64 keyCode)
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case DS4KeyCodes::Touch_L:
|
||||
case DS4KeyCodes::Touch_R:
|
||||
case DS4KeyCodes::Touch_U:
|
||||
case DS4KeyCodes::Touch_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PadHandlerBase::connection ds4_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
DS4Device* ds4_dev = static_cast<DS4Device*>(device.get());
|
||||
|
@ -19,6 +19,7 @@ namespace reports
|
||||
constexpr u32 DS4_OUTPUT_REPORT_BLUETOOTH_SIZE = 78;
|
||||
constexpr u32 DS4_TOUCHPAD_WIDTH = 1920;
|
||||
constexpr u32 DS4_TOUCHPAD_HEIGHT = 942;
|
||||
constexpr u32 DS4_TOUCH_POINT_INACTIVE = 0x80;
|
||||
|
||||
struct ds4_touch_point
|
||||
{
|
||||
@ -33,7 +34,7 @@ namespace reports
|
||||
struct ds4_touch_report
|
||||
{
|
||||
u8 timestamp;
|
||||
ds4_touch_point points[2];
|
||||
std::array<ds4_touch_point, 2> points;
|
||||
};
|
||||
static_assert(sizeof(ds4_touch_report) == 9);
|
||||
|
||||
@ -61,7 +62,7 @@ namespace reports
|
||||
u8 report_id;
|
||||
ds4_input_report_common common;
|
||||
u8 num_touch_reports;
|
||||
ds4_touch_report touch_reports[3];
|
||||
std::array<ds4_touch_report, 3> touch_reports;
|
||||
u8 reserved[3];
|
||||
};
|
||||
static_assert(sizeof(ds4_input_report_usb) == DS4_INPUT_REPORT_USB_SIZE);
|
||||
@ -72,7 +73,7 @@ namespace reports
|
||||
u8 reserved[2];
|
||||
ds4_input_report_common common;
|
||||
u8 num_touch_reports;
|
||||
ds4_touch_report touch_reports[4];
|
||||
std::array<ds4_touch_report, 4> touch_reports;
|
||||
u8 reserved2[2];
|
||||
u8 crc32[4];
|
||||
};
|
||||
@ -150,6 +151,11 @@ class ds4_pad_handler final : public hid_pad_handler<DS4Device>
|
||||
PSButton,
|
||||
TouchPad,
|
||||
|
||||
Touch_L,
|
||||
Touch_R,
|
||||
Touch_U,
|
||||
Touch_D,
|
||||
|
||||
L2,
|
||||
R2,
|
||||
|
||||
@ -184,6 +190,7 @@ private:
|
||||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_left_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
|
@ -52,6 +52,10 @@ dualsense_pad_handler::dualsense_pad_handler()
|
||||
{ DualSenseKeyCodes::PSButton, "PS Button" },
|
||||
{ DualSenseKeyCodes::Mic, "Mic" },
|
||||
{ DualSenseKeyCodes::TouchPad, "Touch Pad" },
|
||||
{ DualSenseKeyCodes::Touch_L, "Touch Left" },
|
||||
{ DualSenseKeyCodes::Touch_R, "Touch Right" },
|
||||
{ DualSenseKeyCodes::Touch_U, "Touch Up" },
|
||||
{ DualSenseKeyCodes::Touch_D, "Touch Down" },
|
||||
{ DualSenseKeyCodes::L1, "L1" },
|
||||
{ DualSenseKeyCodes::L2, "L2" },
|
||||
{ DualSenseKeyCodes::L3, "L3" },
|
||||
@ -538,6 +542,20 @@ bool dualsense_pad_handler::get_is_right_stick(const std::shared_ptr<PadDevice>&
|
||||
}
|
||||
}
|
||||
|
||||
bool dualsense_pad_handler::get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& /*device*/, u64 keyCode)
|
||||
{
|
||||
switch (keyCode)
|
||||
{
|
||||
case DualSenseKeyCodes::Touch_L:
|
||||
case DualSenseKeyCodes::Touch_R:
|
||||
case DualSenseKeyCodes::Touch_U:
|
||||
case DualSenseKeyCodes::Touch_D:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PadHandlerBase::connection dualsense_pad_handler::update_connection(const std::shared_ptr<PadDevice>& device)
|
||||
{
|
||||
DualSenseDevice* dualsense_dev = static_cast<DualSenseDevice*>(device.get());
|
||||
@ -728,6 +746,25 @@ std::unordered_map<u64, u16> dualsense_pad_handler::get_button_values(const std:
|
||||
keyBuffer[DualSenseKeyCodes::TouchPad] = ((data & 0x02) != 0) ? 255 : 0;
|
||||
keyBuffer[DualSenseKeyCodes::Mic] = ((data & 0x04) != 0) ? 255 : 0;
|
||||
|
||||
// Touch Pad
|
||||
for (const dualsense_touch_point& point : input.points)
|
||||
{
|
||||
if (!(point.contact & DUALSENSE_TOUCH_POINT_INACTIVE))
|
||||
{
|
||||
const s32 x = (point.x_hi << 8) | point.x_lo;
|
||||
const s32 y = (point.y_hi << 4) | point.y_lo;
|
||||
|
||||
const f32 x_scaled = ScaledInput(static_cast<float>(x), 0.0f, static_cast<float>(DUALSENSE_TOUCHPAD_WIDTH), 0.0f, 255.0f);
|
||||
const f32 y_scaled = ScaledInput(static_cast<float>(y), 0.0f, static_cast<float>(DUALSENSE_TOUCHPAD_HEIGHT), 0.0f, 255.0f);
|
||||
|
||||
keyBuffer[DualSenseKeyCodes::Touch_L] = Clamp0To255((127.5f - x_scaled) * 2.0f);
|
||||
keyBuffer[DualSenseKeyCodes::Touch_R] = Clamp0To255((x_scaled - 127.5f) * 2.0f);
|
||||
|
||||
keyBuffer[DualSenseKeyCodes::Touch_U] = Clamp0To255((127.5f - y_scaled) * 2.0f);
|
||||
keyBuffer[DualSenseKeyCodes::Touch_D] = Clamp0To255((y_scaled - 127.5f) * 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (dualsense_dev->feature_set == DualSenseDevice::DualSenseFeatureSet::Edge)
|
||||
{
|
||||
keyBuffer[DualSenseKeyCodes::EdgeFnL] = ((data & 0x10) != 0) ? 255 : 0;
|
||||
|
@ -19,6 +19,7 @@ namespace reports
|
||||
constexpr u32 DUALSENSE_INPUT_REPORT_GYRO_X_OFFSET = 15;
|
||||
constexpr u32 DUALSENSE_TOUCHPAD_WIDTH = 1920;
|
||||
constexpr u32 DUALSENSE_TOUCHPAD_HEIGHT = 1080;
|
||||
constexpr u32 DUALSENSE_TOUCH_POINT_INACTIVE = 0x80;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -82,7 +83,7 @@ namespace reports
|
||||
le_t<u16, 1> accel[3];
|
||||
le_t<u32, 1> sensor_timestamp;
|
||||
u8 reserved2;
|
||||
dualsense_touch_point points[2];
|
||||
std::array<dualsense_touch_point, 2> points;
|
||||
u8 reserved3[12];
|
||||
u8 status;
|
||||
u8 reserved4[10];
|
||||
@ -210,6 +211,11 @@ class dualsense_pad_handler final : public hid_pad_handler<DualSenseDevice>
|
||||
Mic,
|
||||
TouchPad,
|
||||
|
||||
Touch_L,
|
||||
Touch_R,
|
||||
Touch_U,
|
||||
Touch_D,
|
||||
|
||||
L2,
|
||||
R2,
|
||||
|
||||
@ -247,6 +253,7 @@ private:
|
||||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_left_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
std::unordered_map<u64, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u64, u16>& data) override;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,20 @@
|
||||
class SDLDevice : public PadDevice
|
||||
{
|
||||
public:
|
||||
|
||||
struct touch_point
|
||||
{
|
||||
int index = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
};
|
||||
|
||||
struct touchpad
|
||||
{
|
||||
int index = 0;
|
||||
std::vector<touch_point> fingers;
|
||||
};
|
||||
|
||||
struct sdl_info
|
||||
{
|
||||
SDL_GameController* game_controller = nullptr;
|
||||
@ -37,6 +51,8 @@ public:
|
||||
|
||||
std::set<SDL_GameControllerButton> button_ids;
|
||||
std::set<SDL_GameControllerAxis> axis_ids;
|
||||
|
||||
std::vector<touchpad> touchpads;
|
||||
};
|
||||
|
||||
sdl_info sdl{};
|
||||
@ -81,6 +97,11 @@ class sdl_pad_handler : public PadHandlerBase
|
||||
Paddle4,
|
||||
Touchpad,
|
||||
|
||||
Touch_L,
|
||||
Touch_R,
|
||||
Touch_U,
|
||||
Touch_D,
|
||||
|
||||
LT,
|
||||
RT,
|
||||
|
||||
@ -124,6 +145,7 @@ private:
|
||||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_left_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
||||
std::unordered_map<u64, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u64, u16>& data) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user