diff --git a/config-tool-web/code.js b/config-tool-web/code.js index a7b1033..2cee705 100644 --- a/config-tool-web/code.js +++ b/config-tool-web/code.js @@ -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; @@ -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."); } } @@ -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) { diff --git a/config-tool-web/index.html b/config-tool-web/index.html index 8c85b27..4e4b1df 100644 --- a/config-tool-web/index.html +++ b/config-tool-web/index.html @@ -182,6 +182,7 @@

HID Remapper Configuration

+ diff --git a/config-tool-web/usages.js b/config-tool-web/usages.js index 324a5fe..72eff30 100644 --- a/config-tool-web/usages.js +++ b/config-tool-web/usages.js @@ -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 = { @@ -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; diff --git a/config-tool/common.py b/config-tool/common.py index 259cd72..e992928 100644 --- a/config-tool/common.py +++ b/config-tool/common.py @@ -10,7 +10,7 @@ CONFIG_USAGE_PAGE = 0xFF00 CONFIG_USAGE = 0x0020 -CONFIG_VERSION = 13 +CONFIG_VERSION = 14 CONFIG_SIZE = 32 REPORT_ID_CONFIG = 100 diff --git a/firmware/src/config.cc b/firmware/src/config.cc index ab1dbad..3fa547c 100644 --- a/firmware/src/config.cc +++ b/firmware/src/config.cc @@ -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; @@ -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); diff --git a/firmware/src/our_descriptor.cc b/firmware/src/our_descriptor.cc index edbac8f..d90ac13 100644 --- a/firmware/src/our_descriptor.cc +++ b/firmware/src/our_descriptor.cc @@ -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); @@ -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: @@ -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[] = { diff --git a/firmware/src/our_descriptor.h b/firmware/src/our_descriptor.h index 6207800..ad0bba6 100644 --- a/firmware/src/our_descriptor.h +++ b/firmware/src/our_descriptor.h @@ -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); diff --git a/firmware/src/tinyusb_stuff.cc b/firmware/src/tinyusb_stuff.cc index c18301d..aba2060 100644 --- a/firmware/src/tinyusb_stuff.cc +++ b/firmware/src/tinyusb_stuff.cc @@ -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[] = {