mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12:00
Improve pad support (#8800)
* Add support for another DS3 HID Report ID for Win7 * Add support for reading accel/gyro pad data over SCP
This commit is contained in:
parent
4c70864588
commit
9a6aac1662
4 changed files with 44 additions and 3 deletions
|
@ -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<ds3_device> ds3dev = std::make_shared<ds3_device>();
|
||||
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_ptr<ds3_d
|
|||
auto& dbuf = ds3dev->buf;
|
||||
|
||||
#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<ds3_d
|
|||
if (result > 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if(dbuf[0] == 0xF2)
|
||||
if (dbuf[0] == ds3dev->report_id)
|
||||
#else
|
||||
if (dbuf[0] == 0x01 && dbuf[1] != 0xFF)
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<PFN_XINPUTGETEXTENDED>(GetProcAddress(library, "XInputGetExtended")); // Optional
|
||||
xinputGetCustomData = reinterpret_cast<PFN_XINPUTGETCUSTOMDATA>(GetProcAddress(library, "XInputGetCustomData")); // Optional
|
||||
xinputGetState = reinterpret_cast<PFN_XINPUTGETSTATE>(GetProcAddress(library, reinterpret_cast<LPCSTR>(100)));
|
||||
if (!xinputGetState)
|
||||
xinputGetState = reinterpret_cast<PFN_XINPUTGETSTATE>(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<PadDevice>& 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<PadDevice>& device, const std::shared_ptr<Pad>& pad)
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue