/*********************************************************************
drawgfx.c
Generic graphic functions.
Copyright Nicola Salmoria and the MAME Team.
Visit http://mamedev.org for licensing and usage restrictions.
*********************************************************************/
#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());
}
/***************************************************************************
GRAPHICS ELEMENTS
***************************************************************************/
/*-------------------------------------------------
gfx_init - allocate memory for the graphics
elements referenced by a machine
-------------------------------------------------*/
void gfx_init(running_machine &machine)
{
const gfx_decode_entry *gfxdecodeinfo = machine.config().m_gfxdecodeinfo;
int curgfx;
// skip if nothing to do
if (gfxdecodeinfo == NULL)
return;
// loop over all elements
for (curgfx = 0; curgfx < MAX_GFX_ELEMENTS && gfxdecodeinfo[curgfx].gfxlayout != NULL; curgfx++)
{
const gfx_decode_entry *gfxdecode = &gfxdecodeinfo[curgfx];
memory_region *region = (gfxdecode->memory_region != NULL) ? machine.root_device().memregion(gfxdecode->memory_region) : NULL;
UINT32 region_length = (region != NULL) ? (8 * region->bytes()) : 0;
const UINT8 *region_base = (region != NULL) ? region->base() : NULL;
UINT32 xscale = (gfxdecode->xscale == 0) ? 1 : gfxdecode->xscale;
UINT32 yscale = (gfxdecode->yscale == 0) ? 1 : gfxdecode->yscale;
UINT32 *extpoffs, extxoffs[MAX_ABS_GFX_SIZE], extyoffs[MAX_ABS_GFX_SIZE];
const gfx_layout *gl = gfxdecode->gfxlayout;
int israw = (gl->planeoffset[0] == GFX_RAW);
int planes = gl->planes;
UINT32 width = gl->width;
UINT32 height = gl->height;
UINT32 total = gl->total;
UINT32 charincrement = gl->charincrement;
gfx_layout glcopy;
int j;
// make a copy of the layout
glcopy = *gfxdecode->gfxlayout;
// copy the X and Y offsets into temporary arrays
memcpy(extxoffs, glcopy.xoffset, sizeof(glcopy.xoffset));
memcpy(extyoffs, glcopy.yoffset, sizeof(glcopy.yoffset));
// if there are extended offsets, copy them over top
if (glcopy.extxoffs != NULL)
memcpy(extxoffs, glcopy.extxoffs, glcopy.width * sizeof(extxoffs[0]));
if (glcopy.extyoffs != NULL)
memcpy(extyoffs, glcopy.extyoffs, glcopy.height * sizeof(extyoffs[0]));
// always use the extended offsets here
glcopy.extxoffs = extxoffs;
glcopy.extyoffs = extyoffs;
extpoffs = glcopy.planeoffset;
// expand X and Y by the scale factors
if (xscale > 1)
{
width *= xscale;
for (j = width - 1; j >= 0; j--)
extxoffs[j] = extxoffs[j / xscale];
}
if (yscale > 1)
{
height *= yscale;
for (j = height - 1; j >= 0; j--)
extyoffs[j] = extyoffs[j / yscale];
}
// if the character count is a region fraction, compute the effective total
if (IS_FRAC(total))
{
assert(region_length != 0);
total = region_length / charincrement * FRAC_NUM(total) / FRAC_DEN(total);
}
// for non-raw graphics, decode the X and Y offsets
if (!israw)
{
// loop over all the planes, converting fractions
for (j = 0; j < planes; j++)
{
UINT32 value1 = extpoffs[j];
if (IS_FRAC(value1))
{
assert(region_length != 0);
extpoffs[j] = FRAC_OFFSET(value1) + region_length * FRAC_NUM(value1) / FRAC_DEN(value1);
}
}
// loop over all the X/Y offsets, converting fractions
for (j = 0; j < width; j++)
{
UINT32 value2 = extxoffs[j];
if (IS_FRAC(value2))
{
assert(region_length != 0);
extxoffs[j] = FRAC_OFFSET(value2) + region_length * FRAC_NUM(value2) / FRAC_DEN(value2);
}
}
for (j = 0; j < height; j++)
{
UINT32 value3 = extyoffs[j];
if (IS_FRAC(value3))
{
assert(region_length != 0);
extyoffs[j] = FRAC_OFFSET(value3) + region_length * FRAC_NUM(value3) / FRAC_DEN(value3);
}
}
}
// otherwise, just use the line modulo
else
{
int base = gfxdecode->start;
int end = region_length/8;
int linemod = gl->yoffset[0];
while (total > 0)
{
int elementbase = base + (total - 1) * charincrement / 8;
int lastpixelbase = elementbase + height * linemod / 8 - 1;
if (lastpixelbase < end)
break;
total--;
}
}
// update glcopy
glcopy.width = width;
glcopy.height = height;
glcopy.total = total;
// allocate the graphics
machine.gfx[curgfx] = auto_alloc(machine, gfx_element(machine, glcopy, (region_base != NULL) ? region_base + gfxdecode->start : NULL, gfxdecode->total_color_codes, gfxdecode->color_codes_start));
}
}
//-------------------------------------------------
// gfx_element - constructor
//-------------------------------------------------
gfx_element::gfx_element(running_machine &machine)
: 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_charincrement(0),
m_machine(machine)
{
}
gfx_element::gfx_element(running_machine &machine, UINT8 *base, UINT32 width, UINT32 height, UINT32 rowbytes, UINT32 color_base, UINT32 color_granularity)
: 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((machine.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_charincrement(0),
m_machine(machine)
{
}
gfx_element::gfx_element(running_machine &machine, const gfx_layout &gl, const UINT8 *srcdata, UINT32 total_colors, UINT32 color_base)
: 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_charincrement(0),
m_machine(machine)
{
// 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)
{
// 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;
m_layout_planeoffset.resize(m_layout_planes);
m_layout_xoffset.resize(m_width);
m_layout_yoffset.resize(m_height);
// raw graphics case
if (m_layout_is_raw)
{
// modulos are determined for us by the layout
m_line_modulo = ((gl.extyoffs != NULL) ? gl.extyoffs[0] : gl.yoffset[0]) / 8;
m_char_modulo = gl.charincrement / 8;
// RAW graphics must have a pointer up front
assert(srcdata != NULL);
m_gfxdata_allocated.reset();
m_gfxdata = const_cast<UINT8 *>(m_srcdata);
}
// decoded graphics case
else
{
// copy offsets
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, 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.reset();
// set the source
set_source(srcdata);
}
//-------------------------------------------------
// 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_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
for (int plane = 0; plane < m_layout_planes; plane++)
{
int planebit = 1 << (m_layout_planes - 1 - plane);
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 * rowbytes();
// iterate over columns
for (int x = 0; x < m_origwidth; x++)
if (readbit(m_srcdata, yoffs + m_layout_xoffset[x]))
dp[x] |= planebit;
}
}
}
// (re)compute pen usage
if (code < m_pen_usage.count())
{
// 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
***************************************************************************/
/*-------------------------------------------------
drawgfx_opaque - render a gfx element with
no transparency
-------------------------------------------------*/
void drawgfx_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty)
{
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY);
}
void drawgfx_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty)
{
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfx_transpen - render a gfx element with
a single transparent pen
-------------------------------------------------*/
void drawgfx_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transpen)
{
// special case invalid pens to opaque
if (transpen > 0xff)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY);
}
void drawgfx_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transpen)
{
// special case invalid pens to opaque
if (transpen > 0xff)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfx_transpen_raw - render a gfx element
with a single transparent pen and no color
lookups
-------------------------------------------------*/
void drawgfx_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transpen)
{
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// render
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY);
}
void drawgfx_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transpen)
{
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// render
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfx_transmask - render a gfx element
with a multiple transparent pens provided as
a mask
-------------------------------------------------*/
void drawgfx_transmask(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transmask)
{
// special case 0 mask to opaque
if (transmask == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY);
}
void drawgfx_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transmask)
{
// special case 0 mask to opaque
if (transmask == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfx_transtable - render a gfx element
using a table to look up which pens are
transparent, opaque, or shadowing
-------------------------------------------------*/
void drawgfx_transtable(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSTABLE16, NO_PRIORITY);
}
void drawgfx_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfx_alpha - render a gfx element with
a single transparent pen, alpha blending the
remaining pixels with a fixed alpha value
-------------------------------------------------*/
void drawgfx_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 transpen, UINT8 alpha)
{
// special case alpha = 0xff
if (alpha == 0xff)
return drawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// get final code and color, and grab lookup tables
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY);
}
/***************************************************************************
DRAWGFXZOOM IMPLEMENTATIONS
***************************************************************************/
/*-------------------------------------------------
drawgfxzoom_opaque - render a scaled gfx
element with no transparency
-------------------------------------------------*/
void drawgfxzoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
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 drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY);
}
void drawgfxzoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
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 drawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfxzoom_transpen - render a scaled gfx
element with a single transparent pen
-------------------------------------------------*/
void drawgfxzoom_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen);
// special case invalid pens to opaque
if (transpen > 0xff)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY);
}
void drawgfxzoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen);
// special case invalid pens to opaque
if (transpen > 0xff)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfxzoom_transpen_raw - render a scaled gfx
element with a single transparent pen and no
color lookups
-------------------------------------------------*/
void drawgfxzoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transpen_raw(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// render
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY);
}
void drawgfxzoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transpen_raw(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// render
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfxzoom_transmask - render a scaled gfx
element with a multiple transparent pens
provided as a mask
-------------------------------------------------*/
void drawgfxzoom_transmask(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transmask)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transmask(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transmask);
// special case 0 mask to opaque
if (transmask == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY);
}
void drawgfxzoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transmask)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transmask(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transmask);
// special case 0 mask to opaque
if (transmask == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return drawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley);
}
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfxzoom_transtable - render a scaled gfx
element using a table to look up which pens
are transparent, opaque, or shadowing
-------------------------------------------------*/
void drawgfxzoom_transtable(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transtable(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, pentable, shadowtable);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSTABLE16, NO_PRIORITY);
}
void drawgfxzoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_transtable(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, pentable, shadowtable);
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY);
}
/*-------------------------------------------------
drawgfxzoom_alpha - render a scaled gfx element
with a single transparent pen, alpha blending
the remaining pixels with a fixed alpha value
-------------------------------------------------*/
void drawgfxzoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, UINT32 transpen, UINT8 alpha)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return drawgfx_alpha(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, transpen, alpha);
// special case alpha = 0xff
if (alpha == 0xff)
return drawgfxzoom_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DECLARE_NO_PRIORITY;
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY);
}
/***************************************************************************
PDRAWGFX IMPLEMENTATIONS
***************************************************************************/
/*-------------------------------------------------
pdrawgfx_opaque - render a gfx element with
no transparency, checking against the priority
bitmap
-------------------------------------------------*/
void pdrawgfx_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8);
}
void pdrawgfx_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfx_transpen - render a gfx element with
a single transparent pen, checking against the
priority bitmap
-------------------------------------------------*/
void pdrawgfx_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transpen)
{
// special case invalid pens to opaque
if (transpen > 0xff)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
}
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8);
}
void pdrawgfx_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transpen)
{
// special case invalid pens to opaque
if (transpen > 0xff)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
}
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfx_transpen_raw - render a gfx element
with a single transparent pen and no color
lookups, checking against the priority bitmap
-------------------------------------------------*/
void pdrawgfx_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transpen)
{
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
DRAWGFX_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8);
}
void pdrawgfx_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transpen)
{
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
DRAWGFX_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfx_transmask - render a gfx element
with a multiple transparent pens provided as
a mask, checking against the priority bitmap
-------------------------------------------------*/
void pdrawgfx_transmask(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transmask)
{
// special case 0 mask to opaque
if (transmask == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
}
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8);
}
void pdrawgfx_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transmask)
{
// special case 0 mask to opaque
if (transmask == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
}
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfx_transtable - render a gfx element
using a table to look up which pens are
transparent, opaque, or shadowing, checking
against the priority bitmap
-------------------------------------------------*/
void pdrawgfx_transtable(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFX_CORE(UINT16, PIXEL_OP_REMAP_TRANSTABLE16_PRIORITY, UINT8);
}
void pdrawgfx_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfx_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 pdrawgfx_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
bitmap_ind8 &priority, UINT32 pmask, UINT32 transpen, UINT8 alpha)
{
// special case alpha = 0xff
if (alpha == 0xff)
return pdrawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFX_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, UINT8);
}
/***************************************************************************
PDRAWGFXZOOM IMPLEMENTATIONS
***************************************************************************/
/*-------------------------------------------------
pdrawgfxzoom_opaque - render a scaled gfx
element with no transparency, checking against
the priority bitmap
-------------------------------------------------*/
void pdrawgfxzoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
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 pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8);
}
void pdrawgfxzoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
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 pdrawgfx_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfxzoom_transpen - render a scaled gfx
element with a single transparent pen,
checking against the priority bitmap
-------------------------------------------------*/
void pdrawgfxzoom_transpen(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen);
// special case invalid pens to opaque
if (transpen > 0xff)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, 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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8);
}
void pdrawgfxzoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen);
// special case invalid pens to opaque
if (transpen > 0xff)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~(1 << transpen)) == 0)
return;
// fully opaque; draw as such
if ((usage & (1 << transpen)) == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, 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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfxzoom_transpen_raw - render a scaled gfx
element with a single transparent pen and no
color lookups, checking against the priority
bitmap
-------------------------------------------------*/
void pdrawgfxzoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transpen_raw(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8);
}
void pdrawgfxzoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transpen)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transpen_raw(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfxzoom_transmask - render a scaled gfx
element with a multiple transparent pens
provided as a mask, checking against the
priority bitmap
-------------------------------------------------*/
void pdrawgfxzoom_transmask(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transmask)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transmask(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transmask);
// special case 0 mask to opaque
if (transmask == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, 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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8);
}
void pdrawgfxzoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transmask)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transmask(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transmask);
// special case 0 mask to opaque
if (transmask == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask);
// use pen usage to optimize
code %= gfx->elements();
if (gfx->has_pen_usage())
{
// fully transparent; do nothing
UINT32 usage = gfx->pen_usage(code);
if ((usage & ~transmask) == 0)
return;
// fully opaque; draw as such
if ((usage & transmask) == 0)
return pdrawgfxzoom_opaque(dest, cliprect, gfx, 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 = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfxzoom_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 pdrawgfxzoom_transtable(bitmap_ind16 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transtable(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, pentable, shadowtable);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFXZOOM_CORE(UINT16, PIXEL_OP_REMAP_TRANSTABLE16_PRIORITY, UINT8);
}
void pdrawgfxzoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
const UINT8 *pentable, const pen_t *shadowtable)
{
assert(pentable != NULL);
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_transtable(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, pentable, shadowtable);
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
code %= gfx->elements();
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, UINT8);
}
/*-------------------------------------------------
pdrawgfxzoom_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 pdrawgfxzoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, INT32 destx, INT32 desty,
UINT32 scalex, UINT32 scaley, bitmap_ind8 &priority, UINT32 pmask,
UINT32 transpen, UINT8 alpha)
{
// non-zoom case
if (scalex == 0x10000 && scaley == 0x10000)
return pdrawgfx_alpha(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, priority, pmask, transpen, alpha);
// special case alpha = 0xff
if (alpha == 0xff)
return pdrawgfxzoom_transpen(dest, cliprect, gfx, code, color, flipx, flipy, destx, desty, scalex, scaley, priority, pmask, transpen);
// early out if completely transparent
code %= gfx->elements();
if (gfx->has_pen_usage() && (gfx->pen_usage(code) & ~(1 << transpen)) == 0)
return;
// high bit of the mask is implicitly on
pmask |= 1 << 31;
// render
const pen_t *paldata = &gfx->machine().pens[gfx->colorbase() + gfx->granularity() * (color % gfx->colors())];
DRAWGFXZOOM_CORE(UINT32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, UINT8);
}
/***************************************************************************
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 transpen)
{
DECLARE_NO_PRIORITY;
if (transpen > 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 transpen)
{
DECLARE_NO_PRIORITY;
if (transpen == 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 transpen)
{
// no rowscroll and no colscroll means no scroll
if (numrows == 0 && numcols == 0)
return copybitmap_trans(dest, src, 0, 0, 0, 0, cliprect, transpen);
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, transpen);
}
// 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, transpen);
}
}
}
// 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, transpen);
}
}
}
}
void copyscrollbitmap_trans(bitmap_ind16 &dest, bitmap_ind16 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect, UINT32 transpen)
{ copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, transpen); }
void copyscrollbitmap_trans(bitmap_rgb32 &dest, bitmap_rgb32 &src, UINT32 numrows, const INT32 *rowscroll, UINT32 numcols, const INT32 *colscroll, const rectangle &cliprect, UINT32 transpen)
{ copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, transpen); }
/***************************************************************************
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 transpen)
{
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 transpen)
{
DECLARE_NO_PRIORITY;
COPYROZBITMAP_CORE(UINT32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY);
}