From 0b36beb10d57168751520acb95a3ad654f1b2a2c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Nov 2023 12:44:22 +0100 Subject: [PATCH] serialize the remap data of custom translations defined at run time. --- src/common/engine/i_interface.h | 1 + src/common/engine/serializer.cpp | 10 ++++- src/d_main.cpp | 5 ++- src/p_saveg.cpp | 6 ++- src/r_data/r_translate.cpp | 65 +++++++++++++++++++++++++++++++- src/r_data/r_translate.h | 6 ++- 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/common/engine/i_interface.h b/src/common/engine/i_interface.h index 6679184de..ff35d6286 100644 --- a/src/common/engine/i_interface.h +++ b/src/common/engine/i_interface.h @@ -48,6 +48,7 @@ struct SystemCallbacks bool (*OkForLocalization)(FTextureID, const char*); FConfigFile* (*GetConfig)(); bool (*WantEscape)(); + FTranslationID(*RemapTranslation)(FTranslationID trans); }; extern SystemCallbacks sysCallbacks; diff --git a/src/common/engine/serializer.cpp b/src/common/engine/serializer.cpp index 71a0031b6..0255fe057 100644 --- a/src/common/engine/serializer.cpp +++ b/src/common/engine/serializer.cpp @@ -56,6 +56,7 @@ #include "texturemanager.h" #include "base64.h" #include "vm.h" +#include "i_interface.h" using namespace FileSys; @@ -1207,7 +1208,14 @@ FSerializer& Serialize(FSerializer& arc, const char* key, FTranslationID& value, int v = value.index(); int* defv = (int*)defval; Serialize(arc, key, v, defv); - value = FTranslationID::fromInt(v); + + if (arc.isReading()) + { + // allow games to alter the loaded value to handle dynamic lists. + if (sysCallbacks.RemapTranslation) value = sysCallbacks.RemapTranslation(FTranslationID::fromInt(v)); + else value = FTranslationID::fromInt(v); + } + return arc; } diff --git a/src/d_main.cpp b/src/d_main.cpp index f1f559363..54b1fffa2 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -3644,8 +3644,9 @@ static int D_DoomMain_Internal (void) OnMenuOpen, System_LanguageChanged, OkForLocalization, - []() ->FConfigFile* { return GameConfig; } - + []() ->FConfigFile* { return GameConfig; }, + nullptr, + RemapUserTranslation }; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index adcea8d90..d524ad139 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -958,6 +958,9 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) } arc("saveversion", SaveVersion); + // this sets up some static data needed further down which means it must be done first. + StaticSerializeTranslations(arc); + if (arc.isReading()) { Thinkers.DestroyAllThinkers(); @@ -1039,7 +1042,6 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) arc("polyobjs", Polyobjects); SerializeSubsectors(arc, "subsectors"); StatusBar->SerializeMessages(arc); - StaticSerializeTranslations(arc); canvasTextureInfo.Serialize(arc); SerializePlayers(arc, hubload); SerializeSounds(arc); @@ -1071,6 +1073,8 @@ void FLevelLocals::Serialize(FSerializer &arc, bool hubload) automap->UpdateShowAllLines(); } + // clean up the static data we allocated + StaticClearSerializeTranslationsData(); } diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index f79cfce80..799b2c32e 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -54,6 +54,14 @@ #include "gi.h" +//---------------------------------------------------------------------------- +// +// helper stuff for serializing TRANSLATION_User +// +//---------------------------------------------------------------------------- + +static TArray> usertransmap; + //---------------------------------------------------------------------------- // // @@ -69,6 +77,7 @@ static void SerializeRemap(FSerializer &arc, FRemapTable &remap) void StaticSerializeTranslations(FSerializer &arc) { + usertransmap.Clear(); if (arc.BeginArray("translations")) { // Does this level have custom translations? @@ -104,6 +113,60 @@ void StaticSerializeTranslations(FSerializer &arc) } arc.EndArray(); } + if (arc.BeginArray("usertranslations")) + { + // Does this level have custom translations? + FRemapTable* trans; + int w; + if (arc.isWriting()) + { + auto size = GPalette.NumTranslations(TRANSLATION_User); + for (unsigned int i = 0; i < size; ++i) + { + trans = GPalette.GetTranslation(TRANSLATION_User, i); + if (trans != NULL && !trans->IsIdentity()) + { + if (arc.BeginObject(nullptr)) + { + arc("index", i); + SerializeRemap(arc, *trans); + arc.EndObject(); + } + } + } + } + else + { + while (arc.BeginObject(nullptr)) + { + arc("index", w); + FRemapTable remap; + SerializeRemap(arc, remap); + // do not add the translation to the global list yet. We want to avoid adding tables that are not needed anymore. + usertransmap.Push(std::make_pair(TRANSLATION(TRANSLATION_User, w), remap)); + arc.EndObject(); + } + } + arc.EndArray(); + } +} + +void StaticClearSerializeTranslationsData() +{ + usertransmap.Reset(); +} + +FTranslationID RemapUserTranslation(FTranslationID trans) +{ + if (GetTranslationType(trans) == TRANSLATION_User) + { + for (auto& check : usertransmap) + { + if (trans == check.first) + return GPalette.AddTranslation(TRANSLATION_User, &check.second); + } + } + return trans; } //---------------------------------------------------------------------------- @@ -773,7 +836,7 @@ DEFINE_ACTION_FUNCTION(_Translation, AddTranslation) { NewTranslation.Remap[i] = ColorMatcher.Pick(self->colors[i]); } - auto trans = GPalette.StoreTranslation(TRANSLATION_Custom, &NewTranslation); + auto trans = GPalette.StoreTranslation(TRANSLATION_User, &NewTranslation); ACTION_RETURN_INT(trans.index()); } diff --git a/src/r_data/r_translate.h b/src/r_data/r_translate.h index 036aeabae..549f4b3a0 100644 --- a/src/r_data/r_translate.h +++ b/src/r_data/r_translate.h @@ -19,6 +19,7 @@ enum TRANSLATION_Blood, TRANSLATION_RainPillar, TRANSLATION_Custom, + TRANSLATION_User, NUM_TRANSLATION_TABLES }; @@ -42,8 +43,11 @@ FTranslationID CreateBloodTranslation(PalEntry color); FTranslationID R_FindCustomTranslation(FName name); void R_ParseTrnslate(); -void StaticSerializeTranslations(FSerializer& arc); +// serialization stuff. +void StaticSerializeTranslations(FSerializer& arc); +void StaticClearSerializeTranslationsData(); +FTranslationID RemapUserTranslation(FTranslationID trans); #endif // __R_TRANSLATE_H