From 8cff33e681deb963b8a48ef939be1eefebba76d9 Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 20 Jan 2024 01:47:03 -0300 Subject: [PATCH] Changes: Ported skincolor cache management from the secondcolor branch Adjusted R_GetTranslationRemap to use a similar caching scheme Made sure that if a skincolor was updated, then related translations would be rebuilt --- src/r_defs.h | 3 -- src/r_draw.c | 85 ++++++++++++++++++++------------------------- src/r_draw.h | 21 +++++++++++ src/r_translation.c | 51 ++++++++++++++++++++------- src/r_translation.h | 13 ++++--- 5 files changed, 105 insertions(+), 68 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 39e6765cd..16c660b01 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -26,9 +26,6 @@ #include "taglist.h" -// Amount of colors in the palette -#define NUM_PALETTE_ENTRIES 256 - // // ClipWallSegment // Clips the given range of columns diff --git a/src/r_draw.c b/src/r_draw.c index b87a8404e..ff2e43df3 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -125,49 +125,37 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; // TRANSLATION COLORMAP CODE // ========================================================================= -enum -{ - DEFAULT_TT_CACHE_INDEX, - BOSS_TT_CACHE_INDEX, - METALSONIC_TT_CACHE_INDEX, - ALLWHITE_TT_CACHE_INDEX, - RAINBOW_TT_CACHE_INDEX, - BLINK_TT_CACHE_INDEX, - DASHMODE_TT_CACHE_INDEX, - - TT_CACHE_SIZE -}; - -static UINT8 **translationtablecache[TT_CACHE_SIZE] = {NULL}; -static UINT8 **skintranslationcache[NUM_PALETTE_ENTRIES] = {NULL}; +static colorcache_t **translationtablecache[TT_CACHE_SIZE] = {NULL}; boolean skincolor_modified[MAXSKINCOLORS]; -static INT32 TranslationToCacheIndex(INT32 translation) +static INT32 SkinToCacheIndex(INT32 translation) { switch (translation) { + case TC_DEFAULT: return DEFAULT_TT_CACHE_INDEX; case TC_BOSS: return BOSS_TT_CACHE_INDEX; case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX; case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX; case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX; case TC_BLINK: return BLINK_TT_CACHE_INDEX; case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX; - default: return DEFAULT_TT_CACHE_INDEX; + default: return translation; } } -static INT32 CacheIndexToTranslation(INT32 index) +static INT32 CacheIndexToSkin(INT32 index) { switch (index) { + case DEFAULT_TT_CACHE_INDEX: return TC_DEFAULT; case BOSS_TT_CACHE_INDEX: return TC_BOSS; case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC; case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE; case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW; case BLINK_TT_CACHE_INDEX: return TC_BLINK; case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE; - default: return TC_DEFAULT; + default: return index; } } @@ -553,23 +541,22 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 translatio */ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags) { - UINT8 ***cache = NULL; - INT32 index, starttranscolor; - UINT8 *ret; + colorcache_t *ret; + INT32 index = 0; + INT32 starttranscolor = DEFAULT_STARTTRANSCOLOR; // Adjust if we want the default colormap if (skinnum >= numskins) I_Error("Invalid skin number %d", skinnum); else if (skinnum >= 0) { - cache = skintranslationcache; - starttranscolor = index = skins[skinnum]->starttranscolor; + index = skins[skinnum]->skinnum; + starttranscolor = skins[skinnum]->starttranscolor; } else if (skinnum <= TC_DEFAULT) { - cache = translationtablecache; - starttranscolor = DEFAULT_STARTTRANSCOLOR; - index = TranslationToCacheIndex(skinnum); + // Do default translation + index = SkinToCacheIndex(skinnum); } else I_Error("Invalid translation %d", skinnum); @@ -577,41 +564,48 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags if (flags & GTC_CACHE) { // Allocate table for skin if necessary - if (!cache[index]) - cache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL); + if (!translationtablecache[index]) + translationtablecache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(colorcache_t**), PU_STATIC, NULL); // Get colormap - ret = cache[index][color]; + ret = translationtablecache[index][color]; // Rebuild the cache if necessary if (skincolor_modified[color]) { - INT32 i; - - for (i = 0; i < TT_CACHE_SIZE; i++) - if (translationtablecache[i] && translationtablecache[i][color]) - R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToTranslation(i), color, starttranscolor); - for (i = 0; i < NUM_PALETTE_ENTRIES; i++) - if (skintranslationcache[i] && skintranslationcache[i][color]) - R_GenerateTranslationColormap(skintranslationcache[i][color], 0, color, i); - + // Moved up here so that R_UpdateTranslationRemaps doesn't cause a stack overflow, + // since in this situation, it will call R_GetTranslationColormap skincolor_modified[color] = false; + + for (unsigned i = 0; i < TT_CACHE_SIZE; i++) + { + if (translationtablecache[i]) + { + colorcache_t *cache = translationtablecache[i][color]; + if (cache) + { + R_GenerateTranslationColormap(cache->colors, CacheIndexToSkin(i), color, starttranscolor); + R_UpdateTranslationRemaps(color, i); + } + } + } } } - else ret = NULL; + else + ret = NULL; // Generate the colormap if necessary if (!ret) { - ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8); - R_GenerateTranslationColormap(ret, skinnum, color, starttranscolor); + ret = Z_Malloc(sizeof(colorcache_t), (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL); + R_GenerateTranslationColormap(ret->colors, skinnum, color, starttranscolor); // Cache the colormap if desired if (flags & GTC_CACHE) - cache[index][color] = ret; + translationtablecache[index][color] = ret; } - return ret; + return ret->colors; } /** \brief Flushes cache of translation colormaps. @@ -629,9 +623,6 @@ void R_FlushTranslationColormapCache(void) for (i = 0; i < TT_CACHE_SIZE; i++) if (translationtablecache[i]) memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**)); - for (i = 0; i < NUM_PALETTE_ENTRIES; i++) - if (skintranslationcache[i]) - memset(skintranslationcache[i], 0, MAXSKINCOLORS * sizeof(UINT8**)); } UINT16 R_GetColorByName(const char *name) diff --git a/src/r_draw.h b/src/r_draw.h index 9cde3cf54..29370015a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -117,6 +117,27 @@ enum TC_DEFAULT }; +// Amount of colors in the palette +#define NUM_PALETTE_ENTRIES 256 + +typedef struct colorcache_s +{ + UINT8 colors[NUM_PALETTE_ENTRIES]; +} colorcache_t; + +enum +{ + DEFAULT_TT_CACHE_INDEX = MAXSKINS, + BOSS_TT_CACHE_INDEX, + METALSONIC_TT_CACHE_INDEX, + ALLWHITE_TT_CACHE_INDEX, + RAINBOW_TT_CACHE_INDEX, + BLINK_TT_CACHE_INDEX, + DASHMODE_TT_CACHE_INDEX, + + TT_CACHE_SIZE +}; + // Custom player skin translation // Initialize color translation tables, for player rendering etc. UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags); diff --git a/src/r_translation.c b/src/r_translation.c index 3799c87cd..7e1e30d0c 100644 --- a/src/r_translation.c +++ b/src/r_translation.c @@ -1103,6 +1103,17 @@ remaptable_t *R_GetTranslationByID(int id) return paletteremaps[id]; } +static void R_ApplyTranslationRemap(remaptable_t *tr, UINT8 *remap, skincolornum_t skincolor, INT32 skinnum) +{ + UINT8 *base_skincolor = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); + + for (unsigned i = 0; i < NUM_PALETTE_ENTRIES; i++) + remap[i] = base_skincolor[i]; + + for (unsigned i = 0; i < tr->num_sources; i++) + PaletteRemap_Apply(remap, &tr->sources[i]); +} + UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum) { remaptable_t *tr = R_GetTranslationByID(id); @@ -1112,25 +1123,39 @@ UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum) if (!tr->num_sources || skincolor == SKINCOLOR_NONE) return tr->remap; - if (!tr->skincolor_remap) - tr->skincolor_remap = Z_Calloc(NUM_PALETTE_ENTRIES * MAXSKINCOLORS, PU_LEVEL, &tr->skincolor_remap); + if (!tr->skincolor_remaps) + Z_Calloc(sizeof(*tr->skincolor_remaps) * TT_CACHE_SIZE, PU_LEVEL, &tr->skincolor_remaps); - if (!tr->skincolor_remap[skincolor]) + if (!tr->skincolor_remaps[skinnum]) + tr->skincolor_remaps[skinnum] = Z_Calloc(NUM_PALETTE_ENTRIES * MAXSKINCOLORS, PU_LEVEL, NULL); + + colorcache_t *cache = tr->skincolor_remaps[skinnum][skincolor]; + if (!cache) { - UINT8 *remap = Z_Calloc(NUM_PALETTE_ENTRIES, PU_LEVEL, NULL); + cache = Z_Calloc(sizeof(colorcache_t), PU_LEVEL, NULL); - UINT8 *base_skincolor = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); + R_ApplyTranslationRemap(tr, cache->colors, skincolor, skinnum); - for (unsigned i = 0; i < NUM_PALETTE_ENTRIES; i++) - remap[i] = base_skincolor[i]; - - for (unsigned i = 0; i < tr->num_sources; i++) - PaletteRemap_Apply(remap, &tr->sources[i]); - - tr->skincolor_remap[skincolor] = remap; + tr->skincolor_remaps[skinnum][skincolor] = cache; } - return tr->skincolor_remap[skincolor]; + return cache->colors; +} + +static void R_UpdateTranslation(remaptable_t *tr, skincolornum_t skincolor, INT32 skinnum) +{ + if (!tr->num_sources || !tr->skincolor_remaps || !tr->skincolor_remaps[skinnum]) + return; + + colorcache_t *cache = tr->skincolor_remaps[skinnum][skincolor]; + if (cache) + R_ApplyTranslationRemap(tr, cache->colors, skincolor, skinnum); +} + +void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 skinnum) +{ + for (unsigned i = 0; i < numpaletteremaps; i++) + R_UpdateTranslation(paletteremaps[i], skincolor, skinnum); } boolean R_TranslationIsValid(int id) diff --git a/src/r_translation.h b/src/r_translation.h index 794eb063c..1eb40233d 100644 --- a/src/r_translation.h +++ b/src/r_translation.h @@ -15,6 +15,8 @@ #include "doomdef.h" +#include "r_draw.h" + typedef enum { REMAP_ADD_INDEXRANGE, @@ -58,16 +60,16 @@ typedef struct typedef struct { - UINT8 remap[256]; + UINT8 remap[NUM_PALETTE_ENTRIES]; unsigned num_entries; paletteremap_t *sources; unsigned num_sources; - // A typical remap is 256 bytes long, and there is currently a maximum of 1182 skincolors. - // This means allocating (1182 * 256) bytes, which equals 302592, or ~302kb of memory for every translation. - // So we allocate a list instead. - UINT8 **skincolor_remap; + // A typical remap is 256 bytes long, and there is currently a maximum of 1182 skincolors, and 263 possible color cache entries. + // This would mean allocating (1182 * 256 * 263) bytes, which equals 79581696 bytes, or ~79mb of memory for every remap. + // So instead a few lists are allocated. + colorcache_t ***skincolor_remaps; } remaptable_t; void PaletteRemap_Init(void); @@ -85,6 +87,7 @@ const char *R_GetCustomTranslationName(unsigned id); unsigned R_NumCustomTranslations(void); remaptable_t *R_GetTranslationByID(int id); UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum); +void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 skinnum); boolean R_TranslationIsValid(int id); void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum);