From 2c0ec96eff77ff62e17d4fae7ed8fcfdcd5a85e0 Mon Sep 17 00:00:00 2001 From: Josh Bodner <30329717+jbodner09@users.noreply.github.com> Date: Fri, 18 Nov 2022 15:42:58 -0800 Subject: [PATCH] Fix credits timing (#1254) * Fix credits timing * Add documentation * Fix typo --- soh/soh/GameMenuBar.cpp | 4 ++++ soh/src/code/z_demo.c | 49 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/soh/soh/GameMenuBar.cpp b/soh/soh/GameMenuBar.cpp index 0a09e5122..c04196469 100644 --- a/soh/soh/GameMenuBar.cpp +++ b/soh/soh/GameMenuBar.cpp @@ -314,6 +314,8 @@ namespace GameMenuBar { CVar_SetS32("gCrouchStabHammerFix", 0); // Fix all crouch stab CVar_SetS32("gCrouchStabFix", 0); + // Fix credits timing + CVar_SetS32("gCreditsFix", 1); // Fix Gerudo Warrior's clothing colors CVar_SetS32("gGerudoWarriorClothingFix", 0); @@ -1166,6 +1168,8 @@ namespace GameMenuBar { UIWidgets::PaddedEnhancementCheckbox("Remove power crouch stab", "gCrouchStabFix", true, false); UIWidgets::Tooltip("Make crouch stabbing always do the same damage as a regular slash"); } + UIWidgets::PaddedEnhancementCheckbox("Fix credits timing", "gCreditsFix", true, false); + UIWidgets::Tooltip("Extend certain credits scenes so the music lines up properly with the visuals"); UIWidgets::PaddedEnhancementCheckbox("Fix Gerudo Warrior's clothing colors", "gGerudoWarriorClothingFix", true, false); UIWidgets::Tooltip("Prevent the Gerudo Warrior's clothes changing color when changing Link's tunic or using bombs in front of her"); diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 4133d4dab..9eeb3bfa8 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -511,7 +511,54 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB temp = 1; } - if ((csCtx->frames == cmd->startFrame) || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) { + bool playCutscene = false; + if (!CVar_GetS32("gCreditsFix", 1) && (cmd->startFrame == csCtx->frames)) { + playCutscene = true; + } else if (CVar_GetS32("gCreditsFix", 1)) { + u16 delay = 0; + + // HACK: Align visual timing with audio during credits sequence + switch (cmd->base) { + case 55: // Gerudo fortress (second scene of credits roll) + delay = 20; + break; + case 56: // Kakariko village + delay = 40; + break; + case 57: // Death mountain trail + delay = 20; + break; + case 58: // Goron city + delay = 20; + break; + case 59: // Lake hylia + delay = 20; + break; + case 62: // Kokiri forest (houses) + delay = 40; + break; + case 63: // Kokiri forest (deku tree) + delay = 40; + break; + case 74: // First gorons dancing + delay = 100; + break; + case 75: // Magic carpet guy and old shop keepers + delay = 180; + break; + case 77: // Sad mido and king zora (plays after scene 78) + delay = 100; + break; + case 78: // Second gorons dancing + delay = 160; + break; + } + if (cmd->startFrame + delay == csCtx->frames) { + playCutscene = true; + } + } + + if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) { csCtx->state = CS_STATE_UNSKIPPABLE_EXEC; Audio_SetCutsceneFlag(0);