diff --git a/src/d_main.c b/src/d_main.c index 80907a013d9c6586c3b0d7cb828404e8d5214d67..9c3053a93eef976b412773a38cb7dbd12ab8b7b4 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -50,6 +50,7 @@ #include "p_saveg.h" #include "r_main.h" #include "r_local.h" +#include "r_translation.h" #include "s_sound.h" #include "st_stuff.h" #include "v_video.h" @@ -1475,6 +1476,8 @@ void D_SRB2Main(void) // setup loading screen SCR_Startup(); + PaletteRemap_Init(); + HU_Init(); CON_Init(); diff --git a/src/deh_lua.c b/src/deh_lua.c index 0b789547b266aeb238701ca6b34c4f8702c334fb..8135a77ff981329ada656e1196f4afc83039ae05 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -572,7 +572,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word); return 0; } - else if (fastncmp("MN_",word,3)) { + else if (fastncmp("MN_",word,3)) + { p = word+3; for (i = 0; i < NUMMENUTYPES; i++) if (fastcmp(p, MENUTYPES_LIST[i])) { @@ -582,6 +583,19 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word); return 0; } + else if (mathlib && fastncmp("TRANSLATION_",word,12)) + { + p = word+12; + for (i = 0; i < (signed)numcustomtranslations; i++) + { + if (fasticmp(p, customtranslations[i].name) == 0) + { + lua_pushinteger(L, (int)customtranslations[i].id); + return 1; + } + } + return luaL_error(L, "translation '%s' could not be found.\n", word); + } if (fastcmp(word, "BT_USE")) // Remove case when 2.3 nears release... { diff --git a/src/deh_lua.h b/src/deh_lua.h index 1bec371ccb42d5b76549103d9068c5e471825c98..9c6fb6257413aefa47f87766a72d7ca0402c8264 100644 --- a/src/deh_lua.h +++ b/src/deh_lua.h @@ -20,6 +20,7 @@ #include "m_misc.h" #include "p_local.h" #include "st_stuff.h" +#include "r_translation.h" #include "fastcmp.h" #include "lua_script.h" #include "lua_libs.h" diff --git a/src/deh_tables.c b/src/deh_tables.c index 7012ede466b2a1734fc9a47d9e63591ed900a05d..1223f0f2c8909e0a7d9960cb45d20d6dd5446797 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -219,6 +219,7 @@ actionpointer_t actionpointers[] = {{A_ChangeColorRelative}, "A_CHANGECOLORRELATIVE"}, {{A_ChangeColorAbsolute}, "A_CHANGECOLORABSOLUTE"}, {{A_Dye}, "A_DYE"}, + {{A_SetTranslation}, "A_SETTRANSLATION"}, {{A_MoveRelative}, "A_MOVERELATIVE"}, {{A_MoveAbsolute}, "A_MOVEABSOLUTE"}, {{A_Thrust}, "A_THRUST"}, diff --git a/src/info.h b/src/info.h index 5c7a9f3fd428579c674c7f969db44f7d71b88f07..4cd6c77b6f5ab65afa35f91eabf03834150a65a8 100644 --- a/src/info.h +++ b/src/info.h @@ -173,6 +173,7 @@ enum actionnum A_CHANGECOLORRELATIVE, A_CHANGECOLORABSOLUTE, A_DYE, + A_SETTRANSLATION, A_MOVERELATIVE, A_MOVEABSOLUTE, A_THRUST, @@ -445,6 +446,7 @@ void A_SetRandomTics(); void A_ChangeColorRelative(); void A_ChangeColorAbsolute(); void A_Dye(); +void A_SetTranslation(); void A_MoveRelative(); void A_MoveAbsolute(); void A_Thrust(); diff --git a/src/p_enemy.c b/src/p_enemy.c index 93c828fbecd1394e1adbeac6aa3fd43cc43437b6..5e546f64a8b1cde1e853526b0fdb84c87edffcea 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -196,6 +196,7 @@ void A_SetRandomTics(mobj_t *actor); void A_ChangeColorRelative(mobj_t *actor); void A_ChangeColorAbsolute(mobj_t *actor); void A_Dye(mobj_t *actor); +void A_SetTranslation(mobj_t *actor); void A_MoveRelative(mobj_t *actor); void A_MoveAbsolute(mobj_t *actor); void A_Thrust(mobj_t *actor); @@ -9068,6 +9069,27 @@ void A_Dye(mobj_t *actor) } } +// Function: A_SetTranslation +// +// Description: Changes the translation of an actor. +// +// var1 = translation ID +// var2 = unused +// +void A_SetTranslation(mobj_t *actor) +{ + INT32 locvar1 = var1; + + mobj_t *target = actor; + if (LUA_CallAction(A_SETTRANSLATION, actor)) + return; + + if (R_TranslationIsValid(locvar1)) + actor->translation = (UINT32)locvar1; + else + actor->translation = 0; +} + // Function: A_MoveRelative // // Description: Moves an object (wrapper for P_Thrust) diff --git a/src/p_setup.c b/src/p_setup.c index e0b6e902d3498cea629cb55840a0622ebd34d909..908c6f031b81e007b12a373f590a35103dcbfaad 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -8165,7 +8165,7 @@ static boolean P_LoadAddon(UINT16 numlumps) HWR_ClearAllTextures(); #endif - R_LoadTrnslateLumps(); + R_LoadParsedTranslations(); // // search for sprite replacements diff --git a/src/r_data.c b/src/r_data.c index 8a7a4dd6fa4e441cd1e31c94bb3102573d77f483..08624b454ed39efa4cf2735dab39ae911aa3df14 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1209,11 +1209,8 @@ void R_InitData(void) R_Init8to16(); } - CONS_Printf("PaletteRemap_Init()...\n"); - PaletteRemap_Init(); - - CONS_Printf("R_LoadTrnslateLumps()...\n"); - R_LoadTrnslateLumps(); + CONS_Printf("R_LoadParsedTranslations()...\n"); + R_LoadParsedTranslations(); CONS_Printf("R_LoadTextures()...\n"); R_LoadTextures(); diff --git a/src/r_translation.c b/src/r_translation.c index f43ff53d26e9280a4e1b4ba6a6bf6477280d1f0a..4125ea94f2611441933838cd3a341aca8084cb89 100644 --- a/src/r_translation.c +++ b/src/r_translation.c @@ -140,7 +140,7 @@ boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end, int pal return true; } -boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2) +boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int _r1, int _g1, int _b1, int _r2, int _g2, int _b2) { if (IndicesOutOfRange(start, end)) return false; @@ -295,6 +295,91 @@ boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r, int g, return true; } +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(unsigned id, int base_translation, struct PaletteRemapParseResult *data) +{ + struct ParsedTranslation *node = Z_Calloc(sizeof(struct ParsedTranslation), PU_STATIC, NULL); + + node->remap = paletteremaps[id]; + node->data = data; + + if (base_translation != -1) + node->baseTranslation = paletteremaps[base_translation]; + + if (parsedTranslationListHead == NULL) + parsedTranslationListHead = parsedTranslationListTail = node; + else + { + parsedTranslationListTail->next = node; + parsedTranslationListTail = node; + } +} + +void PaletteRemap_ApplyResult(remaptable_t *tr, struct PaletteRemapParseResult *data) +{ + int start = data->start; + int end = data->end; + + switch (data->type) + { + case REMAP_ADD_INDEXRANGE: + PaletteRemap_AddIndexRange(tr, start, end, data->indexRange.pal1, data->indexRange.pal2); + break; + case REMAP_ADD_COLORRANGE: + PaletteRemap_AddColorRange(tr, 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, + data->colourisation.r, data->colourisation.g, data->colourisation.b); + break; + case REMAP_ADD_DESATURATION: + PaletteRemap_AddDesaturation(tr, 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); + break; + } +} + +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; + PaletteRemap_SetIdentity(tr); + + if (node->baseTranslation) + memcpy(tr, node->baseTranslation, sizeof(remaptable_t)); + + PaletteRemap_ApplyResult(tr, result); + + Z_Free(result); + Z_Free(node); + + node = next; + } + + parsedTranslationListHead = parsedTranslationListTail = NULL; +} + static boolean ExpectToken(tokenizer_t *sc, const char *expect) { return strcmp(sc->get(sc, 0), expect) == 0; @@ -360,10 +445,21 @@ static struct PaletteRemapParseResult *ThrowError(const char *format, ...) vsprintf(err->error, format, argptr); va_end(argptr); + err->has_error = true; + return err; } -static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr, tokenizer_t *sc) +static struct PaletteRemapParseResult *MakeResult(enum PaletteRemapType 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; + return tr; +} + +static struct PaletteRemapParseResult *PaletteRemap_ParseString(tokenizer_t *sc) { int start, end; @@ -426,7 +522,14 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr if (!ExpectToken(sc, "]")) return ThrowError("expected ']'"); - PaletteRemap_AddColorRange(tr, start, end, r1, g1, b1, r2, g2, b2); + 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; + return tr; } else if (strcmp(tkn, "%") == 0) { @@ -474,7 +577,14 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr if (!ExpectToken(sc, "]")) return ThrowError("expected ']'"); - PaletteRemap_AddDesaturation(tr, start, end, r1, g1, b1, r2, g2, b2); + 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; + return tr; } else if (strcmp(tkn, "#") == 0) { @@ -496,7 +606,11 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr if (!ExpectToken(sc, "]")) return ThrowError("expected ']'"); - PaletteRemap_AddColourisation(tr, start, end, r, g, b); + struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_COLOURISATION, start, end); + tr->colourisation.r = r; + tr->colourisation.g = g; + tr->colourisation.b = b; + return tr; } else if (strcmp(tkn, "@") == 0) { @@ -522,7 +636,12 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr if (!ExpectToken(sc, "]")) return ThrowError("expected ']'"); - PaletteRemap_AddTint(tr, start, end, r, g, b, a); + 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; + return tr; } else { @@ -535,21 +654,24 @@ static struct PaletteRemapParseResult *PaletteRemap_ParseString(remaptable_t *tr if (!ParseNumber(sc, &pal2)) return ThrowError("expected a number for ending index"); - PaletteRemap_AddIndexRange(tr, start, end, pal1, pal2); + struct PaletteRemapParseResult *tr = MakeResult(REMAP_ADD_INDEXRANGE, start, end); + tr->indexRange.pal1 = pal1; + tr->indexRange.pal2 = pal2; + return tr; } return NULL; } -struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(remaptable_t *tr, const char *translation) +struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(const char *translation) { tokenizer_t *sc = Tokenizer_Open(translation, 1); - struct PaletteRemapParseResult *error = PaletteRemap_ParseString(tr, sc); + struct PaletteRemapParseResult *result = PaletteRemap_ParseString(sc); Tokenizer_Close(sc); - return error; + return result; } -static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) +void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) { char *lumpData = (char *)W_CacheLumpNumPwad(wadNum, lumpnum, PU_STATIC); size_t lumpLength = W_LumpLengthPwad(wadNum, lumpnum); @@ -562,7 +684,7 @@ static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) const char *tkn = sc->get(sc, 0); while (tkn != NULL) { - remaptable_t *tr = NULL; + int base_translation = -1; char *name = Z_StrDup(tkn); @@ -571,10 +693,8 @@ static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) { tkn = sc->get(sc, 0); - remaptable_t *tbl = R_GetTranslationByID(R_FindCustomTranslation(tkn)); - if (tbl) - tr = PaletteRemap_Copy(tbl); - else + base_translation = R_FindCustomTranslation(tkn); + if (base_translation == -1) { CONS_Alert(CONS_ERROR, "Error parsing translation '%s': No translation named '%s'\n", name, tkn); goto fail; @@ -582,11 +702,6 @@ static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) tkn = sc->get(sc, 0); } - else - { - tr = PaletteRemap_New(); - PaletteRemap_SetIdentity(tr); - } if (strcmp(tkn, "=") != 0) { @@ -595,12 +710,13 @@ static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) } tkn = sc->get(sc, 0); + struct PaletteRemapParseResult *result = NULL; do { - struct PaletteRemapParseResult *error = PaletteRemap_ParseTranslation(tr, tkn); - if (error) + result = PaletteRemap_ParseTranslation(tkn); + if (result->has_error) { - CONS_Alert(CONS_ERROR, "Error parsing translation '%s': %s\n", name, error->error); - Z_Free(error); + CONS_Alert(CONS_ERROR, "Error parsing translation '%s': %s\n", name, result->error); + Z_Free(result); goto fail; } @@ -614,10 +730,17 @@ static void P_ParseTrnslate(INT32 wadNum, UINT16 lumpnum) tkn = sc->get(sc, 0); } while (true); - // add it + // Allocate it and register it + remaptable_t *tr = PaletteRemap_New(); unsigned id = PaletteRemap_Add(tr); R_AddCustomTranslation(name, id); + + // Free this, since it's no longer needed Z_Free(name); + + // The translation is not generated until later, because the palette may not have been loaded. + // We store the result for when it's needed. + AddParsedTranslation(id, base_translation, result); } fail: @@ -625,29 +748,8 @@ fail: Z_Free(text); } -void R_LoadTrnslateLumps(void) -{ - for (INT32 w = numwadfiles-1; w >= 0; w--) - { - UINT16 lump = W_CheckNumForNamePwad("TRNSLATE", w, 0); - - while (lump != INT16_MAX) - { - P_ParseTrnslate(w, lump); - lump = W_CheckNumForNamePwad("TRNSLATE", (UINT16)w, lump + 1); - } - } -} - -struct CustomTranslation -{ - char *name; - unsigned id; - UINT32 hash; -}; - -static struct CustomTranslation *customtranslations = NULL; -static unsigned numcustomtranslations = 0; +customtranslation_t *customtranslations = NULL; +unsigned numcustomtranslations = 0; int R_FindCustomTranslation(const char *name) { @@ -664,12 +766,12 @@ int R_FindCustomTranslation(const char *name) void R_AddCustomTranslation(const char *name, int trnum) { - struct CustomTranslation *tr = NULL; + customtranslation_t *tr = NULL; UINT32 hash = quickncasehash(name, strlen(name)); for (unsigned i = 0; i < numcustomtranslations; i++) { - struct CustomTranslation *lookup = &customtranslations[i]; + customtranslation_t *lookup = &customtranslations[i]; if (hash == lookup->hash && strcmp(name, lookup->name) == 0) { tr = lookup; @@ -680,7 +782,7 @@ void R_AddCustomTranslation(const char *name, int trnum) if (tr == NULL) { numcustomtranslations++; - customtranslations = Z_Realloc(customtranslations, sizeof(struct CustomTranslation) * numcustomtranslations, PU_STATIC, NULL); + customtranslations = Z_Realloc(customtranslations, sizeof(customtranslation_t) * numcustomtranslations, PU_STATIC, NULL); tr = &customtranslations[numcustomtranslations - 1]; } @@ -696,8 +798,16 @@ unsigned R_NumCustomTranslations(void) remaptable_t *R_GetTranslationByID(int id) { - if (id < 0 || id >= (signed)numpaletteremaps) + if (!R_TranslationIsValid(id)) return NULL; return paletteremaps[id]; } + +boolean R_TranslationIsValid(int id) +{ + if (id < 0 || id >= (signed)numpaletteremaps) + return false; + + return true; +} diff --git a/src/r_translation.h b/src/r_translation.h index e9ca0219f99d01a3c3e64d2d05697887aa4952ce..8fb00660d3a937a90f5d3bc6dc0117a66db4f1b4 100644 --- a/src/r_translation.h +++ b/src/r_translation.h @@ -29,23 +29,75 @@ boolean PaletteRemap_IsIdentity(remaptable_t *tr); unsigned PaletteRemap_Add(remaptable_t *tr); boolean PaletteRemap_AddIndexRange(remaptable_t *tr, int start, int end, int pal1, int pal2); -boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int _r1,int _g1, int _b1, int _r2, int _g2, int _b2); +boolean PaletteRemap_AddColorRange(remaptable_t *tr, int start, int end, int _r1, int _g1, int _b1, int _r2, int _g2, int _b2); boolean PaletteRemap_AddDesaturation(remaptable_t *tr, int start, int end, double r1, double g1, double b1, double r2, double g2, double b2); boolean PaletteRemap_AddColourisation(remaptable_t *tr, int start, int end, int r, int g, int b); boolean PaletteRemap_AddTint(remaptable_t *tr, int start, int end, int r, int g, int b, int amount); +enum PaletteRemapType +{ + REMAP_ADD_INDEXRANGE, + REMAP_ADD_COLORRANGE, + REMAP_ADD_COLOURISATION, + REMAP_ADD_DESATURATION, + REMAP_ADD_TINT +}; + struct PaletteRemapParseResult { + 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; + }; + + boolean has_error; char error[4096]; }; -struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(remaptable_t *tr, const char *translation); +struct PaletteRemapParseResult *PaletteRemap_ParseTranslation(const char *translation); + +void PaletteRemap_ApplyResult(remaptable_t *tr, struct PaletteRemapParseResult *data); + +typedef struct CustomTranslation +{ + char *name; + unsigned id; + UINT32 hash; +} customtranslation_t; + +extern customtranslation_t *customtranslations; +extern unsigned numcustomtranslations; int R_FindCustomTranslation(const char *name); void R_AddCustomTranslation(const char *name, int trnum); unsigned R_NumCustomTranslations(void); remaptable_t *R_GetTranslationByID(int id); +boolean R_TranslationIsValid(int id); -void R_LoadTrnslateLumps(void); +void R_ParseTrnslate(INT32 wadNum, UINT16 lumpnum); +void R_LoadParsedTranslations(void); #endif diff --git a/src/w_wad.c b/src/w_wad.c index d012182f18208bd05435c9f7ee8e43d0f27256e2..87f99a5ed3332a7945f421f05b3701cfaeaf70d4 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -59,6 +59,7 @@ #include "r_textures.h" #include "r_patch.h" #include "r_picformats.h" +#include "r_translation.h" #include "i_time.h" #include "i_system.h" #include "i_video.h" // rendermode @@ -829,6 +830,16 @@ static void W_ReadFileShaders(wadfile_t *wadfile) #endif } +static void W_LoadTrnslateLumps(UINT16 w) +{ + UINT16 lump = W_CheckNumForNamePwad("TRNSLATE", w, 0); + while (lump != INT16_MAX) + { + R_ParseTrnslate(w, lump); + lump = W_CheckNumForNamePwad("TRNSLATE", (UINT16)w, lump + 1); + } +} + // Allocate a wadfile, setup the lumpinfo (directory) and // lumpcache, add the wadfile to the current active wadfiles // @@ -979,6 +990,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) // Read shaders from file W_ReadFileShaders(wadfile); + // The below hack makes me load this here. + W_LoadTrnslateLumps(numwadfiles - 1); + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) {