Building a RetroPie

RetroPie thumb

Consider yourself a gamer, and you're a child of the 80's? This post explains how to build a tiny system to house all your old ROMs so you can once again play all those games from your childhood from the comfort of your couch.


Sources


Parts List

Price Part
HDMI Cable $5.09 HDMI Cable
Gamepad $11.30 Gamepad x2
Raspberry Pi 2 Model B $41.85 Raspberry Pi 2 Model B
5V 2.5A PSU $9.99 5V 2.5A PSU
WiFi Dongle $9.99 WiFi Dongle
Heat sinks $5.05 Heat sinks
microSD Card $6.57 microSD Card
RemotePi board plus 2015 €19.90 RemotePi board plus 2015
Case €7.90 Case
Remote €4.90 Remote (optional)
SD Card case $5.95 SD Card case (pack of 3) (optional)

Assembly

  1. Unwrap the case
  2. Place the Pi on the bottom piece of the case (taking care that the SD slot is in the correct position). Then place all other case parts in their proper position. Assembly 1
  3. Mount the heat sinks. Assembly 2
  4. Mount the RemotePi board.
    • The screw goes in the hole to the right of the SD card slot.
    • Thread one nut to the base of the board.
    • Thread another about 5 turns down. Assembly 3
    • Plug the board in, being mindful of the pins and the screw hole.
    • Thread the final nut to the top of the RemotePi, securing it in place. Assembly 4
  5. Assemble the case (describing from the top down, SD slot facing you).
    • Start with the right side
    • Then the left, make sure the headphone jack sits in the hole Assembly 5
    • Then the back. Slide the top holes over the side teeth first, then pinch the bottom of both sides to bend latches upward allowing them to slide into the bottom holes. May require a little force, but be careful or you may break the holes where the teeth lock in.
    • Then attach the lid.
    • Finally mount the front plate, taking the same care as with the back plate. Before doing this, you may want to put a tiny dot of super glue on the nut below the bottom of RemotePi and on the nut at the base. I found that during testing the nuts would loosen, causing the board to sag. If you do apply the glue leave the front plate off until the glue is dry otherwise it'll frost the plastic, something about the glue fumes does it. I suggest a tiny dot in case you need to remove the board in the future, with a small dot you can easily scrape it off with an exacto knife. Assembly 6

System

RemotePi board

You can watch the install video, or follow the instructions below.

  • Plug in the power to the boards microUSB port (not the pie's). The power button should glow red when off.
  • Press the power button for about 10s until the LED on the front of the board flashes to enter the learning mode.
  • Point your infrared remote towards the receiver and press the button you wish to use to power on the RPi. The newly learned on button is acknowledged with a short green LED blink. Then press the remote button you want to use to switch off the RPi.
  • Try turning the Pi on via the remote now. Extra code will need to be added to get the board to shut down via the remote.
  • First, connect to the pi, then follow the below steps.
cd /etc
sudo nano rc.local

Enter this line just above the last line (before the line exit0)

(/etc/irswitch.sh)&

Press ctrl+x to exit, y to confirm, enter to save the file.

sudo nano irswitch.sh

Copy & paste the following into the editor.

#!/bin/bash

# this is the GPIO pin receiving the shut-down signal
GPIOpin1=14
echo "$GPIOpin1" > /sys/class/gpio/export
echo "in" > /sys/class/gpio/gpio$GPIOpin1/direction
while true; do
  sleep 1
  power=$(cat /sys/class/gpio/gpio$GPIOpin1/value)
  if [ $power != 0 ]; then
    echo "out" > /sys/class/gpio/gpio$GPIOpin1/direction
    echo "1" > /sys/class/gpio/gpio$GPIOpin1/value
    sleep 3
    sudo poweroff
  fi
done

Press ctrl+x to exit, y to confirm, enter to save the file.

sudo chmod +x irswitch.sh

The next part is a bit hacky, but unfortunately EmulationStation's shutdown code is compiled from the file platform.cpp in the runShutdownCommand method, so there's no normal way to alter it's behavior.

sudo mv /sbin/shutdown /sbin/shutdown.bin
sudo nano /sbin/shutdown
#!/bin/bash

while getopts "hr:a:" opt; do
  case $opt in
    h)
      killall emulationstation
      pkill -o -u pi sshd

      echo "Shutting Down RetroPie"

      (
        sleep 1s &&

        (
          GPIOpin=15
          echo "$GPIOpin" > /sys/class/gpio/export
          # execute shutdown sequence on pin
          echo "out" > /sys/class/gpio/gpio$GPIOpin/direction
          echo "1" > /sys/class/gpio/gpio$GPIOpin/value
          sleep 0.125
          echo "0" > /sys/class/gpio/gpio$GPIOpin/value
          sleep 0.2
          echo "1" > /sys/class/gpio/gpio$GPIOpin/value
          sleep 0.4
          echo "0" > /sys/class/gpio/gpio$GPIOpin/value

          /etc/irswitch.sh
        )&>/dev/null
      )&
      ;;
    *)
      /sbin/shutdown.bin "$@"
      ;;
  esac
