diff options
author | 2015-11-08 12:56:12 +0100 | |
---|---|---|
committer | 2015-11-08 12:56:12 +0100 | |
commit | 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch) | |
tree | f310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/emu/drawgfx.cpp | |
parent | a57b46ae933badd7441ce1644711dbb851e2b504 (diff) |
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/emu/drawgfx.cpp')
-rw-r--r-- | src/emu/drawgfx.cpp | 2132 |
1 files changed, 2132 insertions, 0 deletions
diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp new file mode 100644 index 00000000000..1c8a863bc84 --- /dev/null +++ b/src/emu/drawgfx.cpp @@ -0,0 +1,2132 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, Aaron Giles +/********************************************************************* + + drawgfx.c + + Generic graphic functions. +*********************************************************************/ + +#include "emu.h" +#include "drawgfxm.h" + + +/*************************************************************************** + GLOBAL VARIABLES +***************************************************************************/ + +// if this line errors during compile, the size of NO_PRIORITY is wrong and I need to use something else +UINT8 no_priority_size_is_wrong[2 * (sizeof(NO_PRIORITY) == 3) - 1]; + +bitmap_ind8 drawgfx_dummy_priority_bitmap; + + + +/*************************************************************************** + INLINE FUNCTIONS +***************************************************************************/ + +/*------------------------------------------------- + readbit - read a single bit from a base + offset +-------------------------------------------------*/ + +static inline int readbit(const UINT8 *src, unsigned int bitnum) +{ + return src[bitnum / 8] & (0x80 >> (bitnum % 8)); +} + + +/*------------------------------------------------- + normalize_xscroll - normalize an X scroll + value for a bitmap to be positive and less + than the width +-------------------------------------------------*/ + +static inline INT32 normalize_xscroll(bitmap_t &bitmap, INT32 xscroll) +{ + return (xscroll >= 0) ? xscroll % bitmap.width() : (bitmap.width() - (-xscroll) % bitmap.width()); +} + + +/*------------------------------------------------- + normalize_yscroll - normalize a Y scroll + value for a bitmap to be positive and less + than the height +-------------------------------------------------*/ + +static inline INT32 normalize_yscroll(bitmap_t &bitmap, INT32 yscroll) +{ + return (yscroll >= 0) ? yscroll % bitmap.height() : (bitmap.height() - (-yscroll) % bitmap.height()); +} + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type GFXDECODE = &device_creator<gfxdecode_device>; + +gfxdecode_device::gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, GFXDECODE, "gfxdecode", tag, owner, clock, "gfxdecode", __FILE__), + device_gfx_interface(mconfig, *this) +{ +} + + + + +/*************************************************************************** + GRAPHICS ELEMENTS +***************************************************************************/ + + +//------------------------------------------------- +// gfx_element - constructor +//------------------------------------------------- + +gfx_element::gfx_element() + : m_palette(NULL), + m_width(0), + m_height(0), + m_startx(0), + m_starty(0), + m_origwidth(0), + m_origheight(0), + m_total_elements(0), + m_color_base(0), + m_color_depth(0), + m_color_granularity(0), + m_total_colors(0), + m_line_modulo(0), + m_char_modulo(0), + m_srcdata(NULL), + m_dirtyseq(1), + m_gfxdata(NULL), + m_layout_is_raw(false), + m_layout_planes(0), + m_layout_xormask(0), + m_layout_charincrement(0) +{ +} + +gfx_element::gfx_element(palette_device *palette, UINT8 *base, UINT32 width, UINT32 height, UINT32 rowbytes, UINT32 total_colors, UINT32 color_base, UINT32 color_granularity) + : m_palette(palette), + m_width(width), + m_height(height), + m_startx(0), + m_starty(0), + m_origwidth(width), + m_origheight(height), + m_total_elements(1), + m_color_base(color_base), + m_color_depth(color_granularity), + m_color_granularity(color_granularity), + m_total_colors((total_colors - color_base) / color_granularity), + m_line_modulo(rowbytes), + m_char_modulo(0), + m_srcdata(base), + m_dirtyseq(1), + m_gfxdata(base), + m_layout_is_raw(true), + m_layout_planes(0), + m_layout_xormask(0), + m_layout_charincrement(0) +{ +} + +gfx_element::gfx_element(palette_device *palette, const gfx_layout &gl, const UINT8 *srcdata, UINT32 xormask, UINT32 total_colors, UINT32 color_base) + : m_palette(palette), + m_width(0), + m_height(0), + m_startx(0), + m_starty(0), + m_origwidth(0), + m_origheight(0), + m_total_elements(0), + m_color_base(color_base), + m_color_depth(0), + m_color_granularity(0), + m_total_colors(total_colors), + m_line_modulo(0), + m_char_modulo(0), + m_srcdata(NULL), + m_dirtyseq(1), + m_gfxdata(NULL), + m_layout_is_raw(false), + m_layout_planes(0), + m_layout_xormask(xormask), + m_layout_charincrement(0) +{ + // set the layout + set_layout(gl, srcdata); +} + + +//------------------------------------------------- +// set_layout - set the layout for a gfx_element +//------------------------------------------------- + +void gfx_element::set_layout(const gfx_layout &gl, const UINT8 *srcdata) +{ + m_srcdata = srcdata; + + // configure ourselves + m_width = m_origwidth = gl.width; + m_height = m_origheight = gl.height; + m_startx = m_starty = 0; + m_total_elements = gl.total; + m_color_depth = m_color_granularity = 1 << gl.planes; + + // copy data from the layout + m_layout_is_raw = (gl.planeoffset[0] == GFX_RAW); + m_layout_planes = gl.planes; + m_layout_charincrement = gl.charincrement; + + // raw graphics case + if (m_layout_is_raw) + { + // RAW layouts don't need these arrays + m_layout_planeoffset.clear(); + m_layout_xoffset.clear(); + m_layout_yoffset.clear(); + m_gfxdata_allocated.clear(); + + // modulos are determined for us by the layout + m_line_modulo = gl.yoffs(0) / 8; + m_char_modulo = gl.charincrement / 8; + + // RAW graphics must have a pointer up front + assert(srcdata != NULL); + m_gfxdata = const_cast<UINT8 *>(srcdata); + } + + // decoded graphics case + else + { + // copy offsets + m_layout_planeoffset.resize(m_layout_planes); + m_layout_xoffset.resize(m_width); + m_layout_yoffset.resize(m_height); + + for (int p = 0; p < m_layout_planes; p++) + m_layout_planeoffset[p] = gl.planeoffset[p]; + for (int y = 0; y < m_height; y++) + m_layout_yoffset[y] = gl.yoffs(y); + for (int x = 0; x < m_width; x++) + m_layout_xoffset[x] = gl.xoffs(x); + + // we get to pick our own modulos + m_line_modulo = m_origwidth; + m_char_modulo = m_line_modulo * m_origheight; + + // allocate memory for the data + m_gfxdata_allocated.resize(m_total_elements * m_char_modulo); + m_gfxdata = &m_gfxdata_allocated[0]; + } + + // mark everything dirty + m_dirty.resize(m_total_elements); + memset(&m_dirty[0], 1, m_total_elements); + + // allocate a pen usage array for entries with 32 pens or less + if (m_color_depth <= 32) + m_pen_usage.resize(m_total_elements); + else + m_pen_usage.clear(); +} + + +//------------------------------------------------- +// set_raw_layout - set the layout for a gfx_element +//------------------------------------------------- + +void gfx_element::set_raw_layout(const UINT8 *srcdata, UINT32 width, UINT32 height, UINT32 total, UINT32 linemod, UINT32 charmod) +{ + gfx_layout layout = { 0 }; + layout.width = width; + layout.height = height; + layout.total = total; + layout.planes = 8; + layout.planeoffset[0] = GFX_RAW; + layout.yoffset[0] = linemod; + layout.charincrement = charmod; + set_layout(layout, srcdata); +} + + +//------------------------------------------------- +// set_source - set the source data for a gfx_element +//------------------------------------------------- + +void gfx_element::set_source(const UINT8 *source) +{ + m_srcdata = source; + memset(&m_dirty[0], 1, elements()); + if (m_layout_is_raw) m_gfxdata = const_cast<UINT8 *>(source); +} + + +//------------------------------------------------- +// set_source_and_total - set the source data +// and total elements for a gfx_element +//------------------------------------------------- + +void gfx_element::set_source_and_total(const UINT8 *source, UINT32 total) +{ + m_srcdata = source; + m_total_elements = total; + + // mark everything dirty + m_dirty.resize(m_total_elements); + memset(&m_dirty[0], 1, m_total_elements); + + // allocate a pen usage array for entries with 32 pens or less + if (m_color_depth <= 32) + m_pen_usage.resize(m_total_elements); + + if (m_layout_is_raw) + { + m_gfxdata = const_cast<UINT8 *>(source); + } + else + { + // allocate memory for the data + m_gfxdata_allocated.resize(m_total_elements * m_char_modulo); + m_gfxdata = &m_gfxdata_allocated[0]; + } +} + + +//------------------------------------------------- +// set_source_clip - set a source clipping rect +//------------------------------------------------- + +void gfx_element::set_source_clip(UINT32 xoffs, UINT32 width, UINT32 yoffs, UINT32 height) +{ + assert(xoffs < m_origwidth); + assert(yoffs < m_origheight); + assert(xoffs + width <= m_origwidth); + assert(yoffs + height <= m_origheight); + + m_width = width; + m_height = height; + m_startx = xoffs; + m_starty = yoffs; +} + + +//------------------------------------------------- +// decode - decode a single character +//------------------------------------------------- + +void gfx_element::decode(UINT32 code) +{ + // don't decode GFX_RAW + if (!m_layout_is_raw) + { + // zap the data to 0 + UINT8 *decode_base = m_gfxdata + code * m_char_modulo; + memset(decode_base, 0, m_char_modulo); + + // iterate over planes + int plane, planebit; + for (plane = 0, planebit = 1 << (m_layout_planes - 1); + plane < m_layout_planes; + plane++, planebit >>= 1) + { + int planeoffs = code * m_layout_charincrement + m_layout_planeoffset[plane]; + + // iterate over rows + for (int y = 0; y < m_origheight; y++) + { + int yoffs = planeoffs + m_layout_yoffset[y]; + UINT8 *dp = decode_base + y * m_line_modulo; + + // iterate over columns + for (int x = 0; x < m_origwidth; x++) + if (readbit(m_srcdata, (yoffs + m_layout_xoffset[x]) ^ m_layout_xormask)) + dp[x] |= planebit; + } + } + } + + // (re)compute pen usage + if (code < m_pen_usage.size()) + { + // iterate over data, creating a bitmask of live pens + const UINT8 *dp = m_gfxdata + code * m_char_modulo; + UINT32 usage = 0; + for (int y = 0; y < m_origheight; y++) + { + for (int x = 0; x < m_origwidth; x++) + usage |= 1 << dp[x]; + dp += m_line_modulo; + } + + // store the final result + m_pen_usage[code] = usage; + } + + // no longer dirty + m_dirty[code] = 0; +} + + + +/*************************************************************************** + DRAWGFX IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + opaque - render a gfx element with + no transparency +-------------------------------------------------*/ + +void gfx_element::opaque(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty) +{ + color = colorbase() + granularity() * (color % colors()); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_OPAQUE, NO_PRIORITY); +} + +void gfx_element::opaque(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty) +{ + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + transpen - render a gfx element with + a single transparent pen +-------------------------------------------------*/ + +void gfx_element::transpen(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_pen) +{ + // special case invalid pens to opaque + if (trans_pen > 0xff) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + } + + // render + color = colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + +void gfx_element::transpen(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_pen) +{ + // special case invalid pens to opaque + if (trans_pen > 0xff) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + } + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY); +} + + +/*------------------------------------------------- + transpen_raw - render a gfx element + with a single transparent pen and no color + lookups +-------------------------------------------------*/ + +void gfx_element::transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_pen) +{ + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // render + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + +void gfx_element::transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_pen) +{ + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // render + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + + +/*------------------------------------------------- + transmask - render a gfx element + with a multiple transparent pens provided as + a mask +-------------------------------------------------*/ + +void gfx_element::transmask(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_mask) +{ + // special case 0 mask to opaque + if (trans_mask == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + } + + // render + color = colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSMASK, NO_PRIORITY); +} + +void gfx_element::transmask(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_mask) +{ + // special case 0 mask to opaque + if (trans_mask == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + } + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY); +} + + +/*------------------------------------------------- + transtable - render a gfx element + using a table to look up which pens are + transparent, opaque, or shadowing +-------------------------------------------------*/ + +void gfx_element::transtable(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + const UINT8 *pentable) +{ + assert(pentable != NULL); + + // render + color = colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSTABLE16, NO_PRIORITY); +} + +void gfx_element::transtable(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + const UINT8 *pentable) +{ + assert(pentable != NULL); + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY); +} + + +/*------------------------------------------------- + alpha - render a gfx element with + a single transparent pen, alpha blending the + remaining pixels with a fixed alpha value +-------------------------------------------------*/ + +void gfx_element::alpha(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 trans_pen, UINT8 alpha_val) +{ + // special case alpha = 0xff + if (alpha_val == 0xff) + return transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // get final code and color, and grab lookup tables + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY); +} + + + +/*************************************************************************** + DRAWGFXZOOM IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + zoom_opaque - render a scaled gfx + element with no transparency +-------------------------------------------------*/ + +void gfx_element::zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // render + color = colorbase() + granularity() * (color % colors()); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_OPAQUE, NO_PRIORITY); +} + +void gfx_element::zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return opaque(dest, cliprect, code, color, flipx, flipy, destx, desty); + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + zoom_transpen - render a scaled gfx + element with a single transparent pen +-------------------------------------------------*/ + +void gfx_element::zoom_transpen(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen); + + // special case invalid pens to opaque + if (trans_pen > 0xff) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + } + + // render + color = colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + +void gfx_element::zoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen); + + // special case invalid pens to opaque + if (trans_pen > 0xff) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + } + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY); +} + + +/*------------------------------------------------- + zoom_transpen_raw - render a scaled gfx + element with a single transparent pen and no + color lookups +-------------------------------------------------*/ + +void gfx_element::zoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transpen_raw(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // render + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + +void gfx_element::zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transpen_raw(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // render + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); +} + + +/*------------------------------------------------- + zoom_transmask - render a scaled gfx + element with a multiple transparent pens + provided as a mask +-------------------------------------------------*/ + +void gfx_element::zoom_transmask(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_mask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transmask(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_mask); + + // special case 0 mask to opaque + if (trans_mask == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + } + + // render + color = colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSMASK, NO_PRIORITY); +} + +void gfx_element::zoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_mask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transmask(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_mask); + + // special case 0 mask to opaque + if (trans_mask == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley); + } + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY); +} + + +/*------------------------------------------------- + zoom_transtable - render a scaled gfx + element using a table to look up which pens + are transparent, opaque, or shadowing +-------------------------------------------------*/ + +void gfx_element::zoom_transtable(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, const UINT8 *pentable) +{ + assert(pentable != NULL); + + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transtable(dest, cliprect, code, color, flipx, flipy, destx, desty, pentable); + + // render + color = colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSTABLE16, NO_PRIORITY); +} + +void gfx_element::zoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, const UINT8 *pentable) +{ + assert(pentable != NULL); + + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return transtable(dest, cliprect, code, color, flipx, flipy, destx, desty, pentable); + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY); +} + + +/*------------------------------------------------- + zoom_alpha - render a scaled gfx element + with a single transparent pen, alpha blending + the remaining pixels with a fixed alpha value +-------------------------------------------------*/ + +void gfx_element::zoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, UINT32 trans_pen, UINT8 alpha_val) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return alpha(dest, cliprect, code, color, flipx, flipy, destx, desty, trans_pen, alpha_val); + + // special case alpha_val = 0xff + if (alpha_val == 0xff) + return zoom_transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DECLARE_NO_PRIORITY; + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY); +} + + + +/*************************************************************************** + PDRAWGFX IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + prio_opaque - render a gfx element with + no transparency, checking against the priority + bitmap +-------------------------------------------------*/ + +void gfx_element::prio_opaque(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + code %= elements(); + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_OPAQUE_PRIORITY, UINT8); +} + +void gfx_element::prio_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + code %= elements(); + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_transpen - render a gfx element with + a single transparent pen, checking against the + priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_transpen(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen) +{ + // special case invalid pens to opaque + if (trans_pen > 0xff) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + +void gfx_element::prio_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen) +{ + // special case invalid pens to opaque + if (trans_pen > 0xff) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + priotranspen_raw - render a gfx element + with a single transparent pen and no color + lookups, checking against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen) +{ + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + +void gfx_element::prio_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen) +{ + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + DRAWGFX_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_transmask - render a gfx element + with a multiple transparent pens provided as + a mask, checking against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_transmask(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_mask) +{ + // special case 0 mask to opaque + if (trans_mask == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSMASK_PRIORITY, UINT8); +} + +void gfx_element::prio_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_mask) +{ + // special case 0 mask to opaque + if (trans_mask == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_transtable - render a gfx element + using a table to look up which pens are + transparent, opaque, or shadowing, checking + against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_transtable(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, const UINT8 *pentable) +{ + assert(pentable != NULL); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY, UINT8); +} + +void gfx_element::prio_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, const UINT8 *pentable) +{ + assert(pentable != NULL); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_alpha - render a gfx element with + a single transparent pen, alpha blending the + remaining pixels with a fixed alpha value, + checking against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen, UINT8 alpha_val) +{ + // special case alpha = 0xff + if (alpha_val == 0xff) + return prio_transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, UINT8); +} + + + +/*************************************************************************** + PDRAWGFXZOOM IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + prio_zoom_opaque - render a scaled gfx + element with no transparency, checking against + the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + code %= elements(); + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_OPAQUE_PRIORITY, UINT8); +} + +void gfx_element::prio_zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + code %= elements(); + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_zoom_transpen - render a scaled gfx + element with a single transparent pen, + checking against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_transpen(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + + // special case invalid pens to opaque + if (trans_pen > 0xff) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + +void gfx_element::prio_zoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + + // special case invalid pens to opaque + if (trans_pen > 0xff) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~(1 << trans_pen)) == 0) + return; + + // fully opaque; draw as such + if ((usage & (1 << trans_pen)) == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_zoom_transpen_raw - render a scaled gfx + element with a single transparent pen and no + color lookups, checking against the priority + bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transpen_raw(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + +void gfx_element::prio_zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transpen_raw(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_zoom_transmask - render a scaled gfx + element with a multiple transparent pens + provided as a mask, checking against the + priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_transmask(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_mask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transmask(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_mask); + + // special case 0 mask to opaque + if (trans_mask == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSMASK_PRIORITY, UINT8); +} + +void gfx_element::prio_zoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_mask) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transmask(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_mask); + + // special case 0 mask to opaque + if (trans_mask == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + + // use pen usage to optimize + code %= elements(); + if (has_pen_usage()) + { + // fully transparent; do nothing + UINT32 usage = pen_usage(code); + if ((usage & ~trans_mask) == 0) + return; + + // fully opaque; draw as such + if ((usage & trans_mask) == 0) + return prio_zoom_opaque(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask); + } + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_zoom_transtable - render a scaled gfx + element using a table to look up which pens + are transparent, opaque, or shadowing, + checking against the priority bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_transtable(bitmap_ind16 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + const UINT8 *pentable) +{ + assert(pentable != NULL); + + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transtable(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, pentable); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + color = colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY, UINT8); +} + +void gfx_element::prio_zoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + const UINT8 *pentable) +{ + assert(pentable != NULL); + + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_transtable(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, pentable); + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + const pen_t *shadowtable = m_palette->shadow_table(); + code %= elements(); + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, UINT8); +} + + +/*------------------------------------------------- + prio_zoom_alpha - render a scaled gfx + element with a single transparent pen, alpha + blending the remaining pixels with a fixed + alpha value, checking against the priority + bitmap +-------------------------------------------------*/ + +void gfx_element::prio_zoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen, UINT8 alpha_val) +{ + // non-zoom case + if (scalex == 0x10000 && scaley == 0x10000) + return prio_alpha(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen, alpha_val); + + // special case alpha_val = 0xff + if (alpha_val == 0xff) + return prio_zoom_transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask, trans_pen); + + // early out if completely transparent + code %= elements(); + if (has_pen_usage() && (pen_usage(code) & ~(1 << trans_pen)) == 0) + return; + + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // render + const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, UINT8); +} + + +#define PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + UINT32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + { \ + UINT32 srcdata2 = paldata[srcdata]; \ + \ + UINT32 add; \ + add = (srcdata2 & 0x00ff0000) + (DEST & 0x00ff0000); \ + if (add & 0x01000000) DEST = (DEST & 0xff00ffff) | (0x00ff0000); \ + else DEST = (DEST & 0xff00ffff) | (add & 0x00ff0000); \ + add = (srcdata2 & 0x000000ff) + (DEST & 0x000000ff); \ + if (add & 0x00000100) DEST = (DEST & 0xffffff00) | (0x000000ff); \ + else DEST = (DEST & 0xffffff00) | (add & 0x000000ff); \ + add = (srcdata2 & 0x0000ff00) + (DEST & 0x0000ff00); \ + if (add & 0x00010000) DEST = (DEST & 0xffff00ff) | (0x0000ff00); \ + else DEST = (DEST & 0xffff00ff) | (add & 0x0000ff00); \ + } \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + +void gfx_element::prio_transpen_additive(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + bitmap_ind8 &priority, UINT32 pmask, UINT32 trans_pen) +{ + const pen_t *paldata; + + assert(dest.valid()); + assert(dest.bpp() == 32); + + /* get final code and color, and grab lookup tables */ + code %= elements(); + color %= colors(); + paldata = m_palette->pens() + colorbase() + granularity() * color; + + /* use pen usage to optimize */ + if (has_pen_usage()) + { + UINT32 usage = pen_usage(code); + + /* fully transparent; do nothing */ + if ((usage & ~(1 << trans_pen)) == 0) + return; + } + + /* high bit of the mask is implicitly on */ + pmask |= 1 << 31; + + /* render based on dest bitmap depth */ + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32, UINT8); +} + + +void gfx_element::prio_zoom_transpen_additive(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask, + UINT32 trans_pen) +{ + const pen_t *paldata; + + /* non-zoom case */ + + if (scalex == 0x10000 && scaley == 0x10000) + { + prio_transpen_additive(dest, cliprect, code, color, flipx, flipy, destx, desty, priority, pmask, trans_pen); + return; + } + + assert(dest.valid()); + assert(dest.bpp() == 32); + + /* get final code and color, and grab lookup tables */ + code %= elements(); + color %= colors(); + paldata = m_palette->pens() + colorbase() + granularity() * color; + + /* use pen usage to optimize */ + if (has_pen_usage()) + { + UINT32 usage = pen_usage(code); + + /* fully transparent; do nothing */ + if ((usage & ~(1 << trans_pen)) == 0) + return; + } + + /* high bit of the mask is implicitly on */ + pmask |= 1 << 31; + + DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32, UINT8); +} + +//#define MAKE_ARGB_RGB(a, rgb) rgb_t(a, rgb.r(), rgb.g(), rgb.b()) +#define MAKE_ARGB_RGB(a, rgb) rgb_t(rgb).set_a(a) + +// combine in 'alpha' when copying to store in ARGB +#define PIXEL_OP_REMAP_TRANS0_ALPHASTORE32(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + UINT32 srcdata = (SOURCE); \ + if (srcdata != 0) \ + (DEST) = MAKE_ARGB_RGB(alpha,paldata[srcdata]); \ +} \ +while (0) +// combine in 'alphatable' value to store in ARGB +#define PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + UINT32 srcdata = (SOURCE); \ + if (srcdata != 0) \ + (DEST) = MAKE_ARGB_RGB(alphatable[srcdata], paldata[srcdata]); \ +} \ +while (0) +// drawgfxm.h macro to render alpha into 32-bit buffer +#define PIXEL_OP_REMAP_TRANS0_ALPHATABLE32(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + UINT32 srcdata = (SOURCE); \ + if (srcdata != 0) \ + (DEST) = alpha_blend_r32((DEST), paldata[srcdata], alphatable[srcdata]); \ +} \ +while (0) + +/*------------------------------------------------- + alphastore - render a gfx element with + a single transparent pen, storing the alpha value + in alpha field of ARGB32, negative alpha implies alphatable +-------------------------------------------------*/ +void gfx_element::alphastore(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + int fixedalpha, UINT8 *alphatable) +{ + DECLARE_NO_PRIORITY; + const pen_t *paldata; + + assert(dest.bpp() == 32); + assert(dest.format() == BITMAP_FORMAT_ARGB32); + assert(alphatable != NULL); + + /* if we have a fixed alpha, call the standard drawgfx_transpen */ + if (fixedalpha == 0xff) + { + transpen(dest, cliprect, code, color, flipx, flipy, destx, desty, 0); + return; + } + + /* get final code and color, and grab lookup tables */ + code %= elements(); + color %= colors(); + paldata = m_palette->pens() + colorbase() + granularity() * color; + + /* early out if completely transparent */ + if (has_pen_usage() && (pen_usage(code) & ~(1 << 0)) == 0) + return; + + if (fixedalpha >= 0) + { + UINT8 alpha = fixedalpha; + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANS0_ALPHASTORE32, NO_PRIORITY); + } + else + { + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32, NO_PRIORITY); + } +} + +/*------------------------------------------------- + alphatable - render a sprite with either + a fixed alpha value, or if alpha==-1 then uses + the per-pen alphatable[] array + -------------------------------------------------*/ +void gfx_element::alphatable(bitmap_rgb32 &dest, const rectangle &cliprect, + UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty, + int fixedalpha ,UINT8 *alphatable) +{ + DECLARE_NO_PRIORITY; + + const pen_t *paldata; + + /* if we have a fixed alpha, call the standard drawgfx_alpha */ + if (fixedalpha >= 0) + { + alpha(dest, cliprect, code, color, flipx, flipy, destx, desty, 0, fixedalpha); + return; + } + + assert(dest.bpp() == 32); + assert(alphatable != NULL); + + /* get final code and color, and grab lookup tables */ + code %= elements(); + color %= colors(); + paldata = m_palette->pens() + colorbase() + granularity() * color; + + /* early out if completely transparent */ + if (has_pen_usage() && (pen_usage(code) & ~(1 << 0)) == 0) + return; + + DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANS0_ALPHATABLE32, NO_PRIORITY); +} + + +/*************************************************************************** + DRAW_SCANLINE IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + draw_scanline8 - copy pixels from an 8bpp + buffer to a single scanline of a bitmap +-------------------------------------------------*/ + +void draw_scanline8(bitmap_ind16 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT8 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + +void draw_scanline8(bitmap_rgb32 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT8 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + draw_scanline16 - copy pixels from a 16bpp + buffer to a single scanline of a bitmap +-------------------------------------------------*/ + +void draw_scanline16(bitmap_ind16 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT16 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + +void draw_scanline16(bitmap_rgb32 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT16 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + draw_scanline32 - copy pixels from a 32bpp + buffer to a single scanline of a bitmap +-------------------------------------------------*/ + +void draw_scanline32(bitmap_ind16 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT32 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + +void draw_scanline32(bitmap_rgb32 &bitmap, INT32 destx, INT32 desty, INT32 length, const UINT32 *srcptr, const pen_t *paldata) +{ + DECLARE_NO_PRIORITY; + + // palette lookup case + if (paldata != NULL) + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + + // raw copy case + else + DRAWSCANLINE_CORE(UINT32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + + + +/*************************************************************************** + EXTRACT_SCANLINE IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + extract_scanline8 - copy pixels from a single + scanline of a bitmap to an 8bpp buffer +-------------------------------------------------*/ + +void extract_scanline8(bitmap_ind16 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT8 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT16); +} + +void extract_scanline8(bitmap_rgb32 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT8 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT32); +} + + +/*------------------------------------------------- + extract_scanline16 - copy pixels from a single + scanline of a bitmap to a 16bpp buffer +-------------------------------------------------*/ + +void extract_scanline16(bitmap_ind16 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT16 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT16); +} + +void extract_scanline16(bitmap_rgb32 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT16 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT32); +} + + +/*------------------------------------------------- + extract_scanline32 - copy pixels from a single + scanline of a bitmap to a 32bpp buffer +-------------------------------------------------*/ + +void extract_scanline32(bitmap_ind16 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT32 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT16); +} + +void extract_scanline32(bitmap_rgb32 &bitmap, INT32 srcx, INT32 srcy, INT32 length, UINT32 *destptr) +{ + EXTRACTSCANLINE_CORE(UINT32); +} + + + +/*************************************************************************** + COPYBITMAP IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + copybitmap - copy from one bitmap to another, + copying all unclipped pixels +-------------------------------------------------*/ + +void copybitmap(bitmap_ind16 &dest, bitmap_ind16 &src, int flipx, int flipy, INT32 destx, INT32 desty, const rectangle &cliprect) +{ + DECLARE_NO_PRIORITY; + COPYBITMAP_CORE(UINT16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + +void copybitmap(bitmap_rgb32 &dest, bitmap_rgb32 &src, int flipx, int flipy, INT32 destx, INT32 desty, const rectangle &cliprect) +{ + DECLARE_NO_PRIORITY; + COPYBITMAP_CORE(UINT32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + copybitmap_trans - copy from one bitmap to + another, copying all unclipped pixels except + those that match transpen +-------------------------------------------------*/ + +void copybitmap_trans(bitmap_ind16 &dest, bitmap_ind16 &src, int flipx, int flipy, INT32 destx, INT32 desty, const rectangle &cliprect, UINT32 trans_pen) +{ + DECLARE_NO_PRIORITY; + if (trans_pen > 0xffff) + copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); + else + COPYBITMAP_CORE(UINT16, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); +} + +void copybitmap_trans(bitmap_rgb32 &dest, bitmap_rgb32 &src, int flipx, int flipy, INT32 destx, INT32 desty, const rectangle &cliprect, UINT32 trans_pen) +{ + DECLARE_NO_PRIORITY; + if (trans_pen == 0xffffffff) + copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); + else + COPYBITMAP_CORE(UINT32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); +} + + + +/*************************************************************************** + COPYSCROLLBITMAP IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + copyscrollbitmap - copy from one bitmap to + another, copying all unclipped pixels, and + applying scrolling to one or more rows/columns +-------------------------------------------------*/ + +void copyscrollbitmap(bitmap_ind16 &dest, bitmap_ind16 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, 0xffffffff); +} + +void copyscrollbitmap(bitmap_rgb32 &dest, bitmap_rgb32 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, 0xffffffff); +} + + +/*------------------------------------------------- + copyscrollbitmap_trans - copy from one bitmap + to another, copying all unclipped pixels + except those that match transpen, and applying + scrolling to one or more rows/columns +-------------------------------------------------*/ + +template<class _BitmapClass> +static inline void copyscrollbitmap_trans_common(_BitmapClass &dest, _BitmapClass &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect, UINT32 trans_pen) +{ + // no rowscroll and no colscroll means no scroll + if (numrows == 0 && numcols == 0) + return copybitmap_trans(dest, src, 0, 0, 0, 0, cliprect, trans_pen); + + assert(numrows != 0 || rowscroll == NULL); + assert(numrows == 0 || rowscroll != NULL); + assert(numcols != 0 || colscroll == NULL); + assert(numcols == 0 || colscroll != NULL); + + // fully scrolling X,Y playfield + if (numrows <= 1 && numcols <= 1) + { + INT32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + INT32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + + // iterate over all portions of the scroll that overlap the destination + for (INT32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + for (INT32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + copybitmap_trans(dest, src, 0, 0, sx, sy, cliprect, trans_pen); + } + + // scrolling columns plus horizontal scroll + else if (numrows <= 1) + { + INT32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + rectangle subclip = cliprect; + + // determine width of each column + int colwidth = src.width() / numcols; + assert(src.width() % colwidth == 0); + + // iterate over each column + int groupcols; + for (int col = 0; col < numcols; col += groupcols) + { + INT32 yscroll = colscroll[col]; + + // count consecutive columns scrolled by the same amount + for (groupcols = 1; col + groupcols < numcols; groupcols++) + if (colscroll[col + groupcols] != yscroll) + break; + + // iterate over reps of the columns in question + yscroll = normalize_yscroll(src, yscroll); + for (INT32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + { + // compute the cliprect for this group + subclip.min_x = col * colwidth + sx; + subclip.max_x = (col + groupcols) * colwidth - 1 + sx; + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (INT32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, trans_pen); + } + } + } + + // scrolling rows plus vertical scroll + else if (numcols <= 1) + { + INT32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + rectangle subclip = cliprect; + + // determine width of each rows + int rowheight = src.height() / numrows; + assert(src.height() % rowheight == 0); + + // iterate over each row + int grouprows; + for (int row = 0; row < numrows; row += grouprows) + { + INT32 xscroll = rowscroll[row]; + + // count consecutive rows scrolled by the same amount + for (grouprows = 1; row + grouprows < numrows; grouprows++) + if (rowscroll[row + grouprows] != xscroll) + break; + + // iterate over reps of the rows in question + xscroll = normalize_xscroll(src, xscroll); + for (INT32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + { + // compute the cliprect for this group + subclip.min_y = row * rowheight + sy; + subclip.max_y = (row + grouprows) * rowheight - 1 + sy; + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (INT32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, trans_pen); + } + } + } +} + +void copyscrollbitmap_trans(bitmap_ind16 &dest, bitmap_ind16 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect, UINT32 trans_pen) +{ copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen); } + +void copyscrollbitmap_trans(bitmap_rgb32 &dest, bitmap_rgb32 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect, UINT32 trans_pen) +{ copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen); } + + + +/*************************************************************************** + COPYROZBITMAP IMPLEMENTATIONS +***************************************************************************/ + +/*------------------------------------------------- + copyrozbitmap - copy from one bitmap to another, + with zoom and rotation, copying all unclipped + pixels +-------------------------------------------------*/ + +void copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, bitmap_ind16 &src, INT32 startx, INT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, int wraparound) +{ + DECLARE_NO_PRIORITY; + COPYROZBITMAP_CORE(UINT16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + +void copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, bitmap_rgb32 &src, INT32 startx, INT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, int wraparound) +{ + DECLARE_NO_PRIORITY; + COPYROZBITMAP_CORE(UINT32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); +} + + +/*------------------------------------------------- + copyrozbitmap_trans - copy from one bitmap to + another, with zoom and rotation, copying all + unclipped pixels whose values do not match + transpen +-------------------------------------------------*/ + +void copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, bitmap_ind16 &src, INT32 startx, INT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, int wraparound, UINT32 trans_pen) +{ + DECLARE_NO_PRIORITY; + COPYROZBITMAP_CORE(UINT16, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); +} + +void copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, bitmap_rgb32 &src, INT32 startx, INT32 starty, INT32 incxx, INT32 incxy, INT32 incyx, INT32 incyy, int wraparound, UINT32 trans_pen) +{ + DECLARE_NO_PRIORITY; + COPYROZBITMAP_CORE(UINT32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); +} + +GFXDECODE_START( empty ) +GFXDECODE_END |