Ryochan7 / DS4Windows

Like those other ds4tools, but sexier
https://ryochan7.github.io/ds4windows-site/
GNU General Public License v3.0
6.96k stars 807 forks source link

[TODO] Add support for Vmulti driver #943

Closed Ryochan7 closed 3 years ago

Ryochan7 commented 4 years ago

There are several limitations with the SendInput API that is commonly used to emulated KB+M events in Windows applications. Some examples of problems are UAC prompts not allowing events to be used, needing to run a mapping program under the Administrator account depending on the game being played (Mass Effect 1), and anti-cheat software (GameGuard) blocking such events from working in a game.

Back in the antimicro days, I had played around with the Vmulti driver to work around those issues. Besides resolving those issues, events sent through the driver were transmitted slightly quicker than when using the SendInput API calls. Using Touchmote has been the only reason that I have had the Vmulti driver installed lately. Touchmote still uses SendInput for its FPS mouse mode and keyboard events though; Vmulti is mainly used for the Touch cursor.

I would like to add Vmulti support into DS4Windows if it is not too much trouble to implement.

Ryochan7 commented 4 years ago

Still want to attempt this. I need to abstract how output events are generated in the code. A bigger challenge will be how to link the proper event code with the corresponding Windows virtual key code that is used in the profile XML file. Especially with different computers, the association might be different so a startup routine will have to go through and find the appropriate codes.

Ryochan7 commented 4 years ago

Finally got around to experimenting with the Vmulti driver. Unfortunately, the last released stable driver won't do what I want after all. The virtual relative mouse is bound to a [-127, 127] range per event. Gyro Mouse, especially when using a slower poll rate, can go outside of those bounds. Clamping to keep the data in bounds would cause a loss of precision.

A customized vmulti driver would be required in order to increase the bounds of the virtual mouse as defined in the HID Report descriptor. That would also mean that Windows would have to be run in Test mode in order to use that driver as well.

Ryochan7 commented 4 years ago

Having Driver Signature Enforcement disabled would be a problem with some games. One game that would affect my use would be Halo: Master Chief Collection multi-player. Easy Anti-Cheat checks if Driver Signature Enforcement is disabled on the system and will refuse to load the game if it has been disabled. I have experienced this because I am using a custom version of HidGuardian signed with a Test Certificate. Luckily there is an option to disable the Anti-Cheat system and only have access to the single player campaign for the collection.

Ryochan7 commented 4 years ago

Finally taking a shot at this problem. I got most of the routines refactored so many virtual KB+M events work through VMulti. Running into issues with how the general KB+M event routine works in DS4Windows. Also, trying to get macros working with VMulti is going to be a royal pain in my backside.

https://github.com/Ryochan7/DS4Windows/tree/virtualkbm_refactor

Ryochan7 commented 4 years ago

VMulti driver support is pretty much fully functional in the virtualkbm_refactor branch. For some use cases, it would work better than using the SendInput API. Virtual events are more responsive and UAC problems do not occur when using the driver. However, the [-127, 127] range of relative mouse reports for the driver really hampers Gyro Mouse and Touchpad mapping. It is very much possible to initially generate mouse events that exceed that range; more so with Gyro Mouse than with the Touchpad. Clamping has to be done to enforce that range so sensitivity is lost for some fast movements.

As of now, I am not sure these changes will be merged into the jay branch. I think I would have to hard fork the VMulti driver in order to fix the relative mouse range and add some missing multimedia keyboard keys to the driver. That would give me more of an incentive to actually incorporate these changes into the main program.

Ryochan7 commented 4 years ago

I should have mentioned it beforehand that there is currently no way to specify which virtual KB+M API is used at runtime. You have to change which system is used in the code by changing the following line and specify VMultiHandler rather than SendInputHandler.

https://github.com/Ryochan7/DS4Windows/blob/97d0d3e687de010a7b3f875241919c4e54352a33/DS4Windows/DS4Control/ControlService.cs#L145

Obviously if you want to try vmulti, you have to have the driver installed on your system or DS4Windows will attempt to revert back to using SendInput.

Ryochan7 commented 4 years ago

Updated the virtualkbm_refactor branch. The branch is now in sync with version 2.1.5. Also, there is now a command line argument for specifying which KBM handler to use. That should be good enough for testing but adding an extra portion to the Settings tab will probably be required before these changes get merged into the jay branch.

-virtualkbm <identifier>

Valid identifiers: sendinput, vmulti
Ryochan7 commented 4 years ago

I have figured out how to alter the HID Report Descriptor to increase the range of the relative mouse pointer. Bumping up the range of each axis to fit 2 bytes (ushort) should definitely be big enough to work with; it amounts to a range of around [-32767, 32767] per mouse event rather than [-127, 127]. I also had to update the vmulticlient library to change the VMultiRelativeMouseReport struct and also the VMultiDLL C# wrapper.

Larger mouse motions work well with the changes. The big problem is that the changes would not be backwards compatible with the last stable VMulti driver; I don't know of any project that actually uses it other than Touchmote.

