diff options
Diffstat (limited to 'src/emu/drawgfx.cpp')
-rw-r--r-- | src/emu/drawgfx.cpp | 581 |
1 files changed, 566 insertions, 15 deletions
diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp index 3a00569e32c..841ae7c670f 100644 --- a/src/emu/drawgfx.cpp +++ b/src/emu/drawgfx.cpp @@ -1520,20 +1520,7 @@ do if (srcdata != trans_pen) \ { \ if (((1 << ((PRIORITY) & 0x1f)) & pmask) == 0) \ - { \ - u32 srcdata2 = paldata[srcdata]; \ - \ - u32 add; \ - add = (srcdata2 & 0x00ff0000) + (DEST & 0x00ff0000); \ - if (add & 0x01000000) DEST = (DEST & 0xff00ffff) | (0x00ff0000); \ - else DEST = (DEST & 0xff00ffff) | (add & 0x00ff0000); \ - add = (srcdata2 & 0x000000ff) + (DEST & 0x000000ff); \ - if (add & 0x00000100) DEST = (DEST & 0xffffff00) | (0x000000ff); \ - else DEST = (DEST & 0xffffff00) | (add & 0x000000ff); \ - add = (srcdata2 & 0x0000ff00) + (DEST & 0x0000ff00); \ - if (add & 0x00010000) DEST = (DEST & 0xffff00ff) | (0x0000ff00); \ - else DEST = (DEST & 0xffff00ff) | (add & 0x0000ff00); \ - } \ + (DEST) = add_blend_r32((DEST), paldata[srcdata]); \ (PRIORITY) = 31; \ } \ } \ @@ -1689,7 +1676,7 @@ void gfx_element::alphastore(bitmap_rgb32 &dest, const rectangle &cliprect, -------------------------------------------------*/ 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) + int fixedalpha, u8 *alphatable) { DECLARE_NO_PRIORITY; @@ -1753,6 +1740,62 @@ void draw_scanline8(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, cons DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline8(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline8(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + /*------------------------------------------------- draw_scanline16 - copy pixels from a 16bpp @@ -1785,6 +1828,62 @@ void draw_scanline16(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, con DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline16(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline16(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + /*------------------------------------------------- draw_scanline32 - copy pixels from a 32bpp @@ -1817,6 +1916,62 @@ void draw_scanline32(bitmap_rgb32 &bitmap, s32 destx, s32 desty, s32 length, con DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIORITY, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline32(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u16, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + return draw_scanline32(bitmap, destx, desty, length, srcptr, paldata); + + // palette lookup case + if (paldata != nullptr) + DRAWSCANLINE_CORE(u32, PIXEL_OP_REMAP_OPAQUE_PRIMASK, u8); + + // raw copy case + else + DRAWSCANLINE_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + /*************************************************************************** @@ -1893,6 +2048,38 @@ void copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flip COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); + else + COPYBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + copybitmap(dest, src, flipx, flipy, destx, desty, cliprect); + else + COPYBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIMASK, u8); +} + /*------------------------------------------------- copybitmap_trans - copy from one bitmap to @@ -1918,6 +2105,48 @@ void copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, in COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + 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); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + 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); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + copybitmap_trans(dest, src, flipx, flipy, destx, desty, cliprect, trans_pen); + 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); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + copybitmap_trans(dest, src, flipx, flipy, destx, desty, cliprect, trans_pen); + 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_transalphpa - copy from one bitmap @@ -1931,6 +2160,22 @@ void copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flip COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA_PRIORITY, u8); +} + +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) +{ + if (pcode == 0 && pmask == 0xff) + copybitmap_transalpha(dest, src, flipx, flipy, destx, desty, cliprect); + else + COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA_PRIMASK, u8); +} + /*************************************************************************** COPYSCROLLBITMAP IMPLEMENTATIONS @@ -1956,6 +2201,40 @@ void copyscrollbitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, 0xffffffff); } +void prio_copyscrollbitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + prio_copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, priority, pmask, 0xffffffff); +} + +void prio_copyscrollbitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + prio_copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, priority, pmask, 0xffffffff); +} + +void primask_copyscrollbitmap(bitmap_ind16 &dest, const bitmap_ind16 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u8 pcode, u8 pmask) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + if (pcode == 0 && pmask == 0xff) + copyscrollbitmap(dest, src, numrows, rowscroll, numcols, colscroll, cliprect); + else + primask_copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, 0xffffffff, priority, pcode, pmask); +} + +void primask_copyscrollbitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u8 pcode, u8 pmask) +{ + // just call through to the transparent case as the underlying copybitmap will + // optimize for pen == 0xffffffff + if (pcode == 0 && pmask == 0xff) + copyscrollbitmap(dest, src, numrows, rowscroll, numcols, colscroll, cliprect); + else + primask_copyscrollbitmap_trans(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, 0xffffffff, priority, pcode, pmask); +} + /*------------------------------------------------- copyscrollbitmap_trans - copy from one bitmap @@ -2067,6 +2346,214 @@ void copyscrollbitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, u32 num void copyscrollbitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, u32 trans_pen) { copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen); } +template<class _BitmapClass> +static inline void prio_copyscrollbitmap_trans_common(_BitmapClass &dest, const _BitmapClass &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) +{ + // no rowscroll and no colscroll means no scroll + if (numrows == 0 && numcols == 0) + return prio_copybitmap_trans(dest, src, 0, 0, 0, 0, cliprect, priority, pmask, trans_pen); + + assert(numrows != 0 || rowscroll == nullptr); + assert(numrows == 0 || rowscroll != nullptr); + assert(numcols != 0 || colscroll == nullptr); + assert(numcols == 0 || colscroll != nullptr); + + // fully scrolling X,Y playfield + if (numrows <= 1 && numcols <= 1) + { + s32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + s32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + + // iterate over all portions of the scroll that overlap the destination + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + prio_copybitmap_trans(dest, src, 0, 0, sx, sy, cliprect, priority, pmask, trans_pen); + } + + // scrolling columns plus horizontal scroll + else if (numrows <= 1) + { + s32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + rectangle subclip = cliprect; + + // determine width of each column + int colwidth = src.width() / numcols; + assert(src.width() % colwidth == 0); + + // iterate over each column + int groupcols; + for (int col = 0; col < numcols; col += groupcols) + { + s32 yscroll = colscroll[col]; + + // count consecutive columns scrolled by the same amount + for (groupcols = 1; col + groupcols < numcols; groupcols++) + if (colscroll[col + groupcols] != yscroll) + break; + + // iterate over reps of the columns in question + yscroll = normalize_yscroll(src, yscroll); + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + { + // compute the cliprect for this group + subclip.setx(col * colwidth + sx, (col + groupcols) * colwidth - 1 + sx); + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + prio_copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, priority, pmask, trans_pen); + } + } + } + + // scrolling rows plus vertical scroll + else if (numcols <= 1) + { + s32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + rectangle subclip = cliprect; + + // determine width of each rows + int rowheight = src.height() / numrows; + assert(src.height() % rowheight == 0); + + // iterate over each row + int grouprows; + for (int row = 0; row < numrows; row += grouprows) + { + s32 xscroll = rowscroll[row]; + + // count consecutive rows scrolled by the same amount + for (grouprows = 1; row + grouprows < numrows; grouprows++) + if (rowscroll[row + grouprows] != xscroll) + break; + + // iterate over reps of the rows in question + xscroll = normalize_xscroll(src, xscroll); + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + { + // compute the cliprect for this group + subclip.sety(row * rowheight + sy, (row + grouprows) * rowheight - 1 + sy); + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + prio_copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, priority, pmask, trans_pen); + } + } + } +} + +void prio_copyscrollbitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) +{ prio_copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, priority, pmask, trans_pen); } + +void prio_copyscrollbitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, bitmap_ind8 &priority, u32 pmask, u32 trans_pen) +{ prio_copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, priority, pmask, trans_pen); } + +template<class _BitmapClass> +static inline void primask_copyscrollbitmap_trans_common(_BitmapClass &dest, const _BitmapClass &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, u32 trans_pen, bitmap_ind8 &priority, u8 pcode = 0, u8 pmask = 0xff) +{ + // no rowscroll and no colscroll means no scroll + if (pcode == 0 && pmask == 0xff) + return copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen); + + if (numrows == 0 && numcols == 0) + return primask_copybitmap_trans(dest, src, 0, 0, 0, 0, cliprect, trans_pen, priority, pcode, pmask); + + assert(numrows != 0 || rowscroll == nullptr); + assert(numrows == 0 || rowscroll != nullptr); + assert(numcols != 0 || colscroll == nullptr); + assert(numcols == 0 || colscroll != nullptr); + + // fully scrolling X,Y playfield + if (numrows <= 1 && numcols <= 1) + { + s32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + s32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + + // iterate over all portions of the scroll that overlap the destination + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + primask_copybitmap_trans(dest, src, 0, 0, sx, sy, cliprect, trans_pen, priority, pcode, pmask); + } + + // scrolling columns plus horizontal scroll + else if (numrows <= 1) + { + s32 xscroll = normalize_xscroll(src, (numrows == 0) ? 0 : rowscroll[0]); + rectangle subclip = cliprect; + + // determine width of each column + int colwidth = src.width() / numcols; + assert(src.width() % colwidth == 0); + + // iterate over each column + int groupcols; + for (int col = 0; col < numcols; col += groupcols) + { + s32 yscroll = colscroll[col]; + + // count consecutive columns scrolled by the same amount + for (groupcols = 1; col + groupcols < numcols; groupcols++) + if (colscroll[col + groupcols] != yscroll) + break; + + // iterate over reps of the columns in question + yscroll = normalize_yscroll(src, yscroll); + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + { + // compute the cliprect for this group + subclip.setx(col * colwidth + sx, (col + groupcols) * colwidth - 1 + sx); + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + primask_copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, trans_pen, priority, pcode, pmask); + } + } + } + + // scrolling rows plus vertical scroll + else if (numcols <= 1) + { + s32 yscroll = normalize_yscroll(src, (numcols == 0) ? 0 : colscroll[0]); + rectangle subclip = cliprect; + + // determine width of each rows + int rowheight = src.height() / numrows; + assert(src.height() % rowheight == 0); + + // iterate over each row + int grouprows; + for (int row = 0; row < numrows; row += grouprows) + { + s32 xscroll = rowscroll[row]; + + // count consecutive rows scrolled by the same amount + for (grouprows = 1; row + grouprows < numrows; grouprows++) + if (rowscroll[row + grouprows] != xscroll) + break; + + // iterate over reps of the rows in question + xscroll = normalize_xscroll(src, xscroll); + for (s32 sy = yscroll - src.height(); sy < dest.height(); sy += src.height()) + { + // compute the cliprect for this group + subclip.sety(row * rowheight + sy, (row + grouprows) * rowheight - 1 + sy); + subclip &= cliprect; + + // iterate over all portions of the scroll that overlap the destination + for (s32 sx = xscroll - src.width(); sx < dest.width(); sx += src.width()) + primask_copybitmap_trans(dest, src, 0, 0, sx, sy, subclip, trans_pen, priority, pcode, pmask); + } + } + } +} + +void primask_copyscrollbitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) +{ primask_copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen, priority, pcode, pmask); } + +void primask_copyscrollbitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, u32 numrows, const s32 *rowscroll, u32 numcols, const s32 *colscroll, const rectangle &cliprect, u32 trans_pen, bitmap_ind8 &priority, u8 pcode, u8 pmask) +{ primask_copyscrollbitmap_trans_common(dest, src, numrows, rowscroll, numcols, colscroll, cliprect, trans_pen, priority, pcode, pmask); } /*************************************************************************** @@ -2091,6 +2578,38 @@ void copyrozbitmap(bitmap_rgb32 &dest, const rectangle &cliprect, const bitmap_r COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE, NO_PRIORITY); } +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_OPAQUE_PRIORITY, u8); +} + +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) +{ + 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); +} + +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) +{ + 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_trans - copy from one bitmap to @@ -2110,3 +2629,35 @@ void copyrozbitmap_trans(bitmap_rgb32 &dest, const rectangle &cliprect, const bi DECLARE_NO_PRIORITY; COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN, NO_PRIORITY); } + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYROZBITMAP_CORE(u16, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); +} + +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) +{ + // high bit of the mask is implicitly on + pmask |= 1 << 31; + + COPYROZBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSPEN_PRIORITY, u8); +} + +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) +{ + 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); +} + +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) +{ + 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); +} |