nipkownix / re4_tweaks

Fixes and tweaks for the "UHD" port of Resident Evil 4
zlib License
342 stars 32 forks source link

[Feature request] Simultaneous Controller+Keyboard/Mouse (Mixed Input) Support #171

Open AL2009man opened 2 years ago

AL2009man commented 2 years ago

Resident Evil games historically never allow players to use both Game Controller and Mouse Inputs at the same time, if you attempt use both inputs simultaneously: the game starts to conflict. (But it's not as bad as Resident Evil 5's.)

While it is technically possible to work around it by the power of SHIFT (setting a Action Set/Layer to switch between Controller to Keyboard/Mouse on the fly), you may have to deal with potential button prompt flickering. For certain Input setups such as...Gyro Aiming (in style of RE5/6 Nintendo Switch version), Steam Controller, Steam Deck and Accessibility-focused input methods, this is a problem.

Since Resident Evil 4 uses MouseEvent for QTEs (refer to https://github.com/nipkownix/re4_tweaks/issues/148) or when you take damage (affects those who uses Gamepad-to-KB/M Action Set/Layer switching trick), this may become a problem, but I may offer at least...three suggestion:

Option to Lock Gamepad or KB/M Button Prompts/Glyphs.

An option to turn off Automatic Button prompt switch and let players pick between Gamepad or Keyboard/Mouse prompts regardless of your current Input device is extremely useful for folks who use Accessibility-focused devices, non-traditional inputs (Wooting keyboards, Azeron Gaming Keypad, etc.) or uses a Input Remapper and don't have to worry about button prompt flickering.

For example: Kojima Production's Death Stranding provides that option, which enables the ability to use both Gamepad and KB/M at the same time, without any conflictions.

Keyboard/Mouse prompts should change only by keyboard/mouse click

Only have Keyboard/Mouse button prompts be switched based on keyboard/mouse click event and not by Mouse Movement Event. This is something Valve recommends for Gyro/Trackpad Friendliness on Steam Deck (and retroactively all Input Methods)

For example: Unreal Engine 5's City sample only change Keyboard/Mouse prompts by KB/M press.

Mouse as Weapon Aiming only

Having an ability to only have the Mouse Movement Event Affect Weapon Aim is useful for those who wanna assign the supported controller's Gyroscopic Controller for Wepaon Aiming only (again, in style of RE5's Switch version), without having to create workarounds for Menu Navigations or QTE Sequence.

For example: One More Level's Ghostrunner takes that into account by basically disabling Mouse Input while in Menu. Seems to only affect Virtual Mouse Input (aka when you bind the Gyro or Trackpad as a Mouse, using Steam Input Gamepad Emulation), as you can still navigate the menu with a System/Physical Mouse Input.

However, it may cause a problem for some folks who may decide to switch to physical Keyboard/Mouse Inputs in between, so ideally: it should be actived IF a Game Controller is detected.

emoose commented 2 years ago

Looks like the prompts/glyphs are controlled by iLastUsedController, values seem to be 0 for keyboard (or dinput?), 1 for keyboard & mouse, 2 for XInput, not sure what 3 is for though (game treats 0 & 1 as 'pc', 2 & 3 as 'xbox') (E: ah nipkow already documented this at GetLastUsedDevice, nice)

Unfortunately that var also controls which input the game actually accepts too, so eg. forcing it to XInput will make it always show xbox buttons, but then kb/mouse won't work at all. Not sure if that would be possible to fix at all...

Guess our best option might be to find where the glyph-related code is actually reading iLastUsedController, and make it use our own function to decide what glyph type to use instead.

E: guess it's either MessageDisplay::move or IDSystem::set that decides what glyphs to draw, will try experimenting with them some more soon.

E2: seems that it's IDSystem::set that mostly controls glyph prompts, I got something working by overwriting iLastUsedController before it's called, and restoring it afterward, this seems to work to allow forcing a glyph type (eg. XInput glyphs while playing with keyboard seems to work fine, both for button prompts & inventory screen prompts)

Don't really think overwriting like that is the best way to handle it though, if game uses multiple threads for anything I could see that causing an issue...

E3: well, I managed to narrow down the uses in IDSystem::set that actually controlled the glyphs to 2, one for button prompts in-game & another for prompts in inventory screen, that func has a ton of other uses that I'm not sure about though, so pretty likely only changing those 2 would miss a lot of other button prompts in the game too...

The method I used earlier of overwriting iLastUsedController would probably help let us change all of them, but I dunno about the safety of that, maybe the best way would be to sig-scan for iLastUsedController address, and then use the addr to sigscan for uses of it inside IDSystem::set, so we can patch them all to point to our own variable instead, not fully sure what best way to do that is atm though.