SlimDX: Joystick.Poll() завершается успешно на отключенном геймпаде

У меня есть любопытная проблема с SlimDX: мы видели это на Windows 7, и еще не тестировали другие версии: я использую связку дешевых USB-геймпадов (без серийного номера), и иногда один физический геймпад заканчивается до предоставления входных данных более чем одному объекту Joystick.

Сценарий:

  1. Подключите геймпад 1 к слоту концентратора 1. Пэд отображается в DirectInput.GetDevices как GUID f17b2d30. Создайте объект Joystick для площадки.
  2. Подключите геймпад 2 к слоту концентратора 2. Пэд отображается в DirectInput.GetDevices как GUID 5187d2d0. Создайте объект Joystick для площадки.
  3. Нажмите кнопку на геймпаде 2. Состояние не изменилось.
  4. Нажмите кнопку на геймпаде 1. Кнопка появится в GetCurrentState() после Poll() на обоих объектах.
  5. Отключите геймпад 2. Метод Poll() на его объекте продолжает возвращаться без ошибок, но он больше не появляется в DirectInput.GetDevices.
  6. Нажмите кнопку на геймпаде 1. Кнопка появится в GetCurrentState() после Poll() на обоих объектах.

Я проверил объекты в отладчике. Каждый Joystick ссылается на правильный GUID по Information.InstanceGUID, но каждый имеет один и тот же путь USB в Properties.InterfacePath.

Аппаратное обеспечение геймпада, похоже, работает правильно. Если я выполню ту же последовательность действий с тестером джойстика на панели управления, геймпады останутся различимыми.

Похоже, что идентификаторы GUID DirectInput распределяются на основе USB PID и VID, а затем порядка подключения идентичных геймпадов, а не физического пути к USB-порту, к которому они подключены. Если смешать разные модели геймпадов, проблема исчезнет.

Это похоже на ошибку SlimDX или даже на ошибку DirectInput - есть ли обходной путь для этого?


person Adrian Cox    schedule 27.09.2012    source источник
comment
directinput определенно имеет ошибку. Иногда мой контроллер отображается как контроллер 2, хотя у меня есть только один, и это официальный контроллер Xbox 360.   -  person John Lord    schedule 23.11.2018


Ответы (2)


Мой окончательный ответ здесь состоял в том, чтобы полностью отказаться от DirectInput и перейти на RawInput. Я реализовал небольшую библиотеку C DLL для интерфейса между моим кодом C# и RawInput.

У меня было два ограничения: проблемы с поиском имен устройств и сбой чтения информации об устройстве под XP. Ни одна из этих проблем не является критической для моего приложения.

Образец исходного кода на C++ немного длинноват, чтобы поместиться в ответ, здесь так же.

При вызове из C# используются следующие подписи:

    [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);
person Adrian Cox    schedule 20.10.2012
comment
Спасибо ! Не могли бы вы поделиться Adapters.dll? - person Jean-Philippe Encausse; 04.12.2014
comment
@Jean-PhilippeEncausse Источник находится в ссылке pastebin в ответе - в данный момент я не могу распространять двоичный файл и рекомендую скомпилировать его в проект DLL C ++. - person Adrian Cox; 04.12.2014
comment
@Adrian Cox, вчера вечером я успешно скомпилировал ваш проект C++ Adapters.dll с Visual Studio 2013. Сегодня я протестировал ваш метод ProcessInput() и обнаружил, что он возвращает x = 0 по ссылке, независимо от того, насколько энергично я использую CH Products VM Desktop. джойстик, Не могли бы вы сказать мне причину наблюдаемого поведения? Спасибо. - person Frank; 23.12.2015
comment
@Frank Фрэнк, у меня нет этого джойстика, но возможно, что он возвращает вашу координату x как другое значение использования. Для отладки я рекомендую вам начать с возвратов от HidP_GetUsageValue и искать любые, которые меняются при перемещении джойстика. Я имел дело только с простыми двухосевыми цифровыми геймпадами, а более сложные стики могут вести себя иначе. - person Adrian Cox; 23.12.2015
comment
@Adrian Cox, как вам удалось скомпилировать и связать Adapters.dll с помощью компилятора Microsoft Visual Studio 2013 C++? В частности, какие включаемые файлы, включаемые пути к файлам и имена и пути библиотек компоновщика вы использовали. Кроме того, я нашел и исправил как минимум 4 ошибки компиляции и времени выполнения в исходном коде по вашей ссылке pastebin. Вам было бы интересно прочитать мои изменения? - person Frank; 24.12.2015
comment
@Frank Я действительно использовал компиляторы VS2010 - мне интересно увидеть изменения, но я больше не работаю над приложением, для которого оно было разработано. - person Adrian Cox; 27.12.2015

Я думаю, вы должны использовать:

Joystick joy;
string UniquePathForEachJoystick = joy.Properties.InterfacePath.ToString();
person user2330118    schedule 10.03.2015
comment
Хотите объяснить, почему это поможет решить исходную проблему? - person mjuarez; 10.03.2015