summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/emuopts.cpp5
-rw-r--r--src/emu/emuopts.h10
-rw-r--r--src/emu/render.cpp230
-rw-r--r--src/emu/render.h106
-rw-r--r--src/emu/rendlay.cpp296
-rw-r--r--src/emu/uiinput.cpp20
-rw-r--r--src/emu/video.cpp5
7 files changed, 301 insertions, 371 deletions
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<item_layer, int> 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<item_layer, int> 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<item_layer, int> 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 <typename T> 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);
-
- // 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);
- }
- }
+ // 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;
+
+ // 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))
- {
- // iterate over items in the layer
- for (layout_view::item &item : m_curview->items(layer))
- {
- bool checkit;
+ 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);
+ // 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();
+ // 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;
- }
- }
+ // 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;
}
}
+
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); }
};
@@ -602,25 +587,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<item>;
@@ -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();
@@ -2977,25 +3010,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)
- {
- 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;
- }
-
- // 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 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 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);
- }
- }
+ // 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,13 +3390,96 @@ 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;
}
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);
}