All About Artwork


Artwork is processed in rendlay.c. It is a brilliant piece of Aaron Giles programming, which solves all the issues of artwork creation in one stroke.

Take a look at the many artwork examples in the source. MESS layouts are generally much simpler than MAME ones.

When would you use artwork?


Artwork is used whenever you want to add any video artifact that is not present on a CRT. Examples are backgrounds, bezels, LEDs (whether round ones or digital displays) and photographs.

You would also use artwork if the screen needs to be a different aspect ratio than normal. If you had 2 or more screens of different sizes, or an unusual arrangement, you would use artwork for this too.

To describe how the artwork will appear, you compose a file gamename.lay which uses XML formatted plain text.

What files are used for artwork?


  • There are two places where lay files are kept:
    • In the layout folder (internal artwork)
    • Bundled with image files in the artwork folder (external artwork)

About internal artwork

(we use sitcom as an example here)

1. In MESS.MAK, include a line near the bottom which will read like this:

$(MESS_DRIVERS)/sitcom.o: $(MESS_LAYOUT)/sitcom.lh

2. In drivers/sitcom.c, include a line near the top:

#include “sitcom.lh”

3. In drivers/sitcom.c, in the MACHINE_CONFIG, include this line:

MCFG_DEFAULT_LAYOUT(layout_sitcom)

4. That's all for the driver. The only thing left to do is to write sitcom.lay (see below).

5. Please note: You cannot use the 'image' directive.

About external artwork

  • It is not compiled.
  • It is optional - the system will work without it, but will not be as pretty or as usable.
  • Can be used for development, as it saves the bother of having to compile every little change.
  • You only need external artwork when image files (PNG format) are used.
  • The layout together with all needed png files is zipped up into gamename.zip
  • Or, you can make a subfolder under artwork, and leave the files there unzipped.
  • It should be distributed via a fan site or a dedicated page - not with the main executable.

Using internal and external artwork together

  • The external artwork will take precedence. However, since external artwork is optional, the internal artwork performs the “failsafe” option. It could show the game without the images, or it could just carry a message stating that the game needs external artwork to be playable.
  • There is a flag GAME_REQUIRES_ARTWORK for drivers, but it will always nag, even if the artwork is present. It is much better to remove the flag and have the failsafe instead.

When do you need artwork?


It is required for screenless systems. It is optional otherwise. If a screenless system has no artwork, you will receive a message stating “No screens are attached to the system”. Older versions of MESS would just crash.

Key components of a lay file

<?xml version="1.0"?>
<mamelayout version="2">

.. list of objects (elements) to be used ..

<view name="Default Layout">

.. a view describes the layout of the elements ..

</view>
</mamelayout>
The above parts are required. The mamelayout version corresponds to a constant in rendlay.c

const int LAYOUT_VERSION = 2;

The list of art elements is a list of paragraphs which describe the objects to be displayed, in terms of shape, colour and text - but not in dimensions. The view describes where these objects are in relation to each other, and their sizes. The view is also used for clickable artwork.

Examples of Objects


An object is called an element. Here are some examples of elements.

<element name="background">
       <rect>
             <bounds left="0" top="0" right="1" bottom="1" />
             <color red="0.0" green="0.0" blue="0.0" />
       </rect>
</element>

<element name="Text-string">
       <text string="Here is some text"><color red="1.0" green="0.5" blue="0.5" /></text>
</element>

<element name="digit" defstate="0">
        <led7seg>
               <color red="1.0" green="0.0" blue="0.0" />
        </led7seg>
</element>

<element name="a_digit" defstate="0">
        <led16seg>
               <color red="1.0" green="0.0" blue="0.0" />
        </led16seg>
</element>

<element name="a_led">
        <disk>
               <color red="0.0" green="0.75" blue="0.0" />
        </disk>
</element>

<element name="collect">
    <rect state="1">
        <color red="1.0" green="1.0" blue="0.0" />
    </rect>
    <rect state="0">
        <color red="0.5" green="0.5" blue="0.0" />
    </rect>
    <text string="COLLECT">
        <color red="0.0" green="0.0" blue="0.0" />
        <bounds x="0" y="0.1" width="1" height="0.8" />
    </text>
</element>

An element has a name. This is used in a view to reference the element.

<rect> indicates a square or rectangular area, while <disk> indicates a circular or elliptical area, usually for a round LED.

<color> is how to set up a colour in RGB format, where the number can be 0.0, 0.25, 0.5, 0.75, or 1.0. You can use other numbers but it appears they will be rounded down to the nearest quarter. You can also specify alpha.

<text string= is to add a label or heading into the artwork. It also can be coloured.

