From 9a6aac1662ed975a26a758cc9a52e8f645952c9c Mon Sep 17 00:00:00 2001 From: SEt <70444390+SEt-t@users.noreply.github.com> Date: Wed, 16 Sep 2020 23:36:06 +0300 Subject: [PATCH] Improve pad support (#8800) * Add support for another DS3 HID Report ID for Win7 * Add support for reading accel/gyro pad data over SCP --- rpcs3/Input/ds3_pad_handler.cpp | 19 ++++++++++++++++--- rpcs3/Input/ds3_pad_handler.h | 3 +++ rpcs3/Input/xinput_pad_handler.cpp | 15 +++++++++++++++ rpcs3/Input/xinput_pad_handler.h | 10 ++++++++++ 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/rpcs3/Input/ds3_pad_handler.cpp b/rpcs3/Input/ds3_pad_handler.cpp index b0e710e08c..7240e79862 100644 --- a/rpcs3/Input/ds3_pad_handler.cpp +++ b/rpcs3/Input/ds3_pad_handler.cpp @@ -96,7 +96,17 @@ bool ds3_pad_handler::Init() #ifdef _WIN32 u8 buf[0xFF]; buf[0] = 0xF2; - if (handle && (hid_get_feature_report(handle, buf, 0xFF) >= 0)) + bool got_report = false; + if (handle) + { + got_report = hid_get_feature_report(handle, buf, 0xFF) >= 0; + if (!got_report) + { + buf[0] = 0; + got_report = hid_get_feature_report(handle, buf, 0xFF) >= 0; + } + } + if (got_report) #else if(handle) #endif @@ -104,6 +114,9 @@ bool ds3_pad_handler::Init() std::shared_ptr ds3dev = std::make_shared(); ds3dev->device = hid_info->path; ds3dev->handle = handle; +#ifdef _WIN32 + ds3dev->report_id = buf[0]; +#endif controllers.emplace_back(ds3dev); } else @@ -286,7 +299,7 @@ ds3_pad_handler::DS3Status ds3_pad_handler::get_data(const std::shared_ptrbuf; #ifdef _WIN32 - dbuf[0] = 0xF2; + dbuf[0] = ds3dev->report_id; int result = hid_get_feature_report(ds3dev->handle, dbuf, sizeof(dbuf)); #else int result = hid_read(ds3dev->handle, dbuf, sizeof(dbuf)); @@ -295,7 +308,7 @@ ds3_pad_handler::DS3Status ds3_pad_handler::get_data(const std::shared_ptr 0) { #ifdef _WIN32 - if(dbuf[0] == 0xF2) + if (dbuf[0] == ds3dev->report_id) #else if (dbuf[0] == 0x01 && dbuf[1] != 0xFF) #endif diff --git a/rpcs3/Input/ds3_pad_handler.h b/rpcs3/Input/ds3_pad_handler.h index a7117b84cc..18b504d6ab 100644 --- a/rpcs3/Input/ds3_pad_handler.h +++ b/rpcs3/Input/ds3_pad_handler.h @@ -77,6 +77,9 @@ class ds3_pad_handler final : public PadHandlerBase u8 large_motor = 0; u8 small_motor = 0; u8 status = DS3Status::Disconnected; +#ifdef _WIN32 + u8 report_id = 0; +#endif }; const u16 DS3_VID = 0x054C; diff --git a/rpcs3/Input/xinput_pad_handler.cpp b/rpcs3/Input/xinput_pad_handler.cpp index b85c4433e5..f9b19bf287 100644 --- a/rpcs3/Input/xinput_pad_handler.cpp +++ b/rpcs3/Input/xinput_pad_handler.cpp @@ -74,6 +74,7 @@ xinput_pad_handler::~xinput_pad_handler() FreeLibrary(library); library = nullptr; xinputGetExtended = nullptr; + xinputGetCustomData = nullptr; xinputGetState = nullptr; xinputSetState = nullptr; xinputGetBatteryInformation = nullptr; @@ -303,6 +304,7 @@ bool xinput_pad_handler::Init() if (library) { xinputGetExtended = reinterpret_cast(GetProcAddress(library, "XInputGetExtended")); // Optional + xinputGetCustomData = reinterpret_cast(GetProcAddress(library, "XInputGetCustomData")); // Optional xinputGetState = reinterpret_cast(GetProcAddress(library, reinterpret_cast(100))); if (!xinputGetState) xinputGetState = reinterpret_cast(GetProcAddress(library, "XInputGetState")); @@ -319,6 +321,7 @@ bool xinput_pad_handler::Init() FreeLibrary(library); library = nullptr; xinputGetExtended = nullptr; + xinputGetCustomData = nullptr; xinputGetState = nullptr; xinputSetState = nullptr; xinputGetBatteryInformation = nullptr; @@ -450,6 +453,18 @@ void xinput_pad_handler::get_extended_info(const std::shared_ptr& dev (*xinputGetBatteryInformation)(padnum, BATTERY_DEVTYPE_GAMEPAD, &battery_info); pad->m_cable_state = battery_info.BatteryType == BATTERY_TYPE_WIRED ? 1 : 0; pad->m_battery_level = pad->m_cable_state ? BATTERY_LEVEL_FULL : battery_info.BatteryLevel; + + if (xinputGetCustomData) + { + SCP_DS3_ACCEL sensors; + if (xinputGetCustomData(dev->deviceNumber, 0, &sensors) == ERROR_SUCCESS) + { + pad->m_sensors[0].m_value = sensors.SCP_ACCEL_X; + pad->m_sensors[1].m_value = sensors.SCP_ACCEL_Y; + pad->m_sensors[2].m_value = sensors.SCP_ACCEL_Z; + pad->m_sensors[3].m_value = sensors.SCP_GYRO; + } + } } void xinput_pad_handler::apply_pad_data(const std::shared_ptr& device, const std::shared_ptr& pad) diff --git a/rpcs3/Input/xinput_pad_handler.h b/rpcs3/Input/xinput_pad_handler.h index dd3215b174..2e2a6143e3 100644 --- a/rpcs3/Input/xinput_pad_handler.h +++ b/rpcs3/Input/xinput_pad_handler.h @@ -40,6 +40,14 @@ struct SCP_EXTN float SCP_PS; }; +struct SCP_DS3_ACCEL +{ + unsigned short SCP_ACCEL_X; + unsigned short SCP_ACCEL_Z; + unsigned short SCP_ACCEL_Y; + unsigned short SCP_GYRO; +}; + class xinput_pad_handler final : public PadHandlerBase { // These are all the possible buttons on a standard xbox 360 or xbox one controller @@ -103,6 +111,7 @@ public: private: typedef DWORD (WINAPI * PFN_XINPUTGETEXTENDED)(DWORD, SCP_EXTN *); + typedef DWORD (WINAPI * PFN_XINPUTGETCUSTOMDATA)(DWORD, DWORD, void *); typedef DWORD (WINAPI * PFN_XINPUTGETSTATE)(DWORD, XINPUT_STATE *); typedef DWORD (WINAPI * PFN_XINPUTSETSTATE)(DWORD, XINPUT_VIBRATION *); typedef DWORD (WINAPI * PFN_XINPUTGETBATTERYINFORMATION)(DWORD, BYTE, XINPUT_BATTERY_INFORMATION *); @@ -115,6 +124,7 @@ private: bool is_init{ false }; HMODULE library{ nullptr }; PFN_XINPUTGETEXTENDED xinputGetExtended{ nullptr }; + PFN_XINPUTGETCUSTOMDATA xinputGetCustomData{ nullptr }; PFN_XINPUTGETSTATE xinputGetState{ nullptr }; PFN_XINPUTSETSTATE xinputSetState{ nullptr }; PFN_XINPUTGETBATTERYINFORMATION xinputGetBatteryInformation{ nullptr };