Ryochan7 commented 4 years ago

Updated VMulti repos

https://github.com/Ryochan7/vmulti https://github.com/Ryochan7/VMultiDll

Ryochan7 commented 4 years ago

I had to redo some work that I lost from not making a backup before installing Windows again. The enhancements branch of VMultiDll has recent changes that DS4Windows is utilizing. I am thinking about re-factoring the way media keys are structured in the HID Report Descriptor so things will likely change soon.

https://github.com/Ryochan7/VMultiDll/tree/enhancements

The virtualkbm_refactor DS4Windows branch has been updated to version 2.1.9.

Ryochan7 commented 3 years ago

The integration of Flick Stick complicates the matter further. With a 180 degree flick, it is easy to go beyond the bounds of 127 pixels. Support for some form of vmulti will have to remain experimental until the driver can be properly digitally signed. The old vanilla vmulti driver is no longer useful for my use case. The old libraries used in DS4Windows will be removed and replaced with the experimental version included in the VMultiDLL_Test folder.

Also, the milestone associated with this issue can be removed since there is no defined time when vmulti support might ever be included in a public release.

Ryochan7 commented 3 years ago

Going to close this issue for the time being. Support is finished for the most part but it cannot be merged into the main jay branch without an updated VMulti driver. The virtualkbm_refactor will be updated every once in a while with changes from the jay branch.

Ryochan7 commented 3 years ago

Cyberpunk 2077 is another game where VMulti support would be useful. Despite being a single player RPG, the game blocks SendInput events so mixed input support will not work. reWASD is one of the few mappers that is confirmed to allow virtual mouse to work due to its virtual KB+M driver. Since reWASD is confirmed to work, VMulti support would work as well.

https://reddit.com/r/SteamController/comments/kaca39/cyberpunk_2077_has_blocked_all_virtual_inputs/

CodeOhms commented 3 years ago

Someone has used the Interception GitHub project, which has signed drivers, for the same result. They submitted a pull request to the old Jays2Kings repo. https://github.com/Jays2Kings/DS4Windows/pull/636

Ryochan7 commented 3 years ago

I saw that initial post and looked into the Interception project. I cannot remember the exact reason why but I initially ruled it out as a viable option. Maybe I should give that fork a try and see how it compares to vanilla Jays2Kings before I completely discount that route as an option.

Having an updated VMulti driver is something I have been wanting for about 4 years now. Touchmote is the main mapper I use that has some official form of VMulti support. The program uses it for its Touch Cursor mode. For general KB+M purposes, the very limited mouse range [-127, 127] is too small for mapping some elements like Gyro Mouse. It has been several years since the driver was last updated.

CodeOhms commented 3 years ago

Yes, an updated and signed version of vmulti would be great. There is a signed copy of the last update to the original in this release of the TabletDriver project.

Maybe you could use that? I'm looking at using it for a commercial project myself. Though, when using the test program from vmulti only the mouse seems to work - which fortunately for me is all I need anyway 😄.

Ryochan7 commented 3 years ago

Gave the Interception fork a try and it was a bust. I installed the driver and I thought I had everything configured. Kept getting AccessViolationException errors that crashed DS4Windows. After several attempts, I gave up on it.

Not sure what changes might have been made with the version of VMulti that is distributed with TabletDriver. One big issue is that the driver that is distributed is not digitally signed. Windows will have to be run in Test Mode in order to use the driver at all. That is no different than the current situation with the version of VMulti that DS4Windows uses in the virtualkbm_refactor branch. Most users won't want to run Windows in Test Mode at all times and some games will fail to launch if it detects that Windows is in Test Mode (Halo multi-player).

On the plus side, it looks like people have found out that the issue with Cyberpunk 2077 is a legitimate game bug and not an active block. It looks like mixed input might be fixed in a future build of the game.

https://www.reddit.com/r/cyberpunkgame/comments/kb73fr/fix_for_virtual_input_not_working/

CodeOhms commented 3 years ago

Hmmm I thought the vmulti driver packaged with the latest release of Tablet Driver was signed.... [EDIT: The driver given inside the latest release package is indeed signed. I have driver enforcement enabled and checked it with sigverif.exe that comes with Windows.]

That's a shame the fork built on Interception won't work. Hopefully that's not an issue with the Interception driver. I bet its a problem with the code that uses it.

CodeOhms commented 3 years ago

I've recently heard news that some anti cheat engines refuse to start if they detect drivers known for cheat exploitation. This includes the Interception driver! It may not be a worthwhile pursuit to use these existing drivers I am afraid. EAC doesn't complain about the VMulti driver that I found in the TabletDriver project, but I think I will just avoid it altogether now.

If you wanted to continue pursuing this approach maybe you could reach out to Nefarious who signed the ViGEm drivers. Maybe he could sign either yours or his version of VMulti.

Good luck with your pursuit. Keep me posted if you find a way to control the mouse with a virtual driver as I could use this in a product I hope to put on Steam 👍, and eventually open source.