diff options
author | 2017-07-29 15:17:14 +1000 | |
---|---|---|
committer | 2017-07-29 15:17:14 +1000 | |
commit | 3a5c5d15c717e13c5bea47614096defd50db1146 (patch) | |
tree | 486c1e4e28d523a9baf5054520df8d9068ede5ec | |
parent | 9cea5e1518bcd59181cd3428d67b3d4cfa06fa98 (diff) |
Add support for layout item groups, replace simple_list with more
appropriate containers, remove misleading const qualifiers, reduce
repeated XML walking.
(nw) Groups aren't parameterised, so they aren't as useful as they could
be (yes, it's on my TODO list). However, it's already useful for
putting a common set of elements in multiple views, potentially at
different locations/scales. See intlc44.lay and intlc440.lay for
examples of the level of copypasta this can eliminate. Be aware that
groups with explicit bounds don't clip thair content, it's only used for
calucating the transform matrix.
-rw-r--r-- | scripts/build/complay.py | 89 | ||||
-rw-r--r-- | src/emu/render.cpp | 69 | ||||
-rw-r--r-- | src/emu/render.h | 155 | ||||
-rw-r--r-- | src/emu/rendlay.cpp | 424 | ||||
-rw-r--r-- | src/emu/rendutil.h | 40 | ||||
-rw-r--r-- | src/mame/layout/intlc44.lay | 386 | ||||
-rw-r--r-- | src/mame/layout/intlc440.lay | 385 |
7 files changed, 547 insertions, 1001 deletions
diff --git a/scripts/build/complay.py b/scripts/build/complay.py index 4332a952c27..af5003581e6 100644 --- a/scripts/build/complay.py +++ b/scripts/build/complay.py @@ -101,8 +101,10 @@ class LayoutChecker(Minifyer): self.locator = None self.errors = 0 self.elements = { } + self.groups = { } self.views = { } - self.referenced = { } + self.referenced_elements = { } + self.referenced_groups = { } self.have_bounds = [ ] self.have_color = [ ] @@ -163,6 +165,38 @@ class LayoutChecker(Minifyer): except: self.handleError('Element color attribute %s "%s" is not numeric' % (name, attrs[name])) + def checkGroupViewItem(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() + self.in_object = True + self.have_bounds.append(False) + elif 'screen' == name: + if 'index' in attrs: + try: + index = long(attrs['index']) + if 0 > index: + self.handleError('Element screen attribute index "%s" is negative' % (attrs['index'], )) + except: + self.handleError('Element screen attribute index "%s" is not an integer' % (attrs['index'], )) + self.in_object = True + self.have_bounds.append(False) + elif 'group' == name: + if 'ref' not in attrs: + self.handleError('Element group missing attribute ref') + elif attrs['ref'] not in self.referenced_groups: + self.referenced_groups[attrs['ref']] = self.formatLocation() + self.in_object = True + self.have_bounds.append(False) + elif 'bounds' == name: + self.checkBounds(attrs) + self.ignored_depth = 1 + else: + self.handleError('Encountered unexpected element %s' % (name, )) + self.ignored_depth = 1 + def setDocumentLocator(self, locator): self.locator = locator super(LayoutChecker, self).setDocumentLocator(locator) @@ -170,6 +204,7 @@ class LayoutChecker(Minifyer): def startDocument(self): self.in_layout = False self.in_element = False + self.in_group = False self.in_view = False self.in_shape = False self.in_object = False @@ -179,8 +214,10 @@ class LayoutChecker(Minifyer): def endDocument(self): self.locator = None self.elements.clear() + self.groups.clear() self.views.clear() - self.referenced.clear() + self.referenced_elements.clear() + self.referenced_groups.clear() del self.have_bounds[:] del self.have_color[:] super(LayoutChecker, self).endDocument() @@ -238,29 +275,8 @@ class LayoutChecker(Minifyer): self.have_color.append(False) else: self.ignored_depth = 1 - elif self.in_view: - 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: - self.referenced[attrs['element']] = self.formatLocation() - self.in_object = True - self.have_bounds.append(False) - elif 'screen' == name: - if 'index' in attrs: - try: - index = long(attrs['index']) - if 0 > index: - self.handleError('Element screen attribute index "%s" is negative' % (attrs['index'], )) - except: - self.handleError('Element screen attribute index "%s" is not an integer' % (attrs['index'], )) - self.in_object = True - self.have_bounds.append(False) - elif 'bounds' == name: - self.checkBounds(attrs) - self.ignored_depth = 1 - else: - self.ignored_depth = 1 + elif self.in_group or self.in_view: + self.checkGroupViewItem(name, attrs) elif 'element' == name: if 'name' not in attrs: self.handleError('Element element missing attribute name') @@ -270,6 +286,16 @@ class LayoutChecker(Minifyer): else: self.elements[attrs['name']] = self.formatLocation() self.in_element = True + elif 'group' == name: + if 'name' not in attrs: + self.handleError('Element group missing attribute name') + else: + if attrs['name'] in self.groups: + self.handleError('Element group has duplicate name (previous %s)' % (self.groups[attrs['name']], )) + else: + self.groups[attrs['name']] = self.formatLocation() + self.in_group = True + self.have_bounds.append(False) elif 'view' == name: if 'name' not in attrs: self.handleError('Element view missing attribute name') @@ -280,7 +306,10 @@ class LayoutChecker(Minifyer): self.views[attrs['name']] = self.formatLocation() self.in_view = True self.have_bounds.append(False) + elif 'script' == name: + self.ignored_depth = 1 else: + self.handleError('Encountered unexpected element %s' % (name, )) self.ignored_depth = 1 super(LayoutChecker, self).startElement(name, attrs) @@ -296,13 +325,19 @@ class LayoutChecker(Minifyer): self.have_color.pop() elif self.in_element: self.in_element = False + elif self.in_group: + self.in_group = False + self.have_bounds.pop() elif self.in_view: self.in_view = False self.have_bounds.pop() elif self.in_layout: - for element in self.referenced: + for element in self.referenced_elements: if element not in self.elements: - self.handleError('Element "%s" not found (first referenced at %s)' % (element, self.referenced[element])) + self.handleError('Element "%s" not found (first referenced at %s)' % (element, self.referenced_elements[element])) + for group in self.referenced_groups: + if group not in self.groups: + self.handleError('Group "%s" not found (first referenced at %s)' % (group, self.referenced_groups[group])) self.in_layout = False super(LayoutChecker, self).endElement(name) diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 4531b2adc32..31994f19595 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -166,7 +166,7 @@ inline void normalize_bounds(render_bounds &bounds) // appropriate layer index and blendmode //------------------------------------------------- -inline item_layer get_layer_and_blendmode(const layout_view &view, int index, int &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) @@ -174,7 +174,7 @@ inline item_layer get_layer_and_blendmode(const layout_view &view, int index, in // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha) const int *layer_order = layer_order_standard; - if (view.items(ITEM_LAYER_BACKDROP).count() > 1 && view.items(ITEM_LAYER_OVERLAY).empty()) + if (view.items(ITEM_LAYER_BACKDROP).size() > 1 && view.items(ITEM_LAYER_OVERLAY).empty()) layer_order = layer_order_alternate; // select the layer @@ -1068,7 +1068,7 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu // scan for a matching view name size_t viewlen = strlen(viewname); for (view = view_by_index(viewindex = 0); view != nullptr; view = view_by_index(++viewindex)) - if (core_strnicmp(view->name(), viewname, viewlen) == 0) + if (core_strnicmp(view->name().c_str(), viewname, viewlen) == 0) break; } @@ -1132,8 +1132,8 @@ int render_target::configured_view(const char *viewname, int targetindex, int nu const char *render_target::view_name(int viewindex) { - layout_view *view = view_by_index(viewindex); - return (view != nullptr) ? view->name() : nullptr; + layout_view const *const view = view_by_index(viewindex); + return view ? view->name().c_str() : nullptr; } @@ -1274,18 +1274,18 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight) return; } - if (m_curview == nullptr) + if (!m_curview) 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) - + { // iterate over items in the layer for (layout_view::item &curitem : m_curview->items(layer)) - if (curitem.screen() != nullptr) + if (curitem.screen()) { // use a hard-coded default visible area for vector screens - screen_device *screen = curitem.screen(); + 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(); @@ -1312,6 +1312,7 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight) maxyscale = std::max(yscale, maxyscale); screens_considered++; } + } // if there were no screens considered, pick a nominal default if (screens_considered == 0) @@ -1401,7 +1402,7 @@ render_primitive_list &render_target::get_primitives() else { render_primitive *prim = list.alloc(render_primitive::QUAD); - set_render_bounds_xy(&prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); + set_render_bounds_xy(prim->bounds, 0.0f, 0.0f, (float)m_width, (float)m_height); prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 1.0f, 1.0f, 1.0f); prim->texture.base = nullptr; @@ -1411,7 +1412,7 @@ render_primitive_list &render_target::get_primitives() if (m_width > 1 && m_height > 1) { prim = list.alloc(render_primitive::QUAD); - set_render_bounds_xy(&prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1)); + set_render_bounds_xy(prim->bounds, 1.0f, 1.0f, (float)(m_width - 1), (float)(m_height - 1)); prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); prim->texture.base = nullptr; @@ -1613,32 +1614,34 @@ void render_target::load_layout_files(const internal_layout *layoutfile, bool si load_layout_file(nullptr, &layout_vertical); else load_layout_file(nullptr, &layout_horizont); - assert_always(m_filelist.count() > 0, "Couldn't parse default layout??"); + if (m_filelist.empty()) + throw emu_fatalerror("Couldn't parse default layout??"); } if (!have_default) { if (screens == 0) { load_layout_file(nullptr, &layout_noscreens); - assert_always(m_filelist.count() > 0, "Couldn't parse default layout??"); + if (m_filelist.empty()) + throw emu_fatalerror("Couldn't parse default layout??"); } - else - if (screens == 2) + else if (screens == 2) { load_layout_file(nullptr, &layout_dualhsxs); - assert_always(m_filelist.count() > 0, "Couldn't parse default layout??"); + if (m_filelist.empty()) + throw emu_fatalerror("Couldn't parse default layout??"); } - else - if (screens == 3) + else if (screens == 3) { load_layout_file(nullptr, &layout_triphsxs); - assert_always(m_filelist.count() > 0, "Couldn't parse default layout??"); + if (m_filelist.empty()) + throw emu_fatalerror("Couldn't parse default layout??"); } - else - if (screens == 4) + else if (screens == 4) { load_layout_file(nullptr, &layout_quadhsxs); - assert_always(m_filelist.count() > 0, "Couldn't parse default layout??"); + if (m_filelist.empty()) + throw emu_fatalerror("Couldn't parse default layout??"); } } } @@ -1739,7 +1742,7 @@ bool render_target::load_layout_file(const char *dirname, const char *filename) bool result = true; try { - m_filelist.append(*global_alloc(layout_file(m_manager.machine(), *rootnode, dirname))); + m_filelist.emplace_back(m_manager.machine(), *rootnode, dirname); } catch (emu_fatalerror &err) { @@ -1773,7 +1776,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const cliprect.y0 = xform.yoffs; cliprect.x1 = xform.xoffs + xform.xscale; cliprect.y1 = xform.yoffs + xform.yscale; - sect_render_bounds(&cliprect, &m_bounds); + sect_render_bounds(cliprect, m_bounds); float root_xoffs = root_xform.xoffs + fabsf(root_xform.xscale - xform.xscale) * 0.5f; float root_yoffs = root_xform.yoffs + fabsf(root_xform.yscale - xform.yscale) * 0.5f; @@ -1783,7 +1786,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const root_cliprect.y0 = root_yoffs; root_cliprect.x1 = root_xoffs + root_xform.xscale; root_cliprect.y1 = root_yoffs + root_xform.yscale; - sect_render_bounds(&root_cliprect, &m_bounds); + sect_render_bounds(root_cliprect, m_bounds); // compute the container transform object_transform container_xform; @@ -2013,7 +2016,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const // allocate a primitive render_primitive *prim = list.alloc(render_primitive::QUAD); - set_render_bounds_wh(&prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale); + set_render_bounds_wh(prim->bounds, xform.xoffs, xform.yoffs, xform.xscale, xform.yscale); prim->full_bounds = prim->bounds; prim->color = container_xform.color; width = render_round_nearest(prim->bounds.x1) - render_round_nearest(prim->bounds.x0); @@ -2063,7 +2066,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob // compute the bounds s32 width = render_round_nearest(xform.xscale); s32 height = render_round_nearest(xform.yscale); - set_render_bounds_wh(&prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height); + set_render_bounds_wh(prim->bounds, render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), (float) width, (float) height); prim->full_bounds = prim->bounds; if (xform.orientation & ORIENTATION_SWAP_XY) std::swap(width, height); @@ -2080,7 +2083,7 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob cliprect.y0 = render_round_nearest(xform.yoffs); cliprect.x1 = render_round_nearest(xform.xoffs + xform.xscale); cliprect.y1 = render_round_nearest(xform.yoffs + xform.yscale); - sect_render_bounds(&cliprect, &m_bounds); + sect_render_bounds(cliprect, m_bounds); // determine UV coordinates and apply clipping prim->texcoords = oriented_texcoords[xform.orientation]; @@ -2177,7 +2180,7 @@ bool render_target::map_point_internal(s32 target_x, s32 target_y, render_contai // view, or nullptr if it doesn't exist //------------------------------------------------- -layout_view *render_target::view_by_index(int index) const +layout_view *render_target::view_by_index(int index) { // scan the list of views within each layout, skipping those that don't apply for (layout_file &file : m_filelist) @@ -2200,8 +2203,8 @@ int render_target::view_index(layout_view &targetview) const int index = 0; // scan the list of views within each layout, skipping those that don't apply - for (layout_file &file : m_filelist) - for (layout_view &view : file.views()) + for (layout_file const &file : m_filelist) + for (layout_view const &view : file.views()) if (!(m_flags & RENDER_CREATE_NO_ART) || !view.has_art()) { if (&targetview == &view) @@ -2301,7 +2304,7 @@ bool render_target::config_save(util::xml::data_node &targetnode) // output the view if (m_curview != m_base_view) { - targetnode.set_attribute("view", m_curview->name()); + targetnode.set_attribute("view", m_curview->name().c_str()); changed = true; } @@ -2518,7 +2521,7 @@ void render_target::add_clear_extents(render_primitive_list &list) if (x1 - x0 > 0) { render_primitive *prim = list.alloc(render_primitive::QUAD); - set_render_bounds_xy(&prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); + set_render_bounds_xy(prim->bounds, (float)x0, (float)y0, (float)x1, (float)y1); prim->full_bounds = prim->bounds; set_render_color(&prim->color, 1.0f, 0.0f, 0.0f, 0.0f); prim->texture.base = nullptr; diff --git a/src/emu/render.h b/src/emu/render.h index 30453397355..8498abe5cfc 100644 --- a/src/emu/render.h +++ b/src/emu/render.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*************************************************************************** render.h @@ -624,9 +624,14 @@ DECLARE_ENUM_INCDEC_OPERATORS(item_layer) //************************************************************************** -// ======================> layout_element - -// a layout_element is a single named element, which may have multiple components +/// \brief A description of a piece of visible artwork +/// +/// Most view_items (except for those in the screen layer) 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 treated as if they were a single +/// bitmap. class layout_element { public: @@ -641,7 +646,13 @@ public: render_texture *state_texture(int state); private: - // a component represents an image, rectangle, or disk in an element + /// \brief An image, rectangle, or disk in an element + /// + /// Each layout_element contains one or more components. Each + /// component can describe either an image or a rectangle/disk + /// primitive. Each component also has a "state" associated with it, + /// which controls whether or not the component is visible (if the + /// owning item has the same state, it is visible). class component { public: @@ -735,29 +746,73 @@ private: }; -// ======================> layout_view +/// \brief A reusable group of elements +/// +/// Views expand/flatten groups into their component elements applying +/// an optional coordinate transform. This is mainly useful duplicating +/// the same sublayout in multiple views. It would be more useful +/// within a view if it could be parameterised. Groups only exist while +/// parsing a layout file - no information about element grouping is +/// preserved. +class layout_group +{ +public: + typedef std::unordered_map<std::string, layout_group> group_map; + + layout_group(running_machine &machine, util::xml::data_node const &groupnode); + ~layout_group(); + + util::xml::data_node const &get_groupnode() const { return m_groupnode; } -// a layout_view encapsulates a named list of items + render_bounds make_transform(render_bounds const &dest) const; + render_bounds make_transform(render_bounds const &dest, render_bounds const &transform) const; + + void resolve_bounds(group_map &groupmap); + +private: + void resolve_bounds(group_map &groupmap, std::vector<layout_group const *> &seen); + + running_machine & m_machine; + util::xml::data_node const & m_groupnode; + render_bounds m_bounds; + bool m_bounds_resolved; +}; + + +/// \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 { - friend class simple_list<layout_view>; - public: using element_map = std::unordered_map<std::string, layout_element>; - - // an item is a single backdrop, screen, overlay, bezel, cpanel, or marquee item + using group_map = std::unordered_map<std::string, layout_group>; + + /// \brief A single backdrop/screen/overlay/bezel/cpanel/marquee item + /// + /// Each view has four lists of view_items, one for each "layer." + /// Each view item is specified using floating point coordinates in + /// arbitrary units, and is assumed to have square pixels. Each + /// view item can control its orientation independently. Each item + /// can also have an optional name, and can be set at runtime into + /// different "states", which control how the embedded elements are + /// displayed. class item { friend class layout_view; - friend class simple_list<item>; public: // construction/destruction - item(running_machine &machine, util::xml::data_node const &itemnode, element_map &elemmap); - virtual ~item(); + item( + running_machine &machine, + util::xml::data_node const &itemnode, + element_map &elemmap, + render_bounds const &transform); + ~item(); // getters - item *next() const { return m_next; } layout_element *element() const { return m_element; } screen_device *screen() { return m_screen; } const render_bounds &bounds() const { return m_bounds; } @@ -775,7 +830,6 @@ public: private: // internal state - item * m_next; // link to next item layout_element * m_element; // pointer to the associated element (non-screens only) std::string m_output_name; // name of this item std::string m_input_tag; // input tag of this item @@ -787,22 +841,26 @@ public: render_bounds m_rawbounds; // raw (original) bounds of the item render_color m_color; // color of the item }; + using item_list = std::list<item>; // construction/destruction - layout_view(running_machine &machine, util::xml::data_node const &viewnode, element_map &elemmap); - virtual ~layout_view(); + layout_view( + running_machine &machine, + util::xml::data_node const &viewnode, + element_map &elemmap, + group_map const &groupmap); + ~layout_view(); // getters - layout_view *next() const { return m_next; } - const simple_list<item> &items(item_layer layer) const; - const char *name() const { return m_name.c_str(); } + item_list &items(item_layer layer); + 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.count() + m_overlay_list.count() + m_bezel_list.count() + m_cpanel_list.count() + m_marquee_list.count() != 0); } + 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(); } float effective_aspect(render_layer_config config) const { return (config.zoom_to_screen() && m_screens.count() != 0) ? m_scraspect : m_aspect; } // operations @@ -812,8 +870,15 @@ public: void resolve_tags(); private: + // add items, recursing for groups + void add_items( + running_machine &machine, + util::xml::data_node const &parentnode, + element_map &elemmap, + group_map const &groupmap, + render_bounds const &transform); + // internal state - layout_view * m_next; // pointer to next layout in the list std::string m_name; // name of the layout float m_aspect; // X/Y of the layout float m_scraspect; // X/Y of the screen areas @@ -822,41 +887,39 @@ private: 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? - simple_list<item> m_backdrop_list; // list of backdrop items - simple_list<item> m_screen_list; // list of screen items - simple_list<item> m_overlay_list; // list of overlay items - simple_list<item> m_bezel_list; // list of bezel items - simple_list<item> m_cpanel_list; // list of marquee items - simple_list<item> m_marquee_list; // list of marquee items - - static const simple_list<item> s_null_list; + 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 }; -// ======================> layout_file - -// a layout_file consists of a list of elements and a list of views +/// \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 { - friend class simple_list<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>; // construction/destruction - layout_file(running_machine &machine, util::xml::data_node const &rootnode, const char *dirname); - virtual ~layout_file(); + layout_file(running_machine &machine, util::xml::data_node const &rootnode, char const *dirname); + ~layout_file(); // getters - layout_file *next() const { return m_next; } - const element_map &elements() const { return m_elemmap; } - const simple_list<layout_view> &views() const { return m_viewlist; } + element_map const &elements() const { return m_elemmap; } + view_list &views() { return m_viewlist; } + view_list const &views() const { return m_viewlist; } private: // internal state - layout_file * m_next; // pointer to the next file in the list - element_map m_elemmap; // list of shared layout elements - simple_list<layout_view> m_viewlist; // list of views + element_map m_elemmap; // list of shared layout elements + view_list m_viewlist; // list of views }; // ======================> render_target @@ -961,7 +1024,7 @@ private: bool config_save(util::xml::data_node &targetnode); // view lookups - layout_view *view_by_index(int index) const; + layout_view *view_by_index(int index); int view_index(layout_view &view) const; // optimized clearing @@ -978,7 +1041,7 @@ private: render_target * m_next; // link to next target render_manager & m_manager; // reference to our owning manager layout_view * m_curview; // current view - simple_list<layout_file> m_filelist; // list of layout files + std::list<layout_file> m_filelist; // list of layout files u32 m_flags; // creation flags render_primitive_list m_primlist[NUM_PRIMLISTS]; // list of primitives int m_listindex; // index of next primlist to use diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp index c1cc8040f7e..6f30fc65585 100644 --- a/src/emu/rendlay.cpp +++ b/src/emu/rendlay.cpp @@ -1,52 +1,15 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Vas Crabb /*************************************************************************** rendlay.c Core rendering layout parser and manager. -**************************************************************************** - - Overview of objects: - - layout_file -- A layout_file comprises a list of elements and a - list of views. The elements are reusable items that the views - reference. - - layout_view -- A layout_view describes 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. - - view_item -- Each view has four lists of view_items, one for each - "layer." Each view item is specified using floating point - coordinates in arbitrary units, and is assumed to have square - pixels. Each view item can control its orientation independently. - Each item can also have an optional name, and can be set at - runtime into different "states", which control how the embedded - elements are displayed. - - layout_element -- A layout_element is a description of a piece of - visible artwork. Most view_items (except for those in the screen - layer) 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 treated - as if they were a single bitmap. - - element_component -- Each layout_element contains one or more - components. Each component can describe either an image or - a rectangle/disk primitive. Each component also has a "state" - associated with it, which controls whether or not the component - is visible (if the owning item has the same state, it is - visible). - ***************************************************************************/ -#include <ctype.h> - #include "emu.h" + #include "emuopts.h" #include "render.h" #include "rendfont.h" @@ -54,6 +17,10 @@ #include "rendutil.h" #include "xmlfile.h" +#include <ctype.h> +#include <sstream> +#include <type_traits> + /*************************************************************************** @@ -118,15 +85,10 @@ render_screen_list render_target::s_empty_screen_list; // of two integers using the Euclidean algorithm //------------------------------------------------- -inline int gcd(int a, int b) +template <typename M, typename N> +constexpr std::common_type_t<M, N> gcd(M a, N b) { - while (b != 0) - { - int t = b; - b = a % b; - a = t; - } - return a; + return b ? gcd(b, a % b) : a; } @@ -135,13 +97,14 @@ inline int gcd(int a, int b) // dividing out common factors //------------------------------------------------- -inline void reduce_fraction(int &num, int &den) +template <typename M, typename N> +inline void reduce_fraction(M &num, N &den) { // search the greatest common divisor - int div = gcd(num, den); + auto const div = gcd(num, den); // reduce the fraction if a common divisor has been found - if (div > 1) + if (div) { num /= div; den /= div; @@ -149,6 +112,20 @@ inline void reduce_fraction(int &num, int &den) } +//------------------------------------------------- +// render_bounds_transform - apply translation/ +// scaling +//------------------------------------------------- + +inline void render_bounds_transform(render_bounds &bounds, render_bounds const &transform) +{ + bounds.x0 = (bounds.x0 * transform.x1) + transform.x0; + bounds.y0 = (bounds.y0 * transform.y1) + transform.y0; + bounds.x1 = (bounds.x1 * transform.x1) + transform.x0; + bounds.y1 = (bounds.y1 * transform.y1) + transform.y0; +} + + //************************************************************************** // SHARED PARSING HELPERS @@ -432,7 +409,7 @@ layout_element::layout_element(running_machine &machine, util::xml::data_node co // parse components in order bool first = true; - render_bounds bounds = { 0 }; + render_bounds bounds = { 0.0, 0.0, 0.0, 0.0 }; for (util::xml::data_node const *compnode = elemnode.get_first_child(); compnode; compnode = compnode->get_next_sibling()) { make_component_map::const_iterator const make_func(s_make_component.find(compnode->get_name())); @@ -446,7 +423,7 @@ layout_element::layout_element(running_machine &machine, util::xml::data_node co if (first) bounds = newcomp.bounds(); else - union_render_bounds(&bounds, &newcomp.bounds()); + union_render_bounds(bounds, newcomp.bounds()); first = false; // determine the maximum state @@ -480,6 +457,146 @@ layout_element::~layout_element() } + +//************************************************************************** +// LAYOUT GROUP +//************************************************************************** + +//------------------------------------------------- +// layout_group - constructor +//------------------------------------------------- + +layout_group::layout_group(running_machine &machine, util::xml::data_node const &groupnode) + : m_machine(machine) + , m_groupnode(groupnode) + , m_bounds{ 0.0f, 0.0f, 0.0f, 0.0f } + , m_bounds_resolved(false) +{ +} + + +//------------------------------------------------- +// ~layout_group - destructor +//------------------------------------------------- + +layout_group::~layout_group() +{ +} + + +//------------------------------------------------- +// make_transform - create abbreviated transform +// matrix for given destination bounds +//------------------------------------------------- + +render_bounds layout_group::make_transform(render_bounds const &dest) const +{ + assert(m_bounds_resolved); + + return render_bounds{ + dest.x0 - (m_bounds.x0 * (dest.x1 - dest.x0) / (m_bounds.x1 - m_bounds.x0)), + dest.y0 - (m_bounds.y0 * (dest.y1 - dest.y0) / (m_bounds.y1 - m_bounds.y0)), + (dest.x1 - dest.x0) / (m_bounds.x1 - m_bounds.x0), + (dest.y1 - dest.y0) / (m_bounds.y1 - m_bounds.y0) }; +} + +render_bounds layout_group::make_transform(render_bounds const &dest, render_bounds const &transform) const +{ + render_bounds const next(make_transform(dest)); + return render_bounds{ + (transform.x0 * next.x1) + next.x0, + (transform.y0 * next.y1) + next.y0, + transform.x1 * next.x1, + transform.y1 * next.y1 }; +} + + +//------------------------------------------------- +// resolve_bounds - calculate bounds taking +// nested groups into consideration +//------------------------------------------------- + +void layout_group::resolve_bounds(group_map &groupmap) +{ + if (!m_bounds_resolved) + { + std::vector<layout_group const *> seen; + resolve_bounds(groupmap, seen); + } +} + +void layout_group::resolve_bounds(group_map &groupmap, std::vector<layout_group const *> &seen) +{ + if (seen.end() != std::find(seen.begin(), seen.end(), this)) + { + // a wild loop appears! + std::ostringstream path; + for (layout_group const *const group : seen) + path << ' ' << group->m_groupnode.get_name(); + path << ' ' << m_groupnode.get_name(); + throw emu_fatalerror("Recursively nested layout groups:%s", path.str().c_str()); + } + + seen.push_back(this); + if (!m_bounds_resolved) + { + util::xml::data_node const *const boundsnode(m_groupnode.get_child("bounds")); + if (boundsnode) + { + // use explicit bounds + parse_bounds(m_machine, boundsnode, m_bounds); + } + else + { + // otherwise build from items + for (util::xml::data_node const *itemnode = m_groupnode.get_first_child(); itemnode; itemnode = itemnode->get_next_sibling()) + { + if (!strcmp(itemnode->get_name(), "backdrop") || + !strcmp(itemnode->get_name(), "screen") || + !strcmp(itemnode->get_name(), "overlay") || + !strcmp(itemnode->get_name(), "bezel") || + !strcmp(itemnode->get_name(), "cpanel") || + !strcmp(itemnode->get_name(), "marquee")) + { + render_bounds itembounds; + parse_bounds(m_machine, itemnode->get_child("bounds"), itembounds); + union_render_bounds(m_bounds, itembounds); + } + else if (!strcmp(itemnode->get_name(), "group")) + { + char const *ref(xml_get_attribute_string_with_subst(m_machine, *itemnode, "ref", nullptr)); + if (!ref) + throw emu_fatalerror("Nested layout group must have a ref!"); + + group_map::iterator const found(groupmap.find(ref)); + if (groupmap.end() == found) + throw emu_fatalerror("Unable to find layout group %s", ref); + + found->second.resolve_bounds(groupmap, seen); + util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds")); + if (itemboundsnode) + { + render_bounds itembounds; + parse_bounds(m_machine, itemboundsnode, itembounds); + union_render_bounds(m_bounds, itembounds); + } + else + { + union_render_bounds(m_bounds, found->second.m_bounds); + } + } + else if (strcmp(itemnode->get_name(), "bounds")) + { + throw emu_fatalerror("Unknown group element: %s", itemnode->get_name()); + } + } + } + m_bounds_resolved = true; + } +} + + + //------------------------------------------------- // state_texture - return a pointer to a // render_texture for the given state, allocating @@ -2242,49 +2359,27 @@ void layout_element::component::apply_skew(bitmap_argb32 &dest, int skewwidth) // LAYOUT VIEW //************************************************************************** -const simple_list<layout_view::item> layout_view::s_null_list; - //------------------------------------------------- // layout_view - constructor //------------------------------------------------- -layout_view::layout_view(running_machine &machine, util::xml::data_node const &viewnode, element_map &elemmap) - : m_next(nullptr) +layout_view::layout_view( + running_machine &machine, + util::xml::data_node const &viewnode, + element_map &elemmap, + group_map const &groupmap) + : m_name(xml_get_attribute_string_with_subst(machine, viewnode, "name", "")) , m_aspect(1.0f) , m_scraspect(1.0f) { - // allocate a copy of the name - m_name = xml_get_attribute_string_with_subst(machine, viewnode, "name", ""); - // if we have a bounds item, load it util::xml::data_node const *const boundsnode = viewnode.get_child("bounds"); m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0; - if (boundsnode != nullptr) + if (boundsnode) parse_bounds(machine, boundsnode, m_expbounds); - // load backdrop items - for (util::xml::data_node const *itemnode = viewnode.get_child("backdrop"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("backdrop")) - m_backdrop_list.append(*global_alloc(item(machine, *itemnode, elemmap))); - - // load screen items - for (util::xml::data_node const *itemnode = viewnode.get_child("screen"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("screen")) - m_screen_list.append(*global_alloc(item(machine, *itemnode, elemmap))); - - // load overlay items - for (util::xml::data_node const *itemnode = viewnode.get_child("overlay"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("overlay")) - m_overlay_list.append(*global_alloc(item(machine, *itemnode, elemmap))); - - // load bezel items - for (util::xml::data_node const *itemnode = viewnode.get_child("bezel"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("bezel")) - m_bezel_list.append(*global_alloc(item(machine, *itemnode, elemmap))); - - // load cpanel items - for (util::xml::data_node const *itemnode = viewnode.get_child("cpanel"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("cpanel")) - m_cpanel_list.append(*global_alloc(item(machine, *itemnode, elemmap))); - - // load marquee items - for (util::xml::data_node const *itemnode = viewnode.get_child("marquee"); itemnode != nullptr; itemnode = itemnode->get_next_sibling("marquee")) - m_marquee_list.append(*global_alloc(item(machine, *itemnode, elemmap))); + // load items + add_items(machine, viewnode, elemmap, groupmap, render_bounds{ 0.0f, 0.0f, 1.0f, 1.0f }); // recompute the data for the view based on a default layer config recompute(render_layer_config()); @@ -2304,17 +2399,17 @@ layout_view::~layout_view() // items - return the appropriate list //------------------------------------------------- -const simple_list<layout_view::item> &layout_view::items(item_layer layer) const +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: return s_null_list; + 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? } } @@ -2355,16 +2450,16 @@ void layout_view::recompute(render_layer_config layerconfig) if (first) m_bounds = curitem.m_rawbounds; else - union_render_bounds(&m_bounds, &curitem.m_rawbounds); + union_render_bounds(m_bounds, curitem.m_rawbounds); first = false; // accumulate screen bounds - if (curitem.m_screen != nullptr) + if (curitem.m_screen) { if (scrfirst) m_scrbounds = curitem.m_rawbounds; else - union_render_bounds(&m_scrbounds, &curitem.m_rawbounds); + union_render_bounds(m_scrbounds, curitem.m_rawbounds); scrfirst = false; // accumulate the screens in use while we're scanning @@ -2420,9 +2515,9 @@ void layout_view::recompute(render_layer_config layerconfig) } -//----------------------------- +//------------------------------------------------- // resolve_tags - resolve tags -//----------------------------- +//------------------------------------------------- void layout_view::resolve_tags() { @@ -2436,6 +2531,72 @@ void layout_view::resolve_tags() } +//------------------------------------------------- +// add_items - add items, recursing for groups +//------------------------------------------------- + +void layout_view::add_items( + running_machine &machine, + util::xml::data_node const &parentnode, + element_map &elemmap, + group_map const &groupmap, + render_bounds const &transform) +{ + for (util::xml::data_node const *itemnode = parentnode.get_first_child(); itemnode; itemnode = itemnode->get_next_sibling()) + { + if (!strcmp(itemnode->get_name(), "backdrop")) + { + m_backdrop_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "screen")) + { + m_screen_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "overlay")) + { + m_overlay_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "bezel")) + { + m_bezel_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "cpanel")) + { + m_cpanel_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "marquee")) + { + m_marquee_list.emplace_back(machine, *itemnode, elemmap, transform); + } + else if (!strcmp(itemnode->get_name(), "group")) + { + char const *ref(xml_get_attribute_string_with_subst(machine, *itemnode, "ref", nullptr)); + if (!ref) + throw emu_fatalerror("Nested layout group must have a ref!"); + + group_map::const_iterator const found(groupmap.find(ref)); + if (groupmap.end() == found) + throw emu_fatalerror("Unable to find layout group %s", ref); + + render_bounds grouptrans(transform); + util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds")); + if (itemboundsnode) + { + render_bounds itembounds; + parse_bounds(machine, itemboundsnode, itembounds); + grouptrans = found->second.make_transform(itembounds, transform); + } + + add_items(machine, found->second.get_groupnode(), elemmap, groupmap, grouptrans); + } + else if (strcmp(itemnode->get_name(), "bounds")) + { + throw emu_fatalerror("Unknown view item: %s", itemnode->get_name()); + } + } +} + + //************************************************************************** // LAYOUT VIEW ITEM @@ -2445,20 +2606,19 @@ void layout_view::resolve_tags() // item - constructor //------------------------------------------------- -layout_view::item::item(running_machine &machine, util::xml::data_node const &itemnode, element_map &elemmap) - : m_next(nullptr) - , m_element(nullptr) +layout_view::item::item( + running_machine &machine, + util::xml::data_node const &itemnode, + element_map &elemmap, + render_bounds const &transform) + : m_element(nullptr) + , m_output_name(xml_get_attribute_string_with_subst(machine, itemnode, "name", "")) + , m_input_tag(xml_get_attribute_string_with_subst(machine, itemnode, "inputtag", "")) , m_input_port(nullptr) , m_input_mask(0) , m_screen(nullptr) , m_orientation(ROT0) { - // allocate a copy of the output name - m_output_name = xml_get_attribute_string_with_subst(machine, itemnode, "name", ""); - - // allocate a copy of the input tag - m_input_tag = xml_get_attribute_string_with_subst(machine, itemnode, "inputtag", ""); - // find the associated element char const *const name = xml_get_attribute_string_with_subst(machine, itemnode, "element", nullptr); if (name) @@ -2479,6 +2639,7 @@ layout_view::item::item(running_machine &machine, util::xml::data_node const &it if (m_output_name[0] != 0 && m_element != nullptr) machine.output().set_value(m_output_name.c_str(), m_element->default_state()); parse_bounds(machine, itemnode.get_child("bounds"), m_rawbounds); + render_bounds_transform(m_rawbounds, transform); parse_color(machine, itemnode.get_child("color"), m_color); parse_orientation(machine, itemnode.get_child("orientation"), m_orientation); @@ -2527,25 +2688,25 @@ render_container *layout_view::item::screen_container(running_machine &machine) int layout_view::item::state() const { - int state = 0; - - assert(m_element != nullptr); + assert(m_element); - // if configured to an output, fetch the output value - if (m_output_name[0] != 0) - state = m_element->machine().output().get_value(m_output_name.c_str()); - - // if configured to an input, fetch the input value - else if (m_input_tag[0] != 0) + if (!m_output_name.empty()) + { + // if configured to an output, fetch the output value + return m_element->machine().output().get_value(m_output_name.c_str()); + } + else if (!m_input_tag.empty()) { - if (m_input_port != nullptr) + // if configured to an input, fetch the input value + if (m_input_port) { - ioport_field *field = m_input_port->field(m_input_mask); - if (field != nullptr) - state = ((m_input_port->read() ^ field->defvalue()) & m_input_mask) ? 1 : 0; + 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; } } - return state; + + return 0; } @@ -2573,7 +2734,8 @@ void layout_view::item::resolve_tags() //------------------------------------------------- layout_file::layout_file(running_machine &machine, util::xml::data_node const &rootnode, const char *dirname) - : m_next(nullptr) + : m_elemmap() + , m_viewlist() { // find the layout node util::xml::data_node const *const mamelayoutnode = rootnode.get_child("mamelayout"); @@ -2583,16 +2745,30 @@ layout_file::layout_file(running_machine &machine, util::xml::data_node const &r // validate the config data version int const version = mamelayoutnode->get_attribute_int("version", 0); if (version != LAYOUT_VERSION) - throw emu_fatalerror("Invalid XML file: unsupported version"); + throw emu_fatalerror("Invalid layout XML file: unsupported version"); // parse all the elements for (util::xml::data_node const *elemnode = mamelayoutnode->get_child("element"); elemnode; elemnode = elemnode->get_next_sibling("element")) { char const *const name(xml_get_attribute_string_with_subst(machine, *elemnode, "name", nullptr)); if (!name) - throw emu_fatalerror("All layout elements must have a name!\n"); - m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(machine, *elemnode, dirname)); + throw emu_fatalerror("All layout elements must have a name!"); + if (!m_elemmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(machine, *elemnode, dirname)).second) + throw emu_fatalerror("Duplicate layout element name: %s", name); + } + + // parse all the groups + group_map groupmap; + for (util::xml::data_node const *groupnode = mamelayoutnode->get_child("group"); groupnode; groupnode = groupnode->get_next_sibling("group")) + { + char const *const name(xml_get_attribute_string_with_subst(machine, *groupnode, "name", nullptr)); + if (!name) + throw emu_fatalerror("All layout groups must have a name!"); + if (!groupmap.emplace(std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(machine, *groupnode)).second) + throw emu_fatalerror("Duplicate layout group name: %s", name); } + for (group_map::value_type &group : groupmap) + group.second.resolve_bounds(groupmap); // parse all the views for (util::xml::data_node const *viewnode = mamelayoutnode->get_child("view"); viewnode != nullptr; viewnode = viewnode->get_next_sibling("view")) @@ -2603,7 +2779,7 @@ layout_file::layout_file(running_machine &machine, util::xml::data_node const &r // if the emu_fatalerror is allowed to propagate, the entire layout is dropped so you can't select the useful view try { - m_viewlist.append(*global_alloc(layout_view(machine, *viewnode, m_elemmap))); + m_viewlist.emplace_back(machine, *viewnode, m_elemmap, groupmap); } catch (emu_fatalerror const &) { diff --git a/src/emu/rendutil.h b/src/emu/rendutil.h index ba74f8696ed..b84fc60f704 100644 --- a/src/emu/rendutil.h +++ b/src/emu/rendutil.h @@ -52,12 +52,12 @@ static inline float render_round_nearest(float f) bounds -------------------------------------------------*/ -static inline void set_render_bounds_xy(render_bounds *bounds, float x0, float y0, float x1, float y1) +static inline void set_render_bounds_xy(render_bounds &bounds, float x0, float y0, float x1, float y1) { - bounds->x0 = x0; - bounds->y0 = y0; - bounds->x1 = x1; - bounds->y1 = y1; + bounds.x0 = x0; + bounds.y0 = y0; + bounds.x1 = x1; + bounds.y1 = y1; } @@ -66,12 +66,12 @@ static inline void set_render_bounds_xy(render_bounds *bounds, float x0, float y bounds -------------------------------------------------*/ -static inline void set_render_bounds_wh(render_bounds *bounds, float x0, float y0, float width, float height) +static inline void set_render_bounds_wh(render_bounds &bounds, float x0, float y0, float width, float height) { - bounds->x0 = x0; - bounds->y0 = y0; - bounds->x1 = x0 + width; - bounds->y1 = y0 + height; + bounds.x0 = x0; + bounds.y0 = y0; + bounds.x1 = x0 + width; + bounds.y1 = y0 + height; } @@ -80,12 +80,12 @@ static inline void set_render_bounds_wh(render_bounds *bounds, float x0, float y of two render_bounds -------------------------------------------------*/ -static inline void sect_render_bounds(render_bounds *dest, const render_bounds *src) +static inline void sect_render_bounds(render_bounds &dest, const render_bounds &src) { - dest->x0 = (dest->x0 > src->x0) ? dest->x0 : src->x0; - dest->x1 = (dest->x1 < src->x1) ? dest->x1 : src->x1; - dest->y0 = (dest->y0 > src->y0) ? dest->y0 : src->y0; - dest->y1 = (dest->y1 < src->y1) ? dest->y1 : src->y1; + dest.x0 = (std::max)(dest.x0, src.x0); + dest.x1 = (std::min)(dest.x1, src.x1); + dest.y0 = (std::max)(dest.y0, src.y0); + dest.y1 = (std::min)(dest.y1, src.y1); } @@ -94,12 +94,12 @@ static inline void sect_render_bounds(render_bounds *dest, const render_bounds * render_bounds -------------------------------------------------*/ -static inline void union_render_bounds(render_bounds *dest, const render_bounds *src) +static inline void union_render_bounds(render_bounds &dest, const render_bounds &src) { - dest->x0 = (dest->x0 < src->x0) ? dest->x0 : src->x0; - dest->x1 = (dest->x1 > src->x1) ? dest->x1 : src->x1; - dest->y0 = (dest->y0 < src->y0) ? dest->y0 : src->y0; - dest->y1 = (dest->y1 > src->y1) ? dest->y1 : src->y1; + dest.x0 = (std::min)(dest.x0, src.x0); + dest.x1 = (std::max)(dest.x1, src.x1); + dest.y0 = (std::min)(dest.y0, src.y0); + dest.y1 = (std::max)(dest.y1, src.y1); } diff --git a/src/mame/layout/intlc44.lay b/src/mame/layout/intlc44.lay index ffbf6e5f005..19ea53437cf 100644 --- a/src/mame/layout/intlc44.lay +++ b/src/mame/layout/intlc44.lay @@ -160,7 +160,7 @@ Intel INTELLEC® 4/MOD 40 layout <text string="RESET CONTROL" align="1"><color red="1.0" green="1.0" blue="1.0" /></text> </element> - <view name="Terminal Below"> + <group name="panel"> <cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel> <cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel> @@ -536,385 +536,19 @@ Intel INTELLEC® 4/MOD 40 layout <cpanel element="switch" inputtag="MODE" inputmask="0x0008"> <bounds left="697" top="322" right="722" bottom="368" /> </cpanel> + </group> + <view name="Terminal Below"> + <group ref="panel"><bounds left="0" top="0" right="1000" bottom="400" /></group> <screen index="0"><bounds left="0" top="400" right="1000" bottom="1150" /></screen> </view> - <view name="Front Panel"> - <cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel> - - <cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel> - <cpanel element="label_a3"><bounds left="81" top="63" right="185" bottom="70" /></cpanel> - <cpanel element="label_a2"><bounds left="237" top="63" right="341" bottom="70" /></cpanel> - <cpanel element="label_a1"><bounds left="393" top="63" right="497" bottom="70" /></cpanel> - <cpanel element="label_11"><bounds left="81" top="71" right="92" bottom="78" /></cpanel> - <cpanel element="label_10"><bounds left="112" top="71" right="123" bottom="78" /></cpanel> - <cpanel element="label_9"><bounds left="143" top="71" right="154" bottom="78" /></cpanel> - <cpanel element="label_8"><bounds left="174" top="71" right="185" bottom="78" /></cpanel> - <cpanel element="label_7"><bounds left="237" top="71" right="248" bottom="78" /></cpanel> - <cpanel element="label_6"><bounds left="268" top="71" right="279" bottom="78" /></cpanel> - <cpanel element="label_5"><bounds left="299" top="71" right="310" bottom="78" /></cpanel> - <cpanel element="label_4"><bounds left="330" top="71" right="341" bottom="78" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="71" right="404" bottom="78" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="71" right="435" bottom="78" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="71" right="466" bottom="78" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="71" right="497" bottom="78" /></cpanel> - - <cpanel element="label_status"><bounds left="540" top="55" right="662" bottom="63" /></cpanel> - <cpanel element="label_search"><bounds left="561" top="63" right="610" bottom="70" /></cpanel> - <cpanel element="label_complete"><bounds left="561" top="71" right="610" bottom="78" /></cpanel> - <cpanel element="label_pointer"><bounds left="623" top="63" right="672" bottom="70" /></cpanel> - <cpanel element="label_valid"><bounds left="623" top="71" right="672" bottom="78" /></cpanel> - <cpanel element="label_cpu"><bounds left="611" top="71" right="626" bottom="78" /></cpanel> - - <cpanel element="label_instruction"><bounds left="72" top="104" right="350" bottom="112" /></cpanel> - <cpanel element="label_m1"><bounds left="81" top="112" right="185" bottom="119" /></cpanel> - <cpanel element="label_m2"><bounds left="237" top="112" right="341" bottom="119" /></cpanel> - <cpanel element="label_7"><bounds left="81" top="120" right="92" bottom="127" /></cpanel> - <cpanel element="label_6"><bounds left="112" top="120" right="123" bottom="127" /></cpanel> - <cpanel element="label_5"><bounds left="143" top="120" right="154" bottom="127" /></cpanel> - <cpanel element="label_4"><bounds left="174" top="120" right="185" bottom="127" /></cpanel> - <cpanel element="label_3"><bounds left="237" top="120" right="248" bottom="127" /></cpanel> - <cpanel element="label_2"><bounds left="268" top="120" right="279" bottom="127" /></cpanel> - <cpanel element="label_1"><bounds left="299" top="120" right="310" bottom="127" /></cpanel> - <cpanel element="label_0"><bounds left="330" top="120" right="341" bottom="127" /></cpanel> - - <cpanel element="label_active_bank"><bounds left="384" top="104" right="506" bottom="112" /></cpanel> - <cpanel element="label_cm_ram"><bounds left="393" top="112" right="497" bottom="119" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="120" right="404" bottom="127" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="120" right="435" bottom="127" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="120" right="466" bottom="127" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="120" right="497" bottom="127" /></cpanel> - - <cpanel element="label_mode"><bounds left="540" top="104" right="662" bottom="112" /></cpanel> - <cpanel element="label_mon"><bounds left="577" top="120" right="594" bottom="127" /></cpanel> - <cpanel element="label_ram"><bounds left="608" top="120" right="625" bottom="127" /></cpanel> - <cpanel element="label_prom"><bounds left="639" top="120" right="656" bottom="127" /></cpanel> - - <cpanel element="label_execution"><bounds left="72" top="153" right="350" bottom="161" /></cpanel> - <cpanel element="label_x2"><bounds left="81" top="161" right="185" bottom="168" /></cpanel> - <cpanel element="label_x3"><bounds left="237" top="161" right="341" bottom="168" /></cpanel> - <cpanel element="label_3"><bounds left="81" top="169" right="92" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="112" top="169" right="123" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="143" top="169" right="154" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="174" top="169" right="185" bottom="176" /></cpanel> - <cpanel element="label_3"><bounds left="237" top="169" right="248" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="268" top="169" right="279" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="299" top="169" right="310" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="330" top="169" right="341" bottom="176" /></cpanel> - - <cpanel element="label_last_ptr"><bounds left="384" top="153" right="662" bottom="161" /></cpanel> - <cpanel element="label_x2"><bounds left="393" top="161" right="497" bottom="168" /></cpanel> - <cpanel element="label_x3"><bounds left="549" top="161" right="653" bottom="168" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="169" right="404" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="169" right="435" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="169" right="466" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="169" right="497" bottom="176" /></cpanel> - <cpanel element="label_3"><bounds left="549" top="169" right="560" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="580" top="169" right="591" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="611" top="169" right="622" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="642" top="169" right="653" bottom="176" /></cpanel> - - <cpanel element="label_addr_data"><bounds left="72" top="214" right="506" bottom="222" /></cpanel> - <cpanel element="label_11"><bounds left="74" top="230" right="99" bottom="237" /></cpanel> - <cpanel element="label_10"><bounds left="105" top="230" right="130" bottom="237" /></cpanel> - <cpanel element="label_9"><bounds left="136" top="230" right="161" bottom="237" /></cpanel> - <cpanel element="label_8"><bounds left="167" top="230" right="192" bottom="237" /></cpanel> - <cpanel element="label_7"><bounds left="230" top="230" right="255" bottom="237" /></cpanel> - <cpanel element="label_6"><bounds left="261" top="230" right="286" bottom="237" /></cpanel> - <cpanel element="label_5"><bounds left="292" top="230" right="317" bottom="237" /></cpanel> - <cpanel element="label_4"><bounds left="323" top="230" right="348" bottom="237" /></cpanel> - <cpanel element="label_3"><bounds left="386" top="230" right="411" bottom="237" /></cpanel> - <cpanel element="label_2"><bounds left="417" top="230" right="442" bottom="237" /></cpanel> - <cpanel element="label_1"><bounds left="448" top="230" right="473" bottom="237" /></cpanel> - <cpanel element="label_0"><bounds left="479" top="230" right="504" bottom="237" /></cpanel> - - <cpanel element="label_mode_ctrl"><bounds left="571" top="214" right="662" bottom="222" /></cpanel> - <cpanel element="label_mon"><bounds left="573" top="230" right="598" bottom="237" /></cpanel> - <cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel> - <cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel> - - <cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel> - <cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel> - <cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel> - <cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel> - <cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel> - - <cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel> - <cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel> - <cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel> - <cpanel element="label_2"><bounds left="105" top="312" right="130" bottom="319" /></cpanel> - <cpanel element="label_1"><bounds left="136" top="312" right="161" bottom="319" /></cpanel> - <cpanel element="label_0"><bounds left="167" top="312" right="192" bottom="319" /></cpanel> - - <cpanel element="label_search_ctrl"><bounds left="228" top="296" right="381" bottom="304" /></cpanel> - <cpanel element="label_run"><bounds left="230" top="312" right="255" bottom="319" /></cpanel> - <cpanel element="label_next"><bounds left="261" top="304" right="286" bottom="311" /></cpanel> - <cpanel element="label_inst"><bounds left="261" top="312" right="286" bottom="319" /></cpanel> - <cpanel element="label_decr"><bounds left="292" top="312" right="317" bottom="319" /></cpanel> - <cpanel element="label_incr"><bounds left="323" top="312" right="348" bottom="319" /></cpanel> - <cpanel element="label_load"><bounds left="354" top="312" right="379" bottom="319" /></cpanel> - - <cpanel element="label_test"><bounds left="446" top="296" right="506" bottom="304" /></cpanel> - <cpanel element="label_hold"><bounds left="448" top="312" right="473" bottom="319" /></cpanel> - <cpanel element="label_one"><bounds left="479" top="304" right="504" bottom="311" /></cpanel> - <cpanel element="label_shot"><bounds left="479" top="312" right="504" bottom="319" /></cpanel> - - <cpanel element="label_cma"><bounds left="571" top="296" right="631" bottom="304" /></cpanel> - <cpanel element="label_write"><bounds left="604" top="312" right="629" bottom="319" /></cpanel> - <cpanel element="label_enable"><bounds left="514" top="321" right="570" bottom="328" /></cpanel> - <cpanel element="label_disable"><bounds left="514" top="361" right="570" bottom="368" /></cpanel> - - <cpanel element="label_reset_ctrl"><bounds left="664" top="296" right="724" bottom="304" /></cpanel> - <cpanel element="label_reset"><bounds left="666" top="312" right="691" bottom="319" /></cpanel> - <cpanel element="label_reset_mode"><bounds left="697" top="312" right="722" bottom="319" /></cpanel> - <cpanel element="label_system"><bounds left="727" top="321" right="783" bottom="328" /></cpanel> - <cpanel element="label_reset_cpu"><bounds left="727" top="361" right="783" bottom="368" /></cpanel> - - <cpanel name="led_address_a3_3" element="led"> - <bounds left="81" top="79" right="92" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_2" element="led"> - <bounds left="112" top="79" right="123" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_1" element="led"> - <bounds left="143" top="79" right="154" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_0" element="led"> - <bounds left="174" top="79" right="185" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_3" element="led"> - <bounds left="237" top="79" right="248" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_2" element="led"> - <bounds left="268" top="79" right="279" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_1" element="led"> - <bounds left="299" top="79" right="310" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_0" element="led"> - <bounds left="330" top="79" right="341" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_3" element="led"> - <bounds left="393" top="79" right="404" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_2" element="led"> - <bounds left="424" top="79" right="435" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_1" element="led"> - <bounds left="455" top="79" right="466" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_0" element="led"> - <bounds left="486" top="79" right="497" bottom="86" /> - </cpanel> - - <cpanel name="led_status_search" element="led"> - <bounds left="580" top="79" right="591" bottom="86" /> - </cpanel> - <cpanel name="led_status_cpu" element="led"> - <bounds left="611" top="79" right="622" bottom="86" /> - </cpanel> - <cpanel name="led_status_ptr_valid" element="led"> - <bounds left="642" top="79" right="653" bottom="86" /> - </cpanel> - - <cpanel name="led_instruction_m1_3" element="led"> - <bounds left="81" top="128" right="92" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_2" element="led"> - <bounds left="112" top="128" right="123" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_1" element="led"> - <bounds left="143" top="128" right="154" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_0" element="led"> - <bounds left="174" top="128" right="185" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_3" element="led"> - <bounds left="237" top="128" right="248" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_2" element="led"> - <bounds left="268" top="128" right="279" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_1" element="led"> - <bounds left="299" top="128" right="310" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_0" element="led"> - <bounds left="330" top="128" right="341" bottom="135" /> - </cpanel> - - <cpanel name="led_active_bank_3" element="led"> - <bounds left="393" top="128" right="404" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_2" element="led"> - <bounds left="424" top="128" right="435" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_1" element="led"> - <bounds left="455" top="128" right="466" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_0" element="led"> - <bounds left="486" top="128" right="497" bottom="135" /> - </cpanel> - - <cpanel name="led_mode_mon" element="led"> - <bounds left="580" top="128" right="591" bottom="135" /> - </cpanel> - <cpanel name="led_mode_ram" element="led"> - <bounds left="611" top="128" right="622" bottom="135" /> - </cpanel> - <cpanel name="led_mode_prom" element="led"> - <bounds left="642" top="128" right="653" bottom="135" /> - </cpanel> - - <cpanel name="led_execution_x2_3" element="led"> - <bounds left="81" top="177" right="92" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_2" element="led"> - <bounds left="112" top="177" right="123" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_1" element="led"> - <bounds left="143" top="177" right="154" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_0" element="led"> - <bounds left="174" top="177" right="185" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_3" element="led"> - <bounds left="237" top="177" right="248" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_2" element="led"> - <bounds left="268" top="177" right="279" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_1" element="led"> - <bounds left="299" top="177" right="310" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_0" element="led"> - <bounds left="330" top="177" right="341" bottom="184" /> - </cpanel> - - <cpanel name="led_last_ptr_x2_3" element="led"> - <bounds left="393" top="177" right="404" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_2" element="led"> - <bounds left="424" top="177" right="435" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_1" element="led"> - <bounds left="455" top="177" right="466" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_0" element="led"> - <bounds left="486" top="177" right="497" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_3" element="led"> - <bounds left="549" top="177" right="560" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_2" element="led"> - <bounds left="580" top="177" right="591" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_1" element="led"> - <bounds left="611" top="177" right="622" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_0" element="led"> - <bounds left="642" top="177" right="653" bottom="184" /> - </cpanel> - - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0800"> - <bounds left="74" top="240" right="99" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0400"> - <bounds left="105" top="240" right="130" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0200"> - <bounds left="136" top="240" right="161" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0100"> - <bounds left="167" top="240" right="192" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0080"> - <bounds left="230" top="240" right="255" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0040"> - <bounds left="261" top="240" right="286" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0020"> - <bounds left="292" top="240" right="317" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0010"> - <bounds left="323" top="240" right="348" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0008"> - <bounds left="386" top="240" right="411" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0004"> - <bounds left="417" top="240" right="442" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0002"> - <bounds left="448" top="240" right="473" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0001"> - <bounds left="479" top="240" right="504" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="MODE" inputmask="0x0010"> - <bounds left="573" top="240" right="598" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0020"> - <bounds left="604" top="240" right="629" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0040"> - <bounds left="635" top="240" right="660" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="PROM" inputmask="0x0001"> - <bounds left="728" top="240" right="753" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="PASSES" inputmask="0x08"> - <bounds left="74" top="322" right="99" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x04"> - <bounds left="105" top="322" right="130" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x02"> - <bounds left="136" top="322" right="161" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x01"> - <bounds left="167" top="322" right="192" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0001"> - <bounds left="230" top="322" right="255" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0002"> - <bounds left="261" top="322" right="286" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0004"> - <bounds left="292" top="322" right="317" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0008"> - <bounds left="323" top="322" right="348" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0010"> - <bounds left="354" top="322" right="379" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="MODE" inputmask="0x0001"> - <bounds left="448" top="322" right="473" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0002"> - <bounds left="479" top="322" right="504" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0020"> - <bounds left="573" top="322" right="598" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0040"> - <bounds left="604" top="322" right="629" bottom="368" /> - </cpanel> + <view name="Terminal Above"> + <group ref="panel"><bounds left="0" top="750" right="1000" bottom="1150" /></group> + <screen index="0"><bounds left="0" top="0" right="1000" bottom="750" /></screen> + </view> - <cpanel element="switch" inputtag="MODE" inputmask="0x0004"> - <bounds left="666" top="322" right="691" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0008"> - <bounds left="697" top="322" right="722" bottom="368" /> - </cpanel> + <view name="Front Panel"> + <group ref="panel"><bounds left="0" top="0" right="1000" bottom="400" /></group> </view> </mamelayout> diff --git a/src/mame/layout/intlc440.lay b/src/mame/layout/intlc440.lay index bf11a718128..1d2cb625ca2 100644 --- a/src/mame/layout/intlc440.lay +++ b/src/mame/layout/intlc440.lay @@ -156,7 +156,7 @@ Intel INTELLEC® 4/MOD 40 layout <text string="RESET CONTROL" align="1"><color red="1.0" green="1.0" blue="1.0" /></text> </element> - <view name="Terminal Below"> + <group name="panel"> <cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel> <cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel> @@ -531,384 +531,19 @@ Intel INTELLEC® 4/MOD 40 layout <cpanel element="switch" inputtag="MODE" inputmask="0x0008"> <bounds left="697" top="322" right="722" bottom="368" /> </cpanel> + </group> + <view name="Terminal Below"> + <group ref="panel"><bounds left="0" top="0" right="1000" bottom="400" /></group> <screen index="0"><bounds left="0" top="400" right="1000" bottom="1150" /></screen> </view> - <view name="Front Panel"> - <cpanel element="background"><bounds left="0" top="0" right="1000" bottom="400" /></cpanel> - - <cpanel element="label_address"><bounds left="72" top="55" right="506" bottom="63" /></cpanel> - <cpanel element="label_a3"><bounds left="81" top="63" right="185" bottom="70" /></cpanel> - <cpanel element="label_a2"><bounds left="237" top="63" right="341" bottom="70" /></cpanel> - <cpanel element="label_a1"><bounds left="393" top="63" right="497" bottom="70" /></cpanel> - <cpanel element="label_11"><bounds left="81" top="71" right="92" bottom="78" /></cpanel> - <cpanel element="label_10"><bounds left="112" top="71" right="123" bottom="78" /></cpanel> - <cpanel element="label_9"><bounds left="143" top="71" right="154" bottom="78" /></cpanel> - <cpanel element="label_8"><bounds left="174" top="71" right="185" bottom="78" /></cpanel> - <cpanel element="label_7"><bounds left="237" top="71" right="248" bottom="78" /></cpanel> - <cpanel element="label_6"><bounds left="268" top="71" right="279" bottom="78" /></cpanel> - <cpanel element="label_5"><bounds left="299" top="71" right="310" bottom="78" /></cpanel> - <cpanel element="label_4"><bounds left="330" top="71" right="341" bottom="78" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="71" right="404" bottom="78" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="71" right="435" bottom="78" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="71" right="466" bottom="78" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="71" right="497" bottom="78" /></cpanel> - - <cpanel element="label_status"><bounds left="540" top="55" right="662" bottom="63" /></cpanel> - <cpanel element="label_search"><bounds left="561" top="63" right="610" bottom="70" /></cpanel> - <cpanel element="label_complete"><bounds left="561" top="71" right="610" bottom="78" /></cpanel> - <cpanel element="label_pointer"><bounds left="623" top="63" right="672" bottom="70" /></cpanel> - <cpanel element="label_valid"><bounds left="623" top="71" right="672" bottom="78" /></cpanel> - <cpanel element="label_run"><bounds left="611" top="71" right="626" bottom="78" /></cpanel> - - <cpanel element="label_instruction"><bounds left="72" top="104" right="350" bottom="112" /></cpanel> - <cpanel element="label_m1"><bounds left="81" top="112" right="185" bottom="119" /></cpanel> - <cpanel element="label_m2"><bounds left="237" top="112" right="341" bottom="119" /></cpanel> - <cpanel element="label_7"><bounds left="81" top="120" right="92" bottom="127" /></cpanel> - <cpanel element="label_6"><bounds left="112" top="120" right="123" bottom="127" /></cpanel> - <cpanel element="label_5"><bounds left="143" top="120" right="154" bottom="127" /></cpanel> - <cpanel element="label_4"><bounds left="174" top="120" right="185" bottom="127" /></cpanel> - <cpanel element="label_3"><bounds left="237" top="120" right="248" bottom="127" /></cpanel> - <cpanel element="label_2"><bounds left="268" top="120" right="279" bottom="127" /></cpanel> - <cpanel element="label_1"><bounds left="299" top="120" right="310" bottom="127" /></cpanel> - <cpanel element="label_0"><bounds left="330" top="120" right="341" bottom="127" /></cpanel> - - <cpanel element="label_active_bank"><bounds left="384" top="104" right="506" bottom="112" /></cpanel> - <cpanel element="label_cm_ram"><bounds left="393" top="112" right="497" bottom="119" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="120" right="404" bottom="127" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="120" right="435" bottom="127" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="120" right="466" bottom="127" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="120" right="497" bottom="127" /></cpanel> - - <cpanel element="label_mode"><bounds left="540" top="104" right="662" bottom="112" /></cpanel> - <cpanel element="label_mon"><bounds left="577" top="120" right="594" bottom="127" /></cpanel> - <cpanel element="label_ram"><bounds left="608" top="120" right="625" bottom="127" /></cpanel> - <cpanel element="label_prom"><bounds left="639" top="120" right="656" bottom="127" /></cpanel> - - <cpanel element="label_execution"><bounds left="72" top="153" right="350" bottom="161" /></cpanel> - <cpanel element="label_x2"><bounds left="81" top="161" right="185" bottom="168" /></cpanel> - <cpanel element="label_x3"><bounds left="237" top="161" right="341" bottom="168" /></cpanel> - <cpanel element="label_3"><bounds left="81" top="169" right="92" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="112" top="169" right="123" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="143" top="169" right="154" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="174" top="169" right="185" bottom="176" /></cpanel> - <cpanel element="label_3"><bounds left="237" top="169" right="248" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="268" top="169" right="279" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="299" top="169" right="310" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="330" top="169" right="341" bottom="176" /></cpanel> - - <cpanel element="label_last_ptr"><bounds left="384" top="153" right="662" bottom="161" /></cpanel> - <cpanel element="label_x2"><bounds left="393" top="161" right="497" bottom="168" /></cpanel> - <cpanel element="label_x3"><bounds left="549" top="161" right="653" bottom="168" /></cpanel> - <cpanel element="label_3"><bounds left="393" top="169" right="404" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="424" top="169" right="435" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="455" top="169" right="466" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="486" top="169" right="497" bottom="176" /></cpanel> - <cpanel element="label_3"><bounds left="549" top="169" right="560" bottom="176" /></cpanel> - <cpanel element="label_2"><bounds left="580" top="169" right="591" bottom="176" /></cpanel> - <cpanel element="label_1"><bounds left="611" top="169" right="622" bottom="176" /></cpanel> - <cpanel element="label_0"><bounds left="642" top="169" right="653" bottom="176" /></cpanel> - - <cpanel element="label_addr_data"><bounds left="72" top="214" right="506" bottom="222" /></cpanel> - <cpanel element="label_11"><bounds left="74" top="230" right="99" bottom="237" /></cpanel> - <cpanel element="label_10"><bounds left="105" top="230" right="130" bottom="237" /></cpanel> - <cpanel element="label_9"><bounds left="136" top="230" right="161" bottom="237" /></cpanel> - <cpanel element="label_8"><bounds left="167" top="230" right="192" bottom="237" /></cpanel> - <cpanel element="label_7"><bounds left="230" top="230" right="255" bottom="237" /></cpanel> - <cpanel element="label_6"><bounds left="261" top="230" right="286" bottom="237" /></cpanel> - <cpanel element="label_5"><bounds left="292" top="230" right="317" bottom="237" /></cpanel> - <cpanel element="label_4"><bounds left="323" top="230" right="348" bottom="237" /></cpanel> - <cpanel element="label_3"><bounds left="386" top="230" right="411" bottom="237" /></cpanel> - <cpanel element="label_2"><bounds left="417" top="230" right="442" bottom="237" /></cpanel> - <cpanel element="label_1"><bounds left="448" top="230" right="473" bottom="237" /></cpanel> - <cpanel element="label_0"><bounds left="479" top="230" right="504" bottom="237" /></cpanel> - - <cpanel element="label_mode_ctrl"><bounds left="571" top="214" right="662" bottom="222" /></cpanel> - <cpanel element="label_mon"><bounds left="573" top="230" right="598" bottom="237" /></cpanel> - <cpanel element="label_ram"><bounds left="604" top="230" right="629" bottom="237" /></cpanel> - <cpanel element="label_prom"><bounds left="635" top="230" right="660" bottom="237" /></cpanel> - - <cpanel element="label_prgm"><bounds left="728" top="214" right="753" bottom="221" /></cpanel> - <cpanel element="label_prom"><bounds left="728" top="222" right="753" bottom="229" /></cpanel> - <cpanel element="label_pwr"><bounds left="728" top="230" right="753" bottom="237" /></cpanel> - <cpanel element="label_on"><bounds left="758" top="239" right="814" bottom="246" /></cpanel> - <cpanel element="label_off"><bounds left="758" top="279" right="814" bottom="287" /></cpanel> - - <cpanel element="label_pass_counter"><bounds left="72" top="296" right="194" bottom="304" /></cpanel> - <cpanel element="label_passes"><bounds left="74" top="304" right="192" bottom="311" /></cpanel> - <cpanel element="label_3"><bounds left="74" top="312" right="99" bottom="319" /></cpanel> - <cpanel element="label_2"><bounds left="105" top="312" right="130" bottom="319" /></cpanel> - <cpanel element="label_1"><bounds left="136" top="312" right="161" bottom="319" /></cpanel> - <cpanel element="label_0"><bounds left="167" top="312" right="192" bottom="319" /></cpanel> - - <cpanel element="label_search_ctrl"><bounds left="228" top="296" right="381" bottom="304" /></cpanel> - <cpanel element="label_run"><bounds left="230" top="312" right="255" bottom="319" /></cpanel> - <cpanel element="label_next"><bounds left="261" top="304" right="286" bottom="311" /></cpanel> - <cpanel element="label_inst"><bounds left="261" top="312" right="286" bottom="319" /></cpanel> - <cpanel element="label_decr"><bounds left="292" top="312" right="317" bottom="319" /></cpanel> - <cpanel element="label_incr"><bounds left="323" top="312" right="348" bottom="319" /></cpanel> - <cpanel element="label_load"><bounds left="354" top="312" right="379" bottom="319" /></cpanel> - - <cpanel element="label_stop"><bounds left="448" top="312" right="473" bottom="319" /></cpanel> - <cpanel element="label_single"><bounds left="479" top="304" right="504" bottom="311" /></cpanel> - <cpanel element="label_step"><bounds left="479" top="312" right="504" bottom="319" /></cpanel> - - <cpanel element="label_cma"><bounds left="571" top="296" right="631" bottom="304" /></cpanel> - <cpanel element="label_write"><bounds left="604" top="312" right="629" bottom="319" /></cpanel> - <cpanel element="label_enable"><bounds left="514" top="321" right="570" bottom="328" /></cpanel> - <cpanel element="label_disable"><bounds left="514" top="361" right="570" bottom="368" /></cpanel> - - <cpanel element="label_reset_ctrl"><bounds left="664" top="296" right="724" bottom="304" /></cpanel> - <cpanel element="label_reset"><bounds left="666" top="312" right="691" bottom="319" /></cpanel> - <cpanel element="label_reset_mode"><bounds left="697" top="312" right="722" bottom="319" /></cpanel> - <cpanel element="label_system"><bounds left="727" top="321" right="783" bottom="328" /></cpanel> - <cpanel element="label_reset_cpu"><bounds left="727" top="361" right="783" bottom="368" /></cpanel> - - <cpanel name="led_address_a3_3" element="led"> - <bounds left="81" top="79" right="92" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_2" element="led"> - <bounds left="112" top="79" right="123" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_1" element="led"> - <bounds left="143" top="79" right="154" bottom="86" /> - </cpanel> - <cpanel name="led_address_a3_0" element="led"> - <bounds left="174" top="79" right="185" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_3" element="led"> - <bounds left="237" top="79" right="248" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_2" element="led"> - <bounds left="268" top="79" right="279" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_1" element="led"> - <bounds left="299" top="79" right="310" bottom="86" /> - </cpanel> - <cpanel name="led_address_a2_0" element="led"> - <bounds left="330" top="79" right="341" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_3" element="led"> - <bounds left="393" top="79" right="404" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_2" element="led"> - <bounds left="424" top="79" right="435" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_1" element="led"> - <bounds left="455" top="79" right="466" bottom="86" /> - </cpanel> - <cpanel name="led_address_a1_0" element="led"> - <bounds left="486" top="79" right="497" bottom="86" /> - </cpanel> - - <cpanel name="led_status_search" element="led"> - <bounds left="580" top="79" right="591" bottom="86" /> - </cpanel> - <cpanel name="led_status_run" element="led"> - <bounds left="611" top="79" right="622" bottom="86" /> - </cpanel> - <cpanel name="led_status_ptr_valid" element="led"> - <bounds left="642" top="79" right="653" bottom="86" /> - </cpanel> - - <cpanel name="led_instruction_m1_3" element="led"> - <bounds left="81" top="128" right="92" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_2" element="led"> - <bounds left="112" top="128" right="123" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_1" element="led"> - <bounds left="143" top="128" right="154" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m1_0" element="led"> - <bounds left="174" top="128" right="185" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_3" element="led"> - <bounds left="237" top="128" right="248" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_2" element="led"> - <bounds left="268" top="128" right="279" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_1" element="led"> - <bounds left="299" top="128" right="310" bottom="135" /> - </cpanel> - <cpanel name="led_instruction_m2_0" element="led"> - <bounds left="330" top="128" right="341" bottom="135" /> - </cpanel> - - <cpanel name="led_active_bank_3" element="led"> - <bounds left="393" top="128" right="404" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_2" element="led"> - <bounds left="424" top="128" right="435" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_1" element="led"> - <bounds left="455" top="128" right="466" bottom="135" /> - </cpanel> - <cpanel name="led_active_bank_0" element="led"> - <bounds left="486" top="128" right="497" bottom="135" /> - </cpanel> - - <cpanel name="led_mode_mon" element="led"> - <bounds left="580" top="128" right="591" bottom="135" /> - </cpanel> - <cpanel name="led_mode_ram" element="led"> - <bounds left="611" top="128" right="622" bottom="135" /> - </cpanel> - <cpanel name="led_mode_prom" element="led"> - <bounds left="642" top="128" right="653" bottom="135" /> - </cpanel> - - <cpanel name="led_execution_x2_3" element="led"> - <bounds left="81" top="177" right="92" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_2" element="led"> - <bounds left="112" top="177" right="123" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_1" element="led"> - <bounds left="143" top="177" right="154" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x2_0" element="led"> - <bounds left="174" top="177" right="185" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_3" element="led"> - <bounds left="237" top="177" right="248" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_2" element="led"> - <bounds left="268" top="177" right="279" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_1" element="led"> - <bounds left="299" top="177" right="310" bottom="184" /> - </cpanel> - <cpanel name="led_execution_x3_0" element="led"> - <bounds left="330" top="177" right="341" bottom="184" /> - </cpanel> - - <cpanel name="led_last_ptr_x2_3" element="led"> - <bounds left="393" top="177" right="404" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_2" element="led"> - <bounds left="424" top="177" right="435" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_1" element="led"> - <bounds left="455" top="177" right="466" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x2_0" element="led"> - <bounds left="486" top="177" right="497" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_3" element="led"> - <bounds left="549" top="177" right="560" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_2" element="led"> - <bounds left="580" top="177" right="591" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_1" element="led"> - <bounds left="611" top="177" right="622" bottom="184" /> - </cpanel> - <cpanel name="led_last_ptr_x3_0" element="led"> - <bounds left="642" top="177" right="653" bottom="184" /> - </cpanel> - - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0800"> - <bounds left="74" top="240" right="99" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0400"> - <bounds left="105" top="240" right="130" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0200"> - <bounds left="136" top="240" right="161" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0100"> - <bounds left="167" top="240" right="192" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0080"> - <bounds left="230" top="240" right="255" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0040"> - <bounds left="261" top="240" right="286" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0020"> - <bounds left="292" top="240" right="317" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0010"> - <bounds left="323" top="240" right="348" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0008"> - <bounds left="386" top="240" right="411" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0004"> - <bounds left="417" top="240" right="442" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0002"> - <bounds left="448" top="240" right="473" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="ADDRDAT" inputmask="0x0001"> - <bounds left="479" top="240" right="504" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="MODE" inputmask="0x0010"> - <bounds left="573" top="240" right="598" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0020"> - <bounds left="604" top="240" right="629" bottom="286" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0040"> - <bounds left="635" top="240" right="660" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="PROM" inputmask="0x0001"> - <bounds left="728" top="240" right="753" bottom="286" /> - </cpanel> - - <cpanel element="switch" inputtag="PASSES" inputmask="0x08"> - <bounds left="74" top="322" right="99" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x04"> - <bounds left="105" top="322" right="130" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x02"> - <bounds left="136" top="322" right="161" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="PASSES" inputmask="0x01"> - <bounds left="167" top="322" right="192" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0001"> - <bounds left="230" top="322" right="255" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0002"> - <bounds left="261" top="322" right="286" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0004"> - <bounds left="292" top="322" right="317" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0008"> - <bounds left="323" top="322" right="348" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0010"> - <bounds left="354" top="322" right="379" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="MODE" inputmask="0x0001"> - <bounds left="448" top="322" right="473" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0002"> - <bounds left="479" top="322" right="504" bottom="368" /> - </cpanel> - - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0020"> - <bounds left="573" top="322" right="598" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="CONTROL" inputmask="0x0040"> - <bounds left="604" top="322" right="629" bottom="368" /> - </cpanel> + <view name="Terminal Above"> + <group ref="panel"><bounds left="0" top="750" right="1000" bottom="1150" /></group> + <screen index="0"><bounds left="0" top="0" right="1000" bottom="750" /></screen> + </view> - <cpanel element="switch" inputtag="MODE" inputmask="0x0004"> - <bounds left="666" top="322" right="691" bottom="368" /> - </cpanel> - <cpanel element="switch" inputtag="MODE" inputmask="0x0008"> - <bounds left="697" top="322" right="722" bottom="368" /> - </cpanel> + <view name="Front Panel"> + <group ref="panel"><bounds left="0" top="0" right="1000" bottom="400" /></group> </view> </mamelayout> |