worrbase

Setting up RetroPie

2013-10-17

Today, after a few days of work, I finally got RetroPie up and running at an acceptable speed. It was a little longer and a little more difficult than anticipated, so it makes sense to blog about it.

SD Card Selection

Surprisingly, your SD Card makes a significant difference in the time it takes to load games and write out game state. The other, non-obvious, impact of the SD card is contention for IO when other tasks on your pi are reading/writing from/to the SD card.

I had initially chosen a slow, older class 4 card. Whenever some other process wrote out to disk, my games would noticeably lag a bit. I haven't had that problem since switching to a Class 10 though.

Don't just rely on the class number to give you information about the performance characteristics of the SD card. Checkout this handy list before buying.

OS Selection

Go with vanilla Raspbian.

I've played with Darkbasic's Raspbian, PiBang, and vanilla Raspbian for the host image. Raspbian was the fastest by far (after you disable all of the crap, of course). It's also convenient to have raspi-config and raspi-update installed from the getgo. RetroPie expects that you're running Raspbian, and you can hit some interesting behaviour if you aren't.

While I initially liked PiBang, systemd is a poor choice for the pi if you want to emulate. I noticed as I was playing games, systemd was eating a large portion of my CPU, and would occasionally cause lag when there was a sudden burst of activity. Moving to a non-systemd distro (Darkbasic's Raspbian) helped significantly.

Darkbasic's Raspbian was slow enough by itself. I never worked out the reason, since it uses the same repos as vanilla raspbian, with all of the same optimizations, however performance just on the terminal was noticeably slower. I'll post benchmarks later (possibly never).

Darkbasic's Raspbian image is also very minimal, and not configured the same way as vanilla Raspbian. This can lead to some interesting issues when trying to build and run RetroArch (more later).

If you choose not to install Raspbian, and use some minimal RPi distro, I'll include some helpful hints throughout (I set this up several times on the above distros).

Let's get started

Install your favorite image normally. Don't stop any services just yet or do any configuring just yet. Stick to a vanilla install, since that's what RetroPie expects (and it doesn't like any deviation).

Non-raspbian notes

  1. Add an input group.

    addgroup --system input
    
  2. Make sure that /opt/vc/lib is early in your linker path

    Check out /etc/ld.so.conf.d. Some distros will install versions of libEGL and related graphics libraries earlier in your library path. These generally do not work and will throw weird, un-Googleable errors.

    If you see

    libEGL warning: DRI2: xcb_connect failed
    libEGL warning: GLX: XOpenDisplay failed
    

    when starting emulationstation that's symptomatic of this problem. The libraries in /opt/vc/lib are built to use the Raspberry Pi's VideoCore chip.

Pull down the source

After you've logged in and gone through the initial setup for your pi, pull down the RetroPie-Setup source.

git clone git://github.com/petrockblog/RetroPie-Setup.git
cd RetroPie-Setup

Before we compile, I'd recommend setting your CFLAGS. Thanks to a patch I submitted, RetroPie-Setup now has some sane defaults ( -O2 -pipe -mfpu=vfp -march=armv6j -mfloat-abi=hard), but those aren't fast. I'd recommend -Ofast -fno-fast-math -pipe -mfpu=vfp -march=armv6j -mfloat-abi=hard.

  • -Ofast turns on the fastest optimization level, while potentially building unsafe code. It works quite well for me, but YMMV.

  • -fno-fast-math turns off a GCC optimization that -Ofast enables. fast-math uses some "faster" math that doesn't give you the guarantees of some of the standard math functions. In some cases, it's also slower.

  • -mfpu=vfp, -march=arm6j both tell gcc to generate code specific to the raspi architecture, as well as what kind of fpu-specific machien code to generate. These two flags are both used by the raspbian project to build their packages

  • -mfloat-abi=hard tells the compiler to generate fpu-specific instructions. Without this flag, gcc will generate floating point code that will not run on the fpu, but will link to library functions that emulate floating-point code. This is slow. All raspbian packages are built with this flag (that's what puts the 'hf' in 'armhf').

If you're worried about the problems the new flags could introduce, then stick to the defaults. If you're just reading this and you already have RetroPie installed, you should probably rebuild to get the new compiler options ;).

Set the CFLAGS with

export CFLAGS=-Ofast -fno-fast-math -pipe -mfpu=vfp -march=armv6j -mfloat-abi=hard
export CXXFLAGS="${CFLAGS}"
export ASFLAGS="${CFLAGS}"

After all of this, it's just a quick sudo ./retropie_setup.sh. Pick and choose what you want; it's really none of my business, and it's quite easy.

Make sure you pick the source-based builds (I guarantee that the binary ones weren't built with any good options) and that you tell the installer to start emulationstation on boot.

Post installation

Disable everything.

update-rc.d avahi-daemon remove
update-rc.d bluetooth remove
update-rc.d cron remove
update-rc.d cups remove
update-rc.d dbus remove
update-rc.d ifplugd remove
update-rc.d lightdm remove
update-rc.d nfs-common remove
update-rc.d rpcbind remove
update-rc.d rsync remove
update-rc.d rsyslog remove
update-rc.d saned remove
update-rc.d triggerhappy remove
update-rc.d ntp remove
ls /etc/rc3.d
K06rpcbind  README  S02dphys-swapfile  S02ssh  S05plymouth  S05rmnologin

I use ssh to manage the system, so I leave that. Everything else must go.

Don't get me wrong, usually I like logging, ntp and cron, but it's just not necessary on a pi that's dedicated to playing games.

PiBang/systemd notes

PiBang uses this half-assed systemd with sysvinit compatibility. It's a pain in the ass. Almost all of the packages that need to start at boot that you get on PiBang need to be disabled with update-rc.d. Some others though need to be disabled with systemctl disable <service>. I'll leave it as an exercise to the reader to figure out how to tell.

Minimal image notes

You're probably sitting there laughing at how much bloat Raspbian comes with. While that's fair, keep in mind that the RetroPie script installs a ton of shit, cups and sane included. Make sure you audit your startup as well.

Configuring a joystick

Your joystick needs to be configured before you can start playing games. Emulation Station will configure it for you when you first start it up, however that configuration only applies to Emulation Station. You need to configure your emulators on their own.

For RetroArch:

cd ~/RetroPie/emulators/RetroArch/tools/
./retroarch-joyconfig -o p<playernumber>.cfg -p <playernumber> -j <joysticknumber>
# joysticks are 0 indexed (they map to /dev/input/jsn
# players are 1 indexed
cat p*.cfg >> ~/RetroPie/configs/all/retroarch.cfg

Non-raspbian notes

You'll need a udev rule to automatically give the input group permissions to access the joystick devices. Drop the following into /etc/udev/rules.d/99-input.rules

SUBSYSTEM=="input", GROUP="input", MODE="0660"

This ensures that the input group owns any new input devices, and that they are group-readable.

But moooom, I want to use an XBox controller

No. You don't.

You can use xboxdrv to hook up your XBox controller. It's a userspace driver that talks to the raw joystick device and interprets the XBox controllers's raw output into something meaningful.

Since the driver lives in userspace, anytime you twiddle a joystick or press a button, you're hopping like mad between userspace and kernelspace. This is slow. I could actually emulate the slow-mo feature provided by RetroArch just by twiddle both joysticks.

No. I'm a special snowflake and I demand to know how to use an XBox controller

apt-get install xboxdrv
sudo -s
echo xboxdrv --silent > /etc/rc.local

If you don't want to reboot, just execute

xboxdrv --silent &

as root.

You've been warned.

Starting emulationstation on boot

Luckily, RetroPie did half of the work for you! If you selected the option (either in setup or install) to start emulationstation on boot, it'll drop a handy snippet into /etc/profile which will do that on login.

However, you still need to login.

To alleviate that, edit your inittab.

1:2345:respawn:/sbin/getty --autologin pi --noclear 38400 tty1 
#1:2345:respawn:/sbin/getty --noclear 38400 tty1 
#2:23:respawn:/sbin/getty 38400 tty2
#3:23:respawn:/sbin/getty 38400 tty3
#4:23:respawn:/sbin/getty 38400 tty4
#5:23:respawn:/sbin/getty 38400 tty5
#6:23:respawn:/sbin/getty 38400 tty6

Go to line 45 (on raspbian, or where the gettys are started), and enable autologin for whatever user is going to run RetroArch.

In the spirit of disabling everything, I also stopped all of the other gettys from spawning.

Should I overclock?

Well, it depends. Want to run SNES games that have Mode-7 graphics? Or any of the SNES games that packaged an extra processor on the cartridge? Yes. Overclock.

In most other situations, you're fine if you follow this guide. The one thing I would recommend doing, however, is changing the memory/gpu mem split. I gave my GPU 384MB of memory. I'm barely breaking 20MB of memory usage running my pi, so I don't need very much system memory.

Your game will start slowing down as the proc overheats, so make sure you have a heatsink and a case with some kind of airflow if you plan on overclocking.

Notes for non-raspbian users

Yeah, you probably do want to overclock. If your distro is compiled with dumb options, it'll help a bit.

On both Darkbasic's raspbian and PiBang, I had to overclock to get decent performance.

Conclusion

That's about as perfect a setup as you can get for RetroPie. If you have any other suggestions, leave them in the comments. I didn't configure RetroArch anymore than shown above, because well, I didn't need to. For all of my ROMs built by the homebrew community that are totally free and legal to play, I ran into no slowdown with this setup on Raspbian.

However, YMMV, as always.