p2sr / SourceAutoRecord

Speedrun plugin for Source engine games.
https://sar.portal2.sr/
MIT License
93 stars 29 forks source link

Patch windows angle decay #101

Closed ThisAMJ closed 6 months ago

ThisAMJ commented 1 year ago

:eyes:

ThisAMJ commented 1 year ago

We have a lead! +strafe (IN_StrafeDown) stops minor decay! I can't see a reason why in the source code I have, some licensee might need to take a closer look :wink:

mlugg commented 1 year ago

We need to think a bit about how we want to unify angle changes across platforms rules-wise. Windows has this issue specific to it, but you also recently showed a weird floating-point issue on Linux which iirc isn't present on Windows? If we replicate one system on another, we should replicate the whole thing, bugs and all. Doing this accurately will probably boil down to writing an asm blob copying the Linux behaviour precisely.

ThisAMJ commented 1 year ago

To be honest, the Linux behaviour makes minisnaps infeasible and casts into doubt regular viewsnaps. That being the case, I think we would be better suited patching the Linux behaviour and adding angle decay.

Ultimately, I think the community would prefer patching both sides and letting one mouse movement = one mouse movement forevermore, and letting the game be "Portal 2 but with the stupid and inconsistent bugs fixed," but obviously that challenges the 'purity' that mods and people like dwangoAC strive for

Krzyhau commented 9 months ago

After a small research I did, pitch angle decay, both the small and the big one, seems to be exclusively caused by CInput::ApplyMouse function. The math performed in it causes the pitch in view angle to change despite both mouse_x and mouse_y being equal to zero. However, I have failed to figure out the exact reason for math to be incorrect. Moreover, I failed to notice what makes calculations different after portal passage with roll change for big angle decay to exist. It might be that the compiler has produced some faulty logic, because after investigating the disassembled code for a bit I consider it... weird, to say the least. More research will follow, but for now, patching angle decay might be possible by preventing default ApplyMouse behavior when mouse vector is equal to zero, but this will remove both angle decays, as they're most likely a result of the same mathematical issue.

ThisAMJ commented 9 months ago

Major angle decay was investigated and explained by @mlugg and they found it was imprecision in the player's m_Up vector, as you can read on the wiki.

Perhaps you could apply the check for 0 mouse_x/y only when the pitch is near 0 (+-25ish) as that's where minor decay takes place? Major decay is the opposite. Does it not decay while you move your mouse?

That's if we only want to patch minor. Burger wants a patch for both, locked behind cheats

Also I want to add that as I understand it the function is C_Paint_Input::ApplyMouse (or something along those lines), which has more function calls presumably for portal travel and isn't in leaks :(

ThisAMJ commented 9 months ago

bandaid! 5247b087ebb48a896c9b3a1fb7f2b38a6e7c751f

mlugg commented 9 months ago

hi i haven't read this closely so you may have figured this out but for minor decay I think I found it was some stupid matrix transformation in ApplyMouse which should be the identity getting fucked by floating point

Krzyhau commented 9 months ago

I figured out the source of the small decay. The issue appears when the game attempts to convert forward vector into a pitch angle in order to modify it. More specifically, acos is to blame. It produces inaccurate enough number that when put through a bunch of math to create a pitch angle (speficically, 90.0f - acos(value) * 180.0f / M_PI) it creates noticeable error. Interestingly, such issue does not occur when the same mathematical operation is recreated (I assume different math libs or sth?!).

An elegant solution would be to hook into the relevant part of code (C_Paint_Input::ApplyMouse + 0x3E2) and replace acos call with our own (like a naked function with acosf in it or sth). Someone with better hacking skills should do it, because I am unable to get it working lol

Krzyhau commented 9 months ago

Okay, got it working! (3105b920a78289251e416344b574309e76744b43).

In addition, I have a suggestion on how to deal with other view angle drifting issues (including the one @ThisAMJ discovered today). Since the community seems to agree that we should only patch the minor angle decay, and fixing all other view angle drifting issues would only be useful for routing/TASing, I propose that instead of fixing underlying issues, we could either apply what we're doing now without conditions (don't alter view angles when no mouse movement occurs) or write a custom ApplyMouse from scratch. I'm waiting to hear your opinions on that matter.

ThisAMJ commented 6 months ago

Now both minor and major decay have been patched (and there is a bandaid for the nebulous 'small' decay, which shouldn't affect gameplay too much given its relative 'small'-ness)

I also hate that I had to use a Memory::Scan to find MatrixBuildRotationAboutAxis, but I don't think there's a better way.

Discuss the legality of this stuff (and how to improve it) in this thread in the P2SR discord!