summaryrefslogtreecommitdiffstatshomepage
path: root/docs/source/techspecs/layout_files.rst
blob: 976f51475cae733f1776d53097bdd5d55ed10feb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
MAME Layout Files
=================

.. contents:: :local:


.. _layout-intro:

Introduction
------------

Layout files are used to tell MAME what to display when running an emulated
system, and how to arrange it.  MAME can render emulated screens, images, text,
shapes, and specialised objects for common output devices.  Elements can be
static, or dynamically update to reflect the state of inputs and outputs.
Layouts may be automatically generated based on the number/type of emulated
screens, built and linked into the MAME binary, or provided externally.  MAME
layout files are an XML application, using the ``.lay`` filename extension.


.. _layout-concepts:

Core concepts
-------------

.. _layout-concepts-numbers:

Numbers
~~~~~~~

There are two kinds of numbers in MAME layouts: integers and floating-point
numbers.

Integers may be supplied in decimal or hexadecimal notation.  A decimal integer
consists of and optional # (hash) prefix, an optional +/- (plus or minus) sign
character, and a sequence of digits 0-9.  A hexadecimal number consists of one
of the prefixes $ (dollar sign) or 0x (zero ex) followed by a sequence of
hexadecimal digits 0-9 and A-F.  Hexadecimal numbers are case-insensitive for
both the prefix and digits.

Floating-point numbers may be supplied in decimal fixed-point or scientific
notation.  Note that integer prefixes and hexadecimal values are *not*
accepted where a floating-point number is expected.

For a few attributes, both integers and floating-point numbers are allowed.  In
these cases, the presence of a # (hash), $ (dollar sign) or 0x (zero ex) prefix
causes the value to be interpreted as an integer.  If no recognised integer
prefix is found and the value contains a decimal point or the letter E
(uppercase or lowercase) introducing an exponent, it is interpreted as a
floating-point number.  If no integer prefix, decimal point or letter E is
found, the number will be interpreted as an integer.

Numbers are parsed using the "C" locale for portability.


.. _layout-concepts-coordinates:

Coordinates
~~~~~~~~~~~

Layout coordinates are internally represented as IEEE754 32-bit binary
floating-point numbers (also known as "single precision").  Coordinates increase
in the rightward and downward directions.  The origin (0,0) has no particular
significance, and you may freely use negative coordinates in layouts.
Coordinates are supplied as floating-point numbers.

MAME assumes that view coordinates have the same aspect ratio as pixel on the
output device (host screen or window).  Assuming square pixels and no rotation,
this means equal distances in X and Y axes correspond to equal horizontal and
vertical distances in the rendered output.

Views, groups and elements all have their own internal coordinate systems.  When
an element or group is referenced from a view or another group, its coordinates
are scaled as necessary to fit the specified bounds.

Objects are positioned and sized using ``bounds`` elements.  A bounds element
may specify the position of the top left corner and the size using ``x``, ``y``,
``width`` and ``height`` attributes, or it may specify the coordinates of the
edges with the ``left``, ``top``, ``right`` and ``bottom`` attributes.  These
two ``bounds`` elements are equivalent::

    <bounds x="455" y="120" width="11" height="7" />
    <bounds left="455" top="120" right="466" bottom="127" />

Either the ``x`` or ``left`` attribute must be present to distinguish between
the two schemes.  The ``width`` and ``height`` or ``right`` and ``bottom``
default to 1.0 if not supplied.  It is an error if ``width`` or ``height`` are
negative, if ``right`` is less than ``left``, or if ``bottom`` is less than
``top``.


.. _layout-concepts-colours:

Colours
~~~~~~~

Colours are specified in RGBA space.  MAME is not aware of colour profiles and
gamuts, so colours will typically be interpreted as sRGB with your system's
target gamma (usually 2.2).  Channel values are specified as floating-point
numbers.  Red, green and blue channel values range from 0.0 (off) to 1.0 (full
intensity).  Alpha ranges from 0.0 (fully transparent) to 1.0 (opaque).  Colour
channels values are not pre-multiplied by the alpha value.

Component and view item colour is specified using ``color`` elements.
Meaningful attributes are ``red``, ``green``, ``blue`` and ``alpha``.  This
example ``color`` element specifies all channel values::

    <color red="0.85" green="0.4" blue="0.3" alpha="1.0" />

Any omitted channel attributes default to 1.0 (full intensity or opaque).  It
is an error if any channel value falls outside the range of 0.0 to 1.0
(inclusive).


.. _layout-concepts-params:

Parameters
~~~~~~~~~~

Parameters are named variables that can be used in most attributes.  To use
a parameter in an attribute, surround its name with tilde (~) characters.  If a
parameter is not defined, no substitution occurs.  Here is an examples showing
two instances of parameter use -- the values of the ``digitno`` and ``x``
parameters will be substituted for ``~digitno~`` and ``~x~``::

    <bezel name="digit~digitno~" element="digit">
        <bounds x="~x~" y="80" width="25" height="40" />
    </bezel>

A parameter name is a sequence of uppercase English letters A-Z, lowercase
English letters a-z, decimal digits 0-9, and/or underscore (_) characters.
Parameter names are case-sensitive.  When looking for a parameter, the layout
engine starts at the current, innermost scope and works outwards.  The outermost
scope level corresponds to the top-level ``mamelayout`` element.  Each
``repeat``, ``group`` or ``view`` element creates a new, nested scope level.

Internally a parameter can hold a string, integer, or floating-point number, but
this is mostly transparent.  Integers are stored as 64-bit signed
twos-complement values, and floating-point numbers are stored as IEEE754 64-bit
binary floating-point numbers (also known as "double precision").  Integers are
substituted in decimal notation, and floating point numbers are substituted in
default format, which may be decimal fixed-point or scientific notation
depending on the value).  There is no way to override the default formatting of
integer and floating-point number parameters.

There are two kinds of parameters: *value parameters* and *generator
parameters*.  Value parameters keep their assigned value until reassigned.
Generator parameters have a starting value and an increment and/or shift to be
applied for each iteration.

