Duplicate: Phantasy Star Universe (NTSC-U) - Chapter 7 Boss stuckness
#11
(02-25-2015, 07:37 PM)karasuhebi Wrote: So what happens when a game comes along that requires a certain clamping or round mode to fix an error in a scene and then a certain OTHER clamping or round mode to fix another scene? How is an automatic game fix going to handle that?

Are you saying that there will never be a point where PCSX2 is 100% accurate without looking for these problematic formulas in the game code and making fixes for them by using x86 implementations?

Quote from cotton's explanation:

cottonvibes Wrote:Basically there's something called the "The IEEE Standard for Floating-Point Arithmetic" (or IEEE 754), which defines floating point representation; and most systems abide by those rules (of course not our wonderful PS2).

There's 32-bit "Single Precision Floats" (commonly referred to as 'float'), 64-bit "Double Precision Floats" (commonly referred to as 'double'), and there's even 128-bit floats called Quads (most processors don't support these natively).

The one we're concerned about is the Single Precision Float, which is 32bits and has a format like this

S x 1bit | E x 8bits | M x 23bits

S = Sign Bit (0 = Positive Number; 1 = Negative Number)
E = Exponent (Biased according to some formula)
M = Mantissa (Normalized with a hidden bit)
I'm not going to go into detail on how this stuff works, but wikipedia is quite helpful

Anyways what we need to know is that the IEEE 754 standard defines values with the Exponent bits "11111111", as "NaN" values (short for "Not a Number").

To be more precise, there's also INF (infinity) values, qNaN (quiet NaN), and sNaN (signaling NaN).
Basically NaNs are given when the result of an operation is undefined.

Like if you divide 1 / 0, you get a NaN result, because you can't divide a number by 0.
Or if you take the Square-Root of a negative number, you get a NaN value.

INF values are basically what it sounds like, its an attempt to represent infinity.

The tricky part is that now that you have a NaN or INF value, if you ever try and do a calculation with them, you'll get a NaN or INF value as the result.

Example:
NaN + 500 = NaN (generally the same NaN, since it propagates)
INF - 19999999999 = INF

This is how the IEEE 754 standard defined this stuff (I honestly don't like it, but w/e)

The ps2 however doesn't support NaN's and Infinities!
So basically, the numbers in the range of INF/NaN on a IEEE 754 pc, are just very-large numbers (or very small numbers if negative (if the sign bit is 1)).

For comparison of what your x86-32 CPU does VS the ps2 we have:

Your PC:
1/0 = NaN
sqrt (-4) = NaN
INF - 1000 = INF

The PS2:
1/0 = Greatest Positive Float Number (0x7ffffffff)
sqrt (-4) = sqrt(abs(-4)) = 2
INF - 1000 = Some Large Value - 100

And there's many more combinations, but the point is that the results are not the same between PC and the PS2.


So how do we solve these problems?
Well there's no 'fast' way to emulate the ps2 behavior 100% correct (this would require a software FPU, which will be very-slow).

What we do instead is use a combination of clamping, simulation, and cleverness.

The way clamping works is if a value is INF or NaN, we 'clamp' it into the closest value that's not a INF or NaN.
Basically we force values into 'normal numbers' so that it doesn't mess up operations as much.

This isn't 100% exact, but its generally 'good enough' to fix many problems with games.
Let me give you a quick example of something clamping can solve:
Code:
int main() {
float value = INF;
do {
value = value / 2;
if (value <= 1) { print("Hello World"); break; }
} while (true);
}


If the above code was ran on the ps2, it will eventually print "Hello World", because INF is treated as a regular large number, and will continue to be divided by 2 until its less than 1.

But if done on your x86-32 PC, it will never print "Hello World" but continue to loop forever, because Infinity divided by 2 is still Infinity!
Ever seen games that just hang in pcsx2? Sometimes its caused by situations like above.

Clamping can solve this problem like this:
Code:
int main() {
float value = INF;
do {
value = clamp(value); // If value is NaN/INF, make value into a big normal number
value = value / 2;
if (value <= 1) { print("Hello World"); break; }
} while (true);
}


The clamping will convert the INF into a normal (ordered) number. Then that normal number can be divided by 2 repetitively until its less than 1. Then it will eventually satisfy (value less or equal 1), and print "Hello World".


Sometimes clamping breaks games (because of a lot of reasons that will take too long to explain), but the basic problem is:
The ps2's floats have a larger range of valid-values than your PC's floats. Therefore we have to make values 'as close as possible' on the PC to try and make games happy.

Because its impossible to know if clamping will break or help a game in some situations, we have different clamp modes in pcsx2's advanced options.
Also clamping is SLOW if done a lot, so different clamp modes are faster than others ('None' is the fastest of course Razz)


I also should mention that in earlier examples i said:
sqrt(-4) = NaN; // on your PC
sqrt(-4) = 2; // on the ps2

In this case, we simulate the ps2's sqrt instruction by doing this
Code:
float ps2_sqrt(float value) {
value = clamp(value); // Clamp Value if NaN or Inf to an ordered/normal number
value = abs(value); // Make Positive
value = sqrt(value); // Get sqrt of now-positive value
return value;
}


so:
ps2_sqrt(-4) = 2;

Note the part I bolded:

"Well there's no 'fast' way to emulate the ps2 behavior 100% correct (this would require a software FPU, which will be very-slow)."

Maybe one day machines will be fast enough for that software FPU, until then, this is about as good as it gets I think.
[Image: XTe1j6J.png]
Gaming Rig: Intel i7 6700k @ 4.8Ghz | GTX 1070 TI | 32GB RAM | 960GB(480GB+480GB RAID0) SSD | 2x 1TB HDD

Sponsored links

#12
I've read that before, no need for the gigantic quote lol. Next time just quote the important line, eh? ;P
[Image: pNm13X9.gif]
Windows 10 Pro x64 Version 1909 | AMD Ryzen 5 5600X | GIGABYTE AORUS GeForce GTX 1080 Ti | Crucial 16GB (2x8GB) DDR4 3600 RAM | Samsung 850 EVO 500 GB SSD | WD Red Plus 8TB

CPU Intensive Games
GPU Intensive Games
Games that don't need a strong CPU
#13
You have read it, but probably not everyone reading the thread has.
[Image: XTe1j6J.png]
Gaming Rig: Intel i7 6700k @ 4.8Ghz | GTX 1070 TI | 32GB RAM | 960GB(480GB+480GB RAID0) SSD | 2x 1TB HDD
#14
Good point. Oops! :-|
[Image: pNm13X9.gif]
Windows 10 Pro x64 Version 1909 | AMD Ryzen 5 5600X | GIGABYTE AORUS GeForce GTX 1080 Ti | Crucial 16GB (2x8GB) DDR4 3600 RAM | Samsung 850 EVO 500 GB SSD | WD Red Plus 8TB

CPU Intensive Games
GPU Intensive Games
Games that don't need a strong CPU
#15
So far it seems that there's no conflicts with Round Mode Positive.

[Edit]
I do seem to be suffering from Save Data corruption though... whether that's related or not, I can't be too sure. But I never had this issue before.

I might just make a Memory Card from scratch again, because I'm getting lots of these corruption errors lately in PCSX2. First it started with Shining Force EXA, and now with PSU? Either it's a coincidence or there's something wrong with the file. Although it's only happening with these particular two games..



[Edit 2]
I've played from Chapter 1 up to Chapter 7 with no issues. One thing I did notice though is that the boss again wasn't moving. But this time he was visible. It seems you either need 'Nearest' or 'Positive' depending on what's going on. But at least you can pass the boss battle without a hassle regardless.
AMD Ryzen 5 3600 @ 3.60~4.20 GHz | Corsair Vengeance LPX 32 GB (2x16GB) DDR4-3200
MSI GeForce GTX 1660 Super @ 6 GB | Samsung 980 1TB | Windows 10 Pro x64 (22H2)
#16
Hm in the second case where the boss is visible but not moving, does that affect the game experience? Is the boss easier/harder? Can you fix it by changing round mode on the fly?
[Image: newsig.jpg]
#17
Boss is way easier, because you can attack it but it doesn't attack back. And changing it on the fly won't work. You have to load up via a Memory Card Save to apply the change.

The only difference from the original issue is that the boss is visible now. (Normally he always starts invisible and -then- turns visible when he starts attacking).
AMD Ryzen 5 3600 @ 3.60~4.20 GHz | Corsair Vengeance LPX 32 GB (2x16GB) DDR4-3200
MSI GeForce GTX 1660 Super @ 6 GB | Samsung 980 1TB | Windows 10 Pro x64 (22H2)
#18
Hm then it's an issue that doesn't have a workaround at all right? (I mean to have it all play out as it should, not just to be able to progress the game)
[Image: newsig.jpg]
#19
Well the workaround is either EE Round: Positive, or EE Round: Nearest.

If one doesn't work, you'll have to use the other. I got it to work fine before with EE Round: Positive. Boss was attacking as it should. But now this time around it only made him visible..

But for the majority of the game EE Round: Positive seems to be good. I haven't run into any other issues. And at least you can pass that dreaded point of Chapter 7.
Every other enemy so far has been moving correctly. (Currently in Chapter 9)



I guess because of this though - I wouldn't recommend it to be implemented as an Automatic Gamefix. Because it's not 100% certain that it will fix it entirely for the boss fight.
AMD Ryzen 5 3600 @ 3.60~4.20 GHz | Corsair Vengeance LPX 32 GB (2x16GB) DDR4-3200
MSI GeForce GTX 1660 Super @ 6 GB | Samsung 980 1TB | Windows 10 Pro x64 (22H2)
#20
Oh so sometimes it fixes BOTH invisibility and movement and sometimes only invisibility. It's still a fix in either case, so if I got it correctly it should still be implemented?
[Image: newsig.jpg]




Users browsing this thread: 1 Guest(s)