Skip to content

Commit

Permalink
tr2/phase: add suspend and resume functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rr- committed Dec 30, 2024
1 parent acda728 commit ec06b26
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
49 changes: 31 additions & 18 deletions src/tr2/game/phase/executor.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <stdbool.h>
#include <stddef.h>

#define MAX_PHASES 10
static int32_t m_PhaseStackSize = 0;
static PHASE *m_PhaseStack[MAX_PHASES] = {};

static PHASE_CONTROL M_Control(PHASE *phase, int32_t nframes);
static void M_Draw(PHASE *phase);
static int32_t M_Wait(PHASE *phase);
Expand Down Expand Up @@ -51,30 +55,38 @@ static int32_t M_Wait(PHASE *const phase)

GAME_FLOW_DIR PhaseExecutor_Run(PHASE *const phase)
{
PHASE_CONTROL control;
GAME_FLOW_DIR result = (GAME_FLOW_DIR)-1;

PHASE *const prev_phase =
m_PhaseStackSize > 0 ? m_PhaseStack[m_PhaseStackSize - 1] : NULL;
if (prev_phase != NULL && prev_phase->suspend != NULL) {
prev_phase->suspend(phase);
}
m_PhaseStack[m_PhaseStackSize++] = phase;

if (phase->start != NULL) {
control = phase->start(phase);
if (control.action == PHASE_ACTION_END) {
if (phase->end != NULL) {
phase->end(phase);
}
return control.dir;
} else if (g_IsGameToExit) {
if (phase->end != NULL) {
phase->end(phase);
}
return GFD_EXIT_GAME;
const PHASE_CONTROL control = phase->start(phase);
if (g_IsGameToExit) {
result = GFD_EXIT_GAME;
goto finish;
} else if (control.action == PHASE_ACTION_END) {
result = control.dir;
goto finish;
}
}

int32_t nframes = Clock_WaitTick();
while (true) {
control = M_Control(phase, nframes);
const PHASE_CONTROL control = M_Control(phase, nframes);

M_Draw(phase);
if (control.action == PHASE_ACTION_END) {
break;
if (g_IsGameToExit) {
result = GFD_EXIT_GAME;
} else {
result = control.dir;
}
goto finish;
} else if (control.action == PHASE_ACTION_NO_WAIT) {
nframes = 0;
continue;
Expand All @@ -83,13 +95,14 @@ GAME_FLOW_DIR PhaseExecutor_Run(PHASE *const phase)
}
}

finish:
if (phase->end != NULL) {
phase->end(phase);
}

if (g_IsGameToExit) {
return GFD_EXIT_GAME;
if (prev_phase != NULL && prev_phase->resume != NULL) {
prev_phase->resume(phase);
}
m_PhaseStackSize--;

return control.dir;
return result;
}
4 changes: 4 additions & 0 deletions src/tr2/game/phase/priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ typedef struct {

typedef PHASE_CONTROL (*PHASE_START_FUNC)(PHASE *phase);
typedef void (*PHASE_END_FUNC)(PHASE *phase);
typedef void (*PHASE_SUSPEND_FUNC)(PHASE *phase);
typedef void (*PHASE_RESUME_FUNC)(PHASE *phase);
typedef PHASE_CONTROL (*PHASE_CONTROL_FUNC)(PHASE *phase, int32_t num_frames);
typedef void (*PHASE_DRAW_FUNC)(PHASE *phase);
typedef int32_t (*PHASE_WAIT_FUNC)(PHASE *phase);

typedef struct PHASE {
PHASE_START_FUNC start;
PHASE_END_FUNC end;
PHASE_SUSPEND_FUNC suspend;
PHASE_RESUME_FUNC resume;
PHASE_CONTROL_FUNC control;
PHASE_DRAW_FUNC draw;
PHASE_WAIT_FUNC wait;
Expand Down

0 comments on commit ec06b26

Please sign in to comment.