Merge pull request #15640 from LunaMoo/master

Disable ForceMax60FPS for GOW games and replace it with fixed 60 fps
This commit is contained in:
Henrik Rydgård 2022-07-10 23:25:35 +02:00 committed by GitHub
commit d2002eab39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 4 deletions

View file

@ -76,6 +76,8 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix);
CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay);
CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS);
CheckSetting(iniFile, gameID, "GoWFramerateHack60", &flags_.GoWFramerateHack60);
CheckSetting(iniFile, gameID, "GoWFramerateHack30", &flags_.GoWFramerateHack30);
CheckSetting(iniFile, gameID, "JitInvalidationHack", &flags_.JitInvalidationHack);
CheckSetting(iniFile, gameID, "HideISOFiles", &flags_.HideISOFiles);
CheckSetting(iniFile, gameID, "MoreAccurateVMMUL", &flags_.MoreAccurateVMMUL);

View file

@ -66,6 +66,8 @@ struct CompatFlags {
bool YugiohSaveFix;
bool ForceUMDDelay;
bool ForceMax60FPS;
bool GoWFramerateHack60;
bool GoWFramerateHack30;
bool JitInvalidationHack;
bool HideISOFiles;
bool MoreAccurateVMMUL;

View file

@ -25,6 +25,7 @@
#include "Common/Log.h"
#include "Common/Swap.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Debugger/SymbolMap.h"
@ -34,6 +35,7 @@
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/HLE/ReplaceTables.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceDisplay.h"
#include "GPU/Math3D.h"
#include "GPU/GPU.h"
@ -1338,6 +1340,27 @@ static int Hook_soltrigger_render_ucschar() {
return 0;
}
static int Hook_gow_fps_hack() {
if (PSP_CoreParameter().compat.flags().GoWFramerateHack60 || PSP_CoreParameter().compat.flags().GoWFramerateHack30) {
if (PSP_CoreParameter().compat.flags().GoWFramerateHack30) {
__DisplayWaitForVblanks("vblank start waited", 2);
} else {
__DisplayWaitForVblanks("vblank start waited", 1);
}
}
return 0;
}
static int Hook_gow_vortex_hack() {
if (PSP_CoreParameter().compat.flags().GoWFramerateHack60) {
// from my tests both ==0x3F800000 and !=0x3F800000 takes around 1:40-1:50, that seems to match correct behaviour
if (currentMIPS->r[MIPS_REG_S1] == 0 && currentMIPS->r[MIPS_REG_A0] == 0xC0 && currentMIPS->r[MIPS_REG_T4] != 0x3F800000) {
currentMIPS->r[MIPS_REG_S1] = 1;
}
}
return 0;
}
#define JITFUNC(f) (&MIPSComp::MIPSFrontendInterface::f)
// Can either replace with C functions or functions emitted in Asm/ArmAsm.
@ -1454,6 +1477,8 @@ static const ReplacementTableEntry entries[] = {
{ "worms_copy_normalize_alpha", &Hook_worms_copy_normalize_alpha, 0, REPFLAG_HOOKENTER, 0x0CC },
{ "openseason_data_decode", &Hook_openseason_data_decode, 0, REPFLAG_HOOKENTER, 0x2F0 },
{ "soltrigger_render_ucschar", &Hook_soltrigger_render_ucschar, 0, REPFLAG_HOOKENTER, 0 },
{ "gow_fps_hack", &Hook_gow_fps_hack, 0, REPFLAG_HOOKEXIT , 0 },
{ "gow_vortex_hack", &Hook_gow_vortex_hack, 0, REPFLAG_HOOKENTER, 0x60 },
{}
};

View file

@ -732,6 +732,10 @@ static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks
return hleLogSuccessVerboseI(SCEDISPLAY, 0, "waiting for %d vblanks", vblanks);
}
void __DisplayWaitForVblanks(const char* reason, int vblanks, bool callbacks) {
DisplayWaitForVblanks(reason, vblanks, callbacks);
}
static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeight) {
if (displayMode != PSP_DISPLAY_MODE_LCD || displayWidth != 480 || displayHeight != 272) {
WARN_LOG_REPORT(SCEDISPLAY, "Video out requested, not supported: mode=%d size=%d,%d", displayMode, displayWidth, displayHeight);

View file

@ -33,3 +33,4 @@ void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync);
void __DisplaySetWasPaused();
void Register_sceDisplay_driver();
void __DisplayWaitForVblanks(const char* reason, int vblanks, bool callbacks = false);

View file

@ -507,6 +507,8 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0xfe5dd338ab862291, 216, "memset", }, // Metal Gear Solid: Peace Walker demo
{ 0xffc8f5f8f946152c, 192, "dl_write_light_color", },
{ 0x249a3c5981c73480, 1472, "openseason_data_decode", }, // Open Season
{ 0x795d940ad0a605f8, 40, "gow_fps_hack", }, // God of War (all)
{ 0x4c75043b7b0c643b, 512, "gow_vortex_hack", } // God of War: Ghost of Sparta vortex timer hack, avoids softlock #8299
};
namespace MIPSAnalyst {

View file

@ -818,10 +818,9 @@ ULJS00119 = true
ULKS46167 = true
NPJH50017 = true
[ForceMax60FPS]
# The GOW games are very heavy and render as fast as they can. They benefit greatly from
# capping the framerate at 60fps.
[GoWFramerateHack60]
# Replaces ForceMax60FPS for GOW games, should provide smoother experience
# Also works around softlock in GOW:GOS , see #8299
# GOW : Ghost of Sparta
UCUS98737 = true
UCAS40323 = true
@ -855,6 +854,47 @@ UCUS98705 = true
UCED00971 = true
UCUS98713 = true
[GoWFramerateHack30]
# As the 60 fps version, but makes GOW games run on a potato,
# Doesn't suffer from softlock #8299
# disabled by default since most people wouldn't need it
# GOW : Ghost of Sparta
# UCUS98737 = true
# UCAS40323 = true
# NPHG00092 = true
# NPEG00044 = true
# NPEG00045 = true
# NPJG00120 = true
# NPUG80508 = true
# UCJS10114 = true
# UCES01401 = true
# UCES01473 = true
# GOW : Ghost of Sparta Demo
# NPEG90035 = true
# NPUG70125 = true
# NPJG90095 = true
# GOW : Chains Of Olympus
# UCAS40198 = true
# UCUS98653 = true
# UCES00842 = true
# ULJM05438 = true
# ULJM05348 = true
# UCKS45084 = true
# NPUG80325 = true
# NPEG00023 = true
# NPHG00027 = true
# NPHG00028 = true
# NPJH50170 = true
# UCET00844 = true
# GOW: Chains of Olympus Demo
# UCUS98705 = true
# UCED00971 = true
# UCUS98713 = true
[ForceMax60FPS]
# Some games are very heavy and render as fast as they can. They benefit greatly from
# capping the framerate at 60fps.
# F1 2006 has extremely long loading times if we don't limit the framerate.
UCES00238 = true
UCJS10045 = true