Skip to content

Commit

Permalink
tr2/game-flow: make cutscenes run their sequences
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Jan 23, 2025
1 parent c67ca2e commit efa3d90
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 73 deletions.
10 changes: 6 additions & 4 deletions data/tr2/ship/cfg/TR2X_gameflow.json5
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
],
Expand Down Expand Up @@ -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"},
],
Expand Down Expand Up @@ -366,7 +364,8 @@
"path": "data/cut1.tr2",
"music_track": 3,
"sequence": [
{"type": "play_level"}
{"type": "set_cutscene_angle", "angle": 0},
{"type": "play_level"},
],
},
{
Expand All @@ -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"},
],
},
],

Expand Down
19 changes: 18 additions & 1 deletion src/libtrx/game/game_flow/sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
5 changes: 4 additions & 1 deletion src/libtrx/include/libtrx/game/game_flow/sequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
28 changes: 4 additions & 24 deletions src/tr1/game/game_flow/sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/tr1/game/game_flow/sequencer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
85 changes: 42 additions & 43 deletions src/tr2/game/game_flow/sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
}
}

0 comments on commit efa3d90

Please sign in to comment.