diff --git a/src/emu/rendersw.c b/src/emu/rendersw.c index 6248a56c3c5..d71265fd070 100644 --- a/src/emu/rendersw.c +++ b/src/emu/rendersw.c @@ -4,1184 +4,739 @@ Software-only rasterization system. - Copyright Nicola Salmoria and the MAME Team. - Visit http://mamedev.org for licensing and usage restrictions. - **************************************************************************** - This file is not to be directly compiled. Rather, the OSD code should - #define the macros below and then #include this file to generate - rasterizers that are optimized for a given output format. See - windows/rendsoft.c for an example. + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ - -/*************************************************************************** - USAGE VERIFICATION -***************************************************************************/ - -#if !defined(FUNC_PREFIX) -#error Must define FUNC_PREFIX! -#endif - -#if !defined(PIXEL_TYPE) -#error Must define PIXEL_TYPE! -#endif - -#if !defined(SRCSHIFT_R) || !defined(SRCSHIFT_G) || !defined(SRCSHIFT_B) -#error Must define SRCSHIFT_R/SRCSHIFT_G/SRCSHIFT_B! -#endif - -#if !defined(DSTSHIFT_R) || !defined(DSTSHIFT_G) || !defined(DSTSHIFT_B) -#error Must define DSTSHIFT_R/DSTSHIFT_G/DSTSHIFT_B! -#endif - -#if !defined(NO_DEST_READ) -#define NO_DEST_READ 0 -#endif - -#if !defined(BILINEAR_FILTER) -#define BILINEAR_FILTER 0 -#endif - - - -/*************************************************************************** - ONE-TIME-ONLY DEFINITIONS -***************************************************************************/ - -#ifndef FIRST_TIME -#define FIRST_TIME - #include "emucore.h" #include "eminline.h" #include "video/rgbutil.h" #include "render.h" - -/*************************************************************************** - MACROS -***************************************************************************/ - -#define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0) - -#define Tinten(intensity, col) \ - MAKE_RGB((RGB_RED(col) * (intensity)) >> 8, (RGB_GREEN(col) * (intensity)) >> 8, (RGB_BLUE(col) * (intensity)) >> 8) - -#define IS_OPAQUE(a) (a >= (NO_DEST_READ ? 0.5f : 1.0f)) -#define IS_TRANSPARENT(a) (a < (NO_DEST_READ ? 0.5f : 0.0001f)) - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -typedef struct _quad_setup_data quad_setup_data; -struct _quad_setup_data +template +class software_renderer { - INT32 dudx, dvdx, dudy, dvdy; - INT32 startu, startv; - INT32 startx, starty; - INT32 endx, endy; -}; - - - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -static UINT32 cosine_table[2049]; - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - round_nearest - round to nearest in a - predictable way --------------------------------------------------*/ - -INLINE float round_nearest(float f) -{ - return floor(f + 0.5f); -} - - -/*------------------------------------------------------------------------ - ycc_to_rgb - convert YCC to RGB; the YCC pixel - contains Y in the LSB, Cb << 8, and Cr << 16 - This actually a YCbCr conversion, - details my be found in chapter 6.4 ff of - http://softwarecommunity.intel.com/isn/downloads/softwareproducts/pdfs/346495.pdf - The document also contains the constants below as floats. ---------------------------------------------------------------------------*/ - -INLINE UINT8 clamp16_shift8(UINT32 x) -{ - return (((INT32) x < 0) ? 0 : (x > 65535 ? 255: x >> 8)); -} - -INLINE UINT32 ycc_to_rgb(UINT32 ycc) -{ - /* original equations: - - C = Y - 16 - D = Cb - 128 - E = Cr - 128 - - R = clip(( 298 * C + 409 * E + 128) >> 8) - G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) - B = clip(( 298 * C + 516 * D + 128) >> 8) - - R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8) - G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8) - B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8) - - R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) - G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) - B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) - - R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) - G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) - B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) - - Now combine constants: - - R = clip(( 298 * Y + 409 * Cr - 56992) >> 8) - G = clip(( 298 * Y - 100 * Cb - 208 * Cr + 34784) >> 8) - B = clip(( 298 * Y + 516 * Cb - 70688) >> 8) - - Define common = 298 * y - 56992. This will save one addition - - R = clip(( common + 409 * Cr - 0) >> 8) - G = clip(( common - 100 * Cb - 208 * Cr + 91776) >> 8) - B = clip(( common + 516 * Cb - 13696) >> 8) - - */ - UINT8 y = ycc; - UINT8 cb = ycc >> 8; - UINT8 cr = ycc >> 16; - UINT32 r, g, b, common; - - common = 298 * y - 56992; - r = (common + 409 * cr); - g = (common - 100 * cb - 208 * cr + 91776); - b = (common + 516 * cb - 13696); - - /* Now clamp and shift back */ - return MAKE_RGB(clamp16_shift8(r), clamp16_shift8(g), clamp16_shift8(b)); -} - -/*------------------------------------------------- - get_texel_palette16_nearest - return the - nearest neighbor texel from a palettized - 16bpp source --------------------------------------------------*/ - -INLINE UINT32 get_texel_palette16_nearest(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16); - return texture->palette[texbase[0]]; -} - - -/*------------------------------------------------- - get_texel_palette16_bilinear - return a - bilinear filtered texel from a palettized - 16bpp source --------------------------------------------------*/ - -INLINE UINT32 get_texel_palette16_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base; - rgb_t pix00, pix01, pix10, pix11; - INT32 u0, u1, v0, v1; - - u0 = curu >> 16; - u1 = 1; - if (u0 < 0) u0 = u1 = 0; - else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0; - v0 = curv >> 16; - v1 = texture->rowpixels; - if (v0 < 0) v0 = v1 = 0; - else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0; - - texbase += v0 * texture->rowpixels + u0; - - pix00 = texture->palette[texbase[0]]; - pix01 = texture->palette[texbase[u1]]; - pix10 = texture->palette[texbase[v1]]; - pix11 = texture->palette[texbase[u1 + v1]]; - return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); -} - - -/*------------------------------------------------- - get_texel_palette16a_nearest - return the - nearest neighbor texel from a palettized - 16bpp source --------------------------------------------------*/ - -INLINE UINT32 get_texel_palette16a_nearest(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16); - return texture->palette[texbase[0]]; -} - - -/*------------------------------------------------- - get_texel_palette16a_bilinear - return a - bilinear filtered texel from a palettized - 16bpp source --------------------------------------------------*/ - -INLINE UINT32 get_texel_palette16a_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base; - rgb_t pix00, pix01, pix10, pix11; - INT32 u0, u1, v0, v1; - - u0 = curu >> 16; - u1 = 1; - if (u0 < 0) u0 = u1 = 0; - else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0; - v0 = curv >> 16; - v1 = texture->rowpixels; - if (v0 < 0) v0 = v1 = 0; - else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0; - - texbase += v0 * texture->rowpixels + u0; - - pix00 = texture->palette[texbase[0]]; - pix01 = texture->palette[texbase[u1]]; - pix10 = texture->palette[texbase[v1]]; - pix11 = texture->palette[texbase[u1 + v1]]; - return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); -} - - -/*------------------------------------------------- - get_texel_yuy16_nearest - return the - nearest neighbor texel from a 16bpp YCbCr - source (pixel is returned as Cr-Cb-Y --------------------------------------------------*/ - -INLINE UINT32 get_texel_yuy16_nearest(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 17) * 2; - return (texbase[(curu >> 16) & 1] >> 8) | ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); -} - - -/*------------------------------------------------- - get_texel_yuy16_bilinear - return the - nearest neighbor texel from a 16bpp YCbCr - source (pixel is returned as Cr-Cb-Y --------------------------------------------------*/ - -INLINE UINT32 get_texel_yuy16_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT16 *texbase = (const UINT16 *)texture->base; - rgb_t pix00, pix01, pix10, pix11; - INT32 u0, u1, v0, v1; - - u0 = curu >> 16; - u1 = 1; - if (u0 < 0) u0 = u1 = 0; - else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0; - v0 = curv >> 16; - v1 = texture->rowpixels; - if (v0 < 0) v0 = v1 = 0; - else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0; - - texbase += v0 * texture->rowpixels + (u0 & ~1); - - if ((curu & 0x10000) == 0) +private: + // internal structs + struct quad_setup_data { - rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); - pix00 = (texbase[0] >> 8) | cbcr; - pix01 = (texbase[u1] >> 8) | cbcr; - cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16); - pix10 = (texbase[v1 + 0] >> 8) | cbcr; - pix11 = (texbase[v1 + u1] >> 8) | cbcr; + INT32 dudx, dvdx, dudy, dvdy; + INT32 startu, startv; + INT32 startx, starty; + INT32 endx, endy; + }; + + // internal helpers + static inline bool is_opaque(float alpha) { return (alpha >= (_NoDestRead ? 0.5f : 1.0f)); } + static inline bool is_transparent(float alpha) { return (alpha < (_NoDestRead ? 0.5f : 0.0001f)); } + static inline rgb_t apply_intensity(rgb_t color, int intensity) { return MAKE_RGB((RGB_RED(color) * intensity) >> 8, (RGB_GREEN(color) * intensity) >> 8, (RGB_BLUE(color) * intensity) >> 8); } + static inline float round_nearest(float f) { return floor(f + 0.5f); } + + // destination pixels are written based on the values of the template parameters + static inline _PixelType dest_assemble_rgb(UINT32 r, UINT32 g, UINT32 b) { return (r << _DstShiftR) | (g << _DstShiftG) | (b << _DstShiftB); } + static inline _PixelType dest_rgb_to_pixel(UINT32 r, UINT32 g, UINT32 b) { return dest_assemble_rgb(r >> _SrcShiftR, g >> _SrcShiftG, b >> _SrcShiftB); } + + // source 32-bit pixels are in MAME standardized format + static inline UINT32 source32_r(rgb_t pixel) { return (pixel >> (16 + _SrcShiftR)) & (0xff >> _SrcShiftR); } + static inline UINT32 source32_g(rgb_t pixel) { return (pixel >> ( 8 + _SrcShiftG)) & (0xff >> _SrcShiftG); } + static inline UINT32 source32_b(rgb_t pixel) { return (pixel >> ( 0 + _SrcShiftB)) & (0xff >> _SrcShiftB); } + + // destination pixel masks are based on the template parameters as well + static inline UINT32 dest_r(_PixelType pixel) { return (pixel >> _DstShiftR) & (0xff >> _SrcShiftR); } + static inline UINT32 dest_g(_PixelType pixel) { return (pixel >> _DstShiftG) & (0xff >> _SrcShiftG); } + static inline UINT32 dest_b(_PixelType pixel) { return (pixel >> _DstShiftB) & (0xff >> _SrcShiftB); } + + // generic conversion with special optimization for destinations in the standard format + static inline _PixelType source32_to_dest(rgb_t pixel) + { + if (_SrcShiftR == 0 && _SrcShiftG == 0 && _SrcShiftB == 0 && _DstShiftR == 16 && _DstShiftG == 8 && _DstShiftB == 0) + return pixel; + else + return dest_assemble_rgb(source32_r(pixel), source32_g(pixel), source32_b(pixel)); } - else + + + //------------------------------------------------- + // ycc_to_rgb - convert YCC to RGB; the YCC pixel + // contains Y in the LSB, Cb << 8, and Cr << 16 + // This actually a YCbCr conversion, + // details my be found in chapter 6.4 ff of + // http://softwarecommunity.intel.com/isn/downloads/softwareproducts/pdfs/346495.pdf + // The document also contains the constants below as floats. + //------------------------------------------------- + + static inline UINT32 clamp16_shift8(UINT32 x) { - rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); - pix00 = (texbase[1] >> 8) | cbcr; - if (u1 != 0) + return ((INT32(x) < 0) ? 0 : (x > 65535 ? 255: x >> 8)); + } + + static inline UINT32 ycc_to_rgb(UINT32 ycc) + { + // original equations: + // + // C = Y - 16 + // D = Cb - 128 + // E = Cr - 128 + // + // R = clip(( 298 * C + 409 * E + 128) >> 8) + // G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8) + // B = clip(( 298 * C + 516 * D + 128) >> 8) + // + // R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8) + // G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8) + // B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8) + // + // R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) + // G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) + // B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) + // + // R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8) + // G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8) + // B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8) + // + // Now combine constants: + // + // R = clip(( 298 * Y + 409 * Cr - 56992) >> 8) + // G = clip(( 298 * Y - 100 * Cb - 208 * Cr + 34784) >> 8) + // B = clip(( 298 * Y + 516 * Cb - 70688) >> 8) + // + // Define common = 298 * y - 56992. This will save one addition + // + // R = clip(( common + 409 * Cr - 0) >> 8) + // G = clip(( common - 100 * Cb - 208 * Cr + 91776) >> 8) + // B = clip(( common + 516 * Cb - 13696) >> 8) + // + + UINT8 y = ycc; + UINT8 cb = ycc >> 8; + UINT8 cr = ycc >> 16; + + UINT32 common = 298 * y - 56992; + UINT32 r = (common + 409 * cr); + UINT32 g = (common - 100 * cb - 208 * cr + 91776); + UINT32 b = (common + 516 * cb - 13696); + + // Now clamp and shift back + return MAKE_RGB(clamp16_shift8(r), clamp16_shift8(g), clamp16_shift8(b)); + } + + + //------------------------------------------------- + // get_texel_palette16 - return a texel from a + // palettized 16bpp source + //------------------------------------------------- + + static inline UINT32 get_texel_palette16(const render_texinfo &texture, INT32 curu, INT32 curv) + { + if (_BilinearFilter) { - cbcr = ((texbase[2] & 0xff) << 8) | ((texbase[3] & 0xff) << 16); - pix01 = (texbase[2] >> 8) | cbcr; + INT32 u0 = curu >> 16; + INT32 u1 = 1; + if (u0 < 0) u0 = u1 = 0; + else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0; + INT32 v0 = curv >> 16; + INT32 v1 = texture.rowpixels; + if (v0 < 0) v0 = v1 = 0; + else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0; + + const UINT16 *texbase = reinterpret_cast(texture.base); + texbase += v0 * texture.rowpixels + u0; + + rgb_t pix00 = texture.palette[texbase[0]]; + rgb_t pix01 = texture.palette[texbase[u1]]; + rgb_t pix10 = texture.palette[texbase[v1]]; + rgb_t pix11 = texture.palette[texbase[u1 + v1]]; + return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); } else - pix01 = pix00; - cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16); - pix10 = (texbase[v1 + 1] >> 8) | cbcr; - if (u1 != 0) { - cbcr = ((texbase[v1 + 2] & 0xff) << 8) | ((texbase[v1 + 3] & 0xff) << 16); - pix11 = (texbase[v1 + 2] >> 8) | cbcr; + const UINT16 *texbase = reinterpret_cast(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16); + return texture.palette[texbase[0]]; + } + } + + + //------------------------------------------------- + // get_texel_palette16a - return a texel from a + // palettized 16bpp source with alpha + //------------------------------------------------- + + static inline UINT32 get_texel_palette16a(const render_texinfo &texture, INT32 curu, INT32 curv) + { + if (_BilinearFilter) + { + INT32 u0 = curu >> 16; + INT32 u1 = 1; + if (u0 < 0) u0 = u1 = 0; + else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0; + INT32 v0 = curv >> 16; + INT32 v1 = texture.rowpixels; + if (v0 < 0) v0 = v1 = 0; + else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0; + + const UINT16 *texbase = reinterpret_cast(texture.base); + texbase += v0 * texture.rowpixels + u0; + + rgb_t pix00 = texture.palette[texbase[0]]; + rgb_t pix01 = texture.palette[texbase[u1]]; + rgb_t pix10 = texture.palette[texbase[v1]]; + rgb_t pix11 = texture.palette[texbase[u1 + v1]]; + return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); } else - pix11 = pix10; - } - return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); -} - - -/*------------------------------------------------- - get_texel_rgb32_nearest - return the - nearest neighbor texel from a 32bpp RGB source --------------------------------------------------*/ - -INLINE UINT32 get_texel_rgb32_nearest(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16); - return texbase[0]; -} - - -/*------------------------------------------------- - get_texel_rgb32_bilinear - return the - bilinear filtered texel from a 32bpp RGB - source --------------------------------------------------*/ - -INLINE UINT32 get_texel_rgb32_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT32 *texbase = (const UINT32 *)texture->base; - rgb_t pix00, pix01, pix10, pix11; - INT32 u0, u1, v0, v1; - - u0 = curu >> 16; - u1 = 1; - if (u0 < 0) u0 = u1 = 0; - else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0; - v0 = curv >> 16; - v1 = texture->rowpixels; - if (v0 < 0) v0 = v1 = 0; - else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0; - - texbase += v0 * texture->rowpixels + u0; - - pix00 = texbase[0]; - pix01 = texbase[u1]; - pix10 = texbase[v1]; - pix11 = texbase[u1 + v1]; - return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); -} - - -/*------------------------------------------------- - get_texel_argb32_nearest - return the - nearest neighbor texel from a 32bpp ARGB - source --------------------------------------------------*/ - -INLINE UINT32 get_texel_argb32_nearest(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT32 *texbase = (const UINT32 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16); - return texbase[0]; -} - - -/*------------------------------------------------- - get_texel_argb32_bilinear - return the - bilinear filtered texel from a 32bpp ARGB - source --------------------------------------------------*/ - -INLINE UINT32 get_texel_argb32_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv) -{ - const UINT32 *texbase = (const UINT32 *)texture->base; - rgb_t pix00, pix01, pix10, pix11; - INT32 u0, u1, v0, v1; - - u0 = curu >> 16; - u1 = 1; - if (u0 < 0) u0 = u1 = 0; - else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0; - v0 = curv >> 16; - v1 = texture->rowpixels; - if (v0 < 0) v0 = v1 = 0; - else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0; - - texbase += v0 * texture->rowpixels + u0; - - pix00 = texbase[0]; - pix01 = texbase[u1]; - pix10 = texbase[v1]; - pix11 = texbase[u1 + v1]; - return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); -} - - -#endif - - -/*************************************************************************** - MACROS -***************************************************************************/ - -/* source 15-bit pixels are in MAME standardized format */ -#define SOURCE15_R(pix) (((pix) >> (7 + SRCSHIFT_R)) & (0xf8 >> SRCSHIFT_R)) -#define SOURCE15_G(pix) (((pix) >> (2 + SRCSHIFT_G)) & (0xf8 >> SRCSHIFT_G)) -#if (SRCSHIFT_B < 3) -#define SOURCE15_B(pix) (((pix) << (3 - SRCSHIFT_B)) & (0xf8 >> SRCSHIFT_B)) -#else -#define SOURCE15_B(pix) (((pix) >> (SRCSHIFT_B - 3)) & (0xf8 >> SRCSHIFT_B)) -#endif - -/* source 32-bit pixels are in MAME standardized format */ -#define SOURCE32_R(pix) (((pix) >> (16 + SRCSHIFT_R)) & (0xff >> SRCSHIFT_R)) -#define SOURCE32_G(pix) (((pix) >> (8 + SRCSHIFT_G)) & (0xff >> SRCSHIFT_G)) -#define SOURCE32_B(pix) (((pix) >> (0 + SRCSHIFT_B)) & (0xff >> SRCSHIFT_B)) - -/* destination pixels are written based on the values of the macros */ -#define DEST_ASSEMBLE_RGB(r,g,b) (((r) << DSTSHIFT_R) | ((g) << DSTSHIFT_G) | ((b) << DSTSHIFT_B)) -#define DEST_RGB_TO_PIXEL(r,g,b) DEST_ASSEMBLE_RGB((r) >> SRCSHIFT_R, (g) >> SRCSHIFT_G, (b) >> SRCSHIFT_B) - -/* destination pixel masks are based on the macros as well */ -#define DEST_R(pix) (((pix) >> DSTSHIFT_R) & (0xff >> SRCSHIFT_R)) -#define DEST_G(pix) (((pix) >> DSTSHIFT_G) & (0xff >> SRCSHIFT_G)) -#define DEST_B(pix) (((pix) >> DSTSHIFT_B) & (0xff >> SRCSHIFT_B)) - -/* direct 15-bit source to destination pixel conversion */ -#define SOURCE15_TO_DEST(pix) DEST_ASSEMBLE_RGB(SOURCE15_R(pix), SOURCE15_G(pix), SOURCE15_B(pix)) -#ifndef VARIABLE_SHIFT -#if (SRCSHIFT_R == 3) && (SRCSHIFT_G == 3) && (SRCSHIFT_B == 3) && (DSTSHIFT_R == 10) && (DSTSHIFT_G == 5) && (DSTSHIFT_B == 0) -#undef SOURCE15_TO_DEST -#define SOURCE15_TO_DEST(pix) (pix) -#endif -#endif - -/* direct 32-bit source to destination pixel conversion */ -#define SOURCE32_TO_DEST(pix) DEST_ASSEMBLE_RGB(SOURCE32_R(pix), SOURCE32_G(pix), SOURCE32_B(pix)) -#ifndef VARIABLE_SHIFT -#if (SRCSHIFT_R == 0) && (SRCSHIFT_G == 0) && (SRCSHIFT_B == 0) && (DSTSHIFT_R == 16) && (DSTSHIFT_G == 8) && (DSTSHIFT_B == 0) -#undef SOURCE32_TO_DEST -#define SOURCE32_TO_DEST(pix) (pix) -#endif -#endif - -/* texel functions */ -#undef GET_TEXEL -#if BILINEAR_FILTER -#define GET_TEXEL(type) get_texel_##type##_##bilinear -#else -#define GET_TEXEL(type) get_texel_##type##_##nearest -#endif - - - -/*************************************************************************** - LINE RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_aa_pixel - draw an antialiased pixel --------------------------------------------------*/ - -INLINE void FUNC_PREFIX(draw_aa_pixel)(void *dstdata, UINT32 pitch, int x, int y, rgb_t col) -{ - UINT32 dpix, dr, dg, db; - PIXEL_TYPE *dest; - - dest = (PIXEL_TYPE *)dstdata + y * pitch + x; - dpix = NO_DEST_READ ? 0 : *dest; - dr = SOURCE32_R(col) + DEST_R(dpix); - dg = SOURCE32_G(col) + DEST_G(dpix); - db = SOURCE32_B(col) + DEST_B(dpix); - dr = (dr | -(dr >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - dg = (dg | -(dg >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - db = (db | -(db >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(dr, dg, db); -} - - -/*------------------------------------------------- - draw_line - draw a line or point --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_line)(const render_primitive *prim, void *dstdata, INT32 width, INT32 height, UINT32 pitch) -{ - int dx,dy,sx,sy,cx,cy,bwidth; - UINT8 a1; - int x1,x2,y1,y2; - UINT32 col; - int xx,yy; - int beam; - - /* compute the start/end coordinates */ - x1 = (int)(prim->bounds.x0 * 65536.0f); - y1 = (int)(prim->bounds.y0 * 65536.0f); - x2 = (int)(prim->bounds.x1 * 65536.0f); - y2 = (int)(prim->bounds.y1 * 65536.0f); - - /* handle color and intensity */ - col = MAKE_RGB((int)(255.0f * prim->color.r * prim->color.a), (int)(255.0f * prim->color.g * prim->color.a), (int)(255.0f * prim->color.b * prim->color.a)); - - if (PRIMFLAG_GET_ANTIALIAS(prim->flags)) - { - /* build up the cosine table if we haven't yet */ - if (cosine_table[0] == 0) { - int entry; - for (entry = 0; entry <= 2048; entry++) - cosine_table[entry] = (int)((double)(1.0 / cos(atan((double)(entry) / 2048.0))) * 0x10000000 + 0.5); + const UINT16 *texbase = reinterpret_cast(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16); + return texture.palette[texbase[0]]; } + } - beam = prim->width * 65536.0f; - if (beam < 0x00010000) - beam = 0x00010000; - /* draw an anti-aliased line */ - dx = abs(x1 - x2); - dy = abs(y1 - y2); + //------------------------------------------------- + // get_texel_yuy16 - return a texel from a 16bpp + // YCbCr source (pixel is returned as Cr-Cb-Y) + //------------------------------------------------- - if (dx >= dy) + static inline UINT32 get_texel_yuy16(const render_texinfo &texture, INT32 curu, INT32 curv) + { + if (_BilinearFilter) { - sx = ((x1 <= x2) ? 1 : -1); - sy = (dy == 0) ? 0 : div_32x32_shift(y2 - y1, dx, 16); - if (sy < 0) - dy--; - x1 >>= 16; - xx = x2 >> 16; - bwidth = mul_32x32_hi(beam << 4, cosine_table[abs(sy) >> 5]); - y1 -= bwidth >> 1; /* start back half the diameter */ - for (;;) + INT32 u0 = curu >> 16; + INT32 u1 = 1; + if (u0 < 0) u0 = u1 = 0; + else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0; + INT32 v0 = curv >> 16; + INT32 v1 = texture.rowpixels; + if (v0 < 0) v0 = v1 = 0; + else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0; + + const UINT16 *texbase = reinterpret_cast(texture.base); + texbase += v0 * texture.rowpixels + (u0 & ~1); + + rgb_t pix00, pix01, pix10, pix11; + if ((curu & 0x10000) == 0) { - if (x1 >= 0 && x1 < width) + rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); + pix00 = (texbase[0] >> 8) | cbcr; + pix01 = (texbase[u1] >> 8) | cbcr; + cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16); + pix10 = (texbase[v1 + 0] >> 8) | cbcr; + pix11 = (texbase[v1 + u1] >> 8) | cbcr; + } + else + { + rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); + pix00 = (texbase[1] >> 8) | cbcr; + if (u1 != 0) { - dx = bwidth; /* init diameter of beam */ - dy = y1 >> 16; - if (dy >= 0 && dy < height) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, x1, dy, Tinten(0xff & (~y1 >> 8), col)); - dy++; - dx -= 0x10000 - (0xffff & y1); /* take off amount plotted */ - a1 = (dx >> 8) & 0xff; /* calc remainder pixel */ - dx >>= 16; /* adjust to pixel (solid) count */ - while (dx--) /* plot rest of pixels */ + cbcr = ((texbase[2] & 0xff) << 8) | ((texbase[3] & 0xff) << 16); + pix01 = (texbase[2] >> 8) | cbcr; + } + else + pix01 = pix00; + cbcr = ((texbase[v1 + 0] & 0xff) << 8) | ((texbase[v1 + 1] & 0xff) << 16); + pix10 = (texbase[v1 + 1] >> 8) | cbcr; + if (u1 != 0) + { + cbcr = ((texbase[v1 + 2] & 0xff) << 8) | ((texbase[v1 + 3] & 0xff) << 16); + pix11 = (texbase[v1 + 2] >> 8) | cbcr; + } + else + pix11 = pix10; + } + return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); + } + else + { + const UINT16 *texbase = reinterpret_cast(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 17) * 2; + return (texbase[(curu >> 16) & 1] >> 8) | ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); + } + } + + + //------------------------------------------------- + // get_texel_rgb32 - return a texel from a 32bpp + // RGB source + //------------------------------------------------- + + static inline UINT32 get_texel_rgb32(const render_texinfo &texture, INT32 curu, INT32 curv) + { + if (_BilinearFilter) + { + INT32 u0 = curu >> 16; + INT32 u1 = 1; + if (u0 < 0) u0 = u1 = 0; + else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0; + INT32 v0 = curv >> 16; + INT32 v1 = texture.rowpixels; + if (v0 < 0) v0 = v1 = 0; + else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0; + + const UINT32 *texbase = reinterpret_cast(texture.base); + texbase += v0 * texture.rowpixels + u0; + + rgb_t pix00 = texbase[0]; + rgb_t pix01 = texbase[u1]; + rgb_t pix10 = texbase[v1]; + rgb_t pix11 = texbase[u1 + v1]; + return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); + } + else + { + const UINT32 *texbase = reinterpret_cast(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16); + return texbase[0]; + } + } + + + //------------------------------------------------- + // get_texel_argb32 - return a texel from a 32bpp + // ARGB source + //------------------------------------------------- + + static inline UINT32 get_texel_argb32(const render_texinfo &texture, INT32 curu, INT32 curv) + { + if (_BilinearFilter) + { + INT32 u0 = curu >> 16; + INT32 u1 = 1; + if (u0 < 0) u0 = u1 = 0; + else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0; + INT32 v0 = curv >> 16; + INT32 v1 = texture.rowpixels; + if (v0 < 0) v0 = v1 = 0; + else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0; + + const UINT32 *texbase = reinterpret_cast(texture.base); + texbase += v0 * texture.rowpixels + u0; + + rgb_t pix00 = texbase[0]; + rgb_t pix01 = texbase[u1]; + rgb_t pix10 = texbase[v1]; + rgb_t pix11 = texbase[u1 + v1]; + return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); + } + else + { + const UINT32 *texbase = reinterpret_cast(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16); + return texbase[0]; + } + } + + + //------------------------------------------------- + // draw_aa_pixel - draw an antialiased pixel + //------------------------------------------------- + + static inline void draw_aa_pixel(_PixelType *dstdata, UINT32 pitch, int x, int y, rgb_t col) + { + _PixelType *dest = dstdata + y * pitch + x; + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 dr = source32_r(col) + dest_r(dpix); + UINT32 dg = source32_g(col) + dest_g(dpix); + UINT32 db = source32_b(col) + dest_b(dpix); + dr = (dr | -(dr >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + dg = (dg | -(dg >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + db = (db | -(db >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(dr, dg, db); + } + + + //------------------------------------------------- + // draw_line - draw a line or point + //------------------------------------------------- + + static void draw_line(const render_primitive &prim, _PixelType *dstdata, INT32 width, INT32 height, UINT32 pitch) + { + // internal tables + static UINT32 s_cosine_table[2049]; + + // compute the start/end coordinates + int x1 = int(prim.bounds.x0 * 65536.0f); + int y1 = int(prim.bounds.y0 * 65536.0f); + int x2 = int(prim.bounds.x1 * 65536.0f); + int y2 = int(prim.bounds.y1 * 65536.0f); + + // handle color and intensity + UINT32 col = MAKE_RGB(int(255.0f * prim.color.r * prim.color.a), int(255.0f * prim.color.g * prim.color.a), int(255.0f * prim.color.b * prim.color.a)); + + if (PRIMFLAG_GET_ANTIALIAS(prim.flags)) + { + // build up the cosine table if we haven't yet + if (s_cosine_table[0] == 0) + for (int entry = 0; entry <= 2048; entry++) + s_cosine_table[entry] = int(double(1.0 / cos(atan(double(entry) / 2048.0))) * 0x10000000 + 0.5); + + int beam = prim.width * 65536.0f; + if (beam < 0x00010000) + beam = 0x00010000; + + // draw an anti-aliased line + int dx = abs(x1 - x2); + int dy = abs(y1 - y2); + + if (dx >= dy) + { + int sx = ((x1 <= x2) ? 1 : -1); + int sy = (dy == 0) ? 0 : div_32x32_shift(y2 - y1, dx, 16); + if (sy < 0) + dy--; + x1 >>= 16; + int xx = x2 >> 16; + int bwidth = mul_32x32_hi(beam << 4, s_cosine_table[abs(sy) >> 5]); + y1 -= bwidth >> 1; // start back half the diameter + for (;;) + { + if (x1 >= 0 && x1 < width) { + dx = bwidth; // init diameter of beam + dy = y1 >> 16; if (dy >= 0 && dy < height) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, x1, dy, col); + draw_aa_pixel(dstdata, pitch, x1, dy, apply_intensity(0xff & (~y1 >> 8), col)); dy++; + dx -= 0x10000 - (0xffff & y1); // take off amount plotted + UINT8 a1 = (dx >> 8) & 0xff; // calc remainder pixel + dx >>= 16; // adjust to pixel (solid) count + while (dx--) // plot rest of pixels + { + if (dy >= 0 && dy < height) + draw_aa_pixel(dstdata, pitch, x1, dy, col); + dy++; + } + if (dy >= 0 && dy < height) + draw_aa_pixel(dstdata, pitch, x1, dy, apply_intensity(a1,col)); } - if (dy >= 0 && dy < height) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, x1, dy, Tinten(a1,col)); - } - if (x1 == xx) break; - x1 += sx; - y1 += sy; - } - } - else - { - sy = ((y1 <= y2) ? 1: -1); - sx = (dx == 0) ? 0 : div_32x32_shift(x2 - x1, dy, 16); - if (sx < 0) - dx--; - y1 >>= 16; - yy = y2 >> 16; - bwidth = mul_32x32_hi(beam << 4,cosine_table[abs(sx) >> 5]); - x1 -= bwidth >> 1; /* start back half the width */ - for (;;) - { - if (y1 >= 0 && y1 < height) - { - dy = bwidth; /* calc diameter of beam */ - dx = x1 >> 16; - if (dx >= 0 && dx < width) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, dx, y1, Tinten(0xff & (~x1 >> 8), col)); - dx++; - dy -= 0x10000 - (0xffff & x1); /* take off amount plotted */ - a1 = (dy >> 8) & 0xff; /* remainder pixel */ - dy >>= 16; /* adjust to pixel (solid) count */ - while (dy--) /* plot rest of pixels */ - { - if (dx >= 0 && dx < width) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, dx, y1, col); - dx++; - } - if (dx >= 0 && dx < width) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, dx, y1, Tinten(a1, col)); - } - if (y1 == yy) break; - y1 += sy; - x1 += sx; - } - } - } - else /* use good old Bresenham for non-antialiasing 980317 BW */ - { - x1 = (x1 + 0x8000) >> 16; - y1 = (y1 + 0x8000) >> 16; - x2 = (x2 + 0x8000) >> 16; - y2 = (y2 + 0x8000) >> 16; - - dx = abs(x1 - x2); - dy = abs(y1 - y2); - sx = (x1 <= x2) ? 1 : -1; - sy = (y1 <= y2) ? 1 : -1; - cx = dx / 2; - cy = dy / 2; - - if (dx >= dy) - { - for (;;) - { - if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, x1, y1, col); - if (x1 == x2) break; - x1 += sx; - cx -= dy; - if (cx < 0) - { - y1 += sy; - cx += dx; - } - } - } - else - { - for (;;) - { - if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) - FUNC_PREFIX(draw_aa_pixel)(dstdata, pitch, x1, y1, col); - if (y1 == y2) break; - y1 += sy; - cy -= dx; - if (cy < 0) - { + if (x1 == xx) break; x1 += sx; - cy += dy; + y1 += sy; } } - } - } -} - - - -/*************************************************************************** - RECT RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_rect - draw a solid rectangle --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_rect)(const render_primitive *prim, void *dstdata, INT32 width, INT32 height, UINT32 pitch) -{ - render_bounds fpos = prim->bounds; - INT32 startx, starty, endx, endy; - INT32 x, y; - - assert(fpos.x0 <= fpos.x1); - assert(fpos.y0 <= fpos.y1); - - /* clamp to integers */ - startx = round_nearest(fpos.x0); - starty = round_nearest(fpos.y0); - endx = round_nearest(fpos.x1); - endy = round_nearest(fpos.y1); - - /* ensure we fit */ - if (startx < 0) startx = 0; - if (startx >= width) startx = width; - if (endx < 0) endx = 0; - if (endx >= width) endx = width; - if (starty < 0) starty = 0; - if (starty >= height) starty = height; - if (endy < 0) endy = 0; - if (endy >= height) endy = height; - - /* bail if nothing left */ - if (fpos.x0 > fpos.x1 || fpos.y0 > fpos.y1) - return; - - /* only support alpha and "none" blendmodes */ - assert(PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_NONE || - PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_ALPHA); - - /* fast case: no alpha */ - if (PRIMFLAG_GET_BLENDMODE(prim->flags) == BLENDMODE_NONE || IS_OPAQUE(prim->color.a)) - { - UINT32 r = (UINT32)(256.0f * prim->color.r); - UINT32 g = (UINT32)(256.0f * prim->color.g); - UINT32 b = (UINT32)(256.0f * prim->color.b); - UINT32 pix; - - /* clamp R,G,B to 0-256 range */ - if (r > 0xff) { if ((INT32)r < 0) r = 0; else r = 0xff; } - if (g > 0xff) { if ((INT32)g < 0) g = 0; else g = 0xff; } - if (b > 0xff) { if ((INT32)b < 0) b = 0; else b = 0xff; } - pix = DEST_RGB_TO_PIXEL(r, g, b); - - /* loop over rows */ - for (y = starty; y < endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + startx; - - /* loop over cols */ - for (x = startx; x < endx; x++) - *dest++ = pix; - } - } - - /* alpha and/or coloring case */ - else if (!IS_TRANSPARENT(prim->color.a)) - { - UINT32 rmask = DEST_RGB_TO_PIXEL(0xff,0x00,0x00); - UINT32 gmask = DEST_RGB_TO_PIXEL(0x00,0xff,0x00); - UINT32 bmask = DEST_RGB_TO_PIXEL(0x00,0x00,0xff); - UINT32 r = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 g = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 b = (UINT32)(256.0f * prim->color.b * prim->color.a); - UINT32 inva = (UINT32)(256.0f * (1.0f - prim->color.a)); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (r > 0xff) { if ((INT32)r < 0) r = 0; else r = 0xff; } - if (g > 0xff) { if ((INT32)g < 0) g = 0; else g = 0xff; } - if (b > 0xff) { if ((INT32)b < 0) b = 0; else b = 0xff; } - if (inva > 0x100) { if ((INT32)inva < 0) inva = 0; else inva = 0x100; } - - /* pre-shift the RGBA pieces */ - r = DEST_RGB_TO_PIXEL(r, 0, 0) << 8; - g = DEST_RGB_TO_PIXEL(0, g, 0) << 8; - b = DEST_RGB_TO_PIXEL(0, 0, b) << 8; - - /* loop over rows */ - for (y = starty; y < endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + startx; - - /* loop over cols */ - for (x = startx; x < endx; x++) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 dr = (r + ((dpix & rmask) * inva)) & (rmask << 8); - UINT32 dg = (g + ((dpix & gmask) * inva)) & (gmask << 8); - UINT32 db = (b + ((dpix & bmask) * inva)) & (bmask << 8); - *dest++ = (dr | dg | db) >> 8; - } - } - } -} - - - -/*************************************************************************** - 16-BIT PALETTE RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_quad_palette16_none - perform - rasterization of a 16bpp palettized texture --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* ensure all parameters are valid */ - assert(prim->texture.palette != NULL); - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv); - *dest++ = SOURCE32_TO_DEST(pix); - curu += dudx; - curv += dvdx; - } - } - } - - /* coloring-only case */ - else if (IS_OPAQUE(prim->color.a)) - { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - - /* clamp R,G,B to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv); - UINT32 r = (SOURCE32_R(pix) * sr) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - - /* alpha and/or coloring case */ - else if (!IS_TRANSPARENT(prim->color.a)) - { - UINT32 sr = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 sg = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 sb = (UINT32)(256.0f * prim->color.b * prim->color.a); - UINT32 invsa = (UINT32)(256.0f * (1.0f - prim->color.a)); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (invsa > 0x100) { if ((INT32)invsa < 0) invsa = 0; else invsa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb + DEST_B(dpix) * invsa) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } -} - - -/*------------------------------------------------- - draw_quad_palette16_add - perform - rasterization of a 16bpp palettized texture --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* ensure all parameters are valid */ - assert(prim->texture.palette != NULL); - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv); - if ((pix & 0xffffff) != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = SOURCE32_R(pix) + DEST_R(dpix); - UINT32 g = SOURCE32_G(pix) + DEST_G(dpix); - UINT32 b = SOURCE32_B(pix) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - } - - /* alpha and/or coloring case */ - else - { - UINT32 sr = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 sg = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 sb = (UINT32)(256.0f * prim->color.b * prim->color.a); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv); - if ((pix & 0xffffff) != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((SOURCE32_R(pix) * sr) >> 8) + DEST_R(dpix); - UINT32 g = ((SOURCE32_G(pix) * sg) >> 8) + DEST_G(dpix); - UINT32 b = ((SOURCE32_B(pix) * sb) >> 8) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } -} - - - -/*************************************************************************** - 16-BIT ALPHA PALETTE RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_quad_palettea16_alpha - perform - rasterization using standard alpha blending --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* ensure all parameters are valid */ - assert(prim->texture.palette != NULL); - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16a)(&prim->texture, curu, curv); - UINT32 ta = pix >> 24; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 invta = 0x100 - ta; - UINT32 r = (SOURCE32_R(pix) * ta + DEST_R(dpix) * invta) >> 8; - UINT32 g = (SOURCE32_G(pix) * ta + DEST_G(dpix) * invta) >> 8; - UINT32 b = (SOURCE32_B(pix) * ta + DEST_B(dpix) * invta) >> 8; - - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - } - - /* alpha and/or coloring case */ - else - { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - UINT32 sa = (UINT32)(256.0f * prim->color.a); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (sa > 0x100) { if ((INT32)sa < 0) sa = 0; else sa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(palette16a)(&prim->texture, curu, curv); - UINT32 ta = (pix >> 24) * sa; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 invsta = (0x10000 - ta) << 8; - UINT32 r = (SOURCE32_R(pix) * sr * ta + DEST_R(dpix) * invsta) >> 24; - UINT32 g = (SOURCE32_G(pix) * sg * ta + DEST_G(dpix) * invsta) >> 24; - UINT32 b = (SOURCE32_B(pix) * sb * ta + DEST_B(dpix) * invsta) >> 24; - - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - } -} - - - -/*************************************************************************** - 16-BIT YUY RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_quad_yuy16_none - perform - rasterization of a 16bpp YUY image --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - *dest++ = SOURCE32_TO_DEST(pix); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ else { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + int sy = ((y1 <= y2) ? 1: -1); + int sx = (dx == 0) ? 0 : div_32x32_shift(x2 - x1, dy, 16); + if (sx < 0) + dx--; + y1 >>= 16; + int yy = y2 >> 16; + int bwidth = mul_32x32_hi(beam << 4,s_cosine_table[abs(sx) >> 5]); + x1 -= bwidth >> 1; // start back half the width + for (;;) { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - *dest++ = SOURCE32_TO_DEST(pix); - curu += dudx; - curv += dvdx; + if (y1 >= 0 && y1 < height) + { + dy = bwidth; // calc diameter of beam + dx = x1 >> 16; + if (dx >= 0 && dx < width) + draw_aa_pixel(dstdata, pitch, dx, y1, apply_intensity(0xff & (~x1 >> 8), col)); + dx++; + dy -= 0x10000 - (0xffff & x1); // take off amount plotted + UINT8 a1 = (dy >> 8) & 0xff; // remainder pixel + dy >>= 16; // adjust to pixel (solid) count + while (dy--) // plot rest of pixels + { + if (dx >= 0 && dx < width) + draw_aa_pixel(dstdata, pitch, dx, y1, col); + dx++; + } + if (dx >= 0 && dx < width) + draw_aa_pixel(dstdata, pitch, dx, y1, apply_intensity(a1, col)); + } + if (y1 == yy) break; + y1 += sy; + x1 += sx; } } } - } - - /* coloring-only case */ - else if (IS_OPAQUE(prim->color.a)) - { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - - /* clamp R,G,B to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + else // use good old Bresenham for non-antialiasing 980317 BW { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; + x1 = (x1 + 0x8000) >> 16; + y1 = (y1 + 0x8000) >> 16; + x2 = (x2 + 0x8000) >> 16; + y2 = (y2 + 0x8000) >> 16; - /* no lookup case */ - if (palbase == NULL) + int dx = abs(x1 - x2); + int dy = abs(y1 - y2); + int sx = (x1 <= x2) ? 1 : -1; + int sy = (y1 <= y2) ? 1 : -1; + int cx = dx / 2; + int cy = dy / 2; + + if (dx >= dy) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + for (;;) { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - UINT32 r = (SOURCE32_R(pix) * sr) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; + if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) + draw_aa_pixel(dstdata, pitch, x1, y1, col); + if (x1 == x2) break; + x1 += sx; + cx -= dy; + if (cx < 0) + { + y1 += sy; + cx += dx; + } } } - - /* lookup case */ else { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + for (;;) { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - UINT32 r = (SOURCE32_R(pix) * sr) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb) >> 8; + if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) + draw_aa_pixel(dstdata, pitch, x1, y1, col); + if (y1 == y2) break; + y1 += sy; + cy -= dx; + if (cy < 0) + { + x1 += sx; + cy += dy; + } + } + } + } + } - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); + + + //************************************************************************** + // RECT RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // draw_rect - draw a solid rectangle + //------------------------------------------------- + + static void draw_rect(const render_primitive &prim, _PixelType *dstdata, INT32 width, INT32 height, UINT32 pitch) + { + render_bounds fpos = prim.bounds; + assert(fpos.x0 <= fpos.x1); + assert(fpos.y0 <= fpos.y1); + + // clamp to integers + INT32 startx = round_nearest(fpos.x0); + INT32 starty = round_nearest(fpos.y0); + INT32 endx = round_nearest(fpos.x1); + INT32 endy = round_nearest(fpos.y1); + + // ensure we fit + if (startx < 0) startx = 0; + if (startx >= width) startx = width; + if (endx < 0) endx = 0; + if (endx >= width) endx = width; + if (starty < 0) starty = 0; + if (starty >= height) starty = height; + if (endy < 0) endy = 0; + if (endy >= height) endy = height; + + // bail if nothing left + if (fpos.x0 > fpos.x1 || fpos.y0 > fpos.y1) + return; + + // only support alpha and "none" blendmodes + assert(PRIMFLAG_GET_BLENDMODE(prim.flags) == BLENDMODE_NONE || + PRIMFLAG_GET_BLENDMODE(prim.flags) == BLENDMODE_ALPHA); + + // fast case: no alpha + if (PRIMFLAG_GET_BLENDMODE(prim.flags) == BLENDMODE_NONE || is_opaque(prim.color.a)) + { + UINT32 r = UINT32(256.0f * prim.color.r); + UINT32 g = UINT32(256.0f * prim.color.g); + UINT32 b = UINT32(256.0f * prim.color.b); + UINT32 pix; + + // clamp R,G,B to 0-256 range + if (r > 0xff) { if (INT32(r) < 0) r = 0; else r = 0xff; } + if (g > 0xff) { if (INT32(g) < 0) g = 0; else g = 0xff; } + if (b > 0xff) { if (INT32(b) < 0) b = 0; else b = 0xff; } + pix = dest_rgb_to_pixel(r, g, b); + + // loop over rows + for (INT32 y = starty; y < endy; y++) + { + _PixelType *dest = dstdata + y * pitch + startx; + + // loop over cols + for (INT32 x = startx; x < endx; x++) + *dest++ = pix; + } + } + + // alpha and/or coloring case + else if (!is_transparent(prim.color.a)) + { + UINT32 rmask = dest_rgb_to_pixel(0xff,0x00,0x00); + UINT32 gmask = dest_rgb_to_pixel(0x00,0xff,0x00); + UINT32 bmask = dest_rgb_to_pixel(0x00,0x00,0xff); + UINT32 r = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 g = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 b = UINT32(256.0f * prim.color.b * prim.color.a); + UINT32 inva = UINT32(256.0f * (1.0f - prim.color.a)); + + // clamp R,G,B and inverse A to 0-256 range + if (r > 0xff) { if (INT32(r) < 0) r = 0; else r = 0xff; } + if (g > 0xff) { if (INT32(g) < 0) g = 0; else g = 0xff; } + if (b > 0xff) { if (INT32(b) < 0) b = 0; else b = 0xff; } + if (inva > 0x100) { if (INT32(inva) < 0) inva = 0; else inva = 0x100; } + + // pre-shift the RGBA pieces + r = dest_rgb_to_pixel(r, 0, 0) << 8; + g = dest_rgb_to_pixel(0, g, 0) << 8; + b = dest_rgb_to_pixel(0, 0, b) << 8; + + // loop over rows + for (INT32 y = starty; y < endy; y++) + { + _PixelType *dest = dstdata + y * pitch + startx; + + // loop over cols + for (INT32 x = startx; x < endx; x++) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 dr = (r + ((dpix & rmask) * inva)) & (rmask << 8); + UINT32 dg = (g + ((dpix & gmask) * inva)) & (gmask << 8); + UINT32 db = (b + ((dpix & bmask) * inva)) & (bmask << 8); + *dest++ = (dr | dg | db) >> 8; + } + } + } + } + + + //************************************************************************** + // 16-BIT PALETTE RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // draw_quad_palette16_none - perform + // rasterization of a 16bpp palettized texture + //------------------------------------------------- + + static void draw_quad_palette16_none(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) + { + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; + + // ensure all parameters are valid + assert(prim.texture.palette != NULL); + + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) + { + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_palette16(prim.texture, curu, curv); + *dest++ = source32_to_dest(pix); + curu += dudx; + curv += dvdx; + } + } + } + + // coloring-only case + else if (is_opaque(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + + // clamp R,G,B to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_palette16(prim.texture, curu, curv); + UINT32 r = (source32_r(pix) * sr) >> 8; + UINT32 g = (source32_g(pix) * sg) >> 8; + UINT32 b = (source32_b(pix) * sb) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + + // alpha and/or coloring case + else if (!is_transparent(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 sg = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 sb = UINT32(256.0f * prim.color.b * prim.color.a); + UINT32 invsa = UINT32(256.0f * (1.0f - prim.color.a)); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (invsa > 0x100) { if (INT32(invsa) < 0) invsa = 0; else invsa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_palette16(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8; + UINT32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8; + UINT32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); curu += dudx; curv += dvdx; } @@ -1189,446 +744,138 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void } } - /* alpha and/or coloring case */ - else if (!IS_TRANSPARENT(prim->color.a)) + + //------------------------------------------------- + // draw_quad_palette16_add - perform + // rasterization of a 16bpp palettized texture + //------------------------------------------------- + + static void draw_quad_palette16_add(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) { - UINT32 sr = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 sg = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 sb = (UINT32)(256.0f * prim->color.b * prim->color.a); - UINT32 invsa = (UINT32)(256.0f * (1.0f - prim->color.a)); + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (invsa > 0x100) { if ((INT32)invsa < 0) invsa = 0; else invsa = 0x100; } + // ensure all parameters are valid + assert(prim.texture.palette != NULL); - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb + DEST_B(dpix) * invsa) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(&prim->texture, curu, curv)); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb + DEST_B(dpix) * invsa) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); + UINT32 pix = get_texel_palette16(prim.texture, curu, curv); + if ((pix & 0xffffff) != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = source32_r(pix) + dest_r(dpix); + UINT32 g = source32_g(pix) + dest_g(dpix); + UINT32 b = source32_b(pix) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(r, g, b); + } + dest++; curu += dudx; curv += dvdx; } } } - } -} - - -/*************************************************************************** - 32-BIT RGB QUAD RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_quad_rgb32 - perform rasterization of - a 32bpp RGB texture --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + // alpha and/or coloring case + else { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; + UINT32 sr = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 sg = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 sb = UINT32(256.0f * prim.color.b * prim.color.a); - /* no lookup case */ - if (palbase == NULL) + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - *dest++ = SOURCE32_TO_DEST(pix); - curu += dudx; - curv += dvdx; - } - } + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - UINT32 r = palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R; - UINT32 g = palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G; - UINT32 b = palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; + UINT32 pix = get_texel_palette16(prim.texture, curu, curv); + if ((pix & 0xffffff) != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((source32_r(pix) * sr) >> 8) + dest_r(dpix); + UINT32 g = ((source32_g(pix) * sg) >> 8) + dest_g(dpix); + UINT32 b = ((source32_b(pix) * sb) >> 8) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } } } } } - /* coloring-only case */ - else if (IS_OPAQUE(prim->color.a)) + + + //************************************************************************** + // 16-BIT ALPHA PALETTE RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // draw_quad_palettea16_alpha - perform + // rasterization using standard alpha blending + //------------------------------------------------- + + static void draw_quad_palettea16_alpha(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; - /* clamp R,G,B to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } + // ensure all parameters are valid + assert(prim.texture.palette != NULL); - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - UINT32 r = (SOURCE32_R(pix) * sr) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - UINT32 r = (palbase[(pix >> 16) & 0xff] * sr) >> (8 + SRCSHIFT_R); - UINT32 g = (palbase[(pix >> 8) & 0xff] * sg) >> (8 + SRCSHIFT_G); - UINT32 b = (palbase[(pix >> 0) & 0xff] * sb) >> (8 + SRCSHIFT_B); - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } - - /* alpha and/or coloring case */ - else if (!IS_TRANSPARENT(prim->color.a)) - { - UINT32 sr = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 sg = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 sb = (UINT32)(256.0f * prim->color.b * prim->color.a); - UINT32 invsa = (UINT32)(256.0f * (1.0f - prim->color.a)); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (invsa > 0x100) { if ((INT32)invsa < 0) invsa = 0; else invsa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * sr + DEST_R(dpix) * invsa) >> 8; - UINT32 g = (SOURCE32_G(pix) * sg + DEST_G(dpix) * invsa) >> 8; - UINT32 b = (SOURCE32_B(pix) * sb + DEST_B(dpix) * invsa) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(rgb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R) * sr + DEST_R(dpix) * invsa) >> 8; - UINT32 g = ((palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G) * sg + DEST_G(dpix) * invsa) >> 8; - UINT32 b = ((palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B) * sb + DEST_B(dpix) * invsa) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } -} - - -/*------------------------------------------------- - draw_quad_rgb32_add - perform - rasterization by using RGB add --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_rgb32_add)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* simply can't do this without reading from the dest */ - if (NO_DEST_READ) - return; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = SOURCE32_R(pix) + DEST_R(dpix); - UINT32 g = SOURCE32_G(pix) + DEST_G(dpix); - UINT32 b = SOURCE32_B(pix) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R) + DEST_R(dpix); - UINT32 g = (palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G) + DEST_G(dpix); - UINT32 b = (palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } - - /* alpha and/or coloring case */ - else - { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - UINT32 sa = (UINT32)(256.0f * prim->color.a); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (sa > 0x100) { if ((INT32)sa < 0) sa = 0; else sa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((SOURCE32_R(pix) * sr * sa) >> 16) + DEST_R(dpix); - UINT32 g = ((SOURCE32_G(pix) * sg * sa) >> 16) + DEST_G(dpix); - UINT32 b = ((SOURCE32_B(pix) * sb * sa) >> 16) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((palbase[(pix >> 16) & 0xff] * sr * sa) >> (16 + SRCSHIFT_R)) + DEST_R(dpix); - UINT32 g = ((palbase[(pix >> 8) & 0xff] * sr * sa) >> (16 + SRCSHIFT_R)) + DEST_G(dpix); - UINT32 b = ((palbase[(pix >> 0) & 0xff] * sr * sa) >> (16 + SRCSHIFT_R)) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } -} - - - -/*************************************************************************** - 32-BIT ARGB QUAD RASTERIZERS -***************************************************************************/ - -/*------------------------------------------------- - draw_quad_argb32_alpha - perform - rasterization using standard alpha blending --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); + UINT32 pix = get_texel_palette16a(prim.texture, curu, curv); UINT32 ta = pix >> 24; if (ta != 0) { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; + UINT32 dpix = _NoDestRead ? 0 : *dest; UINT32 invta = 0x100 - ta; - UINT32 r = (SOURCE32_R(pix) * ta + DEST_R(dpix) * invta) >> 8; - UINT32 g = (SOURCE32_G(pix) * ta + DEST_G(dpix) * invta) >> 8; - UINT32 b = (SOURCE32_B(pix) * ta + DEST_B(dpix) * invta) >> 8; + UINT32 r = (source32_r(pix) * ta + dest_r(dpix) * invta) >> 8; + UINT32 g = (source32_g(pix) * ta + dest_g(dpix) * invta) >> 8; + UINT32 b = (source32_b(pix) * ta + dest_b(dpix) * invta) >> 8; - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = pix >> 24; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 invta = 0x100 - ta; - UINT32 r = ((palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R) * ta + DEST_R(dpix) * invta) >> 8; - UINT32 g = ((palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G) * ta + DEST_G(dpix) * invta) >> 8; - UINT32 b = ((palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B) * ta + DEST_B(dpix) * invta) >> 8; - - *dest = DEST_ASSEMBLE_RGB(r, g, b); + *dest = dest_assemble_rgb(r, g, b); } dest++; curu += dudx; @@ -1636,272 +883,42 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo } } } - } - /* alpha and/or coloring case */ - else - { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - UINT32 sa = (UINT32)(256.0f * prim->color.a); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (sa > 0x100) { if ((INT32)sa < 0) sa = 0; else sa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + // alpha and/or coloring case + else { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + UINT32 sa = UINT32(256.0f * prim.color.a); - /* no lookup case */ - if (palbase == NULL) + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (sa > 0x100) { if (INT32(sa) < 0) sa = 0; else sa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); + UINT32 pix = get_texel_palette16a(prim.texture, curu, curv); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; + UINT32 dpix = _NoDestRead ? 0 : *dest; UINT32 invsta = (0x10000 - ta) << 8; - UINT32 r = (SOURCE32_R(pix) * sr * ta + DEST_R(dpix) * invsta) >> 24; - UINT32 g = (SOURCE32_G(pix) * sg * ta + DEST_G(dpix) * invsta) >> 24; - UINT32 b = (SOURCE32_B(pix) * sb * ta + DEST_B(dpix) * invsta) >> 24; + UINT32 r = (source32_r(pix) * sr * ta + dest_r(dpix) * invsta) >> 24; + UINT32 g = (source32_g(pix) * sg * ta + dest_g(dpix) * invsta) >> 24; + UINT32 b = (source32_b(pix) * sb * ta + dest_b(dpix) * invsta) >> 24; - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = (pix >> 24) * sa; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 invsta = (0x10000 - ta) << 8; - UINT32 r = ((palbase[(pix >> 16) & 0xff] >> SRCSHIFT_R) * sr * ta + DEST_R(dpix) * invsta) >> 24; - UINT32 g = ((palbase[(pix >> 8) & 0xff] >> SRCSHIFT_G) * sg * ta + DEST_G(dpix) * invsta) >> 24; - UINT32 b = ((palbase[(pix >> 0) & 0xff] >> SRCSHIFT_B) * sb * ta + DEST_B(dpix) * invsta) >> 24; - - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - } - } -} - - -/*------------------------------------------------- - draw_quad_argb32_multiply - perform - rasterization using RGB multiply --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* simply can't do this without reading from the dest */ - if (NO_DEST_READ) - return; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * DEST_R(dpix)) >> (8 - SRCSHIFT_R); - UINT32 g = (SOURCE32_G(pix) * DEST_G(dpix)) >> (8 - SRCSHIFT_G); - UINT32 b = (SOURCE32_B(pix) * DEST_B(dpix)) >> (8 - SRCSHIFT_B); - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (palbase[(pix >> 16) & 0xff] * DEST_R(dpix)) >> 8; - UINT32 g = (palbase[(pix >> 8) & 0xff] * DEST_G(dpix)) >> 8; - UINT32 b = (palbase[(pix >> 0) & 0xff] * DEST_B(dpix)) >> 8; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } - - /* alpha and/or coloring case */ - else - { - UINT32 sr = (UINT32)(256.0f * prim->color.r * prim->color.a); - UINT32 sg = (UINT32)(256.0f * prim->color.g * prim->color.a); - UINT32 sb = (UINT32)(256.0f * prim->color.b * prim->color.a); - - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (SOURCE32_R(pix) * sr * DEST_R(dpix)) >> (16 - SRCSHIFT_R); - UINT32 g = (SOURCE32_G(pix) * sg * DEST_G(dpix)) >> (16 - SRCSHIFT_G); - UINT32 b = (SOURCE32_B(pix) * sb * DEST_B(dpix)) >> (16 - SRCSHIFT_B); - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = (palbase[(pix >> 16) & 0xff] * sr * DEST_R(dpix)) >> 16; - UINT32 g = (palbase[(pix >> 8) & 0xff] * sg * DEST_G(dpix)) >> 16; - UINT32 b = (palbase[(pix >> 0) & 0xff] * sb * DEST_B(dpix)) >> 16; - - *dest++ = DEST_ASSEMBLE_RGB(r, g, b); - curu += dudx; - curv += dvdx; - } - } - } - } -} - - -/*------------------------------------------------- - draw_quad_argb32_add - perform - rasterization by using RGB add --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void *dstdata, UINT32 pitch, quad_setup_data *setup) -{ - const rgb_t *palbase = prim->texture.palette; - INT32 dudx = setup->dudx; - INT32 dvdx = setup->dvdx; - INT32 endx = setup->endx; - INT32 x, y; - - /* simply can't do this without reading from the dest */ - if (NO_DEST_READ) - return; - - /* fast case: no coloring, no alpha */ - if (prim->color.r >= 1.0f && prim->color.g >= 1.0f && prim->color.b >= 1.0f && IS_OPAQUE(prim->color.a)) - { - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) - { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = pix >> 24; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((SOURCE32_R(pix) * ta) >> 8) + DEST_R(dpix); - UINT32 g = ((SOURCE32_G(pix) * ta) >> 8) + DEST_G(dpix); - UINT32 b = ((SOURCE32_B(pix) * ta) >> 8) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(r, g, b); - } - dest++; - curu += dudx; - curv += dvdx; - } - } - - /* lookup case */ - else - { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) - { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = pix >> 24; - if (ta != 0) - { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((palbase[(pix >> 16) & 0xff] * ta) >> (8 + SRCSHIFT_R)) + DEST_R(dpix); - UINT32 g = ((palbase[(pix >> 8) & 0xff] * ta) >> (8 + SRCSHIFT_G)) + DEST_G(dpix); - UINT32 b = ((palbase[(pix >> 0) & 0xff] * ta) >> (8 + SRCSHIFT_B)) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(r, g, b); + *dest = dest_assemble_rgb(r, g, b); } dest++; curu += dudx; @@ -1911,259 +928,1043 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void } } - /* alpha and/or coloring case */ - else + + + //************************************************************************** + // 16-BIT YUY RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // draw_quad_yuy16_none - perform + // rasterization of a 16bpp YUY image + //------------------------------------------------- + + static void draw_quad_yuy16_none(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) { - UINT32 sr = (UINT32)(256.0f * prim->color.r); - UINT32 sg = (UINT32)(256.0f * prim->color.g); - UINT32 sb = (UINT32)(256.0f * prim->color.b); - UINT32 sa = (UINT32)(256.0f * prim->color.a); + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; - /* clamp R,G,B and inverse A to 0-256 range */ - if (sr > 0x100) { if ((INT32)sr < 0) sr = 0; else sr = 0x100; } - if (sg > 0x100) { if ((INT32)sg < 0) sg = 0; else sg = 0x100; } - if (sb > 0x100) { if ((INT32)sb < 0) sb = 0; else sb = 0x100; } - if (sa > 0x100) { if ((INT32)sa < 0) sa = 0; else sa = 0x100; } - - /* loop over rows */ - for (y = setup->starty; y < setup->endy; y++) + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) { - PIXEL_TYPE *dest = (PIXEL_TYPE *)dstdata + y * pitch + setup->startx; - INT32 curu = setup->startu + (y - setup->starty) * setup->dudy; - INT32 curv = setup->startv + (y - setup->starty) * setup->dvdy; - - /* no lookup case */ - if (palbase == NULL) + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = (pix >> 24) * sa; - if (ta != 0) + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((SOURCE32_R(pix) * sr * ta) >> 24) + DEST_R(dpix); - UINT32 g = ((SOURCE32_G(pix) * sg * ta) >> 24) + DEST_G(dpix); - UINT32 b = ((SOURCE32_B(pix) * sb * ta) >> 24) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(r, g, b); + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + *dest++ = source32_to_dest(pix); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + *dest++ = source32_to_dest(pix); + curu += dudx; + curv += dvdx; } - dest++; - curu += dudx; - curv += dvdx; } } + } - /* lookup case */ - else + // coloring-only case + else if (is_opaque(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + + // clamp R,G,B to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) { - /* loop over cols */ - for (x = setup->startx; x < endx; x++) + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) { - UINT32 pix = GET_TEXEL(argb32)(&prim->texture, curu, curv); - UINT32 ta = (pix >> 24) * sa; - if (ta != 0) + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) { - UINT32 dpix = NO_DEST_READ ? 0 : *dest; - UINT32 r = ((palbase[(pix >> 16) & 0xff] * sr * ta) >> (24 + SRCSHIFT_R)) + DEST_R(dpix); - UINT32 g = ((palbase[(pix >> 8) & 0xff] * sr * ta) >> (24 + SRCSHIFT_R)) + DEST_G(dpix); - UINT32 b = ((palbase[(pix >> 0) & 0xff] * sr * ta) >> (24 + SRCSHIFT_R)) + DEST_B(dpix); - r = (r | -(r >> (8 - SRCSHIFT_R))) & (0xff >> SRCSHIFT_R); - g = (g | -(g >> (8 - SRCSHIFT_G))) & (0xff >> SRCSHIFT_G); - b = (b | -(b >> (8 - SRCSHIFT_B))) & (0xff >> SRCSHIFT_B); - *dest = DEST_ASSEMBLE_RGB(r, g, b); + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + UINT32 r = (source32_r(pix) * sr) >> 8; + UINT32 g = (source32_g(pix) * sg) >> 8; + UINT32 b = (source32_b(pix) * sb) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + UINT32 r = (source32_r(pix) * sr) >> 8; + UINT32 g = (source32_g(pix) * sg) >> 8; + UINT32 b = (source32_b(pix) * sb) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else if (!is_transparent(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 sg = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 sb = UINT32(256.0f * prim.color.b * prim.color.a); + UINT32 invsa = UINT32(256.0f * (1.0f - prim.color.a)); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (invsa > 0x100) { if (INT32(invsa) < 0) invsa = 0; else invsa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8; + UINT32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8; + UINT32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv)); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8; + UINT32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8; + UINT32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; } - dest++; - curu += dudx; - curv += dvdx; } } } } -} + //************************************************************************** + // 32-BIT RGB QUAD RASTERIZERS + //************************************************************************** -/*************************************************************************** - CORE QUAD RASTERIZERS -***************************************************************************/ + //------------------------------------------------- + // draw_quad_rgb32 - perform rasterization of + // a 32bpp RGB texture + //------------------------------------------------- -/*------------------------------------------------- - setup_and_draw_textured_quad - perform setup - and then dispatch to a texture-mode-specific - drawing routine --------------------------------------------------*/ - -static void FUNC_PREFIX(setup_and_draw_textured_quad)(const render_primitive *prim, void *dstdata, INT32 width, INT32 height, UINT32 pitch) -{ - float fdudx, fdvdx, fdudy, fdvdy; - quad_setup_data setup; - - assert(prim->bounds.x0 <= prim->bounds.x1); - assert(prim->bounds.y0 <= prim->bounds.y1); - - /* determine U/V deltas */ - fdudx = (prim->texcoords.tr.u - prim->texcoords.tl.u) / (prim->bounds.x1 - prim->bounds.x0); - fdvdx = (prim->texcoords.tr.v - prim->texcoords.tl.v) / (prim->bounds.x1 - prim->bounds.x0); - fdudy = (prim->texcoords.bl.u - prim->texcoords.tl.u) / (prim->bounds.y1 - prim->bounds.y0); - fdvdy = (prim->texcoords.bl.v - prim->texcoords.tl.v) / (prim->bounds.y1 - prim->bounds.y0); - - /* clamp to integers */ - setup.startx = round_nearest(prim->bounds.x0); - setup.starty = round_nearest(prim->bounds.y0); - setup.endx = round_nearest(prim->bounds.x1); - setup.endy = round_nearest(prim->bounds.y1); - - /* ensure we fit */ - if (setup.startx < 0) setup.startx = 0; - if (setup.startx >= width) setup.startx = width; - if (setup.endx < 0) setup.endx = 0; - if (setup.endx >= width) setup.endx = width; - if (setup.starty < 0) setup.starty = 0; - if (setup.starty >= height) setup.starty = height; - if (setup.endy < 0) setup.endy = 0; - if (setup.endy >= height) setup.endy = height; - - /* compute start and delta U,V coordinates now */ - setup.dudx = round_nearest(65536.0f * (float)prim->texture.width * fdudx); - setup.dvdx = round_nearest(65536.0f * (float)prim->texture.height * fdvdx); - setup.dudy = round_nearest(65536.0f * (float)prim->texture.width * fdudy); - setup.dvdy = round_nearest(65536.0f * (float)prim->texture.height * fdvdy); - setup.startu = round_nearest(65536.0f * (float)prim->texture.width * prim->texcoords.tl.u); - setup.startv = round_nearest(65536.0f * (float)prim->texture.height * prim->texcoords.tl.v); - - /* advance U/V to the middle of the first texel */ - setup.startu += (setup.dudx + setup.dudy) / 2; - setup.startv += (setup.dvdx + setup.dvdy) / 2; - - /* if we're bilinear filtering, we need to offset u/v by half a texel */ - if (BILINEAR_FILTER) + static void draw_quad_rgb32(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) { - setup.startu -= 0x8000; - setup.startv -= 0x8000; - } + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; - /* render based on the texture coordinates */ - switch (prim->flags & (PRIMFLAG_TEXFORMAT_MASK | PRIMFLAG_BLENDMODE_MASK)) - { - case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): - case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): - FUNC_PREFIX(draw_quad_palette16_none)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): - FUNC_PREFIX(draw_quad_palette16_add)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTEA16) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): - FUNC_PREFIX(draw_quad_palettea16_alpha)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): - FUNC_PREFIX(draw_quad_yuy16_none)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): - case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): - case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): - FUNC_PREFIX(draw_quad_rgb32)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): - FUNC_PREFIX(draw_quad_rgb32_add)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): - FUNC_PREFIX(draw_quad_argb32_alpha)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY): - FUNC_PREFIX(draw_quad_argb32_multiply)(prim, dstdata, pitch, &setup); - break; - - case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): - FUNC_PREFIX(draw_quad_argb32_add)(prim, dstdata, pitch, &setup); - break; - - default: - fatalerror("Unknown texformat(%d)/blendmode(%d) combo\n", PRIMFLAG_GET_TEXFORMAT(prim->flags), PRIMFLAG_GET_BLENDMODE(prim->flags)); - break; - } -} - - - -/*************************************************************************** - PRIMARY ENTRY POINT -***************************************************************************/ - -/*------------------------------------------------- - draw_primitives - draw a series of primitives - using a software rasterizer --------------------------------------------------*/ - -static void FUNC_PREFIX(draw_primitives)(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch) -{ - const render_primitive *prim; - - /* loop over the list and render each element */ - for (prim = primlist.first(); prim != NULL; prim = prim->next()) - switch (prim->type) + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) { - case render_primitive::LINE: - FUNC_PREFIX(draw_line)(prim, dstdata, width, height, pitch); + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + *dest++ = source32_to_dest(pix); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + UINT32 r = palbase[(pix >> 16) & 0xff] >> _SrcShiftR; + UINT32 g = palbase[(pix >> 8) & 0xff] >> _SrcShiftG; + UINT32 b = palbase[(pix >> 0) & 0xff] >> _SrcShiftB; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + + // coloring-only case + else if (is_opaque(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + + // clamp R,G,B to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + UINT32 r = (source32_r(pix) * sr) >> 8; + UINT32 g = (source32_g(pix) * sg) >> 8; + UINT32 b = (source32_b(pix) * sb) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + UINT32 r = (palbase[(pix >> 16) & 0xff] * sr) >> (8 + _SrcShiftR); + UINT32 g = (palbase[(pix >> 8) & 0xff] * sg) >> (8 + _SrcShiftG); + UINT32 b = (palbase[(pix >> 0) & 0xff] * sb) >> (8 + _SrcShiftB); + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else if (!is_transparent(prim.color.a)) + { + UINT32 sr = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 sg = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 sb = UINT32(256.0f * prim.color.b * prim.color.a); + UINT32 invsa = UINT32(256.0f * (1.0f - prim.color.a)); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (invsa > 0x100) { if (INT32(invsa) < 0) invsa = 0; else invsa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8; + UINT32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8; + UINT32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_rgb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * sr + dest_r(dpix) * invsa) >> 8; + UINT32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * sg + dest_g(dpix) * invsa) >> 8; + UINT32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * sb + dest_b(dpix) * invsa) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + } + + + //------------------------------------------------- + // draw_quad_rgb32_add - perform + // rasterization by using RGB add + //------------------------------------------------- + + static void draw_quad_rgb32_add(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) + { + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; + + // simply can't do this without reading from the dest + if (_NoDestRead) + return; + + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) + { + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = source32_r(pix) + dest_r(dpix); + UINT32 g = source32_g(pix) + dest_g(dpix); + UINT32 b = source32_b(pix) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (palbase[(pix >> 16) & 0xff] >> _SrcShiftR) + dest_r(dpix); + UINT32 g = (palbase[(pix >> 8) & 0xff] >> _SrcShiftG) + dest_g(dpix); + UINT32 b = (palbase[(pix >> 0) & 0xff] >> _SrcShiftB) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + UINT32 sa = UINT32(256.0f * prim.color.a); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (sa > 0x100) { if (INT32(sa) < 0) sa = 0; else sa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((source32_r(pix) * sr * sa) >> 16) + dest_r(dpix); + UINT32 g = ((source32_g(pix) * sg * sa) >> 16) + dest_g(dpix); + UINT32 b = ((source32_b(pix) * sb * sa) >> 16) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((palbase[(pix >> 16) & 0xff] * sr * sa) >> (16 + _SrcShiftR)) + dest_r(dpix); + UINT32 g = ((palbase[(pix >> 8) & 0xff] * sr * sa) >> (16 + _SrcShiftR)) + dest_g(dpix); + UINT32 b = ((palbase[(pix >> 0) & 0xff] * sr * sa) >> (16 + _SrcShiftR)) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + } + + + + //************************************************************************** + // 32-BIT ARGB QUAD RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // draw_quad_argb32_alpha - perform + // rasterization using standard alpha blending + //------------------------------------------------- + + static void draw_quad_argb32_alpha(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) + { + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; + + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) + { + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = pix >> 24; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 invta = 0x100 - ta; + UINT32 r = (source32_r(pix) * ta + dest_r(dpix) * invta) >> 8; + UINT32 g = (source32_g(pix) * ta + dest_g(dpix) * invta) >> 8; + UINT32 b = (source32_b(pix) * ta + dest_b(dpix) * invta) >> 8; + + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = pix >> 24; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 invta = 0x100 - ta; + UINT32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * ta + dest_r(dpix) * invta) >> 8; + UINT32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * ta + dest_g(dpix) * invta) >> 8; + UINT32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * ta + dest_b(dpix) * invta) >> 8; + + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + UINT32 sa = UINT32(256.0f * prim.color.a); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (sa > 0x100) { if (INT32(sa) < 0) sa = 0; else sa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = (pix >> 24) * sa; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 invsta = (0x10000 - ta) << 8; + UINT32 r = (source32_r(pix) * sr * ta + dest_r(dpix) * invsta) >> 24; + UINT32 g = (source32_g(pix) * sg * ta + dest_g(dpix) * invsta) >> 24; + UINT32 b = (source32_b(pix) * sb * ta + dest_b(dpix) * invsta) >> 24; + + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = (pix >> 24) * sa; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 invsta = (0x10000 - ta) << 8; + UINT32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * sr * ta + dest_r(dpix) * invsta) >> 24; + UINT32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * sg * ta + dest_g(dpix) * invsta) >> 24; + UINT32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * sb * ta + dest_b(dpix) * invsta) >> 24; + + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + } + } + } + + + //------------------------------------------------- + // draw_quad_argb32_multiply - perform + // rasterization using RGB multiply + //------------------------------------------------- + + static void draw_quad_argb32_multiply(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) + { + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; + + // simply can't do this without reading from the dest + if (_NoDestRead) + return; + + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) + { + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * dest_r(dpix)) >> (8 - _SrcShiftR); + UINT32 g = (source32_g(pix) * dest_g(dpix)) >> (8 - _SrcShiftG); + UINT32 b = (source32_b(pix) * dest_b(dpix)) >> (8 - _SrcShiftB); + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (palbase[(pix >> 16) & 0xff] * dest_r(dpix)) >> 8; + UINT32 g = (palbase[(pix >> 8) & 0xff] * dest_g(dpix)) >> 8; + UINT32 b = (palbase[(pix >> 0) & 0xff] * dest_b(dpix)) >> 8; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else + { + UINT32 sr = UINT32(256.0f * prim.color.r * prim.color.a); + UINT32 sg = UINT32(256.0f * prim.color.g * prim.color.a); + UINT32 sb = UINT32(256.0f * prim.color.b * prim.color.a); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (source32_r(pix) * sr * dest_r(dpix)) >> (16 - _SrcShiftR); + UINT32 g = (source32_g(pix) * sg * dest_g(dpix)) >> (16 - _SrcShiftG); + UINT32 b = (source32_b(pix) * sb * dest_b(dpix)) >> (16 - _SrcShiftB); + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = (palbase[(pix >> 16) & 0xff] * sr * dest_r(dpix)) >> 16; + UINT32 g = (palbase[(pix >> 8) & 0xff] * sg * dest_g(dpix)) >> 16; + UINT32 b = (palbase[(pix >> 0) & 0xff] * sb * dest_b(dpix)) >> 16; + + *dest++ = dest_assemble_rgb(r, g, b); + curu += dudx; + curv += dvdx; + } + } + } + } + } + + + //------------------------------------------------- + // draw_quad_argb32_add - perform + // rasterization by using RGB add + //------------------------------------------------- + + static void draw_quad_argb32_add(const render_primitive &prim, _PixelType *dstdata, UINT32 pitch, quad_setup_data &setup) + { + const rgb_t *palbase = prim.texture.palette; + INT32 dudx = setup.dudx; + INT32 dvdx = setup.dvdx; + INT32 endx = setup.endx; + + // simply can't do this without reading from the dest + if (_NoDestRead) + return; + + // fast case: no coloring, no alpha + if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a)) + { + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = pix >> 24; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((source32_r(pix) * ta) >> 8) + dest_r(dpix); + UINT32 g = ((source32_g(pix) * ta) >> 8) + dest_g(dpix); + UINT32 b = ((source32_b(pix) * ta) >> 8) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = pix >> 24; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((palbase[(pix >> 16) & 0xff] * ta) >> (8 + _SrcShiftR)) + dest_r(dpix); + UINT32 g = ((palbase[(pix >> 8) & 0xff] * ta) >> (8 + _SrcShiftG)) + dest_g(dpix); + UINT32 b = ((palbase[(pix >> 0) & 0xff] * ta) >> (8 + _SrcShiftB)) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + } + } + + // alpha and/or coloring case + else + { + UINT32 sr = UINT32(256.0f * prim.color.r); + UINT32 sg = UINT32(256.0f * prim.color.g); + UINT32 sb = UINT32(256.0f * prim.color.b); + UINT32 sa = UINT32(256.0f * prim.color.a); + + // clamp R,G,B and inverse A to 0-256 range + if (sr > 0x100) { if (INT32(sr) < 0) sr = 0; else sr = 0x100; } + if (sg > 0x100) { if (INT32(sg) < 0) sg = 0; else sg = 0x100; } + if (sb > 0x100) { if (INT32(sb) < 0) sb = 0; else sb = 0x100; } + if (sa > 0x100) { if (INT32(sa) < 0) sa = 0; else sa = 0x100; } + + // loop over rows + for (INT32 y = setup.starty; y < setup.endy; y++) + { + _PixelType *dest = dstdata + y * pitch + setup.startx; + INT32 curu = setup.startu + (y - setup.starty) * setup.dudy; + INT32 curv = setup.startv + (y - setup.starty) * setup.dvdy; + + // no lookup case + if (palbase == NULL) + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = (pix >> 24) * sa; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((source32_r(pix) * sr * ta) >> 24) + dest_r(dpix); + UINT32 g = ((source32_g(pix) * sg * ta) >> 24) + dest_g(dpix); + UINT32 b = ((source32_b(pix) * sb * ta) >> 24) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + + // lookup case + else + { + // loop over cols + for (INT32 x = setup.startx; x < endx; x++) + { + UINT32 pix = get_texel_argb32(prim.texture, curu, curv); + UINT32 ta = (pix >> 24) * sa; + if (ta != 0) + { + UINT32 dpix = _NoDestRead ? 0 : *dest; + UINT32 r = ((palbase[(pix >> 16) & 0xff] * sr * ta) >> (24 + _SrcShiftR)) + dest_r(dpix); + UINT32 g = ((palbase[(pix >> 8) & 0xff] * sr * ta) >> (24 + _SrcShiftR)) + dest_g(dpix); + UINT32 b = ((palbase[(pix >> 0) & 0xff] * sr * ta) >> (24 + _SrcShiftR)) + dest_b(dpix); + r = (r | -(r >> (8 - _SrcShiftR))) & (0xff >> _SrcShiftR); + g = (g | -(g >> (8 - _SrcShiftG))) & (0xff >> _SrcShiftG); + b = (b | -(b >> (8 - _SrcShiftB))) & (0xff >> _SrcShiftB); + *dest = dest_assemble_rgb(r, g, b); + } + dest++; + curu += dudx; + curv += dvdx; + } + } + } + } + } + + + //************************************************************************** + // CORE QUAD RASTERIZERS + //************************************************************************** + + //------------------------------------------------- + // setup_and_draw_textured_quad - perform setup + // and then dispatch to a texture-mode-specific + // drawing routine + //------------------------------------------------- + + static void setup_and_draw_textured_quad(const render_primitive &prim, _PixelType *dstdata, INT32 width, INT32 height, UINT32 pitch) + { + assert(prim.bounds.x0 <= prim.bounds.x1); + assert(prim.bounds.y0 <= prim.bounds.y1); + + // determine U/V deltas + float fdudx = (prim.texcoords.tr.u - prim.texcoords.tl.u) / (prim.bounds.x1 - prim.bounds.x0); + float fdvdx = (prim.texcoords.tr.v - prim.texcoords.tl.v) / (prim.bounds.x1 - prim.bounds.x0); + float fdudy = (prim.texcoords.bl.u - prim.texcoords.tl.u) / (prim.bounds.y1 - prim.bounds.y0); + float fdvdy = (prim.texcoords.bl.v - prim.texcoords.tl.v) / (prim.bounds.y1 - prim.bounds.y0); + + // clamp to integers + quad_setup_data setup; + setup.startx = round_nearest(prim.bounds.x0); + setup.starty = round_nearest(prim.bounds.y0); + setup.endx = round_nearest(prim.bounds.x1); + setup.endy = round_nearest(prim.bounds.y1); + + // ensure we fit + if (setup.startx < 0) setup.startx = 0; + if (setup.startx >= width) setup.startx = width; + if (setup.endx < 0) setup.endx = 0; + if (setup.endx >= width) setup.endx = width; + if (setup.starty < 0) setup.starty = 0; + if (setup.starty >= height) setup.starty = height; + if (setup.endy < 0) setup.endy = 0; + if (setup.endy >= height) setup.endy = height; + + // compute start and delta U,V coordinates now + setup.dudx = round_nearest(65536.0f * float(prim.texture.width) * fdudx); + setup.dvdx = round_nearest(65536.0f * float(prim.texture.height) * fdvdx); + setup.dudy = round_nearest(65536.0f * float(prim.texture.width) * fdudy); + setup.dvdy = round_nearest(65536.0f * float(prim.texture.height) * fdvdy); + setup.startu = round_nearest(65536.0f * float(prim.texture.width) * prim.texcoords.tl.u); + setup.startv = round_nearest(65536.0f * float(prim.texture.height) * prim.texcoords.tl.v); + + // advance U/V to the middle of the first texel + setup.startu += (setup.dudx + setup.dudy) / 2; + setup.startv += (setup.dvdx + setup.dvdy) / 2; + + // if we're bilinear filtering, we need to offset u/v by half a texel + if (_BilinearFilter) + { + setup.startu -= 0x8000; + setup.startv -= 0x8000; + } + + // render based on the texture coordinates + switch (prim.flags & (PRIMFLAG_TEXFORMAT_MASK | PRIMFLAG_BLENDMODE_MASK)) + { + case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): + case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): + draw_quad_palette16_none(prim, dstdata, pitch, setup); break; - case render_primitive::QUAD: - if (!prim->texture.base) - FUNC_PREFIX(draw_rect)(prim, dstdata, width, height, pitch); - else - FUNC_PREFIX(setup_and_draw_textured_quad)(prim, dstdata, width, height, pitch); + case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTE16) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): + draw_quad_palette16_add(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_PALETTEA16) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): + draw_quad_palettea16_alpha(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_YUY16) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): + draw_quad_yuy16_none(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): + case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): + case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_NONE): + draw_quad_rgb32(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): + draw_quad_rgb32_add(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA): + draw_quad_argb32_alpha(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY): + draw_quad_argb32_multiply(prim, dstdata, pitch, setup); + break; + + case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD): + draw_quad_argb32_add(prim, dstdata, pitch, setup); break; default: - throw emu_fatalerror("Unexpected render_primitive type"); + fatalerror("Unknown texformat(%d)/blendmode(%d) combo\n", PRIMFLAG_GET_TEXFORMAT(prim.flags), PRIMFLAG_GET_BLENDMODE(prim.flags)); + break; } -} + } + //************************************************************************** + // PRIMARY ENTRY POINT + //************************************************************************** -/*************************************************************************** - MACRO UNDOING -***************************************************************************/ + //------------------------------------------------- + // draw_primitives - draw a series of primitives + // using a software rasterizer + //------------------------------------------------- -#undef SOURCE15_R -#undef SOURCE15_G -#undef SOURCE15_B +public: + static void draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch) + { + // loop over the list and render each element + for (const render_primitive *prim = primlist.first(); prim != NULL; prim = prim->next()) + switch (prim->type) + { + case render_primitive::LINE: + draw_line(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch); + break; -#undef SOURCE32_R -#undef SOURCE32_G -#undef SOURCE32_B + case render_primitive::QUAD: + if (!prim->texture.base) + draw_rect(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch); + else + setup_and_draw_textured_quad(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch); + break; -#undef DEST_ASSEMBLE_RGB -#undef DEST_RGB_TO_PIXEL - -#undef DEST_R -#undef DEST_G -#undef DEST_B - -#undef SOURCE15_TO_DEST -#undef SOURCE32_TO_DEST - -#undef FUNC_PREFIX -#undef PIXEL_TYPE - -#undef SRCSHIFT_R -#undef SRCSHIFT_G -#undef SRCSHIFT_B - -#undef DSTSHIFT_R -#undef DSTSHIFT_G -#undef DSTSHIFT_B - -#undef NO_DEST_READ - -#undef VARIABLE_SHIFT + default: + throw emu_fatalerror("Unexpected render_primitive type"); + } + } +}; diff --git a/src/emu/video.c b/src/emu/video.c index 2408f5e4109..a4f9d066401 100644 --- a/src/emu/video.c +++ b/src/emu/video.c @@ -45,6 +45,7 @@ #include "ui.h" #include "aviio.h" #include "crsshair.h" +#include "rendersw.c" #include "snap.lh" @@ -81,15 +82,6 @@ const UINT8 video_manager::s_skiptable[FRAMESKIP_LEVELS][FRAMESKIP_LEVELS] = -//************************************************************************** -// FUNCTION PROTOTYPES -//************************************************************************** - -// software rendering -static void rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); - - - //************************************************************************** // VIDEO MANAGER //************************************************************************** @@ -1076,7 +1068,7 @@ void video_manager::create_snapshot_bitmap(screen_device *screen) // render the screen there render_primitive_list &primlist = m_snap_target->get_primitives(); primlist.acquire_lock(); - rgb888_draw_primitives(primlist, &m_snap_bitmap.pix32(0), width, height, m_snap_bitmap.rowpixels()); + software_renderer::draw_primitives(primlist, &m_snap_bitmap.pix32(0), width, height, m_snap_bitmap.rowpixels()); primlist.release_lock(); } @@ -1299,21 +1291,3 @@ bool video_assert_out_of_range_pixels(running_machine &machine, bitmap_ind16 &bi #endif return false; } - - - -//************************************************************************** -// SOFTWARE RENDERING -//************************************************************************** - -#define FUNC_PREFIX(x) rgb888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 16 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 0 -#define BILINEAR_FILTER 1 - -#include "rendersw.c" diff --git a/src/osd/sdl/drawsdl.c b/src/osd/sdl/drawsdl.c index 9118f411848..8fa25bdd148 100644 --- a/src/osd/sdl/drawsdl.c +++ b/src/osd/sdl/drawsdl.c @@ -16,6 +16,7 @@ // MAME headers #include "emu.h" #include "ui.h" +#include "rendersw.c" // standard SDL headers #include "sdlinc.h" @@ -115,13 +116,6 @@ static int drawsdl_xy_to_render_target(sdl_window_info *window, int x, int y, in static void setup_texture(sdl_window_info *window, int tempwidth, int tempheight); #endif -// soft rendering -static void drawsdl_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_bgr888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_bgra888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_rgb565_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawsdl_rgb555_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); - // YUV overlays static void drawsdl_yuv_init(sdl_info *sdl); @@ -810,23 +804,23 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) switch (rmask) { case 0x0000ff00: - drawsdl_bgra888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer::draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x00ff0000: - drawsdl_rgb888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer::draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0x000000ff: - drawsdl_bgr888_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); + software_renderer::draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 4); break; case 0xf800: - drawsdl_rgb565_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); + software_renderer::draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); break; case 0x7c00: - drawsdl_rgb555_draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); + software_renderer::draw_primitives(*window->primlist, surfptr, mamewidth, mameheight, pitch / 2); break; default: @@ -838,7 +832,7 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) { assert (sdl->yuv_bitmap != NULL); assert (surfptr != NULL); - drawsdl_rgb555_draw_primitives(*window->primlist, sdl->yuv_bitmap, sdl->hw_scale_width, sdl->hw_scale_height, sdl->hw_scale_width); + software_renderer::draw_primitives(*window->primlist, sdl->yuv_bitmap, sdl->hw_scale_width, sdl->hw_scale_height, sdl->hw_scale_width); sm->yuv_blit((UINT16 *)sdl->yuv_bitmap, sdl, surfptr, pitch); } @@ -879,66 +873,6 @@ static int drawsdl_window_draw(sdl_window_info *window, UINT32 dc, int update) #endif return 0; } - -//============================================================ -// SOFTWARE RENDERING -//============================================================ - -#define FUNC_PREFIX(x) drawsdl_rgb888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 16 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawsdl_bgr888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 0 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 16 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawsdl_bgra888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 8 -#define DSTSHIFT_G 16 -#define DSTSHIFT_B 24 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawsdl_rgb565_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 2 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 11 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawsdl_rgb555_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 3 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 10 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - //============================================================ // YUV Blitting //============================================================ diff --git a/src/osd/windows/drawdd.c b/src/osd/windows/drawdd.c index dfab66a6830..f4d41101402 100644 --- a/src/osd/windows/drawdd.c +++ b/src/osd/windows/drawdd.c @@ -51,6 +51,7 @@ #include "render.h" #include "rendutil.h" #include "options.h" +#include "rendersw.c" // MAMEOS headers #include "winmain.h" @@ -59,24 +60,6 @@ -//============================================================ -// DEBUGGING -//============================================================ - - - -//============================================================ -// CONSTANTS -//============================================================ - - - -//============================================================ -// MACROS -//============================================================ - - - //============================================================ // TYPE DEFINITIONS //============================================================ @@ -200,16 +183,6 @@ static int config_adapter_mode(win_window_info *window); static void get_adapter_for_monitor(dd_info *dd, win_monitor_info *monitor); static void pick_best_mode(win_window_info *window); -// rendering -static void drawdd_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_bgr888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb565_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb555_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb888_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_bgr888_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb565_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); -static void drawdd_rgb555_nr_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); - //============================================================ @@ -407,10 +380,10 @@ static int drawdd_window_draw(win_window_info *window, HDC dc, int update) // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { - case 0x00ff0000: drawdd_rgb888_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0x000000ff: drawdd_bgr888_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0xf800: drawdd_rgb565_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; - case 0x7c00: drawdd_rgb555_draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x00ff0000: software_renderer::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x000000ff: software_renderer::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0xf800: software_renderer::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; + case 0x7c00: software_renderer::draw_primitives(*window->primlist, dd->membuffer, dd->blitwidth, dd->blitheight, dd->blitwidth); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; @@ -443,10 +416,10 @@ static int drawdd_window_draw(win_window_info *window, HDC dc, int update) // based on the target format, use one of our standard renderers switch (dd->blitdesc.ddpfPixelFormat.dwRBitMask) { - case 0x00ff0000: drawdd_rgb888_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; - case 0x000000ff: drawdd_bgr888_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; - case 0xf800: drawdd_rgb565_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; - case 0x7c00: drawdd_rgb555_nr_draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; + case 0x00ff0000: software_renderer::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; + case 0x000000ff: software_renderer::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 4); break; + case 0xf800: software_renderer::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; + case 0x7c00: software_renderer::draw_primitives(*window->primlist, dd->blitdesc.lpSurface, dd->blitwidth, dd->blitheight, dd->blitdesc.lPitch / 2); break; default: mame_printf_verbose("DirectDraw: Unknown target mode: R=%08X G=%08X B=%08X\n", (int)dd->blitdesc.ddpfPixelFormat.dwRBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwGBitMask, (int)dd->blitdesc.ddpfPixelFormat.dwBBitMask); break; @@ -1359,107 +1332,3 @@ static void pick_best_mode(win_window_info *window) if (result != DD_OK) mame_printf_verbose("DirectDraw: Error %08X during EnumDisplayModes call\n", (int)result); mame_printf_verbose("DirectDraw: Mode selected = %4dx%4d@%3dHz\n", dd->width, dd->height, dd->refresh); } - - - -//============================================================ -// SOFTWARE RENDERING -//============================================================ - -#define FUNC_PREFIX(x) drawdd_rgb888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 16 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_bgr888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 0 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 16 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_rgb565_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 2 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 11 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_rgb555_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 3 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 10 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 - -#include "rendersw.c" - - - -//============================================================ -// SOFTWARE RENDERING -- NO READING VARIANTS -//============================================================ - -#define FUNC_PREFIX(x) drawdd_rgb888_nr_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 16 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 0 -#define NO_DEST_READ 1 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_bgr888_nr_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 0 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 16 -#define NO_DEST_READ 1 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_rgb565_nr_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 2 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 11 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 -#define NO_DEST_READ 1 - -#include "rendersw.c" - -#define FUNC_PREFIX(x) drawdd_rgb555_nr_##x -#define PIXEL_TYPE UINT16 -#define SRCSHIFT_R 3 -#define SRCSHIFT_G 3 -#define SRCSHIFT_B 3 -#define DSTSHIFT_R 10 -#define DSTSHIFT_G 5 -#define DSTSHIFT_B 0 -#define NO_DEST_READ 1 - -#include "rendersw.c" diff --git a/src/osd/windows/drawgdi.c b/src/osd/windows/drawgdi.c index 2be9b026684..e353e48fc9d 100644 --- a/src/osd/windows/drawgdi.c +++ b/src/osd/windows/drawgdi.c @@ -45,6 +45,7 @@ // MAME headers #include "emu.h" +#include "rendersw.c" // MAMEOS headers #include "window.h" @@ -78,9 +79,6 @@ static void drawgdi_window_destroy(win_window_info *window); static render_primitive_list *drawgdi_window_get_primitives(win_window_info *window); static int drawgdi_window_draw(win_window_info *window, HDC dc, int update); -// rendering -static void drawgdi_rgb888_draw_primitives(const render_primitive_list &primlist, void *dstdata, UINT32 width, UINT32 height, UINT32 pitch); - //============================================================ @@ -216,7 +214,7 @@ static int drawgdi_window_draw(win_window_info *window, HDC dc, int update) // draw the primitives to the bitmap window->primlist->acquire_lock(); - drawgdi_rgb888_draw_primitives(*window->primlist, gdi->bmdata, width, height, pitch); + software_renderer::draw_primitives(*window->primlist, gdi->bmdata, width, height, pitch); window->primlist->release_lock(); // fill in bitmap-specific info @@ -230,20 +228,3 @@ static int drawgdi_window_draw(win_window_info *window, HDC dc, int update) gdi->bmdata, &gdi->bminfo, DIB_RGB_COLORS, SRCCOPY); return 0; } - - - -//============================================================ -// SOFTWARE RENDERING -//============================================================ - -#define FUNC_PREFIX(x) drawgdi_rgb888_##x -#define PIXEL_TYPE UINT32 -#define SRCSHIFT_R 0 -#define SRCSHIFT_G 0 -#define SRCSHIFT_B 0 -#define DSTSHIFT_R 16 -#define DSTSHIFT_G 8 -#define DSTSHIFT_B 0 - -#include "rendersw.c"