diff --git a/docs/source/commandline/commandline-all.rst b/docs/source/commandline/commandline-all.rst index acbd9b50099..c5bced793c5 100644 --- a/docs/source/commandline/commandline-all.rst +++ b/docs/source/commandline/commandline-all.rst @@ -1504,46 +1504,6 @@ Core Artwork Options The default is OFF **-noartwork_crop**. -.. _mame-commandline-nousebackdrops: - -**-[no]use_backdrops** / **-[no]backdrop** - - Enables/disables the display of backdrops. - - The default is ON (**-use_backdrops**). - -.. _mame-commandline-nouseoverlays: - -**-[no]use_overlays** / **-[no]overlay** - - Enables/disables the display of overlays. - - The default is ON (**-use_overlays**). - -.. _mame-commandline-nousebezels: - -**-[no]use_bezels** / **-[no]bezels** - - Enables/disables the display of bezels. - - The default is ON (**-use_bezels**). - -.. _mame-commandline-nousecpanels: - -**-[no]use_cpanels** / **-[no]cpanels** - - Enables/disables the display of control panels. - - The default is ON (**-use_cpanels**). - -.. _mame-commandline-nousemarquees: - -**-[no]use_marquees** / **-[no]marquees** - - Enables/disables the display of marquees. - - The default is ON (**-use_marquees**). - .. _mame-commandline-fallbackartwork: **-fallback_artwork** diff --git a/docs/source/commandline/commandline-index.rst b/docs/source/commandline/commandline-index.rst index a81c85ef4cc..b2caa063d14 100644 --- a/docs/source/commandline/commandline-index.rst +++ b/docs/source/commandline/commandline-index.rst @@ -191,11 +191,6 @@ Core Artwork Options ~~~~~~~~~~~~~~~~~~~~ | :ref:`[no]artwork_crop ` -| :ref:`[no]use_backdrops ` -| :ref:`[no]use_overlays ` -| :ref:`[no]use_bezels ` -| :ref:`[no]use_cpanels ` -| :ref:`[no]use_marquees ` | :ref:`fallback_artwork ` | :ref:`override_artwork ` diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst index 10467a8d0e9..bc05720a692 100644 --- a/docs/source/techspecs/layout_files.rst +++ b/docs/source/techspecs/layout_files.rst @@ -99,7 +99,7 @@ gamuts, so colours will typically be interpreted as sRGB with your system's target gamma (usually 2.2). Channel values are specified as floating-point numbers. Red, green and blue channel values range from 0.0 (off) to 1.0 (full intensity). Alpha ranges from 0.0 (fully transparent) to 1.0 (opaque). Colour -channels values are not pre-multiplied by the alpha value. +channel values are not pre-multiplied by the alpha value. Component and view item colour is specified using ``color`` elements. Meaningful attributes are ``red``, ``green``, ``blue`` and ``alpha``. This @@ -123,9 +123,9 @@ parameter is not defined, no substitution occurs. Here is an examples showing two instances of parameter use -- the values of the ``digitno`` and ``x`` parameters will be substituted for ``~digitno~`` and ``~x~``:: - + - + A parameter name is a sequence of uppercase English letters A-Z, lowercase English letters a-z, decimal digits 0-9, and/or underscore (_) characters. @@ -319,64 +319,6 @@ end of configuration. Values are not updated and layouts are not recomputed if the system reconfigures the screen while running. -.. _layout-concepts-layers: - -Layers -~~~~~~ - -Views are rendered as a stack of layers, named after parts of an arcade cabinet. -The layout supplies elements to be drawn in all layers besides the screen layer, -which is reserved for emulated screens. With the exception of the screen layer, -users can enable or disable layers using the in-emulation menu or command-line -options. - -The following layers are available: - -backdrop - Intended for use in situations were the screen image is projected over a - backdrop using a semi-reflective mirror (Pepper's ghost). This arrangement - is famously used in the Space Invaders deluxe cabinet. -screen - This layer is reserved for emulated screen images, and cannot be disabled by - the user. It is drawn using additive blending. -overlay - This layer is intended for use translucent overlays used to add colour to - games using monochrome monitors like Circus, Gee Bee, and of course Space - Invaders. It is drawn using RGB multiplication. -bezel - This layer is for elements that surround and potentially obscure the screen - image. It is drawn with standard alpha blending. -cpanel - This layer is intended for displaying controls/input devices (control - panels). It is drawn using standard alpha blending. -marquee - This layer is intended for displaying arcade cabinet marquee images. It is - drawn using standard alpha blending. - -By default, layers are drawn in this order (from back to front): - -* screen (add) -* overlay (multiply) -* backdrop (add) -* bezel (alpha) -* cpanel (alpha) -* marquee (alpha) - -If a view has multiple backdrop elements and no overlay elements, a different -order is used (from back to front): - -* backdrop (alpha) -* screen (add) -* bezel (alpha) -* cpanel (alpha) -* marquee (alpha) - -The alternate drawing order makes it simpler to build a backdrop from multiple -scanned/traced pieces of art, as they can have opaque parts. It can't be used -with overlay elements because colour overlays are conventionally placed between -the screen and mirror, and as such do not affect the backdrop. - - .. _layout-parts: Parts of a layout @@ -651,15 +593,14 @@ bounds param Defines or reassigns a value parameter in the view's scope. See :ref:`layout-concepts-params` for details. -backdrop overlay bezel cpanel marquee - Adds an element to the relevant layer (see :ref:`layout-parts-elements` and - :ref:`layout-concepts-layers`). The name of the element to add is specified - using the required ``element`` attribute. It is an error if no element with - this name is defined in the layout file. May optionally be connected to an - emulated I/O port using ``inputtag`` and ``inputmask`` attributes, and/or an - emulated output using a ``name`` attribute. Within a layer, elements are - drawn in the order they appear in the layout file, from front to back. See - below for more details. +element + Adds an element to the view (see :ref:`layout-parts-elements`). The name of + the element to add is specified using the required ``ref`` attribute. It is + an error if no element with this name is defined in the layout file. May + optionally be connected to an emulated I/O port using ``inputtag`` and + ``inputmask`` attributes, and/or an emulated output using a ``name`` + attribute. Within a layer, elements are drawn in the order they appear in + the layout file, from front to back. See below for more details. screen Adds an emulated screen image to the view. The screen must be identified using either an ``index`` attribute or a ``tag`` attribute (it is an error @@ -677,18 +618,16 @@ group repeat Repeats its contents the number of times specified by the required ``count`` attribute. The ``count`` attribute must be a positive integer. A - ``repeat`` element in a view may contain ``backdrop``, ``screen``, - ``overlay``, ``bezel``, ``cpanel``, ``marquee``, ``group``, and further - ``repeat`` elements, which function the same way they do when placed in a - view directly. See :ref:`layout-parts-repeats` for discussion on using - ``repeat`` elements. + ``repeat`` element in a view may contain ``element``, ``screen``, ``group``, + and further ``repeat`` elements, which function the same way they do when + placed in a view directly. See :ref:`layout-parts-repeats` for discussion + on using ``repeat`` elements. -Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``, -``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements) -may be have their orientation altered using an ``orientation`` child element. -For screens, the orientation modifiers are applied in addition to the -orientation modifiers specified on the screen device and on the machine. The -``orientation`` element supports the following attributes, all of which are +Screens (``screen`` elements), layout elements (``element`` elements) and groups +(``group`` elements) may have their orientation altered using an ``orientation`` +child element. For screens, the orientation modifiers are applied in addition +to the orientation modifiers specified on the screen device and on the machine. +The ``orientation`` element supports the following attributes, all of which are optional: rotate @@ -708,63 +647,65 @@ flipy axis, from top to bottom. Must be either ``yes`` or ``no`` if present. Mirroring applies logically after rotation. -Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``, -``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements) -may be positioned and sized using a ``bounds`` child element (see -:ref:`layout-concepts-coordinates` for details). In the absence of a ``bounds`` -child element, screens' and layout elements' bounds default to a unit square -(origin at 0,0 and height and width both equal to 1). In the absence of a -``bounds`` child element, groups are expanded with no translation/scaling (note -that groups may position screens/elements outside their bounds). This example -shows a view instantiating and positioning a screen, an individual layout -element, and two element groups:: +Screens (``screen`` elements) and layout elements (``element`` elements) may +have a ``blend`` attribute to set the blending mode. Supported values are +``none`` (no blending), ``alpha`` (alpha blending), ``multiply`` (RGB +multiplication), and ``add`` (additive blending). The default blending mode for +screens is additive blending, and the default blending mode for layout elements +is alpha blending. + +Screens (``screen`` elements), layout elements (``element`` elements) and groups +(``group`` elements) may be positioned and sized using a ``bounds`` child +element (see :ref:`layout-concepts-coordinates` for details). In the absence of +a ``bounds`` child element, screens' and layout elements' bounds default to a +unit square (origin at 0,0 and height and width both equal to 1). In the +absence of a ``bounds`` child element, groups are expanded with no +translation/scaling (note that groups may position screens/elements outside +their bounds). This example shows a view instantiating and positioning a +screen, an individual layout element, and two element groups:: - + + - -Screens (``screen`` elements), layout elements (``backdrop``, ``overlay``, -``bezel``, ``cpanel`` or ``marquee`` elements) and groups (``group`` elements) -may have a ``color`` child element (see :ref:`layout-concepts-colours`) -specifying a modifier colour. The components colours of the screen or layout -element(s) are multiplied by this colour. +Screens (``screen`` elements), layout elements (``element`` elements) and groups +(``group`` elements) may have a ``color`` child element (see +:ref:`layout-concepts-colours`) specifying a modifier colour. The component +colours of the screen or layout element(s) are multiplied by this colour. -If an element instantiating a layout element (``backdrop``, ``overlay``, -``bezel``, ``cpanel`` or ``marquee``) has ``inputtag`` and ``inputmask`` -attributes, clicking it is equivalent to pressing a key/button mapped to the -corresponding input(s). The ``inputtag`` specifies the tag path of an I/O port -relative to the device that caused the layout file to be loaded. The -``inputmask`` attribute must be an integer specifying the bits of the I/O port -that the element should activate. This sample is shows instantiation of -clickable buttons:: +If an ``element`` element has ``inputtag`` and ``inputmask`` attributes, +clicking it is equivalent to pressing a key/button mapped to the corresponding +input(s). The ``inputtag`` specifies the tag path of an I/O port relative to +the device that caused the layout file to be loaded. The ``inputmask`` +attribute must be an integer specifying the bits of the I/O port that the +element should activate. This sample shows instantiation of clickable buttons:: - + - - - - + + + + + - + +If an ``element`` element has a ``name`` attribute, it will take its state from +the value of the correspondingly named emulated output. Note that output names +are global, which can become an issue when a machine uses multiple instances of +the same type of device. See :ref:`layout-parts-elements` for details on how an +element's state affects its appearance. This example shows how digital displays +may be connected to emulated outputs:: -If an element instantiating a layout element (``backdrop``, ``overlay``, -``bezel``, ``cpanel`` or ``marquee``) has a ``name`` attribute, it will take its -state from the value of the correspondingly named emulated output. Note that -output names are global, which can become an issue when a machine uses multiple -instances of the same type of device. See :ref:`layout-parts-elements` for -details on how an element's state affects its appearance. This example shows -how digital displays may be connected to emulated outputs:: - - - - - - - + + + + + + If an element instantiating a layout element has ``inputtag`` and ``inputmask`` attributes but lacks a ``name`` attribute, it will take its state from the value @@ -829,8 +770,8 @@ To demonstrate how bounds calculation works, consider this example:: - - + + @@ -850,8 +791,8 @@ positions elements outside its explicit bounds:: - - + + @@ -902,8 +843,8 @@ elements allowed inside a ``repeat`` element depend on where it appears: * A repeating block inside the top-level ``mamelayout`` element may contain ``param``, ``element``, ``group`` (definition), and ``repeat`` elements. * A repeating block inside a ``group`` or ``view`` element may contain - ``param``, ``backdrop``, ``screen``, ``overlay``, ``bezel``, ``cpanel``, - ``marquee``, ``group`` (reference), and ``repeat`` elements. + ``param``, ``element`` (reference), ``screen``, ``group`` (reference), and + ``repeat`` elements. A repeating block effectively repeats its contents the number of times specified by its ``count`` attribute. See the relevant sections for details on how the @@ -928,9 +869,9 @@ element):: - + - + Eight five-by-seven dot matrix displays in a row, with pixels controlled by @@ -945,9 +886,9 @@ outputs ``Dot_000`` to ``Dot_764`` (inside a ``group`` or ``view`` element):: - + - + @@ -966,9 +907,9 @@ or ``view`` element):: - + - + @@ -998,14 +939,14 @@ Generating a chequerboard pattern with alternating alpha values 0.4 and 0.2 - + - - + + - + diff --git a/scripts/build/complay.py b/scripts/build/complay.py index b89ca98e19a..3f2a0d8b6b5 100644 --- a/scripts/build/complay.py +++ b/scripts/build/complay.py @@ -99,7 +99,8 @@ class LayoutChecker(Minifyer): SHAPES = frozenset(('disk', 'dotmatrix', 'dotmatrix5dot', 'dotmatrixdot', 'led14seg', 'led14segsc', 'led16seg', 'led16segsc', 'led7seg', 'led8seg_gts1', 'rect')) OBJECTS = frozenset(('backdrop', 'bezel', 'cpanel', 'marquee', 'overlay')) ORIENTATIONS = frozenset((0, 90, 180, 270)) - YESNO = frozenset(("yes", "no")) + YESNO = frozenset(('yes', 'no')) + BLENDMODES = frozenset(('none', 'alpha', 'multiply', 'add')) def __init__(self, output, **kwargs): super(LayoutChecker, self).__init__(output=output, **kwargs) @@ -445,11 +446,14 @@ class LayoutChecker(Minifyer): 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, )) - elif attrs['element'] not in self.referenced_elements: - self.referenced_elements[attrs['element']] = self.formatLocation() + if (name in self.OBJECTS) or ('element' == name): + refattr = 'ref' if 'element' == name else 'element' + if refattr not in attrs: + self.handleError('Element %s missing attribute %s' % (name, refattr)) + elif attrs[refattr] not in self.referenced_elements: + self.referenced_elements[attrs[refattr]] = self.formatLocation() + if ('blend' in attrs) and (attrs['blend'] not in self.BLENDMODES) and not self.VARPATTERN.match(attrs['blend']): + self.handleError('Element %s attribute blend "%s" is unsupported' % (name, attrs['blend'])) if 'inputtag' in attrs: if 'inputmask' not in attrs: self.handleError('Element %s has inputtag attribute without inputmask attribute' % (name, )) diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index 68e3bf7c2d2..c99748e67de 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -113,11 +113,6 @@ const options_entry emu_options::s_option_entries[] = // artwork options { nullptr, nullptr, OPTION_HEADER, "CORE ARTWORK OPTIONS" }, { OPTION_ARTWORK_CROP ";artcrop", "0", OPTION_BOOLEAN, "crop artwork so emulated screen image fills output screen/window in one axis" }, - { OPTION_USE_BACKDROPS ";backdrop", "1", OPTION_BOOLEAN, "enable backdrops if artwork is enabled and available" }, - { OPTION_USE_OVERLAYS ";overlay", "1", OPTION_BOOLEAN, "enable overlays if artwork is enabled and available" }, - { OPTION_USE_BEZELS ";bezel", "1", OPTION_BOOLEAN, "enable bezels if artwork is enabled and available" }, - { OPTION_USE_CPANELS ";cpanel", "1", OPTION_BOOLEAN, "enable cpanels if artwork is enabled and available" }, - { OPTION_USE_MARQUEES ";marquee", "1", OPTION_BOOLEAN, "enable marquees if artwork is enabled and available" }, { OPTION_FALLBACK_ARTWORK, nullptr, OPTION_STRING, "fallback artwork if no external artwork or internal driver layout defined" }, { OPTION_OVERRIDE_ARTWORK, nullptr, OPTION_STRING, "override artwork for external artwork and internal driver layout" }, diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h index b1869c82c16..c16e9c24567 100644 --- a/src/emu/emuopts.h +++ b/src/emu/emuopts.h @@ -97,11 +97,6 @@ // core artwork options #define OPTION_ARTWORK_CROP "artwork_crop" -#define OPTION_USE_BACKDROPS "use_backdrops" -#define OPTION_USE_OVERLAYS "use_overlays" -#define OPTION_USE_BEZELS "use_bezels" -#define OPTION_USE_CPANELS "use_cpanels" -#define OPTION_USE_MARQUEES "use_marquees" #define OPTION_FALLBACK_ARTWORK "fallback_artwork" #define OPTION_OVERRIDE_ARTWORK "override_artwork" @@ -379,11 +374,6 @@ public: // core artwork options bool artwork_crop() const { return bool_value(OPTION_ARTWORK_CROP); } - bool use_backdrops() const { return bool_value(OPTION_USE_BACKDROPS); } - bool use_overlays() const { return bool_value(OPTION_USE_OVERLAYS); } - bool use_bezels() const { return bool_value(OPTION_USE_BEZELS); } - bool use_cpanels() const { return bool_value(OPTION_USE_CPANELS); } - bool use_marquees() const { return bool_value(OPTION_USE_MARQUEES); } const char *fallback_artwork() const { return value(OPTION_FALLBACK_ARTWORK); } const char *override_artwork() const { return value(OPTION_OVERRIDE_ARTWORK); } diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 9b1c09a6f3a..34d29285162 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -111,22 +111,6 @@ static const render_quad_texuv oriented_texcoords[8] = { { 1,1 }, { 1,0 }, { 0,1 }, { 0,0 } } // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y }; -// layer orders -static constexpr std::pair layer_order_standard[]{ - { ITEM_LAYER_SCREEN, -1 }, // FIXME: invalid blend mode - we're relying on the goodness of the OSD - { ITEM_LAYER_OVERLAY, BLENDMODE_RGB_MULTIPLY }, - { ITEM_LAYER_BACKDROP, BLENDMODE_ADD }, - { ITEM_LAYER_BEZEL, BLENDMODE_ALPHA }, - { ITEM_LAYER_CPANEL, BLENDMODE_ALPHA }, - { ITEM_LAYER_MARQUEE, BLENDMODE_ALPHA } }; -static constexpr std::pair layer_order_alternate[]{ - { ITEM_LAYER_BACKDROP, BLENDMODE_ALPHA }, - { ITEM_LAYER_SCREEN, BLENDMODE_ADD }, - { ITEM_LAYER_OVERLAY, BLENDMODE_RGB_MULTIPLY }, - { ITEM_LAYER_BEZEL, BLENDMODE_ALPHA }, - { ITEM_LAYER_CPANEL, BLENDMODE_ALPHA }, - { ITEM_LAYER_MARQUEE, BLENDMODE_ALPHA } }; - //************************************************************************** @@ -177,25 +161,6 @@ inline void normalize_bounds(render_bounds &bounds) } -//------------------------------------------------- -// get_layer_and_blendmode - return the -// appropriate layer index and blendmode -//------------------------------------------------- - -inline item_layer get_layer_and_blendmode(layout_view &view, int index, int &blendmode) -{ - // if we have multiple backdrop pieces and no overlays, render: - // backdrop (add) + screens (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) - // else render: - // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) - - std::pair const *const layer_order(((view.items(ITEM_LAYER_BACKDROP).size() > 1) && view.items(ITEM_LAYER_OVERLAY).empty()) ? layer_order_alternate : layer_order_standard); - - // select the layer and blend mode - blendmode = layer_order[index].second; - return layer_order[index].first; -} - //************************************************************************** // RENDER PRIMITIVE //************************************************************************** @@ -941,11 +906,6 @@ template render_target::render_target(render_manager &manager, T && , m_transform_container(true) { // determine the base layer configuration based on options - m_base_layerconfig.set_backdrops_enabled(manager.machine().options().use_backdrops()); - m_base_layerconfig.set_overlays_enabled(manager.machine().options().use_overlays()); - m_base_layerconfig.set_bezels_enabled(manager.machine().options().use_bezels()); - m_base_layerconfig.set_cpanels_enabled(manager.machine().options().use_cpanels()); - m_base_layerconfig.set_marquees_enabled(manager.machine().options().use_marquees()); m_base_layerconfig.set_zoom_to_screen(manager.machine().options().artwork_crop()); // aspect and scale options @@ -1296,40 +1256,38 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight) throw emu_fatalerror("Mandatory artwork is missing"); // scan the current view for all screens - for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) + for (layout_view::item &curitem : m_curview->items()) { - // iterate over items in the layer - for (layout_view::item &curitem : m_curview->items(layer)) - if (curitem.screen()) + if (curitem.screen()) + { + // use a hard-coded default visible area for vector screens + screen_device *const screen = curitem.screen(); + const rectangle vectorvis(0, 639, 0, 479); + const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area(); + + // apply target orientation to the bounds + render_bounds bounds = curitem.bounds(); + apply_orientation(bounds, m_orientation); + normalize_bounds(bounds); + + // based on the orientation of the screen container, check the bitmap + float xscale, yscale; + if (!(orientation_add(m_orientation, screen->container().orientation()) & ORIENTATION_SWAP_XY)) { - // use a hard-coded default visible area for vector screens - screen_device *const screen = curitem.screen(); - const rectangle vectorvis(0, 639, 0, 479); - const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area(); - - // apply target orientation to the bounds - render_bounds bounds = curitem.bounds(); - apply_orientation(bounds, m_orientation); - normalize_bounds(bounds); - - // based on the orientation of the screen container, check the bitmap - float xscale, yscale; - if (!(orientation_add(m_orientation, screen->container().orientation()) & ORIENTATION_SWAP_XY)) - { - xscale = float(visarea.width()) / bounds.width(); - yscale = float(visarea.height()) / bounds.height(); - } - else - { - xscale = float(visarea.height()) / bounds.width(); - yscale = float(visarea.width()) / bounds.height(); - } - - // pick the greater - maxxscale = std::max(xscale, maxxscale); - maxyscale = std::max(yscale, maxyscale); - screens_considered++; + xscale = float(visarea.width()) / bounds.width(); + yscale = float(visarea.height()) / bounds.height(); } + else + { + xscale = float(visarea.height()) / bounds.width(); + yscale = float(visarea.width()) / bounds.height(); + } + + // pick the greater + maxxscale = std::max(xscale, maxxscale); + maxyscale = std::max(yscale, maxyscale); + screens_considered++; + } } // if there were no screens considered, pick a nominal default @@ -1378,42 +1336,33 @@ render_primitive_list &render_target::get_primitives() root_xform.orientation = m_orientation; root_xform.no_center = false; - // iterate over layers back-to-front, but only if we're running + // iterate over items in the view, but only if we're running if (m_manager.machine().phase() >= machine_phase::RESET) - for (item_layer layernum = ITEM_LAYER_FIRST; layernum < ITEM_LAYER_MAX; ++layernum) + for (layout_view::item &curitem : m_curview->items()) { - int blendmode; - item_layer layer = get_layer_and_blendmode(*m_curview, layernum, blendmode); - if (m_curview->layer_enabled(layer)) - { - // iterate over items in the layer - for (layout_view::item &curitem : m_curview->items(layer)) - { - // first apply orientation to the bounds - render_bounds bounds = curitem.bounds(); - apply_orientation(bounds, root_xform.orientation); - normalize_bounds(bounds); + // first apply orientation to the bounds + render_bounds bounds = curitem.bounds(); + apply_orientation(bounds, root_xform.orientation); + normalize_bounds(bounds); - // apply the transform to the item - object_transform item_xform; - item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; - item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; - item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; - item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; - item_xform.color.r = curitem.color().r * root_xform.color.r; - item_xform.color.g = curitem.color().g * root_xform.color.g; - item_xform.color.b = curitem.color().b * root_xform.color.b; - item_xform.color.a = curitem.color().a * root_xform.color.a; - item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); - item_xform.no_center = false; + // apply the transform to the item + object_transform item_xform; + item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale; + item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale; + item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale; + item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale; + item_xform.color.r = curitem.color().r * root_xform.color.r; + item_xform.color.g = curitem.color().g * root_xform.color.g; + item_xform.color.b = curitem.color().b * root_xform.color.b; + item_xform.color.a = curitem.color().a * root_xform.color.a; + item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation); + item_xform.no_center = false; - // if there is no associated element, it must be a screen element - if (curitem.screen() != nullptr) - add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), blendmode); - else - add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), blendmode); - } - } + // if there is no associated element, it must be a screen element + if (curitem.screen() != nullptr) + add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), curitem.blend_mode()); + else + add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), curitem.blend_mode()); } // if we are not in the running stage, draw an outer box @@ -2521,38 +2470,30 @@ bool render_target::map_point_internal(s32 target_x, s32 target_y, render_contai return false; } - // loop through each layer - for (item_layer layernum = ITEM_LAYER_FIRST; layernum < ITEM_LAYER_MAX; ++layernum) + // iterate over items in the view + for (layout_view::item &item : m_curview->items()) { - int blendmode; - item_layer layer = get_layer_and_blendmode(*m_curview, layernum, blendmode); - if (m_curview->layer_enabled(layer)) + bool checkit; + + // if we're looking for a particular container, verify that we have the right one + if (container != nullptr) + checkit = (item.screen() != nullptr && &item.screen()->container() == container); + + // otherwise, assume we're looking for an input + else + checkit = item.has_input(); + + // this target is worth looking at; now check the point + if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1) { - // iterate over items in the layer - for (layout_view::item &item : m_curview->items(layer)) - { - bool checkit; - - // if we're looking for a particular container, verify that we have the right one - if (container != nullptr) - checkit = (item.screen() != nullptr && &item.screen()->container() == container); - - // otherwise, assume we're looking for an input - else - checkit = item.has_input(); - - // this target is worth looking at; now check the point - if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1) - { - // point successfully mapped - mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0); - mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0); - mapped_input_port = item.input_tag_and_mask(mapped_input_mask); - return true; - } - } + // point successfully mapped + mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0); + mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0); + mapped_input_port = item.input_tag_and_mask(mapped_input_mask); + return true; } } + return false; } @@ -2603,6 +2544,8 @@ int render_target::view_index(layout_view &targetview) const void render_target::config_load(util::xml::data_node const &targetnode) { + int tmpint; + // find the view const char *viewname = targetnode.get_attribute_string("view", nullptr); if (viewname != nullptr) @@ -2619,26 +2562,6 @@ void render_target::config_load(util::xml::data_node const &targetnode) } // modify the artwork config - int tmpint = targetnode.get_attribute_int("backdrops", -1); - if (tmpint == 0 || tmpint == 1) - set_backdrops_enabled(tmpint); - - tmpint = targetnode.get_attribute_int("overlays", -1); - if (tmpint == 0 || tmpint == 1) - set_overlays_enabled(tmpint); - - tmpint = targetnode.get_attribute_int("bezels", -1); - if (tmpint == 0 || tmpint == 1) - set_bezels_enabled(tmpint); - - tmpint = targetnode.get_attribute_int("cpanels", -1); - if (tmpint == 0 || tmpint == 1) - set_cpanels_enabled(tmpint); - - tmpint = targetnode.get_attribute_int("marquees", -1); - if (tmpint == 0 || tmpint == 1) - set_marquees_enabled(tmpint); - tmpint = targetnode.get_attribute_int("zoom", -1); if (tmpint == 0 || tmpint == 1) set_zoom_to_screen(tmpint); @@ -2693,11 +2616,6 @@ bool render_target::config_save(util::xml::data_node &targetnode) // output the layer config if (m_layerconfig != m_base_layerconfig) { - targetnode.set_attribute_int("backdrops", m_layerconfig.backdrops_enabled()); - targetnode.set_attribute_int("overlays", m_layerconfig.overlays_enabled()); - targetnode.set_attribute_int("bezels", m_layerconfig.bezels_enabled()); - targetnode.set_attribute_int("cpanels", m_layerconfig.cpanels_enabled()); - targetnode.set_attribute_int("marquees", m_layerconfig.marquees_enabled()); targetnode.set_attribute_int("zoom", m_layerconfig.zoom_to_screen()); changed = true; } diff --git a/src/emu/render.h b/src/emu/render.h index 93621ea92c1..27e54c90885 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -270,14 +270,9 @@ private: 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 - static constexpr u8 ENABLE_CPANEL = 0x08; // enable cpanel layers - static constexpr u8 ENABLE_MARQUEE = 0x10; // enable marquee layers - static constexpr u8 ZOOM_TO_SCREEN = 0x20; // zoom to screen area by default - 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; + static constexpr u8 ZOOM_TO_SCREEN = 0x01; // zoom to screen area by default + static constexpr u8 ENABLE_SCREEN_OVERLAY = 0x02; // enable screen overlays + static constexpr u8 DEFAULT = ENABLE_SCREEN_OVERLAY; u8 m_state = DEFAULT; @@ -294,19 +289,9 @@ public: 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; } - 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); } }; @@ -601,25 +586,6 @@ private: -//************************************************************************** -// CONSTANTS -//************************************************************************** - -enum item_layer -{ - ITEM_LAYER_FIRST = 0, - ITEM_LAYER_BACKDROP = ITEM_LAYER_FIRST, - ITEM_LAYER_SCREEN, - ITEM_LAYER_OVERLAY, - ITEM_LAYER_BEZEL, - ITEM_LAYER_CPANEL, - ITEM_LAYER_MARQUEE, - ITEM_LAYER_MAX -}; -DECLARE_ENUM_INCDEC_OPERATORS(item_layer) - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -833,9 +799,10 @@ public: screen_device *screen() { return m_screen; } const render_bounds &bounds() const { return m_bounds; } const render_color &color() const { return m_color; } + int blend_mode() const { return m_blend_mode; } int orientation() const { return m_orientation; } render_container *screen_container(running_machine &machine) const; - bool has_input() const { return !m_input_tag.empty(); } + bool has_input() const { return bool(m_input_field); } ioport_port *input_tag_and_mask(ioport_value &mask) const { mask = m_input_mask; return m_input_port; }; // fetch state based on configured source @@ -844,21 +811,31 @@ public: // resolve tags, if any void resolve_tags(); + // setters + void set_blend_mode(int mode) { m_blend_mode = mode; } + private: + static layout_element *find_element(environment &env, util::xml::data_node const &itemnode, element_map &elemmap); + static render_bounds make_bounds(environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); + static std::string make_input_tag(environment &env, util::xml::data_node const &itemnode); + static int get_blend_mode(environment &env, util::xml::data_node const &itemnode); + // internal state - layout_element * m_element; // pointer to the associated element (non-screens only) - output_finder<> m_output; // associated output - bool const m_have_output; // whether we actually have an output - std::string m_input_tag; // input tag of this item - ioport_port * m_input_port; // input port of this item - ioport_value m_input_mask; // input mask of this item - u8 m_input_shift; // input mask rightshift for raw (trailing 0s) - bool m_input_raw; // get raw data from input port - screen_device * m_screen; // pointer to screen - int m_orientation; // orientation of this item - render_bounds m_bounds; // bounds of the item - render_bounds m_rawbounds; // raw (original) bounds of the item - render_color m_color; // color of the item + layout_element *const m_element; // pointer to the associated element (non-screens only) + output_finder<> m_output; // associated output + bool const m_have_output; // whether we actually have an output + std::string const m_input_tag; // input tag of this item + ioport_port * m_input_port; // input port of this item + ioport_field const * m_input_field; // input port field of this item + ioport_value const m_input_mask; // input mask of this item + u8 m_input_shift; // input mask rightshift for raw (trailing 0s) + bool const m_input_raw; // get raw data from input port + screen_device * m_screen; // pointer to screen + int m_orientation; // orientation of this item + render_bounds m_bounds; // bounds of the item + render_bounds const m_rawbounds; // raw (original) bounds of the item + render_color m_color; // color of the item + int m_blend_mode; // blending mode to use when drawing }; using item_list = std::list; @@ -871,15 +848,14 @@ public: ~layout_view(); // getters - item_list &items(item_layer layer); + item_list &items() { return m_items; } const std::string &name() const { return m_name; } const render_bounds &bounds() const { return m_bounds; } const render_bounds &screen_bounds() const { return m_scrbounds; } const render_screen_list &screens() const { return m_screens; } - bool layer_enabled(item_layer layer) const { return m_layenabled[layer]; } // - bool has_art() const { return !m_backdrop_list.empty() || !m_overlay_list.empty() || !m_bezel_list.empty() || !m_cpanel_list.empty() || !m_marquee_list.empty(); } + bool has_art() const { return m_has_art; } float effective_aspect(render_layer_config config) const { return (config.zoom_to_screen() && m_screens.count() != 0) ? m_scraspect : m_aspect; } // operations @@ -889,8 +865,11 @@ public: void resolve_tags(); private: + struct layer_lists; + // add items, recursing for groups void add_items( + layer_lists &layers, environment &env, util::xml::data_node const &parentnode, element_map &elemmap, @@ -912,13 +891,8 @@ private: render_bounds m_bounds; // computed bounds of the view render_bounds m_scrbounds; // computed bounds of the screens within the view render_bounds m_expbounds; // explicit bounds of the view - bool m_layenabled[ITEM_LAYER_MAX]; // is this layer enabled? - item_list m_backdrop_list; // list of backdrop items - item_list m_screen_list; // list of screen items - item_list m_overlay_list; // list of overlay items - item_list m_bezel_list; // list of bezel items - item_list m_cpanel_list; // list of marquee items - item_list m_marquee_list; // list of marquee items + item_list m_items; // list of layout items + bool m_has_art; // true if the layout contains non-screen elements }; @@ -1001,20 +975,10 @@ public: void set_scale_mode(int scale_mode) { m_scale_mode = scale_mode; } // layer config getters - bool backdrops_enabled() const { return m_layerconfig.backdrops_enabled(); } - bool overlays_enabled() const { return m_layerconfig.overlays_enabled(); } - bool bezels_enabled() const { return m_layerconfig.bezels_enabled(); } - bool cpanels_enabled() const { return m_layerconfig.cpanels_enabled(); } - bool marquees_enabled() const { return m_layerconfig.marquees_enabled(); } bool screen_overlay_enabled() const { return m_layerconfig.screen_overlay_enabled(); } bool zoom_to_screen() const { return m_layerconfig.zoom_to_screen(); } // layer config setters - void set_backdrops_enabled(bool enable) { m_layerconfig.set_backdrops_enabled(enable); update_layer_config(); } - void set_overlays_enabled(bool enable) { m_layerconfig.set_overlays_enabled(enable); update_layer_config(); } - void set_bezels_enabled(bool enable) { m_layerconfig.set_bezels_enabled(enable); update_layer_config(); } - void set_cpanels_enabled(bool enable) { m_layerconfig.set_cpanels_enabled(enable); update_layer_config(); } - void set_marquees_enabled(bool enable) { m_layerconfig.set_marquees_enabled(enable); update_layer_config(); } void set_screen_overlay_enabled(bool enable) { m_layerconfig.set_screen_overlay_enabled(enable); update_layer_config(); } void set_zoom_to_screen(bool zoom) { m_layerconfig.set_zoom_to_screen(zoom); update_layer_config(); } diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index d083ba5510a..8fc785b74a7 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -2944,6 +2944,9 @@ void layout_element::component::apply_skew(bitmap_argb32 &dest, int skewwidth) // LAYOUT VIEW //************************************************************************** +struct layout_view::layer_lists { item_list backdrops, screens, overlays, bezels, cpanels, marquees; }; + + //------------------------------------------------- // layout_view - constructor //------------------------------------------------- @@ -2956,11 +2959,41 @@ layout_view::layout_view( : m_name(make_name(env, viewnode)) , m_aspect(1.0f) , m_scraspect(1.0f) + , m_items() + , m_has_art(false) { + // parse the layout m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0; environment local(env); + layer_lists layers; local.set_parameter("viewname", std::string(m_name)); - add_items(local, viewnode, elemmap, groupmap, ROT0, identity_transform, render_color{ 1.0F, 1.0F, 1.0F, 1.0F }, true, false, true); + add_items(layers, local, viewnode, elemmap, groupmap, ROT0, identity_transform, render_color{ 1.0F, 1.0F, 1.0F, 1.0F }, true, false, true); + + // deal with legacy element groupings + if ((layers.backdrops.size() > 1) && layers.overlays.empty()) + { + // multiple backdrop pieces and no overlays (Golly! Ghost! mode): + // backdrop (alpha) + screens (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) + m_items.splice(m_items.end(), layers.backdrops); + m_items.splice(m_items.end(), layers.screens); + m_items.splice(m_items.end(), layers.bezels); + m_items.splice(m_items.end(), layers.cpanels); + m_items.splice(m_items.end(), layers.marquees); + } + else + { + // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) + for (item &backdrop : layers.backdrops) + backdrop.set_blend_mode(BLENDMODE_ADD); + m_items.splice(m_items.end(), layers.screens); + m_items.splice(m_items.end(), layers.overlays); + m_items.splice(m_items.end(), layers.backdrops); + m_items.splice(m_items.end(), layers.bezels); + m_items.splice(m_items.end(), layers.cpanels); + m_items.splice(m_items.end(), layers.marquees); + } + + // calculate metrics recompute(render_layer_config()); for (group_map::value_type &group : groupmap) group.second.set_bounds_unresolved(); @@ -2976,25 +3009,6 @@ layout_view::~layout_view() } -//------------------------------------------------- -// items - return the appropriate list -//------------------------------------------------- - -layout_view::item_list &layout_view::items(item_layer layer) -{ - switch (layer) - { - case ITEM_LAYER_BACKDROP: return m_backdrop_list; - case ITEM_LAYER_SCREEN: return m_screen_list; - case ITEM_LAYER_OVERLAY: return m_overlay_list; - case ITEM_LAYER_BEZEL: return m_bezel_list; - case ITEM_LAYER_CPANEL: return m_cpanel_list; - case ITEM_LAYER_MARQUEE: return m_marquee_list; - default: throw false; // calling this with an invalid layer is bad, m'kay? - } -} - - //------------------------------------------------- // recompute - recompute the bounds and aspect // ratio of a view and all of its contained items @@ -3010,43 +3024,27 @@ void layout_view::recompute(render_layer_config layerconfig) // loop over all layers bool first = true; bool scrfirst = true; - for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) + for (item &curitem : m_items) { - // determine if this layer should be visible - switch (layer) + // accumulate bounds + if (first) + m_bounds = curitem.m_rawbounds; + else + union_render_bounds(m_bounds, curitem.m_rawbounds); + first = false; + + // accumulate screen bounds + if (curitem.m_screen) { - case ITEM_LAYER_BACKDROP: m_layenabled[layer] = layerconfig.backdrops_enabled(); break; - case ITEM_LAYER_OVERLAY: m_layenabled[layer] = layerconfig.overlays_enabled(); break; - case ITEM_LAYER_BEZEL: m_layenabled[layer] = layerconfig.bezels_enabled(); break; - case ITEM_LAYER_CPANEL: m_layenabled[layer] = layerconfig.cpanels_enabled(); break; - case ITEM_LAYER_MARQUEE: m_layenabled[layer] = layerconfig.marquees_enabled(); break; - default: m_layenabled[layer] = true; break; + if (scrfirst) + m_scrbounds = curitem.m_rawbounds; + else + union_render_bounds(m_scrbounds, curitem.m_rawbounds); + scrfirst = false; + + // accumulate the screens in use while we're scanning + m_screens.add(*curitem.m_screen); } - - // only do it if requested - if (m_layenabled[layer]) - for (item &curitem : items(layer)) - { - // accumulate bounds - if (first) - m_bounds = curitem.m_rawbounds; - else - union_render_bounds(m_bounds, curitem.m_rawbounds); - first = false; - - // accumulate screen bounds - if (curitem.m_screen) - { - if (scrfirst) - m_scrbounds = curitem.m_rawbounds; - else - union_render_bounds(m_scrbounds, curitem.m_rawbounds); - scrfirst = false; - - // accumulate the screens in use while we're scanning - m_screens.add(*curitem.m_screen); - } - } } // if we have an explicit bounds, override it @@ -3085,14 +3083,13 @@ void layout_view::recompute(render_layer_config layerconfig) float yscale = (target_bounds.y1 - target_bounds.y0) / (m_bounds.y1 - m_bounds.y0); // normalize all the item bounds - for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) - for (item &curitem : items(layer)) - { - curitem.m_bounds.x0 = target_bounds.x0 + (curitem.m_rawbounds.x0 - xoffs) * xscale; - curitem.m_bounds.x1 = target_bounds.x0 + (curitem.m_rawbounds.x1 - xoffs) * xscale; - curitem.m_bounds.y0 = target_bounds.y0 + (curitem.m_rawbounds.y0 - yoffs) * yscale; - curitem.m_bounds.y1 = target_bounds.y0 + (curitem.m_rawbounds.y1 - yoffs) * yscale; - } + for (item &curitem : items()) + { + curitem.m_bounds.x0 = target_bounds.x0 + (curitem.m_rawbounds.x0 - xoffs) * xscale; + curitem.m_bounds.x1 = target_bounds.x0 + (curitem.m_rawbounds.x1 - xoffs) * xscale; + curitem.m_bounds.y0 = target_bounds.y0 + (curitem.m_rawbounds.y0 - yoffs) * yscale; + curitem.m_bounds.y1 = target_bounds.y0 + (curitem.m_rawbounds.y1 - yoffs) * yscale; + } } @@ -3102,13 +3099,8 @@ void layout_view::recompute(render_layer_config layerconfig) void layout_view::resolve_tags() { - for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer) - { - for (item &curitem : items(layer)) - { - curitem.resolve_tags(); - } - } + for (item &curitem : items()) + curitem.resolve_tags(); } @@ -3117,6 +3109,7 @@ void layout_view::resolve_tags() //------------------------------------------------- void layout_view::add_items( + layer_lists &layers, environment &env, util::xml::data_node const &parentnode, element_map &elemmap, @@ -3154,27 +3147,37 @@ void layout_view::add_items( } else if (!strcmp(itemnode->get_name(), "backdrop")) { - m_backdrop_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.backdrops.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "screen")) { - m_screen_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.screens.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + } + else if (!strcmp(itemnode->get_name(), "element")) + { + layers.screens.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "overlay")) { - m_overlay_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.overlays.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "bezel")) { - m_bezel_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.bezels.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "cpanel")) { - m_cpanel_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.cpanels.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "marquee")) { - m_marquee_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + layers.marquees.emplace_back(env, *itemnode, elemmap, orientation, trans, color); + m_has_art = true; } else if (!strcmp(itemnode->get_name(), "group")) { @@ -3205,6 +3208,7 @@ void layout_view::add_items( environment local(env); add_items( + layers, local, found->second.get_groupnode(), elemmap, @@ -3224,7 +3228,7 @@ void layout_view::add_items( environment local(env); for (int i = 0; count > i; ++i) { - add_items(local, *itemnode, elemmap, groupmap, orientation, trans, color, false, true, !i); + add_items(layers, local, *itemnode, elemmap, groupmap, orientation, trans, color, false, true, !i); local.increment_parameters(); } } @@ -3277,30 +3281,21 @@ layout_view::item::item( int orientation, layout_group::transform const &trans, render_color const &color) - : m_element(nullptr) + : m_element(find_element(env, itemnode, elemmap)) , 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_tag(make_input_tag(env, itemnode)) , m_input_port(nullptr) - , m_input_mask(0) + , m_input_field(nullptr) + , m_input_mask(env.get_attribute_int(itemnode, "inputmask", 0)) , m_input_shift(0) - , m_input_raw(false) + , m_input_raw(0 != env.get_attribute_int(itemnode, "inputraw", 0)) , m_screen(nullptr) , m_orientation(orientation_add(env.parse_orientation(itemnode.get_child("orientation")), orientation)) + , m_rawbounds(make_bounds(env, itemnode, trans)) , m_color(render_color_multiply(env.parse_color(itemnode.get_child("color")), color)) + , m_blend_mode(get_blend_mode(env, itemnode)) { - // find the associated element - 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 - element_map::iterator const found(elemmap.find(name)); - if (elemmap.end() != found) - m_element = &found->second; - else - throw layout_syntax_error(util::string_format("unable to find element %s", name)); - } - // outputs need resolving if (m_have_output) m_output.resolve(); @@ -3309,17 +3304,10 @@ layout_view::item::item( int index = env.get_attribute_int(itemnode, "index", -1); if (index != -1) m_screen = screen_device_iterator(env.machine().root_device()).byindex(index); - m_input_mask = env.get_attribute_int(itemnode, "inputmask", 0); - for (u32 mask = m_input_mask; (mask != 0) && (~mask & 1); mask >>= 1) m_input_shift++; - m_input_raw = env.get_attribute_int(itemnode, "inputraw", 0) == 1; + for (u32 mask = m_input_mask; (mask != 0) && (~mask & 1); mask >>= 1) + m_input_shift++; if (m_have_output && m_element) m_output = m_element->default_state(); - env.parse_bounds(itemnode.get_child("bounds"), m_rawbounds); - render_bounds_transform(m_rawbounds, trans); - if (m_rawbounds.x0 > m_rawbounds.x1) - std::swap(m_rawbounds.x0, m_rawbounds.x1); - if (m_rawbounds.y0 > m_rawbounds.y1) - std::swap(m_rawbounds.y0, m_rawbounds.y1); // sanity checks if (strcmp(itemnode.get_name(), "screen") == 0) @@ -3340,9 +3328,6 @@ layout_view::item::item( { throw layout_syntax_error(util::string_format("item of type %s require an element tag", itemnode.get_name())); } - - if (has_input()) - m_input_port = env.device().ioport(m_input_tag.c_str()); } @@ -3382,17 +3367,17 @@ int layout_view::item::state() const else if (!m_input_tag.empty()) { // if configured to an input, fetch the input value - if (m_input_port) + if (m_input_raw) { - if (m_input_raw) - { + if (m_input_port) return (m_input_port->read() & m_input_mask) >> m_input_shift; - } - else + } + else + { + if (m_input_field) { - ioport_field const *const field = m_input_port->field(m_input_mask); - if (field) - return ((m_input_port->read() ^ field->defvalue()) & m_input_mask) ? 1 : 0; + assert(m_input_port); + return ((m_input_port->read() ^ m_input_field->defvalue()) & m_input_mask) ? 1 : 0; } } } @@ -3405,16 +3390,99 @@ int layout_view::item::state() const // resolve_tags - resolve tags, if any are set //--------------------------------------------- - void layout_view::item::resolve_tags() { - if (has_input()) + if (!m_input_tag.empty()) { m_input_port = m_element->machine().root_device().ioport(m_input_tag.c_str()); + if (m_input_port) + m_input_field = m_input_port->field(m_input_mask); } } +//--------------------------------------------- +// find_element - find element definition +//--------------------------------------------- + +layout_element *layout_view::item::find_element(environment &env, util::xml::data_node const &itemnode, element_map &elemmap) +{ + char const *const name(env.get_attribute_string(itemnode, !strcmp(itemnode.get_name(), "element") ? "ref" : "element", nullptr)); + if (!name) + return nullptr; + + // search the list of elements for a match, error if not found + element_map::iterator const found(elemmap.find(name)); + if (elemmap.end() != found) + return &found->second; + else + throw layout_syntax_error(util::string_format("unable to find element %s", name)); +} + + +//--------------------------------------------- +// make_bounds - get transformed bounds +//--------------------------------------------- + +render_bounds layout_view::item::make_bounds( + environment &env, + util::xml::data_node const &itemnode, + layout_group::transform const &trans) +{ + render_bounds bounds; + env.parse_bounds(itemnode.get_child("bounds"), bounds); + render_bounds_transform(bounds, trans); + if (bounds.x0 > bounds.x1) + std::swap(bounds.x0, bounds.x1); + if (bounds.y0 > bounds.y1) + std::swap(bounds.y0, bounds.y1); + return bounds; +} + + +//--------------------------------------------- +// make_input_tag - get absolute input tag +//--------------------------------------------- + +std::string layout_view::item::make_input_tag(environment &env, util::xml::data_node const &itemnode) +{ + char const *tag(env.get_attribute_string(itemnode, "inputtag", nullptr)); + return tag ? env.device().subtag(tag) : std::string(); +} + + +//--------------------------------------------- +// get_blend_mode - explicit or implicit blend +//--------------------------------------------- + +int layout_view::item::get_blend_mode(environment &env, util::xml::data_node const &itemnode) +{ + // see if there's a blend mode attribute + char const *const mode(env.get_attribute_string(itemnode, "blend", nullptr)); + if (mode) + { + if (!strcmp(mode, "none")) + return BLENDMODE_NONE; + else if (!strcmp(mode, "alpha")) + return BLENDMODE_ALPHA; + else if (!strcmp(mode, "multiply")) + return BLENDMODE_RGB_MULTIPLY; + else if (!strcmp(mode, "add")) + return BLENDMODE_ADD; + else + throw layout_syntax_error(util::string_format("unknown blend mode %s", mode)); + } + + // fall back to implicit blend mode based on element type + if (!strcmp(itemnode.get_name(), "screen")) + return BLENDMODE_ADD; + else if (!strcmp(itemnode.get_name(), "overlay")) + return BLENDMODE_RGB_MULTIPLY; + else + return BLENDMODE_ALPHA; +} + + //************************************************************************** // LAYOUT FILE diff --git a/src/emu/uiinput.cpp b/src/emu/uiinput.cpp index 18fee890eec..78cc662022a 100644 --- a/src/emu/uiinput.cpp +++ b/src/emu/uiinput.cpp @@ -33,18 +33,18 @@ enum //------------------------------------------------- ui_input_manager::ui_input_manager(running_machine &machine) - : m_machine(machine), - m_current_mouse_target(nullptr), - m_current_mouse_down(false), - m_current_mouse_field(nullptr), - m_events_start(0), - m_events_end(0) + : m_machine(machine) + , m_current_mouse_target(nullptr) + , m_current_mouse_down(false) + , m_current_mouse_field(nullptr) + , m_events_start(0) + , m_events_end(0) { - /* create the private data */ + // create the private data m_current_mouse_x = -1; m_current_mouse_y = -1; - /* add a frame callback to poll inputs */ + // add a frame callback to poll inputs machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&ui_input_manager::frame_update, this)); } @@ -95,7 +95,7 @@ void ui_input_manager::frame_update() bool ui_input_manager::push_event(ui_event evt) { - /* some pre-processing (this is an icky place to do this stuff!) */ + // some pre-processing (this is an icky place to do this stuff!) switch (evt.event_type) { case ui_event::MOUSE_MOVE: @@ -126,7 +126,7 @@ bool ui_input_manager::push_event(ui_event evt) break; } - /* is the queue filled up? */ + // is the queue filled up? if ((m_events_end + 1) % ARRAY_LENGTH(m_events) == m_events_start) return false; diff --git a/src/emu/video.cpp b/src/emu/video.cpp index f967ef78935..8732fa9307e 100644 --- a/src/emu/video.cpp +++ b/src/emu/video.cpp @@ -152,11 +152,6 @@ video_manager::video_manager(running_machine &machine) } m_snap_target = machine.render().target_alloc(*root, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); - m_snap_target->set_backdrops_enabled(false); - m_snap_target->set_overlays_enabled(false); - m_snap_target->set_bezels_enabled(false); - m_snap_target->set_cpanels_enabled(false); - m_snap_target->set_marquees_enabled(false); m_snap_target->set_screen_overlay_enabled(false); m_snap_target->set_zoom_to_screen(false); } diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 3024e9cc20b..b786eaeb5c8 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -1925,9 +1925,6 @@ void lua_engine::initialize() * target.max_update_rate - * target.view - current target layout view * target.orientation - current target orientation - * target.backdrops - enable backdrops - * target.bezels - enable bezels - * target.marquees - enable marquees * target.screen_overlay - enable overlays * target.zoom - enable zoom */ @@ -1947,10 +1944,6 @@ void lua_engine::initialize() "max_update_rate", sol::property(&render_target::max_update_rate, &render_target::set_max_update_rate), "view", sol::property(&render_target::view, &render_target::set_view), "orientation", sol::property(&render_target::orientation, &render_target::set_orientation), - "backdrops", sol::property(&render_target::backdrops_enabled, &render_target::set_backdrops_enabled), - "overlays", sol::property(&render_target::overlays_enabled, &render_target::set_overlays_enabled), - "bezels", sol::property(&render_target::bezels_enabled, &render_target::set_bezels_enabled), - "marquees", sol::property(&render_target::marquees_enabled, &render_target::set_marquees_enabled), "screen_overlay", sol::property(&render_target::screen_overlay_enabled, &render_target::set_screen_overlay_enabled), "zoom", sol::property(&render_target::zoom_to_screen, &render_target::set_zoom_to_screen)); diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp index a9134935f7a..f9cff799c1f 100644 --- a/src/frontend/mame/ui/submenu.cpp +++ b/src/frontend/mame/ui/submenu.cpp @@ -55,11 +55,6 @@ std::vector const submenu::advanced_options = { { submenu::option_type::HEAD, __("Artwork Options") }, { submenu::option_type::EMU, __("Artwork Crop"), OPTION_ARTWORK_CROP }, - { submenu::option_type::EMU, __("Use Backdrops"), OPTION_USE_BACKDROPS }, - { submenu::option_type::EMU, __("Use Overlays"), OPTION_USE_OVERLAYS }, - { submenu::option_type::EMU, __("Use Bezels"), OPTION_USE_BEZELS }, - { submenu::option_type::EMU, __("Use Control Panels"), OPTION_USE_CPANELS }, - { submenu::option_type::EMU, __("Use Marquees"), OPTION_USE_MARQUEES }, { submenu::option_type::HEAD, __("State/Playback Options") }, { submenu::option_type::EMU, __("Automatic save/restore"), OPTION_AUTOSAVE }, diff --git a/src/frontend/mame/ui/videoopt.cpp b/src/frontend/mame/ui/videoopt.cpp index 7ee243ec4e2..baa0a265cb6 100644 --- a/src/frontend/mame/ui/videoopt.cpp +++ b/src/frontend/mame/ui/videoopt.cpp @@ -71,86 +71,46 @@ void menu_video_options::handle() { bool changed = false; - /* process the menu */ + // process the menu const event *menu_event = process(0); if (menu_event != nullptr && menu_event->itemref != nullptr) { switch ((uintptr_t)menu_event->itemref) { - /* rotate adds rotation depending on the direction */ - case VIDEO_ITEM_ROTATE: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + // rotate adds rotation depending on the direction + case VIDEO_ITEM_ROTATE: + if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + { + int delta = (menu_event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90; + target->set_orientation(orientation_add(delta, target->orientation())); + if (target->is_ui_target()) { - int delta = (menu_event->iptkey == IPT_UI_LEFT) ? ROT270 : ROT90; - target->set_orientation(orientation_add(delta, target->orientation())); - if (target->is_ui_target()) - { - render_container::user_settings settings; - container().get_user_settings(settings); - settings.m_orientation = orientation_add(delta ^ ROT180, settings.m_orientation); - container().set_user_settings(settings); - } - changed = true; + render_container::user_settings settings; + container().get_user_settings(settings); + settings.m_orientation = orientation_add(delta ^ ROT180, settings.m_orientation); + container().set_user_settings(settings); } - break; + changed = true; + } + break; - /* layer config bitmasks handle left/right keys the same (toggle) */ - case VIDEO_ITEM_BACKDROPS: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_backdrops_enabled(!target->backdrops_enabled()); - changed = true; - } - break; + // layer config bitmasks handle left/right keys the same (toggle) + case VIDEO_ITEM_ZOOM: + if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) + { + target->set_zoom_to_screen(!target->zoom_to_screen()); + changed = true; + } + break; - case VIDEO_ITEM_OVERLAYS: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_overlays_enabled(!target->overlays_enabled()); - changed = true; - } - break; - - case VIDEO_ITEM_BEZELS: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_bezels_enabled(!target->bezels_enabled()); - changed = true; - } - break; - - case VIDEO_ITEM_CPANELS: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_cpanels_enabled(!target->cpanels_enabled()); - changed = true; - } - break; - - case VIDEO_ITEM_MARQUEES: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_marquees_enabled(!target->marquees_enabled()); - changed = true; - } - break; - - case VIDEO_ITEM_ZOOM: - if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT) - { - target->set_zoom_to_screen(!target->zoom_to_screen()); - changed = true; - } - break; - - /* anything else is a view item */ - default: - if (menu_event->iptkey == IPT_UI_SELECT && (int)(uintptr_t)menu_event->itemref >= VIDEO_ITEM_VIEW) - { - target->set_view((uintptr_t)menu_event->itemref - VIDEO_ITEM_VIEW); - changed = true; - } - break; + // anything else is a view item + default: + if (menu_event->iptkey == IPT_UI_SELECT && (int)(uintptr_t)menu_event->itemref >= VIDEO_ITEM_VIEW) + { + target->set_view((uintptr_t)menu_event->itemref - VIDEO_ITEM_VIEW); + changed = true; + } + break; } } @@ -174,56 +134,35 @@ void menu_video_options::populate(float &customtop, float &custombottom) { const char *subtext = ""; std::string tempstring; - int viewnum; int enabled; - /* add items for each view */ - for (viewnum = 0; ; viewnum++) + // add items for each view + for (int viewnum = 0; ; viewnum++) { const char *name = target->view_name(viewnum); if (name == nullptr) break; - /* create a string for the item, replacing underscores with spaces */ + // create a string for the item, replacing underscores with spaces tempstring.assign(name); strreplace(tempstring, "_", " "); item_append(tempstring, "", 0, (void *)(uintptr_t)(VIDEO_ITEM_VIEW + viewnum)); } - /* add a separator */ + // add a separator item_append(menu_item_type::SEPARATOR); - /* add a rotate item */ + // add a rotate item switch (target->orientation()) { - case ROT0: subtext = "None"; break; - case ROT90: subtext = "CW 90" UTF8_DEGREES; break; - case ROT180: subtext = "180" UTF8_DEGREES; break; - case ROT270: subtext = "CCW 90" UTF8_DEGREES; break; + case ROT0: subtext = "None"; break; + case ROT90: subtext = "CW 90" UTF8_DEGREES; break; + case ROT180: subtext = "180" UTF8_DEGREES; break; + case ROT270: subtext = "CCW 90" UTF8_DEGREES; break; } item_append(_("Rotate"), subtext, FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_ROTATE); - /* backdrop item */ - enabled = target->backdrops_enabled(); - item_append(_("Backdrops"), enabled ? _("Enabled") : _("Disabled"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_BACKDROPS); - - /* overlay item */ - enabled = target->overlays_enabled(); - item_append(_("Overlays"), enabled ? _("Enabled") : _("Disabled"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_OVERLAYS); - - /* bezel item */ - enabled = target->bezels_enabled(); - item_append(_("Bezels"), enabled ? _("Enabled") : _("Disabled"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_BEZELS); - - /* cpanel item */ - enabled = target->cpanels_enabled(); - item_append(_("CPanels"), enabled ? _("Enabled") : _("Disabled"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_CPANELS); - - /* marquee item */ - enabled = target->marquees_enabled(); - item_append(_("Marquees"), enabled ? _("Enabled") : _("Disabled"), enabled ? FLAG_LEFT_ARROW : FLAG_RIGHT_ARROW, (void *)VIDEO_ITEM_MARQUEES); - - /* cropping */ + // cropping enabled = target->zoom_to_screen(); item_append(_("View"), enabled ? _("Cropped") : _("Full"), enabled ? FLAG_RIGHT_ARROW : FLAG_LEFT_ARROW, (void *)VIDEO_ITEM_ZOOM); } diff --git a/src/frontend/mame/ui/videoopt.h b/src/frontend/mame/ui/videoopt.h index d920fe55837..c26281ffd1b 100644 --- a/src/frontend/mame/ui/videoopt.h +++ b/src/frontend/mame/ui/videoopt.h @@ -36,11 +36,6 @@ public: private: enum { VIDEO_ITEM_ROTATE = 0x80000000, - VIDEO_ITEM_BACKDROPS, - VIDEO_ITEM_OVERLAYS, - VIDEO_ITEM_BEZELS, - VIDEO_ITEM_CPANELS, - VIDEO_ITEM_MARQUEES, VIDEO_ITEM_ZOOM, VIDEO_ITEM_VIEW }; diff --git a/src/mame/layout/intlc44.lay b/src/mame/layout/intlc44.lay index 1484429952e..7c39187edc4 100644 --- a/src/mame/layout/intlc44.lay +++ b/src/mame/layout/intlc44.lay @@ -155,74 +155,74 @@ Intel INTELLEC® 4/MOD 4 layout - + - + - - - - - - + + + + + + - + - - - - - - + + + + + + - - - - + + + + - + - + - + - - - - + + + + - - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - - + + + + - - - - + + + + - - - - - + + + + + @@ -230,173 +230,173 @@ Intel INTELLEC® 4/MOD 4 layout - + - + - + - - + + - - + + - - + + - + - + - - + + - - + + - + - + - - + + - - + + - - + + - + - + - - + + - - + + - + - + - - + + - + - + - - + + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - - + + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + diff --git a/src/mame/layout/intlc440.lay b/src/mame/layout/intlc440.lay index 8a826178238..c77cfdfae07 100644 --- a/src/mame/layout/intlc440.lay +++ b/src/mame/layout/intlc440.lay @@ -151,73 +151,73 @@ Intel INTELLEC® 4/MOD 40 layout - + - + - - - - - - + + + + + + - + - - - - - - + + + + + + - - - - + + + + - + - + - + - - - - + + + + - - - - - + + + + + - - + + - - - - - - - + + + + + + + - - - + + + - - - - + + + + - - - - - + + + + + @@ -225,173 +225,173 @@ Intel INTELLEC® 4/MOD 40 layout - + - + - + - - + + - - + + - - + + - + - + - - + + - - + + - + - + - - + + - - + + - - + + - + - + - - + + - - + + - + - + - - + + - + - + - - + + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - + - + - + - + - - + + - + - + - - + + - - + + - - + + - - + + - + - + - - + + - + - + - - + + - + - + - - + + - + diff --git a/src/mame/layout/whousetc.lay b/src/mame/layout/whousetc.lay index b76e6901214..d45669bf73c 100644 --- a/src/mame/layout/whousetc.lay +++ b/src/mame/layout/whousetc.lay @@ -813,16 +813,16 @@ Westinghouse Test Console Serial #5 layout - + - + - + - + @@ -836,9 +836,9 @@ Westinghouse Test Console Serial #5 layout - + - +