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> |
||
|---|---|---|
| .. | ||
| crates | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
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— scansrc/**/*.cfor#pragma GLOBAL_ASM(...)(build-free list of pending functions).symbols— parselinker_scripts/<v>/symbol_addrs*.txt.mapfile— minimal GNUld.mapparser:.textsymbols with sizes, plus vram/vrom lookups (vrom derived from each section'sload address).rom— big-endian.z64reader + md5 verification.disasm—rabbitizerwrapper; resolvesjaltargets 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-awareneedsbuild/pokestadium-<v>.map.ps-firstdiffneedsbuild/…z64+.mapandexpected/build/…(make diff-init).ps-fdiffneedsbuild/…z64+.mapandbaseroms/<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-statusbuild-free — validated: total (190) and per-file counts matchgrep -rho 'GLOBAL_ASM("[^"]*")' src/ | wc -landgrep -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.