From b678e65b6e5ddc39a2b361a8d69a2952d0ddc017 Mon Sep 17 00:00:00 2001 From: cottonvibes Date: Sun, 30 May 2010 01:52:43 +0000 Subject: [PATCH] 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 --- pcsx2/Config.h | 18 +++++++------- pcsx2/DataBase_Loader.h | 1 + pcsx2/Pcsx2Config.cpp | 1 + pcsx2/gui/Panels/GameFixesPanel.cpp | 4 ++++ pcsx2/x86/ix86-32/iR5900-32.cpp | 37 +++++++++++++++++++++++++---- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 9e995bacda..99ebfbb659 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -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) diff --git a/pcsx2/DataBase_Loader.h b/pcsx2/DataBase_Loader.h index e86c2e60ca..15d0f0d4f3 100644 --- a/pcsx2/DataBase_Loader.h +++ b/pcsx2/DataBase_Loader.h @@ -420,6 +420,7 @@ static int loadGameSettings(DataBase_Loader* gameDB) { checkGamefix(XgKickHack); checkGamefix(IPUWaitHack); checkGamefix(EETimingHack); + checkGamefix(SkipMPEGHack); return gf; } return 0; diff --git a/pcsx2/Pcsx2Config.cpp b/pcsx2/Pcsx2Config.cpp index 5559c4f970..79ce512e5b 100644 --- a/pcsx2/Pcsx2Config.cpp +++ b/pcsx2/Pcsx2Config.cpp @@ -259,6 +259,7 @@ void Pcsx2Config::GamefixOptions::LoadSave( IniInterface& ini ) IniBitBool( XgKickHack ); IniBitBool( IPUWaitHack ); IniBitBool( EETimingHack ); + IniBitBool( SkipMPEGHack ); } Pcsx2Config::Pcsx2Config() diff --git a/pcsx2/gui/Panels/GameFixesPanel.cpp b/pcsx2/gui/Panels/GameFixesPanel.cpp index 3ac05a2633..578d6c6d0f 100644 --- a/pcsx2/gui/Panels/GameFixesPanel.cpp +++ b/pcsx2/gui/Panels/GameFixesPanel.cpp @@ -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 } }; diff --git a/pcsx2/x86/ix86-32/iR5900-32.cpp b/pcsx2/x86/ix86-32/iR5900-32.cpp index 6b53075361..07689b1350 100644 --- a/pcsx2/x86/ix86-32/iR5900-32.cpp +++ b/pcsx2/x86/ix86-32/iR5900-32.cpp @@ -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