summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-07-28 17:29:42 +1000
committer Vas Crabb <vas@vastheman.com>2017-07-28 17:29:42 +1000
commit2dc60cf04b955d499636f90555ccd6829646a53d (patch)
tree579d759a74cfc085eab7596940e43641f77c6be1
parentc7e64a21d6b646a94ceb0bc12bad76217f1604d1 (diff)
reduce weight of render.h by moving component specialisation declarations into rendlay.cpp
-rw-r--r--src/emu/render.h247
-rw-r--r--src/emu/rendlay.cpp2357
2 files changed, 1219 insertions, 1385 deletions
diff --git a/src/emu/render.h b/src/emu/render.h
index ddb305ca5fa..30453397355 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -53,6 +53,7 @@
#include <memory>
#include <mutex>
#include <string>
+#include <unordered_map>
#include <vector>
@@ -628,16 +629,12 @@ DECLARE_ENUM_INCDEC_OPERATORS(item_layer)
// a layout_element is a single named element, which may have multiple components
class layout_element
{
- friend class simple_list<layout_element>;
-
public:
// construction/destruction
layout_element(running_machine &machine, util::xml::data_node const &elemnode, const char *dirname);
virtual ~layout_element();
// getters
- layout_element *next() const { return m_next; }
- const char *name() const { return m_name.c_str(); }
running_machine &machine() const { return m_machine; }
int default_state() const { return m_defstate; }
int maxstate() const { return m_maxstate; }
@@ -686,220 +683,20 @@ private:
render_color m_color; // color of the element
};
- // image
- class image_component : public component
- {
- public:
- // construction/destruction
- image_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
-
- private:
- // internal helpers
- void load_bitmap();
-
- // internal state
- bitmap_argb32 m_bitmap; // source bitmap for images
- std::string m_dirname; // directory name of image file (for lazy loading)
- std::unique_ptr<emu_file> m_file; // file object for reading image/alpha files
- std::string m_imagefile; // name of the image file (for lazy loading)
- std::string m_alphafile; // name of the alpha file (for lazy loading)
- bool m_hasalpha; // is there any alpha component present?
- };
-
- // rectangle
- class rect_component : public component
- {
- public:
- // construction/destruction
- rect_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // ellipse
- class disk_component : public component
- {
- public:
- // construction/destruction
- disk_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // text string
- class text_component : public component
- {
- public:
- // construction/destruction
- text_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
-
- private:
- // internal state
- std::string m_string; // string for text components
- int m_textalign; // text alignment to box
- };
-
- // 7-segment LCD
- class led7seg_component : public component
- {
- public:
- // construction/destruction
- led7seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 255; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // 8-segment fluorescent (Gottlieb System 1)
- class led8seg_gts1_component : public component
- {
- public:
- // construction/destruction
- led8seg_gts1_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 255; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // 14-segment LCD
- class led14seg_component : public component
- {
- public:
- // construction/destruction
- led14seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 16383; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // 16-segment LCD
- class led16seg_component : public component
- {
- public:
- // construction/destruction
- led16seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 65535; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // 14-segment LCD with semicolon (2 extra segments)
- class led14segsc_component : public component
- {
- public:
- // construction/destruction
- led14segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 65535; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // 16-segment LCD with semicolon (2 extra segments)
- class led16segsc_component : public component
- {
- public:
- // construction/destruction
- led16segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 262143; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
- };
-
- // row of dots for a dotmatrix
- class dotmatrix_component : public component
- {
- public:
- // construction/destruction
- dotmatrix_component(int dots, running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return (1 << m_dots) - 1; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
-
- private:
- // internal state
- int m_dots;
- };
-
- // simple counter
- class simplecounter_component : public component
- {
- public:
- // construction/destruction
- simplecounter_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return m_maxstate; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
-
- private:
- // internal state
- int m_digits; // number of digits for simple counters
- int m_textalign; // text alignment to box
- int m_maxstate;
- };
-
- // fruit machine reel
- class reel_component : public component
- {
- static constexpr unsigned MAX_BITMAPS = 32;
-
- public:
- // construction/destruction
- reel_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname);
-
- protected:
- // overrides
- virtual int maxstate() const override { return 65535; }
- virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override;
-
- private:
- // internal helpers
- void draw_beltreel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state);
- void load_reel_bitmap(int number);
-
- // internal state
- bitmap_argb32 m_bitmap[MAX_BITMAPS]; // source bitmap for images
- std::string m_dirname; // directory name of image file (for lazy loading)
- std::unique_ptr<emu_file> m_file[MAX_BITMAPS]; // file object for reading image/alpha files
- std::string m_imagefile[MAX_BITMAPS]; // name of the image file (for lazy loading)
- std::string m_alphafile[MAX_BITMAPS]; // name of the alpha file (for lazy loading)
- bool m_hasalpha[MAX_BITMAPS]; // is there any alpha component present?
-
- // basically made up of multiple text strings / gfx
- int m_numstops;
- std::string m_stopnames[MAX_BITMAPS];
- int m_stateoffset;
- int m_reelreversed;
- int m_numsymbolsvisible;
- int m_beltreel;
- };
+ // component implementations
+ class image_component;
+ class rect_component;
+ class disk_component;
+ class text_component;
+ class led7seg_component;
+ class led8seg_gts1_component;
+ class led14seg_component;
+ class led16seg_component;
+ class led14segsc_component;
+ class led16segsc_component;
+ class dotmatrix_component;
+ class simplecounter_component;
+ class reel_component;
// a texture encapsulates a texture for a given element in a given state
class texture
@@ -930,9 +727,7 @@ private:
static make_component_map const s_make_component; // maps component XML names to creator functions
// internal state
- layout_element * m_next; // link to next element
running_machine & m_machine; // reference to the owning machine
- std::string m_name; // name of this element
std::vector<component::ptr> m_complist; // list of components
int m_defstate; // default state of this element
int m_maxstate; // maximum state value for all components
@@ -948,6 +743,8 @@ 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
class item
{
@@ -956,7 +753,7 @@ public:
public:
// construction/destruction
- item(running_machine &machine, util::xml::data_node const &itemnode, simple_list<layout_element> &elemlist);
+ item(running_machine &machine, util::xml::data_node const &itemnode, element_map &elemmap);
virtual ~item();
// getters
@@ -992,7 +789,7 @@ public:
};
// construction/destruction
- layout_view(running_machine &machine, util::xml::data_node const &viewnode, simple_list<layout_element> &elemlist);
+ layout_view(running_machine &machine, util::xml::data_node const &viewnode, element_map &elemmap);
virtual ~layout_view();
// getters
@@ -1044,19 +841,21 @@ class layout_file
friend class simple_list<layout_file>;
public:
+ using element_map = std::unordered_map<std::string, layout_element>;
+
// construction/destruction
layout_file(running_machine &machine, util::xml::data_node const &rootnode, const char *dirname);
virtual ~layout_file();
// getters
layout_file *next() const { return m_next; }
- const simple_list<layout_element> &elements() const { return m_elemlist; }
+ const element_map &elements() const { return m_elemmap; }
const simple_list<layout_view> &views() const { return m_viewlist; }
private:
// internal state
layout_file * m_next; // pointer to the next file in the list
- simple_list<layout_element> m_elemlist; // list of shared layout elements
+ element_map m_elemmap; // list of shared layout elements
simple_list<layout_view> m_viewlist; // list of views
};
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 6023923179d..c1cc8040f7e 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -423,17 +423,10 @@ layout_element::make_component_map const layout_element::s_make_component{
//-------------------------------------------------
layout_element::layout_element(running_machine &machine, util::xml::data_node const &elemnode, const char *dirname)
- : m_next(nullptr),
- m_machine(machine),
- m_defstate(0),
- m_maxstate(0)
+ : m_machine(machine)
+ , m_defstate(0)
+ , m_maxstate(0)
{
- // extract the name
- const char *name = xml_get_attribute_string_with_subst(machine, elemnode, "name", nullptr);
- if (name == nullptr)
- throw emu_fatalerror("All layout elements must have a name!\n");
- m_name = name;
-
// get the default state
m_defstate = xml_get_attribute_int_with_subst(machine, elemnode, "defstate", -1);
@@ -534,1386 +527,1428 @@ void layout_element::element_scale(bitmap_argb32 &dest, bitmap_argb32 &source, c
}
-//-------------------------------------------------
-// make_component - create component of given type
-//-------------------------------------------------
-
-template <typename T>
-layout_element::component::ptr layout_element::make_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+// image
+class layout_element::image_component : public component
{
- return std::make_unique<T>(machine, compnode, dirname);
-}
+public:
+ // construction/destruction
+ image_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ , m_hasalpha(false)
+ {
+ if (dirname != nullptr)
+ m_dirname = dirname;
+ m_imagefile = xml_get_attribute_string_with_subst(machine, compnode, "file", "");
+ m_alphafile = xml_get_attribute_string_with_subst(machine, compnode, "alphafile", "");
+ m_file = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
+ }
+protected:
+ // overrides
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ if (!m_bitmap.valid())
+ load_bitmap();
-//-------------------------------------------------
-// make_component - create dotmatrix component
-// with given vertical resolution
-//-------------------------------------------------
+ bitmap_argb32 destsub(dest, bounds);
+ render_resample_argb_bitmap_hq(destsub, m_bitmap, color());
+ }
-template <int D>
-layout_element::component::ptr layout_element::make_dotmatrix_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
-{
- return std::make_unique<dotmatrix_component>(D, machine, compnode, dirname);
-}
+private:
+ // internal helpers
+ void load_bitmap()
+ {
+ // load the basic bitmap
+ assert(m_file != nullptr);
+ m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ // 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);
+ // PNG failed, let's try JPG
+ if (!m_bitmap.valid())
+ render_load_jpeg(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
-//**************************************************************************
-// LAYOUT ELEMENT TEXTURE
-//**************************************************************************
+ // if we can't load the bitmap, allocate a dummy one and report an error
+ if (!m_bitmap.valid())
+ {
+ // draw some stripes in the bitmap
+ m_bitmap.allocate(100, 100);
+ m_bitmap.fill(0);
+ for (int step = 0; step < 100; step += 25)
+ for (int line = 0; line < 100; line++)
+ m_bitmap.pix32((step + line) % 100, line % 100) = rgb_t(0xff,0xff,0xff,0xff);
+
+ // log an error
+ if (m_alphafile.empty())
+ osd_printf_warning("Unable to load component bitmap '%s'\n", m_imagefile.c_str());
+ else
+ osd_printf_warning("Unable to load component bitmap '%s'/'%s'\n", m_imagefile.c_str(), m_alphafile.c_str());
+ }
+ }
-//-------------------------------------------------
-// texture - constructors
-//-------------------------------------------------
+ // internal state
+ bitmap_argb32 m_bitmap; // source bitmap for images
+ std::string m_dirname; // directory name of image file (for lazy loading)
+ std::unique_ptr<emu_file> m_file; // file object for reading image/alpha files
+ std::string m_imagefile; // name of the image file (for lazy loading)
+ std::string m_alphafile; // name of the alpha file (for lazy loading)
+ bool m_hasalpha; // is there any alpha component present?
+};
-layout_element::texture::texture()
- : m_element(nullptr)
- , m_texture(nullptr)
- , m_state(0)
+
+// rectangle
+class layout_element::rect_component : public component
{
-}
+public:
+ // construction/destruction
+ rect_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ // compute premultiplied colors
+ u32 const r = color().r * color().a * 255.0f;
+ u32 const g = color().g * color().a * 255.0f;
+ u32 const b = color().b * color().a * 255.0f;
+ 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 x = bounds.min_x; x <= bounds.max_x; x++)
+ {
+ u32 finalr = r;
+ u32 finalg = g;
+ u32 finalb = b;
-layout_element::texture::texture(texture &&that) : texture()
-{
- operator=(std::move(that));
-}
+ // if we're translucent, add in the destination pixel contribution
+ if (inva > 0)
+ {
+ rgb_t dpix = dest.pix32(y, x);
+ finalr += (dpix.r() * inva) >> 8;
+ finalg += (dpix.g() * inva) >> 8;
+ finalb += (dpix.b() * inva) >> 8;
+ }
+ // store the target pixel, dividing the RGBA values by the overall scale factor
+ dest.pix32(y, x) = rgb_t(finalr, finalg, finalb);
+ }
+ }
+ }
+};
-//-------------------------------------------------
-// ~texture - destructor
-//-------------------------------------------------
-layout_element::texture::~texture()
+// ellipse
+class layout_element::disk_component : public component
{
- if (m_element != nullptr)
- m_element->machine().render().texture_free(m_texture);
-}
+public:
+ // construction/destruction
+ disk_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ // compute premultiplied colors
+ u32 const r = color().r * color().a * 255.0f;
+ u32 const g = color().g * color().a * 255.0f;
+ u32 const b = color().b * color().a * 255.0f;
+ u32 const inva = (1.0f - color().a) * 255.0f;
+
+ // find the center
+ float const xcenter = float(bounds.xcenter());
+ float const ycenter = float(bounds.ycenter());
+ float const xradius = float(bounds.width()) * 0.5f;
+ float const yradius = float(bounds.height()) * 0.5f;
+ float const ooyradius2 = 1.0f / (yradius * yradius);
+
+ // iterate over y
+ for (u32 y = bounds.min_y; y <= bounds.max_y; y++)
+ {
+ float ycoord = ycenter - ((float)y + 0.5f);
+ float xval = xradius * sqrtf(1.0f - (ycoord * ycoord) * ooyradius2);
-//-------------------------------------------------
-// opearator= - move assignment
-//-------------------------------------------------
+ // compute left/right coordinates
+ s32 left = s32(xcenter - xval + 0.5f);
+ s32 right = s32(xcenter + xval + 0.5f);
-layout_element::texture &layout_element::texture::operator=(texture &&that)
-{
- using std::swap;
- swap(m_element, that.m_element);
- swap(m_texture, that.m_texture);
- swap(m_state, that.m_state);
- return *this;
-}
+ // draw this scanline
+ for (u32 x = left; x < right; x++)
+ {
+ u32 finalr = r;
+ u32 finalg = g;
+ u32 finalb = b;
+ // if we're translucent, add in the destination pixel contribution
+ if (inva > 0)
+ {
+ rgb_t dpix = dest.pix32(y, x);
+ finalr += (dpix.r() * inva) >> 8;
+ finalg += (dpix.g() * inva) >> 8;
+ finalb += (dpix.b() * inva) >> 8;
+ }
+ // store the target pixel, dividing the RGBA values by the overall scale factor
+ dest.pix32(y, x) = rgb_t(finalr, finalg, finalb);
+ }
+ }
+ }
+};
-//**************************************************************************
-// LAYOUT ELEMENT COMPONENT
-//**************************************************************************
-//-------------------------------------------------
-// component - constructor
-//-------------------------------------------------
-
-layout_element::component::component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : m_state(0)
+// text string
+class layout_element::text_component : public component
{
- // fetch common data
- m_state = xml_get_attribute_int_with_subst(machine, compnode, "state", -1);
- parse_bounds(machine, compnode.get_child("bounds"), m_bounds);
- parse_color(machine, compnode.get_child("color"), m_color);
-}
+public:
+ // construction/destruction
+ text_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ m_string = xml_get_attribute_string_with_subst(machine, compnode, "string", "");
+ m_textalign = xml_get_attribute_int_with_subst(machine, compnode, "align", 0);
+ }
+protected:
+ // overrides
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ render_font *font = machine.render().font_alloc("default");
+ draw_text(*font, dest, bounds, m_string.c_str(), m_textalign);
+ machine.render().font_free(font);
+ }
-//-------------------------------------------------
-// normalize_bounds - normalize component bounds
-//-------------------------------------------------
+private:
+ // internal state
+ std::string m_string; // string for text components
+ int m_textalign; // text alignment to box
+};
-void layout_element::component::normalize_bounds(float xoffs, float yoffs, float xscale, float yscale)
+
+// 7-segment LCD
+class layout_element::led7seg_component : public component
{
- m_bounds.x0 = (m_bounds.x0 - xoffs) * xscale;
- m_bounds.x1 = (m_bounds.x1 - xoffs) * xscale;
- m_bounds.y0 = (m_bounds.y0 - yoffs) * yscale;
- m_bounds.y1 = (m_bounds.y1 - yoffs) * yscale;
-}
+public:
+ // construction/destruction
+ led7seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual int maxstate() const override { return 255; }
-//-------------------------------------------------
-// image_component - constructor
-//-------------------------------------------------
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff);
+ const rgb_t offpen = rgb_t(0xff,0x20,0x20,0x20);
-layout_element::image_component::image_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
- , m_hasalpha(false)
-{
- if (dirname != nullptr)
- m_dirname = dirname;
- m_imagefile = xml_get_attribute_string_with_subst(machine, compnode, "file", "");
- m_alphafile = xml_get_attribute_string_with_subst(machine, compnode, "alphafile", "");
- m_file = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
-}
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
+ tempbitmap.fill(rgb_t(0xff,0x00,0x00,0x00));
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
+ // top bar
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 0)) ? onpen : offpen);
-void layout_element::image_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- if (!m_bitmap.valid())
- load_bitmap();
+ // top-right bar
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 1)) ? onpen : offpen);
- bitmap_argb32 destsub(dest, bounds);
- render_resample_argb_bitmap_hq(destsub, m_bitmap, color());
-}
+ // bottom-right bar
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 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);
-//-------------------------------------------------
-// load_bitmap - load a PNG/JPG file with artwork for
-// a component
-//-------------------------------------------------
+ // bottom-left bar
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 4)) ? onpen : offpen);
-void layout_element::image_component::load_bitmap()
-{
- // load the basic bitmap
- assert(m_file != nullptr);
- m_hasalpha = render_load_png(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ // top-left bar
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 5)) ? onpen : offpen);
- // 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);
+ // middle bar
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
- // PNG failed, let's try JPG
- if (!m_bitmap.valid())
- render_load_jpeg(m_bitmap, *m_file, m_dirname.c_str(), m_imagefile.c_str());
+ // apply skew
+ apply_skew(tempbitmap, 40);
- // if we can't load the bitmap, allocate a dummy one and report an error
- if (!m_bitmap.valid())
- {
- // draw some stripes in the bitmap
- m_bitmap.allocate(100, 100);
- m_bitmap.fill(0);
- for (int step = 0; step < 100; step += 25)
- for (int line = 0; line < 100; line++)
- m_bitmap.pix32((step + line) % 100, line % 100) = rgb_t(0xff,0xff,0xff,0xff);
-
- // log an error
- if (m_alphafile.empty())
- osd_printf_warning("Unable to load component bitmap '%s'\n", m_imagefile.c_str());
- else
- osd_printf_warning("Unable to load component bitmap '%s'/'%s'\n", m_imagefile.c_str(), m_alphafile.c_str());
- }
-}
+ // decimal point
+ draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 7)) ? onpen : offpen);
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
-//-------------------------------------------------
-// text_component - constructor
-//-------------------------------------------------
-layout_element::text_component::text_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+// 8-segment fluorescent (Gottlieb System 1)
+class layout_element::led8seg_gts1_component : public component
{
- m_string = xml_get_attribute_string_with_subst(machine, compnode, "string", "");
- m_textalign = xml_get_attribute_int_with_subst(machine, compnode, "align", 0);
-}
+public:
+ // construction/destruction
+ led8seg_gts1_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual int maxstate() const override { return 255; }
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff);
+ const rgb_t offpen = rgb_t(0xff,0x20,0x20,0x20);
+ const rgb_t backpen = rgb_t(0xff,0x00,0x00,0x00);
-void layout_element::text_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- render_font *font = machine.render().font_alloc("default");
- draw_text(*font, dest, bounds, m_string.c_str(), m_textalign);
- machine.render().font_free(font);
-}
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
+ tempbitmap.fill(backpen);
-//-------------------------------------------------
-// dotmatrix_component - constructor
-//-------------------------------------------------
+ // top bar
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 0)) ? onpen : offpen);
-layout_element::dotmatrix_component::dotmatrix_component(int dots, running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname),
- m_dots(dots)
-{
-}
+ // top-right bar
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 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 - draw a component
-//-------------------------------------------------
+ // bottom bar
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (state & (1 << 3)) ? onpen : offpen);
-void layout_element::dotmatrix_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
+ // bottom-left bar
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 4)) ? onpen : offpen);
- // sizes for computation
- int bmheight = 300;
- int dotwidth = 250;
+ // top-left bar
+ draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 5)) ? onpen : offpen);
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(dotwidth*m_dots, bmheight);
- tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
+ // horizontal bars
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, 2*bmwidth/3 - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
+ draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3 + bmwidth/2, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
- for (int i = 0; i < m_dots; i++)
- draw_segment_decimal(tempbitmap, ((dotwidth/2 )+ (i * dotwidth)), bmheight/2, dotwidth, (state & (1 << i))?onpen:offpen);
+ // vertical bars
+ draw_segment_vertical(tempbitmap, 0 + segwidth/3 - 8, bmheight/2 - segwidth/3 + 2, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
+ draw_segment_vertical(tempbitmap, 0 + segwidth/3, bmheight/2 - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
-}
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3 - 2, bmheight - segwidth/3 + 8, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
+ draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
+ // apply skew
+ apply_skew(tempbitmap, 40);
-//-------------------------------------------------
-// simplecounter_component - constructor
-//-------------------------------------------------
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
-layout_element::simplecounter_component::simplecounter_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+
+// 14-segment LCD
+class layout_element::led14seg_component : public component
{
- m_digits = xml_get_attribute_int_with_subst(machine, compnode, "digits", 2);
- m_textalign = xml_get_attribute_int_with_subst(machine, compnode, "align", 0);
- m_maxstate = xml_get_attribute_int_with_subst(machine, compnode, "maxstate", 999);
-}
+public:
+ // construction/destruction
+ led14seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual int maxstate() const override { return 16383; }
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
+ const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
+
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
+ 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);
+
+ // right-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 1)) ? onpen : offpen);
+
+ // right-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 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);
+
+ // left-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 4)) ? onpen : offpen);
+
+ // left-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 5)) ? onpen : offpen);
+
+ // horizontal-middle-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
+ segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen);
+
+ // horizontal-middle-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
+ segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen);
+
+ // vertical-middle-top bar
+ draw_segment_vertical_caps(tempbitmap,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen);
+
+ // vertical-middle-bottom bar
+ draw_segment_vertical_caps(tempbitmap,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen);
+
+ // diagonal-left-bottom bar
+ draw_segment_diagonal_1(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 10)) ? onpen : offpen);
+
+ // diagonal-left-top bar
+ draw_segment_diagonal_2(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 11)) ? onpen : offpen);
+
+ // diagonal-right-top bar
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 12)) ? onpen : offpen);
+
+ // diagonal-right-bottom bar
+ draw_segment_diagonal_2(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 13)) ? onpen : offpen);
+
+ // apply skew
+ apply_skew(tempbitmap, 40);
+
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
-void layout_element::simplecounter_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+
+// 16-segment LCD
+class layout_element::led16seg_component : public component
{
- render_font *font = machine.render().font_alloc("default");
- std::string temp = string_format("%0*d", m_digits, state);
- draw_text(*font, dest, bounds, temp.c_str(), m_textalign);
- machine.render().font_free(font);
-}
+public:
+ // construction/destruction
+ led16seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
+protected:
+ // overrides
+ virtual int maxstate() const override { return 65535; }
-//-------------------------------------------------
-// reel_component - constructor
-//-------------------------------------------------
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
+ const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
+
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
+ tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
+
+ // top-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2,
+ segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen);
+
+ // top-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen);
+
+ // right-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 2)) ? onpen : offpen);
+
+ // right-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 3)) ? onpen : offpen);
+
+ // bottom-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2,
+ segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen);
+
+ // bottom-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2,
+ segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen);
+
+ // left-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 6)) ? onpen : offpen);
+
+ // left-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 7)) ? onpen : offpen);
+
+ // horizontal-middle-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
+ segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen);
+
+ // horizontal-middle-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
+ segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen);
+
+ // vertical-middle-top bar
+ draw_segment_vertical_caps(tempbitmap,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen);
+
+ // vertical-middle-bottom bar
+ draw_segment_vertical_caps(tempbitmap,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen);
+
+ // diagonal-left-bottom bar
+ draw_segment_diagonal_1(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 12)) ? onpen : offpen);
+
+ // diagonal-left-top bar
+ draw_segment_diagonal_2(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 13)) ? onpen : offpen);
+
+ // diagonal-right-top bar
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 14)) ? onpen : offpen);
+
+ // diagonal-right-bottom bar
+ draw_segment_diagonal_2(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 15)) ? onpen : offpen);
+
+ // apply skew
+ apply_skew(tempbitmap, 40);
+
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
-layout_element::reel_component::reel_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+
+// 14-segment LCD with semicolon (2 extra segments)
+class layout_element::led14segsc_component : public component
{
- for (auto & elem : m_hasalpha)
- elem = false;
+public:
+ // construction/destruction
+ led14segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ {
+ }
- std::string symbollist = xml_get_attribute_string_with_subst(machine, compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
+protected:
+ // overrides
+ virtual int maxstate() const override { return 65535; }
- // split out position names from string and figure out our number of symbols
- int location;
- m_numstops = 0;
- location=symbollist.find(",");
- while (location!=-1)
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
+ const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
+
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+
+ // allocate a temporary bitmap for drawing, adding some extra space for the tail
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth);
+ 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);
+
+ // right-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 1)) ? onpen : offpen);
+
+ // right-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 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);
+
+ // left-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 4)) ? onpen : offpen);
+
+ // left-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 5)) ? onpen : offpen);
+
+ // horizontal-middle-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
+ segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen);
+
+ // horizontal-middle-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
+ segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen);
+
+ // vertical-middle-top bar
+ draw_segment_vertical_caps(tempbitmap,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen);
+
+ // vertical-middle-bottom bar
+ draw_segment_vertical_caps(tempbitmap,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen);
+
+ // diagonal-left-bottom bar
+ draw_segment_diagonal_1(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 10)) ? onpen : offpen);
+
+ // diagonal-left-top bar
+ draw_segment_diagonal_2(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 11)) ? onpen : offpen);
+
+ // diagonal-right-top bar
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 12)) ? onpen : offpen);
+
+ // diagonal-right-bottom bar
+ draw_segment_diagonal_2(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 13)) ? onpen : offpen);
+
+ // apply skew
+ apply_skew(tempbitmap, 40);
+
+ // comma tail
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth - (segwidth/2), bmwidth + segwidth,
+ bmheight - (segwidth), bmheight + segwidth*1.5,
+ segwidth/2, (state & (1 << 15)) ? onpen : offpen);
+
+ // decimal point
+ draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 14)) ? onpen : offpen);
+
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
+
+
+// 16-segment LCD with semicolon (2 extra segments)
+class layout_element::led16segsc_component : public component
+{
+public:
+ // construction/destruction
+ led16segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
{
- m_stopnames[m_numstops] = symbollist;
- m_stopnames[m_numstops] = m_stopnames[m_numstops].substr(0, location);
- symbollist = symbollist.substr(location+1, symbollist.length()-(location-1));
- m_numstops++;
- location=symbollist.find(",");
}
- m_stopnames[m_numstops++] = symbollist;
- // careful, dirname is nullptr if we're coming from internal layout, and our string assignment doesn't like that
- if (dirname != nullptr)
- m_dirname = dirname;
+protected:
+ // overrides
+ virtual int maxstate() const override { return 262143; }
- for (int i=0;i<m_numstops;i++)
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
{
- location=m_stopnames[i].find(":");
- if (location!=-1)
- {
- m_imagefile[i] = m_stopnames[i];
- m_stopnames[i] = m_stopnames[i].substr(0, location);
- m_imagefile[i] = m_imagefile[i].substr(location+1, m_imagefile[i].length()-(location-1));
+ const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
+ const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
+
+ // sizes for computation
+ int bmwidth = 250;
+ int bmheight = 400;
+ int segwidth = 40;
+ int skewwidth = 40;
+
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth);
+ tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
+
+ // top-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2,
+ segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen);
+
+ // top-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen);
+
+ // right-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 2)) ? onpen : offpen);
+
+ // right-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
+ segwidth, (state & (1 << 3)) ? onpen : offpen);
+
+ // bottom-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2,
+ segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen);
+
+ // bottom-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2,
+ segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen);
+
+ // left-bottom bar
+ draw_segment_vertical(tempbitmap,
+ bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 6)) ? onpen : offpen);
+
+ // left-top bar
+ draw_segment_vertical(tempbitmap,
+ 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
+ segwidth, (state & (1 << 7)) ? onpen : offpen);
+
+ // horizontal-middle-left bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
+ segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen);
+
+ // horizontal-middle-right bar
+ draw_segment_horizontal_caps(tempbitmap,
+ 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
+ segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen);
+
+ // vertical-middle-top bar
+ draw_segment_vertical_caps(tempbitmap,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen);
+
+ // vertical-middle-bottom bar
+ draw_segment_vertical_caps(tempbitmap,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
+ segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen);
+
+ // diagonal-left-bottom bar
+ draw_segment_diagonal_1(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 12)) ? onpen : offpen);
+
+ // diagonal-left-top bar
+ draw_segment_diagonal_2(tempbitmap,
+ 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 13)) ? onpen : offpen);
+
+ // diagonal-right-top bar
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
+ segwidth, (state & (1 << 14)) ? onpen : offpen);
+
+ // diagonal-right-bottom bar
+ draw_segment_diagonal_2(tempbitmap,
+ bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
+ bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
+ segwidth, (state & (1 << 15)) ? onpen : offpen);
+
+ // comma tail
+ draw_segment_diagonal_1(tempbitmap,
+ bmwidth - (segwidth/2), bmwidth + segwidth,
+ bmheight - (segwidth), bmheight + segwidth*1.5,
+ segwidth/2, (state & (1 << 17)) ? onpen : offpen);
+
+ // decimal point (draw last for priority)
+ draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 16)) ? onpen : offpen);
+
+ // apply skew
+ apply_skew(tempbitmap, 40);
+
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
+};
- //m_alphafile[i] =
- m_file[i] = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
- }
- else
- {
- //m_imagefile[i] = 0;
- //m_alphafile[i] = 0;
- m_file[i].reset();
- }
+
+// row of dots for a dotmatrix
+class layout_element::dotmatrix_component : public component
+{
+public:
+ // construction/destruction
+ dotmatrix_component(int dots, running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ , m_dots(dots)
+ {
}
- m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0);
- m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3);
- m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0);
- m_beltreel = xml_get_attribute_int_with_subst(machine, compnode, "beltreel", 0);
-}
+protected:
+ // overrides
+ virtual int maxstate() const override { return (1 << m_dots) - 1; }
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
+ const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
+ // sizes for computation
+ int bmheight = 300;
+ int dotwidth = 250;
+
+ // allocate a temporary bitmap for drawing
+ bitmap_argb32 tempbitmap(dotwidth*m_dots, bmheight);
+ 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);
+
+ // resample to the target size
+ render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ }
-/* state is a normalized value between 0 and 65536 so that we don't need to worry about how many motor steps here or in the .lay, only the number of symbols */
-void layout_element::reel_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+private:
+ // internal state
+ int m_dots;
+};
+
+
+// simple counter
+class layout_element::simplecounter_component : public component
{
- if (m_beltreel)
+public:
+ // construction/destruction
+ simplecounter_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
+ , m_digits(xml_get_attribute_int_with_subst(machine, compnode, "digits", 2))
+ , m_textalign(xml_get_attribute_int_with_subst(machine, compnode, "align", 0))
+ , m_maxstate(xml_get_attribute_int_with_subst(machine, compnode, "maxstate", 999))
{
- draw_beltreel(machine,dest,bounds,state);
- return;
}
- const int max_state_used = 0x10000;
+protected:
+ // overrides
+ virtual int maxstate() const override { return m_maxstate; }
- // shift the reels a bit based on this param, allows fine tuning
- int use_state = (state + m_stateoffset) % max_state_used;
-
- // compute premultiplied colors
- u32 r = color().r * 255.0f;
- u32 g = color().g * 255.0f;
- u32 b = color().b * 255.0f;
- u32 a = color().a * 255.0f;
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ render_font *font = machine.render().font_alloc("default");
+ std::string temp = string_format("%0*d", m_digits, state);
+ draw_text(*font, dest, bounds, temp.c_str(), m_textalign);
+ machine.render().font_free(font);
+ }
- // get the width of the string
- render_font *font = machine.render().font_alloc("default");
- float aspect = 1.0f;
- s32 width;
+private:
+ // internal state
+ int const m_digits; // number of digits for simple counters
+ int const m_textalign; // text alignment to box
+ int const m_maxstate;
+};
- int curry = 0;
- int num_shown = m_numsymbolsvisible;
- int ourheight = bounds.height();
+// fruit machine reel
+class layout_element::reel_component : public component
+{
+ static constexpr unsigned MAX_BITMAPS = 32;
- for (int fruit = 0;fruit<m_numstops;fruit++)
+public:
+ // construction/destruction
+ reel_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : component(machine, compnode, dirname)
{
- int basey;
+ for (auto & elem : m_hasalpha)
+ elem = false;
- if (m_reelreversed==1)
+ std::string symbollist = xml_get_attribute_string_with_subst(machine, compnode, "symbollist", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15");
+
+ // split out position names from string and figure out our number of symbols
+ int location;
+ m_numstops = 0;
+ location=symbollist.find(",");
+ while (location!=-1)
{
- basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
+ m_stopnames[m_numstops] = symbollist;
+ m_stopnames[m_numstops] = m_stopnames[m_numstops].substr(0, location);
+ symbollist = symbollist.substr(location+1, symbollist.length()-(location-1));
+ m_numstops++;
+ location=symbollist.find(",");
}
- else
+ m_stopnames[m_numstops++] = symbollist;
+
+ // careful, dirname is nullptr if we're coming from internal layout, and our string assignment doesn't like that
+ if (dirname != nullptr)
+ m_dirname = dirname;
+
+ for (int i=0;i<m_numstops;i++)
{
- basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
+ location=m_stopnames[i].find(":");
+ if (location!=-1)
+ {
+ m_imagefile[i] = m_stopnames[i];
+ m_stopnames[i] = m_stopnames[i].substr(0, location);
+ m_imagefile[i] = m_imagefile[i].substr(location+1, m_imagefile[i].length()-(location-1));
+
+ //m_alphafile[i] =
+ m_file[i] = std::make_unique<emu_file>(machine.options().art_path(), OPEN_FLAG_READ);
+ }
+ else
+ {
+ //m_imagefile[i] = 0;
+ //m_alphafile[i] = 0;
+ m_file[i].reset();
+ }
+ }
+
+ m_stateoffset = xml_get_attribute_int_with_subst(machine, compnode, "stateoffset", 0);
+ m_numsymbolsvisible = xml_get_attribute_int_with_subst(machine, compnode, "numsymbolsvisible", 3);
+ m_reelreversed = xml_get_attribute_int_with_subst(machine, compnode, "reelreversed", 0);
+ m_beltreel = xml_get_attribute_int_with_subst(machine, compnode, "beltreel", 0);
+ }
+
+protected:
+ // overrides
+ virtual int maxstate() const override { return 65535; }
+ virtual void draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state) override
+ {
+ if (m_beltreel)
+ {
+ draw_beltreel(machine,dest,bounds,state);
+ return;
}
- // wrap around...
- if (basey < bounds.min_y)
- basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
- if (basey > bounds.max_y)
- basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
+ // state is a normalized value between 0 and 65536 so that we don't need to worry about how many motor steps here or in the .lay, only the number of symbols
+ const int max_state_used = 0x10000;
+
+ // shift the reels a bit based on this param, allows fine tuning
+ int use_state = (state + m_stateoffset) % max_state_used;
+
+ // compute premultiplied colors
+ u32 r = color().r * 255.0f;
+ u32 g = color().g * 255.0f;
+ u32 b = color().b * 255.0f;
+ u32 a = color().a * 255.0f;
+
+ // get the width of the string
+ render_font *font = machine.render().font_alloc("default");
+ float aspect = 1.0f;
+ s32 width;
- int endpos = basey+ourheight/num_shown;
+ int curry = 0;
+ int num_shown = m_numsymbolsvisible;
- // 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))
+ int ourheight = bounds.height();
+
+ for (int fruit = 0;fruit<m_numstops;fruit++)
{
- while (1)
+ int basey;
+
+ if (m_reelreversed==1)
+ {
+ basey = bounds.min_y + ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
+ }
+ else
{
- width = font->string_width(ourheight / num_shown, aspect, m_stopnames[fruit].c_str());
- if (width < bounds.width())
- break;
- aspect *= 0.9f;
+ basey = bounds.min_y - ((use_state)*(ourheight/num_shown)/(max_state_used/m_numstops)) + curry;
}
- s32 curx;
- curx = bounds.min_x + (bounds.width() - width) / 2;
+ // wrap around...
+ if (basey < bounds.min_y)
+ basey += ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
+ if (basey > bounds.max_y)
+ basey -= ((max_state_used)*(ourheight/num_shown)/(max_state_used/m_numstops));
- if (m_file[fruit])
- if (!m_bitmap[fruit].valid())
- load_reel_bitmap(fruit);
+ int endpos = basey+ourheight/num_shown;
- if (m_file[fruit]) // render gfx
+ // 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))
{
- bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown);
+ while (1)
+ {
+ width = font->string_width(ourheight / num_shown, aspect, m_stopnames[fruit].c_str());
+ if (width < bounds.width())
+ break;
+ aspect *= 0.9f;
+ }
- if (m_bitmap[fruit].valid())
+ s32 curx;
+ curx = bounds.min_x + (bounds.width() - width) / 2;
+
+ if (m_file[fruit])
+ if (!m_bitmap[fruit].valid())
+ load_reel_bitmap(fruit);
+
+ if (m_file[fruit]) // render gfx
{
- render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color());
+ bitmap_argb32 tempbitmap2(dest.width(), ourheight/num_shown);
- for (int y = 0; y < ourheight/num_shown; y++)
+ if (m_bitmap[fruit].valid())
{
- int effy = basey + y;
+ render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color());
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ for (int y = 0; y < ourheight/num_shown; y++)
{
- u32 *src = &tempbitmap2.pix32(y);
- u32 *d = &dest.pix32(effy);
- for (int x = 0; x < dest.width(); x++)
+ int effy = basey + y;
+
+ if (effy >= bounds.min_y && effy <= bounds.max_y)
{
- int effx = x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ u32 *src = &tempbitmap2.pix32(y);
+ u32 *d = &dest.pix32(effy);
+ for (int x = 0; x < dest.width(); x++)
{
- u32 spix = rgb_t(src[x]).a();
- if (spix != 0)
+ int effx = x;
+ if (effx >= bounds.min_x && effx <= bounds.max_x)
{
- d[effx] = src[x];
+ u32 spix = rgb_t(src[x]).a();
+ if (spix != 0)
+ {
+ d[effx] = src[x];
+ }
}
}
}
}
}
}
- }
- else // render text (fallback)
- {
- // allocate a temporary bitmap
- bitmap_argb32 tempbitmap(dest.width(), dest.height());
-
- const char *origs = m_stopnames[fruit].c_str();
- const char *ends = origs + strlen(origs);
- const char *s = origs;
- char32_t schar;
-
- // loop over characters
- while (*s != 0)
+ else // render text (fallback)
{
- int scharcount = uchar_from_utf8(&schar, s, ends - s);
+ // allocate a temporary bitmap
+ bitmap_argb32 tempbitmap(dest.width(), dest.height());
- if (scharcount == -1)
- break;
-
- // get the font bitmap
- rectangle chbounds;
- font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, schar, chbounds);
+ const char *origs = m_stopnames[fruit].c_str();
+ const char *ends = origs + strlen(origs);
+ const char *s = origs;
+ char32_t schar;
- // copy the data into the target
- for (int y = 0; y < chbounds.height(); y++)
+ // loop over characters
+ while (*s != 0)
{
- int effy = basey + y;
+ int scharcount = uchar_from_utf8(&schar, s, ends - s);
+
+ if (scharcount == -1)
+ break;
+
+ // get the font bitmap
+ rectangle chbounds;
+ font->get_scaled_bitmap_and_bounds(tempbitmap, ourheight/num_shown, aspect, schar, chbounds);
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ // copy the data into the target
+ for (int y = 0; y < chbounds.height(); y++)
{
- u32 *src = &tempbitmap.pix32(y);
- u32 *d = &dest.pix32(effy);
- for (int x = 0; x < chbounds.width(); x++)
+ int effy = basey + y;
+
+ if (effy >= bounds.min_y && effy <= bounds.max_y)
{
- int effx = curx + x + chbounds.min_x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ u32 *src = &tempbitmap.pix32(y);
+ u32 *d = &dest.pix32(effy);
+ for (int x = 0; x < chbounds.width(); x++)
{
- u32 spix = rgb_t(src[x]).a();
- if (spix != 0)
+ int effx = curx + x + chbounds.min_x;
+ if (effx >= bounds.min_x && effx <= bounds.max_x)
{
- rgb_t dpix = d[effx];
- u32 ta = (a * (spix + 1)) >> 8;
- u32 tr = (r * ta + dpix.r() * (0x100 - ta)) >> 8;
- u32 tg = (g * ta + dpix.g() * (0x100 - ta)) >> 8;
- u32 tb = (b * ta + dpix.b() * (0x100 - ta)) >> 8;
- d[effx] = rgb_t(tr, tg, tb);
+ u32 spix = rgb_t(src[x]).a();
+ if (spix != 0)
+ {
+ rgb_t dpix = d[effx];
+ u32 ta = (a * (spix + 1)) >> 8;
+ u32 tr = (r * ta + dpix.r() * (0x100 - ta)) >> 8;
+ u32 tg = (g * ta + dpix.g() * (0x100 - ta)) >> 8;
+ u32 tb = (b * ta + dpix.b() * (0x100 - ta)) >> 8;
+ d[effx] = rgb_t(tr, tg, tb);
+ }
}
}
}
}
- }
- // advance in the X direction
- curx += font->char_width(ourheight/num_shown, aspect, schar);
- s += scharcount;
+ // advance in the X direction
+ curx += font->char_width(ourheight/num_shown, aspect, schar);
+ s += scharcount;
+ }
}
}
+
+ curry += ourheight/num_shown;
}
- curry += ourheight/num_shown;
+ // free the temporary bitmap and font
+ machine.render().font_free(font);
}
- // free the temporary bitmap and font
- machine.render().font_free(font);
-}
-
-
-void layout_element::reel_component::draw_beltreel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- const int max_state_used = 0x10000;
-
- // shift the reels a bit based on this param, allows fine tuning
- int use_state = (state + m_stateoffset) % max_state_used;
-
- // compute premultiplied colors
- u32 r = color().r * 255.0f;
- u32 g = color().g * 255.0f;
- u32 b = color().b * 255.0f;
- u32 a = color().a * 255.0f;
-
- // get the width of the string
- render_font *font = machine.render().font_alloc("default");
- float aspect = 1.0f;
- s32 width;
- int currx = 0;
- int num_shown = m_numsymbolsvisible;
+private:
+ // internal helpers
+ void draw_beltreel(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+ {
+ const int max_state_used = 0x10000;
- int ourwidth = bounds.width();
+ // shift the reels a bit based on this param, allows fine tuning
+ int use_state = (state + m_stateoffset) % max_state_used;
- for (int fruit = 0;fruit<m_numstops;fruit++)
- {
- int basex;
- if (m_reelreversed==1)
- {
- basex = bounds.min_x + ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx;
- }
- else
- {
- basex = bounds.min_x - ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx;
- }
+ // compute premultiplied colors
+ u32 r = color().r * 255.0f;
+ u32 g = color().g * 255.0f;
+ u32 b = color().b * 255.0f;
+ u32 a = color().a * 255.0f;
- // wrap around...
- if (basex < bounds.min_x)
- basex += ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
- if (basex > bounds.max_x)
- basex -= ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
+ // get the width of the string
+ render_font *font = machine.render().font_alloc("default");
+ float aspect = 1.0f;
+ s32 width;
+ int currx = 0;
+ int num_shown = m_numsymbolsvisible;
- int endpos = basex+(ourwidth/num_shown);
+ int ourwidth = bounds.width();
- // 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))
+ for (int fruit = 0;fruit<m_numstops;fruit++)
{
- while (1)
+ int basex;
+ if (m_reelreversed==1)
{
- width = font->string_width(dest.height(), aspect, m_stopnames[fruit].c_str());
- if (width < bounds.width())
- break;
- aspect *= 0.9f;
+ basex = bounds.min_x + ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx;
+ }
+ else
+ {
+ basex = bounds.min_x - ((use_state)*(ourwidth/num_shown)/(max_state_used/m_numstops)) + currx;
}
- s32 curx;
- curx = bounds.min_x;
+ // wrap around...
+ if (basex < bounds.min_x)
+ basex += ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
+ if (basex > bounds.max_x)
+ basex -= ((max_state_used)*(ourwidth/num_shown)/(max_state_used/m_numstops));
- if (m_file[fruit])
- if (!m_bitmap[fruit].valid())
- load_reel_bitmap(fruit);
+ int endpos = basex+(ourwidth/num_shown);
- if (m_file[fruit]) // render gfx
+ // 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))
{
- bitmap_argb32 tempbitmap2(ourwidth/num_shown, dest.height());
+ while (1)
+ {
+ width = font->string_width(dest.height(), aspect, m_stopnames[fruit].c_str());
+ if (width < bounds.width())
+ break;
+ aspect *= 0.9f;
+ }
+
+ s32 curx;
+ curx = bounds.min_x;
- if (m_bitmap[fruit].valid())
+ if (m_file[fruit])
+ if (!m_bitmap[fruit].valid())
+ load_reel_bitmap(fruit);
+
+ if (m_file[fruit]) // render gfx
{
- render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color());
+ bitmap_argb32 tempbitmap2(ourwidth/num_shown, dest.height());
- for (int y = 0; y < dest.height(); y++)
+ if (m_bitmap[fruit].valid())
{
- int effy = y;
+ render_resample_argb_bitmap_hq(tempbitmap2, m_bitmap[fruit], color());
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ for (int y = 0; y < dest.height(); y++)
{
- u32 *src = &tempbitmap2.pix32(y);
- u32 *d = &dest.pix32(effy);
- for (int x = 0; x < ourwidth/num_shown; x++)
+ int effy = y;
+
+ if (effy >= bounds.min_y && effy <= bounds.max_y)
{
- int effx = basex + x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ u32 *src = &tempbitmap2.pix32(y);
+ u32 *d = &dest.pix32(effy);
+ for (int x = 0; x < ourwidth/num_shown; x++)
{
- u32 spix = rgb_t(src[x]).a();
- if (spix != 0)
+ int effx = basex + x;
+ if (effx >= bounds.min_x && effx <= bounds.max_x)
{
- d[effx] = src[x];
+ u32 spix = rgb_t(src[x]).a();
+ if (spix != 0)
+ {
+ d[effx] = src[x];
+ }
}
}
}
- }
+ }
}
}
- }
- else // render text (fallback)
- {
- // allocate a temporary bitmap
- bitmap_argb32 tempbitmap(dest.width(), dest.height());
-
-
- const char *origs =m_stopnames[fruit].c_str();
- const char *ends = origs + strlen(origs);
- const char *s = origs;
- char32_t schar;
-
- // loop over characters
- while (*s != 0)
+ else // render text (fallback)
{
- int scharcount = uchar_from_utf8(&schar, s, ends - s);
+ // allocate a temporary bitmap
+ bitmap_argb32 tempbitmap(dest.width(), dest.height());
- if (scharcount == -1)
- break;
- // get the font bitmap
- rectangle chbounds;
- font->get_scaled_bitmap_and_bounds(tempbitmap, dest.height(), aspect, schar, chbounds);
+ const char *origs =m_stopnames[fruit].c_str();
+ const char *ends = origs + strlen(origs);
+ const char *s = origs;
+ char32_t schar;
- // copy the data into the target
- for (int y = 0; y < chbounds.height(); y++)
+ // loop over characters
+ while (*s != 0)
{
- int effy = y;
+ int scharcount = uchar_from_utf8(&schar, s, ends - s);
+
+ if (scharcount == -1)
+ break;
- if (effy >= bounds.min_y && effy <= bounds.max_y)
+ // get the font bitmap
+ rectangle chbounds;
+ font->get_scaled_bitmap_and_bounds(tempbitmap, dest.height(), aspect, schar, chbounds);
+
+ // copy the data into the target
+ for (int y = 0; y < chbounds.height(); y++)
{
- u32 *src = &tempbitmap.pix32(y);
- u32 *d = &dest.pix32(effy);
- for (int x = 0; x < chbounds.width(); x++)
+ int effy = y;
+
+ if (effy >= bounds.min_y && effy <= bounds.max_y)
{
- int effx = basex + curx + x;
- if (effx >= bounds.min_x && effx <= bounds.max_x)
+ u32 *src = &tempbitmap.pix32(y);
+ u32 *d = &dest.pix32(effy);
+ for (int x = 0; x < chbounds.width(); x++)
{
- u32 spix = rgb_t(src[x]).a();
- if (spix != 0)
+ int effx = basex + curx + x;
+ if (effx >= bounds.min_x && effx <= bounds.max_x)
{
- rgb_t dpix = d[effx];
- u32 ta = (a * (spix + 1)) >> 8;
- u32 tr = (r * ta + dpix.r() * (0x100 - ta)) >> 8;
- u32 tg = (g * ta + dpix.g() * (0x100 - ta)) >> 8;
- u32 tb = (b * ta + dpix.b() * (0x100 - ta)) >> 8;
- d[effx] = rgb_t(tr, tg, tb);
+ u32 spix = rgb_t(src[x]).a();
+ if (spix != 0)
+ {
+ rgb_t dpix = d[effx];
+ u32 ta = (a * (spix + 1)) >> 8;
+ u32 tr = (r * ta + dpix.r() * (0x100 - ta)) >> 8;
+ u32 tg = (g * ta + dpix.g() * (0x100 - ta)) >> 8;
+ u32 tb = (b * ta + dpix.b() * (0x100 - ta)) >> 8;
+ d[effx] = rgb_t(tr, tg, tb);
+ }
}
}
}
}
- }
- // advance in the X direction
- curx += font->char_width(dest.height(), aspect, schar);
- s += scharcount;
+ // advance in the X direction
+ curx += font->char_width(dest.height(), aspect, schar);
+ s += scharcount;
+ }
}
}
+
+ currx += ourwidth/num_shown;
}
- currx += ourwidth/num_shown;
+ // free the temporary bitmap and font
+ machine.render().font_free(font);
}
- // free the temporary bitmap and font
- machine.render().font_free(font);
-}
-
-
-void layout_element::reel_component::load_reel_bitmap(int number)
-{
- // load the basic bitmap
- assert(m_file != nullptr);
- /*m_hasalpha[number] = */ render_load_png(m_bitmap[number], *m_file[number], m_dirname.c_str(), m_imagefile[number].c_str());
-
- // load the alpha bitmap if specified
- //if (m_bitmap[number].valid() && m_alphafile[number])
- // render_load_png(m_bitmap[number], *m_file[number], m_dirname, m_alphafile[number], true);
-
- // if we can't load the bitmap just use text rendering
- if (!m_bitmap[number].valid())
+ void load_reel_bitmap(int number)
{
- // fallback to text rendering
- m_file[number].reset();
- }
-
-}
-
-
-//-------------------------------------------------
-// led7seg_component - constructor
-//-------------------------------------------------
-
-layout_element::led7seg_component::led7seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
-{
-}
-
-
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
-
-void layout_element::led7seg_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff);
- const rgb_t offpen = rgb_t(0xff,0x20,0x20,0x20);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
- 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);
-
- // top-right bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 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);
-
- // bottom bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, bmheight - segwidth/2, segwidth, (state & (1 << 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);
-
- // top-left bar
- draw_segment_vertical(tempbitmap, 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 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);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // decimal point
- draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
-}
-
-
-//-------------------------------------------------
-// led8seg_gts1_component - constructor
-//-------------------------------------------------
-
-layout_element::led8seg_gts1_component::led8seg_gts1_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
-{
-}
-
-
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
-
-void layout_element::led8seg_gts1_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- const rgb_t onpen = rgb_t(0xff,0xff,0xff,0xff);
- const rgb_t offpen = rgb_t(0xff,0x20,0x20,0x20);
- const rgb_t backpen = rgb_t(0xff,0x00,0x00,0x00);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
- tempbitmap.fill(backpen);
+ // load the basic bitmap
+ assert(m_file != nullptr);
+ /*m_hasalpha[number] = */ render_load_png(m_bitmap[number], *m_file[number], m_dirname.c_str(), m_imagefile[number].c_str());
- // top bar
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, bmwidth - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 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);
-
- // bottom-right bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2, segwidth, (state & (1 << 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);
-
- // bottom-left bar
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2, segwidth, (state & (1 << 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);
-
- // horizontal bars
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3, 2*bmwidth/3 - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
- draw_segment_horizontal(tempbitmap, 0 + 2*segwidth/3 + bmwidth/2, bmwidth - 2*segwidth/3, bmheight/2, segwidth, (state & (1 << 6)) ? onpen : offpen);
-
- // vertical bars
- draw_segment_vertical(tempbitmap, 0 + segwidth/3 - 8, bmheight/2 - segwidth/3 + 2, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
- draw_segment_vertical(tempbitmap, 0 + segwidth/3, bmheight/2 - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3 - 2, bmheight - segwidth/3 + 8, 2*bmwidth/3 - segwidth/2 - 4, segwidth + 8, backpen);
- draw_segment_vertical(tempbitmap, bmheight/2 + segwidth/3, bmheight - segwidth/3, 2*bmwidth/3 - segwidth/2 - 4, segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
-}
-
-
-//-------------------------------------------------
-// led14seg_component - constructor
-//-------------------------------------------------
-
-layout_element::led14seg_component::led14seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
-{
-}
+ // load the alpha bitmap if specified
+ //if (m_bitmap[number].valid() && m_alphafile[number])
+ // render_load_png(m_bitmap[number], *m_file[number], m_dirname, m_alphafile[number], true);
+ // if we can't load the bitmap just use text rendering
+ if (!m_bitmap[number].valid())
+ {
+ // fallback to text rendering
+ m_file[number].reset();
+ }
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
+ }
-void layout_element::led14seg_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
- 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);
-
- // right-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 1)) ? onpen : offpen);
-
- // right-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 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);
-
- // left-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 4)) ? onpen : offpen);
-
- // left-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 5)) ? onpen : offpen);
-
- // horizontal-middle-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
- segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen);
-
- // horizontal-middle-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
- segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen);
-
- // vertical-middle-top bar
- draw_segment_vertical_caps(tempbitmap,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen);
-
- // vertical-middle-bottom bar
- draw_segment_vertical_caps(tempbitmap,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen);
-
- // diagonal-left-bottom bar
- draw_segment_diagonal_1(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 10)) ? onpen : offpen);
-
- // diagonal-left-top bar
- draw_segment_diagonal_2(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 11)) ? onpen : offpen);
-
- // diagonal-right-top bar
- draw_segment_diagonal_1(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 12)) ? onpen : offpen);
-
- // diagonal-right-bottom bar
- draw_segment_diagonal_2(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 13)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
-}
+ // internal state
+ bitmap_argb32 m_bitmap[MAX_BITMAPS]; // source bitmap for images
+ std::string m_dirname; // directory name of image file (for lazy loading)
+ std::unique_ptr<emu_file> m_file[MAX_BITMAPS]; // file object for reading image/alpha files
+ std::string m_imagefile[MAX_BITMAPS]; // name of the image file (for lazy loading)
+ std::string m_alphafile[MAX_BITMAPS]; // name of the alpha file (for lazy loading)
+ bool m_hasalpha[MAX_BITMAPS]; // is there any alpha component present?
+
+ // basically made up of multiple text strings / gfx
+ int m_numstops;
+ std::string m_stopnames[MAX_BITMAPS];
+ int m_stateoffset;
+ int m_reelreversed;
+ int m_numsymbolsvisible;
+ int m_beltreel;
+};
//-------------------------------------------------
-// led14segsc_component - constructor
+// make_component - create component of given type
//-------------------------------------------------
-layout_element::led14segsc_component::led14segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+template <typename T>
+layout_element::component::ptr layout_element::make_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
{
+ return std::make_unique<T>(machine, compnode, dirname);
}
//-------------------------------------------------
-// draw - draw a component
+// make_component - create dotmatrix component
+// with given vertical resolution
//-------------------------------------------------
-void layout_element::led14segsc_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+template <int D>
+layout_element::component::ptr layout_element::make_dotmatrix_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
{
- const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing, adding some extra space for the tail
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth);
- 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);
-
- // right-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 1)) ? onpen : offpen);
-
- // right-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 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);
-
- // left-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 4)) ? onpen : offpen);
-
- // left-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 5)) ? onpen : offpen);
-
- // horizontal-middle-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
- segwidth, LINE_CAP_START, (state & (1 << 6)) ? onpen : offpen);
-
- // horizontal-middle-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
- segwidth, LINE_CAP_END, (state & (1 << 7)) ? onpen : offpen);
-
- // vertical-middle-top bar
- draw_segment_vertical_caps(tempbitmap,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 8)) ? onpen : offpen);
-
- // vertical-middle-bottom bar
- draw_segment_vertical_caps(tempbitmap,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 9)) ? onpen : offpen);
-
- // diagonal-left-bottom bar
- draw_segment_diagonal_1(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 10)) ? onpen : offpen);
-
- // diagonal-left-top bar
- draw_segment_diagonal_2(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 11)) ? onpen : offpen);
-
- // diagonal-right-top bar
- draw_segment_diagonal_1(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 12)) ? onpen : offpen);
-
- // diagonal-right-bottom bar
- draw_segment_diagonal_2(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 13)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // comma tail
- draw_segment_diagonal_1(tempbitmap,
- bmwidth - (segwidth/2), bmwidth + segwidth,
- bmheight - (segwidth), bmheight + segwidth*1.5,
- segwidth/2, (state & (1 << 15)) ? onpen : offpen);
-
- // decimal point
- draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 14)) ? onpen : offpen);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ return std::make_unique<dotmatrix_component>(D, machine, compnode, dirname);
}
-//-------------------------------------------------
-// led16seg_component - constructor
-//-------------------------------------------------
-
-layout_element::led16seg_component::led16seg_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
-{
-}
+//**************************************************************************
+// LAYOUT ELEMENT TEXTURE
+//**************************************************************************
//-------------------------------------------------
-// draw - draw a component
+// texture - constructors
//-------------------------------------------------
-void layout_element::led16seg_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+layout_element::texture::texture()
+ : m_element(nullptr)
+ , m_texture(nullptr)
+ , m_state(0)
{
- const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight);
- tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
-
- // top-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2,
- segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen);
-
- // top-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2,
- segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen);
-
- // right-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 2)) ? onpen : offpen);
-
- // right-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 3)) ? onpen : offpen);
-
- // bottom-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2,
- segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen);
-
- // bottom-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2,
- segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen);
-
- // left-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 6)) ? onpen : offpen);
-
- // left-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- // horizontal-middle-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
- segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen);
-
- // horizontal-middle-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
- segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen);
-
- // vertical-middle-top bar
- draw_segment_vertical_caps(tempbitmap,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen);
-
- // vertical-middle-bottom bar
- draw_segment_vertical_caps(tempbitmap,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen);
-
- // diagonal-left-bottom bar
- draw_segment_diagonal_1(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 12)) ? onpen : offpen);
-
- // diagonal-left-top bar
- draw_segment_diagonal_2(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 13)) ? onpen : offpen);
-
- // diagonal-right-top bar
- draw_segment_diagonal_1(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 14)) ? onpen : offpen);
-
- // diagonal-right-bottom bar
- draw_segment_diagonal_2(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 15)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
}
-//-------------------------------------------------
-// led16segsc_component - constructor
-//-------------------------------------------------
-
-layout_element::led16segsc_component::led16segsc_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+layout_element::texture::texture(texture &&that) : texture()
{
+ operator=(std::move(that));
}
//-------------------------------------------------
-// draw - draw a component
+// ~texture - destructor
//-------------------------------------------------
-void layout_element::led16segsc_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+layout_element::texture::~texture()
{
- const rgb_t onpen = rgb_t(0xff, 0xff, 0xff, 0xff);
- const rgb_t offpen = rgb_t(0xff, 0x20, 0x20, 0x20);
-
- // sizes for computation
- int bmwidth = 250;
- int bmheight = 400;
- int segwidth = 40;
- int skewwidth = 40;
-
- // allocate a temporary bitmap for drawing
- bitmap_argb32 tempbitmap(bmwidth + skewwidth, bmheight + segwidth);
- tempbitmap.fill(rgb_t(0xff, 0x00, 0x00, 0x00));
-
- // top-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, 0 + segwidth/2,
- segwidth, LINE_CAP_START, (state & (1 << 0)) ? onpen : offpen);
-
- // top-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, 0 + segwidth/2,
- segwidth, LINE_CAP_END, (state & (1 << 1)) ? onpen : offpen);
-
- // right-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 2)) ? onpen : offpen);
-
- // right-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, bmwidth - segwidth/2,
- segwidth, (state & (1 << 3)) ? onpen : offpen);
-
- // bottom-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight - segwidth/2,
- segwidth, LINE_CAP_END, (state & (1 << 4)) ? onpen : offpen);
-
- // bottom-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight - segwidth/2,
- segwidth, LINE_CAP_START, (state & (1 << 5)) ? onpen : offpen);
-
- // left-bottom bar
- draw_segment_vertical(tempbitmap,
- bmheight/2 + segwidth/3, bmheight - 2*segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 6)) ? onpen : offpen);
-
- // left-top bar
- draw_segment_vertical(tempbitmap,
- 0 + 2*segwidth/3, bmheight/2 - segwidth/3, 0 + segwidth/2,
- segwidth, (state & (1 << 7)) ? onpen : offpen);
-
- // horizontal-middle-left bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + 2*segwidth/3, bmwidth/2 - segwidth/10, bmheight/2,
- segwidth, LINE_CAP_START, (state & (1 << 8)) ? onpen : offpen);
-
- // horizontal-middle-right bar
- draw_segment_horizontal_caps(tempbitmap,
- 0 + bmwidth/2 + segwidth/10, bmwidth - 2*segwidth/3, bmheight/2,
- segwidth, LINE_CAP_END, (state & (1 << 9)) ? onpen : offpen);
-
- // vertical-middle-top bar
- draw_segment_vertical_caps(tempbitmap,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 10)) ? onpen : offpen);
-
- // vertical-middle-bottom bar
- draw_segment_vertical_caps(tempbitmap,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3, bmwidth/2,
- segwidth, LINE_CAP_NONE, (state & (1 << 11)) ? onpen : offpen);
-
- // diagonal-left-bottom bar
- draw_segment_diagonal_1(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 12)) ? onpen : offpen);
-
- // diagonal-left-top bar
- draw_segment_diagonal_2(tempbitmap,
- 0 + segwidth + segwidth/5, bmwidth/2 - segwidth/2 - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 13)) ? onpen : offpen);
-
- // diagonal-right-top bar
- draw_segment_diagonal_1(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- 0 + segwidth + segwidth/3, bmheight/2 - segwidth/2 - segwidth/3,
- segwidth, (state & (1 << 14)) ? onpen : offpen);
-
- // diagonal-right-bottom bar
- draw_segment_diagonal_2(tempbitmap,
- bmwidth/2 + segwidth/2 + segwidth/5, bmwidth - segwidth - segwidth/5,
- bmheight/2 + segwidth/2 + segwidth/3, bmheight - segwidth - segwidth/3,
- segwidth, (state & (1 << 15)) ? onpen : offpen);
-
- // comma tail
- draw_segment_diagonal_1(tempbitmap,
- bmwidth - (segwidth/2), bmwidth + segwidth,
- bmheight - (segwidth), bmheight + segwidth*1.5,
- segwidth/2, (state & (1 << 17)) ? onpen : offpen);
-
- // decimal point (draw last for priority)
- draw_segment_decimal(tempbitmap, bmwidth + segwidth/2, bmheight - segwidth/2, segwidth, (state & (1 << 16)) ? onpen : offpen);
-
- // apply skew
- apply_skew(tempbitmap, 40);
-
- // resample to the target size
- render_resample_argb_bitmap_hq(dest, tempbitmap, color());
+ if (m_element != nullptr)
+ m_element->machine().render().texture_free(m_texture);
}
//-------------------------------------------------
-// rect_component - constructor
+// opearator= - move assignment
//-------------------------------------------------
-layout_element::rect_component::rect_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+layout_element::texture &layout_element::texture::operator=(texture &&that)
{
+ using std::swap;
+ swap(m_element, that.m_element);
+ swap(m_texture, that.m_texture);
+ swap(m_state, that.m_state);
+ return *this;
}
-//-------------------------------------------------
-// draw - draw a component
-//-------------------------------------------------
-void layout_element::rect_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
-{
- // compute premultiplied colors
- u32 r = color().r * color().a * 255.0f;
- u32 g = color().g * color().a * 255.0f;
- u32 b = color().b * color().a * 255.0f;
- u32 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 x = bounds.min_x; x <= bounds.max_x; x++)
- {
- u32 finalr = r;
- u32 finalg = g;
- u32 finalb = b;
-
- // if we're translucent, add in the destination pixel contribution
- if (inva > 0)
- {
- rgb_t dpix = dest.pix32(y, x);
- finalr += (dpix.r() * inva) >> 8;
- finalg += (dpix.g() * inva) >> 8;
- finalb += (dpix.b() * inva) >> 8;
- }
-
- // store the target pixel, dividing the RGBA values by the overall scale factor
- dest.pix32(y, x) = rgb_t(finalr, finalg, finalb);
- }
- }
-}
+//**************************************************************************
+// LAYOUT ELEMENT COMPONENT
+//**************************************************************************
//-------------------------------------------------
-// disk_component - constructor
+// component - constructor
//-------------------------------------------------
-layout_element::disk_component::disk_component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
- : component(machine, compnode, dirname)
+layout_element::component::component(running_machine &machine, util::xml::data_node const &compnode, const char *dirname)
+ : m_state(0)
{
+ // fetch common data
+ m_state = xml_get_attribute_int_with_subst(machine, compnode, "state", -1);
+ parse_bounds(machine, compnode.get_child("bounds"), m_bounds);
+ parse_color(machine, compnode.get_child("color"), m_color);
}
//-------------------------------------------------
-// draw - draw a component
+// normalize_bounds - normalize component bounds
//-------------------------------------------------
-void layout_element::disk_component::draw(running_machine &machine, bitmap_argb32 &dest, const rectangle &bounds, int state)
+void layout_element::component::normalize_bounds(float xoffs, float yoffs, float xscale, float yscale)
{
- // compute premultiplied colors
- u32 r = color().r * color().a * 255.0f;
- u32 g = color().g * color().a * 255.0f;
- u32 b = color().b * color().a * 255.0f;
- u32 inva = (1.0f - color().a) * 255.0f;
-
- // find the center
- float xcenter = float(bounds.xcenter());
- float ycenter = float(bounds.ycenter());
- float xradius = float(bounds.width()) * 0.5f;
- float yradius = float(bounds.height()) * 0.5f;
- float ooyradius2 = 1.0f / (yradius * yradius);
-
- // iterate over y
- for (u32 y = bounds.min_y; y <= bounds.max_y; y++)
- {
- float ycoord = ycenter - ((float)y + 0.5f);
- float xval = xradius * sqrtf(1.0f - (ycoord * ycoord) * ooyradius2);
-
- // compute left/right coordinates
- s32 left = s32(xcenter - xval + 0.5f);
- s32 right = s32(xcenter + xval + 0.5f);
-
- // draw this scanline
- for (u32 x = left; x < right; x++)
- {
- u32 finalr = r;
- u32 finalg = g;
- u32 finalb = b;
-
- // if we're translucent, add in the destination pixel contribution
- if (inva > 0)
- {
- rgb_t dpix = dest.pix32(y, x);
- finalr += (dpix.r() * inva) >> 8;
- finalg += (dpix.g() * inva) >> 8;
- finalb += (dpix.b() * inva) >> 8;
- }
-
- // store the target pixel, dividing the RGBA values by the overall scale factor
- dest.pix32(y, x) = rgb_t(finalr, finalg, finalb);
- }
- }
+ m_bounds.x0 = (m_bounds.x0 - xoffs) * xscale;
+ m_bounds.x1 = (m_bounds.x1 - xoffs) * xscale;
+ m_bounds.y0 = (m_bounds.y0 - yoffs) * yscale;
+ m_bounds.y1 = (m_bounds.y1 - yoffs) * yscale;
}
@@ -2213,7 +2248,7 @@ 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, simple_list<layout_element> &elemlist)
+layout_view::layout_view(running_machine &machine, util::xml::data_node const &viewnode, element_map &elemmap)
: m_next(nullptr)
, m_aspect(1.0f)
, m_scraspect(1.0f)
@@ -2229,27 +2264,27 @@ layout_view::layout_view(running_machine &machine, util::xml::data_node const &v
// 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, elemlist)));
+ 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, elemlist)));
+ 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, elemlist)));
+ 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, elemlist)));
+ 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, elemlist)));
+ 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, elemlist)));
+ m_marquee_list.append(*global_alloc(item(machine, *itemnode, elemmap)));
// recompute the data for the view based on a default layer config
recompute(render_layer_config());
@@ -2410,7 +2445,7 @@ void layout_view::resolve_tags()
// item - constructor
//-------------------------------------------------
-layout_view::item::item(running_machine &machine, util::xml::data_node const &itemnode, simple_list<layout_element> &elemlist)
+layout_view::item::item(running_machine &machine, util::xml::data_node const &itemnode, element_map &elemmap)
: m_next(nullptr)
, m_element(nullptr)
, m_input_port(nullptr)
@@ -2425,19 +2460,14 @@ layout_view::item::item(running_machine &machine, util::xml::data_node const &it
m_input_tag = xml_get_attribute_string_with_subst(machine, itemnode, "inputtag", "");
// find the associated element
- const char *name = xml_get_attribute_string_with_subst(machine, itemnode, "element", nullptr);
- if (name != nullptr)
+ char const *const name = xml_get_attribute_string_with_subst(machine, itemnode, "element", nullptr);
+ if (name)
{
- // search the list of elements for a match
- for (layout_element &elem : elemlist)
- if (strcmp(name, elem.name()) == 0)
- {
- m_element = &elem;
- break;
- }
-
- // error if not found
- if (m_element == nullptr)
+ // search the list of elements for a match, error if not found
+ element_map::iterator const found(elemmap.find(name));
+ if (elemmap.end() != found)
+ m_element = &found->second;
+ else
throw emu_fatalerror("Unable to find layout element %s", name);
}
@@ -2556,8 +2586,13 @@ layout_file::layout_file(running_machine &machine, util::xml::data_node const &r
throw emu_fatalerror("Invalid XML file: unsupported version");
// parse all the elements
- for (util::xml::data_node const *elemnode = mamelayoutnode->get_child("element"); elemnode != nullptr; elemnode = elemnode->get_next_sibling("element"))
- m_elemlist.append(*global_alloc(layout_element(machine, *elemnode, dirname)));
+ 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));
+ }
// parse all the views
for (util::xml::data_node const *viewnode = mamelayoutnode->get_child("view"); viewnode != nullptr; viewnode = viewnode->get_next_sibling("view"))
@@ -2568,7 +2603,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_elemlist)));
+ m_viewlist.append(*global_alloc(layout_view(machine, *viewnode, m_elemmap)));
}
catch (emu_fatalerror const &)
{