PS2Recomp

ran-jGPL-3.0活跃维护

把 PS2 游戏二进制静态重编译成可在 PC 上原生运行的程序,省去逐行模拟开销,方便做移植和逆向分析。

Playstation 2 Static Recompiler & Runtime Tool to make native PC ports

v0.4发布于 2026-04-05 02:24 UTC3,827star +21 / 7 天254fork同步于 2026-11-10 11:39 UTC

怎么上手

由 README 提炼,执行前请确认
git clone --recurse-submodules https://github.com/ran-j/PS2Recomp.git
cd PS2Recomp
cmake -S . -B out/build
cmake --build out/build --config Debug
硬件要求按 README 说明

README 未说明显存或 GPU 型号要求;仅要求宿主 CPU 支持 SSE4/AVX 以运行部分向量路径。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把 PS2 ELF 静态重编译成 C++ 并配运行时,用来做原生 PC 移植

把 PS2 游戏二进制静态重编译成可在 PC 上原生运行的程序,省去逐行模拟开销,方便做移植和逆向分析。

核心能力

  • 将 MIPS R5900 指令逐条翻译为等价 C++ 代码
  • 支持 PS2 专用 MMI 与 VU0 macro 指令
  • 用 TOML 配置 stubs、skip 和指令补丁
  • 支持 handler@地址 绑定 stripped 游戏函数
  • 内置 ps2xIOP 执行原始 IRX 模块

容易踩的坑

