2020-12-05 13:08:24 +01:00
|
|
|
#pragma once
|
2017-04-29 03:02:28 +02:00
|
|
|
|
2021-02-11 22:13:21 +01:00
|
|
|
#include "hid_pad_handler.h"
|
2017-04-29 03:02:28 +02:00
|
|
|
|
2020-12-22 16:04:08 +01:00
|
|
|
#include <unordered_map>
|
|
|
|
|
|
2024-06-27 20:37:33 +02:00
|
|
|
namespace reports
|
2024-04-28 13:13:47 +02:00
|
|
|
{
|
|
|
|
|
constexpr u32 DS4_ACC_RES_PER_G = 8192;
|
|
|
|
|
constexpr u32 DS4_GYRO_RES_PER_DEG_S = 86; // technically this could be 1024, but keeping it at 86 keeps us within 16 bits of precision
|
|
|
|
|
constexpr u32 DS4_FEATURE_REPORT_USB_CALIBRATION_SIZE = 37;
|
|
|
|
|
constexpr u32 DS4_FEATURE_REPORT_BLUETOOTH_CALIBRATION_SIZE = 41;
|
2025-04-05 21:50:45 +02:00
|
|
|
// constexpr u32 DS4_FEATURE_REPORT_PAIRING_INFO_SIZE = 16;
|
|
|
|
|
// constexpr u32 DS4_FEATURE_REPORT_0x81_SIZE = 7;
|
2024-04-28 13:13:47 +02:00
|
|
|
constexpr u32 DS4_FEATURE_REPORT_FIRMWARE_INFO_SIZE = 49;
|
|
|
|
|
constexpr u32 DS4_INPUT_REPORT_USB_SIZE = 64;
|
|
|
|
|
constexpr u32 DS4_INPUT_REPORT_BLUETOOTH_SIZE = 78;
|
|
|
|
|
constexpr u32 DS4_OUTPUT_REPORT_USB_SIZE = 32;
|
|
|
|
|
constexpr u32 DS4_OUTPUT_REPORT_BLUETOOTH_SIZE = 78;
|
|
|
|
|
constexpr u32 DS4_TOUCHPAD_WIDTH = 1920;
|
|
|
|
|
constexpr u32 DS4_TOUCHPAD_HEIGHT = 942;
|
2024-07-30 22:51:17 +02:00
|
|
|
constexpr u32 DS4_TOUCH_POINT_INACTIVE = 0x80;
|
2024-04-28 13:13:47 +02:00
|
|
|
|
|
|
|
|
struct ds4_touch_point
|
|
|
|
|
{
|
|
|
|
|
u8 contact;
|
|
|
|
|
u8 x_lo;
|
|
|
|
|
u8 x_hi : 4;
|
|
|
|
|
u8 y_lo : 4;
|
|
|
|
|
u8 y_hi;
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_touch_point) == 4);
|
|
|
|
|
|
|
|
|
|
struct ds4_touch_report
|
|
|
|
|
{
|
|
|
|
|
u8 timestamp;
|
2024-07-30 22:51:17 +02:00
|
|
|
std::array<ds4_touch_point, 2> points;
|
2024-04-28 13:13:47 +02:00
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_touch_report) == 9);
|
|
|
|
|
|
|
|
|
|
struct ds4_input_report_common
|
|
|
|
|
{
|
|
|
|
|
u8 x;
|
|
|
|
|
u8 y;
|
|
|
|
|
u8 rx;
|
|
|
|
|
u8 ry;
|
|
|
|
|
u8 buttons[3];
|
|
|
|
|
u8 z;
|
|
|
|
|
u8 rz;
|
|
|
|
|
le_t<u16, 1> sensor_timestamp;
|
|
|
|
|
u8 sensor_temperature;
|
|
|
|
|
le_t<u16, 1> gyro[3];
|
|
|
|
|
le_t<u16, 1> accel[3];
|
|
|
|
|
u8 reserved2[5];
|
|
|
|
|
u8 status[2];
|
|
|
|
|
u8 reserved3;
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_input_report_common) == 32);
|
|
|
|
|
|
|
|
|
|
struct ds4_input_report_usb
|
|
|
|
|
{
|
|
|
|
|
u8 report_id;
|
|
|
|
|
ds4_input_report_common common;
|
|
|
|
|
u8 num_touch_reports;
|
2024-07-30 22:51:17 +02:00
|
|
|
std::array<ds4_touch_report, 3> touch_reports;
|
2024-04-28 13:13:47 +02:00
|
|
|
u8 reserved[3];
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_input_report_usb) == DS4_INPUT_REPORT_USB_SIZE);
|
|
|
|
|
|
|
|
|
|
struct ds4_input_report_bt
|
|
|
|
|
{
|
|
|
|
|
u8 report_id;
|
|
|
|
|
u8 reserved[2];
|
|
|
|
|
ds4_input_report_common common;
|
|
|
|
|
u8 num_touch_reports;
|
2024-07-30 22:51:17 +02:00
|
|
|
std::array<ds4_touch_report, 4> touch_reports;
|
2024-04-28 13:13:47 +02:00
|
|
|
u8 reserved2[2];
|
|
|
|
|
u8 crc32[4];
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_input_report_bt) == DS4_INPUT_REPORT_BLUETOOTH_SIZE);
|
|
|
|
|
|
|
|
|
|
struct ds4_output_report_common
|
|
|
|
|
{
|
|
|
|
|
u8 valid_flag0;
|
|
|
|
|
u8 valid_flag1;
|
|
|
|
|
u8 reserved;
|
|
|
|
|
u8 motor_right;
|
|
|
|
|
u8 motor_left;
|
|
|
|
|
u8 lightbar_red;
|
|
|
|
|
u8 lightbar_green;
|
|
|
|
|
u8 lightbar_blue;
|
|
|
|
|
u8 lightbar_blink_on;
|
|
|
|
|
u8 lightbar_blink_off;
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_output_report_common) == 10);
|
|
|
|
|
|
|
|
|
|
struct ds4_output_report_usb
|
|
|
|
|
{
|
|
|
|
|
u8 report_id;
|
|
|
|
|
ds4_output_report_common common;
|
|
|
|
|
u8 reserved[21];
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_output_report_usb) == DS4_OUTPUT_REPORT_USB_SIZE);
|
|
|
|
|
|
|
|
|
|
struct ds4_output_report_bt
|
|
|
|
|
{
|
|
|
|
|
u8 report_id;
|
|
|
|
|
u8 hw_control;
|
|
|
|
|
u8 audio_control;
|
|
|
|
|
ds4_output_report_common common;
|
|
|
|
|
u8 reserved[61];
|
|
|
|
|
u8 crc32[4];
|
|
|
|
|
};
|
|
|
|
|
static_assert(sizeof(ds4_output_report_bt) == DS4_OUTPUT_REPORT_BLUETOOTH_SIZE);
|
2025-04-05 21:50:45 +02:00
|
|
|
} // namespace reports
|
2024-04-28 13:13:47 +02:00
|
|
|
|
2021-02-11 22:13:21 +01:00
|
|
|
class DS4Device : public HidDevice
|
|
|
|
|
{
|
|
|
|
|
public:
|
2021-02-13 01:25:39 +01:00
|
|
|
bool bt_controller{false};
|
|
|
|
|
bool has_calib_data{false};
|
|
|
|
|
std::array<CalibData, CalibIndex::COUNT> calib_data{};
|
2024-06-27 20:37:33 +02:00
|
|
|
reports::ds4_input_report_usb report_usb{};
|
|
|
|
|
reports::ds4_input_report_bt report_bt{};
|
2021-02-11 22:13:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class ds4_pad_handler final : public hid_pad_handler<DS4Device>
|
2017-04-29 03:02:28 +02:00
|
|
|
{
|
2017-11-27 22:31:15 +01:00
|
|
|
// These are all the possible buttons on a standard DS4 controller
|
|
|
|
|
// The touchpad is restricted to its button for now (or forever?)
|
|
|
|
|
enum DS4KeyCodes
|
|
|
|
|
{
|
2021-08-08 16:45:45 +02:00
|
|
|
None = 0,
|
|
|
|
|
|
|
|
|
|
Triangle,
|
2017-11-27 22:31:15 +01:00
|
|
|
Circle,
|
|
|
|
|
Cross,
|
|
|
|
|
Square,
|
|
|
|
|
Left,
|
|
|
|
|
Right,
|
|
|
|
|
Up,
|
|
|
|
|
Down,
|
|
|
|
|
R1,
|
2025-04-05 21:50:45 +02:00
|
|
|
// R2But,
|
2017-11-27 22:31:15 +01:00
|
|
|
R3,
|
|
|
|
|
L1,
|
2025-04-05 21:50:45 +02:00
|
|
|
// L2But,
|
2017-11-27 22:31:15 +01:00
|
|
|
L3,
|
|
|
|
|
Share,
|
|
|
|
|
Options,
|
|
|
|
|
PSButton,
|
|
|
|
|
TouchPad,
|
|
|
|
|
|
2024-07-30 22:51:17 +02:00
|
|
|
Touch_L,
|
|
|
|
|
Touch_R,
|
|
|
|
|
Touch_U,
|
|
|
|
|
Touch_D,
|
|
|
|
|
|
2017-11-27 22:31:15 +01:00
|
|
|
L2,
|
|
|
|
|
R2,
|
|
|
|
|
|
|
|
|
|
LSXNeg,
|
|
|
|
|
LSXPos,
|
|
|
|
|
LSYNeg,
|
|
|
|
|
LSYPos,
|
|
|
|
|
RSXNeg,
|
|
|
|
|
RSXPos,
|
|
|
|
|
RSYNeg,
|
2021-08-08 16:45:45 +02:00
|
|
|
RSYPos
|
2017-11-27 22:31:15 +01:00
|
|
|
};
|
|
|
|
|
|
2017-04-29 03:02:28 +02:00
|
|
|
public:
|
2024-06-11 22:30:16 +02:00
|
|
|
ds4_pad_handler();
|
2017-08-15 14:03:07 +02:00
|
|
|
~ds4_pad_handler();
|
2017-04-29 03:02:28 +02:00
|
|
|
|
2022-10-21 22:35:31 +02:00
|
|
|
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
|
2020-03-05 19:02:28 +01:00
|
|
|
u32 get_battery_level(const std::string& padId) override;
|
2021-08-10 21:45:26 +02:00
|
|
|
void init_config(cfg_pad* cfg) override;
|
2017-04-29 03:02:28 +02:00
|
|
|
|
2017-08-15 14:03:07 +02:00
|
|
|
private:
|
2017-11-27 22:31:15 +01:00
|
|
|
// This function gets us usuable buffer from the rawbuffer of padData
|
2021-04-07 23:05:18 +02:00
|
|
|
bool GetCalibrationData(DS4Device* ds4Device) const;
|
2017-05-19 05:06:31 +02:00
|
|
|
|
2021-02-12 02:44:26 +01:00
|
|
|
// Copies data into padData if status is NewData, otherwise buffer is untouched
|
|
|
|
|
DataStatus get_data(DS4Device* ds4Device) override;
|
|
|
|
|
int send_output_report(DS4Device* device) override;
|
2025-03-03 19:59:08 +01:00
|
|
|
void check_add_device(hid_device* hidDevice, hid_enumerated_device_view path, std::wstring_view serial) override;
|
2019-09-20 16:28:55 +02:00
|
|
|
|
2022-10-15 12:41:21 +02:00
|
|
|
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
|
|
|
|
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;
|
2024-07-30 22:51:17 +02:00
|
|
|
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u64 keyCode) override;
|
2019-09-20 16:28:55 +02:00
|
|
|
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
2022-08-13 09:56:04 +02:00
|
|
|
void get_extended_info(const pad_ensemble& binding) override;
|
|
|
|
|
void apply_pad_data(const pad_ensemble& binding) override;
|
2019-09-20 16:28:55 +02:00
|
|
|
std::unordered_map<u64, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
2020-12-14 14:33:43 +01:00
|
|
|
pad_preview_values get_preview_values(const std::unordered_map<u64, u16>& data) override;
|
2017-04-29 03:02:28 +02:00
|
|
|
};
|