Crate tetanes

Source
Expand description

§TetaNES

Build Status Doc Status Latest Version Downloads License

📖 Summary - ✨ Features - 🌆 Screenshots - 🚀 Getting Started - 🛠️ Roadmap - ⚠️ Known Issues - 💬 Contact

§Summary

TetaNES

photo credit for background: Zsolt Palatinus on unsplash

TetaNES is a cross-platform emulator for the Nintendo Entertainment System (NES) released in Japan in 1983 and North America in 1986, written in Rust using wgpu. It runs on Linux, macOS, Windows, and in a web browser with Web Assembly.

It started as a personal curiosity that turned into a passion project. It is still being actively developed with new features and improvements constantly being added. It is a fairly accurate emulator that can play most NES titles.

TetaNES is also meant to showcase using Rust’s performance, memory safety, and fearless concurrency features in a large project. Features used in this project include complex enums, traits, generics, matching, iterators, channels, and threads.

Try it out in your browser!

§Features

  • Runs on Linux, macOS, Windows, and Web.
  • Standalone emulation core in tetanes-core.
  • NTSC, PAL and Dendy emulation.
  • Headless Mode when using tetanes-core.
  • Pixellate and NTSC filters.
  • CRT shader for that retro feel.
  • Up to 4 players with gamepad support.
  • Zapper (Light Gun) support using the mouse.
  • iNES and NES 2.0 ROM header formats supported.
  • Over 30 supported mappers covering >90% of licensed games.
  • Game Genie Codes.
  • PPU Debugger
  • Runtime performance stats
  • Preference snd keybonding menus using egui.
    • Increase/Decrease speed & Fast Forward
    • Visual & Instant Rewind
    • Save & Load States
    • Battery-backed RAM saves
    • Screenshots
    • Gameplay recording and playback
    • Audio recording

§Screenshots

Donkey Kong  Super Mario Bros. The Legend of Zelda  Metroid

§TetaNES Core

TetaNES is split into two crates. This is the primary crate, which provides the cross-platform emulator UI binary. tetanes-core is the emulation library that emulator developers can use to develop custom emulator applications with. tetanes-core is aimed to have stronger stability guarantees, but it’s still not 1.0 yet and there are several large features on the roadmap that may result in breaking changes.

§Stability

Preferences and save file formats are fairly stable at this point, but since TetaNES is not yet 1.0 and there are several large features on the roadmap that may result in breaking changes which may result in being unable to restore your preferences or save files.

Once some of these larger features are completed, and 1.0 is released, more effort will be dedicatged to versioning these files for backward compatibility in the event of future breaking changes.

§Getting Started

TetaNES runs on all major operating systems (Linux, macOS, Windows, and the web).

§Install

There are multiple options for installation, depending on your operating system, preference and existing tooling.

§Linux
§Ubuntu/Debian

A .deb package is provided under Assets on the latest Release. Once downloaded, you can install it and the required dependencies. e.g.

sudo apt install ./tetanes-0.10.0-1-amd64.deb
§Other Distros

An AppImage is provided under Assets on the latest Release. Simply download it and put it wherever you want.

A .tar.gz package is also provided under Assets on the latest Release. You can place the tetanes binary anywhere in your PATH.

The following dependencies are required to be installed:

  • ALSA Shared Library
  • GTK3

e.g.

apt install libasound2 libgtk-3-0

dnf install alsa-lib gtk3

pacman -Sy alsa-lib gtk3

§MacOS
§App Bundle

The easiest is to download the correct app bundle for your processor. The .dmg downloads can be found under the Assets section of the latest Release.

§Homebrew

TetaNES can also be installed through Homebrew.

brew install lukexor/formulae/tetanes
§Windows

A windows installer is provided under Assets on the latest Release. Note: You will need the latest “Microsoft Visual C++ 2015 - 2022 Redistributable” installed, otherwise you’ll get an error about vcruntime140.dll not being found.

§Cargo Install

You can also build and install with cargo which comes with rustup.

cargo install tetanes

This will install the latest released version of the TetaNES binary to your cargo bin directory located at either $HOME/.cargo/bin/ on a Unix-like platform or %USERPROFILE%\.cargo\bin on Windows.

