Activision Hits Remixed: Limit the front end to one frame per vblank

- Fixes #20287

The menus and manuals flip from a GE finish callback and only sleep 100us
per frame, so the GE's drawing time sets the frame rate. Ours is instant,
so they ran at 400-800fps and the host couldn't keep up. Hook the end of
the per-frame update and wait for a vblank unless one has already passed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-21 15:23:59 +02:00
1 parent 8c7683ea6a
commit ed6e5f0e6f
2 files changed
+18

No files matched your search

+17
View File
@@ -38,6 +38,7 @@
#include "Core/HLE/ReplaceTables.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceDisplay.h"
#include "Core/HW/Display.h"
#include "Core/HW/MMIO.h"
#include "GPU/Math3D.h"
@@ -1771,6 +1772,21 @@ static int Hook_blitz_fps_hack(MIPSState *mips) {
return 0;
}
static int Hook_activisionhits_frame_limit(MIPSState *mips) {
// The manual pages flip from a GE finish callback, and the loop only sleeps 100us between frames,
// so how fast the GE draws sets the frame rate. Ours draws instantly, so it ran at ~800fps (#20287).
// Allow one frame per vblank. Screens that wait for vblank on their own already pass this.
static int lastVCount = -1;
const int vcount = __DisplayGetVCount();
if (vcount <= lastVCount) {
__DisplayWaitForVblanks("vblank start waited", 1);
lastVCount = vcount + 1;
} else {
lastVCount = vcount;
}
return 0;
}
static int Hook_brian_lara_fps_hack(MIPSState *mips) {
if (PSP_CoreParameter().compat.flags().FramerateHack30) {
__DisplayWaitForVblanks("vblank start waited", 1);
@@ -1996,6 +2012,7 @@ static const ReplacementTableEntry entries[] = {
{ "gtavcs_plane_control", &Hook_gtavcs_plane_control_1, 0, REPFLAG_HOOKENTER, 0x620 },
{ "gtavcs_plane_control", &Hook_gtavcs_plane_control_2, 0, REPFLAG_HOOKENTER, 0x6AC },
{ "medievil_projectile_update", &Hook_medievil_projectile_update, 0, REPFLAG_HOOKENTER, 0x6BC },
{ "activisionhits_frame_limit", &Hook_activisionhits_frame_limit, 0, REPFLAG_HOOKEXIT, 0 },
{}
};
+1
View File
@@ -403,6 +403,7 @@ static const HardHashTableEntry hardcodedHashes[] = {
{ 0xb3fef47fb27d57c9, 44, "vector_scale_t", },
{ 0xb43fd5078ae78029, 84, "send_commandi_stall", },
{ 0xb43ffbd4dc446dd2, 324, "atan2f", },
{ 0xb4686bcdfb76e454, 156, "activisionhits_frame_limit", }, // Activision Hits Remixed (issue #20287)
{ 0xb5fdb3083e6f4b3f, 36, "vhtfm_t", },
{ 0xb6a04277fb1e1a1a, 104, "vmmul_q_transp", },
{ 0xb726917d688ac95b, 268, "kagaku_no_ensemble_download_frame", }, // Toaru Majutsu to Kagaku no Ensemble