I’m a child of the 1980s. Miami Vice! Skinny ties! Big hair! Honest, I had hair then…and every town had at least one good video game arcade.

Thanks to the super affordable Raspberry Pi and some clever software, anyone can re-create the classic arcade experience at home. Adafruit brings the genuine “clicky” arcade controls, you bring the game files and a little crafting skill to build it.

Classic game emulation used to require a well-spec’d PC and specialized adapters for the controls, so it’s exciting to see this trickle down to a $40 computer.

Picking a Game Emulator

Before you begin with adding an arcade control you'll need some games to play! In particular we're going to be talking about Retro Gaming here

Retro gaming is one of the most popular uses for the Raspberry Pi, and there are now a multitude of ready-to-go SD card images packed with emulator software (though most require sourcing your own ROM files). The days of installing emulators onesy-twosey are behind us; and the Pi Store (an online app store for Raspberry Pi, recommended in earlier versions of this guide) was shuttered in 2015.

Which emulator is for me?

Before committing to a big arcade project build, we recommend testing one or more of these packages with a keyboard connected and confirm you can set up and run all the games you’re most interested in…then move ahead with more interesting controls.

These are all free downloads, so there’s no harm in downloading them all and seeing what fits your tastes. Also, as you work with each one and tweak and tune, it’s not uncommon to have to wipe and start over. Keep careful notes of your setup process and any configuration changes you make!

Once you've downloaded an emulator image, burn it onto your SD card using these instructions

Help - this emulator doesn't work!

If you encounter difficulty with these packages or just need tips on setting them up, please visit the FAQ and/or support forum on the corresponding project’s web site, not the Adafruit Forums. They’ll be better equipped to answer questions about their own software.

(We can only help out if you have questions specifically about our arcade controls or the retrogame software we’ll introduce on the last page. Please ask for such help in the Adafruit Customer Support Forumsdo not submit support questions as bug reports on GitHub, they’ll be ignored there…and be as specific as possible in describing both the variant of Raspberry Pi hardware you’re using and which software package and release, exact version number or date, etc. Thanks!)

So! Here are a few gaming OSes we’re currently aware of…

Once you've picked it out and installed it on your Raspberry Pi, you can continue to the next step


This is our recommended emulator package!

From the RetroPie web site:

“RetroPie allows you to turn your Raspberry Pi or PC into a retro-gaming machine. It builds upon Raspbian, EmulationStation, RetroArch and many other projects to enable you to play your favourite Arcade, home-console, and classic PC games with the minimum set-up. For power users it also provides a large variety of configuration tools to customise the system as you want.

“RetroPie sits on top of a full OS, you can install it on an existing Raspbian, or start with the RetroPie image and add additional software later. It's up to you.”

From the site’s Download page, there are separate versions of RetroPie optimized for single- and multi-core Raspberry Pi boards (i.e. Pi Zero, original Model A or B, A+ or B+ versus the multi-core Pi 2 and Pi 3); these are not cross-compatible; be sure to start with the right version for your model of Pi!

In particular, we like the 3.8.1 release (see all releases here)

Click here to download the v3.8.1 release for Raspberry Pi 2 and 3

Click here to download the v3.8.1 release for Raspberry Pi Zero and 1

Breaking down some of the jargon above…

  • Raspbian is the standard and most popular Linux operating system distribution for the Raspberry Pi; it’s what most people start with when setting up a Raspberry Pi for “normal computer stuff.”
  • EmulationStation is a graphical front-end that lets you select among different emulators or games installed on the system, as well as configure gaming controls and other options.
  • RetroArch is among the broadest and most popular multi-platform emulators…this is the code that runs the actual games. But it’s not the only one…RetroPie (and most other gaming OSes) collect several others for different situations.


From the PiPlay web site:

“PiPlay, formerly called PiMAME, [is a] pre built Raspberry Pi OS made for gaming and emulation.

“Also included is a suite of software designed to reduce the complexity and time needed to setup a fully working system. An updater is included with the distribution.”

PiPlay lacks the breadth and active development of RetroPie; it’s not currently Pi 3 or Zero compatible, hasn’t been updated since 2015 and the forums are falling victim to spambots. Still, some users report an easier time configuring things here than other distributions…as long as you’re running on the right hardware.


