Layouts and Rendering for MAME Artwork System: Difference between revisions

From MAMEDEV Wiki
(New page: Today is when MAME 0.106u2 should <a href="http://mamedev.org/release.html">be available</a>. I'm sure there will be lots of questions as a result, but the one major change that needs some...)
 
No edit summary
Line 1: Line 1:
Today is when MAME 0.106u2 should <a
MAME 0.106u2 introduced a major change that needs a more detailed description, the concept of layouts and views.
href="http://mamedev.org/release.html">be available</a>. I'm sure there will be lots of questions as a result, but the one major change that needs some more detailed description is the concept of layouts and views.


As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can't run the new renderer without a layout loaded.
As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can't run the new renderer without a layout loaded.


A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3
A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3 games:
games:
 
<!--more-->
<code>&lt;?xml version="1.0"?&gt;
<code>&lt;?xml version="1.0"?&gt;
&lt;mamelayout version="2"&gt;
&lt;mamelayout version="2"&gt;
    &lt;view name="Standard"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;view name="Standard"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;screen index="0"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        &lt;screen index="0"&gt;
&lt;bounds left="0" top="0" right="4" bottom="3" /&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/screen&gt;
            &lt;bounds left="0" top="0" right="4" bottom="3" /&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/view&gt;
        &lt;/screen&gt;
&lt;/mamelayout&gt;</code>
    &lt;/view&gt;
&lt;/mamelayout&gt;</code>


This particular layout has no elements described, and only a single view. The name of the view is "Standard." This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:
This particular layout has no elements described, and only a single view. The name of the view is "Standard." This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:


<ul>
<ul>
<li><b>backdrops</b> specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects</li> <li><b>screens</b> specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)</li> <li><b>overlays</b> specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)</li> <li><b>bezels</b> specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were</li> </ul>
<li><b>backdrops</b> specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects</li>
<li><b>screens</b> specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)</li>
<li><b>overlays</b> specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)</li>
<li><b>bezels</b> specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were</li> </ul>


Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.
Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.


So looking back at the example, you can see that we've specified a single item for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You'll notice that the width of the screen is 4 and the height is 3. What kind of coordinate system is this? Well, it's an arbitrary system, really. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.
Looking back at the example, you can see that a single item has been specified for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You'll notice that the width of the screen is 4 and the height is 3, this is a fairly arbitrary coordinate system. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.


Now, if you're familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting
Now, if you're familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting artwork) was determined by flags in the game. This is true, and in retrospect, was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).
artwork) was determined by flags in the game. This is true. And in retrospect, it was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).


The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:
The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:


<ol>
<ol>
<li>Explicitly specified files (on the command line)</li> <li><i>gamename</i>.lay</li> <li>Game-specific built-in layouts</li> <li><i>parentname</i>.lay</li> <li>Generic built-in layouts</li> </ol>
<li>Explicitly specified files (on the command line)</li>
<li><i>gamename</i>.lay</li>
<li>Game-specific built-in layouts</li>
<li><i>parentname</i>.lay</li>
<li>Generic built-in layouts</li> </ol>


The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.
The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.
Line 37: Line 43:
And finally, just for kicks, there is a "cocktail" layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:
And finally, just for kicks, there is a "cocktail" layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:


<code>&lt;?xml version="1.0"?&gt;
<code>&lt;?xml version="1.0"?&gt;
&lt;mamelayout version="2"&gt;
&lt;mamelayout version="2"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;view name="Cocktail"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;screen index="0"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    &lt;view name="Cocktail"&gt;
&lt;bounds left="-1.33333" top="0.0" right="0.0" bottom="1.0" /&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/screen&gt;
        &lt;screen index="0"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;screen index="0"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            &lt;bounds left="-1.33333" top="0.0" right="0.0" bottom="1.0" /&gt;  
&lt;bounds left="0.01" top="0.0" right="1.34333" bottom="1.0" /&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        &lt;/screen&gt;
&lt;orientation rotate="180" /&gt;
        &lt;screen index="0"&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/screen&gt;
            &lt;bounds left="0.01" top="0.0" right="1.34333" bottom="1.0" /&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/view&gt;
            &lt;orientation rotate="180" /&gt;
