PS2

Static recompilation · WebAssembly · WebGPU

PS2 Web Recomp: Play PS2 Games in Your Browser — No Emulator

ps2-web-recomp is an open-source project by snuri00 that translates a PlayStation 2 game’s Emotion Engine machine code ahead of time into C++ and compiles it to WebAssembly. The browser never interprets the main CPU — the rest of the console is reimplemented by a runtime that draws with WebGPU.

50 fps

Gran Turismo 4 (PAL) at full speed, in Chrome on a laptop’s integrated GPU at twice the PS2’s resolution.

60 fps

God of War II holds 60 fps in heavy combat at native resolution — 48–60 at 2× resolution.

100%

Open source under the MIT license, with 900+ stars on GitHub and a sibling project for PSP games.

0 emulated CPUs

The main CPU is recompiled, not interpreted. Only the I/O processor and hardware are emulated.

How PS2 Web Recomp works

The game’s code is translated, not emulated

A recompiler reads the game’s executable, follows its control flow and emits C++ for every function it finds, in 16 KiB units. The output is compiled to WebAssembly. The R5900’s quirks — 128-bit registers, multimedia instructions, branch delay slots, the PS2’s non-IEEE floating point unit — are all preserved in the generated code.

The rest of the console is a native runtime

A small PS2 kernel answers the operating system’s calls with high-level emulation: threads, semaphores, DMA and vblank interrupt handlers, and the SIF channel. The I/O processor runs the game’s own IRX modules on an R3000 interpreter, while the sound driver, disc streaming and controller drivers work as they do on the console.

Graphics via WebGPU compute shaders

The Graphics Synthesizer’s 4 MB of video memory lives on the GPU in its native swizzled layouts. Triangles are binned into tiles and rasterized with the GS’s own rules for texturing, palettes, alpha blending and depth — so effects that render into a texture or reinterpret a framebuffer as a palette behave like they do on real hardware.

Sound, movies and memory cards

The SPU2 is reimplemented with its 48 ADPCM voices and ADSR envelopes, output through an AudioWorklet. Movies are decoded by an MPEG-2 (IPU) implementation. The disc is read over HTTP Range requests, so only the executable downloads up front — and saves go to a memory card kept in the browser.

Games verified so far

The project brings games up one at a time through its scripted pipeline. These two titles currently go from a disc image to a playable web page:

Gran Turismo 4 Playable

Boots through the opening movie, menus and races, with music and sound effects. Full speed at 50 fps (PAL) at 2× resolution on integrated graphics.

See all details →

God of War II Playable

Menus, cutscenes and combat, built through the same script with no game-specific code. 60 fps in heavy combat at native resolution.

See all details →

Quick start (3 steps)

  1. 1

    Clone the repo and install the toolchain

    You need git, CMake, Ninja, a C++20 compiler, Python 3 and 7-Zip (for .7z disc images). The first run installs the Emscripten SDK automatically.

  2. 2

    Recompile your disc image

    scripts/port.sh mygame "My Game.iso"
  3. 3

    Serve it and play in Chrome or Edge

    python3 scripts/serve.py build/web-mygame games/mygame/disc.iso

    Open http://localhost:8620/ — your browser needs WebGPU. Full walkthrough in the step-by-step tutorial.

Ready to try it?

The full tutorial walks from a fresh machine to a game running in your browser — including the errors you may hit along the way.

Read the tutorial