Setting up RetroPie
2013-10-17Today, 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
-
Add an input group.
addgroup --system input
-
Make sure that
/opt/vc/lib
is early in your linker pathCheck 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 tellgcc
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.