diff --git a/pcsx2/Config.h b/pcsx2/Config.h index a767b0ef27..fb3dbe50f9 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -58,6 +58,7 @@ enum GamefixId Fix_GIFReverse, Fix_FMVinSoftware, Fix_GoemonTlbMiss, + Fix_ScarfaceIbit, GamefixId_COUNT }; @@ -350,7 +351,8 @@ struct Pcsx2Config VIF1StallHack :1, // Like above, processes FIFO data before the stall is allowed (to make sure data goes over). GIFReverseHack :1, // Allows PATH3 to continue even if the FIFO is reversed. 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 + 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 BITFIELD_END GamefixOptions(); diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index c70a636cab..6b7c822f5d 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -319,7 +319,7 @@ void Pcsx2Config::GamefixOptions::Set( GamefixId id, bool enabled ) case Fix_GIFReverse: GIFReverseHack = enabled; break; case Fix_FMVinSoftware: FMVinSoftwareHack = enabled; break; case Fix_GoemonTlbMiss: GoemonTlbHack = enabled; break; - + case Fix_ScarfaceIbit: ScarfaceIbit = enabled; break; jNO_DEFAULT; } } @@ -345,7 +345,7 @@ bool Pcsx2Config::GamefixOptions::Get( GamefixId id ) const case Fix_GIFReverse: return GIFReverseHack; case Fix_FMVinSoftware: return FMVinSoftwareHack; case Fix_GoemonTlbMiss: return GoemonTlbHack; - + case Fix_ScarfaceIbit: return ScarfaceIbit; jNO_DEFAULT; } return false; // unreachable, but we still need to suppress warnings >_< @@ -371,6 +371,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini ) IniBitBool( GIFReverseHack ); IniBitBool( FMVinSoftwareHack ); IniBitBool( GoemonTlbHack ); + IniBitBool( ScarfaceIbit ); } diff --git a/pcsx2/gui/Panels/GameFixesPanel.cpp b/pcsx2/gui/Panels/GameFixesPanel.cpp index 5c82b579cf..e64bd5f0d2 100644 --- a/pcsx2/gui/Panels/GameFixesPanel.cpp +++ b/pcsx2/gui/Panels/GameFixesPanel.cpp @@ -103,6 +103,10 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) { _("Preload TLB hack to avoid tlb miss on Goemon"), wxEmptyString + }, + { + _("VU I bit Hack avoid constant recompilation (Scarface The World Is Yours)"), + wxEmptyString } }; diff --git a/pcsx2/x86/microVU.cpp b/pcsx2/x86/microVU.cpp index f9e43bbdf2..1493eee6e6 100644 --- a/pcsx2/x86/microVU.cpp +++ b/pcsx2/x86/microVU.cpp @@ -255,7 +255,16 @@ _mVUt __fi void* mVUsearchProg(u32 startPC, uptr pState) { if(!quick.prog) { // If null, we need to search for new program std::deque::iterator it(list->begin()); for ( ; it != list->end(); ++it) { - if (mVUcmpProg(mVU, *it[0], 0)) { + 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)) { + 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]; list->erase(it); diff --git a/pcsx2/x86/microVU_Compile.inl b/pcsx2/x86/microVU_Compile.inl index cb8318ab69..8acd9d8762 100644 --- a/pcsx2/x86/microVU_Compile.inl +++ b/pcsx2/x86/microVU_Compile.inl @@ -107,16 +107,21 @@ __ri void flushRegs(mV) { if (!doRegAlloc) mVU.regAlloc->flushAll(); } void doIbit(mV) { if (mVUup.iBit) { incPC(-1); - u32 tempI; mVU.regAlloc->clearRegVF(33); - - if (CHECK_VU_OVERFLOW && ((curI & 0x7fffffff) >= 0x7f800000)) { - DevCon.WriteLn(Color_Green,"microVU%d: Clamping I Reg", mVU.index); - tempI = (0x80000000 & curI) | 0x7f7fffff; // Clamp I Reg + if (EmuConfig.Gamefixes.ScarfaceIbit) { + xMOV(gprT1, ptr32[&curI]); + xMOV(ptr32[&mVU.getVI(REG_I)], gprT1); + } + else { + u32 tempI; + if (CHECK_VU_OVERFLOW && ((curI & 0x7fffffff) >= 0x7f800000)) { + DevCon.WriteLn(Color_Green, "microVU%d: Clamping I Reg", mVU.index); + tempI = (0x80000000 & curI) | 0x7f7fffff; // Clamp I Reg + } + else tempI = curI; + + xMOV(ptr32[&mVU.getVI(REG_I)], tempI); } - else tempI = curI; - - xMOV(ptr32[&mVU.getVI(REG_I)], tempI); incPC(1); } }