diff --git a/src/m_tokenizer.c b/src/m_tokenizer.c index 876dc6b20..f36f7f6f3 100644 --- a/src/m_tokenizer.c +++ b/src/m_tokenizer.c @@ -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) diff --git a/src/r_things.c b/src/r_things.c index 084871700..d135386a0 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -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); diff --git a/src/r_translation.c b/src/r_translation.c index d732f6b08..3799c87cd 100644 --- a/src/r_translation.c +++ b/src/r_translation.c @@ -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) diff --git a/src/r_translation.h b/src/r_translation.h index 70bc2fd27..6219278f6 100644 --- a/src/r_translation.h +++ b/src/r_translation.h @@ -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);