📦sp00nznet / ps3recomp
← 返回首页
Static recompilation runtime libraries for PlayStation 3 titles.
⚖️ MIT📅 创建于 2026-03-11🔄 更新于 2026-10-26

📄 仓库 README

在 GitHub 查看 ↗
来自 GitHub 仓库自述文件 · 版权归原作者所有

ps3recomp

Because the Cell processor deserves a second life

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.


What Is This?

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.

Why PS3?

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:

  • Native performance — no runtime translation overhead
  • Lower hardware requirements — runs on mid-range PCs
  • Moddability — recompiled C/C++ is infinitely more hackable than PPC binaries
  • Preservation — native ports survive long after emulators stop being maintained
  • Portability — the output is C/C++, so it can target any platform a compiler does (see platform support for where the runtime actually stands today)

Platform support

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 Challenge

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.

Architecture

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

How It Works

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
   └─────────────┘

SPU Strategy

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:

  1. SPU programs are self-contained — they live in ELF segments loaded to local store (extract_spu_images.py pulls them out of PRX/ELF)
  2. Recompile each SPU program separately — dedicated spu_disasm.py + spu_lifter.py handle the SPU ISA
  3. SPU local store becomes an array — 256KB per "virtual SPU"
  4. DMA operations become memcpy — via the MFC engine (spu_dma.h)
  5. Channels become cross-thread message queues — preserving ordering guarantees
  6. Per-image function-table dispatch — image_id lets multiple SPU programs (e.g. a SPURS kernel, a policy module, and a job) coexist at overlapping local-store addresses

This mirrors how RPCS3 handles SPU but at compile time rather than runtime. The disassembler, lift

📈 近 7 天 Star 趋势

每日新增 Star(柱)与累计 Star(线)· 数据来自 GitHub

🏆 排名变化趋势

在各榜单中的排名历史(数字越小越靠前)

📋 历史上榜记录

每次快照的详细数据
日期 榜单 排名 周期新增 总 STAR