done
sudo chmod +x /sbin/shutdown
sudo reboot

RetroPie

Installed retropie-v3.0-rpi2.img onto the microSD card via win32DiskImager.

Insert the SD card, plug in wireless dongle, plug in controller, plug in HDMI, then plug in power. Assembly 7

Once the device has booted, & emulation station has started, you'll be prompted to setup your controller. After that's done, you'll want to expand the file system so that you can use all of the SD card. If the audio's not coming through, you'll have to switch the audio from headphones to HDMI. Both of which are done from the RetroPie menu.


Controller

I have an SNES controller so I just setup D-Pad [Up, Left, Down, Right], [A, B, X, Y], Right Bottom, Left Bottom, Start, & Select.

Controller Hotkeys

Hotkeys Action
Select+Start Exit
Select+Right Shoulder Save
Select+Left Shoulder Load
Select+Right Input State Slot Increase
Select+Left Input State Slot Decrease
Select+X RGUI Menu
Select+B Reset

Connecting to WiFi

Hook a keyboard up to one of the free USB slots in order to enter password.


Connecting to device via another computer

Having the IP address isn't required, but I find it useful if you're running multiple boxes. There are a couple ways to get the IP via the commandline.

ping retropie.local

Or via SSH, which will show the IP address in the block of info next to the raspberry ascii art.

ssh pi@retropie.local
raspberry

Connecting via a terminal

ssh pi@192.168.1.234 (use the IP of the Pi), password is raspberry.

To reboot after changes just run sudo reboot.

Connecting via a GUI

I use WinSCP for the simplicity of the GUI. You can connect to the Pi by setting up a New Site and use these settings.

  • File protocol - SFTP
  • Host name - 192.168.1.234 (use the IP of the Pi)
  • User name - pi
  • Password - raspberry

Adding ROMs

SCP into the device and go into /home/pi/RetroPie/roms/. Find the directory of the device and drop your ROMS in. Once they've uploaded, reboot the Pi and a nav option for the device should now show up and display the number of games available.

Extract roms if they're zipped up, at least for older games like

  • NES .nes
  • SNES .smc
  • Sega Master System (1st gen) .sg .sms
  • Sega Genisis .bin

Try to only use ROMs with (U)[i] codes in their name.

ROM code meanings

Key Meaning
(U) US
(E) Europe
(J) Japan
(G) German
[!] Verified good ROM dump
[a] Alternative version
[b*] Bad ROM dump
[f*] Fixed to run better on copiers or emulators
[h*] Hack
[m*] Multilanguage
[o*] Overdump (sometimes bad, sometimes good)
[p*] Pirate

I had a bunch of ROMs I didn't know would work or not, so I dumped them all in a .unused folder, and extracted the ones with the (U)[i] codes. To create the .unused dir I just ran mkdir .unused in a terminal while in the directory with my extracted ROMs.


Scraping ROMS

You can go through the GUI which is much slower & doesn't keep the gamelist.xml and it's associated images with the system, but rather in a top-level directory. This section will outline how to install a script that can scrape individual systems.

You can SSH in and install the script, via the method below. Follow the link for a list of releases.

wget https://github.com/sselph/scraper/releases/download/v1.0.1/scraper_rpi2.zip
sudo unzip scraper_rpi2.zip scraper -d /usr/local/bin/
sudo rm scraper_rpi2.zip

cd RetroPie/roms/snes/
scraper -thumb_only -append -add_not_found

To make things easier I added some alias' so that I can update specific systems. Just create a .bash_aliases file at the root of the retroPie, there should be a .bashrc file there already.

# .bash_aliases

