pokestadium/tools/rust
cristian 91cd790c86 Add Rust matching tools (ps-status, ps-firstdiff, ps-fdiff)
Introduce a cargo workspace under tools/rust/ with a shared ps-core
library and three binaries for the byte-for-byte matching effort:

- ps-status: status of functions pending decompilation. Build-free mode
  scans GLOBAL_ASM in src/ (validated: 190 funcs across 68 files, matching
  grep); build-aware mode reports byte progress per folder from the linker
  .map, porting the progress.py metric.
- ps-firstdiff: first difference(s) between built and expected ROM, with
  function naming and jal-target resolution (like tools/first_diff.py).
- ps-fdiff: non-interactive per-function asm diff of built ROM vs baserom
  (like ./diff.py -mwo <func>).

ps-core provides parsers for GLOBAL_ASM, symbol_addrs, and GNU ld .map
files (with vram/vrom lookups), a .z64 reader with md5 verification, and a
rabbitizer wrapper for disassembly. All parsers are unit-tested.

Wired into tools/Makefile (cargo build, skipped with a warning if cargo is
absent), target/ gitignored, and documented in README.md and
tools/rust/README.md.

The Python scripts (progress.py, tools/first_diff.py, diff.py) are kept in
place: only the build-free ps-status path can be validated without a ROM
and toolchain. Parity of the build-dependent tools must be confirmed in a
full build environment before removing the Python equivalents.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 23:52:13 -04:00
..
crates Add Rust matching tools (ps-status, ps-firstdiff, ps-fdiff) 2026-07-01 23:52:13 -04:00
Cargo.lock Add Rust matching tools (ps-status, ps-firstdiff, ps-fdiff) 2026-07-01 23:52:13 -04:00
Cargo.toml Add Rust matching tools (ps-status, ps-firstdiff, ps-fdiff) 2026-07-01 23:52:13 -04:00
README.md Add Rust matching tools (ps-status, ps-firstdiff, ps-fdiff) 2026-07-01 23:52:13 -04:00

Pokémon Stadium matching tools (Rust)

A cargo workspace with the tooling for the byte-for-byte matching effort. It has no Python dependencies; MIPS disassembly uses the rabbitizer crate — the same disassembler the Python scripts use — for output parity.

Crates

Crate Binary Replaces (eventually)
ps-core (library) shared parsers / models
ps-status ps-status progress.py
ps-firstdiff ps-firstdiff tools/first_diff.py
ps-fdiff ps-fdiff ./diff.py -mwo <func>

ps-core contains the reusable pieces:

  • globalasm — scan src/**/*.c for #pragma GLOBAL_ASM(...) (build-free list of pending functions).
  • symbols — parse linker_scripts/<v>/symbol_addrs*.txt.
  • mapfile — minimal GNU ld .map parser: .text symbols with sizes, plus vram/vrom lookups (vrom derived from each section's load address).
  • rom — big-endian .z64 reader + md5 verification.
  • disasmrabbitizer wrapper; resolves jal targets to symbol names.

Build & test

cargo build --release      # binaries in target/release/
cargo test                 # unit tests
cargo clippy --all-targets

Modes that need build artifacts

ps-status (default), works with only the committed repo. Everything else needs artifacts produced by make:

  • ps-status --build-aware needs build/pokestadium-<v>.map.
  • ps-firstdiff needs build/…z64 + .map and expected/build/… (make diff-init).
  • ps-fdiff needs build/…z64 + .map and baseroms/<v>/baserom.z64.

Parity-validation status

The Python scripts are kept in place. Only the parts validatable without a ROM/toolchain have been checked so far:

  • ps-status build-free — validated: total (190) and per-file counts match grep -rho 'GLOBAL_ASM("[^"]*")' src/ | wc -l and grep -rln GLOBAL_ASM src/.

The build-dependent tools (ps-status --build-aware, ps-firstdiff, ps-fdiff) are covered by unit tests on synthetic fixtures but have not yet been compared against the Python tools on real build output. Before removing progress.py, tools/first_diff.py or diff.py, confirm parity in a full build environment:

# build-aware vs progress.py (compare bytes / percentages)
make && make diff-init
python3 progress.py
./tools/rust/target/release/ps-status --build-aware

# first-diff vs first_diff.py (introduce a deliberate regression first)
python3 tools/first_diff.py
./tools/rust/target/release/ps-firstdiff

# per-function diff vs diff.py
./diff.py -mwo <func>
./tools/rust/target/release/ps-fdiff <func>

Note: ps-fdiff v1 is non-interactive (word-by-word alignment); diff.py's interactive TUI, scoring and insert/delete alignment are not reimplemented.