mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #15640 from LunaMoo/master
Disable ForceMax60FPS for GOW games and replace it with fixed 60 fps
This commit is contained in:
commit
d2002eab39
7 changed files with 80 additions and 4 deletions
|
@ -76,6 +76,8 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) {
|
||||||
CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix);
|
CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix);
|
||||||
CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay);
|
CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay);
|
||||||
CheckSetting(iniFile, gameID, "ForceMax60FPS", &flags_.ForceMax60FPS);
|
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, "JitInvalidationHack", &flags_.JitInvalidationHack);
|
||||||
CheckSetting(iniFile, gameID, "HideISOFiles", &flags_.HideISOFiles);
|
CheckSetting(iniFile, gameID, "HideISOFiles", &flags_.HideISOFiles);
|
||||||
CheckSetting(iniFile, gameID, "MoreAccurateVMMUL", &flags_.MoreAccurateVMMUL);
|
CheckSetting(iniFile, gameID, "MoreAccurateVMMUL", &flags_.MoreAccurateVMMUL);
|
||||||
|
|
|
@ -66,6 +66,8 @@ struct CompatFlags {
|
||||||
bool YugiohSaveFix;
|
bool YugiohSaveFix;
|
||||||
bool ForceUMDDelay;
|
bool ForceUMDDelay;
|
||||||
bool ForceMax60FPS;
|
bool ForceMax60FPS;
|
||||||
|
bool GoWFramerateHack60;
|
||||||
|
bool GoWFramerateHack30;
|
||||||
bool JitInvalidationHack;
|
bool JitInvalidationHack;
|
||||||
bool HideISOFiles;
|
bool HideISOFiles;
|
||||||
bool MoreAccurateVMMUL;
|
bool MoreAccurateVMMUL;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
#include "Common/Swap.h"
|
#include "Common/Swap.h"
|
||||||
#include "Core/Config.h"
|
#include "Core/Config.h"
|
||||||
|
#include "Core/System.h"
|
||||||
#include "Core/Debugger/Breakpoints.h"
|
#include "Core/Debugger/Breakpoints.h"
|
||||||
#include "Core/Debugger/MemBlockInfo.h"
|
#include "Core/Debugger/MemBlockInfo.h"
|
||||||
#include "Core/Debugger/SymbolMap.h"
|
#include "Core/Debugger/SymbolMap.h"
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include "Core/MIPS/MIPSAnalyst.h"
|
#include "Core/MIPS/MIPSAnalyst.h"
|
||||||
#include "Core/HLE/ReplaceTables.h"
|
#include "Core/HLE/ReplaceTables.h"
|
||||||
#include "Core/HLE/FunctionWrappers.h"
|
#include "Core/HLE/FunctionWrappers.h"
|
||||||
|
#include "Core/HLE/sceDisplay.h"
|
||||||
|
|
||||||
#include "GPU/Math3D.h"
|
#include "GPU/Math3D.h"
|
||||||
#include "GPU/GPU.h"
|
#include "GPU/GPU.h"
|
||||||
|
@ -1338,6 +1340,27 @@ static int Hook_soltrigger_render_ucschar() {
|
||||||
return 0;
|
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)
|
#define JITFUNC(f) (&MIPSComp::MIPSFrontendInterface::f)
|
||||||
|
|
||||||
// Can either replace with C functions or functions emitted in Asm/ArmAsm.
|
// 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 },
|
{ "worms_copy_normalize_alpha", &Hook_worms_copy_normalize_alpha, 0, REPFLAG_HOOKENTER, 0x0CC },
|
||||||
{ "openseason_data_decode", &Hook_openseason_data_decode, 0, REPFLAG_HOOKENTER, 0x2F0 },
|
{ "openseason_data_decode", &Hook_openseason_data_decode, 0, REPFLAG_HOOKENTER, 0x2F0 },
|
||||||
{ "soltrigger_render_ucschar", &Hook_soltrigger_render_ucschar, 0, REPFLAG_HOOKENTER, 0 },
|
{ "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 },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -732,6 +732,10 @@ static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks
|
||||||
return hleLogSuccessVerboseI(SCEDISPLAY, 0, "waiting for %d vblanks", vblanks);
|
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) {
|
static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeight) {
|
||||||
if (displayMode != PSP_DISPLAY_MODE_LCD || displayWidth != 480 || displayHeight != 272) {
|
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);
|
WARN_LOG_REPORT(SCEDISPLAY, "Video out requested, not supported: mode=%d size=%d,%d", displayMode, displayWidth, displayHeight);
|
||||||
|
|
|
@ -33,3 +33,4 @@ void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync);
|
||||||
void __DisplaySetWasPaused();
|
void __DisplaySetWasPaused();
|
||||||
|
|
||||||
void Register_sceDisplay_driver();
|
void Register_sceDisplay_driver();
|
||||||
|
void __DisplayWaitForVblanks(const char* reason, int vblanks, bool callbacks = false);
|
||||||
|
|
|
@ -507,6 +507,8 @@ static const HardHashTableEntry hardcodedHashes[] = {
|
||||||
{ 0xfe5dd338ab862291, 216, "memset", }, // Metal Gear Solid: Peace Walker demo
|
{ 0xfe5dd338ab862291, 216, "memset", }, // Metal Gear Solid: Peace Walker demo
|
||||||
{ 0xffc8f5f8f946152c, 192, "dl_write_light_color", },
|
{ 0xffc8f5f8f946152c, 192, "dl_write_light_color", },
|
||||||
{ 0x249a3c5981c73480, 1472, "openseason_data_decode", }, // Open Season
|
{ 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 {
|
namespace MIPSAnalyst {
|
||||||
|
|
|
@ -818,10 +818,9 @@ ULJS00119 = true
|
||||||
ULKS46167 = true
|
ULKS46167 = true
|
||||||
NPJH50017 = true
|
NPJH50017 = true
|
||||||
|
|
||||||
[ForceMax60FPS]
|
[GoWFramerateHack60]
|
||||||
# The GOW games are very heavy and render as fast as they can. They benefit greatly from
|
# Replaces ForceMax60FPS for GOW games, should provide smoother experience
|
||||||
# capping the framerate at 60fps.
|
# Also works around softlock in GOW:GOS , see #8299
|
||||||
|
|
||||||
# GOW : Ghost of Sparta
|
# GOW : Ghost of Sparta
|
||||||
UCUS98737 = true
|
UCUS98737 = true
|
||||||
UCAS40323 = true
|
UCAS40323 = true
|
||||||
|
@ -855,6 +854,47 @@ UCUS98705 = true
|
||||||
UCED00971 = true
|
UCED00971 = true
|
||||||
UCUS98713 = 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.
|
# F1 2006 has extremely long loading times if we don't limit the framerate.
|
||||||
UCES00238 = true
|
UCES00238 = true
|
||||||
UCJS10045 = true
|
UCJS10045 = true
|
||||||
|
|
Loading…
Add table
Reference in a new issue