summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/lib/util/palette.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/lib/util/palette.c')
-rw-r--r--trunk/src/lib/util/palette.c789
1 files changed, 789 insertions, 0 deletions
diff --git a/trunk/src/lib/util/palette.c b/trunk/src/lib/util/palette.c
new file mode 100644
index 00000000000..6ba369d8bc6
--- /dev/null
+++ b/trunk/src/lib/util/palette.c
@@ -0,0 +1,789 @@
+/******************************************************************************
+
+ palette.c
+
+ Palette handling functions.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+
+#include "palette.h"
+#include <stdlib.h>
+#include <math.h>
+
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+/* object to track dirty states */
+typedef struct _dirty_state dirty_state;
+struct _dirty_state
+{
+ UINT32 * dirty; /* bitmap of dirty entries */
+ UINT32 mindirty; /* minimum dirty entry */
+ UINT32 maxdirty; /* minimum dirty entry */
+};
+
+
+/* a single palette client */
+struct _palette_client
+{
+ palette_client *next; /* pointer to next client */
+ palette_t * palette; /* reference to the palette */
+ dirty_state live; /* live dirty state */
+ dirty_state previous; /* previous dirty state */
+};
+
+
+/* a palette object */
+struct _palette_t
+{
+ UINT32 refcount; /* reference count on the palette */
+ UINT32 numcolors; /* number of colors in the palette */
+ UINT32 numgroups; /* number of groups in the palette */
+
+ float brightness; /* overall brightness value */
+ float contrast; /* overall contrast value */
+ float gamma; /* overall gamma value */
+ UINT8 gamma_map[256]; /* gamma map */
+
+ rgb_t * entry_color; /* array of raw colors */
+ float * entry_contrast; /* contrast value for each entry */
+ rgb_t * adjusted_color; /* array of adjusted colors */
+ rgb_t * adjusted_rgb15; /* array of adjusted colors as RGB15 */
+
+ float * group_bright; /* brightness value for each group */
+ float * group_contrast; /* contrast value for each group */
+
+ palette_client *client_list; /* list of clients for this palette */
+};
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+static void internal_palette_free(palette_t *palette);
+static void update_adjusted_color(palette_t *palette, UINT32 group, UINT32 index);
+
+
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+/*-------------------------------------------------
+ adjust_palette_entry - adjust a palette
+ entry for brightness
+-------------------------------------------------*/
+
+INLINE rgb_t adjust_palette_entry(rgb_t entry, float brightness, float contrast, const UINT8 *gamma_map)
+{
+ int r = rgb_clamp((float)gamma_map[RGB_RED(entry)] * contrast + brightness);
+ int g = rgb_clamp((float)gamma_map[RGB_GREEN(entry)] * contrast + brightness);
+ int b = rgb_clamp((float)gamma_map[RGB_BLUE(entry)] * contrast + brightness);
+ int a = RGB_ALPHA(entry);
+ return MAKE_ARGB(a,r,g,b);
+}
+
+
+
+/***************************************************************************
+ PALETTE ALLOCATION
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_alloc - allocate a new palette object
+ and take a single reference on it
+-------------------------------------------------*/
+
+palette_t *palette_alloc(UINT32 numcolors, UINT32 numgroups)
+{
+ palette_t *palette;
+ UINT32 index;
+
+ /* allocate memory */
+ palette = (palette_t *)malloc(sizeof(*palette));
+ if (palette == NULL)
+ goto error;
+ memset(palette, 0, sizeof(*palette));
+
+ /* initialize overall controls */
+ palette->brightness = 0.0f;
+ palette->contrast = 1.0f;
+ palette->gamma = 1.0f;
+ for (index = 0; index < 256; index++)
+ palette->gamma_map[index] = index;
+
+ /* allocate an array of palette entries and individual contrasts for each */
+ palette->entry_color = (rgb_t *)malloc(sizeof(*palette->entry_color) * numcolors);
+ palette->entry_contrast = (float *)malloc(sizeof(*palette->entry_contrast) * numcolors);
+ if (palette->entry_color == NULL || palette->entry_contrast == NULL)
+ goto error;
+
+ /* initialize the entries */
+ for (index = 0; index < numcolors; index++)
+ {
+ palette->entry_color[index] = RGB_BLACK;
+ palette->entry_contrast[index] = 1.0f;
+ }
+
+ /* allocate an array of brightness and contrast for each group */
+ palette->group_bright = (float *)malloc(sizeof(*palette->group_bright) * numgroups);
+ palette->group_contrast = (float *)malloc(sizeof(*palette->group_contrast) * numgroups);
+ if (palette->group_bright == NULL || palette->group_contrast == NULL)
+ goto error;
+
+ /* initialize the entries */
+ for (index = 0; index < numgroups; index++)
+ {
+ palette->group_bright[index] = 0.0f;
+ palette->group_contrast[index] = 1.0f;
+ }
+
+ /* allocate arrays for the adjusted colors */
+ palette->adjusted_color = (rgb_t *)malloc(sizeof(*palette->adjusted_color) * (numcolors * numgroups + 2));
+ palette->adjusted_rgb15 = (rgb_t *)malloc(sizeof(*palette->adjusted_rgb15) * (numcolors * numgroups + 2));
+ if (palette->adjusted_color == NULL || palette->adjusted_rgb15 == NULL)
+ goto error;
+
+ /* initialize the arrays */
+ for (index = 0; index < numcolors * numgroups; index++)
+ {
+ palette->adjusted_color[index] = RGB_BLACK;
+ palette->adjusted_rgb15[index] = rgb_to_rgb15(RGB_BLACK);
+ }
+
+ /* add black and white as the last two colors */
+ palette->adjusted_color[index] = RGB_BLACK;
+ palette->adjusted_rgb15[index++] = rgb_to_rgb15(RGB_BLACK);
+ palette->adjusted_color[index] = RGB_WHITE;
+ palette->adjusted_rgb15[index++] = rgb_to_rgb15(RGB_WHITE);
+
+ /* initialize the remainder of the structure */
+ palette->refcount = 1;
+ palette->numcolors = numcolors;
+ palette->numgroups = numgroups;
+ return palette;
+
+error:
+ if (palette != NULL)
+ internal_palette_free(palette);
+
+ return NULL;
+}
+
+
+/*-------------------------------------------------
+ palette_ref - reference a palette object,
+ incrementing its reference count
+-------------------------------------------------*/
+
+void palette_ref(palette_t *palette)
+{
+ palette->refcount++;
+}
+
+
+/*-------------------------------------------------
+ palette_deref - dereference a palette object;
+ if the reference count goes to 0, it is freed
+-------------------------------------------------*/
+
+void palette_deref(palette_t *palette)
+{
+ /* if the reference count goes to 0, free */
+ if (--palette->refcount == 0)
+ internal_palette_free(palette);
+}
+
+
+
+/***************************************************************************
+ PALETTE INFORMATION
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_get_num_colors - return the number of
+ colors allocated in the palette
+-------------------------------------------------*/
+
+int palette_get_num_colors(palette_t *palette)
+{
+ return palette->numcolors;
+}
+
+
+/*-------------------------------------------------
+ palette_get_num_groups - return the number of
+ groups managed by the palette
+-------------------------------------------------*/
+
+int palette_get_num_groups(palette_t *palette)
+{
+ return palette->numgroups;
+}
+
+
+/*-------------------------------------------------
+ palette_get_max_index - return the maximum
+ allowed index (i.e., length of arrays returned
+ by palette_entry_list*)
+-------------------------------------------------*/
+
+int palette_get_max_index(palette_t *palette)
+{
+ return palette->numcolors * palette->numgroups + 2;
+}
+
+
+/*-------------------------------------------------
+ palette_get_black_entry - return the index of
+ the black entry
+-------------------------------------------------*/
+
+UINT32 palette_get_black_entry(palette_t *palette)
+{
+ return palette->numcolors * palette->numgroups + 0;
+}
+
+
+/*-------------------------------------------------
+ palette_get_white_entry - return the index of
+ the white entry
+-------------------------------------------------*/
+
+UINT32 palette_get_white_entry(palette_t *palette)
+{
+ return palette->numcolors * palette->numgroups + 1;
+}
+
+
+
+/***************************************************************************
+ PALETTE CLIENTS
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_client_alloc - add a new client to a
+ palette
+-------------------------------------------------*/
+
+palette_client *palette_client_alloc(palette_t *palette)
+{
+ UINT32 total_colors = palette->numcolors * palette->numgroups;
+ UINT32 dirty_dwords = (total_colors + 31) / 32;
+ palette_client *client;
+
+ /* allocate memory for the client */
+ client = (palette_client *)malloc(sizeof(*client));
+ if (client == NULL)
+ goto error;
+ memset(client, 0, sizeof(*client));
+
+ /* allocate dirty lists */
+ client->live.dirty = (UINT32 *)malloc(dirty_dwords * sizeof(UINT32));
+ client->previous.dirty = (UINT32 *)malloc(dirty_dwords * sizeof(UINT32));
+ if (client->live.dirty == NULL || client->previous.dirty == NULL)
+ goto error;
+
+ /* mark everything dirty to start with */
+ memset(client->live.dirty, 0xff, dirty_dwords * sizeof(UINT32));
+ memset(client->previous.dirty, 0xff, dirty_dwords * sizeof(UINT32));
+ client->live.dirty[dirty_dwords - 1] &= (1 << (total_colors % 32)) - 1;
+ client->previous.dirty[dirty_dwords - 1] &= (1 << (total_colors % 32)) - 1;
+
+ /* initialize the rest of the structure and add a reference to a palette */
+ client->palette = palette;
+ palette_ref(palette);
+ client->live.mindirty = 0;
+ client->live.maxdirty = total_colors - 1;
+
+ /* now add us to the list of clients */
+ client->next = palette->client_list;
+ palette->client_list = client;
+ return client;
+
+error:
+ if (client != NULL)
+ {
+ if (client->live.dirty != NULL)
+ free(client->live.dirty);
+ if (client->previous.dirty != NULL)
+ free(client->previous.dirty);
+ free(client);
+ }
+ return NULL;
+}
+
+
+/*-------------------------------------------------
+ palette_client_free - remove a client from a
+ palette
+-------------------------------------------------*/
+
+void palette_client_free(palette_client *client)
+{
+ palette_client **curptr;
+
+ /* first locate and remove ourself from the palette's list */
+ for (curptr = &client->palette->client_list; *curptr != NULL; curptr = &(*curptr)->next)
+ if (*curptr == client)
+ {
+ *curptr = client->next;
+ break;
+ }
+
+ /* now deref the palette */
+ palette_deref(client->palette);
+
+ /* free our data */
+ if (client->live.dirty != NULL)
+ free(client->live.dirty);
+ if (client->previous.dirty != NULL)
+ free(client->previous.dirty);
+ free(client);
+}
+
+
+/*-------------------------------------------------
+ palette_client_get_palette - return a pointer
+ to the palette for this client
+-------------------------------------------------*/
+
+palette_t *palette_client_get_palette(palette_client *client)
+{
+ return client->palette;
+}
+
+
+/*-------------------------------------------------
+ palette_client_get_dirty_list - atomically get
+ the current dirty list for a client
+-------------------------------------------------*/
+
+const UINT32 *palette_client_get_dirty_list(palette_client *client, UINT32 *mindirty, UINT32 *maxdirty)
+{
+ dirty_state temp;
+
+ /* fill in the mindirty/maxdirty */
+ if (mindirty != NULL)
+ *mindirty = client->live.mindirty;
+ if (maxdirty != NULL)
+ *maxdirty = client->live.maxdirty;
+
+ /* if nothing to report, report nothing and don't swap */
+ if (client->live.mindirty > client->live.maxdirty)
+ return NULL;
+
+ /* swap the live and previous lists */
+ temp = client->live;
+ client->live = client->previous;
+ client->previous = temp;
+
+ /* erase relevant entries in the new live one */
+ if (client->live.mindirty <= client->live.maxdirty)
+ memset(client->live.dirty, client->live.mindirty / 8, (client->live.maxdirty / 8) + 1 - (client->live.mindirty / 8));
+ client->live.mindirty = client->palette->numcolors * client->palette->numgroups;
+ client->live.maxdirty = 0;
+
+ /* return a pointer to the previous table */
+ return client->previous.dirty;
+}
+
+
+
+/***************************************************************************
+ PALETTE COLOR MANAGEMENT
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_entry_set_color - set the raw RGB
+ color for a given palette index
+-------------------------------------------------*/
+
+void palette_entry_set_color(palette_t *palette, UINT32 index, rgb_t rgb)
+{
+ int groupnum;
+
+ /* if out of range, or unchanged, ignore */
+ if (index >= palette->numcolors || palette->entry_color[index] == rgb)
+ return;
+
+ /* set the color */
+ palette->entry_color[index] = rgb;
+
+ /* update across all groups */
+ for (groupnum = 0; groupnum < palette->numgroups; groupnum++)
+ update_adjusted_color(palette, groupnum, index);
+}
+
+
+/*-------------------------------------------------
+ palette_entry_get_color - return the raw RGB
+ color for a given palette index
+-------------------------------------------------*/
+
+rgb_t palette_entry_get_color(palette_t *palette, UINT32 index)
+{
+ return (index < palette->numcolors) ? palette->entry_color[index] : RGB_BLACK;
+}
+
+
+/*-------------------------------------------------
+ palette_entry_get_adjusted_color - return the
+ adjusted RGB color (after all adjustments) for
+ a given palette index
+-------------------------------------------------*/
+
+rgb_t palette_entry_get_adjusted_color(palette_t *palette, UINT32 index)
+{
+ return (index < palette->numcolors * palette->numgroups) ? palette->adjusted_color[index] : RGB_BLACK;
+}
+
+
+/*-------------------------------------------------
+ palette_entry_list_raw - return the entire
+ palette as an array of raw RGB values
+-------------------------------------------------*/
+
+const rgb_t *palette_entry_list_raw(palette_t *palette)
+{
+ return palette->entry_color;
+}
+
+
+/*-------------------------------------------------
+ palette_entry_list_adjusted - return the
+ entire palette as an array of adjusted RGB
+ values
+-------------------------------------------------*/
+
+const rgb_t *palette_entry_list_adjusted(palette_t *palette)
+{
+ return palette->adjusted_color;
+}
+
+
+/*-------------------------------------------------
+ palette_entry_list_adjusted_rgb15 - return the
+ entire palette as an array of adjusted RGB-15
+ values
+-------------------------------------------------*/
+
+const rgb_t *palette_entry_list_adjusted_rgb15(palette_t *palette)
+{
+ return palette->adjusted_rgb15;
+}
+
+
+
+/***************************************************************************
+ PALETTE ADJUSTMENTS
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_set_brightness - set the overall
+ brightness for the palette
+-------------------------------------------------*/
+
+void palette_set_brightness(palette_t *palette, float brightness)
+{
+ int groupnum, index;
+
+ /* convert incoming value to normalized result */
+ brightness = (brightness - 1.0f) * 256.0f;
+
+ /* set the global brightness if changed */
+ if (palette->brightness == brightness)
+ return;
+ palette->brightness = brightness;
+
+ /* update across all indices in all groups */
+ for (groupnum = 0; groupnum < palette->numgroups; groupnum++)
+ for (index = 0; index < palette->numcolors; index++)
+ update_adjusted_color(palette, groupnum, index);
+}
+
+
+/*-------------------------------------------------
+ palette_set_contrast - set the overall
+ contrast for the palette
+-------------------------------------------------*/
+
+void palette_set_contrast(palette_t *palette, float contrast)
+{
+ int groupnum, index;
+
+ /* set the global contrast if changed */
+ if (palette->contrast == contrast)
+ return;
+ palette->contrast = contrast;
+
+ /* update across all indices in all groups */
+ for (groupnum = 0; groupnum < palette->numgroups; groupnum++)
+ for (index = 0; index < palette->numcolors; index++)
+ update_adjusted_color(palette, groupnum, index);
+}
+
+
+/*-------------------------------------------------
+ palette_set_gamma - set the overall
+ gamma for the palette
+-------------------------------------------------*/
+
+void palette_set_gamma(palette_t *palette, float gamma)
+{
+ int groupnum, index;
+
+ /* set the global gamma if changed */
+ if (palette->gamma == gamma)
+ return;
+ palette->gamma = gamma;
+
+ /* recompute the gamma map */
+ gamma = 1.0f / gamma;
+ for (index = 0; index < 256; index++)
+ {
+ float fval = (float)index * (1.0f / 255.0f);
+ float fresult = pow(fval, gamma);
+ palette->gamma_map[index] = rgb_clamp(255.0f * fresult);
+ }
+
+ /* update across all indices in all groups */
+ for (groupnum = 0; groupnum < palette->numgroups; groupnum++)
+ for (index = 0; index < palette->numcolors; index++)
+ update_adjusted_color(palette, groupnum, index);
+}
+
+
+/*-------------------------------------------------
+ palette_entry_set_contrast - set the contrast
+ adjustment for a single palette index
+-------------------------------------------------*/
+
+void palette_entry_set_contrast(palette_t *palette, UINT32 index, float contrast)
+{
+ int groupnum;
+
+ /* if out of range, or unchanged, ignore */
+ if (index >= palette->numcolors || palette->entry_contrast[index] == contrast)
+ return;
+
+ /* set the contrast */
+ palette->entry_contrast[index] = contrast;
+
+ /* update across all groups */
+ for (groupnum = 0; groupnum < palette->numgroups; groupnum++)
+ update_adjusted_color(palette, groupnum, index);
+}
+
+
+/*-------------------------------------------------
+ palette_entry_get_contrast - return the
+ contrast adjustment for a single palette index
+-------------------------------------------------*/
+
+float palette_entry_get_contrast(palette_t *palette, UINT32 index)
+{
+ return (index < palette->numcolors) ? palette->entry_contrast[index] : 1.0f;
+}
+
+
+/*-------------------------------------------------
+ palette_group_set_brightness - configure
+ overall brightness for a palette group
+-------------------------------------------------*/
+
+void palette_group_set_brightness(palette_t *palette, UINT32 group, float brightness)
+{
+ int index;
+
+ /* convert incoming value to normalized result */
+ brightness = (brightness - 1.0f) * 256.0f;
+
+ /* if out of range, or unchanged, ignore */
+ if (group >= palette->numgroups || palette->group_bright[group] == brightness)
+ return;
+
+ /* set the contrast */
+ palette->group_bright[group] = brightness;
+
+ /* update across all colors */
+ for (index = 0; index < palette->numcolors; index++)
+ update_adjusted_color(palette, group, index);
+}
+
+
+/*-------------------------------------------------
+ palette_group_set_contrast - configure
+ overall contrast for a palette group
+-------------------------------------------------*/
+
+void palette_group_set_contrast(palette_t *palette, UINT32 group, float contrast)
+{
+ int index;
+
+ /* if out of range, or unchanged, ignore */
+ if (group >= palette->numgroups || palette->group_contrast[group] == contrast)
+ return;
+
+ /* set the contrast */
+ palette->group_contrast[group] = contrast;
+
+ /* update across all colors */
+ for (index = 0; index < palette->numcolors; index++)
+ update_adjusted_color(palette, group, index);
+}
+
+
+
+/***************************************************************************
+ PALETTE UTILITIES
+***************************************************************************/
+
+/*-------------------------------------------------
+ palette_normalize_range - normalize a range
+ of palette entries
+-------------------------------------------------*/
+
+void palette_normalize_range(palette_t *palette, UINT32 start, UINT32 end, int lum_min, int lum_max)
+{
+ INT32 ymin = 1000 * 255, ymax = 0;
+ INT32 tmin, tmax;
+ UINT32 index;
+
+ /* clamp within range */
+ start = MAX(start, 0);
+ end = MIN(end, palette->numcolors - 1);
+
+ /* find the minimum and maximum brightness of all the colors in the range */
+ for (index = start; index <= end; index++)
+ {
+ rgb_t rgb = palette->entry_color[index];
+ UINT32 y = 299 * RGB_RED(rgb) + 587 * RGB_GREEN(rgb) + 114 * RGB_BLUE(rgb);
+ ymin = MIN(ymin, y);
+ ymax = MAX(ymax, y);
+ }
+
+ /* determine target minimum/maximum */
+ tmin = (lum_min < 0) ? ((ymin + 500) / 1000) : lum_min;
+ tmax = (lum_max < 0) ? ((ymax + 500) / 1000) : lum_max;
+
+ /* now normalize the palette */
+ for (index = start; index <= end; index++)
+ {
+ rgb_t rgb = palette->entry_color[index];
+ INT32 y = 299 * RGB_RED(rgb) + 587 * RGB_GREEN(rgb) + 114 * RGB_BLUE(rgb);
+ INT32 u = ((INT32)RGB_BLUE(rgb)-y /1000)*492 / 1000;
+ INT32 v = ((INT32)RGB_RED(rgb)-y / 1000)*877 / 1000;
+ INT32 target = tmin + ((y - ymin) * (tmax - tmin + 1)) / (ymax - ymin);
+ UINT8 r = rgb_clamp(target + 1140 * v / 1000);
+ UINT8 g = rgb_clamp(target - 395 * u / 1000 - 581 * v / 1000);
+ UINT8 b = rgb_clamp(target + 2032 * u / 1000);
+ palette_entry_set_color(palette, index, MAKE_RGB(r, g, b));
+ }
+}
+
+
+
+/***************************************************************************
+ INTERNAL ROUTINES
+***************************************************************************/
+
+/*-------------------------------------------------
+ internal_palette_free - free all allocations
+ from a palette
+-------------------------------------------------*/
+
+static void internal_palette_free(palette_t *palette)
+{
+ /* free per-color data */
+ if (palette->entry_color != NULL)
+ free(palette->entry_color);
+ if (palette->entry_contrast != NULL)
+ free(palette->entry_contrast);
+
+ /* free per-group data */
+ if (palette->group_bright != NULL)
+ free(palette->group_bright);
+ if (palette->group_contrast != NULL)
+ free(palette->group_contrast);
+
+ /* free adjusted data */
+ if (palette->adjusted_color != NULL)
+ free(palette->adjusted_color);
+ if (palette->adjusted_rgb15 != NULL)
+ free(palette->adjusted_rgb15);
+
+ /* and the palette itself */
+ free(palette);
+}
+
+
+/*-------------------------------------------------
+ update_adjusted_color - update a color index
+ by group and index pair
+-------------------------------------------------*/
+
+static void update_adjusted_color(palette_t *palette, UINT32 group, UINT32 index)
+{
+ UINT32 finalindex = group * palette->numcolors + index;
+ palette_client *client;
+ rgb_t adjusted;
+
+ /* compute the adjusted value */
+ adjusted = adjust_palette_entry(palette->entry_color[index],
+ palette->group_bright[group] + palette->brightness,
+ palette->group_contrast[group] * palette->entry_contrast[index] * palette->contrast,
+ palette->gamma_map);
+
+ /* if not different, ignore */
+ if (palette->adjusted_color[finalindex] == adjusted)
+ return;
+
+ /* otherwise, modify the adjusted color array */
+ palette->adjusted_color[finalindex] = adjusted;
+ palette->adjusted_rgb15[finalindex] = rgb_to_rgb15(adjusted);
+
+ /* mark dirty in all clients */
+ for (client = palette->client_list; client != NULL; client = client->next)
+ {
+ client->live.dirty[finalindex / 32] |= 1 << (finalindex % 32);
+ client->live.mindirty = MIN(client->live.mindirty, finalindex);
+ client->live.maxdirty = MAX(client->live.maxdirty, finalindex);
+ }
+}