Files
Yanis 90203403dd Decompile overlay 24 (Part 1) (#65)
* GameModeAdventure_001 OK

* GameModeAdventure_024 17%

* GameModeAdventure_024 73%

* GameModeAdventure_024 99%

* jp region differences

* rename GameModeAdventure_024 and GameModeAdventure + UnkStruct_ov000_020d8660_024 OK

* UnkActorSystem1OK

* UnkActorSystem2 OK

* delink more of ov024 & UnkStruct_027e0998_024 OK

* improve instance stuff & UnkStruct_027e0cf8_024 OK

* AdventureModeManager_160_024 OK & GameModeStartUp OK

* fix regressions

* fix regressions 2

* AdventureModeManager_170 OK

* AdventureModeManager_174_Base OK

* AdventureModeManager_174 OK

* mark GameModeAdventure_024 as complete

* AdventureModeManager_178 OK

* AdventureModeManager_180 OK

* AdventureModeManager_184_024 OK

* AdventureModeManager_18C_024 OK & AdventureModeManager_190_024 OK

* AdventureModeManager_15C_20_00 61%

* AdventureModeManager_15C_20_00 OK

* jp version differences

* delink what's left in the overlay

* fix regressions

* AdventureModeManager_1B8_Base_024 98%

* AdventureModeManager_1B8 48% and link AdventureModeManager_024

* AdventureModeManager_1B8_Base and AdventureModeManager_1B8 OK

* oops

* mark statics as local
2026-05-18 21:14:27 +02:00

95 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python
import sys
import pyperclip
import subprocess
import os
from pathlib import Path
import argparse
import re
import tempfile
parser = argparse.ArgumentParser(description="Generates a context for decomp.me")
parser.add_argument('file', help="Input file to preprocess")
parser.add_argument('-f', type=str, dest='out_file', required=False, help='Output context file')
parser.add_argument('-c', action=argparse.BooleanOptionalAction, dest='clipboard', required=False, help='Copy output to clipboard')
parser.add_argument('-e', type=str, dest='encoding', required=False, default="utf-8", help='Input file encoding')
parser.add_argument('-v', action=argparse.BooleanOptionalAction, dest='verbose', required=False, help='Verbose error output')
parser.add_argument('-g', dest="version", required=False, default="EUR")
args = parser.parse_args()
CXX_FLAGS = [
'-nostdinc',
'-Iinclude',
'-Ilibs/c/include',
'-Ilibs/cpp/include',
'-Ilibs/runtime/include',
'-Ilibs/nitro/include',
'-Ilibs/nns/include',
'-Ilibs/dsprotect/include',
f'-DVERSION={args.version}',
'-D__MWERKS__',
]
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
root_dir = script_dir / ".."
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
# Finds all lines starting with #include followed by <...> or "..."
INCLUDE_REGEX = r'^\s*#\s*include\s*([<"][\S ]+[>"])\s*$'
# Finds all line comments and multiline comments
COMMENT_REGEX = r'\/\/.*$|\/\*(?:.|\r|\n)+?\*\/'
with open(args.file, 'r') as f:
contents = f.read()
contents = re.sub(COMMENT_REGEX, '', contents, 0, re.MULTILINE)
includes = re.findall(INCLUDE_REGEX, contents, re.MULTILINE)
_, suffix = os.path.splitext(args.file)
with tempfile.NamedTemporaryFile(delete=True, suffix=suffix) as tmp_file:
# Write includes
for include in includes:
tmp_file.write(f'#include {include}\n'.encode())
tmp_file.flush()
# Run preprocessor
try:
ctx: str = subprocess.check_output([
'gcc',
'-E', '-P', '-fworking-directory', '-undef', '-dD',
*CXX_FLAGS,
tmp_file.name
], cwd=root_dir, encoding=args.encoding)
except subprocess.CalledProcessError as e:
eprint(f"Failed to preprocess '{args.file}'")
if args.verbose: eprint(e)
else: eprint("Use -v for more verbose error output")
exit(1)
lines = ctx.splitlines(True)
for i in reversed(range(len(lines))):
if lines[i].startswith('#define __cplusplus'): lines.pop(i)
elif lines[i].startswith('#define __STDC_HOSTED__'): lines.pop(i)
elif lines[i].startswith('#define __STDC__'): lines.pop(i)
elif lines[i].startswith('#define __STDC_VERSION__'): lines.pop(i)
ctx = ''.join(lines)
if args.out_file:
try:
with open(args.out_file, "w") as file:
file.write(ctx)
except OSError as e:
eprint(f"Failed to write file '{args.out_file}'")
if args.verbose: eprint(e)
else: eprint("Use -v for more verbose error output")
exit(1)
if args.clipboard:
pyperclip.copy(ctx)
eprint("Copied context to clipboard")
if args.out_file is None and not args.clipboard:
print(ctx)