SlimDX: Joystick.Poll() succeeds on disconnected gamepad

£可爱£侵袭症+ 提交于 2019-11-30 00:01:30

问题


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:

  1. Plug in gamepad 1 to hub slot 1. Pad appears in DirectInput.GetDevices as GUID f17b2d30. Create Joystick object for pad.
  2. Plug in gamepad 2 to hub slot 2. Pad appears in DirectInput.GetDevices as GUID 5187d2d0. Create Joystick object for pad.
  3. Press a button on gamepad 2. No change to state.
  4. Press a button on gamepad 1. Button appears set in GetCurrentState() after Poll() on both objects.
  5. Unplug gamepad 2. Poll() method on its object continues to return without error, but it no longer appears in DirectInput.GetDevices.
  6. Press a button on gamepad 1. Button appears set in GetCurrentState() after Poll() 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!