VU/GameDB: Move Mac/Status overflow flag checks to a gamefix

We can't really do this reliably on x86 without soft floats, but superman still needs it, but it breaks other games.
This commit is contained in:
refractionpcsx2 2021-09-29 10:50:49 +01:00
parent d53171e20f
commit 7faa5db9e5
6 changed files with 44 additions and 13 deletions

View File

@ -34,7 +34,7 @@ allowed_game_fixes = [
"GoemonTlbHack",
"VUKickstartHack",
"IbitHack",
"RatchetDynaHack",
"VUOverflowHack",
]
allowed_speed_hacks = ["mvuFlagSpeedHack", "InstantVU1SpeedHack"]
# Patches are allowed to have a 'default' key or a crc-32 key, followed by

View File

@ -14344,6 +14344,8 @@ SLES-53744:
SLES-53746:
name: "Superman Returns"
region: "PAL-E"
gameFixes:
- VUOverflowHack # Fixes SPS.
SLES-53747:
name: "Ed, Edd, 'n Eddy - The Misadventure"
region: "PAL-E"
@ -15535,15 +15537,23 @@ SLES-54347:
SLES-54348:
name: "Superman Returns"
region: "PAL-F"
gameFixes:
- VUOverflowHack # Fixes SPS.
SLES-54349:
name: "Superman Returns"
region: "PAL-I"
gameFixes:
- VUOverflowHack # Fixes SPS.
SLES-54350:
name: "Superman Returns"
region: "PAL-G"
gameFixes:
- VUOverflowHack # Fixes SPS.
SLES-54351:
name: "Superman Returns"
region: "PAL-S"
gameFixes:
- VUOverflowHack # Fixes SPS.
SLES-54354:
name: "Final Fantasy XII"
region: "PAL-E"
@ -38365,6 +38375,8 @@ SLUS-21434:
name: "Superman Returns - The Video Game"
region: "NTSC-U"
compat: 4
gameFixes:
- VUOverflowHack # Fixes SPS.
SLUS-21435:
name: "One Piece - Grand Adventure"
region: "NTSC-U"

View File

@ -39,6 +39,7 @@ enum GamefixId
Fix_GoemonTlbMiss,
Fix_Ibit,
Fix_VUKickstart,
Fix_VUOverflow,
GamefixId_COUNT
};
@ -345,7 +346,8 @@ struct Pcsx2Config
GIFFIFOHack : 1, // Enabled the GIF FIFO (more correct but slower)
GoemonTlbHack : 1, // Gomeon tlb miss hack. The game need to access unmapped virtual address. Instead to handle it as exception, tlb are preloaded at startup
IbitHack : 1, // I bit hack. Needed to stop constant VU recompilation in some games
VUKickstartHack : 1; // Gives new VU programs a slight head start and runs VU's ahead of EE to avoid VU register reading/writing issues
VUKickstartHack : 1, // Gives new VU programs a slight head start and runs VU's ahead of EE to avoid VU register reading/writing issues
VUOverflowHack : 1; // Tries to simulate overflow flag checks (not really possible on x86 without soft floats)
BITFIELD_END
GamefixOptions();
@ -532,6 +534,7 @@ TraceLogFilters& SetTraceConfig();
#define CHECK_VIFFIFOHACK (EmuConfig.Gamefixes.VIFFIFOHack) // Pretends to fill the non-existant VIF FIFO Buffer.
#define CHECK_VIF1STALLHACK (EmuConfig.Gamefixes.VIF1StallHack) // Like above, processes FIFO data before the stall is allowed (to make sure data goes over).
#define CHECK_GIFFIFOHACK (EmuConfig.Gamefixes.GIFFIFOHack) // Enabled the GIF FIFO (more correct but slower)
#define CHECK_VUOVERFLOWHACK (EmuConfig.Gamefixes.VUOverflowHack) // Special Fix for Superman Returns, they check for overflows on PS2 floats which we can't do without soft floats.
//------------ Advanced Options!!! ---------------
#define CHECK_VU_OVERFLOW (EmuConfig.Cpu.Recompiler.vuOverflow)