alias scrape-megadrive='cd RetroPie/roms/megadrive/ && scraper -thumb_only -append -add_not_found && cd "$OLDPWD"'
alias scrape-nes='cd RetroPie/roms/nes/ && scraper -thumb_only -append -add_not_found && cd "$OLDPWD"'
alias scrape-snes='cd RetroPie/roms/snes/ && scraper -thumb_only -append -add_not_found && cd "$OLDPWD"'

Updating ROMS

After you've added new ROMs the only way to get them to show up is to reboot unless you follow the below steps.

In order to have our custom menu show up properly we have to create a theme for the custom 'System' that we're going to make. Spin up WinSCP and navigate into /etc/emulationstation/themes/simple. When you first log in via WinSCP, you'll be in the /home directory, just click on .. above the pi directory and then you'll be at the root, which will allow you to go into /etc.

Copy the retropie theme to a local working directory and rename it to util. I created this local directory structure themes/simple/util. That way I can keep my theme edits organized in case I edit any other themes.

Connect to the Pi.

cd /etc/emulationstation/themes/simple/
sudo mkdir util
sudo chown pi:pi util

You should now be able to copy the new theme files from WinSCP to the pi. Now we'll make a simple script to scrape the contents of nes ROMs.

mkdir ~/RetroPie/util_menu
cd ~/RetroPie/util_menu
sudo nano scrape_nes.sh
#!/bin/bash

killall emulationstation

# The directory that will be scraped
cd RetroPie/roms/nes/
scraper -thumb_only -append -add_not_found
cd "$OLDPWD"

emulationstation

Press ctrl+x to exit, y to confirm, enter to save the file.

sudo chmod +x scrape_nes.sh
cp /etc/emulationstation/es_systems.cfg ~/.emulationstation/es_systems.cfg
sudo nano ~/.emulationstation/es_systems.cfg

I entered this code below the entry for retropie since they're both basically system util "Systems".

<system>
  <name>util</name>
  <fullname>Util</fullname>
  <path>~/RetroPie/util_menu</path>
  <extension>.sh .SH</extension>
  <command>bash %ROM%</command>
  <platform/>
  <theme>theme</theme>
</system>

Press ctrl+x to exit, y to confirm, enter to save the file.

To make things more readable, and not filename specific, we're going to create a fake System.

mkdir .emulationstation/gamelists/util
sudo nano .emulationstation/gamelists/util/gamelist.xml

To cut & paste blocks (there's no copy) you mark the start of the line with ctrl+6 go to the end of your selection then ctrl+k to cut. Then just place your cursor where you want the block and ctrl+u. This will come in handy if you're adding more than one entry.

<?xml version="1.0"?>
<gameList>
  <game>
    <path>./scrape_nes.sh</path>
    <name>Scrape Nintendo Games</name>
  </game>
</gameList>

Reboot for new settings to take effect.

sudo reboot

Removing unwanted Emulators

SCP into the device and go into /home/pi/RetroPie/roms/.

  • amiga - Renamed +Start UAE4All.sh to +Start UAE4All.sh.bak.
  • apple2 - Renamed +Start LinApple.sh to +Start LinApple.sh.bak.
  • macintosh - Renamed Start.txt to Start.txt.bak.
  • pc (IBM) - Renamed +Start DOSBox.sh & +Start rpix86.sh to +Start DOSBox.sh.bak & +Start rpix86.sh.bak.
  • ports - Just deleted the files.
  • scummvm - Renamed +Start ScummVM.sh to +Start ScummVM.sh.bak.
  • zmachine (Infocom) - Just deleted the files.

Backing it up

Now that everything is setup the way you want it, back it up in case something happens to the card, or you just want another one or want to give one as a gift.

Install VirtualBox if you don't already have it installed. I was using v5.0.4r1025460 as of this post. And we'll want to throw Ubuntu on it. You can download Ubuntu from here, I went with v15.04 Desktop (64-bit).

In VirtualBox start a New machine. Before doing so make sure your Default Machine Folder is set to a location with enough space. I changed mine to a partition with plenty of space. You can do that by going to File >> Preferences >> General. Here are my new machine settings.

Name & OS

Name: Ubuntu
Type: Linux
Version: Ubuntu (64-bit)

---

Memory: 2048mb

---

Hard Disk

* Create a virtual hard disk now

I chose the install option rather than the live trial for Ubuntu. User and password were john | doe. Once Ubuntu finally booted I then went to the VirtualBox menu of my Ubuntu instance (not the VirtualBox Manager window), and went to Devices >> Insert Guest Additions CD image. Once that finished you'll want to reboot if it doesn't prompt you to do so. Once booted, open a terminal and enter:

sudo adduser john vboxsf

Then go to the VirtualBox Manager and open the settings for the Ubuntu machine. Once in there, go into the Shared Folders section and add a new Machine Folder. Point it to the folder that has your backup image. Check Auto-mount and Make Permanent. Reboot the machine, and once it's booted go into /media/sf_Share/ (Share is the name you gave the folder, if you called it 'MyShare' it'd show up as sf_MyShare). and you should be able to see the contents of your shared folder. If not, open terminal and enter groups, if you don't see vboxsf listed then you may have made a mistake somewhere.

