Skip to content

Commit

Permalink
tr1/cutscene: restore manual camera positioning
Browse files Browse the repository at this point in the history
Fixes #2739 by bringing back the cutscene positioning game flow events.
We had previously removed these in 718a1d7, thinking they didn't make a
difference. Albeit subtle, turns out they do.
  • Loading branch information
rr- committed Feb 1, 2025
1 parent 3bf7ad2 commit 6eabe8b
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 0 deletions.
2 changes: 2 additions & 0 deletions data/tr1/ship/cfg/TR1X_gameflow.json5
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@
],
"sequence": [
{"type": "load_level"},
{"type": "set_cutscene_pos", "x": 36668, "z": 63180},
{"type": "set_cutscene_angle", "value": -23312},
{"type": "play_level"},
],
Expand All @@ -475,6 +476,7 @@
],
"sequence": [
{"type": "load_level"},
{"type": "set_cutscene_pos", "x": 51962, "z": 53760},
{"type": "set_cutscene_angle", "value": 16380},
{"type": "mesh_swap", "object1_id": "player_1", "object2_id": "pistol_anim", "mesh_id": 1},
{"type": "mesh_swap", "object1_id": "player_1", "object2_id": "pistol_anim", "mesh_id": 4},
Expand Down
22 changes: 22 additions & 0 deletions docs/tr1/GAMEFLOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,28 @@ default gameflow for examples.
</td>
<td colspan="2" align="center">N/A</td>
</tr>
<tr valign="top">
<td rowspan="3">
<code>set_cutscene_pos</code>
</td>
<td>
<code><code>x</code></code>
</td>
<td>Integer</td>
<td colspan="3">Sets the camera's position.</td>
</tr>
<tr valign="top">
<td>
<code><code>y</code></code>
</td>
<td>Integer</td>
</tr>
<tr valign="top">
<td>
<code><code>z</code></code>
</td>
<td>Integer</td>
</tr>
<tr valign="top">
<td>
<code>set_cutscene_angle</code>
Expand Down
26 changes: 26 additions & 0 deletions src/libtrx/game/game_flow/reader_tr1.def.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// NOTE: this is an included file, not a compile unit on its own.
// This is to avoid exposing symbols.

static DECLARE_SEQUENCE_EVENT_HANDLER_FUNC(M_HandleSetCameraPosEvent);
static DECLARE_SEQUENCE_EVENT_HANDLER_FUNC(M_HandleTotalStatsEvent);
static DECLARE_SEQUENCE_EVENT_HANDLER_FUNC(M_HandleMeshSwapEvent);

Expand Down Expand Up @@ -43,6 +44,7 @@ static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = {
// Special cases with custom handlers
{ GFS_LOADING_SCREEN, M_HandlePictureEvent, nullptr },
{ GFS_DISPLAY_PICTURE, M_HandlePictureEvent, nullptr },
{ GFS_SET_CAMERA_POS, M_HandleSetCameraPosEvent, nullptr },
{ GFS_TOTAL_STATS, M_HandleTotalStatsEvent, nullptr },
{ GFS_ADD_ITEM, M_HandleAddItemEvent, nullptr },
{ GFS_MESH_SWAP, M_HandleMeshSwapEvent, nullptr },
Expand All @@ -52,6 +54,30 @@ static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = {
// clang-format on
};

static DECLARE_SEQUENCE_EVENT_HANDLER_FUNC(M_HandleSetCameraPosEvent)
{
if (event != nullptr) {
GF_SET_CAMERA_POS_DATA *const event_data = extra_data;
event_data->x.set = false;
event_data->y.set = false;
event_data->z.set = false;
if (JSON_ObjectContainsKey(event_obj, "x")) {
event_data->x.set = true;
event_data->x.value = JSON_ObjectGetInt(event_obj, "x", 0);
}
if (JSON_ObjectContainsKey(event_obj, "y")) {
event_data->y.set = true;
event_data->y.value = JSON_ObjectGetInt(event_obj, "y", 0);
}
if (JSON_ObjectContainsKey(event_obj, "z")) {
event_data->z.set = true;
event_data->z.value = JSON_ObjectGetInt(event_obj, "z", 0);
}
event->data = event_data;
}
return sizeof(GF_SET_CAMERA_POS_DATA);
}

static DECLARE_SEQUENCE_EVENT_HANDLER_FUNC(M_HandleTotalStatsEvent)
{
const char *const path =
Expand Down
1 change: 1 addition & 0 deletions src/libtrx/include/libtrx/game/enum_map.def
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_EXIT_TO_TITLE, "exit_to_title")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_LEVEL_COMPLETE, "level_complete")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_CAMERA_ANGLE, "set_cutscene_angle")
#if TR_VERSION == 1
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_CAMERA_POS, "set_cutscene_pos")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_FLIP_MAP, "flip_map")
#endif
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ADD_ITEM, "give_item")
Expand Down
1 change: 1 addition & 0 deletions src/libtrx/include/libtrx/game/game_flow/enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ typedef enum {
#if TR_VERSION == 1
GFS_LOADING_SCREEN,
GFS_LOAD_LEVEL,
GFS_SET_CAMERA_POS,
#endif
GFS_SET_CAMERA_ANGLE,
GFS_ADD_ITEM,
Expand Down
7 changes: 7 additions & 0 deletions src/libtrx/include/libtrx/game/game_flow/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ typedef struct {
float fade_out_time;
} GF_DISPLAY_PICTURE_DATA;

typedef struct {
struct {
bool set;
int32_t value;
} x, y, z;
} GF_SET_CAMERA_POS_DATA;

#if TR_VERSION == 2
typedef enum {
GF_INV_REGULAR,
Expand Down
19 changes: 19 additions & 0 deletions src/tr1/game/game_flow/sequencer.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ static DECLARE_EVENT_HANDLER(M_HandlePicture);
static DECLARE_EVENT_HANDLER(M_HandleLevelComplete);
static DECLARE_EVENT_HANDLER(M_HandleLevelStats);
static DECLARE_EVENT_HANDLER(M_HandleTotalStats);
static DECLARE_EVENT_HANDLER(M_HandleSetCameraPos);
static DECLARE_EVENT_HANDLER(M_HandleSetCameraAngle);
static DECLARE_EVENT_HANDLER(M_HandleFlipMap);
static DECLARE_EVENT_HANDLER(M_HandleAddItem);
Expand All @@ -55,6 +56,7 @@ static DECLARE_EVENT_HANDLER((*m_EventHandlers[GFS_NUMBER_OF])) = {
[GFS_LEVEL_COMPLETE] = M_HandleLevelComplete,
[GFS_LEVEL_STATS] = M_HandleLevelStats,
[GFS_TOTAL_STATS] = M_HandleTotalStats,
[GFS_SET_CAMERA_POS] = M_HandleSetCameraPos,
[GFS_SET_CAMERA_ANGLE] = M_HandleSetCameraAngle,
[GFS_FLIP_MAP] = M_HandleFlipMap,
[GFS_ADD_ITEM] = M_HandleAddItem,
Expand Down Expand Up @@ -357,6 +359,23 @@ static DECLARE_EVENT_HANDLER(M_HandleTotalStats)
return gf_cmd;
}

static DECLARE_EVENT_HANDLER(M_HandleSetCameraPos)
{
if (seq_ctx != GFSC_STORY) {
GF_SET_CAMERA_POS_DATA *const data = event->data;
if (data->x.set) {
g_CinePosition.pos.x = (int32_t)(intptr_t)data->x.value;
}
if (data->y.set) {
g_CinePosition.pos.y = (int32_t)(intptr_t)data->y.value;
}
if (data->z.set) {
g_CinePosition.pos.z = (int32_t)(intptr_t)data->z.value;
}
}
return (GF_COMMAND) { .action = GF_NOOP };
}

static DECLARE_EVENT_HANDLER(M_HandleSetCameraAngle)
{
if (seq_ctx != GFSC_STORY) {
Expand Down

0 comments on commit 6eabe8b

Please sign in to comment.