Value parameters are assigned using a ``param`` element with ``name`` and
``value`` attributes.  Value parameters may appear inside the top-level
``mamelayout`` element, inside ``repeat``, and ``view`` elements, and inside
``group`` definition elements (that is, ``group`` elements in the top-level
``mamelayout`` element, as opposed to ``group`` reference elements inside
``view`` elements other ``group`` definition elements).  A value parameter may
be reassigned at any point.

Here's an example assigning the value "4" to the value parameter "firstdigit"::

    <param name="firstdigit" value="4" />

Generator parameters are assigned using a ``param`` element with ``name`` and
``start`` attributes, and ``increment``, ``lshift`` and/or ``rshift``
attributes.  Generator parameters may only appear inside ``repeat`` elements
(see :ref:`layout-parts-repeats` for details).  A generator parameter must not
be reassigned in the same scope (an identically named parameter may be defined
in a child scope).  Here are some example generator parameters::

    <param name="nybble" start="3" increment="-1" />
    <param name="switchpos" start="74" increment="156" />
    <param name="mask" start="0x0800" rshift="4" />

* The ``nybble`` parameter generates values 3, 2, 1...
* The ``switchpos`` parameter generates values 74, 230, 386...
* The ``mask`` parameter generates values 2048, 128, 8...

The ``increment`` attribute must be an integer or floating-point number to be
added to the parameter's value.  The ``lshift`` and ``rshift`` attributes must
be non-negative integers specifying numbers of bits to shift the parameter's
value to the left or right.  The increment and shift are applied at the end of
the repeating block before the next iteration starts.  If both an increment and
shift are supplied, the increment is applied before the shift.

If the ``increment`` attribute is present and is a floating-point number, the
parameter's value will be interpreted as an integer or floating-point number and
converted to a floating-point number before the increment is added.  If the
``increment`` attribute is present and is an integer, the parameter's value will
be interpreted as an integer or floating number before the increment is added.
The increment will be converted to a floating-point number before the addition
if the parameter's value is a floating-point number.

If the ``lshift`` and/or ``rshift`` attributes are present and not equal, the
parameter's value will be interpreted as an integer or floating-point number,
converted to an integer as necessary, and shifted accordingly.  Shifting to the
left is defined as shifting towards the most significant bit.  If both
``lshift`` and ``rshift`` are supplied, they are netted off before being
applied.  This means you cannot, for example, use equal ``lshift`` and
``rshift`` attributes to clear bits at one end of a parameter's value after the
first iteration.

It is an error if a ``param`` element has neither ``value`` nor ``start``
attributes, and it is an error if a ``param`` element has both a ``value``
attribute and any of the ``start``, ``increment``, ``lshift``, or ``rshift``
attributes.

A ``param`` element defines a parameter or reassigns its value in the current,
innermost scope.  It is not possible to define or reassign parameters in a
containing scope.


.. _layout-concepts-predef-params:

Pre-defined parameters
~~~~~~~~~~~~~~~~~~~~~~

A number of pre-defined value parameters are available providing information
about the running machine:

devicetag
    The full tag path of the device that caused the layout to be loaded, for
    example ``:`` for the root driver device, or ``:tty:ie15`` for a terminal
    connected to a port.  This parameter is a string defined at layout (global)
    scope.
devicebasetag
    The base tag of the device that caused the layout to be loaded, for example
    ``root`` for the root driver device, or ``ie15`` for a terminal connected to
    a port.  This parameter is a string defined at layout (global) scope.
devicename
    The full name (description) of the device that caused the layout to be
    loaded, for example ``AIM-65/40`` or ``IE15 Terminal``.  This parameter is a
    string defined at layout (global) scope.
deviceshortname
    The short name of the device that caused the layout to be loaded, for
    example ``aim65_40`` or ``ie15_terminal``.  This parameter is a string
    defined at layout (global) scope.
scr0physicalxaspect
    The horizontal part of the physical aspect ratio of the first screen (if
    present).  The physical aspect ratio is provided as a reduced improper
    fraction.  Note that this is the horizontal component *before* rotation is
    applied.  This parameter is an integer defined at layout (global) scope.
scr0physicalyaspect
    The vertical part of the physical aspect ratio of the first screen (if
    present).  The physical aspect ratio is provided as a reduced improper
    fraction.  Note that this is the vertical component *before* rotation is
    applied.  This parameter is an integer defined at layout (global) scope.
scr0nativexaspect
    The horizontal part of the pixel aspect ratio of the first screen's visible
    area (if present).  The pixel aspect ratio is provided as a reduced improper
    fraction.  Note that this is the horizontal component *before* rotation is
    applied.  This parameter is an integer defined at layout (global) scope.
scr0nativeyaspect
    The vertical part of the pixel aspect ratio of the first screen's visible
    area (if present).  The pixel aspect ratio is provided as a reduced improper
    fraction.  Note that this is the vertical component *before* rotation is
    applied.  This parameter is an integer defined at layout (global) scope.
scr0width
    The width of the first screen's visible area (if present) in emulated
    pixels.  Note that this is the width *before* rotation is applied.  This
    parameter is an integer defined at layout (global) scope.
scr0height
    The height of the first screen's visible area (if present) in emulated
    pixels.  Note that this is the height *before* rotation is applied.  This
    parameter is an integer defined at layout (global) scope.
scr1physicalxaspect
    The horizontal part of the physical aspect ratio of the second screen (if
    present).  This parameter is an integer defined at layout (global) scope.
scr1physicalyaspect
    The vertical part of the physical aspect ratio of the second screen (if
    present).  This parameter is an integer defined at layout (global) scope.
scr1nativexaspect
    The horizontal part of the pixel aspect ratio of the second screen's visible
    area (if present).  This parameter is an integer defined at layout (global)
    scope.
scr1nativeyaspect
    The vertical part of the pixel aspect ratio of the second screen's visible
    area (if present).  This parameter is an integer defined at layout (global)
    scope.
scr1width
    The width of the second screen's visible area (if present) in emulated
    pixels.  This parameter is an integer defined at layout (global) scope.
scr1height
    The height of the second screen's visible area (if present) in emulated
    pixels.  This parameter is an integer defined at layout (global) scope.