Alternatively, if you have cargo binstall installed:

cargo binstall tetanes

This will try to find the target binary for your platform from the latest Release or install from source, similar to above.

§Web

You can also play directly in your web browser without installing by visiting https://lukeworks.tech/tetanes-web.

§Usage

Usage: tetanes [OPTIONS] [PATH]

Arguments:
  [PATH]  The NES ROM to load or a directory containing `.nes` ROM files.
  [default: current directory]

Options:
      --rewind                     Enable rewinding
  -s, --silent                     Silence audio
  -f, --fullscreen                 Start fullscreen
  -4, --four-player <FOUR_PLAYER>  Set four player adapter. [default: 'disabled']
                                   [possible values: disabled, four-score, satellite]
  -z, --zapper                     Enable zapper gun
      --no-threaded                Disable multi-threaded
  -m, --ram-state <RAM_STATE>      Choose power-up RAM state. [default: "all-zeros"]
                                   [possible values: all-zeros, all-ones, random]
  -w, --emulate-ppu-warmup         Whether to emulate PPU warmup where writes to
                                   certain registers are ignored. Can result in
                                   some games not working correctly
  -r, --region <REGION>            Choose default NES region. [default: "ntsc"]
                                   [possible values: ntsc, pal, dendy]
  -i, --save-slot <SAVE_SLOT>      Save slot. [default: 1]
      --no-load                    Don't load save state on start
      --no-save                    Don't auto save state or save on exit
  -x, --speed <SPEED>              Emulation speed. [default: 1.0]
  -g, --genie-code <GENIE_CODE>    Add Game Genie Code(s). e.g. `AATOZE`
                                   (Start Super Mario Bros. with 9 lives)
      --config <CONFIG>            Custom Config path
  -c, --clean                      "Default Config" (skip user config and previous
                                   save states)
  -d, --debug                      Start with debugger open
  -h, --help                       Print help
  -V, --version                    Print version

iNES and NES 2.0 formatted ROMS are supported, though some advanced NES 2.0 features may not be implemented.

§Supported Mappers

Support for the following mappers is currently implemented or in development:

#NameExample Games# of Games1% of Games1
000NROMBomberman, Donkey Kong, Super Mario Bros.~247~10%
001SxROM/MMC1B/CMetroid, Legend of Zelda, Tetris~680~28%
002UxROMCastlevania, Contra, Mega Man~270~11%
003CNROMArkanoid, Paperboy, Pipe Dream~155~6%
004TxROM/MMC3/MMC6Kirby’s Adventure, Super Mario Bros. 2/3~599~24%
005ExROM/MMC5Castlevania 3, Laser Invasion~24<0.01%
007AxROMBattletoads, Marble Madness~75~3%
009PxROM/MMC2Punch Out!!1<0.01%
010FxROM/MMC4Fire Emblem Gaiden3<0.01%
011Color DreamsCrystal Mines, Metal Fighter15~1%
016Bandai FCGDragon Ball: Daimaou Fukkatsu14~1%
018Jaleco SS 88006Magic John15~1%
019Namco163Battle Fleet, Dragon Ninja20~1%
024VRC6aAkumajou Densetsu1<0.01%
026VRC6bMadara, Esper Dream 22<0.01%
034BNROM/NINA-001Deadly Towers, Impossible Mission II3<0.01%
066GxROM/MxROMSuper Mario Bros. + Duck Hunt~17<0.01%
069Sunsoft/FME-7Batman: Return of the Joker, Gimmick!~15<0.01%
071Camerica/CodemastersFirehawk, Bee 52, MiG 29 - Soviet Fighter~15<0.01%
076DxROM/Namco 108Megami Tensei: Digital Devil Story1<0.01%
079NINA-003/006Black Jack, Double Strike16<0.01%
088DxROM/Namco 108Quinty, Dragon Spirit - Aratanaru Densetsu3<0.01%
095DxROM/Namco 108Dragon Buster1<0.01%
113NINA-003/006HES 6-in-1, Total Funpak~3<0.01%
146NINA-003/006Galactic Crusader1<0.01%
153Bandai FCGFamicom Jump II: Saikyou no 7-nin1<0.01%
154DxROM/Namco 108Devil Man1<0.01%
157Bandai FCG/DatachSD Gundam Wars7<0.01%
155SxROM/MMC1ATatakae!! Ramen Man: Sakuretsu Choujin2<0.01%
159Bandai FCGDragon Ball Z: Kyoushuu! Saiya-jin4<0.01%
206DxROM/Namco 108Fantasy Zone, Gauntlet45~2%
210Namco175/340Dream Master, Family Circuit ’914<0.01%
~2256 / 2447~92.2%
  1. Source Mirror

