我正在尝试使用DirectInput API在我的应用程序中使用各种游戏手柄控制器。据我所知,轴在设备之间的映射方式不同。
除了使用DeviceInformation.ProductName / InstanceName来区分控制器以允许不同的轴控制分配之外,是否存在确定控制器类型的通用实践方法?
答案 0 :(得分:0)
如果您只需要知道控制器类型(FirstPerson,Joystick,Gamepad,...),请使用DeviceInformation.DeviceType。
要知道连接了哪个特定控制器,请使用ProductName或更好的ProductGuid。对于两个不同的控制器,ProductName可能相同。另一方面,即使对于相同生产费用的两个控制器,ProductGuid也可能不同。
只有使用ProductGuid,您才能毫无疑问地识别连接的设备实例。
有人可能想通过dev.GetObjects(DeviceObjectTypeFlags.Axis)
预测并查看轴的名称(和偏移),但不能保证名为“X轴”的轴真正映射到someDevice.CurrentJoystickState.X
。
您必须事先为所有要连接的控制器自己完成所有映射(只有在您自己开发应用程序时才可以接受)并将该信息存储在应用程序的配置文件中,或者您将需要提供一些用户可以自己映射新设备的表单。我目前正在开发这个,但这个答案超出了这个问题的范围......
另外考虑一下,为了获得这些基本信息(如ProductGuid),您不必创建设备。这些属性已在DeviceInstance中可用(在Microsoft.DirectX.DirectInput.Manager.GetDevices()的DeviceList中)...
更新:因为我自己的回答是在唠叨我,所以我更倾向于这个话题。
因此,这里有一种方法可以确定要映射到哪些轴的值:
// 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.
// ^^^^
}
到目前为止,我发现了这些使用价值表示:
(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]
因此,使用switch(doi.Usage)
可以自动获取相应的轴值。