When I created the arcade cabinet, I wanted light up buttons because I knew I wanted the lighting configuration to change with each platform being played.
I found RGBCommander online, which was deprecated and unsupported, meanwhile it worked on my console when I figured it out. During this process, I found another tool, LED Spicer, that I’m not going to use because I’m too far invested with RGBCommander, but if I ever upgrade the OS behind my RetroPie setup, I may consider switching.

RGBCommander has been great, I love it, but it’s also not the easiest to setup. The main configuration file is an XML file that contains thousands of lines for multiple systems, game-specific lighting, folder-level for multi-disc/disk games, etc. It can get mind boggling, and if you edit the file once, add a system and come back again, it can be painful to remember how the file works to then execute.
The panel we started with
The cabinet uses an Ultimarc I-PAC Ultimate I/O as its combined input and lighting interface. The control panel includes:
- two illuminated joysticks;
- eight RGB action buttons for each player;
- separate Coin and Start buttons for each player;
- a centrally mounted RGB trackball;
- centre utility buttons labelled Exit, Mode, Menu, and Play; and
- an additional illuminated Coin Insert output.
Each RGB control consumes three LED channels—red, green, and blue. The Ultimate I/O provides enough channels to address the panel controls individually, while RGB Commander changes their colours in response to EmulationStation system and game events.
The authoritative configuration is rgbcmdd.xml, installed on the cabinet at:
/usr/sbin/rgbcommander/rgbcmdd.xml
I have so many backups of this file it isn’t funny. That XML file is much more than a list of colours. It records the relationship between logical controls, physical positions, Ultimate I/O output pins, emulator processes, system profiles, and—in some cases—individual games.
First, understand what the button names really mean
The first trap was the model assuming that the numbered button names followed the panel from left to right. They do not, I had wired them up like this, one set for Player 1, the other for Player 2:
TOP ROW
┌────────┬────────┬────────┬────────┐
│BUTTON2 │BUTTON4 │BUTTON6 │BUTTON8 │
├────────┼────────┼────────┼────────┤
│BUTTON1 │BUTTON3 │BUTTON5 │BUTTON7 │
└────────┴────────┴────────┴────────┘
BOTTOM ROW
Odd-numbered buttons are on the bottom row. Even-numbered buttons are on the top row.
That means this apparently straightforward profile:
<control name="P1_BUTTON1" colour="Red"/>
<control name="P1_BUTTON2" colour="Blue"/>
<control name="P1_BUTTON3" colour="Green"/>
<control name="P1_BUTTON4" colour="Yellow"/>
appears physically as:
Top: Blue Yellow
Bottom: Red Green
This distinction became the foundation for every console profile. A colour list that looks correct in logical button order can be visibly wrong on the real panel.
We found that photographs were indispensable. An early PlayStation layout looked plausible in the XML but revealed the wrong physical placement when illuminated. A later ColecoVision calibration used deliberately distinct colours in each position, making the odd/even arrangement impossible to misread. Once one profile proved the physical map, we could apply the same understanding to both players and every other system.
I used photos, passed into the agent, so it could map the buttons, to the XML definition, to create confidence and build an understanding of how the physical world worked. This blew me away.
Player 2 had a wiring surprise
Player 1 uses the expected RGB channel order. Its joystick occupies pins 1, 2, and 3; Coin uses 4, 5, and 6; Start uses 7, 8, and 9; and the action buttons continue through pins 10 to 33.
The right side of the board is different. Player 2 is wired in BGR order, so its pin triplets are deliberately listed in reverse:
<control name="P2_BUTTON1" pin="75,74,73"/>
<control name="P2_BUTTON2" pin="78,77,76"/>
The same compensation applies to the other Player 2 buttons, joystick, Coin, and Start controls.
At first glance, descending pin numbers look like a configuration error waiting to be tidied up. In reality, they are the correction. Changing them to ascending order would swap red and blue on the entire Player 2 side.
While I knew this as I spent the time wiring up each button, the model behind the agent didn’t, so it had to learn the setup. It discovered this on its own as I provided images and it analyzed the XML.
The trackball introduced a smaller naming complication. Its real hardware name is TRACKBALL, connected to pins 40, 41, and 42. Older profiles also contain P1_TRACKBALL and P2_TRACKBALL aliases. Those aliases are useful for compatibility, but neither one is a substitute for the physical TRACKBALL entry. Removing the middle name would leave the actual illuminated trackball out of the profile.
Recreating familiar controllers on an arcade layout
The most recognizable profiles borrow the visual language of the original controller.
The PlayStation layout uses violet, lime, cyan, and red in the physical positions corresponding to Triangle, Circle, Cross, and Square. The first calibration exposed a placement error when I was programming the XML file manually; the corrected version now appears consistently on both player sides. PSP uses the same face-button arrangement but illuminates Player 1 only, reflecting the handheld’s single-player nature.
The SNES profile uses the familiar green, blue, yellow, and red Super Famicom/PAL palette. Dreamcast uses blue, yellow, green, and red, with subdued additional controls. Saturn uses the Japanese Model 2 pad palette: green, yellow, and blue across the primary bottom row, grey across the upper row, and a muted fourth position.
These profiles are not trying to turn the arcade buttons into perfect replicas. The shapes and spacing are different. Colour provides just enough recognition to make the translation intuitive.
Other systems benefit more from simplicity than authenticity:
- Atari 2600 illuminates one action button.
- Game Gear lights two bottom-row actions for Player 1, along with its Start and joystick treatment.
- SG-1000 exposes two white action buttons for both players.
- WonderSwan and WonderSwan Color use distinct two-button handheld palettes.
- Vectrex presents two actions per player with matching cyan joysticks.
- SuperGrafx illuminates only the first two bottom-row controls in red and blue.
Dark buttons are just as important as lit ones. If a system only needs two controls, six unlit buttons communicate that fact much faster than a diagram hidden in a manual.
Some profiles explain function rather than history
Not every emulated system has one canonical gamepad. Classic computers may use a joystick in one game, the keyboard in another, and a mouse in a third. Ports and Steam titles can vary even more widely.
For those collections, the lighting is intentionally practical:
- pointer-first systems such as Macintosh, ScummVM, ResidualVM, and Z-machine illuminate the physical trackball and likely click actions;
- two-button computer profiles illuminate the first two bottom-row actions and the joysticks;
- the broad PC profile exposes six coloured actions per player, both joysticks, and the trackball;
- controller-driven engines use a conventional four-colour action layout; and
- variable collections such as Ports and Steam use broad diagnostic profiles rather than pretending that every game shares one controller.
This is an important design boundary. The panel should be honest. When the exact layout varies by game, the lights can identify the available control families without claiming more certainty than we have.
Branding can be useful too
The ZX Spectrum profile is a deliberate exception to the usual mirrored Player 1 and Player 2 treatment.
Both gameplay sides use the same red, green, yellow, and blue action arrangement, but the Coin and Start controls form the classic Spectrum colour sequence:
| Control | Colour |
|---|---|
| Player 1 Coin | Red |
| Player 1 Start | Yellow |
| Player 2 Coin | Green |
| Player 2 Start | Blue |
Both joysticks remain dim.
Functionally, the two sides still behave consistently. Visually, the upper controls become a small piece of system branding. Mirroring the Player 1 colours onto Player 2 would be more symmetrical but would erase the point of the design.
System-wide profiles are not always enough
RGB Commander can select a profile from the EmulationStation system name, but some games need more specific treatment.
Arcade collections are the obvious example. MAME games can have ROM-specific button mappings, so the panel can illuminate the controls used by an individual title and fall back to the shared arcade profile when no game-specific definition exists.
SuperGrafx revealed a different version of the same problem. It has its own two-button system profile, but five SuperGrafx titles also appear as per-game emulator routes inside the PC Engine collection: 1941, Aldynes, Battle Ace, Dai Makaimura, and Madou Ou Granzort.
We added matching ROM-specific entries to the PC Engine lighting profile. Those games now receive the red-and-blue SuperGrafx layout regardless of which collection launches them, while ordinary PC Engine titles retain their normal lighting.
The lesson was that the menu folder is not always the whole story. Lighting must sometimes follow the actual game or emulator route rather than the collection label alone.
Lighting must never prevent a game from starting
RGB Commander needs to identify the process that actually runs an emulator. Most Libretro systems eventually launch retroarch. Our Amiga configurations use standalone Amiberry.
The original Amiga lighting entries could leave RGB Commander waiting for the wrong process. Repeated launches filled its message queue, and RetroPie’s start hook could block before Amiberry appeared. A feature intended to clarify the controls was now capable of stopping the game entirely.
We corrected both sides of the failure:
- The Amiga and Amiga CD32 profiles now identify
amiberryas their emulator process. - The launch hook gives RGB Commander two seconds and then continues regardless:
timeout --signal=TERM --kill-after=1s 2s \
rgbparse "$1" "$3" > /dev/null 2>&1 || true
The first correction makes the lighting work. The second establishes the right priority: lighting is helpful, but gameplay is essential. A lighting-service failure must never strand the user outside the emulator.
We validated the correction with A500, A500+, A1200, CD32, and CDTV launches, as well as ordinary Libretro games.
Preserving RGB Commander in Dual DInput mode
The I-PAC also provides the cabinet controls. We keep it in Dual DInput mode so it exposes two independent panel gamepads rather than pretending to be a keyboard or collapsing the cabinet into one Xbox-style player.
RGB Commander 0.4.0.5 recognizes the I-PAC’s older keyboard-mode USB product ID, but not the product ID used in Dual DInput mode. Returning to keyboard mode would have fixed the lights by breaking the input design.
Instead, we created a narrowly scoped compatibility library that is preloaded only into the RGB Commander service. For the Dual DInput device, it changes the product ID reported to that one process. It does not change the real USB descriptor, firmware, input events, or LED protocol, and no other application sees the substitution.
This lets the input and lighting systems remain independent. The virtual gamepad merger handles gameplay controls, while RGB Commander continues to address the physical Ultimate I/O directly.
Our editing and test routine
A lighting change is not complete when the XML looks right. Our normal process is:
- Confirm the physical row and logical button number.
- Define both players for a two-player system, or intentionally limit a handheld to Player 1.
- Preserve Player 2’s reversed BGR pin order.
- Decide explicitly whether unused controls should be dim or fully off.
- Preserve the real
TRACKBALLoutput when compatibility aliases are present. - Validate the XML before installation.
- Back up the live configuration.
- Restart RGB Commander and inspect its service log.
- Launch a Libretro game and a standalone Amiberry game.
- Compare the illuminated panel with the intended physical layout—preferably with a photograph.
The XML is validated before installation with:
xmllint --noout rgbcmdd.xml
After installation, RGB Commander should be active and the emulator launch should never pause waiting for it.
We keep the live XML, a copy beside the full-drive backup, and a working copy on another computer. The file is small, but it represents hours of physical tracing, calibration, system research, and design decisions. Losing it would be more like losing part of the wiring diagram than losing a cosmetic preference.
The result
In the front end, the cabinet can still be playful. The Player 1 joystick is associated with red, Player 2 with blue, and the joystick lighting animates while the buttons display different colours ready for action.
Launch a game and the purpose changes. A one-button system becomes visually simple. A PlayStation game presents a familiar four-colour arrangement. A pointer-oriented computer brings the trackball into focus. A two-player system mirrors the useful controls across both sides. Unused buttons disappear.
The panel no longer asks a new player to understand eight identical glowing buttons. It offers a suggestion and provides guidance before the game even starts.
That is the difference between lighting a control panel and teaching it to explain itself.