NOTE: This Gist was an early write-up of this blog post, part of what became an eleven-part series on my arcade cabinet. I'd suggest you read that post instead of this, but some of the comments on this Gist contain updates and field reports that you might find useful.
I wanted LEDBlinky-style functionality out of my RetroPie cabinet. But I didn't need RGB control or magical frontend integration or anything like that. I had buttons with simple single-color LEDs.
I've got a simple control panel with six buttons per player. All I wanted was this:
- When I launch Street Fighter 2, all twelve buttons should light up.
- When I launch The Simpsons, only the first two buttons for each player should light up.
- When I launch Pac-Man, none of the buttons should light up.
You get the idea.
Here's a demonstration in the form of a shaky video.
Here's how I did it.
I got a Pac-Drive from Ultimarc. It's got 16 terminals for LEDs. 1–6 control Player 1's buttons; 7–12 control Player 2's buttons. The remaining four terminals got devoted to the start buttons (13 and 14), the coin buttons (both on 15), and four small buttons I use for functions (all on 16).
After all that's wired up, all you need is a single USB cable running to your Pi — or, even better, to a powered USB hub that is itself connected to the Pi. The LEDs get powered from USB.
Most of the software for the Pac-Drive is meant for a Windows environment. After some digging, I found this third-party utility for Linux that allows for controlling a Pac-Drive from the command-line. It was exactly what I needed, though it was eight years old and took some wrangling to get installed on a Pi.
From a stock RPi with Raspbian Jessie, you'll need at least these packages:
sudo apt-get install libusb-dev build-essential
You'll also need libhid
, which is hard to find because it's deprecated. There's no package for it in APT, the source code is behind a login for some reason, and then you've got to make a change to the source to get it to compile on the Pi. I solved all three problems by applying that fix and then putting up the fixed source on my server.
From your home directory:
mkdir src && cd src
wget "http://andrewdupont.net/pi/libhid-0.2.16.tar.gz"
tar xvzf libhid-0.2.16.tar.gz
cd libhid-0.2.16
./configure
make
sudo make install
Now we're ready to install the pacdrive
utility.
cd ~/src
wget "http://www.zumbrovalley.net/pacdrive/dnld/pacdrive_0_2.tar.gz"
tar xvzf pacdrive_0_2.tar.gz
cd pacdrive_0_2
make
If you do make install
it'll put the pacdrive
binary in /usr/bin
, though you can edit the Makefile
beforehand to specify a different directory. I did neither; I just manually copied the pacdrive
binary to /home/pi/bin
. (If you do this, make sure you put /home/pi/bin
in your PATH
.)
So now you can control the LEDs from the command line, but that doesn't help much.
One option here would be to use something called controls.dat
, which is a project for cataloguing the controls for most MAME games. (4-way joystick? 8-way? How many buttons? How many players? Hotseat, or does each player have their own controls? And so on.)
The problem with this approach is that (a) the controls.dat
project is dormant; (b) there are lots of gaps in its database.
If you're anything like me, you don't need a comprehensive solution. I don't care how many buttons some random mah-jongg game uses because I'll never play it. I've got about 100 arcade games set up and I don't mind specifying their configs manually.
So here's what I came up with:
- Create a
/home/pi/leds
directory. - Inside that directory, create another directory for each system you want to control. (I've got
arcade
anddaphne
; you might have others.) - Inside each system's directory, define a text file whose name matches the name of the game. For instance:
simpsons2p
is the ROM name for the two-player version of The Simpsons, so I'd create a file calledsimpsons2p.cfg
with these contents:1, 2, 7, 8
. In other words: light up buttons 1, 2, 7, and 8, and turn off all the other LEDs.
This way it's simple to define new configs and simple for RetroPie to know where to look for configs knowing only the system and the ROM name.
All emulator launches go through something called runcommand.sh
. There's a new feature in RetroPie 4.x: the ability to define scripts called runcommand-onstart.sh
and runcommand-onend.sh
. These scripts will run before a game starts and after a game ends, respectively, and they receive some metadata, including the name of the system and the name of the game.
If you want to do it exactly how I did:
cd /opt/retropie/configs/all
nano runcommand-start.sh
(shouldn't needsudo
, but I might be wrong)- Paste the contents of the
runcommand-onstart.sh
from this gist. - Repeat steps 3 and 4 for
runcommand-onend.sh
.
These scripts reference two other scripts called led-start
and led-end
, which you should put in /home/pi/bin
. This is completely overengineered, but it lets me define some buttons as "always on" without having to include them in every single config file. That happens in a file called /home/pi/.ledrc
. Here's what mine looks like:
+13, +14, +15, +16
That means "always light up both start buttons, the coin buttons, and the small function buttons." You can read the source of led-start
to learn more.
If you want to use these scripts, you'll need Ruby, which isn't installed by default on Raspbian Jessie. sudo apt-get install ruby2.1
should take care of it.
What if a game doesn't have a config? Well, if you followed these instructions to the letter, none of the buttons for either player will light up. That's fine with me, because I don't have any games without configs. You might want it to do something different in that situation.
If this doesn't work, it's probably because I left something out. Leave a comment and we'll figure it out together.
Hi, i get Error when trying to install on PRI4/400, any chance for a Fix ? - pi@retropie:~/src/libhid-0.2.16 $ sudo make install
Making install in hidparser
make[1]: Entering directory '/home/pi/src/libhid-0.2.16/hidparser'
if /bin/bash ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I. -I.. -DNDEBUG -fPIC -O2 -Wall -W -Werror -MT hidparser.lo -MD -MP -MF ".deps/hidpa rser.Tpo" -c -o hidparser.lo hidparser.c;
then mv -f ".deps/hidparser.Tpo" ".deps/hidparser.Plo"; else rm -f ".deps/hidpar ser.Tpo"; exit 1; fi
gcc -DHAVE_CONFIG_H -I. -I. -I.. -DNDEBUG -fPIC -O2 -Wall -W -Werror -MT hidpar ser.lo -MD -MP -MF .deps/hidparser.Tpo -c hidparser.c -fPIC -DPIC -o .libs/hidp arser.o
gcc -DHAVE_CONFIG_H -I. -I. -I.. -DNDEBUG -fPIC -O2 -Wall -W -Werror -MT hidpar ser.lo -MD -MP -MF .deps/hidparser.Tpo -c hidparser.c -o hidparser.o >/dev/null 2>&1
/bin/bash ../libtool --tag=CC --mode=link gcc -fPIC -O2 -Wall -W -Werror -o li bhidparser.la -static hidparser.lo
rm -fr .libs/libhidparser.a .libs/libhidparser.la
ar cru .libs/libhidparser.a hidparser.o
ar:
u' modifier ignored since
D' is the default (see `U')ranlib .libs/libhidparser.a
creating libhidparser.la
(cd .libs && rm -f libhidparser.la && ln -s ../libhidparser.la libhidparser.la)
make[2]: Entering directory '/home/pi/src/libhid-0.2.16/hidparser'
make[2]: Nothing to be done for 'install-exec-am'.
test -z "/usr/local/include" || mkdir -p -- "/usr/local/include"
/usr/bin/install -c -m 644 'hidparser.h' '/usr/local/include/hidparser.h'
/usr/bin/install -c -m 644 'hidtypes.h' '/usr/local/include/hidtypes.h'
make[2]: Leaving directory '/home/pi/src/libhid-0.2.16/hidparser'
make[1]: Leaving directory '/home/pi/src/libhid-0.2.16/hidparser'
Making install in src
make[1]: Entering directory '/home/pi/src/libhid-0.2.16/src'
if /bin/bash ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I. -I.. -DNDEBUG -fPIC -I../include -I../hidparser -O2 -Wall -W -Werror -MT linux.lo -MD -MP -MF ".deps/linux.Tpo" -c -o linux.lo linux.c;
then mv -f ".deps/linux.Tpo" ".deps/linux.Plo"; else rm -f ".deps/linux.Tpo"; ex it 1; fi
gcc -DHAVE_CONFIG_H -I. -I. -I.. -DNDEBUG -fPIC -I../include -I../hidparser -O2 -Wall -W -Werror -MT linux.lo -MD -MP -MF .deps/linux.Tpo -c linux.c -fPIC -DP IC -o .libs/linux.o
In file included from linux.c:6:
../include/hid.h:5:10: fatal error: usb.h: No such file or directory
#include <usb.h>
^~~~~~~
compilation terminated.
make[1]: *** [Makefile:427: linux.lo] Error 1
make[1]: Leaving directory '/home/pi/src/libhid-0.2.16/src'
make: *** [Makefile:394: install-recursive] Error 1
Something about missing USB.h ?