Support combinations of skincolors and translations

This commit is contained in:
Lactozilla 2024-01-19 20:39:28 -03:00
parent 4b057f84ec
commit 4e818b87fd
4 changed files with 230 additions and 137 deletions

View file

@ -175,6 +175,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i)
|| tokenizer->input[tokenizer->startPos] == '='
|| tokenizer->input[tokenizer->startPos] == ':'
|| tokenizer->input[tokenizer->startPos] == '%'
|| tokenizer->input[tokenizer->startPos] == '@'
|| tokenizer->input[tokenizer->startPos] == '"')
{
tokenizer->endPos = tokenizer->startPos + 1;
@ -200,6 +201,7 @@ const char *Tokenizer_Read(tokenizer_t *tokenizer, UINT32 i)
&& tokenizer->input[tokenizer->endPos] != '='
&& tokenizer->input[tokenizer->endPos] != ':'
&& tokenizer->input[tokenizer->endPos] != '%'
&& tokenizer->input[tokenizer->endPos] != '@'
&& tokenizer->input[tokenizer->endPos] != ';'
&& tokenizer->inComment == 0)
&& tokenizer->endPos < tokenizer->inputLength)

View file

@ -764,6 +764,12 @@ void R_DrawFlippedMaskedColumn(column_t *column)
UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 translation)
{
INT32 skinnum = TC_DEFAULT;
boolean is_player = mobj->skin && mobj->sprite == SPR_PLAY;
if (is_player) // This thing is a player!
skinnum = ((skin_t*)mobj->skin)->skinnum;
if (R_ThingIsFlashing(mobj)) // Bosses "flash"
{
if (mobj->type == MT_CYBRAKDEMON || mobj->colorized)
@ -775,9 +781,9 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
}
else if (translation != 0)
{
remaptable_t *tr = R_GetTranslationByID(translation);
UINT8 *tr = R_GetTranslationRemap(translation, color, skinnum);
if (tr != NULL)
return tr->remap;
return tr;
}
else if (color != SKINCOLOR_NONE)
{
@ -793,13 +799,8 @@ UINT8 *R_GetTranslationForThing(mobj_t *mobj, skincolornum_t color, UINT16 trans
else
return R_GetTranslationColormap(TC_RAINBOW, color, GTC_CACHE);
}
else if (mobj->skin && mobj->sprite == SPR_PLAY) // This thing is a player!
{
UINT8 skinnum = ((skin_t*)mobj->skin)->skinnum;
else
return R_GetTranslationColormap(skinnum, color, GTC_CACHE);
}
else // Use the defaults
return R_GetTranslationColormap(TC_DEFAULT, 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);

View file

@ -27,56 +27,39 @@ static unsigned numpaletteremaps = 0;
static int allWhiteRemap = 0;
static int dashModeRemap = 0;
static void MakeGrayscaleRemap(void);
static void MakeInvertRemap(void);
static void MakeDashModeRemap(void);
static boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end, int pal1, int pal2);
static boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int r1i, int g1i, int b1i, int r2i, int g2i, int b2i);
static boolean PaletteRemap_AddDesaturation(remaptable_t *tr, int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
static boolean PaletteRemap_AddColourisation(remaptable_t *tr, int start, int end, int r, int g, int b);
static boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r, int g, int b, int amount);
static boolean PaletteRemap_AddInvert(remaptable_t *tr, int start, int end);
static boolean PaletteRemap_DoIndexRange(UINT8 *remap, int start, int end, int pal1, int pal2);
static boolean PaletteRemap_DoColorRange(UINT8 *remap, int start, int end, int r1i, int g1i, int b1i, int r2i, int g2i, int b2i);
static boolean PaletteRemap_DoDesaturation(UINT8 *remap, int start, int end, double r1, double g1, double b1, double r2, double g2, double b2);
static boolean PaletteRemap_DoColourisation(UINT8 *remap, int start, int end, int r, int g, int b);
static boolean PaletteRemap_DoTint(UINT8 *remap, int start, int end, int r, int g, int b, int amount);
static boolean PaletteRemap_DoInvert(UINT8 *remap, int start, int end);
enum PaletteRemapType
static void PaletteRemap_Apply(UINT8 *remap, paletteremap_t *data);
static void InitSource(paletteremap_t *source, paletteremaptype_t type, int start, int end)
{
REMAP_ADD_INDEXRANGE,
REMAP_ADD_COLORRANGE,
REMAP_ADD_COLOURISATION,
REMAP_ADD_DESATURATION,
REMAP_ADD_TINT
};
source->type = type;
source->start = start;
source->end = end;
}
struct PaletteRemapParseResult
static paletteremap_t *AddSource(remaptable_t *tr, paletteremaptype_t type, int start, int end)
{
int start, end;
enum PaletteRemapType type;
union
{
struct
{
int pal1, pal2;
} indexRange;
struct
{
int r1, g1, b1;
int r2, g2, b2;
} colorRange;
struct
{
double r1, g1, b1;
double r2, g2, b2;
} desaturation;
struct
{
int r, g, b;
} colourisation;
struct
{
int r, g, b, amount;
} tint;
};
paletteremap_t *remap = NULL;
char *error;
};
tr->num_sources++;
tr->sources = Z_Realloc(tr->sources, tr->num_sources * sizeof(paletteremap_t), PU_STATIC, NULL);
remap = &tr->sources[tr->num_sources - 1];
InitSource(remap, type, start, end);
return remap;
}
void PaletteRemap_Init(void)
{
@ -86,10 +69,7 @@ void PaletteRemap_Init(void)
PaletteRemap_Add(base);
// Grayscale translation
remaptable_t *grayscale = PaletteRemap_New();
PaletteRemap_SetIdentity(grayscale);
PaletteRemap_AddDesaturation(grayscale, 0, 255, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0);
R_AddCustomTranslation("Grayscale", PaletteRemap_Add(grayscale));
MakeGrayscaleRemap();
// All white (TC_ALLWHITE)
remaptable_t *allWhite = PaletteRemap_New();
@ -103,10 +83,7 @@ void PaletteRemap_Init(void)
R_AddCustomTranslation("AllBlack", PaletteRemap_Add(allBlack));
// Invert
remaptable_t *invertRemap = PaletteRemap_New();
PaletteRemap_SetIdentity(invertRemap);
PaletteRemap_AddInvert(invertRemap, 0, 255);
R_AddCustomTranslation("Invert", PaletteRemap_Add(invertRemap));
MakeInvertRemap();
// Dash mode (TC_DASHMODE)
MakeDashModeRemap();
@ -162,6 +139,36 @@ unsigned PaletteRemap_Add(remaptable_t *tr)
return numpaletteremaps - 1;
}
static void MakeGrayscaleRemap(void)
{
remaptable_t *grayscale = PaletteRemap_New();
paletteremap_t *source = AddSource(grayscale, REMAP_ADD_DESATURATION, 0, 255);
source->desaturation.r1 = 0.0;
source->desaturation.g1 = 0.0;
source->desaturation.b1 = 0.0;
source->desaturation.r2 = 1.0;
source->desaturation.g2 = 1.0;
source->desaturation.b2 = 1.0;
PaletteRemap_SetIdentity(grayscale);
PaletteRemap_Apply(grayscale->remap, source);
R_AddCustomTranslation("Grayscale", PaletteRemap_Add(grayscale));
}
static void MakeInvertRemap(void)
{
remaptable_t *invertRemap = PaletteRemap_New();
paletteremap_t *source = AddSource(invertRemap, REMAP_ADD_INVERT, 0, 255);
PaletteRemap_SetIdentity(invertRemap);
PaletteRemap_Apply(invertRemap->remap, source);
R_AddCustomTranslation("Invert", PaletteRemap_Add(invertRemap));
}
// This is a long one, because MotorRoach basically hand-picked the indices
static void MakeDashModeRemap(void)
{
@ -229,7 +236,7 @@ static boolean IndicesOutOfRange2(int start1, int end1, int start2, int end2)
b = swap; \
}
static boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end, int pal1, int pal2)
static boolean PaletteRemap_DoIndexRange(UINT8 *remap, int start, int end, int pal1, int pal2)
{
if (IndicesOutOfRange2(start, end, pal1, pal2))
return false;
@ -241,7 +248,7 @@ static boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end,
}
else if (start == end)
{
tr->remap[start] = pal1;
remap[start] = pal1;
return true;
}
@ -251,13 +258,13 @@ static boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end,
for (int i = start; i <= end; palcol += palstep, ++i)
{
double idx = round(palcol);
tr->remap[i] = (int)idx;
remap[i] = (int)idx;
}
return true;
}
static boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int r1i, int g1i, int b1i, int r2i, int g2i, int b2i)
static boolean PaletteRemap_DoColorRange(UINT8 *remap, int start, int end, int r1i, int g1i, int b1i, int r2i, int g2i, int b2i)
{
if (IndicesOutOfRange(start, end))
return false;
@ -294,7 +301,7 @@ static boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end,
if (start == end)
{
tr->remap[start] = NearestColor(r, g, b);
remap[start] = NearestColor(r, g, b);
}
else
{
@ -304,7 +311,7 @@ static boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end,
for (int i = start; i <= end; ++i)
{
tr->remap[i] = NearestColor(r, g, b);
remap[i] = NearestColor(r, g, b);
r += rs;
g += gs;
b += bs;
@ -316,7 +323,7 @@ static boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end,
#define CLAMP(val, minval, maxval) max(min(val, maxval), minval)
static boolean PaletteRemap_AddDesaturation(remaptable_t *tr, int start, int end, double r1, double g1, double b1, double r2, double g2, double b2)
static boolean PaletteRemap_DoDesaturation(UINT8 *remap, int start, int end, double r1, double g1, double b1, double r2, double g2, double b2)
{
if (IndicesOutOfRange(start, end))
return false;
@ -345,9 +352,11 @@ static boolean PaletteRemap_AddDesaturation(remaptable_t *tr, int start, int end
for (int c = start; c <= end; c++)
{
double intensity = (pMasterPalette[c].s.red * 77 + pMasterPalette[c].s.green * 143 + pMasterPalette[c].s.blue * 37) / 255.0;
double intensity = (pMasterPalette[remap[c]].s.red * 77
+ pMasterPalette[remap[c]].s.green * 143
+ pMasterPalette[remap[c]].s.blue * 37) / 255.0;
tr->remap[c] = NearestColor(
remap[c] = NearestColor(
min(255, max(0, (int)(r1 + intensity*r2))),
min(255, max(0, (int)(g1 + intensity*g2))),
min(255, max(0, (int)(b1 + intensity*b2)))
@ -361,16 +370,16 @@ static boolean PaletteRemap_AddDesaturation(remaptable_t *tr, int start, int end
#undef SWAP
static boolean PaletteRemap_AddColourisation(remaptable_t *tr, int start, int end, int r, int g, int b)
static boolean PaletteRemap_DoColourisation(UINT8 *remap, int start, int end, int r, int g, int b)
{
if (IndicesOutOfRange(start, end))
return false;
for (int i = start; i < end; ++i)
{
double br = pMasterPalette[i].s.red;
double bg = pMasterPalette[i].s.green;
double bb = pMasterPalette[i].s.blue;
double br = pMasterPalette[remap[i]].s.red;
double bg = pMasterPalette[remap[i]].s.green;
double bb = pMasterPalette[remap[i]].s.blue;
double grey = (br * 0.299 + bg * 0.587 + bb * 0.114) / 255.0f;
if (grey > 1.0)
grey = 1.0;
@ -379,7 +388,7 @@ static boolean PaletteRemap_AddColourisation(remaptable_t *tr, int start, int en
bg = g * grey;
bb = b * grey;
tr->remap[i] = NearestColor(
remap[i] = NearestColor(
(int)br,
(int)bg,
(int)bb
@ -389,16 +398,16 @@ static boolean PaletteRemap_AddColourisation(remaptable_t *tr, int start, int en
return true;
}
static boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r, int g, int b, int amount)
static boolean PaletteRemap_DoTint(UINT8 *remap, int start, int end, int r, int g, int b, int amount)
{
if (IndicesOutOfRange(start, end))
return false;
for (int i = start; i < end; ++i)
{
float br = pMasterPalette[i].s.red;
float bg = pMasterPalette[i].s.green;
float bb = pMasterPalette[i].s.blue;
float br = pMasterPalette[remap[i]].s.red;
float bg = pMasterPalette[remap[i]].s.green;
float bb = pMasterPalette[remap[i]].s.blue;
float a = amount * 0.01f;
float ia = 1.0f - a;
@ -406,7 +415,7 @@ static boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r,
bg = bg * ia + g * a;
bb = bb * ia + b * a;
tr->remap[i] = NearestColor(
remap[i] = NearestColor(
(int)br,
(int)bg,
(int)bb
@ -416,40 +425,44 @@ static boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r,
return true;
}
static boolean PaletteRemap_AddInvert(remaptable_t *tr, int start, int end)
static boolean PaletteRemap_DoInvert(UINT8 *remap, int start, int end)
{
if (IndicesOutOfRange(start, end))
return false;
for (int i = start; i < end; ++i)
{
tr->remap[i] = NearestColor(
255 - tr->remap[pMasterPalette[i].s.red],
255 - tr->remap[pMasterPalette[i].s.green],
255 - tr->remap[pMasterPalette[i].s.blue]
remap[i] = NearestColor(
255 - pMasterPalette[remap[i]].s.red,
255 - pMasterPalette[remap[i]].s.green,
255 - pMasterPalette[remap[i]].s.blue
);
}
return true;
}
struct PaletteRemapParseResult
{
paletteremap_t remap;
char *error;
};
struct ParsedTranslation
{
struct ParsedTranslation *next;
remaptable_t *remap;
remaptable_t *baseTranslation;
struct PaletteRemapParseResult *data;
};
static struct ParsedTranslation *parsedTranslationListHead = NULL;
static struct ParsedTranslation *parsedTranslationListTail = NULL;
static void AddParsedTranslation(remaptable_t *remap, remaptable_t *base_translation, struct PaletteRemapParseResult *data)
static void AddParsedTranslation(remaptable_t *remap, remaptable_t *base_translation)
{
struct ParsedTranslation *node = Z_Calloc(sizeof(struct ParsedTranslation), PU_STATIC, NULL);
node->remap = remap;
node->data = data;
node->baseTranslation = base_translation;
if (parsedTranslationListHead == NULL)
@ -461,7 +474,7 @@ static void AddParsedTranslation(remaptable_t *remap, remaptable_t *base_transla
}
}
static void PaletteRemap_ApplyResult(remaptable_t *tr, struct PaletteRemapParseResult *data)
static void PaletteRemap_Apply(UINT8 *remap, paletteremap_t *data)
{
int start = data->start;
int end = data->end;
@ -469,24 +482,27 @@ static void PaletteRemap_ApplyResult(remaptable_t *tr, struct PaletteRemapParseR
switch (data->type)
{
case REMAP_ADD_INDEXRANGE:
PaletteRemap_AddIndexRange(tr, start, end, data->indexRange.pal1, data->indexRange.pal2);
PaletteRemap_DoIndexRange(remap, start, end, data->indexRange.pal1, data->indexRange.pal2);
break;
case REMAP_ADD_COLORRANGE:
PaletteRemap_AddColorRange(tr, start, end,
PaletteRemap_DoColorRange(remap, start, end,
data->colorRange.r1, data->colorRange.g1, data->colorRange.b1,
data->colorRange.r2, data->colorRange.g2, data->colorRange.b2);
break;
case REMAP_ADD_COLOURISATION:
PaletteRemap_AddColourisation(tr, start, end,
PaletteRemap_DoColourisation(remap, start, end,
data->colourisation.r, data->colourisation.g, data->colourisation.b);
break;
case REMAP_ADD_DESATURATION:
PaletteRemap_AddDesaturation(tr, start, end,
PaletteRemap_DoDesaturation(remap, start, end,
data->desaturation.r1, data->desaturation.g1, data->desaturation.b1,
data->desaturation.r2, data->desaturation.g2, data->desaturation.b2);
break;
case REMAP_ADD_TINT:
PaletteRemap_AddTint(tr, start, end, data->tint.r, data->tint.g, data->tint.b, data->tint.amount);
PaletteRemap_DoTint(remap, start, end, data->tint.r, data->tint.g, data->tint.b, data->tint.amount);
break;
case REMAP_ADD_INVERT:
PaletteRemap_DoInvert(remap, start, end);
break;
}
}
@ -496,26 +512,18 @@ void R_LoadParsedTranslations(void)
struct ParsedTranslation *node = parsedTranslationListHead;
while (node)
{
struct PaletteRemapParseResult *result = node->data;
struct ParsedTranslation *next = node->next;
remaptable_t *tr = node->remap;
if (tr)
{
if (tr->num_entries == 0)
{
tr->num_entries = NUM_PALETTE_ENTRIES;
PaletteRemap_SetIdentity(tr);
PaletteRemap_SetIdentity(tr);
if (node->baseTranslation)
memcpy(tr, node->baseTranslation, sizeof(remaptable_t));
}
if (node->baseTranslation)
memcpy(tr, node->baseTranslation, sizeof(remaptable_t));
PaletteRemap_ApplyResult(tr, result);
}
for (unsigned i = 0; i < tr->num_sources; i++)
PaletteRemap_Apply(tr->remap, &tr->sources[i]);
Z_Free(result);
Z_Free(node);
node = next;
@ -564,12 +572,10 @@ static struct PaletteRemapParseResult *ThrowError(const char *format, ...)
return err;
}
static struct PaletteRemapParseResult *MakeResult(enum PaletteRemapType type, int start, int end)
static struct PaletteRemapParseResult *MakeResult(paletteremaptype_t type, int start, int end)
{
struct PaletteRemapParseResult *tr = Z_Calloc(sizeof(struct PaletteRemapParseResult), PU_STATIC, NULL);
tr->type = type;
tr->start = start;
tr->end = end;
InitSource(&tr->remap, type, start, end);
return tr;
}
@ -640,12 +646,12 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
return ThrowError("expected ']'");
struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_COLORRANGE, start, end);
tr->colorRange.r1 = r1;
tr->colorRange.g1 = g1;
tr->colorRange.b1 = b1;
tr->colorRange.r2 = r2;
tr->colorRange.g2 = g2;
tr->colorRange.b2 = b2;
tr->remap.colorRange.r1 = r1;
tr->remap.colorRange.g1 = g1;
tr->remap.colorRange.b1 = b1;
tr->remap.colorRange.r2 = r2;
tr->remap.colorRange.g2 = g2;
tr->remap.colorRange.b2 = b2;
return tr;
}
else if (strcmp(tkn, "%") == 0)
@ -695,12 +701,12 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
return ThrowError("expected ']'");
struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_DESATURATION, start, end);
tr->desaturation.r1 = r1;
tr->desaturation.g1 = g1;
tr->desaturation.b1 = b1;
tr->desaturation.r2 = r2;
tr->desaturation.g2 = g2;
tr->desaturation.b2 = b2;
tr->remap.desaturation.r1 = r1;
tr->remap.desaturation.g1 = g1;
tr->remap.desaturation.b1 = b1;
tr->remap.desaturation.r2 = r2;
tr->remap.desaturation.g2 = g2;
tr->remap.desaturation.b2 = b2;
return tr;
}
else if (strcmp(tkn, "#") == 0)
@ -724,9 +730,9 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
return ThrowError("expected ']'");
struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_COLOURISATION, start, end);
tr->colourisation.r = r;
tr->colourisation.g = g;
tr->colourisation.b = b;
tr->remap.colourisation.r = r;
tr->remap.colourisation.g = g;
tr->remap.colourisation.b = b;
return tr;
}
else if (strcmp(tkn, "@") == 0)
@ -734,12 +740,10 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
// Tint translation
int a, r, g, b;
if (!ExpectToken(sc, "["))
return ThrowError("expected '[");
if (!ParseNumber(sc, &a))
return ThrowError("expected a number for amount");
if (!ExpectToken(sc, ","))
return ThrowError("expected ','");
if (!ExpectToken(sc, "["))
return ThrowError("expected '[");
if (!ParseNumber(sc, &r))
return ThrowError("expected a number for red");
if (!ExpectToken(sc, ","))
@ -754,10 +758,10 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
return ThrowError("expected ']'");
struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_TINT, start, end);
tr->tint.r = r;
tr->tint.g = g;
tr->tint.b = b;
tr->tint.amount = a;
tr->remap.tint.r = r;
tr->remap.tint.g = g;
tr->remap.tint.b = b;
tr->remap.tint.amount = a;
return tr;
}
else
@ -772,8 +776,8 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc)
return ThrowError("expected a number for ending index");
struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_INDEXRANGE, start, end);
tr->indexRange.pal1 = pal1;
tr->indexRange.pal2 = pal2;
tr->remap.indexRange.pal1 = pal1;
tr->remap.indexRange.pal2 = pal2;
return tr;
}
@ -884,10 +888,16 @@ static void PrepareNewTranslations(struct NewTranslation *list, size_t count)
// The translation is not generated until later, because the palette may not have been loaded.
// We store the result for when it's needed.
for (size_t j = 0; j < entry->num_results; j++)
AddParsedTranslation(tr, base_translation, entry->results[j]);
tr->sources = Z_Malloc(entry->num_results * sizeof(paletteremap_t), PU_STATIC, NULL);
tr->num_sources = entry->num_results;
tr->num_entries = 0;
for (size_t j = 0; j < entry->num_results; j++)
{
memcpy(&tr->sources[j], &entry->results[j]->remap, sizeof(paletteremap_t));
Z_Free(entry->results[j]);
}
AddParsedTranslation(tr, base_translation);
Z_Free(base_translation_name);
Z_Free(entry->results);
@ -1093,6 +1103,36 @@ remaptable_t *R_GetTranslationByID(int id)
return paletteremaps[id];
}
UINT8 *R_GetTranslationRemap(int id, skincolornum_t skincolor, INT32 skinnum)
{
remaptable_t *tr = R_GetTranslationByID(id);
if (!tr)
return NULL;
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_remap[skincolor])
{
UINT8 *remap = Z_Calloc(NUM_PALETTE_ENTRIES, PU_LEVEL, NULL);
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]);
tr->skincolor_remap[skincolor] = remap;
}
return tr->skincolor_remap[skincolor];
}
boolean R_TranslationIsValid(int id)
{
if (id < 0 || id >= (signed)numpaletteremaps)

View file

@ -15,10 +15,59 @@
#include "doomdef.h"
typedef enum
{
REMAP_ADD_INDEXRANGE,
REMAP_ADD_COLORRANGE,
REMAP_ADD_COLOURISATION,
REMAP_ADD_DESATURATION,
REMAP_ADD_TINT,
REMAP_ADD_INVERT
} paletteremaptype_t;
typedef struct
{
int start, end;
paletteremaptype_t type;
union
{
struct
{
int pal1, pal2;
} indexRange;
struct
{
int r1, g1, b1;
int r2, g2, b2;
} colorRange;
struct
{
double r1, g1, b1;
double r2, g2, b2;
} desaturation;
struct
{
int r, g, b;
} colourisation;
struct
{
int r, g, b, amount;
} tint;
};
} paletteremap_t;
typedef struct
{
UINT8 remap[256];
unsigned num_entries;
paletteremap_t *sources;
unsigned num_sources;
// A remap is 256 bytes long, and there is a max of 1182.
// 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;
} remaptable_t;
void PaletteRemap_Init(void);
@ -35,6 +84,7 @@ void R_AddCustomTranslation(const char *name, int trnum);
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);
boolean R_TranslationIsValid(int id);
void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum);