New generic Skip MPEG gamefix that lets you skip videos in games to avoid hanging.

This will replace the many sceMpegIsEnd patches we currently have.
Thanks to pseudonym for coding the recompiler version of this gamefix.

Essentially what it does is, the EE recompiler finds the pattern of code used to check if an MPEG is finished, and then recompiles code to say that it is finished.
This will work for most Videos/FMV's in games, but its possible that some games don't use the same library functions for videos so the correct pattern won't be detected; and therefore the videos will not be skipped.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3121 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
cottonvibes 2010-05-30 01:52:43 +00:00
parent fcd9464a1f
commit b678e65b6e
5 changed files with 49 additions and 12 deletions

View File

@ -432,7 +432,8 @@ struct Pcsx2Config
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.
EETimingHack :1, // General purpose timing hack.
SkipMPEGHack :1; // Skips MPEG videos (Katamari and other games need this)
BITFIELD_END
// all gamefixes are disabled by default.
@ -561,16 +562,17 @@ TraceLogFilters& SetTraceConfig();
#define CHECK_IOPREC (EmuConfig.Cpu.Recompiler.EnableIOP && GetSysCoreAlloc().IsRecAvailable_IOP())
//------------ SPECIAL GAME FIXES!!! ---------------
#define NUM_OF_GAME_FIXES 8
#define NUM_OF_GAME_FIXES 9
#define CHECK_VUADDSUBHACK (EmuConfig.Gamefixes.VuAddSubHack) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_VUADDSUBHACK (EmuConfig.Gamefixes.VuAddSubHack) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_FPUCOMPAREHACK (EmuConfig.Gamefixes.FpuCompareHack) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
#define CHECK_VUCLIPFLAGHACK (EmuConfig.Gamefixes.VuClipFlagHack) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
#define CHECK_FPUMULHACK (EmuConfig.Gamefixes.FpuMulHack) // Special Fix for Tales of Destiny hangs.
#define CHECK_FPUNEGDIVHACK (EmuConfig.Gamefixes.FpuNegDivHack) // Special Fix for Gundam games messed up camera-view.
#define CHECK_XGKICKHACK (EmuConfig.Gamefixes.XgKickHack) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics.
#define CHECK_IPUWAITHACK (EmuConfig.Gamefixes.IPUWaitHack) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics.
#define CHECK_EETIMINGHACK (EmuConfig.Gamefixes.EETimingHack) // Fix all scheduled events to happen in 1 cycle.
#define CHECK_FPUMULHACK (EmuConfig.Gamefixes.FpuMulHack) // Special Fix for Tales of Destiny hangs.
#define CHECK_FPUNEGDIVHACK (EmuConfig.Gamefixes.FpuNegDivHack) // Special Fix for Gundam games messed up camera-view.
#define CHECK_XGKICKHACK (EmuConfig.Gamefixes.XgKickHack) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics.
#define CHECK_IPUWAITHACK (EmuConfig.Gamefixes.IPUWaitHack) // Special Fix For FFX
#define CHECK_EETIMINGHACK (EmuConfig.Gamefixes.EETimingHack) // Fix all scheduled events to happen in 1 cycle.
#define CHECK_SKIPMPEGHACK (EmuConfig.Gamefixes.SkipMPEGHack) // Finds sceMpegIsEnd pattern to tell the game the mpeg is finished (Katamari and a lot of games need this)
//------------ Advanced Options!!! ---------------
#define CHECK_VU_OVERFLOW (EmuConfig.Cpu.Recompiler.vuOverflow)

View File

@ -420,6 +420,7 @@ static int loadGameSettings(DataBase_Loader* gameDB) {
checkGamefix(XgKickHack);
checkGamefix(IPUWaitHack);
checkGamefix(EETimingHack);
checkGamefix(SkipMPEGHack);
return gf;
}
return 0;

View File

@ -259,6 +259,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini )
IniBitBool( XgKickHack );
IniBitBool( IPUWaitHack );
IniBitBool( EETimingHack );
IniBitBool( SkipMPEGHack );
}
Pcsx2Config::Pcsx2Config()

View File

@ -72,6 +72,10 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) :
L" * SSX (Fixes bad graphics and crashes)\n"
L" * Resident Evil: Dead Aim (Causes garbled textures)"
)
},
{
_("Skip MPEG hack - Skips videos/FMV's in games to avoid game hanging/freezes."),
wxEmptyString
}
};

View File

@ -1289,6 +1289,30 @@ void __fastcall dyna_page_reset(u32 start,u32 sz)
#endif
}
// Skip MPEG Game-Fix
bool skipMPEG_By_Pattern(u32 sPC) {
if (!CHECK_SKIPMPEGHACK) return 0;
// sceMpegIsEnd: lw reg, 0x40(a0); jr ra; lw v0, 0(reg)
if ((s_nEndBlock == sPC + 12) && (vtlb_memRead32(sPC + 4) == 0x03e00008)) {
u32 code = vtlb_memRead32(sPC);
u32 p1 = 0x8c800040;
u32 p2 = 0x8c020000 | (code & 0x1f0000) << 5;
if ((code & 0xffe0ffff) != p1) return 0;
if (vtlb_memRead32(sPC+8) != p2) return 0;
xMOV(ptr32[&cpuRegs.GPR.n.v0.UL[0]], 1);
xMOV(ptr32[&cpuRegs.GPR.n.v0.UL[1]], 0);
xMOV(eax, ptr32[&cpuRegs.GPR.n.ra.UL[0]]);
xMOV(ptr32[&cpuRegs.pc], eax);
iBranchTest();
branch = 1;
pc = s_nEndBlock;
return 1;
}
return 0;
}
static void __fastcall recRecompile( const u32 startpc )
{
u32 i = 0;
@ -1690,10 +1714,15 @@ StartRecomp:
break;
}
// Finally: Generate x86 recompiled code!
g_pCurInstInfo = s_pInstCache;
while (!branch && pc < s_nEndBlock) {
recompileNextInstruction(0); // For the love of recursion, batman!
// Skip Recompilation if sceMpegIsEnd Pattern detected
bool doRecompilation = !skipMPEG_By_Pattern(startpc);
if (doRecompilation) {
// Finally: Generate x86 recompiled code!
g_pCurInstInfo = s_pInstCache;
while (!branch && pc < s_nEndBlock) {
recompileNextInstruction(0); // For the love of recursion, batman!
}
}
#ifdef PCSX2_DEBUG