summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-06-12 19:14:18 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-06-12 19:14:18 +0000
commita701f8537ede746d1cf15dc5fd09d0719a19dc23 (patch)
treeedfd55c27ae31dce3bd77e0eab4469a82f98af54 /src
parent50f9e740f00d45bf60ab4e012ec7075775d2fb6c (diff)
Added bilinear filter option to software rendering. Not hooked up to anything yet.
Diffstat (limited to 'src')
-rw-r--r--src/emu/rendersw.c288
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))