diff options
author | 2008-06-12 19:14:18 +0000 | |
---|---|---|
committer | 2008-06-12 19:14:18 +0000 | |
commit | a701f8537ede746d1cf15dc5fd09d0719a19dc23 (patch) | |
tree | edfd55c27ae31dce3bd77e0eab4469a82f98af54 /src | |
parent | 50f9e740f00d45bf60ab4e012ec7075775d2fb6c (diff) |
Added bilinear filter option to software rendering. Not hooked up to anything yet.
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/rendersw.c | 288 |
1 files changed, 241 insertions, 47 deletions
diff --git a/src/emu/rendersw.c b/src/emu/rendersw.c index f435022beb3..059d78f41d2 100644 --- a/src/emu/rendersw.c +++ b/src/emu/rendersw.c @@ -42,6 +42,10 @@ #define NO_DEST_READ 0 #endif +#if !defined(BILINEAR_FILTER) +#define BILINEAR_FILTER 0 +#endif + /*************************************************************************** @@ -53,6 +57,7 @@ #include "mamecore.h" #include "eminline.h" +#include "video/rgbutil.h" #include "render.h" #include <math.h> @@ -99,13 +104,23 @@ 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); } -INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) +/*------------------------------------------------- + ycc_to_rgb - convert YCC to RGB; the YCC pixel + contains Y in the LSB, Cb << 8, and Cr << 16 +-------------------------------------------------*/ + +INLINE UINT32 ycc_to_rgb(UINT32 ycc) { /* original equations: @@ -129,6 +144,9 @@ INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) 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) */ + UINT8 y = ycc; + UINT8 cb = ycc >> 8; + UINT8 cr = ycc >> 16; int r, g, b, common; common = 298 * y - 298 * 16; @@ -146,6 +164,177 @@ INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) return MAKE_RGB(r, g, b); } + +/*------------------------------------------------- + get_texel_palette16_nearest - return the + nearest neighbor texel from a palettized + 16bpp source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_palette16_nearest(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv, const rgb_t *palbase) +{ + return palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; +} + + +/*------------------------------------------------- + get_texel_palette16_bilinear - return a + bilinear filtered texel from a palettized + 16bpp source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_palette16_bilinear(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv, const rgb_t *palbase) +{ + rgb_t pix00, pix01, pix10, pix11; + texbase += (curv >> 16) * texrp + (curu >> 16); + pix00 = palbase[texbase[0]]; + pix01 = palbase[texbase[1]]; + pix10 = palbase[texbase[texrp + 0]]; + pix11 = palbase[texbase[texrp + 1]]; + return rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); +} + + +/*------------------------------------------------- + get_texel_rgb15_nearest - return the + nearest neighbor texel from a 15bpp RGB source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_rgb15_nearest(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + return texbase[(curv >> 16) * texrp + (curu >> 16)]; +} + + +/*------------------------------------------------- + get_texel_rgb15_bilinear - return the + bilinear filtered texel from a 15bpp RGB + source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_rgb15_bilinear(const UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + rgb_t pix00, pix01, pix10, pix11, filtered; + texbase += (curv >> 16) * texrp + (curu >> 16); + pix00 = texbase[0]; + pix01 = texbase[1]; + pix10 = texbase[texrp + 0]; + pix11 = texbase[texrp + 1]; + pix00 = ((pix00 & 0x7fe0) << 6) | (pix00 & 0x1f); + pix01 = ((pix01 & 0x7fe0) << 6) | (pix01 & 0x1f); + pix10 = ((pix10 & 0x7fe0) << 6) | (pix10 & 0x1f); + pix11 = ((pix11 & 0x7fe0) << 6) | (pix11 & 0x1f); + filtered = rgb_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); + return (filtered & 0x1f) | ((filtered & 0x1ff800) >> 6); +} + + +/*------------------------------------------------- + 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 UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; + return (spix[(curu >> 16) & 1] >> 8) | ((spix[0] & 0xff) << 8) | ((spix[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 UINT16 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + rgb_t pix00, pix01, pix10, pix11; + texbase += (curv >> 16) * texrp + (curu >> 17) * 2; + if ((curu & 0x10000) == 0) + { + rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); + pix00 = (texbase[0] >> 8) | cbcr; + pix01 = (texbase[1] >> 8) | cbcr; + cbcr = ((texbase[texrp + 0] & 0xff) << 8) | ((texbase[texrp + 1] & 0xff) << 16); + pix10 = (texbase[texrp + 0] >> 8) | cbcr; + pix11 = (texbase[texrp + 1] >> 8) | cbcr; + } + else + { + rgb_t cbcr = ((texbase[0] & 0xff) << 8) | ((texbase[1] & 0xff) << 16); + pix00 = (texbase[1] >> 8) | cbcr; + cbcr = ((texbase[2] & 0xff) << 8) | ((texbase[3] & 0xff) << 16); + pix01 = (texbase[2] >> 8) | cbcr; + cbcr = ((texbase[texrp + 0] & 0xff) << 8) | ((texbase[texrp + 1] & 0xff) << 16); + pix10 = (texbase[texrp + 1] >> 8) | cbcr; + cbcr = ((texbase[texrp + 2] & 0xff) << 8) | ((texbase[texrp + 3] & 0xff) << 16); + pix11 = (texbase[texrp + 2] >> 8) | cbcr; + } + 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 UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + return texbase[(curv >> 16) * texrp + (curu >> 16)]; +} + + +/*------------------------------------------------- + get_texel_rgb32_bilinear - return the + bilinear filtered texel from a 32bpp RGB + source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_rgb32_bilinear(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + rgb_t pix00, pix01, pix10, pix11; + texbase += (curv >> 16) * texrp + (curu >> 16); + pix00 = texbase[0]; + pix01 = texbase[1]; + pix10 = texbase[texrp + 0]; + pix11 = texbase[texrp + 1]; + 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 UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + return texbase[(curv >> 16) * texrp + (curu >> 16)]; +} + + +/*------------------------------------------------- + get_texel_argb32_bilinear - return the + bilinear filtered texel from a 32bpp ARGB + source +-------------------------------------------------*/ + +INLINE UINT32 get_texel_argb32_bilinear(const UINT32 *texbase, INT32 texrp, INT32 curu, INT32 curv) +{ + rgb_t pix00, pix01, pix10, pix11; + texbase += (curv >> 16) * texrp + (curu >> 16); + pix00 = texbase[0]; + pix01 = texbase[1]; + pix10 = texbase[texrp + 0]; + pix11 = texbase[texrp + 1]; + return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8); +} + + #endif @@ -194,6 +383,14 @@ INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr) #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 + /*************************************************************************** @@ -528,7 +725,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); *dest++ = SOURCE32_TO_DEST(pix); curu += dudx; curv += dvdx; @@ -558,7 +755,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); UINT32 r = (SOURCE32_R(pix) * sr) >> 8; UINT32 g = (SOURCE32_G(pix) * sg) >> 8; UINT32 b = (SOURCE32_B(pix) * sb) >> 8; @@ -594,7 +791,7 @@ static void FUNC_PREFIX(draw_quad_palette16_none)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); 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; @@ -640,7 +837,7 @@ static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, v /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); if ((pix & 0xffffff) != 0) { UINT32 dpix = NO_DEST_READ ? 0 : *dest; @@ -681,7 +878,7 @@ static void FUNC_PREFIX(draw_quad_palette16_add)(const render_primitive *prim, v /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); if ((pix & 0xffffff) != 0) { UINT32 dpix = NO_DEST_READ ? 0 : *dest; @@ -737,7 +934,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); UINT32 ta = pix >> 24; if (ta != 0) { @@ -780,7 +977,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = palbase[texbase[(curv >> 16) * texrp + (curu >> 16)]]; + UINT32 pix = GET_TEXEL(palette16)(texbase, texrp, curu, curv, palbase); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { @@ -837,8 +1034,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(spix[(curu >> 16) & 1] >> 8, spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv)); *dest++ = SOURCE32_TO_DEST(pix); curu += dudx; curv += dvdx; @@ -851,8 +1047,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(palbase[spix[(curu >> 16) & 1] >> 8], spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv)); *dest++ = SOURCE32_TO_DEST(pix); curu += dudx; curv += dvdx; @@ -886,8 +1081,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(spix[(curu >> 16) & 1] >> 8, spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv)); UINT32 r = (SOURCE32_R(pix) * sr) >> 8; UINT32 g = (SOURCE32_G(pix) * sg) >> 8; UINT32 b = (SOURCE32_B(pix) * sb) >> 8; @@ -904,8 +1098,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(palbase[spix[(curu >> 16) & 1] >> 8], spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, curu, curv)); UINT32 r = (SOURCE32_R(pix) * sr) >> 8; UINT32 g = (SOURCE32_G(pix) * sg) >> 8; UINT32 b = (SOURCE32_B(pix) * sb) >> 8; @@ -945,8 +1138,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(spix[(curu >> 16) & 1] >> 8, spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, 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; @@ -964,8 +1156,7 @@ static void FUNC_PREFIX(draw_quad_yuy16_none)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - const UINT16 *spix = &texbase[(curv >> 16) * texrp + (curu >> 17) * 2]; - UINT32 pix = ycc_to_rgb(palbase[spix[(curu >> 16) & 1] >> 8], spix[0], spix[1]); + UINT32 pix = ycc_to_rgb(GET_TEXEL(yuy16)(texbase, texrp, 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; @@ -1016,7 +1207,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); *dest++ = SOURCE15_TO_DEST(pix); curu += dudx; curv += dvdx; @@ -1029,7 +1220,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); UINT32 r = palbase[(pix >> 10) & 0x1f] >> SRCSHIFT_R; UINT32 g = palbase[(pix >> 5) & 0x1f] >> SRCSHIFT_G; UINT32 b = palbase[(pix >> 0) & 0x1f] >> SRCSHIFT_B; @@ -1067,7 +1258,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); UINT32 r = (SOURCE15_R(pix) * sr) >> 8; UINT32 g = (SOURCE15_G(pix) * sg) >> 8; UINT32 b = (SOURCE15_B(pix) * sb) >> 8; @@ -1084,7 +1275,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); UINT32 r = (palbase[(pix >> 10) & 0x1f] * sr) >> (8 + SRCSHIFT_R); UINT32 g = (palbase[(pix >> 5) & 0x1f] * sg) >> (8 + SRCSHIFT_G); UINT32 b = (palbase[(pix >> 0) & 0x1f] * sb) >> (8 + SRCSHIFT_B); @@ -1124,7 +1315,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); UINT32 dpix = NO_DEST_READ ? 0 : *dest; UINT32 r = (SOURCE15_R(pix) * sr + DEST_R(dpix) * invsa) >> 8; UINT32 g = (SOURCE15_G(pix) * sg + DEST_G(dpix) * invsa) >> 8; @@ -1142,7 +1333,7 @@ static void FUNC_PREFIX(draw_quad_rgb15)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb15)(texbase, texrp, curu, curv); UINT32 dpix = NO_DEST_READ ? 0 : *dest; UINT32 r = ((palbase[(pix >> 10) & 0x1f] >> SRCSHIFT_R) * sr + DEST_R(dpix) * invsa) >> 8; UINT32 g = ((palbase[(pix >> 5) & 0x1f] >> SRCSHIFT_G) * sg + DEST_G(dpix) * invsa) >> 8; @@ -1194,7 +1385,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv); *dest++ = SOURCE32_TO_DEST(pix); curu += dudx; curv += dvdx; @@ -1207,7 +1398,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, 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; @@ -1245,7 +1436,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, curu, curv); UINT32 r = (SOURCE32_R(pix) * sr) >> 8; UINT32 g = (SOURCE32_G(pix) * sg) >> 8; UINT32 b = (SOURCE32_B(pix) * sb) >> 8; @@ -1262,7 +1453,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, 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); @@ -1302,7 +1493,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, 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; @@ -1320,7 +1511,7 @@ static void FUNC_PREFIX(draw_quad_rgb32)(const render_primitive *prim, void *dst /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(rgb32)(texbase, texrp, 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; @@ -1372,7 +1563,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = pix >> 24; if (ta != 0) { @@ -1396,7 +1587,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = pix >> 24; if (ta != 0) { @@ -1443,7 +1634,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { @@ -1468,7 +1659,7 @@ static void FUNC_PREFIX(draw_quad_argb32_alpha)(const render_primitive *prim, vo /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { @@ -1525,7 +1716,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, 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); @@ -1541,7 +1732,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, 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; @@ -1580,7 +1771,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, 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); @@ -1596,7 +1787,7 @@ static void FUNC_PREFIX(draw_quad_argb32_multiply)(const render_primitive *prim, /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, 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; @@ -1647,7 +1838,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = pix >> 24; if (ta != 0) { @@ -1672,7 +1863,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = pix >> 24; if (ta != 0) { @@ -1720,7 +1911,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { @@ -1745,7 +1936,7 @@ static void FUNC_PREFIX(draw_quad_argb32_add)(const render_primitive *prim, void /* loop over cols */ for (x = setup->startx; x < endx; x++) { - UINT32 pix = texbase[(curv >> 16) * texrp + (curu >> 16)]; + UINT32 pix = GET_TEXEL(argb32)(texbase, texrp, curu, curv); UINT32 ta = (pix >> 24) * sa; if (ta != 0) { @@ -1817,9 +2008,12 @@ static void FUNC_PREFIX(setup_and_draw_textured_quad)(const render_primitive *pr 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 pixel */ - setup.startu += (setup.dudx + setup.dudy) / 2; - setup.startv += (setup.dvdx + setup.dvdy) / 2; + /* advance U/V to the middle of the first texel */ + if (!BILINEAR_FILTER) + { + setup.startu += (setup.dudx + setup.dudy) / 2; + setup.startv += (setup.dvdx + setup.dvdy) / 2; + } /* render based on the texture coordinates */ switch (prim->flags & (PRIMFLAG_TEXFORMAT_MASK | PRIMFLAG_BLENDMODE_MASK)) |