mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 05:56:00 -04:00
145 lines
11 KiB
Markdown
145 lines
11 KiB
Markdown
# BFM-decomp — Brave Fencer Musashi, decompiled
|
|
|
|

|
|

|
|

|
|
|
|
A **matching decompilation** of *Brave Fencer Musashi* (PlayStation, Square, 1998 — the USA release, SLUS-00726): C source
|
|
that, compiled with the game's own 1990s toolchain, rebuilds every shipped code binary **byte for byte**. It is the first
|
|
public decompilation of this game, and the whole of its game code is matched: the main executable, the always-resident
|
|
engine, every location overlay and every code module streamed from the disc — **218 binaries**, verified against a redump
|
|
image of the original disc on every build.
|
|
|
|
The contract is narrow and machine-checkable. "Matching" means byte-identical output, checked by SHA1 against the
|
|
originals; nothing "functionally equivalent" counts. What the repository claims is exactly what `make check-all` proves.
|
|
|
|
## Where it stands
|
|
|
|
<!-- progress:begin -->
|
|
| Metric | Matched | Of | % |
|
|
|---|---:|---:|---:|
|
|
| Functions byte-identical (all binaries) | 363,214 | 363,214 | 100.00% |
|
|
| Instructions byte-identical (instruction-weighted) | 13,492,113 | 13,492,113 | 100.0% |
|
|
| Distinct code byte-identical (each body once) | 5,820,205 | 5,820,205 | 100.0% |
|
|
| Main executable game code (excl. Sony objects) | 45,150 | 45,150 | 100.0% |
|
|
|
|
218 binaries rebuild byte-identical from source · 360,737 functions in C (255,632 of them shared bodies via 2,220 dedup groups) · 1,256 Sony PsyQ library functions linked from the SDK objects, not our C · 5 hand-written-assembly bodies kept verbatim · 0 assembly stubs left · 0 non-matching functions.
|
|
|
|
_Generated by `tools/progress.py --readme` from `docs/progress.json` — numbers are never typed by hand._
|
|
<!-- progress:end -->
|
|
|
|
Two things in those binaries are deliberately **not** our C, and are stated as such:
|
|
|
|
- **1,256 functions of the main executable are Sony's PsyQ library code** (libcd, libgs, libgte, libgpu, libspu/libsnd,
|
|
libetc, libapi, libcard…). They link byte-identical from the SDK's own objects when you have the SDK, and are carried as
|
|
assembly tiles taken from the disc when you do not — either way the executable is byte-identical. Reimplementing Sony's
|
|
libraries is out of scope.
|
|
- **Five functions across the fleet are hand-written assembly in the original** and are kept as verbatim `__asm__`
|
|
bodies (`config/verbatim_manifest.json`, audited by `tools/verbatim_check.py --strict`).
|
|
|
|
Everything else — every game-code function in all 218 binaries — is C that the pinned compiler turns into the original
|
|
bytes. Progress numbers are generated from the sources (`tools/progress.py`), never typed by hand; the full recipe to
|
|
reproduce them is in [`docs/verification.md`](docs/verification.md).
|
|
|
|
## Build it from your own disc
|
|
|
|
The repository contains **no game data**: no executable, no disassembly, no assets, no memory dumps — only source, build
|
|
configuration, symbol names and hashes. You need your own redump-layout dump of the USA disc (Track 1 SHA1
|
|
`b44f0f0a19936f23b26188b658e13201a6a9c211`, CRC32 `c238191b`; the four-track BIN/CUE is ideal, Track 1 alone works).
|
|
|
|
```bash
|
|
git clone --recurse-submodules https://github.com/Druthulu/BFM-decomp.git && cd BFM-decomp
|
|
make bootstrap # toolchain preflight: venv, submodules, the pinned gcc-2.7.2 cc1 (sha256-checked)
|
|
mkdir -p disks && cp '/path/to/Brave Fencer Musashi (USA)'*.{bin,cue} disks/
|
|
make disc-extract # extracts the disc and checks all 1,801 files against the committed manifest
|
|
make clean && make -j"$(nproc)" extract-all && make -j"$(nproc)" check-all
|
|
# -> "check-all: 218 passed, 0 failed of 218"
|
|
```
|
|
|
|
Linux (WSL2 Ubuntu 24.04 is what the project uses); `binutils-mipsel-linux-gnu`, `cpp-mipsel-linux-gnu`, Python 3.12.
|
|
The main executable's SHA1 is `143dbb89f34491258bbc27810d0a12ec8b43a8dd`. `make help` lists every target;
|
|
[`docs/verification.md`](docs/verification.md) gives each step's expected last line and the record of the last full run.
|
|
|
|
**Toolchain (pinned by fingerprint evidence):** `gcc-2.7.2-psx cc1 -O2 -G0 -mips1 -mcpu=3000 -mgas -msoft-float -fgnu-linker`
|
|
→ `maspsx --aspsx-version=2.56 --expand-div` → `mipsel-linux-gnu-as -march=r3000 -mtune=r3000 -no-pad-sections -O1 -G0`,
|
|
with per-file `-O0` modules where the bytes demand it. The Sony PsyQ SDK objects are **optional** and user-supplied
|
|
(`tools/fetch_psyq.sh`); they are never redistributed.
|
|
|
|
## What is in the repository
|
|
|
|
| Path | What |
|
|
|---|---|
|
|
| `src/` | The C — one directory per binary (`src/` itself is the main executable, `src/resident/`, `src/ov_*/`, `src/md_*/`), `src/shared/` for the code shared across binaries via the dedup registry |
|
|
| `config/` | splat configs, symbol files, per-binary SHA1 contracts (`check.*.sha`), the dedup registry, the Ghidra annotations as text (`config/ghidra/`) |
|
|
| `tools/` | Everything the project built to do this: the byte gate, the extractor, the matching harness, the campaign machinery, the CI audits, the public-flip rewrite tooling; pinned submodules (maspsx, asm-differ, decomp-permuter, m2c) |
|
|
| `docs/` | The matching cookbook (500+ compiler idioms), the gcc-2.7.2 codegen map, the memory map, the decision log, the accelerators, the runbooks, the story and the retrospective |
|
|
| `phase-ends/` | The project's own governance record: one PhaseEnd per phase, the digest, the per-phase logs |
|
|
| `include/`, `extracted/retail/manifest.*` | Headers; the sha1 manifest your disc extraction is checked against |
|
|
|
|
## How it was made
|
|
|
|
This project was carried out end to end by an AI coding agent — Claude Code — working inside a governance framework:
|
|
a static constitution ([`PROJECT_CONTEXT.md`](PROJECT_CONTEXT.md)), a session protocol ([`CLAUDE.md`](CLAUDE.md)),
|
|
two human gates per phase, an append-only record of every phase ([`phase-ends/`](phase-ends/)), and a growing rule set
|
|
distilled from what went wrong. The framework is published separately as
|
|
[**ProjectArchitect**](https://github.com/Druthulu/ProjectArchitect); this repository is its largest worked example.
|
|
|
|
The reverse-engineering side ran on Ghidra driven over MCP, with a PCSX-Redux runtime oracle; the matching side is a
|
|
byte gate over the whole binary, a permuter, a compiler-idiom cookbook, and — decisively — reading the gcc 2.7.2 source
|
|
to explain the bytes the compiler emits. Everything that was learned is written down where it can be reused:
|
|
|
|
- [`docs/matching-cookbook.md`](docs/matching-cookbook.md) — the idioms, each byte-proven, and the compiler-internals laws
|
|
- [`docs/gcc-2.7.2-map/`](docs/gcc-2.7.2-map/) — the codegen map of the pinned compiler, by pass
|
|
- [`docs/decision-log.md`](docs/decision-log.md) — every strategic pivot with its measurement and its hindsight
|
|
- [`docs/accelerators.md`](docs/accelerators.md) — what would have made earlier phases faster
|
|
- [`docs/story.md`](docs/story.md) and [`docs/retrospective.md`](docs/retrospective.md) — the timeline and the retrospective
|
|
- [`docs/public-flip-runbook.md`](docs/public-flip-runbook.md) — how a private repository with game bytes in its history
|
|
became this public one
|
|
|
|
**About the history.** The full development history is here — every commit, date and message — but it was rewritten
|
|
before publication to remove game-derived files from every revision. Old commit hashes cited inside historical documents
|
|
were replaced by inert tokens (`commit:NNNN`, the commit's ordinal); [`docs/commit-map.tsv`](docs/commit-map.tsv) maps
|
|
them to the commits you see, and documents at the tip cite the current hashes directly.
|
|
|
|
## License
|
|
|
|
- `tools/` and `docs/` (the project's own work): **AGPL-3.0** — see [`LICENSE`](LICENSE).
|
|
- `src/`: a reimplementation of copyrighted game code, provided for study and preservation; **no license is asserted** —
|
|
see [`src/NOTICE.md`](src/NOTICE.md).
|
|
- Third-party components keep their own licenses — see [`THIRD_PARTY.md`](THIRD_PARTY.md). `tools/brave-CUE/` (CUE's
|
|
reference extractor) is GPL-3.0; the Sony PsyQ SDK is never distributed.
|
|
|
|
## Contributing, and the no-ROM policy
|
|
|
|
Nothing derived from the game may enter the repository: no executable, no disassembly, no assets, no memory image,
|
|
no SDK. CI enforces the tracked tree (`tools/audit_public.py`: no ROM-derived content by hash, no purge path, nothing
|
|
over 50 MiB), keeps every source text and portable, and compiles every translation unit with the pinned compiler. Byte
|
|
identity itself is verified locally with the disc, and the record of the last full run is committed.
|
|
|
|
The matching frontier is empty, so contributions that help most are not new matches: readability (structs and names
|
|
in place of raw addresses), shiftability, tooling, and documentation. Open an issue first if you are unsure whether
|
|
something is ROM-derived.
|
|
|
|
## Special thanks
|
|
|
|
In the tradition of [sotn-decomp](https://github.com/Xeeynamo/sotn-decomp), whose method this project followed from
|
|
day one — this work stands on:
|
|
|
|
- [splat](https://github.com/ethteck/splat), [spimdisasm](https://github.com/Decompollaborate/spimdisasm) and
|
|
[rabbitizer](https://github.com/Decompollaborate/rabbitizer) — the split and the disassembly
|
|
- [maspsx](https://github.com/mkst/maspsx) (mkst) — ASPSX's quirks, reproduced
|
|
- [asm-differ](https://github.com/simonlindholm/asm-differ) and [decomp-permuter](https://github.com/simonlindholm/decomp-permuter) (simonlindholm)
|
|
- [m2c](https://github.com/matt-kempster/m2c) (matt-kempster) — the scaffolds
|
|
- [old-gcc](https://github.com/decompals/old-gcc) (decompals) — the compilers, and the gcc 2.7.2 source itself
|
|
- [Ghidra](https://github.com/NationalSecurityAgency/ghidra), [ghidra_psx_ldr](https://github.com/lab313ru/ghidra_psx_ldr) (lab313ru)
|
|
and [GhidrAssistMCP](https://github.com/symgraph/GhidrAssistMCP) — the static oracle and its hands
|
|
- [psyq-obj-parser](https://github.com/decompme/compilers) (decomp.me) — Sony's objects, readable
|
|
- [PCSX-Redux](https://github.com/grumpycoders/pcsx-redux) — the runtime oracle
|
|
- [brave-CUE](tools/brave-CUE/) (CUE) — the reference extractor ours was validated against
|
|
- The Xenogears, Vagrant Story and Tomba! decompilations — sibling PsyQ idioms
|
|
- [redump](http://redump.org/), [TCRF](https://tcrf.net/) and [gamehacking.org](https://gamehacking.org/) — the ground truth on the disc and in memory
|
|
- The [Brave Fencer Musashi Archipelago world](https://github.com/AegeusEvander/Brave-Fencer-Musashi-AP-World) (AegeusEvander) — the living RAM map
|
|
- [ProjectArchitect](https://github.com/Druthulu/ProjectArchitect) and [Claude Code](https://claude.ai/code) — the method and the hands
|
|
|
|
*Brave Fencer Musashi is © 1998 Square. This project is not affiliated with or endorsed by Square Enix.*
|