Showing posts with label DirectInput. Show all posts
Showing posts with label DirectInput. Show all posts

Wednesday, 7 September 2011

Smart auto configuration and selection of consumer flight-simulator controllers

I've not made a 'serious' programming post in a while so this is my attempt to sound worthy and contribute something that might be useful or insightful (this is an expanded and updated version of a document I posted on Google+ a few days ago).

Introduction

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.

Enumerating Devices

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.

Identity Crisis

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
Most sticks I've been testing use DI8DEVTYPE_JOYSTICK (0x14) with a subType of 0x02 but every so often you'll find one that uses an off-the wall descriptor. So this isn't a safe means to pick out a default controller(s).

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


Compound Problem

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.

Suggested implementation

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.

Wednesday, 13 July 2011

G940 now with LED control

Today I added some code to apply any OEM specific support in our DirectInput controller DLL. Here is a desk photo of the G940 throttle unit with the buttons cycling through each colour (green, amber, red, off). I had some link issues with Logitech's supplied LIB and I hope it's just confined to the debug symbols (turning them off fixed the link error).

Tempting to program a game of Simon for it.

The force-feedback functions are done but it's worth mentioning that there's a gulf between a powered joystick and simple force-feedback. What I'm finding is that the range of powered motion doesn't always match the full range of motion in the joystick. Those mechanism are typically designed to apply force sensations for gaming purposes. I had high hopes that such devices could simulate a force-trim system but not all devices are created equal. They can approximate to varying degrees.

If you're in the market for a new HOTAS and considering one of these for a helicopter simulation then I suggest a forum search for Black Shark players and the G940. I'm personally torn between non-FF and this device. The lamp buttons are kind of cool but presently there's no way to link them to game values.


In Combat-Helo, the virtual cockpit data contains information about switches that are considered lamps, there's logic to switch lamped buttons on events. This is an obvious place to add a hook for a devices 'lamp' list to illuminated cockpit switches. And I could add some fake ones for RWR warnings, it should be quite quick to implement that way.

Finally I'm able to map the funny guarded "arm" switch on the Saitek X65F with this new wrapper, that joystick has 50 mappable buttons alone, never mind the POVs and axis. It works fine alongside the G940.

Other news. It's almost time for another progress video. There's some niggling issues with the rocket aim to sort out, when I'm happy with the rockets I reckon it's time to show off some firepower.

If you have some cool non standard hardware device that we can support in Combat-Helo then email richard at tricubicstudios dot com.