mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-22 04:21:23 +00:00
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
This commit is contained in:
parent
9851ec56cf
commit
8cff33e681
5 changed files with 105 additions and 68 deletions
|
@ -26,9 +26,6 @@
|
||||||
|
|
||||||
#include "taglist.h"
|
#include "taglist.h"
|
||||||
|
|
||||||
// Amount of colors in the palette
|
|
||||||
#define NUM_PALETTE_ENTRIES 256
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ClipWallSegment
|
// ClipWallSegment
|
||||||
// Clips the given range of columns
|
// Clips the given range of columns
|
||||||
|
|
85
src/r_draw.c
85
src/r_draw.c
|
@ -125,49 +125,37 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
|
||||||
// TRANSLATION COLORMAP CODE
|
// TRANSLATION COLORMAP CODE
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
enum
|
static colorcache_t **translationtablecache[TT_CACHE_SIZE] = {NULL};
|
||||||
{
|
|
||||||
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};
|
|
||||||
|
|
||||||
boolean skincolor_modified[MAXSKINCOLORS];
|
boolean skincolor_modified[MAXSKINCOLORS];
|
||||||
|
|
||||||
static INT32 TranslationToCacheIndex(INT32 translation)
|
static INT32 SkinToCacheIndex(INT32 translation)
|
||||||
{
|
{
|
||||||
switch (translation)
|
switch (translation)
|
||||||
{
|
{
|
||||||
|
case TC_DEFAULT: return DEFAULT_TT_CACHE_INDEX;
|
||||||
case TC_BOSS: return BOSS_TT_CACHE_INDEX;
|
case TC_BOSS: return BOSS_TT_CACHE_INDEX;
|
||||||
case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX;
|
case TC_METALSONIC: return METALSONIC_TT_CACHE_INDEX;
|
||||||
case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX;
|
case TC_ALLWHITE: return ALLWHITE_TT_CACHE_INDEX;
|
||||||
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
|
case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX;
|
||||||
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
|
case TC_BLINK: return BLINK_TT_CACHE_INDEX;
|
||||||
case TC_DASHMODE: return DASHMODE_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)
|
switch (index)
|
||||||
{
|
{
|
||||||
|
case DEFAULT_TT_CACHE_INDEX: return TC_DEFAULT;
|
||||||
case BOSS_TT_CACHE_INDEX: return TC_BOSS;
|
case BOSS_TT_CACHE_INDEX: return TC_BOSS;
|
||||||
case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC;
|
case METALSONIC_TT_CACHE_INDEX: return TC_METALSONIC;
|
||||||
case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE;
|
case ALLWHITE_TT_CACHE_INDEX: return TC_ALLWHITE;
|
||||||
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
|
case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW;
|
||||||
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
|
case BLINK_TT_CACHE_INDEX: return TC_BLINK;
|
||||||
case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE;
|
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* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags)
|
||||||
{
|
{
|
||||||
UINT8 ***cache = NULL;
|
colorcache_t *ret;
|
||||||
INT32 index, starttranscolor;
|
INT32 index = 0;
|
||||||
UINT8 *ret;
|
INT32 starttranscolor = DEFAULT_STARTTRANSCOLOR;
|
||||||
|
|
||||||
// Adjust if we want the default colormap
|
// Adjust if we want the default colormap
|
||||||
if (skinnum >= numskins)
|
if (skinnum >= numskins)
|
||||||
I_Error("Invalid skin number %d", skinnum);
|
I_Error("Invalid skin number %d", skinnum);
|
||||||
else if (skinnum >= 0)
|
else if (skinnum >= 0)
|
||||||
{
|
{
|
||||||
cache = skintranslationcache;
|
index = skins[skinnum]->skinnum;
|
||||||
starttranscolor = index = skins[skinnum]->starttranscolor;
|
starttranscolor = skins[skinnum]->starttranscolor;
|
||||||
}
|
}
|
||||||
else if (skinnum <= TC_DEFAULT)
|
else if (skinnum <= TC_DEFAULT)
|
||||||
{
|
{
|
||||||
cache = translationtablecache;
|
// Do default translation
|
||||||
starttranscolor = DEFAULT_STARTTRANSCOLOR;
|
index = SkinToCacheIndex(skinnum);
|
||||||
index = TranslationToCacheIndex(skinnum);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
I_Error("Invalid translation %d", skinnum);
|
I_Error("Invalid translation %d", skinnum);
|
||||||
|
@ -577,41 +564,48 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
|
||||||
if (flags & GTC_CACHE)
|
if (flags & GTC_CACHE)
|
||||||
{
|
{
|
||||||
// Allocate table for skin if necessary
|
// Allocate table for skin if necessary
|
||||||
if (!cache[index])
|
if (!translationtablecache[index])
|
||||||
cache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
|
translationtablecache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(colorcache_t**), PU_STATIC, NULL);
|
||||||
|
|
||||||
// Get colormap
|
// Get colormap
|
||||||
ret = cache[index][color];
|
ret = translationtablecache[index][color];
|
||||||
|
|
||||||
// Rebuild the cache if necessary
|
// Rebuild the cache if necessary
|
||||||
if (skincolor_modified[color])
|
if (skincolor_modified[color])
|
||||||
{
|
{
|
||||||
INT32 i;
|
// Moved up here so that R_UpdateTranslationRemaps doesn't cause a stack overflow,
|
||||||
|
// since in this situation, it will call R_GetTranslationColormap
|
||||||
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);
|
|
||||||
|
|
||||||
skincolor_modified[color] = false;
|
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
|
// Generate the colormap if necessary
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
|
ret = Z_Malloc(sizeof(colorcache_t), (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL);
|
||||||
R_GenerateTranslationColormap(ret, skinnum, color, starttranscolor);
|
R_GenerateTranslationColormap(ret->colors, skinnum, color, starttranscolor);
|
||||||
|
|
||||||
// Cache the colormap if desired
|
// Cache the colormap if desired
|
||||||
if (flags & GTC_CACHE)
|
if (flags & GTC_CACHE)
|
||||||
cache[index][color] = ret;
|
translationtablecache[index][color] = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret->colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Flushes cache of translation colormaps.
|
/** \brief Flushes cache of translation colormaps.
|
||||||
|
@ -629,9 +623,6 @@ void R_FlushTranslationColormapCache(void)
|
||||||
for (i = 0; i < TT_CACHE_SIZE; i++)
|
for (i = 0; i < TT_CACHE_SIZE; i++)
|
||||||
if (translationtablecache[i])
|
if (translationtablecache[i])
|
||||||
memset(translationtablecache[i], 0, MAXSKINCOLORS * sizeof(UINT8**));
|
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)
|
UINT16 R_GetColorByName(const char *name)
|
||||||
|
|
21
src/r_draw.h
21
src/r_draw.h
|
@ -117,6 +117,27 @@ enum
|
||||||
TC_DEFAULT
|
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
|
// Custom player skin translation
|
||||||
// Initialize color translation tables, for player rendering etc.
|
// Initialize color translation tables, for player rendering etc.
|
||||||
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags);
|
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags);
|
||||||
|
|
|
@ -1103,6 +1103,17 @@ remaptable_t *R_GetTranslationByID(int id)
|
||||||
return paletteremaps[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)
|
UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum)
|
||||||
{
|
{
|
||||||
remaptable_t *tr = R_GetTranslationByID(id);
|
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)
|
if (!tr->num_sources || skincolor == SKINCOLOR_NONE)
|
||||||
return tr->remap;
|
return tr->remap;
|
||||||
|
|
||||||
if (!tr->skincolor_remap)
|
if (!tr->skincolor_remaps)
|
||||||
tr->skincolor_remap = Z_Calloc(NUM_PALETTE_ENTRIES * MAXSKINCOLORS, PU_LEVEL, &tr->skincolor_remap);
|
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++)
|
tr->skincolor_remaps[skinnum][skincolor] = cache;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
boolean R_TranslationIsValid(int id)
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
|
||||||
|
#include "r_draw.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
REMAP_ADD_INDEXRANGE,
|
REMAP_ADD_INDEXRANGE,
|
||||||
|
@ -58,16 +60,16 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
UINT8 remap[256];
|
UINT8 remap[NUM_PALETTE_ENTRIES];
|
||||||
unsigned num_entries;
|
unsigned num_entries;
|
||||||
|
|
||||||
paletteremap_t *sources;
|
paletteremap_t *sources;
|
||||||
unsigned num_sources;
|
unsigned num_sources;
|
||||||
|
|
||||||
// A typical remap is 256 bytes long, and there is currently a maximum of 1182 skincolors.
|
// A typical remap is 256 bytes long, and there is currently a maximum of 1182 skincolors, and 263 possible color cache entries.
|
||||||
// This means allocating (1182 * 256) bytes, which equals 302592, or ~302kb of memory for every translation.
|
// This would mean allocating (1182 * 256 * 263) bytes, which equals 79581696 bytes, or ~79mb of memory for every remap.
|
||||||
// So we allocate a list instead.
|
// So instead a few lists are allocated.
|
||||||
UINT8 **skincolor_remap;
|
colorcache_t ***skincolor_remaps;
|
||||||
} remaptable_t;
|
} remaptable_t;
|
||||||
|
|
||||||
void PaletteRemap_Init(void);
|
void PaletteRemap_Init(void);
|
||||||
|
@ -85,6 +87,7 @@ const char *R_GetCustomTranslationName(unsigned id);
|
||||||
unsigned R_NumCustomTranslations(void);
|
unsigned R_NumCustomTranslations(void);
|
||||||
remaptable_t *R_GetTranslationByID(int id);
|
remaptable_t *R_GetTranslationByID(int id);
|
||||||
UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum);
|
UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum);
|
||||||
|
void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 skinnum);
|
||||||
boolean R_TranslationIsValid(int id);
|
boolean R_TranslationIsValid(int id);
|
||||||
|
|
||||||
void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum);
|
void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum);
|
||||||
|
|
Loading…
Reference in a new issue