Fixed
- Linux/macOS build failure -
std::chrono::clock_castis a C++23 feature unavailable in clang + libstdc++ on Ubuntu 22.04 / macOS 14; all Linux (clang, gcc, AoT, AppImage) and macOS builds were failing; replaced with portabletime_point_castarithmetic inSaveStateManager.cpp. (#1219) - clang
[[nodiscard]]placement error inLynxMemoryManager-[[nodiscard]]placed after__forceinlinewas parsed by clang as an attribute on the return type rather than on the function, causing all Linux/clang CI jobs to fail with'nodiscard' attribute cannot be applied to types; moved[[nodiscard]]before__forceinline. (#1220) - Accuracy test CI always failing -
accuracy-tests.ymlbuilds the fullNexen.slnincludingUI.csprojwhich referencesPansy.Core; the pansy repo was never cloned in CI causingCS0246on every run; added pansy checkout to bothsmoke-testsandaccuracy-testsjobs. (#1219) - C++ tests CI missing pansy checkout - Same pansy reference issue affected
tests.yml; added checkout there as well. (#1219) - Accuracy tests running on every push - Removed
push/pull_requesttriggers fromaccuracy-tests.yml; workflow now only runs onworkflow_dispatchand the nightly schedule. (#1219) - Avalonia 12 menu icon loading crash -
ImageUtilitiesthrew an unhandledArgumentExceptionon Avalonia 12 when SVG assets failed to decode; hardened the icon load path with SVG -> PNG fallback and a non-throwing empty-image fallback to prevent UI-thread crashes. (#1212) - ReactiveUI Avalonia runtime initialization - Startup crash regression introduced when
UseReactiveUI()was removed during Avalonia 12 migration; restored correctReactiveUI.Avaloniaruntime initialization. (#1205) - Avalonia SVG image loading pipeline - Avalonia 12 changed the SVG loading API; replaced the old load path with the
Svg.Controls.Skia.Avaloniapipeline so SVG assets render correctly without PNG fallback masking. (#1214)
Performance
- CDL recording page cache - ~75-80% CDL overhead reduction - Eliminated all virtual calls from the
RecordReadhot path. Every memory read previously triggered 2 virtual calls + a switch per read (~10-15 ns x 3-4M reads/sec). Replaced with a flat 4 KB page cache mapping CPU-space addresses directly to absolute ROM offsets;RebuildPageCachekeeps the cache coherent for consoles with dynamic mapping. (#1207) - Avalonia rendering pipeline lock reduction - Consolidated
DrawOperationbitmap locks from 3 to 2 per frame; loweredDispatcherPriorityfromMaxValuetoRender. (#1207) - SNES memory handler devirtualization - Every SNES CPU memory access (~3.58M/sec) went through virtual dispatch; for the common case (
RamHandler/RomHandler) this resolved to a trivial array access. Added direct-access pointer fields (_directReadPtr,_directWritePtr,_directMask) toIMemoryHandlersoSnesMemoryManagerbypasses virtual dispatch with an inline array access for the dominant code paths. (#1208) - NES VS Dual per-frame 240 KB allocation eliminated -
NesPpu::SendFrameVsDualSystem()was allocating 240 KB on every frame; moved to lazy member allocation. (#1208) - NES internal RAM fast path - NES CPU reads to internal RAM (~30% of all CPU reads) now bypass virtual dispatch; combined with the mapper fast path, ~90% of all NES CPU memory accesses are devirtualized. (#1209)
- Atari 2600
std::functionelimination - Replacedstd::functionread/write bus callbacks with a directAtari2600Bus*pointer, eliminating type-erasure overhead on every CPU memory access. (#1209) - Multi-system memory dispatch optimization - Targeted SMS, Game Boy, PCE, Genesis, and Lynx with cached
CheatManager*pointers,[[likely]]/[[unlikely]]branch annotations, and a Lynx fast-path/slow-path split (inline header fast path for direct RAM,.cppslow path for overlay dispatch). (#1211) - ChannelF callback removal - Finalized removal of callback-based dispatch in the ChannelF CPU/memory-manager path. (#1215)
- WonderSwan flash dirty-state caching - Added dirty-flag caching to the WonderSwan flash save-state path to avoid unnecessary I/O on unmodified flash banks. (#1215)
- GBA/NES hotpath benchmarks - branch hints discarded - Real emulator-path microbenchmarks for GBA
ProcessDma,ProcessInternalCycle(0%/5%/50% pending-update distributions), and NESBaseMapper::ReadVram; measured and discarded[[likely]]/[[unlikely]]annotations that caused a +14.7% regression. (#1217, #1218) - Repeatable benchmark script - Added
~scripts/run-memory-hotpath-benchmarks.ps1for consistent hotpath perf audits with labeled, timestamped JSON output. (#1218)
Downloads
Windows
| Build | Download | Notes |
|---|---|---|
| Standard | Nexen-Windows-x64-v1.4.25.exe | Single-file, recommended |
| Native AOT | Nexen-Windows-x64-AoT-v1.4.25.exe | Faster startup |
Linux
| Build | Download | Notes |
|---|---|---|
| AppImage x64 | Nexen-Linux-x64-v1.4.25.AppImage | Recommended |
| AppImage ARM64 | Nexen-Linux-ARM64-v1.4.25.AppImage | Raspberry Pi, etc. |
| Binary x64 (clang) | Nexen-Linux-x64-v1.4.25.tar.gz | Tarball, requires SDL2 |
| Binary x64 (gcc) | Nexen-Linux-x64-gcc-v1.4.25.tar.gz | Tarball, requires SDL2 |
| Binary ARM64 (clang) | Nexen-Linux-ARM64-v1.4.25.tar.gz | Tarball, requires SDL2 |
| Binary ARM64 (gcc) | Nexen-Linux-ARM64-gcc-v1.4.25.tar.gz | Tarball, requires SDL2 |
| Native AOT x64 | Nexen-Linux-x64-AoT-v1.4.25.tar.gz | Faster startup |
macOS (Apple Silicon)
| Build | Download | Notes |
|---|---|---|
| Standard | Nexen-macOS-ARM64-v1.4.25.zip | App bundle |
| Temporarily unavailable | .NET 10 ILC compiler bug |
Notes:
- Linux requires SDL2 (
sudo apt install libsdl2-2.0-0)- macOS: Right-click -> Open on first launch to bypass Gatekeeper