Patch giants cutscene to fix music desync, update RT64

This commit is contained in:
Mr-Wiseguy 2024-03-15 01:17:56 -04:00
parent de35dfc8a8
commit ff5dd7f50c
3 changed files with 55 additions and 3 deletions

@ -1 +1 @@
Subproject commit 33b5686c649bb501884d114192924233957c9a49 Subproject commit 97502ffed099612b59ce23a886d78873d9c6e9ef

View File

@ -1,5 +1,6 @@
#include "patches.h" #include "patches.h"
#include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h" #include "overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope.h"
#include "overlays/actors/ovl_En_Fall/z_en_fall.h"
#define PAGE_BG_WIDTH (PAGE_BG_COLS * PAGE_BG_QUAD_WIDTH) #define PAGE_BG_WIDTH (PAGE_BG_COLS * PAGE_BG_QUAD_WIDTH)
#define PAGE_BG_HEIGHT (PAGE_BG_ROWS * PAGE_BG_QUAD_HEIGHT) #define PAGE_BG_HEIGHT (PAGE_BG_ROWS * PAGE_BG_QUAD_HEIGHT)
@ -257,3 +258,43 @@ Gfx* KaleidoScope_DrawPageSections(Gfx* gfx, Vtx* vertices, TexturePtr* textures
return gfx; return gfx;
} }
typedef void (*CutsceneHandler)(PlayState* play, CutsceneContext* csCtx);
extern CutsceneHandler sScriptedCutsceneHandlers[];
void Cutscene_SetupScripted(PlayState* play, CutsceneContext* csCtx);
int extra_vis = 0;
// @recomp Patch the giants cutscene to make certain frames take longer to mimic performance on console.
// This prevents the music from desyncing from the cutscene as it was designed around the console's frame times.
void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) {
if ((gSaveContext.cutsceneTrigger != 0) && (play->transitionTrigger == TRANS_TRIGGER_START)) {
gSaveContext.cutsceneTrigger = 0;
}
if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_IDLE)) {
gSaveContext.save.cutsceneIndex = 0xFFFD;
gSaveContext.cutsceneTrigger = 1;
}
if (gSaveContext.save.cutsceneIndex >= 0xFFF0) {
Cutscene_SetupScripted(play, csCtx);
sScriptedCutsceneHandlers[csCtx->state](play, csCtx);
}
// @recomp Insert extra VI interrupt delays on certain frames of the giants cutscene to match console
// framerates. This prevents the music from desyncing with the cutscene.
if (play->sceneId == SCENE_00KEIKOKU && gSaveContext.sceneLayer == 1) {
s32 curFrame = play->csCtx.curFrame;
s32 scriptIndex = play->csCtx.scriptIndex;
// These regions of lag were determined by measuring framerate on console, though they pretty clearly
// correspond to specific camera angles and effects active during the cutscene.
if (
(scriptIndex == 0 && curFrame >= 1123 && curFrame <= 1381) ||
(scriptIndex != 0 && curFrame >= 4 && curFrame <= 85) ||
(scriptIndex != 0 && curFrame >= 431 && curFrame <= 490)
) {
extra_vis = 1;
}
}
}

View File

@ -58,8 +58,6 @@ void Graph_SetNextGfxPool(GraphicsContext* gfxCtx) {
// @recomp Enable RT64 extended GBI mode and set the current framerate // @recomp Enable RT64 extended GBI mode and set the current framerate
OPEN_DISPS(gfxCtx); OPEN_DISPS(gfxCtx);
gEXEnable(POLY_OPA_DISP++); gEXEnable(POLY_OPA_DISP++);
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / gFramerateDivisor);
// gEXPrint(POLY_OPA_DISP++);
CLOSE_DISPS(gfxCtx); CLOSE_DISPS(gfxCtx);
} }
@ -78,6 +76,9 @@ extern volatile OSTime gRDPTimeAcc;
extern OSTime sGraphPrevUpdateEndTime; extern OSTime sGraphPrevUpdateEndTime;
extern volatile OSTime gGraphUpdatePeriod; extern volatile OSTime gGraphUpdatePeriod;
extern int extra_vis;
// @recomp Modified to report errors instead of skipping frames. // @recomp Modified to report errors instead of skipping frames.
/** /**
* Run the game state logic, then finalize the gfx buffer * Run the game state logic, then finalize the gfx buffer
@ -93,6 +94,9 @@ void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) {
OPEN_DISPS(gfxCtx); OPEN_DISPS(gfxCtx);
// @recomp Send the current framerate to RT64, including any extra VI interrupt periods.
gEXSetRefreshRate(POLY_OPA_DISP++, 60 / (gameState->framerateDivisor + extra_vis));
gSPEndDisplayList(WORK_DISP++); gSPEndDisplayList(WORK_DISP++);
gSPEndDisplayList(POLY_OPA_DISP++); gSPEndDisplayList(POLY_OPA_DISP++);
gSPEndDisplayList(POLY_XLU_DISP++); gSPEndDisplayList(POLY_XLU_DISP++);
@ -147,10 +151,17 @@ void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) {
} }
if (!problem) { if (!problem) {
// @recomp Temporarily adjust the framerate divisor to include any extra VI interrupt periods.
u8 old_divisor = gameState->framerateDivisor;
gameState->framerateDivisor += extra_vis;
Graph_TaskSet00(gfxCtx, gameState); Graph_TaskSet00(gfxCtx, gameState);
// @recomp Restore the old framerate divisor.
gameState->framerateDivisor = old_divisor;
gfxCtx->gfxPoolIdx++; gfxCtx->gfxPoolIdx++;
gfxCtx->framebufferIndex++; gfxCtx->framebufferIndex++;
} }
// @recomp Clear any extra VI interrupt periods.
extra_vis = 0;
{ {
OSTime time = osGetTime(); OSTime time = osGetTime();