# allows for easy partition manipulation via a GUI
sudo apt-get install gparted
# allows for showing progress
sudo apt-get install pv

Insert the card with retropie on it. Go up to the Ubuntu VM menu, Devices >> USB >> Generic Flash Card Reader/Writer. The Boot partition and the retropie partition should mount.

sudo fdisk -l

Two devices should show up, the OS, and the SD card. The SD card will have a boot partition (FAT16) and retropie will be Linux (ext4).

Opened up gparted, selected the sd card from the top right corner, right-clicked on the ext4 partition (retropie) and chose unmount. Then I could resize it. So I resized it to a little over the minimum. For example it was using about 5.5GB of space, so I just set it to about 6GB.

sudo fdisk -l
sudo dd if=/dev/sdb | pv | gzip > /media/sf_RetroPie/backup.gz
gzip -dc /media/sf_RetroPie/backup.gz | pv | sudo dd bs=4M of=/dev/sdb

# You can try something like this to give you a more common progress bar with
# estimated time until completion.
gzip -dc /media/sf_RetroPie/backup.gz | pv -s 6G | sudo dd bs=4M of=/dev/sdb
# 6G being the estimated size of the final unzipped contents. I found it tends to
hang if the file size is too great though and you have to manually exit.

29 minutes to create the backup from a fully expanded 8GB card. Actual used size was about 6GB, final backup size was 2.35GB. About another half hour to write from the backup. Make sure to test the backups too. So backup from one card and have an extra to write/test with.


Useful (but eventually not used)

Open win32DiskImager back up and the Image File field enter in a path to where you want to save the backup. For example C:\backups\2015-09-07_retropie_backup.img. Make sure the Device dropdown has your retropie's SD card drive letter. Then just click Read. This'll take a few minutes depending on the size of the SD card since we've allocated the full size of the disk.

Since we've expanded the file system we have to shrink the .img down afterwards otherwise there's a good chance you won't be able to install it onto another SD card. Doing this also means you have to re-expand the file system once you install it onto another card.

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sdb1  *      8192   124927   116736   57M  e W95 FAT16 (LBA)  BOOT
/dev/sdb2       124928 12537855 12412928  5.9G 83 Linux            retropie (ext4)

# Mounts img for manipulation
sudo modprobe loop
sudo losetup -f
sudo losetup /dev/loop0 <name_of_img>
sudo partprobe /dev/loop0
sudo gparted /dev/loop0

# Create uncompressed img
sudo dd if=/dev/sdb bs=1M | pv | dd of=/media/sf_RetroPie/test.img

# lists mount points
df

# A
cd /media/sf_RetroPie # (otherwise there'll be nested dirs)
tar -zcvf backup.tar.gz 2015-09-12_retropie_backup_bak.img

# C
sudo tar -cvpjf /media/sf_RetroPie/backup.bz2 -C /dev/sdb .
sudo tar -xvpjf /media/sf_RetroPie/backup.bz2 -C /dev/sdb --numeric-owner

tar -cvz -f archive-$(date +%Y%m%d).tar.gz ./new/

Setting up a VNC server

sudo apt-get install tightvncserver
sudo apt-get install xrdp

# start the server on port 5901
vncserver :1
# use password - 'raspberr' since it can only be 8 characters long.

What Dis?

My name's Trevor Lemon, and this is my blog. I'll try to update it with whatever I'm working on, random thoughts, links to shit I think is cool; whatever I deem worthy I suppose.

If you want to keep up with muh craziness bookmark my RSS feed.

Archive