diff options
Diffstat (limited to 'src/emu/rendlay.h')
-rw-r--r-- | src/emu/rendlay.h | 672 |
1 files changed, 660 insertions, 12 deletions
diff --git a/src/emu/rendlay.h b/src/emu/rendlay.h index d1de55f73ef..23431e7fd92 100644 --- a/src/emu/rendlay.h +++ b/src/emu/rendlay.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*************************************************************************** rendlay.h @@ -13,23 +13,671 @@ #pragma once +#include "rendertypes.h" +#include "screen.h" + +#include "interface/uievents.h" + +#include <array> +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <string_view> +#include <tuple> +#include <unordered_map> +#include <vector> + //************************************************************************** -// GLOBAL VARIABLES +// TYPE DEFINITIONS //************************************************************************** -// no screens layouts -extern const internal_layout layout_noscreens; // for screenless systems +namespace emu::render::detail { + +struct bounds_step +{ + render_bounds get() const { return bounds; } + + int state; + render_bounds bounds; + render_bounds delta; +}; +using bounds_vector = std::vector<bounds_step>; + +struct color_step +{ + render_color get() const { return color; } + + int state; + render_color color; + render_color delta; +}; +using color_vector = std::vector<color_step>; + + +class layout_environment; +class view_environment; + +} // namespace emu::render::detail + + +/// \brief A description of a piece of visible artwork +/// +/// Most view items (except for those referencing screens) have exactly +/// one layout_element which describes the contents of the item. +/// Elements are separate from items because they can be re-used +/// multiple times within a layout. Even though an element can contain +/// a number of components, they are drawn as a single textured quad. +class layout_element +{ +public: + using environment = emu::render::detail::layout_environment; + using draw_delegate = delegate<void (int, bitmap_argb32 &)>; + + // construction/destruction + layout_element(environment &env, util::xml::data_node const &elemnode); + virtual ~layout_element(); + + // getters + running_machine &machine() const { return m_machine; } + int default_state() const { return m_defstate; } + render_texture *state_texture(int state); + + // set handlers + void set_draw_callback(draw_delegate &&handler); + + // operations + void preload(); + void invalidate() { m_invalidated = true; } + void prepare(); + +private: + /// \brief A drawing component within a layout element + /// + /// Each #layout_element contains one or more components. Each + /// component can describe either an image or a rectangle/disk + /// primitive. A component can also have a state mask and value + /// for controlling visibility. If the state of the item + /// instantiating the element matches the component's state value + /// for the bits that are set in the mask, the component is visible. + class component + { + public: + typedef std::unique_ptr<component> ptr; + + // construction/destruction + component(environment &env, util::xml::data_node const &compnode); + virtual ~component() = default; + + // setup + void normalize_bounds(float xoffs, float yoffs, float xscale, float yscale); + + // getters + int statemask() const { return m_statemask; } + int stateval() const { return m_stateval; } + std::pair<int, bool> statewrap() const; + render_bounds overall_bounds() const; + render_bounds bounds(int state) const; + render_color color(int state) const; + + // operations + virtual void preload(running_machine &machine); + virtual void draw(running_machine &machine, bitmap_argb32 &dest, int state); + + protected: + // helpers + virtual int maxstate() const; + virtual void draw_aligned(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state); + + // drawing helpers + static void draw_text(render_font &font, bitmap_argb32 &dest, const rectangle &bounds, std::string_view str, int align, const render_color &color); + static void draw_segment_horizontal_caps(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, int caps, rgb_t color); + static void draw_segment_horizontal(bitmap_argb32 &dest, int minx, int maxx, int midy, int width, rgb_t color); + static void draw_segment_vertical_caps(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, int caps, rgb_t color); + static void draw_segment_vertical(bitmap_argb32 &dest, int miny, int maxy, int midx, int width, rgb_t color); + static void draw_segment_diagonal_1(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color); + static void draw_segment_diagonal_2(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color); + static void draw_segment_decimal(bitmap_argb32 &dest, int midx, int midy, int width, rgb_t color); + static void draw_segment_comma(bitmap_argb32 &dest, int minx, int maxx, int miny, int maxy, int width, rgb_t color); + static void apply_skew(bitmap_argb32 &dest, int skewwidth); + + private: + using bounds_vector = emu::render::detail::bounds_vector; + using color_vector = emu::render::detail::color_vector; + + // internal state + int const m_statemask; // bits of state used to control visibility + int const m_stateval; // masked state value to make component visible + bounds_vector m_bounds; // bounds of the element + color_vector m_color; // color of the element + }; + + // component implementations + class image_component; + class rect_component; + class disk_component; + class text_component; + class led7seg_component; + class led14seg_component; + class led16seg_component; + class led14segsc_component; + class led16segsc_component; + class simplecounter_component; + class reel_component; + + // a texture encapsulates a texture for a given element in a given state + class texture + { + public: + texture(); + texture(texture const &that) = delete; + texture(texture &&that); + + ~texture(); + + texture &operator=(texture const &that) = delete; + texture &operator=(texture &&that); + + layout_element * m_element; // pointer back to the element + render_texture * m_texture; // texture for this state + int m_state; // associated state number + }; + + typedef component::ptr (*make_component_func)(environment &env, util::xml::data_node const &compnode); + typedef std::map<std::string, make_component_func> make_component_map; + + // internal helpers + static void element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, const rectangle &sbounds, void *param); + template <typename T> static component::ptr make_component(environment &env, util::xml::data_node const &compnode); + + static make_component_map const s_make_component; // maps component XML names to creator functions + + // internal state + running_machine & m_machine; // reference to the owning machine + std::vector<component::ptr> m_complist; // list of components + int const m_defstate; // default state of this element + int m_statemask; // mask to apply to state values + bool m_foldhigh; // whether we need to fold state values above the mask range + std::vector<texture> m_elemtex; // array of element textures used for managing the scaled bitmaps + draw_delegate m_draw; // draw delegate (called after components are drawn) + bool m_invalidated; // force redrawing on next frame if set +}; + + +/// \brief A reusable group of items +/// +/// Views expand/flatten groups into their component elements applying +/// an optional coordinate transform. This is useful for duplicating +/// the same sublayout in multiple views, or grouping related items to +/// simplify overall view arrangement. Groups only exist while parsing +/// a layout file - no information about element grouping is preserved +/// after the views have been built. +class layout_group +{ +public: + using environment = emu::render::detail::layout_environment; + using group_map = std::unordered_map<std::string, layout_group>; + using transform = std::array<std::array<float, 3>, 3>; + + layout_group(util::xml::data_node const &groupnode); + ~layout_group(); + + util::xml::data_node const &get_groupnode() const { return m_groupnode; } + + transform make_transform(int orientation, render_bounds const &dest) const; + transform make_transform(int orientation, transform const &trans) const; + transform make_transform(int orientation, render_bounds const &dest, transform const &trans) const; + + void set_bounds_unresolved(); + void resolve_bounds(environment &env, group_map &groupmap); + +private: + void resolve_bounds(environment &env, group_map &groupmap, std::vector<layout_group const *> &seen); + void resolve_bounds( + environment &env, + util::xml::data_node const &parentnode, + group_map &groupmap, + std::vector<layout_group const *> &seen, + bool &empty, + bool vistoggle, + bool repeat, + bool init); + + util::xml::data_node const & m_groupnode; + render_bounds m_bounds; + bool m_bounds_resolved; +}; + + +/// \brief A single item in a view +/// +/// Each view has a list of item structures describing the visual +/// elements to draw, where they are located, additional blending modes, +/// and bindings for inputs and outputs. +class layout_view_item +{ + friend class layout_view; + +public: + using view_environment = emu::render::detail::view_environment; + using element_map = std::unordered_map<std::string, layout_element>; + using state_delegate = delegate<int ()>; + using bounds_delegate = delegate<render_bounds ()>; + using color_delegate = delegate<render_color ()>; + using scroll_size_delegate = delegate<float ()>; + using scroll_pos_delegate = delegate<float ()>; + + // construction/destruction + layout_view_item( + view_environment &env, + util::xml::data_node const &itemnode, + element_map &elemmap, + int orientation, + layout_group::transform const &trans, + render_color const &color); + ~layout_view_item(); + + // getters + std::string const &id() const { return m_id; } + layout_element *element() const { return m_element; } + screen_device *screen() const { return m_screen; } + bool bounds_animated() const { return m_bounds.size() > 1U; } + bool color_animated() const { return m_color.size() > 1U; } + render_bounds bounds() const { return m_get_bounds(); } + render_color color() const { return m_get_color(); } + bool scroll_wrap_x() const { return m_scrollwrapx; } + bool scroll_wrap_y() const { return m_scrollwrapy; } + float scroll_size_x() const { return m_get_scroll_size_x(); } + float scroll_size_y() const { return m_get_scroll_size_y(); } + float scroll_pos_x() const { return m_get_scroll_pos_x(); } + float scroll_pos_y() const { return m_get_scroll_pos_y(); } + int blend_mode() const { return m_blend_mode; } + u32 visibility_mask() const { return m_visibility_mask; } + int orientation() const { return m_orientation; } + render_container *screen_container() const { return m_screen ? &m_screen->container() : nullptr; } + + // interactivity + bool has_input() const { return bool(m_input_port); } + std::pair<ioport_port *, ioport_value> input_tag_and_mask() const { return std::make_pair(m_input_port, m_input_mask); } + bool clickthrough() const { return m_clickthrough; } + + // fetch state based on configured source + int element_state() const { return m_get_elem_state(); } + int animation_state() const { return m_get_anim_state(); } + + // set state + void set_state(int state) { m_elem_state = state; } + void set_scroll_size_x(float size) { m_scrollsizex = std::clamp(size, 0.01f, 1.0f); } + void set_scroll_size_y(float size) { m_scrollsizey = std::clamp(size, 0.01f, 1.0f); } + void set_scroll_pos_x(float pos) { m_scrollposx = pos; } + void set_scroll_pos_y(float pos) { m_scrollposy = pos; } + + // set handlers + void set_element_state_callback(state_delegate &&handler); + void set_animation_state_callback(state_delegate &&handler); + void set_bounds_callback(bounds_delegate &&handler); + void set_color_callback(color_delegate &&handler); + void set_scroll_size_x_callback(scroll_size_delegate &&handler); + void set_scroll_size_y_callback(scroll_size_delegate &&handler); + void set_scroll_pos_x_callback(scroll_pos_delegate &&handler); + void set_scroll_pos_y_callback(scroll_pos_delegate &&handler); + + // resolve tags, if any + void resolve_tags(); + +private: + using bounds_vector = emu::render::detail::bounds_vector; + using color_vector = emu::render::detail::color_vector; + + state_delegate default_get_elem_state(); + state_delegate default_get_anim_state(); + bounds_delegate default_get_bounds(); + color_delegate default_get_color(); + scroll_size_delegate default_get_scroll_size_x(); + scroll_size_delegate default_get_scroll_size_y(); + scroll_pos_delegate default_get_scroll_pos_x(); + scroll_pos_delegate default_get_scroll_pos_y(); + int get_state() const; + int get_output() const; + int get_input_raw() const; + int get_input_field_cached() const; + int get_input_field_conditional() const; + int get_anim_output() const; + int get_anim_input() const; + float get_scrollsizex() const; + float get_scrollsizey() const; + float get_scrollposx() const; + float get_scrollposy() const; + template <bool Wrap> float get_scrollx_output() const; + template <bool Wrap> float get_scrolly_output() const; + template <bool Wrap> float get_scrollx_input() const; + template <bool Wrap> float get_scrolly_input() const; + render_bounds get_interpolated_bounds() const; + render_color get_interpolated_color() const; + + static layout_element *find_element(view_environment &env, util::xml::data_node const &itemnode, element_map &elemmap); + static bounds_vector make_bounds(view_environment &env, util::xml::data_node const &itemnode, layout_group::transform const &trans); + static color_vector make_color(view_environment &env, util::xml::data_node const &itemnode, render_color const &mult); + + // internal state + layout_element *const m_element; // pointer to the associated element (non-screens only) + state_delegate m_get_elem_state; // resolved element state function + state_delegate m_get_anim_state; // resolved animation state function + bounds_delegate m_get_bounds; // resolved bounds function + color_delegate m_get_color; // resolved color function + scroll_size_delegate m_get_scroll_size_x; // resolved horizontal scroll window size function + scroll_size_delegate m_get_scroll_size_y; // resolved vertical scroll window size function + scroll_pos_delegate m_get_scroll_pos_x; // resolved horizontal scroll position function + scroll_pos_delegate m_get_scroll_pos_y; // resolved vertical scroll position function + output_finder<> m_output; // associated output + output_finder<> m_animoutput; // associated output for animation if different + output_finder<> m_scrollxoutput; // associated output for horizontal scroll position + output_finder<> m_scrollyoutput; // associated output for vertical scroll position + ioport_port * m_animinput_port; // input port used for animation + ioport_port * m_scrollxinput_port; // input port used for horizontal scrolling + ioport_port * m_scrollyinput_port; // input port used for vertical scrolling + bool const m_scrollwrapx; // whether horizontal scrolling works like a loop + bool const m_scrollwrapy; // whether vertical scrolling works like a loop + int m_elem_state; // element state used in absence of bindings + float m_scrollsizex; // horizontal scroll window size used in absence of bindings + float m_scrollsizey; // vertical scroll window size used in absence of bindings + float m_scrollposx; // horizontal scroll position used in absence of bindings + float m_scrollposy; // vertical scroll position used in absence of bindings + ioport_value const m_animmask; // mask for animation state + ioport_value const m_scrollxmask; // mask for horizontal scroll position + ioport_value const m_scrollymask; // mask for vertical scroll position + ioport_value const m_scrollxmin; // minimum value for horizontal scroll position + ioport_value const m_scrollymin; // minimum value for vertical scroll position + ioport_value const m_scrollxmax; // maximum value for horizontal scroll position + ioport_value const m_scrollymax; // maximum value for vertical scroll position + u8 const m_animshift; // shift for animation state + u8 const m_scrollxshift; // shift for horizontal scroll position + u8 const m_scrollyshift; // shift for vertical scroll position + 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 const m_input_shift; // input mask rightshift for raw (trailing 0s) + bool m_clickthrough; // should click pass through to lower elements + screen_device * m_screen; // pointer to screen + int const m_orientation; // orientation of this item + bounds_vector m_bounds; // bounds of the item + color_vector const m_color; // color of the item + int m_blend_mode; // blending mode to use when drawing + u32 m_visibility_mask; // combined mask of parent visibility groups + + // cold items + std::string const m_id; // optional unique item identifier + std::string const m_input_tag; // input tag of this item + std::string const m_animinput_tag; // tag of input port for animation state + std::string const m_scrollxinput_tag; // tag of input port for horizontal scroll position + std::string const m_scrollyinput_tag; // tag of input port for vertical scroll position + bounds_vector const m_rawbounds; // raw (original) bounds of the item + bool const m_have_output; // whether we actually have an output + bool const m_input_raw; // get raw data from input port + bool const m_have_animoutput; // whether we actually have an output for animation + bool const m_have_scrollxoutput; // whether we actually have an output for horizontal scroll + bool const m_have_scrollyoutput; // whether we actually have an output for vertical scroll + bool const m_has_clickthrough; // whether clickthrough was explicitly configured +}; + + +/// \brief A single view within a #layout_file +/// +/// The view is described using arbitrary coordinates that are scaled to +/// fit within the render target. Pixels within a view are assumed to +/// be square. +class layout_view +{ +public: + using layout_environment = emu::render::detail::layout_environment; + using view_environment = emu::render::detail::view_environment; + using element_map = layout_view_item::element_map; + using group_map = std::unordered_map<std::string, layout_group>; + using screen_ref_vector = std::vector<std::reference_wrapper<screen_device const>>; + using prepare_items_delegate = delegate<void ()>; + using preload_delegate = delegate<void ()>; + using recomputed_delegate = delegate<void ()>; + using pointer_updated_delegate = delegate<void (osd::ui_event_handler::pointer, u16, u16, float, float, u32, u32, u32, s16)>; + using pointer_left_delegate = delegate<void (osd::ui_event_handler::pointer, u16, u16, float, float, u32, s16)>; + using forget_pointers_delegate = delegate<void ()>; + + using item = layout_view_item; + using item_list = std::list<item>; + using item_ref_vector = std::vector<std::reference_wrapper<item> >; + + /// \brief A subset of items in a view that can be hidden or shown + /// + /// Visibility toggles allow the user to show or hide selected parts + /// of a view. + class visibility_toggle + { + public: + // construction/destruction/assignment + visibility_toggle(std::string &&name, u32 mask); + visibility_toggle(visibility_toggle const &) = default; + visibility_toggle(visibility_toggle &&) = default; + visibility_toggle &operator=(visibility_toggle const &) = default; + visibility_toggle &operator=(visibility_toggle &&) = default; + + // getters + std::string const &name() const { return m_name; } + u32 mask() const { return m_mask; } + + private: + std::string m_name; // display name for the toggle + u32 m_mask; // toggle combination to show + }; + using visibility_toggle_vector = std::vector<visibility_toggle>; + + /// \brief An edge of an item in a view + class edge + { + public: + // construction/destruction + constexpr edge(unsigned index, float position, bool trailing) + : m_index(index) + , m_position(position) + , m_trailing(trailing) + { + } + + // getters + constexpr unsigned index() const { return m_index; } + constexpr float position() const { return m_position; } + constexpr bool trailing() const { return m_trailing; } + + // comparison + constexpr bool operator<(edge const &that) const + { + return std::make_tuple(m_position, m_trailing, m_index) < std::make_tuple(that.m_position, that.m_trailing, that.m_index); + } + + private: + unsigned m_index; // index of item in some collection + float m_position; // position of edge on given axis + bool m_trailing; // false for edge at lower position on axis + }; + using edge_vector = std::vector<edge>; + + // construction/destruction + layout_view( + layout_environment &env, + util::xml::data_node const &viewnode, + element_map &elemmap, + group_map &groupmap); + ~layout_view(); + + // getters + item *get_item(std::string const &id); + item_list &items() { return m_items; } + bool has_screen(screen_device const &screen) const; + const std::string &name() const { return m_name; } + const std::string &unqualified_name() const { return m_unqualified_name; } + size_t visible_screen_count() const { return m_screens.size(); } + float effective_aspect() const { return m_effaspect; } + const render_bounds &bounds() const { return m_bounds; } + bool has_visible_screen(screen_device const &screen) const; + const item_ref_vector &visible_items() const { return m_visible_items; } + const item_ref_vector &visible_screen_items() const { return m_screen_items; } + const item_ref_vector &interactive_items() const { return m_interactive_items; } + const edge_vector &interactive_edges_x() const { return m_interactive_edges_x; } + const edge_vector &interactive_edges_y() const { return m_interactive_edges_y; } + const screen_ref_vector &visible_screens() const { return m_screens; } + const visibility_toggle_vector &visibility_toggles() const { return m_vistoggles; } + u32 default_visibility_mask() const { return m_defvismask; } + bool has_art() const { return m_has_art; } + bool show_pointers() const { return m_show_ptr; } + bool hide_inactive_pointers() const { return m_ptr_time_out; } + + // setters + void set_show_pointers(bool value) noexcept; + void set_hide_inactive_pointers(bool value) noexcept ATTR_COLD; + + // set handlers + void set_prepare_items_callback(prepare_items_delegate &&handler) ATTR_COLD; + void set_preload_callback(preload_delegate &&handler) ATTR_COLD; + void set_recomputed_callback(recomputed_delegate &&handler) ATTR_COLD; + void set_pointer_updated_callback(pointer_updated_delegate &&handler) ATTR_COLD; + void set_pointer_left_callback(pointer_left_delegate &&handler) ATTR_COLD; + void set_pointer_aborted_callback(pointer_left_delegate &&handler) ATTR_COLD; + void set_forget_pointers_callback(forget_pointers_delegate &&handler) ATTR_COLD; + + // operations + void prepare_items(); + void recompute(u32 visibility_mask, bool zoom_to_screens); + void preload(); + + // resolve tags, if any + void resolve_tags(); + + // pointer input + void pointer_updated(osd::ui_event_handler::pointer type, u16 ptrid, u16 device, float x, float y, u32 buttons, u32 pressed, u32 released, s16 clicks) + { + if (!m_pointer_updated.isnull()) + m_pointer_updated(type, ptrid, device, x, y, buttons, pressed, released, clicks); + } + void pointer_left(osd::ui_event_handler::pointer type, u16 ptrid, u16 device, float x, float y, u32 released, s16 clicks) + { + if (!m_pointer_left.isnull()) + m_pointer_left(type, ptrid, device, x, y, released, clicks); + } + void pointer_aborted(osd::ui_event_handler::pointer type, u16 ptrid, u16 device, float x, float y, u32 released, s16 clicks) + { + if (!m_pointer_aborted.isnull()) + m_pointer_aborted(type, ptrid, device, x, y, released, clicks); + } + void forget_pointers() + { + if (!m_forget_pointers.isnull()) + m_forget_pointers(); + } + +private: + struct layer_lists; + + using item_id_map = std::unordered_map< + std::reference_wrapper<std::string const>, + item &, + std::hash<std::string>, + std::equal_to<std::string> >; + + // add items, recursing for groups + void add_items( + layer_lists &layers, + view_environment &env, + util::xml::data_node const &parentnode, + element_map &elemmap, + group_map &groupmap, + int orientation, + layout_group::transform const &trans, + render_color const &color, + bool root, + bool repeat, + bool init); + + static std::string make_name(layout_environment &env, util::xml::data_node const &viewnode); + + // internal state + float m_effaspect; // X/Y of the layout in current configuration + render_bounds m_bounds; // computed bounds of the view in current configuration + item_list m_items; // list of layout items + item_ref_vector m_visible_items; // all visible items + item_ref_vector m_screen_items; // visible items that represent screens to draw + item_ref_vector m_interactive_items;// visible items that can accept pointer input + edge_vector m_interactive_edges_x; + edge_vector m_interactive_edges_y; + screen_ref_vector m_screens; // list screens visible in current configuration + + // handlers + prepare_items_delegate m_prepare_items; // prepare items for adding to render container + preload_delegate m_preload; // additional actions when visible items change + recomputed_delegate m_recomputed; // additional actions on resizing/visibility change + pointer_updated_delegate m_pointer_updated; // pointer state updated + pointer_left_delegate m_pointer_left; // pointer left normally + pointer_left_delegate m_pointer_aborted; // pointer left abnormally + forget_pointers_delegate m_forget_pointers; // stop processing pointer input + + // cold items + std::string m_name; // display name for the view + std::string m_unqualified_name; // the name exactly as specified in the layout file + element_map & m_elemmap; // reference to shared elements + item_id_map m_items_by_id; // items with non-empty ID indexed by ID + visibility_toggle_vector m_vistoggles; // collections of items that can be shown/hidden + render_bounds m_expbounds; // explicit bounds of the view + u32 m_defvismask; // default visibility mask + bool m_has_art; // true if the layout contains non-screen elements + bool m_show_ptr; // whether pointers should be displayed + bool m_ptr_time_out; // whether pointers should be hidden after inactivity + s8 m_exp_show_ptr; // explicitly configured pointer visibility +}; + + +/// \brief Layout description file +/// +/// Comprises a list of elements and a list of views. The elements are +/// reusable items that the views reference. +class layout_file +{ +public: + using element_map = std::unordered_map<std::string, layout_element>; + using group_map = std::unordered_map<std::string, layout_group>; + using view_list = std::list<layout_view>; + using resolve_tags_delegate = delegate<void ()>; + + // construction/destruction + layout_file(device_t &device, util::xml::data_node const &rootnode, char const *searchpath, char const *dirname); + ~layout_file(); + + // getters + device_t &device() const { return m_device; } + element_map &elements() { return m_elemmap; } + element_map const &elements() const { return m_elemmap; } + view_list &views() { return m_viewlist; } + view_list const &views() const { return m_viewlist; } + + // resolve tags, if any + void resolve_tags(); + + // set handlers + void set_resolve_tags_callback(resolve_tags_delegate &&handler); -// dual screen layouts -extern const internal_layout layout_dualhsxs; // dual 4:3 screens side-by-side -extern const internal_layout layout_dualhovu; // dual 4:3 screens above and below -extern const internal_layout layout_dualhuov; // dual 4:3 screens below and above +private: + using environment = emu::render::detail::layout_environment; -// triple screen layouts -extern const internal_layout layout_triphsxs; // triple 4:3 screens side-by-side + // add elements and parameters + void add_elements( + environment &env, + util::xml::data_node const &parentnode, + group_map &groupmap, + bool repeat, + bool init); -// quad screen layouts -extern const internal_layout layout_quadhsxs; // quad 4:3 screens side-by-side + // internal state + device_t & m_device; // device that caused file to be loaded + element_map m_elemmap; // list of shared layout elements + view_list m_viewlist; // list of views + resolve_tags_delegate m_resolve_tags; // additional actions after resolving tags +}; #endif // MAME_EMU_RENDLAY_H |