View File

@ -269,7 +269,8 @@ const wxChar *const tbl_GamefixNames[] =
L"GIFFIFO",
L"GoemonTlb",
L"Ibit",
L"VUKickstart"
L"VUKickstart",
L"VUOverflow"
};
const __fi wxChar* EnumToString( GamefixId id )
@ -329,7 +330,8 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled )
case Fix_GIFFIFO: GIFFIFOHack = enabled; break;
case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break;
case Fix_Ibit: IbitHack = enabled; break;
case Fix_VUKickstart: VUKickstartHack = enabled; break;
case Fix_VUKickstart: VUKickstartHack = enabled; break;
case Fix_VUOverflow: VUOverflowHack = enabled; break;
jNO_DEFAULT;
}
}
@ -353,6 +355,7 @@ bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const
case Fix_GoemonTlbMiss: return GoemonTlbHack;
case Fix_Ibit: return IbitHack;
case Fix_VUKickstart: return VUKickstartHack;
case Fix_VUOverflow: return VUOverflowHack;
jNO_DEFAULT;
}
return false; // unreachable, but we still need to suppress warnings >_<
@ -376,6 +379,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
IniBitBool( GoemonTlbHack );
IniBitBool( IbitHack );
IniBitBool( VUKickstartHack );
IniBitBool( VUOverflowHack );
}

View File

@ -96,6 +96,10 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent )
{
_("VU Kickstart (Run ahead) to avoid sync problems when reading or writing VU registers"),
wxEmptyString
},
{
_("VU Overflow hack to check for possible float overflows (Superman Returns)"),
wxEmptyString
}
};

View File

@ -78,17 +78,18 @@ static void mVUupdateFlags(mV, const xmm& reg, const xmm& regT1in = xEmptyReg, c
xMOVMSKPS(gprT2, regT1); // Used for Zero Flag Calculation
xAND(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
xSHL(mReg, 4 + ADD_XYZW);
xSHL(mReg, 4);
//-------------------------Check for Zero flags------------------------------
xAND(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
if (mFLAG.doFlag)
SHIFT_XYZW(gprT2);
xOR(mReg, gprT2);
//-------------------------Overflow Flags-----------------------------------
if (sFLAG.doFlag)
// We can't really do this because of the limited range of x86 and the value MIGHT genuinely be FLT_MAX (x86)
// so this will need to remain as a gamefix for the one game that needs it (Superman Returns)
// until some sort of soft float implementation.
if (sFLAG.doFlag && CHECK_VUOVERFLOWHACK)
{
//Calculate overflow
xMOVAPS(regT1, regT2);
@ -97,16 +98,23 @@ static void mVUupdateFlags(mV, const xmm& reg, const xmm& regT1in = xEmptyReg, c
xMOVMSKPS(gprT2, regT1); // Grab sign bits for equal results
xAND(gprT2, AND_XYZW); // Grab "Is FLT_MAX" bits from the previous calculation
xForwardJump32 oJMP(Jcc_Zero);
xOR(sReg, 0x820000);
xOR(sReg, 0x820000);
if (mFLAG.doFlag)
{
xSHL(gprT2, 12); // Add the results to the MAC Flag
xOR(mReg, gprT2);
}
oJMP.SetTarget();
xSHL(gprT2, 12 + ADD_XYZW); // Add the results to the MAC Flag
xOR(mReg, gprT2);
}
//-------------------------Write back flags------------------------------
//-------------------------Write back flags------------------------------
if (mFLAG.doFlag)
{
SHIFT_XYZW(mReg); // If it was Single Scalar, move the flags in to the correct position
mVUallocMFLAGb(mVU, mReg, mFLAG.write); // Set Mac Flag
}
if (sFLAG.doFlag)
{
xAND(mReg, 0xFF); // Ignore overflow bits, they're handled separately