scr\ *N*\ physicalxaspect
    The horizontal part of the physical aspect ratio of the (zero-based) *N*\ th
    screen (if present).  This parameter is an integer defined at layout
    (global) scope.
scr\ *N*\ physicalyaspect
    The vertical part of the physical aspect ratio of the (zero-based) *N*\ th
    screen (if present).  This parameter is an integer defined at layout
    (global) scope.
scr\ *N*\ nativexaspect
    The horizontal part of the pixel aspect ratio of the (zero-based) *N*\ th
    screen's visible area (if present).  This parameter is an integer defined at
    layout (global) scope.
scr\ *N*\ nativeyaspect
    The vertical part of the pixel aspect ratio of the (zero-based) *N*\ th
    screen's visible area (if present).  This parameter is an integer defined at
    layout (global) scope.
scr\ *N*\ width
    The width of the (zero-based) *N*\ th screen's visible area (if present) in
    emulated pixels.  This parameter is an integer defined at layout (global)
    scope.
scr\ *N*\ height
    The height of the (zero-based) *N*\ th screen's visible area (if present) in
    emulated pixels.  This parameter is an integer defined at layout (global)
    scope.
viewname
    The name of the current view.  This parameter is a string defined at view
    scope.  It is not defined outside a view.

For screen-related parameters, screens are numbered from zero in the order they
appear in machine configuration, and all screens are included (not just
subdevices of the device that caused the layout to be loaded).  X/width and
Y/height refer to the horizontal and vertical dimensions of the screen *before*
rotation is applied.  Values based on the visible area are calculated at the
end of configuration.  Values are not updated and layouts are not recomputed if
the system reconfigures the screen while running.


.. _layout-concepts-layers:

Layers
~~~~~~

Views are rendered as a stack of layers, named after parts of an arcade cabinet.
The layout supplies elements to be drawn in all layers besides the screen layer,
which is reserved for emulated screens.  With the exception of the screen layer,
users can enable or disable layers using the in-emulation menu or command-line
options.

The following layers are available:

backdrop
    Intended for use in situations were the screen image is projected over a
    backdrop using a semi-reflective mirror (Pepper's ghost).  This arrangement
    is famously used in the Space Invaders deluxe cabinet.
screen
    This layer is reserved for emulated screen images, and cannot be disabled by
    the user.  It is drawn using additive blending.
overlay
    This layer is intended for use translucent overlays used to add colour to
    games using monochrome monitors like Circus, Gee Bee, and of course Space
    Invaders.  It is drawn using RGB multiplication.
bezel
    This layer is for elements that surround and potentially obscure the screen
    image.  It is drawn with standard alpha blending.
cpanel
    This layer is intended for displaying controls/input devices (control
    panels).  It is drawn using standard alpha blending.
marquee
    This layer is intended for displaying arcade cabinet marquee images.  It is
    drawn using standard alpha blending.

By default, layers are drawn in this order (from back to front):

* screen (add)
* overlay (multiply)
* backdrop (add)
* bezel (alpha)
* cpanel (alpha)
* marquee (alpha)

If a view has multiple backdrop elements and no overlay elements, a different
order is used (from back to front):

* backdrop (alpha)
* screen (add)
* bezel (alpha)
* cpanel (alpha)
* marquee (alpha)

The alternate drawing order makes it simpler to build a backdrop from multiple
scanned/traced pieces of art, as they can have opaque parts.  It can't be used
with overlay elements because colour overlays are conventionally placed between
the screen and mirror, and as such do not affect the backdrop.


.. _layout-parts:

Parts of a layout
-----------------

A *view* specifies an arrangement graphical object to display.  A MAME layout
file can contain multiple views.  Views are built up from *elements* and
*screens*.  To simplify complex layouts, reusable groups and repeating blocks
are supported.

The top-level element of a MAME layout file must be a ``mamelayout`` element
with a ``version`` attribute.  The ``version`` attribute must be an integer.
Currently MAME only supports version 2, and will not load any other version.
This is an example opening tag for a top-level ``mamelayout`` element::

    <mamelayout version="2">

In general, children of the top-level ``mamelayout`` element are processed in
reading order from top to bottom.  The exception is that, for historical
reasons, views are processed last.  This means views see the final values of all
parameters at the end of the ``mamelayout`` element, and may refer to elements
and groups that appear after them.

The following elements are allowed inside the top-level ``mamelayout`` element:

param
    Defines or reassigns a value parameter.  See :ref:`layout-concepts-params`
    for details.
element
    Defines an element -- one of the basic objects that can be arranged in a
    view.  See :ref:`layout-parts-elements` for details.
group
    Defines a reusable group of elements/screens that may be referenced from
    views or other groups.  See :ref:`layout-parts-groups` for details.
repeat
    A repeating group of elements -- may contain ``param``, ``element``,
    ``group``, and ``repeat`` elements.  See :ref:`layout-parts-repeats` for
    details.
view
    An arrangement of elements and/or screens that can be displayed on an output
    device (a host screen/window).  See :ref:`layout-parts-views` for details.
script
    Allows lua script to be supplied for enhanced interactive layouts.


.. _layout-parts-elements:

Elements
~~~~~~~~

Elements are one of the basic visual objects that may be arranged, along with
screens, to make up a view.  Elements may be built up one or more *components*,
but an element is treated as as single surface when building the scene graph
and rendering.  An element may be used in multiple views, and may be used
multiple times within a view.

An element's appearance depends on its *state*.  The state is an integer which
usually comes from an I/O port field or an emulated output (see the discussion
of :ref:`layout-parts-views` for information on connecting an element to an I/O
port or output).  Any component of an element may be restricted to only drawing
when the element's state is a particular value.  Some components (e.g.
multi-segment displays and reels) use the state directly to determine their
appearance.

Each element has its own internal coordinate system.  The bounds of the
element's coordinate system are computed as the union of the bounds of the
individual components it's composed of.

