summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/rendersw.hxx
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-11-21 02:16:51 +1100
committer Vas Crabb <vas@vastheman.com>2021-11-21 02:16:51 +1100
commitd026c7736fac7026f72894ce2b7d7d44e6b21b9b (patch)
tree6e332cde3d815c3086febc9ced8e985326a8d453 /src/emu/rendersw.hxx
parenta143b7f5b44d8f2e8e2e4c6dee4392e17500d220 (diff)
emu/rendersw.hxx: Support texture wrap/clamp properly for (A)RGB formats.
Also got rid of names starting with an underscore followed by an uppercase letter, as they are reserved. Yes, get_texel_rgb32 and get_texel_argb32 are identical - thew were already identical before.
Diffstat (limited to 'src/emu/rendersw.hxx')
-rw-r--r--src/emu/rendersw.hxx799
1 files changed, 443 insertions, 356 deletions
diff --git a/src/emu/rendersw.hxx b/src/emu/rendersw.hxx
index db6b41f9bba..840f7fa5d8a 100644
--- a/src/emu/rendersw.hxx
+++ b/src/emu/rendersw.hxx
@@ -15,7 +15,7 @@
#include "render.h"
-template<typename _PixelType, int _SrcShiftR, int _SrcShiftG, int _SrcShiftB, int _DstShiftR, int _DstShiftG, int _DstShiftB, bool _NoDestRead = false, bool _BilinearFilter = false>
+template <typename PixelType, int SrcShiftR, int SrcShiftG, int SrcShiftB, int DstShiftR, int DstShiftG, int DstShiftB, bool NoDestRead = false, bool BilinearFilter = false>
class software_renderer
{
private:
@@ -29,29 +29,29 @@ private:
};
// internal helpers
- static constexpr bool is_opaque(float alpha) { return (alpha >= (_NoDestRead ? 0.5f : 1.0f)); }
- static constexpr bool is_transparent(float alpha) { return (alpha < (_NoDestRead ? 0.5f : 0.0001f)); }
+ static constexpr bool is_opaque(float alpha) { return (alpha >= (NoDestRead ? 0.5f : 1.0f)); }
+ static constexpr bool is_transparent(float alpha) { return (alpha < (NoDestRead ? 0.5f : 0.0001f)); }
static inline rgb_t apply_intensity(int intensity, rgb_t color) { return color.scale8(intensity); }
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 constexpr _PixelType dest_assemble_rgb(u32 r, u32 g, u32 b) { return (r << _DstShiftR) | (g << _DstShiftG) | (b << _DstShiftB); }
- static constexpr _PixelType dest_rgb_to_pixel(u32 r, u32 g, u32 b) { return dest_assemble_rgb(r >> _SrcShiftR, g >> _SrcShiftG, b >> _SrcShiftB); }
+ static constexpr PixelType dest_assemble_rgb(u32 r, u32 g, u32 b) { return (r << DstShiftR) | (g << DstShiftG) | (b << DstShiftB); }
+ static constexpr PixelType dest_rgb_to_pixel(u32 r, u32 g, u32 b) { return dest_assemble_rgb(r >> SrcShiftR, g >> SrcShiftG, b >> SrcShiftB); }
// source 32-bit pixels are in MAME standardized format
- static constexpr u32 source32_r(u32 pixel) { return (pixel >> (16 + _SrcShiftR)) & (0xff >> _SrcShiftR); }
- static constexpr u32 source32_g(u32 pixel) { return (pixel >> ( 8 + _SrcShiftG)) & (0xff >> _SrcShiftG); }
- static constexpr u32 source32_b(u32 pixel) { return (pixel >> ( 0 + _SrcShiftB)) & (0xff >> _SrcShiftB); }
+ static constexpr u32 source32_r(u32 pixel) { return (pixel >> (16 + SrcShiftR)) & (0xff >> SrcShiftR); }
+ static constexpr u32 source32_g(u32 pixel) { return (pixel >> ( 8 + SrcShiftG)) & (0xff >> SrcShiftG); }
+ static constexpr u32 source32_b(u32 pixel) { return (pixel >> ( 0 + SrcShiftB)) & (0xff >> SrcShiftB); }
// destination pixel masks are based on the template parameters as well
- static constexpr u32 dest_r(_PixelType pixel) { return (pixel >> _DstShiftR) & (0xff >> _SrcShiftR); }
- static constexpr u32 dest_g(_PixelType pixel) { return (pixel >> _DstShiftG) & (0xff >> _SrcShiftG); }
- static constexpr u32 dest_b(_PixelType pixel) { return (pixel >> _DstShiftB) & (0xff >> _SrcShiftB); }
+ static constexpr u32 dest_r(PixelType pixel) { return (pixel >> DstShiftR) & (0xff >> SrcShiftR); }
+ static constexpr u32 dest_g(PixelType pixel) { return (pixel >> DstShiftG) & (0xff >> SrcShiftG); }
+ static constexpr u32 dest_b(PixelType pixel) { return (pixel >> DstShiftB) & (0xff >> SrcShiftB); }
// generic conversion with special optimization for destinations in the standard format
- static constexpr _PixelType source32_to_dest(u32 pixel)
+ static constexpr PixelType source32_to_dest(u32 pixel)
{
- if (_SrcShiftR == 0 && _SrcShiftG == 0 && _SrcShiftB == 0 && _DstShiftR == 16 && _DstShiftG == 8 && _DstShiftB == 0)
+ 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));
@@ -69,7 +69,7 @@ private:
static constexpr u32 clamp16_shift8(u32 x)
{
- return ((s32(x) < 0) ? 0 : (x > 65535 ? 255: x >> 8));
+ return (s32(x) < 0) ? 0 : (x > 65535) ? 255 : (x >> 8);
}
static constexpr u32 ycc_to_rgb(u32 ycc)
@@ -131,7 +131,7 @@ private:
static inline u32 get_texel_palette16(const render_texinfo &texture, s32 curu, s32 curv)
{
const rgb_t *palbase = texture.palette;
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
s32 u0 = curu >> 16;
s32 u1 = 1;
@@ -167,7 +167,7 @@ private:
static inline u32 get_texel_palette16a(const render_texinfo &texture, s32 curu, s32 curv)
{
const rgb_t *palbase = texture.palette;
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
s32 u0 = curu >> 16;
s32 u1 = 1;
@@ -198,7 +198,7 @@ private:
static inline u32 get_texel_yuy16(const render_texinfo &texture, s32 curu, s32 curv)
{
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
s32 u0 = curu >> 16;
s32 u1 = 1;
@@ -258,28 +258,67 @@ private:
// RGB source
//-------------------------------------------------
+ template <bool Wrap>
static inline u32 get_texel_rgb32(const render_texinfo &texture, s32 curu, s32 curv)
{
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
- s32 u0 = curu >> 16;
- s32 u1 = 1;
- if (u0 < 0) u0 = u1 = 0;
- else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0;
- s32 v0 = curv >> 16;
- s32 v1 = texture.rowpixels;
- if (v0 < 0) v0 = v1 = 0;
- else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0;
-
- const u32 *texbase = reinterpret_cast<const u32 *>(texture.base);
- texbase += v0 * texture.rowpixels + u0;
+ s32 u0, u1, v0, v1;
+ if constexpr (Wrap)
+ {
+ u0 = (curu >> 16) % texture.width;
+ if (0 > u0)
+ u0 += texture.width;
+ u1 = (u0 + 1) % texture.width;
+
+ v0 = (curv >> 16) % texture.height;
+ if (0 > v0)
+ v0 += texture.height;
+ v1 = (v0 + 1) % texture.height;
+ }
+ else
+ {
+ u0 = curu >> 16;
+ if (u0 < 0)
+ u0 = u1 = 0;
+ else if (texture.width <= (u0 + 1))
+ u0 = u1 = texture.width - 1;
+ else
+ u1 = u0 + 1;
- return rgbaint_t::bilinear_filter(texbase[0], texbase[u1], texbase[v1], texbase[u1 + v1], curu >> 8, curv >> 8);
+ v0 = curv >> 16;
+ if (v0 < 0)
+ v0 = v1 = 0;
+ else if (texture.height <= (v0 + 1))
+ v0 = v1 = texture.height - 1;
+ else
+ v1 = v0 + 1;
+ }
+ u32 const *const texbase = reinterpret_cast<u32 const *>(texture.base);
+ u32 const *const row0base = texbase + (v0 * texture.rowpixels);
+ u32 const *const row1base = texbase + (v1 * texture.rowpixels);
+ return rgbaint_t::bilinear_filter(row0base[u0], row0base[u1], row1base[u0], row1base[u1], curu >> 8, curv >> 8);
}
else
{
- const u32 *texbase = reinterpret_cast<const u32 *>(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16);
- return texbase[0];
+ s32 u, v;
+ if constexpr (Wrap)
+ {
+ u = (curu >> 16) % texture.width;
+ if (0 > u)
+ u += texture.width;
+
+ v = (curv >> 16) % texture.height;
+ if (0 > v)
+ v += texture.height;
+ }
+ else
+ {
+ u = std::clamp<s32>(curu >> 16, 0, texture.width - 1);
+ v = std::clamp<s32>(curv >> 16, 0, texture.height - 1);
+ }
+ u32 const *const rowbase = reinterpret_cast<u32 const *>(texture.base) + (v * texture.rowpixels);
+ return rowbase[u];
}
}
@@ -289,28 +328,67 @@ private:
// ARGB source
//-------------------------------------------------
- static inline u32 get_texel_argb32(const render_texinfo &texture, s32 curu, s32 curv)
+ template <bool Wrap>
+ static inline u32 get_texel_argb32(render_texinfo const &texture, s32 curu, s32 curv)
{
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
- s32 u0 = curu >> 16;
- s32 u1 = 1;
- if (u0 < 0) u0 = u1 = 0;
- else if (u0 + 1 >= texture.width) u0 = texture.width - 1, u1 = 0;
- s32 v0 = curv >> 16;
- s32 v1 = texture.rowpixels;
- if (v0 < 0) v0 = v1 = 0;
- else if (v0 + 1 >= texture.height) v0 = texture.height - 1, v1 = 0;
-
- const u32 *texbase = reinterpret_cast<const u32 *>(texture.base);
- texbase += v0 * texture.rowpixels + u0;
+ s32 u0, u1, v0, v1;
+ if constexpr (Wrap)
+ {
+ u0 = (curu >> 16) % texture.width;
+ if (0 > u0)
+ u0 += texture.width;
+ u1 = (u0 + 1) % texture.width;
+
+ v0 = (curv >> 16) % texture.height;
+ if (0 > v0)
+ v0 += texture.height;
+ v1 = (v0 + 1) % texture.height;
+ }
+ else
+ {
+ u0 = curu >> 16;
+ if (u0 < 0)
+ u0 = u1 = 0;
+ else if (texture.width <= (u0 + 1))
+ u0 = u1 = texture.width - 1;
+ else
+ u1 = u0 + 1;
- return rgbaint_t::bilinear_filter(texbase[0], texbase[u1], texbase[v1], texbase[u1 + v1], curu >> 8, curv >> 8);
+ v0 = curv >> 16;
+ if (v0 < 0)
+ v0 = v1 = 0;
+ else if (texture.height <= (v0 + 1))
+ v0 = v1 = texture.height - 1;
+ else
+ v1 = v0 + 1;
+ }
+ u32 const *const texbase = reinterpret_cast<u32 const *>(texture.base);
+ u32 const *const row0base = texbase + (v0 * texture.rowpixels);
+ u32 const *const row1base = texbase + (v1 * texture.rowpixels);
+ return rgbaint_t::bilinear_filter(row0base[u0], row0base[u1], row1base[u0], row1base[u1], curu >> 8, curv >> 8);
}
else
{
- const u32 *texbase = reinterpret_cast<const u32 *>(texture.base) + (curv >> 16) * texture.rowpixels + (curu >> 16);
- return texbase[0];
+ s32 u, v;
+ if constexpr (Wrap)
+ {
+ u = (curu >> 16) % texture.width;
+ if (0 > u)
+ u += texture.width;
+
+ v = (curv >> 16) % texture.height;
+ if (0 > v)
+ v += texture.height;
+ }
+ else
+ {
+ u = std::clamp<s32>(curu >> 16, 0, texture.width - 1);
+ v = std::clamp<s32>(curv >> 16, 0, texture.height - 1);
+ }
+ u32 const *const rowbase = reinterpret_cast<u32 const *>(texture.base) + (v * texture.rowpixels);
+ return rowbase[u];
}
}
@@ -319,16 +397,16 @@ private:
// draw_aa_pixel - draw an antialiased pixel
//-------------------------------------------------
- static inline void draw_aa_pixel(_PixelType *dstdata, u32 pitch, int x, int y, u32 col)
+ static inline void draw_aa_pixel(PixelType *dstdata, u32 pitch, int x, int y, u32 col)
{
- _PixelType *dest = dstdata + y * pitch + x;
- u32 dpix = _NoDestRead ? 0 : *dest;
+ PixelType *dest = dstdata + y * pitch + x;
+ u32 dpix = NoDestRead ? 0 : *dest;
u32 dr = source32_r(col) + dest_r(dpix);
u32 dg = source32_g(col) + dest_g(dpix);
u32 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);
+ 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);
}
@@ -337,7 +415,7 @@ private:
// draw_line - draw a line or point
//-------------------------------------------------
- static void draw_line(const render_primitive &prim, _PixelType *dstdata, s32 width, s32 height, u32 pitch)
+ static void draw_line(const render_primitive &prim, PixelType *dstdata, s32 width, s32 height, u32 pitch)
{
// internal tables
static u32 s_cosine_table[2049];
@@ -498,7 +576,7 @@ private:
// draw_rect - draw a solid rectangle
//-------------------------------------------------
- static void draw_rect(const render_primitive &prim, _PixelType *dstdata, s32 width, s32 height, u32 pitch)
+ static void draw_rect(const render_primitive &prim, PixelType *dstdata, s32 width, s32 height, u32 pitch)
{
render_bounds fpos = prim.bounds;
assert(fpos.x0 <= fpos.x1);
@@ -545,7 +623,7 @@ private:
// loop over rows
for (s32 y = starty; y < endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + startx;
+ PixelType *dest = dstdata + y * pitch + startx;
// loop over cols
for (s32 x = startx; x < endx; x++)
@@ -578,12 +656,12 @@ private:
// loop over rows
for (s32 y = starty; y < endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + startx;
+ PixelType *dest = dstdata + y * pitch + startx;
// loop over cols
for (s32 x = startx; x < endx; x++)
{
- u32 dpix = _NoDestRead ? 0 : *dest;
+ u32 dpix = NoDestRead ? 0 : *dest;
u32 dr = (r + ((dpix & rmask) * inva)) & (rmask << 8);
u32 dg = (g + ((dpix & gmask) * inva)) & (gmask << 8);
u32 db = (b + ((dpix & bmask) * inva)) & (bmask << 8);
@@ -603,7 +681,7 @@ private:
// rasterization of a 16bpp palettized texture
//-------------------------------------------------
- static void draw_quad_palette16_none(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data &setup)
+ static void draw_quad_palette16_none(const render_primitive &prim, PixelType *dstdata, u32 pitch, const quad_setup_data &setup)
{
// ensure all parameters are valid
assert(prim.texture.palette != nullptr);
@@ -614,7 +692,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -644,7 +722,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -680,7 +758,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -688,7 +766,7 @@ private:
for (s32 x = setup.startx; x < setup.endx; x++)
{
const u32 pix = get_texel_palette16(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
const u32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8;
const u32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8;
const u32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8;
@@ -707,7 +785,7 @@ private:
// rasterization of a 16bpp palettized texture
//-------------------------------------------------
- static void draw_quad_palette16_add(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ static void draw_quad_palette16_add(const render_primitive &prim, PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
{
// ensure all parameters are valid
assert(prim.texture.palette != nullptr);
@@ -718,7 +796,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -728,13 +806,13 @@ private:
const u32 pix = get_texel_palette16(prim.texture, curu, curv);
if ((pix & 0xffffff) != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
u32 r = source32_r(pix) + dest_r(dpix);
u32 g = source32_g(pix) + dest_g(dpix);
u32 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);
+ 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++;
@@ -759,7 +837,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -769,13 +847,13 @@ private:
const u32 pix = get_texel_palette16(prim.texture, curu, curv);
if ((pix & 0xffffff) != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
u32 r = ((source32_r(pix) * sr) >> 8) + dest_r(dpix);
u32 g = ((source32_g(pix) * sg) >> 8) + dest_g(dpix);
u32 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);
+ 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 += setup.dudx;
curv += setup.dvdx;
@@ -796,7 +874,7 @@ private:
// rasterization of a 16bpp YUY image
//-------------------------------------------------
- static void draw_quad_yuy16_none(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ static void draw_quad_yuy16_none(const render_primitive &prim, PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
{
// 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))
@@ -804,7 +882,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -834,7 +912,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -870,7 +948,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -878,7 +956,7 @@ private:
for (s32 x = setup.startx; x < setup.endx; x++)
{
const u32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv));
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
const u32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8;
const u32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8;
const u32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8;
@@ -898,10 +976,10 @@ private:
// conversion
//-------------------------------------------------
- static void draw_quad_yuy16_add(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ static void draw_quad_yuy16_add(const render_primitive &prim, PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
{
// simply can't do this without reading from the dest
- if constexpr (_NoDestRead)
+ if constexpr (NoDestRead)
return;
// fast case: no coloring, no alpha
@@ -910,7 +988,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -918,13 +996,13 @@ private:
for (s32 x = setup.startx; x < setup.endx; x++)
{
const u32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv));
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
u32 r = source32_r(pix) + dest_r(dpix);
u32 g = source32_g(pix) + dest_g(dpix);
u32 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);
+ 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 += setup.dudx;
curv += setup.dvdx;
@@ -949,7 +1027,7 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
@@ -957,13 +1035,13 @@ private:
for (s32 x = setup.startx; x < setup.endx; x++)
{
const u32 pix = ycc_to_rgb(get_texel_yuy16(prim.texture, curu, curv));
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ const u32 dpix = NoDestRead ? 0 : *dest;
u32 r = ((source32_r(pix) * sr * sa) >> 16) + dest_r(dpix);
u32 g = ((source32_g(pix) * sg * sa) >> 16) + dest_g(dpix);
u32 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);
+ 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 += setup.dudx;
curv += setup.dvdx;
@@ -982,9 +1060,10 @@ private:
// a 32bpp RGB texture
//-------------------------------------------------
- static void draw_quad_rgb32(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ template <bool Wrap>
+ static void draw_quad_rgb32(render_primitive const &prim, PixelType *dstdata, u32 pitch, quad_setup_data const &setup)
{
- const rgb_t *palbase = prim.texture.palette;
+ rgb_t const *const palbase = prim.texture.palette;
// 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))
@@ -992,33 +1071,34 @@ private:
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
*dest++ = source32_to_dest(pix);
curu += setup.dudx;
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
- const u32 r = palbase[(pix >> 16) & 0xff] >> _SrcShiftR;
- const u32 g = palbase[(pix >> 8) & 0xff] >> _SrcShiftG;
- const u32 b = palbase[(pix >> 0) & 0xff] >> _SrcShiftB;
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
+ u32 const r = palbase[(pix >> 16) & 0xff] >> SrcShiftR;
+ u32 const g = palbase[(pix >> 8) & 0xff] >> SrcShiftG;
+ u32 const b = palbase[(pix >> 0) & 0xff] >> SrcShiftB;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1027,53 +1107,50 @@ private:
}
}
}
-
- // coloring-only case
else if (is_opaque(prim.color.a))
{
- u32 sr = u32(256.0f * prim.color.r);
- u32 sg = u32(256.0f * prim.color.g);
- u32 sb = u32(256.0f * prim.color.b);
+ // coloring-only case
// clamp R,G,B to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
+ u32 const sr = u32(std::clamp(256.0f * prim.color.r, 0.0f, 256.0f));
+ u32 const sg = u32(std::clamp(256.0f * prim.color.g, 0.0f, 256.0f));
+ u32 const sb = u32(std::clamp(256.0f * prim.color.b, 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
- const u32 r = (source32_r(pix) * sr) >> 8;
- const u32 g = (source32_g(pix) * sg) >> 8;
- const u32 b = (source32_b(pix) * sb) >> 8;
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
+ u32 const r = (source32_r(pix) * sr) >> 8;
+ u32 const g = (source32_g(pix) * sg) >> 8;
+ u32 const b = (source32_b(pix) * sb) >> 8;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
- const u32 r = (palbase[(pix >> 16) & 0xff] * sr) >> (8 + _SrcShiftR);
- const u32 g = (palbase[(pix >> 8) & 0xff] * sg) >> (8 + _SrcShiftG);
- const u32 b = (palbase[(pix >> 0) & 0xff] * sb) >> (8 + _SrcShiftB);
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
+ u32 const r = (palbase[(pix >> 16) & 0xff] * sr) >> (8 + SrcShiftR);
+ u32 const g = (palbase[(pix >> 8) & 0xff] * sg) >> (8 + SrcShiftG);
+ u32 const b = (palbase[(pix >> 0) & 0xff] * sb) >> (8 + SrcShiftB);
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1082,57 +1159,53 @@ private:
}
}
}
-
- // alpha and/or coloring case
else if (!is_transparent(prim.color.a))
{
- u32 sr = u32(256.0f * prim.color.r * prim.color.a);
- u32 sg = u32(256.0f * prim.color.g * prim.color.a);
- u32 sb = u32(256.0f * prim.color.b * prim.color.a);
- u32 invsa = u32(256.0f * (1.0f - prim.color.a));
+ // alpha and/or coloring case
// clamp R,G,B and inverse A to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
- if (invsa > 0x100) { if (s32(invsa) < 0) invsa = 0; else invsa = 0x100; }
+ u32 sr = u32(std::clamp(256.0f * prim.color.r * prim.color.a, 0.0f, 256.0f));
+ u32 sg = u32(std::clamp(256.0f * prim.color.g * prim.color.a, 0.0f, 256.0f));
+ u32 sb = u32(std::clamp(256.0f * prim.color.b * prim.color.a, 0.0f, 256.0f));
+ u32 invsa = u32(std::clamp(256.0f * (1.0f - prim.color.a), 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8;
- const u32 g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8;
- const u32 b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8;
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = (source32_r(pix) * sr + dest_r(dpix) * invsa) >> 8;
+ u32 const g = (source32_g(pix) * sg + dest_g(dpix) * invsa) >> 8;
+ u32 const b = (source32_b(pix) * sb + dest_b(dpix) * invsa) >> 8;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_rgb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * sr + dest_r(dpix) * invsa) >> 8;
- const u32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * sg + dest_g(dpix) * invsa) >> 8;
- const u32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * sb + dest_b(dpix) * invsa) >> 8;
+ u32 const pix = get_texel_rgb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = ((palbase[(pix >> 16) & 0xff] >> SrcShiftR) * sr + dest_r(dpix) * invsa) >> 8;
+ u32 const g = ((palbase[(pix >> 8) & 0xff] >> SrcShiftG) * sg + dest_g(dpix) * invsa) >> 8;
+ u32 const b = ((palbase[(pix >> 0) & 0xff] >> SrcShiftB) * sb + dest_b(dpix) * invsa) >> 8;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1149,58 +1222,61 @@ private:
// rasterization by using RGB add
//-------------------------------------------------
- static void draw_quad_rgb32_add(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ template <bool Wrap>
+ static void draw_quad_rgb32_add(render_primitive const &prim, PixelType *dstdata, u32 pitch, quad_setup_data const &setup)
{
- const rgb_t *palbase = prim.texture.palette;
-
// simply can't do this without reading from the dest
- if (_NoDestRead)
+ if (NoDestRead)
return;
- // fast case: no coloring, no alpha
+ rgb_t const *const palbase = prim.texture.palette;
+
if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a))
{
+ // fast case: no coloring, no alpha
+
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
u32 r = source32_r(pix) + dest_r(dpix);
u32 g = source32_g(pix) + dest_g(dpix);
u32 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);
+ 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 += setup.dudx;
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- u32 r = (palbase[(pix >> 16) & 0xff] >> _SrcShiftR) + dest_r(dpix);
- u32 g = (palbase[(pix >> 8) & 0xff] >> _SrcShiftG) + dest_g(dpix);
- u32 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);
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 r = (palbase[(pix >> 16) & 0xff] >> SrcShiftR) + dest_r(dpix);
+ u32 g = (palbase[(pix >> 8) & 0xff] >> SrcShiftG) + dest_g(dpix);
+ u32 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 += setup.dudx;
curv += setup.dvdx;
@@ -1208,62 +1284,58 @@ private:
}
}
}
-
- // alpha and/or coloring case
else
{
- u32 sr = u32(256.0f * prim.color.r);
- u32 sg = u32(256.0f * prim.color.g);
- u32 sb = u32(256.0f * prim.color.b);
- u32 sa = u32(256.0f * prim.color.a);
+ // alpha and/or coloring case
// clamp R,G,B and inverse A to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
- if (sa > 0x100) { if (s32(sa) < 0) sa = 0; else sa = 0x100; }
+ u32 const sr = u32(std::clamp(256.0f * prim.color.r, 0.0f, 256.0f));
+ u32 const sg = u32(std::clamp(256.0f * prim.color.g, 0.0f, 256.0f));
+ u32 const sb = u32(std::clamp(256.0f * prim.color.b, 0.0f, 256.0f));
+ u32 const sa = u32(std::clamp(256.0f * prim.color.a, 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
u32 r = ((source32_r(pix) * sr * sa) >> 16) + dest_r(dpix);
u32 g = ((source32_g(pix) * sg * sa) >> 16) + dest_g(dpix);
u32 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);
+ 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 += setup.dudx;
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- u32 r = ((palbase[(pix >> 16) & 0xff] * sr * sa) >> (16 + _SrcShiftR)) + dest_r(dpix);
- u32 g = ((palbase[(pix >> 8) & 0xff] * sr * sa) >> (16 + _SrcShiftR)) + dest_g(dpix);
- u32 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);
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 r = ((palbase[(pix >> 16) & 0xff] * sr * sa) >> (16 + SrcShiftR)) + dest_r(dpix);
+ u32 g = ((palbase[(pix >> 8) & 0xff] * sr * sa) >> (16 + SrcShiftR)) + dest_g(dpix);
+ u32 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 += setup.dudx;
curv += setup.dvdx;
@@ -1279,35 +1351,38 @@ private:
// rasterization using RGB multiply
//-------------------------------------------------
- static void draw_quad_rgb32_multiply(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ template <bool Wrap>
+ static void draw_quad_rgb32_multiply(render_primitive const &prim, PixelType *dstdata, u32 pitch, quad_setup_data const &setup)
{
- const rgb_t *palbase = prim.texture.palette;
-
// simply can't do this without reading from the dest
- if (_NoDestRead)
+ if (NoDestRead)
return;
- // fast case: no coloring, no alpha
+ rgb_t const *const palbase = prim.texture.palette;
+
if (prim.color.r >= 1.0f && prim.color.g >= 1.0f && prim.color.b >= 1.0f && is_opaque(prim.color.a))
{
+ // fast case: no coloring, no alpha
+
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = (source32_r(pix) * dest_r(dpix)) >> (8 - _SrcShiftR);
- const u32 g = (source32_g(pix) * dest_g(dpix)) >> (8 - _SrcShiftG);
- const u32 b = (source32_b(pix) * dest_b(dpix)) >> (8 - _SrcShiftB);
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = (source32_r(pix) * dest_r(dpix)) >> (8 - SrcShiftR);
+ u32 const g = (source32_g(pix) * dest_g(dpix)) >> (8 - SrcShiftG);
+ u32 const b = (source32_b(pix) * dest_b(dpix)) >> (8 - SrcShiftB);
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1316,14 +1391,16 @@ private:
}
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = (palbase[(pix >> 16) & 0xff] * dest_r(dpix)) >> 8;
- const u32 g = (palbase[(pix >> 8) & 0xff] * dest_g(dpix)) >> 8;
- const u32 b = (palbase[(pix >> 0) & 0xff] * dest_b(dpix)) >> 8;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = (palbase[(pix >> 16) & 0xff] * dest_r(dpix)) >> 8;
+ u32 const g = (palbase[(pix >> 8) & 0xff] * dest_g(dpix)) >> 8;
+ u32 const b = (palbase[(pix >> 0) & 0xff] * dest_b(dpix)) >> 8;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1332,37 +1409,34 @@ private:
}
}
}
-
- // alpha and/or coloring case
else
{
- u32 sr = u32(256.0f * prim.color.r * prim.color.a);
- u32 sg = u32(256.0f * prim.color.g * prim.color.a);
- u32 sb = u32(256.0f * prim.color.b * prim.color.a);
+ // alpha and/or coloring case
// clamp R,G,B to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
+ u32 const sr = u32(std::clamp(256.0f * prim.color.r * prim.color.a, 0.0f, 256.0f));
+ u32 const sg = u32(std::clamp(256.0f * prim.color.g * prim.color.a, 0.0f, 256.0f));
+ u32 const sb = u32(std::clamp(256.0f * prim.color.b * prim.color.a, 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = (source32_r(pix) * sr * dest_r(dpix)) >> (16 - _SrcShiftR);
- const u32 g = (source32_g(pix) * sg * dest_g(dpix)) >> (16 - _SrcShiftG);
- const u32 b = (source32_b(pix) * sb * dest_b(dpix)) >> (16 - _SrcShiftB);
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = (source32_r(pix) * sr * dest_r(dpix)) >> (16 - SrcShiftR);
+ u32 const g = (source32_g(pix) * sg * dest_g(dpix)) >> (16 - SrcShiftG);
+ u32 const b = (source32_b(pix) * sb * dest_b(dpix)) >> (16 - SrcShiftB);
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1371,14 +1445,16 @@ private:
}
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 r = (palbase[(pix >> 16) & 0xff] * sr * dest_r(dpix)) >> 16;
- const u32 g = (palbase[(pix >> 8) & 0xff] * sg * dest_g(dpix)) >> 16;
- const u32 b = (palbase[(pix >> 0) & 0xff] * sb * dest_b(dpix)) >> 16;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const r = (palbase[(pix >> 16) & 0xff] * sr * dest_r(dpix)) >> 16;
+ u32 const g = (palbase[(pix >> 8) & 0xff] * sg * dest_g(dpix)) >> 16;
+ u32 const b = (palbase[(pix >> 0) & 0xff] * sb * dest_b(dpix)) >> 16;
*dest++ = dest_assemble_rgb(r, g, b);
curu += setup.dudx;
@@ -1399,35 +1475,38 @@ private:
// rasterization using standard alpha blending
//-------------------------------------------------
- static void draw_quad_argb32_alpha(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ template <bool Wrap>
+ static void draw_quad_argb32_alpha(render_primitive const &prim, PixelType *dstdata, u32 pitch, quad_setup_data const &setup)
{
- const rgb_t *palbase = prim.texture.palette;
+ rgb_t const *const palbase = prim.texture.palette;
- // 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))
{
+ // fast case: no coloring, no alpha
+
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = pix >> 24;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = pix >> 24;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 invta = 0x100 - ta;
- const u32 r = (source32_r(pix) * ta + dest_r(dpix) * invta) >> 8;
- const u32 g = (source32_g(pix) * ta + dest_g(dpix) * invta) >> 8;
- const u32 b = (source32_b(pix) * ta + dest_b(dpix) * invta) >> 8;
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const invta = 0x100 - ta;
+ u32 const r = (source32_r(pix) * ta + dest_r(dpix) * invta) >> 8;
+ u32 const g = (source32_g(pix) * ta + dest_g(dpix) * invta) >> 8;
+ u32 const b = (source32_b(pix) * ta + dest_b(dpix) * invta) >> 8;
*dest = dest_assemble_rgb(r, g, b);
}
@@ -1436,22 +1515,22 @@ private:
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = pix >> 24;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = pix >> 24;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 invta = 0x100 - ta;
- const u32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * ta + dest_r(dpix) * invta) >> 8;
- const u32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * ta + dest_g(dpix) * invta) >> 8;
- const u32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * ta + dest_b(dpix) * invta) >> 8;
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const invta = 0x100 - ta;
+ u32 const r = ((palbase[(pix >> 16) & 0xff] >> SrcShiftR) * ta + dest_r(dpix) * invta) >> 8;
+ u32 const g = ((palbase[(pix >> 8) & 0xff] >> SrcShiftG) * ta + dest_g(dpix) * invta) >> 8;
+ u32 const b = ((palbase[(pix >> 0) & 0xff] >> SrcShiftB) * ta + dest_b(dpix) * invta) >> 8;
*dest = dest_assemble_rgb(r, g, b);
}
@@ -1462,43 +1541,39 @@ private:
}
}
}
-
- // alpha and/or coloring case
else
{
- u32 sr = u32(256.0f * prim.color.r);
- u32 sg = u32(256.0f * prim.color.g);
- u32 sb = u32(256.0f * prim.color.b);
- u32 sa = u32(256.0f * prim.color.a);
+ // alpha and/or coloring case
// clamp R,G,B and inverse A to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
- if (sa > 0x100) { if (s32(sa) < 0) sa = 0; else sa = 0x100; }
+ u32 const sr = u32(std::clamp(256.0f * prim.color.r, 0.0f, 256.0f));
+ u32 const sg = u32(std::clamp(256.0f * prim.color.g, 0.0f, 256.0f));
+ u32 const sb = u32(std::clamp(256.0f * prim.color.b, 0.0f, 256.0f));
+ u32 const sa = u32(std::clamp(256.0f * prim.color.a, 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = (pix >> 24) * sa;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = (pix >> 24) * sa;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 invsta = (0x10000 - ta) << 8;
- const u32 r = (source32_r(pix) * sr * ta + dest_r(dpix) * invsta) >> 24;
- const u32 g = (source32_g(pix) * sg * ta + dest_g(dpix) * invsta) >> 24;
- const u32 b = (source32_b(pix) * sb * ta + dest_b(dpix) * invsta) >> 24;
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const invsta = (0x10000 - ta) << 8;
+ u32 const r = (source32_r(pix) * sr * ta + dest_r(dpix) * invsta) >> 24;
+ u32 const g = (source32_g(pix) * sg * ta + dest_g(dpix) * invsta) >> 24;
+ u32 const b = (source32_b(pix) * sb * ta + dest_b(dpix) * invsta) >> 24;
*dest = dest_assemble_rgb(r, g, b);
}
@@ -1507,23 +1582,22 @@ private:
curv += setup.dvdx;
}
}
-
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = (pix >> 24) * sa;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = (pix >> 24) * sa;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- const u32 invsta = (0x10000 - ta) << 8;
- const u32 r = ((palbase[(pix >> 16) & 0xff] >> _SrcShiftR) * sr * ta + dest_r(dpix) * invsta) >> 24;
- const u32 g = ((palbase[(pix >> 8) & 0xff] >> _SrcShiftG) * sg * ta + dest_g(dpix) * invsta) >> 24;
- const u32 b = ((palbase[(pix >> 0) & 0xff] >> _SrcShiftB) * sb * ta + dest_b(dpix) * invsta) >> 24;
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 const invsta = (0x10000 - ta) << 8;
+ u32 const r = ((palbase[(pix >> 16) & 0xff] >> SrcShiftR) * sr * ta + dest_r(dpix) * invsta) >> 24;
+ u32 const g = ((palbase[(pix >> 8) & 0xff] >> SrcShiftG) * sg * ta + dest_g(dpix) * invsta) >> 24;
+ u32 const b = ((palbase[(pix >> 0) & 0xff] >> SrcShiftB) * sb * ta + dest_b(dpix) * invsta) >> 24;
*dest = dest_assemble_rgb(r, g, b);
}
@@ -1542,41 +1616,43 @@ private:
// rasterization by using RGB add
//-------------------------------------------------
- static void draw_quad_argb32_add(const render_primitive &prim, _PixelType *dstdata, u32 pitch, const quad_setup_data&setup)
+ template <bool Wrap>
+ static void draw_quad_argb32_add(render_primitive const &prim, PixelType *dstdata, u32 pitch, quad_setup_data const &setup)
{
- const rgb_t *palbase = prim.texture.palette;
-
// simply can't do this without reading from the dest
- if (_NoDestRead)
+ if (NoDestRead)
return;
+ rgb_t const *const palbase = prim.texture.palette;
+
// 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 (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = pix >> 24;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = pix >> 24;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ u32 const dpix = NoDestRead ? 0 : *dest;
u32 r = ((source32_r(pix) * ta) >> 8) + dest_r(dpix);
u32 g = ((source32_g(pix) * ta) >> 8) + dest_g(dpix);
u32 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);
+ 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++;
@@ -1584,24 +1660,24 @@ private:
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = pix >> 24;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = pix >> 24;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- u32 r = ((palbase[(pix >> 16) & 0xff] * ta) >> (8 + _SrcShiftR)) + dest_r(dpix);
- u32 g = ((palbase[(pix >> 8) & 0xff] * ta) >> (8 + _SrcShiftG)) + dest_g(dpix);
- u32 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);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 r = ((palbase[(pix >> 16) & 0xff] * ta) >> (8 + SrcShiftR)) + dest_r(dpix);
+ u32 g = ((palbase[(pix >> 8) & 0xff] * ta) >> (8 + SrcShiftG)) + dest_g(dpix);
+ u32 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++;
@@ -1611,45 +1687,41 @@ private:
}
}
}
-
- // alpha and/or coloring case
else
{
- u32 sr = u32(256.0f * prim.color.r);
- u32 sg = u32(256.0f * prim.color.g);
- u32 sb = u32(256.0f * prim.color.b);
- u32 sa = u32(256.0f * prim.color.a);
+ // alpha and/or coloring case
// clamp R,G,B and inverse A to 0-256 range
- if (sr > 0x100) { if (s32(sr) < 0) sr = 0; else sr = 0x100; }
- if (sg > 0x100) { if (s32(sg) < 0) sg = 0; else sg = 0x100; }
- if (sb > 0x100) { if (s32(sb) < 0) sb = 0; else sb = 0x100; }
- if (sa > 0x100) { if (s32(sa) < 0) sa = 0; else sa = 0x100; }
+ u32 const sr = u32(std::clamp(256.0f * prim.color.r, 0.0f, 256.0f));
+ u32 const sg = u32(std::clamp(256.0f * prim.color.g, 0.0f, 256.0f));
+ u32 const sb = u32(std::clamp(256.0f * prim.color.b, 0.0f, 256.0f));
+ u32 const sa = u32(std::clamp(256.0f * prim.color.a, 0.0f, 256.0f));
// loop over rows
for (s32 y = setup.starty; y < setup.endy; y++)
{
- _PixelType *dest = dstdata + y * pitch + setup.startx;
+ PixelType *dest = dstdata + y * pitch + setup.startx;
s32 curu = setup.startu + (y - setup.starty) * setup.dudy;
s32 curv = setup.startv + (y - setup.starty) * setup.dvdy;
- // no lookup case
- if (palbase == nullptr)
+ if (!palbase)
{
+ // no lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = (pix >> 24) * sa;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = (pix >> 24) * sa;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
+ u32 const dpix = NoDestRead ? 0 : *dest;
u32 r = ((source32_r(pix) * sr * ta) >> 24) + dest_r(dpix);
u32 g = ((source32_g(pix) * sg * ta) >> 24) + dest_g(dpix);
u32 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);
+ 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++;
@@ -1657,24 +1729,24 @@ private:
curv += setup.dvdx;
}
}
-
- // lookup case
else
{
+ // lookup case
+
// loop over cols
for (s32 x = setup.startx; x < setup.endx; x++)
{
- const u32 pix = get_texel_argb32(prim.texture, curu, curv);
- const u32 ta = (pix >> 24) * sa;
+ u32 const pix = get_texel_argb32<Wrap>(prim.texture, curu, curv);
+ u32 const ta = (pix >> 24) * sa;
if (ta != 0)
{
- const u32 dpix = _NoDestRead ? 0 : *dest;
- u32 r = ((palbase[(pix >> 16) & 0xff] * sr * ta) >> (24 + _SrcShiftR)) + dest_r(dpix);
- u32 g = ((palbase[(pix >> 8) & 0xff] * sr * ta) >> (24 + _SrcShiftR)) + dest_g(dpix);
- u32 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);
+ u32 const dpix = NoDestRead ? 0 : *dest;
+ u32 r = ((palbase[(pix >> 16) & 0xff] * sr * ta) >> (24 + SrcShiftR)) + dest_r(dpix);
+ u32 g = ((palbase[(pix >> 8) & 0xff] * sr * ta) >> (24 + SrcShiftR)) + dest_g(dpix);
+ u32 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++;
@@ -1697,7 +1769,7 @@ private:
// drawing routine
//-------------------------------------------------
- static void setup_and_draw_textured_quad(const render_primitive &prim, _PixelType *dstdata, s32 width, s32 height, u32 pitch)
+ static void setup_and_draw_textured_quad(const render_primitive &prim, PixelType *dstdata, s32 width, s32 height, u32 pitch)
{
assert(prim.bounds.x0 <= prim.bounds.x1);
assert(prim.bounds.y0 <= prim.bounds.y1);
@@ -1738,7 +1810,7 @@ private:
setup.startv += (setup.dvdx + setup.dvdy) / 2;
// if we're bilinear filtering, we need to offset u/v by half a texel
- if constexpr (_BilinearFilter)
+ if constexpr (BilinearFilter)
{
setup.startu -= 0x8000;
setup.startv -= 0x8000;
@@ -1768,24 +1840,39 @@ private:
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);
+ if (PRIMFLAG_GET_TEXWRAP(prim.flags))
+ draw_quad_rgb32<true>(prim, dstdata, pitch, setup);
+ else
+ draw_quad_rgb32<false>(prim, dstdata, pitch, setup);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY):
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_RGB_MULTIPLY):
- draw_quad_rgb32_multiply(prim, dstdata, pitch, setup);
+ if (PRIMFLAG_GET_TEXWRAP(prim.flags))
+ draw_quad_rgb32_multiply<true>(prim, dstdata, pitch, setup);
+ else
+ draw_quad_rgb32_multiply<false>(prim, dstdata, pitch, setup);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_RGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD):
- draw_quad_rgb32_add(prim, dstdata, pitch, setup);
+ if (PRIMFLAG_GET_TEXWRAP(prim.flags))
+ draw_quad_rgb32_add<true>(prim, dstdata, pitch, setup);
+ else
+ draw_quad_rgb32_add<false>(prim, dstdata, pitch, setup);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA):
- draw_quad_argb32_alpha(prim, dstdata, pitch, setup);
+ if (PRIMFLAG_GET_TEXWRAP(prim.flags))
+ draw_quad_argb32_alpha<true>(prim, dstdata, pitch, setup);
+ else
+ draw_quad_argb32_alpha<false>(prim, dstdata, pitch, setup);
break;
case PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32) | PRIMFLAG_BLENDMODE(BLENDMODE_ADD):
- draw_quad_argb32_add(prim, dstdata, pitch, setup);
+ if (PRIMFLAG_GET_TEXWRAP(prim.flags))
+ draw_quad_argb32_add<true>(prim, dstdata, pitch, setup);
+ else
+ draw_quad_argb32_add<false>(prim, dstdata, pitch, setup);
break;
default:
@@ -1812,14 +1899,14 @@ public:
switch (prim->type)
{
case render_primitive::LINE:
- draw_line(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch);
+ draw_line(*prim, reinterpret_cast<PixelType *>(dstdata), width, height, pitch);
break;
case render_primitive::QUAD:
if (!prim->texture.base)
- draw_rect(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch);
+ draw_rect(*prim, reinterpret_cast<PixelType *>(dstdata), width, height, pitch);
else
- setup_and_draw_textured_quad(*prim, reinterpret_cast<_PixelType *>(dstdata), width, height, pitch);
+ setup_and_draw_textured_quad(*prim, reinterpret_cast<PixelType *>(dstdata), width, height, pitch);
break;
default: