A work-in-progress matching decompilation of Shin Megami Tensei: Persona 4
for the PlayStation 2 (USA v1.00, SLUS_217.82). The goal is readable C that
compiles to the original machine code. Unfinished functions still use retail
assembly so the build can reproduce the executable while recovery continues.
This is not a PC port. You need your own disc image and compiler toolchain; the repository does not include the game executable or disc assets.
Requirements:
- Python 3.10+, Git and Make.
- GNU MIPS binutils with R5900 support:
mipsel-linux-gnu-as,mipsel-linux-gnu-ldandmipsel-linux-gnu-objcopy. The decompals build supports the target. - MWCCPS2 3.0.1 build 210 for game code and build 119 for RenderWare. On Linux, run the Windows compilers through wibo.
- ee-gcc 2.96 for the configured GCC units.
- A Persona 4 USA disc image matching the Redump record.
git clone https://github.com/Raikaru/Persona4-Decompilation.git
cd Persona4-Decompilation
python -m pip install -r requirements-python.txtSet the compiler paths in tools/verify_config.local.json and
tools/build_config.local.json, or use the P4_* environment variables.
Getting Started gives the configuration and Docker
instructions. These local files are ignored by Git; do not change the shared
configuration to suit your machine.
make setup ISO="/path/to/Shin Megami Tensei - Persona 4 (USA).iso"
make split
make regenerate-asm
makemake split extracts the bulk assembly and data. make regenerate-asm
recreates the per-function fallbacks; a fresh checkout needs both. make
then builds the image, checks both retail hashes and verifies the C functions.
| Output | Expected SHA-1 |
|---|---|
Retail ELF (SLUS_217.82) |
4eeec0360cf2715535d9f7e52eb69d786fb0158c |
| Loadable image | 3d1d3d2b9d6ccb60836db239ab49674223025a78 |
The retail executable contains code from several toolchains:
| Code | Compiler and flags |
|---|---|
| Most Atlus game and engine units | MWCCPS2 3.0.1 build 210, -O2 |
| Remaining RenderWare holding units | build 210, -O2 or per-unit -O2,p |
| Recovered RenderWare Graphics 3.7 source | MWCCPS2 3.0.1 build 119, -O4,p -inline auto |
| Configured CRI and other GCC units | ee-gcc 2.96, -O2 -G0 |
tools/verify.py compiles whole source files and compares each marked
function with retail. It masks relocation fields for the byte comparison and
checks their targets separately. tools/build.py decides which objects can
replace retail code, links them at their original addresses, and checks the
image and ELF hashes. GNU ld is the default linker; the optional MWLD backend
requires MWLDPS2. See The Retail Build and the
linker reference.
A byte match does not mean the source is finished. Names, types and data
layouts are still being recovered. Likewise, an object containing
INCLUDE_ASM can be linked without being fully decompiled. Progress separates
Atlus code, proven Sony SDK code, and other middleware; retail assembly does
not count as recovered C.
decomp.dev publishes the
CI results. Its headline figures are first-party (Atlus game and engine) code;
the whole program, including Sony SDK and middleware, is the whole category.
The table below is the last committed report, not a fresh measurement of your
working tree. Run make verify for that.
Detailed progress
| Item | Verified value |
|---|---|
| Retail executable | SLUS_217.82; SHA-1 4eeec0360cf2715535d9f7e52eb69d786fb0158c |
| Loadable image | 0x838a00 bytes at 0x00100000; SHA-1 3d1d3d2b9d6ccb60836db239ab49674223025a78 |
| Canonical function windows | 13,102; all mapped to C or owned retail assembly |
| Byte-identical functions | 9,593 (73.218% of windows) |
Under test (a // FUN_ marker scores them) |
13,102 (100.0% of windows) |
| Not yet under test, supplied as retail bytes | 0 (0.0% of windows) |
| Fully linked ASM-free C files | 4,574 (34.911% of windows) |
| Assembly fallbacks inside other linked objects | 489 |
| Atlus game/engine | 6,861 functions; 6,773 C-matched (98.717%); 6,860 physically linked, including retail ASM (99.985%) |
| Proven Sony PS2 SDK | 491 functions; 152 C-matched (30.957%); 491 physically linked, including retail ASM (100.0%) |
| Other third-party/vendor | 5,750 functions; 2,668 C-matched (46.4%); 1,235 physically linked, including retail ASM (21.478%) |
| Unattributed | 0 functions; 0 C-matched (0.0%); 0 physically linked, including retail ASM (0.0%) |
Byte-identical is not recovered: a matching function can still have an address for a name and raw field offsets. Fully linked counts only files whose every function is matching C and linked from that same source file; physical linkage also includes retail assembly and SDK black boxes. make recovery ranks the game files needing work.
To publish new measurements, run make build-progress followed by
make progress. The first supplies the verified link report; the second
updates the endpoints and this table.
Start with CONTRIBUTING.md, then pick an INCLUDE_ASM
function or improve the names and types of an existing match. For example:
python tools/verify.py src/Battle/btlUnit.c
python tools/fndiff.py src/Battle/btlUnit.c btlUnitGetSphereWorldCenter
python tools/decomp_lint.py src/Battle/btlUnit.cKeep unmatched functions on their assembly fallback. Verify the whole owning file, not an isolated copy of the function, and check that its object remains in the final link. The matching guide covers the working loop; source rules explain what counts as an honest recovery.
src/ recovered C and INCLUDE_ASM fallbacks
src/promoted/ units whose original ownership is partly unresolved
include/ project and middleware headers
config/ addresses, names, compiler choices and assembly manifest
tools/ extraction, build, verification and analysis
tests/ tooling regression tests
wiki/ setup and contributor guides
docs/ compiler findings and technical references
docs/probe_archive/ saved C attempts and measurements
progress/ committed progress reports
orig/ asm/ assets/ local retail inputs and generated data, with tracked ASM exceptions
build/ local build output (ignored)
The documentation index points to the detailed guides. The architecture overview explains how the game's systems fit together. Probe records stay tracked: the retail executable can reproduce disassembly, not the source hypotheses and measurements used to recover it.
- Persona 3 FES
shares engine code.
make shared-p3 P3_ROOT=/path/to/Persona3-FES-Decompilationcompares the trees without copying source. - Digital Devil Saga 1 & 2 reconstructs earlier games in the same engine family.