Imagine you've just spent an hour (or five) downloading a new combat flight-simulator, hurriedly gone through the installation process and clicked on the .EXE. There's a pregnant pause while your hard-drive goes bananas loading a series of splash screens before finally presenting a glorious menu.
So you click the FLY button and find yourself for the first time presented with a bit of green at the bottom of the screen, some blue at the top (if you're lucky) and as you touch the controller your viewpoint begins to hurtle sideways or spin around. Worse still, everything seems fine until you try taking off only to discover the throttle is connected to the elevator controls, or the toe brakes are controlling roll.
It's happened to me in any number of simulations and games. Then comes the arduous process of going through set-up screens to set your joystick axis to the correct control and remove your steering wheel assignments. Console games have it easy, just load and go. And that's what I like in my games and sims. To quote someone. "Linux is only free if your time's worth nothing".
Developing on the PC platform is made easier through the use of middle-ware. As is often though, there's little focus on the input interface. How can you handle touch screens, with multi-touch or exotic RTS keypads, 10 button mice, multi-media keyboards and a plethora of dedicated flight simulation joysticks in one easy abstract interface? Some libraries try to tackle these, the cross-platform SDL library does a reasonable job and was used in Combat-Helo until recently.
To ensure everything works smoothly for exotic simulation hardware DirectInput is the way to go but there's always a few small gottcha's if you're engaged in trying to smooth out that end-user experience. Hence this blog entry where I want to share some of the lessons learned.
DirectX provides a mechanism for querying each joystick type, the drviers can specify if it's a gamepad, a steering wheel, a yolk, first person shooter device etc. Well you're running a flight simulation so you might think you can query all devices and look for only those flagged as flight-sticks. Well, wrong. You can but it's not safe to do so. Some joysticks might be dual purpose, the driver author only gets to pick one descriptor. Sometimes they are just incorrect for whatever reason.
For example, Saitek drivers for the Pro-flight X65F force sensing HOTAS don't identify themselves as a flight-stick. They flag themselves as a first person shooter device when in reality it's a desk hogging 45 button, 8 axis dual throttle metal monster with an illuminated control panel. I wouldn't be using it in Call of Duty but it's first rate for games like Hawx. I will add that I'm using the stock drivers that come on CD with boxed product and also this is only a concern when implementing auto selection logic.
|"Not a flying toy" Saitek X65F 12kg of desk metal|
Below is the contents of a file generated by Combat-Helo after a game device audit during startup (values are in decimal).
Detected devices: Index , Type, SubType, OEM String 0 24 3 3Dconnexion KMJ Emulator 1 20 2 Logitech Extreme 3D 2 20 2 Logitech G940 Joystick 3 20 2 Logitech G940 Throttle 4 20 1 Logitech G940 Pedals 5 24 1 SpaceNavigator 6 20 1 Saitek Pro Flight Rudder Pedals 7 20 1 Cyborg F.L.Y.5 Flight Stick 8 24 3 Saitek X65F Flight Controller 9 21 2 Controller (Aviator for Xbox 360/PC) END
Another thing to note is the Logitech G940 is reported as a compound device. One physical plug but is visible to Windows as three distinct joystick devices. If you need to support all the features on these high-end devices then opensource cross-platform libraries like SDL don't cut the mustard at all. Until there's an alternative such as OpenIN from the Khronos group it's DirectInput or partial support.
To make auto-selection of devices and configuration more difficult, both the throttle and joystick of a compound device may be flagged as full featured joysticks. What we don't want is a throttle ending up as the primary controller.
So regardless of the expansive descriptors available to joystick controllers in DirectInput, you can't trust them and will need to rely on a combination of descriptors and device caps enumeration to get number of axis, buttons and force-feedback.
For Combat-Helo what we did was put place joysticks with sub-type 0x02 at the head of a list. Also any devices flagged as the correct type (flight-stick, full featured) would then be added to the head of the list moving the rest down. For each device you enumerate each 'object' on that device, an object is a button, axis, slider etc and often the text string can yield clues. For example an axis named "Throttle". However I've yet to try this on a non-English PC, so it's something to be aware of.
Eventually whatever device is first in the list should be the best all-round first choice from which the users first-time action-mapping can be assembled and saved. After which it can be edited or deleted at the gamers discretion but I hope the first choice was close enough to the mark to minimise those first flight blues.
Use the Force, it is strong and is weak
Force-feedback (FF) axis can be a really good indicator of a primary controller since usually only the joystick will have this feature. You do need to be careful as rumble-pads can look like they have two FF axis, it is conceivable that a flight simulation enthusiasts might have an XBOX controller attached, they certainly are a good analog of the Apache CP/G TEDEC hand-grip.
My test system is not typical. My goal was to consider some basic logic to prevent conflict and configure a complex simulation to be ready-to-fly out of the box. Configuration menus offer easy ways to change any conflicts if/when the logic fails.
I want to take this opportunity to thank Madcatz (Saitek UK) and Logitech for their kind assistance and support.
|Quick control set-up and edit panel, auto select|
chose the compound HOTAS.