nipkownix / re4_tweaks

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

Suggestion: Restored Camera Movement for Xinput Devices #118

Open LethalPlacebo opened 2 years ago

LethalPlacebo commented 2 years ago

In the original GameCube version of RE4, you had pretty fine control over the camera with the C-Stick. It was easy to look around Leon and diagonals worked properly as well. But when using an Xinput controller with the Steam version of RE4, the control of the camera is massively reduced, but from the inside out. Basically, if you try to turn the camera left, it won't register until about halfway, which then snaps the camera about 45 degrees or so. You can still use the camera for the extreme edges, but fine control is lost. Diagonals also don't work in Xinput. This is separate from the game's bad deadzone.

Strangely enough, the camera does work properly when using Dinput, but when you aim your gun, it has the same bad deadzone as Xinput (I use an Xbox One controller and solve the deadzone using Steam input). I dunno if anything can be done about this, but I just thought I'd bring it up, thanks so much for all your hard work.

Here is a video demonstrating GC, Steam/Xinput, and Steam/Dinput:

https://youtu.be/H54_p4ut-hA

emoose commented 2 years ago

Looks like the 2-byte shorts at bio4.exe+0x82CA40 & bio4.exe+0x82CA44 (1.1.0) have something to do with XInput deadzone, changing those to 32767 seems to almost set a 100% deadzone (some inputs get through somehow though - maybe their deadzone code is buggy...)

Decreasing them seems to reduce the deadzone a little - unfortunately even with them both at 0 there's still some kind of deadzone being used, maybe in PadRead somewhere.

E: hmm, think bio4.exe+0x82CA40 is for LS, bio4.exe+0x82CA44 for RS - also noticed that setting RS to 0 does seem to reduce deadzone while aiming, but changing LS deadzone hardly seemed to make a difference :/

nipkownix commented 2 years ago

Interesting issue, mostly because Dinput does seem to work correctly here (at least the C-Stick part). I wonder how they managed to mess this up, but seeing as Xinput support was added by the Xbox 360 porting team, this being messed up doesn't surprise me at all..

Edit: Seems there is some deadzone stuff in PadRead, yeah. Well, I say "deadzone", but they're actually just continuously overwriting the stick value with "0" until some arbitrary number is reached ._.

nipkownix commented 2 years ago

685ad1e has some changes that should improve this.

Two new options: RemoveExtraXinputDeadzone - Makes the C-Stick stuff behave like it does on Dinput. (Not sure why they even added this) XinputDeadzone - changes the RS and LS Xinput deadzone values (bio4.exe+0x82CA40 & bio4.exe+0x82CA44 mentioned by @emoose earlier. Thanks!). We default to a bit less than half of the original value now. Seems to work just fine.

Test build: dinput8-deadzone-changes_v1.zip

LethalPlacebo commented 2 years ago

Just tested the test build and oh my god, you did it! It's fixed! Full camera functionality restored, thank you so much! There is a deadzone left slightly bigger than I'd like, but this is very easily solved with the Steam Input settings. Thanks again!

80T commented 2 years ago

This is amazing! I would've never thought RE4 HD or any RE4 port on PC will ever reach this state of polish and fixes.. (well, not with the help of CAPCOM anyways.. )

