Zexe is a modern project designed to turn ZX Spectrum snapshots into standalone, self-contained executable files for Windows and Linux. It allows you to package your favorite ZX Spectrum games into a single binary that includes both the emulator and the game data, making them as easy to run as any other native application.
The project consists of two main tools:
- zexe-runner: A specialized, lightweight ZX Spectrum emulator built in Rust using rustzx-core. It is optimized for performance, low-latency audio, and features a clean OpenGL-based renderer.
- zexe-bundler: A packaging utility that attaches a ZX Spectrum snapshot and configuration metadata to the runner, creating the final standalone executable.
- Portable: Generates a single file with no external dependencies required.
- Multi-Platform: Native support for both Windows and Linux.
- Snapshot Format Support: Handles
.sna,.z80, and.szxsnapshot formats. - Spectrum 48K/128K Support: Automatic selection of 48K or 128K modes based on the input snapshot.
- High-Quality Rendering: Uses OpenGL (via
glow) for smooth scaling, with support for built-in filtering (Nearest, Linear, Scanlines). - RetroArch Shader Support: Support for external and embedded RetroArch-compatible
.glslshaders for advanced post-processing. - Joystick Mapping: Support for Kempston, Sinclair, and Cursor joysticks mapped to the cursor keys.
- OSD (On-Screen Display): Semi-transparent overlay for volume control and status information.
- Rust (latest stable version recommended)
- A C compiler (for some dependencies)
- Development headers for OpenGL and ALSA (on Linux)
You can use the provided batch script to build both components and package them into the dist folder:
build_dist.batOr manually:
cd zexe-runner
cargo build --release
cd ../zexe-bundler
cargo build --releaseYou can use the provided shell script:
chmod +x build_dist.sh
./build_dist.shOr manually:
cd zexe-runner && cargo build --release
cd ../zexe-bundler && cargo build --releaseNote: The Linux script will attempt to use upx to compress the resulting binaries if it is installed.
To create a standalone game, you need the zexe-bundler and zexe-runner binaries (found in the dist folder after building).
Run the bundler with your game snapshot. The bundler will also automatically look for .glsl, .pok, and .json files with the same name as the input if you don't provide them explicitly.
Windows:
.\dist\zexe-bundler.exe my_game.z80This will generate my_game.exe.
Linux:
./dist/zexe-bundler my_game.z80This will generate my_game.
Customizing the Output: If you want to specify a different output name:
.\dist\zexe-bundler.exe my_game.z80 --output different_name.exeCustomizing the Runner:
By default, the bundler looks for zexe-runner (or zexe-runner.exe) in the current working directory. If it is located elsewhere, use the --runner flag:
./zexe-bundler game.z80 --runner ./path/to/zexe-runnerWith optional components:
./dist/zexe-bundler game.z80 --output game.exe --shader crt.glsl --pokes cheats.pok --config custom.jsonOnce running the executable, the following hotkeys are available:
- ESC: Exit the application.
- F1: Show version info on OSD.
- F2: Cycle filtering modes (Nearest, Linear, Scanlines, Shaders).
- F3: Cycle joystick modes (Kempston, Sinclair 1/2, Cursor, Off).
- F4: Cycle border modes (Full, Minimal, None).
- F5: Toggle Fullscreen.
- F6: Toggle POKEs (cheats) if a
.pokfile is loaded. - F7 / F8: Decrease / Increase volume.
- F9: Toggle Mute.
- F10: Toggle between 1x speed and Full Speed (Warpspeed).
When a joystick mode is active (F3), the Arrow Keys and Alt Left are automatically mapped to the corresponding ZX Spectrum inputs:
- Kempston: Arrow keys + Alt Left (Fire).
- Sinclair 1 / 2: Arrow keys + Alt Left (Fire).
- Cursor: Arrow keys + Alt Left (Fire / Key 0).
Note: You can still use the standard numeric keys (1-0) for Sinclair joysticks if you prefer, as they are part of the standard keyboard mapping.
Zexe supports custom OpenGL shaders for post-processing. To ensure compatibility, shaders should follow the RetroArch (.glsl) standard format.
- Internal: Use the
--shaderflag withzexe-bundlerto embed a.glslfile. - External/Fallback: The runner will look for shaders in the following order:
- An embedded shader in the executable.
- A file with the same name as the executable (e.g.,
my_game.glsl). - A file named
shader.glslin the same directory as the executable.
You can include POKEs to cheat in games.
- Internal: Use the
--pokesflag withzexe-bundlerto embed a.pokfile. - External/Fallback: The runner will look for a
.pokfile with the same name as your executable (e.g.,my_game.pok) in the same directory.
A config.json can be embedded using the --config flag or placed in the same directory as a fallback.
- Order of preference: Embedded configuration >
my_game.json>config.json. - Available settings:
fullscreen: true/falsefiltering: "Nearest", "Linear", "Scanlines", "Embedded", "Custom"joystick: "Kempston", "Sinclair1", "Sinclair2", "Cursor", "Off"border: "Full", "Minimal", "None"cheats_enabled: true/falsevolume: 0-200 (100 is default)
This project is licensed under the GPLv3 License - see the LICENSE file for details.