# Shin Megami Tensei: Persona 4 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. [![first-party functions](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=first-party%20functions&measure=matched_functions&category=main)](https://decomp.dev/Raikaru/Persona4-Decompilation) [![first-party fully C-linked](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=first-party%20fully%20C-linked&measure=complete_code&category=main)](https://decomp.dev/Raikaru/Persona4-Decompilation) ## Quickstart Requirements: - Python 3.10+, Git and Make. - GNU MIPS binutils with R5900 support: `mipsel-linux-gnu-as`, `mipsel-linux-gnu-ld` and `mipsel-linux-gnu-objcopy`. The [decompals build](https://github.com/decompals/binutils-mips-ps2-decompals) 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](https://github.com/decompals/wibo). - ee-gcc 2.96 for the configured GCC units. - A Persona 4 USA disc image matching the [Redump record](http://redump.org/disc/5576/). ```sh git clone https://github.com/Raikaru/Persona4-Decompilation.git cd Persona4-Decompilation python -m pip install -r requirements-python.txt ``` Set the compiler paths in `tools/verify_config.local.json` and `tools/build_config.local.json`, or use the `P4_*` environment variables. [Getting Started](wiki/Getting-Started.md) gives the configuration and Docker instructions. These local files are ignored by Git; do not change the shared configuration to suit your machine. ```sh make setup ISO="/path/to/Shin Megami Tensei - Persona 4 (USA).iso" make split make regenerate-asm make ``` `make 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` | ## How it works 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](wiki/The-Retail-Build.md) and the [linker reference](docs/gnu_linker.md). 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. ## Status [decomp.dev](https://decomp.dev/Raikaru/Persona4-Decompilation) 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 [![perfect match](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=all%20code%20perfect%20match&measure=code&category=whole)](https://decomp.dev/Raikaru/Persona4-Decompilation) [![fuzzy match](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=all%20code%20fuzzy%20match&measure=fuzzy_match_percent&category=whole)](https://decomp.dev/Raikaru/Persona4-Decompilation) [![all functions](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=all%20functions&measure=matched_functions&category=whole)](https://decomp.dev/Raikaru/Persona4-Decompilation) [![ASM-free linked C](https://img.shields.io/endpoint?url=https%3A%2F%2FRaikaru.github.io%2FPersona4-Decompilation%2Fprogress%2Flinked.json)](https://Raikaru.github.io/Persona4-Decompilation/progress/linked.json) [![Sony SDK fully C-linked](https://decomp.dev/Raikaru/Persona4-Decompilation.svg?mode=shield&label=Sony%20SDK%20fully%20C-linked&measure=complete_code&category=sony_sdk)](https://decomp.dev/Raikaru/Persona4-Decompilation) | 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.
## Contributing Start with [CONTRIBUTING.md](CONTRIBUTING.md), then pick an `INCLUDE_ASM` function or improve the names and types of an existing match. For example: ```sh 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.c ``` Keep 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](wiki/Matching-a-Function.md) covers the working loop; [source rules](docs/STYLE.md) explain what counts as an honest recovery. ## Project structure ```text 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](wiki/Home.md) points to the detailed guides. The [architecture overview](docs/architecture.md) 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. ## Related projects - [Persona 3 FES](https://github.com/Raikaru/Persona3-FES-Decompilation) shares engine code. `make shared-p3 P3_ROOT=/path/to/Persona3-FES-Decompilation` compares the trees without copying source. - [Digital Devil Saga 1 & 2](https://github.com/Raikaru/dds-decomp) reconstructs earlier games in the same engine family.