summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--class/gamepad/usb_gamepad.h6
-rw-r--r--class/gamepad/usbd_gamepad.c25
-rw-r--r--demo/gamepad_template.c2
3 files changed, 29 insertions, 4 deletions
diff --git a/class/gamepad/usb_gamepad.h b/class/gamepad/usb_gamepad.h
index 28e2e646..8b93713a 100644
--- a/class/gamepad/usb_gamepad.h
+++ b/class/gamepad/usb_gamepad.h
@@ -143,12 +143,12 @@ struct xinput_out_report {
} __PACKED;
// clang-format off
-#define XINPUT_DESCRIPTOR_LEN (9 + 16 + 7 + 7)
+#define XINPUT_DESCRIPTOR_LEN (9 + 17 + 7 + 7)
#define XINPUT_DESCRIPTOR_INIT(bInterfaceNumber, out_ep, in_ep) \
USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, 0x00, 0x02, 0xff, 0x5d, 0x01, 0x00), /* XInput proprietary descriptor (0x21) */ \
- 16, 0x21, 0x00, 0x01, 0x01, 0x24, in_ep, 0x14, 0x03, 0x00, 0x03, 0x13, out_ep, 0x00, 0x03, 0x00, \
- USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \
+ 0x11, 0x21, 0x00, 0x01, 0x01, 0x25, in_ep, 0x14, 0x00, 0x00, 0x00, 0x00, 0x13, out_ep, 0x08, 0x00, 0x00, \
+ USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x03, 32, 0x01), \
USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x03, 32, 0x08)
// clang-format on
diff --git a/class/gamepad/usbd_gamepad.c b/class/gamepad/usbd_gamepad.c
index 37eb040c..f59c07db 100644
--- a/class/gamepad/usbd_gamepad.c
+++ b/class/gamepad/usbd_gamepad.c
@@ -21,6 +21,24 @@ static int xinput_vendor_class_request_handler(uint8_t busid, struct usb_setup_p
return 0;
}
+// Convert analog value from Joypad (0-255, center 128) to signed 16-bit
+static int16_t convert_axis_to_s16(uint8_t value)
+{
+ int32_t scaled = ((int32_t)value - 128) * 256;
+ if (scaled < -32768) scaled = -32768;
+ if (scaled > 32767) scaled = 32767;
+ return (int16_t)scaled;
+}
+
+// Convert and invert axis (for Y-axis where convention differs)
+static int16_t convert_axis_to_s16_inverted(uint8_t value)
+{
+ int32_t scaled = -((int32_t)value - 128) * 256;
+ if (scaled < -32768) scaled = -32768;
+ if (scaled > 32767) scaled = 32767;
+ return (int16_t)scaled;
+}
+
int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *report)
{
struct xinput_in_report *xinput_report;
@@ -68,6 +86,13 @@ int usbd_gamepad_xinput_send_report(uint8_t ep, struct usb_gamepad_report *repor
if (xinput_report->rt == 0 && (report->buttons & USB_GAMEPAD_BUTTON_R2))
xinput_report->rt = 0xFF;
+ // Analog sticks (signed 16-bit, -32768 to +32767)
+ // Y-axis inverted: input 0=down, XInput convention positive=up
+ xinput_report->lx = convert_axis_to_s16(report->lx);
+ xinput_report->ly = convert_axis_to_s16_inverted(report->ly);
+ xinput_report->rx = convert_axis_to_s16(report->rx);
+ xinput_report->ry = convert_axis_to_s16_inverted(report->ry);
+
return usbd_ep_start_write(0, ep, gamepad_report_buffer, sizeof(struct xinput_in_report));
}
diff --git a/demo/gamepad_template.c b/demo/gamepad_template.c
index 171ab517..f9470678 100644
--- a/demo/gamepad_template.c
+++ b/demo/gamepad_template.c
@@ -89,7 +89,7 @@ static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
- if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
+ if (index >= 4) {
return NULL;
}