mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-10-03 11:06:40 -04:00
8f747334d6
fix: patching NOP things that code gen already know how to handle feat: added a bug on JAL/J/JAR code gen feat: enhanced tom file fix: fix memory layout for ps2 macros feat: added a lot of not working garbabe to runtime (fix later) feat: some code organization feat: added new tests feat: update readme
134 lines
3.9 KiB
Markdown
134 lines
3.9 KiB
Markdown
## PS2Recomp: PlayStation 2 Static Recompiler (Experimental)
|
|
|
|
[](https://discord.gg/JQ8mawxUEf)
|
|
|
|
Also check our [WIKI](https://github.com/ran-j/PS2Recomp/wiki)
|
|
|
|
|
|
This project statically recompiles PS2 ELF binaries into C++ and provides a runtime to execute the generated code.
|
|
|
|
### Modules
|
|
|
|
* `ps2xAnalyzer`: scans ELF/functions and writes TOML config (`stubs`, `skip`, instruction patches).
|
|
* `ps2xRecomp`: reads TOML + ELF, decodes R5900 instructions, and generates C++ output.
|
|
* `ps2xRuntime`: hosts memory, function registration, syscall dispatch, and hardware stubs.
|
|
|
|
### Features
|
|
|
|
* Translates MIPS R5900 instructions to C++ code
|
|
* PS2-specific MMI and VU0 macro support.
|
|
* Single-file or multi-file output.
|
|
* Configurable stubs, skips, and instruction patches.
|
|
* Instruction-driven syscall handling.
|
|
|
|
### How It Works
|
|
PS2Recomp works by:
|
|
|
|
* Parsing a PS2 ELF file to extract functions, symbols, and relocations
|
|
* Decoding the MIPS R5900 instructions in each function
|
|
* Translating those instructions to equivalent C++ code
|
|
* Generating a runtime that can execute the recompiled code
|
|
|
|
The translated code is very literal, with each MIPS instruction mapping to a C++ operation. For example, `addiu $r4, $r4, 0x20` becomes `ctx->r4 = ADD32(ctx->r4, 0X20);`.
|
|
|
|
### Current Behavior
|
|
|
|
* `stubs` entries generate wrappers that call known runtime syscall/stub handlers by name.
|
|
* `skip` entries are not recompiled and generate explicit `ps2_stubs::TODO_NAMED(...)` wrappers.
|
|
* Recompiled `SYSCALL` now calls `runtime->handleSyscall(...)` with the encoded syscall immediate.
|
|
* Runtime syscall dispatch tries encoded syscall ID first, then falls back to `$v1`.
|
|
|
|
### Requirements
|
|
|
|
* CMake 3.20+
|
|
* C++20 compiler (currently tested mainly with MSVC)
|
|
* SSE4/AVX host support for some vector paths
|
|
|
|
### Build
|
|
|
|
```bash
|
|
git clone --recurse-submodules https://github.com/ran-j/PS2Recomp.git
|
|
cd PS2Recomp
|
|
|
|
cmake -S . -B out/build
|
|
cmake --build out/build --config Debug
|
|
```
|
|
|
|
### Usage
|
|
|
|
1. Analyze ELF and generate config:
|
|
|
|
```bash
|
|
./ps2_analyzer your_game.elf config.toml
|
|
```
|
|
*For better results on retail games, see the [Ghidra Workflow](ps2xAnalyzer/Readme.md#3-ghidra-integration-recommended-for-complex-games).*
|
|
|
|
2. Recompile using generated TOML:
|
|
|
|
```bash
|
|
./ps2_recomp config.toml
|
|
```
|
|
|
|
3. Build generated output and link with `ps2xRuntime`.
|
|
|
|
### Configuration
|
|
|
|
Main fields in `config.toml`:
|
|
|
|
* `general.input`: source ELF path.
|
|
* `general.ghidra_output`: optional function map CSV.
|
|
* `general.output`: generated C++ output folder.
|
|
* `general.single_file_output`: one combined cpp or one file per function.
|
|
* `general.patch_syscalls`: apply configured patches to `SYSCALL` instructions (`false` recommended).
|
|
* `general.patch_cop0`: apply configured patches to COP0 instructions.
|
|
* `general.patch_cache`: apply configured patches to CACHE instructions.
|
|
* `general.stubs`: names to force as stubs.
|
|
* `general.skip`: names to force as skipped wrappers.
|
|
* `patches.instructions`: raw instruction replacements by address.
|
|
|
|
Example:
|
|
|
|
```toml
|
|
[general]
|
|
input = "path/to/game.elf"
|
|
ghidra_output = ""
|
|
output = "output/"
|
|
|
|
single_file_output = true
|
|
patch_syscalls = false
|
|
patch_cop0 = true
|
|
patch_cache = true
|
|
|
|
stubs = ["printf", "malloc", "free"]
|
|
|
|
skip = ["abort", "exit"]
|
|
|
|
[patches]
|
|
instructions = [
|
|
{ address = "0x100004", value = "0x00000000" }
|
|
]
|
|
```
|
|
|
|
### Runtime
|
|
|
|
To execute the recompiled code.
|
|
|
|
`ps2xRuntime` currently provides:
|
|
|
|
* Guest memory model and function dispatch table.
|
|
* Some syscall dispatcher with common kernel IDs.
|
|
* Basic GS/VU/file/system stubs.
|
|
* Foundation to expand and port your game.
|
|
|
|
### Limitations
|
|
|
|
* Graphics Synthesizer and other hardware components need external implementation
|
|
* VU1 microcode is not complete.
|
|
* Hardware emulation is partial and many paths are stubbed.
|
|
|
|
### Acknowledgments
|
|
|
|
* Inspired by N64Recomp
|
|
* Uses ELFIO for ELF parsing
|
|
* Uses toml11 for TOML parsing
|
|
* Uses fmt for string formatting |