Skip to content
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

Games that abuse floating-point inaccuracies #245

Open
PSI-Rockin opened this issue Jan 1, 2020 · 6 comments
Open

Games that abuse floating-point inaccuracies #245

PSI-Rockin opened this issue Jan 1, 2020 · 6 comments

Comments

@PSI-Rockin
Copy link
Owner

PSI-Rockin commented Jan 1, 2020

While many games perhaps have missing polygons or minor SPS due to rounding and clamping issues, this list is reserved for games that outright break when floating-point math is inaccurate.

  • Valkyrie Profile 2/other Tri-Ace games: Calculates a decryption key on the VUs that is used to load the main executable. The result is one-bit off on x86 compared to the PS2, but this is enough to prevent the game from booting.
  • Tony Hawk American Wasteland/other Neversoft engine games: Converts a GIFtag to a float then applies mathematical operations on it that, algebraically speaking, should cancel out. However, this causes errors to accumulate. Depending on the rounding mode, this corrupts the GIFtag and causes a crash when reaching the memory card screen.
  • Stuntman: Escort missions involve a car following a predetermined path. Floating point inaccuracies cause the car to be desynced from its path, making the mission (and the game) impossible to complete. See Stuntman - FPU rounding errors for AI pathing PCSX2/pcsx2#2990 for details.
  • Powerdrome: Relies on the additional precision the PS2 has. Does a calculation equivalent to MIN_FLT + 0.5 * (MAX_FLT + MAX_FLT), which on real hardware results in 0. However, x86 truncates MAX_FLT * 2 to MAX_FLT, so the result is MIN_FLT + 0.5 * MAX_FLT, which causes valid vertices to be culled in the game's garbage coordinate sanitization code.

This list is incomplete and needs more examples.

@weirdbeardgame
Copy link
Contributor

weirdbeardgame commented Jan 1, 2020

I'll post the classic games
Katamari Damacy, If the floating points in this game are known to get quite massive having a variety of effects A.
the game will turn into or explode into a mess of massive SPS causing the game world to be unviewable or B. the objects will not be attached to the ball or in the incorrect positions

gran turismo 4 with out proper accuracy cars will randomly be in space

@tadanokojin
Copy link
Contributor

PCSX2/pcsx2#2990

is worth a mention I think

@weirdbeardgame
Copy link
Contributor

Klonoa 2 without proper rounding the Green sphere elevators will be in the wrong positions and the wrong size

@PSI-Rockin
Copy link
Owner Author

PSI-Rockin commented Feb 15, 2020

To clarify on the Powerdrome problem. Note that MAX_FLT and MIN_FLT respectively are from x86's perspective - the PS2 can support floats up to MAX_FLT * 2 and MIN_FLT * 2.

The VU1 pseudocode is something like this:

upper_bound = MAX_FLT
lower_bound = MIN_FLT
loop:
    ... process vertex ...
    upper_bound = max(upper_bound, vertex)
    lower_bound = min(lower_bound, vertex)
    goto loop if not all vertices are processed
diff = 0.5 * (upper_bound - lower_bound) + lower_bound

diff gets used in vertex culling code. Because on all emulators, it ends up equaling 0.5 * MIN_FLT, the culling code is triggered and the vertices are discarded unnecessarily.

This is impossible to emulate correctly without using softfloats, which will unnecessarily slow down emulation. The best course of action is to patch the code at the following addresses:

[$3820] 8020005e:7f7fffff muli.w vf1, vf0, I            loi 0x7f7fffff
[$3828] 81c000a2:ff7fffff addi.xyz vf2, vf0, I          loi 0xff7fffff

The LOIs may be changed to MAX_FLT / 2 and MIN_FLT / 2 respectively to work on emulators. The micro's CRC is 0x7FEF354E.

@refractionpcsx2
Copy link
Contributor

refractionpcsx2 commented Feb 15, 2020

Powerdrome VU data is stored in the following EE memory addresses on the PAL release at least
0x0037A688 = ff7fffff
0x0037A680 = 7f7fffff

@ps1freak26
Copy link

Destruction Derby Arenas has corrupt textures from floating point inaccuracies.

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

No branches or pull requests

5 participants