diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 8685b4ec1..85fffe888 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -406,7 +406,7 @@ void P_SetupLevel(FLevelLocals *Level, int position, bool newGame) { Level->Players[i]->mo = nullptr; } - ClearScriptedTranslations(); + ClearTranslationSlot(TRANSLATION_LevelScripted); // Initial height of PointOfView will be set by player think. diff --git a/src/playsim/p_acs.cpp b/src/playsim/p_acs.cpp index 6e435c56d..25d9ae6b5 100644 --- a/src/playsim/p_acs.cpp +++ b/src/playsim/p_acs.cpp @@ -9591,6 +9591,7 @@ scriptwait: if (translation != NULL) { UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, transi), translation); + delete translation; translation = NULL; } break; diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 13dc24957..c31d5410d 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -53,18 +53,33 @@ #include "gi.h" +static FMemArena remapArena; static TAutoGrowArray TranslationTables[NUM_TRANSLATION_TABLES]; +inline FRemapTable* AllocRemap(FRemapTable *remap) +{ + auto newremap = (FRemapTable*)remapArena.Alloc(sizeof(FRemapTable)); + if (remap) *newremap = *remap; + else newremap->MakeIdentity(); + return newremap; +} + void UpdateTranslation(int trans, FRemapTable* remap) { - TranslationTables[GetTranslationType(trans)].SetVal(GetTranslationIndex(trans), remap); + auto newremap = AllocRemap(remap); + TranslationTables[GetTranslationType(trans)].SetVal(GetTranslationIndex(trans), newremap); remap->UpdateNative(); } -int AddTranslation(int slot, FRemapTable* remap) +int AddTranslation(int slot, FRemapTable* remap, int count) { - auto i = TranslationTables[slot].Push(remap); - return TRANSLATION(slot, i); + uint32_t id; + for (int i = 0; i < count; i++) + { + auto newremap = AllocRemap(&remap[i]); + id = TranslationTables[slot].Push(newremap); + } + return TRANSLATION(slot, id); } FRemapTable* GetTranslation(int slot, int index) @@ -78,19 +93,14 @@ void CopyTranslation(int dest, int src) TranslationTables[GetTranslationType(dest)][GetTranslationType(src)]->UpdateNative(); } -void ClearScriptedTranslations() +void ClearTranslationSlot(int slot) { - // [RH] Clear any scripted translation colors the previous level may have set. - for (unsigned i = 0; i < TranslationTables[TRANSLATION_LevelScripted].Size(); ++i) - { - FRemapTable* table = TranslationTables[TRANSLATION_LevelScripted][i]; - if (table != nullptr) - { - delete table; - TranslationTables[TRANSLATION_LevelScripted][i] = nullptr; - } - } - TranslationTables[TRANSLATION_LevelScripted].Clear(); + TranslationTables[slot].Clear(); +} + +unsigned NumTranslations(int slot) +{ + return TranslationTables[slot].Size(); } //---------------------------------------------------------------------------- @@ -103,18 +113,12 @@ FRemapTable *TranslationToTable(int translation) { unsigned int type = GetTranslationType(translation); unsigned int index = GetTranslationIndex(translation); - TAutoGrowArray *slots; - if (type <= 0 || type >= NUM_TRANSLATION_TABLES) + if (type <= 0 || type >= NUM_TRANSLATION_TABLES || index >= NumTranslations(type)) { return NULL; } - slots = &TranslationTables[type]; - if (index >= slots->Size()) - { - return NULL; - } - return slots->operator[](index); + return GetTranslation(type, index); } @@ -253,9 +257,10 @@ void FRemapTable::StaticSerializeTranslations(FSerializer &arc) int w; if (arc.isWriting()) { - for (unsigned int i = 0; i < TranslationTables[TRANSLATION_LevelScripted].Size(); ++i) + auto size = NumTranslations(TRANSLATION_LevelScripted); + for (unsigned int i = 0; i < size; ++i) { - trans = TranslationTables[TRANSLATION_LevelScripted][i]; + trans = TranslationToTable(TRANSLATION(TRANSLATION_LevelScripted, i)); if (trans != NULL && !trans->IsIdentity()) { if (arc.BeginObject(nullptr)) @@ -272,13 +277,9 @@ void FRemapTable::StaticSerializeTranslations(FSerializer &arc) while (arc.BeginObject(nullptr)) { arc("index", w); - trans = TranslationTables[TRANSLATION_LevelScripted].GetVal(w); - if (trans == NULL) - { - trans = new FRemapTable; - TranslationTables[TRANSLATION_LevelScripted].SetVal(w, trans); - } - trans->Serialize(arc); + FRemapTable remap; + remap.Serialize(arc); + UpdateTranslation(TRANSLATION(TRANSLATION_LevelScripted, w), &remap); arc.EndObject(); } } @@ -770,25 +771,36 @@ int FRemapTable::StoreTranslation(int slot) { unsigned int i; - for (i = 0; i < TranslationTables[slot].Size(); i++) + auto size = NumTranslations(slot); + for (i = 0; i < size; i++) { - if (*this == *TranslationTables[slot][i]) + if (*this == *TranslationToTable(TRANSLATION(slot, i))) { // A duplicate of this translation already exists return TRANSLATION(slot, i); } } - if (TranslationTables[slot].Size() >= MAX_DECORATE_TRANSLATIONS) + if (size >= MAX_DECORATE_TRANSLATIONS) { I_Error("Too many DECORATE translations"); } - FRemapTable *newtrans = new FRemapTable; - *newtrans = *this; - i = TranslationTables[slot].Push(newtrans); - return TRANSLATION(slot, i); + return AddTranslation(slot, this); } +//---------------------------------------------------------------------------- +// +// +// +//---------------------------------------------------------------------------- + +static void PushIdentityTable(int slot) +{ + FRemapTable table; + table.MakeIdentity(); + AddTranslation(slot, &table); +} + //---------------------------------------------------------------------------- // // @@ -804,7 +816,7 @@ int CreateBloodTranslation(PalEntry color) if (BloodTranslationColors.Size() == 0) { // Don't use the first slot. - TranslationTables[TRANSLATION_Blood].Push(NULL); + PushIdentityTable(TRANSLATION_Blood); BloodTranslationColors.Push(0); } @@ -822,35 +834,22 @@ int CreateBloodTranslation(PalEntry color) { I_Error("Too many blood colors"); } - FRemapTable *trans = new FRemapTable; - trans->Palette[0] = 0; - trans->Remap[0] = 0; + FRemapTable trans; + trans.Palette[0] = 0; + trans.Remap[0] = 0; for (i = 1; i < 256; i++) { - int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); + int bright = std::max(std::max(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); PalEntry pe = PalEntry(255, color.r*bright/255, color.g*bright/255, color.b*bright/255); int entry = ColorMatcher.Pick(pe.r, pe.g, pe.b); - trans->Palette[i] = pe; - trans->Remap[i] = entry; + trans.Palette[i] = pe; + trans.Remap[i] = entry; } - TranslationTables[TRANSLATION_Blood].Push(trans); + AddTranslation(TRANSLATION_Blood, &trans); return BloodTranslationColors.Push(color); } -//---------------------------------------------------------------------------- -// -// -// -//---------------------------------------------------------------------------- - -static void PushIdentityTable(int slot) -{ - FRemapTable *table = new FRemapTable; - table->MakeIdentity(); - TranslationTables[slot].Push(table); -} - //---------------------------------------------------------------------------- // // R_InitTranslationTables @@ -878,9 +877,10 @@ void R_InitTranslationTables () // The three standard translations from Doom or Heretic (seven for Strife), // plus the generic ice translation. + FRemapTable stdremaps[10]; for (i = 0; i < 8; ++i) { - PushIdentityTable(TRANSLATION_Standard); + stdremaps[i].MakeIdentity(); } // Each player corpse has its own translation so they won't change @@ -895,84 +895,84 @@ void R_InitTranslationTables () { for (i = 0x70; i < 0x80; i++) { // map green ramp to gray, brown, red - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = 0x60 + (i&0xf); - TranslationTables[TRANSLATION_Standard][1]->Remap[i] = 0x40 + (i&0xf); - TranslationTables[TRANSLATION_Standard][2]->Remap[i] = 0x20 + (i&0xf); + stdremaps[0].Remap[i] = 0x60 + (i&0xf); + stdremaps[1].Remap[i] = 0x40 + (i&0xf); + stdremaps[2].Remap[i] = 0x20 + (i&0xf); - TranslationTables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[0x60 + (i&0xf)] | MAKEARGB(255,0,0,0); - TranslationTables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[0x40 + (i&0xf)] | MAKEARGB(255,0,0,0); - TranslationTables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[0x20 + (i&0xf)] | MAKEARGB(255,0,0,0); + stdremaps[0].Palette[i] = GPalette.BaseColors[0x60 + (i&0xf)] | MAKEARGB(255,0,0,0); + stdremaps[1].Palette[i] = GPalette.BaseColors[0x40 + (i&0xf)] | MAKEARGB(255,0,0,0); + stdremaps[2].Palette[i] = GPalette.BaseColors[0x20 + (i&0xf)] | MAKEARGB(255,0,0,0); } } else if (gameinfo.gametype == GAME_Heretic) { for (i = 225; i <= 240; i++) { - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = 114+(i-225); // yellow - TranslationTables[TRANSLATION_Standard][1]->Remap[i] = 145+(i-225); // red - TranslationTables[TRANSLATION_Standard][2]->Remap[i] = 190+(i-225); // blue + stdremaps[0].Remap[i] = 114+(i-225); // yellow + stdremaps[1].Remap[i] = 145+(i-225); // red + stdremaps[2].Remap[i] = 190+(i-225); // blue - TranslationTables[TRANSLATION_Standard][0]->Palette[i] = GPalette.BaseColors[114+(i-225)] | MAKEARGB(255,0,0,0); - TranslationTables[TRANSLATION_Standard][1]->Palette[i] = GPalette.BaseColors[145+(i-225)] | MAKEARGB(255,0,0,0); - TranslationTables[TRANSLATION_Standard][2]->Palette[i] = GPalette.BaseColors[190+(i-225)] | MAKEARGB(255,0,0,0); + stdremaps[0].Palette[i] = GPalette.BaseColors[114+(i-225)] | MAKEARGB(255,0,0,0); + stdremaps[1].Palette[i] = GPalette.BaseColors[145+(i-225)] | MAKEARGB(255,0,0,0); + stdremaps[2].Palette[i] = GPalette.BaseColors[190+(i-225)] | MAKEARGB(255,0,0,0); } } else if (gameinfo.gametype == GAME_Strife) { for (i = 0x20; i <= 0x3F; ++i) { - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = i - 0x20; - TranslationTables[TRANSLATION_Standard][1]->Remap[i] = i - 0x20; - TranslationTables[TRANSLATION_Standard][2]->Remap[i] = 0xD0 + (i&0xf); - TranslationTables[TRANSLATION_Standard][3]->Remap[i] = 0xD0 + (i&0xf); - TranslationTables[TRANSLATION_Standard][4]->Remap[i] = i - 0x20; - TranslationTables[TRANSLATION_Standard][5]->Remap[i] = i - 0x20; - TranslationTables[TRANSLATION_Standard][6]->Remap[i] = i - 0x20; + stdremaps[0].Remap[i] = i - 0x20; + stdremaps[1].Remap[i] = i - 0x20; + stdremaps[2].Remap[i] = 0xD0 + (i&0xf); + stdremaps[3].Remap[i] = 0xD0 + (i&0xf); + stdremaps[4].Remap[i] = i - 0x20; + stdremaps[5].Remap[i] = i - 0x20; + stdremaps[6].Remap[i] = i - 0x20; } for (i = 0x50; i <= 0x5F; ++i) { // Merchant hair - TranslationTables[TRANSLATION_Standard][4]->Remap[i] = 0x80 + (i&0xf); - TranslationTables[TRANSLATION_Standard][5]->Remap[i] = 0x10 + (i&0xf); - TranslationTables[TRANSLATION_Standard][6]->Remap[i] = 0x40 + (i&0xf); + stdremaps[4].Remap[i] = 0x80 + (i&0xf); + stdremaps[5].Remap[i] = 0x10 + (i&0xf); + stdremaps[6].Remap[i] = 0x40 + (i&0xf); } for (i = 0x80; i <= 0x8F; ++i) { - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = 0x40 + (i&0xf); // red - TranslationTables[TRANSLATION_Standard][1]->Remap[i] = 0xB0 + (i&0xf); // rust - TranslationTables[TRANSLATION_Standard][2]->Remap[i] = 0x10 + (i&0xf); // gray - TranslationTables[TRANSLATION_Standard][3]->Remap[i] = 0x30 + (i&0xf); // dark green - TranslationTables[TRANSLATION_Standard][4]->Remap[i] = 0x50 + (i&0xf); // gold - TranslationTables[TRANSLATION_Standard][5]->Remap[i] = 0x60 + (i&0xf); // bright green - TranslationTables[TRANSLATION_Standard][6]->Remap[i] = 0x90 + (i&0xf); // blue + stdremaps[0].Remap[i] = 0x40 + (i&0xf); // red + stdremaps[1].Remap[i] = 0xB0 + (i&0xf); // rust + stdremaps[2].Remap[i] = 0x10 + (i&0xf); // gray + stdremaps[3].Remap[i] = 0x30 + (i&0xf); // dark green + stdremaps[4].Remap[i] = 0x50 + (i&0xf); // gold + stdremaps[5].Remap[i] = 0x60 + (i&0xf); // bright green + stdremaps[6].Remap[i] = 0x90 + (i&0xf); // blue } for (i = 0xC0; i <= 0xCF; ++i) { - TranslationTables[TRANSLATION_Standard][4]->Remap[i] = 0xA0 + (i&0xf); - TranslationTables[TRANSLATION_Standard][5]->Remap[i] = 0x20 + (i&0xf); - TranslationTables[TRANSLATION_Standard][6]->Remap[i] = (i&0xf); + stdremaps[4].Remap[i] = 0xA0 + (i&0xf); + stdremaps[5].Remap[i] = 0x20 + (i&0xf); + stdremaps[6].Remap[i] = (i&0xf); } - TranslationTables[TRANSLATION_Standard][6]->Remap[0xC0] = 1; + stdremaps[6].Remap[0xC0] = 1; for (i = 0xD0; i <= 0xDF; ++i) { - TranslationTables[TRANSLATION_Standard][4]->Remap[i] = 0xB0 + (i&0xf); - TranslationTables[TRANSLATION_Standard][5]->Remap[i] = 0x30 + (i&0xf); - TranslationTables[TRANSLATION_Standard][6]->Remap[i] = 0x10 + (i&0xf); + stdremaps[4].Remap[i] = 0xB0 + (i&0xf); + stdremaps[5].Remap[i] = 0x30 + (i&0xf); + stdremaps[6].Remap[i] = 0x10 + (i&0xf); } for (i = 0xF1; i <= 0xF6; ++i) { - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = 0xDF + (i&0xf); + stdremaps[0].Remap[i] = 0xDF + (i&0xf); } for (i = 0xF7; i <= 0xFB; ++i) { - TranslationTables[TRANSLATION_Standard][0]->Remap[i] = i - 6; + stdremaps[0].Remap[i] = i - 6; } for (i = 0; i < 7; ++i) { for (int j = 0x20; j <= 0xFB; ++j) { - TranslationTables[TRANSLATION_Standard][i]->Palette[j] = - GPalette.BaseColors[TranslationTables[TRANSLATION_Standard][i]->Remap[j]] | MAKEARGB(255,0,0,0); + stdremaps[i].Palette[j] = + GPalette.BaseColors[stdremaps[i].Remap[j]] | MAKEARGB(255,0,0,0); } } } @@ -986,7 +986,7 @@ void R_InitTranslationTables () { IcePaletteRemap[i] = ColorMatcher.Pick (IcePalette[i][0], IcePalette[i][1], IcePalette[i][2]); } - FRemapTable *remap = TranslationTables[TRANSLATION_Standard][STD_Ice]; + FRemapTable *remap = &stdremaps[STD_Ice]; remap->Remap[0] = 0; remap->Palette[0] = 0; for (i = 1; i < 256; ++i) @@ -1000,8 +1000,7 @@ void R_InitTranslationTables () } // The alphatexture translation. This is just a standard index as gray mapping. - PushIdentityTable(TRANSLATION_Standard); - remap = TranslationTables[TRANSLATION_Standard][STD_Gray]; + remap = &stdremaps[STD_Gray]; remap->Remap[0] = 0; remap->Palette[0] = 0; for (i = 1; i < 256; i++) @@ -1011,8 +1010,7 @@ void R_InitTranslationTables () } // Palette to grayscale ramp. For internal use only, because the remap does not map to the palette. - PushIdentityTable(TRANSLATION_Standard); - remap = TranslationTables[TRANSLATION_Standard][STD_Grayscale]; + remap = &stdremaps[STD_Grayscale]; remap->Remap[0] = 0; remap->Palette[0] = 0; for (i = 1; i < 256; i++) @@ -1025,6 +1023,7 @@ void R_InitTranslationTables () remap->Remap[i] = v; remap->Palette[i] = PalEntry(255, v, v, v); } + AddTranslation(TRANSLATION_Standard, stdremaps, 10); } @@ -1038,17 +1037,10 @@ void R_DeinitTranslationTables() { for (int i = 0; i < NUM_TRANSLATION_TABLES; ++i) { - for (unsigned int j = 0; j < TranslationTables[i].Size(); ++j) - { - if (TranslationTables[i][j] != NULL) - { - delete TranslationTables[i][j]; - TranslationTables[i][j] = NULL; - } - } - TranslationTables[i].Clear(); + ClearTranslationSlot(i); } BloodTranslationColors.Clear(); + remapArena.FreeAllBlocks(); } //---------------------------------------------------------------------------- @@ -1326,12 +1318,12 @@ void R_BuildPlayerTranslation (int player) D_GetPlayerColor (player, &h, &s, &v, &colorset); - R_CreatePlayerTranslation (h, s, v, colorset, - &Skins[players[player].userinfo.GetSkin()], - TranslationTables[TRANSLATION_Players][player], - TranslationTables[TRANSLATION_PlayersExtra][player], - TranslationTables[TRANSLATION_RainPillar][player] - ); + FRemapTable remaps[3]; + R_CreatePlayerTranslation (h, s, v, colorset, &Skins[players[player].userinfo.GetSkin()], &remaps[0], &remaps[1], &remaps[2]); + + UpdateTranslation(TRANSLATION(TRANSLATION_Players, player), &remaps[0]); + UpdateTranslation(TRANSLATION(TRANSLATION_PlayersExtra, player), &remaps[1]); + UpdateTranslation(TRANSLATION(TRANSLATION_RainPillar, player), &remaps[2]); } //---------------------------------------------------------------------------- @@ -1363,7 +1355,7 @@ DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation) PARAM_UINT(pnum); PARAM_POINTER(cls, FPlayerClass); - if (pnum >= MAXPLAYERS || tgroup >= NUM_TRANSLATION_TABLES || tnum >= TranslationTables[tgroup].Size()) + if (pnum >= MAXPLAYERS || tgroup >= NUM_TRANSLATION_TABLES) { ACTION_RETURN_BOOL(false); } @@ -1375,8 +1367,10 @@ DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation) if (cls != nullptr) { PlayerSkin = R_FindSkin(Skins[PlayerSkin].Name, int(cls - &PlayerClasses[0])); + FRemapTable remap; R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset), - &Skins[PlayerSkin], TranslationTables[tgroup][tnum]); + &Skins[PlayerSkin], &remap); + UpdateTranslation(TRANSLATION(tgroup, tnum), &remap); } ACTION_RETURN_BOOL(true); } @@ -1440,7 +1434,7 @@ DEFINE_ACTION_FUNCTION(_Translation, GetID) void R_ParseTrnslate() { customTranslationMap.Clear(); - TranslationTables[TRANSLATION_Custom].Clear(); + ClearTranslationSlot(TRANSLATION_Custom); int lump; int lastlump = 0; @@ -1452,7 +1446,7 @@ void R_ParseTrnslate() sc.TokenMustBe(TK_Identifier); FName newtrans = sc.String; - FRemapTable *base = nullptr; + FRemapTable NewTranslation; if (sc.CheckToken(':')) { sc.MustGetAnyToken(); @@ -1463,7 +1457,7 @@ void R_ParseTrnslate() { sc.ScriptError("Translation must be in the range [0,%d]", max); } - base = TranslationTables[TRANSLATION_Standard][sc.Number]; + NewTranslation = *TranslationToTable(TRANSLATION(TRANSLATION_Standard, sc.Number)); } else if (sc.TokenType == TK_Identifier) { @@ -1472,7 +1466,7 @@ void R_ParseTrnslate() { sc.ScriptError("Base translation '%s' not found in '%s'", sc.String, newtrans.GetChars()); } - base = TranslationTables[GetTranslationType(tnum)][GetTranslationIndex(tnum)]; + NewTranslation = *TranslationToTable(tnum); } else { @@ -1480,10 +1474,8 @@ void R_ParseTrnslate() sc.TokenMustBe(TK_Identifier); } } - sc.MustGetToken('='); - FRemapTable NewTranslation; - if (base != nullptr) NewTranslation = *base; else NewTranslation.MakeIdentity(); + sc.MustGetToken('='); do { sc.MustGetToken(TK_StringConst); diff --git a/src/r_data/r_translate.h b/src/r_data/r_translate.h index 07338178e..e86c47658 100644 --- a/src/r_data/r_translate.h +++ b/src/r_data/r_translate.h @@ -128,10 +128,10 @@ inline int GetTranslationIndex(uint32_t trans) // Retrieve the FRemapTable that an actor's translation value maps to. FRemapTable *TranslationToTable(int translation); void UpdateTranslation(int trans, FRemapTable* remap); -int AddTranslation(int slot, FRemapTable* remap); +int AddTranslation(int slot, FRemapTable* remap, int count = 1); FRemapTable* GetTranslation(int slot, int index); void CopyTranslation(int dest, int src); -void ClearScriptedTranslations(); +void ClearTranslationSlot(int slot); #define MAX_ACS_TRANSLATIONS 65535