tr1/game-flow: fix story so far not playing cafe.rpl

Resolves #2779.
This commit is contained in:
Marcin Kurczewski 2025-04-18 15:27:33 +02:00
parent f144f8ccad
commit 0fc11f401b
2 changed files with 40 additions and 1 deletions

View file

@ -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

View file

@ -6,6 +6,7 @@
#include "game/level.h"
#include "game/savegame.h"
#include <libtrx/config.h>
#include <libtrx/game/game_string_table.h>
#include <libtrx/log.h>
@ -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;