The Spectrum Dispatch News

technology

God of War Running in Browser via WebAssembly Recompilation

PSP games translated from MIPS to C++, compiled to WebAssembly, and running in the browser at native resolution or higher with full audio and controls.

God of War Running in Browser via WebAssembly Recompilation

A new project has made it possible to run PSP games directly in web browsers without an emulator, by translating the games’ machine code ahead of time into C++ and compiling to WebAssembly.

God of War Running in Browser via WebAssembly Recompilation

The first games brought to the browser this way are God of War: Chains of Olympus and God of War: Ghost of Sparta. According to the project documentation, Chains of Olympus plays through menus, cutscenes and combat at 60 frames per second in Chrome and Firefox on laptops, and up to four times the PSP’s native 480×272 resolution. The game also runs on phones with on-screen touch controls, with music, speech and sound effects working. Ghost of Sparta runs at 55 to 60 frames per second at three times the native resolution.

The technical approach involves several components. PSPRecomp analyzes the PSP executable and emits C++ code for its functions. That code runs against a register file and a model of the PSP’s memory. The project adds fixes and a new web profile target for PSPRecomp.

A reimplemented PSP kernel handles what the game requests from the operating system: cooperative threads with semaphores, event flags and callbacks, memory partitions, file system access (with disc data streamed via HTTP Range requests), controller input, audio output, save data and message dialogs.

The graphics chip implementation decodes display lists on the CPU and hands batched triangles and render state to WebGL. Framebuffers become WebGL render targets, and the system can render at one to four times the native resolution. The graphics chip and WebGL context run on a worker thread with an OffscreenCanvas, allowing the game’s CPU and graphics work to happen in parallel, much like on the actual PSP.

Sound comes from a reimplementation of the PSP’s voice synthesizer handling 32 voices of ADPCM with pitch and ADSR envelopes, plus ATRAC3+ streams decoded with FFmpeg, mixed to an AudioWorklet.

Optimization required careful profiling. An early build ran at 6 frames per second. A key improvement came from addressing how God of War swaps its framebuffer: by holding the thread that swaps twice within one vertical blank until the next one, work per displayed frame dropped by a factor of eight. Firefox-specific issues included re-validating index buffers after changes, solved by giving each draw a small index buffer. Reducing stencil buffer mirroring operations from 60 million pixels per frame at 4× resolution down to about 7 million came from tracking which rectangles and values actually changed.

Users must provide their own PSP game disc images. The project requires git, CMake, Ninja, a C++20 compiler and Python 3, with about 2 GB of disk space per game. Porting a game takes a few minutes on an 8-core laptop.

Key facts

  • God of War: Chains of Olympus and Ghost of Sparta run at 60 fps at up to 4× native resolution in browsers
  • The project translates PSP MIPS machine code to C++, compiles to WebAssembly, and reimplements the PSP OS and graphics chip
  • Graphics and audio work fully, including music, speech and sound effects

Sources

← All posts