From the Recalbox web site:

“Recalbox offers a wide selection of consoles and game systems. From the very first arcade systems to the NES, the MEGADRIVE and even 32-bit platforms, such as the Playstation.

“With Kodi already included, Recalbox also serves as a Media Center. By connecting it to your home network, you will be able to stream videos from any compatible devices (NAS, PC, External HDD, etc.).”

A relative newcomer with an impressive variety of emulated systems. One SD card image (from their DIY recalbox” link) is compatible with all current Raspberry Pi boards (no separate single- or multi-core downloads).

It appears that recalbox has its own support for interfacing arcade buttons and joysticks to the Pi’s GPIO header, obviating the need for our own software explained on the last page. Have not experimented with this yet!


From the Lakka web site:

“Lakka is a lightweight Linux distribution that transforms a small computer into a full blown game console.

“Lakka is the official Linux distribution of RetroArch and the libretro ecosystem.

“Each game system is implemented as a libretro core, while the frontend RetroArch takes care of inputs and display. This clear separation ensures modularity and centralized configuration.”

Lakka is not as all-inclusive as other packages, but as a result it’s extremely compact. There are separate downloads for single- and multi-core Raspberry Pi boards.

Adding Controls: Hardware

At this point you should have one (or more) games playable from the keyboard. The next step is adding nifty controls…

Console-Style Controls with USB

If you’re aiming for a home TV gaming console feel, things are super easy: a variety of USB-compatible gaming controllers exist that’ll plug straight into the Pi and you’re done!

If aiming to simulate a particularly nostalgic console, chances are you can find an equivalent controller in USB format. Look around a site like NewEgg or just Google search for some options…I’ve seen classic-style controllers resembling the NES, Genesis, Playstation and more, as well as USB adapters if you’d prefer using actual original controls.

Pictured: Logitech F310

Arcade and Handheld Gaming Controls

Let’s look at arcade-style controls first, since they’re physically larger and thus easier to work with…

Just as there are USB console-style controllers, so too are there USB arcade-style setups. They’re often a bit costly though…also, nearly all of them are laid out for 1990s fighting games. If the ready-mades meet your needs, fantastic. But maybe you want something simpler, or may have ergonomic preferences (I’ve always prefered right-handed joysticking, for example). Making your own control box (or even a whole cabinet) is a satisfying DIY project!

This is where things take a creative turn. There’s no One Right Way™ to arrange controls that can cover every game. Instead, pick a few favorites and devise a layout that handles the most frequently-used inputs well. For everything else, you can still use a keyboard.

You’ll also need to build your control panel using the materials and tools best suited to your own skills. I’m fortunate to have access to a laser cutter that can work with acrylic, but that’s a tall order for most. Scrap plywood or a metal project box are viable materials (a cigar box works great too!), while a drill, hole saw, Dremel tool or wood rasp are all reasonable tools for making holes. Improvise!

We have a nice assortment of arcade-style controls in the shop…

Our Small Arcade Joystick is the gamer’s equivalent of the IBM Model M keyboard — clicky and built like a tank!

This is an 8-way “digital” joystick. Most classic games are designed for this type of stick, and it’s easy to interface…the Raspberry Pi can’t read proportional “analog” joysticks directly.

Our 30mm Arcade Button is available in six different colors and is similarly industrial-grade. Any momentary push-type button (“normally open” contacts) will also work.

Large (60mm) and Massive (100mm) arcade buttons come in five colors and are irresistible! These bigger buttons are typically seen on quiz games rather than fast-twitch shooters.

A classic Atari or Commodore joystick can also be used, since these are just passive switches internally. Most later gaming consoles used serial protocols for their controls…unfortnately those won’t work here…but as mentioned previously, USB clones exist for most.

We offer a variety of arcade controls, but we don't sell COMMON SENSE. When drilling and cutting, take precautions such as wearing SAFETY GLASSES, always cut AWAY from yourself, etc.

Connecting to the Raspberry Pi

The controls will be wired to the 40-pin GPIO (general-purpose input/output) header on the Raspberry Pi board.

