Static recompilation runtime libraries for PlayStation 3 titles. Turn PS3 binaries into native executables. No emulator required.
Join the sp00nznet recomp Discord — the community hub for sp00nznet's recomp projects, where ps3recomp development happens in the open. Good place to ask questions, show a port you are working on, or find out what people are stuck on before you duplicate the effort.
ps3recomp is an open-source toolkit that provides the runtime libraries, system stubs, and analysis tools needed to statically recompile PlayStation 3 games into native PC executables.
Instead of interpreting or dynamically recompiling PowerPC/SPU instructions at runtime (what emulators like RPCS3 do brilliantly), we take the opposite approach: translate everything ahead of time into C/C++ that compiles with your favorite compiler on any modern platform.
This is the same philosophy behind: - N64Recomp (N64 -> native) - UnleashedRecomp (Xbox 360 -> native) - PS2Recomp (PS2 -> native) - burnout3 (Original Xbox -> native) - ReXGlue (Xbox 360 -> native) - AnyPS5 (PS5 -> native)
...but for the PS3's glorious, terrifying Cell Broadband Engine.
The PlayStation 3 has over 3,000 titles and some of the most beloved games ever made. RPCS3 has done heroic work making ~70% of the library playable through emulation, but static recompilation offers something different:
CI builds and tests every row on every pull request: Windows (clang-cl), macOS arm64, Linux (GCC and Clang), and Linux with the Vulkan backend on lavapipe under the validation layer. A green check means the runtime built and the tests passed. It does not mean a game ran; the last row is the only one that claims that.
| Windows | macOS (arm64) | Linux | |
|---|---|---|---|
| Runtime library builds | yes | yes | yes |
| Lifter test suites + C unit tests | yes | yes | yes |
| Render backend | D3D12 | Metal | Vulkan (opt-in); null (headless, CI) |
| Runs a recompiled game, in this tree | yes | no | no |
What stops macOS and Linux running a title is the PPU boot scaffold.
ppu_loader.cpp, boot_main.cpp and the HLE dispatch are compiled per game,
not into the library. They compile on POSIX with zero errors (a CI ratchet
keeps it that way) and the frame clock runs there, but no title has yet been
booted to gameplay from this tree on either OS.
The renderers are further along than that. ps3recomp_host drives cellGcm
→ RSX → backend end to end with no game. With guest programs on, Metal and
Vulkan both run the title's own shaders on the shared register-file draw
engine. Every ps3recomp_host scene passes on both, including render-to-texture,
MRT, depth textures, cube maps and stencil. Linux's default stays the headless
null backend, a CPU triangle filler that CI draws with.
Downstream, people are already past this. Twisted Metal's menus run on Linux/Vulkan, inFamous on macOS, and Killzone 3 under Proton (see In the community). Those ports carry patches that are still on their way upstream, which is why the table still says "no".
The PS3's Cell processor is a beast unlike anything else:
| Component | What It Is | Why It's Hard |
|---|---|---|
| PPU | PowerPC 64-bit main CPU | Custom ISA extensions, VMX/AltiVec SIMD |
| 6x SPU | 128-bit SIMD vector processors | Proprietary ISA, 256KB local store, explicit DMA |
| Memory | 256MB XDR RAM | 128-byte alignment requirements, split bus |
| LV2 Kernel | Proprietary OS layer | ~300+ system calls, complex threading model |
| PRX Modules | Dynamic libraries | 100+ system libraries with intricate interdependencies |
We don't shy away from hard problems. We just break them into smaller ones.
ps3recomp/
├── tools/ # Binary analysis & recompilation pipeline
│ ├── elf_parser.py # Parse PS3 ELF/SELF/PRX binaries
│ ├── ppu_disasm.py # PowerPC disassembler with PS3 extensions
│ ├── ppu_lifter.py # PPU assembly -> C code lifter
│ ├── spu_disasm.py # SPU instruction set disassembler
│ ├── spu_lifter.py # SPU assembly -> C code lifter
│ ├── extract_spu_images.py # Extract embedded SPU images from PRX/ELF
│ ├── find_spu_functions.py # SPU function boundary detection
│ ├── wrap_spu_elf.py # Wrap a raw SPU blob as a loadable ELF
│ ├── prx_analyzer.py # Analyze PRX imports/exports and NIDs
│ ├── nid_database.py # Function Name ID (NID) resolver
│ ├── find_functions.py # Function boundary detection
│ └── generate_stubs.py # Generate HLE stub skeletons from a NID list
│
├── runtime/ # Core runtime for recompiled executables
│ ├── ppu/ # PPU execution context
│ │ ├── ppu_context.h # Register file, CR, LR, CTR, FPSCR
│ │ ├── ppu_memory.h # Memory access macros (loads, stores, byte-swap)
│ │ └── ppu_ops.h # Instruction operation macros
│ ├── spu/ # SPU execution context
│ │ ├── spu_context.h # 128×128-bit register file, 256KB local store, image_id
│ │ ├── spu_channels.c # Channel ops + per-image function-table dispatch
│ │ ├── spu_helpers.h # SPU intrinsics (incl. float conversions)
│ │ ├── spu_dma.h # DMA (MFC) transfer engine
│ │ └── tests/ # Self-contained SPU runtime tests
│ ├── memory/ # Memory subsystem
│ │ └── vm.h # Virtual memory manager (256MB address space)
│ └── syscalls/ # LV2 kernel system call implementations
│ ├── sys_ppu_thread.h # Thread creation/management
│ ├── sys_mutex.h # Mutex/cond synchronization
│ ├── sys_memory.h # Memory allocation/mapping
│ ├── sys_fs.h # Filesystem operations
│ └── lv2_syscall_table.h # Full syscall dispatch table
│
├── libs/ # HLE library implementations
│ ├── audio/ # cellAudio, cellAdec, libmixer, libsnd3, libsynth2
│ ├── video/ # cellGcmSys, cellResc, cellVideoOut, cellVpost, cellVdec
│ ├── input/ # cellPad, cellKb, cellMouse
│ ├── hardware/ # cellGem, cellCamera, cellUsbd
│ ├── network/ # cellNetCtl, cellHttp, cellHttps, cellSsl, sceNp*
│ ├── filesystem/ # cellFs, cellGame, cellSaveData, cellStorage
│ ├── system/ # cellSysutil, cellSysmodule, cellRtc, sysPrxForUser
│ ├── spurs/ # cellSpurs, cellFiber, cellSpursJq, cellDaisy (SPU task management)
│ ├── sync/ # cellSync, cellSync2 (cross-PPU/SPU synchronization)
│ ├── codec/ # cellJpgDec, cellPngDec, cellGifDec, cellPamf, cellDmux, cellAdecAtrac3p, cellAdecCelp8, cellVdecDivx
│ ├── font/ # cellFont, cellFontFT, cellFreeType, cellL10n
│ └── misc/ # cellScreenshot, cellSubdisplay, cellImeJp, cellVideoExport, cellMusicExport, cellGameRecording, etc.
│
├── include/ps3emu/ # Public API headers
│ ├── ps3types.h # Fundamental PS3 types (u8-u128, s8-s64, be_t<>)
│ ├── endian.h # Big-endian <-> little-endian conversion
│ ├── nid.h # NID hashing and lookup
│ ├── module.h # Module registration framework
│ └── error_codes.h # PS3 system error codes (CELL_OK, CELL_E*)
│
├── templates/project/ # Starter template for new game ports
│ ├── CMakeLists.txt # Build system
│ ├── main.cpp # Application entry point
│ ├── stubs.cpp # Game-specific function overrides
│ └── config.toml # Recompiler configuration
│
├── config/ # Reference configurations
│ └── example.toml # Example recompilation config
│
└── docs/ # See the Documentation table below
The pipeline follows the same proven approach as our burnout3 project, adapted for the Cell architecture:
PS3 Game Disc / PKG
│
▼
┌─────────────┐
│ SELF/EBOOT │ Encrypted PS3 executable
│ Decryption │ (requires keys / fSELF)
└──────┬──────┘
│
▼
┌─────────────┐
│ ELF Parser │ Extract sections, segments, relocations
│ + PRX Scan │ Identify imported NIDs & library deps
└──────┬──────┘
│
▼
┌─────────────┐
│ PPU Disasm │ Disassemble PowerPC 64-bit + VMX
│ + Analysis │ Function boundaries, jump tables, ABI
└──────┬──────┘
│
▼
┌─────────────┐
│ PPU Lifter │ PowerPC → C code generation
│ + SPU Lift │ SPU programs → C code generation
└──────┬──────┘
│
▼
┌─────────────┐
│ Link with │ ps3recomp runtime + HLE libs
│ Runtime │ Provides all PS3 OS services
└──────┬──────┘
│
▼
┌─────────────┐
│ Compile & │ MSVC / GCC / Clang
│ Ship! │ Native x86-64 executable
└─────────────┘
The SPU is the elephant in the room. Each SPU has its own instruction set, its own 256KB memory, and communicates with the PPU via DMA and mailbox channels. Our approach:
extract_spu_images.py pulls them out of PRX/ELF)spu_disasm.py + spu_lifter.py handle the SPU ISAspu_dma.h)image_id lets multiple SPU programs (e.g. a SPURS kernel, a policy module, and a job) coexist at overlapping local-store addressesThis mirrors how RPCS3 handles SPU but at compile time rather than runtime. The disassembler, lift
| 日期 | 榜单 | 排名 | 周期新增 | 总 STAR |
|---|