必须加 --recurse-submodules 克隆,否则子模块缺失;需要 CMake 3.20+ 和 C++20 编译器,目前主要在 MSVC 上测试;零售或 stripped 游戏建议先用 Ghidra 导出 TOML/CSV,直接跑 analyzer 只适合带调试符号的 ELF。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.4
  1. v0.4pre-release最新正式版2026-04-05 · 2026-04-05 02:24 UTC

    What's Changed

    • sceGsSetDefDBuff and sceGsSwapDBuff implementation based on the DC version by @roby65 in https://github.com/ran-j/PS2Recomp/pull/106

    • feat: remove memory and pad from stub section

    • feat: add support for resume entry targets in CodeGenerator (this allow jumps in address outside function) feat: refactor entry point discovery one more try to reduce big generated file

    • feat: optmizations for release build

    • feat: remove unused file

    • feat: added some test cases for code gen

    • feat: added log macro and remove win specific code

    • feat: refactor runtime folder structure feat: added reset sound driver RPC state and compatibility layout feat: rename and added new test feat: update RPC calls to use defined constants feat: added more PSMC(16, 32) feat: change cd read to try find the asset ignoring case sensitive fix: fix some render problems feat: add logs on pad feat: added more RPC handles

    • feat: added game override for code veronica

    • feat: apply vita patch

    • feat: flags to disable build

    • feat: fix merges feat: break a lot of tests

    • feat: better throw error on empty cd path feat: remove recompiler unusde function feat: apply missing patch

    • feat: gamedp is now part of lib feat: missing file

    • feat: small cleanup

    • feat: missing vita changes

    • feat: fix more merge

    • feat: fix tests

    • feat: last missing feature

    • feat: added missing import

    • feat: rename test local functions

    • feat: init syscall on ps2 list

    • feat: added DMA helpers

    • feat: faster builds feat: more implement for darkcloud

    • feat: back missing file

    • feat: added missing includes

    • feat: remove test

    • feat: missing include

    • feat: read register funtion

    • feat: build fix

    • feat: force exit on detach thread

    Full Changelog: https://github.com/ran-j/PS2Recomp/compare/v0.3...v0.4

    Note the runtime is way more generic, but since we dont emulate IOP modules YOU need to handle then on RPC or your game will be stuck.

    Code veronica graphical fixes and we can boot dark cloud 2 with some graphic glitchs.

  2. v0.3pre-release2026-03-18 · 2026-03-18 23:27 UTC
    查看更新说明

    What's Changed

    • fix: CRITICAL fix on code gen on generating BEQ translation, I added a small yeld because goto could spin forever and monopolize guest execution

    • feat: add scratchpad alias base and improve scratchpad address handling

    • feat: added debug logging on GifArbiter for submit and drain operations

    • feat: add interrupt and thread management syscall implementations fix: change some IDs calls to match ps2sdk

    • feat: added vif1 logs

    • feat: added logs on gs gpu feat: added performLocalToLocalTransfer to GS emulation path for TRXDIR = 2. (emulates the PS2 GS “copy this rectangle from one place in VRAM to another”)

    • feat: added PSMT8 and refactor PSMT4

    • feat: some identation on vu1 feat: added some logs on vu1

    • feat: added GuestExecutionScope to temporarily stop owning guest execution, then restore it exactly as it was. feat: added vsync wizardry feat: added some regression test

    • fix: fix gs logger

    • feat: remove extra logs I think they will help no one feat: move join all threads to prevent the app to get stuck on close, but now it random crash on closing feat: one more small test on psmt4 to try fix ghosting on re code veronica

    • feat: added a small case for exporter from ghidra for metal slug 3

    • feat: added ugly code to pass on test

    Full Changelog: https://github.com/ran-j/PS2Recomp/compare/v0.2...v0.3

    Know issue

    Some games create larger cpp files, I`m aware about that bug, but I dont have a solution for now, the bug consist in wrong boundries funcctions check, that can occur even on ghidra so this is a bit more complicated to solve.

    Special

    Now we can boot Resident Evil code veronica (SLUS_201.84). Its only get to memory card part not more than that for now.

    I used ghidra workflow but should work on local analyzer as well.

  3. v0.2pre-release2026-03-09 · 2026-03-09 03:43 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/ran-j/PS2Recomp/compare/v0.1...v0.2

  4. v0.1pre-release2026-02-27 · 2026-02-27 06:46 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/ran-j/PS2Recomp/compare/v0.0...v0.1

  5. v0.0V0pre-release2026-02-22 · 2026-02-22 05:22 UTC
    查看更新说明

    We have a recompiler with a lot of instructions and workflow for strip and debug symbol games. We also have a runtime with simple GS, DMA and many more.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    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

    • 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.
    • ps2xIOP: R3000A IRX execution, a virtual IOP kernel, and generic HLE fallbacks.

    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.
    • stubs also supports address bindings with handler@0xADDRESS for stripped games (for example sceCdRead@0x00123456).
    • Address bindings also support generic return handlers for triage: ret0, ret1, reta0.
    • Recompiler now tries relocation-symbol auto-binding at callsites (J/JAL) before raw address dispatch; when relocation symbol is known (for example sceCdRead), it can call runtime handlers without manual address mapping.
    • Recompiler discovers additional internal static entry targets and emits entry_... wrappers for those addresses.
    • For unresolved static J/JAL sites, generated code falls back to runtime->lookupFunction(0x...).
    • 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

    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:

    • general.input: source ELF path.
    • general.ghidra_output: recommended function map CSV exported from Ghidra.
    • general.output: generated C++ output folder.
    • general.single_file_output: one combined cpp or one file per function.
    • general.low_memory_mode: reduce peak output-generation memory by avoiding retained disassembly strings and forcing serial output generation. Generated instruction comments are still emitted; disassembly text is produced while writing each output file instead of being kept in memory.
    • general.output_worker_threads: number of output-generation workers (clamped to nproc * 2). A positive value uses exactly that many workers. 0 uses nproc - 1 when at least two hardware threads are available, otherwise serial output generation. 1 forces serial output generation.
    • 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. Also accepts handler@0xADDRESS to bind a stripped function address directly to a runtime syscall/stub handler. Includes generic handlers ret0, ret1, reta0.
    • general.skip: names to force as skipped wrappers.
    • patches.instructions: raw instruction replacements by address.

    Address binding for stripped ELFs:

    • Use handler@0xADDRESS inside general.stubs to map a stripped function start directly to a runtime handler.
    • Example: sceCdRead@0x00123456 binds function start 0x00123456 to ps2_stubs::sceCdRead(...).
    • Generic temporary handlers are available: ret0@0xADDR, ret1@0xADDR, reta0@0xADDR.
    • Before manual binding, prefer recompilation from a Ghidra-exported TOML/CSV first. The extra boundaries and synthetic entry points are usually more important than manual early triage.
    • The address must be the function start in that exact ELF build.
    • Addresses are not portable across different games/regions/builds.
    • The handler name must exist in runtime call lists (PS2_SYSCALL_LIST or PS2_STUB_LIST).

    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:

    • 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.
    • ps2xIOP execution of original IRX modules with generic HLE fallbacks.

    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:

    • Header: ps2xRuntime/include/game_overrides.h
    • Register macro: PS2_REGISTER_GAME_OVERRIDE(name, elfName, entry, crc32, applyFn)
    • Direct bind helper: ps2_game_overrides::bindAddressHandler(runtime, addr, "handler")

    Use Game Override modules when:

    • You need per-game/per-build routing or patches without polluting global behavior.
    • You need to bind many addresses, or install custom replacement logic for a specific title.
    Recommended Iteration Loop
    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" }
    }
    
    • original is the release a user must own. On retail discs the ELF is named after the serial (SLUS_203.12 is SLUS-20312), and the prefix gives the region: SLUS/SCUS USA, SLES/SCES Europe, SLPS/SLPM/SCPS Japan.
    • status is one of exploring, in-progress, playable, released, complete, paused. Edit it when the project moves on: a stale status is worse than none.
    • Never put a game file, or a link to one, in the file.

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

    Limitations

    • Performance is very bad for VU and GS
    • 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
    • Reference for runtime PCSX2