§Controls

Keybindings can be customized in the keybindings menu. Below are the defaults.

NES joypad:

ButtonKeyboard (Player 1)Controller
AZEast
BXSouth
A (Turbo)ANorth
B (Turbo)SWest
SelectQSelect
StartWStart
D-PadArrow KeysD-Pad

Controller Layout:

SDL-compatible mappings are used: https://github.com/mdqinc/SDL_GameControllerDB?tab=readme-ov-file but can be overriden by setting SDL_GAMECONTROLLERCONFIG.

           Left Triggers                        Right Triggers
              _=====_                               _=====_
             / _____ \                             / _____ \
           +.-'_____'-.---------------------------.-'     '-.+
          /   |     |  '.                       .'            \
         / ___| /|\ |___ \                     /      (N)      \
        / |      |      | ;    _         _    ;                 ;  Action Pad
 D-Pad  | | <---   ---> | |  <:_|       |_:>  |  (W)       (E)  |  (South, East,
        | |___   |   ___| ;  Select    Start  ;                 ;   North, West)
        |\    | \|/ |    /  _              _   \      (S)      /|
        | \   |_____|  .','" "',        ,'" "', '.           .' |
        |  '-.______.-' / Left  \------/ Right \  '-._____.-'   |
        |              /\ Stick /      \ Stick /\               |
        |             /  '.___.'        '.___.'  \              |
        |            /                            \             |
         \          /                              \           /
          \________/                                \_________/

Emulator shortcuts:

ActionKeyboardController
PauseEscapeGuide Button
About TetaNESF1
Preferences MenuCtrl-P or F2
Load/Open ROMCtrl-O or F3
QuitCtrl-Q
ResetCtrl-R
Power CycleCtrl-H
Increase Speed by 25%=Right Shoulder
Decrease Speed by 25%-Left Shoulder
Increase Emulation ScaleShift-=
Decrease Emulation ScaleShift–
Increase UI ScaleCtrl-=
Decrease UI ScaleCtrl–
Fast-Forward 2xSpace (Hold)
Set Save State Slot (1-4)Ctrl-(1-4)
Save StateCtrl-S
Load StateCtrl-L
Instant RewindR (Tap)
Visual RewindR (Hold)
Take ScreenshotF10
Toggle Gameplay RecordingShift-V
Toggle Audio RecordingShift-R
Toggle AudioCtrl-M
Toggle Pulse Channel 1Shift-1
Toggle Pulse Channel 2Shift-2
Toggle Triangle ChannelShift-3
Toggle Noise ChannelShift-4
Toggle DMC ChannelShift-5
Toggle Mapper ChannelShift-6
Toggle FullscreenCtrl-Enter
Toggle NTSC FilterCtrl-N
Toggle CRT ShaderCtrl-T
Toggle CPU DebuggerShift-D
Toggle PPU DebuggerShift-P
Toggle APU DebuggerShift-A

While the CPU Debugger is open:

ActionKeyboard
Step a single CPU instructionC
Step over a functionO
Step out of a functionShift-O
Step a single scanlineShift-L
Step an entire frameShift-F

While the PPU Debugger is open:

ActionKeyboard
Move debug scanline up by 1Ctrl-Up
Move debug scanline up by 10Ctrl-Shift-Up
Move debug scanline down by 1Ctrl-Down
Move debug scanline down by 10Ctrl-Shift-Down

Other mappings can be found and modified in the Config -> Keybinds menu.

§Directories