Every element must have a ``name`` attribute specifying its name.  Elements are
referred to by name when instantiated in groups or views.  It is an error for a
layout file to contain multiple elements with identical ``name`` attributes.
Elements may optionally supply a default state value with a ``defstate``
attribute, to be used if not connected to an emulated output or I/O port.  If
present, the ``defstate`` attribute must be a non-negative integer.

Child elements of the ``element`` element instantiate components, which are
drawn in reading order from first to last (components draw on top of components
that come before them).  All components support a few common features:

* Each component may have a ``state`` attribute.  If present, the component will
  only be drawn when the element's state matches its value (if absent, the
  component will always be drawn).  If present, the ``state`` attribute must be
  a non-negative integer.
* Each component may have a ``bounds`` child element specifying its position and
  size (see :ref:`layout-concepts-coordinates`).  If no such element is present,
  the bounds default to a unit square (width and height of 1.0) with the top
  left corner at (0,0).
* Each component may have a ``color`` child element specifying an RGBA colour
  (see :ref:`layout-concepts-colours` for details).  This can be used to control
  the colour of geometric, algorithmically drawn, or textual components.  It is
  ignored for ``image`` components.  If no such element is present, the colour
  defaults to opaque white.

The following components are supported:

rect
    Draws a uniform colour rectangle filling its bounds.
disk
    Draws a uniform colour ellipse fitted to its bounds.
image
    Draws an image loaded from a PNG or JPEG file.  The name of the file to load
    (including the file name extension) is supplied with the required ``file``
    attribute.  Additionally, an optional ``alphafile`` attribute may be used to
    specify the name of a PNG file (including the file name extension) to load
    into the alpha channel of the image.  The image file(s) should be placed in
    the same directory/archive as the layout file.  If the ``alphafile``
    attribute refers  refers to a file, it must have the same dimensions as the
    file referred to by the ``file`` attribute, and must have a bit depth no
    greater than eight bits per channel per pixel.  The intensity from this
    image (brightness) is copied to the alpha channel, with full intensity (white
    in a greyscale image) corresponding to fully opaque, and black corresponding
    to fully transparent.
text
    Draws text in using the UI font in the specified colour.  The text to draw
    must be supplied using a ``string`` attribute.  An ``align`` attribute may
    be supplied to set text alignment.  If present, the ``align`` attribute must
    be an integer, where 0 (zero) means centred, 1 (one) means left-aligned, and
    2 (two) means right-aligned.  If the ``align`` attribute is absent, the text
    will be centred.
dotmatrix
    Draws an eight-pixel horizontal segment of a dot matrix display, using
    circular pixels in the specified colour.  The bits of the element's state
    determine which pixels are lit, with the least significant bit corresponding
    to the leftmost pixel.  Unlit pixels are drawn at low intensity (0x20/0xff).
dotmatrix5dot
    Draws a five-pixel horizontal segment of a dot matrix display, using
    circular pixels in the specified colour.  The bits of the element's state
    determine which pixels are lit, with the least significant bit corresponding
    to the leftmost pixel.  Unlit pixels are drawn at low intensity (0x20/0xff).
dotmatrixdot
    Draws a single element of a dot matrix display as a circular pixels in the
    specified colour.  The least significant bit of the element's state
    determines whether the pixel is lit.  An unlit pixel is drawn at low
    intensity (0x20/0xff).
led7seg
    Draws a standard seven-segment (plus decimal point) digital LED/fluorescent
    display in the specified colour.  The low eight bits of the element's state
    control which segments are lit.  Starting from the least significant bit,
    the bits correspond to the top segment, the upper right-hand segment,
    continuing clockwise to the upper left segment, the middle bar, and the
    decimal point.  Unlit segments are drawn at low intensity (0x20/0xff).
led8seg_gts1
    Draws an eight-segment digital fluorescent display of the type used in
    Gottlieb System 1 pinball machines (actually a Futaba part).  Compared to
    standard seven-segment displays, these displays have no decimal point, the
    horizontal middle bar is broken in the centre, and there is a broken
    vertical middle bar controlled by the bit that would control the decimal
    point in a standard seven-segment display.  Unlit segments are drawn at low
    intensity (0x20/0xff).
led14seg
    Draws a standard fourteen-segment alphanumeric LED/fluorescent display in
    the specified colour.  The low fourteen bits of the element's state control
    which segments are lit.  Starting from the least significant bit, the bits
    correspond to the top segment, the upper right-hand segment, continuing
    clockwise to the upper left segment, the left-hand and right-hand halves of
    the horizontal middle bar, the upper and lower halves of the vertical middle
    bar, and the diagonal bars clockwise from lower left to lower right.  Unlit
    segments are drawn at low intensity (0x20/0xff).
led14segsc
    Draws a standard fourteen-segment alphanumeric LED/fluorescent display with
    decimal point/comma in the specified colour.  The low sixteen bits of the
    element's state control which segments are lit.  The low fourteen bits
    correspond to the same segments as in the ``led14seg`` component.  Two
    additional bits correspond to the decimal point and comma tail.  Unlit
    segments are drawn at low intensity (0x20/0xff).
led16seg
    Draws a standard sixteen-segment alphanumeric LED/fluorescent display in the
    specified colour.  The low sixteen bits of the element's state control which
    segments are lit.  Starting from the least significant bit, the bits
    correspond to the left-hand half of the top bar, the right-hand half of the
    top bar, continuing clockwise to the upper left segment, the left-hand and
    right-hand halves of the horizontal middle bar, the upper and lower halves
    of the vertical middle bar, and the diagonal bars clockwise from lower left
    to lower right.  Unlit segments are drawn at low intensity (0x20/0xff).
led16segsc
    Draws a standard sixteen-segment alphanumeric LED/fluorescent display with
    decimal point/comma in the specified colour.  The low eighteen bits of the
    element's state control which segments are lit.  The low sixteen bits
    correspond to the same segments as in the ``led16seg`` component.  Two
    additional bits correspond to the decimal point and comma tail.  Unlit
    segments are drawn at low intensity (0x20/0xff).