Early model Raspberry Pi boards had a 26-pin header…same idea, just with fewer spots to connect things.

Each pin on this header has a unique “GPIO number” …not in-order, but we provide a map below for translating. Buttons and a joystick (each of 4 directions) will connect between any available GPIO pin and a ground (GND) pin.

This map is turned 90- degrees from the photo above…so the 5V pins are nearest the corner of the board, while GPIO21 is nearest the USB connectors:

  • All of the green pins are fair game for connecting buttons.
  • Yellow pins may or may not be available for controls, depending what hardware features are enabled on the system:
    • GPIO2 and GPIO3 are off-limits if using any I2C peripherals (for example, most real-time clock boards).
    • GPIO14 and GPIO15 are off-limits if using the TTL serial port (for example, with a serial console cable, or thermal printer).
    • If using one of our PiTFT displays (as most of our portable gaming projects do), another seven GPIO pins are out of commission: GPIO7-GPIO11 and GPIO24-25.
    • Our I2S audio amplifier board needs GPIO pins 18, 19 and 21.
  • Avoid red pins, these carry power and aren’t suitable for controls.
  • Black pins are ground points. The other leg of each button (and the “common” pin from a joystick) will need to connect to one of these. There are several scattered around…if you need more, one of our small Perma-Proto boards can be used to provide a single large “ground rail” where one side of all the buttons can be connected. Alternately, if you have extra unused GPIO pins and just need a couple extra ground connections, we’ll show a software work-around for this.

Do I need Pull-up or Pull-down resistors?

You do not need external pull-up resistors for the buttons or arcade controller…they can wire direct to the GPIO pins and grounds. The Raspberry Pi has its own “internal” pull-ups.

Just as the layout and build technique of the control panel requires creative interpretation, so too will you need to decide on your own wiring methodology. We have some parts that can help. Aside from the aforementioned Perma-Proto board, there are quick-connect wires that work with the buttons and jumper wires in various lengths that can be used with a joystick or plug directly into the GPIO pins (without a Perma-Proto board). Options abound! You’ll likely need some combination of these, and may need to solder some connections.

Example: Connecting an Arcade Joystick & 2 Buttons

Here’s a pinout diagram for our arcade stick. Only one wire needs to go to GND, then each of the other four goes to a different GPIO pin.

These directions apply when the stick is oriented with the header at the top. It’s fine to install the stick in a different orientation, you’ll just need to adapt the wiring connections to match.

If using quick-connect wires for buttons: the end plug tends to block adjacent pins on the GPIO header. You can trim it down a bit using an X-Acto knife or Dremel tool, or cut the plugs off and solder the wires to a Perma Proto board, or simply plan out your wiring to avoid nearby pins…

  • Joystick UP: GPIO10
  • Joystick DOWN: GPIO17
  • Joystick LEFT: GPIO23
  • Joystick RIGHT: GPIO9
  • Button A (one contact): GPIO23
  • Button B (one contact): GPIO 7
  • Joystick Ground, Button A & B second contacts: GND (theres a bunch of GND pins available)

Here’s a basic no-soldering wiring setup we use for TV gaming with one joystick and two buttons, using 5 female-to-female jumpers (small white squares) for the joystick and two unmodified quick connects (larger white rectangles) for the buttons. Notice how the quick connects each span a GPIO and adjacent ground pin.


It’s a pretty basic layout, but sufficient to accommodate quite a few classic games. For the remaining seldom-used functions (coin insert, start game), a regular USB keyboard is kept nearby.

An example case I made from laser-cut acrylic, but any workable material will do. A cigar box makes a great fit!

The case should be at least 50mm (2 inches) deep to accommodate the buttons and solderless connectors.

The shelf at the top holds a small USB keyboard. This is a catch-all for seldom-used functions (e.g. coin or game start). Only the essential controls were assigned to arcade buttons…but keep adding others if you like!

Adding More Buttons

Here’s an example layout if we want to add six buttons plus a joystick, using the same button quick-connects:

This layout avoids most of the peripheral pins (e.g. I2C), but does use pins that would be required for a PiTFT display…so this is only viable if using HDMI or composite video out.

