tags:

views:

36

answers:

1

I'm trying to use a variety of gamepad controllers in my application using the DirectInput API. From what I can tell, the axes are mapped differently between devices.

Is there a common practice method for determining the controller type other than by using DeviceInformation.ProductName/InstanceName to differentiate between controllers to allow for different axis control assignment?

A: 

If you just need to know the controller type (FirstPerson, Joystick, Gamepad, ...), use DeviceInformation.DeviceType.

To know which specific controller is connected, use ProductName or better ProductGuid. ProductName might be the same for two differing controllers. ProductGuid on the other hand might be different even for two controllers of the same production charge.

Only by using the ProductGuid you can doubtlessly identify a connected device instance.

One might be tempted to foreach through dev.GetObjects(DeviceObjectTypeFlags.Axis) and check the axes' names (and offsets), but there is no warranty that an axis named "X axis" really maps to someDevice.CurrentJoystickState.X.

You'll either have to do all the mapping yourself beforehand for any controller that will be connected (which is only acceptable if you develop the application for yourself) and store that information in the config file of your app, or you will need to provide some form where the user can map a new device herself. I'm currently developing just that, but that answer would go beyond the scope of this question...

Consider also that in order to get this basic information (as ProductGuid) you don't have to create a device. These properties are already available in a DeviceInstance (within the DeviceList from Microsoft.DirectX.DirectInput.Manager.GetDevices())...


Update: Because my own answer was nagging me I dived into the topic a bit more.
So here is a way to determine which axes to map to which values:

// loop through the axes of an acquired device:
foreach (DeviceObjectInstance doi in 
    _currentDevice.GetObjects(DeviceObjectTypeFlags.Axis))
{
    doi.Name; // the name of the axis, e.g. 'X-Achse' (that's a german device...)
    doi.Offset / 4; // the enumeration 'index' of the axis
    doi.UsagePage; // the UsagePage determines the context of the axis value
    // vvvv
    doi.Usage; // the Usage tells you which JoystickState field to map to.
    // ^^^^
}

Up to now, I found these usage value representations:

(with JoystickState s = _currentDevice.CurrentJoystickState)
  Usage   Axis value
   48      s.X
   49      s.Y
   50      s.Z
   51      s.Rx
   52      s.Ry
   53      s.Rz
   54      s.GetSlider()[0]

So using a switch(doi.Usage) you can automatically get the corresponding axis value.

Martin