summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/video/rgbgen.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/video/rgbgen.h')
-rw-r--r--src/emu/video/rgbgen.h396
1 files changed, 396 insertions, 0 deletions
diff --git a/src/emu/video/rgbgen.h b/src/emu/video/rgbgen.h
new file mode 100644
index 00000000000..1a5469fef80
--- /dev/null
+++ b/src/emu/video/rgbgen.h
@@ -0,0 +1,396 @@
+/***************************************************************************
+
+ rgbgen.h
+
+ General RGB utilities.
+
+ Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+***************************************************************************/
+
+#ifndef __RGBGEN__
+#define __RGBGEN__
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* intermediate RGB values are stored in a struct */
+typedef struct { INT16 dummy, r, g, b; } rgbint;
+
+/* intermediate RGB values are stored in a struct */
+typedef struct { INT16 a, r, g, b; } rgbaint;
+
+
+
+/***************************************************************************
+ BASIC CONVERSIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgb_comp_to_rgbint - converts a trio of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgb_comp_to_rgbint(rgbint *rgb, INT16 r, INT16 g, INT16 b)
+{
+ rgb->r = r;
+ rgb->g = g;
+ rgb->b = b;
+}
+
+
+/*-------------------------------------------------
+ rgba_comp_to_rgbint - converts a quad of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgba_comp_to_rgbaint(rgbaint *rgb, INT16 a, INT16 r, INT16 g, INT16 b)
+{
+ rgb->a = a;
+ rgb->r = r;
+ rgb->g = g;
+ rgb->b = b;
+}
+
+
+/*-------------------------------------------------
+ rgb_to_rgbint - converts a packed trio of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgb_to_rgbint(rgbint *rgb, rgb_t color)
+{
+ rgb->r = RGB_RED(color);
+ rgb->g = RGB_GREEN(color);
+ rgb->b = RGB_BLUE(color);
+}
+
+
+/*-------------------------------------------------
+ rgba_to_rgbaint - converts a packed quad of RGB
+ components to an rgbint type
+-------------------------------------------------*/
+
+INLINE void rgba_to_rgbaint(rgbaint *rgb, rgb_t color)
+{
+ rgb->a = RGB_ALPHA(color);
+ rgb->r = RGB_RED(color);
+ rgb->g = RGB_GREEN(color);
+ rgb->b = RGB_BLUE(color);
+}
+
+
+/*-------------------------------------------------
+ rgbint_to_rgb - converts an rgbint back to
+ a packed trio of RGB values
+-------------------------------------------------*/
+
+INLINE rgb_t rgbint_to_rgb(const rgbint *color)
+{
+ return MAKE_RGB(color->r, color->g, color->b);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_to_rgba - converts an rgbint back to
+ a packed quad of RGB values
+-------------------------------------------------*/
+
+INLINE rgb_t rgbaint_to_rgba(const rgbaint *color)
+{
+ return MAKE_ARGB(color->a, color->r, color->g, color->b);
+}
+
+
+/*-------------------------------------------------
+ rgbint_to_rgb_clamp - converts an rgbint back
+ to a packed trio of RGB values, clamping them
+ to bytes first
+-------------------------------------------------*/
+
+INLINE rgb_t rgbint_to_rgb_clamp(const rgbint *color)
+{
+ UINT8 r = (color->r < 0) ? 0 : (color->r > 255) ? 255 : color->r;
+ UINT8 g = (color->g < 0) ? 0 : (color->g > 255) ? 255 : color->g;
+ UINT8 b = (color->b < 0) ? 0 : (color->b > 255) ? 255 : color->b;
+ return MAKE_RGB(r, g, b);
+}
+
+
+/*-------------------------------------------------
+ rgbaint_to_rgba_clamp - converts an rgbint back
+ to a packed quad of RGB values, clamping them
+ to bytes first
+-------------------------------------------------*/
+
+INLINE rgb_t rgbaint_to_rgba_clamp(const rgbaint *color)
+{
+ UINT8 a = (color->a < 0) ? 0 : (color->a > 255) ? 255 : color->a;
+ UINT8 r = (color->r < 0) ? 0 : (color->r > 255) ? 255 : color->r;
+ UINT8 g = (color->g < 0) ? 0 : (color->g > 255) ? 255 : color->g;
+ UINT8 b = (color->b < 0) ? 0 : (color->b > 255) ? 255 : color->b;
+ return MAKE_ARGB(a, r, g, b);
+}
+
+
+
+/***************************************************************************
+ CORE MATH
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgbint_add - add two rgbint values
+-------------------------------------------------*/
+
+INLINE void rgbint_add(rgbint *color1, const rgbint *color2)
+{
+ color1->r += color2->r;
+ color1->g += color2->g;
+ color1->b += color2->b;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_add - add two rgbaint values
+-------------------------------------------------*/
+
+INLINE void rgbaint_add(rgbaint *color1, const rgbaint *color2)
+{
+ color1->a += color2->a;
+ color1->r += color2->r;
+ color1->g += color2->g;
+ color1->b += color2->b;
+}
+
+
+/*-------------------------------------------------
+ rgbint_sub - subtract two rgbint values
+-------------------------------------------------*/
+
+INLINE void rgbint_sub(rgbint *color1, const rgbint *color2)
+{
+ color1->r -= color2->r;
+ color1->g -= color2->g;
+ color1->b -= color2->b;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_sub - subtract two rgbaint values
+-------------------------------------------------*/
+
+INLINE void rgbaint_sub(rgbaint *color1, const rgbaint *color2)
+{
+ color1->a -= color2->a;
+ color1->r -= color2->r;
+ color1->g -= color2->g;
+ color1->b -= color2->b;
+}
+
+
+/*-------------------------------------------------
+ rgbint_subr - reverse subtract two rgbint
+ values
+-------------------------------------------------*/
+
+INLINE void rgbint_subr(rgbint *color1, const rgbint *color2)
+{
+ color1->r = color2->r - color1->r;
+ color1->g = color2->g - color1->g;
+ color1->b = color2->b - color1->b;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_subr - reverse subtract two rgbaint
+ values
+-------------------------------------------------*/
+
+INLINE void rgbaint_subr(rgbaint *color1, const rgbaint *color2)
+{
+ color1->a = color2->a - color1->a;
+ color1->r = color2->r - color1->r;
+ color1->g = color2->g - color1->g;
+ color1->b = color2->b - color1->b;
+}
+
+
+
+/***************************************************************************
+ HIGHER LEVEL OPERATIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ rgbint_blend - blend two colors by the given
+ scale factor
+-------------------------------------------------*/
+
+INLINE void rgbint_blend(rgbint *color1, const rgbint *color2, UINT8 color1scale)
+{
+ int scale1 = (int)color1scale + 1;
+ int scale2 = 256 - scale1;
+
+ color1->r = (color1->r * scale1 + color2->r * scale2) >> 8;
+ color1->g = (color1->g * scale1 + color2->g * scale2) >> 8;
+ color1->b = (color1->b * scale1 + color2->b * scale2) >> 8;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_blend - blend two colors by the given
+ scale factor
+-------------------------------------------------*/
+
+INLINE void rgbaint_blend(rgbaint *color1, const rgbaint *color2, UINT8 color1scale)
+{
+ int scale1 = (int)color1scale + 1;
+ int scale2 = 256 - scale1;
+
+ color1->a = (color1->a * scale1 + color2->a * scale2) >> 8;
+ color1->r = (color1->r * scale1 + color2->r * scale2) >> 8;
+ color1->g = (color1->g * scale1 + color2->g * scale2) >> 8;
+ color1->b = (color1->b * scale1 + color2->b * scale2) >> 8;
+}
+
+
+/*-------------------------------------------------
+ rgbint_scale_and_clamp - scale the given
+ color by an 8.8 scale factor and clamp to
+ byte values
+-------------------------------------------------*/
+
+INLINE void rgbint_scale_and_clamp(rgbint *color, INT16 colorscale)
+{
+ color->r = (color->r * colorscale) >> 8;
+ if ((UINT16)color->r > 255) { color->r = (color->r < 0) ? 0 : 255; }
+ color->g = (color->g * colorscale) >> 8;
+ if ((UINT16)color->g > 255) { color->g = (color->g < 0) ? 0 : 255; }
+ color->b = (color->b * colorscale) >> 8;
+ if ((UINT16)color->b > 255) { color->b = (color->b < 0) ? 0 : 255; }
+}
+
+
+/*-------------------------------------------------
+ rgbaint_scale_and_clamp - scale the given
+ color by an 8.8 scale factor and clamp to
+ byte values
+-------------------------------------------------*/
+
+INLINE void rgbaint_scale_and_clamp(rgbaint *color, INT16 colorscale)
+{
+ color->a = (color->a * colorscale) >> 8;
+ if ((UINT16)color->a > 255) { color->a = (color->a < 0) ? 0 : 255; }
+ color->r = (color->r * colorscale) >> 8;
+ if ((UINT16)color->r > 255) { color->r = (color->r < 0) ? 0 : 255; }
+ color->g = (color->g * colorscale) >> 8;
+ if ((UINT16)color->g > 255) { color->g = (color->g < 0) ? 0 : 255; }
+ color->b = (color->b * colorscale) >> 8;
+ if ((UINT16)color->b > 255) { color->b = (color->b < 0) ? 0 : 255; }
+}
+
+
+/*-------------------------------------------------
+ rgb_bilinear_filter - bilinear filter between
+ four pixel values; this code is derived from
+ code provided by Michael Herf
+-------------------------------------------------*/
+
+INLINE rgb_t rgb_bilinear_filter(rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ UINT32 ag0, ag1, rb0, rb1;
+
+ rb0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ rb1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+ ag0 = (rgb00 & 0x0000ff00) + ((((rgb01 & 0x0000ff00) - (rgb00 & 0x0000ff00)) * u) >> 8);
+ ag1 = (rgb10 & 0x0000ff00) + ((((rgb11 & 0x0000ff00) - (rgb10 & 0x0000ff00)) * u) >> 8);
+
+ rb0 = (rb0 & 0x00ff00ff) + ((((rb1 & 0x00ff00ff) - (rb0 & 0x00ff00ff)) * v) >> 8);
+ ag0 = (ag0 & 0x0000ff00) + ((((ag1 & 0x0000ff00) - (ag0 & 0x0000ff00)) * v) >> 8);
+
+ return (ag0 & 0x0000ff00) | (rb0 & 0x00ff00ff);
+}
+
+
+/*-------------------------------------------------
+ rgba_bilinear_filter - bilinear filter between
+ four pixel values; this code is derived from
+ code provided by Michael Herf
+-------------------------------------------------*/
+
+INLINE rgb_t rgba_bilinear_filter(rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ UINT32 ag0, ag1, rb0, rb1;
+
+ rb0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ rb1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+ rgb00 >>= 8;
+ rgb01 >>= 8;
+ rgb10 >>= 8;
+ rgb11 >>= 8;
+ ag0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ ag1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+
+ rb0 = (rb0 & 0x00ff00ff) + ((((rb1 & 0x00ff00ff) - (rb0 & 0x00ff00ff)) * v) >> 8);
+ ag0 = (ag0 & 0x00ff00ff) + ((((ag1 & 0x00ff00ff) - (ag0 & 0x00ff00ff)) * v) >> 8);
+
+ return ((ag0 << 8) & 0xff00ff00) | (rb0 & 0x00ff00ff);
+}
+
+
+/*-------------------------------------------------
+ rgbint_bilinear_filter - bilinear filter between
+ four pixel values; this code is derived from
+ code provided by Michael Herf
+-------------------------------------------------*/
+
+INLINE void rgbint_bilinear_filter(rgbint *color, rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ UINT32 ag0, ag1, rb0, rb1;
+
+ rb0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ rb1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+ ag0 = (rgb00 & 0x0000ff00) + ((((rgb01 & 0x0000ff00) - (rgb00 & 0x0000ff00)) * u) >> 8);
+ ag1 = (rgb10 & 0x0000ff00) + ((((rgb11 & 0x0000ff00) - (rgb10 & 0x0000ff00)) * u) >> 8);
+
+ rb0 = (rb0 & 0x00ff00ff) + ((((rb1 & 0x00ff00ff) - (rb0 & 0x00ff00ff)) * v) >> 8);
+ ag0 = (ag0 & 0x0000ff00) + ((((ag1 & 0x0000ff00) - (ag0 & 0x0000ff00)) * v) >> 8);
+
+ color->r = rb0 >> 16;
+ color->g = ag0 >> 8;
+ color->b = rb0;
+}
+
+
+/*-------------------------------------------------
+ rgbaint_bilinear_filter - bilinear filter between
+ four pixel values; this code is derived from
+ code provided by Michael Herf
+-------------------------------------------------*/
+
+INLINE void rgbaint_bilinear_filter(rgbaint *color, rgb_t rgb00, rgb_t rgb01, rgb_t rgb10, rgb_t rgb11, UINT8 u, UINT8 v)
+{
+ UINT32 ag0, ag1, rb0, rb1;
+
+ rb0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ rb1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+ rgb00 >>= 8;
+ rgb01 >>= 8;
+ rgb10 >>= 8;
+ rgb11 >>= 8;
+ ag0 = (rgb00 & 0x00ff00ff) + ((((rgb01 & 0x00ff00ff) - (rgb00 & 0x00ff00ff)) * u) >> 8);
+ ag1 = (rgb10 & 0x00ff00ff) + ((((rgb11 & 0x00ff00ff) - (rgb10 & 0x00ff00ff)) * u) >> 8);
+
+ rb0 = (rb0 & 0x00ff00ff) + ((((rb1 & 0x00ff00ff) - (rb0 & 0x00ff00ff)) * v) >> 8);
+ ag0 = (ag0 & 0x00ff00ff) + ((((ag1 & 0x00ff00ff) - (ag0 & 0x00ff00ff)) * v) >> 8);
+
+ color->a = ag0 >> 16;
+ color->r = rb0 >> 16;
+ color->g = ag0;
+ color->b = rb0;
+}
+
+
+#endif /* __RGBUTIL__ */