This is mostly due to the size of the button quick-connect plugs. Trimming the flanges off with an X-Acto knife, you can probably create a more compact arrangement.

“A”, “B”, “X” and “Y” here refer to the controller button names used in EmulationStation, not necessarily the keys to which they’re assigned.

Example: A Mini Portable Gaming Handheld

For handheld projects, the principles are the same as above, just squeezed into a very constrained space. Smaller components are used and the connections are a bit more challenging.

You’ll find examples in our PiGRRL, PiGRRL 2, Pocket PiGRRLPiGRRL Zero and Super Game Pi projects.

Most of these use a PiTFT display, so there’s a set of GPIO pins that are off-limits. Otherwise, it’s all the same idea…buttons wired to GPIO and ground pins.

The Raspberry Gear project uses a different approach…a microcontroller acts as an intermediary to the Pi’s USB port.

In earlier projects, we’d hack apart an actual game controller to repurpose the buttons and circuit boards. More recently, we’ve started producing custom gamepad PCBs to which buttons and wires can be soldered:

Installing Retrogame

If using a USB game controller, there’s nothing to see here…you’re done, go ahead and play! These directions apply if you’re using custom controls as covered on the prior page.

Our retrogame utility is the software glue that links our GPIO-connected controls to “virtual” keyboard input.

Some of our projects (eg PiGRRL Zero) provide a ready-made SD card image…if you’re building with the same hardware combo, it’s good to go with no changes, retrogame is already installed. Otherwise…

Download and Install

We have a script to help set this up. You’ll need access to the Pi’s command line…either log in over the network using ssh, or the emulation package you’re using should have some option to access a command line (e.g. with RetroPie, press “F4”).

Then type (or copy & paste, if using ssh):

curl -O https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/retrogame.sh
sudo bash retrogame.sh

When run, you’ll be asked to pick one of several control configurations. For example, if using the simple joystick-and-two-buttons arrangement from the prior page, pick #2. If you’re planning on making your own custom setup, just pick any of these, and we’ll explain on the next page how to customize this.

If you’ve installed retrogame previously, you’ll be warned that its configuration file will be rewritten. Press “y” if that’s okay. Otherwise, exit and make a backup of that file, so you can restore it later.

The script then downloads and installs the retrogame executable (/usr/local/bin/retrogame) and configuration file (/boot/retrogame.cfg), then performs some administration tasks…/etc/rc.local is amended to make retrogame launch on startup, and a “udev rule” file (/etc/udev/rules.d/10-retrogame.rules) is generated to help it simulate a keyboard.

Once finished (should only take a moment), you’ll be prompted to reboot.

If you have other setup tasks to perform (installing other packages, or changing overscan settings using raspi-config), you don’t need to reboot just yet…answer “n” in that case.

Configuring Retrogame

New retrogame: Settings File

The latest version of retrogame reads the file /boot/retrogame.cfg on startup. A sample retrogame.cfg file was placed there by our installer on the prior page.

Below is an example from the PiGRRL 2 configuration file: There’s a lot of stuff in there but really it’s pretty simple…most of it is comments, which start with a ‘#’ character.

# Sample configuration file for retrogame.
# Really minimal syntax, typically two elements per line w/space delimiter:
# 1) a key name (from keyTable.h; shortened from /usr/include/linux/input.h).
# 2) a GPIO pin number; when grounded, will simulate corresponding keypress.
# Uses Broadcom pin numbers for GPIO.
# If first element is GND, the corresponding pin (or pins, multiple can be
# given) is a LOW-level output; an extra ground pin for connecting buttons.
# A '#' character indicates a comment to end-of-line.
# File can be edited "live," no need to restart retrogame!

# Here's a pin configuration for the PiGRRL 2 project:

LEFT       4  # Joypad left
RIGHT     19  # Joypad right
UP        16  # Joypad up
DOWN      26  # Joypad down
LEFTCTRL  14  # 'A' button
LEFTALT   15  # 'B' button
Z         20  # 'X' button
X         18  # 'Y' button
SPACE      5  # 'Select' button
ENTER      6  # 'Start' button
A         12  # Left shoulder button
S         13  # Right shoulder button
ESC       17  # Exit ROM; PiTFT Button 1
1         22  # PiTFT Button 2
2         23  # PiTFT Button 3
3         27  # PiTFT Button 4

