summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/rendlay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/rendlay.cpp')
-rw-r--r--src/emu/rendlay.cpp417
1 files changed, 253 insertions, 164 deletions
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 2c4057501d6..b47d643e254 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -20,6 +20,7 @@
#include <ctype.h>
#include <algorithm>
+#include <cmath>
#include <cstddef>
#include <cstdio>
#include <cstring>
@@ -69,23 +70,26 @@ enum
std::locale const f_portable_locale("C");
+constexpr layout_group::transform identity_transform{{ {{ 1.0F, 0.0F, 0.0F }}, {{ 0.0F, 1.0F, 0.0F }}, {{ 0.0F, 0.0F, 1.0F }} }};
+
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
-//-------------------------------------------------
-// render_bounds_transform - apply translation/
-// scaling
-//-------------------------------------------------
+inline void render_bounds_transform(render_bounds &bounds, layout_group::transform const &trans)
+{
+ bounds = render_bounds{
+ (bounds.x0 * trans[0][0]) + (bounds.y0 * trans[0][1]) + trans[0][2],
+ (bounds.x0 * trans[1][0]) + (bounds.y0 * trans[1][1]) + trans[1][2],
+ (bounds.x1 * trans[0][0]) + (bounds.y1 * trans[0][1]) + trans[0][2],
+ (bounds.x1 * trans[1][0]) + (bounds.y1 * trans[1][1]) + trans[1][2] };
+}
-inline void render_bounds_transform(render_bounds &bounds, render_bounds const &transform)
+constexpr render_color render_color_multiply(render_color const &x, render_color const &y)
{
- 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;
+ return render_color{ x.a * y.a, x.r * y.r, x.g * y.g, x.b * y.b };
}
@@ -129,7 +133,7 @@ private:
, m_int_increment(i)
, m_shift(s)
, m_text_valid(true)
- , m_incrementing(true)
+ , m_generator(true)
{ }
entry(std::string &&name, std::string &&t, double i, int s)
: m_name(std::move(name))
@@ -137,7 +141,7 @@ private:
, m_float_increment(i)
, m_shift(s)
, m_text_valid(true)
- , m_incrementing(true)
+ , m_generator(true)
{ }
entry(entry &&) = default;
entry &operator=(entry &&) = default;
@@ -165,7 +169,7 @@ private:
}
std::string const &name() const { return m_name; }
- bool is_incrementing() const { return m_incrementing; }
+ bool is_generator() const { return m_generator; }
std::string const &get_text()
{
@@ -187,7 +191,7 @@ private:
void increment()
{
- if (is_incrementing())
+ if (is_generator())
{
// apply increment
if (m_float_increment)
@@ -342,7 +346,7 @@ private:
bool m_text_valid = false;
bool m_int_valid = false;
bool m_float_valid = false;
- bool m_incrementing = false;
+ bool m_generator = false;
};
using entry_vector = std::vector<entry>;
@@ -631,7 +635,7 @@ public:
throw layout_syntax_error("increment attribute must be a number");
}
- // don't allow incrementing parameters to be redefined
+ // don't allow generator parameters to be redefined
if (init)
{
entry_vector::iterator const pos(
@@ -641,7 +645,7 @@ public:
name,
[] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
if ((m_entries.end() != pos) && (pos->name() == name))
- throw layout_syntax_error("incrementing parameters must be defined exactly once per scope");
+ throw layout_syntax_error("generator parameters must be defined exactly once per scope");
std::pair<char const *, char const *> const expanded(expand(start));
if (floatincrement)
@@ -668,8 +672,8 @@ public:
[] (entry const &lhs, auto const &rhs) { return lhs.name() < rhs; }));
if ((m_entries.end() == pos) || (pos->name() != name))
m_entries.emplace(pos, std::move(name), std::string(expanded.first, expanded.second));
- else if (pos->is_incrementing())
- throw layout_syntax_error("incrementing parameters must be defined exactly once per scope");
+ else if (pos->is_generator())
+ throw layout_syntax_error("generator parameters must be defined exactly once per scope");
else
pos->set(std::string(expanded.first, expanded.second));
}
@@ -677,8 +681,18 @@ public:
void increment_parameters()
{
- for (entry &e : m_entries)
- e.increment();
+ m_entries.erase(
+ std::remove_if(
+ m_entries.begin(),
+ m_entries.end(),
+ [] (entry &e)
+ {
+ if (!e.is_generator())
+ return true;
+ e.increment();
+ return false;
+ }),
+ m_entries.end());
}
char const *get_attribute_string(util::xml::data_node const &node, char const *name, char const *defvalue)
@@ -778,53 +792,50 @@ public:
}
}
- void parse_color(util::xml::data_node const *node, render_color &result)
+ render_color parse_color(util::xml::data_node const *node)
{
- // default to white
+ // default to opaque white
if (!node)
- {
- result.r = result.g = result.b = result.a = 1.0F;
- }
- else
- {
- // parse attributes
- result.r = get_attribute_float(*node, "red", 1.0F);
- result.g = get_attribute_float(*node, "green", 1.0F);
- result.b = get_attribute_float(*node, "blue", 1.0F);
- result.a = get_attribute_float(*node, "alpha", 1.0F);
+ return render_color{ 1.0F, 1.0F, 1.0F, 1.0F };
- // check for errors
- if ((0.0F > (std::min)({ result.r, result.g, result.b, result.a })) || (1.0F < (std::max)({ result.r, result.g, result.b, result.a })))
- throw layout_syntax_error(util::string_format("illegal RGBA color %f,%f,%f,%f", result.r, result.g, result.b, result.a));
- }
+ // parse attributes
+ render_color const result{
+ get_attribute_float(*node, "alpha", 1.0F),
+ get_attribute_float(*node, "red", 1.0F),
+ get_attribute_float(*node, "green", 1.0F),
+ get_attribute_float(*node, "blue", 1.0F) };
+
+ // check for errors
+ if ((0.0F > (std::min)({ result.r, result.g, result.b, result.a })) || (1.0F < (std::max)({ result.r, result.g, result.b, result.a })))
+ throw layout_syntax_error(util::string_format("illegal RGBA color %f,%f,%f,%f", result.r, result.g, result.b, result.a));
+
+ return result;
}
- void parse_orientation(util::xml::data_node const *node, int &result)
+ int parse_orientation(util::xml::data_node const *node)
{
// default to no transform
if (!node)
- {
- result = ROT0;
- }
- else
- {
- // parse attributes
- int const rotate(get_attribute_int(*node, "rotate", 0));
- switch (rotate)
- {
- case 0: result = ROT0; break;
- case 90: result = ROT90; break;
- case 180: result = ROT180; break;
- case 270: result = ROT270; break;
- default: throw layout_syntax_error(util::string_format("invalid rotate attribute %d", rotate));
- }
- if (!std::strcmp("yes", get_attribute_string(*node, "swapxy", "no")))
- result ^= ORIENTATION_SWAP_XY;
- if (!std::strcmp("yes", get_attribute_string(*node, "flipx", "no")))
- result ^= ORIENTATION_FLIP_X;
- if (!std::strcmp("yes", get_attribute_string(*node, "flipy", "no")))
- result ^= ORIENTATION_FLIP_Y;
- }
+ return ROT0;
+
+ // parse attributes
+ int result;
+ int const rotate(get_attribute_int(*node, "rotate", 0));
+ switch (rotate)
+ {
+ case 0: result = ROT0; break;
+ case 90: result = ROT90; break;
+ case 180: result = ROT180; break;
+ case 270: result = ROT270; break;
+ default: throw layout_syntax_error(util::string_format("invalid rotate attribute %d", rotate));
+ }
+ if (!std::strcmp("yes", get_attribute_string(*node, "swapxy", "no")))
+ result ^= ORIENTATION_SWAP_XY;
+ if (!std::strcmp("yes", get_attribute_string(*node, "flipx", "no")))
+ result ^= ORIENTATION_FLIP_X;
+ if (!std::strcmp("yes", get_attribute_string(*node, "flipy", "no")))
+ result ^= ORIENTATION_FLIP_Y;
+ return result;
}
};
@@ -955,25 +966,65 @@ layout_group::~layout_group()
// matrix for given destination bounds
//-------------------------------------------------
-render_bounds layout_group::make_transform(render_bounds const &dest) const
+layout_group::transform layout_group::make_transform(int orientation, render_bounds const &dest) const
+{
+ assert(m_bounds_resolved);
+
+ // make orientation matrix
+ transform result{{ {{ 1.0F, 0.0F, 0.0F }}, {{ 0.0F, 1.0F, 0.0F }}, {{ 0.0F, 0.0F, 1.0F }} }};
+ if (orientation & ORIENTATION_SWAP_XY)
+ {
+ std::swap(result[0][0], result[0][1]);
+ std::swap(result[1][0], result[1][1]);
+ }
+ if (orientation & ORIENTATION_FLIP_X)
+ {
+ result[0][0] = -result[0][0];
+ result[0][1] = -result[0][1];
+ }
+ if (orientation & ORIENTATION_FLIP_Y)
+ {
+ result[1][0] = -result[1][0];
+ result[1][1] = -result[1][1];
+ }
+
+ // apply to bounds and force into destination rectangle
+ render_bounds bounds(m_bounds);
+ render_bounds_transform(bounds, result);
+ result[0][0] *= (dest.x1 - dest.x0) / std::fabs(bounds.x1 - bounds.x0);
+ result[0][1] *= (dest.x1 - dest.x0) / std::fabs(bounds.x1 - bounds.x0);
+ result[0][2] = dest.x0 - ((std::min)(bounds.x0, bounds.x1) * (dest.x1 - dest.x0) / std::fabs(bounds.x1 - bounds.x0));
+ result[1][0] *= (dest.y1 - dest.y0) / std::fabs(bounds.y1 - bounds.y0);
+ result[1][1] *= (dest.y1 - dest.y0) / std::fabs(bounds.y1 - bounds.y0);
+ result[1][2] = dest.y0 - ((std::min)(bounds.y0, bounds.y1) * (dest.y1 - dest.y0) / std::fabs(bounds.y1 - bounds.y0));
+ return result;
+}
+
+layout_group::transform layout_group::make_transform(int orientation, transform const &trans) 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 const dest{
+ m_bounds.x0,
+ m_bounds.y0,
+ (orientation & ORIENTATION_SWAP_XY) ? (m_bounds.x0 + m_bounds.y1 - m_bounds.y0) : m_bounds.x1,
+ (orientation & ORIENTATION_SWAP_XY) ? (m_bounds.y0 + m_bounds.x1 - m_bounds.x0) : m_bounds.y1 };
+ return make_transform(orientation, dest, trans);
}
-render_bounds layout_group::make_transform(render_bounds const &dest, render_bounds const &transform) const
+layout_group::transform layout_group::make_transform(int orientation, render_bounds const &dest, transform const &trans) 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 };
+ transform const next(make_transform(orientation, dest));
+ transform result{{ {{ 0.0F, 0.0F, 0.0F }}, {{ 0.0F, 0.0F, 0.0F }}, {{ 0.0F, 0.0F, 0.0F }} }};
+ for (unsigned y = 0; 3U > y; ++y)
+ {
+ for (unsigned x = 0; 3U > x; ++x)
+ {
+ for (unsigned i = 0; 3U > i; ++i)
+ result[y][x] += trans[y][i] * next[i][x];
+ }
+ }
+ return result;
}
@@ -1003,8 +1054,8 @@ void layout_group::resolve_bounds(environment &env, group_map &groupmap, std::ve
// 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();
+ path << ' ' << group->m_groupnode.get_attribute_string("name", nullptr);
+ path << ' ' << m_groupnode.get_attribute_string("name", nullptr);
throw layout_syntax_error(util::string_format("recursively nested groups %s", path.str()));
}
@@ -1014,6 +1065,7 @@ void layout_group::resolve_bounds(environment &env, group_map &groupmap, std::ve
environment local(env);
resolve_bounds(local, m_groupnode, groupmap, seen, false, true);
}
+ seen.pop_back();
}
void layout_group::resolve_bounds(
@@ -1061,17 +1113,33 @@ void layout_group::resolve_bounds(
}
else if (!strcmp(itemnode->get_name(), "group"))
{
- char const *ref(env.get_attribute_string(*itemnode, "ref", nullptr));
- if (!ref)
- throw layout_syntax_error("nested group must have ref attribute");
-
- group_map::iterator const found(groupmap.find(ref));
- if (groupmap.end() == found)
- throw layout_syntax_error(util::string_format("unable to find group %s", ref));
-
- environment local(env);
- found->second.resolve_bounds(local, groupmap, seen);
- union_render_bounds(m_bounds, found->second.m_bounds);
+ util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds"));
+ if (itemboundsnode)
+ {
+ render_bounds itembounds;
+ env.parse_bounds(itemboundsnode, itembounds);
+ union_render_bounds(m_bounds, itembounds);
+ }
+ else
+ {
+ char const *ref(env.get_attribute_string(*itemnode, "ref", nullptr));
+ if (!ref)
+ throw layout_syntax_error("nested group must have ref attribute");
+
+ group_map::iterator const found(groupmap.find(ref));
+ if (groupmap.end() == found)
+ throw layout_syntax_error(util::string_format("unable to find group %s", ref));
+
+ int const orientation(env.parse_orientation(itemnode->get_child("orientation")));
+ environment local(env);
+ found->second.resolve_bounds(local, groupmap, seen);
+ render_bounds const itembounds{
+ found->second.m_bounds.x0,
+ found->second.m_bounds.y0,
+ (orientation & ORIENTATION_SWAP_XY) ? (found->second.m_bounds.x0 + found->second.m_bounds.y1 - found->second.m_bounds.y0) : found->second.m_bounds.x1,
+ (orientation & ORIENTATION_SWAP_XY) ? (found->second.m_bounds.y0 + found->second.m_bounds.x1 - found->second.m_bounds.x0) : found->second.m_bounds.y1 };
+ union_render_bounds(m_bounds, itembounds);
+ }
}
else if (!strcmp(itemnode->get_name(), "repeat"))
{
@@ -1139,11 +1207,11 @@ void layout_element::element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, c
if (curcomp->state() == -1 || curcomp->state() == elemtex->m_state)
{
// get the local scaled bounds
- rectangle bounds;
- bounds.min_x = render_round_nearest(curcomp->bounds().x0 * dest.width());
- bounds.min_y = render_round_nearest(curcomp->bounds().y0 * dest.height());
- bounds.max_x = render_round_nearest(curcomp->bounds().x1 * dest.width());
- bounds.max_y = render_round_nearest(curcomp->bounds().y1 * dest.height());
+ rectangle bounds(
+ render_round_nearest(curcomp->bounds().x0 * dest.width()),
+ render_round_nearest(curcomp->bounds().x1 * dest.width()),
+ render_round_nearest(curcomp->bounds().y0 * dest.height()),
+ render_round_nearest(curcomp->bounds().y1 * dest.height()));
bounds &= dest.cliprect();
// based on the component type, add to the texture
@@ -1188,24 +1256,24 @@ private:
ru_imgformat const format = render_detect_image(*m_file, m_dirname.c_str(), m_imagefile.c_str());
switch (format)
{
- case RENDUTIL_IMGFORMAT_ERROR:
- break;
-
- case RENDUTIL_IMGFORMAT_PNG:
- // load the basic bitmap
- m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ case RENDUTIL_IMGFORMAT_ERROR:
+ break;
- // load the alpha bitmap if specified
- if (m_bitmap.valid() && !m_alphafile.empty())
- render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_alphafile.c_str(), true);
- break;
+ case RENDUTIL_IMGFORMAT_PNG:
+ // load the basic bitmap
+ m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ break;
- default:
- // try JPG
- render_load_jpeg(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
- break;
+ default:
+ // try JPG
+ render_load_jpeg(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ break;
}
+ // load the alpha bitmap if specified
+ if (m_bitmap.valid() && !m_alphafile.empty())
+ render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_alphafile.c_str(), true);
+
// if we can't load the bitmap, allocate a dummy one and report an error
if (!m_bitmap.valid())
{
@@ -1255,9 +1323,9 @@ protected:
u32 const inva = (1.0f - color().a) * 255.0f;
// iterate over X and Y
- for (u32 y = bounds.min_y; y <= bounds.max_y; y++)
+ for (u32 y = bounds.top(); y <= bounds.bottom(); y++)
{
- for (u32 x = bounds.min_x; x <= bounds.max_x; x++)
+ for (u32 x = bounds.left(); x <= bounds.right(); x++)
{
u32 finalr = r;
u32 finalg = g;
@@ -1308,7 +1376,7 @@ protected:
float const ooyradius2 = 1.0f / (yradius * yradius);
// iterate over y
- for (u32 y = bounds.min_y; y <= bounds.max_y; y++)
+ for (u32 y = bounds.top(); y <= bounds.bottom(); y++)
{
float ycoord = ycenter - ((float)y + 0.5f);
float xval = xradius * sqrtf(1.0f - (ycoord * ycoord) * ooyradius2);
@@ -1399,31 +1467,31 @@ protected:
tempbitmap.fill(rgb_t(0xff,0x00,0x00,0x00));
// top bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 0)) ? onpen : offpen);
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, BIT(state, 0) ? onpen : offpen);
// top-right bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 1)) ? onpen : offpen);
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, BIT(state, 1) ? onpen : offpen);
// bottom-right bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 2)) ? onpen : offpen);
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, BIT(state, 2) ? onpen : offpen);
// bottom bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (state & (1 << 3)) ? onpen : offpen);
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, BIT(state, 3) ? onpen : offpen);
// bottom-left bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 4)) ? onpen : offpen);
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, BIT(state, 4) ? onpen : offpen);
// top-left bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 5)) ? onpen : offpen);
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, BIT(state, 5) ? onpen : offpen);
// middle bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight/2, segwidth, BIT(state, 6) ? onpen : offpen);
// apply skew
apply_skew(tempbitmap, 40);
// decimal point
- draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 7)) ? onpen : offpen);
+ draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, BIT(state, 7) ? onpen : offpen);
// resample to the target size
render_resample_argb_bitmap_hq(dest, tempbitmap, color());
@@ -2014,7 +2082,7 @@ protected:
tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
for (int i = 0; i < m_dots; i++)
- draw_segment_decimal(tempbitmap, ((dotwidth/2 )+ (i * dotwidth)), bmheight/2, dotwidth, (state & (1 << i))?onpen:offpen);
+ draw_segment_decimal(tempbitmap, ((dotwidth / 2) + (i * dotwidth)), bmheight / 2, dotwidth, BIT(state, i) ? onpen : offpen);
// resample to the target size
render_resample_argb_bitmap_hq(dest, tempbitmap, color());
@@ -2155,25 +2223,25 @@ protected:
{
int basey;
- if (m_reelreversed==1)
+ if (m_reelreversed)
{
- basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
+ basey = bounds.top() + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
}
else
{
- basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
+ basey = bounds.top() - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
}
// wrap around...
- if (basey < bounds.min_y)
+ if (basey < bounds.top())
basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
- if (basey > bounds.max_y)
+ if (basey > bounds.bottom())
basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
int endpos = basey+ourheight/num_shown;
// only render the symbol / text if it's atually in view because the code is SLOW
- if ((endpos >= bounds.min_y) && (basey <= bounds.max_y))
+ if ((endpos >= bounds.top()) && (basey <= bounds.bottom()))
{
while (1)
{
@@ -2184,7 +2252,7 @@ protected:
}
s32 curx;
- curx = bounds.min_x + (bounds.width() - width) / 2;
+ curx = bounds.left() + (bounds.width() - width) / 2;
if (m_file[fruit])
if (!m_bitmap[fruit].valid())
@@ -2202,14 +2270,14 @@ protected:
{
int effy = basey + y;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ if (effy >= bounds.top() && effy <= bounds.bottom())
{
u32 *src = &tempbitmap2.pix32(y);
u32 *d = &dest.pix32(effy);
for (int x = 0; x < dest.width(); x++)
{
int effx = x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ if (effx >= bounds.left() && effx <= bounds.right())
{
u32 spix = rgb_t(src[x]).a();
if (spix != 0)
@@ -2249,14 +2317,14 @@ protected:
{
int effy = basey + y;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ if (effy >= bounds.top() && effy <= bounds.bottom())
{
u32 *src = &tempbitmap.pix32(y);
u32 *d = &dest.pix32(effy);
for (int x = 0; x < chbounds.width(); x++)
{
- int effx = curx + x + chbounds.min_x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ int effx = curx + x + chbounds.left();
+ if (effx >= bounds.left() && effx <= bounds.right())
{
u32 spix = rgb_t(src[x]).a();
if (spix != 0)
@@ -2324,15 +2392,15 @@ private:
}
// wrap around...
- if (basex < bounds.min_x)
+ if (basex < bounds.left())
basex += ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
- if (basex > bounds.max_x)
+ if (basex > bounds.right())
basex -= ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
int endpos = basex+(ourwidth/num_shown);
// only render the symbol / text if it's atually in view because the code is SLOW
- if ((endpos >= bounds.min_x) && (basex <= bounds.max_x))
+ if ((endpos >= bounds.left()) && (basex <= bounds.right()))
{
while (1)
{
@@ -2343,7 +2411,7 @@ private:
}
s32 curx;
- curx = bounds.min_x;
+ curx = bounds.left();
if (m_file[fruit])
if (!m_bitmap[fruit].valid())
@@ -2361,14 +2429,14 @@ private:
{
int effy = y;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ if (effy >= bounds.top() && effy <= bounds.bottom())
{
u32 *src = &tempbitmap2.pix32(y);
u32 *d = &dest.pix32(effy);
for (int x = 0; x < ourwidth/num_shown; x++)
{
int effx = basex + x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ if (effx >= bounds.left() && effx <= bounds.right())
{
u32 spix = rgb_t(src[x]).a();
if (spix != 0)
@@ -2410,14 +2478,14 @@ private:
{
int effy = y;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ if (effy >= bounds.top() && effy <= bounds.bottom())
{
u32 *src = &tempbitmap.pix32(y);
u32 *d = &dest.pix32(effy);
for (int x = 0; x < chbounds.width(); x++)
{
int effx = basex + curx + x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ if (effx >= bounds.left() && effx <= bounds.right())
{
u32 spix = rgb_t(src[x]).a();
if (spix != 0)
@@ -2566,12 +2634,10 @@ layout_element::texture &layout_element::texture::operator=(texture &&that)
//-------------------------------------------------
layout_element::component::component(environment &env, util::xml::data_node const &compnode, const char *dirname)
- : m_state(0)
+ : m_state(env.get_attribute_int(compnode, "state", -1))
+ , m_color(env.parse_color(compnode.get_child("color")))
{
- // fetch common data
- m_state = env.get_attribute_int(compnode, "state", -1);
env.parse_bounds(compnode.get_child("bounds"), m_bounds);
- env.parse_color(compnode.get_child("color"), m_color);
}
@@ -2618,17 +2684,17 @@ void layout_element::component::draw_text(render_font &font, bitmap_argb32 &dest
{
// left
case 1:
- curx = bounds.min_x;
+ curx = bounds.left();
break;
// right
case 2:
- curx = bounds.max_x - width;
+ curx = bounds.right() - width;
break;
// default to center
default:
- curx = bounds.min_x + (bounds.width() - width) / 2;
+ curx = bounds.left() + (bounds.width() - width) / 2;
break;
}
@@ -2656,15 +2722,15 @@ void layout_element::component::draw_text(render_font &font, bitmap_argb32 &dest
// copy the data into the target
for (int y = 0; y < chbounds.height(); y++)
{
- int effy = bounds.min_y + y;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ int effy = bounds.top() + y;
+ if (effy >= bounds.top() && effy <= bounds.bottom())
{
u32 *src = &tempbitmap.pix32(y);
u32 *d = &dest.pix32(effy);
for (int x = 0; x < chbounds.width(); x++)
{
- int effx = curx + x + chbounds.min_x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ int effx = curx + x + chbounds.left();
+ if (effx >= bounds.left() && effx <= bounds.right())
{
u32 spix = rgb_t(src[x]).a();
if (spix != 0)
@@ -2894,7 +2960,7 @@ layout_view::layout_view(
m_expbounds.x0 = m_expbounds.y0 = m_expbounds.x1 = m_expbounds.y1 = 0;
environment local(env);
local.set_parameter("viewname", std::string(m_name));
- add_items(local, viewnode, elemmap, groupmap, render_bounds{ 0.0f, 0.0f, 1.0f, 1.0f }, true, false, true);
+ add_items(local, viewnode, elemmap, groupmap, ROT0, identity_transform, render_color{ 1.0F, 1.0F, 1.0F, 1.0F }, true, false, true);
recompute(render_layer_config());
for (group_map::value_type &group : groupmap)
group.second.set_bounds_unresolved();
@@ -3055,7 +3121,9 @@ void layout_view::add_items(
util::xml::data_node const &parentnode,
element_map &elemmap,
group_map &groupmap,
- render_bounds const &transform,
+ int orientation,
+ layout_group::transform const &trans,
+ render_color const &color,
bool root,
bool repeat,
bool init)
@@ -3086,27 +3154,27 @@ void layout_view::add_items(
}
else if (!strcmp(itemnode->get_name(), "backdrop"))
{
- m_backdrop_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_backdrop_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "screen"))
{
- m_screen_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_screen_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "overlay"))
{
- m_overlay_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_overlay_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "bezel"))
{
- m_bezel_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_bezel_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "cpanel"))
{
- m_cpanel_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_cpanel_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "marquee"))
{
- m_marquee_list.emplace_back(env, *itemnode, elemmap, transform);
+ m_marquee_list.emplace_back(env, *itemnode, elemmap, orientation, trans, color);
}
else if (!strcmp(itemnode->get_name(), "group"))
{
@@ -3120,17 +3188,33 @@ void layout_view::add_items(
unresolved = false;
found->second.resolve_bounds(env, groupmap);
- render_bounds grouptrans(transform);
+ layout_group::transform grouptrans(trans);
util::xml::data_node const *const itemboundsnode(itemnode->get_child("bounds"));
+ util::xml::data_node const *const itemorientnode(itemnode->get_child("orientation"));
+ int const grouporient(env.parse_orientation(itemorientnode));
if (itemboundsnode)
{
render_bounds itembounds;
env.parse_bounds(itemboundsnode, itembounds);
- grouptrans = found->second.make_transform(itembounds, transform);
+ grouptrans = found->second.make_transform(grouporient, itembounds, trans);
+ }
+ else if (itemorientnode)
+ {
+ grouptrans = found->second.make_transform(grouporient, trans);
}
environment local(env);
- add_items(local, found->second.get_groupnode(), elemmap, groupmap, grouptrans, false, false, true);
+ add_items(
+ local,
+ found->second.get_groupnode(),
+ elemmap,
+ groupmap,
+ orientation_add(grouporient, orientation),
+ grouptrans,
+ render_color_multiply(env.parse_color(itemnode->get_child("color")), color),
+ false,
+ false,
+ true);
}
else if (!strcmp(itemnode->get_name(), "repeat"))
{
@@ -3140,7 +3224,7 @@ void layout_view::add_items(
environment local(env);
for (int i = 0; count > i; ++i)
{
- add_items(local, *itemnode, elemmap, groupmap, transform, false, true, !i);
+ add_items(local, *itemnode, elemmap, groupmap, orientation, trans, color, false, true, !i);
local.increment_parameters();
}
}
@@ -3190,7 +3274,9 @@ layout_view::item::item(
environment &env,
util::xml::data_node const &itemnode,
element_map &elemmap,
- render_bounds const &transform)
+ int orientation,
+ layout_group::transform const &trans,
+ render_color const &color)
: m_element(nullptr)
, m_output(env.device(), env.get_attribute_string(itemnode, "name", ""))
, m_have_output(env.get_attribute_string(itemnode, "name", "")[0])
@@ -3198,7 +3284,8 @@ layout_view::item::item(
, m_input_port(nullptr)
, m_input_mask(0)
, m_screen(nullptr)
- , m_orientation(ROT0)
+ , m_orientation(orientation_add(env.parse_orientation(itemnode.get_child("orientation")), orientation))
+ , m_color(render_color_multiply(env.parse_color(itemnode.get_child("color")), color))
{
// find the associated element
char const *const name(env.get_attribute_string(itemnode, "element", nullptr));
@@ -3224,9 +3311,11 @@ layout_view::item::item(
if (m_have_output && m_element)
m_output = m_element->default_state();
env.parse_bounds(itemnode.get_child("bounds"), m_rawbounds);
- render_bounds_transform(m_rawbounds, transform);
- env.parse_color(itemnode.get_child("color"), m_color);
- env.parse_orientation(itemnode.get_child("orientation"), m_orientation);
+ render_bounds_transform(m_rawbounds, trans);
+ if (m_rawbounds.x0 > m_rawbounds.x1)
+ std::swap(m_rawbounds.x0, m_rawbounds.x1);
+ if (m_rawbounds.y0 > m_rawbounds.y1)
+ std::swap(m_rawbounds.y0, m_rawbounds.y1);
// sanity checks
if (strcmp(itemnode.get_name(), "screen") == 0)