NES emulator in rust

Overview

plastic

NES emulator in Rust

Build status codecov dependency status license

plastic is a NES emulator built from scratch using Rust.

This is a personal project for fun and to experience emulating hardware and connecting them together.

Building and installation

Pre-built

There are pre-built binaries in the releases tab, Plastic comes in different UIs, some work in Windows and Linux and some are for one of them, check Interfaces for more details.

Building

If you want to experience the latest development version, you can build Plastic yourself. You would need Rust itself and any UI dependency for the UI you want to use if needed. For example:

Recommended UI for linux is GTK:

cargo run --release -p nes_ui_gtk

Recommended UI for windows is Native_Windows:

cargo run --release -p nes_ui_native_windows

Note: --release should be used as running the emulator in debug mode would slow it down very much that it would make games unplayable.

Components

  • 6502 CPU, all official and unofficial instructions with accurate timing (without BCD mode).
  • Picture Processing Unit, almost accurate with some small timing issues that would not effect most games.
  • Cartridge and INES file handling (still missing INES2.0)
  • Mappers:
    • Mapper 0
    • Mapper 1
    • Mapper 2
    • Mapper 3
    • Mapper 4
    • Mapper 5 (Milestone)
    • Mapper 6
    • Mapper 7
    • Mapper 8
    • Mapper 9
    • Mapper 10
    • Mapper 11
    • Mapper 66
  • Audio Processing Unit:
    • 2 Pulse wave(square)
    • Triangle
    • Noise
    • DMC
    • IRQ support
  • Controller: controllable using the keyboard and controller (tested with PS4 controller)

Interfaces

One advantage of this emulator is the great abstraction, for example, adding UI handlers for the emulator is very easy and straight forward. All you have to do is to write a UiProvider, and simply use it with NES like so:

use plastic_core::nes::NES;

// Provider implement trait `UiProvider`
let mut nes = NES::new("path/to/rom.nes", Provider {})?;

nes.run();

For now all UI providers can reset the game through <CTRL-R>

Using this design, I have implemented some providers which have different purposes:

SFML

SFML is a game development UI library, it has a good and easy to use API and is the most performing UI in the list.

Advantages
  1. Designed for Canvas and raw drawing, which makes it faster.
  2. Has support for gamepad (only tested with PS4).

GTK

GTK is a casual GUI library that is used to make all kinds of applications and not designed for games.

The reason I chose to go with it is for future plans to add a debugger, which would be a lot easier to add in this UI compared to SFML.

From the screenshot, it looks exactly like SFML, and that's because I haven't added anything specific to GTK yet. But it has almost the same performance as SFML, so hopefully there will not be much different in performance even after adding the debugger.

Advantages
  1. Ability to add buttons and menus which enable easier integration for debuggers and anything similar.
  2. Ability to open a NES file through the menu or by dragging the .NES file into the app.
  3. Can run without specifying a ROM from the command line.
  4. Ability to pause and resume emulation through <ESC> key and from the menues.
Disadvantages
  1. Does not offer gamepad support, but it can be added through other external libraries.

Native Windows GUI

Has the same UI and usages as the GTK version, but is targetted for windows as GTK require additional libraries to work for windows.

Advantages (in addition to GTK)
  1. Run on the native windows APIs, which is fast and does not need any additional libraries.
Disadvantages
  1. Does not offer gamepad support, but it can be added through other external libraries.

TUI

TUI demo

This is just for fun, but it is actually working way better than I expected. Check the demo.

I used gilrs for gamepad support and its working very nicely, keyboard on the other hand is not very responsive, so it is advised to use gamepad. Also since this uses one character for each pixel, it is advised to use the smallest font size your terminal emulator supports. Have fun.

Controls

In all the UI providers I followed the same controlling scheme, as well as the ability to reset through <CTRL-R>:

Keyboard

keyboard nes controller
J B
K A
U Select
I Start
W Up
S Down
A Left
D Right

Gamepad

