libmame - MAME as a C library
Table Of Contents
Compiling with libmame
Using the libmame API
libmame is a patch to the official MAME sources that allows MAME to be built as a C library instead of as a standalone program*.
The benefit of libmame is to allow programs to incorporate game emulation into themselves directly; rather than forking a copy of the MAME standalone and giving up control of the audio, video, and user input system, a program built using libmame can run the emulator within its own process space and have full control over the rendering of audio and video and the handling of user input.
This allows some interesting use cases:
- MAME can be built directly into a "frontend" program and allow for unique features, such as:
- Rendering the game screen in any position on the monitor, including being embedded in or sharing the screen with other UI elements
- Rendering the UI that would normally control the game in a way that integrates with the frontend UI rather than being the MAME default boxed-list UI system
- Programmatically saving and loading game states to start emulated games at a known point in time, every time, according to user preferences
- Implement sophisticated user input schemes that may involve user interaction not possible with standalone MAME
- Sophisticated benchmarking programs that 'play' the game during the benchmark, or game playback systems that can play back games starting with a saved game state and a recorded sequence of user inputs, resulting in much smaller playback files than standard movie files
- Automated test suites that run games and detect crashes or even unintended changes to game states (i.e. start a game from a known save state, feed it canned input for a fixed number of frames, and then save its game state and compare to a previously saved state to ensure that the game is still playing exactly as before a MAME coding change)
- Embedding MAME in unusual places, such as directly into operating systems or window managers or elsewhere that unique functionality could be provided (example: a Linux installer that plays MAME games while the user waits for the install to complete).
* (actually, the patched version can be compiled as a standalone program as normal but has the additional feature of supporting being compiled as a library, but for the purposes of this documentation, only the patched MAME compiled as a library will be considered)
Compiling with libmame
libmame is a patch that can be applied to the standard MAME source code to produce a modified version of MAME, still under the MAME license, that can be compiled as a library.
libmame is defined as a C API in a single header file, libmame.h. Programs can link against the library either statically (although this produces a very large executable) or dynamically (the preferred mechanism). The libmame library only exports C symbols in its API although the MAME internals do require linking against the C++ standard library so although programs using libmame can be C programs, a C++ standard library must be present on the system to use libmame.
Using the libmame API
LibMame provides a single API for (almost) all functionality of the MAME
engine. It provides the following types of functions:
- Functions for querying the set of games supported by this version of
LibMame, and many descriptive details about each game:
- A function for running a MAME game (only one MAME game may be run
concurrently within the same process due to limitations in the MAME
engine). MAME will emulate the game and will interact with the rest
of the system (for displaying frames of the game, playing sound, and
getting controller input) via callbacks.
- Functions for manipulating a running MAME game, including pausing,
resetting, and manipulating configuration values of various kinds.
- Miscellaneous functions necessary for supporting the other libmame
In general, applications using libmame will follow this pattern:
- Call LibMame_Initialize.
- Collect game information for display using the LibMame_Get_Game_XXX
- Look up the number of the game that the user wants to play using
- Set options for running the game by first calling
LibMame_Get_Default_RunGameOptions, and then customizing the resulting
options according to user preference.
- Set up internal state for managing the display, sound, and controller
input for the game about to be run.
The target display frame rate can be found by calling
LibMame_Get_Game_ScreenRefreshRateHz, if needed, and the size at which
the game was originally redered is known by calling
LibMame_Get_Game_ScreenResolution, although this is not necessarily
the same resolution as the visible portion of the game's screen; the
visible portion of the game's screen can only be discerned by examining
the render primitive bounds in the UpdateVideo callback.
The set of controls that the game will require inputs on can be found by
calling LibMame_Get_Game_AllControllers (and the maximum number of
players for whom controller input is needed is available from
LibMame_Get_Game_MaxSimultaneousPlayers). The application will
typically use this information to decide how to map whatever controls
it knows about to the inputs that the game is expecting, usually via
user preference (managed by the application).
- Call LibMame_RunGame to run the game, passing in pointers to callback
functions that will handle the rendering of audio and video and
collecting controller input.
- As the game is running, according to user input, call the
LibMame_RunningGame_XXX functions (but only from the
MakeRunningGameCallbacks (or in certain cases, Paused) callbacks, which
means that user commands must typically be noted and then applied at the
next call to MakeRunningGameCallbacks).
- When the game completes (i.e. the LibMame_RunningGame_Schedule_Exit
callback is made by the application), LibMame_RunGame will return, and
the application may then repeat steps 5, 6, and 7 if it wishes.
- When the application is completely finished calling any LibMame
functions, before it exits, it must then call LibMame_Deinitialize.
Please keep in mind that although the API is structured as if it were
possible to run multiple MAME games simultaneously from the same
application, there is a limit in the MAME engine that prevents more than
one game from running at a time. This limit may someday be lifted, in
which case this API will already be ready to take advantage of that, but
until the limit is lifted, remember that LibMame_RunGame may only be called
from one thread at a time within a single application.
Doxygen-generated API documentation for libmame is available here.
A few example programs, which are fairly useful in their own right, are available at the examples page.
Please see the downloads page for downloads including the libmame patch and pre-built binaries where applicable.
To build libmame from source, please see the building libmame page.
The libmame patch makes changes to the existing MAME source code and adds some new source files to the MAME source tree. All contents of the patch - its modifications to existing source and the new files it adds - are Copyright Bryan Ischo and the MAME Team. This means that MAME programs built using the patch, or the modified source of MAME or the patch itself, are copyright and may not be distributed except under the terms of the MAME license.
The end result is that programs that link statically against libmame must include the source code both for the libmame-modified version of MAME and the source code of the program linking against libmame.
It is believed that this same requirement applies to programs that dynamically link against libmame, so the same rules apply there as well.
See the license.txt file in the docs directory of the MAME source code distribution for the full license.
This page Copyright 2011 Bryan Ischo.