simplecounter
    Displays the numeric value of the element's state using the system font in
    the specified colour.  The value is formatted in decimal notation.  A
    ``digits`` attribute may be supplied to specify the minimum number of digits
    to display.  If present, the ``digits`` attribute must be a positive
    integer; if absent, a minimum of two digits will be displayed.  A
    ``maxstate`` attribute may be supplied to specify the maximum state value to
    display.  If present, the ``maxstate`` attribute must be a non-negative
    number; if absent it defaults to 999.  An ``align`` attribute may be supplied
    to set text alignment.  If present, the ``align`` attribute must be an
    integer, where 0 (zero) means centred, 1 (one) means left-aligned, and 2
    (two) means right-aligned; if absent, the text will be centred.
reel
    Used for drawing slot machine reels.  Supported attributes include
    ``symbollist``, ``stateoffset``, ``numsymbolsvisible``, ``reelreversed``,
    and ``beltreel``.

An example element that draws a static left-aligned text string::

    <element name="label_reset_cpu">
        <text string="CPU" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
    </element>


An example element that displays a circular LED where the intensity depends on
the state of an active-high output::

    <element name="led" defstate="0">
        <rect state="0"><color red="0.43" green="0.35" blue="0.39" /></rect>
        <rect state="1"><color red="1.0" green="0.18" blue="0.20" /></rect>
    </element>

An example element for a button that gives visual feedback when clicked::

    <element name="btn_rst">
        <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect>
        <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect>
        <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect>
        <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect>
        <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect>
        <text string="RESET"><bounds x="0.1" y="0.4" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text>
    </element>


.. _layout-parts-views:

Views
~~~~~

A view defines an arrangement of elements and/or emulated screen images that can
be displayed in a window or on a screen.  Views also connect elements to
emulated I/O ports and/or outputs.  A layout file may contain multiple views.
If a view references a non-existent screen, it will be considered *unviable*.
MAME will print a warning message, skip over the unviable view, and continue to
load views from the layout file.  This is particularly useful for systems where
a screen is optional, for example computer systems with front panel controls and
an optional serial terminal.

Views are identified by name in MAME's user interface and in command-line
options.  For layouts files associated with devices other than the root driver
device, view names are prefixed with the device's tag (with the initial colon
omitted) -- for example a view called "Keyboard LEDs" loaded for the device
``:tty:ie15`` will be called "tty:ie15 Keyboard LEDs" in MAME's user interface.
Views are listed in the order they are loaded.  Within a layout file, views are
loaded in the order they appear, from top to bottom.

Views are created with ``view`` elements inside the top-level ``mamelayout``
element.  Each ``view`` element must have a ``name`` attribute, supplying its
human-readable name for use in the user interface and command-line options.
This is an example of a valid opening tag for a ``view`` element::

    <view name="Control panel">

A view creates a nested parameter scope inside the parameter scope of the
top-level ``mamelayout`` element.  For historical reasons, ``view`` elements are
processed *after* all other child elements of the top-level ``mamelayout``
element.  This means a view can reference elements and groups that appear after
it in the file, and parameters from the enclosing scope will have their final
values from the end of the ``mamelayout`` element.

The following child elements are allowed inside a ``view`` element:

bounds
    Sets the origin and size of the view's internal coordinate system if
    present.  See :ref:`layout-concepts-coordinates` for details.  If absent,
    the bounds of the view are computed as the union of the bounds of all
    screens and elements within the view.  It only makes sense to have one
    ``bounds`` as a direct child of a view element.  Any content outside the
    view's bounds is cropped, and the view is scaled proportionally to fit the
    output window or screen.
param
    Defines or reassigns a value parameter in the view's scope.  See
    :ref:`layout-concepts-params` for details.
backdrop overlay bezel cpanel marquee
    Adds an element to the relevant layer (see :ref:`layout-parts-elements` and
    :ref:`layout-concepts-layers`).  The name of the element to add is specified
    using the required ``element`` attribute.  It is an error if no element with
    this name is defined in the layout file.  May optionally be connected to an
    emulated I/O port using ``inputtag`` and ``inputmask`` attributes, and/or an
    emulated output using a ``name`` attribute.  Within a layer, elements are
    drawn in the order they appear in the layout file, from front to back.  See
    below for more details.
screen
    Adds an emulated screen image to the view.  The screen must be identified
    using either an ``index`` attribute or a ``tag`` attribute (it is an error
    for a ``screen`` element to have both ``index`` and ``tag`` attributes).
    If present, the ``index`` attribute must be a non-negative integer.  Screens
    are numbered by the order they appear in machine configuration, starting at
    zero (0).  If present, the ``tag`` attribute must be the tag path to the
    screen relative to the device that causes the layout to be loaded.  Screens
    are drawn in the order they appear in the layout file, from front to back.
group
    Adds the content of the group to the view (see :ref:`layout-parts-groups`).
    The name of the group to add is specified using the required ``ref``
    attribute.  It is an error if no group with this name is defined in the
    layout file.  See below for more details on positioning.
repeat
    Repeats its contents the number of times specified by the required ``count``
    attribute.  The ``count`` attribute must be a positive integer.  A
    ``repeat`` element in a view may contain ``backdrop``, ``screen``,
    ``overlay``, ``bezel``, ``cpanel``, ``marquee``, ``group``, and further
    ``repeat`` elements, which function the same way they do when placed in a
    view directly.  See :ref:`layout-parts-repeats` for discussion on using
    ``repeat`` elements.

Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``,
``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements)
may be have their orientation altered using an ``orientation`` child element.
For screens, the orientation modifiers are applied in addition to the
orientation modifiers specified on the screen device and on the machine.  The
``orientation`` element supports the following attributes, all of which are
optional:

rotate
    If present, applies clockwise rotation in ninety degree implements.  Must be
    an integer equal to 0, 90, 180 or 270.
swapxy
    Allows the screen, element or group to be mirrored along a line at
    forty-five degrees to vertical from upper left to lower right.  Must be
    either ``yes`` or ``no`` if present.  Mirroring applies logically after
    rotation.
flipx
    Allows the screen, element or group to be mirrored around its vertical axis,
    from left to right.  Must be either ``yes`` or ``no`` if present.  Mirroring
    applies logically after rotation.
