4

I am trying to use DirectInput to capture XBOX One controller input signals. I am tying it to a C# WinForms application. The issue I am having is: When the form has focus, it captures inputs just fine. When the window loses focus, I don't get any feedback. On Windows 7, this isn't an issue.

I have tried other controllers on Windows 10: PS4, Logitech, Steering Wheels, etc... Everything works as expected: When the window loses focus, I still get feedback. It's just the XBOX One controller on Windows 10.

I thought maybe it had something to do with this line:

dev.SetCooperativeLevel(_ctlParent, CooperativeLevel.Background | CooperativeLevel.Nonexclusive);

But, even if I take that line out, everything still acts the same.

It seems like the XBOX One controller ignores the CooperativeLevel.Background flag and adds the CooperativeLevel.Foreground flag. Here is some more info about the flags.

Is there anyone else familiar with this issue that has figured out a work around?

Andy
  • 12,859
  • 5
  • 41
  • 56
  • Do you know if SharpDX is using legacy DirectInput, XINPUT, or Windows.Gaming.Input? – Chuck Walbourn Feb 12 '18 at 22:15
  • I am pretty sure it's a wrapper around DirectInput.. The API i call almost matches 1-for-1 on calls (i ported this from a C++ program that used DirectInput) – Andy Feb 13 '18 at 13:22
  • 1
    Ok, well the first thing to say is that you should be using XINPUT or ``Windows.Gaming.Input`` for Xbox 360 / Xbox One Game Controllers, and only falling back to DirectInput for legacy HID controllers. DirectInput support for these controllers is largely intended for old games, so they will have quirks when using that emulation. – Chuck Walbourn Feb 13 '18 at 18:59
  • @ChuckWalbourn, Thank you -- I am going to go look in to that and see if that will work for our solution. Thanks for taking the time to help out. – Andy Feb 13 '18 at 21:05
  • Hey @ChuckWalbourn, It works for me! if you make an answer about XINPUT I will accept it. The namespace `Windows.Gaming.Input` is for UWP apps, but i found a .NET wrapper (https://github.com/speps/XInputDotNet). Thank again for all your help. – Andy Feb 14 '18 at 00:40

2 Answers2

5

Been exploring this myself regarding XBox One controllers. Each API has its own set of limitations when it comes to XBox One and XBox360 controllers.

Here's a summary of what I've learned:

Windows.Gaming.Input ref

Unlimited(?) number of controllers on Windows 10.
(Until recently I thought the limit was 8 but I've tested with 9 XBox 360/XBox One controllers so the MAX_PLAYER_NUMBER=8 found in DirectXTK is not set according to a real limit for Windows 10. ref)

Limitations:

  • Controllers can’t be accessed in the background...
    (Not 100% sure though. I haven't gotten the controllers to work in the background myself and documentation says this limitation exists for UWP apps. ref )
  • Only works on UWP devices (e.g. Windows 10, XBoxOne, Windows Tablets, etc)
  • The Gamepad class only supports Xbox One certified or Xbox 360 compatible gamepads (ref), other gamepads can be accessed via the RawGameController class (ref).

XInput ref

API for accessing 4 XInput compatible controllers (e.g. XBox 360 or XBox One controllers)

  • XInput controllers can be accessed in the background.

Limitations:

  • Max 4 controllers.
  • Only XInput capable devices.
  • Unable to activate the extra 2 rumble motors in XBox One controller triggers. (Use Windows.Gaming.Input to do that.)

DirectInput ref

The oldest of these APIs.
Unlimited number of controllers (?)

Limitations:

  • XBox One controllers cannot be accessed in the background. (Bug or a feature?)
  • XBox 360 and XBox One controllers have triggers on the same axis, no guide button and no rumble.
  • Windows Store Apps can’t use DirectInput. ref
  • Microsoft no longer recommends using DirectInput. ref

Raw Input ref

Unlimited number of controllers (Lacking reference. Tested with 9 controllers.)

  • XBox One and other controllers can be accessed in the background.
    (Use this source code to try it out: ref)

Limitations:

  • XBox 360 and XBox One controllers have triggers on the same axis, no guide button and probably no rumble. (Tested using this source code ref)
supersmo
  • 61
  • 1
  • 3
  • If someone has ever managed to access controllers in the background using Windows.Gaming.Input in a non UWP/Windows Store app please let me know in the comments. – supersmo Jan 30 '19 at 10:48
  • Written native windows app with WinRT APIs loaded at runtime (using [LoadLibrary and GetProcAddress](https://stackoverflow.com/a/55490560/1795050)) and `Windows.Gaming.Input` class usage. Seems working fine with vibration while window is not focused and no issues. – DJm00n Apr 04 '19 at 11:32
  • @DJm00n Do you have code for a working sample in an open source repository that you could reference? I have a use case where accessing in the background would prove very useful. – supersmo Feb 04 '20 at 20:12
  • according to my knowledge Windows.gaming.input is designed to run only while there is a window and it has a focus. See https://stackoverflow.com/questions/57042069/xbox-360-wireless-controller-is-not-working-via-c-winrt-and-windows-gaming-inp for details and the link to my test repo. – DJm00n Feb 06 '20 at 07:15
  • 1
    Thanks DJm00N! I too thought controllers couldn't be accessed in the background via Windows.Gaming.Input but your previous post game me some hopes. Thanks for clearing up the confusion. – supersmo Feb 09 '20 at 14:03
1

The drivers for the Xbox 360 Common Controller and the Xbox One Controller both emulate "HID" for use with the legacy DirectInput API for older games, but the emulation tends to have some quirks like this one.

Probably the best solution is to use XINPUT for these controllers and only fall back to DirectInput for legacy HID controllers. For Windows 10 DirectX 12 / UWP apps you can use Windows.Gaming.Input directly as well.

See XINPUT and Windows 8 and DirectX Tool Kit: Now with GamePads.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • A bit off topic but I'll go for it. Only one window can receive xinput/direct-input input messages from a gamepad at a time right? – KeyC0de Apr 25 '21 at 00:01
  • Hi Chuck. The following statement is made in the UWP docs: "A Windows application must have focus to receive input from an Xbox One Controller.". This suggests that the Xbox One controller is "special" in some sense and that even when used by the most current API available, it still behaves in this undesirable fashion, so I am puzzled that you call it a quirk of the emulation for the legacy API. Is the driver stack for this controller simply buggy? It's very hard to see this as a feature of any kind... – Neilski Mar 12 '22 at 14:30
  • "Windows.Gaming.Input" is the API that is used for gamepad input for UWP and it only accepts input when the application is in focus. XInput is not actually supported for UWP. The ``xinput_uap.lib`` is just an XINPUT API wrapper around `Windows.Gaming.Input` – Chuck Walbourn Mar 14 '22 at 03:39