The actual palette remapping

This commit is contained in:
GenericHeroGuy 2025-01-24 18:18:37 +01:00
parent 63d558725e
commit 48bb0ea5ef
10 changed files with 150 additions and 3 deletions

View file

@ -1506,6 +1506,8 @@ void D_SRB2Main(void)
#endif //ifndef DEVELOP
R_InitPaletteRemap();
// now do it again for the SOC colors in main.pk3!
M_InitPlayerSetupColors();

View file

@ -522,12 +522,18 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe
#endif
#ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT)
{
if (W_NeedPaletteRemap())
R_DoPaletteRemapFlat(pdata, lumplength);
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
}
else
#endif
{
(void)lumplength;
dealloc = false;
if (W_NeedPaletteRemap())
R_DoPaletteRemapPatch(realpatch, lumplength);
}
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch);
@ -878,6 +884,11 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
PU_HWRCACHE, &grMipmap->data));
// palette remapping
// have to do this here since the lump isn't cached
if (wadfiles[WADFILENUM(flatlumpnum)]->compatmode)
R_DoPaletteRemapFlat(grMipmap->data, size);
flat = grMipmap->data;
for (steppy = 0; steppy < size; steppy++)
if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX)

View file

@ -292,6 +292,7 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
char colormap[9] = "COLORMAP";
lumpnum_t lump;
const lumpnum_t basecolormaplump = W_GetNumForName(colormap);
boolean remap = false;
if (num > 0 && num <= 10000)
snprintf(colormap, 8, "CLM%04u", num-1);
@ -301,6 +302,7 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
lump = basecolormaplump;
else
{
remap = wadfiles[WADFILENUM(lump)]->compatmode;
if (W_LumpLength(lump) != W_LumpLength(basecolormaplump))
{
CONS_Alert(CONS_WARNING, "%s lump size does not match COLORMAP, results may be unexpected.\n", colormap);
@ -309,6 +311,19 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
W_ReadLumpHeader(lump, colormaps, W_LumpLength(basecolormaplump), 0U);
if (remap)
{
lighttable_t *copy = malloc(W_LumpLength(basecolormaplump));
memcpy(copy, colormaps, W_LumpLength(basecolormaplump));
for (int p = 0; p < LIGHTLEVELS; p++)
{
for (int i = 0; i < 256; i++)
// 2.2 colormap index to 2.1, then 2.1 palette color to 2.2
colormaps[p*256 + i] = R_GetPaletteRemap(copy[p*256 + R_InvPaletteRemap(i)]);
}
free(copy);
}
// Encore mode.
if (newencoremap != LUMPERROR)
{
@ -320,6 +335,16 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
colormap_p = colormap_p2 = colormaps;
colormap_p += COLORMAP_REMAPOFFSET;
remap = wadfiles[WADFILENUM(newencoremap)]->compatmode;
if (remap)
{
UINT8 *copy = malloc(256);
memcpy(copy, encoremap, 256);
for (i = 0; i < 256; i++)
encoremap[i] = R_GetPaletteRemap(copy[R_InvPaletteRemap(i)]);
free(copy);
}
for (p = 0; p < LIGHTLEVELS; p++)
{
for (i = 0; i < 256; i++)

View file

@ -108,6 +108,7 @@ UINT8 r8_flatcolor;
UINT8 *transtables; // translucency tables
UINT8 *blendtables[NUMBLENDMAPS];
UINT8 *palremap, *invremap;
/** \brief R_DrawTransColumn uses this
*/
@ -348,6 +349,24 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel)
return transtables + (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
}
void R_InitPaletteRemap(void)
{
palremap = static_cast<UINT8 *>(Z_Malloc(256, PU_STATIC, NULL));
invremap = static_cast<UINT8 *>(Z_Malloc(256, PU_STATIC, NULL));
W_ReadLump(W_GetNumForName("PALREMAP"), palremap);
W_ReadLump(W_GetNumForName("INVREMAP"), invremap);
}
UINT8 R_GetPaletteRemap(UINT8 color)
{
return palremap[color];
}
UINT8 R_InvPaletteRemap(UINT8 color)
{
return invremap[color];
}
/** \brief Retrieves a translation colormap from the cache.
\param skinnum number of skin, TC_DEFAULT or TC_BOSS

View file

@ -167,11 +167,16 @@ enum
extern UINT8 *blendtables[NUMBLENDMAPS];
extern UINT8 *palremap, *invremap;
void R_InitTranslucencyTables(void);
void R_GenerateBlendTables(void);
void R_InitPaletteRemap(void);
UINT8 *R_GetTranslucencyTable(INT32 alphalevel);
UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
UINT8 R_GetPaletteRemap(UINT8 color);
UINT8 R_InvPaletteRemap(UINT8 color);
// Color ramp modification should force a recache
extern UINT8 skincolor_modified[];

View file

@ -295,6 +295,28 @@ static boolean R_CheckTextureLumpLength(texture_t *texture, size_t patch)
return true;
}
void R_DoPaletteRemapPatch(softwarepatch_t *patch, size_t size)
{
(void)size;
UINT32 *columns = patch->columnofs;
for (INT16 i = 0; i < patch->width; i++)
{
UINT8 *p = (UINT8 *)patch + columns[i];
while (*p++ != 0xff) // topdelta
{
int length = *p++;
for (length += 2; length--; p++)
*p = R_GetPaletteRemap(*p);
}
}
}
void R_DoPaletteRemapFlat(UINT8 *data, size_t size)
{
for (size_t i = 0; i < size; i++, data++)
*data = R_GetPaletteRemap(*data);
}
//
// R_GenerateTexture
//
@ -363,6 +385,9 @@ UINT8 *R_GenerateTexture(size_t texnum)
goto multipatch;
#endif
if (W_NeedPaletteRemap())
R_DoPaletteRemapPatch(realpatch, lumplength);
// Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true;
@ -458,12 +483,18 @@ UINT8 *R_GenerateTexture(size_t texnum)
#endif
#ifdef WALLFLATS
if (texture->type == TEXTURETYPE_FLAT)
{
if (W_NeedPaletteRemap())
R_DoPaletteRemapFlat(pdata, lumplength);
realpatch = (softwarepatch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_DOOMPATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
}
else
#endif
{
(void)lumplength;
dealloc = false;
if (W_NeedPaletteRemap())
R_DoPaletteRemapPatch(realpatch, lumplength);
}
x1 = patch->originx;
@ -893,7 +924,10 @@ UINT8 *R_GetBrightmapColumn(fixed_t tex, INT32 col)
void *R_GetFlat(lumpnum_t flatlumpnum)
{
return W_CacheLumpNum(flatlumpnum, PU_LEVEL);
void *flat = W_CacheLumpNum(flatlumpnum, PU_LEVEL);
if (W_NeedPaletteRemap())
R_DoPaletteRemapFlat(flat, W_LumpLength(flatlumpnum));
return flat;
}
//

View file

@ -94,6 +94,8 @@ boolean R_TextureHasBrightmap(INT32 texnum);
boolean R_TextureCanRemap(INT32 texnum);
void R_CheckTextureCache(INT32 tex);
void R_ClearTextureNumCache(boolean btell);
void R_DoPaletteRemapPatch(softwarepatch_t *patch, size_t size);
void R_DoPaletteRemapFlat(UINT8 *data, size_t size);
// Retrieve texture data.
void *R_GetLevelFlat(drawspandata_t* ds, levelflat_t *levelflat);

View file

@ -312,6 +312,9 @@ UINT32 V_GammaCorrect(UINT32 input, double power)
static void LoadPalette(const char *lumpname)
{
lumpnum_t lumpnum = W_GetNumForName(lumpname);
boolean remap = wadfiles[WADFILENUM(lumpnum)]->compatmode;
if (remap) // if we're remapping, start with PLAYPAL as a base
lumpnum = W_GetNumForName("PLAYPAL");
size_t i, palsize = W_LumpLength(lumpnum)/3;
UINT8 *pal;
@ -329,26 +332,51 @@ static void LoadPalette(const char *lumpname)
pLocalPalette = pMasterPalette;
pGammaCorrectedPalette = Z_Malloc(sizeof (*pGammaCorrectedPalette)*palsize, PU_STATIC, NULL);
// load the new palette (or PLAYPAL if remapping)
pal = W_CacheLumpNum(lumpnum, PU_CACHE);
for (i = 0; i < palsize; i++)
{
RGBA_t pGCP;
pMasterPalette[i].s.red = *pal++;
pMasterPalette[i].s.green = *pal++;
pMasterPalette[i].s.blue = *pal++;
pMasterPalette[i].s.alpha = 0xFF;
}
RGBA_t *target = NULL;
if (remap)
{
// get the target palette we want
lumpnum = W_GetNumForName(lumpname);
pal = W_CacheLumpNum(lumpnum, PU_CACHE);
palsize = W_LumpLength(lumpnum)/3;
target = malloc(sizeof (*target)*palsize);
for (i = 0; i < palsize; i++)
{
target[i].s.red = *pal++;
target[i].s.green = *pal++;
target[i].s.blue = *pal++;
target[i].s.alpha = 0xFF;
}
}
for (i = 0; i < palsize; i++)
{
if (remap) // now map the target palette (2.1) to master palette (2.2)
pMasterPalette[i].rgba = target[R_InvPaletteRemap(i)].rgba;
pGammaCorrectedPalette[i].rgba = V_GammaDecode(pMasterPalette[i].rgba);
if (!Cubeapply)
continue;
// Short hand this so its easier to type
pGCP = pGammaCorrectedPalette[i];
RGBA_t pGCP = pGammaCorrectedPalette[i];
V_CubeApply(&pGCP.s.red,&pGCP.s.green,&pGCP.s.blue);
pLocalPalette[i].rgba = V_GammaEncode(pGammaCorrectedPalette[i].rgba);
}
if (remap)
free(target);
}
void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue)

View file

@ -1485,6 +1485,18 @@ void zerr(int ret)
}
#endif
// only do palette swapping ONCE, when caching the whole patch
// dumb hack but it works!
static boolean dopalswap = false;
// returns true if the most recently loaded lump is freshly cached, AND comes from a compatmode file
boolean W_NeedPaletteRemap(void)
{
boolean r = dopalswap;
dopalswap = false;
return r;
}
/** Reads bytes from the head of a lump.
* Note: If the lump is compressed, the whole thing has to be read anyway.
*
@ -1673,11 +1685,15 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
lumpcache = wadfiles[wad]->lumpcache;
if (!lumpcache[lump])
{
dopalswap = wadfiles[wad]->compatmode;
void *ptr = Z_Malloc(W_LumpLengthPwad(wad, lump), tag, &lumpcache[lump]);
W_ReadLumpHeaderPwad(wad, lump, ptr, 0, 0); // read the lump in full
}
else
{
dopalswap = false;
Z_ChangeTag(lumpcache[lump], tag);
}
return lumpcache[lump];
}
@ -1819,6 +1835,10 @@ void *W_CacheSoftwarePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag)
ptr = Picture_PNGConvert((UINT8 *)lumpdata, PICFMT_DOOMPATCH, NULL, NULL, NULL, NULL, len, &len, 0);
#endif
// we already know this is a patch, do palette remapping here
if (wadfiles[wad]->compatmode)
R_DoPaletteRemapPatch(ptr, wadfiles[wad]->lumpinfo[lump].size);
dest = Z_Calloc(sizeof(patch_t), tag, &lumpcache[lump]);
Patch_Create(ptr, len, dest);

View file

@ -196,6 +196,7 @@ void *W_CacheLumpNumForce(lumpnum_t lumpnum, INT32 tag);
boolean W_IsLumpCached(lumpnum_t lump, void *ptr);
boolean W_IsPatchCached(lumpnum_t lump, void *ptr);
boolean W_NeedPaletteRemap(void);
void *W_CacheLumpName(const char *name, INT32 tag);
void *W_CachePatchName(const char *name, INT32 tag);