There are several types of digital LEDs that can be used. <led7seg> is the usual 7-segment with decimal point, but there are also <led14seg>, <led14segsc>, <led16seg>, <led16segsc> where sc indicates a semi-colon feature. There is also a <dotmatrix> option.

<state>, if used, can be 0 or 1 and is controlled by the driver program. You can specify different colours or shapes for each state. <defstate> indicates if the element should appear or not before the driver issues any commands to it (for example if a LED should be on or off at powerup).

As you can see, the system is quite versatile. You can consider each element to be like a sprite, which can be any size, in any position, and used many times.

Examples of Views


A view describes the complete appearance, by using the elements and other things.

<?xml version="1.0"?>
<mamelayout version="2">
	<element name="digit" defstate="0">
		<led7seg>
			<color red="0.75" green="0" blue="0.0" />
		</led7seg>
	</element>

	<view name="Default Layout">
		<!-- Led address display -->
		<bezel name="digit0" element="digit">
			<bounds x="0" y="0" width="18" height="24" />
		</bezel>
		<bezel name="digit1" element="digit">
			<bounds x="18" y="0" width="18" height="24" />
		</bezel>
		<bezel name="digit2" element="digit">
			<bounds x="36" y="0" width="18" height="24" />
		</bezel>
		<bezel name="digit3" element="digit">
			<bounds x="54" y="0" width="18" height="24" />
		</bezel>
		<bezel name="digit4" element="digit">
			<bounds x="80" y="0" width="18" height="24" />
		</bezel>
		<bezel name="digit5" element="digit">
			<bounds x="98" y="0" width="18" height="24" />
		</bezel>
	</view>
</mamelayout>
Here, we firstly define an element which is a 7-segment red LED.

Then, in the view, we need 6 of these digits. Note that the element name “digit” has been used 6 times in the view, to create 6 digits. The bezel names (digit0 through to digit5) are used by our driver to enable individual control. In the driver, use the line:

output_set_digit_value(digit-to-use, segments);

where digit-to-use is a number (0 to 5 - the string “digit” is assumed), and segments is a byte controlling the state of the individual 8 parts of a digit (bit 0 = segment a, etc). If your program has the segments in a different order, use the BITSWAP8 macro to fix it.

Note that each digit has a <bounds directive; this indicates where each digit will be in relation to its neighbours. In this case, each one is just to the right of the one before. You have a choice of using x, y, width, height OR left, right, top, bottom. You can't mix them in the one line.

There is no need to indicate a total size of the screen; rendlay will find the minimum and maximum values, and will magically size and scale the artwork by itself.

<element name="red_led">
		<disk>
			<color red="1.0" green="0.0" blue="0.0" />
		</disk>
	</element>

	<view name="Cassette LED">
		<bezel name="cass_led" element="red_led">
			<bounds left="0" right="20" top="1020" bottom="1045" />
		</bezel>
		<screen index="0">
			<bounds x="0" y="0" width="1400" height="1050" />
		</screen>
	</view>
This one describes a round red LED, then places it in the bottom left corner of the CRT. In the driver, use the line:

output_set_value(“cass_led”, state);

where “cass_led” is the bezel-name of the LED, and “state” is 0 or 1.

You can see that the screen is listed as <screen index=“0”>, and has no element. Screen indexes correspond to each screen in the order listed in MACHINE_CONFIG. The artwork system doesn't use screen names.

You can have more than one view. Each view has a name <view name=”view-name”>, and these names appear in the Video option in the menu. Make sure you don't end up with 2 views having the same name (such as Standard). And, make sure you arrange things so that the default view is the view that should normally be used.

Clickable Artwork


This allows you to use the mouse (the OS mouse, not an emulated one) to operate pushbuttons that are in the artwork. It can be a button you have drawn, or a button in a photo of a pcb (for example).

The prerequisites are that you run MESS in windowed mode; and that the OS mouse pointer is visible. In Windows, you may need to use the -nohc command-line parameter.

<bezel element="pushbuttonCTRL" inputtag="CTRL" inputmask="0x10">
            <bounds x="765" y="338" width="40" height="40"/>
        </bezel>

The new directives are inputtag and inputmask. Inputtag corresponds to the PORT_START name in the driver, while inputmask is the PORT_BIT. <bounds describes the position and size of the area that will respond to the mouseclick. You should make sure this area aligns exactly with a picture of a suitably-labelled button.

Directives not yet explained


image file alphafile

rotate swapxy flipx flipy backdrop overlay bezel cpanel marquee orientation

~scr#nativexaspect~ ~scr#nativeyaspect~ ~scr#width~ ~scr#height~

Further Reading