ShadPS4 Source Code Structure Overview: A Deep Dive into the PS4 Emulator Architecture

ShadPS4 organizes its C++ codebase into distinct layers—system emulation, GPU/video pipeline, input/UI, and build tooling—with the src/ directory containing core logic and src/video_core/ handling Vulkan-based graphics rendering.

The shadps4-emu repository represents a native C++ implementation of a PlayStation 4 emulator, architected to separate system-level concerns from hardware abstraction. This shadps4-emu source code structure overview examines how the project organizes its emulation core, graphics pipeline, and user interface components across the src/ directory tree.

Application Entry Point and CLI Parsing

The emulator boots through src/main.cpp, which implements the main function responsible for high-level orchestration. This file creates an EmulatorState singleton, loads user configuration, and parses command-line options using CLI11.

The parser resolves the game ELF path or CUSA ID, then invokes Core::Emulator::Run to begin execution. All initialization logic flows through this single entry point, making it the starting line for understanding the shadps4-emu source code structure.

// Simplified flow from main.cpp
auto* emulator = Common::Singleton<Core::Emulator>::Instance();
emulator->Run(ebootPath, gameArgs, overrideRoot);

Emulator Core Architecture

The core emulation logic resides in src/emulator.h and src/emulator.cpp, where the Emulator class owns and coordinates all subsystems. This architecture separates concerns into distinct managers for memory, modules, threading, and platform abstraction.

Emulator State and Main Loop

The Emulator class maintains the runtime state and drives the main execution loop. It instantiates and manages the core subsystems including the loader, memory manager, GPU interface, and input handler. The main loop processes CPU emulation while coordinating with the Vulkan renderer for graphics submission.

Module Loading and ELF Parsing

The module system in src/core/module.h and src/core/module.cpp handles parsing of PS4 ELF files (including SPRX modules). It maps binaries into the emulated address space, resolves symbols using the AeroLib NID table, and manages Thread-Local Storage (TLS) indices and relocations.

// Example of manual module loading
u32 maxTlsIdx = 0;
Core::Module my_mod(memory, "/path/to/module.sprx", maxTlsIdx);

// Resolve exported function via NID
using EntryFn = int(*)(int);
auto fn_ptr = reinterpret_cast<EntryFn>(my_mod.FindByName("SomeExportedFunction"));
int result = fn_ptr(42);

Memory Management

The virtual address space implementation lives in src/core/memory.h and src/core/memory.cpp. The MemoryManager class provides MapMemory functionality, protection flag handling, and page-table management to mirror the PS4's memory architecture.

Threading and TLS

Thread abstraction resides in src/core/thread.h and src/core/thread.cpp, providing thin wrappers around host threads that expose the PS4 kernel API (threadCreate, threadJoin, etc.). Thread-Local Storage support is implemented in src/core/tls.h and src/core/tls.cpp to satisfy the PS4 ABI requirements.

Signal Handling and Platform Abstraction

POSIX-style signal handling for kernel-layer operations (such as SIGSEGV for illegal memory accesses) is implemented in src/core/signals.h and src/core/signals.cpp. Platform detection and OS-specific backend selection occur in src/core/platform.h, which configures Vulkan, SDL, and other host-specific implementations.

GPU and Video Core (Vulkan Implementation)

The graphics subsystem in src/video_core/ implements the PS4's GCN-style pipeline using Vulkan. This layer separates renderer orchestration, resource management, and shader compilation.

Vulkan Renderer Pipeline

The high-level renderer implementation in src/video_core/renderer_vulkan/ manages command submission, swap-chain handling, and per-frame synchronization. Key components include:

// Example draw submission flow
auto* renderer = emulator->GetRenderer();   // Returns Core::RendererVulkan*
renderer->BeginFrame();
renderer->ClearRenderTarget(0, {0.1f, 0.1f, 0.1f, 1.0f});
renderer->EndFrame();   // Presents the swapchain

Resource Management

The resource pool system in src/video_core/renderer_vulkan/vk_resource_pool.cpp manages Vulkan buffers, images, descriptor sets, and a master semaphore for cross-queue work synchronization.

