USB game controllers : seeking a good write-up

My first foray into usb game controller HID has led to mass confusion. I am using

and Arduino IDE, under OSX, using the handy "Joystick Show" app to verify HID function.

Here is where it gets interesting. The library seems to support a controller with a wholotta axes, like 10 or so. But my Joystick Show app only recognizes the first N of them, I think 7 (going from memory here as I am not staring at the running sketch at this moment). The library names some of these axes with meaningful labels such as Throttle, Rudder, Accelerator, etc. The Joystick Show app simply numbers them.

For example, if I make my duino control "Accelerator," Joystick Show doesn't see it at all because Accelerator as defined in the library is an axis numbered higher than the range of axes Joystick Show recognises. But if I make my duino control "Throttle" via the library, Joystick Show acknowledges input on Axis 7. So now I've learnt that Throttle is a label for Axis 7. (sorry, I don't read C++ well enough to pore over the library code and quickly understand what the author is doing, so I'm treating it for now as a black box).

The actual games that I'm trying to control seem to have expectations about the HID that will be used. They may expect a manufacturer-specific device (such as a brand name wheel and pedals) or an xbox style game pad. They don't seem to be flexible enough to accept a generic HID. And they don't accept the names from the library. If I say I'm using "Gamepad plus Keyboard" for example, I may be offered a choice of "Xaxis" and "Yaxis" for inputs; "Throttle" is not on the list of options.

So, what I'm trying to figure out is the relationship between the raw axes (numbered), which I think is what Joystick Show is reporting, the names assigned in the duino library, and the axes as recognised by Some Game or Other. Is there a way to figure this out, other than tedious empiricism?

My problem thus far is that I can get my duino to control axis N (as long as N is not > 7) as shown by Joystick Show, but I have not yet been able to get any of my target games to accept the axes I can control; when I wiggle arduino inputs, Joystick Show says that axes are being driven but I don't seem to be able to select those axes for specific game controls. I have not yet tried every possible axis because it's rather time-consuming and I was hoping to find some doco that would provide the key...

Clearly I'm missing an essential piece of the puzzle here, some kind of mapping. The games are commercial and proprietary so no hope of reconfiguring them, I suspect. I have to learn what they expect and feed it to them. Is there a good write-up somewhere for the semi-beginner which explains just how HID data maps from physical actuator to game input?

The USB HID protocol is very flexible, you should know more about the Report tables and values expected by your games. Each game may want to connect to a different HID device, with the JoystickLibrary implementing just one of these devices.

You may find more useful information from the device documentation, if you know which device an application will connect to. Or, if you have such a device at hand, you can try to figure out what information it sends over USB, and then mimic the same behaviour on the Arduino.

Following up here for the sake of any other dumb n00b who is on the same track.

The answers I have found so far:

(1) while the Arduino library I am using (mheironimus, v2) supports 11 axes, OSX appears to acknowledge only 8. While the library assigns names to some of the higher-numbered axes, such as Accelerator, Brake, etc, my OSX games look only at axes 0 through 3, and they are arbitrarily assignable to whatever game control I wish. The named axes provided by the library are invisible to OSX and the game engines don't care which axis is assigned to which function, that's a user configuration choice. This naming of axes really confused me initially.

  1. OSX behaves very badly if the MULTI_AXIS joystick type is instantiated. It behaves properly only if the JOYSTICK joystick type is instantiated (and the JOYSTICK type can have up to 11 axes, so that's multi-axis enough for me!) Symptom of improper configuration is that the mouse pointer gets hijacked by the game controller. Very confusing and took a while to sort out, as I thought that JOYSTICK meant "not multi axis".

  2. JoystickShow.app does not distinguish between MULTI_AXIS and JOYSTICK types, but it does accurately represent the axis numbers, switches, etc. -- it's a dandy debugging tool for this effort.

After discovering these facts the hard way (empirically) I am now able to replicate (most of) the features of existing game controllers under OSX, via Arduino. The one feature of mheironimus' super-duper library that is still not working right for me is the Hat switch. If I add a Hat switch to my Arduino joystick emulator, for some reason the hat switch cannot be initialised and is always set to zero (straight up position). More research needed.