From e4903df939d785196d8b090872da05e15a95bdcf Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 16 Sep 2019 22:20:37 -0400 Subject: drawgfxm.h: Rename to drawgfxt.ipp and replace the mega-macros with template functions (nw) --- scripts/src/emu.lua | 2 +- src/emu/drawgfx.cpp | 294 +++---- src/emu/drawgfx.h | 13 + src/emu/drawgfxm.h | 1292 ---------------------------- src/emu/drawgfxt.ipp | 1911 ++++++++++++++++++++++++++++++++++++++++++ src/mame/video/psikyosh.cpp | 23 +- src/mame/video/suna8.cpp | 24 +- src/mame/video/tc0080vco.cpp | 22 +- 8 files changed, 2058 insertions(+), 1523 deletions(-) delete mode 100644 src/emu/drawgfxm.h create mode 100644 src/emu/drawgfxt.ipp diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua index 6ab5f100cba..197e4181258 100644 --- a/scripts/src/emu.lua +++ b/scripts/src/emu.lua @@ -105,7 +105,7 @@ files { MAME_DIR .. "src/emu/divtlb.h", MAME_DIR .. "src/emu/drawgfx.cpp", MAME_DIR .. "src/emu/drawgfx.h", - MAME_DIR .. "src/emu/drawgfxm.h", + MAME_DIR .. "src/emu/drawgfxt.ipp", MAME_DIR .. "src/emu/driver.cpp", MAME_DIR .. "src/emu/driver.h", MAME_DIR .. "src/emu/drivenum.cpp", diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp index d6d9019fb8a..488a0c9740e 100644 --- a/src/emu/drawgfx.cpp +++ b/src/emu/drawgfx.cpp @@ -8,18 +8,7 @@ *********************************************************************/ #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 -u8 no_priority_size_is_wrong[2 * (sizeof(NO_PRIORITY) == 3) - 1]; - -bitmap_ind8 drawgfx_dummy_priority_bitmap; - +#include "drawgfxt.ipp" /*************************************************************************** @@ -364,8 +353,7 @@ void gfx_element::opaque(bitmap_ind16 &dest, const rectangle &cliprect, { color = colorbase() + granularity() * (color % colors()); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_OPAQUE, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_OPAQUE(destp, srcp); }); } void gfx_element::opaque(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -373,8 +361,7 @@ void gfx_element::opaque(bitmap_rgb32 &dest, const rectangle &cliprect, { const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); } @@ -407,8 +394,7 @@ void gfx_element::transpen(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_pen, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } void gfx_element::transpen(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -435,8 +421,7 @@ void gfx_element::transpen(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_pen, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN(destp, srcp); }); } @@ -456,8 +441,7 @@ void gfx_element::transpen_raw(bitmap_ind16 &dest, const rectangle &cliprect, return; // render - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_pen, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } void gfx_element::transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -470,8 +454,7 @@ void gfx_element::transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, return; // render - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_pen, color](u32 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } @@ -505,8 +488,7 @@ void gfx_element::transmask(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSMASK, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_mask, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSMASK(destp, srcp); }); } void gfx_element::transmask(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -533,8 +515,7 @@ void gfx_element::transmask(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_mask, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSMASK(destp, srcp); }); } @@ -554,8 +535,7 @@ void gfx_element::transtable(bitmap_ind16 &dest, const rectangle &cliprect, color = colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSTABLE16, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [pentable, color, shadowtable](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSTABLE16(destp, srcp); }); } void gfx_element::transtable(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -568,8 +548,7 @@ void gfx_element::transtable(bitmap_rgb32 &dest, const rectangle &cliprect, 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(u32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [pentable, paldata, shadowtable](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSTABLE32(destp, srcp); }); } @@ -594,8 +573,7 @@ void gfx_element::alpha(bitmap_rgb32 &dest, const rectangle &cliprect, // 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(u32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [trans_pen, alpha_val, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_ALPHA32(destp, srcp); }); } @@ -620,8 +598,7 @@ void gfx_element::zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_OPAQUE, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_OPAQUE(destp, srcp); }); } void gfx_element::zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -635,8 +612,7 @@ void gfx_element::zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); } @@ -673,8 +649,7 @@ void gfx_element::zoom_transpen(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_pen, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } void gfx_element::zoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -705,8 +680,7 @@ void gfx_element::zoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSPEN, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_pen, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN(destp, srcp); }); } @@ -730,8 +704,7 @@ void gfx_element::zoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprec return; // render - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_pen, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } void gfx_element::zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -748,8 +721,7 @@ void gfx_element::zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprec return; // render - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REBASE_TRANSPEN, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_pen, color](u32 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN(destp, srcp); }); } @@ -787,8 +759,7 @@ void gfx_element::zoom_transmask(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSMASK, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_mask, color](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSMASK(destp, srcp); }); } void gfx_element::zoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -819,8 +790,7 @@ void gfx_element::zoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSMASK, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_mask, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSMASK(destp, srcp); }); } @@ -844,8 +814,7 @@ void gfx_element::zoom_transtable(bitmap_ind16 &dest, const rectangle &cliprect, color = colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSTABLE16, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [pentable, color, shadowtable](u16 &destp, const u8 &srcp) { PIXEL_OP_REBASE_TRANSTABLE16(destp, srcp); }); } void gfx_element::zoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -862,8 +831,7 @@ void gfx_element::zoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, 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(u32, PIXEL_OP_REMAP_TRANSTABLE32, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [pentable, paldata, shadowtable](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSTABLE32(destp, srcp); }); } @@ -892,8 +860,7 @@ void gfx_element::zoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DECLARE_NO_PRIORITY; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32, NO_PRIORITY); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, [trans_pen, alpha_val, paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_ALPHA32(destp, srcp); }); } @@ -918,7 +885,7 @@ void gfx_element::prio_opaque(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); code %= elements(); - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_OPAQUE_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_OPAQUE_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -931,7 +898,7 @@ void gfx_element::prio_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); code %= elements(); - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); } @@ -968,7 +935,7 @@ void gfx_element::prio_transpen(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -998,7 +965,7 @@ void gfx_element::prio_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_PRIORITY(destp, pri, srcp); }); } @@ -1021,7 +988,7 @@ void gfx_element::prio_transpen_raw(bitmap_ind16 &dest, const rectangle &cliprec pmask |= 1 << 31; // render - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1037,7 +1004,7 @@ void gfx_element::prio_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprec pmask |= 1 << 31; // render - DRAWGFX_CORE(u32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, color](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } @@ -1074,7 +1041,7 @@ void gfx_element::prio_transmask(bitmap_ind16 &dest, const rectangle &cliprect, // render color = colorbase() + granularity() * (color % colors()); - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSMASK_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_mask, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSMASK_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1104,7 +1071,7 @@ void gfx_element::prio_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_mask, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSMASK_PRIORITY(destp, pri, srcp); }); } @@ -1128,7 +1095,7 @@ void gfx_element::prio_transtable(bitmap_ind16 &dest, const rectangle &cliprect, color = colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DRAWGFX_CORE(u16, PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, pentable, color, shadowtable](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1144,7 +1111,7 @@ void gfx_element::prio_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, pentable, paldata, shadowtable](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY(destp, pri, srcp); }); } @@ -1173,7 +1140,7 @@ void gfx_element::prio_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, alpha_val, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY(destp, pri, srcp); }); } @@ -1202,7 +1169,7 @@ void gfx_element::prio_zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect // render color = colorbase() + granularity() * (color % colors()); code %= elements(); - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_OPAQUE_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_OPAQUE_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1219,7 +1186,7 @@ void gfx_element::prio_zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); code %= elements(); - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); } @@ -1261,7 +1228,7 @@ void gfx_element::prio_zoom_transpen(bitmap_ind16 &dest, const rectangle &clipre // render color = colorbase() + granularity() * (color % colors()); - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_zoom_transpen(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1296,7 +1263,7 @@ void gfx_element::prio_zoom_transpen(bitmap_rgb32 &dest, const rectangle &clipre // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_PRIORITY(destp, pri, srcp); }); } @@ -1325,7 +1292,7 @@ void gfx_element::prio_zoom_transpen_raw(bitmap_ind16 &dest, const rectangle &cl pmask |= 1 << 31; // render - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1346,7 +1313,7 @@ void gfx_element::prio_zoom_transpen_raw(bitmap_rgb32 &dest, const rectangle &cl pmask |= 1 << 31; // render - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REBASE_TRANSPEN_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, color](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY(destp, pri, srcp); }); } @@ -1389,7 +1356,7 @@ void gfx_element::prio_zoom_transmask(bitmap_ind16 &dest, const rectangle &clipr // render color = colorbase() + granularity() * (color % colors()); - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSMASK_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_mask, color](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSMASK_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_zoom_transmask(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1424,7 +1391,7 @@ void gfx_element::prio_zoom_transmask(bitmap_rgb32 &dest, const rectangle &clipr // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSMASK_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_mask, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSMASK_PRIORITY(destp, pri, srcp); }); } @@ -1453,7 +1420,7 @@ void gfx_element::prio_zoom_transtable(bitmap_ind16 &dest, const rectangle &clip color = colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DRAWGFXZOOM_CORE(u16, PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, pentable, color, shadowtable](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY(destp, pri, srcp); }); } void gfx_element::prio_zoom_transtable(bitmap_rgb32 &dest, const rectangle &cliprect, @@ -1474,7 +1441,7 @@ void gfx_element::prio_zoom_transtable(bitmap_rgb32 &dest, const rectangle &clip const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); const pen_t *shadowtable = m_palette->shadow_table(); code %= elements(); - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, pentable, paldata, shadowtable](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY(destp, pri, srcp); }); } @@ -1509,7 +1476,7 @@ void gfx_element::prio_zoom_alpha(bitmap_rgb32 &dest, const rectangle &cliprect, // render const pen_t *paldata = m_palette->pens() + colorbase() + granularity() * (color % colors()); - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, alpha_val, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY(destp, pri, srcp); }); } @@ -1554,7 +1521,7 @@ void gfx_element::prio_transpen_additive(bitmap_rgb32 &dest, const rectangle &cl pmask |= 1 << 31; /* render based on dest bitmap depth */ - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32, u8); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, priority, [pmask, trans_pen, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32(destp, pri, srcp); }); } @@ -1594,14 +1561,14 @@ void gfx_element::prio_zoom_transpen_additive(bitmap_rgb32 &dest, const rectangl /* high bit of the mask is implicitly on */ pmask |= 1 << 31; - DRAWGFXZOOM_CORE(u32, PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32, u8); + drawgfxzoom_core(dest, cliprect, code, flipx, flipy, destx, desty, scalex, scaley, priority, [pmask, trans_pen, paldata](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_TRANSPEN_PRIORITY_ADDIIVE32(destp, pri, srcp); }); } //#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) \ +#define PIXEL_OP_REMAP_TRANS0_ALPHASTORE32(DEST, SOURCE) \ do \ { \ u32 srcdata = (SOURCE); \ @@ -1610,7 +1577,7 @@ do } \ while (0) // combine in 'alphatable' value to store in ARGB -#define PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32(DEST, PRIORITY, SOURCE) \ +#define PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32(DEST, SOURCE) \ do \ { \ u32 srcdata = (SOURCE); \ @@ -1619,7 +1586,7 @@ do } \ while (0) // drawgfxm.h macro to render alpha into 32-bit buffer -#define PIXEL_OP_REMAP_TRANS0_ALPHATABLE32(DEST, PRIORITY, SOURCE) \ +#define PIXEL_OP_REMAP_TRANS0_ALPHATABLE32(DEST, SOURCE) \ do \ { \ u32 srcdata = (SOURCE); \ @@ -1637,7 +1604,6 @@ void gfx_element::alphastore(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, int fixedalpha, u8 *alphatable) { - DECLARE_NO_PRIORITY; const pen_t *paldata; assert(alphatable != nullptr); @@ -1659,14 +1625,9 @@ void gfx_element::alphastore(bitmap_rgb32 &dest, const rectangle &cliprect, return; if (fixedalpha >= 0) - { - u8 alpha = fixedalpha; - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANS0_ALPHASTORE32, NO_PRIORITY); - } + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [paldata, alpha = fixedalpha, alphatable](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANS0_ALPHASTORE32(destp, srcp); }); else - { - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32, NO_PRIORITY); - } + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [paldata, alphatable](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANS0_ALPHATABLESTORE32(destp, srcp); }); } /*------------------------------------------------- @@ -1678,8 +1639,6 @@ void gfx_element::alphatable(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, int fixedalpha, u8 *alphatable) { - DECLARE_NO_PRIORITY; - const pen_t *paldata; /* if we have a fixed alpha, call the standard drawgfx_alpha */ @@ -1701,7 +1660,7 @@ void gfx_element::alphatable(bitmap_rgb32 &dest, const rectangle &cliprect, if (has_pen_usage() && (pen_usage(code) & ~(1 << 0)) == 0) return; - DRAWGFX_CORE(u32, PIXEL_OP_REMAP_TRANS0_ALPHATABLE32, NO_PRIORITY); + drawgfx_core(dest, cliprect, code, flipx, flipy, destx, desty, [paldata, fixedalpha, alphatable](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_TRANS0_ALPHATABLE32(destp, srcp); }); } @@ -1716,28 +1675,24 @@ void gfx_element::alphatable(bitmap_rgb32 &dest, const rectangle &cliprect, void draw_scanline8(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u16 &destp, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u16 &destp, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u32 &destp, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u32 &destp, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void prio_draw_scanline8(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1747,11 +1702,11 @@ void prio_draw_scanline8(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void prio_draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1761,11 +1716,11 @@ void prio_draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void primask_draw_scanline8(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1775,11 +1730,11 @@ void primask_draw_scanline8(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 leng // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u16 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } void primask_draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u8 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1789,11 +1744,11 @@ void primask_draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 leng // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u32 &destp, u8 &pri, const u8 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } @@ -1804,28 +1759,24 @@ void primask_draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 leng void draw_scanline16(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u16 &destp, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u16 &destp, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u32 &destp, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u32 &destp, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void prio_draw_scanline16(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1835,11 +1786,11 @@ void prio_draw_scanline16(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void prio_draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1849,11 +1800,11 @@ void prio_draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u32 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u32 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void primask_draw_scanline16(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1863,11 +1814,11 @@ void primask_draw_scanline16(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 len // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } void primask_draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u16 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1877,11 +1828,11 @@ void primask_draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 len // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u32 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u32 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } @@ -1892,28 +1843,24 @@ void primask_draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 len void draw_scanline32(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u16 &destp, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u16 &destp, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata) { - DECLARE_NO_PRIORITY; - // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [paldata](u32 &destp, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE(destp, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void prio_draw_scanline32(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1923,11 +1870,11 @@ void prio_draw_scanline32(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u16 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u16 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void prio_draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u32 pmask) @@ -1937,11 +1884,11 @@ void prio_draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIORITY(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void primask_draw_scanline32(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1951,11 +1898,11 @@ void primask_draw_scanline32(bitmap_ind16 &bitmap, s32 destx, s32 desty, s32 len // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u16 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u16 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } void primask_draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, const pen_t *paldata, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -1965,11 +1912,11 @@ void primask_draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 len // palette lookup case if (paldata != nullptr) - DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [paldata, pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_REMAP_OPAQUE_PRIMASK(destp, pri, srcp); }); // raw copy case else - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + drawscanline_core(bitmap, destx, desty, length, srcptr, priority, [pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } @@ -1985,14 +1932,12 @@ void primask_draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 len void copybitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect) { - DECLARE_NO_PRIORITY; - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, [](u16 &destp, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect) { - DECLARE_NO_PRIORITY; - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, [](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void prio_copybitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask) @@ -2000,7 +1945,7 @@ void prio_copybitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void prio_copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask) @@ -2008,7 +1953,7 @@ void prio_copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void primask_copybitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2016,7 +1961,7 @@ void primask_copybitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, if (pcode == 0 && pmask == 0xff) copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); else - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } void primask_copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2024,7 +1969,7 @@ void primask_copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, if (pcode == 0 && pmask == 0xff) copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); else - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } @@ -2036,20 +1981,18 @@ void primask_copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, void copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 trans_pen) { - DECLARE_NO_PRIORITY; if (trans_pen > 0xffff) copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); else - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, [trans_pen](u16 &destp, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN(destp, srcp); }); } void copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 trans_pen) { - DECLARE_NO_PRIORITY; if (trans_pen == 0xffffffff) copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); else - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, [trans_pen](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN(destp, srcp); }); } void prio_copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) @@ -2060,7 +2003,7 @@ void prio_copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int flip if (trans_pen > 0xffff) prio_copybitmap(dest, src, flipx, flipy, destx, desty, cliprect, priority, pmask); else - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pmask, trans_pen](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void prio_copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) @@ -2071,7 +2014,7 @@ void prio_copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flip if (trans_pen == 0xffffffff) prio_copybitmap(dest, src, flipx, flipy, destx, desty, cliprect, priority, pmask); else - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pmask, trans_pen](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void primask_copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2081,7 +2024,7 @@ void primask_copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int f else if (trans_pen > 0xffff) primask_copybitmap(dest, src, flipx, flipy, destx, desty, cliprect, priority, pcode, pmask); else - COPYBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN_PRIMASK, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [trans_pen, pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIMASK(destp, pri, srcp); }); } void primask_copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2091,7 +2034,7 @@ void primask_copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int f else if (trans_pen == 0xffffffff) primask_copybitmap(dest, src, flipx, flipy, destx, desty, cliprect, priority, pcode, pmask); else - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN_PRIMASK, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [trans_pen, pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIMASK(destp, pri, srcp); }); } @@ -2103,8 +2046,7 @@ void primask_copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int f void copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect) { - DECLARE_NO_PRIORITY; - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA, NO_PRIORITY); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, [](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSALPHA(destp, srcp); }); } void prio_copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask) @@ -2112,7 +2054,7 @@ void prio_copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA_PRIORITY, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSALPHA_PRIORITY(destp, pri, srcp); }); } void primask_copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2120,7 +2062,7 @@ void primask_copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, if (pcode == 0 && pmask == 0xff) copybitmap_transalpha(dest, src, flipx, flipy, destx, desty, cliprect); else - COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA_PRIMASK, u8); + copybitmap_core(dest, src, flipx, flipy, destx, desty, cliprect, priority, [pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSALPHA_PRIMASK(destp, pri, srcp); }); } @@ -2515,14 +2457,12 @@ void primask_copyscrollbitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, void copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound) { - DECLARE_NO_PRIORITY; - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, [](u16 &destp, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound) { - DECLARE_NO_PRIORITY; - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, [](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE(destp, srcp); }); } void prio_copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u32 pmask) @@ -2530,7 +2470,7 @@ void prio_copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, const bit // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void prio_copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u32 pmask) @@ -2538,7 +2478,7 @@ void prio_copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const bit // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIORITY(destp, pri, srcp); }); } void primask_copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2546,7 +2486,7 @@ void primask_copyrozbitmap(bitmap_ind16 &dest, const rectangle &cliprect, const if (pcode == 0 && pmask == 0xff) copyrozbitmap(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound); else - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } void primask_copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2554,7 +2494,7 @@ void primask_copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const if (pcode == 0 && pmask == 0xff) copyrozbitmap(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound); else - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_OPAQUE_PRIMASK(destp, pri, srcp); }); } @@ -2567,14 +2507,12 @@ void primask_copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const void copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, u32 trans_pen) { - DECLARE_NO_PRIORITY; - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, [trans_pen](u16 &destp, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN(destp, srcp); }); } void copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, u32 trans_pen) { - DECLARE_NO_PRIORITY; - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, [trans_pen](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN(destp, srcp); }); } void prio_copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) @@ -2582,7 +2520,7 @@ void prio_copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, con // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pmask, trans_pen](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void prio_copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) @@ -2590,7 +2528,7 @@ void prio_copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, con // high bit of the mask is implicitly on pmask |= 1 << 31; - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [pmask, trans_pen](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIORITY(destp, pri, srcp); }); } void primask_copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, const bitmap_ind16 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2598,7 +2536,7 @@ void primask_copyrozbitmap_trans(bitmap_ind16 &dest, const rectangle &cliprect, if (pcode == 0 && pmask == 0xff) copyrozbitmap_trans(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, trans_pen); else - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN_PRIMASK, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [trans_pen, pcode, pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIMASK(destp, pri, srcp); }); } void primask_copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_rgb32 &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) @@ -2606,5 +2544,5 @@ void primask_copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, if (pcode == 0 && pmask == 0xff) copyrozbitmap_trans(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, trans_pen); else - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN_PRIMASK, u8); + copyrozbitmap_core(dest, cliprect, src, startx, starty, incxx, incxy, incyx, incyy, wraparound, priority, [trans_pen, pcode, pmask](u32 &destp, u8 &pri, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_PRIMASK(destp, pri, srcp); }); } diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h index ec2e650a11a..08732a42bfd 100644 --- a/src/emu/drawgfx.h +++ b/src/emu/drawgfx.h @@ -202,6 +202,9 @@ public: // ----- core graphics drawing ----- + // core drawgfx implementation + template void drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, FunctionClass pixel_op); + // specific drawgfx implementations for each transparency type void opaque(bitmap_ind16 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty); void opaque(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty); @@ -217,6 +220,9 @@ public: // ----- zoomed graphics drawing ----- + // core zoom implementation + template void drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, FunctionClass pixel_op); + // specific zoom implementations for each transparency type void zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley); void zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley); @@ -232,6 +238,9 @@ public: // ----- priority masked graphics drawing ----- + // core prio implementation + template void drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, PriorityType &priority, FunctionClass pixel_op); + // specific prio implementations for each transparency type void prio_opaque(bitmap_ind16 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, bitmap_ind8 &priority, u32 pmask); void prio_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, bitmap_ind8 &priority, u32 pmask); @@ -247,6 +256,9 @@ public: // ----- priority masked zoomed graphics drawing ----- + // core prio_zoom implementation + template void drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, PriorityType &priority, FunctionClass pixel_op); + // specific prio_zoom implementations for each transparency type void prio_zoom_opaque(bitmap_ind16 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, bitmap_ind8 &priority, u32 pmask); void prio_zoom_opaque(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, bitmap_ind8 &priority, u32 pmask); @@ -265,6 +277,7 @@ public: void prio_zoom_transpen_additive(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, bitmap_ind8 &priority, u32 pmask, u32 trans_pen); void alphastore(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, int fixedalpha, u8 *alphatable); void alphatable(bitmap_rgb32 &dest, const rectangle &cliprect, u32 code, u32 color, int flipx, int flipy, s32 destx, s32 desty, int fixedalpha, u8 *alphatable); + private: // internal helpers void decode(u32 code); diff --git a/src/emu/drawgfxm.h b/src/emu/drawgfxm.h deleted file mode 100644 index 6699b866697..00000000000 --- a/src/emu/drawgfxm.h +++ /dev/null @@ -1,1292 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Nicola Salmoria, Aaron Giles -/********************************************************************* - - drawgfxm.h - - Macros implementing drawgfx core operations. Drivers can use - these if they need custom behavior not provided by the existing - drawgfx functions. -********************************************************************** - - How to use these macros: - - There are two sets of macros. The PIXEL_OP* macros are simple - per-pixel operations, designed to take a SOURCE pixel and - copy it to the DEST, perhaps updating the PRIORITY pixel as - well. On their own, they are not particularly useful. - - The second set of macros represents the core gfx/bitmap walking - and rendering code. These macros generally take the target pixel - type (u8, u16, u32), one of the PIXEL_OP* macros, - and a priority bitmap pixel type (u8, u16, u32, or the - special type NO_PRIORITY). - - Although the code may look inefficient at first, the compiler is - able to easily optimize out unused cases due to the way the - macros are written, leaving behind just the cases we are - interested in. - - The general approach for using these macros is: - - my_drawing_function(params) - { - // ensure that all the required parameters for the mega - // macro are defined (if they are not needed, just declare - // the variables and set them equal to a known constant - // value to help the compiler) - - // set up any additional variables needed by the PIXEL_OP* - // macro you want to use (each macro has its own - // requirements) - - MEGA_MACRO(BITMAP_TYPE, PIXEL_OP, PRIORITY_TYPE); - } - -*********************************************************************/ - -#pragma once - -#ifndef __DRAWGFXM_H__ -#define __DRAWGFXM_H__ - -/* special priority type meaning "none" */ -struct NO_PRIORITY { char dummy[3]; }; - -extern bitmap_ind8 drawgfx_dummy_priority_bitmap; -#define DECLARE_NO_PRIORITY bitmap_t &priority = drawgfx_dummy_priority_bitmap; - - -/* macros for using the optional priority */ -#define PRIORITY_VALID(x) (sizeof(x) != sizeof(NO_PRIORITY)) -#define PRIORITY_ADDR(p,t,y,x) (PRIORITY_VALID(t) ? (&(p).pixt(y, x)) : nullptr) -#define PRIORITY_ADVANCE(t,p,i) do { if (PRIORITY_VALID(t)) (p) += (i); } while (0) - - -/*************************************************************************** - PIXEL OPERATIONS -***************************************************************************/ - -/*------------------------------------------------- - PIXEL_OP_COPY_OPAQUE - render all pixels - regardless of pen, copying directly --------------------------------------------------*/ - -#define PIXEL_OP_COPY_OPAQUE(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - (DEST) = SOURCE; \ -} \ -while (0) -#define PIXEL_OP_COPY_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = SOURCE; \ - (PRIORITY) = 31; \ -} \ -while (0) -#define PIXEL_OP_COPY_OPAQUE_PRIMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - (DEST) = SOURCE; \ - (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_COPY_TRANSPEN - render all pixels - except those matching 'transpen', copying - directly --------------------------------------------------*/ - -#define PIXEL_OP_COPY_TRANSPEN(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - (DEST) = SOURCE; \ -} \ -while (0) -#define PIXEL_OP_COPY_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = SOURCE; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) -#define PIXEL_OP_COPY_TRANSPEN_PRIMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - { \ - (DEST) = SOURCE; \ - (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_COPY_TRANSALPHA - render all pixels - except those with an alpha of zero, copying - directly --------------------------------------------------*/ - -#define PIXEL_OP_COPY_TRANSALPHA(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if ((srcdata & 0xff000000) != 0) \ - (DEST) = SOURCE; \ -} \ -while (0) -#define PIXEL_OP_COPY_TRANSALPHA_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if ((srcdata & 0xff000000) != 0) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = SOURCE; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) -#define PIXEL_OP_COPY_TRANSALPHA_PRIMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if ((srcdata & 0xff000000) != 0) \ - { \ - (DEST) = SOURCE; \ - (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REMAP_OPAQUE - render all pixels - regardless of pen, mapping the pen via the - 'paldata' array --------------------------------------------------*/ - -#define PIXEL_OP_REMAP_OPAQUE(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - (DEST) = paldata[SOURCE]; \ -} \ -while (0) -#define PIXEL_OP_REMAP_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = paldata[SOURCE]; \ - (PRIORITY) = 31; \ -} \ -while (0) -#define PIXEL_OP_REMAP_OPAQUE_PRIMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - (DEST) = paldata[SOURCE]; \ - (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REBASE_OPAQUE - render all pixels - regardless of pen, adding 'color' to the - pen value --------------------------------------------------*/ - -#define PIXEL_OP_REBASE_OPAQUE(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - (DEST) = color + (SOURCE); \ -} \ -while (0) -#define PIXEL_OP_REBASE_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = color + (SOURCE); \ - (PRIORITY) = 31; \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REMAP_TRANSPEN - render all pixels - except those matching 'trans_pen', mapping the - pen via the 'paldata' array --------------------------------------------------*/ - -#define PIXEL_OP_REMAP_TRANSPEN(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - (DEST) = paldata[srcdata]; \ -} \ -while (0) -#define PIXEL_OP_REMAP_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = paldata[srcdata]; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REBASE_TRANSPEN - render all pixels - except those matching 'transpen', adding - 'color' to the pen value --------------------------------------------------*/ - -#define PIXEL_OP_REBASE_TRANSPEN(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - (DEST) = color + srcdata; \ -} \ -while (0) -#define PIXEL_OP_REBASE_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = color + srcdata; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REMAP_TRANSMASK - render all pixels - except those matching 'trans_mask', mapping the - pen via the 'paldata' array --------------------------------------------------*/ - -#define PIXEL_OP_REMAP_TRANSMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (((trans_mask >> srcdata) & 1) == 0) \ - (DEST) = paldata[srcdata]; \ -} \ -while (0) -#define PIXEL_OP_REMAP_TRANSMASK_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (((trans_mask >> srcdata) & 1) == 0) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = paldata[srcdata]; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REBASE_TRANSMASK - render all pixels - except those matching 'trans_mask', adding - 'color' to the pen value --------------------------------------------------*/ - -#define PIXEL_OP_REBASE_TRANSMASK(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (((trans_mask >> srcdata) & 1) == 0) \ - (DEST) = color + srcdata; \ -} \ -while (0) -#define PIXEL_OP_REBASE_TRANSMASK_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (((trans_mask >> srcdata) & 1) == 0) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = color + srcdata; \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REBASE_TRANSTABLE - look up each pen in - 'pentable'; if the entry is DRAWMODE_NONE, - don't draw it; if the entry is DRAWMODE_SOURCE, - add 'color' to the pen value; if the entry is - DRAWMODE_SHADOW, generate a shadow of the - destination pixel using 'shadowtable' - - PIXEL_OP_REMAP_TRANSTABLE - look up each pen in - 'pentable'; if the entry is DRAWMODE_NONE, - don't draw it; if the entry is DRAWMODE_SOURCE, - look up the pen via the 'paldata' array; if the - entry is DRAWMODE_SHADOW, generate a shadow of - the destination pixel using 'shadowtable' --------------------------------------------------*/ - -#define PIXEL_OP_REBASE_TRANSTABLE16(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - u32 entry = pentable[srcdata]; \ - if (entry != DRAWMODE_NONE) \ - { \ - if (entry == DRAWMODE_SOURCE) \ - (DEST) = color + srcdata; \ - else \ - (DEST) = shadowtable[DEST]; \ - } \ -} \ -while (0) -#define PIXEL_OP_REMAP_TRANSTABLE32(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - u32 entry = pentable[srcdata]; \ - if (entry != DRAWMODE_NONE) \ - { \ - if (entry == DRAWMODE_SOURCE) \ - (DEST) = paldata[srcdata]; \ - else \ - (DEST) = shadowtable[rgb_t(DEST).as_rgb15()]; \ - } \ -} \ -while (0) -#define PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - u32 entry = pentable[srcdata]; \ - if (entry != DRAWMODE_NONE) \ - { \ - u8 pridata = (PRIORITY); \ - if (entry == DRAWMODE_SOURCE) \ - { \ - if (((1 << (pridata & 0x1f)) & pmask) == 0) \ - (DEST) = color + srcdata; \ - (PRIORITY) = 31; \ - } \ - else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ - { \ - (DEST) = shadowtable[DEST]; \ - (PRIORITY) = pridata | 0x80; \ - } \ - } \ -} \ -while (0) -#define PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - u32 entry = pentable[srcdata]; \ - if (entry != DRAWMODE_NONE) \ - { \ - u8 pridata = (PRIORITY); \ - if (entry == DRAWMODE_SOURCE) \ - { \ - if (((1 << (pridata & 0x1f)) & pmask) == 0) \ - (DEST) = paldata[srcdata]; \ - (PRIORITY) = 31; \ - } \ - else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ - { \ - (DEST) = shadowtable[rgb_t(DEST).as_rgb15()]; \ - (PRIORITY) = pridata | 0x80; \ - } \ - } \ -} \ -while (0) - -/*------------------------------------------------- - PIXEL_OP_REMAP_TRANSPEN_ALPHA - render all - pixels except those matching 'transpen', - mapping the pen to via the 'paldata' array; - the resulting color is RGB alpha blended - against the destination using 'alpha' --------------------------------------------------*/ - -#define PIXEL_OP_REMAP_TRANSPEN_ALPHA32(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - (DEST) = alpha_blend_r32((DEST), paldata[srcdata], alpha_val); \ -} \ -while (0) -#define PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY(DEST, PRIORITY, SOURCE) \ -do \ -{ \ - u32 srcdata = (SOURCE); \ - if (srcdata != trans_pen) \ - { \ - if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - (DEST) = alpha_blend_r32((DEST), paldata[srcdata], alpha_val); \ - (PRIORITY) = 31; \ - } \ -} \ -while (0) - - -/*************************************************************************** - BASIC DRAWGFX CORE -***************************************************************************/ - -/* - Assumed input parameters or local variables: - - bitmap_t &dest - the bitmap to render to - const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') - gfx_element *gfx - pointer to the gfx_element to render - u32 code - index of the entry within gfx_element - u32 color - index of the color within gfx_element - int flipx - non-zero means render right-to-left instead of left-to-right - int flipy - non-zero means render bottom-to-top instead of top-to-bottom - s32 destx - the top-left X coordinate to render to - s32 desty - the top-left Y coordinate to render to - bitmap_t &priority - the priority bitmap (even if PRIORITY_TYPE is NO_PRIORITY, at least needs a dummy) -*/ - - -#define DRAWGFX_CORE(PIXEL_TYPE, PIXEL_OP, PRIORITY_TYPE) \ -do { \ - g_profiler.start(PROFILER_DRAWGFX); \ - do { \ - const u8 *srcdata; \ - s32 destendx, destendy; \ - s32 srcx, srcy; \ - s32 curx, cury; \ - s32 dy; \ - \ - assert(dest.valid()); \ - assert(!PRIORITY_VALID(PRIORITY_TYPE) || priority.valid()); \ - assert(dest.cliprect().contains(cliprect)); \ - assert(code < elements()); \ - \ - /* ignore empty/invalid cliprects */ \ - if (cliprect.empty()) \ - break; \ - \ - /* compute final pixel in X and exit if we are entirely clipped */ \ - destendx = destx + width() - 1; \ - if (destx > cliprect.right() || destendx < cliprect.left()) \ - break; \ - \ - /* apply left clip */ \ - srcx = 0; \ - if (destx < cliprect.left()) \ - { \ - srcx = cliprect.left() - destx; \ - destx = cliprect.left(); \ - } \ - \ - /* apply right clip */ \ - if (destendx > cliprect.right()) \ - destendx = cliprect.right(); \ - \ - /* compute final pixel in Y and exit if we are entirely clipped */ \ - destendy = desty + height() - 1; \ - if (desty > cliprect.bottom() || destendy < cliprect.top()) \ - break; \ - \ - /* apply top clip */ \ - srcy = 0; \ - if (desty < cliprect.top()) \ - { \ - srcy = cliprect.top() - desty; \ - desty = cliprect.top(); \ - } \ - \ - /* apply bottom clip */ \ - if (destendy > cliprect.bottom()) \ - destendy = cliprect.bottom(); \ - \ - /* apply X flipping */ \ - if (flipx) \ - srcx = width() - 1 - srcx; \ - \ - /* apply Y flipping */ \ - dy = rowbytes(); \ - if (flipy) \ - { \ - srcy = height() - 1 - srcy; \ - dy = -dy; \ - } \ - \ - /* fetch the source data */ \ - srcdata = get_data(code); \ - \ - /* compute how many blocks of 4 pixels we have */ \ - u32 numblocks = (destendx + 1 - destx) / 4; \ - u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; \ - \ - /* adjust srcdata to point to the first source pixel of the row */ \ - srcdata += srcy * rowbytes() + srcx; \ - \ - /* non-flipped 8bpp case */ \ - if (!flipx) \ - { \ - /* iterate over pixels in Y */ \ - for (cury = desty; cury <= destendy; cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, destx); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ - const u8 *srcptr = srcdata; \ - srcdata += dy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[1]); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[2]); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[3]); \ - \ - srcptr += 4; \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcptr++; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - \ - /* flipped 8bpp case */ \ - else \ - { \ - /* iterate over pixels in Y */ \ - for (cury = desty; cury <= destendy; cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, destx); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ - const u8 *srcptr = srcdata; \ - srcdata += dy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[ 0]); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[-1]); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[-2]); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[-3]); \ - \ - srcptr -= 4; \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcptr--; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - } while (0); \ - g_profiler.stop(); \ -} while (0) - - - -/*************************************************************************** - BASIC DRAWGFXZOOM CORE -***************************************************************************/ - -/* - Assumed input parameters or local variables: - - bitmap_t &dest - the bitmap to render to - const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') - gfx_element *gfx - pointer to the gfx_element to render - u32 code - index of the entry within gfx_element - u32 color - index of the color within gfx_element - int flipx - non-zero means render right-to-left instead of left-to-right - int flipy - non-zero means render bottom-to-top instead of top-to-bottom - s32 destx - the top-left X coordinate to render to - s32 desty - the top-left Y coordinate to render to - u32 scalex - the 16.16 scale factor in the X dimension - u32 scaley - the 16.16 scale factor in the Y dimension - bitmap_t &priority - the priority bitmap (even if PRIORITY_TYPE is NO_PRIORITY, at least needs a dummy) -*/ - - -#define DRAWGFXZOOM_CORE(PIXEL_TYPE, PIXEL_OP, PRIORITY_TYPE) \ -do { \ - g_profiler.start(PROFILER_DRAWGFX); \ - do { \ - const u8 *srcdata; \ - u32 dstwidth, dstheight; \ - s32 destendx, destendy; \ - s32 srcx, srcy; \ - s32 curx, cury; \ - s32 dx, dy; \ - \ - assert(dest.valid()); \ - assert(!PRIORITY_VALID(PRIORITY_TYPE) || priority.valid()); \ - assert(dest.cliprect().contains(cliprect)); \ - \ - /* ignore empty/invalid cliprects */ \ - if (cliprect.empty()) \ - break; \ - \ - /* compute scaled size */ \ - dstwidth = (scalex * width() + 0x8000) >> 16; \ - dstheight = (scaley * height() + 0x8000) >> 16; \ - if (dstwidth < 1 || dstheight < 1) \ - break; \ - \ - /* compute 16.16 source steps in dx and dy */ \ - dx = (width() << 16) / dstwidth; \ - dy = (height() << 16) / dstheight; \ - \ - /* compute final pixel in X and exit if we are entirely clipped */ \ - destendx = destx + dstwidth - 1; \ - if (destx > cliprect.right() || destendx < cliprect.left()) \ - break; \ - \ - /* apply left clip */ \ - srcx = 0; \ - if (destx < cliprect.left()) \ - { \ - srcx = (cliprect.left() - destx) * dx; \ - destx = cliprect.left(); \ - } \ - \ - /* apply right clip */ \ - if (destendx > cliprect.right()) \ - destendx = cliprect.right(); \ - \ - /* compute final pixel in Y and exit if we are entirely clipped */ \ - destendy = desty + dstheight - 1; \ - if (desty > cliprect.bottom() || destendy < cliprect.top()) \ - { \ - g_profiler.stop(); \ - return; \ - } \ - \ - /* apply top clip */ \ - srcy = 0; \ - if (desty < cliprect.top()) \ - { \ - srcy = (cliprect.top() - desty) * dy; \ - desty = cliprect.top(); \ - } \ - \ - /* apply bottom clip */ \ - if (destendy > cliprect.bottom()) \ - destendy = cliprect.bottom(); \ - \ - /* apply X flipping */ \ - if (flipx) \ - { \ - srcx = (dstwidth - 1) * dx - srcx; \ - dx = -dx; \ - } \ - \ - /* apply Y flipping */ \ - if (flipy) \ - { \ - srcy = (dstheight - 1) * dy - srcy; \ - dy = -dy; \ - } \ - \ - /* fetch the source data */ \ - srcdata = get_data(code); \ - \ - /* compute how many blocks of 4 pixels we have */ \ - u32 numblocks = (destendx + 1 - destx) / 4; \ - u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; \ - \ - /* iterate over pixels in Y */ \ - for (cury = desty; cury <= destendy; cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, destx); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ - const u8 *srcptr = srcdata + (srcy >> 16) * rowbytes(); \ - s32 cursrcx = srcx; \ - srcy += dy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[cursrcx >> 16]); \ - cursrcx += dx; \ - PIXEL_OP(destptr[1], priptr[1], srcptr[cursrcx >> 16]); \ - cursrcx += dx; \ - PIXEL_OP(destptr[2], priptr[2], srcptr[cursrcx >> 16]); \ - cursrcx += dx; \ - PIXEL_OP(destptr[3], priptr[3], srcptr[cursrcx >> 16]); \ - cursrcx += dx; \ - \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[cursrcx >> 16]); \ - cursrcx += dx; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } while (0); \ - g_profiler.stop(); \ -} while (0) - - - -/*************************************************************************** - BASIC COPYBITMAP CORE -***************************************************************************/ - -/* - Assumed input parameters or local variables: - - bitmap_t &dest - the bitmap to copy to - bitmap_t &src - the bitmap to copy from (must be same bpp as dest) - const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') - int flipx - non-zero means render right-to-left instead of left-to-right - int flipy - non-zero means render bottom-to-top instead of top-to-bottom - s32 destx - the top-left X coordinate to copy to - s32 desty - the top-left Y coordinate to copy to - bitmap_t &priority - the priority bitmap (even if PRIORITY_TYPE is NO_PRIORITY, at least needs a dummy) -*/ - -#define COPYBITMAP_CORE(PIXEL_TYPE, PIXEL_OP, PRIORITY_TYPE) \ -do { \ - g_profiler.start(PROFILER_COPYBITMAP); \ - do { \ - const PIXEL_TYPE *srcdata; \ - u32 numblocks, leftovers; \ - s32 destendx, destendy; \ - s32 srcx, srcy; \ - s32 curx, cury; \ - s32 dx, dy; \ - \ - assert(dest.valid()); \ - assert(src.valid()); \ - assert(!PRIORITY_VALID(PRIORITY_TYPE) || priority.valid()); \ - assert(dest.cliprect().contains(cliprect)); \ - \ - /* ignore empty/invalid cliprects */ \ - if (cliprect.empty()) \ - break; \ - \ - /* standard setup; dx counts bytes in X, dy counts pixels in Y */ \ - dx = 1; \ - dy = src.rowpixels(); \ - \ - /* compute final pixel in X and exit if we are entirely clipped */ \ - destendx = destx + src.width() - 1; \ - if (destx > cliprect.right() || destendx < cliprect.left()) \ - break; \ - \ - /* apply left clip */ \ - srcx = 0; \ - if (destx < cliprect.left()) \ - { \ - srcx = cliprect.left() - destx; \ - destx = cliprect.left(); \ - } \ - \ - /* apply right clip */ \ - if (destendx > cliprect.right()) \ - destendx = cliprect.right(); \ - \ - /* compute final pixel in Y and exit if we are entirely clipped */ \ - destendy = desty + src.height() - 1; \ - if (desty > cliprect.bottom() || destendy < cliprect.top()) \ - break; \ - \ - /* apply top clip */ \ - srcy = 0; \ - if (desty < cliprect.top()) \ - { \ - srcy = cliprect.top() - desty; \ - desty = cliprect.top(); \ - } \ - \ - /* apply bottom clip */ \ - if (destendy > cliprect.bottom()) \ - destendy = cliprect.bottom(); \ - \ - /* apply X flipping */ \ - if (flipx) \ - { \ - srcx = src.width() - 1 - srcx; \ - dx = -dx; \ - } \ - \ - /* apply Y flipping */ \ - if (flipy) \ - { \ - srcy = src.height() - 1 - srcy; \ - dy = -dy; \ - } \ - \ - /* compute how many blocks of 4 pixels we have */ \ - numblocks = (destendx + 1 - destx) / 4; \ - leftovers = (destendx + 1 - destx) - 4 * numblocks; \ - \ - /* compute the address of the first source pixel of the first row */ \ - srcdata = &src.pixt(srcy, srcx); \ - \ - /* non-flipped case */ \ - if (!flipx) \ - { \ - /* iterate over pixels in Y */ \ - for (cury = desty; cury <= destendy; cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, destx); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ - const PIXEL_TYPE *srcptr = srcdata; \ - srcdata += dy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[1]); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[2]); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[3]); \ - \ - srcptr += 4; \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcptr++; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - \ - /* flipped case */ \ - else \ - { \ - /* iterate over pixels in Y */ \ - for (cury = desty; cury <= destendy; cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, destx); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, destx); \ - const PIXEL_TYPE *srcptr = srcdata; \ - srcdata += dy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[ 0]); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[-1]); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[-2]); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[-3]); \ - \ - srcptr -= 4; \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcptr--; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - } while (0); \ - g_profiler.stop(); \ -} while (0) - - - -/*************************************************************************** - BASIC COPYROZBITMAP CORE -***************************************************************************/ - -/* - Assumed input parameters or local variables: - - bitmap_t &dest - the bitmap to copy to - bitmap_t &src - the bitmap to copy from (must be same bpp as dest) - const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') - s32 destx - the 16.16 source X position at destination pixel (0,0) - s32 desty - the 16.16 source Y position at destination pixel (0,0) - s32 incxx - the 16.16 amount to increment in source X for each destination X pixel - s32 incyx - the 16.16 amount to increment in source Y for each destination X pixel - s32 incxy - the 16.16 amount to increment in source X for each destination Y pixel - s32 incyy - the 16.16 amount to increment in source Y for each destination Y pixel - int wraparound - non-zero means wrap when hitting the edges of the source - bitmap_t &priority - the priority bitmap (even if PRIORITY_TYPE is NO_PRIORITY, at least needs a dummy) -*/ - -#define COPYROZBITMAP_CORE(PIXEL_TYPE, PIXEL_OP, PRIORITY_TYPE) \ -do { \ - u32 srcfixwidth, srcfixheight; \ - u32 numblocks, leftovers; \ - s32 curx, cury; \ - \ - g_profiler.start(PROFILER_COPYBITMAP); \ - \ - assert(dest.valid()); \ - assert(dest.valid()); \ - assert(!PRIORITY_VALID(PRIORITY_TYPE) || priority.valid()); \ - assert(dest.cliprect().contains(cliprect)); \ - assert(!wraparound || (src.width() & (src.width() - 1)) == 0); \ - assert(!wraparound || (src.height() & (src.height() - 1)) == 0); \ - \ - /* ignore empty/invalid cliprects */ \ - if (cliprect.empty()) \ - break; \ - \ - /* compute fixed-point 16.16 size of the source bitmap */ \ - srcfixwidth = src.width() << 16; \ - srcfixheight = src.height() << 16; \ - \ - /* advance the starting coordinates to the top-left of the cliprect */ \ - startx += cliprect.left() * incxx + cliprect.top() * incyx; \ - starty += cliprect.left() * incxy + cliprect.top() * incyy; \ - \ - /* compute how many blocks of 4 pixels we have */ \ - numblocks = cliprect.width() / 4; \ - leftovers = cliprect.width() - 4 * numblocks; \ - \ - /* if incxy and incyx are 0, then we aren't rotating, just zooming */ \ - if (incxy == 0 && incyx == 0) \ - { \ - /* zoom-only, non-wraparound case */ \ - if (!wraparound) \ - { \ - /* iterate over pixels in Y */ \ - for (cury = cliprect.top(); cury <= cliprect.bottom(); cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, cliprect.left()); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, cliprect.left()); \ - const PIXEL_TYPE *srcptr; \ - s32 srcx = startx; \ - s32 srcy = starty; \ - \ - starty += incyy; \ - \ - /* check srcy for the whole row at once */ \ - if ((u32)srcy < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16); \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - if (u32(srcx) < srcfixwidth) \ - PIXEL_OP(destptr[0], priptr[0], srcptr[srcx >> 16]); \ - srcx += incxx; \ - \ - if (u32(srcx) < srcfixwidth) \ - PIXEL_OP(destptr[1], priptr[1], srcptr[srcx >> 16]); \ - srcx += incxx; \ - \ - if (u32(srcx) < srcfixwidth) \ - PIXEL_OP(destptr[2], priptr[2], srcptr[srcx >> 16]); \ - srcx += incxx; \ - \ - if (u32(srcx) < srcfixwidth) \ - PIXEL_OP(destptr[3], priptr[3], srcptr[srcx >> 16]); \ - srcx += incxx; \ - \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - if (u32(srcx) < srcfixwidth) \ - PIXEL_OP(destptr[0], priptr[0], srcptr[srcx >> 16]); \ - srcx += incxx; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - } \ - \ - /* zoom-only, wraparound case */ \ - else \ - { \ - /* convert srcfixwidth/height into a mask and apply */ \ - srcfixwidth--; \ - srcfixheight--; \ - startx &= srcfixwidth; \ - starty &= srcfixheight; \ - \ - /* iterate over pixels in Y */ \ - for (cury = cliprect.top(); cury <= cliprect.bottom(); cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, cliprect.left()); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, cliprect.left()); \ - const PIXEL_TYPE *srcptr = &src.pixt(starty >> 16); \ - s32 srcx = startx; \ - \ - starty = (starty + incyy) & srcfixheight; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[srcx >> 16]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - \ - PIXEL_OP(destptr[1], priptr[1], srcptr[srcx >> 16]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - \ - PIXEL_OP(destptr[2], priptr[2], srcptr[srcx >> 16]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - \ - PIXEL_OP(destptr[3], priptr[3], srcptr[srcx >> 16]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[srcx >> 16]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - } \ - \ - /* full rotation case */ \ - else \ - { \ - /* full rotation, non-wraparound case */ \ - if (!wraparound) \ - { \ - /* iterate over pixels in Y */ \ - for (cury = cliprect.top(); cury <= cliprect.bottom(); cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, cliprect.left()); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, cliprect.left()); \ - const PIXEL_TYPE *srcptr; \ - s32 srcx = startx; \ - s32 srcy = starty; \ - \ - startx += incyx; \ - starty += incyy; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - if (u32(srcx) < srcfixwidth && (u32)srcy < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - } \ - srcx += incxx; \ - srcy += incxy; \ - \ - if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[0]); \ - } \ - srcx += incxx; \ - srcy += incxy; \ - \ - if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[0]); \ - } \ - srcx += incxx; \ - srcy += incxy; \ - \ - if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[0]); \ - } \ - srcx += incxx; \ - srcy += incxy; \ - \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - } \ - srcx += incxx; \ - srcy += incxy; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - \ - /* zoom-only, wraparound case */ \ - else \ - { \ - /* convert srcfixwidth/height into a mask and apply */ \ - srcfixwidth--; \ - srcfixheight--; \ - startx &= srcfixwidth; \ - starty &= srcfixheight; \ - \ - /* iterate over pixels in Y */ \ - for (cury = cliprect.top(); cury <= cliprect.bottom(); cury++) \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, cury, cliprect.left()); \ - PIXEL_TYPE *destptr = &dest.pixt(cury, cliprect.left()); \ - const PIXEL_TYPE *srcptr; \ - s32 srcx = startx; \ - s32 srcy = starty; \ - \ - startx = (startx + incyx) & srcfixwidth; \ - starty = (starty + incyy) & srcfixheight; \ - \ - /* iterate over unrolled blocks of 4 */ \ - for (curx = 0; curx < numblocks; curx++) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - srcy = (srcy + incxy) & srcfixheight; \ - \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[0]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - srcy = (srcy + incxy) & srcfixheight; \ - \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[0]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - srcy = (srcy + incxy) & srcfixheight; \ - \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[0]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - srcy = (srcy + incxy) & srcfixheight; \ - \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - for (curx = 0; curx < leftovers; curx++) \ - { \ - srcptr = &src.pixt(srcy >> 16, srcx >> 16); \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcx = (srcx + incxx) & srcfixwidth; \ - srcy = (srcy + incxy) & srcfixheight; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ - } \ - } \ - g_profiler.stop(); \ -} while (0) - - - -/*************************************************************************** - BASIC DRAWSCANLINE CORE -***************************************************************************/ - -/* - Assumed input parameters or local variables: - - bitmap_t &bitmap - the bitmap to copy to - s32 destx - the X coordinate to copy to - s32 desty - the Y coordinate to copy to - s32 length - the total number of pixels to copy - const UINTx *srcptr - pointer to memory containing the source pixels - bitmap_t &priority - the priority bitmap (even if PRIORITY_TYPE is NO_PRIORITY, at least needs a dummy) -*/ - -#define DRAWSCANLINE_CORE(PIXEL_TYPE, PIXEL_OP, PRIORITY_TYPE) \ -do { \ - assert(bitmap.valid()); \ - assert(destx >= 0); \ - assert(destx + length <= bitmap.width()); \ - assert(desty >= 0); \ - assert(desty < bitmap.height()); \ - assert(srcptr != nullptr); \ - assert(!PRIORITY_VALID(PRIORITY_TYPE) || priority.valid()); \ - \ - { \ - PRIORITY_TYPE *priptr = PRIORITY_ADDR(priority, PRIORITY_TYPE, desty, destx); \ - PIXEL_TYPE *destptr = &bitmap.pixt(desty, destx); \ - \ - /* iterate over unrolled blocks of 4 */ \ - while (length >= 4) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - PIXEL_OP(destptr[1], priptr[1], srcptr[1]); \ - PIXEL_OP(destptr[2], priptr[2], srcptr[2]); \ - PIXEL_OP(destptr[3], priptr[3], srcptr[3]); \ - \ - length -= 4; \ - srcptr += 4; \ - destptr += 4; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 4); \ - } \ - \ - /* iterate over leftover pixels */ \ - while (length-- > 0) \ - { \ - PIXEL_OP(destptr[0], priptr[0], srcptr[0]); \ - srcptr++; \ - destptr++; \ - PRIORITY_ADVANCE(PRIORITY_TYPE, priptr, 1); \ - } \ - } \ -} while (0) - - -#endif /* __DRAWGFXM_H__ */ diff --git a/src/emu/drawgfxt.ipp b/src/emu/drawgfxt.ipp new file mode 100644 index 00000000000..eb4910ebf78 --- /dev/null +++ b/src/emu/drawgfxt.ipp @@ -0,0 +1,1911 @@ +// license:BSD-3-Clause +// copyright-holders:Nicola Salmoria, Aaron Giles +/********************************************************************* + + drawgfxt.ipp + + Template function implementing drawgfx core operations. Drivers + can use these if they need custom behavior not provided by the + existing drawgfx functions. + +*********************************************************************/ + +#pragma once + +#ifndef MAME_EMU_DRAWGFXT_IPP +#define MAME_EMU_DRAWGFXT_IPP + + +/*************************************************************************** + PIXEL OPERATIONS +***************************************************************************/ + +/*------------------------------------------------- + PIXEL_OP_COPY_OPAQUE - render all pixels + regardless of pen, copying directly +-------------------------------------------------*/ + +#define PIXEL_OP_COPY_OPAQUE(DEST, SOURCE) \ +do \ +{ \ + (DEST) = SOURCE; \ +} \ +while (0) +#define PIXEL_OP_COPY_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = SOURCE; \ + (PRIORITY) = 31; \ +} \ +while (0) +#define PIXEL_OP_COPY_OPAQUE_PRIMASK(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + (DEST) = SOURCE; \ + (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_COPY_TRANSPEN - render all pixels + except those matching 'transpen', copying + directly +-------------------------------------------------*/ + +#define PIXEL_OP_COPY_TRANSPEN(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + (DEST) = SOURCE; \ +} \ +while (0) +#define PIXEL_OP_COPY_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = SOURCE; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) +#define PIXEL_OP_COPY_TRANSPEN_PRIMASK(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + (DEST) = SOURCE; \ + (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_COPY_TRANSALPHA - render all pixels + except those with an alpha of zero, copying + directly +-------------------------------------------------*/ + +#define PIXEL_OP_COPY_TRANSALPHA(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if ((srcdata & 0xff000000) != 0) \ + (DEST) = SOURCE; \ +} \ +while (0) +#define PIXEL_OP_COPY_TRANSALPHA_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if ((srcdata & 0xff000000) != 0) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = SOURCE; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) +#define PIXEL_OP_COPY_TRANSALPHA_PRIMASK(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if ((srcdata & 0xff000000) != 0) \ + { \ + (DEST) = SOURCE; \ + (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REMAP_OPAQUE - render all pixels + regardless of pen, mapping the pen via the + 'paldata' array +-------------------------------------------------*/ + +#define PIXEL_OP_REMAP_OPAQUE(DEST, SOURCE) \ +do \ +{ \ + (DEST) = paldata[SOURCE]; \ +} \ +while (0) +#define PIXEL_OP_REMAP_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = paldata[SOURCE]; \ + (PRIORITY) = 31; \ +} \ +while (0) +#define PIXEL_OP_REMAP_OPAQUE_PRIMASK(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + (DEST) = paldata[SOURCE]; \ + (PRIORITY) = ((PRIORITY) & pmask) | pcode; \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REBASE_OPAQUE - render all pixels + regardless of pen, adding 'color' to the + pen value +-------------------------------------------------*/ + +#define PIXEL_OP_REBASE_OPAQUE(DEST, SOURCE) \ +do \ +{ \ + (DEST) = color + (SOURCE); \ +} \ +while (0) +#define PIXEL_OP_REBASE_OPAQUE_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = color + (SOURCE); \ + (PRIORITY) = 31; \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REMAP_TRANSPEN - render all pixels + except those matching 'trans_pen', mapping the + pen via the 'paldata' array +-------------------------------------------------*/ + +#define PIXEL_OP_REMAP_TRANSPEN(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + (DEST) = paldata[srcdata]; \ +} \ +while (0) +#define PIXEL_OP_REMAP_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = paldata[srcdata]; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REBASE_TRANSPEN - render all pixels + except those matching 'transpen', adding + 'color' to the pen value +-------------------------------------------------*/ + +#define PIXEL_OP_REBASE_TRANSPEN(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + (DEST) = color + srcdata; \ +} \ +while (0) +#define PIXEL_OP_REBASE_TRANSPEN_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = color + srcdata; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REMAP_TRANSMASK - render all pixels + except those matching 'trans_mask', mapping the + pen via the 'paldata' array +-------------------------------------------------*/ + +#define PIXEL_OP_REMAP_TRANSMASK(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (((trans_mask >> srcdata) & 1) == 0) \ + (DEST) = paldata[srcdata]; \ +} \ +while (0) +#define PIXEL_OP_REMAP_TRANSMASK_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (((trans_mask >> srcdata) & 1) == 0) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = paldata[srcdata]; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REBASE_TRANSMASK - render all pixels + except those matching 'trans_mask', adding + 'color' to the pen value +-------------------------------------------------*/ + +#define PIXEL_OP_REBASE_TRANSMASK(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (((trans_mask >> srcdata) & 1) == 0) \ + (DEST) = color + srcdata; \ +} \ +while (0) +#define PIXEL_OP_REBASE_TRANSMASK_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (((trans_mask >> srcdata) & 1) == 0) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = color + srcdata; \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REBASE_TRANSTABLE - look up each pen in + 'pentable'; if the entry is DRAWMODE_NONE, + don't draw it; if the entry is DRAWMODE_SOURCE, + add 'color' to the pen value; if the entry is + DRAWMODE_SHADOW, generate a shadow of the + destination pixel using 'shadowtable' + + PIXEL_OP_REMAP_TRANSTABLE - look up each pen in + 'pentable'; if the entry is DRAWMODE_NONE, + don't draw it; if the entry is DRAWMODE_SOURCE, + look up the pen via the 'paldata' array; if the + entry is DRAWMODE_SHADOW, generate a shadow of + the destination pixel using 'shadowtable' +-------------------------------------------------*/ + +#define PIXEL_OP_REBASE_TRANSTABLE16(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + u32 entry = pentable[srcdata]; \ + if (entry != DRAWMODE_NONE) \ + { \ + if (entry == DRAWMODE_SOURCE) \ + (DEST) = color + srcdata; \ + else \ + (DEST) = shadowtable[DEST]; \ + } \ +} \ +while (0) +#define PIXEL_OP_REMAP_TRANSTABLE32(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + u32 entry = pentable[srcdata]; \ + if (entry != DRAWMODE_NONE) \ + { \ + if (entry == DRAWMODE_SOURCE) \ + (DEST) = paldata[srcdata]; \ + else \ + (DEST) = shadowtable[rgb_t(DEST).as_rgb15()]; \ + } \ +} \ +while (0) +#define PIXEL_OP_REBASE_TRANSTABLE16_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + u32 entry = pentable[srcdata]; \ + if (entry != DRAWMODE_NONE) \ + { \ + u8 pridata = (PRIORITY); \ + if (entry == DRAWMODE_SOURCE) \ + { \ + if (((1 << (pridata & 0x1f)) & pmask) == 0) \ + (DEST) = color + srcdata; \ + (PRIORITY) = 31; \ + } \ + else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ + { \ + (DEST) = shadowtable[DEST]; \ + (PRIORITY) = pridata | 0x80; \ + } \ + } \ +} \ +while (0) +#define PIXEL_OP_REMAP_TRANSTABLE32_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + u32 entry = pentable[srcdata]; \ + if (entry != DRAWMODE_NONE) \ + { \ + u8 pridata = (PRIORITY); \ + if (entry == DRAWMODE_SOURCE) \ + { \ + if (((1 << (pridata & 0x1f)) & pmask) == 0) \ + (DEST) = paldata[srcdata]; \ + (PRIORITY) = 31; \ + } \ + else if ((pridata & 0x80) == 0 && ((1 << (pridata & 0x1f)) & pmask) == 0) \ + { \ + (DEST) = shadowtable[rgb_t(DEST).as_rgb15()]; \ + (PRIORITY) = pridata | 0x80; \ + } \ + } \ +} \ +while (0) + +/*------------------------------------------------- + PIXEL_OP_REMAP_TRANSPEN_ALPHA - render all + pixels except those matching 'transpen', + mapping the pen to via the 'paldata' array; + the resulting color is RGB alpha blended + against the destination using 'alpha' +-------------------------------------------------*/ + +#define PIXEL_OP_REMAP_TRANSPEN_ALPHA32(DEST, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + (DEST) = alpha_blend_r32((DEST), paldata[srcdata], alpha_val); \ +} \ +while (0) +#define PIXEL_OP_REMAP_TRANSPEN_ALPHA32_PRIORITY(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if (srcdata != trans_pen) \ + { \ + if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ + (DEST) = alpha_blend_r32((DEST), paldata[srcdata], alpha_val); \ + (PRIORITY) = 31; \ + } \ +} \ +while (0) + + +/*************************************************************************** + BASIC DRAWGFX CORE +***************************************************************************/ + +/* + Input parameters: + + bitmap_t &dest - the bitmap to render to + const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') + gfx_element *gfx - pointer to the gfx_element to render + u32 code - index of the entry within gfx_element + int flipx - non-zero means render right-to-left instead of left-to-right + int flipy - non-zero means render bottom-to-top instead of top-to-bottom + s32 destx - the top-left X coordinate to render to + s32 desty - the top-left Y coordinate to render to + bitmap_t &priority - the priority bitmap (if and only if priority is to be applied) +*/ + + +template +void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_DRAWGFX); + do { + assert(dest.valid()); + assert(dest.cliprect().contains(cliprect)); + assert(code < elements()); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + width() - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = cliprect.left() - destx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + height() - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + break; + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = cliprect.top() - desty; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + srcx = width() - 1 - srcx; + + // apply Y flipping + s32 dy = rowbytes(); + if (flipy) + { + srcy = height() - 1 - srcy; + dy = -dy; + } + + // fetch the source data + const u8 *srcdata = get_data(code); + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // adjust srcdata to point to the first source pixel of the row + srcdata += srcy * rowbytes() + srcx; + + // non-flipped 8bpp case + if (!flipx) + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[0]); + pixel_op(destptr[1], srcptr[1]); + pixel_op(destptr[2], srcptr[2]); + pixel_op(destptr[3], srcptr[3]); + + srcptr += 4; + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[0]); + srcptr++; + destptr++; + } + } + } + + // flipped 8bpp case + else + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[ 0]); + pixel_op(destptr[1], srcptr[-1]); + pixel_op(destptr[2], srcptr[-2]); + pixel_op(destptr[3], srcptr[-3]); + + srcptr -= 4; + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[0]); + srcptr--; + destptr++; + } + } + } + } while (0); + g_profiler.stop(); +} + + +template +void gfx_element::drawgfx_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, PriorityType &priority, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_DRAWGFX); + do { + assert(dest.valid()); + assert(priority.valid()); + assert(dest.cliprect().contains(cliprect)); + assert(code < elements()); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + width() - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = cliprect.left() - destx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + height() - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + break; + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = cliprect.top() - desty; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + srcx = width() - 1 - srcx; + + // apply Y flipping + s32 dy = rowbytes(); + if (flipy) + { + srcy = height() - 1 - srcy; + dy = -dy; + } + + // fetch the source data + const u8 *srcdata = get_data(code); + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // adjust srcdata to point to the first source pixel of the row + srcdata += srcy * rowbytes() + srcx; + + // non-flipped 8bpp case + if (!flipx) + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *priptr = &priority.pix(cury, destx); + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + pixel_op(destptr[1], priptr[1], srcptr[1]); + pixel_op(destptr[2], priptr[2], srcptr[2]); + pixel_op(destptr[3], priptr[3], srcptr[3]); + + srcptr += 4; + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcptr++; + destptr++; + priptr++; + } + } + } + + // flipped 8bpp case + else + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *priptr = &priority.pix(cury, destx); + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[ 0]); + pixel_op(destptr[1], priptr[1], srcptr[-1]); + pixel_op(destptr[2], priptr[2], srcptr[-2]); + pixel_op(destptr[3], priptr[3], srcptr[-3]); + + srcptr -= 4; + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcptr--; + destptr++; + priptr++; + } + } + } + } while (0); + g_profiler.stop(); +} + + + +/*************************************************************************** + BASIC DRAWGFXZOOM CORE +***************************************************************************/ + +/* + Input parameters: + + bitmap_t &dest - the bitmap to render to + const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') + gfx_element *gfx - pointer to the gfx_element to render + u32 code - index of the entry within gfx_element + int flipx - non-zero means render right-to-left instead of left-to-right + int flipy - non-zero means render bottom-to-top instead of top-to-bottom + s32 destx - the top-left X coordinate to render to + s32 desty - the top-left Y coordinate to render to + u32 scalex - the 16.16 scale factor in the X dimension + u32 scaley - the 16.16 scale factor in the Y dimension + bitmap_t &priority - the priority bitmap (if and only if priority is to be applied) +*/ + + +template +void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_DRAWGFX); + do { + assert(dest.valid()); + assert(dest.cliprect().contains(cliprect)); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // compute scaled size + u32 dstwidth = (scalex * width() + 0x8000) >> 16; + u32 dstheight = (scaley * height() + 0x8000) >> 16; + if (dstwidth < 1 || dstheight < 1) + break; + + // compute 16.16 source steps in dx and dy + s32 dx = (width() << 16) / dstwidth; + s32 dy = (height() << 16) / dstheight; + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + dstwidth - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = (cliprect.left() - destx) * dx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + dstheight - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + { + g_profiler.stop(); + return; + } + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = (cliprect.top() - desty) * dy; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + { + srcx = (dstwidth - 1) * dx - srcx; + dx = -dx; + } + + // apply Y flipping + if (flipy) + { + srcy = (dstheight - 1) * dy - srcy; + dy = -dy; + } + + // fetch the source data + const u8 *srcdata = get_data(code); + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata + (srcy >> 16) * rowbytes(); + s32 cursrcx = srcx; + srcy += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[1], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[2], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[3], srcptr[cursrcx >> 16]); + cursrcx += dx; + + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[cursrcx >> 16]); + cursrcx += dx; + destptr++; + } + } + } while (0); + g_profiler.stop(); +} + + +template +void gfx_element::drawgfxzoom_core(BitmapType &dest, const rectangle &cliprect, u32 code, int flipx, int flipy, s32 destx, s32 desty, u32 scalex, u32 scaley, PriorityType &priority, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_DRAWGFX); + do { + assert(dest.valid()); + assert(priority.valid()); + assert(dest.cliprect().contains(cliprect)); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // compute scaled size + u32 dstwidth = (scalex * width() + 0x8000) >> 16; + u32 dstheight = (scaley * height() + 0x8000) >> 16; + if (dstwidth < 1 || dstheight < 1) + break; + + // compute 16.16 source steps in dx and dy + s32 dx = (width() << 16) / dstwidth; + s32 dy = (height() << 16) / dstheight; + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + dstwidth - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = (cliprect.left() - destx) * dx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + dstheight - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + { + g_profiler.stop(); + return; + } + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = (cliprect.top() - desty) * dy; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + { + srcx = (dstwidth - 1) * dx - srcx; + dx = -dx; + } + + // apply Y flipping + if (flipy) + { + srcy = (dstheight - 1) * dy - srcy; + dy = -dy; + } + + // fetch the source data + const u8 *srcdata = get_data(code); + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *priptr = &priority.pix(cury, destx); + auto *destptr = &dest.pix(cury, destx); + const u8 *srcptr = srcdata + (srcy >> 16) * rowbytes(); + s32 cursrcx = srcx; + srcy += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[1], priptr[1], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[2], priptr[2], srcptr[cursrcx >> 16]); + cursrcx += dx; + pixel_op(destptr[3], priptr[3], srcptr[cursrcx >> 16]); + cursrcx += dx; + + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[cursrcx >> 16]); + cursrcx += dx; + destptr++; + priptr++; + } + } + } while (0); + g_profiler.stop(); +} + + + +/*************************************************************************** + BASIC COPYBITMAP CORE +***************************************************************************/ + +/* + Input parameters: + + bitmap_t &dest - the bitmap to copy to + bitmap_t &src - the bitmap to copy from (must be same bpp as dest) + const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') + int flipx - non-zero means render right-to-left instead of left-to-right + int flipy - non-zero means render bottom-to-top instead of top-to-bottom + s32 destx - the top-left X coordinate to copy to + s32 desty - the top-left Y coordinate to copy to + bitmap_t &priority - the priority bitmap (if and only if priority is to be applied) +*/ + +template +void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_COPYBITMAP); + do { + assert(dest.valid()); + assert(src.valid()); + assert(dest.cliprect().contains(cliprect)); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // standard setup; dx counts bytes in X, dy counts pixels in Y + s32 dx = 1; + s32 dy = src.rowpixels(); + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + src.width() - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = cliprect.left() - destx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + src.height() - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + break; + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = cliprect.top() - desty; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + { + srcx = src.width() - 1 - srcx; + dx = -dx; + } + + // apply Y flipping + if (flipy) + { + srcy = src.height() - 1 - srcy; + dy = -dy; + } + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // compute the address of the first source pixel of the first row + const auto *srcdata = &src.pix(srcy, srcx); + + // non-flipped case + if (!flipx) + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *destptr = &dest.pix(cury, destx); + const auto *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[0]); + pixel_op(destptr[1], srcptr[1]); + pixel_op(destptr[2], srcptr[2]); + pixel_op(destptr[3], srcptr[3]); + + srcptr += 4; + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[0]); + srcptr++; + destptr++; + } + } + } + + // flipped case + else + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *destptr = &dest.pix(cury, destx); + const auto *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[ 0]); + pixel_op(destptr[1], srcptr[-1]); + pixel_op(destptr[2], srcptr[-2]); + pixel_op(destptr[3], srcptr[-3]); + + srcptr -= 4; + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[0]); + srcptr--; + destptr++; + } + } + } + } while (0); + g_profiler.stop(); +} + + +template +void copybitmap_core(BitmapType &dest, const BitmapType &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, PriorityType &priority, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_COPYBITMAP); + do { + assert(dest.valid()); + assert(src.valid()); + assert(priority.valid()); + assert(dest.cliprect().contains(cliprect)); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + break; + + // standard setup; dx counts bytes in X, dy counts pixels in Y + s32 dx = 1; + s32 dy = src.rowpixels(); + + // compute final pixel in X and exit if we are entirely clipped + s32 destendx = destx + src.width() - 1; + if (destx > cliprect.right() || destendx < cliprect.left()) + break; + + // apply left clip + s32 srcx = 0; + if (destx < cliprect.left()) + { + srcx = cliprect.left() - destx; + destx = cliprect.left(); + } + + // apply right clip + if (destendx > cliprect.right()) + destendx = cliprect.right(); + + // compute final pixel in Y and exit if we are entirely clipped + s32 destendy = desty + src.height() - 1; + if (desty > cliprect.bottom() || destendy < cliprect.top()) + break; + + // apply top clip + s32 srcy = 0; + if (desty < cliprect.top()) + { + srcy = cliprect.top() - desty; + desty = cliprect.top(); + } + + // apply bottom clip + if (destendy > cliprect.bottom()) + destendy = cliprect.bottom(); + + // apply X flipping + if (flipx) + { + srcx = src.width() - 1 - srcx; + dx = -dx; + } + + // apply Y flipping + if (flipy) + { + srcy = src.height() - 1 - srcy; + dy = -dy; + } + + // compute how many blocks of 4 pixels we have + u32 numblocks = (destendx + 1 - destx) / 4; + u32 leftovers = (destendx + 1 - destx) - 4 * numblocks; + + // compute the address of the first source pixel of the first row + const auto *srcdata = &src.pix(srcy, srcx); + + // non-flipped case + if (!flipx) + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *priptr = &priority.pix(cury, destx); + auto *destptr = &dest.pix(cury, destx); + const auto *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + pixel_op(destptr[1], priptr[1], srcptr[1]); + pixel_op(destptr[2], priptr[2], srcptr[2]); + pixel_op(destptr[3], priptr[3], srcptr[3]); + + srcptr += 4; + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcptr++; + destptr++; + priptr++; + } + } + } + + // flipped case + else + { + // iterate over pixels in Y + for (s32 cury = desty; cury <= destendy; cury++) + { + auto *priptr = &priority.pix(cury, destx); + auto *destptr = &dest.pix(cury, destx); + const auto *srcptr = srcdata; + srcdata += dy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[ 0]); + pixel_op(destptr[1], priptr[1], srcptr[-1]); + pixel_op(destptr[2], priptr[2], srcptr[-2]); + pixel_op(destptr[3], priptr[3], srcptr[-3]); + + srcptr -= 4; + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcptr--; + destptr++; + priptr++; + } + } + } + } while (0); + g_profiler.stop(); +} + + + +/*************************************************************************** + BASIC COPYROZBITMAP CORE +***************************************************************************/ + +/* + Input parameters: + + bitmap_t &dest - the bitmap to copy to + bitmap_t &src - the bitmap to copy from (must be same bpp as dest) + const rectangle &cliprect - a clipping rectangle (assumed to be clipped to the size of 'dest') + s32 destx - the 16.16 source X position at destination pixel (0,0) + s32 desty - the 16.16 source Y position at destination pixel (0,0) + s32 incxx - the 16.16 amount to increment in source X for each destination X pixel + s32 incyx - the 16.16 amount to increment in source Y for each destination X pixel + s32 incxy - the 16.16 amount to increment in source X for each destination Y pixel + s32 incyy - the 16.16 amount to increment in source Y for each destination Y pixel + int wraparound - non-zero means wrap when hitting the edges of the source + bitmap_t &priority - the priority bitmap (if and only if priority is to be applied) +*/ + +template +void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, const BitmapType &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_COPYBITMAP); + + assert(dest.valid()); + assert(dest.valid()); + assert(dest.cliprect().contains(cliprect)); + assert(!wraparound || (src.width() & (src.width() - 1)) == 0); + assert(!wraparound || (src.height() & (src.height() - 1)) == 0); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + { + g_profiler.stop(); + return; + } + + // compute fixed-point 16.16 size of the source bitmap + u32 srcfixwidth = src.width() << 16; + u32 srcfixheight = src.height() << 16; + + // advance the starting coordinates to the top-left of the cliprect + startx += cliprect.left() * incxx + cliprect.top() * incyx; + starty += cliprect.left() * incxy + cliprect.top() * incyy; + + // compute how many blocks of 4 pixels we have + u32 numblocks = cliprect.width() / 4; + u32 leftovers = cliprect.width() - 4 * numblocks; + + // if incxy and incyx are 0, then we aren't rotating, just zooming + if (incxy == 0 && incyx == 0) + { + // zoom-only, non-wraparound case + if (!wraparound) + { + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + starty += incyy; + + // check srcy for the whole row at once + if (u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16); + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[0], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[1], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[2], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[3], srcptr[srcx >> 16]); + srcx += incxx; + + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[0], srcptr[srcx >> 16]); + srcx += incxx; + destptr++; + } + } + } + } + + // zoom-only, wraparound case + else + { + // convert srcfixwidth/height into a mask and apply + srcfixwidth--; + srcfixheight--; + startx &= srcfixwidth; + starty &= srcfixheight; + + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *destptr = &dest.pix(cury, cliprect.left()); + const auto *srcptr = &src.pix(starty >> 16); + s32 srcx = startx; + + starty = (starty + incyy) & srcfixheight; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[1], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[2], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[3], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + destptr++; + } + } + } + } + + // full rotation case + else + { + // full rotation, non-wraparound case + if (!wraparound) + { + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + startx += incyx; + starty += incyy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[1], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[2], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[3], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + destptr++; + } + } + } + + // zoom-only, wraparound case + else + { + // convert srcfixwidth/height into a mask and apply + srcfixwidth--; + srcfixheight--; + startx &= srcfixwidth; + starty &= srcfixheight; + + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + startx = (startx + incyx) & srcfixwidth; + starty = (starty + incyy) & srcfixheight; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[1], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[2], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[3], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + destptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + destptr++; + } + } + } + } + g_profiler.stop(); +} + + +template +void copyrozbitmap_core(BitmapType &dest, const rectangle &cliprect, const BitmapType &src, s32 startx, s32 starty, s32 incxx, s32 incxy, s32 incyx, s32 incyy, int wraparound, PriorityType &priority, FunctionClass pixel_op) +{ + g_profiler.start(PROFILER_COPYBITMAP); + + assert(dest.valid()); + assert(dest.valid()); + assert(priority.valid()); + assert(dest.cliprect().contains(cliprect)); + assert(!wraparound || (src.width() & (src.width() - 1)) == 0); + assert(!wraparound || (src.height() & (src.height() - 1)) == 0); + + // ignore empty/invalid cliprects + if (cliprect.empty()) + { + g_profiler.stop(); + return; + } + + // compute fixed-point 16.16 size of the source bitmap + u32 srcfixwidth = src.width() << 16; + u32 srcfixheight = src.height() << 16; + + // advance the starting coordinates to the top-left of the cliprect + startx += cliprect.left() * incxx + cliprect.top() * incyx; + starty += cliprect.left() * incxy + cliprect.top() * incyy; + + // compute how many blocks of 4 pixels we have + u32 numblocks = cliprect.width() / 4; + u32 leftovers = cliprect.width() - 4 * numblocks; + + // if incxy and incyx are 0, then we aren't rotating, just zooming + if (incxy == 0 && incyx == 0) + { + // zoom-only, non-wraparound case + if (!wraparound) + { + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *priptr = &priority.pix(cury, cliprect.left()); + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + starty += incyy; + + // check srcy for the whole row at once + if (u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16); + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[0], priptr[0], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[1], priptr[1], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[2], priptr[2], srcptr[srcx >> 16]); + srcx += incxx; + + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[3], priptr[3], srcptr[srcx >> 16]); + srcx += incxx; + + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + if (u32(srcx) < srcfixwidth) + pixel_op(destptr[0], priptr[0], srcptr[srcx >> 16]); + srcx += incxx; + destptr++; + priptr++; + } + } + } + } + + // zoom-only, wraparound case + else + { + // convert srcfixwidth/height into a mask and apply + srcfixwidth--; + srcfixheight--; + startx &= srcfixwidth; + starty &= srcfixheight; + + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *priptr = &priority.pix(cury, cliprect.left()); + auto *destptr = &dest.pix(cury, cliprect.left()); + const auto *srcptr = &src.pix(starty >> 16); + s32 srcx = startx; + + starty = (starty + incyy) & srcfixheight; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[1], priptr[1], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[2], priptr[2], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + pixel_op(destptr[3], priptr[3], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + pixel_op(destptr[0], priptr[0], srcptr[srcx >> 16]); + srcx = (srcx + incxx) & srcfixwidth; + destptr++; + priptr++; + } + } + } + } + + // full rotation case + else + { + // full rotation, non-wraparound case + if (!wraparound) + { + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *priptr = &priority.pix(cury, cliprect.left()); + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + startx += incyx; + starty += incyy; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], priptr[0], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[1], priptr[1], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[2], priptr[2], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[3], priptr[3], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + if (u32(srcx) < srcfixwidth && u32(srcy) < srcfixheight) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], priptr[0], srcptr[0]); + } + srcx += incxx; + srcy += incxy; + destptr++; + priptr++; + } + } + } + + // zoom-only, wraparound case + else + { + // convert srcfixwidth/height into a mask and apply + srcfixwidth--; + srcfixheight--; + startx &= srcfixwidth; + starty &= srcfixheight; + + // iterate over pixels in Y + for (s32 cury = cliprect.top(); cury <= cliprect.bottom(); cury++) + { + auto *priptr = &priority.pix(cury, cliprect.left()); + auto *destptr = &dest.pix(cury, cliprect.left()); + s32 srcx = startx; + s32 srcy = starty; + + startx = (startx + incyx) & srcfixwidth; + starty = (starty + incyy) & srcfixheight; + + // iterate over unrolled blocks of 4 + for (s32 curx = 0; curx < numblocks; curx++) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[1], priptr[1], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[2], priptr[2], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[3], priptr[3], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + + destptr += 4; + priptr += 4; + } + + // iterate over leftover pixels + for (s32 curx = 0; curx < leftovers; curx++) + { + const auto *srcptr = &src.pix(srcy >> 16, srcx >> 16); + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcx = (srcx + incxx) & srcfixwidth; + srcy = (srcy + incxy) & srcfixheight; + destptr++; + priptr++; + } + } + } + } + g_profiler.stop(); +} + + + +/*************************************************************************** + BASIC DRAWSCANLINE CORE +***************************************************************************/ + +/* + Input parameters: + + bitmap_t &bitmap - the bitmap to copy to + s32 destx - the X coordinate to copy to + s32 desty - the Y coordinate to copy to + s32 length - the total number of pixels to copy + const UINTx *srcptr - pointer to memory containing the source pixels + bitmap_t &priority - the priority bitmap (if and only if priority is to be applied) +*/ + +template +void drawscanline_core(BitmapType &bitmap, s32 destx, s32 desty, s32 length, const SourceType *srcptr, FunctionClass pixel_op) +{ + assert(bitmap.valid()); + assert(destx >= 0); + assert(destx + length <= bitmap.width()); + assert(desty >= 0); + assert(desty < bitmap.height()); + assert(srcptr != nullptr); + + auto *destptr = &bitmap.pix(desty, destx); + + // iterate over unrolled blocks of 4 + while (length >= 4) + { + pixel_op(destptr[0], srcptr[0]); + pixel_op(destptr[1], srcptr[1]); + pixel_op(destptr[2], srcptr[2]); + pixel_op(destptr[3], srcptr[3]); + + length -= 4; + srcptr += 4; + destptr += 4; + } + + // iterate over leftover pixels + while (length-- > 0) + { + pixel_op(destptr[0], srcptr[0]); + srcptr++; + destptr++; + } +} + + +template +void drawscanline_core(BitmapType &bitmap, s32 destx, s32 desty, s32 length, const SourceType *srcptr, PriorityType &priority, FunctionClass pixel_op) +{ + assert(bitmap.valid()); + assert(destx >= 0); + assert(destx + length <= bitmap.width()); + assert(desty >= 0); + assert(desty < bitmap.height()); + assert(srcptr != nullptr); + assert(priority.valid()); + + auto *priptr = &priority.pix(desty, destx); + auto *destptr = &bitmap.pix(desty, destx); + + // iterate over unrolled blocks of 4 + while (length >= 4) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + pixel_op(destptr[1], priptr[1], srcptr[1]); + pixel_op(destptr[2], priptr[2], srcptr[2]); + pixel_op(destptr[3], priptr[3], srcptr[3]); + + length -= 4; + srcptr += 4; + destptr += 4; + priptr += 4; + + // iterate over leftover pixels + while (length-- > 0) + { + pixel_op(destptr[0], priptr[0], srcptr[0]); + srcptr++; + destptr++; + priptr++; + } + } +} + + +#endif // MAME_EMU_DRAWGFXT_IPP diff --git a/src/mame/video/psikyosh.cpp b/src/mame/video/psikyosh.cpp index ca12c5d05d2..7b97e5b98e2 100644 --- a/src/mame/video/psikyosh.cpp +++ b/src/mame/video/psikyosh.cpp @@ -65,7 +65,7 @@ The only viable way to do this is to have one tilemap per bank (0x0a-0x20), and */ #include "emu.h" -#include "drawgfxm.h" +#include "drawgfxt.ipp" #include "includes/psikyosh.h" #include @@ -76,7 +76,7 @@ static constexpr u32 BG_TRANSPEN = 0x00ff00ff; // used for representing transpar //#define DEBUG_MESSAGE // take ARGB pixel with stored alpha and blend in to RGB32 bitmap -#define PIXEL_OP_COPY_TRANSPEN_ARGBRENDER32(DEST, PRIORITY, SOURCE) \ +#define PIXEL_OP_COPY_TRANSPEN_ARGBRENDER32(DEST, SOURCE) \ do \ { \ const rgb_t srcdata = (SOURCE); \ @@ -85,7 +85,7 @@ do } \ while (0) // take RGB pixel with separate alpha and blend in to RGB32 bitmap -#define PIXEL_OP_COPY_TRANSPEN_ALPHARENDER32(DEST, PRIORITY, SOURCE) \ +#define PIXEL_OP_COPY_TRANSPEN_ALPHARENDER32(DEST, SOURCE) \ do \ { \ const u32 srcdata = (SOURCE); \ @@ -94,7 +94,7 @@ do } \ while (0) // take ARGB pixel with stored alpha and copy in to RGB32 bitmap, scipping BG_TRANSPEN -#define PIXEL_OP_COPY_TRANSPEN_RENDER32(DEST, PRIORITY, SOURCE) \ +#define PIXEL_OP_COPY_TRANSPEN_RENDER32(DEST, SOURCE) \ do \ { \ const u32 srcdata = (SOURCE); \ @@ -171,10 +171,7 @@ static inline void pixop_transparent_alphatable(u8 source, u32 *dest, const pen_ -------------------------------------------------*/ void psikyosh_state::draw_scanline32_alpha(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr, int alpha) { - DECLARE_NO_PRIORITY; - u32 const transpen = BG_TRANSPEN; - - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_TRANSPEN_ALPHARENDER32, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [alpha, transpen = BG_TRANSPEN](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_ALPHARENDER32(destp, srcp); }); } /*------------------------------------------------- @@ -183,10 +180,7 @@ void psikyosh_state::draw_scanline32_alpha(bitmap_rgb32 &bitmap, s32 destx, s32 -------------------------------------------------*/ void psikyosh_state::draw_scanline32_argb(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr) { - DECLARE_NO_PRIORITY; - u32 const transpen = BG_TRANSPEN; - - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_TRANSPEN_ARGBRENDER32, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [transpen = BG_TRANSPEN](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_ARGBRENDER32(destp, srcp); }); } /*------------------------------------------------- @@ -195,10 +189,7 @@ void psikyosh_state::draw_scanline32_argb(bitmap_rgb32 &bitmap, s32 destx, s32 d -------------------------------------------------*/ void psikyosh_state::draw_scanline32_transpen(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, const u32 *srcptr) { - DECLARE_NO_PRIORITY; - u32 const transpen = BG_TRANSPEN; - - DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_TRANSPEN_RENDER32, NO_PRIORITY); + drawscanline_core(bitmap, destx, desty, length, srcptr, [transpen = BG_TRANSPEN](u32 &destp, const u32 &srcp) { PIXEL_OP_COPY_TRANSPEN_RENDER32(destp, srcp); }); } diff --git a/src/mame/video/suna8.cpp b/src/mame/video/suna8.cpp index c12dbeb9d85..f1e4cd650b2 100644 --- a/src/mame/video/suna8.cpp +++ b/src/mame/video/suna8.cpp @@ -29,7 +29,7 @@ #include "emu.h" #include "includes/suna8.h" -#include "drawgfxm.h" +#include "drawgfxt.ipp" /*************************************************************************** For Debug: there's no tilemap, just sprites. @@ -188,19 +188,6 @@ do } \ while (0) -class mygfx_element : public gfx_element -{ -public: - void prio_mask_transpen(bitmap_ind16 &dest, const rectangle &cliprect, - uint32_t code, uint32_t color, int flipx, int flipy, int32_t destx, int32_t desty, - bitmap_ind8 &priority, uint32_t trans_pen) - { - color = colorbase() + granularity() * (color % colors()); - code %= elements(); - DRAWGFX_CORE(uint16_t, PIXEL_OP_REBASE_TRANSPEN_PRIORITY_MASK, uint8_t); - } -}; - /*************************************************************************** [ Sprites Format ] @@ -434,8 +421,13 @@ void suna8_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, cons int color = (((attr >> 2) & 0xf) ^ colorbank) + 0x10 * m_palettebank; // player2 in hardhea2 and sparkman if (read_mask) - ((mygfx_element*)(m_gfxdecode->gfx(which)))->prio_mask_transpen(bitmap, cliprect, - code, color, tile_flipx, tile_flipy, sx, sy, screen.priority(), 0xf); + { + gfx_element *mygfx = m_gfxdecode->gfx(which); + color = mygfx->colorbase() + mygfx->granularity() * (color % mygfx->colors()); + mygfx->drawgfx_core(bitmap, cliprect, code % mygfx->elements(), + tile_flipx, tile_flipy, sx, sy, screen.priority(), + [color, trans_pen = 0xf](uint16_t &destp, uint8_t &pri, const uint8_t &srcp) { PIXEL_OP_REBASE_TRANSPEN_PRIORITY_MASK(destp, pri, srcp); }); + } else m_gfxdecode->gfx(which)->transpen(bitmap, cliprect, code, color, tile_flipx, tile_flipy, sx, sy, 0xf); diff --git a/src/mame/video/tc0080vco.cpp b/src/mame/video/tc0080vco.cpp index fcc725abd69..e935ed2264c 100644 --- a/src/mame/video/tc0080vco.cpp +++ b/src/mame/video/tc0080vco.cpp @@ -64,7 +64,7 @@ this seems to be the only zoom feature actually used in the games. #include "tc0080vco.h" #include "video/taito_helper.h" -#include "drawgfxm.h" +#include "drawgfxt.ipp" #include "screen.h" @@ -710,25 +710,7 @@ void tc0080vco_device::bg1_tilemap_draw(screen_device &screen, bitmap_ind16 &bit sy = (( 0x3fe - m_scroll_ram[layer + 3]) << 16) - (max_y + min_y) * (zy - 0x10000); } - { - bitmap_ind16 &dest = bitmap; - bitmap_ind16 &src = srcbitmap; - s32 startx = sx; - s32 starty = sy; - s32 incxx = zx; - s32 incxy = 0; - s32 incyx = 0; - s32 incyy = zy; - int wraparound = 0; - u8 privalue = priority; - u8 primask = pmask; - bitmap_ind8 &priority = screen.priority(); - - if (dest.bpp() == 16) - COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_TRANS0_SET_PRIORITY, u8); - else - COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANS0_SET_PRIORITY, u8); - } + copyrozbitmap_core(bitmap, cliprect, srcbitmap, sx, sy, zx, 0, 0, zy, 0, screen.priority(), [privalue = priority, primask = pmask](u16 &destp, u8 &pri, const u16 &srcp) { PIXEL_OP_COPY_TRANS0_SET_PRIORITY(destp, pri, srcp); }); } } -- cgit v1.2.3