summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/render.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/render.cpp')
-rw-r--r--src/emu/render.cpp287
1 files changed, 115 insertions, 172 deletions
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index ab26abaf154..0c598345ea1 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -111,22 +111,6 @@ static const render_quad_texuv oriented_texcoords[8] =
{ { 1,1 }, { 1,0 }, { 0,1 }, { 0,0 } } // ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y
};
-// layer orders
-static constexpr std::pair<item_layer, int> layer_order_standard[]{
- { ITEM_LAYER_SCREEN, -1 }, // FIXME: invalid blend mode - we're relying on the goodness of the OSD
- { ITEM_LAYER_OVERLAY, BLENDMODE_RGB_MULTIPLY },
- { ITEM_LAYER_BACKDROP, BLENDMODE_ADD },
- { ITEM_LAYER_BEZEL, BLENDMODE_ALPHA },
- { ITEM_LAYER_CPANEL, BLENDMODE_ALPHA },
- { ITEM_LAYER_MARQUEE, BLENDMODE_ALPHA } };
-static constexpr std::pair<item_layer, int> layer_order_alternate[]{
- { ITEM_LAYER_BACKDROP, BLENDMODE_ALPHA },
- { ITEM_LAYER_SCREEN, BLENDMODE_ADD },
- { ITEM_LAYER_OVERLAY, BLENDMODE_RGB_MULTIPLY },
- { ITEM_LAYER_BEZEL, BLENDMODE_ALPHA },
- { ITEM_LAYER_CPANEL, BLENDMODE_ALPHA },
- { ITEM_LAYER_MARQUEE, BLENDMODE_ALPHA } };
-
//**************************************************************************
@@ -177,25 +161,6 @@ inline void normalize_bounds(render_bounds &bounds)
}
-//-------------------------------------------------
-// get_layer_and_blendmode - return the
-// appropriate layer index and blendmode
-//-------------------------------------------------
-
-inline item_layer get_layer_and_blendmode(layout_view &view, int index, int &blendmode)
-{
- // if we have multiple backdrop pieces and no overlays, render:
- // backdrop (add) + screens (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha)
- // else render:
- // screens (add) + overlays (RGB multiply) + backdrop (add) + bezels (alpha) + cpanels (alpha) + marquees (alpha)
-
- std::pair<item_layer, int> const *const layer_order(((view.items(ITEM_LAYER_BACKDROP).size() > 1) && view.items(ITEM_LAYER_OVERLAY).empty()) ? layer_order_alternate : layer_order_standard);
-
- // select the layer and blend mode
- blendmode = layer_order[index].second;
- return layer_order[index].first;
-}
-
//**************************************************************************
// RENDER PRIMITIVE
//**************************************************************************
@@ -396,7 +361,7 @@ void render_texture::set_bitmap(bitmap_t &bitmap, const rectangle &sbounds, text
assert(bitmap.cliprect().contains(sbounds));
// ensure we have a valid palette for palettized modes
- if (format == TEXFORMAT_PALETTE16 || format == TEXFORMAT_PALETTEA16)
+ if (format == TEXFORMAT_PALETTE16)
assert(bitmap.palette() != nullptr);
// invalidate references to the old bitmap
@@ -446,8 +411,8 @@ void render_texture::get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo
int sheight = m_sbounds.height();
// ensure height/width are non-zero
- if (dwidth < 1) dwidth = 1;
- if (dheight < 1) dheight = 1;
+ if (dwidth == 0) dwidth = 1;
+ if (dheight == 0) dheight = 1;
texinfo.unique_id = m_id;
texinfo.old_id = m_old_id;
@@ -495,7 +460,8 @@ void render_texture::get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo
for (scalenum = 0; scalenum < ARRAY_LENGTH(m_scaled); scalenum++)
if ((lowest == -1 || m_scaled[scalenum].seqid < m_scaled[lowest].seqid) && !primlist.has_reference(m_scaled[scalenum].bitmap))
lowest = scalenum;
- assert_always(lowest != -1, "Too many live texture instances!");
+ if (-1 == lowest)
+ throw emu_fatalerror("render_texture::get_scaled: Too many live texture instances!");
// throw out any existing entries
scaled = &m_scaled[lowest];
@@ -530,18 +496,17 @@ void render_texture::get_scaled(u32 dwidth, u32 dheight, render_texinfo &texinfo
// palette for a texture
//-------------------------------------------------
-const rgb_t *render_texture::get_adjusted_palette(render_container &container)
+const rgb_t *render_texture::get_adjusted_palette(render_container &container, u32 &out_length)
{
// override the palette with our adjusted palette
switch (m_format)
{
case TEXFORMAT_PALETTE16:
- case TEXFORMAT_PALETTEA16:
assert(m_bitmap->palette() != nullptr);
// return our adjusted palette
- return container.bcg_lookup_table(m_format, m_bitmap->palette());
+ return container.bcg_lookup_table(m_format, out_length, m_bitmap->palette());
case TEXFORMAT_RGB32:
case TEXFORMAT_ARGB32:
@@ -550,7 +515,7 @@ const rgb_t *render_texture::get_adjusted_palette(render_container &container)
// if no adjustment necessary, return nullptr
if (!container.has_brightness_contrast_gamma_changes())
return nullptr;
- return container.bcg_lookup_table(m_format);
+ return container.bcg_lookup_table(m_format, out_length);
default:
assert(false);
@@ -714,12 +679,11 @@ float render_container::apply_brightness_contrast_gamma_fp(float value)
// given texture mode
//-------------------------------------------------
-const rgb_t *render_container::bcg_lookup_table(int texformat, palette_t *palette)
+const rgb_t *render_container::bcg_lookup_table(int texformat, u32 &out_length, palette_t *palette)
{
switch (texformat)
{
case TEXFORMAT_PALETTE16:
- case TEXFORMAT_PALETTEA16:
if (m_palclient == nullptr) // if adjusted palette hasn't been created yet, create it
{
m_palclient = std::make_unique<palette_client>(*palette);
@@ -727,14 +691,17 @@ const rgb_t *render_container::bcg_lookup_table(int texformat, palette_t *palett
recompute_lookups();
}
assert (palette == &m_palclient->palette());
+ out_length = palette->max_index();
return &m_bcglookup[0];
case TEXFORMAT_RGB32:
case TEXFORMAT_ARGB32:
case TEXFORMAT_YUY16:
+ out_length = 256;
return m_bcglookup256;
default:
+ out_length = 0;
return nullptr;
}
}
@@ -941,11 +908,6 @@ template <typename T> render_target::render_target(render_manager &manager, T &&
, m_transform_container(true)
{
// determine the base layer configuration based on options
- m_base_layerconfig.set_backdrops_enabled(manager.machine().options().use_backdrops());
- m_base_layerconfig.set_overlays_enabled(manager.machine().options().use_overlays());
- m_base_layerconfig.set_bezels_enabled(manager.machine().options().use_bezels());
- m_base_layerconfig.set_cpanels_enabled(manager.machine().options().use_cpanels());
- m_base_layerconfig.set_marquees_enabled(manager.machine().options().use_marquees());
m_base_layerconfig.set_zoom_to_screen(manager.machine().options().artwork_crop());
// aspect and scale options
@@ -1296,40 +1258,38 @@ void render_target::compute_minimum_size(s32 &minwidth, s32 &minheight)
throw emu_fatalerror("Mandatory artwork is missing");
// scan the current view for all screens
- for (item_layer layer = ITEM_LAYER_FIRST; layer < ITEM_LAYER_MAX; ++layer)
+ for (layout_view::item &curitem : m_curview->items())
{
- // iterate over items in the layer
- for (layout_view::item &curitem : m_curview->items(layer))
- if (curitem.screen())
+ if (curitem.screen())
+ {
+ // use a hard-coded default visible area for vector screens
+ screen_device *const screen = curitem.screen();
+ const rectangle vectorvis(0, 639, 0, 479);
+ const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area();
+
+ // apply target orientation to the bounds
+ render_bounds bounds = curitem.bounds();
+ apply_orientation(bounds, m_orientation);
+ normalize_bounds(bounds);
+
+ // based on the orientation of the screen container, check the bitmap
+ float xscale, yscale;
+ if (!(orientation_add(m_orientation, screen->container().orientation()) & ORIENTATION_SWAP_XY))
{
- // use a hard-coded default visible area for vector screens
- screen_device *const screen = curitem.screen();
- const rectangle vectorvis(0, 639, 0, 479);
- const rectangle &visarea = (screen->screen_type() == SCREEN_TYPE_VECTOR) ? vectorvis : screen->visible_area();
-
- // apply target orientation to the bounds
- render_bounds bounds = curitem.bounds();
- apply_orientation(bounds, m_orientation);
- normalize_bounds(bounds);
-
- // based on the orientation of the screen container, check the bitmap
- float xscale, yscale;
- if (!(orientation_add(m_orientation, screen->container().orientation()) & ORIENTATION_SWAP_XY))
- {
- xscale = float(visarea.width()) / bounds.width();
- yscale = float(visarea.height()) / bounds.height();
- }
- else
- {
- xscale = float(visarea.height()) / bounds.width();
- yscale = float(visarea.width()) / bounds.height();
- }
-
- // pick the greater
- maxxscale = std::max(xscale, maxxscale);
- maxyscale = std::max(yscale, maxyscale);
- screens_considered++;
+ xscale = float(visarea.width()) / bounds.width();
+ yscale = float(visarea.height()) / bounds.height();
}
+ else
+ {
+ xscale = float(visarea.height()) / bounds.width();
+ yscale = float(visarea.width()) / bounds.height();
+ }
+
+ // pick the greater
+ maxxscale = std::max(xscale, maxxscale);
+ maxyscale = std::max(yscale, maxyscale);
+ screens_considered++;
+ }
}
// if there were no screens considered, pick a nominal default
@@ -1378,42 +1338,33 @@ render_primitive_list &render_target::get_primitives()
root_xform.orientation = m_orientation;
root_xform.no_center = false;
- // iterate over layers back-to-front, but only if we're running
+ // iterate over items in the view, but only if we're running
if (m_manager.machine().phase() >= machine_phase::RESET)
- for (item_layer layernum = ITEM_LAYER_FIRST; layernum < ITEM_LAYER_MAX; ++layernum)
+ for (layout_view::item &curitem : m_curview->items())
{
- int blendmode;
- item_layer layer = get_layer_and_blendmode(*m_curview, layernum, blendmode);
- if (m_curview->layer_enabled(layer))
- {
- // iterate over items in the layer
- for (layout_view::item &curitem : m_curview->items(layer))
- {
- // first apply orientation to the bounds
- render_bounds bounds = curitem.bounds();
- apply_orientation(bounds, root_xform.orientation);
- normalize_bounds(bounds);
-
- // apply the transform to the item
- object_transform item_xform;
- item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale;
- item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale;
- item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale;
- item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale;
- item_xform.color.r = curitem.color().r * root_xform.color.r;
- item_xform.color.g = curitem.color().g * root_xform.color.g;
- item_xform.color.b = curitem.color().b * root_xform.color.b;
- item_xform.color.a = curitem.color().a * root_xform.color.a;
- item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation);
- item_xform.no_center = false;
-
- // if there is no associated element, it must be a screen element
- if (curitem.screen() != nullptr)
- add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), blendmode);
- else
- add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), blendmode);
- }
- }
+ // first apply orientation to the bounds
+ render_bounds bounds = curitem.bounds();
+ apply_orientation(bounds, root_xform.orientation);
+ normalize_bounds(bounds);
+
+ // apply the transform to the item
+ object_transform item_xform;
+ item_xform.xoffs = root_xform.xoffs + bounds.x0 * root_xform.xscale;
+ item_xform.yoffs = root_xform.yoffs + bounds.y0 * root_xform.yscale;
+ item_xform.xscale = (bounds.x1 - bounds.x0) * root_xform.xscale;
+ item_xform.yscale = (bounds.y1 - bounds.y0) * root_xform.yscale;
+ item_xform.color.r = curitem.color().r * root_xform.color.r;
+ item_xform.color.g = curitem.color().g * root_xform.color.g;
+ item_xform.color.b = curitem.color().b * root_xform.color.b;
+ item_xform.color.a = curitem.color().a * root_xform.color.a;
+ item_xform.orientation = orientation_add(curitem.orientation(), root_xform.orientation);
+ item_xform.no_center = false;
+
+ // if there is no associated element, it must be a screen element
+ if (curitem.screen() != nullptr)
+ add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), curitem.blend_mode());
+ else
+ add_element_primitives(list, item_xform, *curitem.element(), curitem.state(), curitem.blend_mode());
}
// if we are not in the running stage, draw an outer box
@@ -2110,7 +2061,27 @@ bool render_target::load_layout_file(const char *dirname, const char *filename)
return false;
// read the file
- util::xml::file::ptr rootnode(util::xml::file::read(layoutfile, nullptr));
+ util::xml::parse_options parseopt;
+ util::xml::parse_error parseerr;
+ parseopt.error = &parseerr;
+ util::xml::file::ptr rootnode(util::xml::file::read(layoutfile, &parseopt));
+ if (!rootnode)
+ {
+ if (parseerr.error_message)
+ {
+ osd_printf_warning(
+ "Error parsing XML file '%s' at line %d column %d: %s, ignoring\n",
+ filename,
+ parseerr.error_line,
+ parseerr.error_column,
+ parseerr.error_message);
+ }
+ else
+ {
+ osd_printf_warning("Error parsing XML file '%s', ignorning\n", filename);
+ }
+ return false;
+ }
// if we didn't get a properly-formatted XML file, record a warning and exit
if (!load_layout_file(m_manager.machine().root_device(), dirname, *rootnode))
@@ -2299,7 +2270,7 @@ void render_target::add_container_primitives(render_primitive_list &list, const
curitem.texture()->get_scaled(width, height, prim->texture, list, curitem.flags());
// set the palette
- prim->texture.palette = curitem.texture()->get_adjusted_palette(container);
+ prim->texture.palette = curitem.texture()->get_adjusted_palette(container, prim->texture.palette_length);
// determine UV coordinates
prim->texcoords = oriented_texcoords[finalorient];
@@ -2521,38 +2492,30 @@ bool render_target::map_point_internal(s32 target_x, s32 target_y, render_contai
return false;
}
- // loop through each layer
- for (item_layer layernum = ITEM_LAYER_FIRST; layernum < ITEM_LAYER_MAX; ++layernum)
+ // iterate over items in the view
+ for (layout_view::item &item : m_curview->items())
{
- int blendmode;
- item_layer layer = get_layer_and_blendmode(*m_curview, layernum, blendmode);
- if (m_curview->layer_enabled(layer))
- {
- // iterate over items in the layer
- for (layout_view::item &item : m_curview->items(layer))
- {
- bool checkit;
+ bool checkit;
- // if we're looking for a particular container, verify that we have the right one
- if (container != nullptr)
- checkit = (item.screen() != nullptr && &item.screen()->container() == container);
+ // if we're looking for a particular container, verify that we have the right one
+ if (container != nullptr)
+ checkit = (item.screen() != nullptr && &item.screen()->container() == container);
- // otherwise, assume we're looking for an input
- else
- checkit = item.has_input();
+ // otherwise, assume we're looking for an input
+ else
+ checkit = item.has_input();
- // this target is worth looking at; now check the point
- if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1)
- {
- // point successfully mapped
- mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0);
- mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0);
- mapped_input_port = item.input_tag_and_mask(mapped_input_mask);
- return true;
- }
- }
+ // this target is worth looking at; now check the point
+ if (checkit && target_fx >= item.bounds().x0 && target_fx < item.bounds().x1 && target_fy >= item.bounds().y0 && target_fy < item.bounds().y1)
+ {
+ // point successfully mapped
+ mapped_x = (target_fx - item.bounds().x0) / (item.bounds().x1 - item.bounds().x0);
+ mapped_y = (target_fy - item.bounds().y0) / (item.bounds().y1 - item.bounds().y0);
+ mapped_input_port = item.input_tag_and_mask(mapped_input_mask);
+ return true;
}
}
+
return false;
}
@@ -2603,6 +2566,8 @@ int render_target::view_index(layout_view &targetview) const
void render_target::config_load(util::xml::data_node const &targetnode)
{
+ int tmpint;
+
// find the view
const char *viewname = targetnode.get_attribute_string("view", nullptr);
if (viewname != nullptr)
@@ -2619,26 +2584,6 @@ void render_target::config_load(util::xml::data_node const &targetnode)
}
// modify the artwork config
- int tmpint = targetnode.get_attribute_int("backdrops", -1);
- if (tmpint == 0 || tmpint == 1)
- set_backdrops_enabled(tmpint);
-
- tmpint = targetnode.get_attribute_int("overlays", -1);
- if (tmpint == 0 || tmpint == 1)
- set_overlays_enabled(tmpint);
-
- tmpint = targetnode.get_attribute_int("bezels", -1);
- if (tmpint == 0 || tmpint == 1)
- set_bezels_enabled(tmpint);
-
- tmpint = targetnode.get_attribute_int("cpanels", -1);
- if (tmpint == 0 || tmpint == 1)
- set_cpanels_enabled(tmpint);
-
- tmpint = targetnode.get_attribute_int("marquees", -1);
- if (tmpint == 0 || tmpint == 1)
- set_marquees_enabled(tmpint);
-
tmpint = targetnode.get_attribute_int("zoom", -1);
if (tmpint == 0 || tmpint == 1)
set_zoom_to_screen(tmpint);
@@ -2693,11 +2638,6 @@ bool render_target::config_save(util::xml::data_node &targetnode)
// output the layer config
if (m_layerconfig != m_base_layerconfig)
{
- targetnode.set_attribute_int("backdrops", m_layerconfig.backdrops_enabled());
- targetnode.set_attribute_int("overlays", m_layerconfig.overlays_enabled());
- targetnode.set_attribute_int("bezels", m_layerconfig.bezels_enabled());
- targetnode.set_attribute_int("cpanels", m_layerconfig.cpanels_enabled());
- targetnode.set_attribute_int("marquees", m_layerconfig.marquees_enabled());
targetnode.set_attribute_int("zoom", m_layerconfig.zoom_to_screen());
changed = true;
}
@@ -2775,7 +2715,8 @@ bool render_target::remove_clear_extent(const render_bounds &bounds)
// make a copy of this extent
memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext));
last += ext[1] + 2;
- assert_always(last < max, "Ran out of clear extents!\n");
+ if (last >= max)
+ throw emu_fatalerror("render_target::remove_clear_extent: Ran out of clear extents!");
// split the extent between pieces
ext[ext[1] + 2] = -(-ext[0] - diff);
@@ -2795,7 +2736,8 @@ bool render_target::remove_clear_extent(const render_bounds &bounds)
// make a copy of this extent
memmove(&ext[ext[1] + 2], &ext[0], (last - ext) * sizeof(*ext));
last += ext[1] + 2;
- assert_always(last < max, "Ran out of clear extents!\n");
+ if (last >= max)
+ throw emu_fatalerror("render_target::remove_clear_extent: Ran out of clear extents!");
// split the extent between pieces
ext[ext[1] + 2] = -diff;
@@ -2820,7 +2762,8 @@ bool render_target::remove_clear_extent(const render_bounds &bounds)
memmove(&xext[2], &xext[0], (last - xext) * sizeof(*xext));
last += 2;
linelast += 2;
- assert_always(last < max, "Ran out of clear extents!\n");
+ if (last >= max)
+ throw emu_fatalerror("render_target::remove_clear_extent: Ran out of clear extents!");
// split this extent into three parts
xext[0] = boundsx0 - x0;
@@ -2948,7 +2891,7 @@ void render_target::add_clear_and_optimize_primitive_list(render_primitive_list
case render_primitive::QUAD:
{
// stop when we hit an alpha texture
- if (PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_PALETTEA16)
+ if (PRIMFLAG_GET_TEXFORMAT(prim.flags) == TEXFORMAT_ARGB32)
goto done;
// if this quad can't be cleanly removed from the extents list, we're done