Pipeline Handling and Caching

Graphics and compute pipeline creation, state caching, and serialization for fast reloads are handled in:

Shader Compilation

The AeroLib HLE shader compiler (based on Yuzu's Hades) resides in src/shader_recompiler/. It translates PS4 shader binaries into Vulkan SPIR-V, with entry points in recompiler.cpp and recompiler.h.

Texture and Buffer Caches

PS4-specific memory features including multi-level page tables, tiling, and on-the-fly format conversion are implemented in:

  • src/video_core/texture_cache/
  • src/video_core/buffer_cache/

Host Shaders and Debugging

Compute shaders for texture detiling, color conversion, and FidelityFX Super Resolution (FSR) are located in src/video_core/host_shaders/ (.comp and .frag files). RenderDoc integration for frame capture debugging is implemented in src/video_core/renderdoc.cpp.

Input Handling and UI Layer

The input abstraction layer in src/input/ provides unified controller, mouse, and keyboard support. Key files include src/input/controller.cpp and src/input/input_handler.cpp, which expose a consistent API to both the core emulation and the UI.

The ImGui integration layer in src/imgui/ renders the configuration interface used by the QtLauncher front-end. The main interface definitions reside in src/imgui/imgui_layer.h.

// Example controller mapping configuration
auto* km = Core::KeyManager::GetInstance();
km->SetKey("L1", Core::KeyCode::Keyboard_W);
km->SaveToFile();  // Persists to <UserDir>/keys.toml

Build System and Auxiliary Tooling

The project uses CMake as its primary build system, configured through the top-level CMakeLists.txt. Platform-specific detection scripts reside in cmake/, including FindxxHash.cmake and FindRenderDoc.cmake for locating optional dependencies.

The build system configures Vulkan, SDL3, and optional third-party libraries based on the host platform detected in src/core/platform.h.

Python utilities in scripts/ automate development tasks, notably scripts/ps4_names2stubs.py, which generates syscall stubs from the ps4_names.txt database. For reproducible Linux builds, the repository includes a shell.nix expression.

Summary

  • ShadPS4 separates concerns into distinct layers: system emulation, GPU/video pipeline, input/UI, and build tooling.
  • The entry point in src/main.cpp orchestrates initialization using CLI11, while src/emulator.cpp manages the runtime state.
  • Core emulation logic resides in src/core/, handling ELF loading, memory management, threading, TLS, and platform abstraction.
  • The Vulkan-based graphics pipeline in src/video_core/ includes the renderer, resource pools, shader recompiler (AeroLib), and texture/buffer caches.
  • Input abstraction and ImGui UI layers bridge the core emulation with user interaction.
  • CMake drives the build system, with Python scripts automating syscall stub generation.

Frequently Asked Questions

What programming language is ShadPS4 written in?

ShadPS4 is implemented primarily in C++ as a native systems project. The codebase leverages modern C++ features for performance-critical emulation tasks while maintaining cross-platform compatibility across Windows, Linux, and macOS.

How does ShadPS4 handle PS4 graphics rendering?

The emulator implements the PS4's GCN-style graphics pipeline using Vulkan through the src/video_core/ directory. It includes a custom shader recompiler (AeroLib) that translates PS4 shader binaries to SPIR-V, along with texture and buffer caches that handle the console's specific memory tiling and format requirements.

Where is the main entry point for the emulator?

The application entry point resides in src/main.cpp, which creates the EmulatorState singleton, parses command-line arguments using CLI11, and invokes Core::Emulator::Run. This file serves as the orchestration layer that initializes all subsystems before handing control to the core emulation loop.

Can the graphics backend be replaced without modifying core emulation logic?

Yes, the modular architecture in src/video_core/ abstracts the graphics implementation from the core emulation. The renderer interface in src/video_core/renderer_vulkan/ could theoretically be swapped for a DirectX 12 or Metal backend by implementing the same resource management and pipeline interfaces, without touching the ELF loader or memory management code in src/core/.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →