diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 931867142200338b7635d7b04307df587eafa129..c7256666a5ef146d9273d4a4d28c77b216372ea2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1473,37 +1473,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) if (gpatch && hwrPatch && hwrPatch->mipmap->format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - INT32 skinnum = TC_DEFAULT; + INT32 skinnum = R_GetTranslationIndexForThing(spr->mobj, spr->mobj->color); - if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" - { - if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) - skinnum = TC_ALLWHITE; - else if (spr->mobj->type == MT_METALSONIC_BATTLE) - skinnum = TC_METALSONIC; - else - skinnum = TC_BOSS; - } - else if ((skincolornum_t)spr->mobj->color != SKINCOLOR_NONE) - { - if (spr->mobj->colorized) - skinnum = TC_RAINBOW; - else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD - && (spr->mobj->player->charflags & SF_DASHMODE) - && ((leveltime/2) & 1)) - { - if (spr->mobj->player->charflags & SF_MACHINE) - skinnum = TC_DASHMODE; - else - skinnum = TC_RAINBOW; - } - else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - skinnum = ((skin_t*)spr->mobj->skin)->skinnum; - else - skinnum = TC_DEFAULT; - } - - // Translation or skin number found HWR_GetBlendedTexture(gpatch, blendgpatch, skinnum, spr->colormap, (skincolornum_t)spr->mobj->color); } else // Sprite diff --git a/src/r_draw.c b/src/r_draw.c index 906398ec4972e53565cdcfa04deb51557956d39c..4bf50cf286f7fad423133ac5f806ef09db74647e 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -125,7 +125,7 @@ INT32 R_SkinTranslationToCacheIndex(INT32 translation) } } -static INT32 CacheIndexToSkin(INT32 index) +INT32 R_CacheIndexToSkinTranslation(INT32 index) { switch (index) { @@ -140,6 +140,19 @@ static INT32 CacheIndexToSkin(INT32 index) } } +boolean R_IsSkinTranslationRemappable(INT32 translation) +{ + switch (translation) + { + case TC_METALSONIC: + case TC_ALLWHITE: + case TC_DASHMODE: + return false; + default: + return true; + } +} + CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; /** \brief Initializes the translucency tables used by the Software renderer. @@ -456,7 +469,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 translatio for (i = 0; i < NUM_PALETTE_ENTRIES; i++) dest_colormap[i] = (UINT8)i; - // White! + // Boss flashing inverts the grayscale ramp if (translation == TC_BOSS) { UINT8 *originalColormap = R_GetTranslationColormap(TC_DEFAULT, (skincolornum_t)color, GTC_CACHE); @@ -468,6 +481,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 translatio dest_colormap[31-i] = i; } } + // Metal Sonic flashing else if (translation == TC_METALSONIC) { for (i = 0; i < 6; i++) @@ -555,7 +569,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags // Rebuild the cache if necessary if (skincolor_modified[color]) { - // Moved up here so that R_UpdateTranslationRemaps doesn't cause a stack overflow, + // Moved up here so that R_UpdateTranslationRemaps doesn't cause infinite recursion, // since in this situation, it will call R_GetTranslationColormap skincolor_modified[color] = false; @@ -566,7 +580,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolornum_t color, UINT8 flags colorcache_t *cache = translationtablecache[i][color]; if (cache) { - R_GenerateTranslationColormap(cache->colors, CacheIndexToSkin(i), color, starttranscolor); + R_GenerateTranslationColormap(cache->colors, R_CacheIndexToSkinTranslation(i), color, starttranscolor); R_UpdateTranslationRemaps(color, i); } } diff --git a/src/r_draw.h b/src/r_draw.h index d5c5b4e25d36ba375d365a2d13f0ba5fab19e3f3..bfcf09fab070d046cdf48ac6e8d8fbb9df2f0b2a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -90,6 +90,8 @@ enum }; INT32 R_SkinTranslationToCacheIndex(INT32 translation); +INT32 R_CacheIndexToSkinTranslation(INT32 index); +boolean R_IsSkinTranslationRemappable(INT32 translation); // Amount of colors in the palette #define NUM_PALETTE_ENTRIES 256 diff --git a/src/r_things.c b/src/r_things.c index 2c0529e47a572b8fcd5b7966fcb7652e13a6b03b..7ff4d5bd580e8bf383d560c4481685095170cf71 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -957,12 +957,21 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol) dc_texturemid = basetexturemid; } -UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation) +INT32 R_GetTranslationIndexForThing(mobj_t *mobj, skincolornum_t color) { INT32 skinnum = TC_DEFAULT; - boolean is_player = mobj->skin && mobj->sprite == SPR_PLAY; - if (is_player) // This thing is a player! + if (R_ThingIsFlashing(mobj)) // Bosses "flash" + { + if (mobj->type == MT_CYBRAKDEMON || mobj->colorized) + return TC_ALLWHITE; + else if (mobj->type == MT_METALSONIC_BATTLE) + return TC_METALSONIC; + else + return TC_BOSS; + } + + if (mobj->skin && mobj->sprite == SPR_PLAY) // This thing is a player! skinnum = ((skin_t*)mobj->skin)->skinnum; if (color != SKINCOLOR_NONE) @@ -983,25 +992,42 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans } } - if (R_ThingIsFlashing(mobj)) // Bosses "flash" + return skinnum; +} + +UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation) +{ + INT32 skinnum = R_GetTranslationIndexForThing(mobj, color); + + boolean use_translation_colormap = color != SKINCOLOR_NONE; + + if (skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || skinnum == TC_DASHMODE) { - if (mobj->type == MT_CYBRAKDEMON || mobj->colorized) - return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); - else if (mobj->type == MT_METALSONIC_BATTLE) - return R_GetTranslationColormap(TC_METALSONIC, 0, GTC_CACHE); - else - return R_GetTranslationColormap(TC_BOSS, color, GTC_CACHE); + use_translation_colormap = true; + + // Those translations don't support color remapping, so they + // will use SKINCOLOR_NONE always and reduce memory usage. + color = SKINCOLOR_NONE; } - else if (translation != 0) + else if (skinnum == TC_BOSS) { - UINT8 *tr = R_GetTranslationRemap(translation, color, skinnum); - if (tr != NULL) - return tr; + use_translation_colormap = true; } - else if (color != SKINCOLOR_NONE) + + if (translation != 0) + { + return R_GetTranslationRemap(translation, color, skinnum); + } + else if (use_translation_colormap) + { return R_GetTranslationColormap(skinnum, color, GTC_CACHE); - else if (mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. - return R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE); + } + else if (mobj->sprite == SPR_PLAY && (skinnum >= 0 && skinnum < numskins)) + { + // Looks like a player, but doesn't have a color? + // Use the skin's prefcolor. + return R_GetTranslationColormap(TC_DEFAULT, skins[skinnum]->prefcolor, GTC_CACHE); + } return NULL; } diff --git a/src/r_things.h b/src/r_things.h index ae21d2404bc1793c569194f22ed0a8e815c89e46..4d6cd5094ff47201bf90ea360e3d315e87bd3c06 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 1999-2024 by Sonic Team Junior. +// Copyright (C) 1999-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -92,6 +92,7 @@ boolean R_ThingIsFullDark (mobj_t *thing); boolean R_ThingIsFlashing (mobj_t *thing); +INT32 R_GetTranslationIndexForThing(mobj_t *mobj, skincolornum_t color); UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation); transnum_t R_GetThingTransTable(fixed_t alpha, transnum_t transmap); diff --git a/src/r_translation.c b/src/r_translation.c index 53bb0e6a0fd12fa1291d697db462b647d8909503..9fa76272a4d7fe32be6a4be8e8b4a0e92205852a 100644 --- a/src/r_translation.c +++ b/src/r_translation.c @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2006 by Randy Heit. -// Copyright (C) 2023-2024 by Sonic Team Junior. +// Copyright (C) 2023-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -1120,7 +1120,7 @@ UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum) if (!tr) return NULL; - if (!tr->num_sources || skincolor == SKINCOLOR_NONE) + if (!tr->num_sources || (skincolor == SKINCOLOR_NONE && skinnum >= 0)) return tr->remap; if (!tr->skincolor_remaps) @@ -1144,20 +1144,22 @@ UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum) return cache->colors; } -static void R_UpdateTranslation(remaptable_t *tr, skincolornum_t skincolor, INT32 skinnum) +static void R_UpdateTranslation(remaptable_t *tr, skincolornum_t skincolor, INT32 cache_index) { - if (!tr->num_sources || !tr->skincolor_remaps || !tr->skincolor_remaps[skinnum]) + if (skincolor == SKINCOLOR_NONE + || !R_IsSkinTranslationRemappable(R_CacheIndexToSkinTranslation(cache_index)) + || !tr->num_sources || !tr->skincolor_remaps || !tr->skincolor_remaps[cache_index]) return; - colorcache_t *cache = tr->skincolor_remaps[skinnum][skincolor]; + colorcache_t *cache = tr->skincolor_remaps[cache_index][skincolor - 1]; if (cache) - R_ApplyTranslationRemap(tr, cache->colors, skincolor, skinnum); + R_ApplyTranslationRemap(tr, cache->colors, skincolor, cache_index); } -void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 skinnum) +void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 cache_index) { for (unsigned i = 0; i < numpaletteremaps; i++) - R_UpdateTranslation(paletteremaps[i], skincolor, skinnum); + R_UpdateTranslation(paletteremaps[i], skincolor, cache_index); } boolean R_TranslationIsValid(int id) diff --git a/src/r_translation.h b/src/r_translation.h index 9cae1a6470d71ae76647a4c6f70b821d0f615d6a..ca0af716db79e74a0b8f3dbcda3e103375471209 100644 --- a/src/r_translation.h +++ b/src/r_translation.h @@ -1,7 +1,7 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- // Copyright (C) 1998-2006 by Randy Heit. -// Copyright (C) 2023-2024 by Sonic Team Junior. +// Copyright (C) 2023-2025 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. @@ -87,7 +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); +void R_UpdateTranslationRemaps(skincolornum_t skincolor, INT32 cache_index); boolean R_TranslationIsValid(int id); void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum);