Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable ForceMax60FPS for GOW games and replace it with fixed 60 fps #15640

Merged
merged 7 commits into from
Jul 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Core/Compatibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,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);
Expand Down
2 changes: 2 additions & 0 deletions Core/Compatibility.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ struct CompatFlags {
bool YugiohSaveFix;
bool ForceUMDDelay;
bool ForceMax60FPS;
bool GoWFramerateHack60;
bool GoWFramerateHack30;
bool JitInvalidationHack;
bool HideISOFiles;
bool MoreAccurateVMMUL;
Expand Down
25 changes: 25 additions & 0 deletions Core/HLE/ReplaceTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 },
{}
};

Expand Down
4 changes: 4 additions & 0 deletions Core/HLE/sceDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,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);
Expand Down
1 change: 1 addition & 0 deletions Core/HLE/sceDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
2 changes: 2 additions & 0 deletions Core/MIPS/MIPSAnalyst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
48 changes: 44 additions & 4 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -802,10 +802,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
Expand Down Expand Up @@ -839,6 +838,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
Expand Down