flipy
    Allows the screen, element or group to be mirrored around its horizontal
    axis, from top to bottom.  Must be either ``yes`` or ``no`` if present.
    Mirroring applies logically after rotation.

Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``,
``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements)
may be positioned and sized using a ``bounds`` child element (see
:ref:`layout-concepts-coordinates` for details).  In the absence of a ``bounds``
child element, screens' and layout elements' bounds default to a unit square
(origin at 0,0 and height and width both equal to 1).  In the absence of a
``bounds`` child element, groups are expanded with no translation/scaling (note
that groups may position screens/elements outside their bounds).  This example
shows a view instantiating and positioning a screen, an individual layout
element, and two element groups::

    <view name="LED Displays, Terminal and Keypad">
        <cpanel element="beige"><bounds x="320" y="0" width="172" height="372" /></cpanel>
        <group ref="displays"><bounds x="0" y="0" width="320" height="132" /></group>
        <group ref="keypad"><bounds x="336" y="16" width="140" height="260" /></group>
        <screen index="0"><bounds x="0" y="132" width="320" height="240" /></screen>
    </view>

Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``,
``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements)
may have a ``color`` child element (see :ref:`layout-concepts-colours`)
specifying a modifier colour.  The components colours of the screen or layout
element(s) are multiplied by this colour.

If an element instantiating a layout element (``backdrop``, ``overlay``,
``bezel``, ``cpanel`` or ``marquee``) has ``inputtag`` and ``inputmask``
attributes, clicking it is equivalent to pressing a key/button mapped to the
corresponding input(s).  The ``inputtag`` specifies the tag path of an I/O port
relative to the device that caused the layout file to be loaded.  The
``inputmask`` attribute must be an integer specifying the bits of the I/O port
that the element should activate.  This sample is shows instantiation of
clickable buttons::

    <cpanel element="btn_3" inputtag="X2" inputmask="0x10">
        <bounds x="2.30" y="4.325" width="1.0" height="1.0" />
    </cpanel>
    <cpanel element="btn_0" inputtag="X0" inputmask="0x20">
        <bounds x="0.725" y="5.375" width="1.0" height="1.0" /></cpanel>
    <cpanel element="btn_rst" inputtag="RESET" inputmask="0x01">
        <bounds x="1.775" y="5.375" width="1.0" height="1.0" />
    </cpanel>


If an element instantiating a layout element (``backdrop``, ``overlay``,
``bezel``, ``cpanel`` or ``marquee``) has a ``name`` attribute, it will take its
state from the value of the correspondingly named emulated output.  Note that
output names are global, which can become an issue when a machine uses multiple
instances of the same type of device.  See :ref:`layout-parts-elements` for
details on how an element's state affects its appearance.  This example shows
how digital displays may be connected to emulated outputs::

    <cpanel name="digit6" element="digit"><bounds x="16" y="16" width="48" height="80" /></cpanel>
    <cpanel name="digit5" element="digit"><bounds x="64" y="16" width="48" height="80" /></cpanel>
    <cpanel name="digit4" element="digit"><bounds x="112" y="16" width="48" height="80" /></cpanel>
    <cpanel name="digit3" element="digit"><bounds x="160" y="16" width="48" height="80" /></cpanel>
    <cpanel name="digit2" element="digit"><bounds x="208" y="16" width="48" height="80" /></cpanel>
    <cpanel name="digit1" element="digit"><bounds x="256" y="16" width="48" height="80" /></cpanel>

If an element instantiating a layout element has ``inputtag`` and ``inputmask``
attributes but lacks a ``name`` attribute, it will take its state from the value
of the corresponding I/O port, masked with the ``inputmask`` value, and shifted
to the right so that the least significant one bit of the mask aligns with the
least significant bit of the value (for example a mask of 0x05 will result in no
shift, while a mask of 0xb0 will result in the value being shifted four bits to
the right).  This is often used to allow clickable buttons and toggle switches
to provide visible feedback.

When handling mouse input, MAME treats all layout elements as being rectangular,
and only activates the frontmost element whose area includes the location of the
mouse pointer.


.. _layout-parts-groups:

Reusable groups
~~~~~~~~~~~~~~~

Groups allow an arrangement of screens and/or layout elements to be used
multiple times in views or other groups.  Groups can be beneficial even if you
only use the arrangement once, as they can be used to encapsulate part of a
complex layout.  Groups are defined using ``group`` elements inside the
top-level ``mamelayout`` element, and instantiated using ``group`` elements
inside ``view`` and other ``group`` elements.

Each group definition element must have a ``name`` attribute providing a unique
identifier.  It is an error if a layout file contains multiple group definitions
with identical ``name`` attributes.  The value of the ``name`` attribute is used
when instantiating the group from a view or another group.  This is an example
opening tag for a group definition element inside the top-level ``mamelayout``
element::

    <group name="panel">

This group may then be instantiated in a view or another group element using a
group reference element, optionally supplying destination bounds, orientation,
and/or modifier colour.  The ``ref`` attribute identifies the group to
instantiate -- in this example, destination bounds are supplied::

    <group ref="panel"><bounds x="87" y="58" width="23" height="23.5" /></group>

Group definition elements allow all the same child elements as views.
Positioning and orienting screens, layout elements and nested groups works the
same way as for views.  See :ref:`layout-parts-views` for details.  A group may
instantiate other groups, but recursive loops are not permitted.  It is an error
if a group directly or indirectly instantiates itself.

Groups have their own internal coordinate systems.  If a group definition
element has no ``bounds`` element as a direct child, its bounds are computed as
the union of the bounds of all the screens, layout elements and/or nested groups
it instantiates.  A ``bounds`` child element may be used to explicitly specify
group bounds (see :ref:`layout-concepts-coordinates` for details).  Note that
groups' bounds are only used for the purpose of calculating the coordinate
transform when instantiating a group.  A group may position screens and/or
elements outside its bounds, and they will not be cropped.

