• Stars
    star
    396
  • Rank 108,801 (Top 3 %)
  • Language
    C++
  • License
    MIT License
  • Created about 7 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Another NES Emulator - written for fun & learning - first implementation of wideNES

ANESE Logo

Build Status GitHub Actions Build Status Windows Build Status macOS/Linux

ANESE (Another NES Emulator) is a Nintendo Entertainment System Emulator written for fun and learning.

Accuracy and performance are long-term goals, but the primary focus is getting popular titles up and running. There are still a lot of bugs, but many games are working quite well already.

ANESE is cross-platform, and is regularly tested on macOS, Windows, and Linux.

ANESE core uses clean and interesting C++11, emphasizing readability, maintainability, and approachability. It is well commented, providing in-line sources and insights for much of the implementation. It is also dependency free (aside from stdlib), making it easy to embed in other projects.

WideNES

wideNES is a novel technique that can automatically "map-out" levels and worlds in NES games. Check out the wideNES Readme for details.

A GIF is worth a 1000 words:

wideNES on Metroid

Pretty cool huh? Here's another one:

wideNES on SMB1

Downloads

Official releases of ANESE can be found on the Releases tab on GitHub.

Alternatively, for the most up-to-date version of ANESE, nightly builds are available. These are compiled directly from the latest ANESE commit, so there may/will be bugs.

Windows: You can download builds of ANESE from AppVeyor's build artifacts page.

macOS: Travis uploads ANESE.app bundles to this GDrive folder.

Building

Dependencies

ANESE's emulation core (src/nes) doesn't have any major dependencies, but the UI does use a couple. Most of these dependencies are bundled with ANESE (see: /thirdparty), although some require additional installation:

  • SDL2 (video/audio/controls)
    • Linux: apt-get install libsdl2-dev (on Ubuntu)
    • MacOS: brew install SDL2
    • Windows:
      • Download dev libs from here and unzip them somewhere.
      • EITHER: Set the SDL environment variable to point to the dev libs
      • OR: Unzip them to C:\sdl2\ (Where I put them)
      • OR: Modify the SDL2_MORE_INCLUDE_DIR variable in CMakeLists.txt to point to the SDL2 dev libs

Generating + Compiling

ANESE builds with CMake

On macOS / Linux

# in ANESE root
mkdir build
cd build
cmake ..
make

make install # on macOS: creates ANESE.app in ANESE/bin/

On Windows:

mkdir build
cd build
cmake ..
msbuild anese.sln /p:Configuration=Release

Running

ANESE opens to a directory-browser, from which ROMs can be launched.

ANESE can run from the shell using anese [rom.nes] syntax. Certain features are only accessible from the command-line at the moment (e.g: movie recording / playback, PPU timing hacks). For a full list of switches, run anese -h

Windows Users: make sure the executable can find SDL2.dll! Download the runtime DLLs from the SDL website, and plop them in the same directory as anese.exe

Mappers

Most popular Mappers are implemented:

# Name Some Games
000 NROM Super Mario Bros. 1, Donkey Kong, Duck Hunt
001 MMC1 Legend of Zelda, Dr. Mario, Metroid
002 UxROM Megaman, Contra, Castlevania
003 CNROM Arkanoid, Cybernoid, Solomon's Key
004 MMC3 Super Mario Bros 2 & 3, Kirby's Adventure
007 AxROM Marble Madness, Battletoads
009 MMC2 Punch Out!!

Feel free to open a PR for any mappers you implement :)

Controls

Currently hard-coded to the following:

Button Key Controller
A Z X
B X A
Start Enter Start
Select Right Shift Select
Up Up arrow D-Pad
Down Down arrow D-Pad
Left Left arrow D-Pad
Right Right arrow D-Pad

Any xbox-compatible controller should work.

There are also a couple of emulator actions:

Action Key Controller
Pause / Open Menu Esc Left Thumbstick Button
Reset Ctrl - R
Power Cycle Ctrl - P
Toggle CPU logging Ctrl - C
Speed +25% Ctrl - =
Speed -25% Ctrl - -
Fast-Forward Space Right Thumbstick Button
Make Save-State Ctrl - (1-4)
Load Save-State Ctrl - Shift - (1-4)

