nes_rs is a work-in-progress NES emulator written in Rust, created as a learning project with support for save states, rewind, audio recording, and multiple mappers.
nes_rs running FROM BELOW |
nes_rs in rewind mode |
This project was created to learn Rust and better understand how emulators work.
It is still a work in progress, and compatibility is not guaranteed. Some games may not run correctly or may exhibit bugs.
The emulator can be built and run on Linux, macOS, and Windows.
cargo run --release --bin nes_rs -- ./path/to/rom.nesYou can download and play free ROMs such as from-below.
- Rewind gameplay in real time
- Input recording and replay
- Debug views (tiles, sprites, palettes, nametables)
- Modular architecture (core + frontend)
- High CPU accuracy (based on AccuracyCoin tests)
If you have SDL2 installed, you can simply build using Cargo:
cargo build --releaseYou can install SDL2 using your package manager, e.g.,
pacman -S sdl2If you don't have SDL2 installed, you can compile it as part of the emulator:
cargo build --release --features bundled-sdl2If you encounter an error like Compatibility with CMake < 3.5 has been removed from CMake. then you will have to downgrade your CMake version or install/compile SDL2 manually.
This error originates from the SDL2 crate, not from the emulator itself.
nes_rs --help
A NES emulator
Usage: nes_rs [OPTIONS] <ROM_PATH>
Arguments:
<ROM_PATH> path to the ROM
Options:
--export-wav whether to record the in game audio. The recording is written to "./<rom_name>.wav"
--scaling <SCALING> the scaling factor [default: 6]
--palette-path <PALETTE_PATH> provide a path to a custom palette
--enable-integer-scaling enables integer scaling
-h, --help Print help
nes_rs ./from_below.nes --palette-path ./contrast.palette --enable-integer-scaling --scaling 2You can generate a custom palette using https://bisqwit.iki.fi/utils/nespalette.php
Default key bindings are shown below.
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
The emulator passes most CPU-related tests from AccuracyCoin, indicating high CPU accuracy (see image below for detailed results).
Test results of AccuracyCoin
- Creating and loading save states
- Rewinding time
- Audio playback and recording
- Custom palettes
- Fast-forward
- Take screenshots
- Record and replay input
- Show a tile grid overlay
- Show an FPS counter
- Show the contents of the character RAM
- Show all nametables
- Show the contents of the OAM memory
- Show the current palette
Supported Mappers:
- NROM (id: 0)
- MMC1 (id: 1)
- CNROM (id: 3)
nes_rs/ ← workspace root
├── Cargo.toml
├── nes_rs_core/ ← the emulator itself
│ ├── Cargo.toml
│ └── src/...
└── nes_rs/ ← the emulator front end
├── Cargo.toml
└── src/...
The emulator core is completely independent of the front end and any graphics crates such as sdl2. This separation allows the core to be reused independently, making it easier to build alternative frontends (e.g., native, web, or mobile).
- PPU: switch from scanline to pixel rendering
- Add more mappers
- Add no_std support
- Multiple save states + selection UI
- Visual indicators (pause, fast-forward, state load)
- Video recording
- Cheat support (possibly via public database)
- Android version
- Publish on crates.io
- AUR package
Name: omelette_font
Created By Bananattack - https://github.com/Bananattack/omelette_font
Licence: https://github.com/Bananattack/omelette_font/blob/master/asset_license.md
Since this is my first emulator the initial architecture was inspired by https://bugzmanov.github.io/nes_ebook/chapter_1.html. However, the current version is far more complex and feature-rich, having among others a more accurate CPU and PPU, audio, more mappers, and save states.
MIT

