David Erik García Arenas
← All projects

RYU6Recomp

Bringing a PS4 game demo to Windows, as a research prototype.

Recovering verifiable behaviour from a binary with no source and no documentation

Engineering research · Apr 2026 – present

At a glance

Challenge
Run a PS4 game demo on a Windows PC, although its code expects console memory, GPU commands, shader formats and system services a PC lacks.
Solution
Rehost it: the demo's x86-64 code runs directly on the CPU, system calls are reimplemented in C++, and GCN shaders are translated to SPIR-V for Vulkan.
Result
99.73% of the demo's pixel shaders translate cleanly, and one fix cut frame-present waits from up to 1.9 s to about 7 ms. Research prototype, not playable.
shadPS4 emulationWith my fixshadPS4 emulationWith my fix
The before/after: the same cutscene in stock emulation (hair blocked, no alpha) and with my alpha-to-coverage fix in the emulator's shader backend.
Mesh regionDrawn in-frameMesh regionDrawn in-frame
The hair mesh (event 3013): its region in magenta, and its draw within the lit frame.
Mayu regionsDrawn in-frameMayu regionsDrawn in-frame
The mayu meshes: dedicated eyebrow, sideburn and goatee detail geometry (event 3022), and hair plus mayu drawn together.
The diagnostic overlay I built into the reference emulator (shadPS4, used as the oracle), frame 153502: frame-time budget, the live camera block read out of memory, player-position candidate scanning, and every render pass listed by its fragment shader
The diagnostic overlay I built into the reference emulator (shadPS4, used as the oracle), frame 153502: frame-time budget, the live camera block read out of memory, player-position candidate scanning, and every render pass listed by its fragment shader
Reference run in shadPS4, frame 50941 with passes switched off one at a time. 147 passes seen in the run; HUD elements, motion blur and a character-halo pass are marked confirmed once switching them off changed what was drawn
Reference run in shadPS4, frame 50941 with passes switched off one at a time. 147 passes seen in the run; HUD elements, motion blur and a character-halo pass are marked confirmed once switching them off changed what was drawn
Reference run in shadPS4, frame 47819 with most full-screen work skipped, leaving the draws that still compose the scene. Draw counts and indices per draw are listed for each pass
Reference run in shadPS4, frame 47819 with most full-screen work skipped, leaving the draws that still compose the scene. Draw counts and indices per draw are listed for each pass
Reference run in shadPS4, frame 118777: the recovered view basis, projection matrix and combined view-projection alongside the live pass list, with the free camera driving the main view
Reference run in shadPS4, frame 118777: the recovered view basis, projection matrix and combined view-projection alongside the live pass list, with the free camera driving the main view
The hair fix up close: hair, mayu and eyelashes all alpha-tested. RenderDoc backbuffer, frame 1377
The hair fix up close: hair, mayu and eyelashes all alpha-tested. RenderDoc backbuffer, frame 1377
In my patched shadPS4 build, RenderDoc: event browser, vertex buffers, mesh viewer
In my patched shadPS4 build, RenderDoc: event browser, vertex buffers, mesh viewer
In my patched shadPS4 build: Lua test stage loading c_am_dummy, a real model from the game
In my patched shadPS4 build: Lua test stage loading c_am_dummy, a real model from the game
Fight scene in my patched shadPS4 build during an early experiment (bloom and lens-flare artifacts).
Fight scene in my patched shadPS4 build during an early experiment (bloom and lens-flare artifacts).
Reference render from my patched shadPS4 build, used as the target for the native renderer
Reference render from my patched shadPS4 build, used as the target for the native renderer
Pass 24 boundary, shader group 11 landing: the street renders with real materials from my own pipeline
Pass 24 boundary, shader group 11 landing: the street renders with real materials from my own pipeline
Live run 235, shader group 145 under a single-channel debug view, checking geometry and coverage
Live run 235, shader group 145 under a single-channel debug view, checking geometry and coverage
Fragcoord passthrough for group 147: isolating a pass to prove the plumbing before the real shader lands
Fragcoord passthrough for group 147: isolating a pass to prove the plumbing before the real shader lands
Shader group 144 during bring-up
Shader group 144 during bring-up
Reference target (shadPS4): group 17, event 9696, slot-0 output during shader-group bring-up
Reference target (shadPS4): group 17, event 9696, slot-0 output during shader-group bring-up
Reference target (shadPS4): group 58, event 10478, slot-0 output
Reference target (shadPS4): group 58, event 10478, slot-0 output
Reference target (shadPS4): group 183, event 12686, slot-0 output
Reference target (shadPS4): group 183, event 12686, slot-0 output

The problem

The binary assumes console-specific memory, GPU commands, shader formats, synchronization and operating-system services that do not exist on a desktop host.

Approach

PS4 demo binary(x86-64)Code runs directlyon the PC's CPUSystem callsredone in C++GCN shadersto SPIR-VVulkan rendereron WindowsPS4 demo binary(x86-64)Code runs directlyon the PC's CPUSystem callsredone in C++GCN shadersto SPIR-VVulkan rendereron Windows
Simplified view of the rehosting approach. A research prototype: it does not establish playability.

Outcome

Accepted source milestones cover runtime, memory, shader and presentation work; the current state does not establish complete playability, visual correctness or general compatibility.

Built with

Read the writeupTry the alpha-to-coverage demo