mirror of
https://github.com/LostArtefacts/TR2X.git
synced 2025-02-17 04:27:52 +00:00
166 lines
4.9 KiB
Python
Executable File
166 lines
4.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
import re
|
|
|
|
from tr2x.ida_progress import FUNC_PTR_RE, VAR_RE, Symbol, parse_progress_file
|
|
from tr2x.paths import TR2X_PROGRESS_FILE, TR2X_SRC_DIR
|
|
|
|
FUNCS_H_FILE = TR2X_SRC_DIR / "global/funcs.h"
|
|
VARS_H_FILE = TR2X_SRC_DIR / "global/vars_decomp.h"
|
|
TYPES_H_FILE = TR2X_SRC_DIR / "global/types.h"
|
|
|
|
|
|
COMMON_HEADER = [
|
|
"// This file is autogenerated. To update it, run tools/generate_funcs.",
|
|
"",
|
|
"#pragma once",
|
|
"",
|
|
]
|
|
|
|
|
|
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 in function.flags 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 in variable.flags 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/collision.h>",
|
|
"#include <libtrx/game/effects.h>",
|
|
"#include <libtrx/game/gameflow/types.h>",
|
|
"#include <libtrx/game/items.h>",
|
|
"#include <libtrx/game/lara/types.h>",
|
|
"#include <libtrx/game/lot.h>",
|
|
"#include <libtrx/game/math.h>",
|
|
"#include <libtrx/game/objects/common.h>",
|
|
"#include <libtrx/game/rooms/types.h>",
|
|
"",
|
|
"#include <ddraw.h>",
|
|
"#include <ddrawi.h>",
|
|
"#include <d3dhal.h>",
|
|
"#include <dsound.h>",
|
|
"#include <stdbool.h>",
|
|
"#include <stdint.h>",
|
|
"#include <windows.h>",
|
|
"",
|
|
"#pragma pack(push, 1)",
|
|
"",
|
|
"// clang-format off",
|
|
]
|
|
footer = [
|
|
"",
|
|
"// clang-format on",
|
|
]
|
|
|
|
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(TR2X_PROGRESS_FILE)
|
|
|
|
make_funcs_h(progress_file.functions)
|
|
make_vars_h(progress_file.variables)
|
|
make_types_h(progress_file.types)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|