Skip to content

Commit

Permalink
New emulated device type: XAC compatible
Browse files Browse the repository at this point in the history
This adds a new emulated device type that is meant to be used when
plugging HID Remapper into USB ports on the Xbox Adaptive Controller.

Technically other device types like the Switch gamepad were already
compatible, but this lets us have exactly the inputs the XAC
understands with proper labels.

Also I secretly hope this will be compatible with the Hori Flex.

Bumps config version to 14.
  • Loading branch information
jfedor2 committed Jun 27, 2024
1 parent 996aa32 commit 241159b
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 6 deletions.
6 changes: 3 additions & 3 deletions config-tool-web/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const STICKY_FLAG = 1 << 0;
const TAP_FLAG = 1 << 1;
const HOLD_FLAG = 1 << 2;
const CONFIG_SIZE = 32;
const CONFIG_VERSION = 13;
const CONFIG_VERSION = 14;
const VENDOR_ID = 0xCAFE;
const PRODUCT_ID = 0xBAF2;
const DEFAULT_PARTIAL_SCROLL_TIMEOUT = 1000000;
Expand Down Expand Up @@ -864,7 +864,7 @@ function add_crc(data) {
}

function check_json_version(config_version) {
if (!([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].includes(config_version))) {
if (!([3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].includes(config_version))) {
throw new Error("Incompatible version.");
}
}
Expand All @@ -880,7 +880,7 @@ async function check_device_version() {
// device because it could be version X, ignore our GET_CONFIG call with version Y and
// just happen to have Y at the right place in the buffer from some previous call done
// by some other software.
for (const version of [CONFIG_VERSION, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2]) {
for (const version of [CONFIG_VERSION, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2]) {
await send_feature_command(GET_CONFIG, [], version);
const [received_version] = await read_config_feature([UINT8]);
if (received_version == version) {
Expand Down
1 change: 1 addition & 0 deletions config-tool-web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ <h1 class="mt-sm-5 mt-3">HID Remapper Configuration</h1>
<option value="2">Switch gamepad</option>
<option value="3">PS4 arcade stick</option>
<option value="4">Stadia controller</option>
<option value="5">XAC compatible</option>
</select>
</div>
</div>
Expand Down
20 changes: 20 additions & 0 deletions config-tool-web/usages.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,25 @@ const usages = {
"0x00090011": { 'name': 'Assistant', 'class': 'mouse' },
"0x00090012": { 'name': 'Capture', 'class': 'mouse' },
},
5: {
"0x00010030": { 'name': 'Left stick X', 'class': 'mouse' },
"0x00010031": { 'name': 'Left stick Y', 'class': 'mouse' },
"0x00010032": { 'name': 'Right stick X', 'class': 'mouse' },
"0x00010035": { 'name': 'Right stick Y', 'class': 'mouse' },
"0x00010039": { 'name': 'D-pad', 'class': 'mouse' },
"0x00090005": { 'name': 'A', 'class': 'mouse' },
"0x00090006": { 'name': 'B', 'class': 'mouse' },
"0x0009000b": { 'name': 'X', 'class': 'mouse' },
"0x0009000c": { 'name': 'Y', 'class': 'mouse' },
"0x00090004": { 'name': 'LB', 'class': 'mouse' },
"0x0009000a": { 'name': 'RB', 'class': 'mouse' },
"0x00090001": { 'name': 'X1', 'class': 'mouse' },
"0x00090002": { 'name': 'X2', 'class': 'mouse' },
"0x00090003": { 'name': 'LSB', 'class': 'mouse' },
"0x00090009": { 'name': 'RSB', 'class': 'mouse' },
"0x00090007": { 'name': 'View', 'class': 'mouse' },
"0x00090008": { 'name': 'Menu', 'class': 'mouse' },
},
};

const common_target_usages = {
Expand Down Expand Up @@ -538,6 +557,7 @@ Object.assign(usages[0], common_target_usages);
Object.assign(usages[2], common_target_usages);
Object.assign(usages[3], common_target_usages);
Object.assign(usages[4], common_target_usages);
Object.assign(usages[5], common_target_usages);
usages[1] = usages[0]; // absolute mouse & keyboard is the same as regular mouse & keyboard

export default usages;
2 changes: 1 addition & 1 deletion config-tool/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
CONFIG_USAGE_PAGE = 0xFF00
CONFIG_USAGE = 0x0020

CONFIG_VERSION = 13
CONFIG_VERSION = 14
CONFIG_SIZE = 32
REPORT_ID_CONFIG = 100

Expand Down
4 changes: 3 additions & 1 deletion firmware/src/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "platform.h"
#include "remapper.h"

const uint8_t CONFIG_VERSION = 13;
const uint8_t CONFIG_VERSION = 14;

const uint8_t CONFIG_FLAG_UNMAPPED_PASSTHROUGH = 0x01;
const uint8_t CONFIG_FLAG_UNMAPPED_PASSTHROUGH_MASK = 0b00001111;
Expand Down Expand Up @@ -526,6 +526,8 @@ void load_config(const uint8_t* persisted_config) {
return;
}

// v14 is same as v13, it just introduces a new emulated device type

persist_config_v13_t* config = (persist_config_v13_t*) persisted_config;
unmapped_passthrough_layer_mask = config->unmapped_passthrough_layer_mask;
ignore_auth_dev_inputs = config->flags & (1 << CONFIG_FLAG_IGNORE_AUTH_DEV_INPUTS_BIT);
Expand Down
49 changes: 49 additions & 0 deletions firmware/src/our_descriptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,41 @@ uint8_t const our_report_descriptor_stadia[] = {
0xC0, // End Collection
};

uint8_t const our_report_descriptor_xac_compat[] = {
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x05, // Usage (Game Pad)
0xA1, 0x01, // Collection (Application)
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)
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)
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)
0x65, 0x00, // Unit (None)
0x45, 0x00, // Physical Maximum (0)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (0x01)
0x29, 0x0C, // Usage Maximum (0x0C)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x0C, // Report Count (12)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
};

void kb_mouse_handle_set_report(uint8_t report_id, const uint8_t* buffer, uint16_t reqlen) {
if (report_id == REPORT_ID_MULTIPLIER && reqlen >= 1) {
memcpy(&resolution_multiplier, buffer, 1);
Expand Down Expand Up @@ -520,6 +555,12 @@ void stadia_clear_report(uint8_t* report, uint8_t report_id, uint16_t len) {
memcpy(report, stadia_neutral, sizeof(stadia_neutral));
}

static const uint8_t xac_compat_neutral[] = { 0x80, 0x80, 0x80, 0x80, 0x08, 0x00 };

void xac_compat_clear_report(uint8_t* report, uint8_t report_id, uint16_t len) {
memcpy(report, xac_compat_neutral, sizeof(xac_compat_neutral));
}

int32_t horipad_default_value(uint32_t usage) {
switch (usage) {
case 0x00010039:
Expand Down Expand Up @@ -616,6 +657,14 @@ const our_descriptor_def_t our_descriptors[] = {
.default_value = ps4_stadia_default_value,
.sanitize_report = stadia_sanitize_report,
},
{
.idx = 5,
.descriptor = our_report_descriptor_xac_compat,
.descriptor_length = sizeof(our_report_descriptor_xac_compat),
.handle_received_report = do_handle_received_report,
.clear_report = xac_compat_clear_report,
.default_value = ps4_stadia_default_value, // sic
},
};

const uint8_t config_report_descriptor[] = {
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/our_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#define MAX_INPUT_REPORT_ID 3

#define NOUR_DESCRIPTORS 5
#define NOUR_DESCRIPTORS 6

typedef void (*device_connected_t)(uint16_t interface, uint16_t vid, uint16_t pid);
typedef void (*device_disconnected_t)(uint8_t dev_addr);
Expand Down
7 changes: 7 additions & 0 deletions firmware/src/tinyusb_stuff.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,19 @@ const uint8_t configuration_descriptor4[] = {
TUD_HID_DESCRIPTOR(1, 0, HID_ITF_PROTOCOL_NONE, config_report_descriptor_length, 0x83, CFG_TUD_HID_EP_BUFSIZE, 1),
};

const uint8_t configuration_descriptor5[] = {
TUD_CONFIG_DESCRIPTOR(1, 2, 0, TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_HID_DESC_LEN, 0, 100),
TUD_HID_DESCRIPTOR(0, 0, HID_ITF_PROTOCOL_NONE, our_descriptors[5].descriptor_length, 0x81, CFG_TUD_HID_EP_BUFSIZE, 1),
TUD_HID_DESCRIPTOR(1, 0, HID_ITF_PROTOCOL_NONE, config_report_descriptor_length, 0x83, CFG_TUD_HID_EP_BUFSIZE, 1),
};

const uint8_t* configuration_descriptors[] = {
configuration_descriptor0,
configuration_descriptor1,
configuration_descriptor2,
configuration_descriptor3,
configuration_descriptor4,
configuration_descriptor5,
};

char const* string_desc_arr[] = {
Expand Down

0 comments on commit 241159b

Please sign in to comment.