TetaNES saves files to disk to support a number of features and, depending on the file type, varies based on operating system.

§Preferences
  • Linux: $HOME/.config
  • macOS: $HOME/Library/Application Support
  • Windows: %LOCALAPPDATA%\tetanes
  • Web: localStorage (e.g. config/config.json)
§Screenshots
  • Linux, macOS, & Windows: $HOME/Pictures
  • Web: Does not currently support saving screenshots.
§Replay Recordings
  • Linux, macOS, & Windows: $HOME/Documents
  • Web: Does not currently support saving recordings.
§Audio Recordings
  • Linux, macOS, & Windows: $HOME/Music
  • Web: Does not currently support saving recordings.
§Battery-backed RAM, save states, and logs
  • Linux: $HOME/.local/share/tetanes
  • macOS: $HOME/Library/Application Support/tetanes
  • Windows: %LOCALAPPDATA%\tetanes
  • Web: localStorage (e.g. data/save/AO Demo/slot-1.sav)

§Powerup State

The original NES hardware had semi-random contents located in RAM upon power-up and several games made use of this to seed their Random Number Generators (RNGs). By default, TetaNES honors the original hardware and emulates randomized powerup RAM state. This shows up in several games such as Final Fantasy, River City Ransom, and Impossible Mission II, amongst others. Not emulating this would make these games seem deterministic when they weren’t intended to be.

If you would like TetaNES to provide fully deterministic emulated power-up state, you’ll need to change the RAM State setting in the configuration menu and trigger a power-cycle or use the -m/--ram_state flag from the command line.

§Building/Running

To build/run TetaNES, you’ll need a nightly version of the compiler and run cargo build or cargo build --release (if you want better framerates).

To run the web version, you’ll also need the wasm32-unknown-unknown target and trunk installed:

rustup target add wasm32-unknown-unknown
trunk serve --release

Unit and integration tests can be run with cargo test. There are also several test roms that can be run to test various capabilities of the emulator. They are all located in the tetanes-core/tests_roms/ directory.

Run them in a similar way you would run a game. e.g.

cargo run --release tetanes-core/test_roms/cpu/nestest.nes
§Feature Flags
  • profiling - Enables puffin profiling.
  • webgpu - Enables the BrowserWebGpu backend for TetaNES Web. The default is to use WebGl2 until WebGPU is stable across all platforms and browsers. Currently pending Firefox and Chrome on Linux (See: https://caniuse.com/webgpu).

§Troubleshooting

If you get an error running a ROM that’s using the supported Mapper list above, it could be a corrupted or incompatible ROM format. If you’re unsure which games use which mappers, see http://bootgod.dyndns.org:7777/. Trying other versions of the same game from different sources sometimes resolves the issue.

If you get some other error when trying to start a game that previously worked, try removing any configurations or save states from the Directories listed above to ensure it’s not an incompatible savestate file causing the issue.

If you encounter any shortcuts not working, ensure your operating system does not have a binding for it that is overriding it. macOS specifically has many things bound to Ctrl-*.

If an an issue is not already created, please use the github issue tracker to create it.

§Roadmap

See ROADMAP.md.

§Known Issues

See the github issue tracker.

§Documentation

In addition to the wealth of information in the docs/ directory, I also referenced these websites extensively during development:

§License

TetaNES is licensed under a MIT or Apache-2.0 license. See the LICENSE-MIT or LICENSE-APACHE file in the root for a copy.

§Contribution

While this is primarily a personal project, I welcome any contributions or suggestions. Feel free to submit a pull request if you want to help out!

§Contact

For issue reporting, please use the github issue tracker. You can also contact me directly at https://lukeworks.tech/contact/.

§Credits

Implementation was inspiried by several amazing NES projects, without which I would not have been able to understand or digest all the information on the NES wiki.

I also couldn’t have gotten this far without the amazing people over on the NES Dev Forums:

Also, a huge shout out to OneLoneCoder for his NES and olcPixelGameEngine series as those helped a ton in some recent refactorings.

Modules§

error
logging
nes
User Interface representing the the NES Control Deck
platform
sys
thread

Macros§

feature
Checks if the current platform supports a given feature.