6 releases
Uses new Rust 2024
| new 0.1.5 | Mar 1, 2026 |
|---|---|
| 0.1.4 | Mar 1, 2026 |
| 0.1.3 | Feb 28, 2026 |
#26 in Emulators
Used in 3 crates
285KB
6.5K
SLoC
monsoon-core
Core NES emulation library — cycle-accurate MOS 6502 CPU, 2C02 PPU, memory subsystem, ROM parsing, and save states.
This is the primary crate for anyone wanting to embed NES emulation in their own project. It is part of the Monsoon Emulator project.
Public API Modules
emulation::nes— The top-levelNesstruct that orchestrates all emulation. Provides methods to load ROMs, step individual cycles or full frames, save/load state, read the pixel buffer, and access CPU/PPU debug information.emulation::rom— ROM file parsing for iNES, NES 2.0, and archaic iNES formats. IncludesRomFilefor loading ROMs from bytes andRomBuilderfor programmatic construction.emulation::savestate— Serializable emulator state snapshots. Save states can be encoded in binary (postcard) or JSON format.emulation::screen_renderer— TheScreenRenderertrait for implementing custom pixel renderers, plusNoneRenderer(a no-op fallback) and thedeclare_renderers!macro for registering renderers.emulation::palette_util— NES color palette types (RgbColor,RgbPalette) and.palfile parsing.emulation::ppu_util— PPU constants (output dimensions, tile counts) and debug data types (EmulatorFetchable,TileData,PaletteData,NametableData).util— Serialization helpers (ToBytes) and hashing utilities (Hashable).
Internal implementation modules (cpu, ppu, mem, opcode) are pub(crate) and not accessible to downstream consumers.
Quick Start
use monsoon_core::emulation::nes::Nes;
use monsoon_core::emulation::rom::RomFile;
fn main() {
let mut nes = Nes::default();
// Load a ROM from raw bytes
let rom_data = std::fs::read("game.nes").unwrap();
let rom = RomFile::load(&rom_data, Some("game.nes".to_string())).unwrap();
nes.load_rom(&rom);
// Power on and run a single frame
nes.power();
nes.step_frame().expect("emulation error");
// Get the rendered frame as a buffer of palette indices
let pixels = nes.get_pixel_buffer();
println!("Frame rendered: {} pixels", pixels.len());
}
Pixel Buffer Format
Nes::get_pixel_buffer() returns a Vec<u16> of palette indices, not RGB values. Each 16-bit entry encodes:
- Bits 0–5: NES color index (0–63)
- Bits 6–8: Emphasis bits from the PPU mask register
Use a ScreenRenderer implementation (e.g., LookupPaletteRenderer from the monsoon-default-renderers crate) to convert these indices to RGB colors.
Save States
use monsoon_core::emulation::nes::Nes;
use monsoon_core::emulation::savestate::try_load_state_from_bytes;
use monsoon_core::util::ToBytes;
let mut nes = Nes::default();
// Save state
if let Some(state) = nes.save_state() {
// Binary format (compact)
let bytes = state.to_bytes(None);
std::fs::write("save.state", &bytes).unwrap();
// JSON format (human-readable)
let json_bytes = state.to_bytes(Some("json".to_string()));
std::fs::write("save.json", &json_bytes).unwrap();
}
// Load state
let data = std::fs::read("save.state").unwrap();
if let Some(state) = try_load_state_from_bytes(&data) {
nes.load_state(state);
}
License
This project is licensed under the Apache-2.0 License.
Dependencies
~1.4–2.5MB
~56K SLoC