PS2Recomp README

The project's README from github.com/ran-j/PS2Recomp. As one markdown file: README.md.

PS2Recomp: PlayStation 2 Static Recompiler (Experimental)

Discord

Also check our WIKI

This project statically recompiles PS2 ELF binaries into C++ and provides a runtime to execute the generated code.

Modules

Features

How It Works

PS2Recomp works by:

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

Requirements

Build

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

Preferred workflow for retail or stripped games:

  1. Open the ELF in Ghidra.
  2. Run ps2xRecomp/tools/ghidra/ExportPS2Functions.java.
  3. Use the exported TOML and CSV map.
  4. Recompile with the exported TOML:
./ps2_recomp config.toml

Fallback workflow for quick local experiments or ELFs with debug symbol :

./ps2_analyzer your_game.elf config.toml

See the Ghidra Workflow for ghdira instructions.

Then build generated output and link with ps2xRuntime.

Configuration

Main fields in config.toml:

Address binding for stripped ELFs:

Example:

# stripped function binding by address:
stubs = ["sceCdRead@0x00123456", "SifLoadModule@0x00127890"]
# temporary return handlers:
stubs = ["ret0@0x001D9410", "ret1@0x001D5BC8", "reta0@0x0024B7C0"]
# mixed example:
stubs = ["printf", "sceCdRead@0x00123456", "SifLoadModule@0x00127890"] 

Runtime

To execute the recompiled code.

ps2xRuntime currently provides:

See IOP emulation for module execution and the service boundary.

Game Override Hooks

Game overrides are runtime-side, build-scoped patch modules.

A game override is C++ code that runs during loadELF and can replace EE function bindings by address for one specific game build. IOP RPC/DMA behavior is handled by the ps2xIOP emulator and its runtime transport. This is separate from recompilation output and separate from global runtime stubs/syscalls.

API:

Use Game Override modules when:

  1. Run with minimal config and no aggressive skipping.
  2. Fix hard blockers first (function not found, syscall TODO, critical IO stubs).
  3. Use temporary return stubs only to classify call importance.
  4. Promote temporary fixes to real implementations.
  5. Move per-game hacks into game overrides keyed by ELF metadata.
  6. Re-test from cold boot after each batch.

Describing Your Game Project

A game project built with PS2Recomp can describe itself in a .recomp.json file at the root of its repository. Lists of recomp and decomp projects, such as recomp.board, read that file instead of guessing the game, system and status from the README.

[!NOTE] This file is optional: PS2Recomp does not read it and works the same without it. .recomp.json and recomp.board are third-party projects; the PS2Recomp developers have no ties to them.

Starter file:

{
  "$schema": "https://recomp.fyi/schema/v1.json",
  "game": "<title as it shipped>",
  "system": "PS2",
  "type": "recomp",
  "toolchain": "PS2Recomp",
  "status": "in-progress",
  "original": { "region": "USA", "serial": "SLUS-20312" }
}

Other fields (Wikidata item, target platforms, maintainers, links, what help is wanted) and the JSON Schema are in the specification.

Limitations

Acknowledgments

PS2Recomp (ran-j/PS2Recomp)

Searching Database…

What is this?PS2Recomp statically recompiles PlayStation 2 ELF binaries into C++ source code and ships a runtime to execute that generated code, letting you build native PC ports of PS2 games.
Is this an emulator or a compiler toolchain?It is a toolchain, not an emulator like PCSX2: ps2xRecomp translates MIPS R5900 instructions into literal C++ code, ps2xRuntime executes that generated code on real hardware, and ps2xIOP runs the original IOP modules with HLE fallbacks.
How do I turn a PS2 game ELF into C++ with this?For retail or stripped games you open the ELF in Ghidra, run the included ExportPS2Functions.java script to get a TOML/CSV function map, then recompile using that exported TOML and link the generated output with ps2xRuntime.
What do I need installed before building this?You need CMake 3.20 or newer, a C++20 compiler (currently tested mainly with MSVC), and a host CPU with SSE4/AVX support for some of the vector translation paths; for retail games you also need Ghidra.
Does the generated code run at full speed?No, performance is currently very bad for VU and GS code paths, and hardware emulation is only partial with many functions left as stubs that need to be implemented per game.
Which OS does this build and run on?The build is CMake-based and is currently tested mainly on Windows with MSVC; other compilers/platforms are not confirmed as supported.
What is the difference between a stub entry and a skip entry in the config?Stub entries generate wrapper calls into known runtime syscall/stub handlers (including address-bound bindings like sceCdRead@0xADDRESS for stripped games), while skip entries are left unrecompiled and just emit explicit TODO wrapper calls.
What are Game Override hooks used for?They are build-scoped C++ modules that run during loadELF and let you replace specific EE function bindings by address for one exact game build, keeping per-title hacks separate from the global runtime stubs and syscalls.
Why would someone use this instead of just running the game in PCSX2?PS2Recomp aims to produce a native, standalone PC port by converting the game's MIPS code into compiled C++ (similar in spirit to N64Recomp), rather than emulating the original PS2 instructions at runtime like PCSX2 does; PCSX2 is only used as a reference for runtime behavior.
What is a .recomp.json file for?It is an optional metadata file a ported game project can include to describe its original release, serial, region and porting status; PS2Recomp itself never reads it, but third-party catalogs like recomp.board use it instead of guessing project details.
Creator
ran-j
Size
6 MB
Stars
3.6K
Updated
CommitOct 14
Age
1y
Commits · 90 Days