A few months ago, I took on a small project to replace my home arcade system’s user interface. Not that there was anything functionally wrong with the original, but it had a certain lackluster appeal to it. It was written in C and used the portable SDL library for managing the menu interface for MAME, MESS, Stella, UAE, and VICE. This next edition would need to have some cool graphics and animation, and perhaps play some nostalgic tunes and videos when sitting idle.
I did not want to waste any time writing my own animation or OpenGL effects, so finding an API that could provide me those functional needs, and without spending a hundred hours learning it, was tops on my list. I started at the SDL web site, because it hosts a bunch of project links that have implemented its library, including SDKs and other APIs for game programming and GUI management. I ran across ClanLib, but was initially turned off because it was written in C++. I have written so little in C++, because I got stuck in my own way from being very proficient in programming C. But its API looked simple and clean, judging by their documentation and tutorials, and it got further endorsement when I learned that a game, Ballbuster, uses it. That convinced me to kick its tires.
Fortunately, it is relatively simple to setup C/C++ projects using Linux and KDevelop. I was coding, compiling, and cursing in no time! But before I could really settle into my hacking, I needed a solid plan on what the GUI would look like. In stepped the Gimp.
The Gimp provides all the image editing tools and functions an amateur like me can handle. But it also manages image layers quite nicely for my needs to quickly build mock displays. I found I spent nearly half of the project’s time manipulating graphics as I did the other half in the programmer’s editor. Of course, the rest of it was spent pondering the same burning question, “Why doesn’t this work?”
But diligence eventually won over and I was able to implement many useful features of ClanLib, including its XML, JPEG, and PNG providers, sprites, fonts, keyboard and joystick handling, and both 2D and 3D modes of operation are supported. I cannot say enough good things about its XML provider; it is the heart for providing all the required information needed to do the rendering. Take a look at my arcade’s configuration file to see what I mean. As far as sounds, tunes, and videos… I took the easy way out and simply invoked system calls to utilities that do that best, such as timidity++ and mplayer. The result are these sources.
The project exposed some quirks that is evident from inconsistencies in Linux device drivers. While SDL and ClanLib both do their best in providing a nice abstract layer to mask these inconsistencies, there are still some unfortunate hacks and workarounds I needed to implement to work with the different video card drivers and gamepad devices I am accustomed to. For example, switching from fullscreen to window, then back to fullscreen required a different process — and even timings — depending upon whether the system was using a 2D or 3D accelerated video card.
Using the Microsoft Xbox 360 controller produced a lot of garbage events on the USB port that the driver did not clean up upon initialization, and those events caused my application to process them as regular user inputs. Again, I had to put in a special test case for that device, emptying the events before moving on to the main loop. While the Sony Playstation 3 controller was handled cleanly by its driver, the MAME/MESS emulation engines did not support those complex devices. I was lucky my nagging to the SDLMAME project team took it to heart, and there is a new attribute, sixaxis, in their configuration file to support those sporty game pads.
One of the features of using SDL and ClanLib is that their APIs are portable between Linux, Windows, and MacOS. I will take on the process of porting this project to Vista next, hopefully only having to use Microsoft’s Visual C++ 2008 Express. Even though I have made a Linux Live edition for Christmas 2006, I am hoping this porting effort will be successful, because I know of many family and friends that would enjoy running this home arcade implementation on their personal computers. I suspect upfront that the Windows device drivers will behave much more consistently with these APIs. I will post the progress and outcomes on that effort.