Back to the Computer Controlled Player for MAME page
Alejandro Dubrovsky (33289401)
MAME (Multiple Arcade Machine Emulator) is, as its name suggests, an emulator of arcade machines' hardware. It first got released in February 1997 by Nicola Salmoria, and while it was slower than the many other emulators available at the time, it quickly gathered a strong following due to the quick accumulation of emulated games. That it managed to do this was at least partly due to its strongly modularised design and its clean inter-CPU interfaces. MAME currently (as of June 2005) provides the hardware emulation for about 5600 games, including clones and variants, spanning release dates from 1975 to 2002. It is released with a BSD-style license (as of version 0.97) with further restrictions on selling either source code or binaries.
MAME was originally a DOS program, but a clean interface dividing all operating system-dependant parts from the core of the program was conducive to it being ported to other platforms. The port to a POSIXish platform, and the XWindows graphical environment was named XMAME and was originally done by Allard Van Der Bas, Dick the Ridder, Juan Antonio Martinez, and Hans de Goede only a couple of months after the first MAME release. It later grew many video and audio backends. It still tracks mainline development closely, and an XMAME release almost always follows very soon after a MAME release. XMAME will be the main focus of this report, and it is the X11 video backend which will be tapped to supply an interface to an external agent.
In the context of this report, an agent, and, more specifically, a game playing agent, will be understood to be a program that takes input from the system, say video, score, and other miscellaneous game state data, and outputs its actions as a player would, in the case of arcade games, joystick movements and button presses.
MAME was designed for speed and portability, and is therefore written in C. It is divided into two layers joined by a thin connecting interface. The platform-independent emulation layer writes its video output to a 16-bit indexed or 32-bit RGB framebuffer, its audio to an audio buffer in a standard 44KHz 16-bit stereo wav format and takes its input from an input array of MAME-defined input constants (such as button 1 press or joystick 1 left release). The operating system dependent (OSD) layer is responsible for making that framebuffer visible on the screen, piping the audio buffer to the sound card, transforming it into a suitable format if needed, and grabbing the hardware input and filling the input array. The interface is the common definition of how these two layers talk to each other.
Each game emulated has an assigned driver which defines the system the game runs on. The system definition consists of the CPUs involved and the memory mappings and ports that each CPU has access to and their interconnections. It also defines what video and audio hardware the game uses and their memory mappings, the ROM mapping and references to a machine definition for other miscellaneous bits of hardware (e.g. ROM decoding, real-time clocks, coin and joystick mapping). The CPU, video hardware, audio hardware and machine emulations referenced in the driver are kept in the cpu, vidhrdw, sndhrdw and machine subdirectories respectively, and are each used by many games.
The interface to the operating system dependant calls is defined in osdepend.h. It defines calls which the operating system dependant layer should implement, like opening and closing a display, outputting video and audio data, open, read, write and close files, read keyboard and game input data, get time data, and other less critical tasks.
XMAME is implemented as fulfilling the operating system dependant layer defined in osdepend.h. It consists of a unix core, which provides the file calls and timing implementations, and video, audio, joystick, and frameskip drivers, the video drivers usually having to provide keyboard and mouse handling since they are interdependent. XMAME also provides capabilities to produce many video effects to make the image look like the original games did on their monitors.
Available video drivers as of version 0.97 are SVGA, which does not require XWindows, xgl (OpenGL backends), SDL, itself an interface library that can write to many different backends, and the X11 backend, which can output in XV, DGA or plain Xlib modes. The XV output of the X11 backend is likely the fastest XMAME backend for which root access is not needed.
A program trying to play a game as an agent would need have access to the framebuffer and would need to make its actions be considered as inputs to MAME. It would be preferable for it to be platform-independent and to be unobtrusive if its not in use, and in implementation code so as to ease the complexity of keeping up with the main branch of MAME development. It would also be preferable for the action of the game to be optionally visible just like in normal settings, and for a human to be able to intervene in case overriding or triggering some actions was desired.
While the desirability of a platform-independent interface would make it imperative to modify the emulation layer only, all other requirements could be easily met by acting as an extra video driver under the XMAME implementation, so the platform-independent feature was eliminated. XMAME's x11 video driver already handles several different video modes, and it was quite natural to implement the controller as another video mode. The only difference between this controller mode and a standard mode is that it acts as a secondary video mode, that is, all data is sent to the controller mode and input taken from the controller mode as well as to and from whichever video mode is being used for normal display. This satisfies all other requirements. 1
The controller module, when compiled in and enabled, is called at initialisation stage (sysdep_display_init in x11.c), when opening a display (sysdep_display_open in x11.c), when outputting the frame buffer (sysdep_display_update in x11.c), when closing the display (sysdep_display_close in x11.c) and when exiting (sysdep_display_exit in x11.c). Its actions are captured by requesting them when the x11 driver polls the keyboard (sysdep_display_driver_update_keyboard in xinput.c). These are the same points at which the normal video drivers are called.
The controller module itself is a thin interface that mostly calls the initialisation, frame buffer update, action polling and exiting functions of the real agent selected at runtime. It also converts from MAME's internal indexed bitmap format to a BGRA format, keeps track of keyboard states to avoid confusing MAME in case the agent reports illegal action or keyboard events (e.g. releasing a key twice in a row), provides Python bindings for the interface functions so that agents can be written in that language if desired,2 and provides the current score of the game being played to the agent.
While MAME presents a great opportunity to try machine learning algorithms in a variety of environments, it also presents some special challenges of its own. These include legal issues, lack of control of the environment, lack of state inspection capabilities, and dealing with ancient optimisation techniques and encodings.
While MAME presents a uniform interface to a wide variety of predesigned environments, these environments are almost all commercially produced and a license needed to make use of them. There is a short collection of games that have been supposedly released to be used free of charge at Legal MAME ROMs http://www.sys2064.com/legalroms.htm. There is also a collection of about 25 Atari games being sold for small amounts of money ($2 and $6 at the time of writing) at StarRoms http://www.starroms.com. Other ROM licences can be bought on-line. Trying to obtain a new license from the copyright holders for old games is a tricky procedure since it is hard to find out who the current copyright holders are, and once they are found, they seem to be quite unresponsive to enquiries. If you own a game PCB board then in some countries you are allowed to read the ROM contents from the board. Unfortunately, this is not the case in Australia at the moment (as far as I know, consult your local lawyer).
The source code for arcade games are almost universally unavailable to the public3. This makes modification of the environment almost impossible and observation of the environment's internal state very hard. The only possibility is to observe the emulated memory state and extract information from it.
The most vital piece of information that would be desirable to extract for machine learning purposes would be an end of game marker (i.e. ``Game Over''). I have found no way of extracting this information internally in a game generic manner and have resorted to ad-hoc per game methods extracting features from the resulting framebuffer that only occur at the end of the game (e.g detecting the presence of the ``E'' in ``Game Over'' at a certain location on the screen). Other important information that would help a program would be feedback on its current score and state of bitmaps in the game. I do not think a generic internal way for extracting bitmaps is feasible, but the current score does.
One of the possible forms of feedback that can be supplied to an agent is its current score in the game since a score is an almost universal way of measuring performance in games. Supplying scores though, is a labour intensive, per game, or at least per game family, process. The score has to be found somewhere in the emulated CPU's RAM and decoded. Luckily, MAME comes with a very useful in-game debugger, and people have been very interested in keeping their high scores table, so a short tutorial available at Mame high score tutorial http://www.mameworld.net/highscore/tutorial.htm on how to find these high scores can be easily adapted to finding the current score. The size of the score in bytes can also be guessed from the large collection of high score address ranges described in the hiscore.dat file available from Mame high score download page http://www.mameworld.net/highscore/download.htm which MAME uses to save these high scores table.
The process involves playing the game, pausing at some point, and searching for some encoding of your current score in RAM with the debugger. Since the encoding is unknown prior to finding the score, a lot of different encodings probably have to be tried. The CPU family used for the game should be consulted since this will likely limit the types of encodings that are likely to be used, especially regarding little versus big-endian choices. A non-complete list of encodings follows:
The interface design has not been finalised, and the current implementation does not exactly match the design presented above. Intermediate layers of preprocessing could be added in the future which would extract various bits of information from the framebuffer image, and which the agent could request. Interfacing with the OpenCV library OpenCV library http://sourceforge.net/projects/opencvlibrary/ is planned to help with this part. Another tempting option is to make the agents more independent from the main MAME process by communicating with it through pipes or TCP connections, but speed is usually at a premium in machine learning and this setup could have a significant impact on performance.
The latest version of this document and the interface implementation will be found at Mame Machine Learning interface http://www.organicrobot.com/mame/.
This document was generated using the LaTeX2HTML translator Version 2002-2-1 (1.71)
Copyright © 1993, 1994, 1995, 1996,
Nikos Drakos,
Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999,
Ross Moore,
Mathematics Department, Macquarie University, Sydney.
The command line arguments were:
latex2html -no_subdir -split 0 -show_section_numbers /tmp/lyx_tmpdir12104YZsyV/lyx_tmpbuf0/mamereport.tex
The translation was initiated by Alejandro Dubrovsky on 2005-08-02