diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index 229b26fc4..ead177e7f 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -53,7 +53,6 @@ {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 2}, {"type": "add_secret_reward", "item": "small_medipack"}, {"type": "play_level"}, - {"type": "set_cutscene_angle", "angle": 0}, {"type": "play_cutscene", "cutscene_num": 0}, {"type": "level_complete"}, ], @@ -259,7 +258,6 @@ {"type": "play_fmv", "fmv_num": 6}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 8}, {"type": "play_level"}, - {"type": "set_cutscene_angle", "angle": 0}, {"type": "play_cutscene", "cutscene_num": 3}, {"type": "level_complete"}, ], @@ -366,7 +364,8 @@ "path": "data/cut1.tr2", "music_track": 3, "sequence": [ - {"type": "play_level"} + {"type": "set_cutscene_angle", "angle": 0}, + {"type": "play_level"}, ], }, { @@ -382,7 +381,10 @@ { "path": "data/cut4.tr2", "music_track": 30, - "sequence": [{"type": "play_level"}], + "sequence": [ + {"type": "set_cutscene_angle", "angle": 0}, + {"type": "play_level"}, + ], }, ], diff --git a/src/libtrx/game/game_flow/sequencer.c b/src/libtrx/game/game_flow/sequencer.c index 783f455dc..8c79ab187 100644 --- a/src/libtrx/game/game_flow/sequencer.c +++ b/src/libtrx/game/game_flow/sequencer.c @@ -39,10 +39,27 @@ GAME_FLOW_COMMAND GF_ShowInventoryKeys(const GAME_OBJECT_ID receptacle_type_id) return GF_ShowInventory(INV_KEYS_MODE); } -GAME_FLOW_COMMAND GF_PlayCutscene(const int32_t cutscene_num) +GAME_FLOW_COMMAND GF_RunDemo(const int32_t demo_num) +{ + PHASE *const demo_phase = Phase_Demo_Create(demo_num); + const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(demo_phase); + Phase_Demo_Destroy(demo_phase); + return gf_cmd; +} + +GAME_FLOW_COMMAND GF_RunCutscene(const int32_t cutscene_num) { PHASE *const cutscene_phase = Phase_Cutscene_Create(cutscene_num); const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(cutscene_phase); Phase_Cutscene_Destroy(cutscene_phase); return gf_cmd; } + +GAME_FLOW_COMMAND GF_RunGame( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + PHASE *const phase = Phase_Game_Create(level_num, level_type); + const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); + Phase_Game_Destroy(phase); + return gf_cmd; +} diff --git a/src/libtrx/include/libtrx/game/game_flow/sequencer.h b/src/libtrx/include/libtrx/game/game_flow/sequencer.h index c76f6ecc2..e97ebee84 100644 --- a/src/libtrx/include/libtrx/game/game_flow/sequencer.h +++ b/src/libtrx/include/libtrx/game/game_flow/sequencer.h @@ -7,4 +7,7 @@ GAME_FLOW_COMMAND GF_EnterPhotoMode(void); GAME_FLOW_COMMAND GF_PauseGame(void); GAME_FLOW_COMMAND GF_ShowInventory(INVENTORY_MODE inv_mode); GAME_FLOW_COMMAND GF_ShowInventoryKeys(GAME_OBJECT_ID receptacle_type_id); -GAME_FLOW_COMMAND GF_PlayCutscene(int32_t cutscene_num); +GAME_FLOW_COMMAND GF_RunDemo(int32_t demo_num); +GAME_FLOW_COMMAND GF_RunCutscene(int32_t cutscene_num); +GAME_FLOW_COMMAND GF_RunGame( + int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); diff --git a/src/tr1/game/game_flow/sequencer.c b/src/tr1/game/game_flow/sequencer.c index 8d5964e08..c7f3a030e 100644 --- a/src/tr1/game/game_flow/sequencer.c +++ b/src/tr1/game/game_flow/sequencer.c @@ -80,23 +80,20 @@ GF_InterpretSequence(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type) case GFS_PLAY_LEVEL: if (g_GameFlow.levels[level_num].level_type == GFL_CUTSCENE) { if (level_type != GFL_SAVED) { - command = GF_PlayCutscene((int32_t)(intptr_t)event->data); + command = GF_RunCutscene((int32_t)(intptr_t)event->data); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; } } } else if (level_type == GFL_DEMO) { - PHASE *const phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Demo_Destroy(phase); - return gf_cmd; + return GF_RunDemo(level_num); } else { if (level_type != GFL_SAVED && level_num != g_GameFlow.first_level_num) { Lara_RevertToPistolsIfNeeded(); } - command = GF_PlayLevel(level_num, level_type); + command = GF_RunGame(level_num, level_type); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; @@ -309,7 +306,7 @@ GF_StorySoFar(const GAME_FLOW_SEQUENCE *const sequence, int32_t savegame_level) case GFS_PLAY_LEVEL: { const int32_t level_num = (int32_t)(intptr_t)event->data; if (g_GameFlow.levels[level_num].level_type == GFL_CUTSCENE) { - command = GF_PlayCutscene((int32_t)(intptr_t)event->data); + command = GF_RunCutscene((int32_t)(intptr_t)event->data); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; @@ -395,23 +392,6 @@ GAME_FLOW_COMMAND GF_LoadLevel( return (GAME_FLOW_COMMAND) { .action = GF_NOOP }; } -GAME_FLOW_COMMAND GF_PlayLevel( - const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) -{ - PHASE *const phase = Phase_Game_Create(level_num, level_type); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Game_Destroy(phase); - return gf_cmd; -} - -GAME_FLOW_COMMAND GF_PlayDemo(const int32_t level_num) -{ - PHASE *const phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Demo_Destroy(phase); - return gf_cmd; -} - GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num) { const int32_t level_num = Demo_ChooseLevel(demo_num); diff --git a/src/tr1/game/game_flow/sequencer.h b/src/tr1/game/game_flow/sequencer.h index 020c4d5c7..91af575c6 100644 --- a/src/tr1/game/game_flow/sequencer.h +++ b/src/tr1/game/game_flow/sequencer.h @@ -7,6 +7,7 @@ GAME_FLOW_COMMAND GF_InterpretSequence(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num); +GAME_FLOW_COMMAND GF_DoCutsceneSequence(int32_t demo_num); GAME_FLOW_COMMAND GF_StorySoFar(const GAME_FLOW_SEQUENCE *sequence, int32_t savegame_level); GAME_FLOW_COMMAND GF_PlayAvailableStory(int32_t slot_num); diff --git a/src/tr2/game/game_flow/sequencer.c b/src/tr2/game/game_flow/sequencer.c index 3ad6ffd06..dc94e1050 100644 --- a/src/tr2/game/game_flow/sequencer.c +++ b/src/tr2/game/game_flow/sequencer.c @@ -22,20 +22,10 @@ GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num) return GF_InterpretSequence(&g_GameFlow.demos[demo_num].sequence, GFL_DEMO); } -GAME_FLOW_COMMAND GF_StartGame( - const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +GAME_FLOW_COMMAND GF_DoCutsceneSequence(const int32_t cutscene_num) { - if (level_type == GFL_DEMO) { - PHASE *const demo_phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(demo_phase); - Phase_Demo_Destroy(demo_phase); - return gf_cmd; - } else { - PHASE *const phase = Phase_Game_Create(level_num, level_type); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Game_Destroy(phase); - return gf_cmd; - } + return GF_InterpretSequence( + &g_GameFlow.cutscenes[cutscene_num].sequence, GFL_CUTSCENE); } bool GF_DoFrontendSequence(void) @@ -49,6 +39,43 @@ bool GF_DoFrontendSequence(void) return gf_cmd.action == GF_EXIT_GAME; } +GAME_FLOW_COMMAND GF_DoLevelSequence( + const int32_t start_level, const GAME_FLOW_LEVEL_TYPE type) +{ + GameStringTable_Apply(start_level); + int32_t current_level = start_level; + while (true) { + if (current_level > GF_GetLevelCount() - 1) { + return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; + } + + LOG_DEBUG("running sequence for level=%d type=%d", current_level, type); + const GAME_FLOW_COMMAND gf_cmd = GF_InterpretSequence( + &g_GameFlow.levels[current_level].sequence, type); + LOG_DEBUG("sequence finished"); + current_level++; + + if (g_GameFlow.single_level >= 0) { + return gf_cmd; + } + if (gf_cmd.action != GF_LEVEL_COMPLETE) { + return gf_cmd; + } + } +} + +GAME_FLOW_COMMAND GF_RunLevel( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + if (level_type == GFL_DEMO) { + return GF_RunDemo(level_num); + } else if (level_type == GFL_CUTSCENE) { + return GF_RunCutscene(level_num); + } else { + return GF_RunGame(level_num, level_type); + } +} + GAME_FLOW_COMMAND GF_InterpretSequence( const GAME_FLOW_SEQUENCE *sequence, GAME_FLOW_LEVEL_TYPE type) { @@ -95,7 +122,7 @@ GAME_FLOW_COMMAND GF_InterpretSequence( if (type == GFL_MID_STORY) { return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; } - gf_cmd = GF_StartGame(level_num, type); + gf_cmd = GF_RunLevel(level_num, type); if (type == GFL_SAVED) { type = GFL_NORMAL; } @@ -109,10 +136,7 @@ GAME_FLOW_COMMAND GF_InterpretSequence( case GFS_PLAY_CUTSCENE: { const int16_t cutscene_num = (int16_t)(intptr_t)event->data; if (type != GFL_SAVED) { - if (cutscene_num < 0 || cutscene_num >= GF_GetCutsceneCount()) { - LOG_ERROR("Invalid cutscene number: %d", cutscene_num); - } - gf_cmd = GF_PlayCutscene(cutscene_num); + gf_cmd = GF_DoCutsceneSequence(cutscene_num); if (gf_cmd.action != GF_NOOP && gf_cmd.action != GF_LEVEL_COMPLETE) { return gf_cmd; @@ -236,28 +260,3 @@ GAME_FLOW_COMMAND GF_InterpretSequence( } return gf_cmd; } - -GAME_FLOW_COMMAND GF_DoLevelSequence( - const int32_t start_level, const GAME_FLOW_LEVEL_TYPE type) -{ - GameStringTable_Apply(start_level); - int32_t current_level = start_level; - while (true) { - if (current_level > GF_GetLevelCount() - 1) { - return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; - } - - LOG_DEBUG("running sequence for level=%d type=%d", current_level, type); - const GAME_FLOW_COMMAND gf_cmd = GF_InterpretSequence( - &g_GameFlow.levels[current_level].sequence, type); - LOG_DEBUG("sequence finished"); - current_level++; - - if (g_GameFlow.single_level >= 0) { - return gf_cmd; - } - if (gf_cmd.action != GF_LEVEL_COMPLETE) { - return gf_cmd; - } - } -}