After playing around aimlessly a bit with my Raspberry Pi (most recently, an install of the very nice RaspBMC), I thought of a decent purpose for it while showing my kids Super Mario Bros. and The Legend of Zelda running on the VirtualNES emulator on my Windows laptop. Before they get too spoiled on the Xbox 360′s graphics and sound, I want to get them some exposure to a few of the simple but influential 8-bit games from my childhood. At the same time, I don’t want my laptop to become the family’s game machine. We have a pretty massive TV and plenty of Xbox controllers, so I figured I could throw the Raspberry Pi into the mix and come out with a neat retro gaming console.
As with all things Linux, the devil is in the details. Like, can you get the application to work with both video and sound, and are all of the peripherals fully functional? Add to that the uncertainty of the performance of regular Linux applications on the particular hardware limitations of the Raspberry Pi, and any simple-seeming project quickly develops into a series of and-now-this-doesn’t-work obstacles. Case in point, a Google search turned up a number of people who had already thought of turning their Raspberry Pi’s into 80′s game console emulators, and it quickly became obvious that this wasn’t going to be a completely painless process.
This post on the Raspberry Pi forum from a few months earlier basically sums it up.
I have a NES emulator working without sound, using the Debian image, will only work running through console no LXDE
sudo apt-get install fceu
./fceu -input1 gamepad -inputcfg gamepad1 /home/pi/mario_bros.zip
Command above will map gamepad buttons to your keyboard, and load game image path you specify. Appears to work fine apart from no sound, I’ve had a few levels on Mario Bros.
Not tried with a joypad, I have a wireless xbox360 joypad that is discovered as a usb device, but have not had chance to try to get it working yet. It doesn’t work by default
An then a reply to that already discouraging post makes the landscape seem even more bleak.
Oh yeah, that’s the one! I tried to use mednafen, but even disabling openGL so it would use SDL for graphics would only give me a blank screen. I’ve tried to find some console emulators that use openGLES but every time I find one, it turns out that it’s only available as a pre-assembled package for platform x.
Well, posts like those would certainly dissuade most human beings from settling on this as a weekend project, but thankfully, plenty of people far smarter than I have been diligently working at converting their Raspberry Pi’s into something resembling a game console, and you and I can now directly benefit from their labor. I’m happy to report that I am getting decently playable NES emulation with sound (and slightly-less-satisfactory SNES emulation) from my Raspberry Pi after a few hours of struggle. And what with how quickly I’m willing to reformat the SD card with a different image (what? an update to RaspBMC?), I thought I should document my steps for posterity.
One of the most frustrating things about doing anything in Linux after living in Windows is that it rarely works as smoothly as you would expect and it takes some patience to get past the obstacles. On top of that, when you turn to Google for help, forum threads typically assume the readers will have more than a passing familiarity with the Linux file structure, command line input, Make files, and the like. Once I find what looks like a possible fix, I often find myself searching for help on how to implement the fix, which frequently turns out to be out-of-date and no longer applicable.
So, for those of us who are not going to know how to chmod +x a shell script without some hand-holding, here are the steps I’ve followed so far, that are hopefully detailed enough that you end up with a working RPi game console instead of seething frustration. At times, I assume that you’re still using the ‘pi’ user account, but if you’re not, you’ll probably be able to recognize where you need to substitute your new account. If you happen across this post and you can see where I’m definitely doing stuff horribly wrong, please leave a comment and I’ll try to make it better.
Steps to set up the SD card and configure Raspbian with the necessary software
1. On your main computer (I’m assuming you’re running Windows here), get the latest release of Rasbian from the Raspberry PI Downloads page, extract it, and install it to your SD card using whatever method you’re comfortable with. In Windows 7, I’ve successfully used win32diskimager more than once, but it will complain at me every time. This post was written while using “2012-12-16-wheezy-raspbian”, the latest release at the time.
Connect the Raspberry Pi to a TV or monitor, connect a USB keyboard (my superstitous nature makes me connect it to the bottom USB port), and connect an ethernet cable. You can also connect your wired Xbox controller or Xbox 360 Wireless Gaming Receiver now, if you like. Boot up the Raspberry Pi and use the
raspi-config utility (it should run automatically at the first boot) to a) enable the SSH server, b) change the memory split to 50% of the total memory (set it to 128 MB for the original Model B boards with 256 MB memory, and to 256 MB for the upgraded version of the Model B boards with 512 MB memory), c) if you are not using a UK keyboard, change the keyboard layout to US or whatever is appropriate, and d) expand the root partition to fill the SD card. Choose finish and allow the Raspberry Pi to reboot. Note the IP address of the Raspberry Pi, which is reported in the lines just before the logon prompt.
I also overclock it to the Modest setting (800MHz), but you can play with this to meet your needs. You can also bump up the memory split to allocate 192 MB to the GPU, but it hasn’t been necessary in my experience. If you need to run the
raspi-config utility again, open a terminal (Alt+F1 through Alt+F6) and enter
there. I don’t recommend changing the setting to boot straight into the GUI, as the Emulation Station and RetroArch stuff that comes later is best launched from the command prompt immediately after logging in and offers something of a GUI anyway.
2. Back on the Windows computer, download PuTTY, which will allow you to access the RPi command prompt from your Windows computer across your LAN. Launch PuTTY, connect to the RPi using its IP address, and log in (username: pi and password: raspberry). The best thing about accessing the RPi via PuTTY is that you can copy command lines from your web browser in Windows and paste them into the PuTTY window, saving you from typing in lots of unfamiliar Linux commands.
3. In the PuTTY window, update the package lists from the repositories and retrieve new versions of existing packages with
sudo apt-get update && sudo apt-get upgrade -y
4. Still in the PuTTY window, install GIT, vim, xboxdrv, and other useful software with
sudo apt-get install -y git vim dialog xboxdrv
and then reboot the RPi with
sudo shutdown -r now
5. Reconnect to the RPi with PuTTY and follow the instructions at RetroPie-Setup: An initialization script for RetroArch on the Raspberry Pi to install RetroArch for the Raspberry Pi. You can leave the options for installing components at their defaults, but I generally deselect some of the cores that I don’t want or that I expect won’t work very well on the RPi. The installation will take a few hours, but the fewer emulator cores you choose to install, the faster it will go. Reboot at the end of the RetroArch installation.
6. Copy your ROMs into the appropriate, console-named subfolder under /home/pi/RetroPie/roms/ on the RPi. You can put them on a flash drive and transfer them to the RPi via command line or in X, or you can use WinSCP to copy files from a Windows machine to the RPi across the network, which is the method I prefer to use. (WinSCP can, to some extent, also allow you to edit config files on the Raspberry Pi, which you’ll need to do from time to time.)
That takes care of the basics. Now you can launch the Emulation Station, which is the front-end we’ll be interacting with to choose between games, by entering
at a terminal prompt using the USB keyboard (it does not like to be started from an SSH connection). Manually starting Emulation Station each time is optional, as it is possible to launch the Emulation Station automatically at start up, though I’m not sure I actually want this behavior at each boot and so continue to launch it myself.
Your Raspberry Pi now has all the necessary software to emulate games and accept input from your Xbox 360 controller. It’s now time to…
Configure the controller
Once you have those components installed, it’s time for the next step in any Linux project: discover what’s not working. (I have a long, involved tale about trying to map all of the buttons on my old Logitech MX510 mouse, but I digress…)
For one thing, a wired (and potentially wireless) Xbox 360 controller isn’t going to automatically work, and unless you’re content using the keyboard in games, you’re going to want to get it working ASAP. You can connect the controller, and you may get the ring of lights to pulse, but you’ll need to crank up
xboxdrv before you can do anything with it, as
xboxdrv is how the RPi talks to the Xbox 360 controller. I strongly recommend reading through the list of xboxdrv switches, as I spent a long time trying to figure out why the triggers and analog sticks weren’t mapping until I went back and RTFM.
The manual way of starting up
xboxdrv for a single controller is to just run
sudo xboxdrv --trigger-as-button --silent
at the command prompt each time you turn on the RPi, but you could start this up automatically, too. If you don’t run it with
sudo, you’ll get an error: USBController::USBController(): libusb_open() failed: LIBUSB_ERROR_ACCESS. The creator’s proposed workaround is to add the current user to the ‘root’ group, which I’m not terribly keen on, so I’d be content with just continuing to run it with
sudo. If you want to see your joystick axis and button press information output to the console, just run sudo xboxdrv without the
--silent switch, but this eats up some CPU, so use the
--silent switch when you’re going to be playing games.
The automatic way of starting up
xboxdrv for a single wireless controller is to add the command to /etc/rc.local, which is a file that runs (like a script) at the end of multi-user boot levels (think: before a user logs on). It makes sense to start up
xboxdrv automatically, particularly because we want to pass some arguments that would be annoying to type each time. While connected via PuTTY, start by backing up /etc/rc.local with
sudo cp /etc/rc.local /etc/rc.local.bak
Open /etc/rc.local using the vim text editor with
sudo vim /etc/rc.local
Arrow down to the line immediately before
exit 0, hit the Esc key, and type or copy and paste
xboxdrv --dpad-as-button --trigger-as-button --wid 0 --led 2 --deadzone 4000 --silent &
then hit Enter, and type
Hit Esc again, type
and hit Enter to save the changes and exit the editor. Reboot the RPi again, and now you should see that the Xbox 360 driver is up and running even before the login prompt appears. How’s that for awesome?
(The official instructions in the Using a single controller section of the xboxdrv manual at http://pingus.seul.org/~grumbel/xboxdrv/xboxdrv.html don’t seem to apply to the RPi at this point, as the xpad driver isn’t loaded and the upinput and joydev modules are loaded during boot.)
If you want to be even more slick and automatically start up support for up to 4 controllers, check out https://github.com/petrockblog/RetroPie-Setup/wiki/Setting-up-the-XBox360-controller.
Now that the controller and the RPi are talking, you need to configure RetroArch to work with it. It is certainly possible to do all the text file editing and copying in LXDE, which is the graphical interface on the Raspbian distribution, but I’m trying to get better with vim, so I’m going to use it in this case. In PuTTY, enter
cp ~/RetroPie/configs/all/retroarch.cfg ~/RetroPie/configs/all/retroarch.cfg.bak
to back up the default RetroArch configuration file, and then
to open the file in vim. It’s good to get some idea of the options and their defaults, I think, so I really recommend looking through this file, as you may need to come back later and tweak it to resolve problems with sound in games. Exit the file by typing
and hitting Enter.
Back on the USB keyboard attached to the RPi, log in and enter
to navigate to the directory containing the retroarch-joyconfig utility that you’ll use to set up the controller. (If you’re getting an error message about files or directories not being found, you may be using a US keyboard but the RPi is still set to a UK keyboard layout. This would cause the tilde key “~” to enter a logical negation symbol “¬” instead. The tilde in a path is expanded to be the current user’s home directory, and the logical negation symbol is not.) Enter
./retroarch-joyconfig -o p1.cfg -p 1 -j 0
to fire up the utility and then follow the instructions to push the buttons and move the sticks/triggers/dpad. (The -o switch causes the output to be sent to a file, otherwise, it is just echo’d to the screen.) If you mess up, just keep pressing buttons until the utility exits and then enter
./retroarch-joyconfig -o p1.cfg -p 1 -j 0
again to start over.
When you’re done, you should have a new p1.cfg file at ~/RetroPie/emulators/RetroArch/tools. The contents of this file is what will eventually tell the Emulation Station, RetroArch and each of the various system emulators how to interpret the commands coming from your controller, but it needs to be appended to the end of that retroarch.cfg file first. To do this, enter
sudo cat p*.cfg >> ~/RetroPie/configs/all/retroarch.cfg
(I initially had some problems with analog joysticks and triggers not registering in the retroarch-joyconfig utility until I started passing the
--trigger-as-button switch when launching
xboxdrv. However, even when the analog sticks are mapped by retroarch-joyconfig, I don’t have the use of them in NES games like Metroid, and that’s mostly OK by me, except that the dpad on the Xbox 360 controller has always seemed horribly sloppy to me, even in Xbox games. For some reason, the analog joystick movements would be picked up by
xboxdrv if I omitted the
--trigger-as-button switch, but not by the
retroarch-joyconfig utility. The problem with the triggers is that without the
--trigger-as-button switch, each trigger pull and release counts as two analog axis movements. This is desired for games where the trigger acts as a brake or gas pedal, but NES and SNES games have little or no use for this. Analog joysticks behave the same way, throwing tons of input at the slightest movement when the NES really just needs to know when it’s been pushed and released. It’s possible to turn the analog sticks off entirely by passing
--dpad-only switch, but what I really want is to accurately control NES games with the far more reliable left analog stick – something I’m still working on.)
(If you get an error “Couldn’t open joystick #0.”, it probably means that
xboxdrv needs to be restarted first.)
Get impatient and try playing a game
Assuming you haven’t had any insurmountable problems with the directions above, you should be able to get into a game in a few simple steps:
1. plug everything into the RPi (HDMI, wired controller or Xbox 360 wireless gaming receiver, etc.)
2. turn on the Xbox controller (if you need to link the controller with the dongle, you may have to reboot once this has been done before the RPi will see it)
3. reboot the RPi (
sudo shutdown -r now from a terminal) and log in as the ‘pi’ user
4. at the prompt, enter
emulationstation to launch the front-end
5. use an analog stick or D-pad on the Xbox 360 controller to browse the ROMs (use right and left to browse the different systems) and one of the buttons to launch a game.
And you definitely should pat yourself on the back for getting this far.
But your game probably won’t have sound.
Wrestle with the sound
I’m using a pair of headphones plugged into the analog jack, and while many people report that the game’s audio when output through HDMI is fine, the audio out through the analog jack is decidedly not fine. Well, the sound starts off fine, but within 20-30 seconds it starts becoming increasingly choppy and a few moments later I’m ripping off the headphones. I Googled this a ton, and eventually changed retroarch.cfg to use the options recommended at https://github.com/petrockblog/RetroPie-Setup/wiki/Sound-Issues by uncommenting and/or editing these lines in the file (again, with vim):
audio_enable = true audio_out_rate = 44100 audio_driver = sdl
You can also try setting the experimental “audio_rate_control” to false and/or the “audio_latency” to 128.
I had read a bit about ALSA and very little about SDL, but from what I can tell, it boils down to ALSA (which is in alpha on the Raspberry Pi) should be faster than SDL once ALSA is working completely, but for right now, we’re better off using something else, and that something else seems to be SDL.
So that’s it, you should be able to play those old NES games now, but with the far more comfortable Xbox 360 controller.
And while you’re editing retroarch.cfg, you may want to map a controller button to exit the game and return to the Emulation Station GUI. The Esc key on the keyboard does this, by default.
Because I had mapped so many strange buttons to the silver Xbox guide button during my trial-and-error period, I was able to easily identify the number assigned to it in retroarch.cfg, and that number happened to be 8. So, to make the Xbox guide button on my controller exit a game and return to the Emulation Station menu, I added a line to the bottom of retroarch.cfg:
input_exit_emulator_btn = "8"
There is a very real risk that a misplaced thumb will hit the guide button instead of Back or Start and boot me out unexpectedly, but you may consider it an acceptable trade-off. On the other hand, it may be a better idea to map the guide button to save the game state (by default, the F2 key does this).
The keyboard is still convenient for saving and loading game states, and I don’t know if all of the functions can be mapped to buttons on the controller (it sounds like it’s not possible), so it stays within reach for now.
While playing a game:
F2 – save state to current slot (defaults to slot 0)
F4 – load state from current slot (defaults to slot 0)
F6 – decrease the save slot (defaults to slot 0)
F7 – increase the save slot (defaults to slot 1)
F8 – take a screenshot (saved to the ROM’s directory)
F9 – mute audio
While in the Emulation Station GUI (such as it is):
Arrow keys – navigate through ROMs and systems (consoles)
Enter – launch the selected ROM
F1 – restart or shutdown the Raspberry Pi (once you enter this menu, you’re kinda stuck unless you hit F4)
F4 – terminate Emulation Station and return to the command prompt
Recently, themes for each console have been developed for the Emulation Station, which I think everyone would agree could really use a designer’s touch. The theme files can be downloaded from aloshi.com/emulationstation, and some simple instructions can be found in the readme of the Emulation Station project at github at https://github.com/Aloshi/EmulationStation/blob/master/THEMES.md.
So that’s that. I’m playing Final Fantasy and Super Mario Bros. 3 for the first time in years, and it’s pretty neat.
Some games, or maybe all games that scroll from top to bottom, but certainly Final Fantasy and Dragon Warrior, tend to artifact at the top and bottom of the screen when walking north and south on the world map. I haven’t begun to try to tinker with the video settings in order to alleviate this problem.
I seemed to be having a problem restoring from save states when I built my first RPi/RetroArch box back in early October, 2012. If I changed to a different emulator (and possibly to another game within the same emulator), I lost the ability to later load from a save state. The load would fail. I could, however, successfully save and restore as long as I stayed within a game. Resolving this problem was one of the reasons I rebuilt the whole thing from scratch in late January, 2013. It doesn’t seem to be a very common problem, however, as I’ve only found one thread that describes exactly my initial problem, and that was for RetroArch on the PS3: http://forum.themaister.net/viewtopic.php?id=231. In that thread, the OP pinpoints the problem to changing emulators, after which the save state files cannot be loaded. To my mind, this indicates the problem lies outside the save state files themselves.
But my problem was sadly not resolved with the rebuild, and in some ways is actually worse after the rebuild. Not only can I neither save nor load states in games with save state files created before the rebuild, but now, instead of the save/load message that is typically output to the screen as yellow letters, I just get a black box (possibly with black letters, rendering the text impossible to read) whenever I trigger a save or load. After I renamed or deleted the old savestate files in the ROM’s directory, I was able to create a new save state without issue and load it.
This is rather disappointing for games that I had played for awhile and was relying on the save state, but I guess I can live with starting over.
A possible work around to this problem, for games that support saving in-game, is to use the rewind feature instead of save states to undo mistakes as soon as they happen, and then rely on the in-game saves. For games that don’t support in-game saves, I guess I’m SOL until I get it figured out.
The NES theme, at least, seems a little goofy. It looks like the game titles are supposed to be listed on the right-half of the screen, but they are centered instead.
When I launch a NES game, I get two warnings in the terminal:
RetroArch [WARN] :: ORGB155 pixel format is deprecated, and will be slower. For 15/16-bit, RGB565 format is preferred.
RetroArch [WARN] :: [GL]: Stock GLSL shaders will be used.
I was having a few problems with
xboxdrv and wireless controllers, in the early days. When using the USB Xbox 360 Wireless Gaming Receiver for Windows through a USB hub, approximately 60 seconds after launching
xboxdrv, xboxdrv will crash and I’ll get an error stating [ERROR] USBController::on_read_data(): failed to resubmit USB transfer: LIBUSB_ERROR_NO_DEVICE followed by Shutdown complete. This doesn’t happen when using a wired controller or when the USB Xbox 360 Wireless Gaming Receiver for Windows is connected directly to the USB port on the RPi, so maybe a powered USB hub would produce a better experience. I’ve also heard that the Xbox 360 Wireless Gaming Receiver for Windows draws a lot of power, so it may be a good idea to get it working through a powered hub anyway.