&lt;/mamelayout&gt;</code>
        &lt;/screen&gt;
    &lt;/view&gt;
&lt;/mamelayout&gt;</code>


You'll notice a couple of interesting things here. First is, you can repeat the same screen multiple times in a view if you'd like. For fun, I've even created a "quad" view that displays the screen 4 times rotated all four directions. Second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here I'm using
You'll notice a couple of interesting things here. The first is that you can repeat the same screen multiple times in a view. For fun, you could even creat a "quad" view that displays the screen 4 times rotated in all four directions. The second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here we're using 1.333 as the width of each screen and 1.0 as the height. This is the essentially the same as 4:3.
1.333 as the width of each screen and 1.0 as the height. This is the same as 4:3. Really. :)


For completeness sake, here are all the attributes you can specify for
For completeness sake, here are all the attributes you can specify for items:
items:


<code>&lt;bounds left="0" top="0" right="4" bottom="3" /&gt; &lt;bounds x="0" y="0" width="4" height="3" /&gt; &lt;color red="1.0" green="1.0" blue="1.0" alpha="0.5" /&gt; &lt;orientation rotate="90" swapxy="yes" flipx="yes" flipy="no"
<code>&lt;bounds left="0" top="0" right="4" bottom="3" /&gt;
/&gt;</code>
&lt;bounds x="0" y="0" width="4" height="3" /&gt;
&lt;color red="1.0" green="1.0" blue="1.0" alpha="0.5" /&gt;
&lt;orientation rotate="90" swapxy="yes" flipx="yes" flipy="no" /&gt;</code>


You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.
You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.
Well, that seems like enough for a single article. I'll talk about elements and artwork and how they work in the next article.

Revision as of 13:49, 24 June 2008

MAME 0.106u2 introduced a major change that needs a more detailed description, the concept of layouts and views.

As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can't run the new renderer without a layout loaded.

A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3 games:

<?xml version="1.0"?>
<mamelayout version="2">
    <view name="Standard">
        <screen index="0">
            <bounds left="0" top="0" right="4" bottom="3" />  
        </screen>
    </view>
</mamelayout>

This particular layout has no elements described, and only a single view. The name of the view is "Standard." This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:

  • backdrops specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects
  • screens specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)
  • overlays specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)
  • bezels specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were

Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.

Looking back at the example, you can see that a single item has been specified for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You'll notice that the width of the screen is 4 and the height is 3, this is a fairly arbitrary coordinate system. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.

Now, if you're familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting artwork) was determined by flags in the game. This is true, and in retrospect, was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).

The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:

  1. Explicitly specified files (on the command line)
  2. gamename.lay
  3. Game-specific built-in layouts
  4. parentname.lay
  5. Generic built-in layouts

The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.

Second, there are a number of built-in layouts. By default, each screen in the game gets a Standard layout, which is simply a single screen displayed at its appropriate aspect ratio. Each screen in the game also gets a Native layout, which is a single screen displayed 1:1 with the height/width ratio of the pixels. This produces, for example, widescreen Capcom games for those who still believe they should be widescreen. Multi-screen games get a few additional options for displaying both screens at the same time, either on top of each other or side-by-side. And finally, just for kicks, there is a "cocktail" layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:

<?xml version="1.0"?>
<mamelayout version="2">
    <view name="Cocktail">
        <screen index="0">
            <bounds left="-1.33333" top="0.0" right="0.0" bottom="1.0" /> 
        </screen>
        <screen index="0">
            <bounds left="0.01" top="0.0" right="1.34333" bottom="1.0" />
            <orientation rotate="180" />
        </screen>
    </view>
</mamelayout>

You'll notice a couple of interesting things here. The first is that you can repeat the same screen multiple times in a view. For fun, you could even creat a "quad" view that displays the screen 4 times rotated in all four directions. The second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here we're using 1.333 as the width of each screen and 1.0 as the height. This is the essentially the same as 4:3.

For completeness sake, here are all the attributes you can specify for items:

<bounds left="0" top="0" right="4" bottom="3" />
<bounds x="0" y="0" width="4" height="3" />
<color red="1.0" green="1.0" blue="1.0" alpha="0.5" />
<orientation rotate="90" swapxy="yes" flipx="yes" flipy="no" />

You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.