问题
I've got a curious problem with SlimDX: we've seen this on Windows 7, and haven't yet tested other versions: I'm using a bundle of cheap USB gamepads (no serial number), and sometimes one physical gamepad ends up providing the input to more than one Joystick
object.
The scenario is:
- Plug in gamepad 1 to hub slot 1. Pad appears in
DirectInput.GetDevices
as GUID f17b2d30. CreateJoystick
object for pad. - Plug in gamepad 2 to hub slot 2. Pad appears in
DirectInput.GetDevices
as GUID 5187d2d0. CreateJoystick
object for pad. - Press a button on gamepad 2. No change to state.
- Press a button on gamepad 1. Button appears set in
GetCurrentState()
afterPoll()
on both objects. - Unplug gamepad 2.
Poll()
method on its object continues to return without error, but it no longer appears inDirectInput.GetDevices
. - Press a button on gamepad 1. Button appears set in
GetCurrentState()
afterPoll()
on both objects.
I've examined the objects in the debugger. Each Joystick
references the correct GUID by Information.InstanceGUID
, but each has the same USB path in Properties.InterfacePath
.
The gamepad hardware seems to be working correctly - If I perform the same sequence with the control panel joystick tester the gamepads remain distinct.
The DirectInput GUIDs seem to be allocated based on the USB PID and VID, then the order the identical gamepads are plugged in, rather than the physical path to USB port they're plugged in to. If I mix different models of gamepad, the problem goes away.
It feels like a SlimDX or even a DirectInput bug - is there a workaround for this?
回答1:
My final answer here was to drop DirectInput altogether, and move to RawInput. I implemented a small C DLL to interface between my C# code and RawInput.
I've had two limitations: trouble finding device names, and a crash reading device information under XP. Neither of these are a critical problem for my application.
Sample C++ source code is a bit long to fit in an answer, so is here.
Calling from C# uses these signatures:
[DllImport("Adapters.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int InitialiseGamepads(IntPtr hwnd);
[DllImport("Adapters.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr GetDevicePath(int index);
[DllImport("Adapters.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int PollDeviceChange();
[DllImport("Adapters.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int ProcessInput(IntPtr wParam, IntPtr lParam,
out byte buttons, out int x, out int y);
回答2:
I think, you should use:
Joystick joy;
string UniquePathForEachJoystick = joy.Properties.InterfacePath.ToString();
来源:https://stackoverflow.com/questions/12619385/slimdx-joystick-poll-succeeds-on-disconnected-gamepad