There is still some "cross deadzone" which I've "treated" with an anti-deadzone of .200 cross shaped in Steam Input, even after setting a 0.000000 deadzone in the tweaker's configuration. Now everything seems perfectly linear and smooth without any dead.. zones or other weird behavior. Thing is that now, with no more deadzones (as per the original GC/Wii versions) there seems to be an issue with character turning being highly sensitive.. while moving forward, tilting the analog in any direction but, for just a bit, will make the character turn and make it difficult to keep running/walking in a straight line. I've made sure I haven't overdone the anti-deadzone, which might have resulted in the same behavior. Seems to me that somewhere during the porting process, likely the 360 version, the movement and aiming got treated as the same input and not separately as 2 separate actions, thus, in this scenario, one deadzone for both or none at all.. Likely the easiest way to "fix" the sensitive turning for the porting team was to just add this per axis deadzone ("overwriting the stick value with "0" until some arbitrary number is reached ._.") which would be a "real" cross shaped deadzone and actually works wonders for "translating" axis values from a stick to a directional pad (which they might've done in the port.. I assume GC version had the proper, independent analog to movement treatment.. with the proper axis to movement scaling and.. "deadzoning..".. ) But.. as a consequence, we've ended up with the weird deadzone for aiming which this new test implementation just fixed. So.. if the movement and aiming are not actually "intertwined".. linked somehow in this port, an additional "per axis nulling" deadzone (just for movement) would be fantastic (that "zeroing the axis values" until a threshold is reached)

Cheers!

nipkownix commented 2 years ago

Well, with 0.40 deadzone in re4_tweaks, everything feels very similar to the GC version running on Dolphin. As in: There is a "deadzone" before Leon begins turning when moving the left stick, but there isn't one when aiming with the same left stick.

I'd say your issues are being caused by Steam's anti-deadzone thing. Is that really needed?

80T commented 2 years ago

Well, with 0.40 deadzone in re4_tweaks, everything feels very similar to the GC version running on Dolphin. As in: There is a "deadzone" before Leon begins turning when moving the left stick, but there isn't one when aiming with the same left stick.

I'd say your issues are being caused by Steam's anti-deadzone thing. Is that really needed?

From what I've experimented yesterday evening I have found that anti deadzone of .200 to be necessary for the aiming and even still, the turning still felt more sensitive than the GC original. Basically, by default, there seems to be a cross deadzone that is not the exact same for movement and aiming on the PC port, but hard linked to one another. The movement deadzone is higher, but not enough, especially when you cut into it to bring the aiming deadzone back to zero. If we could add some axis independent deadzone just for movement and maybe even configurable, it would be perfect. I'll try to experiment more when I get home tonight, but regardless, the worst part was already fixed as far as I'm concerned. I can now actually make a proper Steam Input config and not have gaps in the camera movement. This is a huge milestone in my eyes as far as controls are concerned in this game.

Cheers!

80T commented 2 years ago

Soo, did some more experimentation with the Steam Input On/Off, deadzones / anti-deadzones On/Off, Dolphin/Steam, DualSense/XBOne controllers..

Dolphin: (I don't have a save on the game, thus I am only able to test the first handgun.. sniper is required to properly determine aim behavior)

Steam: (Dinput - can not be tampered with, as Steam Input will automatically convert it to XInput)

Steam: (XInput - Either XBOne or DualSense with Steam Input support enabled - no difference either way) *With the fix applied (Stick/s deadzone to 0.000000 and "remove XI Extra Deadzone" enabled)

What I believe should be happening with the movement input from the left stick is to "null" both X/Y axes to give them a proper cross shaped deadzone as could be seen in the following linked picture where I've tried to do a representation of what the ideal movement should be translated to from the left stick: https://i.ibb.co/HdRD42z/Cross-axis-nulling-deadzone.png Basically, the stick's movement should be split in 8 x 45 degrees "sectors" in which the cardinals should only take one axis input, either X or Y, and the diagonals should only take a mix of X+Y or Y+X.

So, from "0" to "360" it should go like this:

To achieve these ideal values (well, a very close approximation, due to hardware tolerances.. ) with equal spacing/mapping of the cardinal and ordinal directions we'd just need to "null" the X/Y axes up to a threshold (that could even be configurable) but only while moving.

That threshold could easily be calculated with an online geometry calculator to a value of 0.3827 (roughly approximated to 0.4 if needed be) as can be seen in the following picture: https://i.ibb.co/HVhk1px/Octagon-deadzone-value.png Caveat here is that the deadzone has to actually be simply nulling the axis values up to that threshold, otherwise, calculating the "deadzone" by other means might end up as in the Steam Input's case with a "pseudo cross deadzone" which becomes lower and lower as the stick moves further away from the center (it can even be seen in the Steam Input's UI analog graph itself) thus, the more you push the stick outwards in any direction, the more the cardinal directions become prioritized, thus the turning becomes more sensitive at the edges than just after the deadzone threshold is passed at about the middle of the stick's range.

Hopefully this could be of any help.

Cheers!

EDIT:

This is the Octagon Calculator: https://www.omnicalculator.com/math/octagon (and for a value of 32768, a perfect nulling threshold value would be 12540 - well, half that.. as we're talking half axis per direction)