New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows Joystick Impl for Gamepad Trigger Separate Polling #2428
Comments
Never looked too deep into the new input library, but I originally wanted to implement XInput for Force Feedback, which I then dropped due to the limitation to 4 gamepads/joysticks. And combining/aligning both together is kind of a huge PITA already. I don't think that would be different for the Windows Gaming thing (which I think is more or less just an extra UWP layer/API on top of XInput). XInput has the advantage of providing built-in force feedback possibilities. As a downside, there's still the two different input standards: A DirectInput controllers won't necessarily be recognized by XInput, unless the driver provides both (and vice-versa). This makes workarounds necessary, such as the rather popular x360ce. At least as far as Steam games goes, this wouldn't be a problem (since Steam Input is providing the necessary wrappers as a layer between). |
Regarding device-count, I'm not seeing any upper limit on devices in either Windows.Gaming.Input nor GameInput. Both of these APIs provide means to do vibration / force-feedback. |
Ah, sorry, I completely missed the reply. I think I could get 5+ devices ready, but I also just looked around and seems as if the new API doesn't utilize XInput and therefore has a limit of 8 devices. |
After some testing I can confirm that RawInput also is not able to distinguish between left and right triggers, so I see no reason to consider it over the current DirectInput implementation. |
I've been experimenting with GameInput as an alternative to directinput and xinput in my own input library, so here's some things I've found (although note my experience with GameInput is just 1 day worth so far). The issue of xbox controllers merging the trigger axes when not accessed by XInput unfortunately affects other low level APIs like RawInput and HID. IIRC, DirectInput is fed data from RawInput internally, so MS expose Xbox controllers as HID devices with the merged triggers. This means HID level, RawInput (which is HID data passed through the windows message system) and DirectInput all end up with the same issue. XInput can see the real data coming from the controller, which is separate trigger axes. SFML can't really move to XInput only, that would block all non XBox peripherals. Sticking to just DirectInput means everything works, but XBox controllers have no vibration and the merged triggers (but other gamepads are fine). One option is to do both. MS provide some code (about 100 lines) that can detect if a directinput device is actually an xbox controller. If it is, GameInput is an interesting option. It works with all DirectInput compatible game style devices (joysticks, gamepads, rudder pedals, wheels, etc) but also gives XInput features to Xbox controllers (separate triggers, vibration). The code is easier than DirectInput, but a little harder than XInput.
I do like it though. I'm replacing my own DirectInput and XInput code with just GameInput. One particular thing I like in it is it assigns persistent IDs to devices that will be consistent over disconnects and even system reboots. Identical devices are even identified uniquely as long as they don't change usb ports. So it's great for anything with complex input configuration (like flight sims). On the issue of focus, GameInput does allow out of focus reading of some devices (gamepads, joysticks, etc) but not others (mouse and keyboard). There might be flags for the mouse/keyboard to change that, I haven't looked. But this proposal wasn't about replacing the keyboard and mouse code in SFML too. |
Many modern games actually only support XInput, so it wouldn't be that off, but there'd still be the maximum number of devices as an issue.
Yep, I remember looking at that, but never got around testing it.
Since Windows 7, 8, and 8.1 are all in their end of life with no security updates etc. I'd say this is a non-issue.
No offense to anyone, but some people can be overly paranoid. But also are you sure you're not confusing this with SteamInput, which provides its own emulation layer (which might cause issues with some game/hardware combinations)?
I can certainly see that, but at the same time the Windows/Platform SDK itself is rather big already (and I was pretty sure the headers are included already; I might be off and/or this might have changed, too).
SFML can/could/should just continue using the classic hooks for this. I see no reason to change that. As far as I'm aware GameInput has this in there mostly for Xbox development. |
All of this aligns with my own and @ShadowMarker789's research on this topic. We added a page to the wiki comparing the various options for gamepad support on Windows. I think the GameInput option is purely impossible as it stands now. The Microsoft docs say it will be merged into the Windows SDK at some point in the future, maybe this is when SFML could rely on it. I think a combination of XInput + DirectInput is the best way to properly support Xbox controllers & other vendor joysticks, there's already an example of this being done by an SFML user who wrote a Gamepad library and open sourced it. My current game I rely only on XInput and swerve |
Yeah, GameInput does seem less suited the more I use it (it's been an interesting 48 hours of experimenting). It sounds good on paper, but I'm finding issues like aggregate keyboard/mouse devices not currently implemented (so I'm getting 6 mice and 6 keyboards), device display names don't work for me, no min/max axes queries, etc. Getting it working with a range of hardware was pretty easy (already got Virpil HOTAS with 60 button throttle, PS5 controller, xbox controller, rudder pedals, arcade stick, etc), but my DirectInput code already supports all of those and using the xbox detection code lets me use xinput just for xbox controllers. Adding XInput to sf::Joystick while keeping DirectInput seems the best way to go and would allow better xbox controller use while still supporting things like play station controllers. |
Change Windows Joystick Implementation to a modern API that allows the consuming programmer to query the two analog triggers of the gamepad device separately.
The current sf::Joystick implementation uses Windows DirectInput v8 which has limitations and is deprecated.
Below exerpt from Microsoft Documentation
Microsoft recommended moving to XInput from DirectInput a while ago, really pushing for Gamepad standardization on windows gaming machines, but it's also simultaneously reasonable to want to be able to support multiple different kinds of gaming controllers and not just XInput-capable ones.
The newer gaming-input APIs in modern windows have newer APIs that let one do this.
The most compelling candidate to me is Windows.Gaming.Input::RawGameController
Which itself has an API not too dissimilar to that of sf::Joystick
Being the ones that immediately caught my eye.
Limitations and negatives
Windows Minimum Version Supported
Which is akin to Windows 10 any version, so that won't work on Windows 7. I would like to raise a question and discussion about what version(s) of Windows SFML is looking to target as a minimum version.
Focus
This API only gives you non-zero input when the window is in focus. If current focused window is not owned by the calling process, then a zero input is given regardless of the actual state of the controller.
Potentially a sticky issue - Has anyone here playing a game with multiple displays trailed their cursor over to the other display to use a separate app while still controlling the game with the offhand on their controller?
Alternative APIs
RawInput
Even lower-level and ancient in comparison to DirectInput. It will report the axes separately, but it is a pain to use, and I wouldn't want to be a maintainer for RawInput. If you do your flags right on registration you can get out-of-focus controller input, but it'll be restricted to a particular HWND for the calling process's WndProc
GameInput
Newer than Windows.Gaming.Input, but not reliably present on consumer machines, I believe it was pushed out in a windows update not that long ago, and there are redistributables for GameInput
XInput
Older than Windows.Gaming.Input, with multiple versions available, v 1.4 being the newest. Restricted to gamepad-style controllers though, and it does give you input regardless of window focus.
Multiple?
Potentially one can query for the presence of libraries at runtime and selectively use consumers of said libraries depending on what can be found.
In this way, the joystick initializer could ...
Test for GameInput presence (LoadLibraryW of
gameinput.dll
) and if present, use a consumer of GameInput to implement the joystick eventing.If not found, check for Windows minimum version - if it's greater than or equal to 10.0.15063.0, use WGI
If not meeting the min-ver, fallback to DirectInput v8 as per the current implementation.
This would let most users use the axes of the gamepad triggers independently, and still have some functionality for those poor users stuck on Windows 7.
HOWEVER - it would require that the relevant headers for WGI and GameInput are not directly linked, they would need to be treated differently, as we still want the build application to be able to run without the presence of those libraries! (This implies a large amount of programming work)
Your environment
Windows, this is an issue/discussion that covers multiple versions.
Steps to reproduce
(I'm not actually a C/C++ developer so I can't make a simple example app to demonstrate the linking of the two axes on Windows, sorry!)
Expected behavior
The axes for the gamepad controllers' left and right triggers should be reported independently as two separate buttons or axes.
Actual behavior
There is a single axes reported for both triggers, holding down both triggers reports the same as holding down neither trigger.
This is potentially a very large discussion block, very happy to have feedback on and replies for discussing this and SFML's joystick implementations going forward.
The text was updated successfully, but these errors were encountered: