diff options
author | 2021-11-18 10:34:38 +1100 | |
---|---|---|
committer | 2021-11-18 10:34:38 +1100 | |
commit | 5afce6cfab6320ee062da5f7b7438294672f9af1 (patch) | |
tree | 5902ddf0b74f27e3d43bc0556dcfd29198e86efd /src/emu/render.cpp | |
parent | ded9ecfc1cf7864f206b92480eaebf32092ef8f2 (diff) |
emu/render.cpp, emu/rendlay.cpp: Added scroll support for all elements.
Diffstat (limited to 'src/emu/render.cpp')
-rw-r--r-- | src/emu/render.cpp | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/src/emu/render.cpp b/src/emu/render.cpp index 0fef6bafe41..42a837062a3 100644 --- a/src/emu/render.cpp +++ b/src/emu/render.cpp @@ -1097,7 +1097,7 @@ unsigned render_target::configured_view(const char *viewname, int targetindex, i screen_device const &screen = screens[index() % screens.size()]; for (unsigned i = 0; !view && (m_views.size() > i); ++i) { - for (layout_view::item &viewitem : m_views[i].first.items()) + for (layout_view_item &viewitem : m_views[i].first.items()) { screen_device const *const viewscreen(viewitem.screen()); if (viewscreen == &screen) @@ -1286,7 +1286,7 @@ 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 (layout_view::item &curitem : current_view().items()) + for (layout_view_item &curitem : current_view().items()) { screen_device const *const screen = curitem.screen(); if (screen) @@ -1370,7 +1370,7 @@ render_primitive_list &render_target::get_primitives() { // we're running - iterate over items in the view current_view().prepare_items(); - for (layout_view::item &curitem : current_view().visible_items()) + for (layout_view_item &curitem : current_view().visible_items()) { // first apply orientation to the bounds render_bounds bounds = curitem.bounds(); @@ -1391,7 +1391,7 @@ render_primitive_list &render_target::get_primitives() if (curitem.screen()) add_container_primitives(list, root_xform, item_xform, curitem.screen()->container(), curitem.blend_mode()); else - add_element_primitives(list, item_xform, *curitem.element(), curitem.element_state(), curitem.blend_mode()); + add_element_primitives(list, item_xform, curitem); } } else @@ -1494,10 +1494,10 @@ bool render_target::map_point_container(s32 target_x, s32 target_y, render_conta auto const found(std::find_if( items.begin(), items.end(), - [&container] (layout_view::item &item) { return &item.screen()->container() == &container; })); + [&container] (layout_view_item &item) { return &item.screen()->container() == &container; })); if (items.end() != found) { - layout_view::item &item(*found); + layout_view_item &item(*found); render_bounds const bounds(item.bounds()); if (bounds.includes(target_f.first, target_f.second)) { @@ -1555,7 +1555,7 @@ bool render_target::map_point_input(s32 target_x, s32 target_y, ioport_port *&in { if (m_hit_test[i] && m_hit_test[items.size() + i]) { - layout_view::item &item(items[i]); + layout_view_item &item(items[i]); render_bounds const bounds(item.bounds()); if (bounds.includes(target_f.first, target_f.second)) { @@ -2523,11 +2523,13 @@ void render_target::add_container_primitives(render_primitive_list &list, const // for an element in the current state //------------------------------------------------- -void render_target::add_element_primitives(render_primitive_list &list, const object_transform &xform, layout_element &element, int state, int blendmode) +void render_target::add_element_primitives(render_primitive_list &list, const object_transform &xform, layout_view_item &item) { + layout_element &element(*item.element()); + int const blendmode(item.blend_mode()); + // limit state range to non-negative values - if (state < 0) - state = 0; + int const state((std::max)(item.element_state(), 0)); // get a pointer to the relevant texture render_texture *texture = element.state_texture(state); @@ -2537,29 +2539,70 @@ void render_target::add_element_primitives(render_primitive_list &list, const ob // configure the basics prim->color = xform.color; - prim->flags = PRIMFLAG_TEXORIENT(xform.orientation) | PRIMFLAG_BLENDMODE(blendmode) | PRIMFLAG_TEXFORMAT(texture->format()); + prim->flags = + PRIMFLAG_TEXORIENT(xform.orientation) | + PRIMFLAG_TEXFORMAT(texture->format()) | + PRIMFLAG_BLENDMODE(blendmode) | + PRIMFLAG_TEXWRAP((item.scroll_wrap_x() || item.scroll_wrap_y()) ? 1 : 0); // compute the bounds - s32 width = render_round_nearest(xform.xscale); - s32 height = render_round_nearest(xform.yscale); - prim->bounds.set_wh(render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), float(width), float(height)); + float const primwidth(render_round_nearest(xform.xscale)); + float const primheight(render_round_nearest(xform.yscale)); + prim->bounds.set_wh(render_round_nearest(xform.xoffs), render_round_nearest(xform.yoffs), primwidth, primheight); prim->full_bounds = prim->bounds; - if (xform.orientation & ORIENTATION_SWAP_XY) - std::swap(width, height); - width = (std::min)(width, m_maxtexwidth); - height = (std::min)(height, m_maxtexheight); // get the scaled texture and append it - texture->get_scaled(width, height, prim->texture, list, prim->flags); + float const xsize(item.scroll_size_x()); + float const ysize(item.scroll_size_y()); + s32 texwidth = render_round_nearest(((xform.orientation & ORIENTATION_SWAP_XY) ? primwidth : primheight) / xsize); + s32 texheight = render_round_nearest(((xform.orientation & ORIENTATION_SWAP_XY) ? primheight : primwidth) / ysize); + texwidth = (std::min)(texwidth, m_maxtexwidth); + texheight = (std::min)(texheight, m_maxtexheight); + texture->get_scaled(texwidth, texheight, prim->texture, list, prim->flags); // compute the clip rect render_bounds cliprect = prim->bounds & m_bounds; // determine UV coordinates and apply clipping - prim->texcoords = oriented_texcoords[xform.orientation]; - bool clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); + float const xwindow((xform.orientation & ORIENTATION_SWAP_XY) ? primwidth : primheight); + float const ywindow((xform.orientation & ORIENTATION_SWAP_XY) ? primheight : primwidth); + float const xrange(float(texwidth) - (item.scroll_wrap_x() ? 0.0f : xwindow)); + float const yrange(float(texheight) - (item.scroll_wrap_y() ? 0.0f : ywindow)); + float const xoffset(render_round_nearest(item.scroll_pos_x() * xrange) / float(texwidth)); + float const yoffset(render_round_nearest(item.scroll_pos_y() * yrange) / float(texheight)); + float const xend(xoffset + (xwindow / float(texwidth))); + float const yend(yoffset + (ywindow / float(texheight))); + switch (xform.orientation) + { + default: + case 0: + prim->texcoords = render_quad_texuv{ { xoffset, yoffset }, { xend, yoffset }, { xoffset, yend }, { xend, yend } }; + break; + case ORIENTATION_FLIP_X: + prim->texcoords = render_quad_texuv{ { xend, yoffset }, { xoffset, yoffset }, { xend, yend }, { xoffset, yend } }; + break; + case ORIENTATION_FLIP_Y: + prim->texcoords = render_quad_texuv{ { xoffset, yend }, { xend, yend }, { xoffset, yoffset }, { xend, yoffset } }; + break; + case ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y: + prim->texcoords = render_quad_texuv{ { xend, yend }, { xoffset, yend }, { xend, yoffset }, { xoffset, yoffset } }; + break; + case ORIENTATION_SWAP_XY: + prim->texcoords = render_quad_texuv{ { xoffset, yoffset }, { xoffset, yend }, { xend, yoffset }, { xend, yend } }; + break; + case ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X: + prim->texcoords = render_quad_texuv{ { xoffset, yend }, { xoffset, yoffset }, { xend, yend }, { xend, yoffset } }; + break; + case ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y: + prim->texcoords = render_quad_texuv{ { xend, yoffset }, { xend, yend }, { xoffset, yoffset }, { xoffset, yend } }; + break; + case ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y: + prim->texcoords = render_quad_texuv{ { xend, yend }, { xend, yoffset }, { xoffset, yend }, { xoffset, yoffset } }; + break; + } // add to the list or free if we're clipped out + bool const clipped = render_clip_quad(&prim->bounds, &cliprect, &prim->texcoords); list.append_or_return(*prim, clipped); } } |