diff --git a/docs/tr1/CHANGELOG.md b/docs/tr1/CHANGELOG.md index 9b5e1b249..2944c1b5d 100644 --- a/docs/tr1/CHANGELOG.md +++ b/docs/tr1/CHANGELOG.md @@ -27,6 +27,7 @@ - fixed the camera going out of bounds in 60fps near specific invalid floor data (known as no-space) (#2764, regression from 4.9) - fixed wrong PS1-style title bar color for the end of the level stats dialog (regression from 4.9) - fixed Story So Far showing up even when there's nothing to play (#2611, regression from 2.10) +- fixed Story So Far not playing the opening FMV, `cafe.rpl` (#2779, regression from 2.10) - improved bubble appearance (#2672) - improved rendering performance - improved pause exit dialog - it can now be canceled with escape diff --git a/src/tr1/game/game_flow/sequencer_misc.c b/src/tr1/game/game_flow/sequencer_misc.c index 962a86cc8..548adaece 100644 --- a/src/tr1/game/game_flow/sequencer_misc.c +++ b/src/tr1/game/game_flow/sequencer_misc.c @@ -6,6 +6,7 @@ #include "game/level.h" #include "game/savegame.h" +#include #include #include @@ -23,6 +24,12 @@ GF_COMMAND GF_RunTitle(void) GF_COMMAND GF_PlayAvailableStory(const int32_t slot_num) { const int32_t savegame_level = Savegame_GetLevelNumber(slot_num); + const bool prev_enable_legal = g_Config.gameplay.enable_legal; + g_Config.gameplay.enable_legal = false; + + // Play intro FMVs and cutscenes + GF_DoFrontendSequence(); + const GF_LEVEL_TABLE *const level_table = GF_GetLevelTable(GFLT_MAIN); for (int32_t i = 0; i <= MIN(savegame_level, level_table->count); i++) { const GF_LEVEL *const level = GF_GetLevel(GFLT_MAIN, i); @@ -36,12 +43,35 @@ GF_COMMAND GF_PlayAvailableStory(const int32_t slot_num) break; } } + + g_Config.gameplay.enable_legal = prev_enable_legal; return (GF_COMMAND) { .action = GF_EXIT_TO_TITLE }; } bool GF_HasAvailableStory(const int32_t slot_num) { const int32_t savegame_level = Savegame_GetLevelNumber(slot_num); + + // Check intro FMVs and cutscenes in frontend sequence (skip legal FMVs) + const GF_LEVEL *const title_level = GF_GetTitleLevel(); + if (title_level != nullptr) { + const GF_SEQUENCE *const seq = &title_level->sequence; + for (int32_t j = 0; j < seq->length; j++) { + const GF_SEQUENCE_EVENT *const ev = &seq->events[j]; + if (ev->type == GFS_PLAY_CUTSCENE) { + return true; + } + if (ev->type == GFS_PLAY_FMV) { + const int32_t fmv_id = (int32_t)(intptr_t)ev->data; + const GF_FMV *const fmv = &g_GameFlow.fmvs[fmv_id]; + if (!fmv->is_legal) { + return true; + } + } + } + } + + // Check for any cutscenes or FMVs up until the save point const GF_LEVEL_TABLE *const level_table = GF_GetLevelTable(GFLT_MAIN); const int32_t max_level = MIN(savegame_level, level_table->count); for (int32_t i = 0; i <= max_level; i++) { @@ -52,12 +82,20 @@ bool GF_HasAvailableStory(const int32_t slot_num) const GF_SEQUENCE *const seq = &level->sequence; for (int32_t j = 0; j < seq->length; j++) { const GF_SEQUENCE_EVENT *const ev = &seq->events[j]; + // Stop checking after the saved level if (ev->type == GFS_LOOP_GAME) { break; } - if (ev->type == GFS_PLAY_CUTSCENE || ev->type == GFS_PLAY_FMV) { + if (ev->type == GFS_PLAY_CUTSCENE) { return true; } + if (ev->type == GFS_PLAY_FMV) { + const int32_t fmv_id = (int32_t)(intptr_t)ev->data; + const GF_FMV *const fmv = &g_GameFlow.fmvs[fmv_id]; + if (!fmv->is_legal) { + return true; + } + } } } return false;