[Soft-Float] - Implements accurate VU clip.

Improves performance of clip, while being accurate.

Test Ratchet Gladiator to verify this commit (game needs this alongside accurate Mul support on the COP2 to fix some physics behaviours).
This commit is contained in:
GitHubProUser67 2025-01-28 22:14:48 +01:00
parent 7efe187b2d
commit 459c574d24
3 changed files with 50 additions and 7 deletions

View File

@ -540,6 +540,40 @@ s32 PS2Float::Ftoi(s32 complement, u32 f1)
return (s32)result;
}
u8 PS2Float::Clip(u32 f1, u32 f2, bool& cplus, bool& cminus)
{
bool resultPlus = false;
bool resultMinus = false;
u32 a;
if ((f1 & 0x7F800000) == 0)
{
f1 &= 0xFF800000;
}
a = f1;
if ((f2 & 0x7F800000) == 0)
{
f2 &= 0xFF800000;
}
f1 = f1 & MAX_FLOATING_POINT_VALUE;
f2 = f2 & MAX_FLOATING_POINT_VALUE;
if ((-1 < (int)a) && (f2 < f1))
resultPlus = true;
cplus = resultPlus;
if (((int)a < 0) && (f2 < f1))
resultMinus = true;
cminus = resultMinus;
return 0;
}
bool PS2Float::DetermineMultiplicationDivisionOperationSign(PS2Float a, PS2Float b)
{
return a.Sign() ^ b.Sign();

View File

@ -72,6 +72,8 @@ public:
static s32 Ftoi(s32 complement, u32 f1);
static u8 Clip(u32 f1, u32 f2, bool& cplus, bool& cminus);
PS2Float Add(PS2Float addend);
PS2Float Sub(PS2Float subtrahend);

View File

@ -1805,15 +1805,22 @@ static __fi void _vuCLIP(VURegs* VU)
{
if (CHECK_VU_SOFT_ADDSUB((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_MULDIV((VU == &VU1) ? 1 : 0) || CHECK_VU_SOFT_SQRT((VU == &VU1) ? 1 : 0))
{
double value = PS2Float(PS2Float(VU->VF[_Ft_].i.w).Abs()).ToDouble();
bool cplus = false;
bool cminus = false;
u32 value = PS2Float(VU->VF[_Ft_].i.w).Abs();
VU->clipflag <<= 6;
if (PS2Float(VU->VF[_Fs_].i.x).ToDouble() > +value) VU->clipflag |= 0x01;
if (PS2Float(VU->VF[_Fs_].i.x).ToDouble() < -value) VU->clipflag |= 0x02;
if (PS2Float(VU->VF[_Fs_].i.y).ToDouble() > +value) VU->clipflag |= 0x04;
if (PS2Float(VU->VF[_Fs_].i.y).ToDouble() < -value) VU->clipflag |= 0x08;
if (PS2Float(VU->VF[_Fs_].i.z).ToDouble() > +value) VU->clipflag |= 0x10;
if (PS2Float(VU->VF[_Fs_].i.z).ToDouble() < -value) VU->clipflag |= 0x20;
PS2Float::Clip(VU->VF[_Fs_].i.x, value, cplus, cminus);
if (cplus) VU->clipflag |= 0x01;
if (cminus) VU->clipflag |= 0x02;
PS2Float::Clip(VU->VF[_Fs_].i.y, value, cplus, cminus);
if (cplus) VU->clipflag |= 0x04;
if (cminus) VU->clipflag |= 0x08;
PS2Float::Clip(VU->VF[_Fs_].i.z, value, cplus, cminus);
if (cplus) VU->clipflag |= 0x10;
if (cminus) VU->clipflag |= 0x20;
}
else
{