To demonstrate how bounds calculation works, consider this example::

    <group name="autobounds">
        <!-- bounds automatically calculated with origin at (5,10), width 30, and height 15 -->
        <cpanel element="topleft"><bounds x="5" y="10" width="10" height="10" /></cpanel>
        <cpanel element="bottomright"><bounds x="25" y="15" width="10" height="10" /></cpanel>
    </group>

    <view name="Test">
        <!--
            group bounds translated and scaled to fit - 2/3 scale horizontally and double vertically
            element topleft positioned at (0,0) with width 6.67 and height 20
            element bottomright positioned at (13.33,10) with width 6.67 and height 20
            view bounds calculated with origin at (0,0), width 20, and height 30
        -->
        <group ref="autobounds"><bounds x="0" y="0" width="20" height="30" /></group>
    </view>

This is relatively straightforward, as all elements inherently fall within the
group's automatically computed bounds.  Now consider what happens if a group
positions elements outside its explicit bounds::

    <group name="periphery">
        <!-- elements are above the top edge and to the right of the right edge of the bounds -->
        <bounds x="10" y="10" width="20" height="25" />
        <cpanel element="topleft"><bounds x="10" y="0" width="10" height="10" /></cpanel>
        <cpanel element="bottomright"><bounds x="30" y="20" width="10" height="10" /></cpanel>
    </group>

    <view name="Test">
        <!--
            group bounds translated and scaled to fit - 3/2 scale horizontally and unity vertically
            element topleft positioned at (5,-5) with width 15 and height 10
            element bottomright positioned at (35,15) with width 15 and height 10
            view bounds calculated with origin at (5,-5), width 45, and height 30
        -->
        <group ref="periphery"><bounds x="5" y="5" width="30" height="25" /></group>
    </view>

The group's elements are translated and scaled as necessary to distort the
group's internal bounds to the destination bounds in the view.  The group's
content is not restricted to its bounds.  The view considers the bounds of the
actual layout elements when computing its bounds, not the destination bounds
specified for the group.

