Nes-emulator - A NES emulator made to learn the Rust programming language

Overview

nes-emulator

Building

$ rustc --version
rustc 1.32.0 (9fda7c223 2019-01-16)
$ cargo --version
cargo 1.32.0 (8610973aa 2019-01-02)

$ cargo build --release
$ cargo run --release --bin nes-emulator

The emulator loads a ROM in iNES format located at the hardcoded path roms/mario.nes.

On Windows, you may need to statically-link SDL by enabling the appropriate feature:

$ cargo run --release --bin nes-emulator --features 'sdl2/bundled'

Inputs

The emulator has been tested with an Xbox 360 controller, but should work with any controller the SDL library recognizes.

Additionally, these keyboard keys control the emulator:

  • Escape: Exits the emulator
  • Pause: (Developer use) Breaks a command-line debugger
  • F5: Saves a savestate
  • F6: Loads the most recent savestate
  • F7: Restart the current ROM and playback a video of recorded inputs
  • F8: Set video recording start point
  • Tab: Toggles "turbo mode", which removes the 60 FPS limit.
Comments
  • Getting things working on Windows

    Getting things working on Windows

    Hey there,

    So, I can't 100% get this running (https://github.com/Rust-SDL2/rust-sdl2/issues/865), but I wanted to show you a diff that I think will get things working:

    diff --git a/src/headless.rs b/src/headless.rs
    index dbe25e0..73f831a 100644
    --- a/src/headless.rs
    +++ b/src/headless.rs
    @@ -14,7 +14,6 @@ use std::io::Read;
     use std::io::Write;
     use std::fs::File;
     use std::fmt::Debug;
    -use std::os::unix::io::FromRawFd;
    
     use crate::joystick::Joystick;
     use crate::mapper::AddressSpace;
    @@ -27,8 +26,8 @@ use crate::common::Clocked;
    
     fn main() {
         // Standard stdout() object is line-buffered
    -    let stdin = unsafe { File::from_raw_fd(0) };
    -    let stdout = unsafe { File::from_raw_fd(1) };
    +    let stdin = std::io::stdin();
    +    let stdout = std::io::stdout();
         let mut headless = Headless::new(
             Box::new(stdin),
             Box::new(stdout),
    

    In general, using the standard library here helps with portability. Of course, it's your project, and so feel free to ignore/close this issue!

    opened by steveklabnik 4
  • fix mapper number detection

    fix mapper number detection

    per header https://wiki.nesdev.com/w/index.php/INES , calculation should shift header 7 nibble and then add header 6 nibble. An example is the Zelda rom, it uses mapper 1, but the code as written detects it as mapper 16 because it is adding 0 to 1 and shifting the result by 4, instead of shifting 0 by 4 and adding it to 1.

    opened by donbright 2
  • Dereferencing Headless::joystick1 is UB

    Dereferencing Headless::joystick1 is UB

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/headless.rs#L117

    https://doc.rust-lang.org/reference/behavior-considered-undefined.html : Dereferencing a null or dangling raw pointer.

    Headless::joystick1/2 are initialized with:

    impl Headless {
        fn command_load_rom(&mut self) {
            let mut record_tas = self.read_byte();
            let filename = self.read_length_string();
            let mut joystick1 = Box::new(Joystick::new());
            let mut joystick2 = Box::new(Joystick::new());
            self.joystick1 = &mut *joystick1;
            self.joystick2 = &mut *joystick2;
            ...
            // drop joystick1 joystick2
            // Headless::joystick1/2 are dangling pointers since joystick1 joystick2 are freed
        }
    
    opened by kpp 2
  • Error on nightly Rust

    Error on nightly Rust

    Building with nightly instead of stable produces:

    error[E0597]: `texture_creator` does not live long enough
       --> src\main.rs:96:32
        |
    96  |     let mut texture = Box::new(texture_creator.create_texture(
        |                                ^^^^^^^^^^^^^^^ borrowed value does not live long enough
    ...
    142 |         texture: &mut *texture,
        |                  ------------- cast requires that `texture_creator` is borrowed for `'static`
    ...
    179 | }
        | - `texture_creator` dropped here while still borrowed
    
    

    I am not sure why this is an error in nightly but not in stable...

    Anyway, what it's complaining about is this: as main ends, texture_creator will be freed, and then GLOBAL_STATE will be holding invalid memory; any destructors that run after texture_creator is freed could access that invalid memory.

    Ideally, GLOBAL_STATE would use lazy_static, I think. Not 100% sure how much contortion that would take.

    opened by steveklabnik 2
  • Why not use buffered stdout instead of File::from_raw_fd(1)?

    Why not use buffered stdout instead of File::from_raw_fd(1)?

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/headless.rs#L30

    What's wrong with line-buffered stdout?

    opened by kpp 1
  • UB while loading Vec<bool>

    UB while loading Vec

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/serialization.rs#L144

    impl<T: Savable> Savable for Vec<T> {
    ...
        fn load(&mut self, fh: &mut Read) {
            let mut len = 0usize;
            len.load(fh);
            self.truncate(0);
            self.reserve(len);
            for i in 0..len {
                let mut x:T = unsafe { std::mem::uninitialized() };
                x.load(fh);
                self.push(x);
            }
    }
    

    In case of Vec<bool> we got:

    let mut x:bool = unsafe { std::mem::uninitialized() };
    

    Which is UB by definition: https://doc.rust-lang.org/reference/behavior-considered-undefined.html

    See comment https://github.com/rust-lang/rust/issues/53491#issuecomment-456775716

    opened by kpp 1
  • Transmuting self to mut self is UB

    Transmuting self to mut self is UB

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/joystick.rs#L49

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/ppu.rs#L493

    https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/joystick.rs#L43 https://github.com/MichaelBurge/nes-emulator/blob/0b9e321832360b93ed6fcd9d54bb3c3f11eca00a/src/joystick.rs#L49

    opened by kpp 1
NES emulator written in Rust to learn Rust

OxideNES A NES emulator in Rust. CPU should be accurate, PPU is mostly accurate, timing between the 2 is off for some corner cases and hardware qui

null 37 Nov 7, 2022
An NES emulator written in Rust

Pinky Pinky is an NES emulator written in Rust completely from scratch based only on publicly available documentation. You can run it in your Web brow

Koute 709 Dec 23, 2022
NES emulator written in Rust

sprocketnes is an emulator for the Nintendo Entertainment System written in the Rust programming language. Its purpose is to serve as a technology dem

Patrick Walton 725 Dec 27, 2022
NES emulator in rust

NES emulator in Rust plastic is a NES emulator built from scratch using Rust. This is a personal project for fun and to experience emulating hardware

Amjad Alsharafi 27 Dec 15, 2022
a work-in-progress NES emulator written in rust.

sayaka-rs a work-in-progress NES emulator, written in Rust. the project image is an edit of a frame from the Mahou Shoujo Madoka Magica manga. the Mik

Lumine 1 Jan 16, 2022
A NES emulator written in Rust, with a focus on expandability and accuracy

A NES emulator written in Rust, with a focus on expandability and accuracy

Benjamin Mordaunt 4 Sep 19, 2022
A simple NES emulator implemented in Rust. (WIP)

remu A ?? ?? BLAZINGLY FAST* ?? ?? NES emulator implemented in Rust. Status: Work in progress. About This emulator is mainly meant to be more of a lea

luna 10 Aug 25, 2022
đŸ¥” MOS-6502 and NES emulator in Rust (SDL/WebAssembly)

?? Potatis /mos6502 - Generic CPU emulator. Passes all tests, including illegal ops. (No BCD mode). /nes - A very incomplete NES emulator. /nes-sdl -

Henrik Persson 28 Jan 9, 2023
A **BLAZINGLY FAST** rust emulator for the NES.

rust-nes A BLAZINGLY FAST rust emulator for the NES. Install / Usage Clone the repository and navigate to it git clone https://github.com/imagine-huss

null 7 Jan 20, 2023
RustBoyAdvance-NG is a Nintendoâ„¢ Game Boy Advance emulator and debugger, written in the rust programming language.

RustBoyAdvance-NG Nintendo GameBoy Advance â„¢ emulator and debugger, written in rust. WebAssembly Demo: https://michelhe.github.io/rustboyadvance-ng/ P

MishMish 510 Dec 30, 2022
Another Chip8 Emulator(ACE) made using Rust

ACE(Another Chip8 Emulator) ACE(Another Chip8 Emulator) This is a chip8 emulator created using Rust programming Language. It's purpose is to learn Rus

Sakura 4 Nov 12, 2021
Chip8 emulator written in pure rust, using rust-sdl2 for graphics

Rust-8 chip8 emulator written in rust, using rust-sdl2 for graphics. Features Fully implemented all 35 original chip8 opcodes. This emulator does NOT

Chris Hinson 7 Dec 28, 2022
Commodore 64 emulator written in Rust

Rust64 - a C64 emulator written in Rust This is my attempt to study the Rust programming language and have fun at the same time. The goal is to presen

Krzysztof Kondrak 214 Dec 27, 2022
A Flash Player emulator written in Rust

website | demo | nightly builds | wiki Ruffle Ruffle is an Adobe Flash Player emulator written in the Rust programming language. Ruffle targets both t

Ruffle 11.2k Jan 8, 2023
A Game Boy research project and emulator written in Rust

Mooneye GB Mooneye GB is a Game Boy research project and emulator written in Rust. The main goals of this project are accuracy and documentation. Some

Joonas Javanainen 802 Dec 28, 2022
A Gameboy Emulator in Rust

RBoy A Gameboy Color Emulator written in Rust Implemented CPU All instructions correct All timings correct Double speed mode GPU Normal mode Color mod

Mathijs van de Nes 512 Dec 23, 2022
RGB (Rust Game Boy) is a simple emulator for the original game boy

RGB RGB (Rust Game Boy) is a simple emulator for the original game boy and the color game boy. Warning: This no longer compiles in the latest versions

Niven Achenjang 18 Dec 2, 2022
Full featured Cross-platform GameBoy emulator by Rust. Forever boys!.

Gameboy Full featured Cross-platform GameBoy emulator. Forever boys!. You can start a game with the following command, here with a built-in game "Boxe

Mohanson 1.2k Jan 2, 2023
ZX Spectrum emulator written in Rust

rustzx ZX Spectrum emulator which I writing in rust. I develop this project just for fun and for learning the basics of computer architecture. License

Vladislav Nikonov 162 Dec 27, 2022