gamepad (PS4) nes controller
X B
O A
Select Select
Start Start
Button Up Up
Button Down Down
Button Left Left
Button Right Right

For now its static, and there is no way to change it except for doing it in the code, TODO later.

License

This project is under MIT license.

NES is a product and/or trademark of Nintendo Co., Ltd. Nintendo Co., Ltd. and is not affiliated in any way with Plastic or its author

References

Most of the documentation for NES components can be found in the NES dev wiki

For the CPU(6502), this has the instruction set, and I used Klaus2m5's tests for testing the CPU alone without the other NES components.

You might also like...
Commodore 64 emulator written in Rust
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

A Flash Player emulator written in Rust
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

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

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

RGB (Rust Game Boy) is a simple emulator for the original game boy
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

Full featured Cross-platform GameBoy emulator by Rust. Forever boys!.
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

RustBoyAdvance-NG is a Nintendo™ Game Boy Advance emulator and debugger, written in the rust programming language.
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

ZX Spectrum emulator written in Rust
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

Intel 8080 cpu emulator by Rust
Intel 8080 cpu emulator by Rust

i8080 i8080 is a emulator for Intel 8080 cpu. 8080 Programmers Manual 8080 opcodes [dependencies] i8080 = { git = "https://github.com/mohanson/i8080"

Comments
  • Bump thread_local from 1.0.1 to 1.1.4

    Bump thread_local from 1.0.1 to 1.1.4

    Bumps thread_local from 1.0.1 to 1.1.4.

    Commits
    • 4a54e57 Bump version to 1.1.4
    • ebf8b45 Merge pull request #34 from ibraheemdev/patch-1
    • 3d69afa Fix memory ordering in RawIter::next
    • c7d8dcd Bump version to 1.1.3
    • 5e8bbf2 Merge pull request #30 from Marwes/fix_drop
    • a44b836 fix: Drop the value in the ThreadLocal on drop
    • 322cf34 Bump version to 1.1.2
    • dca4007 Merge pull request #29 from Kestrer/raw-iter
    • 33ad405 Add #[inline] to non-generic functions
    • 810c043 Implement iterator logic in RawIter
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump smallvec from 1.5.1 to 1.8.0

    Bump smallvec from 1.5.1 to 1.8.0

    Bumps smallvec from 1.5.1 to 1.8.0.

    Release notes

    Sourced from smallvec's releases.

    v1.8.0

    • Add optional support for the arbitrary crate (#275).

    v1.7.0

    • new_const and from_const constructors for creating a SmallVec in const contexts. Requires Rust 1.51 and the optional const_new feature. (#265)

    v1.6.1

    • Fix a possible buffer overflow in insert_many (#252, #254).

    v1.6.0

    • The "union" feature is now compatible with stable Rust 1.49 (#248, #247).
    • Fixed warnings when compiling with Rust 1.51 nightly (#242, #246).
    Commits
    • 0a4fdff Version 1.8.0
    • 6d0dea5 Auto merge of #275 - as-com:arbitrary-support, r=mbrubeck
    • 9bcd950 Add support for arbitrary
    • 7cbb3b1 Auto merge of #271 - saethlin:drain-aliasing-test, r=jdm
    • 0fced9d Test for drains that shift the tail, when inline
    • 218e0bb Merge pull request #270 from servo/github-actions
    • 52c50af Replace TravisCI with Github Actions.
    • 5ae217a Include the cost of shifts in insert/remove benchmarks (#268)
    • 58edc0e Version 1.7.0
    • 1e4b151 Added feature const_new which enables SmallVec::new_const() (#265)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
Releases(v0.2.2)
Owner
Amjad Alsharafi
Pogramming and Security enthusiast
Amjad Alsharafi
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
Learn emulator and programming languages, target chip8, nes, gbc, gba ...

[WIP]learn emulator go-chip8 go run main.go source https://en.wikipedia.org/wiki/CHIP-8 http://devernay.free.fr/hacks/chip8/C8TECH10.HTM https://githu

早晨海风 4 Apr 30, 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