Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decompile lift #1734

Merged
merged 5 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions docs/tr2/progress.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 10 additions & 5 deletions docs/tr2/progress.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2653,6 +2653,11 @@ typedef struct __unaligned {
int32_t pitch;
} SKIDOO_INFO;

typedef struct __unaligned { // decompiled
int32_t start_height;
int32_t wait_time;
} LIFT_INFO;

typedef struct __unaligned {
struct {
XYZ_16 min;
Expand Down Expand Up @@ -3580,11 +3585,11 @@ typedef enum {
0x00435650 0x0036 -R void __cdecl DrawBridgeFloor(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x00435690 0x003B -R void __cdecl DrawBridgeCeiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x004356D0 0x002C -R void __cdecl DrawBridgeCollision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);
0x00435700 0x0035 -R void __cdecl InitialiseLift(int16_t item_num);
0x00435740 0x00D4 -R void __cdecl LiftControl(int16_t item_num);
0x00435820 0x0179 -R void __cdecl LiftFloorCeiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling);
0x004359A0 0x0035 -R void __cdecl LiftFloor(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x004359E0 0x0035 -R void __cdecl LiftCeiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x00435700 0x0035 + void __cdecl Lift_Initialise(int16_t item_num);
0x00435740 0x00D4 + void __cdecl Lift_Control(int16_t item_num);
0x00435820 0x0179 + void __cdecl Lift_FloorCeiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling);
0x004359A0 0x0035 + void __cdecl Lift_Floor(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x004359E0 0x0035 + void __cdecl Lift_Ceiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x00435A20 0x0016 -R void __cdecl BridgeFlatFloor(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x00435A40 0x001B -R void __cdecl BridgeFlatCeiling(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height);
0x00435A60 0x003B -R int32_t __cdecl GetOffset(ITEM *item, int32_t x, int32_t z);
Expand Down
10 changes: 10 additions & 0 deletions src/libtrx/include/libtrx/game/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@

#pragma pack(push, 1)

typedef struct __PACKING {
int32_t x;
int32_t z;
} XZ_32;

typedef struct __PACKING {
int16_t x;
int16_t z;
} XZ_16;

typedef struct __PACKING {
int32_t x;
int32_t y;
Expand Down
166 changes: 166 additions & 0 deletions src/tr2/game/objects/general/lift.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#include "game/objects/general/lift.h"

#include "game/items.h"
#include "game/room.h"
#include "global/funcs.h"
#include "global/vars.h"

#define LIFT_WAIT_TIME (3 * FRAMES_PER_SECOND) // = 90
#define LIFT_SHIFT 16
#define LIFT_HEIGHT (STEP_L * 5) // = 1280
#define LIFT_TRAVEL_DIST (STEP_L * 22)

typedef enum {
LIFT_STATE_DOOR_CLOSED = 0,
LIFT_STATE_DOOR_OPEN = 1,
} LIFT_STATE;

void __cdecl Lift_Initialise(const int16_t item_num)
{
ITEM *const item = Item_Get(item_num);

LIFT_INFO *const lift_data =
game_malloc(sizeof(LIFT_INFO), GBUF_TEMP_ALLOC);
lift_data->start_height = item->pos.y;
lift_data->wait_time = 0;

item->data = lift_data;
}

void __cdecl Lift_Control(const int16_t item_num)
{
ITEM *const item = Item_Get(item_num);
LIFT_INFO *const lift_data = item->data;

if (Item_IsTriggerActive(item)) {
if (item->pos.y
< lift_data->start_height + LIFT_TRAVEL_DIST - LIFT_SHIFT) {
if (lift_data->wait_time < LIFT_WAIT_TIME) {
item->goal_anim_state = LIFT_STATE_DOOR_OPEN;
lift_data->wait_time++;
} else {
item->goal_anim_state = LIFT_STATE_DOOR_CLOSED;
item->pos.y += LIFT_SHIFT;
}
} else {
item->goal_anim_state = LIFT_STATE_DOOR_OPEN;
lift_data->wait_time = 0;
}
} else {
if (item->pos.y > lift_data->start_height + LIFT_SHIFT) {
if (lift_data->wait_time < LIFT_WAIT_TIME) {
item->goal_anim_state = LIFT_STATE_DOOR_OPEN;
lift_data->wait_time++;
} else {
item->goal_anim_state = LIFT_STATE_DOOR_CLOSED;
item->pos.y -= LIFT_SHIFT;
}
} else {
item->goal_anim_state = LIFT_STATE_DOOR_OPEN;
lift_data->wait_time = 0;
}
}

Item_Animate(item);

int16_t room_num = item->room_num;
Room_GetSector(item->pos.x, item->pos.y, item->pos.z, &room_num);
if (item->room_num != room_num) {
Item_NewRoom(item_num, room_num);
}
}

void __cdecl Lift_FloorCeiling(
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
int32_t *const out_floor, int32_t *const out_ceiling)
{
const XZ_32 lift_tile = {
.x = item->pos.x >> WALL_SHIFT,
.z = item->pos.z >> WALL_SHIFT,
};

const XZ_32 lara_tile = {
.x = g_LaraItem->pos.x >> WALL_SHIFT,
.z = g_LaraItem->pos.z >> WALL_SHIFT,
};

const XZ_32 test_tile = {
.x = x >> WALL_SHIFT,
.z = z >> WALL_SHIFT,
};

// clang-format off
const bool point_in_shaft =
(test_tile.x == lift_tile.x || test_tile.x + 1 == lift_tile.x) &&
(test_tile.z == lift_tile.z || test_tile.z - 1 == lift_tile.z);

const bool lara_in_shaft =
(lara_tile.x == lift_tile.x || lara_tile.x + 1 == lift_tile.x) &&
(lara_tile.z == lift_tile.z || lara_tile.z - 1 == lift_tile.z);
// clang-format on

const int32_t lift_floor = item->pos.y;
const int32_t lift_ceiling = item->pos.y - LIFT_HEIGHT;

*out_floor = 0x7FFF;
*out_ceiling = -0x7FFF;

if (lara_in_shaft) {
if (item->current_anim_state == LIFT_STATE_DOOR_CLOSED
&& g_LaraItem->pos.y < lift_floor + STEP_L
&& g_LaraItem->pos.y > lift_ceiling + STEP_L) {
if (point_in_shaft) {
*out_floor = lift_floor;
*out_ceiling = lift_ceiling + STEP_L;
} else {
*out_floor = NO_HEIGHT;
*out_ceiling = 0x7FFF;
}
} else if (point_in_shaft) {
if (g_LaraItem->pos.y < lift_ceiling + STEP_L) {
*out_floor = lift_ceiling;
} else if (g_LaraItem->pos.y < lift_floor + STEP_L) {
*out_floor = lift_floor;
*out_ceiling = lift_ceiling + STEP_L;
} else {
*out_ceiling = lift_floor + STEP_L;
}
}
} else if (point_in_shaft) {
if (y <= lift_ceiling) {
*out_floor = lift_ceiling;
} else if (y >= lift_floor + STEP_L) {
*out_ceiling = lift_floor + STEP_L;
} else if (item->current_anim_state == LIFT_STATE_DOOR_OPEN) {
*out_floor = lift_floor;
*out_ceiling = lift_ceiling + STEP_L;
} else {
*out_floor = NO_HEIGHT;
*out_ceiling = 0x7FFF;
}
}
}

void __cdecl Lift_Floor(
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
int32_t *const out_height)
{
int32_t floor;
int32_t height;
Lift_FloorCeiling(item, x, y, z, &floor, &height);
if (floor < *out_height) {
*out_height = floor;
}
}

void __cdecl Lift_Ceiling(
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
int32_t *const out_height)
{
int32_t floor;
int32_t height;
Lift_FloorCeiling(item, x, y, z, &floor, &height);
if (height > *out_height) {
*out_height = height;
}
}
18 changes: 18 additions & 0 deletions src/tr2/game/objects/general/lift.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "global/types.h"

typedef struct __PACKING {
int32_t start_height;
int32_t wait_time;
} LIFT_INFO;

void __cdecl Lift_Initialise(int16_t item_num);
void __cdecl Lift_Control(int16_t item_num);
void __cdecl Lift_FloorCeiling(
const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_floor,
int32_t *out_ceiling);
void __cdecl Lift_Floor(
const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height);
void __cdecl Lift_Ceiling(
const ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *out_height);
5 changes: 0 additions & 5 deletions src/tr2/global/funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,6 @@
#define DrawBridgeFloor ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x00435650)
#define DrawBridgeCeiling ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x00435690)
#define DrawBridgeCollision ((void __cdecl (*)(int16_t item_num, ITEM *lara_item, COLL_INFO *coll))0x004356D0)
#define InitialiseLift ((void __cdecl (*)(int16_t item_num))0x00435700)
#define LiftControl ((void __cdecl (*)(int16_t item_num))0x00435740)
#define LiftFloorCeiling ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *floor, int32_t *ceiling))0x00435820)
#define LiftFloor ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x004359A0)
#define LiftCeiling ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x004359E0)
#define BridgeFlatFloor ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x00435A20)
#define BridgeFlatCeiling ((void __cdecl (*)(ITEM *item, int32_t x, int32_t y, int32_t z, int32_t *height))0x00435A40)
#define GetOffset ((int32_t __cdecl (*)(ITEM *item, int32_t x, int32_t z))0x00435A60)
Expand Down
6 changes: 6 additions & 0 deletions src/tr2/inject_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "game/objects/general/final_level_counter.h"
#include "game/objects/general/gong_bonger.h"
#include "game/objects/general/keyhole.h"
#include "game/objects/general/lift.h"
#include "game/objects/general/movable_block.h"
#include "game/objects/general/pickup.h"
#include "game/objects/general/puzzle_hole.h"
Expand Down Expand Up @@ -1016,6 +1017,11 @@ static void M_Objects(const bool enable)
INJECT(enable, 0x00434800, GongBonger_Control);
INJECT(enable, 0x004348C0, Zipline_Collision);
INJECT(enable, 0x00434980, Zipline_Control);
INJECT(enable, 0x00435700, Lift_Initialise);
INJECT(enable, 0x00435740, Lift_Control);
INJECT(enable, 0x00435820, Lift_FloorCeiling);
INJECT(enable, 0x004359A0, Lift_Floor);
INJECT(enable, 0x004359E0, Lift_Ceiling);
INJECT(enable, 0x00435D70, Detonator_Control);
INJECT(enable, 0x00437E70, Pickup_Collision);
INJECT(enable, 0x004382F0, Switch_Collision);
Expand Down
1 change: 1 addition & 0 deletions src/tr2/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ dll_sources = [
'game/objects/general/final_level_counter.c',
'game/objects/general/gong_bonger.c',
'game/objects/general/keyhole.c',
'game/objects/general/lift.c',
'game/objects/general/movable_block.c',
'game/objects/general/pickup.c',
'game/objects/general/puzzle_hole.c',
Expand Down
Loading