Problem is, I don't want to have to support a custom version of Mame to do so. I'm looking at ways I can make my lighting software a standalone utility that interfaces with Mame. Even supporting the utility will be a pain though. It take time/money to do so. Unfortunately no one wants to pay for software these days so supporting a custom Mame utility will probably end up being a loosing proposition for me.
What do you need to know from mame?
I need to know the default input port mappings. Mame has XML config files for the control mappings but these only exist if the user modified the defaults. The defaults are hardwired via the machines input port code. If you look in the driver code for a specific game (say asteroids) you'll see a bunch of macros calls:
PORT_START_TAG("IN1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_COIN1)
...
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT)
These macro's actually write a function that hardcodes the default values for a particular driver.
I love the way I have things setup on my cabinet now but can't see this being a practical solution for most people since it would require me to provide a version of mame. I have made it very friendly and generic. All one has to do is make a config file that maps controls to LED output #'s on the LED-WIZ. Once this is done, you fire up mame and any game you start will automatically light the controls that it uses.
One of the great things about my setup is that when you pop up the controls dialog in mame and make changes to control mappings, you see the changes made instantly on the control panels lighting. You couldn't get this with a FE or any other approach.
What would be really great is if mame had a plugin infrastructure that allowed an outside utility to access mame data structures.
As a side note too, I've hooked up some code to fire a solenoid from the LED-WIZ as well. This will allow me to do a Qbert knocker. I haven't built a relay circuit yet but the code is in place and right now when Qbert jumps of the cliff, my lights all flash.
It sounds like you are making johny5 but for LEDs

That's a hint.
Ok, I will come right out and say it. You have all the information available from mame. First, the macros in the driver are not hardcoded mappings, as in hardcoded to keypresses. They are just "hardcoded" to a constant. For example.
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT)
That means the bit at 0x40 of some port of some chip that is being emulated handles joystick right on the real machine.
So, you need to know what keypress is joystick right, for this particular game. You have this info. If the person uses ctrlr files you use those, if not you can use the "cfg" files which are in the same xml format as the ctrlr files. These are created when a game is first played and contain the control info. Ctrlr files will override this though. If the file doesn't exist mame will create the file with default, so you know if the file doesn't exist to use mame defaul mappings, which happen to be in the mame.cfg file (this is where the general mappings are stored, I believe).
Ctrlr files have a heirarchy to them. if you put in an entry for neogeo it will affect all neogeo game. But if you also have an entry for mslug mame will modify the neogeo entry with the mslug. So if the neogeo sets coin1 to 3 and player 1 button 1 to T ... then mslug entry sets button 1 to W ... then mslug will use 3 for coin since its parent overwrote the defaults, but use W for button one as it override its parent.
Again, this is what johnny5 does, along with adding in controls.dat info for better accuracy, to display a control layout graphic.