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
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, "Fixed60FPShack", &flags_.Fixed60FPShack);
CheckSetting(iniFile, gameID, "Fixed30FPShack", &flags_.Fixed30FPShack);
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 Fixed60FPShack;
bool Fixed30FPShack;
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().Fixed60FPShack || PSP_CoreParameter().compat.flags().Fixed30FPShack) {
if (PSP_CoreParameter().compat.flags().Fixed30FPShack) {
__DisplayWaitForVblanks("vblank start waited", 2);
} else {
__DisplayWaitForVblanks("vblank start waited", 1);
}
}
return 0;
}

static int Hook_gow_vortex_hack() {
if (PSP_CoreParameter().compat.flags().Fixed60FPShack) {
//from my tests ==0x3F800000 takes around 1:50s, when != it's roughtly 2:50s and that seems more correct
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, still wrong, but it's a start
};

namespace MIPSAnalyst {
Expand Down
49 changes: 45 additions & 4 deletions assets/compat.ini
Original file line number Diff line number Diff line change
Expand Up @@ -802,10 +802,10 @@ 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.

[Fixed60FPShack]
LunaMoo marked this conversation as resolved.
Show resolved Hide resolved
# Replaces ForceMax60FPS for GOW games, should provide smoother experience
# Unfortunately just like the latter still causes softlock in GOW:GOS , see #8299
# Worked around by another hack, but still have to work on that
LunaMoo marked this conversation as resolved.
Show resolved Hide resolved
# GOW : Ghost of Sparta
UCUS98737 = true
UCAS40323 = true
Expand Down Expand Up @@ -839,6 +839,47 @@ UCUS98705 = true
UCED00971 = true
UCUS98713 = true

[Fixed30FPShack]
# As the 60 fps version, but makes the GOW 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