mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 12:47:58 +03:00
parent
83ab279364
commit
27edc31c0a
19 changed files with 79 additions and 1701 deletions
Binary file not shown.
|
@ -1,4 +1,5 @@
|
|||
## [Unreleased](https://github.com/LostArtefacts/TRX/compare/tr2-0.7.1...develop) - ××××-××-××
|
||||
- completed decompilation efforts – TR2X.dll is gone, Tomb2.exe no longer needed (#1694)
|
||||
- added an option to use PS1 contrast levels, available under F8 (#1646)
|
||||
- added an option to allow disabling the developer console (#2063)
|
||||
- fixed Lara prioritising throwing a spent flare while mid-air, so to avoid missing ledge grabs (#1989)
|
||||
|
|
|
@ -58,27 +58,6 @@ typedef enum {
|
|||
LA_VEHICLE_HIT_BACK = 14,
|
||||
} LARA_ANIM_VEHICLE;
|
||||
|
||||
int32_t __stdcall WinMain(
|
||||
HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
|
||||
int32_t nShowCmd)
|
||||
{
|
||||
g_CmdLine = lpCmdLine;
|
||||
HWND game_window = WinVidFindGameWindow();
|
||||
if (game_window) {
|
||||
SetForegroundWindow(game_window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_AppResultCode = 0;
|
||||
g_IsGameToExit = false;
|
||||
Shell_Setup();
|
||||
Shell_Main();
|
||||
Shell_Shutdown();
|
||||
|
||||
cleanup:
|
||||
return g_AppResultCode;
|
||||
}
|
||||
|
||||
int16_t __cdecl TitleSequence(void)
|
||||
{
|
||||
GF_N_LoadStrings(-1);
|
||||
|
@ -134,11 +113,6 @@ int16_t __cdecl TitleSequence(void)
|
|||
return GFD_EXIT_GAME;
|
||||
}
|
||||
|
||||
HWND __cdecl WinVidFindGameWindow(void)
|
||||
{
|
||||
return FindWindowA(CLASS_NAME, WINDOW_NAME);
|
||||
}
|
||||
|
||||
void __cdecl Game_SetCutsceneTrack(const int32_t track)
|
||||
{
|
||||
g_CineTrackID = track;
|
||||
|
|
|
@ -3,18 +3,13 @@
|
|||
#include "global/types.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
// TODO: This is a placeholder file containing functions that originated from
|
||||
// the decompilation phase, and they are currently disorganized. Eventually,
|
||||
// they'll need to be properly modularized. The same applies to all files
|
||||
// within the decomp/ directory which are scheduled for extensive refactoring.
|
||||
|
||||
int32_t __stdcall WinMain(
|
||||
HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
|
||||
int32_t nShowCmd);
|
||||
int16_t __cdecl TitleSequence(void);
|
||||
HWND __cdecl WinVidFindGameWindow(void);
|
||||
void __cdecl Game_SetCutsceneTrack(int32_t track);
|
||||
void __cdecl CutscenePlayer_Control(int16_t item_num);
|
||||
void __cdecl Lara_Control_Cutscene(int16_t item_num);
|
||||
|
|
|
@ -185,6 +185,10 @@ void __cdecl Effect_CreateBartoliLight(const int16_t item_num)
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
void FX_Empty(ITEM *const item)
|
||||
{
|
||||
}
|
||||
|
||||
void __cdecl FX_AssaultStart(ITEM *const item)
|
||||
{
|
||||
g_SaveGame.statistics.timer = 0;
|
||||
|
|
|
@ -11,6 +11,7 @@ int16_t __cdecl Effect_MissileFlame(
|
|||
|
||||
void __cdecl Effect_CreateBartoliLight(int16_t item_num);
|
||||
|
||||
void FX_Empty(ITEM *item);
|
||||
void __cdecl FX_AssaultStart(ITEM *item);
|
||||
|
||||
void __cdecl CreateBubble(const XYZ_32 *pos, int16_t room_num);
|
||||
|
|
|
@ -182,9 +182,7 @@ cleanup:
|
|||
|
||||
void Pickup_Setup(OBJECT *const obj)
|
||||
{
|
||||
// TODO: change this to Pickup_Collision after we decompile
|
||||
// both comparisons in ExtractSaveGameInfo() and GetCarriedItems()
|
||||
obj->collision = (void *)0x00437E70;
|
||||
obj->collision = Pickup_Collision;
|
||||
obj->draw_routine = Pickup_Draw;
|
||||
obj->save_position = 1;
|
||||
obj->save_flags = 1;
|
||||
|
|
|
@ -55,9 +55,7 @@ static void M_MarkDone(ITEM *const puzzle_hole_item)
|
|||
void PuzzleHole_Setup(OBJECT *const obj, const bool done)
|
||||
{
|
||||
if (!done) {
|
||||
// TODO: change this to PuzzleHole_Collision after we decompile
|
||||
// the comparison in ExtractSaveGameInfo()
|
||||
obj->collision = (void *)0x00438A80;
|
||||
obj->collision = PuzzleHole_Collision;
|
||||
}
|
||||
obj->save_flags = 1;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "global/vars.h"
|
||||
|
||||
#include "decomp/effects.h"
|
||||
|
||||
#include <libtrx/game/sound/ids.h>
|
||||
|
||||
#ifndef MESON_BUILD
|
||||
|
@ -23,7 +25,42 @@ int32_t g_CineTrackID = 1;
|
|||
int32_t g_CineTickRate = 0x8000; // PHD_ONE/TICKS_PER_FRAME
|
||||
int32_t g_FlipEffect = -1;
|
||||
uint32_t g_AssaultBestTime = -1;
|
||||
void (*g_EffectRoutines[32])(ITEM *item);
|
||||
|
||||
void (*g_EffectRoutines[])(ITEM *item) = {
|
||||
FX_Turn180,
|
||||
FX_FloorShake,
|
||||
FX_LaraNormal,
|
||||
FX_Bubbles,
|
||||
FX_FinishLevel,
|
||||
FX_Flood,
|
||||
FX_Chandelier,
|
||||
FX_Rubble,
|
||||
FX_Piston,
|
||||
FX_Curtain,
|
||||
FX_SetChange,
|
||||
FX_Explosion,
|
||||
FX_LaraHandsFree,
|
||||
FX_FlipMap,
|
||||
FX_LaraDrawRightGun,
|
||||
FX_LaraDrawLeftGun,
|
||||
FX_Empty,
|
||||
FX_Empty,
|
||||
FX_SwapMeshesWithMeshSwap1,
|
||||
FX_SwapMeshesWithMeshSwap2,
|
||||
FX_SwapMeshesWithMeshSwap3,
|
||||
FX_InvisibilityOn,
|
||||
FX_InvisibilityOff,
|
||||
FX_DynamicLightOn,
|
||||
FX_DynamicLightOff,
|
||||
FX_Statue,
|
||||
FX_ResetHair,
|
||||
FX_Boiler,
|
||||
FX_AssaultReset,
|
||||
FX_AssaultStop,
|
||||
FX_AssaultStart,
|
||||
FX_AssaultFinished,
|
||||
};
|
||||
|
||||
int16_t g_CineTargetAngle = PHD_90;
|
||||
int32_t g_OverlayStatus = 1;
|
||||
int16_t g_Inv_MainObjectsCount = 8;
|
||||
|
|
|
@ -24,7 +24,7 @@ extern int32_t g_CineTrackID;
|
|||
extern int32_t g_CineTickRate;
|
||||
extern int32_t g_FlipEffect;
|
||||
extern uint32_t g_AssaultBestTime;
|
||||
extern void (*g_EffectRoutines[32])(ITEM *item);
|
||||
extern void (*g_EffectRoutines[])(ITEM *item);
|
||||
extern int16_t g_CineTargetAngle;
|
||||
extern int32_t g_OverlayStatus;
|
||||
extern int16_t g_Inv_MainObjectsCount;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,3 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
void Inject_Exec(void);
|
|
@ -1,28 +0,0 @@
|
|||
#include "inject_util.h"
|
||||
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
void InjectImpl(bool enable, void (*from)(void), void (*to)(void))
|
||||
{
|
||||
if (from == to) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
void (*aux)(void) = from;
|
||||
from = to;
|
||||
to = aux;
|
||||
}
|
||||
|
||||
DWORD tmp;
|
||||
LOG_DEBUG("Patching %p to %p", from, to);
|
||||
VirtualProtect(from, sizeof(JMP), PAGE_EXECUTE_READWRITE, &tmp);
|
||||
HANDLE hCurrentProcess = GetCurrentProcess();
|
||||
JMP buf;
|
||||
buf.opcode = 0xE9;
|
||||
buf.offset = (DWORD)(to) - ((DWORD)(from) + sizeof(JMP));
|
||||
WriteProcessMemory(hCurrentProcess, from, &buf, sizeof(JMP), &tmp);
|
||||
CloseHandle(hCurrentProcess);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
uint8_t opcode; // must be 0xE9
|
||||
uint32_t offset;
|
||||
} JMP;
|
||||
#pragma pack(pop)
|
||||
|
||||
void InjectImpl(bool enable, void (*from)(void), void (*to)(void));
|
||||
|
||||
#define INJECT(enable, from, to) \
|
||||
{ \
|
||||
InjectImpl(enable, (void (*)(void))from, (void (*)(void))to); \
|
||||
}
|
24
src/tr2/main.c
Normal file
24
src/tr2/main.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "decomp/decomp.h"
|
||||
#include "game/shell.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/filesystem.h>
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
int32_t __stdcall WinMain(
|
||||
HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
|
||||
int32_t nShowCmd)
|
||||
{
|
||||
Log_Init(File_GetFullPath("TR2X.log"));
|
||||
g_CmdLine = lpCmdLine;
|
||||
g_AppResultCode = 0;
|
||||
g_IsGameToExit = false;
|
||||
Shell_Setup();
|
||||
Shell_Main();
|
||||
Shell_Shutdown();
|
||||
|
||||
cleanup:
|
||||
return g_AppResultCode;
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
#include "inject_exec.h"
|
||||
|
||||
#include <libtrx/filesystem.h>
|
||||
#include <libtrx/log.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
BOOL APIENTRY
|
||||
DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
Log_Init(File_GetFullPath("TR2X.log"));
|
||||
LOG_DEBUG("Injected\n");
|
||||
|
||||
Inject_Exec();
|
||||
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
LOG_DEBUG("Exiting\n");
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
// The path to the legitimate host process
|
||||
const char *m_HostProcessPath = "Tomb2.exe";
|
||||
|
||||
static bool M_FileExists(const char *path)
|
||||
{
|
||||
DWORD fileAttributes = GetFileAttributes(path);
|
||||
if (fileAttributes != INVALID_FILE_ATTRIBUTES
|
||||
&& !(fileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool M_InjectDLL(HANDLE process_handle, const char *dll_path)
|
||||
{
|
||||
bool success = false;
|
||||
LPVOID load_library_addr =
|
||||
(LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
|
||||
|
||||
fprintf(stderr, "Injecting %s\n", dll_path);
|
||||
|
||||
if (!M_FileExists(dll_path)) {
|
||||
fprintf(stderr, "DLL does not exist.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
LPVOID dll_path_adr = VirtualAllocEx(
|
||||
process_handle, NULL, strlen(dll_path) + 1, MEM_RESERVE | MEM_COMMIT,
|
||||
PAGE_READWRITE);
|
||||
if (!dll_path_adr) {
|
||||
fprintf(stderr, "Failed to allocate remote memory.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!WriteProcessMemory(
|
||||
process_handle, dll_path_adr, dll_path, strlen(dll_path) + 1,
|
||||
NULL)) {
|
||||
fprintf(stderr, "Failed to write remote memory.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
HANDLE remote_thread_handle = CreateRemoteThread(
|
||||
process_handle, NULL, 0, (LPTHREAD_START_ROUTINE)load_library_addr,
|
||||
dll_path_adr, 0, NULL);
|
||||
if (remote_thread_handle == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "Failed to create remote thread.\n");
|
||||
goto finish;
|
||||
}
|
||||
WaitForSingleObject(remote_thread_handle, INFINITE);
|
||||
|
||||
VirtualFreeEx(
|
||||
process_handle, dll_path_adr, strlen(dll_path) + 1, MEM_RELEASE);
|
||||
CloseHandle(remote_thread_handle);
|
||||
|
||||
success = true;
|
||||
finish:
|
||||
return success;
|
||||
}
|
||||
|
||||
const char *GetDLLPath(void)
|
||||
{
|
||||
static char dll_path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, dll_path, MAX_PATH);
|
||||
char *suffix = strstr(dll_path, ".exe");
|
||||
if (suffix != NULL) {
|
||||
strcpy(suffix, ".dll");
|
||||
}
|
||||
return dll_path;
|
||||
}
|
||||
|
||||
char *GetHostProcessArguments(
|
||||
const char *host_process_path, const int32_t argc, const char *const argv[])
|
||||
{
|
||||
size_t length = 1; // null terminator
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
if (i > 0) {
|
||||
length++;
|
||||
}
|
||||
|
||||
const char *arg = i == 0 ? host_process_path : argv[i];
|
||||
if (strchr(arg, ' ')) {
|
||||
length += 1;
|
||||
length += strlen(arg);
|
||||
length += 1;
|
||||
} else {
|
||||
length += strlen(arg);
|
||||
}
|
||||
}
|
||||
|
||||
char *cmdline = malloc(length);
|
||||
cmdline[0] = '\0';
|
||||
|
||||
for (int32_t i = 0; i < argc; i++) {
|
||||
if (i > 0) {
|
||||
strcat(cmdline, " ");
|
||||
}
|
||||
|
||||
const char *arg = i == 0 ? host_process_path : argv[i];
|
||||
if (strchr(arg, ' ')) {
|
||||
strcat(cmdline, "\"");
|
||||
strcat(cmdline, arg);
|
||||
strcat(cmdline, "\"");
|
||||
} else {
|
||||
strcat(cmdline, arg);
|
||||
}
|
||||
}
|
||||
|
||||
return cmdline;
|
||||
}
|
||||
|
||||
int32_t main(const int32_t argc, const char *const argv[])
|
||||
{
|
||||
bool success = false;
|
||||
const char *dll_path = GetDLLPath();
|
||||
char *cmdline = GetHostProcessArguments(m_HostProcessPath, argc, argv);
|
||||
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
|
||||
if (!CreateProcess(
|
||||
m_HostProcessPath, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED,
|
||||
NULL, NULL, &si, &pi)) {
|
||||
fprintf(stderr, "Failed to create the process.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!M_InjectDLL(pi.hProcess, dll_path)) {
|
||||
fprintf(stderr, "Failed to inject the DLL.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (ResumeThread(pi.hThread) == (DWORD)-1) {
|
||||
fprintf(stderr, "Failed to resume the execution of the process.\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
||||
finish:
|
||||
if (cmdline) {
|
||||
free(cmdline);
|
||||
cmdline = NULL;
|
||||
}
|
||||
if (pi.hThread) {
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
if (pi.hProcess) {
|
||||
CloseHandle(pi.hProcess);
|
||||
}
|
||||
return success ? 0 : 1;
|
||||
}
|
|
@ -31,8 +31,7 @@ dep_sdl2 = dependency('SDL2', static: staticdeps)
|
|||
dep_mathlibrary = c_compiler.find_library('m', static: staticdeps, required : false)
|
||||
|
||||
# autogenerated files
|
||||
exe_resources = []
|
||||
dll_resources = []
|
||||
resources = []
|
||||
python3 = find_program('python3', required: true)
|
||||
git = find_program('git', required: true)
|
||||
|
||||
|
@ -63,18 +62,12 @@ if host_machine.system() == 'windows'
|
|||
|
||||
version_resource = windows.compile_resources(version_rc)
|
||||
icon_resource = windows.compile_resources(icon_rc)
|
||||
exe_resources = [version_resource, icon_resource]
|
||||
dll_resources = [version_resource]
|
||||
resources = [version_resource, icon_resource]
|
||||
|
||||
link_args += ['-static']
|
||||
endif
|
||||
|
||||
exe_sources = [
|
||||
'main_exe.c',
|
||||
exe_resources,
|
||||
]
|
||||
|
||||
dll_sources = [
|
||||
sources = [
|
||||
init,
|
||||
'config.c',
|
||||
'config_map.c',
|
||||
|
@ -283,13 +276,11 @@ dll_sources = [
|
|||
'game/viewport.c',
|
||||
'global/enum_map.c',
|
||||
'global/vars.c',
|
||||
'inject_exec.c',
|
||||
'inject_util.c',
|
||||
'main_dll.c',
|
||||
dll_resources,
|
||||
'main.c',
|
||||
resources,
|
||||
]
|
||||
|
||||
dll_dependencies = [
|
||||
dependencies = [
|
||||
dep_trx,
|
||||
dep_sdl2,
|
||||
dep_mathlibrary,
|
||||
|
@ -297,16 +288,9 @@ dll_dependencies = [
|
|||
|
||||
executable(
|
||||
'TR2X',
|
||||
exe_sources,
|
||||
sources,
|
||||
name_prefix: '',
|
||||
link_args: link_args,
|
||||
dependencies: dependencies,
|
||||
gui_app: true,
|
||||
)
|
||||
|
||||
library(
|
||||
'TR2X',
|
||||
dll_sources,
|
||||
name_prefix: '',
|
||||
dependencies: dll_dependencies,
|
||||
link_args: link_args,
|
||||
)
|
||||
|
|
|
@ -1,185 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from shared.ida_progress import Symbol, parse_progress_file
|
||||
from shared.paths import TR2Paths
|
||||
|
||||
FUNCS_H_FILE = TR2Paths.src_dir / "global/funcs.h"
|
||||
VARS_H_FILE = TR2Paths.src_dir / "global/vars_decomp.h"
|
||||
TYPES_H_FILE = TR2Paths.src_dir / "global/types_decomp.h"
|
||||
|
||||
|
||||
COMMON_HEADER = [
|
||||
"// This file is autogenerated. To update it, run tools/generate_funcs.",
|
||||
"",
|
||||
"#pragma once",
|
||||
"",
|
||||
]
|
||||
|
||||
FUNC_PTR_RE = re.compile(
|
||||
r"^"
|
||||
r"(?P<ret_type>.+?)\s*"
|
||||
r"\("
|
||||
r"\s*\*(?P<call_type>.*?\s)\s*(?P<func_name>\w+)"
|
||||
r"(?P<array_def>\[[^\]]*?\]+)?"
|
||||
r"\)\s*"
|
||||
r"\((?P<args>.+)\)"
|
||||
r";?$"
|
||||
)
|
||||
|
||||
VAR_RE = re.compile(
|
||||
r"^"
|
||||
r"(?P<ret_type>.+?)\s*"
|
||||
r"(?P<var_name>\b\w+)\s*"
|
||||
r"(?P<array_def>(?:\[[^\]]*?\])*)"
|
||||
r"(\s*=\s*(?P<value_def>.*?))?"
|
||||
r";?"
|
||||
r"(\s*\/\/\s*(?P<comment>.*))?"
|
||||
r"$"
|
||||
)
|
||||
|
||||
|
||||
def update_file(path: Path, new_content: str) -> None:
|
||||
if path.read_text() != new_content:
|
||||
path.write_text(new_content)
|
||||
|
||||
|
||||
def make_func_pointer_define(function: Symbol) -> str:
|
||||
if match := re.match(
|
||||
r"(?P<ret_type>.+?\W)(?P<func_name>\b\w+)\s*\((?P<args>.+)\);?",
|
||||
function.signature,
|
||||
):
|
||||
ret_type = match.group("ret_type").strip()
|
||||
func_name = match.group("func_name").strip()
|
||||
args = match.group("args").strip()
|
||||
return f"#define {func_name} (({ret_type} (*)({args})){function.offset_str})"
|
||||
return ""
|
||||
|
||||
|
||||
def make_var_pointer_define(variable: Symbol) -> str:
|
||||
if match := FUNC_PTR_RE.match(variable.signature):
|
||||
ret_type = match.group("ret_type")
|
||||
call_type = match.group("call_type")
|
||||
array_def = match.group("array_def")
|
||||
func_name = match.group("func_name")
|
||||
args = match.group("args")
|
||||
if array_def:
|
||||
return f"#define {func_name} (*(({ret_type}({call_type} *(*){array_def})({args})){variable.offset_str}))"
|
||||
else:
|
||||
return f"#define {func_name} (*({ret_type}({call_type}**)({args})){variable.offset_str})"
|
||||
|
||||
if match := VAR_RE.match(variable.signature):
|
||||
ret_type = match.group("ret_type")
|
||||
var_name = match.group("var_name")
|
||||
array_def = match.group("array_def")
|
||||
value_def = match.group("value_def")
|
||||
comment = match.group("comment")
|
||||
if not array_def and not value_def and comment == "no-dereferencing":
|
||||
return f"#define {var_name} (({ret_type}){variable.offset_str})"
|
||||
if array_def:
|
||||
return f"#define {var_name} (*({ret_type}(*){array_def}){variable.offset_str})"
|
||||
elif value_def:
|
||||
return f"#define {var_name} (*({ret_type}*){variable.offset_str}) // = {value_def}"
|
||||
else:
|
||||
return f"#define {var_name} (*({ret_type}*){variable.offset_str})"
|
||||
|
||||
print("warn: unrecognized signature", variable.signature)
|
||||
return ""
|
||||
|
||||
|
||||
def make_funcs_h(functions: list[Symbol]) -> None:
|
||||
header = [
|
||||
*COMMON_HEADER,
|
||||
'#include "global/types.h"',
|
||||
"",
|
||||
"// clang-format off",
|
||||
]
|
||||
footer = ["// clang-format on"]
|
||||
|
||||
defines = []
|
||||
for function in functions:
|
||||
if not function.is_decompiled and (
|
||||
define := make_func_pointer_define(function)
|
||||
):
|
||||
defines.append(define)
|
||||
|
||||
update_file(FUNCS_H_FILE, "\n".join([*header, *defines, *footer]) + "\n")
|
||||
|
||||
|
||||
def make_vars_h(variables: list[Symbol]) -> None:
|
||||
header = [
|
||||
*COMMON_HEADER,
|
||||
'#include "global/types.h"',
|
||||
'#include "inject_util.h"',
|
||||
"",
|
||||
"// clang-format off",
|
||||
]
|
||||
footer = [
|
||||
"",
|
||||
"// clang-format on",
|
||||
]
|
||||
|
||||
defines = []
|
||||
for variable in sorted(variables, key=lambda symbol: symbol.offset):
|
||||
if not variable.is_decompiled and (
|
||||
define := make_var_pointer_define(variable)
|
||||
):
|
||||
defines.append(define)
|
||||
|
||||
update_file(VARS_H_FILE, "\n".join([*header, *defines, *footer]) + "\n")
|
||||
|
||||
|
||||
def make_types_h(types: list[str]) -> None:
|
||||
header = [
|
||||
*COMMON_HEADER,
|
||||
'#include "const.h"',
|
||||
"",
|
||||
"#include <libtrx/game/items.h>",
|
||||
"#include <libtrx/game/math.h>",
|
||||
"#include <libtrx/game/rooms/types.h>",
|
||||
"#include <libtrx/game/text.h>",
|
||||
"",
|
||||
"#include <stdbool.h>",
|
||||
"#include <stdint.h>",
|
||||
"",
|
||||
"#pragma pack(push, 1)",
|
||||
"",
|
||||
"// clang-format off",
|
||||
]
|
||||
footer = [
|
||||
"",
|
||||
"// clang-format on",
|
||||
"",
|
||||
"#pragma pack(pop)",
|
||||
]
|
||||
|
||||
update_file(
|
||||
TYPES_H_FILE,
|
||||
"\n".join(
|
||||
[
|
||||
*header,
|
||||
"\n\n".join(
|
||||
[
|
||||
definition.strip()
|
||||
for definition in types
|
||||
if "// decompiled" not in definition.strip()
|
||||
]
|
||||
),
|
||||
*footer,
|
||||
]
|
||||
)
|
||||
+ "\n",
|
||||
)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
progress_file = parse_progress_file(TR2Paths.progress_file)
|
||||
|
||||
make_funcs_h(progress_file.functions)
|
||||
make_vars_h(progress_file.variables)
|
||||
make_types_h(progress_file.types)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue