From 27df9d7eef78469bf19f0834846c7d259a4e8e05 Mon Sep 17 00:00:00 2001 From: Claudio Baecchi Date: Sat, 4 Jul 2026 17:27:42 +0200 Subject: [PATCH] Work on Yaml. Working on binutils --- Makefile | 39 ++++++++++++++++++++++++++++++++++++++- README.md | 37 ++++++++++++++++++++++++++++++++++++- config/kuon.yaml | 3 +++ configure.py | 20 ++++++++++---------- 4 files changed, 87 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 2d5fcd0..bef588d 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,42 @@ MAKEFLAGS += --no-print-directory NUMPROC ?= $(shell nproc) +CHECK_ENV_CMDS := \ + python3 \ + ninja \ + stat \ + iconv \ + mips-ps2-decompals-as \ + mips-ps2-decompals-strip \ + mips-ps2-decompals-ld \ + mips-ps2-decompals-objcopy + +GREEN := \033[32m +RED := \033[31m +YELLOW := \033[33m +RESET := \033[0m + +.check-env: + @missing=0; \ + output=""; \ + for cmd in $(CHECK_ENV_CMDS); do \ + if command -v $$cmd >/dev/null 2>&1; then \ + output="$$output ${GREEN}[OK]${RESET} $$cmd\n"; \ + else \ + output="$$output ${RED}[MISSING]${RESET} $$cmd\n"; \ + missing=1; \ + fi; \ + done; \ + if [ $$missing -eq 1 ]; then \ + printf "%-11s %s\n" "STATUS" "COMMAND"; \ + printf "%-11s %s\n" "------" "-------"; \ + printf "$$output"; \ + printf "\n${RED}Environment check failed${RESET}\n\n"; \ + exit 1; \ + fi + +WITH_ENV := .check-env + .PHONY: help \ .build-only .check-files-on-error configure build extract-data make-asm map-mismatch report clean \ @@ -50,8 +86,9 @@ endef export PY_HELP_SCRIPT PYHELP := python3 -c "$$PY_HELP_SCRIPT" -help: ## Show this help +help: $(WITH_ENV) ## Show this help @$(PYHELP) $(MAKEFILE_LIST) + ## ## Commands: configure: ## Configure project (needs SLUS_210.07) diff --git a/README.md b/README.md index 7b53386..55838db 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,39 @@ sudo apt install libc6:i386 libstdc++6:i386 ### Install dependencies ```bash -sudo apt install make binutils-mips-linux-gnu gcc-mips-linux-gnu python3-venv +sudo apt install make python3-venv ``` +### Install decompals binutils + +This project requires a custom PS2-specific version of binutils to assemble the extracted MIPS assembly. The system-provided `binutils-mips-linux-gnu` package may not work correctly with PS2 assembly, so manual installation is required. + +Download the [binutils-mips-ps2-decompals-linux-x86-64.tar.gz (v0.10)](https://github.com/decompals/binutils-mips-ps2-decompals/releases/download/v0.10/binutils-mips-ps2-decompals-linux-x86-64.tar.gz) package. + +Extract the archive to a location of your choice, for example: + +```bash +sudo mkdir -p /opt/binutils-mips-ps2-decompals +sudo tar -xzf binutils-mips-ps2-decompals-linux-x86-64.tar.gz -C /opt/binutils-mips-ps2-decompals +``` + +Then add the bin directory to your `PATH` environment variable: + +```bash +export PATH="/opt/binutils-mips-ps2-decompals/:$PATH" +``` + +To make this change persistent, add the line above to your shell configuration file (for example `~/.bashrc`, `~/.zshrc`, or equivalent), then restart your terminal or reload your shell. + +Verify the installation by running: + +```bash +mips-ps2-decompals-as --version +``` + +If the installation was successful, the command should print the assembler version information. + + ### Setup a Virtual Environment for Python Python's virtual environments are the preferred way to use this software, as you may not be allowed to install packages globally. ```bash @@ -37,6 +67,11 @@ python3 -m pip install -r requirements.txt ### Copy assets from game DVD/ISO The main executable is needed in order to perform the decompilation. +#### JP +```bash +make jp-clean +``` + ### Command Help To have a list all available commands, run `make` without targets: ```bash diff --git a/config/kuon.yaml b/config/kuon.yaml index f208efc..56619ba 100644 --- a/config/kuon.yaml +++ b/config/kuon.yaml @@ -455,4 +455,7 @@ segments: # vutext - [0x11C700, textbin, vutext] + #- { start: 0x157880, type: bss, vram: 0x257880, name: "bss_asm" } + + - [0x157900] diff --git a/configure.py b/configure.py index 96d6773..52aab06 100755 --- a/configure.py +++ b/configure.py @@ -48,6 +48,8 @@ def suppress_stdout_stderr(): ROOT = Path(__file__).parent.resolve() TOOLS_DIR = ROOT / "tools" +CROSS = "mips-ps2-decompals-" + COMPILER = "ee-gcc2.9-991111-01" COMPILER_FLAGS = "-DMATCHING_DECOMP -O2 -g2 -gstabs" # -malign-functions=3 @@ -151,7 +153,7 @@ def write_permuter_settings(config_dir: Path, src_path: Path, language: str): with open(config_dir / "permuter_settings.toml", "w") as f: f.write( f"""compiler_command = "{game_compile_cmd} -D__GNUC__" -assembler_command = "mips-linux-gnu-as -march=r5900 -mabi=eabi -Iinclude" +assembler_command = "{CROSS}as -march=r5900 -mabi=eabi -Iinclude" compiler_type = "gcc" [preserve_macros] @@ -211,8 +213,6 @@ def build_stuff( ninja = ninja_syntax.Writer(open(str(ROOT / config_dir / "build.ninja"), "w"), width=9999) # Rules - cross = "mips-linux-gnu-" - ld_args = "--no-warn-rwx-segments -EL -T undefined_syms.txt -T undefined_syms_auto.txt -T undefined_funcs_auto.txt -Map $mapfile -T $in -o $out" cpp = Path("..", "..", get_compiler_command("cpp")) @@ -223,7 +223,7 @@ def build_stuff( # NOTE: Japanese strings are EUC-JP encoded!! # We need to convert them from (-f) UTF-8 to (-t) EUC-JP while compiling, # otherwise Japanese strings will be compiled wrong! - command=f"{cpp} {common_includes} $in -o - | iconv -f=UTF-8 -t=EUC-JP $in | {cross}as -no-pad-sections -EL -march=5900 -mabi=eabi -I{src_path.parent / 'include'} -o $out", + command=f"{cpp} {common_includes} $in -o - | iconv -f=UTF-8 -t=EUC-JP | {CROSS}as -no-pad-sections -EL -march=5900 -mabi=eabi -I{src_path.parent / 'include'} -o $out", ) ninja.rule( @@ -235,14 +235,14 @@ def build_stuff( f"{game_compile_cmd.replace(' -c ', ' -S ')} $in -o $$s_in && " # .......... 3) replace -c with -S in gcc command to generate intermediate assembly file instead of object f"python3 {ROOT}/tools/python/fix_asm_matching.py {language} $$s_in && " # . 4) fix assembly file using known patterns with tools/python/fix_asm_matching.py f"{game_compile_cmd} $$s_in -o $out && " # ................................. 5) compile assembly file into object - f"{cross}strip $out -N dummy-symbol-name" # ................................ 6) strip 'dummy-symbol-name' from object + f"{CROSS}strip $out -N dummy-symbol-name" # ................................ 6) strip 'dummy-symbol-name' from object ), ) ninja.rule( "cc", description="cc $in", - command=f"{game_compile_cmd} $in -o $out && {cross}strip $out -N dummy-symbol-name", + command=f"{game_compile_cmd} $in -o $out && {CROSS}strip $out -N dummy-symbol-name", ) ninja.rule( @@ -253,20 +253,20 @@ def build_stuff( f'mkdir -p $$(dirname "$$eucjp_in") && ' # .............................. 2) create directory from eucjp_in var: s_in=cc-src/src/path/to/file.c.eucjp.c -> mkdir -p cc-src/src/path/to/ f"iconv -o $$eucjp_in -f=UTF-8 -t=EUC-JP $in && " # ..................... 3) convert source file to EUC-JP (save converted source to cc-src/src/file.c.eucjp.c) f'{game_compile_cmd} -I$$(dirname "$in") $$eucjp_in -o $out && ' # ...... 4) compile converted source file into object (also add original source directory as include path to allow relative imports) - f"{cross}strip $out -N dummy-symbol-name" # ............................. 5) strip 'dummy-symbol-name' from object + f"{CROSS}strip $out -N dummy-symbol-name" # ............................. 5) strip 'dummy-symbol-name' from object ), ) ninja.rule( "libcc", description="cc $in", - command=f"{lib_compile_cmd} $in -o $out && {cross}strip $out -N dummy-symbol-name", + command=f"{lib_compile_cmd} $in -o $out && {CROSS}strip $out -N dummy-symbol-name", ) ninja.rule( "ld", description="link $out", - command=f"{cross}ld {ld_args}", + command=f"{CROSS}ld {ld_args}", ) ninja.rule( @@ -278,7 +278,7 @@ def build_stuff( ninja.rule( "elf", description="elf $out", - command=f"{cross}objcopy $in $out -O binary && python3 {ROOT}/tools/python/fix_bin_matching.py {language} $out", + command=f"{CROSS}objcopy $in $out -O binary && python3 {ROOT}/tools/python/fix_bin_matching.py {language} $out", ) for entry in linker_entries: