I received my first gaming system, a Nintendo Entertainment System, on Christmas Day, 1991. I firmly believe that my vague memories of unboxing it and connecting it to our large tube television in the basemnet are real and not imagined, but no one in the family seems to remember, so I'll just assume my memories are real. My sister got a Sega Genesis a few years later, and playing games on those two systems make up the bulk of my early gaming memories (besides DOS games).
So in 2014 when my friend suggested we rip the guts out of an old NES system and put a Raspberry Pi in it, loaded with all sorts of emulators, I didn't hesitate to begin ordering the necessary parts!
|NES Console & 2 Original NES Controllers||1||$30.00||$30.00|
|[NES Controller RetroUSB Chip](http://www.retrousb.com/)||2||$18.00||$36.00|
|Mausberry Circuits Shutdown Switch||1||$12.99||$12.99|
|Plugable 7 Port High Speed USB 2.0 Hub with 3A Power Adapter||1||$17.95||$17.95|
|TrendNet Bluetooth Adapter||1||$10.99||$10.99|
|Raspberry PI with WIFI Adapter, Case, Power Supply, Cables||1||$62.95||$62.95|
|32 GB SD Card||1||$14.99||$14.99|
|Panel Mount HDMI Cable Jack||1||$5.95||$5.95|
|Panel Mount 2.1 mm DC Barrel Jack Plug||1||$2.95||$2.95|
|Panel Mount Ethernet Extension Cable||1||$4.95||$4.95|
|Panel Mount USB Cable - A Male to A Female||2||$7.90||$15.80|
|GPIO Wires (male to female)||6||Owned||Owned|
|Total Cost (USD):||$169.72|
- Emulation Station (bundled in RetroPie)
- Mausberry interrupt script for soft shutdowns (don't use their polling one, it slows the entire system down).
The code provided by the Mausberry manufacturer was interesting because I began to notice framerate drops if I ran that script in the background. It would poll extremely frequently for a reset or shutdown command and ended up consuming too many resources. I wrote a new script that used interrupts instead:
from subprocess import call import RPi.GPIO as gpio def loop(): raw_input() def shutdown(pin): call('halt', shell=False) gpio.setmode(gpio.BOARD) gpio.setup(23, gpio.IN) gpio.add_event_detect(23, gpio.RISING, callback=shutdown, bouncetime=200) loop()
Our first task was to remove all the original NES parts that we no longer needed. The only parts that we kept were the power buttons and female NES controller ports on the front of the case:
We used a dremmel to grind out holes for an ethernet port, HDMI port, and a DC power jack. The dremmel didn't do a great job (let's be honest, I can't control a dremmel if my life depneded on it), and I should have bought a good file to do all the detail work. I bought two USB ports as well, but decided to just feed them through the mouth of the NES after my bigtime dremmel fail. All ports were either hot glued or screwd into place.
Next we mounted the raspberry pi with a velcro strip, and connected the ports that were mounted on the exterior of the case (ethernet, HDMI, power):
The retrofit is starting to take shape. Next we wired the orignial NES power and reset buttons to the Mausberry circuit which were then connected to a couple of the Pi's GPIO pins. A python script listens for an interrupt on those pins and if one is detected, a software shutdown or reset is initiated to gracefully turn the Pi off. We replaced the original red LED with a blue one as well:
To use the original nintendo controllers we needed a circuit that could translate the information being sent from the nintendo controllers into a standard format that could be received by the Pi via USB. The RetroUSB NES RetroKit does this for us; we soldered the wires from the original female NES controller ports to the RetroUSB circuit and connected their USB end into the Pi:
As you can see, the cables are crazy long and have a lot of wires packed in them. We shortened them eventually but they still took up far too much space within the case.
The final step was to use velcro to mount a USB hub with 7 ports. A wifi dongle and usb dongle were connected to the HUB as well as some USB extension cables to the mouth of the case to allow a keyboard, mouse, or control to be connected easily:
Build complete! Now it was time to program the damn thing.
We flashed RetroPie (version 2.X) onto the SD card that is then inserted into the Pi. RetroPie is composed of many pieces of software: the Raspbian operating system, EmulationStation (a GUI for selecting emulators and games) and RetroArch (an emulation management platform). RetroPie has an enormous community supporting it and is the defacto standard for projects like this.
Raspbian is a free open source operation system based on Debian. It has everything you need to manage your Pi right out of the box, including all sorts of drivers and configuration specific to Pi hardware. You can overclock your Pi, upgrade your OS, and tweak tons of settings from their simple menu.
EmulationStation provides a nice front end for setting up controls and launching various ROMs.
RetroArch is the core emulator management sytem within the RetroPie project. It contains the configuration and BIOS's of dozens of different emulation systems. It supports anything from Atari 2600 and ColecoVision up to Sega, Playstation, and N64. In many cases you will still need to go download the BIOS yourself as it would be illegal for them to provide that as part of their package. It comes preconfigured to know what inputs are required for each of these systems and can recognize many controllers as soon as they are plugged in.
In our version of RetroPie, we still had to do a lot of manual controller configuration. For example, to use a playstation 3 controller we had to download a few pieces of code to pair the controller and then install the six axis manager to interpret the inputs from the controllers:
wget http://www.pabr.org/sixlinux/sixpair.c gcc -o sixpair sixpair.c -lusb sudo ./sixpair Current Bluetooth master: DE:AD:BE:EF:00:00 Setting master bd_addr to: 00:1F:81:00:06:20 wget http://sourceforge.net/projects/qtsixa/files/QtSixA%201.5.1/QtSixA-1.5.1-src.tar.gz tar xfvz QtSixA-1.5.1-src.tar.gz wget https://bugs.launchpad.net/qtsixa/+bug/1036744/+attachment/3260906/+files/compilation_sid.patch patch ~/QtSixA-1.5.1/sixad/shared.h < compilation_sid.patch cd QtSixA-1.5.1/sixad make sudo mkdir -p /var/lib/sixad/profiles sudo checkinstall sudo sixad --start sudo update-rc.d sixad defaults sudo jstest /dev/input/js0
Updating rc.d ensures the six axis manager runs on every boot. To tweak the config you could use jstest to determine which button corresponds to which number, and then update the RetroArch controller config:
input_driver = "udev" input_device = "PLAYSTATION(R)3 Controller" input_b_btn = "13" input_y_btn = "15" input_select_btn = "0" input_start_btn = "3" input_up_btn = "4" input_down_btn = "6" input_left_btn = "7" input_right_btn = "5" input_a_btn = "14" input_x_btn = "12" input_l_btn = "10" input_r_btn = "11" input_l2_btn = "8" input_r2_btn = "9" input_l3_btn = "1" input_r3_btn = "2" input_l_x_plus_axis = "-0" input_l_x_minus_axis = "+0" input_l_y_plus_axis = "+1" input_l_y_minus_axis = "-1" input_r_x_plus_axis = "-2" input_r_x_minus_axis = "+2" input_r_y_plus_axis = "+3" input_r_y_minus_axis = "-3" input_enable_hotkey_btn = "0" input_exit_emulator_btn = "3"
Once wifi and bluetooth were working, the BIOS for each emulator downloaded, ROMS downloaded and installed, and controllers were paired and set up for each emulator, we were ready to play!
We ended up building 3 of these systems and each build took around 6 hours to complete from start to finish. Getting some of the emulators running proved to be a real challenge in some cases, and mapping the controllers for each system was probably our biggest pain point. Many of these kinks have been ironed out in the latest version of RetroPie, and most people embarking on a similar project will have smooth sailing.
Performance and framerates were tolerable for most emulators, but that largely depended on which emulator you chose. We added heat sinks and thermal paste to ur Pi's and overclocked them to the maximum setting allowed within retropi-config. Some emulators (NES ones in particular) can barely run on a Pi while others are pretty smooth...which is interesting, as the most common Sega Genesis emulator seems to run quite smoothly. N64 is basically a no go although certain games are somewhat playable.
Although I don't play the system much, it does get dragged out from time to time when friends are over. It's a real joy for me to go through all the games that are available and see someone discover a game they haven't played or thought about in 15 to 25 years.