From 3eb67df257bb49013bbe9a3e42b649e4dc6152fb Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Thu, 20 Feb 2025 17:44:01 +0000
Subject: [PATCH 1/6] rooms: move no floor marker to TRX
This moves TR2's no floor indicator to TRX's room module.
---
src/libtrx/game/rooms/common.c | 11 +++++++++++
src/libtrx/include/libtrx/game/rooms/common.h | 3 +++
src/tr2/game/game_flow/sequencer_events.c | 6 +++---
src/tr2/game/lara/control.c | 2 +-
src/tr2/game/room.c | 2 +-
src/tr2/global/vars.c | 1 -
src/tr2/global/vars.h | 1 -
7 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c
index 7bb107ba6..04b078d56 100644
--- a/src/libtrx/game/rooms/common.c
+++ b/src/libtrx/game/rooms/common.c
@@ -32,6 +32,7 @@ static bool m_FlipStatus = false;
static int32_t m_FlipEffect = -1;
static int32_t m_FlipTimer = 0;
static int32_t m_FlipSlotFlags[MAX_FLIP_MAPS] = {};
+static int16_t m_NoFloorHeight = 0;
static const int16_t *M_ReadTrigger(
const int16_t *data, int16_t fd_entry, SECTOR *sector);
@@ -416,3 +417,13 @@ SECTOR *Room_GetUnitSector(
{
return &room->sectors[z_sector + x_sector * room->size.z];
}
+
+void Room_SetNoFloorHeight(const int16_t floor_height)
+{
+ m_NoFloorHeight = floor_height;
+}
+
+bool Room_IsNoFloorHeight(const int16_t height)
+{
+ return m_NoFloorHeight != 0 && height >= m_NoFloorHeight;
+}
diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h
index be704fe11..0fded45b8 100644
--- a/src/libtrx/include/libtrx/game/rooms/common.h
+++ b/src/libtrx/include/libtrx/game/rooms/common.h
@@ -35,3 +35,6 @@ BOUNDS_32 Room_GetWorldBounds(void);
SECTOR *Room_GetWorldSector(const ROOM *room, int32_t x_pos, int32_t z_pos);
SECTOR *Room_GetUnitSector(
const ROOM *room, int32_t x_sector, int32_t z_sector);
+
+void Room_SetNoFloorHeight(int16_t floor_height);
+bool Room_IsNoFloorHeight(int16_t height);
diff --git a/src/tr2/game/game_flow/sequencer_events.c b/src/tr2/game/game_flow/sequencer_events.c
index b8d1ca9e2..2151d2c45 100644
--- a/src/tr2/game/game_flow/sequencer_events.c
+++ b/src/tr2/game/game_flow/sequencer_events.c
@@ -31,7 +31,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetNumSecrets);
static DECLARE_GF_EVENT_HANDLER((*m_EventHandlers[GFS_NUMBER_OF])) = {
// clang-format off
- [GFS_LOOP_GAME] = M_HandlePlayLevel,
+ [GFS_LOOP_GAME] = M_HandlePlayLevel,
[GFS_PLAY_MUSIC] = M_HandlePlayMusic,
[GFS_LEVEL_COMPLETE] = M_HandleLevelComplete,
[GFS_ENABLE_SUNSET] = M_HandleEnableSunset,
@@ -200,7 +200,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor)
{
GF_COMMAND gf_cmd = { .action = GF_NOOP };
if (seq_ctx != GFSC_STORY) {
- g_GF_NoFloor = (int16_t)(intptr_t)event->data;
+ Room_SetNoFloorHeight((int16_t)(intptr_t)event->data);
}
return gf_cmd;
}
@@ -262,7 +262,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetNumSecrets)
void GF_PreSequenceHook(
const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg)
{
- g_GF_NoFloor = 0;
+ Room_SetNoFloorHeight(0);
Output_SetSunsetEnabled(false);
g_GF_LaraStartAnim = 0;
g_GF_RemoveAmmo = false;
diff --git a/src/tr2/game/lara/control.c b/src/tr2/game/lara/control.c
index 0d9e53592..ce2ac7db1 100644
--- a/src/tr2/game/lara/control.c
+++ b/src/tr2/game/lara/control.c
@@ -633,7 +633,7 @@ void Lara_Control(const int16_t item_num)
g_Lara.death_timer++;
return;
}
- } else if (g_GF_NoFloor && item->pos.y >= g_GF_NoFloor) {
+ } else if (Room_IsNoFloorHeight(item->pos.y)) {
item->hit_points = -1;
g_Lara.death_timer = 9 * FRAMES_PER_SECOND;
}
diff --git a/src/tr2/game/room.c b/src/tr2/game/room.c
index e9d5f7a62..0b5230819 100644
--- a/src/tr2/game/room.c
+++ b/src/tr2/game/room.c
@@ -644,7 +644,7 @@ int32_t Room_GetHeight(
const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
int32_t height = pit_sector->floor.height;
- if (g_GF_NoFloor && g_GF_NoFloor == height) {
+ if (Room_IsNoFloorHeight(height)) {
height = 0x4000;
} else {
height = M_GetFloorTiltHeight(pit_sector, x, z);
diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c
index d5dfc9603..a67237bfb 100644
--- a/src/tr2/global/vars.c
+++ b/src/tr2/global/vars.c
@@ -265,7 +265,6 @@ REQUEST_INFO g_SaveGameRequester = {
bool g_GF_RemoveAmmo = false;
bool g_GF_RemoveWeapons = false;
-int16_t g_GF_NoFloor = 0;
int16_t g_GF_NumSecrets = 3;
int32_t g_GF_LaraStartAnim;
int32_t g_GF_ScriptVersion;
diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h
index d966f5411..7640ba232 100644
--- a/src/tr2/global/vars.h
+++ b/src/tr2/global/vars.h
@@ -77,7 +77,6 @@ extern REQUEST_INFO g_SaveGameRequester;
extern bool g_GF_RemoveAmmo;
extern bool g_GF_RemoveWeapons;
-extern int16_t g_GF_NoFloor;
extern int16_t g_GF_NumSecrets;
extern int32_t g_GF_LaraStartAnim;
From 981d9999d403112ae535bd83f4c79e93af3ffe8d Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Fri, 21 Feb 2025 10:14:39 +0000
Subject: [PATCH 2/6] tr1/game_flow: add support for no floor
This adds support for no floor in TR1, in the same style as TR2's
Floating Islands.
Resolves #2541.
---
docs/GAME_FLOW.md | 2 +-
docs/tr1/CHANGELOG.md | 1 +
docs/tr1/README.md | 1 +
src/libtrx/game/game_flow/reader_tr1.def.c | 1 +
src/libtrx/include/libtrx/game/enum_map.def | 2 +-
src/libtrx/include/libtrx/game/game_flow/enum.h | 2 +-
src/tr1/game/game_flow/sequencer_events.c | 14 +++++++++++++-
src/tr1/game/lara/common.c | 3 +++
src/tr1/game/room.c | 8 +++++++-
9 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/docs/GAME_FLOW.md b/docs/GAME_FLOW.md
index fe25e2ea1..24226714a 100644
--- a/docs/GAME_FLOW.md
+++ b/docs/GAME_FLOW.md
@@ -841,7 +841,7 @@ default game flow for examples.
- disable_floor ² |
+ disable_floor |
value |
Integer |
diff --git a/docs/tr1/CHANGELOG.md b/docs/tr1/CHANGELOG.md
index dea5a5b2d..228644cee 100644
--- a/docs/tr1/CHANGELOG.md
+++ b/docs/tr1/CHANGELOG.md
@@ -1,4 +1,5 @@
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.3...develop) - ××××-××-××
+- added support for custom levels to use `disable_floor` in the gameflow, similar to TR2's Floating Islands (#2541)
## [4.8.3](https://github.com/LostArtefacts/TRX/compare/tr1-4.8.2...tr1-4.8.3) - 2025-02-17
- fixed some of Lara's speech in the gym not playing in response to player action (#2514, regression from 4.8)
diff --git a/docs/tr1/README.md b/docs/tr1/README.md
index da3a70707..d1570c335 100644
--- a/docs/tr1/README.md
+++ b/docs/tr1/README.md
@@ -402,6 +402,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- added a photo mode feature
- added optional automatic key/puzzle inventory item pre-selection
- added ability for falling pushblocks to kill Lara outright if one lands directly on her
+- added support for custom levels to define "no floor", to create an abyss like in TR2's Floating Islands
- changed weapon pickup behavior when unarmed to set any weapon as the default weapon, not just pistols
- fixed keys and items not working when drawing guns immediately after using them
- fixed counting the secret in The Great Pyramid
diff --git a/src/libtrx/game/game_flow/reader_tr1.def.c b/src/libtrx/game/game_flow/reader_tr1.def.c
index 4ae7d8191..34944fe87 100644
--- a/src/libtrx/game/game_flow/reader_tr1.def.c
+++ b/src/libtrx/game/game_flow/reader_tr1.def.c
@@ -32,6 +32,7 @@ static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = {
{ GFS_PLAY_MUSIC, M_HandleIntEvent, "music_track" },
{ GFS_SET_CAMERA_ANGLE, M_HandleIntEvent, "value" },
{ GFS_SETUP_BACON_LARA, M_HandleIntEvent, "anchor_room" },
+ { GFS_DISABLE_FLOOR, M_HandleIntEvent, "height" },
// Special cases with custom handlers
{ GFS_LOADING_SCREEN, M_HandlePictureEvent, nullptr },
diff --git a/src/libtrx/include/libtrx/game/enum_map.def b/src/libtrx/include/libtrx/game/enum_map.def
index 6d37d0ec5..48b3ac199 100644
--- a/src/libtrx/include/libtrx/game/enum_map.def
+++ b/src/libtrx/include/libtrx/game/enum_map.def
@@ -79,6 +79,7 @@ ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ADD_ITEM, "give_item")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_WEAPONS, "remove_weapons")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_AMMO, "remove_ammo")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_MEDIPACKS, "remove_medipacks")
+ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_DISABLE_FLOOR, "disable_floor")
#if TR_VERSION == 1
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_SCIONS, "remove_scions")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_MESH_SWAP, "mesh_swap")
@@ -88,7 +89,6 @@ ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_REMOVE_FLARES, "remove_flares")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ENABLE_SUNSET, "enable_sunset")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_NUM_SECRETS, "set_secret_count")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_SET_START_ANIM, "set_lara_start_anim")
-ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_DISABLE_FLOOR, "disable_floor")
ENUM_MAP_DEFINE(GF_SEQUENCE_EVENT_TYPE, GFS_ADD_SECRET_REWARD, "add_secret_reward")
#endif
diff --git a/src/libtrx/include/libtrx/game/game_flow/enum.h b/src/libtrx/include/libtrx/game/game_flow/enum.h
index 02e5bd561..4c51c5963 100644
--- a/src/libtrx/include/libtrx/game/game_flow/enum.h
+++ b/src/libtrx/include/libtrx/game/game_flow/enum.h
@@ -73,6 +73,7 @@ typedef enum {
GFS_REMOVE_WEAPONS,
GFS_REMOVE_AMMO,
GFS_REMOVE_MEDIPACKS,
+ GFS_DISABLE_FLOOR,
#if TR_VERSION == 1
GFS_REMOVE_SCIONS,
GFS_FLIP_MAP,
@@ -82,7 +83,6 @@ typedef enum {
GFS_REMOVE_FLARES,
GFS_SET_START_ANIM,
GFS_SET_NUM_SECRETS,
- GFS_DISABLE_FLOOR,
GFS_ENABLE_SUNSET,
GFS_ADD_SECRET_REWARD,
#endif
diff --git a/src/tr1/game/game_flow/sequencer_events.c b/src/tr1/game/game_flow/sequencer_events.c
index d0ff9fc9d..04d57a971 100644
--- a/src/tr1/game/game_flow/sequencer_events.c
+++ b/src/tr1/game/game_flow/sequencer_events.c
@@ -22,6 +22,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandlePlayMusic);
static DECLARE_GF_EVENT_HANDLER(M_HandleLevelComplete);
static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraPos);
static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraAngle);
+static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor);
static DECLARE_GF_EVENT_HANDLER(M_HandleFlipMap);
static DECLARE_GF_EVENT_HANDLER(M_HandleAddItem);
static DECLARE_GF_EVENT_HANDLER(M_HandleRemoveWeapons);
@@ -33,11 +34,12 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetupBaconLara);
static DECLARE_GF_EVENT_HANDLER((*m_EventHandlers[GFS_NUMBER_OF])) = {
// clang-format off
- [GFS_LOOP_GAME] = M_HandlePlayLevel,
+ [GFS_LOOP_GAME] = M_HandlePlayLevel,
[GFS_PLAY_MUSIC] = M_HandlePlayMusic,
[GFS_LEVEL_COMPLETE] = M_HandleLevelComplete,
[GFS_SET_CAMERA_POS] = M_HandleSetCameraPos,
[GFS_SET_CAMERA_ANGLE] = M_HandleSetCameraAngle,
+ [GFS_DISABLE_FLOOR] = M_HandleDisableFloor,
[GFS_FLIP_MAP] = M_HandleFlipMap,
[GFS_ADD_ITEM] = M_HandleAddItem,
[GFS_REMOVE_WEAPONS] = M_HandleRemoveWeapons,
@@ -272,6 +274,15 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetCameraAngle)
return (GF_COMMAND) { .action = GF_NOOP };
}
+static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor)
+{
+ GF_COMMAND gf_cmd = { .action = GF_NOOP };
+ if (seq_ctx != GFSC_STORY) {
+ Room_SetNoFloorHeight((int16_t)(intptr_t)event->data);
+ }
+ return gf_cmd;
+}
+
static DECLARE_GF_EVENT_HANDLER(M_HandleFlipMap)
{
if (seq_ctx != GFSC_STORY) {
@@ -349,6 +360,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetupBaconLara)
void GF_PreSequenceHook(
const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg)
{
+ Room_SetNoFloorHeight(0);
g_GameInfo.remove_guns = false;
g_GameInfo.remove_scions = false;
g_GameInfo.remove_ammo = false;
diff --git a/src/tr1/game/lara/common.c b/src/tr1/game/lara/common.c
index f5b91ac86..971464d18 100644
--- a/src/tr1/game/lara/common.c
+++ b/src/tr1/game/lara/common.c
@@ -285,6 +285,9 @@ void Lara_Control(void)
if (g_LaraItem->flags & IF_INVISIBLE) {
return;
}
+ } else if (Room_IsNoFloorHeight(item->pos.y)) {
+ item->hit_points = -1;
+ g_Lara.death_timer = 9 * LOGIC_FPS;
}
Camera_MoveManual();
diff --git a/src/tr1/game/room.c b/src/tr1/game/room.c
index f223afa9e..9386708f2 100644
--- a/src/tr1/game/room.c
+++ b/src/tr1/game/room.c
@@ -281,7 +281,13 @@ int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z)
g_HeightType = HT_WALL;
sector = Room_GetPitSector(sector, x, z);
- int16_t height = M_GetFloorTiltHeight(sector, x, z);
+ int32_t height = sector->floor.height;
+
+ if (Room_IsNoFloorHeight(height)) {
+ height = 0x4000;
+ } else {
+ height = M_GetFloorTiltHeight(sector, x, z);
+ }
if (sector->trigger == nullptr) {
return height;
From 484a3dcca5abc1c1fb1519be55fc2809361c8071 Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Fri, 21 Feb 2025 10:41:48 +0000
Subject: [PATCH 3/6] rooms: move floor height function to TRX
This moves Room_GetHeight to TRX, which in turn allows us to eliminate
g_HeightType.
---
src/libtrx/game/rooms/common.c | 87 +++++++++++++++++++
src/libtrx/include/libtrx/game/rooms/common.h | 3 +
src/libtrx/include/libtrx/game/rooms/enum.h | 6 ++
src/tr1/game/collide.c | 8 +-
src/tr1/game/room.c | 80 -----------------
src/tr1/game/room.h | 2 -
src/tr1/global/types.h | 6 --
src/tr1/global/vars.c | 1 -
src/tr1/global/vars.h | 1 -
src/tr2/decomp/skidoo.c | 2 +-
src/tr2/game/collide.c | 8 +-
src/tr2/game/objects/general/movable_block.c | 2 +-
src/tr2/game/room.c | 80 -----------------
src/tr2/game/room.h | 2 -
src/tr2/global/types_decomp.h | 6 --
src/tr2/global/vars.c | 1 -
src/tr2/global/vars.h | 1 -
17 files changed, 106 insertions(+), 190 deletions(-)
diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c
index 04b078d56..5288a563b 100644
--- a/src/libtrx/game/rooms/common.c
+++ b/src/libtrx/game/rooms/common.c
@@ -1,6 +1,7 @@
#include "game/rooms/common.h"
#include "debug.h"
+#include "game/camera.h"
#include "game/const.h"
#include "game/game_buf.h"
#include "game/items.h"
@@ -33,11 +34,13 @@ static int32_t m_FlipEffect = -1;
static int32_t m_FlipTimer = 0;
static int32_t m_FlipSlotFlags[MAX_FLIP_MAPS] = {};
static int16_t m_NoFloorHeight = 0;
+static HEIGHT_TYPE m_HeightType = HT_WALL;
static const int16_t *M_ReadTrigger(
const int16_t *data, int16_t fd_entry, SECTOR *sector);
static void M_AddFlipItems(const ROOM *room);
static void M_RemoveFlipItems(const ROOM *room);
+static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z);
static const int16_t *M_ReadTrigger(
const int16_t *data, const int16_t fd_entry, SECTOR *const sector)
@@ -146,6 +149,40 @@ static void M_RemoveFlipItems(const ROOM *const room)
}
}
+static int16_t M_GetFloorTiltHeight(
+ const SECTOR *const sector, const int32_t x, const int32_t z)
+{
+ int16_t height = sector->floor.height;
+ if (sector->floor.tilt == 0) {
+ return height;
+ }
+
+ const int32_t z_off = sector->floor.tilt >> 8;
+ const int32_t x_off = (int8_t)sector->floor.tilt;
+
+ const HEIGHT_TYPE slope_type =
+ (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE;
+ if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) {
+ return height;
+ }
+
+ m_HeightType = slope_type;
+
+ if (z_off < 0) {
+ height -= (int16_t)NEG_TILT(z_off, z);
+ } else {
+ height += (int16_t)POS_TILT(z_off, z);
+ }
+
+ if (x_off < 0) {
+ height -= (int16_t)NEG_TILT(x_off, x);
+ } else {
+ height += (int16_t)POS_TILT(x_off, x);
+ }
+
+ return height;
+}
+
void Room_InitialiseRooms(const int32_t num_rooms)
{
m_RoomCount = num_rooms;
@@ -418,6 +455,17 @@ SECTOR *Room_GetUnitSector(
return &room->sectors[z_sector + x_sector * room->size.z];
}
+SECTOR *Room_GetPitSector(
+ const SECTOR *sector, const int32_t x, const int32_t z)
+{
+ while (sector->portal_room.pit != NO_ROOM) {
+ const ROOM *const room = Room_Get(sector->portal_room.pit);
+ sector = Room_GetWorldSector(room, x, z);
+ }
+
+ return (SECTOR *)sector;
+}
+
void Room_SetNoFloorHeight(const int16_t floor_height)
{
m_NoFloorHeight = floor_height;
@@ -427,3 +475,42 @@ bool Room_IsNoFloorHeight(const int16_t height)
{
return m_NoFloorHeight != 0 && height >= m_NoFloorHeight;
}
+
+HEIGHT_TYPE Room_GetHeightType(void)
+{
+ return m_HeightType;
+}
+
+int16_t Room_GetHeight(
+ const SECTOR *sector, const int32_t x, const int32_t y, const int32_t z)
+{
+ m_HeightType = HT_WALL;
+
+ const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
+ int32_t height = pit_sector->floor.height;
+
+ if (Room_IsNoFloorHeight(height)) {
+ height = 0x4000;
+ } else {
+ height = M_GetFloorTiltHeight(pit_sector, x, z);
+ }
+
+ if (pit_sector->trigger == nullptr) {
+ return height;
+ }
+
+ const TRIGGER_CMD *cmd = pit_sector->trigger->command;
+ for (; cmd != nullptr; cmd = cmd->next_cmd) {
+ if (cmd->type != TO_OBJECT) {
+ continue;
+ }
+
+ const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
+ const OBJECT *const obj = Object_Get(item->object_id);
+ if (obj->floor_height_func != nullptr) {
+ height = obj->floor_height_func(item, x, y, z, height);
+ }
+ }
+
+ return height;
+}
diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h
index 0fded45b8..b75d45072 100644
--- a/src/libtrx/include/libtrx/game/rooms/common.h
+++ b/src/libtrx/include/libtrx/game/rooms/common.h
@@ -35,6 +35,9 @@ BOUNDS_32 Room_GetWorldBounds(void);
SECTOR *Room_GetWorldSector(const ROOM *room, int32_t x_pos, int32_t z_pos);
SECTOR *Room_GetUnitSector(
const ROOM *room, int32_t x_sector, int32_t z_sector);
+SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
void Room_SetNoFloorHeight(int16_t floor_height);
bool Room_IsNoFloorHeight(int16_t height);
+HEIGHT_TYPE Room_GetHeightType(void);
+int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
diff --git a/src/libtrx/include/libtrx/game/rooms/enum.h b/src/libtrx/include/libtrx/game/rooms/enum.h
index 0f85e8799..8dcbab259 100644
--- a/src/libtrx/include/libtrx/game/rooms/enum.h
+++ b/src/libtrx/include/libtrx/game/rooms/enum.h
@@ -1,5 +1,11 @@
#pragma once
+typedef enum {
+ HT_WALL = 0,
+ HT_SMALL_SLOPE = 1,
+ HT_BIG_SLOPE = 2,
+} HEIGHT_TYPE;
+
typedef enum {
RF_UNDERWATER = 0x01,
RF_OUTSIDE = 0x08,
diff --git a/src/tr1/game/collide.c b/src/tr1/game/collide.c
index b21f04adf..35c64fb16 100644
--- a/src/tr1/game/collide.c
+++ b/src/tr1/game/collide.c
@@ -41,7 +41,7 @@ void Collide_GetCollisionInfo(
coll->mid_floor = height;
coll->mid_ceiling = ceiling;
- coll->mid_type = g_HeightType;
+ coll->mid_type = Room_GetHeightType();
if (!g_Config.gameplay.fix_bridge_collision
|| !Room_IsOnWalkable(sector, x, ytop, z, room_height)) {
@@ -123,7 +123,7 @@ void Collide_GetCollisionInfo(
coll->front_floor = height;
coll->front_ceiling = ceiling;
- coll->front_type = g_HeightType;
+ coll->front_type = Room_GetHeightType();
if (!g_Config.gameplay.fix_bridge_collision
|| !Room_IsOnWalkable(sector, x, ytop, z, room_height)) {
@@ -158,7 +158,7 @@ void Collide_GetCollisionInfo(
coll->left_floor = height;
coll->left_ceiling = ceiling;
- coll->left_type = g_HeightType;
+ coll->left_type = Room_GetHeightType();
if (!g_Config.gameplay.fix_bridge_collision
|| !Room_IsOnWalkable(sector, x, ytop, z, room_height)) {
@@ -193,7 +193,7 @@ void Collide_GetCollisionInfo(
coll->right_floor = height;
coll->right_ceiling = ceiling;
- coll->right_type = g_HeightType;
+ coll->right_type = Room_GetHeightType();
if (!g_Config.gameplay.fix_bridge_collision
|| !Room_IsOnWalkable(sector, x, ytop, z, room_height)) {
diff --git a/src/tr1/game/room.c b/src/tr1/game/room.c
index 9386708f2..d0fcbd66f 100644
--- a/src/tr1/game/room.c
+++ b/src/tr1/game/room.c
@@ -21,8 +21,6 @@
static void M_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger);
-static int16_t M_GetFloorTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z);
static int16_t M_GetCeilingTiltHeight(
const SECTOR *sector, const int32_t x, const int32_t z);
static SECTOR *M_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
@@ -162,17 +160,6 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num)
Room_MarkToBeDrawn(room_num);
}
-SECTOR *Room_GetPitSector(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- while (sector->portal_room.pit != NO_ROOM) {
- const ROOM *const room = Room_Get(sector->portal_room.pit);
- sector = Room_GetWorldSector(room, x, z);
- }
-
- return (SECTOR *)sector;
-}
-
static SECTOR *M_GetSkySector(
const SECTOR *sector, const int32_t x, const int32_t z)
{
@@ -276,73 +263,6 @@ int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z)
return height;
}
-int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z)
-{
- g_HeightType = HT_WALL;
- sector = Room_GetPitSector(sector, x, z);
-
- int32_t height = sector->floor.height;
-
- if (Room_IsNoFloorHeight(height)) {
- height = 0x4000;
- } else {
- height = M_GetFloorTiltHeight(sector, x, z);
- }
-
- if (sector->trigger == nullptr) {
- return height;
- }
-
- const TRIGGER_CMD *cmd = sector->trigger->command;
- for (; cmd != nullptr; cmd = cmd->next_cmd) {
- if (cmd->type != TO_OBJECT) {
- continue;
- }
-
- const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
- const OBJECT *const obj = Object_Get(item->object_id);
- if (obj->floor_height_func != nullptr) {
- height = obj->floor_height_func(item, x, y, z, height);
- }
- }
-
- return height;
-}
-
-static int16_t M_GetFloorTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- int16_t height = sector->floor.height;
- if (sector->floor.tilt == 0) {
- return height;
- }
-
- const int32_t z_off = sector->floor.tilt >> 8;
- const int32_t x_off = (int8_t)sector->floor.tilt;
-
- const HEIGHT_TYPE slope_type =
- (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE;
- if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) {
- return height;
- }
-
- g_HeightType = slope_type;
-
- if (z_off < 0) {
- height -= (int16_t)NEG_TILT(z_off, z);
- } else {
- height += (int16_t)POS_TILT(z_off, z);
- }
-
- if (x_off < 0) {
- height -= (int16_t)NEG_TILT(x_off, x);
- } else {
- height += (int16_t)POS_TILT(x_off, x);
- }
-
- return height;
-}
-
static int16_t M_GetCeilingTiltHeight(
const SECTOR *sector, const int32_t x, const int32_t z)
{
diff --git a/src/tr1/game/room.h b/src/tr1/game/room.h
index c12aeb3d0..6b47c1391 100644
--- a/src/tr1/game/room.h
+++ b/src/tr1/game/room.h
@@ -13,9 +13,7 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num);
void Room_GetNearByRooms(
int32_t x, int32_t y, int32_t z, int32_t r, int32_t h, int16_t room_num);
SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num);
-SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
-int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num);
void Room_TestTriggers(const ITEM *item);
diff --git a/src/tr1/global/types.h b/src/tr1/global/types.h
index 09505a9c4..316a4cdd8 100644
--- a/src/tr1/global/types.h
+++ b/src/tr1/global/types.h
@@ -58,12 +58,6 @@ typedef enum {
COLL_CLAMP = 32,
} COLL_TYPE;
-typedef enum {
- HT_WALL = 0,
- HT_SMALL_SLOPE = 1,
- HT_BIG_SLOPE = 2,
-} HEIGHT_TYPE;
-
typedef enum {
IC_BLACK = 0,
IC_GREY = 1,
diff --git a/src/tr1/global/vars.c b/src/tr1/global/vars.c
index 8d914491d..d15f20fdb 100644
--- a/src/tr1/global/vars.c
+++ b/src/tr1/global/vars.c
@@ -19,7 +19,6 @@ int32_t g_SavedGamesCount = 0;
int32_t g_SaveCounter = 0;
bool g_LevelComplete = false;
int32_t g_OverlayFlag = 0;
-int32_t g_HeightType = 0;
INVENTORY_MODE g_InvMode;
diff --git a/src/tr1/global/vars.h b/src/tr1/global/vars.h
index a2ee2ca45..b0d83e4e5 100644
--- a/src/tr1/global/vars.h
+++ b/src/tr1/global/vars.h
@@ -27,7 +27,6 @@ extern int32_t g_SavedGamesCount;
extern int32_t g_SaveCounter;
extern bool g_LevelComplete;
extern int32_t g_OverlayFlag;
-extern int32_t g_HeightType;
extern REQUEST_INFO g_SavegameRequester;
diff --git a/src/tr2/decomp/skidoo.c b/src/tr2/decomp/skidoo.c
index 045340d7a..5b511397f 100644
--- a/src/tr2/decomp/skidoo.c
+++ b/src/tr2/decomp/skidoo.c
@@ -559,7 +559,7 @@ int32_t Skidoo_CheckGetOffOK(int32_t direction)
const SECTOR *const sector = Room_GetSector(x, y, z, &room_num);
const int32_t height = Room_GetHeight(sector, x, y, z);
- if (g_HeightType == HT_BIG_SLOPE || height == NO_HEIGHT) {
+ if (Room_GetHeightType() == HT_BIG_SLOPE || height == NO_HEIGHT) {
return false;
}
diff --git a/src/tr2/game/collide.c b/src/tr2/game/collide.c
index 568e1b383..1aeeb5ae8 100644
--- a/src/tr2/game/collide.c
+++ b/src/tr2/game/collide.c
@@ -40,7 +40,7 @@ void Collide_GetCollisionInfo(
coll->side_mid.floor = height;
coll->side_mid.ceiling = ceiling;
- coll->side_mid.type = g_HeightType;
+ coll->side_mid.type = Room_GetHeightType();
const int16_t tilt = Room_GetTiltType(sector, x, g_LaraItem->pos.y, z);
coll->z_tilt = tilt >> 8;
@@ -113,7 +113,7 @@ void Collide_GetCollisionInfo(
coll->side_front.floor = height;
coll->side_front.ceiling = ceiling;
- coll->side_front.type = g_HeightType;
+ coll->side_front.type = Room_GetHeightType();
if (coll->slopes_are_walls && coll->side_front.type == HT_BIG_SLOPE
&& coll->side_front.floor < 0) {
coll->side_front.floor = -32767;
@@ -141,7 +141,7 @@ void Collide_GetCollisionInfo(
coll->side_left.floor = height;
coll->side_left.ceiling = ceiling;
- coll->side_left.type = g_HeightType;
+ coll->side_left.type = Room_GetHeightType();
if (coll->slopes_are_walls && coll->side_left.type == HT_BIG_SLOPE
&& coll->side_left.floor < 0) {
coll->side_left.floor = -32767;
@@ -169,7 +169,7 @@ void Collide_GetCollisionInfo(
coll->side_right.floor = height;
coll->side_right.ceiling = ceiling;
- coll->side_right.type = g_HeightType;
+ coll->side_right.type = Room_GetHeightType();
if (coll->slopes_are_walls && coll->side_right.type == HT_BIG_SLOPE
&& coll->side_right.floor < 0) {
coll->side_right.floor = -32767;
diff --git a/src/tr2/game/objects/general/movable_block.c b/src/tr2/game/objects/general/movable_block.c
index 5c3a63ca8..bf48ed9a4 100644
--- a/src/tr2/game/objects/general/movable_block.c
+++ b/src/tr2/game/objects/general/movable_block.c
@@ -103,7 +103,7 @@ static bool M_TestPush(
}
Room_GetHeight(sector, x, y, z);
- if (g_HeightType != HT_WALL) {
+ if (Room_GetHeightType() != HT_WALL) {
return false;
}
diff --git a/src/tr2/game/room.c b/src/tr2/game/room.c
index 0b5230819..d2b69320e 100644
--- a/src/tr2/game/room.c
+++ b/src/tr2/game/room.c
@@ -20,47 +20,12 @@
#include
void Room_MarkToBeDrawn(int16_t room_num);
-static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z);
static int16_t M_GetCeilingTiltHeight(
const SECTOR *sector, int32_t x, int32_t z);
static void M_TriggerMusicTrack(int16_t track, const TRIGGER *trigger);
static bool M_TestLava(const ITEM *item);
-static int16_t M_GetFloorTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- int16_t height = sector->floor.height;
- if (sector->floor.tilt == 0) {
- return height;
- }
-
- const int32_t z_off = sector->floor.tilt >> 8;
- const int32_t x_off = (int8_t)sector->floor.tilt;
-
- const HEIGHT_TYPE slope_type =
- (ABS(z_off) > 2 || ABS(x_off) > 2) ? HT_BIG_SLOPE : HT_SMALL_SLOPE;
- if (Camera_IsChunky() && slope_type == HT_BIG_SLOPE) {
- return height;
- }
-
- g_HeightType = slope_type;
-
- if (z_off < 0) {
- height -= (int16_t)NEG_TILT(z_off, z);
- } else {
- height += (int16_t)POS_TILT(z_off, z);
- }
-
- if (x_off < 0) {
- height -= (int16_t)NEG_TILT(x_off, x);
- } else {
- height += (int16_t)POS_TILT(x_off, x);
- }
-
- return height;
-}
-
static int16_t M_GetCeilingTiltHeight(
const SECTOR *sector, const int32_t x, const int32_t z)
{
@@ -496,17 +461,6 @@ int16_t Room_GetTiltType(
return sector->floor.tilt;
}
-SECTOR *Room_GetPitSector(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- while (sector->portal_room.pit != NO_ROOM) {
- const ROOM *const room = Room_Get(sector->portal_room.pit);
- sector = Room_GetWorldSector(room, x, z);
- }
-
- return (SECTOR *)sector;
-}
-
SECTOR *Room_GetSkySector(
const SECTOR *sector, const int32_t x, const int32_t z)
{
@@ -636,40 +590,6 @@ int32_t Room_GetWaterHeight(
}
}
-int32_t Room_GetHeight(
- const SECTOR *sector, const int32_t x, const int32_t y, const int32_t z)
-{
- g_HeightType = 0;
-
- const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
- int32_t height = pit_sector->floor.height;
-
- if (Room_IsNoFloorHeight(height)) {
- height = 0x4000;
- } else {
- height = M_GetFloorTiltHeight(pit_sector, x, z);
- }
-
- if (pit_sector->trigger == nullptr) {
- return height;
- }
-
- const TRIGGER_CMD *cmd = pit_sector->trigger->command;
- for (; cmd != nullptr; cmd = cmd->next_cmd) {
- if (cmd->type != TO_OBJECT) {
- continue;
- }
-
- const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
- const OBJECT *const obj = Object_Get(item->object_id);
- if (obj->floor_height_func != nullptr) {
- height = obj->floor_height_func(item, x, y, z, height);
- }
- }
-
- return height;
-}
-
void Room_TestTriggers(const ITEM *const item)
{
int16_t room_num = item->room_num;
diff --git a/src/tr2/game/room.h b/src/tr2/game/room.h
index ecdda372d..c36fb71b0 100644
--- a/src/tr2/game/room.h
+++ b/src/tr2/game/room.h
@@ -15,12 +15,10 @@ int16_t Room_GetTiltType(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
// TODO: poor abstraction
void Room_InitCinematic(void);
-SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num);
int32_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num);
-int32_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
int32_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
void Room_TestTriggers(const ITEM *item);
diff --git a/src/tr2/global/types_decomp.h b/src/tr2/global/types_decomp.h
index 0ebd67542..83949787c 100644
--- a/src/tr2/global/types_decomp.h
+++ b/src/tr2/global/types_decomp.h
@@ -232,12 +232,6 @@ typedef enum {
COLL_CLAMP = 0x20,
} COLL_TYPE;
-typedef enum {
- HT_WALL = 0,
- HT_SMALL_SLOPE = 1,
- HT_BIG_SLOPE = 2,
-} HEIGHT_TYPE;
-
typedef struct {
int32_t boat_turn;
int32_t left_fallspeed;
diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c
index a67237bfb..bda567bfd 100644
--- a/src/tr2/global/vars.c
+++ b/src/tr2/global/vars.c
@@ -64,7 +64,6 @@ LARA_INFO g_Lara;
ITEM *g_LaraItem = nullptr;
CREATURE *g_BaddieSlots = nullptr;
-int32_t g_HeightType;
bool g_CameraUnderwater;
char g_LevelFileName[256];
diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h
index 7640ba232..8d7b5c582 100644
--- a/src/tr2/global/vars.h
+++ b/src/tr2/global/vars.h
@@ -64,7 +64,6 @@ extern SAVEGAME_INFO g_SaveGame;
extern LARA_INFO g_Lara;
extern ITEM *g_LaraItem;
extern CREATURE *g_BaddieSlots;
-extern int32_t g_HeightType;
extern bool g_CameraUnderwater;
extern char g_LevelFileName[256];
extern WEAPON_INFO g_Weapons[];
From 5c1dcb0d217f5629f482b75092254455dc1fc96b Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Fri, 21 Feb 2025 10:52:46 +0000
Subject: [PATCH 4/6] rooms: move ceiling height function to TRX
This moves Room_GetCeiling to TRX.
---
src/libtrx/game/rooms/common.c | 71 +++++++++++++++++
src/libtrx/include/libtrx/game/rooms/common.h | 2 +
src/tr1/game/room.c | 76 +------------------
src/tr1/game/room.h | 1 -
src/tr2/game/room.c | 71 -----------------
src/tr2/game/room.h | 2 -
6 files changed, 74 insertions(+), 149 deletions(-)
diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c
index 5288a563b..f3c6a5ebf 100644
--- a/src/libtrx/game/rooms/common.c
+++ b/src/libtrx/game/rooms/common.c
@@ -41,6 +41,8 @@ static const int16_t *M_ReadTrigger(
static void M_AddFlipItems(const ROOM *room);
static void M_RemoveFlipItems(const ROOM *room);
static int16_t M_GetFloorTiltHeight(const SECTOR *sector, int32_t x, int32_t z);
+static int16_t M_GetCeilingTiltHeight(
+ const SECTOR *sector, int32_t x, int32_t z);
static const int16_t *M_ReadTrigger(
const int16_t *data, const int16_t fd_entry, SECTOR *const sector)
@@ -183,6 +185,36 @@ static int16_t M_GetFloorTiltHeight(
return height;
}
+static int16_t M_GetCeilingTiltHeight(
+ const SECTOR *sector, const int32_t x, const int32_t z)
+{
+ int16_t height = sector->ceiling.height;
+ if (sector->ceiling.tilt == 0) {
+ return height;
+ }
+
+ const int32_t z_off = sector->ceiling.tilt >> 8;
+ const int32_t x_off = (int8_t)sector->ceiling.tilt;
+
+ if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) {
+ return height;
+ }
+
+ if (z_off < 0) {
+ height += (int16_t)NEG_TILT(z_off, z);
+ } else {
+ height -= (int16_t)POS_TILT(z_off, z);
+ }
+
+ if (x_off < 0) {
+ height += (int16_t)POS_TILT(x_off, x);
+ } else {
+ height -= (int16_t)NEG_TILT(x_off, x);
+ }
+
+ return height;
+}
+
void Room_InitialiseRooms(const int32_t num_rooms)
{
m_RoomCount = num_rooms;
@@ -466,6 +498,17 @@ SECTOR *Room_GetPitSector(
return (SECTOR *)sector;
}
+SECTOR *Room_GetSkySector(
+ const SECTOR *sector, const int32_t x, const int32_t z)
+{
+ while (sector->portal_room.sky != NO_ROOM) {
+ const ROOM *const room = Room_Get(sector->portal_room.sky);
+ sector = Room_GetWorldSector(room, x, z);
+ }
+
+ return (SECTOR *)sector;
+}
+
void Room_SetNoFloorHeight(const int16_t floor_height)
{
m_NoFloorHeight = floor_height;
@@ -514,3 +557,31 @@ int16_t Room_GetHeight(
return height;
}
+
+int16_t Room_GetCeiling(
+ const SECTOR *const sector, const int32_t x, const int32_t y,
+ const int32_t z)
+{
+ const SECTOR *const sky_sector = Room_GetSkySector(sector, x, z);
+ int16_t height = M_GetCeilingTiltHeight(sky_sector, x, z);
+
+ const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
+ if (pit_sector->trigger == nullptr) {
+ return height;
+ }
+
+ const TRIGGER_CMD *cmd = pit_sector->trigger->command;
+ for (; cmd != nullptr; cmd = cmd->next_cmd) {
+ if (cmd->type != TO_OBJECT) {
+ continue;
+ }
+
+ const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
+ const OBJECT *const obj = Object_Get(item->object_id);
+ if (obj->ceiling_height_func != nullptr) {
+ height = obj->ceiling_height_func(item, x, y, z, height);
+ }
+ }
+
+ return height;
+}
diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h
index b75d45072..f44c2116e 100644
--- a/src/libtrx/include/libtrx/game/rooms/common.h
+++ b/src/libtrx/include/libtrx/game/rooms/common.h
@@ -36,8 +36,10 @@ SECTOR *Room_GetWorldSector(const ROOM *room, int32_t x_pos, int32_t z_pos);
SECTOR *Room_GetUnitSector(
const ROOM *room, int32_t x_sector, int32_t z_sector);
SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
+SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
void Room_SetNoFloorHeight(int16_t floor_height);
bool Room_IsNoFloorHeight(int16_t height);
HEIGHT_TYPE Room_GetHeightType(void);
int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
+int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
diff --git a/src/tr1/game/room.c b/src/tr1/game/room.c
index d0fcbd66f..56784c9e0 100644
--- a/src/tr1/game/room.c
+++ b/src/tr1/game/room.c
@@ -21,9 +21,6 @@
static void M_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger);
-static int16_t M_GetCeilingTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z);
-static SECTOR *M_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
static bool M_TestLava(const ITEM *const item);
static void M_TriggerMusicTrack(int16_t track, const TRIGGER *const trigger)
@@ -160,17 +157,6 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num)
Room_MarkToBeDrawn(room_num);
}
-static SECTOR *M_GetSkySector(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- while (sector->portal_room.sky != NO_ROOM) {
- const ROOM *const room = Room_Get(sector->portal_room.sky);
- sector = Room_GetWorldSector(room, x, z);
- }
-
- return (SECTOR *)sector;
-}
-
SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num)
{
int16_t portal_room;
@@ -233,66 +219,6 @@ SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num)
return sector;
}
-int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z)
-{
- int16_t *data;
- int16_t type;
- int16_t trigger;
-
- const SECTOR *const sky_sector = M_GetSkySector(sector, x, z);
- int16_t height = M_GetCeilingTiltHeight(sky_sector, x, z);
-
- sector = Room_GetPitSector(sector, x, z);
- if (sector->trigger == nullptr) {
- return height;
- }
-
- const TRIGGER_CMD *cmd = sector->trigger->command;
- for (; cmd != nullptr; cmd = cmd->next_cmd) {
- if (cmd->type != TO_OBJECT) {
- continue;
- }
-
- const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
- const OBJECT *const obj = Object_Get(item->object_id);
- if (obj->ceiling_height_func != nullptr) {
- height = obj->ceiling_height_func(item, x, y, z, height);
- }
- }
-
- return height;
-}
-
-static int16_t M_GetCeilingTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- int16_t height = sector->ceiling.height;
- if (sector->ceiling.tilt == 0) {
- return height;
- }
-
- const int32_t z_off = sector->ceiling.tilt >> 8;
- const int32_t x_off = (int8_t)sector->ceiling.tilt;
-
- if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) {
- return height;
- }
-
- if (z_off < 0) {
- height += (int16_t)NEG_TILT(z_off, z);
- } else {
- height -= (int16_t)POS_TILT(z_off, z);
- }
-
- if (x_off < 0) {
- height += (int16_t)POS_TILT(x_off, x);
- } else {
- height -= (int16_t)NEG_TILT(x_off, x);
- }
-
- return height;
-}
-
int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num)
{
const ROOM *room = Room_Get(room_num);
@@ -385,7 +311,7 @@ void Room_AlterFloorHeight(const ITEM *const item, const int32_t height)
} while (portal_room != NO_ROOM);
const SECTOR *const sky_sector =
- M_GetSkySector(sector, item->pos.x, item->pos.z);
+ Room_GetSkySector(sector, item->pos.x, item->pos.z);
sector = Room_GetPitSector(sector, item->pos.x, item->pos.z);
if (sector->floor.height != NO_HEIGHT) {
diff --git a/src/tr1/game/room.h b/src/tr1/game/room.h
index 6b47c1391..ab41fb4d7 100644
--- a/src/tr1/game/room.h
+++ b/src/tr1/game/room.h
@@ -13,7 +13,6 @@ void Room_GetNewRoom(int32_t x, int32_t y, int32_t z, int16_t room_num);
void Room_GetNearByRooms(
int32_t x, int32_t y, int32_t z, int32_t r, int32_t h, int16_t room_num);
SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num);
-int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
int16_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num);
void Room_TestTriggers(const ITEM *item);
diff --git a/src/tr2/game/room.c b/src/tr2/game/room.c
index d2b69320e..d7c6ee006 100644
--- a/src/tr2/game/room.c
+++ b/src/tr2/game/room.c
@@ -20,42 +20,10 @@
#include
void Room_MarkToBeDrawn(int16_t room_num);
-static int16_t M_GetCeilingTiltHeight(
- const SECTOR *sector, int32_t x, int32_t z);
static void M_TriggerMusicTrack(int16_t track, const TRIGGER *trigger);
static bool M_TestLava(const ITEM *item);
-static int16_t M_GetCeilingTiltHeight(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- int16_t height = sector->ceiling.height;
- if (sector->ceiling.tilt == 0) {
- return height;
- }
-
- const int32_t z_off = sector->ceiling.tilt >> 8;
- const int32_t x_off = (int8_t)sector->ceiling.tilt;
-
- if (Camera_IsChunky() && (ABS(z_off) > 2 || ABS(x_off) > 2)) {
- return height;
- }
-
- if (z_off < 0) {
- height += (int16_t)NEG_TILT(z_off, z);
- } else {
- height -= (int16_t)POS_TILT(z_off, z);
- }
-
- if (x_off < 0) {
- height += (int16_t)POS_TILT(x_off, x);
- } else {
- height -= (int16_t)NEG_TILT(x_off, x);
- }
-
- return height;
-}
-
static void M_TriggerMusicTrack(
const int16_t track, const TRIGGER *const trigger)
{
@@ -461,17 +429,6 @@ int16_t Room_GetTiltType(
return sector->floor.tilt;
}
-SECTOR *Room_GetSkySector(
- const SECTOR *sector, const int32_t x, const int32_t z)
-{
- while (sector->portal_room.sky != NO_ROOM) {
- const ROOM *const room = Room_Get(sector->portal_room.sky);
- sector = Room_GetWorldSector(room, x, z);
- }
-
- return (SECTOR *)sector;
-}
-
SECTOR *Room_GetSector(
const int32_t x, const int32_t y, const int32_t z, int16_t *const room_num)
{
@@ -599,34 +556,6 @@ void Room_TestTriggers(const ITEM *const item)
Room_TestSectorTrigger(item, sector);
}
-int32_t Room_GetCeiling(
- const SECTOR *const sector, const int32_t x, const int32_t y,
- const int32_t z)
-{
- const SECTOR *const sky_sector = Room_GetSkySector(sector, x, z);
- int32_t height = M_GetCeilingTiltHeight(sky_sector, x, z);
-
- const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
- if (pit_sector->trigger == nullptr) {
- return height;
- }
-
- const TRIGGER_CMD *cmd = pit_sector->trigger->command;
- for (; cmd != nullptr; cmd = cmd->next_cmd) {
- if (cmd->type != TO_OBJECT) {
- continue;
- }
-
- const ITEM *const item = Item_Get((int16_t)(intptr_t)cmd->parameter);
- const OBJECT *const obj = Object_Get(item->object_id);
- if (obj->ceiling_height_func != nullptr) {
- height = obj->ceiling_height_func(item, x, y, z, height);
- }
- }
-
- return height;
-}
-
void Room_AlterFloorHeight(const ITEM *const item, const int32_t height)
{
int16_t room_num = item->room_num;
diff --git a/src/tr2/game/room.h b/src/tr2/game/room.h
index c36fb71b0..460ec9732 100644
--- a/src/tr2/game/room.h
+++ b/src/tr2/game/room.h
@@ -15,11 +15,9 @@ int16_t Room_GetTiltType(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
// TODO: poor abstraction
void Room_InitCinematic(void);
-SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num);
int32_t Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num);
-int32_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
void Room_TestTriggers(const ITEM *item);
void Room_TestSectorTrigger(const ITEM *item, const SECTOR *sector);
From d38552f79c4c5a5216776648ce9c4f5259bfc92c Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Fri, 21 Feb 2025 12:09:17 +0000
Subject: [PATCH 5/6] rooms: rename no floor internals
This renames the no floor internal concept to abyss.
---
src/libtrx/game/rooms/common.c | 12 ++++++------
src/libtrx/include/libtrx/game/rooms/common.h | 4 ++--
src/tr1/game/game_flow/sequencer_events.c | 4 ++--
src/tr1/game/lara/common.c | 2 +-
src/tr2/game/game_flow/sequencer_events.c | 4 ++--
src/tr2/game/lara/control.c | 2 +-
6 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c
index f3c6a5ebf..b82e2d058 100644
--- a/src/libtrx/game/rooms/common.c
+++ b/src/libtrx/game/rooms/common.c
@@ -33,7 +33,7 @@ static bool m_FlipStatus = false;
static int32_t m_FlipEffect = -1;
static int32_t m_FlipTimer = 0;
static int32_t m_FlipSlotFlags[MAX_FLIP_MAPS] = {};
-static int16_t m_NoFloorHeight = 0;
+static int16_t m_AbyssHeight = 0;
static HEIGHT_TYPE m_HeightType = HT_WALL;
static const int16_t *M_ReadTrigger(
@@ -509,14 +509,14 @@ SECTOR *Room_GetSkySector(
return (SECTOR *)sector;
}
-void Room_SetNoFloorHeight(const int16_t floor_height)
+void Room_SetAbyssHeight(const int16_t height)
{
- m_NoFloorHeight = floor_height;
+ m_AbyssHeight = height;
}
-bool Room_IsNoFloorHeight(const int16_t height)
+bool Room_IsAbyssHeight(const int16_t height)
{
- return m_NoFloorHeight != 0 && height >= m_NoFloorHeight;
+ return m_AbyssHeight != 0 && height >= m_AbyssHeight;
}
HEIGHT_TYPE Room_GetHeightType(void)
@@ -532,7 +532,7 @@ int16_t Room_GetHeight(
const SECTOR *const pit_sector = Room_GetPitSector(sector, x, z);
int32_t height = pit_sector->floor.height;
- if (Room_IsNoFloorHeight(height)) {
+ if (Room_IsAbyssHeight(height)) {
height = 0x4000;
} else {
height = M_GetFloorTiltHeight(pit_sector, x, z);
diff --git a/src/libtrx/include/libtrx/game/rooms/common.h b/src/libtrx/include/libtrx/game/rooms/common.h
index f44c2116e..43f483665 100644
--- a/src/libtrx/include/libtrx/game/rooms/common.h
+++ b/src/libtrx/include/libtrx/game/rooms/common.h
@@ -38,8 +38,8 @@ SECTOR *Room_GetUnitSector(
SECTOR *Room_GetPitSector(const SECTOR *sector, int32_t x, int32_t z);
SECTOR *Room_GetSkySector(const SECTOR *sector, int32_t x, int32_t z);
-void Room_SetNoFloorHeight(int16_t floor_height);
-bool Room_IsNoFloorHeight(int16_t height);
+void Room_SetAbyssHeight(int16_t height);
+bool Room_IsAbyssHeight(int16_t height);
HEIGHT_TYPE Room_GetHeightType(void);
int16_t Room_GetHeight(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
int16_t Room_GetCeiling(const SECTOR *sector, int32_t x, int32_t y, int32_t z);
diff --git a/src/tr1/game/game_flow/sequencer_events.c b/src/tr1/game/game_flow/sequencer_events.c
index 04d57a971..00f66fced 100644
--- a/src/tr1/game/game_flow/sequencer_events.c
+++ b/src/tr1/game/game_flow/sequencer_events.c
@@ -278,7 +278,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor)
{
GF_COMMAND gf_cmd = { .action = GF_NOOP };
if (seq_ctx != GFSC_STORY) {
- Room_SetNoFloorHeight((int16_t)(intptr_t)event->data);
+ Room_SetAbyssHeight((int16_t)(intptr_t)event->data);
}
return gf_cmd;
}
@@ -360,7 +360,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetupBaconLara)
void GF_PreSequenceHook(
const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg)
{
- Room_SetNoFloorHeight(0);
+ Room_SetAbyssHeight(0);
g_GameInfo.remove_guns = false;
g_GameInfo.remove_scions = false;
g_GameInfo.remove_ammo = false;
diff --git a/src/tr1/game/lara/common.c b/src/tr1/game/lara/common.c
index 971464d18..7897a9fab 100644
--- a/src/tr1/game/lara/common.c
+++ b/src/tr1/game/lara/common.c
@@ -285,7 +285,7 @@ void Lara_Control(void)
if (g_LaraItem->flags & IF_INVISIBLE) {
return;
}
- } else if (Room_IsNoFloorHeight(item->pos.y)) {
+ } else if (Room_IsAbyssHeight(item->pos.y)) {
item->hit_points = -1;
g_Lara.death_timer = 9 * LOGIC_FPS;
}
diff --git a/src/tr2/game/game_flow/sequencer_events.c b/src/tr2/game/game_flow/sequencer_events.c
index 2151d2c45..595a5b609 100644
--- a/src/tr2/game/game_flow/sequencer_events.c
+++ b/src/tr2/game/game_flow/sequencer_events.c
@@ -200,7 +200,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleDisableFloor)
{
GF_COMMAND gf_cmd = { .action = GF_NOOP };
if (seq_ctx != GFSC_STORY) {
- Room_SetNoFloorHeight((int16_t)(intptr_t)event->data);
+ Room_SetAbyssHeight((int16_t)(intptr_t)event->data);
}
return gf_cmd;
}
@@ -262,7 +262,7 @@ static DECLARE_GF_EVENT_HANDLER(M_HandleSetNumSecrets)
void GF_PreSequenceHook(
const GF_SEQUENCE_CONTEXT seq_ctx, void *const seq_ctx_arg)
{
- Room_SetNoFloorHeight(0);
+ Room_SetAbyssHeight(0);
Output_SetSunsetEnabled(false);
g_GF_LaraStartAnim = 0;
g_GF_RemoveAmmo = false;
diff --git a/src/tr2/game/lara/control.c b/src/tr2/game/lara/control.c
index ce2ac7db1..702445db1 100644
--- a/src/tr2/game/lara/control.c
+++ b/src/tr2/game/lara/control.c
@@ -633,7 +633,7 @@ void Lara_Control(const int16_t item_num)
g_Lara.death_timer++;
return;
}
- } else if (Room_IsNoFloorHeight(item->pos.y)) {
+ } else if (Room_IsAbyssHeight(item->pos.y)) {
item->hit_points = -1;
g_Lara.death_timer = 9 * FRAMES_PER_SECOND;
}
From b7faeef2507a9d6b1715a3c1bcbcaba78a46385b Mon Sep 17 00:00:00 2001
From: lahm86 <33758420+lahm86@users.noreply.github.com>
Date: Fri, 21 Feb 2025 16:30:33 +0000
Subject: [PATCH 6/6] rooms: use calculated max abyss height
Rather than hardcoding the maximum abyss height to 16384, we calculate
it based on the OG difference between this and Floating Islands abyss
height. This avoids potential collision issues near the top of the
level.
---
src/libtrx/game/rooms/common.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/libtrx/game/rooms/common.c b/src/libtrx/game/rooms/common.c
index b82e2d058..a2fd63f9d 100644
--- a/src/libtrx/game/rooms/common.c
+++ b/src/libtrx/game/rooms/common.c
@@ -33,7 +33,8 @@ static bool m_FlipStatus = false;
static int32_t m_FlipEffect = -1;
static int32_t m_FlipTimer = 0;
static int32_t m_FlipSlotFlags[MAX_FLIP_MAPS] = {};
-static int16_t m_AbyssHeight = 0;
+static int16_t m_AbyssMinHeight = 0;
+static int32_t m_AbyssMaxHeight = 0;
static HEIGHT_TYPE m_HeightType = HT_WALL;
static const int16_t *M_ReadTrigger(
@@ -511,12 +512,17 @@ SECTOR *Room_GetSkySector(
void Room_SetAbyssHeight(const int16_t height)
{
- m_AbyssHeight = height;
+ // Once Lara reaches the min abyss height, she will be killed; she will
+ // continue to fall however, so the max height is needed until the inventory
+ // is shown, otherwise Lara will hit the floor.
+ m_AbyssMinHeight = height;
+ m_AbyssMaxHeight = height == 0 ? 0 : m_AbyssMinHeight + 26 * STEP_L;
+ CLAMPG(m_AbyssMaxHeight, MAX_HEIGHT - STEP_L);
}
bool Room_IsAbyssHeight(const int16_t height)
{
- return m_AbyssHeight != 0 && height >= m_AbyssHeight;
+ return m_AbyssMinHeight != 0 && height >= m_AbyssMinHeight;
}
HEIGHT_TYPE Room_GetHeightType(void)
@@ -533,7 +539,7 @@ int16_t Room_GetHeight(
int32_t height = pit_sector->floor.height;
if (Room_IsAbyssHeight(height)) {
- height = 0x4000;
+ height = m_AbyssMaxHeight;
} else {
height = M_GetFloorTiltHeight(pit_sector, x, z);
}
|