(there are 4 save-state slots)

DISCLAIMERS

  • ANESE is not the best emulator out there, far from it! Expect bugs!
  • My APU uses a naive sampling algorithm with a basic lookup table grafted from the nesdev wiki. The blargg-apu branch has an older version of ANESE that uses Blargg's awesome nes_snd_emu library for the APU, and while my integration was a bit unstable at times, it did sound a lot better when it did work.
  • The CPU is instruction-cycle accurate, but not sub-instruction cycle accurate. While this inaccuracy doesn't affect most games, there are some that that rely on sub-instruction level timings (eg: Solomon's Key).
    • The --alt-nmi-timing flag might fix some of these games.

TODO

These are features that will add major value to ANESE:

  • Implement: Cycle accurate CPU (will probably fix many bugs)
  • Implement: Better menu (not just fs, also config)
  • CMake: more robust macOS bundles (good way to get SDL2.0 packaged?)
  • Implement: LibRetro Core
  • Implement: Get the Light-gun working
  • Debugging: Add debug GUI
    • All objects implementing the Memory interface must also implement peek, i.e: a const read. As such, a debugger could easily inspect any/all memory locations with no side effects!

Here's a couple that have been crossed off already:

  • Implement: My own APU (don't use Blarrg's)
  • Refactor: Modularize main.cc - push everything into src/ui/
    • Refactor: Split gui.cc into more files!
  • Refactor: Push common mapper behavior to Base Mapper (eg: bank chunking)

And here are some ongoing low-priority goals:

  • Refactor: Roll-my-own Sound_Queue (SDL_QueueAudio?)
  • Cleanup: Unify naming conventions (either camelCase or snake_case)
  • Cleanup: Comment the codebase even more
  • Security: Actually bounds-check files lol
  • Cleanup: Conform to the .fm2 movie format better
  • Cleanup: Remove fatal asserts (?)
  • Cleanup: Switch to a better logging system (*cough* not fprintf *cough*)

Roadmap

Key Milestones

  • Parse iNES files
  • Create Cartridges (iNES + Mapper interface)
  • CPU
    • Set Up Memory Map
    • Hardware Structures (registers)
    • Core Loop / Basic Functionality
      • Read / Write RAM
      • Addressing Modes
      • Fetch - Decode - Execute
    • Official Opcodes Implemented
    • Handle Interrupts
  • PPU
    • Set Up Basic Rendering Context (SDL)
    • Implement Registers + Memory Map them
    • Implement DMA
    • Generate NMI -> CPU
    • Core rendering loop
      • Background Rendering
      • Sprite Rendering - currently not hardware accurate
      • Proper Background / Foreground blending
    • Sprite Zero Hit
    • Misc PPU flags (emphasize RGB, Greyscale, etc...)
  • APU
    • Implement Registers + Memory Map them
    • Frame Timer IRQ - kinda
    • Set Up Basic Sound Output Context (SDL)
    • Channels
      • Pulse 1
      • Pulse 2
      • Triangle
      • Noise
      • DMC
    • DMC DMA
  • Joypads
    • Basic Controller
    • Zapper - still needs work
    • NES Four Score

Secondary Milestones

  • Loading Files with picker
  • Reset / Power-cycle
  • Fast Forward
  • Run / Pause
  • Saving
    • Battery Backed RAM - Saves to .sav
    • Save-states
      • Dump to file
  • Config File
    • Preserve ROM path
    • Window size
    • Controls
  • Running NESTEST (behind a flag)
  • Controller support - currently very basic
  • A SDL GUI
    • SDL-based ROM picker
    • Options menu

Tertiary Milestones (Fun Features!)

  • Zipped ROM support
  • Rewind
  • Game Genie
  • Movie recording and playback
  • More ROM formats (not just iNES)
  • Proper PAL handling?
  • Proper NTSC artifacting?
  • Multiple Front-ends
    • SDL Standalone
    • LibRetro
  • Debugger!
    • CPU
      • Step through instructions
    • PPU Views
      • Static Palette
      • Palette Memory
      • Pattern Tables
      • Nametables
      • OAM memory

