* [Perf] Gate event-flag tracing so it allocates nothing when disabled TraceEventFlag built its interpolated argument (and, on the wait path, FormatFrameChain + a new StringBuilder(256) in FormatGuestWaitObject plus ~12 guest-memory reads) on every call, then checked the env var inside the method — so every sceKernelSetEventFlag/Clear/Poll/Wait paid a string allocation and an Environment.GetEnvironmentVariable P/Invoke even with tracing off. Cache the flag once in a static readonly bool and gate every call site, matching the semaphore/event-queue pattern. Behavior is unchanged when SHARPEMU_LOG_EVENT_FLAG=1. * [Perf] Hoist IsNoBlockLeaf classification to import-stub setup The leaf-dispatch path called IsNoBlockLeafImport(nid) — a ~30-literal string pattern match — on every leaf import. IsLeaf/NidHash were already precomputed on ImportStubEntry at stub setup; add IsNoBlockLeaf alongside them and read the field in the hot path. Behavior unchanged. * [Perf] Cache trace env-var flags read on hot paths Two SHARPEMU_LOG_* env vars were read via Environment.GetEnvironmentVariable (a P/Invoke + transient string) on hot paths: SHARPEMU_LOG_FIBER on every fiber context transfer, and SHARPEMU_LOG_DIRECT_MEMORY on every direct-memory op (~8 sites). Cache both once — _logFiber alongside the other backend _log* flags, and _traceDirectMemory behind the existing ShouldTraceDirectMemory helper. Behavior unchanged. * [Perf] Avoid per-iteration thread snapshot in the idle pump loop PumpUntilGuestThreadsIdle allocated a full GuestThreadState[] snapshot (via LINQ Values.ToArray()) on every spin just to tally three run-state booleans. Tally them under the lock with an allocation-free helper, and only materialize the snapshot inside the gated (default-off) diagnostic dump. SnapshotGuestThreads now uses Values.CopyTo instead of LINQ. Behavior unchanged. * [Perf] De-LINQ GetPixelColorExportMask on the per-draw path GetPixelColorExportMask ran a Select/OfType/Where/Aggregate chain over all shader instructions, allocating iterators + closures, and is called per render target (twice per draw via CreateRenderState and HasPixelColorExport). Replace with a manual scan producing the identical mask — no allocation, and it removes an authored-LINQ use the repo bans. * [Perf] De-LINQ per-draw render-target selection in AgcExports The bound-render-target selection used Where(...).OrderBy(...).ToArray() (plus a second Where/ToArray fallback) on every translated draw, allocating LINQ iterators + closures. Replace with an explicit filter into a pre-sized list + List.Sort by slot; slots are distinct so this matches the stable OrderBy. Same result, no per-draw LINQ allocations. * [Perf] De-LINQ per-draw render-target validation in the Vulkan presenter SubmitOffscreenTranslatedDraw validated its render targets with targets.Any(...) twice plus targets.Select(a=>a.Address).Distinct().Count() (a per-draw HashSet), and broadcast a single blend with Enumerable.Repeat(...).ToArray(). Targets are <= 8, so replace with manual scans (invalid-target check; combined dimension-mismatch + pairwise aliasing check) and Array.Fill. Same results, no per-draw LINQ allocations. * [Perf] Binary-search VirtualQuery region lookup (SortedList) _mappedRegions was an unordered Dictionary, so TryFindVirtualQueryRegionLocked scanned every region for containment/next — O(n) per sceKernelVirtualQuery and O(n^2) when an allocator walks the address space with the findNext flag. Store regions in a SortedList keyed by base address (every write already uses the region's own address as the key) and find the containing/next region with a binary search over the sorted keys. Also drops a now-redundant Values.OrderBy. Non-overlapping regions assumed (mmap semantics), so only the floor region can contain the query. Behavior-preserving; worth spot-checking VirtualQuery-heavy titles. * [Perf] Remove stray CLI packages.lock.json committed by mistake git add -A in an earlier commit swept in a regenerated src/SharpEmu.CLI/packages.lock.json. main tracks no lock files (central package management, no RestorePackagesWithLockFile), and REUSE.toml no longer covers packages.lock.json, so the committed file failed the REUSE Compliance check. Remove it.
SharpEmu
An experimental PlayStation 5 emulator for Windows, Linux and macOS.
Join our Discord for development updates, compatibility discussions, support, and community chat.
Note
SharpEmu supports Windows x64, Linux x64, and macOS x64. Apple Silicon Macs can run the macOS x64 build through Rosetta 2.
Warning
SharpEmu is an experimental PS5 emulator developed from scratch in C#. The current focus is on accuracy and infrastructure setup rather than game-specific compatibility.
Info
SharpEmu is an emulator project currently in its early stages of development.
This project is developed purely for research and educational purposes. There are no commercial goals associated with it. We enjoy learning about system architecture and reverse engineering.
SharpEmu focuses exclusively on the PlayStation 5.
Our goal is not to emulate PS4 games, as there is already an excellent emulator dedicated to that platform: ShadPS4.
Status
The emulator can currently load the eboot.bin of real games, execute native CPU instructions, and partially handle kernel-related functionality. However, several critical components are still missing.
Current capabilities include:
- Loading
eboot.binand.elffiles - Executing native CPU instructions
- Reading basic game metadata (title, version, etc.)
- Loading system modules (
prx/sys_module) - Partial support for some kernel functions
FiberandAMPRexports- PlayGo scenarios
- Initial loading game files
- Shader/resource submits and AGC initial
- Video outputs in some games
Some games have reached like sceVideoOut and AGC stages.
SharpEmu supports Windows, Linux, and macOS hosts. Video output uses Vulkan on Windows and Linux, and MoltenVK on macOS. Platform support is still experimental, so compatibility and performance vary by game, operating system, and GPU driver.
Using
Download the release archive for your operating system, extract it, and launch
SharpEmu with the path to a legally obtained game's eboot.bin.
Windows PowerShell:
.\SharpEmu.exe "C:\path\to\game\eboot.bin" 2>&1 |
Tee-Object -FilePath "SharpEmu.log"
Linux and macOS:
chmod +x ./SharpEmu
./SharpEmu "/path/to/game/eboot.bin" 2>&1 |
tee SharpEmu.log
A Vulkan-capable GPU and current graphics driver are required. The macOS release includes the MoltenVK Vulkan implementation.
Games Tested
-
Demon's Souls Remake
- Demon's Souls [PPSA01341]
- Demon's Souls is now video loop. Shaders are ready to be converted to SPIR-V/Vulkan. We are continuing our work on this.

-
Poppy Playtime Chapter 1
-
SILENT HILL: The Short Message
-
Dreaming Sarah
- Dreaming Sarah [PPSA02929]
- Real texture rendering for this game;

Important
This project does not support or condone piracy.
All games used during development and testing are dumped from consoles that we personally own.
Users are expected to use legally obtained copies of their games.
Build
- Install the .NET SDK version specified in
global.json. - Clone the repository:
git clone https://github.com/sharpemu/sharpemu.git - Open the solution file (
SharpEmu.slnx) in VSCode. - Build the project:
dotnet buildordotnet publish - Build artifacts will be located in the
artifactsdirectory.
Disclaimer
SharpEmu is an experimental emulator intended for research and educational purposes.
This project does not contain any copyrighted system firmware, game data, or proprietary PlayStation assets.
Special Thanks
The following projects were extremely helpful during development:
-
ShadPS4
Helped with understanding the basic architecture of the PlayStation 4. -
Kyty
One of the few PS5 emulator projects available and very useful for studying native code execution. -
Ryujinx
Provided valuable references for filesystem handling and low-level C# implementation patterns.
License
Contributing
Before opening an issue or pull request, please read our contribution guidelines:
The guide covers:
- Coding style and formatting
- AI-assisted contributions
- Pull request expectations
- Testing guidelines
- Legal and reverse engineering policy
