MAME Cabinet


In 2008, Sears was selling the "Extreme Arcade" made by Chicago Gaming Company for a couple hundred bucks. I picked one up and it was OK. It had a couple dozen old Atari and Taito games on it, but most of them were "remastered", aka not original. It also couldn't save games.
Then I got some Raspberry Pis and converted this cabinet over to a pi based MAME cabinet.

Buttons

The cabinet's controls are all simple switches, including the 4 direction joysticks. With the joysticks, it has a total of 18 switches. The joysticks are all wired to connectors connecting to a small custom ARM based controller board. I ordered some mating connectors, a 2.54mm header, some ribbon cable, and some IDC connectors. I soldered the connectors and header to some copper clad perfboard, and made a cable between the rpi and the perfboard with the ribbon cable and IDC connectors. I connected a 1K resistor between the GPIO pin and the buttons to limit current draw, and that's pretty much it. The rpi has 17 GPIO pins on the P1 connector and 4 more on the P5 connector, which was plenty for the buttons the cabinet had.

Display

The cabinet had a 20" CRT in it. Initially I used a Lenovo HDMI to VGA adapter with the stock CRT. Unfortunately, the CRT died. I ended up replacing it with a Dell 1908fp LCD. It fits almost perfectly, with just a little bit of the screen below the bottom bezel. I put a VESA mount on a 2x4 piece of scrap wood, and mounted the panel to that, which was then mounted in the cabinet. It works great. I then use an HDMI to DVI cable to connect the rpi to the display.

Raspberry Pi

I started off with the pimame Linux distribution for the rpi, which is a customized Raspbian. This was OK initially, but it boots to a rather unexciting terminal based menu. I ended up modifying it to use Emulation Station as the menuing system. Since the cabinet has 3 buttons per player (plus start buttons for each), it can reasonably simulate some arcade games, NES, and Sega Genesis games, so that's what I've got it configured for. Configuration here.

To make the GPIO pins generate keystrokes, I use a simple python script based on the script from here. It essentially polls the GPIOs for changes and generates keyboard key up/down events using the Linux uinput kernel module. Player 1's joystick is mapped to the up/down/left/right keyboard keys, and the main button for Player 1 is mapped to Enter, so it just works with most configurations.

I've converted this from a polling python script (which consumes CPU and has higher latency on detecting changes) to a C program using the rpi's sysfs interface for userland gpio interrupts. This gives more CPU for emulation, and faster response time on the controls. Here is the code.

MAME

MAME is a bit unintuitive in how it works.
MAME hard codes the list of ROMs, their names, and their checksums/sizes, etc. And with each release things are added, changed, and rearranged.

Also, MAME ROMs are not standalone. They have parent/child relationships in the sense that the parent ROM has all the files it needs to run (maybe), and variations on that ROM will only include the files that changed. So for example, Pac-Man is a variation on the Japanese version Puckman. So the pacman.zip ROM can't run without the puckman.zip ROM being present. There's not really any good way to view these relationships. The windows-based MAME UI program has all that hard coded into it, so you need to find the version of MAMEUI that corresponds to the ROM set you have.

These relationships can change from release to release. The "maybe" I added in there refers to other ROMs that may be necessary, like for NeoGeo systems, they need the neogeo BIOS ROM. And for CPS2 systems, they have a qsound chip that needs the qsound ROM too. All of this changes from release to release as new hardware is emulated, or whatever.

So, you really need the ROM set that matches the release of MAME you're using. Any old MAME ROM may or may not work depending on what ROM set it is from, what MAME version you're using, and what changed in the interim between those two releases.

MAME4ALL is based on version 0.37b5 of MAME, which is a particularly old release of MAME. But it has its reasons. Mainly, that is when fundamental changes to MAME took place that made it less suitable for lower powered systems. That's also the reason MAME4ALL is typically used on phones and other devices. Since it is a particularly old version of MAME, it also doesn't have support for everything that has been added in the interim.

Display Sleep

By default, the Linux console on the rpi will send a CEC STANDBY command to the connected HDMI display depending on the configuration set with setterm. However, this doesn't work if 1) you're not at the Linux console, and 2) with HDMI -> !HDMI adapters. However, Broadcom provides some interfaces for the rpi to turn off the HDMI interface entirely, which will sleep the display if you have HDMI to !HDMI adatpers, such as my HDMI to DVI setup. The tvservice command provided by Broadcom provides a command line interface to this API.

I added an option to EmulationStation to sleep the HDMI interface using the Broadcom API. This actually works out really well, since I can pretty much leave the cabinet turned on, with the display sleeping automatically, and use very little power when not in use.

Updated July 11 2013