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[] = {