Skip to content

Commit

Permalink
Improve PS4 compatibility
Browse files Browse the repository at this point in the history
PS4 Tatacon will be recognized by PS4, but will timeout after
around 8 minutes like all unauthorized controllers.

Dualshock4 mode will not work on PS4.
  • Loading branch information
ravinrabbid committed Nov 16, 2024
1 parent b32fe99 commit 33530a3
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 70 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ If you have any questions about the project in general or need hints how to buil

## Features

- Various controller emulation modes
- HORI PS4-095 Taiko Drum for PS4 (Untested! Will probably timeout after 8 minutes)
- Various controller emulation modes
- HORI PS4-095 Taiko Drum for PS4 (will timeout after ~8 minutes, replug before each song)
- HORI NSW-079 Taiko Drum for Switch (compatible with Taiko no Tatsujin Rhythm Festival / Drum'n'Fun on Switch)
- Dualshock 4 (does not work on an actual PS4!)
- Dualshock 4 (Only for PC/Steam, will not work on an actual PS4!)
- Dualshock 3
- Switch Pro Controller
- XInput
Expand Down
150 changes: 83 additions & 67 deletions src/usb/device/hid/ps4_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const uint8_t ps4_desc_hid_report[] = {
0x75, 0x08, // Report Size (8)
0x95, 0x04, // Report Count (4)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
Expand All @@ -68,22 +69,23 @@ const uint8_t ps4_desc_hid_report[] = {
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x42, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x65, 0x00, // Unit (None)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0E, // Usage Maximum (0x0E)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x0E, // Report Count (14)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

0x65, 0x00, // Unit (None)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0E, // Usage Maximum (0x0E)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x0E, // Report Count (14)
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)
0x75, 0x06, // Report Size (6)
0x95, 0x01, // Report Count (1)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x7F, // Logical Maximum (127)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x33, // Usage (Rx)
0x09, 0x34, // Usage (Ry)
Expand All @@ -92,18 +94,22 @@ const uint8_t ps4_desc_hid_report[] = {
0x75, 0x08, // Report Size (8)
0x95, 0x02, // Report Count (2)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
0x09, 0x21, // Usage (0x21)
0x95, 0x36, // Report Count (54)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05, // Report ID (5)
0x09, 0x22, // Usage (0x22)
0x95, 0x1F, // Report Count (31)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x04, // Report ID (4)
0x09, 0x23, // Usage (0x23)
0x95, 0x24, // Report Count (36)

0x85, 0x05, // Report ID (5)
0x09, 0x22, // Usage (0x22)
0x95, 0x1F, // Report Count (31)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)

0x85, 0x03, // Report ID (3)
0x0A, 0x21, 0x27, // Usage (0x2721)
0x95, 0x2F, // Report Count (47)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)

0x85, 0x02, // Report ID (2)
0x09, 0x24, // Usage (0x24)
0x95, 0x24, // Report Count (36)
Expand Down Expand Up @@ -139,149 +145,150 @@ const uint8_t ps4_desc_hid_report[] = {
0x95, 0x2C, // Report Count (44)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x06, 0x80, 0xFF, // Usage Page (Vendor Defined 0xFF80)
0x85, 0x80, // Report ID (-128)
0x85, 0x80, // Report ID (128)
0x09, 0x20, // Usage (0x20)
0x95, 0x06, // Report Count (6)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x81, // Report ID (-127)
0x85, 0x81, // Report ID (129)
0x09, 0x21, // Usage (0x21)
0x95, 0x06, // Report Count (6)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x82, // Report ID (-126)
0x85, 0x82, // Report ID (130)
0x09, 0x22, // Usage (0x22)
0x95, 0x05, // Report Count (5)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x83, // Report ID (-125)
0x85, 0x83, // Report ID (131)
0x09, 0x23, // Usage (0x23)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x84, // Report ID (-124)
0x85, 0x84, // Report ID (132)
0x09, 0x24, // Usage (0x24)
0x95, 0x04, // Report Count (4)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x85, // Report ID (-123)
0x85, 0x85, // Report ID (133)
0x09, 0x25, // Usage (0x25)
0x95, 0x06, // Report Count (6)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x86, // Report ID (-122)
0x85, 0x86, // Report ID (134)
0x09, 0x26, // Usage (0x26)
0x95, 0x06, // Report Count (6)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x87, // Report ID (-121)
0x85, 0x87, // Report ID (135)
0x09, 0x27, // Usage (0x27)
0x95, 0x23, // Report Count (35)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x88, // Report ID (-120)
0x85, 0x88, // Report ID (136)
0x09, 0x28, // Usage (0x28)
0x95, 0x22, // Report Count (34)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x89, // Report ID (-119)
0x85, 0x89, // Report ID (137)
0x09, 0x29, // Usage (0x29)
0x95, 0x02, // Report Count (2)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x90, // Report ID (-112)
0x85, 0x90, // Report ID (144)
0x09, 0x30, // Usage (0x30)
0x95, 0x05, // Report Count (5)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x91, // Report ID (-111)
0x85, 0x91, // Report ID (145)
0x09, 0x31, // Usage (0x31)
0x95, 0x03, // Report Count (3)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x92, // Report ID (-110)
0x85, 0x92, // Report ID (146)
0x09, 0x32, // Usage (0x32)
0x95, 0x03, // Report Count (3)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x93, // Report ID (-109)
0x85, 0x93, // Report ID (147)
0x09, 0x33, // Usage (0x33)
0x95, 0x0C, // Report Count (12)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA0, // Report ID (-96)
0x85, 0xA0, // Report ID (160)
0x09, 0x40, // Usage (0x40)
0x95, 0x06, // Report Count (6)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA1, // Report ID (-95)
0x85, 0xA1, // Report ID (161)
0x09, 0x41, // Usage (0x41)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA2, // Report ID (-94)
0x85, 0xA2, // Report ID (162)
0x09, 0x42, // Usage (0x42)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA3, // Report ID (-93)
0x85, 0xA3, // Report ID (163)
0x09, 0x43, // Usage (0x43)
0x95, 0x30, // Report Count (48)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA4, // Report ID (-92)
0x85, 0xA4, // Report ID (164)
0x09, 0x44, // Usage (0x44)
0x95, 0x0D, // Report Count (13)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA5, // Report ID (-91)
0x85, 0xA5, // Report ID (165)
0x09, 0x45, // Usage (0x45)
0x95, 0x15, // Report Count (21)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA6, // Report ID (-90)
0x85, 0xA6, // Report ID (166)
0x09, 0x46, // Usage (0x46)
0x95, 0x15, // Report Count (21)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF0, // Report ID (-16)
0x09, 0x47, // Usage (0x47)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF1, // Report ID (-15)
0x09, 0x48, // Usage (0x48)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2, // Report ID (-14)
0x09, 0x49, // Usage (0x49)
0x95, 0x0F, // Report Count (15)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA7, // Report ID (-89)
0x85, 0xA7, // Report ID (247)
0x09, 0x4A, // Usage (0x4A)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA8, // Report ID (-88)
0x85, 0xA8, // Report ID (250)
0x09, 0x4B, // Usage (0x4B)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xA9, // Report ID (-87)
0x85, 0xA9, // Report ID (251)
0x09, 0x4C, // Usage (0x4C)
0x95, 0x08, // Report Count (8)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAA, // Report ID (-86)
0x85, 0xAA, // Report ID (252)
0x09, 0x4E, // Usage (0x4E)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAB, // Report ID (-85)
0x85, 0xAB, // Report ID (253)
0x09, 0x4F, // Usage (0x4F)
0x95, 0x39, // Report Count (57)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAC, // Report ID (-84)
0x85, 0xAC, // Report ID (254)
0x09, 0x50, // Usage (0x50)
0x95, 0x39, // Report Count (57)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAD, // Report ID (-83)
0x85, 0xAD, // Report ID (255)
0x09, 0x51, // Usage (0x51)
0x95, 0x0B, // Report Count (11)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAE, // Report ID (-82)
0x85, 0xAE, // Report ID (256)
0x09, 0x52, // Usage (0x52)
0x95, 0x01, // Report Count (1)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xAF, // Report ID (-81)
0x85, 0xAF, // Report ID (175)
0x09, 0x53, // Usage (0x53)
0x95, 0x02, // Report Count (2)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB0, // Report ID (-80)
0x85, 0xB0, // Report ID (176)
0x09, 0x54, // Usage (0x54)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB1, // Report ID (-79)
0x09, 0x55, // Usage (0x55)
0x95, 0x02, // Report Count (2)
0xC0, // End Collection

0x06, 0xF0, 0xFF, // Usage Page (Vendor Defined 0xFFF0)
0x09, 0x40, // Usage (0x40)
0xA1, 0x01, // Collection (Application)
0x85, 0xF0, // Report ID (-16) AUTH F0
0x09, 0x47, // Usage (0x47)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xB2, // Report ID (-78)
0x09, 0x56, // Usage (0x56)
0x95, 0x02, // Report Count (2)
0x85, 0xF1, // Report ID (-15) AUTH F1
0x09, 0x48, // Usage (0x48)
0x95, 0x3F, // Report Count (63)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF2, // Report ID (-14) AUTH F2
0x09, 0x49, // Usage (0x49)
0x95, 0x0F, // Report Count (15)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0xF3, // Report ID (-13) Auth F3 (Reset)
0x0A, 0x01, 0x47, // Usage (0x4701)
0x95, 0x07, // Report Count (7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
};
Expand Down Expand Up @@ -311,6 +318,12 @@ static const uint8_t ps4_0x02_report[] = {0x04, 0x00, 0xf9, 0xff, 0x06, 0x00, 0x
0x88, 0xdd, 0xa9, 0x23, 0x62, 0xdc, 0x1c, 0x02, 0x1c, 0x02, 0x05, 0x20,
0xfb, 0xdf, 0x49, 0x20, 0xb7, 0xdf, 0x0d, 0x20, 0xf4, 0xdf, 0x01, 0x00};

// Controller Descriptor
static const uint8_t ps4_0x03_report[] = {0x21, 0x27, 0x04, 0xcf, 0x00, 0x2c, 0x56, 0x08, 0x00, 0x3d, 0x00, 0xe8,
0x03, 0x04, 0x00, 0xff, 0x7f, 0x0d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static hid_ps4_report_t last_report = {};

bool send_hid_ps4_report(usb_report_t report) {
Expand Down Expand Up @@ -361,6 +374,9 @@ uint16_t hid_ps4_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
case 0x02:
memcpy(buffer, ps4_0x02_report, sizeof(ps4_0x02_report));
return sizeof(ps4_0x02_report);
case 0x03:
memcpy(buffer, ps4_0x03_report, sizeof(ps4_0x03_report));
return sizeof(ps4_0x03_report);
default:
}
}
Expand Down

0 comments on commit 33530a3

Please sign in to comment.