From 6adc5080154819eb7543cb35328082280804fb07 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 16 Sep 2020 02:55:04 +1000 Subject: [PATCH] emu/rendlay.cpp: Added parameter animation and state masks. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Components may have multiple bounds and/or color child elements with state attributes, allowing for piecewise linear position/size/colour animation. Components may have a statemask attribute, allowing for things like using external images to draw a multi-segment LED/VFD display without requiring dozens of outputs for the individual lines or thousands of images for all possible states. (Texture caching still never releases anything, so MAME can still exceed the maximum number of textures, but that’s a separate issue.) Image components with alpha now blend over previously drawn components. Layouts have been changed to use yes/no for inputraw to match what's used for flipx/flipy. External layouts with 1/0 will still work, but complay.py will complain. --- docs/source/techspecs/layout_files.rst | 100 +++- scripts/build/complay.py | 112 ++-- src/emu/render.cpp | 6 +- src/emu/render.h | 46 +- src/emu/rendlay.cpp | 727 +++++++++++++++++-------- src/emu/rendutil.cpp | 3 +- src/mame/layout/aci_ggm.lay | 162 +++--- src/mame/layout/alphie.lay | 8 +- src/mame/layout/conic_cchess2.lay | 4 +- src/mame/layout/copycat.lay | 12 +- src/mame/layout/ctstein.lay | 8 +- src/mame/layout/esq1by22.lay | 2 +- src/mame/layout/matchme.lay | 18 +- src/mame/layout/matchnum.lay | 4 +- src/mame/layout/mephisto_1.lay | 4 +- src/mame/layout/mephisto_3.lay | 2 +- src/mame/layout/mephisto_alm16.lay | 8 +- src/mame/layout/mephisto_alm32.lay | 8 +- src/mame/layout/mephisto_esb2.lay | 6 +- src/mame/layout/mephisto_gen32.lay | 8 +- src/mame/layout/mephisto_mirage.lay | 12 +- src/mame/layout/microvision.lay | 4 +- src/mame/layout/novag_savant.lay | 4 +- src/mame/layout/novag_supercon.lay | 16 +- src/mame/layout/qfire.lay | 4 +- src/mame/layout/saitek_mark5.lay | 148 ++--- src/mame/layout/saitek_mark6.lay | 148 ++--- src/mame/layout/saitek_ssystem3.lay | 16 +- src/mame/layout/saitek_ssystem4.lay | 4 +- src/mame/layout/simon.lay | 8 +- src/mame/layout/speedfrk.lay | 8 +- src/mame/layout/ssimon.lay | 32 +- src/mame/layout/touchme.lay | 6 +- src/mame/layout/zodiac.lay | 2 +- 34 files changed, 1026 insertions(+), 634 deletions(-) diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst index 4d7f9f5d712..31864f1c70f 100644 --- a/docs/source/techspecs/layout_files.rst +++ b/docs/source/techspecs/layout_files.rst @@ -398,19 +398,59 @@ Child elements of the ``element`` element instantiate components, which are drawn in reading order from first to last (components draw on top of components that come before them). All components support a few common features: -* Each component may have a ``state`` attribute. If present, the component will - only be drawn when the element’s state matches its value (if absent, the - component will always be drawn). If present, the ``state`` attribute must be - a non-negative integer. +* Components may be conditionally drawn depending on the element’s state by + supplying ``state`` and/or ``statemask`` attributes. If present, these + attributes must be non-negative integers. If only the ``state`` attribute is + present, the component will only be drawn when the element’s state matches its + value. If only the ``statemask`` attribute is present, the component will + only be drawn when all the bits that are set in its value are set in the + element’s state. + + If both the ``state`` and ``statemask`` attributes are present, the component + will only be drawn when the bits in the element’s state corresponding to the + bits that are set in the ``statemask`` attribute’s value match the value of the + corresponding bits in the ``state`` attribute’s value. + + (The component will always be drawn if neither ``state`` nor ``statemask`` + attributes are present, or if the ``statemask`` attribute’s value is zero.) * Each component may have a ``bounds`` child element specifying its position and size (see :ref:`layout-concepts-coordinates`). If no such element is present, the bounds default to a unit square (width and height of 1.0) with the top left corner at (0,0). + + A component’s position and/or size may be animated according to the element’s + state by supplying multiple ``bounds`` child elements with ``state`` + attributes. The ``state`` attribute of each ``bounds`` child element must be + a non-negative integer. The ``state`` attributes must not be equal for any + two ``bounds`` elements within a component. + + If the element’s state is lower than the ``state`` value of any ``bounds`` + child element, the position/size specified by the ``bounds`` child element + with the lowest ``state`` value will be used. If the element’s state is + higher than the ``state`` value of any ``bounds`` child element, the + position/size specified by the ``bounds`` child element with the highest + ``state`` value will be used. If the element’s state is between the ``state`` + values of two ``bounds`` child elements, the position/size will be + interpolated linearly. * Each component may have a ``color`` child element specifying an RGBA colour (see :ref:`layout-concepts-colours` for details). This can be used to control - the colour of geometric, algorithmically drawn, or textual components. It is - ignored for ``image`` components. If no such element is present, the colour - defaults to opaque white. + the colour of geometric, algorithmically drawn, or textual components. For + ``image`` components, the colour of the image pixels is multiplied by the + specified colour. If no such element is present, the colour defaults to + opaque white. + + A component’s color may be animated according to the element’s state by + supplying multiple ``color`` child elements with ``state`` attributes. The + ``state`` attributes must not be equal for any two ``color`` elements within a + component. + + If the element’s state is lower than the ``state`` value of any ``color`` + child element, the colour specified by the ``color`` child element with the + lowest ``state`` value will be used. If the element’s state is higher than + the ``state`` value of any ``color`` child element, the colour specified by + the ``color`` child element with the highest ``state`` value will be used. If + the element’s state is between the ``state`` values of two ``color`` child + elements, the RGBA colour components will be interpolated linearly. The following components are supported: @@ -523,7 +563,6 @@ An example element that draws a static left-aligned text string:: - An example element that displays a circular LED where the intensity depends on the state of an active-high output:: @@ -543,6 +582,51 @@ An example element for a button that gives visual feedback when clicked:: +An example of an element that draws a seven-segment LED display using external +segment images:: + + + + + + + + + + + + + +An example of a bar graph that grows vertically and changes colour from green, +through yellow, to red as the state increases:: + + + + + + + + + + + +An example of a bar graph that grows horizontally to the left or right and +changes colour from green, through yellow, to red as the state changes from the +neutral position:: + + + + + + + + + + + + + + .. _layout-parts-views: diff --git a/scripts/build/complay.py b/scripts/build/complay.py index 2fbc7667a8e..34a43992b7c 100755 --- a/scripts/build/complay.py +++ b/scripts/build/complay.py @@ -219,10 +219,6 @@ class LayoutChecker(Minifyer): 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.checkFloatAttribute('bounds', attrs, 'left', 0.0) top = self.checkFloatAttribute('bounds', attrs, 'top', 0.0) right = self.checkFloatAttribute('bounds', attrs, 'right', 1.0) @@ -258,9 +254,15 @@ class LayoutChecker(Minifyer): if self.checkIntAttribute('orientation', attrs, 'rotate', 0) not in self.ORIENTATIONS: self.handleError('Element orientation attribute rotate "%s" is unsupported' % (attrs['rotate'], )) for name in ('swapxy', 'flipx', 'flipy'): - if attrs.get(name, 'no') not in self.YESNO: + if (attrs.get(name, 'no') not in self.YESNO) and (not self.VARPATTERN.match(attrs['yesno'])): self.handleError('Element orientation attribute %s "%s" is not "yes" or "no"' % (name, attrs[name])) + def checkColor(self, attrs): + self.checkColorChannel(attrs, 'red') + self.checkColorChannel(attrs, 'green') + self.checkColorChannel(attrs, 'blue') + self.checkColorChannel(attrs, 'alpha') + def checkColorChannel(self, attrs, name): channel = self.checkFloatAttribute('color', attrs, name, None) if (channel is not None) and ((0.0 > channel) or (1.0 < channel)): @@ -268,7 +270,7 @@ class LayoutChecker(Minifyer): def checkTag(self, tag, element, attr): if '' == tag: - self.handleError('Element %s attribute %s is empty', (element, attr)) + self.handleError('Element %s attribute %s is empty' % (element, attr)) else: if tag.find('^') >= 0: self.handleError('Element %s attribute %s "%s" contains parent device reference' % (element, attr, tag)) @@ -278,12 +280,22 @@ class LayoutChecker(Minifyer): self.handleError('Element %s attribute %s "%s" contains double separator' % (element, attr, tag)) def checkComponent(self, name, attrs): - state = self.checkIntAttribute(name, attrs, 'state', None) - if (state is not None) and (0 > state): - self.handleError('Element %s attribute state "%s" is negative' % (name, attrs['state'])) + statemask = self.checkIntAttribute(name, attrs, 'statemask', None) + stateval = self.checkIntAttribute(name, attrs, 'state', None) + if stateval is not None: + if 0 > stateval: + self.handleError('Element %s attribute state "%s" is negative' % (name, attrs['state'])) + if (statemask is not None) and (stateval & ~statemask): + self.handleError('Element %s attribute state "%s" has bits set that are clear in attribute statemask "%s"' % (name, attrs['state'], attrs['statemask'])) self.handlers.append((self.componentStartHandler, self.componentEndHandler)) - self.have_bounds.append(False) - self.have_color.append(False) + self.have_bounds.append({ }) + self.have_color.append({ }) + + def startObject(self): + self.handlers.append((self.objectStartHandler, self.objectEndHandler)) + self.have_bounds.append(None) + self.have_orientation.append(False) + self.have_color.append(None) def rootStartHandler(self, name, attrs): if 'mamelayout' != name: @@ -337,7 +349,7 @@ class LayoutChecker(Minifyer): self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler)) self.variable_scopes.append({ }) self.repeat_depth.append(0) - self.have_bounds.append(False) + self.have_bounds.append(None) elif ('view' == name) and (not self.repeat_depth[-1]): self.current_collections = { } if 'name' not in attrs: @@ -350,7 +362,7 @@ class LayoutChecker(Minifyer): self.handlers.append((self.groupViewStartHandler, self.groupViewEndHandler)) self.variable_scopes.append({ }) self.repeat_depth.append(0) - self.have_bounds.append(False) + self.have_bounds.append(None) elif 'repeat' == name: if 'count' not in attrs: self.handleError('Element repeat missing attribute count') @@ -433,16 +445,25 @@ class LayoutChecker(Minifyer): def componentStartHandler(self, name, attrs): if 'bounds' == name: + state = self.checkIntAttribute(name, attrs, 'state', 0) + if state is not None: + if 0 > state: + self.handleError('Element bounds attribute state "%s" is negative' % (attrs['state'], )) + if state in self.have_bounds[-1]: + self.handleError('Duplicate bounds for state %d (previous %s)' % (state, self.have_bounds[-1][state])) + else: + self.have_bounds[-1][state] = self.formatLocation() self.checkBounds(attrs) elif 'color' == name: - if self.have_color[-1]: - self.handleError('Duplicate color element') - else: - self.have_color[-1] = True - self.checkColorChannel(attrs, 'red') - self.checkColorChannel(attrs, 'green') - self.checkColorChannel(attrs, 'blue') - self.checkColorChannel(attrs, 'alpha') + state = self.checkIntAttribute(name, attrs, 'state', 0) + if state is not None: + if 0 > state: + self.handleError('Element color attribute state "%s" is negative' % (attrs['state'], )) + if state in self.have_color[-1]: + self.handleError('Duplicate color for state %d (previous %s)' % (state, self.have_color[-1][state])) + else: + self.have_color[-1][state] = self.formatLocation() + self.checkColor(attrs) self.ignored_depth = 1 def componentEndHandler(self, name): @@ -464,25 +485,21 @@ class LayoutChecker(Minifyer): self.checkTag(attrs['inputtag'], name, 'inputtag') elif 'inputmask' in attrs: self.handleError('Element %s has inputmask attribute without inputtag attribute' % (name, )) - inputraw = self.checkIntAttribute(name, attrs, 'inputraw', None) - if (inputraw is not None): + inputraw = None + if 'inputraw' in attrs: + if (attrs['inputraw'] not in self.YESNO) and (not self.VARPATTERN.match(attrs['inputraw'])): + self.handleError('Element %s attribute inputraw "%s" is not "yes" or "no"' % (name, attrs['inputraw'])) + else: + inputraw = 'yes' == attrs['inputraw'] if 'inputmask' not in attrs: self.handleError('Element %s has inputraw attribute without inputmask attribute' % (name, )) if 'inputtag' not in attrs: self.handleError('Element %s has inputraw attribute without inputtag attribute' % (name, )) - if ((0 > inputraw) or (1 < inputraw)): - self.handleError('Element %s attribute inputraw "%s" not in valid range 0-1' % (name, attrs['inputraw'])) inputmask = self.checkIntAttribute(name, attrs, 'inputmask', None) if (inputmask is not None) and (0 == inputmask): if (inputraw is None) or (0 == inputraw): self.handleError('Element %s attribute inputmask "%s" is zero' % (name, attrs['inputmask'])) - if ('element' != name) and not self.has_legacy_object: - self.has_legacy_object = True - if self.has_collection: - self.handleError('Layout contains collection as well as legacy backdrop elements') - self.handlers.append((self.objectStartHandler, self.objectEndHandler)) - self.have_bounds.append(False) - self.have_orientation.append(False) + self.startObject(); elif 'screen' == name: if 'index' in attrs: index = self.checkIntAttribute(name, attrs, 'index', None) @@ -495,9 +512,7 @@ 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.handlers.append((self.objectStartHandler, self.objectEndHandler)) - self.have_bounds.append(False) - self.have_orientation.append(False) + self.startObject(); elif 'group' == name: if 'ref' not in attrs: self.handleError('Element group missing attribute ref') @@ -510,9 +525,7 @@ class LayoutChecker(Minifyer): self.current_collections[n] = l else: self.handleError('Element group instantiates collection with duplicate name "%s" from %s (previous %s)' % (n, l, self.current_collections[n])) - self.handlers.append((self.objectStartHandler, self.objectEndHandler)) - self.have_bounds.append(False) - self.have_orientation.append(False) + self.startObject(); elif 'repeat' == name: if 'count' not in attrs: self.handleError('Element repeat missing attribute count') @@ -532,16 +545,16 @@ class LayoutChecker(Minifyer): self.handleError('Element collection has duplicate name (previous %s)' % (self.current_collections[attrs['name']], )) if attrs.get('visible', 'yes') not in self.YESNO: self.handleError('Element collection attribute visible "%s" is not "yes" or "no"' % (attrs['visible'], )) - if not self.has_collection: - self.has_collection = True - if self.has_legacy_object: - self.handleError('Layout contains collection as well as legacy backdrop elements') self.variable_scopes.append({ }) self.collection_depth += 1 elif 'param' == name: self.checkParameter(attrs) self.ignored_depth = 1 elif 'bounds' == name: + if self.have_bounds[-1] is not None: + self.handleError('Duplicate element bounds (previous %s)' % (self.have_bounds[-1], )) + else: + self.have_bounds[-1] = self.formatLocation() self.checkBounds(attrs) if self.repeat_depth[-1]: self.handleError('Element bounds inside repeat') @@ -566,14 +579,25 @@ class LayoutChecker(Minifyer): def objectStartHandler(self, name, attrs): if 'bounds' == name: + if self.have_bounds[-1] is not None: + self.handleError('Duplicate element bounds (previous %s)' % (self.have_bounds[-1], )) + else: + self.have_bounds[-1] = self.formatLocation() self.checkBounds(attrs) elif 'orientation' == name: self.checkOrientation(attrs) + if 'color' == name: + if self.have_color[-1] is not None: + self.handleError('Duplicate element color (previous %s)' % (self.have_color[-1], )) + else: + self.have_color[-1] = self.formatLocation() + self.checkColor(attrs) self.ignored_depth = 1 def objectEndHandler(self, name): self.have_bounds.pop() self.have_orientation.pop() + self.have_color.pop() self.handlers.pop() def setDocumentLocator(self, locator): @@ -586,8 +610,6 @@ class LayoutChecker(Minifyer): self.variable_scopes = [ ] self.repeat_depth = [ ] self.collection_depth = 0 - self.has_collection = False - self.has_legacy_object = False self.have_bounds = [ ] self.have_orientation = [ ] self.have_color = [ ] @@ -609,8 +631,6 @@ class LayoutChecker(Minifyer): del self.variable_scopes del self.repeat_depth del self.collection_depth - del self.has_collection - del self.has_legacy_object del self.have_bounds del self.have_orientation del self.have_color diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 221ce9fc929..46123a02b3f 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -2511,15 +2511,13 @@ void render_target::add_container_primitives(render_primitive_list &list, const void render_target::add_element_primitives(render_primitive_list &list, const object_transform &xform, layout_element &element, int state, int blendmode) { - // if we're out of range, bail - if (state > element.maxstate()) - return; + // limit state range to non-negative values if (state < 0) state = 0; // get a pointer to the relevant texture render_texture *texture = element.state_texture(state); - if (texture != nullptr) + if (texture) { render_primitive *prim = list.alloc(render_primitive::QUAD); diff --git a/src/emu/render.h b/src/emu/render.h index b0d0df82d3c..1545a3f041d 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -579,7 +579,6 @@ public: // getters running_machine &machine() const { return m_machine; } int default_state() const { return m_defstate; } - int maxstate() const { return m_maxstate; } render_texture *state_texture(int state); private: @@ -603,17 +602,22 @@ private: void normalize_bounds(float xoffs, float yoffs, float xscale, float yscale); // getters - int state() const { return m_state; } - virtual int maxstate() const { return m_state; } - const render_bounds &bounds() const { return m_bounds; } - const render_color &color() const { return m_color; } + int statemask() const { return m_statemask; } + int stateval() const { return m_stateval; } + std::pair statewrap() const; + render_bounds overall_bounds() const; + render_bounds bounds(int state) const; + render_color color(int state) const; // operations virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) = 0; protected: - // helpers - void draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, const char *str, int align); + // helper + virtual int maxstate() const { return -1; } + + // drawing helpers + void draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, const char *str, int align, const render_color &color); void draw_segment_horizontal_caps(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, int caps, rgb_t color); void draw_segment_horizontal(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, rgb_t color); void draw_segment_vertical_caps(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, int caps, rgb_t color); @@ -625,10 +629,27 @@ private: void apply_skew(bitmap_argb32 &dest, int skewwidth); private: + struct bounds_step + { + int state; + render_bounds bounds; + render_bounds delta; + }; + using bounds_vector = std::vector; + + struct color_step + { + int state; + render_color color; + render_color delta; + }; + using color_vector = std::vector; + // internal state - int m_state; // state where this component is visible (-1 means all states) - render_bounds m_bounds; // bounds of the element - render_color m_color; // color of the element + int const m_statemask; // bits of state used to control visibility + int const m_stateval; // masked state value to make component visible + bounds_vector m_bounds; // bounds of the element + color_vector m_color; // color of the element }; // component implementations @@ -677,8 +698,9 @@ private: // internal state running_machine & m_machine; // reference to the owning machine std::vector m_complist; // list of components - int m_defstate; // default state of this element - int m_maxstate; // maximum state value for all components + int const m_defstate; // default state of this element + int m_statemask; // mask to apply to state values + bool m_foldhigh; // whether we need to fold state values above the mask range std::vector m_elemtex; // array of element textures used for managing the scaled bitmaps }; diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index 72c50a3db3b..198fa03998a 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -9,12 +9,14 @@ ***************************************************************************/ #include "emu.h" +#include "render.h" +#include "rendlay.h" #include "emuopts.h" -#include "render.h" #include "rendfont.h" -#include "rendlay.h" #include "rendutil.h" +#include "video/rgbutil.h" + #include "vecstream.h" #include "xmlfile.h" @@ -938,12 +940,10 @@ layout_element::make_component_map const layout_element::s_make_component{ 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) + , m_defstate(env.get_attribute_int(elemnode, "defstate", -1)) + , m_statemask(0) + , m_foldhigh(false) { - // get the default state - m_defstate = env.get_attribute_int(elemnode, "defstate", -1); - // parse components in order bool first = true; render_bounds bounds = { 0.0, 0.0, 0.0, 0.0 }; @@ -958,13 +958,15 @@ layout_element::layout_element(environment &env, util::xml::data_node const &ele // accumulate bounds if (first) - bounds = newcomp.bounds(); + bounds = newcomp.overall_bounds(); else - union_render_bounds(bounds, newcomp.bounds()); + union_render_bounds(bounds, newcomp.overall_bounds()); first = false; // determine the maximum state - m_maxstate = std::max(m_maxstate, newcomp.maxstate()); + std::pair const wrap(newcomp.statewrap()); + m_statemask |= wrap.first; + m_foldhigh = m_foldhigh || wrap.second; } if (!m_complist.empty()) @@ -972,8 +974,8 @@ layout_element::layout_element(environment &env, util::xml::data_node const &ele // determine the scale/offset for normalization float xoffs = bounds.x0; float yoffs = bounds.y0; - float xscale = 1.0f / (bounds.x1 - bounds.x0); - float yscale = 1.0f / (bounds.y1 - bounds.y0); + float xscale = 1.0F / (bounds.x1 - bounds.x0); + float yscale = 1.0F / (bounds.y1 - bounds.y0); // normalize all the component bounds for (component::ptr const &curcomp : m_complist) @@ -981,7 +983,7 @@ layout_element::layout_element(environment &env, util::xml::data_node const &ele } // allocate an array of element textures for the states - m_elemtex.resize(m_maxstate + 1); + m_elemtex.resize((m_statemask + 1) << (m_foldhigh ? 1 : 0)); } @@ -1005,7 +1007,7 @@ layout_element::~layout_element() 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{ 0.0F, 0.0F, 0.0F, 0.0F } , m_bounds_resolved(false) { } @@ -1284,8 +1286,12 @@ void layout_group::resolve_bounds( render_texture *layout_element::state_texture(int state) { - assert(state <= m_maxstate); - if (m_elemtex[state].m_texture == nullptr) + if (m_foldhigh && (state & ~m_statemask)) + state = (state & m_statemask) | (((m_statemask << 1) | 1) & ~m_statemask); + else + state &= m_statemask; + assert(m_elemtex.size() > state); + if (!m_elemtex[state].m_texture) { m_elemtex[state].m_element = this; m_elemtex[state].m_state = state; @@ -1303,23 +1309,26 @@ render_texture *layout_element::state_texture(int state) void layout_element::element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param) { - texture *elemtex = (texture *)param; + texture const &elemtex(*reinterpret_cast(param)); // iterate over components that are part of the current state - for (auto &curcomp : elemtex->m_element->m_complist) - if (curcomp->state() == -1 || curcomp->state() == elemtex->m_state) + for (auto const &curcomp : elemtex.m_element->m_complist) + { + if ((elemtex.m_state & curcomp->statemask()) == curcomp->stateval()) { // get the local scaled bounds + render_bounds const compbounds(curcomp->bounds(elemtex.m_state)); rectangle bounds( - render_round_nearest(curcomp->bounds().x0 * dest.width()), - render_round_nearest(curcomp->bounds().x1 * dest.width()), - render_round_nearest(curcomp->bounds().y0 * dest.height()), - render_round_nearest(curcomp->bounds().y1 * dest.height())); + render_round_nearest(compbounds.x0 * dest.width()), + render_round_nearest(compbounds.x1 * dest.width()), + render_round_nearest(compbounds.y0 * dest.height()), + render_round_nearest(compbounds.y1 * dest.height())); bounds &= dest.cliprect(); // based on the component type, add to the texture - curcomp->draw(elemtex->m_element->machine(), dest, bounds, elemtex->m_state); + curcomp->draw(elemtex.m_element->machine(), dest, bounds, elemtex.m_state); } + } } @@ -1330,13 +1339,10 @@ public: // construction/destruction image_component(environment &env, util::xml::data_node const &compnode, const char *dirname) : component(env, compnode, dirname) - , m_hasalpha(false) + , m_dirname(dirname ? dirname : "") + , m_imagefile(env.get_attribute_string(compnode, "file", "")) + , m_alphafile(env.get_attribute_string(compnode, "alphafile", "")) { - if (dirname != nullptr) - m_dirname = dirname; - m_imagefile = env.get_attribute_string(compnode, "file", ""); - m_alphafile = env.get_attribute_string(compnode, "alphafile", ""); - m_file = std::make_unique(env.machine().options().art_path(), OPEN_FLAG_READ); } protected: @@ -1344,19 +1350,56 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { if (!m_bitmap.valid()) - load_bitmap(); + load_bitmap(machine); - bitmap_argb32 destsub(dest, bounds); - render_resample_argb_bitmap_hq(destsub, m_bitmap, color()); + render_color const c(color(state)); + if (m_hasalpha || (1.0F > c.a)) + { + bitmap_argb32 tempbitmap(dest.width(), dest.height()); + render_resample_argb_bitmap_hq(tempbitmap, m_bitmap, c); + for (s32 y0 = 0, y1 = bounds.top(); bounds.bottom() >= y1; ++y0, ++y1) + { + u32 const *src(&tempbitmap.pix(y0, 0)); + u32 *dst(&dest.pix(y1, bounds.left())); + for (s32 x1 = bounds.left(); bounds.right() >= x1; ++x1, ++src, ++dst) + { + rgb_t const a(*src); + u32 const aa(a.a()); + if (aa) + { + rgb_t const b(*dst); + u32 const ba(b.a()); + if (ba) + { + u32 const ca((aa * 255) + (ba * (255 - aa))); + *dst = rgb_t( + u8(ca / 255), + u8(((a.r() * aa * 255) + (b.r() * ba * (255 - aa))) / ca), + u8(((a.g() * aa * 255) + (b.g() * ba * (255 - aa))) / ca), + u8(((a.b() * aa * 255) + (b.b() * ba * (255 - aa))) / ca)); + } + else + { + *dst = *src; + } + } + } + } + } + else + { + bitmap_argb32 destsub(dest, bounds); + render_resample_argb_bitmap_hq(destsub, m_bitmap, c); + } } private: // internal helpers - void load_bitmap() + void load_bitmap(running_machine &machine) { - assert(m_file != nullptr); + emu_file file(machine.options().art_path(), OPEN_FLAG_READ); - ru_imgformat const format = render_detect_image(*m_file, m_dirname.c_str(), m_imagefile.c_str()); + ru_imgformat const format = render_detect_image(file, m_dirname.c_str(), m_imagefile.c_str()); switch (format) { case RENDUTIL_IMGFORMAT_ERROR: @@ -1364,18 +1407,18 @@ private: case RENDUTIL_IMGFORMAT_PNG: // load the basic bitmap - m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str()); + m_hasalpha = render_load_png(m_bitmap, file, m_dirname.c_str(), m_imagefile.c_str()); break; default: // try JPG - render_load_jpeg(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str()); + render_load_jpeg(m_bitmap, file, m_dirname.c_str(), m_imagefile.c_str()); break; } // load the alpha bitmap if specified if (m_bitmap.valid() && !m_alphafile.empty()) - render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_alphafile.c_str(), true); + render_load_png(m_bitmap, file, m_dirname.c_str(), m_alphafile.c_str(), true); // if we can't load the bitmap, allocate a dummy one and report an error if (!m_bitmap.valid()) @@ -1397,11 +1440,10 @@ private: // internal state bitmap_argb32 m_bitmap; // source bitmap for images - std::string m_dirname; // directory name of image file (for lazy loading) - std::unique_ptr m_file; // file object for reading image/alpha files - std::string m_imagefile; // name of the image file (for lazy loading) - std::string m_alphafile; // name of the alpha file (for lazy loading) - bool m_hasalpha; // is there any alpha component present? + std::string const m_dirname; // directory name of image file (for lazy loading) + std::string const m_imagefile; // name of the image file (for lazy loading) + std::string const m_alphafile; // name of the alpha file (for lazy loading) + bool m_hasalpha = false; // is there any alpha component present? }; @@ -1420,10 +1462,11 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { // compute premultiplied colors - u32 const r = color().r * color().a * 255.0f; - u32 const g = color().g * color().a * 255.0f; - u32 const b = color().b * color().a * 255.0f; - u32 const inva = (1.0f - color().a) * 255.0f; + render_color const c = color(state); + u32 const r = c.r * c.a * 255.0f; + u32 const g = c.g * c.a * 255.0f; + u32 const b = c.b * c.a * 255.0f; + u32 const inva = (1.0f - c.a) * 255.0f; // iterate over X and Y for (u32 y = bounds.top(); y <= bounds.bottom(); y++) @@ -1466,10 +1509,11 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { // compute premultiplied colors - u32 const r = color().r * color().a * 255.0f; - u32 const g = color().g * color().a * 255.0f; - u32 const b = color().b * color().a * 255.0f; - u32 const inva = (1.0f - color().a) * 255.0f; + render_color const c(color(state)); + u32 const r = c.r * c.a * 255.0f; + u32 const g = c.g * c.a * 255.0f; + u32 const b = c.b * c.a * 255.0f; + u32 const inva = (1.0f - c.a) * 255.0f; // find the center float const xcenter = float(bounds.xcenter()); @@ -1481,7 +1525,7 @@ protected: // iterate over y for (u32 y = bounds.top(); y <= bounds.bottom(); y++) { - float ycoord = ycenter - ((float)y + 0.5f); + float ycoord = ycenter - (float(y) + 0.5f); float xval = xradius * sqrtf(1.0f - (ycoord * ycoord) * ooyradius2); // compute left/right coordinates @@ -1529,7 +1573,7 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { render_font *font = machine.render().font_alloc("default"); - draw_text(*font, dest, bounds, m_string.c_str(), m_textalign); + draw_text(*font, dest, bounds, m_string.c_str(), m_textalign, color(state)); machine.render().font_free(font); } @@ -1556,14 +1600,14 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff); - const rgb_t offpen = rgb_t(0x20,0xff,0xff,0xff); + rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff); + rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff); // sizes for computation - int bmwidth = 250; - int bmheight = 400; - int segwidth = 40; - int skewwidth = 40; + int const bmwidth = 250; + int const bmheight = 400; + int const segwidth = 40; + int const skewwidth = 40; // allocate a temporary bitmap for drawing bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight); @@ -1597,7 +1641,7 @@ protected: draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, BIT(state, 7) ? onpen : offpen); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -1618,15 +1662,15 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff); - const rgb_t offpen = rgb_t(0x20,0xff,0xff,0xff); - const rgb_t backpen = rgb_t(0x00,0x00,0x00,0x00); + rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff); + rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff); + rgb_t const backpen = rgb_t(0x00, 0x00, 0x00, 0x00); // sizes for computation - int bmwidth = 250; - int bmheight = 400; - int segwidth = 40; - int skewwidth = 40; + int const bmwidth = 250; + int const bmheight = 400; + int const segwidth = 40; + int const skewwidth = 40; // allocate a temporary bitmap for drawing bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight); @@ -1665,7 +1709,7 @@ protected: apply_skew(tempbitmap, 40); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -1686,14 +1730,14 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff); - const rgb_t offpen = rgb_t(0x20, 0xff, 0xff, 0xff); + rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff); + rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff); // sizes for computation - int bmwidth = 250; - int bmheight = 400; - int segwidth = 40; - int skewwidth = 40; + int const bmwidth = 250; + int const bmheight = 400; + int const segwidth = 40; + int const skewwidth = 40; // allocate a temporary bitmap for drawing bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight); @@ -1701,83 +1745,83 @@ protected: // top bar draw_segment_horizontal(tempbitmap, - 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 0)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 0)) ? onpen : offpen); // right-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 1)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 1)) ? onpen : offpen); // right-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 2)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 2)) ? onpen : offpen); // bottom bar draw_segment_horizontal(tempbitmap, - 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, - segwidth, (state & (1 << 3)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, + segwidth, (state & (1 << 3)) ? onpen : offpen); // left-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 4)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 4)) ? onpen : offpen); // left-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 5)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 5)) ? onpen : offpen); // horizontal-middle-left bar draw_segment_horizontal_caps(tempbitmap, - 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, - segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, + segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen); // horizontal-middle-right bar draw_segment_horizontal_caps(tempbitmap, - 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, - segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen); + 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, + segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen); // vertical-middle-top bar draw_segment_vertical_caps(tempbitmap, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen); + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen); // vertical-middle-bottom bar draw_segment_vertical_caps(tempbitmap, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen); + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen); // diagonal-left-bottom bar draw_segment_diagonal_1(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 10)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 10)) ? onpen : offpen); // diagonal-left-top bar draw_segment_diagonal_2(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 11)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 11)) ? onpen : offpen); // diagonal-right-top bar draw_segment_diagonal_1(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 12)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 12)) ? onpen : offpen); // diagonal-right-bottom bar draw_segment_diagonal_2(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 13)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 13)) ? onpen : offpen); // apply skew apply_skew(tempbitmap, 40); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -1899,7 +1943,7 @@ protected: apply_skew(tempbitmap, 40); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -1920,14 +1964,14 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff); - const rgb_t offpen = rgb_t(0x20, 0xff, 0xff, 0xff); + rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff); + rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff); // sizes for computation - int bmwidth = 250; - int bmheight = 400; - int segwidth = 40; - int skewwidth = 40; + int const bmwidth = 250; + int const bmheight = 400; + int const segwidth = 40; + int const skewwidth = 40; // allocate a temporary bitmap for drawing, adding some extra space for the tail bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth); @@ -1935,92 +1979,94 @@ protected: // top bar draw_segment_horizontal(tempbitmap, - 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 0)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 0)) ? onpen : offpen); // right-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 1)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 1)) ? onpen : offpen); // right-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 2)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 2)) ? onpen : offpen); // bottom bar draw_segment_horizontal(tempbitmap, - 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, - segwidth, (state & (1 << 3)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, + segwidth, (state & (1 << 3)) ? onpen : offpen); // left-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 4)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 4)) ? onpen : offpen); // left-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 5)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 5)) ? onpen : offpen); // horizontal-middle-left bar draw_segment_horizontal_caps(tempbitmap, - 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, - segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, + segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen); // horizontal-middle-right bar draw_segment_horizontal_caps(tempbitmap, - 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, - segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen); + 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, + segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen); // vertical-middle-top bar draw_segment_vertical_caps(tempbitmap, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen); + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen); // vertical-middle-bottom bar draw_segment_vertical_caps(tempbitmap, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen); + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen); // diagonal-left-bottom bar draw_segment_diagonal_1(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 10)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 10)) ? onpen : offpen); // diagonal-left-top bar draw_segment_diagonal_2(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 11)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 11)) ? onpen : offpen); // diagonal-right-top bar draw_segment_diagonal_1(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 12)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 12)) ? onpen : offpen); // diagonal-right-bottom bar draw_segment_diagonal_2(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 13)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 13)) ? onpen : offpen); // apply skew apply_skew(tempbitmap, 40); // comma tail draw_segment_diagonal_1(tempbitmap, - bmwidth - (segwidth/2), bmwidth + segwidth, - bmheight - (segwidth), bmheight + segwidth*1.5, - segwidth/2, (state & (1 << 15)) ? onpen : offpen); + bmwidth - (segwidth/2), bmwidth + segwidth, + bmheight - (segwidth), bmheight + segwidth*1.5, + segwidth/2, (state & (1 << 15)) ? onpen : offpen); // decimal point - draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 14)) ? onpen : offpen); + draw_segment_decimal(tempbitmap, + bmwidth + segwidth/2, bmheight - segwidth/2, + segwidth, (state & (1 << 14)) ? onpen : offpen); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -2041,14 +2087,14 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff); - const rgb_t offpen = rgb_t(0x20, 0xff, 0xff, 0xff); + rgb_t const onpen = rgb_t(0xff, 0xff, 0xff, 0xff); + rgb_t const offpen = rgb_t(0x20, 0xff, 0xff, 0xff); // sizes for computation - int bmwidth = 250; - int bmheight = 400; - int segwidth = 40; - int skewwidth = 40; + int const bmwidth = 250; + int const bmheight = 400; + int const segwidth = 40; + int const skewwidth = 40; // allocate a temporary bitmap for drawing bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth); @@ -2056,102 +2102,103 @@ protected: // top-left bar draw_segment_horizontal_caps(tempbitmap, - 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2, - segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2, + segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen); // top-right bar draw_segment_horizontal_caps(tempbitmap, - 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2, - segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen); + 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2, + segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen); // right-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 2)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 2)) ? onpen : offpen); // right-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, - segwidth, (state & (1 << 3)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, + segwidth, (state & (1 << 3)) ? onpen : offpen); // bottom-right bar draw_segment_horizontal_caps(tempbitmap, - 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2, - segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen); + 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2, + segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen); // bottom-left bar draw_segment_horizontal_caps(tempbitmap, - 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2, - segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2, + segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen); // left-bottom bar draw_segment_vertical(tempbitmap, - bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 6)) ? onpen : offpen); + bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 6)) ? onpen : offpen); // left-top bar draw_segment_vertical(tempbitmap, - 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, - segwidth, (state & (1 << 7)) ? onpen : offpen); + 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, + segwidth, (state & (1 << 7)) ? onpen : offpen); // horizontal-middle-left bar draw_segment_horizontal_caps(tempbitmap, - 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, - segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen); + 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2, + segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen); // horizontal-middle-right bar draw_segment_horizontal_caps(tempbitmap, - 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, - segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen); + 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2, + segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen); // vertical-middle-top bar draw_segment_vertical_caps(tempbitmap, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen); + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen); // vertical-middle-bottom bar draw_segment_vertical_caps(tempbitmap, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, - segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen); + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2, + segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen); // diagonal-left-bottom bar draw_segment_diagonal_1(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 12)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 12)) ? onpen : offpen); // diagonal-left-top bar draw_segment_diagonal_2(tempbitmap, - 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 13)) ? onpen : offpen); + 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 13)) ? onpen : offpen); // diagonal-right-top bar draw_segment_diagonal_1(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, - segwidth, (state & (1 << 14)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, + segwidth, (state & (1 << 14)) ? onpen : offpen); // diagonal-right-bottom bar draw_segment_diagonal_2(tempbitmap, - bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, - bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, - segwidth, (state & (1 << 15)) ? onpen : offpen); - - // comma tail - draw_segment_diagonal_1(tempbitmap, - bmwidth - (segwidth/2), bmwidth + segwidth, - bmheight - (segwidth), bmheight + segwidth*1.5, - segwidth/2, (state & (1 << 17)) ? onpen : offpen); - - // decimal point (draw last for priority) - draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 16)) ? onpen : offpen); + bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5, + bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, + segwidth, (state & (1 << 15)) ? onpen : offpen); // apply skew apply_skew(tempbitmap, 40); + // comma tail + draw_segment_diagonal_1(tempbitmap, + bmwidth - (segwidth/2), bmwidth + segwidth, bmheight - (segwidth), bmheight + segwidth*1.5, + segwidth/2, (state & (1 << 17)) ? onpen : offpen); + + // decimal point (draw last for priority) + draw_segment_decimal(tempbitmap, + bmwidth + segwidth/2, bmheight - segwidth/2, + segwidth, (state & (1 << 16)) ? onpen : offpen); + // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } }; @@ -2188,7 +2235,7 @@ protected: draw_segment_decimal(tempbitmap, ((dotwidth / 2) + (i * dotwidth)), bmheight / 2, dotwidth, BIT(state, i) ? onpen : offpen); // resample to the target size - render_resample_argb_bitmap_hq(dest, tempbitmap, color()); + render_resample_argb_bitmap_hq(dest, tempbitmap, color(state)); } private: @@ -2216,9 +2263,8 @@ protected: virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override { - render_font *font = machine.render().font_alloc("default"); - std::string temp = string_format("%0*d", m_digits, state); - draw_text(*font, dest, bounds, temp.c_str(), m_textalign); + render_font *const font = machine.render().font_alloc("default"); + draw_text(*font, dest, bounds, string_format("%0*d", m_digits, state).c_str(), m_textalign, color(state)); machine.render().font_free(font); } @@ -2307,10 +2353,11 @@ protected: int use_state = (state + m_stateoffset) % max_state_used; // compute premultiplied colors - u32 r = color().r * 255.0f; - u32 g = color().g * 255.0f; - u32 b = color().b * 255.0f; - u32 a = color().a * 255.0f; + render_color const c(color(state)); + u32 const r = c.r * 255.0f; + u32 const g = c.g * 255.0f; + u32 const b = c.b * 255.0f; + u32 const a = c.a * 255.0f; // get the width of the string render_font *font = machine.render().font_alloc("default"); @@ -2367,7 +2414,7 @@ protected: if (m_bitmap[fruit].valid()) { - render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color()); + render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c); for (int y = 0; y < ourheight/num_shown; y++) { @@ -2468,10 +2515,11 @@ private: int use_state = (state + m_stateoffset) % max_state_used; // compute premultiplied colors - u32 r = color().r * 255.0f; - u32 g = color().g * 255.0f; - u32 b = color().b * 255.0f; - u32 a = color().a * 255.0f; + render_color const c(color(state)); + u32 const r = c.r * 255.0f; + u32 const g = c.g * 255.0f; + u32 const b = c.b * 255.0f; + u32 const a = c.a * 255.0f; // get the width of the string render_font *font = machine.render().font_alloc("default"); @@ -2526,7 +2574,7 @@ private: if (m_bitmap[fruit].valid()) { - render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color()); + render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], c); for (int y = 0; y < dest.height(); y++) { @@ -2736,10 +2784,206 @@ layout_element::texture &layout_element::texture::operator=(texture &&that) //------------------------------------------------- layout_element::component::component(environment &env, util::xml::data_node const &compnode, const char *dirname) - : m_state(env.get_attribute_int(compnode, "state", -1)) - , m_color(env.parse_color(compnode.get_child("color"))) + : m_statemask(env.get_attribute_int(compnode, "statemask", env.get_attribute_string(compnode, "state", "")[0] ? ~0 : 0)) + , m_stateval(env.get_attribute_int(compnode, "state", m_statemask) & m_statemask) { - env.parse_bounds(compnode.get_child("bounds"), m_bounds); + for (util::xml::data_node const *child = compnode.get_first_child(); child; child = child->get_next_sibling()) + { + if (!strcmp(child->get_name(), "bounds")) + { + int const state(env.get_attribute_int(*child, "state", 0)); + auto const pos( + std::lower_bound( + m_bounds.begin(), + m_bounds.end(), + state, + [] (bounds_step const &lhs, int rhs) { return lhs.state < rhs; })); + if ((m_bounds.end() != pos) && (state == pos->state)) + { + throw layout_syntax_error( + util::string_format( + "%s component has duplicate bounds for state %d", + compnode.get_name(), + state)); + } + bounds_step &ins(*m_bounds.emplace(pos, bounds_step{ state, { 0.0F, 0.0F, 0.0F, 0.0F }, { 0.0F, 0.0F, 0.0F, 0.0F } })); + env.parse_bounds(child, ins.bounds); + } + else if (!strcmp(child->get_name(), "color")) + { + int const state(env.get_attribute_int(*child, "state", 0)); + auto const pos( + std::lower_bound( + m_color.begin(), + m_color.end(), + state, + [] (color_step const &lhs, int rhs) { return lhs.state < rhs; })); + if ((m_color.end() != pos) && (state == pos->state)) + { + throw layout_syntax_error( + util::string_format( + "%s component has duplicate color for state %d", + compnode.get_name(), + state)); + } + m_color.emplace(pos, color_step{ state, env.parse_color(child), { 0.0F, 0.0F, 0.0F, 0.0F } }); + } + } + if (m_bounds.empty()) + { + m_bounds.emplace_back(bounds_step{ 0, { 0.0F, 0.0F, 1.0F, 1.0F }, { 0.0F, 0.0F, 0.0F, 0.0F } }); + } + else + { + auto i(m_bounds.begin()); + auto j(i); + while (m_bounds.end() != ++j) + { + assert(j->state > i->state); + + i->delta.x0 = (j->bounds.x0 - i->bounds.x0) / (j->state - i->state); + i->delta.x1 = (j->bounds.x1 - i->bounds.x1) / (j->state - i->state); + i->delta.y0 = (j->bounds.y0 - i->bounds.y0) / (j->state - i->state); + i->delta.y1 = (j->bounds.y1 - i->bounds.y1) / (j->state - i->state); + + i = j; + } + } + if (m_color.empty()) + { + m_color.emplace_back(color_step{ 0, { 1.0F, 1.0F, 1.0F, 1.0F }, { 0.0F, 0.0F, 0.0F, 0.0F } }); + } + else + { + auto i(m_color.begin()); + auto j(i); + while (m_color.end() != ++j) + { + assert(j->state > i->state); + + i->delta.a = (j->color.a - i->color.a) / (j->state - i->state); + i->delta.r = (j->color.r - i->color.r) / (j->state - i->state); + i->delta.g = (j->color.g - i->color.g) / (j->state - i->state); + i->delta.b = (j->color.b - i->color.b) / (j->state - i->state); + + i = j; + } + } +} + + +//------------------------------------------------- +// statewrap - get state wraparound requirements +//------------------------------------------------- + +std::pair layout_element::component::statewrap() const +{ + int result(0); + bool fold; + auto const adjustmask = + [&result, &fold] (int val, int mask) + { + assert(!(val & ~mask)); + auto const splatright = + [] (int x) + { + for (unsigned shift = 1; (sizeof(x) * 4) >= shift; shift <<= 1) + x |= (x >> shift); + return x; + }; + int const unfolded(splatright(mask)); + int const folded(splatright(~mask | splatright(val))); + if (unsigned(folded) < unsigned(unfolded)) + { + result |= folded; + fold = true; + } + else + { + result |= unfolded; + } + }; + adjustmask(stateval(), statemask()); + int max(maxstate()); + if (m_bounds.size() > 1U) + max = (std::max)(max, m_bounds.back().state); + if (m_color.size() > 1U) + max = (std::max)(max, m_color.back().state); + if (0 <= max) + adjustmask(max, ~0); + return std::make_pair(result, fold); +} + + +//------------------------------------------------- +// overall_bounds - maximum bounds for all states +//------------------------------------------------- + +render_bounds layout_element::component::overall_bounds() const +{ + auto i(m_bounds.begin()); + render_bounds result(i->bounds); + while (m_bounds.end() != ++i) + union_render_bounds(result, i->bounds); + return result; +} + + +//------------------------------------------------- +// bounds - bounds for a given state +//------------------------------------------------- + +render_bounds layout_element::component::bounds(int state) const +{ + auto pos( + std::lower_bound( + m_bounds.begin(), + m_bounds.end(), + state, + [] (bounds_step const &lhs, int rhs) { return lhs.state < rhs; })); + if (m_bounds.begin() == pos) + { + return pos->bounds; + } + else + { + --pos; + render_bounds result(pos->bounds); + result.x0 += pos->delta.x0 * (state - pos->state); + result.x1 += pos->delta.x1 * (state - pos->state); + result.y0 += pos->delta.y0 * (state - pos->state); + result.y1 += pos->delta.y1 * (state - pos->state); + return result; + } +} + + +//------------------------------------------------- +// color - color for a given state +//------------------------------------------------- + +render_color layout_element::component::color(int state) const +{ + auto pos( + std::lower_bound( + m_color.begin(), + m_color.end(), + state, + [] (color_step const &lhs, int rhs) { return lhs.state < rhs; })); + if (m_color.begin() == pos) + { + return pos->color; + } + else + { + --pos; + render_color result(pos->color); + result.a += pos->delta.a * (state - pos->state); + result.r += pos->delta.r * (state - pos->state); + result.g += pos->delta.g * (state - pos->state); + result.b += pos->delta.b * (state - pos->state); + return result; + } } @@ -2749,10 +2993,27 @@ layout_element::component::component(environment &env, util::xml::data_node cons void layout_element::component::normalize_bounds(float xoffs, float yoffs, float xscale, float yscale) { - m_bounds.x0 = (m_bounds.x0 - xoffs) * xscale; - m_bounds.x1 = (m_bounds.x1 - xoffs) * xscale; - m_bounds.y0 = (m_bounds.y0 - yoffs) * yscale; - m_bounds.y1 = (m_bounds.y1 - yoffs) * yscale; + auto i(m_bounds.begin()); + i->bounds.x0 = (i->bounds.x0 - xoffs) * xscale; + i->bounds.x1 = (i->bounds.x1 - xoffs) * xscale; + i->bounds.y0 = (i->bounds.y0 - yoffs) * yscale; + i->bounds.y1 = (i->bounds.y1 - yoffs) * yscale; + + auto j(i); + while (m_bounds.end() != ++j) + { + j->bounds.x0 = (j->bounds.x0 - xoffs) * xscale; + j->bounds.x1 = (j->bounds.x1 - xoffs) * xscale; + j->bounds.y0 = (j->bounds.y0 - yoffs) * yscale; + j->bounds.y1 = (j->bounds.y1 - yoffs) * yscale; + + i->delta.x0 = (j->bounds.x0 - i->bounds.x0) / (j->state - i->state); + i->delta.x1 = (j->bounds.x1 - i->bounds.x1) / (j->state - i->state); + i->delta.y0 = (j->bounds.y0 - i->bounds.y0) / (j->state - i->state); + i->delta.y1 = (j->bounds.y1 - i->bounds.y1) / (j->state - i->state); + + i = j; + } } @@ -2760,13 +3021,19 @@ void layout_element::component::normalize_bounds(float xoffs, float yoffs, float // draw_text - draw text in the specified color //------------------------------------------------- -void layout_element::component::draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, const char *str, int align) +void layout_element::component::draw_text( + render_font &font, + bitmap_argb32 &dest, + const rectangle &bounds, + const char *str, + int align, + const render_color &color) { // compute premultiplied colors - u32 r = color().r * 255.0f; - u32 g = color().g * 255.0f; - u32 b = color().b * 255.0f; - u32 a = color().a * 255.0f; + u32 const r(color.r * 255.0f); + u32 const g(color.g * 255.0f); + u32 const b(color.b * 255.0f); + u32 const a(color.a * 255.0f); // get the width of the string float aspect = 1.0f; diff --git a/src/emu/rendutil.cpp b/src/emu/rendutil.cpp index 8baf312d224..f3e4950f598 100644 --- a/src/emu/rendutil.cpp +++ b/src/emu/rendutil.cpp @@ -9,12 +9,13 @@ ***************************************************************************/ #include "emu.h" -#include "render.h" #include "rendutil.h" + #include "png.h" #include "jpeglib.h" + /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ diff --git a/src/mame/layout/aci_ggm.lay b/src/mame/layout/aci_ggm.lay index 42c92f0db4d..45c32e621cb 100644 --- a/src/mame/layout/aci_ggm.lay +++ b/src/mame/layout/aci_ggm.lay @@ -242,104 +242,104 @@ license:CC0 - - - - - - + + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + - - + + - - + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - - - + + + + + + + + diff --git a/src/mame/layout/alphie.lay b/src/mame/layout/alphie.lay index de54036991c..a9abb89f1ee 100644 --- a/src/mame/layout/alphie.lay +++ b/src/mame/layout/alphie.lay @@ -65,10 +65,10 @@ license:CC0 - - - - + + + + diff --git a/src/mame/layout/conic_cchess2.lay b/src/mame/layout/conic_cchess2.lay index 3c2310448f2..ff0e87c2a0c 100644 --- a/src/mame/layout/conic_cchess2.lay +++ b/src/mame/layout/conic_cchess2.lay @@ -467,8 +467,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/copycat.lay b/src/mame/layout/copycat.lay index a49dd9f7472..ded15900bd3 100644 --- a/src/mame/layout/copycat.lay +++ b/src/mame/layout/copycat.lay @@ -119,17 +119,17 @@ license:CC0 - - + + - + - - + + - + diff --git a/src/mame/layout/ctstein.lay b/src/mame/layout/ctstein.lay index ffbe26ef17a..5ae84b7d3b0 100644 --- a/src/mame/layout/ctstein.lay +++ b/src/mame/layout/ctstein.lay @@ -138,10 +138,10 @@ license:CC0 - - - - + + + + diff --git a/src/mame/layout/esq1by22.lay b/src/mame/layout/esq1by22.lay index 0595ab1536d..a0c8f7448d5 100644 --- a/src/mame/layout/esq1by22.lay +++ b/src/mame/layout/esq1by22.lay @@ -18,7 +18,7 @@ license:CC0 - + diff --git a/src/mame/layout/matchme.lay b/src/mame/layout/matchme.lay index 82f5aa722ad..8f873795e1b 100644 --- a/src/mame/layout/matchme.lay +++ b/src/mame/layout/matchme.lay @@ -159,16 +159,16 @@ license:CC0 - - - - + + + + - - - - - + + + + + diff --git a/src/mame/layout/matchnum.lay b/src/mame/layout/matchnum.lay index b4b22329f46..5deab68b61b 100644 --- a/src/mame/layout/matchnum.lay +++ b/src/mame/layout/matchnum.lay @@ -150,8 +150,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_1.lay b/src/mame/layout/mephisto_1.lay index 76ffd55ce0d..52234d8d003 100644 --- a/src/mame/layout/mephisto_1.lay +++ b/src/mame/layout/mephisto_1.lay @@ -164,8 +164,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_3.lay b/src/mame/layout/mephisto_3.lay index dc1c7919b40..91fcc64682a 100644 --- a/src/mame/layout/mephisto_3.lay +++ b/src/mame/layout/mephisto_3.lay @@ -230,7 +230,7 @@ license:CC0 - + diff --git a/src/mame/layout/mephisto_alm16.lay b/src/mame/layout/mephisto_alm16.lay index ec968e41698..608eee4ca39 100644 --- a/src/mame/layout/mephisto_alm16.lay +++ b/src/mame/layout/mephisto_alm16.lay @@ -293,12 +293,12 @@ license:CC0 - + - + @@ -348,8 +348,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_alm32.lay b/src/mame/layout/mephisto_alm32.lay index 6fecadda389..8f102e04a91 100644 --- a/src/mame/layout/mephisto_alm32.lay +++ b/src/mame/layout/mephisto_alm32.lay @@ -293,12 +293,12 @@ license:CC0 - + - + @@ -357,8 +357,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_esb2.lay b/src/mame/layout/mephisto_esb2.lay index ab11ab3617b..72aca3d1360 100644 --- a/src/mame/layout/mephisto_esb2.lay +++ b/src/mame/layout/mephisto_esb2.lay @@ -230,7 +230,7 @@ license:CC0 - + @@ -540,8 +540,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_gen32.lay b/src/mame/layout/mephisto_gen32.lay index 59f748e9858..4d841a1e0ee 100644 --- a/src/mame/layout/mephisto_gen32.lay +++ b/src/mame/layout/mephisto_gen32.lay @@ -293,12 +293,12 @@ license:CC0 - + - + @@ -348,8 +348,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/mephisto_mirage.lay b/src/mame/layout/mephisto_mirage.lay index 3229a7c4cea..b85f78e58aa 100644 --- a/src/mame/layout/mephisto_mirage.lay +++ b/src/mame/layout/mephisto_mirage.lay @@ -190,10 +190,10 @@ license:CC0 - - - - + + + + @@ -273,12 +273,12 @@ license:CC0 - + - + diff --git a/src/mame/layout/microvision.lay b/src/mame/layout/microvision.lay index 34c266c700d..571b5a8afb7 100644 --- a/src/mame/layout/microvision.lay +++ b/src/mame/layout/microvision.lay @@ -40,8 +40,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/novag_savant.lay b/src/mame/layout/novag_savant.lay index f38bdf2d9c2..14be66c7015 100644 --- a/src/mame/layout/novag_savant.lay +++ b/src/mame/layout/novag_savant.lay @@ -235,8 +235,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/novag_supercon.lay b/src/mame/layout/novag_supercon.lay index 3d45f8e75c4..beac0315af8 100644 --- a/src/mame/layout/novag_supercon.lay +++ b/src/mame/layout/novag_supercon.lay @@ -599,15 +599,15 @@ license:CC0 - - - + + + - - - - - + + + + + diff --git a/src/mame/layout/qfire.lay b/src/mame/layout/qfire.lay index 055f3d89c64..035703242e5 100644 --- a/src/mame/layout/qfire.lay +++ b/src/mame/layout/qfire.lay @@ -102,10 +102,10 @@ license:CC0 - + - + diff --git a/src/mame/layout/saitek_mark5.lay b/src/mame/layout/saitek_mark5.lay index d16efecf8fd..8bfa228b11c 100644 --- a/src/mame/layout/saitek_mark5.lay +++ b/src/mame/layout/saitek_mark5.lay @@ -218,67 +218,67 @@ license:CC0 - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -309,31 +309,31 @@ license:CC0 - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - + @@ -404,8 +404,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/saitek_mark6.lay b/src/mame/layout/saitek_mark6.lay index 47741a91cf0..728653b9676 100644 --- a/src/mame/layout/saitek_mark6.lay +++ b/src/mame/layout/saitek_mark6.lay @@ -532,67 +532,67 @@ license:CC0 - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -623,31 +623,31 @@ license:CC0 - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - + @@ -718,8 +718,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/saitek_ssystem3.lay b/src/mame/layout/saitek_ssystem3.lay index 07dce2f931d..0ee2fa6e6c7 100644 --- a/src/mame/layout/saitek_ssystem3.lay +++ b/src/mame/layout/saitek_ssystem3.lay @@ -206,8 +206,8 @@ license:CC0 - - + + @@ -262,8 +262,8 @@ license:CC0 - - + + @@ -275,8 +275,8 @@ license:CC0 - - + + @@ -376,8 +376,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/saitek_ssystem4.lay b/src/mame/layout/saitek_ssystem4.lay index f722be515bc..bbe201a234d 100644 --- a/src/mame/layout/saitek_ssystem4.lay +++ b/src/mame/layout/saitek_ssystem4.lay @@ -90,8 +90,8 @@ license:CC0 - - + + diff --git a/src/mame/layout/simon.lay b/src/mame/layout/simon.lay index a7af62af55f..ef2f491a5c6 100644 --- a/src/mame/layout/simon.lay +++ b/src/mame/layout/simon.lay @@ -198,10 +198,10 @@ license:CC0 - + - + @@ -220,10 +220,10 @@ license:CC0 - + - + diff --git a/src/mame/layout/speedfrk.lay b/src/mame/layout/speedfrk.lay index 44b9bf2f0f7..4b24da8ef64 100644 --- a/src/mame/layout/speedfrk.lay +++ b/src/mame/layout/speedfrk.lay @@ -94,7 +94,7 @@ license:CC0 - + @@ -103,7 +103,7 @@ license:CC0 - + @@ -112,7 +112,7 @@ license:CC0 - + @@ -121,7 +121,7 @@ license:CC0 - + diff --git a/src/mame/layout/ssimon.lay b/src/mame/layout/ssimon.lay index bbdd3616113..bc819d755a3 100644 --- a/src/mame/layout/ssimon.lay +++ b/src/mame/layout/ssimon.lay @@ -212,10 +212,10 @@ license:CC0 - - - - + + + + @@ -245,20 +245,20 @@ license:CC0 - - - - - - + + + + + + - - - - - - + + + + + + diff --git a/src/mame/layout/touchme.lay b/src/mame/layout/touchme.lay index a97fd470405..25df5f557fa 100644 --- a/src/mame/layout/touchme.lay +++ b/src/mame/layout/touchme.lay @@ -199,9 +199,9 @@ license:CC0 - - - + + + diff --git a/src/mame/layout/zodiac.lay b/src/mame/layout/zodiac.lay index 1213cb5d15c..1409315e37b 100644 --- a/src/mame/layout/zodiac.lay +++ b/src/mame/layout/zodiac.lay @@ -218,7 +218,7 @@ license:CC0 - +