rpcs3/rpcs3/Input/skateboard_pad_handler.h
2023-09-05 20:41:39 +02:00

189 lines
7.6 KiB
C++

#pragma once
#include "hid_pad_handler.h"
#include <array>
#include <unordered_map>
namespace
{
// Descriptor
// 0x09, 0x05, // Usage (0x05)
// 0xA1, 0x01, // Collection (Application)
// 0x05, 0x09, // Usage Page (Button)
// 0x19, 0x01, // Usage Minimum (0x01)
// 0x29, 0x0D, // Usage Maximum (0x0D)
// 0x15, 0x00, // Logical Minimum (0)
// 0x25, 0x01, // Logical Maximum (1)
// 0x75, 0x01, // Report Size (1)
// 0x95, 0x0D, // Report Count (13)
// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x75, 0x03, // Report Size (3)
// 0x95, 0x01, // Report Count (1)
// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
// 0x09, 0x39, // Usage (Hat switch)
// 0x15, 0x00, // Logical Minimum (0)
// 0x25, 0x07, // Logical Maximum (7)
// 0x35, 0x00, // Physical Minimum (0)
// 0x46, 0x3B, 0x01, // Physical Maximum (315)
// 0x65, 0x14, // Unit (System: English Rotation, Length: Centimeter)
// 0x75, 0x04, // Report Size (4)
// 0x95, 0x01, // Report Count (1)
// 0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
// 0x75, 0x04, // Report Size (4)
// 0x95, 0x01, // Report Count (1)
// 0x81, 0x03, // Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x09, 0x30, // Usage (X)
// 0x09, 0x31, // Usage (Y)
// 0x09, 0x32, // Usage (Z)
// 0x09, 0x35, // Usage (Rz)
// 0x15, 0x00, // Logical Minimum (0)
// 0x26, 0xFF, 0x00, // Logical Maximum (255)
// 0x35, 0x00, // Physical Minimum (0)
// 0x46, 0xFF, 0x00, // Physical Maximum (255)
// 0x65, 0x00, // Unit (None)
// 0x75, 0x08, // Report Size (8)
// 0x95, 0x04, // Report Count (4)
// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
// 0x09, 0x20, // Usage (0x20)
// 0x09, 0x21, // Usage (0x21)
// 0x09, 0x22, // Usage (0x22)
// 0x09, 0x23, // Usage (0x23)
// 0x09, 0x24, // Usage (0x24)
// 0x09, 0x25, // Usage (0x25)
// 0x09, 0x26, // Usage (0x26)
// 0x09, 0x27, // Usage (0x27)
// 0x09, 0x28, // Usage (0x28)
// 0x09, 0x29, // Usage (0x29)
// 0x09, 0x2A, // Usage (0x2A)
// 0x09, 0x2B, // Usage (0x2B)
// 0x15, 0x00, // Logical Minimum (0)
// 0x26, 0xFF, 0x00, // Logical Maximum (255)
// 0x75, 0x08, // Report Size (8)
// 0x95, 0x0C, // Report Count (12)
// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x09, 0x2C, // Usage (0x2C)
// 0x09, 0x2D, // Usage (0x2D)
// 0x09, 0x2E, // Usage (0x2E)
// 0x09, 0x2F, // Usage (0x2F)
// 0x15, 0x00, // Logical Minimum (0)
// 0x26, 0xFF, 0x03, // Logical Maximum (1023)
// 0x35, 0x00, // Physical Minimum (0)
// 0x46, 0xFF, 0x03, // Physical Maximum (1023)
// 0x75, 0x10, // Report Size (16)
// 0x95, 0x04, // Report Count (4)
// 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// 0x0A, 0x21, 0x26, // Usage (0x2621)
// 0x15, 0x00, // Logical Minimum (0)
// 0x26, 0xFF, 0x00, // Logical Maximum (255)
// 0x35, 0x00, // Physical Minimum (0)
// 0x46, 0xFF, 0x00, // Physical Maximum (255)
// 0x75, 0x08, // Report Size (8)
// 0x95, 0x08, // Report Count (8)
// 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
// 0x0A, 0x21, 0x26, // Usage (0x2621)
// 0x15, 0x00, // Logical Minimum (0)
// 0x26, 0xFF, 0x00, // Logical Maximum (255)
// 0x75, 0x08, // Report Size (8)
// 0x95, 0x08, // Report Count (8)
// 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
// 0xC0, // End Collection
#pragma pack(push, 1)
struct skateboard_input_report
{
// 13 buttons, value range 0 to 1, 13 bits + 3 bits padding (2 bytes total)
u16 buttons{};
// d-pad, value range 0 to 7 (8 directions), 4 bits + 4 bits padding (1 byte total)
u8 d_pad{};
// 4 axis (X, Y, Z, RZ), value range 0 to 255, 1 byte each (4 bytes total)
u8 axis_x{};
u8 axis_y{};
u8 axis_z{};
u8 axis_rz{};
// 12 axis (0x20 - 0x2B), value range 0 to 255, 1 byte each (12 bytes total)
// These 12 values match the pressure sensitivity values of the buttons (CELL_PAD_BTN_OFFSET_PRESS)
u8 pressure_right{}; // value for CELL_PAD_BTN_OFFSET_PRESS_RIGHT -> always 0 ?
u8 pressure_left{}; // value for CELL_PAD_BTN_OFFSET_PRESS_LEFT -> always 0 ?
u8 pressure_up{}; // value for CELL_PAD_BTN_OFFSET_PRESS_UP -> always 0 ?
u8 pressure_down{}; // value for CELL_PAD_BTN_OFFSET_PRESS_DOWN -> always 0 ?
u8 pressure_triangle{}; // value for CELL_PAD_BTN_OFFSET_PRESS_TRIANGLE -> infrared nose
u8 pressure_circle{}; // value for CELL_PAD_BTN_OFFSET_PRESS_CIRCLE -> infrared tail
u8 pressure_cross{}; // value for CELL_PAD_BTN_OFFSET_PRESS_CROSS -> infrared left
u8 pressure_square{}; // value for CELL_PAD_BTN_OFFSET_PRESS_SQUARE -> infrared right
u8 pressure_l1{}; // value for CELL_PAD_BTN_OFFSET_PRESS_L1 -> tilt left (probably)
u8 pressure_r1{}; // value for CELL_PAD_BTN_OFFSET_PRESS_R1 -> tilt right (probably)
u8 pressure_l2{}; // value for CELL_PAD_BTN_OFFSET_PRESS_L2 -> always 0 ?
u8 pressure_r2{}; // value for CELL_PAD_BTN_OFFSET_PRESS_R2 -> always 0 ?
// 4 axis (0x2C - 0x2F), value range 0 to 1023, 2 bytes each (8 bytes total)
std::array<u16, 4> large_axes{};
};
#pragma pack(pop)
struct skateboard_output_report
{
// 8 axis (0x2621), value range 0 to 255, 1 byte each (8 bytes total)
std::array<u8, 8> data{};
};
struct skateboard_feature_report
{
// 8 axis (0x2621), value range 0 to 255, 1 byte each (8 bytes total)
std::array<u8, 8> data{};
};
}
class skateboard_device : public HidDevice
{
public:
bool skateboard_is_on = false;
};
class skateboard_pad_handler final : public hid_pad_handler<skateboard_device>
{
enum skateboard_key_codes
{
none = 0,
left,
right,
up,
down,
cross,
square,
circle,
triangle,
start,
select,
ps,
ir_nose,
ir_tail,
ir_left,
ir_right,
tilt_left,
tilt_right,
};
public:
skateboard_pad_handler();
~skateboard_pad_handler();
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;
void init_config(cfg_pad* cfg) override;
private:
DataStatus get_data(skateboard_device* device) override;
void check_add_device(hid_device* hidDevice, std::string_view path, std::wstring_view wide_serial) override;
int send_output_report(skateboard_device* device) 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;
void get_extended_info(const pad_ensemble& binding) override;
void apply_pad_data(const pad_ensemble& binding) override;
};