# For configurations with few buttons (e.g. Cupcade), a key can be followed
# by multiple pin numbers.  When those pins are all held for a few seconds,
# this will generate the corresponding keypress (e.g. ESC to exit ROM).
# Only ONE such combo is supported within the file though; later entries
# will override earlier.

The important lines, in the middle, consist of a key name followed by a GPIO pin number. That’s really all there is to it.

Your basic letter and number key names are straightforward…for function keys and such, you can look in the file keyTable.h (included alongside the retrogame executable) for valid names, or in /usr/include/linux/input.x (remove the initial “KEY_” from the name).

If you want to use a GPIO pin as a spare ground for buttons: use “GND” as the key name, then list one or more pin numbers separated by spaces.

If you need just one more key…not as a gaming control, but for accessing menus or similar…follow a key name with multiple pin numbers (these can already be assigned to other keys themselves, that’s fine). When those buttons are all held for a few seconds, the corresponding keypress will be generated. We used this in our Cupcade project to access the Escape key. Currently only one such multi-button combo can be assigned.

If you want to put retrogame.cfg somewhere other than /boot, or assign a different name: in /etc/rc.local, where retrogame is being run, insert the absolute pathname to your configuration file as an argument (i.e. just before the “&”):

/usr/local/bin/retrogame /boot/myConfig.cfg &

Locating the configuration file in /boot makes it easier to edit this file on a non-Pi system, since the SD card can be inserted in a USB reader and accessed from most any computer.

If editing in /boot directly on the Pi, you’ll need to do this as root, i.e. sudo nano /boot/retrogame.cfg

If you change the name or location of the configuration file, you’ll need to reboot or restart retrogame. But if you’re just editing the pin assignments in the existing file, there’s no need…retrogame will pick up on these changes automatically, while its running, once changes are written to the file.

Configuring Older Retrogame

This is for the old version of retrogame that required recompilation. You probably don't need this page but its here for historical purposes!

Classic retrogame: Edit Source Code

Assigning keys and buttons in the old retrogame is quite a bit more involved…this is why we recommend just downloading and installing the newer version. But if this is what you have around, here’s the procedure…

Edit the retrogame.c file in the unZIPped Adafruit-Retrogame directory…

cd Adafruit-Retrogame
nano retrogame.c

About a hundred lines down, you’ll see a table that looks like this:

ioStandard[] = {
        // This pin/key table is used when the PiTFT isn't found
        // (using HDMI or composite instead), as with our original
        // retro gaming guide.
        // Input   Output (from /usr/include/linux/input.h)
        {  25,     KEY_LEFT     },   // Joystick (4 pins)
        {   9,     KEY_RIGHT    },
        {  10,     KEY_UP       },
        {  17,     KEY_DOWN     },
        {  23,     KEY_LEFTCTRL },   // A/Fire/jump/primary
        {   7,     KEY_LEFTALT  },   // B/Bomb/secondary
        // For credit/start/etc., use USB keyboard or add more buttons.
        {  -1,     -1           } }; // END OF LIST, DO NOT CHANGE

Careful now…make sure you’re editing the ioStandard[] table, not the similar-looking ioTFT[] table. The latter applied specifically to the Cupcade project and nothing else.

Within each set of braces is a GPIO pin number and a corresponding key name (from /usr/include/linux/input.h). Because we’re editing C source code, it’s vitally important to maintain the syntax exactly. Open brace, number, comma, key name, close brace, comma. The last item must be {-1, -1}.

If you need an extra ground pin (and have extra GPIO pins available that you’re not using for controls), set the key code to GND instead.

Write your changes to the file and exit the editor, then type:

make retrogame

This should build the retrogame executable. If you instead get an error message, there’s a problem in the edited table — most likely a missing curly brace, comma or semicolon.

Depending what’s in /etc/rc.local, you might need to move retrogame to a different location (such as /usr/local/bin). Reboot to use the new settings. Test it out…if anything needs changing, you’ll have to repeat the whole edit-compile-move-reboot sequence.