Refactor and optimize translation caching

This commit is contained in:
Jaime Ita Passos 2021-08-10 00:46:36 -03:00
parent 2aa9bb59ef
commit 655b48b52e
5 changed files with 97 additions and 85 deletions

View file

@ -30,9 +30,6 @@
#include "lua_hud.h" // hud_running errors
#include "lua_hook.h" // hook_cmd_running errors
extern CV_PossibleValue_t Color_cons_t[];
extern UINT8 skincolor_modified[];
boolean LUA_CallAction(enum actionnum actionnum, mobj_t *actor);
state_t *astate;

View file

@ -9111,7 +9111,7 @@ static UINT16 M_SetupChoosePlayerDirect(INT32 choice)
{
INT32 skinnum, botskinnum;
UINT16 i;
UINT16 firstvalid = 65535, lastvalid = 65535;
INT32 firstvalid = INT32_MAX, lastvalid = INT32_MAX;
boolean allowed = false;
(void)choice;
@ -9155,7 +9155,7 @@ static UINT16 M_SetupChoosePlayerDirect(INT32 choice)
}
// Handling order.
if (firstvalid == 65535)
if (firstvalid == INT32_MAX)
firstvalid = i;
else
{
@ -9518,7 +9518,7 @@ static void M_ChoosePlayer(INT32 choice)
UINT8 skinnum;
// skip this if forcecharacter or no characters available
if (choice == 65535)
if (choice == INT32_MAX)
{
skinnum = botskin = 0;
botingame = false;

View file

@ -122,54 +122,56 @@ float focallengthf, zeroheight;
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
// =========================================================================
// TRANSLATION COLORMAP CODE
// TRANSLATION COLORMAP CODE
// =========================================================================
#define DEFAULT_TT_CACHE_INDEX MAXSKINS
#define BOSS_TT_CACHE_INDEX (MAXSKINS + 1)
#define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2)
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
#define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
#define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
#define DEFAULT_STARTTRANSCOLOR 96
static UINT8 **translationtablecache[MAXSKINS + 7] = {NULL};
UINT8 skincolor_modified[MAXSKINCOLORS];
static INT32 SkinToCacheIndex(INT32 skinnum)
enum
{
switch (skinnum)
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];
static INT32 TranslationToCacheIndex(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: break;
default: return DEFAULT_TT_CACHE_INDEX;
}
return skinnum;
}
static INT32 CacheIndexToSkin(INT32 ttc)
static INT32 CacheIndexToTranslation(INT32 index)
{
switch (ttc)
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: break;
default: return TC_DEFAULT;
}
return ttc;
}
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@ -398,18 +400,18 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
RGBA_t color;
UINT8 brightness;
INT32 j;
UINT8 colorbrightnesses[16];
UINT8 colorbrightnesses[COLORRAMPSIZE];
UINT16 brightdif;
INT32 temp;
// first generate the brightness of all the colours of that skincolour
for (i = 0; i < 16; i++)
for (i = 0; i < COLORRAMPSIZE; i++)
{
color = V_GetColor(skincolors[skincolor].ramp[i]);
SETBRIGHTNESS(colorbrightnesses[i], color.s.red, color.s.green, color.s.blue);
}
// next, for every colour in the palette, choose the transcolor that has the closest brightness
// next, for every colour in the palette, choose the translated colour that has the closest brightness
for (i = 0; i < NUM_PALETTE_ENTRIES; i++)
{
if (i == 0 || i == 31) // pure black and pure white don't change
@ -420,7 +422,7 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
color = V_GetColor(i);
SETBRIGHTNESS(brightness, color.s.red, color.s.green, color.s.blue);
brightdif = 256;
for (j = 0; j < 16; j++)
for (j = 0; j < COLORRAMPSIZE; j++)
{
temp = abs((INT16)brightness - (INT16)colorbrightnesses[j]);
if (temp < brightdif)
@ -436,28 +438,29 @@ static void R_RainbowColormap(UINT8 *dest_colormap, UINT16 skincolor)
/** \brief Generates a translation colormap.
\param dest_colormap colormap to populate
\param skinnum skin number, or a translation mode
\param color translation color
\param dest_colormap colormap to populate
\param translation translation mode
\param color translation color
\param starttranscolor starting point of the translation
\return void
*/
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, UINT16 color)
static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 translation, UINT16 color, INT32 starttranscolor)
{
INT32 i, starttranscolor, skinramplength;
INT32 i, skinramplength;
// Handle a couple of simple special cases
if (skinnum < TC_DEFAULT)
if (translation < TC_DEFAULT)
{
switch (skinnum)
switch (translation)
{
case TC_ALLWHITE:
memset(dest_colormap, 0, NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
case TC_RAINBOW:
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
I_Error("Invalid skin color #%hu", (UINT16)color);
else if (color != SKINCOLOR_NONE)
{
R_RainbowColormap(dest_colormap, color);
return;
@ -465,8 +468,8 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
break;
case TC_BLINK:
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (color != SKINCOLOR_NONE)
I_Error("Invalid skin color #%hu", (UINT16)color);
else if (color != SKINCOLOR_NONE)
{
memset(dest_colormap, skincolors[color].ramp[3], NUM_PALETTE_ENTRIES * sizeof(UINT8));
return;
@ -480,26 +483,28 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
dest_colormap[i] = (UINT8)i;
// White!
if (skinnum == TC_BOSS)
if (translation == TC_BOSS)
{
UINT8 *originalColormap = R_GetTranslationColormap(TC_DEFAULT, (skincolornum_t)color, GTC_CACHE);
for (i = 0; i < 16; i++)
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d", starttranscolor);
for (i = 0; i < COLORRAMPSIZE; i++)
{
dest_colormap[DEFAULT_STARTTRANSCOLOR + i] = originalColormap[DEFAULT_STARTTRANSCOLOR + i];
dest_colormap[starttranscolor + i] = originalColormap[starttranscolor + i];
dest_colormap[31-i] = i;
}
}
else if (skinnum == TC_METALSONIC)
else if (translation == TC_METALSONIC)
{
for (i = 0; i < 6; i++)
{
dest_colormap[skincolors[SKINCOLOR_BLUE].ramp[12-i]] = skincolors[SKINCOLOR_BLUE].ramp[i];
}
dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
for (i = 0; i < 16; i++)
for (i = 0; i < COLORRAMPSIZE; i++)
dest_colormap[96+i] = dest_colormap[skincolors[SKINCOLOR_COBALT].ramp[i]];
}
else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
else if (translation == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
{
// greens -> ketchups
dest_colormap[96] = dest_colormap[97] = 48;
@ -543,26 +548,21 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
}
if (color >= numskincolors)
I_Error("Invalid skin color #%hu.", (UINT16)color);
if (skinnum < 0 && skinnum > TC_DEFAULT)
I_Error("Invalid translation colormap index %d.", skinnum);
starttranscolor = (skinnum != TC_DEFAULT) ? skins[skinnum]->starttranscolor : DEFAULT_STARTTRANSCOLOR;
I_Error("Invalid skin color #%hu", (UINT16)color);
if (starttranscolor >= NUM_PALETTE_ENTRIES)
I_Error("Invalid startcolor #%d.", starttranscolor);
I_Error("Invalid startcolor #%d", starttranscolor);
// Fill in the entries of the palette that are fixed
for (i = 0; i < starttranscolor; i++)
dest_colormap[i] = (UINT8)i;
i = starttranscolor + 16;
i = starttranscolor + COLORRAMPSIZE;
if (i < NUM_PALETTE_ENTRIES)
{
for (i = (UINT8)i; i < NUM_PALETTE_ENTRIES; i++)
dest_colormap[i] = (UINT8)i;
skinramplength = 16;
skinramplength = COLORRAMPSIZE;
}
else
skinramplength = i - NUM_PALETTE_ENTRIES; // shouldn't this be NUM_PALETTE_ENTRIES - starttranscolor?
@ -575,7 +575,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
/** \brief Retrieves a translation colormap from the cache.
\param skinnum number of skin, TC_DEFAULT or TC_BOSS
\param skinnum number of skin, or translation modes
\param color translation color
\param flags set GTC_CACHE to use the cache
@ -583,25 +583,47 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
*/
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags)
{
UINT8* ret;
INT32 skintableindex = SkinToCacheIndex(skinnum); // Adjust if we want the default colormap
INT32 i;
UINT8 ***cache = NULL;
INT32 index, starttranscolor;
UINT8 *ret;
// 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;
}
else if (skinnum <= TC_DEFAULT)
{
cache = translationtablecache;
starttranscolor = DEFAULT_STARTTRANSCOLOR;
index = TranslationToCacheIndex(skinnum);
}
else
I_Error("Invalid translation %d", skinnum);
if (flags & GTC_CACHE)
{
// Allocate table for skin if necessary
if (!translationtablecache[skintableindex])
translationtablecache[skintableindex] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
if (!cache[index])
cache[index] = Z_Calloc(MAXSKINCOLORS * sizeof(UINT8**), PU_STATIC, NULL);
// Get colormap
ret = translationtablecache[skintableindex][color];
ret = cache[index][color];
// Rebuild the cache if necessary
if (skincolor_modified[color])
{
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
INT32 i;
for (i = 0; i < TT_CACHE_SIZE; i++)
if (translationtablecache[i] && translationtablecache[i][color])
R_GenerateTranslationColormap(translationtablecache[i][color], CacheIndexToSkin(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;
}
@ -612,11 +634,11 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags
if (!ret)
{
ret = Z_MallocAlign(NUM_PALETTE_ENTRIES, (flags & GTC_CACHE) ? PU_LEVEL : PU_STATIC, NULL, 8);
R_GenerateTranslationColormap(ret, skinnum, color);
R_GenerateTranslationColormap(ret, skinnum, color, starttranscolor);
// Cache the colormap if desired
if (flags & GTC_CACHE)
translationtablecache[skintableindex][color] = ret;
cache[index][color] = ret;
}
return ret;
@ -634,9 +656,12 @@ void R_FlushTranslationColormapCache(void)
{
INT32 i;
for (i = 0; i < (INT32)(sizeof(translationtablecache) / sizeof(translationtablecache[0])); i++)
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)

View file

@ -147,7 +147,7 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
// Color ramp modification should force a recache
extern UINT8 skincolor_modified[];
extern boolean skincolor_modified[];
void R_InitViewBuffer(INT32 width, INT32 height);
void R_InitViewBorder(void);

View file

@ -128,8 +128,6 @@ static patch_t *gotrflag;
static patch_t *gotbflag;
static patch_t *fnshico;
static boolean facefreed[MAXPLAYERS];
hudinfo_t hudinfo[NUMHUDITEMS] =
{
{ 16, 176, V_SNAPTOLEFT|V_SNAPTOBOTTOM}, // HUD_LIVES
@ -361,17 +359,14 @@ void ST_LoadFaceGraphics(INT32 skinnum)
}
else
faceprefix[skinnum] = superprefix[skinnum] = W_CachePatchName("MISSING", PU_HUDGFX); // ditto
facefreed[skinnum] = false;
}
void ST_ReloadSkinFaceGraphics(void)
{
INT32 i;
if (faceprefix)
Z_Free(faceprefix);
if (superprefix)
Z_Free(superprefix);
Z_Free(faceprefix);
Z_Free(superprefix);
if (!numskins)
return;
@ -421,11 +416,6 @@ lumpnum_t st_borderpatchnum;
void ST_Init(void)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
facefreed[i] = true;
if (dedicated)
return;