mirror of
https://github.com/BanjoRecomp/BanjoRecomp
synced 2026-05-23 06:34:20 -04:00
Fix timings for dingpot cutscene. (#107)
* Fix timings for dingpot cutscene. * Remove comment, adjust timing. * Match spacing.
This commit is contained in:
@@ -93,7 +93,7 @@ void hotpatch_intro_opa_map_model(BKModelBin* model_bin) {
|
||||
gSPDisplayList(&dl[INTRO_OPA_DL_WALL_PATCH_INDEX], intro_wall_extension_dl);
|
||||
}
|
||||
|
||||
void reset_intro_cutscene_timings_state(void);
|
||||
void reset_cutscene_timings_state(void);
|
||||
|
||||
// @recomp Patched to act as a point to run code when a new map is loaded.
|
||||
// This includes:
|
||||
@@ -132,5 +132,5 @@ RECOMP_PATCH void func_803329AC(void){
|
||||
note_saving_on_map_load();
|
||||
|
||||
// @recomp Reset the intro cutscene timing corrections so the cutscene can be played again
|
||||
reset_intro_cutscene_timings_state();
|
||||
reset_cutscene_timings_state();
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ extern s32 func_8033A170(void);
|
||||
extern enum map_e map_get(void);
|
||||
extern enum bswatergroup_e player_getWaterState(void);
|
||||
|
||||
extern u32 get_intro_cutscene_counter(void);
|
||||
extern u32 get_cutscene_counter(void);
|
||||
|
||||
// @recomp Patched to give the bees in the bee swarm individual IDs. The bees can show interpolation glitches otherwise, as they all share one matrix
|
||||
// group and can get culled individually based on distance. This is easily reproduceable by walking into a beehive with bees from a far away distance.
|
||||
@@ -135,7 +135,7 @@ bool skip_drawing_intro_bulls(u32 model_id) {
|
||||
return
|
||||
(map_get() == MAP_1E_CS_START_NINTENDO) &&
|
||||
(model_id == ASSET_353_MODEL_BIGBUTT || model_id == ASSET_354_MODEL_BULL_INTRO) &&
|
||||
get_intro_cutscene_counter() < 180;
|
||||
get_cutscene_counter() < 180;
|
||||
}
|
||||
|
||||
// @recomp Patched to skip drawing the bull actors on the intro cutscene's start.
|
||||
|
||||
+42
-30
@@ -150,63 +150,69 @@ RECOMP_PATCH void func_80345EB0(enum item_e item){
|
||||
}
|
||||
}
|
||||
|
||||
// The intro cutscene stutters on console, but it does not stutter in recomp.
|
||||
// The concert intro cutscene stutters on console, but it does not stutter in recomp.
|
||||
// The cutscene is timed with the stutters in mind so this causes desyncs with the music and sound effects.
|
||||
// We have manually analyzed the cutscene and taken note of the exact frames during which it stutters,
|
||||
// and we lag the game to 15 FPS internally (this cutscene targets 20 FPS) for a few frames when it would
|
||||
// have stuttered on console in order to keep the cutscene in sync.
|
||||
|
||||
// What frames of the cutscene to lag on, and for how many frames.
|
||||
int introStuttersStartFrames[] = { 269, 521, 583, 663, 769, 959, 1155, 1182, 1214 };
|
||||
int introStutterDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4 };
|
||||
int concertStuttersStartFrames[] = { 269, 521, 583, 663, 769, 959, 1155, 1182, 1214 };
|
||||
int concertStutterDurations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4 };
|
||||
|
||||
// What frames of the cutscene to lag on, and for how many frames.
|
||||
int lairDingpotStuttersStartFrames[] = { 258, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000 };
|
||||
int lairDingpotStutterDurations[] = { 6, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 };
|
||||
|
||||
// These are reset on map load, so that the cutscene can be replayed (such as when saving and exiting)
|
||||
// See func_803329AC in load_patches.c
|
||||
int introCutsceneCounter = 0;
|
||||
int introCutsceneNextStutter = 0;
|
||||
int introCutsceneLagIndex = 0;
|
||||
int cutsceneCounter = 0;
|
||||
int cutsceneNextStutter = 0;
|
||||
int cutsceneLagIndex = 0;
|
||||
|
||||
bool should_lag_intro_cutscene(void) {
|
||||
bool should_lag_cutscene(int *stuttersStartFrames, int *stutterDurations, int stuttersStartFramesCount) {
|
||||
// No stutters left to compensate for. Exit the function early.
|
||||
if (introCutsceneNextStutter == -1) {
|
||||
if (cutsceneNextStutter == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//recomp_printf("cutsceneCounter %d\n", cutsceneCounter);
|
||||
|
||||
// First frame of the cutscene. Set the first stutter frame.
|
||||
if (introCutsceneNextStutter < introStuttersStartFrames[0]) {
|
||||
introCutsceneNextStutter = introStuttersStartFrames[0];
|
||||
//recomp_printf("Start intro cutscene with timing corrections. First stutter frame: %d\n", introCutsceneNextStutter);
|
||||
if (cutsceneNextStutter < stuttersStartFrames[0]) {
|
||||
cutsceneNextStutter = stuttersStartFrames[0];
|
||||
//recomp_printf("Start cutscene with timing corrections. First stutter frame: %d\n", cutsceneNextStutter);
|
||||
}
|
||||
|
||||
if (introCutsceneCounter >= (introCutsceneNextStutter) && introCutsceneCounter < (introCutsceneNextStutter + introStutterDurations[introCutsceneLagIndex])) {
|
||||
if (cutsceneCounter >= (cutsceneNextStutter) && cutsceneCounter < (cutsceneNextStutter + stutterDurations[cutsceneLagIndex])) {
|
||||
// A stutter would have occured on console now. Lag the game for a given amount of frames.
|
||||
//recomp_printf("LAGGING. Stutter number %d. Frame number %d\n", introCutsceneLagIndex, introCutsceneCounter);
|
||||
//recomp_printf("LAGGING. Stutter number %d. Frame number %d\n", cutsceneLagIndex, cutsceneCounter);
|
||||
return TRUE;
|
||||
} else if (introCutsceneCounter > (introCutsceneNextStutter)) {
|
||||
introCutsceneLagIndex++;
|
||||
if (introCutsceneLagIndex >= (int)sizeof(introStuttersStartFrames) / (int)sizeof(introStuttersStartFrames[0])) {
|
||||
} else if (cutsceneCounter > (cutsceneNextStutter)) {
|
||||
cutsceneLagIndex++;
|
||||
if (cutsceneLagIndex >= stuttersStartFramesCount) {
|
||||
// That was the last stutter. We're done.
|
||||
introCutsceneNextStutter = -1;
|
||||
//recomp_printf("End intro cutscene. %d\n", introCutsceneNextStutter);
|
||||
cutsceneNextStutter = -1;
|
||||
//recomp_printf("End cutscene. %d\n", cutsceneNextStutter);
|
||||
} else {
|
||||
// Set the next stutter frame.
|
||||
introCutsceneNextStutter = introStuttersStartFrames[introCutsceneLagIndex];
|
||||
//recomp_printf("Next stutter: %d\n", introCutsceneNextStutter);
|
||||
cutsceneNextStutter = stuttersStartFrames[cutsceneLagIndex];
|
||||
//recomp_printf("Next stutter: %d\n", cutsceneNextStutter);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
// Reset the custom cutscene frame counter and the stutter frame index used to
|
||||
// correct the timings of the intro cutscene.
|
||||
void reset_intro_cutscene_timings_state(void) {
|
||||
introCutsceneCounter = 0;
|
||||
introCutsceneNextStutter = 0;
|
||||
introCutsceneLagIndex = 0;
|
||||
// correct the timings of the cutscene.
|
||||
void reset_cutscene_timings_state(void) {
|
||||
cutsceneCounter = 0;
|
||||
cutsceneNextStutter = 0;
|
||||
cutsceneLagIndex = 0;
|
||||
}
|
||||
|
||||
// Return the current intro cutscene counter.
|
||||
u32 get_intro_cutscene_counter(void) {
|
||||
return introCutsceneCounter;
|
||||
// Return the current cutscene counter.
|
||||
u32 get_cutscene_counter(void) {
|
||||
return cutsceneCounter;
|
||||
}
|
||||
|
||||
// Check the current map to see if it's a cutscene map that requires timing fixes,
|
||||
@@ -214,10 +220,16 @@ u32 get_intro_cutscene_counter(void) {
|
||||
void handle_cutscene_timings(void) {
|
||||
switch (map_get()) {
|
||||
case MAP_1E_CS_START_NINTENDO:
|
||||
if (should_lag_intro_cutscene()) {
|
||||
if (should_lag_cutscene(concertStuttersStartFrames, concertStutterDurations, (int)sizeof(concertStuttersStartFrames) / (int)sizeof(concertStuttersStartFrames[0]))) {
|
||||
extraVis = 1;
|
||||
}
|
||||
introCutsceneCounter++;
|
||||
cutsceneCounter++;
|
||||
break;
|
||||
case MAP_7B_CS_INTRO_GL_DINGPOT_1:
|
||||
if (should_lag_cutscene(lairDingpotStuttersStartFrames, lairDingpotStutterDurations, (int)sizeof(lairDingpotStuttersStartFrames) / (int)sizeof(lairDingpotStuttersStartFrames[0]))) {
|
||||
extraVis = 1;
|
||||
}
|
||||
cutsceneCounter++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user