From 37bd71ce19d6ae754bd66bd8ffd56e80d7c9956c Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Wed, 18 Sep 2024 00:23:38 +0200 Subject: [PATCH 1/3] console/cmd: move /pos to libtrx --- data/ship/cfg/TR2X_gameflow.json5 | 64 ++++++++++++------------- docs/progress.txt | 6 +-- meson.build | 1 + src/game/console.c | 10 ++-- src/game/console_cmd.c | 66 ++++++++++---------------- src/game/console_cmd.h | 15 ------ src/game/game_string.c | 2 + src/game/game_string.def | 1 - src/game/lara/common.c | 8 ++++ src/game/lara/common.h | 5 ++ src/game/objects/common.c | 5 ++ src/game/objects/common.h | 1 + src/global/types.h | 79 +------------------------------ subprojects/libtrx | 2 +- tools/generate_funcs | 2 + tools/tr2x/paths.py | 4 ++ tools/update_gameflow | 38 ++++++++++----- 17 files changed, 124 insertions(+), 185 deletions(-) delete mode 100644 src/game/console_cmd.h create mode 100644 src/game/lara/common.c create mode 100644 src/game/lara/common.h diff --git a/data/ship/cfg/TR2X_gameflow.json5 b/data/ship/cfg/TR2X_gameflow.json5 index 37e5397c..634cf7f3 100644 --- a/data/ship/cfg/TR2X_gameflow.json5 +++ b/data/ship/cfg/TR2X_gameflow.json5 @@ -351,48 +351,48 @@ }, "game_strings": { - "OSD_FLY_MODE_ON": "Fly mode enabled", + "OSD_COMMAND_BAD_INVOCATION": "Invalid invocation: %s", + "OSD_COMMAND_UNAVAILABLE": "This command is not currently available", + "OSD_COMPLETE_LEVEL": "Level complete!", + "OSD_CURRENT_HEALTH_GET": "Current Lara's health: %d", + "OSD_CURRENT_HEALTH_SET": "Lara's health set to %d", + "OSD_DOOR_CLOSE": "Close Sesame!", + "OSD_DOOR_OPEN": "Open Sesame!", + "OSD_DOOR_OPEN_FAIL": "No doors in Lara's proximity", + "OSD_FLIPMAP_FAIL_ALREADY_OFF": "Flipmap is already OFF", + "OSD_FLIPMAP_FAIL_ALREADY_ON": "Flipmap is already ON", + "OSD_FLIPMAP_OFF": "Flipmap set to OFF", + "OSD_FLIPMAP_ON": "Flipmap set to ON", "OSD_FLY_MODE_OFF": "Fly mode disabled", - "OSD_POS_GET": "Room: %d\nPosition: %.3f, %.3f, %.3f\nRotation: %.3f,%.3f,%.3f", - "OSD_POS_SET_POS": "Teleported to position: %.3f %.3f %.3f", - "OSD_POS_SET_POS_FAIL": "Failed to teleport to position: %.3f %.3f %.3f", - "OSD_POS_SET_ROOM": "Teleported to room: %d", - "OSD_POS_SET_ROOM_FAIL": "Failed to teleport to room: %d", - "OSD_POS_SET_ITEM": "Teleported to object: %s", - "OSD_POS_SET_ITEM_FAIL": "Failed to teleport to object: %s", + "OSD_FLY_MODE_ON": "Fly mode enabled", "OSD_GIVE_ITEM": "Added %s to Lara's inventory", - "OSD_GIVE_ITEM_ALL_KEYS": "Surprise! Every key item Lara needs is now in her backpack.", "OSD_GIVE_ITEM_ALL_GUNS": "Lock'n'load - Lara's armed to the teeth!", + "OSD_GIVE_ITEM_ALL_KEYS": "Surprise! Every key item Lara needs is now in her backpack.", "OSD_GIVE_ITEM_CHEAT": "Lara's backpack just got way heavier!", - "OSD_FLIPMAP_ON": "Flipmap set to ON", - "OSD_FLIPMAP_OFF": "Flipmap set to OFF", - "OSD_FLIPMAP_FAIL_ALREADY_ON": "Flipmap is already ON", - "OSD_FLIPMAP_FAIL_ALREADY_OFF": "Flipmap is already OFF", - "OSD_KILL_ALL": "Poof! %d enemies gone!", - "OSD_KILL_ALL_FAIL": "Uh-oh, there are no enemies left to kill...", - "OSD_KILL": "Bye-bye!", - "OSD_KILL_FAIL": "No enemy nearby...", - "OSD_COMPLETE_LEVEL": "Level complete!", - "OSD_PLAY_LEVEL": "Loading %s", + "OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health", + "OSD_HEAL_SUCCESS": "Healed Lara back to full health", "OSD_INVALID_ITEM": "Invalid item: %s", - "OSD_INVALID_ROOM": "Invalid room: %d. Valid rooms are 0-%d", - "OSD_INVALID_OBJECT": "Invalid object", - "OSD_OBJECT_NOT_FOUND": "Object not found", "OSD_INVALID_LEVEL": "Invalid level", + "OSD_INVALID_OBJECT": "Invalid object", + "OSD_INVALID_ROOM": "Invalid room: %d. Valid rooms are 0-%d", "OSD_INVALID_SAVE_SLOT": "Invalid save slot %d", - "OSD_UNKNOWN_COMMAND": "Unknown command: %s", - "OSD_COMMAND_BAD_INVOCATION": "Invalid invocation: %s", - "OSD_COMMAND_UNAVAILABLE": "This command is not currently available", - "OSD_DOOR_OPEN": "Open Sesame!", - "OSD_DOOR_CLOSE": "Close Sesame!", - "OSD_DOOR_OPEN_FAIL": "No doors in Lara's proximity", + "OSD_KILL": "Bye-bye!", + "OSD_KILL_ALL": "Poof! %d enemies gone!", + "OSD_KILL_ALL_FAIL": "Uh-oh, there are no enemies left to kill...", + "OSD_KILL_FAIL": "No enemy nearby...", "OSD_LOAD_GAME": "Loaded game from save slot %d", "OSD_LOAD_GAME_FAIL_UNAVAILABLE_SLOT": "Save slot %d is not available", + "OSD_OBJECT_NOT_FOUND": "Object not found", + "OSD_PLAY_LEVEL": "Loading %s", + "OSD_POS_GET": "Room: %d\nPosition: %.3f, %.3f, %.3f\nRotation: %.3f,%.3f,%.3f", + "OSD_POS_SET_ITEM": "Teleported to object: %s", + "OSD_POS_SET_ITEM_FAIL": "Failed to teleport to object: %s", + "OSD_POS_SET_POS": "Teleported to position: %.3f %.3f %.3f", + "OSD_POS_SET_POS_FAIL": "Failed to teleport to position: %.3f %.3f %.3f", + "OSD_POS_SET_ROOM": "Teleported to room: %d", + "OSD_POS_SET_ROOM_FAIL": "Failed to teleport to room: %d", "OSD_SAVE_GAME": "Saved game to save slot %d", "OSD_SAVE_GAME_FAIL": "Cannot save the game in the current state", - "OSD_CURRENT_HEALTH_GET": "Current Lara's health: %d", - "OSD_CURRENT_HEALTH_SET": "Lara's health set to %d", - "OSD_HEAL_ALREADY_FULL_HP": "Lara's already at full health", - "OSD_HEAL_SUCCESS": "Healed Lara back to full health", + "OSD_UNKNOWN_COMMAND": "Unknown command: %s", }, } diff --git a/docs/progress.txt b/docs/progress.txt index 40369afa..2bb2da69 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -473,13 +473,13 @@ typedef enum { DRAW_COLOR_KEY = 1, } DRAW_TYPE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int32_t floor; int32_t ceiling; int32_t type; } COLL_SIDE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled COLL_SIDE side_mid; COLL_SIDE side_front; COLL_SIDE side_left; @@ -1107,7 +1107,7 @@ typedef struct __unaligned { uint16_t reserved4[2]; } GAME_FLOW; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t mesh_count; int16_t mesh_idx; int32_t bone_idx; diff --git a/meson.build b/meson.build index 84ef5c17..9e95cc4f 100644 --- a/meson.build +++ b/meson.build @@ -110,6 +110,7 @@ dll_sources = [ 'src/game/inventory/ring.c', 'src/game/inventory/vars.c', 'src/game/items.c', + 'src/game/lara/common.c', 'src/game/lara/lara_cheat.c', 'src/game/lara/lara_col.c', 'src/game/lara/lara_control.c', diff --git a/src/game/console.c b/src/game/console.c index 63f22578..e4d91726 100644 --- a/src/game/console.c +++ b/src/game/console.c @@ -1,7 +1,6 @@ #include "game/console.h" #include "game/clock.h" -#include "game/console_cmd.h" #include "game/game_string.h" #include "game/input.h" #include "game/output.h" @@ -9,6 +8,7 @@ #include "global/const.h" #include "global/types.h" +#include #include #include #include @@ -51,6 +51,7 @@ static void Console_UpdatePromptTextstring(void); static void Console_UpdateCaretTextstring(void); static COMMAND_RESULT Console_Eval(const char *cmdline); +extern CONSOLE_COMMAND *g_ConsoleCommands[]; static void Console_ShutdownPrompt(void) { if (m_Prompt.prompt_ts != NULL) { @@ -91,8 +92,11 @@ static COMMAND_RESULT Console_Eval(const char *const cmdline) const char *args = NULL; const CONSOLE_COMMAND *matching_cmd = NULL; - for (CONSOLE_COMMAND *cur_cmd = &g_ConsoleCommands[0]; - cur_cmd->proc != NULL; cur_cmd++) { + for (int32_t i = 0;; i++) { + CONSOLE_COMMAND *cur_cmd = g_ConsoleCommands[i]; + if (cur_cmd == NULL) { + break; + } if (strstr(cmdline, cur_cmd->prefix) != cmdline) { continue; } diff --git a/src/game/console_cmd.c b/src/game/console_cmd.c index f41e4a8b..e2a2eaf4 100644 --- a/src/game/console_cmd.c +++ b/src/game/console_cmd.c @@ -1,5 +1,3 @@ -#include "game/console_cmd.h" - #include "decomp/effects.h" #include "game/console.h" #include "game/creature.h" @@ -20,6 +18,8 @@ #include "global/vars.h" #include "lara/lara_misc.h" +#include +#include #include #include @@ -30,7 +30,6 @@ static bool Console_Cmd_CanTargetObject(GAME_OBJECT_ID object_id); static bool Console_Cmd_CanTargetObjectCreature(GAME_OBJECT_ID object_id); static bool Console_Cmd_CanTargetObjectPickup(GAME_OBJECT_ID object_id); static bool Console_Cmd_IsFloatRound(float num); -static COMMAND_RESULT Console_Cmd_Pos(const char *args); static COMMAND_RESULT Console_Cmd_Teleport(const char *args); static COMMAND_RESULT Console_Cmd_SetHealth(const char *args); static COMMAND_RESULT Console_Cmd_Heal(const char *args); @@ -70,22 +69,6 @@ static inline bool Console_Cmd_IsFloatRound(const float num) return (fabsf(num) - roundf(num)) < 0.0001f; } -static COMMAND_RESULT Console_Cmd_Pos(const char *const args) -{ - if (!g_Objects[O_LARA].loaded) { - return CR_UNAVAILABLE; - } - - Console_Log( - GS(OSD_POS_GET), g_LaraItem->room_num, - g_LaraItem->pos.x / (float)WALL_L, g_LaraItem->pos.y / (float)WALL_L, - g_LaraItem->pos.z / (float)WALL_L, - g_LaraItem->rot.x * 360.0f / (float)PHD_ONE, - g_LaraItem->rot.y * 360.0f / (float)PHD_ONE, - g_LaraItem->rot.z * 360.0f / (float)PHD_ONE); - return CR_SUCCESS; -} - static COMMAND_RESULT Console_Cmd_Teleport(const char *const args) { if (g_GameInfo.current_level.type == GFL_TITLE @@ -603,26 +586,27 @@ static COMMAND_RESULT Console_Cmd_Abortion(const char *const args) return CR_SUCCESS; } -CONSOLE_COMMAND g_ConsoleCommands[] = { - { .prefix = "pos", .proc = Console_Cmd_Pos }, - { .prefix = "tp", .proc = Console_Cmd_Teleport }, - { .prefix = "hp", .proc = Console_Cmd_SetHealth }, - { .prefix = "heal", .proc = Console_Cmd_Heal }, - { .prefix = "fly", .proc = Console_Cmd_Fly }, - { .prefix = "give", .proc = Console_Cmd_GiveItem }, - { .prefix = "gimme", .proc = Console_Cmd_GiveItem }, - { .prefix = "flip", .proc = Console_Cmd_FlipMap }, - { .prefix = "flipmap", .proc = Console_Cmd_FlipMap }, - { .prefix = "kill", .proc = Console_Cmd_Kill }, - { .prefix = "endlevel", .proc = Console_Cmd_EndLevel }, - { .prefix = "play", .proc = Console_Cmd_StartLevel }, - { .prefix = "level", .proc = Console_Cmd_StartLevel }, - { .prefix = "load", .proc = Console_Cmd_LoadGame }, - { .prefix = "save", .proc = Console_Cmd_SaveGame }, - { .prefix = "demo", .proc = Console_Cmd_StartDemo }, - { .prefix = "title", .proc = Console_Cmd_ExitToTitle }, - { .prefix = "exit", .proc = Console_Cmd_ExitGame }, - { .prefix = "abortion", .proc = Console_Cmd_Abortion }, - { .prefix = "natlastinks", .proc = Console_Cmd_Abortion }, - { .prefix = NULL, .proc = NULL }, +CONSOLE_COMMAND *g_ConsoleCommands[] = { + &(CONSOLE_COMMAND) { .prefix = "tp", .proc = Console_Cmd_Teleport }, + &(CONSOLE_COMMAND) { .prefix = "hp", .proc = Console_Cmd_SetHealth }, + &(CONSOLE_COMMAND) { .prefix = "heal", .proc = Console_Cmd_Heal }, + &(CONSOLE_COMMAND) { .prefix = "fly", .proc = Console_Cmd_Fly }, + &(CONSOLE_COMMAND) { .prefix = "give", .proc = Console_Cmd_GiveItem }, + &(CONSOLE_COMMAND) { .prefix = "gimme", .proc = Console_Cmd_GiveItem }, + &(CONSOLE_COMMAND) { .prefix = "flip", .proc = Console_Cmd_FlipMap }, + &(CONSOLE_COMMAND) { .prefix = "flipmap", .proc = Console_Cmd_FlipMap }, + &(CONSOLE_COMMAND) { .prefix = "kill", .proc = Console_Cmd_Kill }, + &(CONSOLE_COMMAND) { .prefix = "endlevel", .proc = Console_Cmd_EndLevel }, + &(CONSOLE_COMMAND) { .prefix = "play", .proc = Console_Cmd_StartLevel }, + &(CONSOLE_COMMAND) { .prefix = "level", .proc = Console_Cmd_StartLevel }, + &(CONSOLE_COMMAND) { .prefix = "load", .proc = Console_Cmd_LoadGame }, + &(CONSOLE_COMMAND) { .prefix = "save", .proc = Console_Cmd_SaveGame }, + &(CONSOLE_COMMAND) { .prefix = "demo", .proc = Console_Cmd_StartDemo }, + &(CONSOLE_COMMAND) { .prefix = "title", .proc = Console_Cmd_ExitToTitle }, + &(CONSOLE_COMMAND) { .prefix = "exit", .proc = Console_Cmd_ExitGame }, + &(CONSOLE_COMMAND) { .prefix = "abortion", .proc = Console_Cmd_Abortion }, + &(CONSOLE_COMMAND) { .prefix = "natlastinks", + .proc = Console_Cmd_Abortion }, + &g_Console_Cmd_Pos, + NULL, }; diff --git a/src/game/console_cmd.h b/src/game/console_cmd.h deleted file mode 100644 index cc218c34..00000000 --- a/src/game/console_cmd.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -typedef enum { - CR_SUCCESS, - CR_FAILURE, - CR_UNAVAILABLE, - CR_BAD_INVOCATION, -} COMMAND_RESULT; - -typedef struct CONSOLE_COMMAND { - const char *prefix; - COMMAND_RESULT (*proc)(const char *args); -} CONSOLE_COMMAND; - -extern CONSOLE_COMMAND g_ConsoleCommands[]; diff --git a/src/game/game_string.c b/src/game/game_string.c index aff8bd57..56bf3122 100644 --- a/src/game/game_string.c +++ b/src/game/game_string.c @@ -5,6 +5,8 @@ void GameString_Init(void) { #include "game_string.def" + +#include } void GameString_Shutdown(void) diff --git a/src/game/game_string.def b/src/game/game_string.def index f3f7a24f..49cc2d42 100644 --- a/src/game/game_string.def +++ b/src/game/game_string.def @@ -1,6 +1,5 @@ GS_DEFINE(OSD_FLY_MODE_ON, "Fly mode enabled") GS_DEFINE(OSD_FLY_MODE_OFF, "Fly mode disabled") -GS_DEFINE(OSD_POS_GET, "Room: %d\nPosition: %.3f, %.3f, %.3f\nRotation: %.3f,%.3f,%.3f") GS_DEFINE(OSD_POS_SET_POS, "Teleported to position: %.3f %.3f %.3f") GS_DEFINE(OSD_POS_SET_POS_FAIL, "Failed to teleport to position: %.3f %.3f %.3f") GS_DEFINE(OSD_POS_SET_ROOM, "Teleported to room: %d") diff --git a/src/game/lara/common.c b/src/game/lara/common.c new file mode 100644 index 00000000..d0ec42c7 --- /dev/null +++ b/src/game/lara/common.c @@ -0,0 +1,8 @@ +#include "game/lara/common.h" + +#include "global/vars.h" + +ITEM_INFO *Lara_GetItem(void) +{ + return g_LaraItem; +} diff --git a/src/game/lara/common.h b/src/game/lara/common.h new file mode 100644 index 00000000..ee4675e4 --- /dev/null +++ b/src/game/lara/common.h @@ -0,0 +1,5 @@ +#pragma once + +#include "game/items.h" + +ITEM_INFO *Lara_GetItem(void); diff --git a/src/game/objects/common.c b/src/game/objects/common.c index 278c77cf..7276dd5c 100644 --- a/src/game/objects/common.c +++ b/src/game/objects/common.c @@ -5,6 +5,11 @@ #include "global/funcs.h" #include "global/vars.h" +OBJECT_INFO *Object_GetObject(GAME_OBJECT_ID object_id) +{ + return &g_Objects[object_id]; +} + GAME_OBJECT_ID Object_GetCognate( GAME_OBJECT_ID key_id, const GAME_OBJECT_PAIR *test_map) { diff --git a/src/game/objects/common.h b/src/game/objects/common.h index d5f7b242..35f2b699 100644 --- a/src/game/objects/common.h +++ b/src/game/objects/common.h @@ -7,6 +7,7 @@ typedef struct GAME_OBJECT_PAIR { const GAME_OBJECT_ID value_id; } GAME_OBJECT_PAIR; +OBJECT_INFO *Object_Get(GAME_OBJECT_ID object_id); GAME_OBJECT_ID Object_GetCognate( GAME_OBJECT_ID key_id, const GAME_OBJECT_PAIR *test_map); GAME_OBJECT_ID Object_GetCognateInverse( diff --git a/src/global/types.h b/src/global/types.h index f916c689..7e2f4fc0 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -4,8 +4,10 @@ #include "const.h" +#include #include #include +#include #include #include @@ -463,43 +465,6 @@ typedef enum { DRAW_COLOR_KEY = 1, } DRAW_TYPE; -typedef struct __unaligned { - int32_t floor; - int32_t ceiling; - int32_t type; -} COLL_SIDE; - -typedef struct __unaligned { - COLL_SIDE side_mid; - COLL_SIDE side_front; - COLL_SIDE side_left; - COLL_SIDE side_right; - int32_t radius; - int32_t bad_pos; - int32_t bad_neg; - int32_t bad_ceiling; - XYZ_32 shift; - XYZ_32 old; - int16_t old_anim_state; - int16_t old_anim_num; - int16_t old_frame_num; - int16_t facing; - int16_t quadrant; - int16_t coll_type; - int16_t *trigger; - int8_t x_tilt; - int8_t z_tilt; - int8_t hit_by_baddie; - int8_t hit_static; - uint16_t slopes_are_walls: 1; // 0x01 1 - uint16_t slopes_are_pits: 1; // 0x02 2 - uint16_t lava_is_pit: 1; // 0x04 4 - uint16_t enable_baddie_push: 1; // 0x08 8 - uint16_t enable_spaz: 1; // 0x10 16 - uint16_t hit_ceiling: 1; // 0x20 32 - uint16_t pad: 10; -} COLL_INFO; - typedef struct __unaligned { int16_t min_x; int16_t max_x; @@ -1056,46 +1021,6 @@ typedef struct __unaligned { uint16_t reserved4[2]; } GAME_FLOW; -typedef struct __unaligned { - int16_t mesh_count; - int16_t mesh_idx; - int32_t bone_idx; - int16_t *frame_base; // TODO: make me FRAME_INFO - - void (*initialise)(int16_t item_num); - void (*control)(int16_t item_num); - void (*floor)( - const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, - int32_t *height); - void (*ceiling)( - const ITEM_INFO *item, int32_t x, int32_t y, int32_t z, - int32_t *height); - void (*draw_routine)(const ITEM_INFO *item); - void (*collision)(int16_t - item_num, ITEM_INFO *lara_item, COLL_INFO *coll); - - int16_t anim_idx; - int16_t hit_points; - int16_t pivot_length; - int16_t radius; - int16_t shadow_size; - - union { - uint16_t flags; - struct { - uint16_t loaded: 1; // 0x01 1 - uint16_t intelligent: 1; // 0x02 2 - uint16_t save_position: 1; // 0x04 4 - uint16_t save_hitpoints: 1; // 0x08 8 - uint16_t save_flags: 1; // 0x10 16 - uint16_t save_anim: 1; // 0x20 32 - uint16_t semi_transparent: 1; // 0x40 64 - uint16_t water_creature: 1; // 0x80 128 - uint16_t pad : 8; - }; - }; -} OBJECT_INFO; - typedef struct __unaligned { GAME_VECTOR pos; GAME_VECTOR target; diff --git a/subprojects/libtrx b/subprojects/libtrx index c1f3ab51..4f8c78dc 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit c1f3ab51a07bd8ff93f975b3112830f838147a21 +Subproject commit 4f8c78dc1ef579df12b507d5eef7b8004023d253 diff --git a/tools/generate_funcs b/tools/generate_funcs index 9d484203..7bfd2608 100755 --- a/tools/generate_funcs +++ b/tools/generate_funcs @@ -113,8 +113,10 @@ def make_types_h(types: list[str]) -> None: *COMMON_HEADER, '#include "const.h"', "", + "#include ", "#include ", "#include ", + "#include ", "", "#include ", "#include ", diff --git a/tools/tr2x/paths.py b/tools/tr2x/paths.py index ebc12274..759504b2 100644 --- a/tools/tr2x/paths.py +++ b/tools/tr2x/paths.py @@ -6,4 +6,8 @@ TR2X_DATA_DIR = TR2X_REPO_DIR / "data" TR2X_SRC_DIR = TR2X_REPO_DIR / "src" +LIBTRX_REPO_DIR = TR2X_REPO_DIR / "subprojects/libtrx" +LIBTRX_SRC_DIR = LIBTRX_REPO_DIR / "src" +LIBTRX_INCLUDE_DIR = LIBTRX_REPO_DIR / "include/libtrx" + TR2X_PROGRESS_FILE = TR2X_DOCS_DIR / "progress.txt" diff --git a/tools/update_gameflow b/tools/update_gameflow index e359f9dd..f7e9bb81 100755 --- a/tools/update_gameflow +++ b/tools/update_gameflow @@ -1,24 +1,34 @@ #!/usr/bin/env python3 -from pathlib import Path import json import re +from pathlib import Path -from tr2x.paths import TR2X_DATA_DIR, TR2X_SRC_DIR +from tr2x.paths import LIBTRX_INCLUDE_DIR, TR2X_DATA_DIR, TR2X_SRC_DIR SHIP_DIR = TR2X_DATA_DIR / "ship" -GAME_STRINGS_DEF_PATH = TR2X_SRC_DIR / "game/game_string.def" +GAME_STRING_DEF_PATHS = [ + TR2X_SRC_DIR / "game/game_string.def", + LIBTRX_INCLUDE_DIR / "game/game_string.def", +] OBJECT_STRINGS_DEF_PATH = TR2X_SRC_DIR / "game/objects/names.def" -def get_string_map(path: Path) -> dict[str, str]: +def get_strings_map(paths: list[Path]) -> dict[str, str]: result: dict[str, str] = {} - for line in path.read_text().splitlines(): - if match := re.match(r'^[A-Z_]*_DEFINE\((\w+),\s*"([^"]+)"\)$', line.strip()): - result[match.group(1)] = match.group(2) + for path in paths: + for line in path.read_text().splitlines(): + if match := re.match( + r'^\w+DEFINE\((\w+),\s*"([^"]+)"\)$', line.strip() + ): + result[match.group(1)] = match.group(2) return result -def postprocess_gameflow(gameflow: str, object_strings_map: dict[str, str], game_strings_map: dict[str, str]) -> str: +def postprocess_gameflow( + gameflow: str, + object_strings_map: dict[str, str], + game_strings_map: dict[str, str], +) -> str: gameflow = re.sub( r'^( "object_strings": {)[^}]*(})', ' "object_strings": {\n' @@ -36,7 +46,9 @@ def postprocess_gameflow(gameflow: str, object_strings_map: dict[str, str], game ' "game_strings": {\n' + "\n".join( f" {json.dumps(key)}: {json.dumps(value)}," - for key, value in game_strings_map.items() + for key, value in sorted( + game_strings_map.items(), key=lambda kv: kv[0] + ) ) + "\n }", gameflow, @@ -46,14 +58,16 @@ def postprocess_gameflow(gameflow: str, object_strings_map: dict[str, str], game def main() -> None: - object_strings_map = get_string_map(OBJECT_STRINGS_DEF_PATH) - game_strings_map = get_string_map(GAME_STRINGS_DEF_PATH) + object_strings_map = get_strings_map([OBJECT_STRINGS_DEF_PATH]) + game_strings_map = get_strings_map(GAME_STRING_DEF_PATHS) assert object_strings_map assert game_strings_map for gameflow_path in SHIP_DIR.rglob("*gameflow*.json*"): old_gameflow = gameflow_path.read_text() - new_gameflow = postprocess_gameflow(old_gameflow, object_strings_map, game_strings_map) + new_gameflow = postprocess_gameflow( + old_gameflow, object_strings_map, game_strings_map + ) if new_gameflow != old_gameflow: gameflow_path.write_text(new_gameflow) From 86bf636e1c481c079844792de358c9ae6c0f511e Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Wed, 18 Sep 2024 01:37:16 +0200 Subject: [PATCH 2/3] console/cmd: move /hp to libtrx --- src/game/console_cmd.c | 31 ++----------------------------- src/game/game.c | 16 ++++++++++++++++ src/game/game.h | 1 + subprojects/libtrx | 2 +- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/src/game/console_cmd.c b/src/game/console_cmd.c index e2a2eaf4..a1ba93f6 100644 --- a/src/game/console_cmd.c +++ b/src/game/console_cmd.c @@ -19,6 +19,7 @@ #include "lara/lara_misc.h" #include +#include #include #include #include @@ -31,7 +32,6 @@ static bool Console_Cmd_CanTargetObjectCreature(GAME_OBJECT_ID object_id); static bool Console_Cmd_CanTargetObjectPickup(GAME_OBJECT_ID object_id); static bool Console_Cmd_IsFloatRound(float num); static COMMAND_RESULT Console_Cmd_Teleport(const char *args); -static COMMAND_RESULT Console_Cmd_SetHealth(const char *args); static COMMAND_RESULT Console_Cmd_Heal(const char *args); static COMMAND_RESULT Console_Cmd_Fly(const char *const args); static COMMAND_RESULT Console_Cmd_FlipMap(const char *args); @@ -199,33 +199,6 @@ static COMMAND_RESULT Console_Cmd_Teleport(const char *const args) return CR_BAD_INVOCATION; } -static COMMAND_RESULT Console_Cmd_SetHealth(const char *const args) -{ - if (g_GameInfo.current_level.type == GFL_TITLE - || g_GameInfo.current_level.type == GFL_DEMO - || g_GameInfo.current_level.type == GFL_CUTSCENE) { - return CR_UNAVAILABLE; - } - - if (!g_Objects[O_LARA].loaded) { - return CR_UNAVAILABLE; - } - - if (strcmp(args, "") == 0) { - Console_Log(GS(OSD_CURRENT_HEALTH_GET), g_LaraItem->hit_points); - return CR_SUCCESS; - } - - int32_t hp; - if (sscanf(args, "%d", &hp) != 1) { - return CR_BAD_INVOCATION; - } - - g_LaraItem->hit_points = hp; - Console_Log(GS(OSD_CURRENT_HEALTH_SET), hp); - return CR_SUCCESS; -} - static COMMAND_RESULT Console_Cmd_Heal(const char *const args) { if (g_GameInfo.current_level.type == GFL_TITLE @@ -588,7 +561,6 @@ static COMMAND_RESULT Console_Cmd_Abortion(const char *const args) CONSOLE_COMMAND *g_ConsoleCommands[] = { &(CONSOLE_COMMAND) { .prefix = "tp", .proc = Console_Cmd_Teleport }, - &(CONSOLE_COMMAND) { .prefix = "hp", .proc = Console_Cmd_SetHealth }, &(CONSOLE_COMMAND) { .prefix = "heal", .proc = Console_Cmd_Heal }, &(CONSOLE_COMMAND) { .prefix = "fly", .proc = Console_Cmd_Fly }, &(CONSOLE_COMMAND) { .prefix = "give", .proc = Console_Cmd_GiveItem }, @@ -608,5 +580,6 @@ CONSOLE_COMMAND *g_ConsoleCommands[] = { &(CONSOLE_COMMAND) { .prefix = "natlastinks", .proc = Console_Cmd_Abortion }, &g_Console_Cmd_Pos, + &g_Console_Cmd_SetHealth, NULL, }; diff --git a/src/game/game.c b/src/game/game.c index f1848547..903243e0 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -3,6 +3,7 @@ #include "decomp/decomp.h" #include "game/camera.h" #include "game/demo.h" +#include "game/gameflow/gameflow_new.h" #include "game/input.h" #include "game/inventory/common.h" #include "game/lara/lara_control.h" @@ -296,3 +297,18 @@ int32_t __cdecl Game_Loop(const bool demo_mode) return dir; } + +bool Game_IsPlayable(void) +{ + if (g_GameInfo.current_level.type == GFL_TITLE + || g_GameInfo.current_level.type == GFL_DEMO + || g_GameInfo.current_level.type == GFL_CUTSCENE) { + return false; + } + + if (!g_Objects[O_LARA].loaded) { + return false; + } + + return true; +} diff --git a/src/game/game.h b/src/game/game.h index 2115e0f8..6a32c5f9 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -7,3 +7,4 @@ int32_t __cdecl Game_Draw(void); int32_t __cdecl Game_DrawCinematic(void); int16_t __cdecl Game_Start(int32_t level_num, GF_LEVEL_TYPE level_type); int32_t __cdecl Game_Loop(bool demo_mode); +bool Game_IsPlayable(void); diff --git a/subprojects/libtrx b/subprojects/libtrx index 4f8c78dc..d9f924c5 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit 4f8c78dc1ef579df12b507d5eef7b8004023d253 +Subproject commit d9f924c571287ac61d2a8ac325c781836a102d3b From 54c84fdccc7d9364dba2c5ced223561fc5fec60d Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Wed, 18 Sep 2024 01:49:23 +0200 Subject: [PATCH 3/3] console/cmd: improve /hp input sanitization --- CHANGELOG.md | 1 + subprojects/libtrx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb5651f8..ee7389cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - fixed secret rewards not displaying shotgun ammo (#159) - fixed controls dialog remapping being too sensitive (#5) - fixed `/tp` console command during special animations in HSH and Offshore Rig (#178, regression from 0.2) +- fixed `/hp` console command taking arbitrary integers - fixed console commands being able to interfere with demos, cutscenes and the title screen (#182, #179, regression from 0.2) - fixed console registering key inputs too eagerly (regression from 0.2) - fixed console not being drawn in cutscenes (#180, regression from 0.2) diff --git a/subprojects/libtrx b/subprojects/libtrx index d9f924c5..b95beda5 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit d9f924c571287ac61d2a8ac325c781836a102d3b +Subproject commit b95beda546dc57bb42dcd781471e13e10a82b9fd