When a group is instantiated, it creates a nested parameter scope.  The logical
parent scope is the parameter scope of the view, group or repeating block where
the group is instantiated (*not* its lexical parent, the top-level
``mamelayout`` element).  Any ``param`` elements inside the group definition
element set parameters in the local scope for the group instantiation.  Local
parameters do not persist across multiple instantiations.  See
:ref:`layout-concepts-params` for more detail on parameters.  (Note that the
group's name is not part of its content, and any parameter references in the
``name`` attribute itself will be substituted at the point where the group
definition appears in the top-level ``mamelayout`` element's scope.)


.. _layout-parts-repeats:

Repeating blocks
~~~~~~~~~~~~~~~~

Repeating blocks provide a concise way to generate or arrange large numbers of
similar elements.  Repeating blocks are generally used in conjunction with
generator parameters (see :ref:`layout-concepts-params`).  Repeating blocks may
be nested for more complex arrangements.

Repeating blocks are created with ``repeat`` elements.  Each ``repeat`` element
requires a ``count`` attribute specifying the number of iterations to generate.
The ``count`` attribute must be a positive integer.  Repeating blocks are
allowed inside the top-level ``mamelayout`` element, inside ``group`` and
``view`` elements, and insider other ``repeat`` elements.  The exact child
elements allowed inside a ``repeat`` element depend on where it appears:

* A repeating block inside the top-level ``mamelayout`` element may contain
  ``param``, ``element``, ``group`` (definition), and ``repeat`` elements.
* A repeating block inside a ``group`` or ``view`` element may contain
  ``param``, ``backdrop``, ``screen``, ``overlay``, ``bezel``, ``cpanel``,
  ``marquee``, ``group`` (reference), and ``repeat`` elements.

A repeating block effectively repeats its contents the number of times specified
by its ``count`` attribute.  See the relevant sections for details on how the
child elements are used (:ref:`layout-parts`, :ref:`layout-parts-groups`, and
:ref:`layout-parts-views`).  A repeating block creates a nested parameter scope
inside the parameter scope of its lexical (DOM) parent element.

Generating white number labels from zero to eleven named ``label_0``,
``label_1``, and so on (inside the top-level ``mamelayout`` element)::

    <repeat count="12">
        <param name="labelnum" start="0" increment="1" />
        <element name="label_~labelnum~">
            <text string="~labelnum~"><color red="1.0" green="1.0" blue="1.0" /></text>
        </element>
    </repeat>

A horizontal row of forty digital displays, with five units space between them,
controlled by outputs ``digit0`` to ``digit39`` (inside a ``group`` or ``view``
element)::

    <repeat count="40">
        <param name="i" start="0" increment="1" />
        <param name="x" start="5" increment="30" />
        <bezel name="digit~i~" element="digit">
            <bounds x="~x~" y="5" width="25" height="50" />
        </bezel>
    </repeat>

Eight five-by-seven dot matrix displays in a row, with pixels controlled by
outputs ``Dot_000`` to ``Dot_764`` (inside a ``group`` or ``view`` element)::

    <repeat count="8"> <!-- 8 digits -->
        <param name="digitno" start="1" increment="1" />
        <param name="digitx" start="0" increment="935" /> <!-- distance between digits ((111 * 5) + 380) -->
        <repeat count="7"> <!-- 7 rows in each digit -->
            <param name="rowno" start="1" increment="1" />
            <param name="rowy" start="0" increment="114" /> <!-- vertical distance between LEDs -->
            <repeat count="5"> <!-- 5 columns in each digit -->
                <param name="colno" start="1" increment="1" />
                <param name="colx" start="~digitx~" increment="111" /> <!-- horizontal distance between LEDs -->
                <bezel name="Dot_~digitno~~rowno~~colno~" element="Pixel" state="0">
                    <bounds x="~colx~" y="~rowy~" width="100" height="100" /> <!-- size of each LED -->
                </bezel>
            </repeat>
        </repeat>
    </repeat>

Two horizontally separated, clickable, four-by-four keypads (inside a ``group``
or ``view`` element)::

    <repeat count="2">
        <param name="group" start="0" increment="4" />
        <param name="padx" start="10" increment="530" />
        <param name="mask" start="0x01" lshift="4" />
        <repeat count="4">
            <param name="row" start="0" increment="1" />
            <param name="y" start="100" increment="110" />
            <repeat count="4">
                <param name="col" start="~group~" increment="1" />
                <param name="btnx" start="~padx~" increment="110" />
                <param name="mask" start="~mask~" lshift="1" />
                <bezel element="btn~row~~col~" inputtag="row~row~" inputmask="~mask~">
                    <bounds x="~btnx~" y="~y~" width="80" height="80" />
                </bezel>
            </repeat>
        </repeat>
    </repeat>

The buttons are drawn using elements ``btn00`` in the top left, ``bnt07`` in the
top right, ``btn30`` in the bottom left, and ``btn37`` in the bottom right,
counting in between.  The four rows are connected to I/O ports ``row0``,
``row1``, ``row2``, and ``row3``, from top to bottom.  The columns are connected
to consecutive I/O port bits, starting with the least significant bit on the
left.   Note that the ``mask`` parameter in the innermost ``repeat`` element
takes its initial value from the correspondingly named parameter in the
enclosing scope, but does not modify it.

Generating a chequerboard pattern with alternating alpha values 0.4 and 0.2
(inside a ``group`` or ``view`` element)::

    <repeat count="4">
        <param name="pairy" start="3" increment="20" />
        <param name="pairno" start="7" increment="-2" />
        <repeat count="2">
            <param name="rowy" start="~pairy~" increment="10" />
            <param name="rowno" start="~pairno~" increment="-1" />
            <param name="lalpha" start="0.4" increment="-0.2" />
            <param name="ralpha" start="0.2" increment="0.2" />
            <repeat count="4">
                <param name="lx" start="3" increment="20" />
                <param name="rx" start="13" increment="20" />
                <param name="lmask" start="0x01" lshift="2" />
                <param name="rmask" start="0x02" lshift="2" />
                <bezel element="hl" inputtag="board:IN.~rowno~" inputmask="~lmask~">
                    <bounds x="~lx~" y="~rowy~" width="10" height="10" />
                    <color alpha="~lalpha~" />
                </bezel>
                <bezel element="hl" inputtag="board:IN.~rowno~" inputmask="~rmask~">
                    <bounds x="~rx~" y="~rowy~" width="10" height="10" />
                    <color alpha="~ralpha~" />
                </bezel>
            </repeat>
        </repeat>
    </repeat>

The outermost ``repeat`` element generates a group of two rows on each
iteration; the next ``repeat`` element generates an individual row on each
iteration; the innermost ``repeat`` element produces two horizontally adjacent
tiles on each iteration.  Rows are connected to I/O ports ``board:IN.7`` at the
top to ``board.IN.0`` at the bottom.


.. _layout-errors:

Error handling
--------------

* For internal (developer-supplied) layout files, errors detected by the
  ``complay.py`` script result in a build failure.
* MAME will stop loading a layout file if a syntax error is encountered.  No
  views from the layout will be available.  Examples of syntax errors include
  undefined element or group references, invalid bounds, invalid colours,
  recursively nested groups, and redefined generator parameters.
* When loading a layout file, if a view references a non-existent screen, MAME
  will print a warning message and continue.  Views referencing non-existent
  screens are considered unviable and not available to the user.


.. _layout-autogen:

Automatically-generated views
-----------------------------

After loading internal (developer-supplied) and external (user-supplied)
layouts, MAME automatically generates views based on the machine configuration.
The following views will be automatically generated:

* If the system has no screens and no viable views were found in the internal
  and external layouts, MAME will load a view that shows the message "No screens
  attached to the system".
* For each emulated screen, MAME will generate a view showing the screen at its
  physical aspect ratio with rotation applied.
* For each emulated screen where the configured pixel aspect ratio doesn't match
  the physical aspect ratio, MAME will generate a view showing the screen at an
  aspect ratio that produces square pixels, with rotation applied.
* If the system has a single emulated screen, MAME will generate a view showing
  two copies of the screen image above each other with a small gap between them.
  The upper copy will be rotated by 180 degrees.  This view can be used in a
  "cocktail table" cabinet for simultaneous two-player games, or alternating
  play games that don't automatically rotate the display for the second player.
  The screen will be displayed at its physical aspect ratio, with rotation
  applied.
* If the system has exactly two emulated screens and no view in the internal or
  external layouts shows all screens, or if the system has more than two
  emulated screens, MAME will generate views with the screens arranged
  horizontally from left to right and vertically from top to bottom, both with
  and without small gaps between them.  The screens will be displayed at
  physical aspect ratio, with rotation applied.
* If the system has three or more emulated screens, MAME will generate views
  tiling the screens in grid patterns, in both row-major (left-to-right then
  top-to-bottom) and column-major (top-to-bottom then left-to-right) order.
  Views are generated with and without gaps between the screens.  The screens
  will be displayed at physical aspect ratio, with rotation applied.


.. _layout-complay:

Using complay.py
----------------

The MAME source contains a Python script called ``complay.py``, found in the
``scripts/build`` subdirectory.  This script is used as part of MAME's build
process to reduce the size of data for internal layouts and convert it to a form
that can be built into the executable.  However, it can also detect many common
layout file format errors, and generally provides better error messages than
MAME does when loading a layout file.  Note that it doesn't actually run the
whole layout engine, so it can't detect errors like undefined element references
when parameters are used, or recursively nested groups.  The ``complay.py``
script is compatible with both Python 2.7 and Python 3 interpreters.

The ``complay.py`` script takes three parameters -- an input file name, an
output file name, and a base name for variables in the output::

    python scripts/build/complay.py input [output [varname]]

The input file name is required.  If no output file name is supplied,
``complay.py`` will parse and check the input, reporting any errors found,
without producing output.  If no base variable name is provided, ``complay.py``
will generate one based on the input file name.  This is not guaranteed to
produce valid identifiers.  The exit status is 0 (zero) on success, 1 on an
error in the command invocation, 2 if error are found in the input file, or 3
in case of an I/O error.  If an output file name is specified, the file will be
created/overwritten on success or removed on failure.

To check a layout file for common errors, run the script with the path to the
file no check and no output file name or base variable name.  For example::

    python scripts/build/complay.py artwork/dino/default.lay