Accuracy & Compatibility

  • More Mappers! Always more mappers!
  • Add automatic testing
    • Screenshots: compare power-on with 30 seconds of button mashing
    • Test ROMs: Parse debug outputs
  • CPU
    • Implement Unofficial Opcodes
    • Pass More Tests
    • (Stretch) Switch to sub-instruction level cycle-based emulation (vs instruction level)
  • PPU
    • Make the sprite rendering pipeline more accurate (fetch-timings)
    • Pass More Tests
    • Make value in PPU <-> CPU bus decay?

Attributions

  • A big shout-out to LaiNES and fogleman/nes, two solid NES emulators that I referenced while implementing some particularly tricky parts of the PPU). While I actively avoided looking at the source codes of other NES emulators while writing my initial implementations of the CPU and PPU, I did sneak a peek at how others solved some problems once I got stuck.
  • These awesome libraries are used throughout ANESE's UI and in WideNES:

More Repositories

1

gdbstub

An ergonomic, featureful, and easy-to-integrate implementation of the GDB Remote Serial Protocol in Rust (with no-compromises #![no_std] support)
Rust
286
star
2

clicky

A clickwheel iPod emulator (WIP)
Rust
159
star
3

surface-dial-linux

A Linux userspace controller for the Microsoft Surface Dial. Requires Linux Kernel 4.19 or higher.
Rust
71
star
4

ts7200

A high-level emulator for the TS-7200 Single Board Computer, as used in CS 452 - Real-Time Programming at the University of Waterloo
Rust
30
star
5

inlinable-dyn-extension-traits

An exploration into the various ways optional trait methods can be implemented in Rust.
Rust
29
star
6

spotify-car-thing-bt

code to connect + communicate with a Spotify Car Thing
Rust
27
star
7

armv4t_emu

An emulator for the ARMv4t instruction set written in Rust
Rust
25
star
8

libc_alloc

A simple global allocator for Rust which hooks into `libc`. Useful in `no_std` contexts.
Rust
21
star
9

compressed-emoji-shortcodes

A Quest to Find a Highly Compressed Emoji :shortcode: Lookup Function
Rust
16
star
10

analog_literals

Multi-Dimensional Analog Literals in Rust
Rust
15
star
11

osxhidtouch

User-space HID multitouch touchscreen driver for Mac OS X (Adapted for XPS 15 9560 from kyewei/osxhidtouch)
Objective-C
14
star
12

uwmips

A simulator for the UW MIPS instruction set, with a time-traveling debugger
Rust
10
star
13

AC8E

A Chip8 emulator written in Rust for fun and learning
Rust
9
star
14

mips241

A emulator and disassembler for the version of MIPS used in CS 241
C++
8
star
15

fusion-kbd-controller-rs

Control the RGB Fusion Keyboard of the Gigabyte AERO 15X
Rust
7
star
16

dicesiege

DiceWars for the JavaScript century
4
star
17

1212

1212! is a game inspired by 1010! where you place pieces, make lines, score points, and last as long as you can.
JavaScript
3
star
18

gdb-optional-step-bug

GDB client doesn't respect optional single-step support on certain target architectures
Rust
3
star
19

antigravity

https://xkcd.com/353/
Rust
3
star
20

vrai-tracer

Following along with "Ray Tracing in One Weekend" in Rust.
Rust
2
star
21

bconsole

A better console for node.js
JavaScript
2
star
22

wide-libretro

A "shim" around existing libretro cores that adds faux-widescreen support to retro games
Rust
2
star
23

embcrusted

A z-machine interpreter for running Infocom-era text adventure games on embedded hardware.
Rust
2
star
24

blog

If I write something interesting, it will probably be published over here!
HTML
1
star
25

rl-inventory-prices

Calculate trading value for each item in a player's Rocket League inventory
Rust
1
star
26

clap-shell-completions

A hand-rolled `clap_complete`, with support for dynamic completions driven by callbacks
Rust
1
star