summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/render.h
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2019-07-06 00:23:20 +1000
committer Vas Crabb <vas@vastheman.com>2019-07-06 00:23:20 +1000
commitc38a3395e94e38a37cf6b8efdf9f49a5c9d415df (patch)
tree8ad5f6ee37953b4d19241ce31d11da23a712cc3e /src/emu/render.h
parent7ee50ffec7afabd20a027f89e47f11b116301071 (diff)
Make layout format more flexible:
* There is no longer a concept of "layers" - there are only screens and elements. * Elements are now instantiated with <element ref="..."> * Screens and elements can have explicit blending mode specified with blend="..." * Default blending mode for screens is "add" and default for other elements is "alpha" * Other supported modes are "none" and "multiply" * This removes the options to enable/disable layers individually - use views instead * Legacy layouts can still be loaded, and support won't be removed for at least a year The current artwork model is over-stretched. It's based on a Space Invaders cabinet model, and isn't applicable to a lot of the systems MAME emulates now. The fact that MAME has to switch to an "alternate" mode to deal with games like Golly! Ghost! without requiring pre-matted bitmaps shows that the Space Invaders model wasn't even adequate for general arcade use. It shows in that for a lot of the systems that heavily depend on artwork, people just seem to randomly choose layers for elements until they get something that works. Also, the fact that MAME will switch to an alternate (Golly! Ghost!) mode depending on the combination of elements is a trap for people learning to make artwork. There are cases that the current approach of implying the blending mode from the layer doesn't work with. Examples include LEDs behind diffusers (requires additive blending for layout elements), and mutliple stacked LCD panels (requires RGB multiplication for screens). For configurability, it's now a lot easier to make multiple views using groups. For example, if you want to make it possible to hide the control panel section of your layout, you can put the control panel elements in a group and create views with and without it. I will gradually migrate the internal artwork to use the new approach. I have an XSLT stylesheet that helps with this, but I'm not comfortable adding it because it isn't a complete solution and it still requires manul steps. I wanted to get the re-worked pointer handling done sooner so I could push them both at the same time, but unfortunately various things have prevented me from progressing as quickly as I wanted to. Sorry guys, that stuff's going to have to wait.
Diffstat (limited to 'src/emu/render.h')
-rw-r--r--src/emu/render.h106
1 files changed, 35 insertions, 71 deletions
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(); }