summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-07-22 03:22:31 +1000
committer Vas Crabb <vas@vastheman.com>2018-07-22 03:22:31 +1000
commitdce955c68db3cfc700cae11743ad966036faa64f (patch)
tree2f68af92c4321a474449be8cde7e78ffb1ca58f3
parent10f9ec6fcc71b7ed498ce2e825c1b83ee0f53eec (diff)
rendlay: allow user variables and repetition in layouts, also add a few more predefined variables
-rw-r--r--scripts/build/complay.py442
-rw-r--r--src/devices/machine/ie15.cpp10
-rw-r--r--src/emu/layout/quadhsxs.lay48
-rw-r--r--src/emu/render.cpp2
-rw-r--r--src/emu/render.h181
-rw-r--r--src/emu/rendlay.cpp1255
-rw-r--r--src/lib/util/xmlfile.cpp2
-rw-r--r--src/mame/layout/intlc44.lay307
-rw-r--r--src/mame/layout/intlc440.lay307
-rw-r--r--src/mame/layout/mephisto_academy.lay212
-rw-r--r--src/mame/layout/ninjaw.lay36
-rw-r--r--src/mame/layout/playch10.lay24
-rw-r--r--src/mame/layout/ppsatan.lay37
-rw-r--r--src/mame/layout/wildfire.lay133
14 files changed, 1532 insertions, 1464 deletions
diff --git a/scripts/build/complay.py b/scripts/build/complay.py
index 9932c604cb4..8ac24bb005a 100644
--- a/scripts/build/complay.py
+++ b/scripts/build/complay.py
@@ -93,7 +93,8 @@ class XmlError(Exception):
class LayoutChecker(Minifyer):
BADTAGPATTERN = re.compile('[^abcdefghijklmnopqrstuvwxyz0123456789_.:^$]')
- VARPATTERN = re.compile('^~scr(0|[1-9][0-9]*)(native[xy]aspect|width|height)~$')
+ VARPATTERN = re.compile('^.*~[0-9A-Za-z_]+~.*$')
+ FLOATCHARS = re.compile('^.*[.eE].*$')
SHAPES = frozenset(('disk', 'led14seg', 'led14segsc', 'led16seg', 'led16segsc', 'led7seg', 'led8seg_gts1', 'rect'))
OBJECTS = frozenset(('backdrop', 'bezel', 'cpanel', 'marquee', 'overlay'))
@@ -106,8 +107,6 @@ class LayoutChecker(Minifyer):
self.views = { }
self.referenced_elements = { }
self.referenced_groups = { }
- self.have_bounds = [ ]
- self.have_color = [ ]
def formatLocation(self):
return '%s:%d:%d' % (self.locator.getSystemId(), self.locator.getLineNumber(), self.locator.getColumnNumber())
@@ -116,36 +115,125 @@ class LayoutChecker(Minifyer):
self.errors += 1
sys.stderr.write('error: %s: %s\n' % (self.formatLocation(), msg))
- def checkBoundsDimension(self, attrs, name):
- if name in attrs:
- try:
- return float(attrs[name])
- except:
- if not self.VARPATTERN.match(attrs[name]):
- self.handleError('Element bounds attribute %s "%s" is not numeric' % (name, attrs[name]))
- return None
+ def checkIntAttribute(self, name, attrs, key, default):
+ if key not in attrs:
+ return default
+ val = attrs[key]
+ if self.VARPATTERN.match(val):
+ return None
+ base = 10
+ offs = 0
+ if (len(val) >= 1) and ('$' == val[0]):
+ base = 16
+ offs = 1
+ elif (len(val) >= 2) and ('0' == val[0]) and (('x' == val[1]) or ('X' == val[1])):
+ base = 16
+ offs = 2
+ elif (len(val) >= 1) and ('#' == val[0]):
+ offs = 1
+ try:
+ return int(val[offs:], base)
+ except:
+ self.handleError('Element %s attribute %s "%s" is not an integer' % (name, key, val))
+ return None
+
+ def checkFloatAttribute(self, name, attrs, key, default):
+ if key not in attrs:
+ return default
+ val = attrs[key]
+ if self.VARPATTERN.match(val):
+ return None
+ try:
+ return float(val)
+ except:
+ self.handleError('Element %s attribute %s "%s" is not a floating point number' % (name, key, val))
+ return None
+
+ def checkNumericAttribute(self, name, attrs, key, default):
+ if key not in attrs:
+ return default
+ val = attrs[key]
+ if self.VARPATTERN.match(val):
+ return None
+ base = 0
+ offs = 0
+ try:
+ if (len(val) >= 1) and ('$' == val[0]):
+ base = 16
+ offs = 1
+ elif (len(val) >= 2) and ('0' == val[0]) and (('x' == val[1]) or ('X' == val[1])):
+ base = 16
+ offs = 2
+ elif (len(val) >= 1) and ('#' == val[0]):
+ base = 10
+ offs = 1
+ elif self.FLOATCHARS.match(val):
+ return float(val)
+ return int(val[offs:], base)
+ except:
+ self.handleError('Element %s attribute %s "%s" is not a number' % (name, key, val))
+ return None
+
+ def checkParameter(self, attrs):
+ if 'name' not in attrs:
+ self.handleError('Element param missing attribute name')
+ else:
+ name = attrs['name']
+ self.checkNumericAttribute('param', attrs, 'increment', None)
+ lshift = self.checkIntAttribute('param', attrs, 'lshift', None)
+ if (lshift is not None) and (0 > lshift):
+ self.handleError('Element param attribute lshift "%s" is negative', (attrs['lshift'], ))
+ rshift = self.checkIntAttribute('param', attrs, 'rshift', None)
+ if (rshift is not None) and (0 > rshift):
+ self.handleError('Element param attribute rshift "%s" is negative', (attrs['rshift'], ))
+ if self.repeat_depth and self.repeat_depth[-1]:
+ if 'start' in attrs:
+ if 'value' in attrs:
+ self.handleError('Element param has both start and value attributes')
+ if 'name' in attrs:
+ if name not in self.variable_scopes[-1]:
+ self.variable_scopes[-1][name] = True
+ elif not self.VARPATTERN.match(name):
+ self.handleError('Incrementing parameter "%s" redefined', (name, ))
+ else:
+ if 'value' not in attrs:
+ self.handleError('Element param missing attribute value')
+ if ('increment' in attrs) or ('lshift' in attrs) or ('rshift' in attrs):
+ self.handleError('Element param has increment/lshift/rshift attribute(s) without start attribute')
+ if 'name' in attrs:
+ if not self.variable_scopes[-1].get(name, False):
+ self.variable_scopes[-1][name] = False
+ elif not self.VARPATTERN.match(name):
+ self.handleError('Incrementing parameter "%s" redefined', (name, ))
+ else:
+ if ('start' in attrs) or ('increment' in attrs) or ('lshift' in attrs) or ('rshift' in attrs):
+ self.handleError('Element param with start/increment/lshift/rshift attribute(s) not in repeat scope')
+ if 'value' not in attrs:
+ self.handleError('Element param missing attribute value')
+ if 'name' in attrs:
+ self.variable_scopes[-1][attrs['name']] = False
def checkBounds(self, attrs):
if self.have_bounds[-1]:
self.handleError('Duplicate element bounds')
else:
self.have_bounds[-1] = True
- left = self.checkBoundsDimension(attrs, 'left')
- top = self.checkBoundsDimension(attrs, 'top')
- right = self.checkBoundsDimension(attrs, 'right')
- bottom = self.checkBoundsDimension(attrs, 'bottom')
- x = self.checkBoundsDimension(attrs, 'bottom')
- y = self.checkBoundsDimension(attrs, 'bottom')
- width = self.checkBoundsDimension(attrs, 'width')
- height = self.checkBoundsDimension(attrs, 'height')
+ left = self.checkFloatAttribute('bounds', attrs, 'left', 0.0)
+ top = self.checkFloatAttribute('bounds', attrs, 'top', 0.0)
+ right = self.checkFloatAttribute('bounds', attrs, 'right', 1.0)
+ bottom = self.checkFloatAttribute('bounds', attrs, 'bottom', 1.0)
+ x = self.checkFloatAttribute('bounds', attrs, 'x', 0.0)
+ y = self.checkFloatAttribute('bounds', attrs, 'y', 0.0)
+ width = self.checkFloatAttribute('bounds', attrs, 'width', 1.0)
+ height = self.checkFloatAttribute('bounds', attrs, 'height', 1.0)
if (left is not None) and (right is not None) and (left > right):
self.handleError('Element bounds attribute left "%s" is greater than attribute right "%s"' % (
- attrs['left'],
- attrs['right']))
+ attrs.get('left', 0.0),
+ attrs.get('right', 1.0)))
if (top is not None) and (bottom is not None) and (top > bottom):
self.handleError('Element bounds attribute top "%s" is greater than attribute bottom "%s"' % (
- attrs['top'],
- attrs['bottom']))
+ attrs.get('top', 0.0),
+ attrs.get('bottom', 1.0)))
if (width is not None) and (0.0 > width):
self.handleError('Element bounds attribute width "%s" is negative' % (attrs['width'], ))
if (height is not None) and (0.0 > height):
@@ -155,16 +243,12 @@ class LayoutChecker(Minifyer):
has_ltrb = ('left' in attrs) or ('top' in attrs) or ('right' in attrs) or ('bottom' in attrs)
has_origin_size = ('x' in attrs) or ('y' in attrs) or ('width' in attrs) or ('height' in attrs)
if has_ltrb and has_origin_size:
- self.handleError('Element bounds has both left/top/right/bottom and origin/size')
+ self.handleError('Element bounds has both left/top/right/bottom and origin/size attributes')
def checkColorChannel(self, attrs, name):
- if name in attrs:
- try:
- channel = float(attrs[name])
- if (0.0 > channel) or (1.0 < channel):
- self.handleError('Element color attribute %s "%s" outside valid range 0.0-1.0' % (name, attrs[name]))
- except:
- self.handleError('Element color attribute %s "%s" is not numeric' % (name, attrs[name]))
+ channel = self.checkFloatAttribute('color', attrs, name, None)
+ if (channel is not None) and ((0.0 > channel) or (1.0 < channel)):
+ self.handleError('Element color attribute %s "%s" outside valid range 0.0-1.0' % (name, attrs[name]))
def checkTag(self, tag, element, attr):
if '' == tag:
@@ -177,7 +261,118 @@ class LayoutChecker(Minifyer):
if tag.find('::') >= 0:
self.handleError('Element %s attribute %s "%s" contains double separator' % (element, attr, tag))
- def checkGroupViewItem(self, name, attrs):
+ def rootStartHandler(self, name, attrs):
+ if 'mamelayout' != name:
+ self.ignored_depth = 1
+ self.handleError('Expected root element mamelayout but found %s' % (name, ))
+ else:
+ if 'version' not in attrs:
+ self.handleError('Element mamelayout missing attribute version')
+ else:
+ try:
+ long(attrs['version'])
+ except:
+ self.handleError('Element mamelayout attribute version "%s" is not an integer' % (attrs['version'], ))
+ self.variable_scopes.append({ })
+ self.handlers.append((self.layoutStartHandler, self.layoutEndHandler))
+
+ def rootEndHandler(self, name, attrs):
+ pass # should be unreachable
+
+ def layoutStartHandler(self, name, attrs):
+ if 'element' == name:
+ if 'name' not in attrs:
+ self.handleError('Element element missing attribute name')
+ else:
+ if attrs['name'] not in self.elements:
+ self.elements[attrs['name']] = self.formatLocation()
+ elif not self.VARPATTERN.match(attrs['name']):
+ self.handleError('Element element has duplicate name (previous %s)' % (self.elements[attrs['name']], ))
+ self.handlers.append((self.elementStartHandler, self.elementEndHandler))
+ elif 'group' == name:
+ if 'name' not in attrs:
+ self.handleError('Element group missing attribute name')
+ else:
+ if attrs['name'] not in self.groups:
+ self.groups[attrs['name']] = self.formatLocation()
+ elif not self.VARPATTERN.match(attrs['name']):
+ self.handleError('Element group has duplicate name (previous %s)' % (self.groups[attrs['name']], ))
+ self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler))
+ self.variable_scopes.append({ })
+ self.repeat_depth.append(0)
+ self.have_bounds.append(False)
+ elif 'view' == name:
+ if 'name' not in attrs:
+ self.handleError('Element view missing attribute name')
+ else:
+ if attrs['name'] not in self.views:
+ self.views[attrs['name']] = self.formatLocation()
+ elif not self.VARPATTERN.match(attrs['name']):
+ self.handleError('Element view has duplicate name (previous %s)' % (self.views[attrs['name']], ))
+ self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler))
+ self.variable_scopes.append({ })
+ self.repeat_depth.append(0)
+ self.have_bounds.append(False)
+ elif 'param' == name:
+ self.checkParameter(attrs)
+ self.ignored_depth = 1
+ elif 'script' == name:
+ self.ignored_depth = 1
+ else:
+ self.handleError('Encountered unexpected element %s' % (name, ))
+ self.ignored_depth = 1
+
+ def layoutEndHandler(self, name):
+ for element in self.referenced_elements:
+ if (element not in self.elements) and (not self.VARPATTERN.match(element)):
+ self.handleError('Element "%s" not found (first referenced at %s)' % (element, self.referenced_elements[element]))
+ for group in self.referenced_groups:
+ if (group not in self.groups) and (not self.VARPATTERN.match(group)):
+ self.handleError('Group "%s" not found (first referenced at %s)' % (group, self.referenced_groups[group]))
+ self.variable_scopes.pop()
+ self.handlers.pop()
+
+ def elementStartHandler(self, name, attrs):
+ if name in self.SHAPES:
+ self.handlers.append((self.shapeStartHandler, self.shapeEndHandler))
+ self.have_bounds.append(False)
+ self.have_color.append(False)
+ elif 'text' == name:
+ if 'string' not in attrs:
+ self.handleError('Element bounds missing attribute string')
+ if 'align' in attrs:
+ align = self.checkIntAttribute(name, attrs, 'align', None)
+ if (align is not None) and ((0 > align) or (2 < align)):
+ self.handleError('Element text attribute align "%s" not in valid range 0-2' % (attrs['align'], ))
+ self.handlers.append((self.shapeStartHandler, self.shapeEndHandler))
+ self.have_bounds.append(False)
+ self.have_color.append(False)
+ else:
+ self.ignored_depth = 1
+
+ def elementEndHandler(self, name):
+ self.handlers.pop()
+
+ def shapeStartHandler(self, name, attrs):
+ if 'bounds' == name:
+ self.checkBounds(attrs)
+ elif 'color' == name:
+ if self.have_color[-1]:
+ self.handleError('Duplicate bounds element')
+ else:
+ self.have_color[-1] = True
+ self.checkColorChannel(attrs, 'red')
+ self.checkColorChannel(attrs, 'green')
+ self.checkColorChannel(attrs, 'blue')
+ self.checkColorChannel(attrs, 'alpha')
+ self.ignored_depth = 1
+
+ def shapeEndHandler(self, name):
+ self.have_bounds.pop()
+ self.have_color.pop()
+ self.handlers.pop()
+
+ def groupViewStartHandler(self, name, attrs):
if name in self.OBJECTS:
if 'element' not in attrs:
self.handleError('Element %s missing attribute element', (name, ))
@@ -187,21 +382,14 @@ class LayoutChecker(Minifyer):
if 'inputmask' not in attrs:
self.handleError('Element %s has inputtag without inputmask attribute' % (name, ))
self.checkTag(attrs['inputtag'], name, 'inputtag')
- if 'inputmask' in attrs:
- try:
- int(attrs['inputmask'], 0)
- except:
- self.handleError('Element %s attribute inputmask "%s" is not an integer' % (name, attrs['inputmask']))
- self.in_object = True
+ self.checkIntAttribute(name, attrs, 'inputmask', None)
+ self.handlers.append((self.objectStartHandler, self.objectEndHandler))
self.have_bounds.append(False)
elif 'screen' == name:
if 'index' in attrs:
- try:
- index = long(attrs['index'], 0)
- if 0 > index:
- self.handleError('Element screen attribute index "%s" is negative' % (attrs['index'], ))
- except:
- self.handleError('Element screen attribute index "%s" is not an integer' % (attrs['index'], ))
+ index = self.checkIntAttribute(name, attrs, 'index', None)
+ if (index is not None) and (0 > index):
+ self.handleError('Element screen attribute index "%s" is negative' % (attrs['index'], ))
if 'tag' in attrs:
self.handleError('Element screen has both index and tag attributes')
if 'tag' in attrs:
@@ -209,34 +397,65 @@ class LayoutChecker(Minifyer):
self.checkTag(tag, name, 'tag')
if self.BADTAGPATTERN.search(tag):
self.handleError('Element screen attribute tag "%s" contains invalid characters' % (tag, ))
- self.in_object = True
+ self.handlers.append((self.objectStartHandler, self.objectEndHandler))
self.have_bounds.append(False)
elif 'group' == name:
if 'ref' not in attrs:
self.handleError('Element group missing attribute ref')
elif attrs['ref'] not in self.referenced_groups:
self.referenced_groups[attrs['ref']] = self.formatLocation()
- self.in_object = True
+ self.handlers.append((self.objectStartHandler, self.objectEndHandler))
self.have_bounds.append(False)
+ elif 'repeat' == name:
+ if 'count' not in attrs:
+ self.handleError('Element repeat missing attribute count')
+ else:
+ count = self.checkIntAttribute(name, attrs, 'count', None)
+ if (count is not None) and (0 >= count):
+ self.handleError('Element repeat attribute count "%s" is negative' % (attrs['count'], ))
+ self.variable_scopes.append({ })
+ self.repeat_depth[-1] += 1
+ elif 'param' == name:
+ self.checkParameter(attrs)
+ self.ignored_depth = 1
elif 'bounds' == name:
self.checkBounds(attrs)
+ if self.repeat_depth[-1]:
+ self.handleError('Element bounds inside repeat')
self.ignored_depth = 1
else:
self.handleError('Encountered unexpected element %s' % (name, ))
self.ignored_depth = 1
+ def groupViewEndHandler(self, name):
+ self.variable_scopes.pop()
+ if self.repeat_depth[-1]:
+ self.repeat_depth[-1] -= 1
+ else:
+ self.repeat_depth.pop()
+ self.have_bounds.pop()
+ self.handlers.pop()
+
+ def objectStartHandler(self, name, attrs):
+ if 'bounds' == name:
+ self.checkBounds(attrs)
+ self.ignored_depth = 1
+
+ def objectEndHandler(self, name):
+ self.have_bounds.pop()
+ self.handlers.pop()
+
def setDocumentLocator(self, locator):
self.locator = locator
super(LayoutChecker, self).setDocumentLocator(locator)
def startDocument(self):
- self.in_layout = False
- self.in_element = False
- self.in_group = False
- self.in_view = False
- self.in_shape = False
- self.in_object = False
+ self.handlers = [(self.rootStartHandler, self.rootEndHandler)]
self.ignored_depth = 0
+ self.variable_scopes = [ ]
+ self.repeat_depth = [ ]
+ self.have_bounds = [ ]
+ self.have_color = [ ]
super(LayoutChecker, self).startDocument()
def endDocument(self):
@@ -246,127 +465,26 @@ class LayoutChecker(Minifyer):
self.views.clear()
self.referenced_elements.clear()
self.referenced_groups.clear()
- del self.have_bounds[:]
- del self.have_color[:]
+ del self.handlers
+ del self.ignored_depth
+ del self.variable_scopes
+ del self.repeat_depth
+ del self.have_bounds
+ del self.have_color
super(LayoutChecker, self).endDocument()
def startElement(self, name, attrs):
if 0 < self.ignored_depth:
self.ignored_depth += 1
- elif not self.in_layout:
- if 'mamelayout' != name:
- self.ignored_depth = 1
- self.handleError('Expected root element mamelayout but found %s' % (name, ))
- else:
- if 'version' not in attrs:
- self.handleError('Element mamelayout missing attribute version')
- else:
- try:
- long(attrs['version'])
- except:
- self.handleError('Element mamelayout attribute version "%s" is not an integer' % (attrs['version'], ))
- self.in_layout = True
- elif self.in_object:
- if 'bounds' == name:
- self.checkBounds(attrs)
- self.ignored_depth = 1
- elif self.in_shape:
- if 'bounds' == name:
- self.checkBounds(attrs)
- elif 'color' == name:
- if self.have_color[-1]:
- self.handleError('Duplicate bounds element')
- else:
- self.have_color[-1] = True
- self.checkColorChannel(attrs, 'red')
- self.checkColorChannel(attrs, 'green')
- self.checkColorChannel(attrs, 'blue')
- self.checkColorChannel(attrs, 'alpha')
- self.ignored_depth = 1
- elif self.in_element:
- if name in self.SHAPES:
- self.in_shape = True
- self.have_bounds.append(False)
- self.have_color.append(False)
- elif 'text' == name:
- if 'string' not in attrs:
- self.handleError('Element bounds missing attribute string')
- if 'align' in attrs:
- try:
- align = long(attrs['align'])
- if (0 > align) or (2 < align):
- self.handleError('Element text attribute align "%s" not in valid range 0-2' % (attrs['align'], ))
- except:
- self.handleError('Element text attribute align "%s" is not an integer' % (attrs['align'], ))
- self.in_shape = True
- self.have_bounds.append(False)
- self.have_color.append(False)
- else:
- self.ignored_depth = 1
- elif self.in_group or self.in_view:
- self.checkGroupViewItem(name, attrs)
- elif 'element' == name:
- if 'name' not in attrs:
- self.handleError('Element element missing attribute name')
- else:
- if attrs['name'] in self.elements:
- self.handleError('Element element has duplicate name (previous %s)' % (self.elements[attrs['name']], ))
- else:
- self.elements[attrs['name']] = self.formatLocation()
- self.in_element = True
- elif 'group' == name:
- if 'name' not in attrs:
- self.handleError('Element group missing attribute name')
- else:
- if attrs['name'] in self.groups:
- self.handleError('Element group has duplicate name (previous %s)' % (self.groups[attrs['name']], ))
- else:
- self.groups[attrs['name']] = self.formatLocation()
- self.in_group = True
- self.have_bounds.append(False)
- elif 'view' == name:
- if 'name' not in attrs:
- self.handleError('Element view missing attribute name')
- else:
- if attrs['name'] in self.views:
- self.handleError('Element view has duplicate name (previous %s)' % (self.views[attrs['name']], ))
- else:
- self.views[attrs['name']] = self.formatLocation()
- self.in_view = True
- self.have_bounds.append(False)
- elif 'script' == name:
- self.ignored_depth = 1
else:
- self.handleError('Encountered unexpected element %s' % (name, ))
- self.ignored_depth = 1
+ self.handlers[-1][0](name, attrs)
super(LayoutChecker, self).startElement(name, attrs)
def endElement(self, name):
if 0 < self.ignored_depth:
self.ignored_depth -= 1
- elif self.in_object:
- self.in_object = False
- self.have_bounds.pop()
- elif self.in_shape:
- self.in_shape = False
- self.have_bounds.pop()
- self.have_color.pop()
- elif self.in_element:
- self.in_element = False
- elif self.in_group:
- self.in_group = False
- self.have_bounds.pop()
- elif self.in_view:
- self.in_view = False
- self.have_bounds.pop()
- elif self.in_layout:
- for element in self.referenced_elements:
- if element not in self.elements:
- self.handleError('Element "%s" not found (first referenced at %s)' % (element, self.referenced_elements[element]))
- for group in self.referenced_groups:
- if group not in self.groups:
- self.handleError('Group "%s" not found (first referenced at %s)' % (group, self.referenced_groups[group]))
- self.in_layout = False
+ else:
+ self.handlers[-1][1](name)
super(LayoutChecker, self).endElement(name)
diff --git a/src/devices/machine/ie15.cpp b/src/devices/machine/ie15.cpp
index 308c059de38..6b60489504d 100644
--- a/src/devices/machine/ie15.cpp
+++ b/src/devices/machine/ie15.cpp
@@ -604,13 +604,13 @@ ROM_START( ie15 )
ROM_END
MACHINE_CONFIG_START(ie15_device::device_add_mconfig)
- ie15core(config);
-
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
MCFG_SCREEN_UPDATE_DRIVER(ie15_device, screen_update)
- MCFG_SCREEN_RAW_PARAMS(XTAL(30'800'000)/2, IE15_TOTAL_HORZ, IE15_HORZ_START,
- IE15_HORZ_START+IE15_DISP_HORZ, IE15_TOTAL_VERT, IE15_VERT_START,
- IE15_VERT_START+IE15_DISP_VERT);
+ MCFG_SCREEN_RAW_PARAMS(XTAL(30'800'000)/2,
+ IE15_TOTAL_HORZ, IE15_HORZ_START, IE15_HORZ_START+IE15_DISP_HORZ,
+ IE15_TOTAL_VERT, IE15_VERT_START, IE15_VERT_START+IE15_DISP_VERT);
+
+ ie15core(config);
MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_ie15)
MCFG_PALETTE_ADD_MONOCHROME("palette")
diff --git a/src/emu/layout/quadhsxs.lay b/src/emu/layout/quadhsxs.lay
index b07a04e7b11..a5a347299cb 100644
--- a/src/emu/layout/quadhsxs.lay
+++ b/src/emu/layout/quadhsxs.lay
@@ -1,53 +1,5 @@
<?xml version="1.0"?>
<mamelayout version="2">
- <view name="Screen 0 Standard (4:3)">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 1 Standard (4:3)">
- <screen index="1">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 2 Standard (4:3)">
- <screen index="2">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 3 Standard (4:3)">
- <screen index="3">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
- <screen index="0">
- <bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
- </screen>
- </view>
-
- <view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
- <screen index="1">
- <bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
- </screen>
- </view>
-
- <view name="Screen 2 Pixel Aspect (~scr2nativexaspect~:~scr2nativeyaspect~)">
- <screen index="2">
- <bounds left="0" top="0" right="~scr2width~" bottom="~scr2height~" />
- </screen>
- </view>
-
- <view name="Screen 3 Pixel Aspect (~scr3nativexaspect~:~scr3nativeyaspect~)">
- <screen index="3">
- <bounds left="0" top="0" right="~scr3width~" bottom="~scr3height~" />
- </screen>
- </view>
-
<view name="Quad Side-by-Side">
<screen index="0">
<bounds x="0" y="0" width="4" height="3" />
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index f1ce0b1fc8e..9ec8445fa49 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -79,7 +79,7 @@ enum
//**************************************************************************
// an object_transform is used to track transformations when building an object list
-struct object_transform
+struct render_target::object_transform
{
float xoffs, yoffs; // offset transforms
float xscale, yscale; // scale transforms
diff --git a/src/emu/render.h b/src/emu/render.h
index 66c885a4c78..e07e7e7cad7 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -57,6 +57,9 @@
#include <vector>
+namespace emu { namespace render { namespace detail { class layout_environment; } } }
+
+
//**************************************************************************
// CONSTANTS
//**************************************************************************
@@ -127,41 +130,38 @@ constexpr u32 PRIMFLAG_PACKABLE = 1 << PRIMFLAG_PACKABLE_SHIFT;
// MACROS
//**************************************************************************
-#define PRIMFLAG_TEXORIENT(x) ((x) << PRIMFLAG_TEXORIENT_SHIFT)
-#define PRIMFLAG_GET_TEXORIENT(x) (((x) & PRIMFLAG_TEXORIENT_MASK) >> PRIMFLAG_TEXORIENT_SHIFT)
+constexpr u32 PRIMFLAG_TEXORIENT(u32 x) { return x << PRIMFLAG_TEXORIENT_SHIFT; }
+constexpr u32 PRIMFLAG_GET_TEXORIENT(u32 x) { return (x & PRIMFLAG_TEXORIENT_MASK) >> PRIMFLAG_TEXORIENT_SHIFT; }
-#define PRIMFLAG_TEXFORMAT(x) ((x) << PRIMFLAG_TEXFORMAT_SHIFT)
-#define PRIMFLAG_GET_TEXFORMAT(x) (((x) & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT)
+constexpr u32 PRIMFLAG_TEXFORMAT(u32 x) { return x << PRIMFLAG_TEXFORMAT_SHIFT; }
+constexpr u32 PRIMFLAG_GET_TEXFORMAT(u32 x) { return (x & PRIMFLAG_TEXFORMAT_MASK) >> PRIMFLAG_TEXFORMAT_SHIFT; }
-#define PRIMFLAG_BLENDMODE(x) ((x) << PRIMFLAG_BLENDMODE_SHIFT)
-#define PRIMFLAG_GET_BLENDMODE(x) (((x) & PRIMFLAG_BLENDMODE_MASK) >> PRIMFLAG_BLENDMODE_SHIFT)
+constexpr u32 PRIMFLAG_BLENDMODE(u32 x) { return x << PRIMFLAG_BLENDMODE_SHIFT; }
+constexpr u32 PRIMFLAG_GET_BLENDMODE(u32 x) { return (x & PRIMFLAG_BLENDMODE_MASK) >> PRIMFLAG_BLENDMODE_SHIFT; }
-#define PRIMFLAG_ANTIALIAS(x) ((x) << PRIMFLAG_ANTIALIAS_SHIFT)
-#define PRIMFLAG_GET_ANTIALIAS(x) (((x) & PRIMFLAG_ANTIALIAS_MASK) >> PRIMFLAG_ANTIALIAS_SHIFT)
+constexpr u32 PRIMFLAG_ANTIALIAS(u32 x) { return x << PRIMFLAG_ANTIALIAS_SHIFT; }
+constexpr u32 PRIMFLAG_GET_ANTIALIAS(u32 x) { return (x & PRIMFLAG_ANTIALIAS_MASK) >> PRIMFLAG_ANTIALIAS_SHIFT; }
-#define PRIMFLAG_SCREENTEX(x) ((x) << PRIMFLAG_SCREENTEX_SHIFT)
-#define PRIMFLAG_GET_SCREENTEX(x) (((x) & PRIMFLAG_SCREENTEX_MASK) >> PRIMFLAG_SCREENTEX_SHIFT)
+constexpr u32 PRIMFLAG_SCREENTEX(u32 x) { return x << PRIMFLAG_SCREENTEX_SHIFT; }
+constexpr u32 PRIMFLAG_GET_SCREENTEX(u32 x) { return (x & PRIMFLAG_SCREENTEX_MASK) >> PRIMFLAG_SCREENTEX_SHIFT; }
-#define PRIMFLAG_TEXWRAP(x) ((x) << PRIMFLAG_TEXWRAP_SHIFT)
-#define PRIMFLAG_GET_TEXWRAP(x) (((x) & PRIMFLAG_TEXWRAP_MASK) >> PRIMFLAG_TEXWRAP_SHIFT)
+constexpr u32 PRIMFLAG_TEXWRAP(u32 x) { return x << PRIMFLAG_TEXWRAP_SHIFT; }
+constexpr u32 PRIMFLAG_GET_TEXWRAP(u32 x) { return (x & PRIMFLAG_TEXWRAP_MASK) >> PRIMFLAG_TEXWRAP_SHIFT; }
-#define PRIMFLAG_TEXSHADE(x) ((x) << PRIMFLAG_TEXSHADE_SHIFT)
-#define PRIMFLAG_GET_TEXSHADE(x) (((x) & PRIMFLAG_TEXSHADE_MASK) >> PRIMFLAG_TEXSHADE_SHIFT)
+constexpr u32 PRIMFLAG_TEXSHADE(u32 x) { return x << PRIMFLAG_TEXSHADE_SHIFT; }
+constexpr u32 PRIMFLAG_GET_TEXSHADE(u32 x) { return (x & PRIMFLAG_TEXSHADE_MASK) >> PRIMFLAG_TEXSHADE_SHIFT; }
-#define PRIMFLAG_VECTOR(x) ((x) << PRIMFLAG_VECTOR_SHIFT)
-#define PRIMFLAG_GET_VECTOR(x) (((x) & PRIMFLAG_VECTOR_MASK) >> PRIMFLAG_VECTOR_SHIFT)
+constexpr u32 PRIMFLAG_VECTOR(u32 x) { return x << PRIMFLAG_VECTOR_SHIFT; }
+constexpr u32 PRIMFLAG_GET_VECTOR(u32 x) { return (x & PRIMFLAG_VECTOR_MASK) >> PRIMFLAG_VECTOR_SHIFT; }
-#define PRIMFLAG_VECTORBUF(x) ((x) << PRIMFLAG_VECTORBUF_SHIFT)
-#define PRIMFLAG_GET_VECTORBUF(x) (((x) & PRIMFLAG_VECTORBUF_MASK) >> PRIMFLAG_VECTORBUF_SHIFT)
+constexpr u32 PRIMFLAG_VECTORBUF(u32 x) { return x << PRIMFLAG_VECTORBUF_SHIFT; }
+constexpr u32 PRIMFLAG_GET_VECTORBUF(u32 x) { return (x & PRIMFLAG_VECTORBUF_MASK) >> PRIMFLAG_VECTORBUF_SHIFT; }
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
-// private classes declared in render.cpp
-struct object_transform;
-
// texture scaling callback
typedef void (*texture_scaler_func)(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
@@ -173,8 +173,8 @@ struct render_bounds
float x1; // rightmost X coordinate
float y1; // bottommost Y coordinate
- float width() const { return x1 - x0; }
- float height() const { return y1 - y0; }
+ constexpr float width() const { return x1 - x0; }
+ constexpr float height() const { return y1 - y0; }
};
@@ -232,12 +232,10 @@ class render_screen_list
public:
// construction/destruction
- item(screen_device &screen)
- : m_next(nullptr),
- m_screen(screen) { }
+ item(screen_device &screen) : m_screen(screen) { }
// state
- item * m_next; // next screen in list
+ item * m_next = nullptr; // next screen in list
screen_device & m_screen; // reference to screen device
};
@@ -253,7 +251,7 @@ public:
int contains(screen_device &screen) const
{
int count = 0;
- for (item *curitem = m_list.first(); curitem != nullptr; curitem = curitem->m_next)
+ for (item *curitem = m_list.first(); curitem; curitem = curitem->m_next)
if (&curitem->m_screen == &screen) count++;
return count;
}
@@ -269,6 +267,7 @@ private:
// render_layer_config - describes the state of layers
class render_layer_config
{
+private:
static constexpr u8 ENABLE_BACKDROP = 0x01; // enable backdrop layers
static constexpr u8 ENABLE_OVERLAY = 0x02; // enable overlay layers
static constexpr u8 ENABLE_BEZEL = 0x04; // enable bezel layers
@@ -278,31 +277,36 @@ class render_layer_config
static constexpr u8 ENABLE_SCREEN_OVERLAY = 0x40; // enable screen overlays
static constexpr u8 DEFAULT = ENABLE_BACKDROP | ENABLE_OVERLAY | ENABLE_BEZEL | ENABLE_CPANEL | ENABLE_MARQUEE | ENABLE_SCREEN_OVERLAY;
+ u8 m_state = DEFAULT;
+
+ render_layer_config &set_flag(u8 flag, bool enable)
+ {
+ if (enable) m_state |= flag;
+ else m_state &= ~flag;
+ return *this;
+ }
+
public:
- render_layer_config()
- : m_state(DEFAULT) { }
+ constexpr render_layer_config() { }
bool operator==(const render_layer_config &rhs) const { return m_state == rhs.m_state; }
bool operator!=(const render_layer_config &rhs) const { return m_state != rhs.m_state; }
- bool backdrops_enabled() const { return ((m_state & ENABLE_BACKDROP) != 0); }
- bool overlays_enabled() const { return ((m_state & ENABLE_OVERLAY) != 0); }
- bool bezels_enabled() const { return ((m_state & ENABLE_BEZEL) != 0); }
- bool cpanels_enabled() const { return ((m_state & ENABLE_CPANEL) != 0); }
- bool marquees_enabled() const { return ((m_state & ENABLE_MARQUEE) != 0); }
- bool screen_overlay_enabled() const { return ((m_state & ENABLE_SCREEN_OVERLAY) != 0); }
- bool zoom_to_screen() const { return ((m_state & ZOOM_TO_SCREEN) != 0); }
-
- render_layer_config &set_backdrops_enabled(bool enable) { if (enable) m_state |= ENABLE_BACKDROP; else m_state &= ~ENABLE_BACKDROP; return *this; }
- render_layer_config &set_overlays_enabled(bool enable) { if (enable) m_state |= ENABLE_OVERLAY; else m_state &= ~ENABLE_OVERLAY; return *this; }
- render_layer_config &set_bezels_enabled(bool enable) { if (enable) m_state |= ENABLE_BEZEL; else m_state &= ~ENABLE_BEZEL; return *this; }
- render_layer_config &set_cpanels_enabled(bool enable) { if (enable) m_state |= ENABLE_CPANEL; else m_state &= ~ENABLE_CPANEL; return *this; }
- render_layer_config &set_marquees_enabled(bool enable) { if (enable) m_state |= ENABLE_MARQUEE; else m_state &= ~ENABLE_MARQUEE; return *this; }
- render_layer_config &set_screen_overlay_enabled(bool enable) { if (enable) m_state |= ENABLE_SCREEN_OVERLAY; else m_state &= ~ENABLE_SCREEN_OVERLAY; return *this; }
- render_layer_config &set_zoom_to_screen(bool zoom) { if (zoom) m_state |= ZOOM_TO_SCREEN; else m_state &= ~ZOOM_TO_SCREEN; return *this; }
-
-private:
- u8 m_state;
+ constexpr bool backdrops_enabled() const { return (m_state & ENABLE_BACKDROP) != 0; }
+ constexpr bool overlays_enabled() const { return (m_state & ENABLE_OVERLAY) != 0; }
+ constexpr bool bezels_enabled() const { return (m_state & ENABLE_BEZEL) != 0; }
+ constexpr bool cpanels_enabled() const { return (m_state & ENABLE_CPANEL) != 0; }
+ constexpr bool marquees_enabled() const { return (m_state & ENABLE_MARQUEE) != 0; }
+ constexpr bool screen_overlay_enabled() const { return (m_state & ENABLE_SCREEN_OVERLAY) != 0; }
+ constexpr bool zoom_to_screen() const { return (m_state & ZOOM_TO_SCREEN) != 0; }
+
+ render_layer_config &set_backdrops_enabled(bool enable) { return set_flag(ENABLE_BACKDROP, enable); }
+ render_layer_config &set_overlays_enabled(bool enable) { return set_flag(ENABLE_OVERLAY, enable); }
+ render_layer_config &set_bezels_enabled(bool enable) { return set_flag(ENABLE_BEZEL, enable); }
+ render_layer_config &set_cpanels_enabled(bool enable) { return set_flag(ENABLE_CPANEL, enable); }
+ render_layer_config &set_marquees_enabled(bool enable) { return set_flag(ENABLE_MARQUEE, enable); }
+ render_layer_config &set_screen_overlay_enabled(bool enable) { return set_flag(ENABLE_SCREEN_OVERLAY, enable); }
+ render_layer_config &set_zoom_to_screen(bool zoom) { return set_flag(ZOOM_TO_SCREEN, zoom); }
};
@@ -314,13 +318,7 @@ class render_primitive
friend class simple_list<render_primitive>;
public:
- render_primitive():
- type(),
- flags(0),
- width(0),
- container(nullptr),
- m_next(nullptr)
- {}
+ render_primitive() { }
// render primitive types
enum primitive_type
@@ -342,19 +340,19 @@ public:
void reset();
// public state
- primitive_type type; // type of primitive
+ primitive_type type = INVALID; // type of primitive
render_bounds bounds; // bounds or positions
render_bounds full_bounds; // bounds or positions (unclipped)
render_color color; // RGBA values
- u32 flags; // flags
- float width; // width (for line primitives)
+ u32 flags = 0U; // flags
+ float width = 0.0F; // width (for line primitives)
render_texinfo texture; // texture info (for quad primitives)
render_quad_texuv texcoords; // texture coordinates (for quad primitives)
- render_container * container; // the render container we belong to
+ render_container * container = nullptr;// the render container we belong to
private:
// internal state
- render_primitive * m_next; // pointer to next element
+ render_primitive * m_next = nullptr; // pointer to next element
};
@@ -459,7 +457,7 @@ private:
struct scaled_texture
{
bitmap_argb32 * bitmap; // final bitmap
- u32 seqid; // sequence number
+ u32 seqid; // sequence number
};
// internal state
@@ -468,12 +466,12 @@ private:
bitmap_t * m_bitmap; // pointer to the original bitmap
rectangle m_sbounds; // source bounds within the bitmap
texture_format m_format; // format of the texture data
- u64 m_osddata; // aux data to pass to osd
+ u64 m_osddata; // aux data to pass to osd
// scaling state (ARGB32 only)
texture_scaler_func m_scaler; // scaling callback
void * m_param; // scaling callback parameter
- u32 m_curseq; // current sequence number
+ u32 m_curseq; // current sequence number
scaled_texture m_scaled[MAX_TEXTURE_SCALES];// array of scaled variants of this texture
};
@@ -566,11 +564,11 @@ private:
private:
// internal state
item * m_next; // pointer to the next element in the list
- u8 m_type; // type of element
+ u8 m_type; // type of element
render_bounds m_bounds; // bounds of the element
render_color m_color; // RGBA factors
- u32 m_flags; // option flags
- u32 m_internal; // internal flags
+ u32 m_flags; // option flags
+ u32 m_internal; // internal flags
float m_width; // width of the line (lines only)
render_texture * m_texture; // pointer to the source texture (quads only)
};
@@ -635,8 +633,10 @@ DECLARE_ENUM_INCDEC_OPERATORS(item_layer)
class layout_element
{
public:
+ using environment = emu::render::detail::layout_environment;
+
// construction/destruction
- layout_element(running_machine &machine, util::xml::data_node const &elemnode, const char *dirname);
+ layout_element(environment &env, util::xml::data_node const &elemnode, const char *dirname);
virtual ~layout_element();
// getters
@@ -659,7 +659,7 @@ private:
typedef std::unique_ptr<component> ptr;
// construction/destruction
- component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
+ component(environment &env, util::xml::data_node const &compnode, const char *dirname);
virtual ~component() = default;
// setup
@@ -727,13 +727,13 @@ private:
int m_state; // associated state number
};
- typedef component::ptr (*make_component_func)(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
+ typedef component::ptr (*make_component_func)(environment &env, util::xml::data_node const &compnode, const char *dirname);
typedef std::map<std::string, make_component_func> make_component_map;
// internal helpers
static void element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param);
- template <typename T> static component::ptr make_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
- template <int D> static component::ptr make_dotmatrix_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
+ template <typename T> static component::ptr make_component(environment &env, util::xml::data_node const &compnode, const char *dirname);
+ template <int D> static component::ptr make_dotmatrix_component(environment &env, util::xml::data_node const &compnode, const char *dirname);
static make_component_map const s_make_component; // maps component XML names to creator functions
@@ -757,9 +757,10 @@ private:
class layout_group
{
public:
- typedef std::unordered_map<std::string, layout_group> group_map;
+ using environment = emu::render::detail::layout_environment;
+ using group_map = std::unordered_map<std::string, layout_group>;
- layout_group(running_machine &machine, util::xml::data_node const &groupnode);
+ layout_group(util::xml::data_node const &groupnode);
~layout_group();
util::xml::data_node const &get_groupnode() const { return m_groupnode; }
@@ -767,12 +768,19 @@ public:
render_bounds make_transform(render_bounds const &dest) const;
render_bounds make_transform(render_bounds const &dest, render_bounds const &transform) const;
- void resolve_bounds(group_map &groupmap);
+ void set_bounds_unresolved();
+ void resolve_bounds(environment &env, group_map &groupmap);
private:
- void resolve_bounds(group_map &groupmap, std::vector<layout_group const *> &seen);
+ void resolve_bounds(environment &env, group_map &groupmap, std::vector<layout_group const *> &seen);
+ void resolve_bounds(
+ environment &env,
+ util::xml::data_node const &parentnode,
+ group_map &groupmap,
+ std::vector<layout_group const *> &seen,
+ bool repeat,
+ bool init);
- running_machine & m_machine;
util::xml::data_node const & m_groupnode;
render_bounds m_bounds;
bool m_bounds_resolved;
@@ -787,6 +795,7 @@ private:
class layout_view
{
public:
+ using environment = emu::render::detail::layout_environment;
using element_map = std::unordered_map<std::string, layout_element>;
using group_map = std::unordered_map<std::string, layout_group>;
@@ -806,7 +815,7 @@ public:
public:
// construction/destruction
item(
- device_t &device,
+ environment &env,
util::xml::data_node const &itemnode,
element_map &elemmap,
render_bounds const &transform);
@@ -846,10 +855,10 @@ public:
// construction/destruction
layout_view(
- device_t &device,
+ environment &env,
util::xml::data_node const &viewnode,
element_map &elemmap,
- group_map const &groupmap);
+ group_map &groupmap);
~layout_view();
// getters
@@ -873,13 +882,16 @@ public:
private:
// add items, recursing for groups
void add_items(
- device_t &device,
+ environment &env,
util::xml::data_node const &parentnode,
element_map &elemmap,
- group_map const &groupmap,
- render_bounds const &transform);
+ group_map &groupmap,
+ render_bounds const &transform,
+ bool root,
+ bool repeat,
+ bool init);
- static std::string make_name(device_t &device, util::xml::data_node const &viewnode);
+ static std::string make_name(environment &env, util::xml::data_node const &viewnode);
// internal state
std::string m_name; // name of the layout
@@ -1014,6 +1026,9 @@ public:
void resolve_tags();
private:
+ // private classes declared in render.cpp
+ struct object_transform;
+
// internal helpers
enum constructor_impl_t { CONSTRUCTOR_IMPL };
template <typename T> render_target(render_manager &manager, T&& layout, u32 flags, constructor_impl_t);
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index e245aebf2dd..d07c07704a6 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -15,12 +15,21 @@
#include "rendfont.h"
#include "rendlay.h"
#include "rendutil.h"
+#include "vecstream.h"
#include "xmlfile.h"
#include <ctype.h>
+#include <algorithm>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
+#include <iomanip>
+#include <locale>
#include <sstream>
#include <stdexcept>
+#include <tuple>
#include <type_traits>
+#include <utility>
@@ -69,6 +78,8 @@ enum
LINE_CAP_END = 2
};
+std::locale const f_portable_locale("C");
+
//**************************************************************************
@@ -129,253 +140,727 @@ inline void render_bounds_transform(render_bounds &bounds, render_bounds const &
class layout_syntax_error : public std::invalid_argument { using std::invalid_argument::invalid_argument; };
class layout_reference_error : public std::out_of_range { using std::out_of_range::out_of_range; };
+} // anonymous namespace
-//**************************************************************************
-// SHARED PARSING HELPERS
-//**************************************************************************
+namespace emu { namespace render { namespace detail {
-//-------------------------------------------------
-// get_variable_value - compute the value of
-// a variable in an XML attribute
-//-------------------------------------------------
-
-int get_variable_value(running_machine &machine, const char *string, char **outputptr)
+class layout_environment
{
- char temp[100];
-
- // screen 0 parameters
- int scrnum = 0;
- for (const screen_device &device : screen_device_iterator(machine.root_device()))
- {
- // native X aspect factor
- sprintf(temp, "~scr%dnativexaspect~", scrnum);
- if (!strncmp(string, temp, strlen(temp)))
+private:
+ class entry
+ {
+ public:
+ entry(std::string &&name, std::string &&t)
+ : m_name(std::move(name))
+ , m_text(std::move(t))
+ , m_text_valid(true)
+ { }
+ entry(std::string &&name, s64 i)
+ : m_name(std::move(name))
+ , m_int(i)
+ , m_int_valid(true)
+ { }
+ entry(std::string &&name, double f)
+ : m_name(std::move(name))
+ , m_float(f)
+ , m_float_valid(true)
+ { }
+ entry(std::string &&name, std::string &&t, s64 i, int s)
+ : m_name(std::move(name))
+ , m_text(std::move(t))
+ , m_int_increment(i)
+ , m_shift(s)
+ , m_text_valid(true)
+ , m_incrementing(true)
+ { }
+ entry(std::string &&name, std::string &&t, double i, int s)
+ : m_name(std::move(name))
+ , m_text(std::move(t))
+ , m_float_increment(i)
+ , m_shift(s)
+ , m_text_valid(true)
+ , m_incrementing(true)
+ { }
+ entry(entry &&) = default;
+ entry &operator=(entry &&) = default;
+
+ void set(std::string &&t)
{
- int num = device.visible_area().width();
- int den = device.visible_area().height();
- reduce_fraction(num, den);
- *outputptr += sprintf(*outputptr, "%d", num);
- return strlen(temp);
+ m_text = std::move(t);
+ m_text_valid = true;
+ m_int_valid = false;
+ m_float_valid = false;
}
-
- // native Y aspect factor
- sprintf(temp, "~scr%dnativeyaspect~", scrnum);
- if (!strncmp(string, temp, strlen(temp)))
+ void set(s64 i)
{
- int num = device.visible_area().width();
- int den = device.visible_area().height();
- reduce_fraction(num, den);
- *outputptr += sprintf(*outputptr, "%d", den);
- return strlen(temp);
+ m_int = i;
+ m_text_valid = false;
+ m_int_valid = true;
+ m_float_valid = false;
}
-
- // native width
- sprintf(temp, "~scr%dwidth~", scrnum);
- if (!strncmp(string, temp, strlen(temp)))
+ void set(double f)
{
- *outputptr += sprintf(*outputptr, "%d", device.visible_area().width());
- return strlen(temp);
+ m_float = f;
+ m_text_valid = false;
+ m_int_valid = false;
+ m_float_valid = true;
}
- // native height
- sprintf(temp, "~scr%dheight~", scrnum);
- if (!strncmp(string, temp, strlen(temp)))
+ std::string const &name() const { return m_name; }
+ bool is_incrementing() const { return m_incrementing; }
+
+ std::string const &get_text()
{
- *outputptr += sprintf(*outputptr, "%d", device.visible_area().height());
- return strlen(temp);
+ if (!m_text_valid)
+ {
+ if (m_float_valid)
+ {
+ m_text = std::to_string(m_float);
+ m_text_valid = true;
+ }
+ else if (m_int_valid)
+ {
+ m_text = std::to_string(m_int);
+ m_text_valid = true;
+ }
+ }
+ return m_text;
}
- // keep count
- scrnum++;
- }
+ void increment()
+ {
+ if (is_incrementing())
+ {
+ // apply increment
+ if (m_float_increment)
+ {
+ if (m_int_valid && !m_float_valid)
+ {
+ m_float = m_int;
+ m_float_valid = true;
+ }
+ if (m_text_valid && !m_float_valid)
+ {
+ std::istringstream stream(m_text);
+ stream.imbue(f_portable_locale);
+ m_text.c_str();
+ if (m_text[0] == '$')
+ {
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_float = uvalue;
+ }
+ else if ((m_text[0] == '0') && ((m_text[1] == 'x') || (m_text[1] == 'X')))
+ {
+ stream.get();
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_float = uvalue;
+ }
+ else if (m_text[0] == '#')
+ {
+ stream.get();
+ stream >> m_int;
+ m_float = m_int;
+ }
+ else
+ {
+ stream >> m_float;
+ }
+ m_float_valid = bool(stream);
+ }
+ m_float += m_float_increment;
+ m_int_valid = m_text_valid = false;
+ }
+ else
+ {
+ if (m_text_valid && !m_int_valid && !m_float_valid)
+ {
+ std::istringstream stream(m_text);
+ stream.imbue(f_portable_locale);
+ m_text.c_str();
+ if (m_text[0] == '$')
+ {
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_int = s64(uvalue);
+ m_int_valid = bool(stream);
+ }
+ else if ((m_text[0] == '0') && ((m_text[1] == 'x') || (m_text[1] == 'X')))
+ {
+ stream.get();
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_int = s64(uvalue);
+ m_int_valid = bool(stream);
+ }
+ else if (m_text[0] == '#')
+ {
+ stream.get();
+ stream >> m_int;
+ m_int_valid = bool(stream);
+ }
+ else if (m_text.find_first_of(".eE") != std::string::npos)
+ {
+ stream >> m_float;
+ m_float_valid = bool(stream);
+ }
+ else
+ {
+ stream >> m_int;
+ m_int_valid = bool(stream);
+ }
+ }
- // default: copy the first character and continue
- **outputptr = *string;
- *outputptr += 1;
- return 1;
-}
+ if (m_float_valid)
+ {
+ m_float += m_int_increment;
+ m_int_valid = m_text_valid = false;
+ }
+ else
+ {
+ m_int += m_int_increment;
+ m_float_valid = m_text_valid = false;
+ }
+ }
+ // apply shift
+ if (m_shift)
+ {
+ if (m_float_valid && !m_int_valid)
+ {
+ m_int = s64(m_float);
+ m_int_valid = true;
+ }
+ if (m_text_valid && !m_int_valid)
+ {
+ std::istringstream stream(m_text);
+ stream.imbue(f_portable_locale);
+ m_text.c_str();
+ if (m_text[0] == '$')
+ {
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_int = s64(uvalue);
+ }
+ else if ((m_text[0] == '0') && ((m_text[1] == 'x') || (m_text[1] == 'X')))
+ {
+ stream.get();
+ stream.get();
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ m_int = s64(uvalue);
+ }
+ else
+ {
+ if (m_text[0] == '#')
+ stream.get();
+ stream >> m_int;
+ }
+ m_int_valid = bool(stream);
+ }
+ if (0 > m_shift)
+ m_int >>= -m_shift;
+ else
+ m_int <<= m_shift;
+ m_text_valid = m_float_valid = false;
+ }
+ }
+ }
-//-------------------------------------------------
-// xml_get_attribute_string_with_subst - analog
-// to xml_get_attribute_string but with variable
-// substitution
-//-------------------------------------------------
+ static bool name_less(entry const &lhs, entry const &rhs) { return lhs.name() < rhs.name(); }
+
+ private:
+ std::string m_name;
+ std::string m_text;
+ s64 m_int = 0, m_int_increment = 0;
+ double m_float = 0.0, m_float_increment = 0.0;
+ int m_shift = 0;
+ bool m_text_valid = false;
+ bool m_int_valid = false;
+ bool m_float_valid = false;
+ bool m_incrementing = false;
+ };
+
+ using entry_vector = std::vector<entry>;
+
+ template <typename T, typename U>
+ void try_insert(T &&name, U &&value)
+ {
+ entry_vector::iterator const pos(
+ std::lower_bound(
+ m_entries.begin(),
+ m_entries.end(),
+ name,
+ [] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
+ if ((m_entries.end() == pos) || (pos->name() != name))
+ m_entries.emplace(pos, std::forward<T>(name), std::forward<U>(value));
+ }
+
+ template <typename T, typename U>
+ void set(T &&name, U &&value)
+ {
+ entry_vector::iterator const pos(
+ std::lower_bound(
+ m_entries.begin(),
+ m_entries.end(),
+ name,
+ [] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
+ if ((m_entries.end() == pos) || (pos->name() != name))
+ m_entries.emplace(pos, std::forward<T>(name), std::forward<U>(value));
+ else
+ pos->set(std::forward<U>(value));
+ }
-const char *xml_get_attribute_string_with_subst(running_machine &machine, util::xml::data_node const &node, const char *attribute, const char *defvalue)
-{
- const char *str = node.get_attribute_string(attribute, nullptr);
- static char buffer[1000];
+ void cache_device_entries()
+ {
+ if (!m_next && !m_cached)
+ {
+ try_insert("devicetag", device().tag());
+ try_insert("devicebasetag", device().basetag());
+ try_insert("devicename", device().name());
+ try_insert("deviceshortname", device().shortname());
+ util::ovectorstream tmp;
+ unsigned i(0U);
+ for (screen_device const &screen : screen_device_iterator(machine().root_device()))
+ {
+ s64 const w(screen.visible_area().width()), h(screen.visible_area().height());
+ s64 xaspect(w), yaspect(h);
+ reduce_fraction(xaspect, yaspect);
+
+ tmp.seekp(0);
+ util::stream_format(tmp, "scr%unativexaspect", i);
+ tmp.put('\0');
+ try_insert(&tmp.vec()[0], xaspect);
+
+ tmp.seekp(0);
+ util::stream_format(tmp, "scr%unativeyaspect", i);
+ tmp.put('\0');
+ try_insert(&tmp.vec()[0], yaspect);
+
+ tmp.seekp(0);
+ util::stream_format(tmp, "scr%uwidth", i);
+ tmp.put('\0');
+ try_insert(&tmp.vec()[0], w);
+
+ tmp.seekp(0);
+ util::stream_format(tmp, "scr%uheight", i);
+ tmp.put('\0');
+ try_insert(&tmp.vec()[0], h);
+
+ ++i;
+ }
+ m_cached = true;
+ }
+ }
- // if nothing, just return the default
- if (str == nullptr)
- return defvalue;
+ entry *find_entry(char const *begin, char const *end)
+ {
+ cache_device_entries();
+ entry_vector::iterator const pos(
+ std::lower_bound(
+ m_entries.begin(),
+ m_entries.end(),
+ std::make_pair(begin, end - begin),
+ [] (entry const &lhs, std::pair<char const *, std::ptrdiff_t> const &rhs)
+ { return 0 > std::strncmp(lhs.name().c_str(), rhs.first, rhs.second); }));
+ if ((m_entries.end() != pos) && (pos->name().length() == (end - begin)) && !std::strncmp(pos->name().c_str(), begin, end - begin))
+ return &*pos;
+ else
+ return m_next ? m_next->find_entry(begin, end) : nullptr;
+ }
- // if no tildes, don't worry
- if (strchr(str, '~') == nullptr)
- return str;
+ template <typename... T>
+ std::tuple<char const *, char const *, bool> get_variable_text(T &&... args)
+ {
+ entry *const found(find_entry(std::forward<T>(args)...));
+ if (found)
+ {
+ std::string const &text(found->get_text());
+ char const *const begin(text.c_str());
+ return std::make_tuple(begin, begin + text.length(), true);
+ }
+ else
+ {
+ return std::make_tuple(nullptr, nullptr, false);
+ }
+ }
- // make a copy of the string, doing substitutions along the way
- const char *s;
- char *d;
- for (s = str, d = buffer; *s != 0; )
+ std::pair<char const *, char const *> expand(char const *begin, char const *end)
{
- // if not a variable, just copy
- if (*s != '~')
- *d++ = *s++;
+ // search for candidate variable references
+ char const *start(begin);
+ char const *pos(std::find_if(start, end, is_variable_start));
+ while (pos != end)
+ {
+ char const *const term(std::find_if(pos + 1, end, [] (char ch) { return !is_variable_char(ch); }));
+ if ((term == end) || !is_variable_end(*term))
+ {
+ // not a valid variable name - keep searching
+ pos = std::find_if(term, end, is_variable_start);
+ }
+ else
+ {
+ // looks like a variable reference - try to look it up
+ std::tuple<char const *, char const *, bool> const text(get_variable_text(pos + 1, term));
+ if (std::get<2>(text))
+ {
+ // variable found
+ if (begin == start)
+ m_buffer.seekp(0);
+ m_buffer.write(start, pos - start);
+ m_buffer.write(std::get<0>(text), std::get<1>(text) - std::get<0>(text));
+ start = term + 1;
+ pos = std::find_if(start, end, is_variable_start);
+ }
+ else
+ {
+ // variable not found - move on
+ pos = std::find_if(pos + 1, end, is_variable_start);
+ }
+ }
+ }
- // extract the variable
+ // short-circuit the case where no substitutions were made
+ if (start == begin)
+ {
+ return std::make_pair(begin, end);
+ }
else
- s += get_variable_value(machine, s, &d);
+ {
+ m_buffer.write(start, pos - start);
+ m_buffer.put('\0');
+ std::vector<char> const &vec(m_buffer.vec());
+ if (vec.empty())
+ return std::make_pair(nullptr, nullptr);
+ else
+ return std::make_pair(&vec[0], &vec[0] + vec.size() - 1);
+ }
}
- *d = 0;
- return buffer;
-}
-
-//-------------------------------------------------
-// xml_get_attribute_int_with_subst - analog
-// to xml_get_attribute_int but with variable
-// substitution
-//-------------------------------------------------
+ std::pair<char const *, char const *> expand(char const *str)
+ {
+ return expand(str, str + strlen(str));
+ }
-int xml_get_attribute_int_with_subst(running_machine &machine, util::xml::data_node const &node, const char *attribute, int defvalue)
-{
- const char *string = xml_get_attribute_string_with_subst(machine, node, attribute, nullptr);
- int value;
- unsigned int uvalue;
-
- if (string == nullptr)
- return defvalue;
- if (string[0] == '$')
- return (sscanf(&string[1], "%X", &uvalue) == 1) ? uvalue : defvalue;
- if (string[0] == '0' && string[1] == 'x')
- return (sscanf(&string[2], "%X", &uvalue) == 1) ? uvalue : defvalue;
- if (string[0] == '#')
- return (sscanf(&string[1], "%d", &value) == 1) ? value : defvalue;
- return (sscanf(&string[0], "%d", &value) == 1) ? value : defvalue;
-}
+ std::string parameter_name(util::xml::data_node const &node)
+ {
+ char const *const attrib(node.get_attribute_string("name", nullptr));
+ if (!attrib)
+ throw layout_syntax_error("parameter lacks name attribute");
+ std::pair<char const *, char const *> const expanded(expand(attrib));
+ return std::string(expanded.first, expanded.second);
+ }
+ static constexpr bool is_variable_start(char ch)
+ {
+ return '~' == ch;
+ }
+ static constexpr bool is_variable_end(char ch)
+ {
+ return '~' == ch;
+ }
+ static constexpr bool is_variable_char(char ch)
+ {
+ return (('0' <= ch) && ('9' >= ch)) || (('A' <= ch) && ('Z' >= ch)) || (('a' <= ch) && ('z' >= ch)) || ('_' == ch);
+ }
-//-------------------------------------------------
-// xml_get_attribute_float_with_subst - analog
-// to xml_get_attribute_float but with variable
-// substitution
-//-------------------------------------------------
+ entry_vector m_entries;
+ util::ovectorstream m_buffer;
+ device_t &m_device;
+ layout_environment *const m_next = nullptr;
+ bool m_cached = false;
-float xml_get_attribute_float_with_subst(running_machine &machine, util::xml::data_node const &node, const char *attribute, float defvalue)
-{
- const char *string = xml_get_attribute_string_with_subst(machine, node, attribute, nullptr);
- float value;
+public:
+ explicit layout_environment(device_t &device) : m_device(device) { }
+ explicit layout_environment(layout_environment &next) : m_device(next.m_device), m_next(&next) { }
+ layout_environment(layout_environment const &) = delete;
- if (string == nullptr || sscanf(string, "%f", &value) != 1)
- return defvalue;
- return value;
-}
+ device_t &device() { return m_device; }
+ running_machine &machine() { return device().machine(); }
+ bool is_root_device() { return &device() == &machine().root_device(); }
+ void set_parameter(std::string &&name, std::string &&value)
+ {
+ set(std::move(name), std::move(value));
+ }
-//-------------------------------------------------
-// parse_bounds - parse a bounds XML node
-//-------------------------------------------------
+ void set_parameter(std::string &&name, s64 value)
+ {
+ set(std::move(name), value);
+ }
-void parse_bounds(running_machine &machine, util::xml::data_node const *boundsnode, render_bounds &bounds)
-{
- // skip if nothing
- if (boundsnode == nullptr)
+ void set_parameter(std::string &&name, double value)
{
- bounds.x0 = bounds.y0 = 0.0f;
- bounds.x1 = bounds.y1 = 1.0f;
- return;
+ set(std::move(name), value);
}
- // parse out the data
- if (boundsnode->has_attribute("left"))
+ void set_parameter(util::xml::data_node const &node)
{
- // left/right/top/bottom format
- bounds.x0 = xml_get_attribute_float_with_subst(machine, *boundsnode, "left", 0.0f);
- bounds.x1 = xml_get_attribute_float_with_subst(machine, *boundsnode, "right", 1.0f);
- bounds.y0 = xml_get_attribute_float_with_subst(machine, *boundsnode, "top", 0.0f);
- bounds.y1 = xml_get_attribute_float_with_subst(machine, *boundsnode, "bottom", 1.0f);
+ // do basic validation
+ std::string name(parameter_name(node));
+ if (node.has_attribute("start") || node.has_attribute("increment") || node.has_attribute("lshift") || node.has_attribute("rshift"))
+ throw layout_syntax_error("start/increment/lshift/rshift attributes are only allowed for repeat parameters");
+ char const *const value(node.get_attribute_string("value", nullptr));
+ if (!value)
+ throw layout_syntax_error("parameter lacks value attribute");
+
+ // expand value and stash
+ std::pair<char const *, char const *> const expanded(expand(value));
+ set(std::move(name), std::string(expanded.first, expanded.second));
}
- else if (boundsnode->has_attribute("x"))
+
+ void set_repeat_parameter(util::xml::data_node const &node, bool init)
{
- // x/y/width/height format
- bounds.x0 = xml_get_attribute_float_with_subst(machine, *boundsnode, "x", 0.0f);
- bounds.x1 = bounds.x0 + xml_get_attribute_float_with_subst(machine, *boundsnode, "width", 1.0f);
- bounds.y0 = xml_get_attribute_float_with_subst(machine, *boundsnode, "y", 0.0f);
- bounds.y1 = bounds.y0 + xml_get_attribute_float_with_subst(machine, *boundsnode, "height", 1.0f);
+ // two types are allowed here - static value, and start/increment/lshift/rshift
+ std::string name(parameter_name(node));
+ char const *const start(node.get_attribute_string("start", nullptr));
+ if (start)
+ {
+ // simple validity checks
+ if (node.has_attribute("value"))
+ throw layout_syntax_error("start attribute may not be used in combination with value attribute");
+ int const lshift(node.has_attribute("lshift") ? get_attribute_int(node, "lshift", -1) : 0);
+ int const rshift(node.has_attribute("rshift") ? get_attribute_int(node, "rshift", -1) : 0);
+ if ((0 > lshift) || (0 > rshift))
+ throw layout_syntax_error("lshift/rshift attributes must be non-negative integers");
+
+ // increment is more complex - it may be an integer or a floating-point number
+ s64 intincrement(0);
+ double floatincrement(0);
+ char const *const increment(node.get_attribute_string("increment", nullptr));
+ if (increment)
+ {
+ std::pair<char const *, char const *> const expanded(expand(increment));
+ unsigned const hexprefix((expanded.first[0] == '$') ? 1U : ((expanded.first[0] == '0') && ((expanded.first[1] == 'x') || (expanded.first[1] == 'X'))) ? 2U : 0U);
+ unsigned const decprefix((expanded.first[0] == '#') ? 1U : 0U);
+ bool const floatchars(std::find_if(expanded.first, expanded.second, [] (char ch) { return ('.' == ch) || ('e' == ch) || ('E' == ch); }) != expanded.second);
+ std::istringstream stream(std::string(expanded.first + hexprefix + decprefix, expanded.second));
+ stream.imbue(f_portable_locale);
+ if (!hexprefix && !decprefix && floatchars)
+ {
+ stream >> floatincrement;
+ }
+ else if (hexprefix)
+ {
+ u64 uvalue;
+ stream >> std::hex >> uvalue;
+ intincrement = s64(uvalue);
+ }
+ else
+ {
+ stream >> intincrement;
+ }
+
+ // reject obviously bad stuff
+ if (!stream)
+ throw layout_syntax_error("increment attribute must be a number");
+ }
+
+ // don't allow incrementing parameters to be redefined
+ if (init)
+ {
+ entry_vector::iterator const pos(
+ std::lower_bound(
+ m_entries.begin(),
+ m_entries.end(),
+ name,
+ [] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
+ if ((m_entries.end() != pos) && (pos->name() == name))
+ throw layout_syntax_error("incrementing parameters must be defined exactly once per scope");
+
+ std::pair<char const *, char const *> const expanded(expand(start));
+ if (floatincrement)
+ m_entries.emplace(pos, std::move(name), std::string(expanded.first, expanded.second), floatincrement, lshift - rshift);
+ else
+ m_entries.emplace(pos, std::move(name), std::string(expanded.first, expanded.second), intincrement, lshift - rshift);
+ }
+ }
+ else if (node.has_attribute("increment") || node.has_attribute("lshift") || node.has_attribute("rshift"))
+ {
+ throw layout_syntax_error("increment/lshift/rshift attributes require start attribute");
+ }
+ else
+ {
+ char const *const value(node.get_attribute_string("value", nullptr));
+ if (!value)
+ throw layout_syntax_error("parameter lacks value attribute");
+ std::pair<char const *, char const *> const expanded(expand(value));
+ entry_vector::iterator const pos(
+ std::lower_bound(
+ m_entries.begin(),
+ m_entries.end(),
+ name,
+ [] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
+ if ((m_entries.end() == pos) || (pos->name() != name))
+ m_entries.emplace(pos, std::move(name), std::string(expanded.first, expanded.second));
+ else if (pos->is_incrementing())
+ throw layout_syntax_error("incrementing parameters must be defined exactly once per scope");
+ else
+ pos->set(std::string(expanded.first, expanded.second));
+ }
}
- else
+
+ void increment_parameters()
{
- throw layout_syntax_error("bounds element requires either left or x attribute");
+ for (entry &e : m_entries)
+ e.increment();
}
- // check for errors
- if ((bounds.x0 > bounds.x1) || (bounds.y0 > bounds.y1))
- throw layout_syntax_error(util::string_format("illegal bounds (%f-%f)-(%f-%f)", bounds.x0, bounds.x1, bounds.y0, bounds.y1));
-}
+ char const *get_attribute_string(util::xml::data_node const &node, char const *name, char const *defvalue)
+ {
+ char const *const attrib(node.get_attribute_string(name, nullptr));
+ return attrib ? expand(attrib).first : defvalue;
+ }
+ int get_attribute_int(util::xml::data_node const &node, const char *name, int defvalue)
+ {
+ char const *const attrib(node.get_attribute_string(name, nullptr));
+ if (!attrib)
+ return defvalue;
-//-------------------------------------------------
-// parse_color - parse a color XML node
-//-------------------------------------------------
+ // similar to what XML nodes do
+ std::pair<char const *, char const *> const expanded(expand(attrib));
+ std::istringstream stream;
+ stream.imbue(f_portable_locale);
+ int result;
+ if (expanded.first[0] == '$')
+ {
+ stream.str(std::string(expanded.first + 1, expanded.second));
+ unsigned uvalue;
+ stream >> std::hex >> uvalue;
+ result = int(uvalue);
+ }
+ else if ((expanded.first[0] == '0') && ((expanded.first[1] == 'x') || (expanded.first[1] == 'X')))
+ {
+ stream.str(std::string(expanded.first + 2, expanded.second));
+ unsigned uvalue;
+ stream >> std::hex >> uvalue;
+ result = int(uvalue);
+ }
+ else if (expanded.first[0] == '#')
+ {
+ stream.str(std::string(expanded.first + 1, expanded.second));
+ stream >> result;
+ }
+ else
+ {
+ stream.str(std::string(expanded.first, expanded.second));
+ stream >> result;
+ }
-void parse_color(running_machine &machine, util::xml::data_node const *colornode, render_color &color)
-{
- // skip if nothing
- if (colornode == nullptr)
- {
- color.r = color.g = color.b = color.a = 1.0f;
- return;
+ return stream ? result : defvalue;
}
- // parse out the data
- color.r = xml_get_attribute_float_with_subst(machine, *colornode, "red", 1.0);
- color.g = xml_get_attribute_float_with_subst(machine, *colornode, "green", 1.0);
- color.b = xml_get_attribute_float_with_subst(machine, *colornode, "blue", 1.0);
- color.a = xml_get_attribute_float_with_subst(machine, *colornode, "alpha", 1.0);
+ float get_attribute_float(util::xml::data_node const &node, char const *name, float defvalue)
+ {
+ char const *const attrib(node.get_attribute_string(name, nullptr));
+ if (!attrib)
+ return defvalue;
- // check for errors
- if ((color.r < 0.0f) || (color.r > 1.0f) || (color.g < 0.0f) || (color.g > 1.0f) ||
- (color.b < 0.0f) || (color.b > 1.0f) || (color.a < 0.0f) || (color.a > 1.0f))
- throw layout_syntax_error(util::string_format("illegal RGBA color %f,%f,%f,%f", color.r, color.g, color.b, color.a));
-}
+ // similar to what XML nodes do
+ std::pair<char const *, char const *> const expanded(expand(attrib));
+ std::istringstream stream(std::string(expanded.first, expanded.second));
+ stream.imbue(f_portable_locale);
+ float result;
+ return (stream >> result) ? result : defvalue;
+ }
+ void parse_bounds(util::xml::data_node const *node, render_bounds &result)
+ {
+ // default to unit rectangle
+ if (!node)
+ {
+ result.x0 = result.y0 = 0.0F;
+ result.x1 = result.y1 = 1.0F;
+ }
+ else
+ {
+ // parse attributes
+ if (node->has_attribute("left"))
+ {
+ // left/right/top/bottom format
+ result.x0 = get_attribute_float(*node, "left", 0.0F);
+ result.x1 = get_attribute_float(*node, "right", 1.0F);
+ result.y0 = get_attribute_float(*node, "top", 0.0F);
+ result.y1 = get_attribute_float(*node, "bottom", 1.0F);
+ }
+ else if (node->has_attribute("x"))
+ {
+ // x/y/width/height format
+ result.x0 = get_attribute_float(*node, "x", 0.0F);
+ result.x1 = result.x0 + get_attribute_float(*node, "width", 1.0F);
+ result.y0 = get_attribute_float(*node, "y", 0.0F);
+ result.y1 = result.y0 + get_attribute_float(*node, "height", 1.0F);
+ }
+ else
+ {
+ throw layout_syntax_error("bounds element requires either left or x attribute");
+ }
-//-------------------------------------------------
-// parse_orientation - parse an orientation XML
-// node
-//-------------------------------------------------
+ // check for errors
+ if ((result.x0 > result.x1) || (result.y0 > result.y1))
+ throw layout_syntax_error(util::string_format("illegal bounds (%f-%f)-(%f-%f)", result.x0, result.x1, result.y0, result.y1));
+ }
+ }
-void parse_orientation(running_machine &machine, util::xml::data_node const *orientnode, int &orientation)
-{
- // skip if nothing
- if (orientnode == nullptr)
+ void parse_color(util::xml::data_node const *node, render_color &result)
{
- orientation = ROT0;
- return;
+ // default to white
+ if (!node)
+ {
+ result.r = result.g = result.b = result.a = 1.0F;
+ }
+ else
+ {
+ // parse attributes
+ result.r = get_attribute_float(*node, "red", 1.0F);
+ result.g = get_attribute_float(*node, "green", 1.0F);
+ result.b = get_attribute_float(*node, "blue", 1.0F);
+ result.a = get_attribute_float(*node, "alpha", 1.0F);
+
+ // check for errors
+ if ((0.0F > (std::min)({ result.r, result.g, result.b, result.a })) || (1.0F < (std::max)({ result.r, result.g, result.b, result.a })))
+ throw layout_syntax_error(util::string_format("illegal RGBA color %f,%f,%f,%f", result.r, result.g, result.b, result.a));
+ }
}
- // parse out the data
- int rotate = xml_get_attribute_int_with_subst(machine, *orientnode, "rotate", 0);
- switch (rotate)
+ void parse_orientation(util::xml::data_node const *node, int &result)
{
- case 0: orientation = ROT0; break;
- case 90: orientation = ROT90; break;
- case 180: orientation = ROT180; break;
- case 270: orientation = ROT270; break;
- default: throw layout_syntax_error(util::string_format("invalid rotate attribute %d", rotate));
+ // default to no transform
+ if (!node)
+ {
+ result = ROT0;
+ }
+ else
+ {
+ // parse attributes
+ int const rotate(get_attribute_int(*node, "rotate", 0));
+ switch (rotate)
+ {
+ case 0: result = ROT0; break;
+ case 90: result = ROT90; break;
+ case 180: result = ROT180; break;
+ case 270: result = ROT270; break;
+ default: throw layout_syntax_error(util::string_format("invalid rotate attribute %d", rotate));
+ }
+ if (!std::strcmp("yes", get_attribute_string(*node, "swapxy", "no")))
+ result ^= ORIENTATION_SWAP_XY;
+ if (!std::strcmp("yes", get_attribute_string(*node, "flipx", "no")))
+ result ^= ORIENTATION_FLIP_X;
+ if (!std::strcmp("yes", get_attribute_string(*node, "flipy", "no")))
+ result ^= ORIENTATION_FLIP_Y;
+ }
}
- if (strcmp("yes", xml_get_attribute_string_with_subst(machine, *orientnode, "swapxy", "no")) == 0)
- orientation ^= ORIENTATION_SWAP_XY;
- if (strcmp("yes", xml_get_attribute_string_with_subst(machine, *orientnode, "flipx", "no")) == 0)
- orientation ^= ORIENTATION_FLIP_X;
- if (strcmp("yes", xml_get_attribute_string_with_subst(machine, *orientnode, "flipy", "no")) == 0)
- orientation ^= ORIENTATION_FLIP_Y;
-}
+};
-} // anonymous namespace
+} } } // namespace emu::render::detail
@@ -413,13 +898,13 @@ layout_element::make_component_map const layout_element::s_make_component{
// layout_element - constructor
//-------------------------------------------------
-layout_element::layout_element(running_machine &machine, util::xml::data_node const &elemnode, const char *dirname)
- : m_machine(machine)
+layout_element::layout_element(environment &env, util::xml::data_node const &elemnode, const char *dirname)
+ : m_machine(env.machine())
, m_defstate(0)
, m_maxstate(0)
{
// get the default state
- m_defstate = xml_get_attribute_int_with_subst(machine, elemnode, "defstate", -1);
+ m_defstate = env.get_attribute_int(elemnode, "defstate", -1);
// parse components in order
bool first = true;
@@ -431,7 +916,7 @@ layout_element::layout_element(running_machine &machine, util::xml::data_node co
throw layout_syntax_error(util::string_format("unknown element component %s", compnode->get_name()));
// insert the new component into the list
- component const &newcomp(**m_complist.emplace(m_complist.end(), make_func->second(machine, *compnode, dirname)));
+ component const &newcomp(**m_complist.emplace(m_complist.end(), make_func->second(env, *compnode, dirname)));
// accumulate bounds
if (first)
@@ -480,9 +965,8 @@ layout_element::~layout_element()
// layout_group - constructor
//-------------------------------------------------
-layout_group::layout_group(running_machine &machine, util::xml::data_node const &groupnode)
- : m_machine(machine)
- , m_groupnode(groupnode)
+layout_group::layout_group(util::xml::data_node const &groupnode)
+ : m_groupnode(groupnode)
, m_bounds{ 0.0f, 0.0f, 0.0f, 0.0f }
, m_bounds_resolved(false)
{
@@ -530,16 +1014,21 @@ render_bounds layout_group::make_transform(render_bounds const &dest, render_bou
// nested groups into consideration
//-------------------------------------------------
-void layout_group::resolve_bounds(group_map &groupmap)
+void layout_group::set_bounds_unresolved()
+{
+ m_bounds_resolved = false;
+}
+
+void layout_group::resolve_bounds(environment &env, group_map &groupmap)
{
if (!m_bounds_resolved)
{
std::vector<layout_group const *> seen;
- resolve_bounds(groupmap, seen);
+ resolve_bounds(env, groupmap, seen);
}
}
-void layout_group::resolve_bounds(group_map &groupmap, std::vector<layout_group const *> &seen)
+void layout_group::resolve_bounds(environment &env, group_map &groupmap, std::vector<layout_group const *> &seen)
{
if (seen.end() != std::find(seen.begin(), seen.end(), this))
{
@@ -554,59 +1043,87 @@ void layout_group::resolve_bounds(group_map &groupmap, std::vector<layout_group
seen.push_back(this);
if (!m_bounds_resolved)
{
- util::xml::data_node const *const boundsnode(m_groupnode.get_child("bounds"));
- if (boundsnode)
+ environment local(env);
+ resolve_bounds(local, m_groupnode, groupmap, seen, false, true);
+ }
+}
+
+void layout_group::resolve_bounds(
+ environment &env,
+ util::xml::data_node const &parentnode,
+ group_map &groupmap,
+ std::vector<layout_group const *> &seen,
+ bool repeat,
+ bool init)
+{
+ bool envaltered(false);
+ bool unresolved(true);
+ for (util::xml::data_node const *itemnode = parentnode.get_first_child(); !m_bounds_resolved && itemnode; itemnode = itemnode->get_next_sibling())
+ {
+ if (!strcmp(itemnode->get_name(), "bounds"))
{
// use explicit bounds
- parse_bounds(m_machine, boundsnode, m_bounds);
+ env.parse_bounds(itemnode, m_bounds);
+ m_bounds_resolved = true;
}
- else
+ else if (!strcmp(itemnode->get_name(), "param"))
{
- // otherwise build from items
- for (util::xml::data_node const *itemnode = m_groupnode.get_first_child(); itemnode; itemnode = itemnode->get_next_sibling())
+ envaltered = true;
+ if (!unresolved)
{
- if (!strcmp(itemnode->get_name(), "backdrop") ||
- !strcmp(itemnode->get_name(), "screen") ||
- !strcmp(itemnode->get_name(), "overlay") ||
- !strcmp(itemnode->get_name(), "bezel") ||
- !strcmp(itemnode->get_name(), "cpanel") ||
- !strcmp(itemnode->get_name(), "marquee"))
- {
- render_bounds itembounds;
- parse_bounds(m_machine, itemnode->get_child("bounds"), itembounds);
- union_render_bounds(m_bounds, itembounds);
- }
- else if (!strcmp(itemnode->get_name(), "group"))
- {
- char const *ref(xml_get_attribute_string_with_subst(m_machine, *itemnode, "ref", nullptr));
- if (!ref)
- throw layout_syntax_error("nested group must have ref attribute");
+ unresolved = true;
+ for (group_map::value_type &group : groupmap)
+ group.second.set_bounds_unresolved();
+ }
+ if (!repeat)
+ env.set_parameter(*itemnode);
+ else
+ env.set_repeat_parameter(*itemnode, init);
+ }
+ else if (!strcmp(itemnode->get_name(), "backdrop") ||
+ !strcmp(itemnode->get_name(), "screen") ||
+ !strcmp(itemnode->get_name(), "overlay") ||
+ !strcmp(itemnode->get_name(), "bezel") ||
+ !strcmp(itemnode->get_name(), "cpanel") ||
+ !strcmp(itemnode->get_name(), "marquee"))
+ {
+ render_bounds itembounds;
+ env.parse_bounds(itemnode->get_child("bounds"), itembounds);
+ union_render_bounds(m_bounds, itembounds);
+ }
+ else if (!strcmp(itemnode->get_name(), "group"))
+ {
+ char const *ref(env.get_attribute_string(*itemnode, "ref", nullptr));
+ if (!ref)
+ throw layout_syntax_error("nested group must have ref attribute");
- group_map::iterator const found(groupmap.find(ref));
- if (groupmap.end() == found)
- throw layout_syntax_error(util::string_format("unable to find group %s", ref));
+ group_map::iterator const found(groupmap.find(ref));
+ if (groupmap.end() == found)
+ throw layout_syntax_error(util::string_format("unable to find group %s", ref));
- found->second.resolve_bounds(groupmap, seen);
- util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds"));
- if (itemboundsnode)
- {
- render_bounds itembounds;
- parse_bounds(m_machine, itemboundsnode, itembounds);
- union_render_bounds(m_bounds, itembounds);
- }
- else
- {
- union_render_bounds(m_bounds, found->second.m_bounds);
- }
- }
- else if (strcmp(itemnode->get_name(), "bounds"))
- {
- throw layout_syntax_error(util::string_format("unknown group element %s", itemnode->get_name()));
- }
+ environment local(env);
+ found->second.resolve_bounds(local, groupmap, seen);
+ union_render_bounds(m_bounds, found->second.m_bounds);
+ }
+ else if (!strcmp(itemnode->get_name(), "repeat"))
+ {
+ int const count(env.get_attribute_int(*itemnode, "count", -1));
+ if (0 >= count)
+ throw layout_syntax_error("repeat must have positive integer count attribute");
+ environment local(env);
+ for (int i = 0; !m_bounds_resolved && (count > i); ++i)
+ {
+ resolve_bounds(local, *itemnode, groupmap, seen, true, !i);
+ local.increment_parameters();
}
}
- m_bounds_resolved = true;
+ else
+ {
+ throw layout_syntax_error(util::string_format("unknown group element %s", itemnode->get_name()));
+ }
}
+ if (!repeat)
+ m_bounds_resolved = true;
}
@@ -663,15 +1180,15 @@ class layout_element::image_component : public component
{
public:
// construction/destruction
- image_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ image_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
, m_hasalpha(false)
{
if (dirname != nullptr)
m_dirname = dirname;
- m_imagefile = xml_get_attribute_string_with_subst(machine, compnode, "file", "");
- m_alphafile = xml_get_attribute_string_with_subst(machine, compnode, "alphafile", "");
- m_file = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
+ m_imagefile = env.get_attribute_string(compnode, "file", "");
+ m_alphafile = env.get_attribute_string(compnode, "alphafile", "");
+ m_file = std::make_unique<emu_file>(env.machine().options().art_path(), OPEN_FLAG_READ);
}
protected:
@@ -745,8 +1262,8 @@ class layout_element::rect_component : public component
{
public:
// construction/destruction
- rect_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ rect_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -791,8 +1308,8 @@ class layout_element::disk_component : public component
{
public:
// construction/destruction
- disk_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ disk_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -852,11 +1369,11 @@ class layout_element::text_component : public component
{
public:
// construction/destruction
- text_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ text_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
- m_string = xml_get_attribute_string_with_subst(machine, compnode, "string", "");
- m_textalign = xml_get_attribute_int_with_subst(machine, compnode, "align", 0);
+ m_string = env.get_attribute_string(compnode, "string", "");
+ m_textalign = env.get_attribute_int(compnode, "align", 0);
}
protected:
@@ -880,8 +1397,8 @@ class layout_element::led7seg_component : public component
{
public:
// construction/destruction
- led7seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led7seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -942,8 +1459,8 @@ class layout_element::led8seg_gts1_component : public component
{
public:
// construction/destruction
- led8seg_gts1_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led8seg_gts1_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -1010,8 +1527,8 @@ class layout_element::led14seg_component : public component
{
public:
// construction/destruction
- led14seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led14seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -1122,8 +1639,8 @@ class layout_element::led16seg_component : public component
{
public:
// construction/destruction
- led16seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led16seg_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -1244,8 +1761,8 @@ class layout_element::led14segsc_component : public component
{
public:
// construction/destruction
- led14segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led14segsc_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -1365,8 +1882,8 @@ class layout_element::led16segsc_component : public component
{
public:
// construction/destruction
- led16segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ led16segsc_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
}
@@ -1496,8 +2013,8 @@ class layout_element::dotmatrix_component : public component
{
public:
// construction/destruction
- dotmatrix_component(int dots, running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ dotmatrix_component(int dots, environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
, m_dots(dots)
{
}
@@ -1537,11 +2054,11 @@ class layout_element::simplecounter_component : public component
{
public:
// construction/destruction
- simplecounter_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
- , m_digits(xml_get_attribute_int_with_subst(machine, compnode, "digits", 2))
- , m_textalign(xml_get_attribute_int_with_subst(machine, compnode, "align", 0))
- , m_maxstate(xml_get_attribute_int_with_subst(machine, compnode, "maxstate", 999))
+ simplecounter_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
+ , m_digits(env.get_attribute_int(compnode, "digits", 2))
+ , m_textalign(env.get_attribute_int(compnode, "align", 0))
+ , m_maxstate(env.get_attribute_int(compnode, "maxstate", 999))
{
}
@@ -1572,13 +2089,13 @@ class layout_element::reel_component : public component
public:
// construction/destruction
- reel_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+ reel_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
+ : component(env, compnode, dirname)
{
for (auto & elem : m_hasalpha)
elem = false;
- std::string symbollist = xml_get_attribute_string_with_subst(machine, compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
+ std::string symbollist = env.get_attribute_string(compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
// split out position names from string and figure out our number of symbols
int location;
@@ -1608,7 +2125,7 @@ public:
m_imagefile[i] = m_imagefile[i].substr(location+1, m_imagefile[i].length()-(location-1));
//m_alphafile[i] =
- m_file[i] = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
+ m_file[i] = std::make_unique<emu_file>(env.machine().options().art_path(), OPEN_FLAG_READ);
}
else
{
@@ -1618,10 +2135,10 @@ public:
}
}
- m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0);
- m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3);
- m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0);
- m_beltreel = xml_get_attribute_int_with_subst(machine, compnode, "beltreel", 0);
+ m_stateoffset = env.get_attribute_int(compnode, "stateoffset", 0);
+ m_numsymbolsvisible = env.get_attribute_int(compnode, "numsymbolsvisible", 3);
+ m_reelreversed = env.get_attribute_int(compnode, "reelreversed", 0);
+ m_beltreel = env.get_attribute_int(compnode, "beltreel", 0);
}
protected:
@@ -1631,7 +2148,7 @@ protected:
{
if (m_beltreel)
{
- draw_beltreel(machine,dest,bounds,state);
+ draw_beltreel(machine, dest, bounds, state);
return;
}
@@ -1996,9 +2513,9 @@ private:
//-------------------------------------------------
template <typename T>
-layout_element::component::ptr layout_element::make_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+layout_element::component::ptr layout_element::make_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
{
- return std::make_unique<T>(machine, compnode, dirname);
+ return std::make_unique<T>(env, compnode, dirname);
}
@@ -2008,9 +2525,9 @@ layout_element::component::ptr layout_element::make_component(running_machine &m
//-------------------------------------------------
template <int D>
-layout_element::component::ptr layout_element::make_dotmatrix_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+layout_element::component::ptr layout_element::make_dotmatrix_component(environment &env, util::xml::data_node const &compnode, const char *dirname)
{
- return std::make_unique<dotmatrix_component>(D, machine, compnode, dirname);
+ return std::make_unique<dotmatrix_component>(D, env, compnode, dirname);
}
@@ -2071,13 +2588,13 @@ layout_element::texture &layout_element::texture::operator=(texture &&that)
// component - constructor
//-------------------------------------------------
-layout_element::component::component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+layout_element::component::component(environment &env, util::xml::data_node const &compnode, const char *dirname)
: m_state(0)
{
// fetch common data
- m_state = xml_get_attribute_int_with_subst(machine, compnode, "state", -1);
- parse_bounds(machine, compnode.get_child("bounds"), m_bounds);
- parse_color(machine, compnode.get_child("color"), m_color);
+ m_state = env.get_attribute_int(compnode, "state", -1);
+ env.parse_bounds(compnode.get_child("bounds"), m_bounds);
+ env.parse_color(compnode.get_child("color"), m_color);
}
@@ -2389,25 +2906,21 @@ void layout_element::component::apply_skew(bitmap_argb32 &dest, int skewwidth)
//-------------------------------------------------
layout_view::layout_view(
- device_t &device,
+ environment &env,
util::xml::data_node const &viewnode,
element_map &elemmap,
- group_map const &groupmap)
- : m_name(make_name(device, viewnode))
+ group_map &groupmap)
+ : m_name(make_name(env, viewnode))
, m_aspect(1.0f)
, m_scraspect(1.0f)
{
- // if we have a bounds item, load it
- util::xml::data_node const *const boundsnode = viewnode.get_child("bounds");
m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0;
- if (boundsnode)
- parse_bounds(device.machine(), boundsnode, m_expbounds);
-
- // load items
- add_items(device, viewnode, elemmap, groupmap, render_bounds{ 0.0f, 0.0f, 1.0f, 1.0f });
-
- // recompute the data for the view based on a default layer config
+ environment local(env);
+ local.set_parameter("viewname", std::string(m_name));
+ add_items(local, viewnode, elemmap, groupmap, render_bounds{ 0.0f, 0.0f, 1.0f, 1.0f }, true, false, true);
recompute(render_layer_config());
+ for (group_map::value_type &group : groupmap)
+ group.second.set_bounds_unresolved();
}
@@ -2561,76 +3074,125 @@ void layout_view::resolve_tags()
//-------------------------------------------------
void layout_view::add_items(
- device_t &device,
+ environment &env,
util::xml::data_node const &parentnode,
element_map &elemmap,
- group_map const &groupmap,
- render_bounds const &transform)
-{
+ group_map &groupmap,
+ render_bounds const &transform,
+ bool root,
+ bool repeat,
+ bool init)
+{
+ bool envaltered(false);
+ bool unresolved(true);
for (util::xml::data_node const *itemnode = parentnode.get_first_child(); itemnode; itemnode = itemnode->get_next_sibling())
{
- if (!strcmp(itemnode->get_name(), "backdrop"))
+ if (!strcmp(itemnode->get_name(), "bounds"))
+ {
+ // set explicit bounds
+ if (root)
+ env.parse_bounds(itemnode, m_expbounds);
+ }
+ else if (!strcmp(itemnode->get_name(), "param"))
{
- m_backdrop_list.emplace_back(device, *itemnode, elemmap, transform);
+ envaltered = true;
+ if (!unresolved)
+ {
+ unresolved = true;
+ for (group_map::value_type &group : groupmap)
+ group.second.set_bounds_unresolved();
+ }
+ if (!repeat)
+ env.set_parameter(*itemnode);
+ else
+ env.set_repeat_parameter(*itemnode, init);
+ }
+ else if (!strcmp(itemnode->get_name(), "backdrop"))
+ {
+ m_backdrop_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "screen"))
{
- m_screen_list.emplace_back(device, *itemnode, elemmap, transform);
+ m_screen_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "overlay"))
{
- m_overlay_list.emplace_back(device, *itemnode, elemmap, transform);
+ m_overlay_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "bezel"))
{
- m_bezel_list.emplace_back(device, *itemnode, elemmap, transform);
+ m_bezel_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "cpanel"))
{
- m_cpanel_list.emplace_back(device, *itemnode, elemmap, transform);
+ m_cpanel_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "marquee"))
{
- m_marquee_list.emplace_back(device, *itemnode, elemmap, transform);
+ m_marquee_list.emplace_back(env, *itemnode, elemmap, transform);
}
else if (!strcmp(itemnode->get_name(), "group"))
{
- char const *ref(xml_get_attribute_string_with_subst(device.machine(), *itemnode, "ref", nullptr));
+ char const *ref(env.get_attribute_string(*itemnode, "ref", nullptr));
if (!ref)
throw layout_syntax_error("nested group must have ref attribute");
- group_map::const_iterator const found(groupmap.find(ref));
+ group_map::iterator const found(groupmap.find(ref));
if (groupmap.end() == found)
throw layout_syntax_error(util::string_format("unable to find group %s", ref));
+ unresolved = false;
+ found->second.resolve_bounds(env, groupmap);
render_bounds grouptrans(transform);
util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds"));
if (itemboundsnode)
{
render_bounds itembounds;
- parse_bounds(device.machine(), itemboundsnode, itembounds);
+ env.parse_bounds(itemboundsnode, itembounds);
grouptrans = found->second.make_transform(itembounds, transform);
}
- add_items(device, found->second.get_groupnode(), elemmap, groupmap, grouptrans);
+ environment local(env);
+ add_items(local, found->second.get_groupnode(), elemmap, groupmap, grouptrans, false, false, true);
}
- else if (strcmp(itemnode->get_name(), "bounds"))
+ else if (!strcmp(itemnode->get_name(), "repeat"))
+ {
+ int const count(env.get_attribute_int(*itemnode, "count", -1));
+ if (0 >= count)
+ throw layout_syntax_error("repeat must have positive integer count attribute");
+ environment local(env);
+ for (int i = 0; count > i; ++i)
+ {
+ add_items(local, *itemnode, elemmap, groupmap, transform, false, true, !i);
+ local.increment_parameters();
+ }
+ }
+ else
{
throw layout_syntax_error(util::string_format("unknown view item %s", itemnode->get_name()));
}
}
+
+ if (envaltered && !unresolved)
+ {
+ for (group_map::value_type &group : groupmap)
+ group.second.set_bounds_unresolved();
+ }
}
-std::string layout_view::make_name(device_t &device, util::xml::data_node const &viewnode)
+std::string layout_view::make_name(environment &env, util::xml::data_node const &viewnode)
{
- char const *const name(xml_get_attribute_string_with_subst(device.machine(), viewnode, "name", ""));
- if (&device == &device.machine().root_device())
+ char const *const name(env.get_attribute_string(viewnode, "name", nullptr));
+ if (!name)
+ throw layout_syntax_error("view must have name attribute");
+
+ if (env.is_root_device())
{
return name;
}
else
{
- char const *tag(device.tag());
+ char const *tag(env.device().tag());
if (':' == *tag)
++tag;
return util::string_format("%s %s", tag, name);
@@ -2648,22 +3210,21 @@ std::string layout_view::make_name(device_t &device, util::xml::data_node const
//-------------------------------------------------
layout_view::item::item(
- device_t &device,
+ environment &env,
util::xml::data_node const &itemnode,
element_map &elemmap,
render_bounds const &transform)
: m_element(nullptr)
- , m_output(device, xml_get_attribute_string_with_subst(device.machine(), itemnode, "name", ""))
- , m_have_output(xml_get_attribute_string_with_subst(device.machine(), itemnode, "name", "")[0])
- , m_input_tag(xml_get_attribute_string_with_subst(device.machine(), itemnode, "inputtag", ""))
+ , m_output(env.device(), env.get_attribute_string(itemnode, "name", ""))
+ , m_have_output(env.get_attribute_string(itemnode, "name", "")[0])
+ , m_input_tag(env.get_attribute_string(itemnode, "inputtag", ""))
, m_input_port(nullptr)
, m_input_mask(0)
, m_screen(nullptr)
, m_orientation(ROT0)
{
// find the associated element
- running_machine &machine(device.machine());
- char const *const name = xml_get_attribute_string_with_subst(machine, itemnode, "element", nullptr);
+ char const *const name(env.get_attribute_string(itemnode, "element", nullptr));
if (name)
{
// search the list of elements for a match, error if not found
@@ -2679,24 +3240,24 @@ layout_view::item::item(
m_output.resolve();
// fetch common data
- int index = xml_get_attribute_int_with_subst(machine, itemnode, "index", -1);
+ int index = env.get_attribute_int(itemnode, "index", -1);
if (index != -1)
- m_screen = screen_device_iterator(machine.root_device()).byindex(index);
- m_input_mask = xml_get_attribute_int_with_subst(machine, itemnode, "inputmask", 0);
+ m_screen = screen_device_iterator(env.machine().root_device()).byindex(index);
+ m_input_mask = env.get_attribute_int(itemnode, "inputmask", 0);
if (m_have_output && m_element)
m_output = m_element->default_state();
- parse_bounds(machine, itemnode.get_child("bounds"), m_rawbounds);
+ env.parse_bounds(itemnode.get_child("bounds"), m_rawbounds);
render_bounds_transform(m_rawbounds, transform);
- parse_color(machine, itemnode.get_child("color"), m_color);
- parse_orientation(machine, itemnode.get_child("orientation"), m_orientation);
+ env.parse_color(itemnode.get_child("color"), m_color);
+ env.parse_orientation(itemnode.get_child("orientation"), m_orientation);
// sanity checks
if (strcmp(itemnode.get_name(), "screen") == 0)
{
if (itemnode.has_attribute("tag"))
{
- char const *const tag(xml_get_attribute_string_with_subst(machine, itemnode, "tag", ""));
- m_screen = dynamic_cast<screen_device *>(device.subdevice(tag));
+ char const *const tag(env.get_attribute_string(itemnode, "tag", ""));
+ m_screen = dynamic_cast<screen_device *>(env.device().subdevice(tag));
if (!m_screen)
throw layout_reference_error(util::string_format("invalid screen tag '%d'", tag));
}
@@ -2711,7 +3272,7 @@ layout_view::item::item(
}
if (has_input())
- m_input_port = device.ioport(m_input_tag.c_str());
+ m_input_port = env.device().ioport(m_input_tag.c_str());
}
@@ -2790,7 +3351,7 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode,
: m_elemmap()
, m_viewlist()
{
- running_machine &machine(device.machine());
+ emu::render::detail::layout_environment env(device);
try
{
// find the layout node
@@ -2803,13 +3364,17 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode,
if (version != LAYOUT_VERSION)
throw layout_syntax_error(util::string_format("unsupported version %d", version));
+ // parse all the parameters
+ for (util::xml::data_node const *elemnode = mamelayoutnode->get_child("param") ; elemnode; elemnode = elemnode->get_next_sibling("param"))
+ env.set_parameter(*elemnode);
+
// parse all the elements
for (util::xml::data_node const *elemnode = mamelayoutnode->get_child("element"); elemnode; elemnode = elemnode->get_next_sibling("element"))
{
- char const *const name(xml_get_attribute_string_with_subst(machine, *elemnode, "name", nullptr));
+ char const *const name(env.get_attribute_string(*elemnode, "name", nullptr));
if (!name)
throw layout_syntax_error("element lacks name attribute");
- if (!m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(machine, *elemnode, dirname)).second)
+ if (!m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(env, *elemnode, dirname)).second)
throw layout_syntax_error(util::string_format("duplicate element name %s", name));
}
@@ -2817,14 +3382,12 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode,
group_map groupmap;
for (util::xml::data_node const *groupnode = mamelayoutnode->get_child("group"); groupnode; groupnode = groupnode->get_next_sibling("group"))
{
- char const *const name(xml_get_attribute_string_with_subst(machine, *groupnode, "name", nullptr));
+ char const *const name(env.get_attribute_string(*groupnode, "name", nullptr));
if (!name)
throw layout_syntax_error("group lacks name attribute");
- if (!groupmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(machine, *groupnode)).second)
+ if (!groupmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(*groupnode)).second)
throw layout_syntax_error(util::string_format("duplicate group name %s", name));
}
- for (group_map::value_type &group : groupmap)
- group.second.resolve_bounds(groupmap);
// parse all the views
for (util::xml::data_node const *viewnode = mamelayoutnode->get_child("view"); viewnode != nullptr; viewnode = viewnode->get_next_sibling("view"))
@@ -2835,11 +3398,11 @@ layout_file::layout_file(device_t &device, util::xml::data_node const &rootnode,
// if the error is allowed to propagate, the entire layout is dropped so you can't select the useful view
try
{
- m_viewlist.emplace_back(device, *viewnode, m_elemmap, groupmap);
+ m_viewlist.emplace_back(env, *viewnode, m_elemmap, groupmap);
}
catch (layout_reference_error const &err)
{
- osd_printf_warning("Error instantiating layout view %s: %s\n", xml_get_attribute_string_with_subst(machine, *viewnode, "name", ""), err.what());
+ osd_printf_warning("Error instantiating layout view %s: %s\n", env.get_attribute_string(*viewnode, "name", ""), err.what());
}
}
}
diff --git a/src/lib/util/xmlfile.cpp b/src/lib/util/xmlfile.cpp
index d96c5913728..1014a7b245c 100644
--- a/src/lib/util/xmlfile.cpp
+++ b/src/lib/util/xmlfile.cpp
@@ -598,7 +598,7 @@ int data_node::get_attribute_int(const char *attribute, int defvalue) const
stream >> std::hex >> uvalue;
result = int(uvalue);
}
- else if (string[0] == '0' && string[1] == 'x')
+ else if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X')))
{
stream.str(&string[2]);
unsigned uvalue;
diff --git a/src/mame/layout/intlc44.lay b/src/mame/layout/intlc44.lay
index 19ea53437cf..5f64a31bd6e 100644
--- a/src/mame/layout/intlc44.lay
+++ b/src/mame/layout/intlc44.lay
@@ -164,21 +164,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel>
<cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel>
- <cpanel element="label_a3"><bounds left="81" top="63" right="185" bottom="70" /></cpanel>
- <cpanel element="label_a2"><bounds left="237" top="63" right="341" bottom="70" /></cpanel>
- <cpanel element="label_a1"><bounds left="393" top="63" right="497" bottom="70" /></cpanel>
- <cpanel element="label_11"><bounds left="81" top="71" right="92" bottom="78" /></cpanel>
- <cpanel element="label_10"><bounds left="112" top="71" right="123" bottom="78" /></cpanel>
- <cpanel element="label_9"><bounds left="143" top="71" right="154" bottom="78" /></cpanel>
- <cpanel element="label_8"><bounds left="174" top="71" right="185" bottom="78" /></cpanel>
- <cpanel element="label_7"><bounds left="237" top="71" right="248" bottom="78" /></cpanel>
- <cpanel element="label_6"><bounds left="268" top="71" right="279" bottom="78" /></cpanel>
- <cpanel element="label_5"><bounds left="299" top="71" right="310" bottom="78" /></cpanel>
- <cpanel element="label_4"><bounds left="330" top="71" right="341" bottom="78" /></cpanel>
- <cpanel element="label_3"><bounds left="393" top="71" right="404" bottom="78" /></cpanel>
- <cpanel element="label_2"><bounds left="424" top="71" right="435" bottom="78" /></cpanel>
- <cpanel element="label_1"><bounds left="455" top="71" right="466" bottom="78" /></cpanel>
- <cpanel element="label_0"><bounds left="486" top="71" right="497" bottom="78" /></cpanel>
<cpanel element="label_status"><bounds left="540" top="55" right="662" bottom="63" /></cpanel>
<cpanel element="label_search"><bounds left="561" top="63" right="610" bottom="70" /></cpanel>
@@ -188,16 +173,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_cpu"><bounds left="611" top="71" right="626" bottom="78" /></cpanel>
<cpanel element="label_instruction"><bounds left="72" top="104" right="350" bottom="112" /></cpanel>
- <cpanel element="label_m1"><bounds left="81" top="112" right="185" bottom="119" /></cpanel>
- <cpanel element="label_m2"><bounds left="237" top="112" right="341" bottom="119" /></cpanel>
- <cpanel element="label_7"><bounds left="81" top="120" right="92" bottom="127" /></cpanel>
- <cpanel element="label_6"><bounds left="112" top="120" right="123" bottom="127" /></cpanel>
- <cpanel element="label_5"><bounds left="143" top="120" right="154" bottom="127" /></cpanel>
- <cpanel element="label_4"><bounds left="174" top="120" right="185" bottom="127" /></cpanel>
- <cpanel element="label_3"><bounds left="237" top="120" right="248" bottom="127" /></cpanel>
- <cpanel element="label_2"><bounds left="268" top="120" right="279" bottom="127" /></cpanel>
- <cpanel element="label_1"><bounds left="299" top="120" right="310" bottom="127" /></cpanel>
- <cpanel element="label_0"><bounds left="330" top="120" right="341" bottom="127" /></cpanel>
<cpanel element="label_active_bank"><bounds left="384" top="104" right="506" bottom="112" /></cpanel>
<cpanel element="label_cm_ram"><bounds left="393" top="112" right="497" bottom="119" /></cpanel>
@@ -212,42 +187,10 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_prom"><bounds left="639" top="120" right="656" bottom="127" /></cpanel>
<cpanel element="label_execution"><bounds left="72" top="153" right="350" bottom="161" /></cpanel>
- <cpanel element="label_x2"><bounds left="81" top="161" right="185" bottom="168" /></cpanel>
- <cpanel element="label_x3"><bounds left="237" top="161" right="341" bottom="168" /></cpanel>
- <cpanel element="label_3"><bounds left="81" top="169" right="92" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="112" top="169" right="123" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="143" top="169" right="154" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="174" top="169" right="185" bottom="176" /></cpanel>
- <cpanel element="label_3"><bounds left="237" top="169" right="248" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="268" top="169" right="279" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="299" top="169" right="310" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="330" top="169" right="341" bottom="176" /></cpanel>
<cpanel element="label_last_ptr"><bounds left="384" top="153" right="662" bottom="161" /></cpanel>
- <cpanel element="label_x2"><bounds left="393" top="161" right="497" bottom="168" /></cpanel>
- <cpanel element="label_x3"><bounds left="549" top="161" right="653" bottom="168" /></cpanel>
- <cpanel element="label_3"><bounds left="393" top="169" right="404" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="424" top="169" right="435" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="455" top="169" right="466" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="486" top="169" right="497" bottom="176" /></cpanel>
- <cpanel element="label_3"><bounds left="549" top="169" right="560" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="580" top="169" right="591" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="611" top="169" right="622" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="642" top="169" right="653" bottom="176" /></cpanel>
<cpanel element="label_addr_data"><bounds left="72" top="214" right="506" bottom="222" /></cpanel>
- <cpanel element="label_11"><bounds left="74" top="230" right="99" bottom="237" /></cpanel>
- <cpanel element="label_10"><bounds left="105" top="230" right="130" bottom="237" /></cpanel>
- <cpanel element="label_9"><bounds left="136" top="230" right="161" bottom="237" /></cpanel>
- <cpanel element="label_8"><bounds left="167" top="230" right="192" bottom="237" /></cpanel>
- <cpanel element="label_7"><bounds left="230" top="230" right="255" bottom="237" /></cpanel>
- <cpanel element="label_6"><bounds left="261" top="230" right="286" bottom="237" /></cpanel>
- <cpanel element="label_5"><bounds left="292" top="230" right="317" bottom="237" /></cpanel>
- <cpanel element="label_4"><bounds left="323" top="230" right="348" bottom="237" /></cpanel>
- <cpanel element="label_3"><bounds left="386" top="230" right="411" bottom="237" /></cpanel>
- <cpanel element="label_2"><bounds left="417" top="230" right="442" bottom="237" /></cpanel>
- <cpanel element="label_1"><bounds left="448" top="230" right="473" bottom="237" /></cpanel>
- <cpanel element="label_0"><bounds left="479" top="230" right="504" bottom="237" /></cpanel>
<cpanel element="label_mode_ctrl"><bounds left="571" top="214" right="662" bottom="222" /></cpanel>
<cpanel element="label_mon"><bounds left="573" top="230" right="598" bottom="237" /></cpanel>
@@ -262,10 +205,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
- <cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
- <cpanel element="label_2"><bounds left="105" top="312" right="130" bottom="319" /></cpanel>
- <cpanel element="label_1"><bounds left="136" top="312" right="161" bottom="319" /></cpanel>
- <cpanel element="label_0"><bounds left="167" top="312" right="192" bottom="319" /></cpanel>
<cpanel element="label_search_ctrl"><bounds left="228" top="296" right="381" bottom="304" /></cpanel>
<cpanel element="label_run"><bounds left="230" top="312" right="255" bottom="319" /></cpanel>
@@ -291,42 +230,35 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_system"><bounds left="727" top="321" right="783" bottom="328" /></cpanel>
<cpanel element="label_reset_cpu"><bounds left="727" top="361" right="783" bottom="368" /></cpanel>
- <cpanel name="led_address_a3_3" element="led">
- <bounds left="81" top="79" right="92" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_2" element="led">
- <bounds left="112" top="79" right="123" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_1" element="led">
- <bounds left="143" top="79" right="154" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_0" element="led">
- <bounds left="174" top="79" right="185" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_3" element="led">
- <bounds left="237" top="79" right="248" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_2" element="led">
- <bounds left="268" top="79" right="279" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_1" element="led">
- <bounds left="299" top="79" right="310" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_0" element="led">
- <bounds left="330" top="79" right="341" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_3" element="led">
- <bounds left="393" top="79" right="404" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_2" element="led">
- <bounds left="424" top="79" right="435" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_1" element="led">
- <bounds left="455" top="79" right="466" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_0" element="led">
- <bounds left="486" top="79" right="497" bottom="86" />
- </cpanel>
+ <repeat count="3">
+ <param name="labelnum" start="11" increment="-4" />
+ <param name="ledpos" start="81" increment="156" />
+ <param name="nybble" start="3" increment="-1" />
+ <param name="switchpos" start="74" increment="156" />
+ <param name="mask" start="0x0800" rshift="4" />
+ <cpanel element="label_a~nybble~">
+ <bounds x="~ledpos~" y="63" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="labelnum" start="~labelnum~" increment="-1" />
+ <param name="ledpos" start="~ledpos~" increment="31" />
+ <param name="switchpos" start="~switchpos~" increment="31" />
+ <param name="bit" start="3" increment="-1" />
+ <param name="mask" start="~mask~" rshift="1" />
+ <cpanel element="label_~labelnum~">
+ <bounds x="~ledpos~" y="71" width="11" height="7" />
+ </cpanel>
+ <cpanel element="label_~labelnum~">
+ <bounds x="~switchpos~" y="230" width="25" height="7" />
+ </cpanel>
+ <cpanel name="led_address_a~nybble~_~bit~" element="led">
+ <bounds x="~ledpos~" y="79" width="11" height="7" />
+ </cpanel>
+ <cpanel element="switch" inputtag="ADDRDAT" inputmask="~mask~">
+ <bounds x="~switchpos~" y="240" width="25" height="46" />
+ </cpanel>
+ </repeat>
+ </repeat>
<cpanel name="led_status_search" element="led">
<bounds left="580" top="79" right="591" bottom="86" />
@@ -338,31 +270,6 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="642" top="79" right="653" bottom="86" />
</cpanel>
- <cpanel name="led_instruction_m1_3" element="led">
- <bounds left="81" top="128" right="92" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_2" element="led">
- <bounds left="112" top="128" right="123" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_1" element="led">
- <bounds left="143" top="128" right="154" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_0" element="led">
- <bounds left="174" top="128" right="185" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_3" element="led">
- <bounds left="237" top="128" right="248" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_2" element="led">
- <bounds left="268" top="128" right="279" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_1" element="led">
- <bounds left="299" top="128" right="310" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_0" element="led">
- <bounds left="330" top="128" right="341" bottom="135" />
- </cpanel>
-
<cpanel name="led_active_bank_3" element="led">
<bounds left="393" top="128" right="404" bottom="135" />
</cpanel>
@@ -386,92 +293,53 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="642" top="128" right="653" bottom="135" />
</cpanel>
- <cpanel name="led_execution_x2_3" element="led">
- <bounds left="81" top="177" right="92" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_2" element="led">
- <bounds left="112" top="177" right="123" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_1" element="led">
- <bounds left="143" top="177" right="154" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_0" element="led">
- <bounds left="174" top="177" right="185" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_3" element="led">
- <bounds left="237" top="177" right="248" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_2" element="led">
- <bounds left="268" top="177" right="279" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_1" element="led">
- <bounds left="299" top="177" right="310" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_0" element="led">
- <bounds left="330" top="177" right="341" bottom="184" />
- </cpanel>
-
- <cpanel name="led_last_ptr_x2_3" element="led">
- <bounds left="393" top="177" right="404" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_2" element="led">
- <bounds left="424" top="177" right="435" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_1" element="led">
- <bounds left="455" top="177" right="466" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_0" element="led">
- <bounds left="486" top="177" right="497" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_3" element="led">
- <bounds left="549" top="177" right="560" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_2" element="led">
- <bounds left="580" top="177" right="591" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_1" element="led">
- <bounds left="611" top="177" right="622" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_0" element="led">
- <bounds left="642" top="177" right="653" bottom="184" />
- </cpanel>
-
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0800">
- <bounds left="74" top="240" right="99" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0400">
- <bounds left="105" top="240" right="130" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0200">
- <bounds left="136" top="240" right="161" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0100">
- <bounds left="167" top="240" right="192" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0080">
- <bounds left="230" top="240" right="255" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0040">
- <bounds left="261" top="240" right="286" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0020">
- <bounds left="292" top="240" right="317" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0010">
- <bounds left="323" top="240" right="348" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0008">
- <bounds left="386" top="240" right="411" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0004">
- <bounds left="417" top="240" right="442" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0002">
- <bounds left="448" top="240" right="473" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0001">
- <bounds left="479" top="240" right="504" bottom="286" />
- </cpanel>
+ <repeat count="2">
+ <param name="xpos" start="81" increment="156" />
+ <param name="mnybble" start="1" increment="1" />
+ <param name="xnybble" start="2" increment="1" />
+ <param name="mbit" start="7" increment="-4" />
+ <cpanel element="label_m~mnybble~">
+ <bounds x="~xpos~" y="112" width="104" height="7" />
+ </cpanel>
+ <cpanel element="label_x~xnybble~">
+ <bounds x="~xpos~" y="161" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="~xpos~" increment="31" />
+ <param name="mbit" start="~mbit~" increment="-1" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~mbit~">
+ <bounds x="~xpos~" y="120" width="11" height="7" />
+ </cpanel>
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="169" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_instruction_m~mnybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="128" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_execution_x~xnybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="177" width="11" height="7" />
+ </cpanel>
+ </repeat>
+ </repeat>
+
+ <repeat count="2">
+ <param name="xpos" start="393" increment="156" />
+ <param name="nybble" start="2" increment="1" />
+ <cpanel element="label_x~nybble~">
+ <bounds x="~xpos~" y="161" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="~xpos~" increment="31" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="169" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_last_ptr_x~nybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="177" width="11" height="7" />
+ </cpanel>
+ </repeat>
+ </repeat>
<cpanel element="switch" inputtag="MODE" inputmask="0x0010">
<bounds left="573" top="240" right="598" bottom="286" />
@@ -487,18 +355,17 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="728" top="240" right="753" bottom="286" />
</cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x08">
- <bounds left="74" top="322" right="99" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x04">
- <bounds left="105" top="322" right="130" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x02">
- <bounds left="136" top="322" right="161" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x01">
- <bounds left="167" top="322" right="192" bottom="368" />
- </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="74" increment="31" />
+ <param name="mask" start="0x08" rshift="1" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="312" width="25" height="7" />
+ </cpanel>
+ <cpanel element="switch" inputtag="PASSES" inputmask="~mask~">
+ <bounds x="~xpos~" y="322" width="25" height="46" />
+ </cpanel>
+ </repeat>
<cpanel element="switch" inputtag="CONTROL" inputmask="0x0001">
<bounds left="230" top="322" right="255" bottom="368" />
diff --git a/src/mame/layout/intlc440.lay b/src/mame/layout/intlc440.lay
index 1d2cb625ca2..fa2b97734e8 100644
--- a/src/mame/layout/intlc440.lay
+++ b/src/mame/layout/intlc440.lay
@@ -160,21 +160,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel>
<cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel>
- <cpanel element="label_a3"><bounds left="81" top="63" right="185" bottom="70" /></cpanel>
- <cpanel element="label_a2"><bounds left="237" top="63" right="341" bottom="70" /></cpanel>
- <cpanel element="label_a1"><bounds left="393" top="63" right="497" bottom="70" /></cpanel>
- <cpanel element="label_11"><bounds left="81" top="71" right="92" bottom="78" /></cpanel>
- <cpanel element="label_10"><bounds left="112" top="71" right="123" bottom="78" /></cpanel>
- <cpanel element="label_9"><bounds left="143" top="71" right="154" bottom="78" /></cpanel>
- <cpanel element="label_8"><bounds left="174" top="71" right="185" bottom="78" /></cpanel>
- <cpanel element="label_7"><bounds left="237" top="71" right="248" bottom="78" /></cpanel>
- <cpanel element="label_6"><bounds left="268" top="71" right="279" bottom="78" /></cpanel>
- <cpanel element="label_5"><bounds left="299" top="71" right="310" bottom="78" /></cpanel>
- <cpanel element="label_4"><bounds left="330" top="71" right="341" bottom="78" /></cpanel>
- <cpanel element="label_3"><bounds left="393" top="71" right="404" bottom="78" /></cpanel>
- <cpanel element="label_2"><bounds left="424" top="71" right="435" bottom="78" /></cpanel>
- <cpanel element="label_1"><bounds left="455" top="71" right="466" bottom="78" /></cpanel>
- <cpanel element="label_0"><bounds left="486" top="71" right="497" bottom="78" /></cpanel>
<cpanel element="label_status"><bounds left="540" top="55" right="662" bottom="63" /></cpanel>
<cpanel element="label_search"><bounds left="561" top="63" right="610" bottom="70" /></cpanel>
@@ -184,16 +169,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_run"><bounds left="611" top="71" right="626" bottom="78" /></cpanel>
<cpanel element="label_instruction"><bounds left="72" top="104" right="350" bottom="112" /></cpanel>
- <cpanel element="label_m1"><bounds left="81" top="112" right="185" bottom="119" /></cpanel>
- <cpanel element="label_m2"><bounds left="237" top="112" right="341" bottom="119" /></cpanel>
- <cpanel element="label_7"><bounds left="81" top="120" right="92" bottom="127" /></cpanel>
- <cpanel element="label_6"><bounds left="112" top="120" right="123" bottom="127" /></cpanel>
- <cpanel element="label_5"><bounds left="143" top="120" right="154" bottom="127" /></cpanel>
- <cpanel element="label_4"><bounds left="174" top="120" right="185" bottom="127" /></cpanel>
- <cpanel element="label_3"><bounds left="237" top="120" right="248" bottom="127" /></cpanel>
- <cpanel element="label_2"><bounds left="268" top="120" right="279" bottom="127" /></cpanel>
- <cpanel element="label_1"><bounds left="299" top="120" right="310" bottom="127" /></cpanel>
- <cpanel element="label_0"><bounds left="330" top="120" right="341" bottom="127" /></cpanel>
<cpanel element="label_active_bank"><bounds left="384" top="104" right="506" bottom="112" /></cpanel>
<cpanel element="label_cm_ram"><bounds left="393" top="112" right="497" bottom="119" /></cpanel>
@@ -208,42 +183,10 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_prom"><bounds left="639" top="120" right="656" bottom="127" /></cpanel>
<cpanel element="label_execution"><bounds left="72" top="153" right="350" bottom="161" /></cpanel>
- <cpanel element="label_x2"><bounds left="81" top="161" right="185" bottom="168" /></cpanel>
- <cpanel element="label_x3"><bounds left="237" top="161" right="341" bottom="168" /></cpanel>
- <cpanel element="label_3"><bounds left="81" top="169" right="92" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="112" top="169" right="123" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="143" top="169" right="154" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="174" top="169" right="185" bottom="176" /></cpanel>
- <cpanel element="label_3"><bounds left="237" top="169" right="248" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="268" top="169" right="279" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="299" top="169" right="310" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="330" top="169" right="341" bottom="176" /></cpanel>
<cpanel element="label_last_ptr"><bounds left="384" top="153" right="662" bottom="161" /></cpanel>
- <cpanel element="label_x2"><bounds left="393" top="161" right="497" bottom="168" /></cpanel>
- <cpanel element="label_x3"><bounds left="549" top="161" right="653" bottom="168" /></cpanel>
- <cpanel element="label_3"><bounds left="393" top="169" right="404" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="424" top="169" right="435" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="455" top="169" right="466" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="486" top="169" right="497" bottom="176" /></cpanel>
- <cpanel element="label_3"><bounds left="549" top="169" right="560" bottom="176" /></cpanel>
- <cpanel element="label_2"><bounds left="580" top="169" right="591" bottom="176" /></cpanel>
- <cpanel element="label_1"><bounds left="611" top="169" right="622" bottom="176" /></cpanel>
- <cpanel element="label_0"><bounds left="642" top="169" right="653" bottom="176" /></cpanel>
<cpanel element="label_addr_data"><bounds left="72" top="214" right="506" bottom="222" /></cpanel>
- <cpanel element="label_11"><bounds left="74" top="230" right="99" bottom="237" /></cpanel>
- <cpanel element="label_10"><bounds left="105" top="230" right="130" bottom="237" /></cpanel>
- <cpanel element="label_9"><bounds left="136" top="230" right="161" bottom="237" /></cpanel>
- <cpanel element="label_8"><bounds left="167" top="230" right="192" bottom="237" /></cpanel>
- <cpanel element="label_7"><bounds left="230" top="230" right="255" bottom="237" /></cpanel>
- <cpanel element="label_6"><bounds left="261" top="230" right="286" bottom="237" /></cpanel>
- <cpanel element="label_5"><bounds left="292" top="230" right="317" bottom="237" /></cpanel>
- <cpanel element="label_4"><bounds left="323" top="230" right="348" bottom="237" /></cpanel>
- <cpanel element="label_3"><bounds left="386" top="230" right="411" bottom="237" /></cpanel>
- <cpanel element="label_2"><bounds left="417" top="230" right="442" bottom="237" /></cpanel>
- <cpanel element="label_1"><bounds left="448" top="230" right="473" bottom="237" /></cpanel>
- <cpanel element="label_0"><bounds left="479" top="230" right="504" bottom="237" /></cpanel>
<cpanel element="label_mode_ctrl"><bounds left="571" top="214" right="662" bottom="222" /></cpanel>
<cpanel element="label_mon"><bounds left="573" top="230" right="598" bottom="237" /></cpanel>
@@ -258,10 +201,6 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel>
<cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel>
- <cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel>
- <cpanel element="label_2"><bounds left="105" top="312" right="130" bottom="319" /></cpanel>
- <cpanel element="label_1"><bounds left="136" top="312" right="161" bottom="319" /></cpanel>
- <cpanel element="label_0"><bounds left="167" top="312" right="192" bottom="319" /></cpanel>
<cpanel element="label_search_ctrl"><bounds left="228" top="296" right="381" bottom="304" /></cpanel>
<cpanel element="label_run"><bounds left="230" top="312" right="255" bottom="319" /></cpanel>
@@ -286,42 +225,35 @@ Intel INTELLEC® 4/MOD 40 layout
<cpanel element="label_system"><bounds left="727" top="321" right="783" bottom="328" /></cpanel>
<cpanel element="label_reset_cpu"><bounds left="727" top="361" right="783" bottom="368" /></cpanel>
- <cpanel name="led_address_a3_3" element="led">
- <bounds left="81" top="79" right="92" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_2" element="led">
- <bounds left="112" top="79" right="123" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_1" element="led">
- <bounds left="143" top="79" right="154" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a3_0" element="led">
- <bounds left="174" top="79" right="185" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_3" element="led">
- <bounds left="237" top="79" right="248" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_2" element="led">
- <bounds left="268" top="79" right="279" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_1" element="led">
- <bounds left="299" top="79" right="310" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a2_0" element="led">
- <bounds left="330" top="79" right="341" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_3" element="led">
- <bounds left="393" top="79" right="404" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_2" element="led">
- <bounds left="424" top="79" right="435" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_1" element="led">
- <bounds left="455" top="79" right="466" bottom="86" />
- </cpanel>
- <cpanel name="led_address_a1_0" element="led">
- <bounds left="486" top="79" right="497" bottom="86" />
- </cpanel>
+ <repeat count="3">
+ <param name="labelnum" start="11" increment="-4" />
+ <param name="ledpos" start="81" increment="156" />
+ <param name="nybble" start="3" increment="-1" />
+ <param name="switchpos" start="74" increment="156" />
+ <param name="mask" start="0x0800" rshift="4" />
+ <cpanel element="label_a~nybble~">
+ <bounds x="~ledpos~" y="63" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="labelnum" start="~labelnum~" increment="-1" />
+ <param name="ledpos" start="~ledpos~" increment="31" />
+ <param name="switchpos" start="~switchpos~" increment="31" />
+ <param name="bit" start="3" increment="-1" />
+ <param name="mask" start="~mask~" rshift="1" />
+ <cpanel element="label_~labelnum~">
+ <bounds x="~ledpos~" y="71" width="11" height="7" />
+ </cpanel>
+ <cpanel element="label_~labelnum~">
+ <bounds x="~switchpos~" y="230" width="25" height="7" />
+ </cpanel>
+ <cpanel name="led_address_a~nybble~_~bit~" element="led">
+ <bounds x="~ledpos~" y="79" width="11" height="7" />
+ </cpanel>
+ <cpanel element="switch" inputtag="ADDRDAT" inputmask="~mask~">
+ <bounds x="~switchpos~" y="240" width="25" height="46" />
+ </cpanel>
+ </repeat>
+ </repeat>
<cpanel name="led_status_search" element="led">
<bounds left="580" top="79" right="591" bottom="86" />
@@ -333,31 +265,6 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="642" top="79" right="653" bottom="86" />
</cpanel>
- <cpanel name="led_instruction_m1_3" element="led">
- <bounds left="81" top="128" right="92" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_2" element="led">
- <bounds left="112" top="128" right="123" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_1" element="led">
- <bounds left="143" top="128" right="154" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m1_0" element="led">
- <bounds left="174" top="128" right="185" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_3" element="led">
- <bounds left="237" top="128" right="248" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_2" element="led">
- <bounds left="268" top="128" right="279" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_1" element="led">
- <bounds left="299" top="128" right="310" bottom="135" />
- </cpanel>
- <cpanel name="led_instruction_m2_0" element="led">
- <bounds left="330" top="128" right="341" bottom="135" />
- </cpanel>
-
<cpanel name="led_active_bank_3" element="led">
<bounds left="393" top="128" right="404" bottom="135" />
</cpanel>
@@ -381,92 +288,53 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="642" top="128" right="653" bottom="135" />
</cpanel>
- <cpanel name="led_execution_x2_3" element="led">
- <bounds left="81" top="177" right="92" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_2" element="led">
- <bounds left="112" top="177" right="123" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_1" element="led">
- <bounds left="143" top="177" right="154" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x2_0" element="led">
- <bounds left="174" top="177" right="185" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_3" element="led">
- <bounds left="237" top="177" right="248" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_2" element="led">
- <bounds left="268" top="177" right="279" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_1" element="led">
- <bounds left="299" top="177" right="310" bottom="184" />
- </cpanel>
- <cpanel name="led_execution_x3_0" element="led">
- <bounds left="330" top="177" right="341" bottom="184" />
- </cpanel>
-
- <cpanel name="led_last_ptr_x2_3" element="led">
- <bounds left="393" top="177" right="404" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_2" element="led">
- <bounds left="424" top="177" right="435" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_1" element="led">
- <bounds left="455" top="177" right="466" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x2_0" element="led">
- <bounds left="486" top="177" right="497" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_3" element="led">
- <bounds left="549" top="177" right="560" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_2" element="led">
- <bounds left="580" top="177" right="591" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_1" element="led">
- <bounds left="611" top="177" right="622" bottom="184" />
- </cpanel>
- <cpanel name="led_last_ptr_x3_0" element="led">
- <bounds left="642" top="177" right="653" bottom="184" />
- </cpanel>
-
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0800">
- <bounds left="74" top="240" right="99" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0400">
- <bounds left="105" top="240" right="130" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0200">
- <bounds left="136" top="240" right="161" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0100">
- <bounds left="167" top="240" right="192" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0080">
- <bounds left="230" top="240" right="255" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0040">
- <bounds left="261" top="240" right="286" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0020">
- <bounds left="292" top="240" right="317" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0010">
- <bounds left="323" top="240" right="348" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0008">
- <bounds left="386" top="240" right="411" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0004">
- <bounds left="417" top="240" right="442" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0002">
- <bounds left="448" top="240" right="473" bottom="286" />
- </cpanel>
- <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0001">
- <bounds left="479" top="240" right="504" bottom="286" />
- </cpanel>
+ <repeat count="2">
+ <param name="xpos" start="81" increment="156" />
+ <param name="mnybble" start="1" increment="1" />
+ <param name="xnybble" start="2" increment="1" />
+ <param name="mbit" start="7" increment="-4" />
+ <cpanel element="label_m~mnybble~">
+ <bounds x="~xpos~" y="112" width="104" height="7" />
+ </cpanel>
+ <cpanel element="label_x~xnybble~">
+ <bounds x="~xpos~" y="161" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="~xpos~" increment="31" />
+ <param name="mbit" start="~mbit~" increment="-1" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~mbit~">
+ <bounds x="~xpos~" y="120" width="11" height="7" />
+ </cpanel>
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="169" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_instruction_m~mnybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="128" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_execution_x~xnybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="177" width="11" height="7" />
+ </cpanel>
+ </repeat>
+ </repeat>
+
+ <repeat count="2">
+ <param name="xpos" start="393" increment="156" />
+ <param name="nybble" start="2" increment="1" />
+ <cpanel element="label_x~nybble~">
+ <bounds x="~xpos~" y="161" width="104" height="7" />
+ </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="~xpos~" increment="31" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="169" width="11" height="7" />
+ </cpanel>
+ <cpanel name="led_last_ptr_x~nybble~_~bit~" element="led">
+ <bounds x="~xpos~" y="177" width="11" height="7" />
+ </cpanel>
+ </repeat>
+ </repeat>
<cpanel element="switch" inputtag="MODE" inputmask="0x0010">
<bounds left="573" top="240" right="598" bottom="286" />
@@ -482,18 +350,17 @@ Intel INTELLEC® 4/MOD 40 layout
<bounds left="728" top="240" right="753" bottom="286" />
</cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x08">
- <bounds left="74" top="322" right="99" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x04">
- <bounds left="105" top="322" right="130" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x02">
- <bounds left="136" top="322" right="161" bottom="368" />
- </cpanel>
- <cpanel element="switch" inputtag="PASSES" inputmask="0x01">
- <bounds left="167" top="322" right="192" bottom="368" />
- </cpanel>
+ <repeat count="4">
+ <param name="xpos" start="74" increment="31" />
+ <param name="mask" start="0x08" rshift="1" />
+ <param name="bit" start="3" increment="-1" />
+ <cpanel element="label_~bit~">
+ <bounds x="~xpos~" y="312" width="25" height="7" />
+ </cpanel>
+ <cpanel element="switch" inputtag="PASSES" inputmask="~mask~">
+ <bounds x="~xpos~" y="322" width="25" height="46" />
+ </cpanel>
+ </repeat>
<cpanel element="switch" inputtag="CONTROL" inputmask="0x0001">
<bounds left="230" top="322" right="255" bottom="368" />
diff --git a/src/mame/layout/mephisto_academy.lay b/src/mame/layout/mephisto_academy.lay
index 565f670185b..fbea1e63ff8 100644
--- a/src/mame/layout/mephisto_academy.lay
+++ b/src/mame/layout/mephisto_academy.lay
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<mamelayout version="2">
-<!-- define elements -->
+ <!-- define elements -->
<element name="led" defstate="0">
<disk state="0">
<color red="0.20" green="0.0" blue="0.0" />
@@ -69,7 +69,7 @@
<element name="text_p6"> <rect><color red="0.59" green="0.39" blue="0.20" /></rect> <text string="&#x265f;"> <color red="1" green="1" blue="1" /></text> </element>
<element name="text_lcd"> <rect><color red="0.59" green="0.39" blue="0.20" /></rect> <text string="MULTI INFO LCD"><color red="1" green="1" blue="1" /></text> </element>
-<!-- build screen -->
+ <!-- build screen -->
<group name="panel">
<bezel element="background"><bounds x="25" y="0" width="50.25" height="8.5" /></bezel>
<bezel element="background"><bounds x="1" y="0" width="24" height="1" /></bezel>
@@ -119,16 +119,15 @@
<view name="Chessboard + Display">
<bezel element="background"><bounds x="-1" y="0" width="87" height="88" /></bezel>
- <!-- chessboard coords -->
+ <!-- chessboard coords -->
- <bezel element="text_8"><bounds x="-0.8" y="7" width="2" height="2" /></bezel>
- <bezel element="text_7"><bounds x="-0.8" y="17" width="2" height="2" /></bezel>
- <bezel element="text_6"><bounds x="-0.8" y="27" width="2" height="2" /></bezel>
- <bezel element="text_5"><bounds x="-0.8" y="37" width="2" height="2" /></bezel>
- <bezel element="text_4"><bounds x="-0.8" y="47" width="2" height="2" /></bezel>
- <bezel element="text_3"><bounds x="-0.8" y="57" width="2" height="2" /></bezel>
- <bezel element="text_2"><bounds x="-0.8" y="67" width="2" height="2" /></bezel>
- <bezel element="text_1"><bounds x="-0.8" y="77" width="2" height="2" /></bezel>
+ <repeat count="8">
+ <param name="num" start="8" increment="-1" />
+ <param name="y" start="7" increment="10" />
+ <bezel element="text_~num~">
+ <bounds x="-0.8" y="~y~" width="2" height="2" />
+ </bezel>
+ </repeat>
<bezel element="text_a"><bounds x="7" y="85" width="2" height="2" /></bezel>
<bezel element="text_b"><bounds x="17" y="85" width="2" height="2" /></bezel>
@@ -139,7 +138,7 @@
<bezel element="text_g"><bounds x="67" y="85" width="2" height="2" /></bezel>
<bezel element="text_h"><bounds x="77" y="85" width="2" height="2" /></bezel>
- <!-- chessboard bezel -->
+ <!-- chessboard bezel -->
<bezel element="white"><bounds x="2" y="2" width="82" height="82" /></bezel>
<bezel element="white"><bounds x="3" y="3" width="80" height="80" /></bezel>
@@ -184,155 +183,46 @@
<bezel element="black"><bounds x="43" y="73" width="10" height="10.5" /></bezel>
<bezel element="black"><bounds x="63" y="73" width="10" height="10.5" /></bezel>
- <!-- chessboard leds -->
-
- <bezel name="led0" element="led"><bounds x="11.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led1" element="led"><bounds x="21.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led2" element="led"><bounds x="31.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led3" element="led"><bounds x="41.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led4" element="led"><bounds x="51.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led5" element="led"><bounds x="61.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led6" element="led"><bounds x="71.2" y="81.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led7" element="led"><bounds x="81.2" y="81.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led8" element="led"><bounds x="11.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led9" element="led"><bounds x="21.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led10" element="led"><bounds x="31.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led11" element="led"><bounds x="41.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led12" element="led"><bounds x="51.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led13" element="led"><bounds x="61.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led14" element="led"><bounds x="71.2" y="71.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led15" element="led"><bounds x="81.2" y="71.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led16" element="led"><bounds x="11.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led17" element="led"><bounds x="21.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led18" element="led"><bounds x="31.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led19" element="led"><bounds x="41.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led20" element="led"><bounds x="51.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led21" element="led"><bounds x="61.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led22" element="led"><bounds x="71.2" y="61.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led23" element="led"><bounds x="81.2" y="61.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led24" element="led"><bounds x="11.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led25" element="led"><bounds x="21.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led26" element="led"><bounds x="31.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led27" element="led"><bounds x="41.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led28" element="led"><bounds x="51.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led29" element="led"><bounds x="61.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led30" element="led"><bounds x="71.2" y="51.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led31" element="led"><bounds x="81.2" y="51.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led32" element="led"><bounds x="11.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led33" element="led"><bounds x="21.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led34" element="led"><bounds x="31.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led35" element="led"><bounds x="41.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led36" element="led"><bounds x="51.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led37" element="led"><bounds x="61.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led38" element="led"><bounds x="71.2" y="41.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led39" element="led"><bounds x="81.2" y="41.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led40" element="led"><bounds x="11.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led41" element="led"><bounds x="21.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led42" element="led"><bounds x="31.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led43" element="led"><bounds x="41.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led44" element="led"><bounds x="51.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led45" element="led"><bounds x="61.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led46" element="led"><bounds x="71.2" y="31.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led47" element="led"><bounds x="81.2" y="31.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led48" element="led"><bounds x="11.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led49" element="led"><bounds x="21.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led50" element="led"><bounds x="31.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led51" element="led"><bounds x="41.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led52" element="led"><bounds x="51.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led53" element="led"><bounds x="61.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led54" element="led"><bounds x="71.2" y="21.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led55" element="led"><bounds x="81.2" y="21.3" width="1.5" height="1.5" /></bezel>
-
- <bezel name="led56" element="led"><bounds x="11.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led57" element="led"><bounds x="21.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led58" element="led"><bounds x="31.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led59" element="led"><bounds x="41.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led60" element="led"><bounds x="51.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led61" element="led"><bounds x="61.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led62" element="led"><bounds x="71.2" y="11.3" width="1.5" height="1.5" /></bezel>
- <bezel name="led63" element="led"><bounds x="81.2" y="11.3" width="1.5" height="1.5" /></bezel>
-
- <!-- chessboard sensors -->
-
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x01"><bounds x="3" y="3" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x02"><bounds x="13" y="3" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x04"><bounds x="23" y="3" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x08"><bounds x="33" y="3" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x10"><bounds x="43" y="3" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x20"><bounds x="53" y="3" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x40"><bounds x="63" y="3" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.7" inputmask="0x80"><bounds x="73" y="3" width="10" height="10" /><color alpha="0.2" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x01"><bounds x="3" y="13" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x02"><bounds x="13" y="13" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x04"><bounds x="23" y="13" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x08"><bounds x="33" y="13" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x10"><bounds x="43" y="13" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x20"><bounds x="53" y="13" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x40"><bounds x="63" y="13" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.6" inputmask="0x80"><bounds x="73" y="13" width="10" height="10" /><color alpha="0.4" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x01"><bounds x="3" y="23" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x02"><bounds x="13" y="23" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x04"><bounds x="23" y="23" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x08"><bounds x="33" y="23" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x10"><bounds x="43" y="23" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x20"><bounds x="53" y="23" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x40"><bounds x="63" y="23" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.5" inputmask="0x80"><bounds x="73" y="23" width="10" height="10" /><color alpha="0.2" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x01"><bounds x="3" y="33" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x02"><bounds x="13" y="33" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x04"><bounds x="23" y="33" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x08"><bounds x="33" y="33" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x10"><bounds x="43" y="33" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x20"><bounds x="53" y="33" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x40"><bounds x="63" y="33" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.4" inputmask="0x80"><bounds x="73" y="33" width="10" height="10" /><color alpha="0.4" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x01"><bounds x="3" y="43" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x02"><bounds x="13" y="43" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x04"><bounds x="23" y="43" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x08"><bounds x="33" y="43" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x10"><bounds x="43" y="43" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x20"><bounds x="53" y="43" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x40"><bounds x="63" y="43" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.3" inputmask="0x80"><bounds x="73" y="43" width="10" height="10" /><color alpha="0.2" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x01"><bounds x="3" y="53" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x02"><bounds x="13" y="53" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x04"><bounds x="23" y="53" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x08"><bounds x="33" y="53" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x10"><bounds x="43" y="53" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x20"><bounds x="53" y="53" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x40"><bounds x="63" y="53" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.2" inputmask="0x80"><bounds x="73" y="53" width="10" height="10" /><color alpha="0.4" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x01"><bounds x="3" y="63" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x02"><bounds x="13" y="63" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x04"><bounds x="23" y="63" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x08"><bounds x="33" y="63" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x10"><bounds x="43" y="63" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x20"><bounds x="53" y="63" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x40"><bounds x="63" y="63" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.1" inputmask="0x80"><bounds x="73" y="63" width="10" height="10" /><color alpha="0.2" /></bezel>
-
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x01"><bounds x="3" y="73" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x02"><bounds x="13" y="73" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x04"><bounds x="23" y="73" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x08"><bounds x="33" y="73" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x10"><bounds x="43" y="73" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x20"><bounds x="53" y="73" width="10" height="10" /><color alpha="0.4" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x40"><bounds x="63" y="73" width="10" height="10" /><color alpha="0.2" /></bezel>
- <bezel element="hl" inputtag="board:IN.0" inputmask="0x80"><bounds x="73" y="73" width="10" height="10" /><color alpha="0.4" /></bezel>
-
- <!-- LCD panel -->
+ <!-- chessboard LEDs -->
+ <repeat count="8">
+ <param name="ledy" start="81.3" increment="-10" />
+ <param name="ledno" start="0" increment="8" />
+ <repeat count="8">
+ <param name="ledx" start="11.2" increment="10" />
+ <param name="ledno" start="~ledno~" increment="1" />
+ <bezel name="led~ledno~" element="led">
+ <bounds x="~ledx~" y="~ledy~" width="1.5" height="1.5" />
+ </bezel>
+ </repeat>
+ </repeat>
+
+ <!-- chessboard sensors -->
+ <repeat count="4">
+ <param name="ipty" start="3" increment="20" />
+ <param name="iptno" start="7" increment="-2" />
+ <repeat count="2">
+ <param name="ipty" start="~ipty~" increment="10" />
+ <param name="iptno" start="~iptno~" 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.~iptno~" inputmask="~lmask~">
+ <bounds x="~lx~" y="~ipty~" width="10" height="10" />
+ <color alpha="~lalpha~" />
+ </bezel>
+ <bezel element="hl" inputtag="board:IN.~iptno~" inputmask="~rmask~">
+ <bounds x="~rx~" y="~ipty~" width="10" height="10" />
+ <color alpha="~ralpha~" />
+ </bezel>
+ </repeat>
+ </repeat>
+ </repeat>
+
+ <!-- LCD panel -->
<bezel element="background"><bounds x="-1" y="88" width="6" height="8.5" /></bezel>
<bezel element="background"><bounds x="80" y="88" width="6" height="8.5" /></bezel>
<group ref="panel"><bounds x="5" y="88" width="75.25" height="8.5" /></group>
diff --git a/src/mame/layout/ninjaw.lay b/src/mame/layout/ninjaw.lay
index e0a7010ae8b..7f205058673 100644
--- a/src/mame/layout/ninjaw.lay
+++ b/src/mame/layout/ninjaw.lay
@@ -1,41 +1,5 @@
<?xml version="1.0"?>
<mamelayout version="2">
- <view name="Screen 0 Standard (4:3)">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 1 Standard (4:3)">
- <screen index="1">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 2 Standard (4:3)">
- <screen index="2">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
- <screen index="0">
- <bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
- </screen>
- </view>
-
- <view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
- <screen index="1">
- <bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
- </screen>
- </view>
-
- <view name="Screen 2 Pixel Aspect (~scr2nativexaspect~:~scr2nativeyaspect~)">
- <screen index="2">
- <bounds left="0" top="0" right="~scr2width~" bottom="~scr2height~" />
- </screen>
- </view>
-
<view name="Triple Side-by-Side">
<screen index="0">
<bounds x="0" y="0" width="4" height="3" />
diff --git a/src/mame/layout/playch10.lay b/src/mame/layout/playch10.lay
index 088c2f0bedb..203cef8ec8a 100644
--- a/src/mame/layout/playch10.lay
+++ b/src/mame/layout/playch10.lay
@@ -6,30 +6,6 @@
</led7seg>
</element>
- <view name="Screen 0 Standard (4:3)">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 1 Standard (4:3)">
- <screen index="1">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
- <screen index="0">
- <bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
- </screen>
- </view>
-
- <view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
- <screen index="1">
- <bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
- </screen>
- </view>
-
<view name="Single Screen">
<bounds x="0" y="0" width="40" height="35" />
<bezel name="digit_3" element="digit">
diff --git a/src/mame/layout/ppsatan.lay b/src/mame/layout/ppsatan.lay
index 81e243edb99..8a53ac47910 100644
--- a/src/mame/layout/ppsatan.lay
+++ b/src/mame/layout/ppsatan.lay
@@ -1,41 +1,5 @@
<?xml version="1.0"?>
<mamelayout version="2">
- <view name="Screen 0 Standard (4:3)">
- <screen index="0">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 1 Standard (4:3)">
- <screen index="1">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 2 Standard (4:3)">
- <screen index="2">
- <bounds left="0" top="0" right="4" bottom="3" />
- </screen>
- </view>
-
- <view name="Screen 0 Pixel Aspect (~scr0nativexaspect~:~scr0nativeyaspect~)">
- <screen index="0">
- <bounds left="0" top="0" right="~scr0width~" bottom="~scr0height~" />
- </screen>
- </view>
-
- <view name="Screen 1 Pixel Aspect (~scr1nativexaspect~:~scr1nativeyaspect~)">
- <screen index="1">
- <bounds left="0" top="0" right="~scr1width~" bottom="~scr1height~" />
- </screen>
- </view>
-
- <view name="Screen 2 Pixel Aspect (~scr2nativexaspect~:~scr2nativeyaspect~)">
- <screen index="2">
- <bounds left="0" top="0" right="~scr2width~" bottom="~scr2height~" />
- </screen>
- </view>
-
<view name="Poka Poka Satan Custom">
<screen index="0">
<bounds x="0" y="0" width="4" height="3" />
@@ -47,5 +11,4 @@
<bounds x="+2.2" y="3.4" width="4" height="3" />
</screen>
</view>
-
</mamelayout>
diff --git a/src/mame/layout/wildfire.lay b/src/mame/layout/wildfire.lay
index c2c5ef210be..7bec0a1d3d2 100644
--- a/src/mame/layout/wildfire.lay
+++ b/src/mame/layout/wildfire.lay
@@ -26,125 +26,18 @@
<bezel name="digit1" element="digit"><bounds x="10" y="0" width="10" height="15" /></bezel>
<bezel name="digit2" element="digit"><bounds x="20" y="0" width="10" height="15" /></bezel>
- <!-- 13*8 matrix (first 3 are the 7segs) -->
-
- <bezel name="lamp0" element="led"><bounds x="0" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp1" element="led"><bounds x="2" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp2" element="led"><bounds x="4" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp3" element="led"><bounds x="6" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp4" element="led"><bounds x="8" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp5" element="led"><bounds x="10" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp6" element="led"><bounds x="12" y="20" width="1" height="1" /></bezel>
- <bezel name="lamp7" element="led"><bounds x="14" y="20" width="1" height="1" /></bezel>
-
- <bezel name="lamp10" element="led"><bounds x="0" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp11" element="led"><bounds x="2" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp12" element="led"><bounds x="4" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp13" element="led"><bounds x="6" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp14" element="led"><bounds x="8" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp15" element="led"><bounds x="10" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp16" element="led"><bounds x="12" y="22" width="1" height="1" /></bezel>
- <bezel name="lamp17" element="led"><bounds x="14" y="22" width="1" height="1" /></bezel>
-
- <bezel name="lamp20" element="led"><bounds x="0" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp21" element="led"><bounds x="2" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp22" element="led"><bounds x="4" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp23" element="led"><bounds x="6" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp24" element="led"><bounds x="8" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp25" element="led"><bounds x="10" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp26" element="led"><bounds x="12" y="24" width="1" height="1" /></bezel>
- <bezel name="lamp27" element="led"><bounds x="14" y="24" width="1" height="1" /></bezel>
-
- <bezel name="lamp30" element="led"><bounds x="0" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp31" element="led"><bounds x="2" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp32" element="led"><bounds x="4" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp33" element="led"><bounds x="6" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp34" element="led"><bounds x="8" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp35" element="led"><bounds x="10" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp36" element="led"><bounds x="12" y="26" width="1" height="1" /></bezel>
- <bezel name="lamp37" element="led"><bounds x="14" y="26" width="1" height="1" /></bezel>
-
- <bezel name="lamp40" element="led"><bounds x="0" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp41" element="led"><bounds x="2" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp42" element="led"><bounds x="4" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp43" element="led"><bounds x="6" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp44" element="led"><bounds x="8" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp45" element="led"><bounds x="10" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp46" element="led"><bounds x="12" y="28" width="1" height="1" /></bezel>
- <bezel name="lamp47" element="led"><bounds x="14" y="28" width="1" height="1" /></bezel>
-
- <bezel name="lamp50" element="led"><bounds x="0" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp51" element="led"><bounds x="2" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp52" element="led"><bounds x="4" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp53" element="led"><bounds x="6" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp54" element="led"><bounds x="8" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp55" element="led"><bounds x="10" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp56" element="led"><bounds x="12" y="30" width="1" height="1" /></bezel>
- <bezel name="lamp57" element="led"><bounds x="14" y="30" width="1" height="1" /></bezel>
-
- <bezel name="lamp60" element="led"><bounds x="0" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp61" element="led"><bounds x="2" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp62" element="led"><bounds x="4" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp63" element="led"><bounds x="6" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp64" element="led"><bounds x="8" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp65" element="led"><bounds x="10" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp66" element="led"><bounds x="12" y="32" width="1" height="1" /></bezel>
- <bezel name="lamp67" element="led"><bounds x="14" y="32" width="1" height="1" /></bezel>
-
- <bezel name="lamp70" element="led"><bounds x="0" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp71" element="led"><bounds x="2" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp72" element="led"><bounds x="4" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp73" element="led"><bounds x="6" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp74" element="led"><bounds x="8" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp75" element="led"><bounds x="10" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp76" element="led"><bounds x="12" y="34" width="1" height="1" /></bezel>
- <bezel name="lamp77" element="led"><bounds x="14" y="34" width="1" height="1" /></bezel>
-
- <bezel name="lamp80" element="led"><bounds x="0" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp81" element="led"><bounds x="2" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp82" element="led"><bounds x="4" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp83" element="led"><bounds x="6" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp84" element="led"><bounds x="8" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp85" element="led"><bounds x="10" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp86" element="led"><bounds x="12" y="36" width="1" height="1" /></bezel>
- <bezel name="lamp87" element="led"><bounds x="14" y="36" width="1" height="1" /></bezel>
-
- <bezel name="lamp90" element="led"><bounds x="0" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp91" element="led"><bounds x="2" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp92" element="led"><bounds x="4" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp93" element="led"><bounds x="6" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp94" element="led"><bounds x="8" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp95" element="led"><bounds x="10" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp96" element="led"><bounds x="12" y="38" width="1" height="1" /></bezel>
- <bezel name="lamp97" element="led"><bounds x="14" y="38" width="1" height="1" /></bezel>
-
- <bezel name="lamp100" element="led"><bounds x="0" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp101" element="led"><bounds x="2" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp102" element="led"><bounds x="4" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp103" element="led"><bounds x="6" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp104" element="led"><bounds x="8" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp105" element="led"><bounds x="10" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp106" element="led"><bounds x="12" y="40" width="1" height="1" /></bezel>
- <bezel name="lamp107" element="led"><bounds x="14" y="40" width="1" height="1" /></bezel>
-
- <bezel name="lamp110" element="led"><bounds x="0" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp111" element="led"><bounds x="2" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp112" element="led"><bounds x="4" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp113" element="led"><bounds x="6" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp114" element="led"><bounds x="8" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp115" element="led"><bounds x="10" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp116" element="led"><bounds x="12" y="42" width="1" height="1" /></bezel>
- <bezel name="lamp117" element="led"><bounds x="14" y="42" width="1" height="1" /></bezel>
-
- <bezel name="lamp120" element="led"><bounds x="0" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp121" element="led"><bounds x="2" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp122" element="led"><bounds x="4" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp123" element="led"><bounds x="6" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp124" element="led"><bounds x="8" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp125" element="led"><bounds x="10" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp126" element="led"><bounds x="12" y="44" width="1" height="1" /></bezel>
- <bezel name="lamp127" element="led"><bounds x="14" y="44" width="1" height="1" /></bezel>
-
-
+ <!-- 13*8 matrix (first 3 are the 7segs) -->
+
+ <repeat count="13">
+ <param name="ypos" start="20" increment="2" />
+ <param name="lampno" start="0" increment="10" />
+ <repeat count="8">
+ <param name="xpos" start="0" increment="2" />
+ <param name="lampno" start="~lampno~" increment="1" />
+ <bezel name="lamp~lampno~" element="led">
+ <bounds x="~xpos~" y="~ypos~" width="1" height="1" />
+ </bezel>
+ </repeat>
+ </repeat>
</view>
</mamelayout>