From 5a50de02ed1cbf5de02c4bf59765a90a4dd4ebfa Mon Sep 17 00:00:00 2001 From: lahm86 <33758420+lahm86@users.noreply.github.com> Date: Sat, 26 Apr 2025 10:21:03 +0100 Subject: [PATCH] door: move door module to TRX This moves the door module fully to TRX as the logic is identical in both games. --- .../game/objects/general/door.c | 60 +++-- .../include/libtrx/game/objects/common.h | 1 + src/libtrx/meson.build | 1 + src/tr1/game/objects/common.h | 1 - src/tr1/game/objects/general/door.c | 253 ------------------ src/tr1/global/types.h | 6 - src/tr1/meson.build | 1 - src/tr2/game/objects/common.h | 1 - src/tr2/global/types_decomp.h | 6 - src/tr2/meson.build | 1 - 10 files changed, 34 insertions(+), 297 deletions(-) rename src/{tr2 => libtrx}/game/objects/general/door.c (86%) delete mode 100644 src/tr1/game/objects/general/door.c diff --git a/src/tr2/game/objects/general/door.c b/src/libtrx/game/objects/general/door.c similarity index 86% rename from src/tr2/game/objects/general/door.c rename to src/libtrx/game/objects/general/door.c index e97ec0cd5..e81c4ca39 100644 --- a/src/tr2/game/objects/general/door.c +++ b/src/libtrx/game/objects/general/door.c @@ -1,13 +1,16 @@ -#include "game/box.h" -#include "game/items.h" -#include "game/objects/common.h" -#include "game/room.h" -#include "global/vars.h" +#include "game/objects/general/door.h" -#include -#include -#include -#include +#include "game/game_buf.h" +#include "game/lara/common.h" +#include "game/objects/common.h" +#include "game/pathing.h" +#include "game/rooms.h" + +typedef struct { + SECTOR *sector; + SECTOR old_sector; + int16_t box_num; +} DOORPOS_DATA; typedef struct { DOORPOS_DATA d1; @@ -82,7 +85,7 @@ static void M_Shut(DOORPOS_DATA *const d) sector->portal_room.pit = NO_ROOM_NEG; sector->portal_room.wall = NO_ROOM; - const int16_t box_num = d->block; + const int16_t box_num = d->box_num; if (box_num != NO_BOX) { Box_GetBox(box_num)->overlap_index |= BOX_BLOCKED; } @@ -96,7 +99,7 @@ static void M_Open(DOORPOS_DATA *const d) *d->sector = d->old_sector; - const int16_t box_num = d->block; + const int16_t box_num = d->box_num; if (box_num != NO_BOX) { Box_GetBox(box_num)->overlap_index &= ~BOX_BLOCKED; } @@ -117,10 +120,11 @@ static void M_InitialisePortal( } int16_t box_num = sector->box; - if (!(Box_GetBox(box_num)->overlap_index & BOX_BLOCKABLE)) { + const BOX_INFO *const box = Box_GetBox(box_num); + if ((box->overlap_index & BOX_BLOCKABLE) == 0) { box_num = NO_BOX; } - door_pos->block = box_num; + door_pos->box_num = box_num; door_pos->old_sector = *door_pos->sector; } @@ -192,32 +196,32 @@ static void M_Initialise(const int16_t item_num) static void M_Control(const int16_t item_num) { ITEM *const item = Item_Get(item_num); - DOOR_DATA *const data = item->data; + DOOR_DATA *const door = item->data; if (Item_IsTriggerActive(item)) { if (item->current_anim_state == DOOR_STATE_CLOSED) { item->goal_anim_state = DOOR_STATE_OPEN; } else { - M_Open(&data->d1); - M_Open(&data->d2); - M_Open(&data->d1flip); - M_Open(&data->d2flip); + M_Open(&door->d1); + M_Open(&door->d2); + M_Open(&door->d1flip); + M_Open(&door->d2flip); } } else { if (item->current_anim_state == DOOR_STATE_OPEN) { item->goal_anim_state = DOOR_STATE_CLOSED; } else { - M_Shut(&data->d1); - M_Shut(&data->d2); - M_Shut(&data->d1flip); - M_Shut(&data->d2flip); + M_Shut(&door->d1); + M_Shut(&door->d2); + M_Shut(&door->d1flip); + M_Shut(&door->d2flip); } } - M_Check(&data->d1); - M_Check(&data->d2); - M_Check(&data->d1flip); - M_Check(&data->d2flip); + M_Check(&door->d1); + M_Check(&door->d2); + M_Check(&door->d1flip); + M_Check(&door->d2flip); Item_Animate(item); } @@ -237,8 +241,8 @@ void Door_Collision( if (coll->enable_baddie_push) { Lara_Push( item, coll, - item->current_anim_state != item->goal_anim_state ? coll->enable_hit - : false, + coll->enable_hit + && item->current_anim_state != item->goal_anim_state, true); } } diff --git a/src/libtrx/include/libtrx/game/objects/common.h b/src/libtrx/include/libtrx/game/objects/common.h index f65578f14..18de887cd 100644 --- a/src/libtrx/include/libtrx/game/objects/common.h +++ b/src/libtrx/include/libtrx/game/objects/common.h @@ -36,6 +36,7 @@ void Object_SwapMesh( ANIM *Object_GetAnim(const OBJECT *obj, int32_t anim_idx); ANIM_BONE *Object_GetBone(const OBJECT *obj, int32_t bone_idx); +extern void Object_DrawUnclippedItem(const ITEM *item); extern void Object_DrawMesh(int32_t mesh_idx, int32_t clip, bool interpolated); void Object_DrawInterpolatedObject( diff --git a/src/libtrx/meson.build b/src/libtrx/meson.build index d3866bca2..78793400b 100644 --- a/src/libtrx/meson.build +++ b/src/libtrx/meson.build @@ -176,6 +176,7 @@ sources = [ 'game/objects/general/bridge_flat.c', 'game/objects/general/bridge_tilt1.c', 'game/objects/general/bridge_tilt2.c', + 'game/objects/general/door.c', 'game/objects/general/drawbridge.c', 'game/objects/general/trapdoor.c', 'game/objects/names.c', diff --git a/src/tr1/game/objects/common.h b/src/tr1/game/objects/common.h index dd39f97e8..5b9da9fdc 100644 --- a/src/tr1/game/objects/common.h +++ b/src/tr1/game/objects/common.h @@ -12,7 +12,6 @@ void Object_DrawDummyItem(const ITEM *item); void Object_DrawSpriteItem(const ITEM *item); void Object_DrawPickupItem(const ITEM *item); void Object_DrawAnimatingItem(const ITEM *item); -void Object_DrawUnclippedItem(const ITEM *item); void Object_SetMeshReflective( GAME_OBJECT_ID obj_id, int32_t mesh_idx, bool enabled); void Object_SetReflective(GAME_OBJECT_ID obj_id, bool enabled); diff --git a/src/tr1/game/objects/general/door.c b/src/tr1/game/objects/general/door.c deleted file mode 100644 index 5cbe0bfcc..000000000 --- a/src/tr1/game/objects/general/door.c +++ /dev/null @@ -1,253 +0,0 @@ -#include "game/box.h" -#include "game/items.h" -#include "game/lara/common.h" -#include "game/objects/common.h" -#include "game/room.h" -#include "global/vars.h" - -#include -#include -#include -#include - -typedef struct { - DOORPOS_DATA d1; - DOORPOS_DATA d1flip; - DOORPOS_DATA d2; - DOORPOS_DATA d2flip; -} DOOR_DATA; - -static SECTOR *M_GetRoomRelSector( - const ROOM *room, const ITEM *item, int32_t sector_dx, int32_t sector_dz); -static void M_InitialisePortal( - const ROOM *room, const ITEM *item, int32_t sector_dx, int32_t sector_dz, - DOORPOS_DATA *door_pos); - -static bool M_LaraDoorCollision(const SECTOR *sector); -static void M_Check(DOORPOS_DATA *d); -static void M_Shut(DOORPOS_DATA *d); -static void M_Open(DOORPOS_DATA *d); -static void M_Setup(OBJECT *obj); -static void M_Initialise(int16_t item_num); -static void M_Control(int16_t item_num); - -static SECTOR *M_GetRoomRelSector( - const ROOM *const room, const ITEM *item, const int32_t sector_dx, - const int32_t sector_dz) -{ - const XZ_32 sector = { - .x = ((item->pos.x - room->pos.x) >> WALL_SHIFT) + sector_dx, - .z = ((item->pos.z - room->pos.z) >> WALL_SHIFT) + sector_dz, - }; - return Room_GetUnitSector(room, sector.x, sector.z); -} - -static void M_InitialisePortal( - const ROOM *const room, const ITEM *const item, const int32_t sector_dx, - const int32_t sector_dz, DOORPOS_DATA *const door_pos) -{ - door_pos->sector = M_GetRoomRelSector(room, item, sector_dx, sector_dz); - - const SECTOR *sector = door_pos->sector; - - const int16_t room_num = sector->portal_room.wall; - if (room_num != NO_ROOM) { - sector = - M_GetRoomRelSector(Room_Get(room_num), item, sector_dx, sector_dz); - } - - int16_t box_num = sector->box; - if (!(Box_GetBox(box_num)->overlap_index & BOX_BLOCKABLE)) { - box_num = NO_BOX; - } - door_pos->block = box_num; - door_pos->old_sector = *door_pos->sector; -} - -static bool M_LaraDoorCollision(const SECTOR *const sector) -{ - // Check if Lara is on the same tile as the invisible block. - if (g_LaraItem == nullptr) { - return false; - } - - int16_t room_num = g_LaraItem->room_num; - const SECTOR *const lara_sector = Room_GetSector( - g_LaraItem->pos.x, g_LaraItem->pos.y, g_LaraItem->pos.z, &room_num); - return lara_sector == sector; -} - -static void M_Check(DOORPOS_DATA *const d) -{ - // Forcefully remove the invisible block if Lara happens to occupy the same - // tile. This ensures that Lara doesn't void if a timed door happens to - // close right on her, or the player loads the game while standing on a - // closed door's block tile. - if (M_LaraDoorCollision(d->sector)) { - M_Open(d); - } -} - -static void M_Shut(DOORPOS_DATA *const d) -{ - // Change the level geometry so that the door tile is impassable. - SECTOR *const sector = d->sector; - if (sector == nullptr) { - return; - } - - sector->box = NO_BOX; - sector->floor.height = NO_HEIGHT; - sector->ceiling.height = NO_HEIGHT; - sector->floor.tilt = 0; - sector->ceiling.tilt = 0; - sector->portal_room.sky = NO_ROOM; - sector->portal_room.pit = NO_ROOM; - sector->portal_room.wall = NO_ROOM; - - const int16_t box_num = d->block; - if (box_num != NO_BOX) { - Box_GetBox(box_num)->overlap_index |= BOX_BLOCKED; - } -} - -static void M_Open(DOORPOS_DATA *const d) -{ - // Restore the level geometry so that the door tile is passable. - SECTOR *const sector = d->sector; - if (!sector) { - return; - } - - *sector = d->old_sector; - - const int16_t box_num = d->block; - if (box_num != NO_BOX) { - Box_GetBox(box_num)->overlap_index &= ~BOX_BLOCKED; - } -} - -static void M_Setup(OBJECT *const obj) -{ - obj->initialise_func = M_Initialise; - obj->control_func = M_Control; - obj->draw_func = Object_DrawUnclippedItem; - obj->collision_func = Door_Collision; - obj->save_anim = 1; - obj->save_flags = 1; -} - -static void M_Initialise(const int16_t item_num) -{ - ITEM *const item = Item_Get(item_num); - DOOR_DATA *const door = GameBuf_Alloc(sizeof(DOOR_DATA), GBUF_ITEM_DATA); - item->data = door; - - int32_t dx = 0; - int32_t dz = 0; - if (item->rot.y == 0) { - dz = -1; - } else if (item->rot.y == -DEG_180) { - dz = 1; - } else if (item->rot.y == DEG_90) { - dx = -1; - } else { - dx = 1; - } - - int16_t room_num = item->room_num; - const ROOM *room = Room_Get(room_num); - M_InitialisePortal(room, item, dx, dz, &door->d1); - - if (room->flipped_room == -1) { - door->d1flip.sector = nullptr; - } else { - room = Room_Get(room->flipped_room); - M_InitialisePortal(room, item, dx, dz, &door->d1flip); - } - - room_num = door->d1.sector->portal_room.wall; - M_Shut(&door->d1); - M_Shut(&door->d1flip); - - if (room_num == NO_ROOM) { - door->d2.sector = nullptr; - door->d2flip.sector = nullptr; - return; - } - - room = Room_Get(room_num); - M_InitialisePortal(room, item, 0, 0, &door->d2); - if (room->flipped_room == -1) { - door->d2flip.sector = nullptr; - } else { - room = Room_Get(room->flipped_room); - M_InitialisePortal(room, item, 0, 0, &door->d2flip); - } - - M_Shut(&door->d2); - M_Shut(&door->d2flip); - - const int16_t prev_room = item->room_num; - Item_NewRoom(item_num, room_num); - item->room_num = prev_room; -} - -static void M_Control(const int16_t item_num) -{ - ITEM *const item = Item_Get(item_num); - DOOR_DATA *door = item->data; - - if (Item_IsTriggerActive(item)) { - if (item->current_anim_state == DOOR_STATE_CLOSED) { - item->goal_anim_state = DOOR_STATE_OPEN; - } else { - M_Open(&door->d1); - M_Open(&door->d2); - M_Open(&door->d1flip); - M_Open(&door->d2flip); - } - } else { - if (item->current_anim_state == DOOR_STATE_OPEN) { - item->goal_anim_state = DOOR_STATE_CLOSED; - } else { - M_Shut(&door->d1); - M_Shut(&door->d2); - M_Shut(&door->d1flip); - M_Shut(&door->d2flip); - } - } - - M_Check(&door->d1); - M_Check(&door->d2); - M_Check(&door->d1flip); - M_Check(&door->d2flip); - Item_Animate(item); -} - -void Door_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll) -{ - ITEM *const item = Item_Get(item_num); - if (!Lara_TestBoundsCollide(item, coll->radius)) { - return; - } - if (!Collide_TestCollision(item, lara_item)) { - return; - } - if (coll->enable_baddie_push) { - if (item->current_anim_state != item->goal_anim_state) { - Lara_Push(item, coll, coll->enable_hit, true); - } else { - Lara_Push(item, coll, false, true); - } - } -} - -REGISTER_OBJECT(O_DOOR_TYPE_1, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_2, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_3, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_4, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_5, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_6, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_7, M_Setup) -REGISTER_OBJECT(O_DOOR_TYPE_8, M_Setup) diff --git a/src/tr1/global/types.h b/src/tr1/global/types.h index 54dd99625..6b7384d57 100644 --- a/src/tr1/global/types.h +++ b/src/tr1/global/types.h @@ -123,12 +123,6 @@ typedef struct { }; } PHD_VBUF; -typedef struct { - SECTOR *sector; - SECTOR old_sector; - int16_t block; -} DOORPOS_DATA; - typedef struct { PASSPORT_MODE passport_selection; int32_t select_save_slot; diff --git a/src/tr1/meson.build b/src/tr1/meson.build index 277258aec..71f6c3254 100644 --- a/src/tr1/meson.build +++ b/src/tr1/meson.build @@ -197,7 +197,6 @@ sources = [ 'game/objects/general/cabin.c', 'game/objects/general/camera_target.c', 'game/objects/general/cog.c', - 'game/objects/general/door.c', 'game/objects/general/earthquake.c', 'game/objects/general/keyhole.c', 'game/objects/general/moving_bar.c', diff --git a/src/tr2/game/objects/common.h b/src/tr2/game/objects/common.h index 15a9e8cc0..65911e138 100644 --- a/src/tr2/game/objects/common.h +++ b/src/tr2/game/objects/common.h @@ -6,7 +6,6 @@ void Object_DrawDummyItem(const ITEM *item); void Object_DrawAnimatingItem(const ITEM *item); -void Object_DrawUnclippedItem(const ITEM *item); void Object_DrawSpriteItem(const ITEM *item); void Object_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll); diff --git a/src/tr2/global/types_decomp.h b/src/tr2/global/types_decomp.h index 8427402b1..3d1825df8 100644 --- a/src/tr2/global/types_decomp.h +++ b/src/tr2/global/types_decomp.h @@ -120,12 +120,6 @@ typedef enum { GFE_REMOVE_AMMO = 22, } GF_EVENTS; -typedef struct { - SECTOR *sector; - SECTOR old_sector; - int16_t block; -} DOORPOS_DATA; - typedef enum { TRAP_SET = 0, TRAP_ACTIVATE = 1, diff --git a/src/tr2/meson.build b/src/tr2/meson.build index ea203d6bf..80c5e9c77 100644 --- a/src/tr2/meson.build +++ b/src/tr2/meson.build @@ -195,7 +195,6 @@ sources = [ 'game/objects/general/cutscene_player.c', 'game/objects/general/detonator.c', 'game/objects/general/ding_dong.c', - 'game/objects/general/door.c', 'game/objects/general/earthquake.c', 'game/objects/general/final_cutscene.c', 'game/objects/general/final_level_counter.c',