.. _layscript: MAME Layout Scripting ===================== .. contents:: :local: .. _layscript-intro: Introduction ------------ MAME layout files can embed Lua script to provide enhanced functionality. Although there’s a lot you can do with conditionally drawn components and parameter animation, some things can only be done with scripting. MAME uses an event-based model. Scripts can supply function that will be called after certain events, or when certain data is required. Layout scripting requires the layout plugin to be enabled. For example, to run BWB Touble Take with the Lua script in the layout enabled, you might use this command:: mame64 -plugins -plugin layout v4dbltak If you may want to add the settings to enable the layout plugin to an INI file to save having to enable it every time you start a system. .. _layscript-examples: Practical examples ------------------ Before diving into the technical details of how it works, we’ll start with some complete examples using Lua script to enhance layouts. Espial: joystick split across ports ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Take a look at the player input definitions for Espial: .. code-block:: C++ PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL PORT_START("IN2") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY There are two joysticks, one used for both players on an upright cabinet or the first player on a cocktail cabinet, and one used for the second player on a cocktail cabinet. Notice that the switches for the first joystick are split across the two I/O ports. There’s no layout file syntax to build element state using bits from multiple I/O ports. It’s also inconvenient if each joystick needs to be defined as a separate element because the bits for the switches aren’t arranged the same way. We can overcome these limitations using a script to read the player inputs and set the items’ element state: .. code-block:: XML The layout has a ``script`` element containing the Lua script. This is called as a function by the layout plugin when the layout file is loaded. The layout views have been built at this point, but the emulated system has not finished starting. In particular, it’s not safe to access inputs and outputs at this time. The key variable in the script environment is ``file``, which gives the script access its layout file. We supply a function to be called after tags in the layout file have been resolved. At this point, the emulated system will have completed starting. This function does the following tasks * Looks up the two I/O ports used for player input. I/O ports can be looked up by tag relative to the device that caused the layout file to be loaded. * Looks up the two view items used to display joystick state. Views can be looked up by name (i.e. value of the ``name`` attribute), and items within a view can be looked up by ID (i.e. the value of the ``id`` attribute). * Supplies a function to be called before view items are added to the render target. * Hides the warning that reminds the user to enable the layout plugin by setting the element state for the item to 0 (the text component is only drawn when the element state is 1). The function called before view items are added to the render target reads the player inputs, and shuffle the bits into the order needed by the joystick element.