GameInputManager and HIDAPIDeviceMBS issues

I’m writing some software that takes input from USB Joystick boards like these

The devices are recognised by GameInputManager no problem and I can read the buttons without issue.

The problem I have is that the systems my software must work with may have more than one of these controllers connected. So I need to be able to have Button #1 on the first device perform action X, and Button #1 on the second device to perform action Y.

The problem is that the GameInputManager just shows these devices using the same name, so I can’t distinguish between them in code. It’s fine on first run and setup using the GameInputDevice’s index , however if the USB devices are removed, or plugged into different USB sockets etc., the next time my app runs, I can’t guarantee each device will have the same index, therefore I can’t be sure I am using the correct button on the correct device for each action.

These boards all have unique serial numbers that allow you to distinguish between them in code when more than one is used, however it appears that GameInputDevice does not allow you to read a USB device’s serial number.

I have tried using the MBS class HIDAPIDeviceMBS and I can read all the relevant data about a device, including serial number, internal object handle etc. The problem I have is that I can’t work out how the data I read from the USB boards converts into elements like Button #1, Button #2 etc. Reading the USB HID specs, it say I should be able to obtain a feature list from the device itself, however using the GetFeatureReport seems to only return identical data to the Read method, so I’m not sure how I work out how many buttons the device has etc.

Any ideas if I can get the USB device’s serial number using GameInputManager, or indeed get the internal object handle for a GameInputManager device? If I could get the handle from GameInputManager and HIDAPIDeviceMBS, then I could use MBS to get the serial etc. and match the handle it gives me to that of the GameInputManager device to ensure I’m getting input from the device I think I am (if the handles would even be the same?).

Anyone have any ideas?

You would need to lookup the HID protocol definition.
There you can learn what data packets look like what fields they include and maybe even which code means what.

I’ll be frank, I’m completely lost.

I’ve read this:

The device gives me a Usage Page of 1 (Generic Desktop Controls) and Usage ID of 4 (Joystick). Which is fine and makes sense. I can obtain a Feature Report using GetFeatureReport. Some devices don’t have one and those that return anything only return the same data that using the Read method does.

The Read method pulls back data which when I view it manually it’s fairly easy to figure out how it relates to the various buttons and axis on the device. It seems to just be the raw data of the current status of the buttons. However different devices obviously supply different amounts of data dependant on how many buttons and axis they have. So I’m unsure how I’d automatically figure out what this data means in software without having some sort of feature report for the device.

From reading around (pages like I should be able to pull off a HID report descriptor from the device that describes the buttons. However, using HIDAPIDeviceMBS the only way I can get data from the device is either using the GetFeatureReport or Read methods. Using GetFeatureReport either gives me nothing or data identical to the Read method (which appears to simply be button status data).

So where do I pull the device report descriptors from? Am I missing something obvious?

Just to clarify what I can get from the USB devices. I have 3 different devices here, all of which identify as Usage Page 1 (Generic Desktop Controls) and Usage ID 4 (Joystick). So they all should be using the same protocol.

The raw bit stream I get from each is:

Leo Bodnar Interface Board:

00000000 00000000 00000000 00000000 00001111

As this board only has buttons, each of the bytes above represent buttons. The first four bytes (32 bits) represents the state of the 32 buttons and the last byte represents the four way hat switch (last 4 bits only).

Cheap Gamepad:

10000000 10000000 10000000 10000000 00001111 00000000

The first four bytes represents the two analogue axis and hold 0 to 255 dependant on the position. In the example above all are at their middle position. The fifth byte is four buttons and the hat switch and the last byte represents six buttons (two unused bits).

Flight Sim Joystick:

00000000 00000000 10000000 00000000 00000111 00000000

The first byte is the analogue throttle, the second is the analogue yaw control and the third and fourth are the X and Y analogue axis of the joystick. The fifth byte is the hat switch and four buttons, with the last byte being more buttons.

So as you can see, although all the devices report as the same type of device, the format of the data is always a little different and the number of buttons and axis varies.

Reading through the HID documents is like wading through treacle and every search I make leads me back to the same document I posted earlier (which doesn’t actually explain how I get a list of button elements from the device, only what each usage ID is).

From what I can understand, I need to obtain a device descriptor from the device, but I can’t find any way to do this using the HIDAPIDeviceMBS class. The above data is all I can get from the devices.

Am I missing something in the HIDAPIDeviceMBS? I’m starting to think there is no way to get the device descriptor using this class.