From 56a976e277a4a05622bd6396d8ee9049b62049cd Mon Sep 17 00:00:00 2001 From: hibye8313 Date: Tue, 30 Apr 2019 16:19:46 -0400 Subject: [PATCH] microVU: Add gamefix for Crash Tag Team Racing. Fixes constant recompilation problems. --- pcsx2/Config.h | 40 +++++++++++++++-------------- pcsx2/Pcsx2Config.cpp | 6 ++++- pcsx2/gui/Panels/GameFixesPanel.cpp | 4 +++ pcsx2/x86/microVU.cpp | 15 +++++++++-- pcsx2/x86/microVU_Compile.inl | 2 +- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index db0dc695e3..4c5302140f 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -59,6 +59,7 @@ enum GamefixId Fix_FMVinSoftware, Fix_GoemonTlbMiss, Fix_ScarfaceIbit, + Fix_CrashTagTeamIbit, GamefixId_COUNT }; @@ -343,25 +344,26 @@ struct Pcsx2Config // NOTE: The GUI's GameFixes panel is dependent on the order of bits in this structure. struct GamefixOptions { - BITFIELD32() - bool - VuAddSubHack :1, // Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate. - VuClipFlagHack :1, // Persona games, maybe others. It's to do with the VU clip flag (again). - FpuCompareHack :1, // Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. - FpuMulHack :1, // Tales of Destiny hangs. - FpuNegDivHack :1, // Gundam games messed up camera-view. - XgKickHack :1, // Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others. - IPUWaitHack :1, // FFX FMV, makes GIF flush before doing IPU work. Fixes bad graphics overlay. - EETimingHack :1, // General purpose timing hack. - SkipMPEGHack :1, // Skips MPEG videos (Katamari and other games need this) - OPHFlagHack :1, // Bleach Blade Battlers - DMABusyHack :1, // Denies writes to the DMAC when it's busy. This is correct behaviour but bad timing can cause problems. - VIFFIFOHack :1, // Pretends to fill the non-existant VIF FIFO Buffer. - VIF1StallHack :1, // Like above, processes FIFO data before the stall is allowed (to make sure data goes over). - GIFFIFOHack :1, // Enabled the GIF FIFO (more correct but slower) - FMVinSoftwareHack:1, // Toggle in and out of software rendering when an FMV runs. - 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 - ScarfaceIbit :1; // Scarface I bit hack. Needed to stop constant VU recompilation + BITFIELD32() + bool + VuAddSubHack : 1, // Tri-ace games, they use an encryption algorithm that requires VU ADDI opcode to be bit-accurate. + VuClipFlagHack : 1, // Persona games, maybe others. It's to do with the VU clip flag (again). + FpuCompareHack : 1, // Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. + FpuMulHack : 1, // Tales of Destiny hangs. + FpuNegDivHack : 1, // Gundam games messed up camera-view. + XgKickHack : 1, // Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics, but breaks Tri-ace games and others. + IPUWaitHack : 1, // FFX FMV, makes GIF flush before doing IPU work. Fixes bad graphics overlay. + EETimingHack : 1, // General purpose timing hack. + SkipMPEGHack : 1, // Skips MPEG videos (Katamari and other games need this) + OPHFlagHack : 1, // Bleach Blade Battlers + DMABusyHack : 1, // Denies writes to the DMAC when it's busy. This is correct behaviour but bad timing can cause problems. + VIFFIFOHack : 1, // Pretends to fill the non-existant VIF FIFO Buffer. + VIF1StallHack : 1, // Like above, processes FIFO data before the stall is allowed (to make sure data goes over). + GIFFIFOHack : 1, // Enabled the GIF FIFO (more correct but slower) + FMVinSoftwareHack : 1, // Toggle in and out of software rendering when an FMV runs. + 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 + ScarfaceIbit : 1, // Scarface I bit hack. Needed to stop constant VU recompilation + CrashTagTeamRacingIbit : 1; // Crash Tag Team Racing I bit hack. Needed to stop constant VU recompilation BITFIELD_END GamefixOptions(); diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 7ab97ba617..8138720158 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -267,7 +267,8 @@ const wxChar *const tbl_GamefixNames[] = L"GIFFIFO", L"FMVinSoftware", L"GoemonTlb", - L"ScarfaceIbit" + L"ScarfaceIbit", + L"CrashTagTeamRacingIbit" }; const __fi wxChar* EnumToString( GamefixId id ) @@ -331,6 +332,7 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled ) case Fix_FMVinSoftware: FMVinSoftwareHack = enabled; break; case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break; case Fix_ScarfaceIbit: ScarfaceIbit = enabled; break; + case Fix_CrashTagTeamIbit: CrashTagTeamRacingIbit = enabled; break; jNO_DEFAULT; } } @@ -357,6 +359,7 @@ bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const case Fix_FMVinSoftware: return FMVinSoftwareHack; case Fix_GoemonTlbMiss: return GoemonTlbHack; case Fix_ScarfaceIbit: return ScarfaceIbit; + case Fix_CrashTagTeamIbit: return CrashTagTeamRacingIbit; jNO_DEFAULT; } return false; // unreachable, but we still need to suppress warnings >_< @@ -383,6 +386,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini ) IniBitBool( FMVinSoftwareHack ); IniBitBool( GoemonTlbHack ); IniBitBool( ScarfaceIbit ); + IniBitBool( CrashTagTeamRacingIbit ); } diff --git a/pcsx2/gui/Panels/GameFixesPanel.cpp b/pcsx2/gui/Panels/GameFixesPanel.cpp index 33da312ab8..fc8b0d3410 100644 --- a/pcsx2/gui/Panels/GameFixesPanel.cpp +++ b/pcsx2/gui/Panels/GameFixesPanel.cpp @@ -107,6 +107,10 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) { _("VU I bit Hack avoid constant recompilation (Scarface The World Is Yours)"), wxEmptyString + }, + { + _("VU I bit Hack avoid constant recompilation (Crash Tag Team Racing)"), + wxEmptyString } }; diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index 36535f171c..1bec37a9d8 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -264,13 +264,24 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) { for ( ; it != list->end(); ++it) { bool b = mVUcmpProg(mVU, *it[0], 0); if (EmuConfig.Gamefixes.ScarfaceIbit) { - if (isVU1 && ((((u32*)mVU.regs().Micro)[startPC / 4 + 1]) == 0x80200118) && ((((u32*)mVU.regs().Micro)[startPC / 4 + 3]) == 0x81000062)) { + if (isVU1 && ((((u32*)mVU.regs().Micro)[startPC / 4 + 1]) == 0x80200118) && + ((((u32*)mVU.regs().Micro)[startPC / 4 + 3]) == 0x81000062)) { b = true; mVU.prog.cleared = 0; mVU.prog.cur = it[0]; mVU.prog.isSame = 1; } - } + } else if (EmuConfig.Gamefixes.CrashTagTeamRacingIbit) { + // Crash tag team tends to make changes to the I register settings in the addresses 0x2bd0 - 0x3ff8 + // so detect when the code is only changed in this region and don't recompile. Use the same Scarface hack + // to access the new I regsiter settings (Look at doIbit() in microVU_Compile.inl + if (isVU1 && (memcmp_mmx((u8 *)(it[0]->data), (u8 *)(mVU.regs().Micro), 0x2bd0) == 0)) { + b = true; + mVU.prog.cleared = 0; + mVU.prog.cur = it[0]; + mVU.prog.isSame = 1; + } + } if (b) { quick.block = it[0]->block[startPC/8]; quick.prog = it[0]; diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index 6b4da0b317..196051e9e3 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -108,7 +108,7 @@ void doIbit(mV) { if (mVUup.iBit) { incPC(-1); mVU.regAlloc->clearRegVF(33); - if (EmuConfig.Gamefixes.ScarfaceIbit) { + if (EmuConfig.Gamefixes.ScarfaceIbit || EmuConfig.Gamefixes.CrashTagTeamRacingIbit) { xMOV(gprT1, ptr32[&curI]); xMOV(ptr32[&mVU.getVI(REG_I)], gprT1); }