Skip to content

Proof of concept - Replacing Xinput with SDL2 #74

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

Closed
wants to merge 2 commits into from

Conversation

joao678
Copy link

@joao678 joao678 commented Dec 31, 2023

This pull request replaces the xinput functions with generic SDL2 ones, with the objective of allowing any controller (including xbox) to be translated to DirectInput, can be useful with Nintendo Switch/PS4/PS5 controllers.

Tested on FlatOut 2 with a DualSense PS5 controller.

Can be used with devreorder as well to hide existing directinput controllers, so only the xidi ones exist.

TODO: find a way to handle controllers connecting and disconnecting

@samuelgr
Copy link
Owner

samuelgr commented Jan 9, 2024

Thanks for sharing this proof of concept! I'm glad to see that Xidi's physical controller back-end is modular (and readable) enough that it was possible to go in and change XInput to another back-end, and I'm also glad to hear that it worked.

Long term, I don't think switching from XInput to SDL2 is the right solution. I recognize that people want to use PS4/PS5/Nintendo Switch (and possibly other) controllers with Xidi, and SDL2 certainly shows some implementation techniques for how to achieve that. What I have been considering is a Xidi-specific modular back-end whose implementation can be inspired by SDL2 but does not use it directly. That makes Xidi code easier to maintain and also fully under the control of this project. I'm also wondering about the comment "TODO: find a way to handle controllers connecting and disconnecting" and, in particular, whether or not it means that the current implementation of the SDL2 breaks an existing Xidi feature that works with XInput.

Until Xidi properly supports these additional controllers, it is possible to use a project like x360ce to make non-XInput controllers available via XInput. I've used this project in the past (version 3 I believe, the one that uses custom XInput DLLs) so that my old DirectInput-only Logitech controllers would work with XInput-only games. I haven't tested this with Xidi, but in theory this should allow non-XInput controllers like Nintendo Switch and PS4/PS5 controllers to become available via XInput and thus able to be used with Xidi. (And if that doesn't currently work, I don't foresee it being too hard to fix.)

The key reason that comes to mind for not wanting to switch to SDL2 directly is that there is a maintenance burden to doing so, which is introduced because we would need to modify SDL2 code itself so that it integrates correctly with Xidi.

SDL2 itself makes calls to DirectInput, in particular by using the exact interface that the HookModule form of Xidi intercepts. So what would happen in a situation in which the HookModule form is being used is the game calls Xidi, Xidi calls its own integrated SDL2 library, the SDL2 library calls the hooked interface, that hooked interface redirects to Xidi, Xidi calls the SDL2 again, and... we get a circular dependency problem. We can't just not hook that interface because then the games wouldn't work with Xidi at all. To fix this we would need to make changes to the SDL2 code itself, and the moment we start making changes to third-party code we introduce a maintenance burden. The more invasive, low-level, and/or complex the change, the greater the burden.

Some good examples of applications and games for which this would actually be an issue are any that require the HookModule for of Xidi, and this includes emulators and other games that themselves use SDL2 for controller support.

I had the same circular dependency problem with the HookModule form of Xidi when it intercepts WinMM functions. However, in this case there is no third-party maintenance burden because the circular dependency is between the HookModule and WinMM forms of Xidi (in other words, it is between two DLLs that are both part of Xidi). To give an idea of the complexity of the fix, I ended up creating an entire API to allow the HookModule and WinMM modules to communicate so that the WinMM module would be able to access the unhooked system functions directly, even if the HookModule form had intercepted them. Some parts of the implementation are here and here.

@samuelgr samuelgr closed this Jan 9, 2024
@joao678
Copy link
Author

joao678 commented Jan 9, 2024

Thanks for the feedback! I understand your concerns regarding maintenance and your reasons to not make such a switch.

I had no idea HookModule had such an impact in the aspects you've mentioned to the point of modifying the core SDL2 code to solve potential issues, SDL is a whole other beast entirely and it's probably for the best we don't mess with it.

I like the idea of a modular backend too and I'm actually working on something similiar with Xidi as well. Scripting.
I've managed to get LuaJIT working inside of Xidi but unlike this PR where it changes how the physical controller is read, instead I'm feeding the virtual DirectInput controller directly from a single .lua script (I've actually used SDL2 from lua too just for testing purposes, but it can be literally anything else instead, ex: data coming from a server...things like that)

Apologies for opening an entire PR just for this, but I've found no other way to communicate this better other than just showing the entire thing (and maybe the messy code, but then again I'm not a C/C++ developer, but hey it's just a proof of concept right? 😉).

I hope your idea of a modular backend goes forward since Xidi is the only method that works on both Windows/Linux/Wine/Proton, there are alternatives like vJoy but that is a windows system driver so that's probably not happening in other operating systems. Don't know if x360ce works though, might have to test it aswell.

A way of futureproofing Xidi whould be very appreciated because who knows what kind of crazy new controller comes out next year (but one thing's for sure SDL probably is going to support it)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants