jfedor2 / hid-remapper

USB input remapping dongle
Other
757 stars 103 forks source link

Can't monitor joystick X-Axis input from Sega Astro City Mini Arcade Stick #148

Open techhitnz opened 1 week ago

techhitnz commented 1 week ago

Hi,

I have a Sega Astro City Mini Arcade Stick, and I can monitor every button and joystick input EXCEPT for the joystick X-axis. Joystick Y-axis can be monitored fine.

image

I have tested that the controller is able to be tested fine under Windows (USB controller settings), and with the same USB A to USB C adapter. I've also tried another USB A to USB C adapter which exhibits the same issue.

The same USB A to USB C adapter is how I can get my Taito Egret II Mini Arcade Stick working fine on a Nintendo Switch.

When I clear the mappings and replug the joystick in to remonitor - without pressing anything I get 3 values that show up instantly.

image

Cursor X remains unresponsive, and I have no idea what 0x00010000 is, as that showed up without any input.

Can you please advise.

techhitnz commented 1 week ago

I have attached a Wireguard USB capture. astrocity wireguard capture.zip

jfedor2 commented 1 week ago

That device has a broken report descriptor. You can try configuring a custom usage as follows: Screenshot from 2024-06-26 00-02-44

techhitnz commented 1 week ago

Thank you so much! That worked.

image

This is amazing - I can now use controllers that had no 3rd party joystick converter support for on my Nintendo Switch.

techhitnz commented 1 week ago

Are you able to dumb it down to explain what the issue is and what custom usages are used for. Forgive me, but I couldn't find any documentation on that specifically.

techhitnz commented 1 week ago

Also, I wanted to have the configuration to support both my controllers:

However, now with this new configuration, the Egret no longer functions as expected (compared to when I had it supporting the Egret controller alone).

This is what my mapping looks like: image

The highlighted top part in red is mapping my Egret. The Green highlighted part below is the mapping for the Astro City.

Is there any way that I can solve for this through your web configurator. Or will I need to buy another Waveshare RP2040-PiZero specifically for each controller?

jfedor2 commented 1 week ago

All USB input devices have an HID report descriptor, it's basically a schema for the inputs that they're going to be sending. Since every device can have a different number and type of buttons, axes etc., the binary format of the reports that the device is sending is not the same between devices. So the report descriptor tells the host "this bit will mean button X is pressed" and "these bits will be the state of the X axis of the left stick".

So far so good.

But on some devices the report descriptor is clearly incorrect, or at least slightly ambiguous. For example on the Astro City Mini stick, here's how the descriptor starts:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x02,        //   Collection (Logical)
0x75, 0x08,        //     Report Size (8)
0x95, 0x05,        //     Report Count (5)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xFF, 0x00,  //     Physical Maximum (255)
0x09, 0x30,        //     Usage (X)
0x09, 0x30,        //     Usage (X)
0x09, 0x30,        //     Usage (X)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)

This won't make sense you you if it's the first time you see a report descriptor, but note the four instances of "Usage (X)". This entry is supposed to tell the host where in the report to find data for the X axis of the stick. So why is there four of them? I don't know. What I do know is that the controller actually sends the X axis of the stick in the fourth byte: the last one of the four positions given by the descriptor. But HID Remapper doesn't know that so it assumes that the first occurrence of that usage is the correct one and because of that it doesn't see the data coming from the stick.

Custom usages in HID Remapper are a way of patching the report descriptor, essentially fixing it when necessary. Previously we had hardcoded fixes in the firmware for some devices, but with custom usages, it's now user configurable.

The custom usage you configured just tells HID Remapper that the X axis of the stick is locate at bit offset 24 (fourth byte) and takes up 8 bits.

Now you might ask, if the device has a broken report descriptor, how does it work at all? It's typically one of two options: it works with devices (such as the Astro City Mini console possibly) that have the format of the report hardwired and don't even bother parsing the report descriptor, or it works because (let's say) Windows makes different assumptions than HID Remapper when it encounters such ambiguous entries in the report descriptor. For example here it's possible that Windows looks at the last occurrence of the usage, where HID Remapper looks at the first one. (Though this contradicts my previous experience with Windows behavior so I'm not really sure.)

jfedor2 commented 1 week ago

I don't have a great solution to the two controllers needing different configurations.

HID Remapper supports per-device mappings, but it's based on hub ports, not device IDs.

You could probably add a physical switch to your Remapper (just a simple slider or on/off switch wired to one of the GPIO pins) and make it so that the switch activates a layer. Then you could put the mappings for the Egret on, say, layers 0 and 1, and the mappings for the Astro City on layers 2 and 3. Though it might require some modification to the mappings because of the special behavior of layer 0.

For now it's probably simpler to just get another Remapper.

techhitnz commented 1 week ago

Thank you for taking the time to explain and work through my issue.