serialize the remap data of custom translations defined at run time.

This commit is contained in:
Christoph Oelckers 2023-11-19 12:44:22 +01:00
parent 8e319a7669
commit 0b36beb10d
6 changed files with 87 additions and 6 deletions

View file

@ -48,6 +48,7 @@ struct SystemCallbacks
bool (*OkForLocalization)(FTextureID, const char*);
FConfigFile* (*GetConfig)();
bool (*WantEscape)();
FTranslationID(*RemapTranslation)(FTranslationID trans);
};
extern SystemCallbacks sysCallbacks;

View file

@ -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;
}

View file

@ -3644,8 +3644,9 @@ static int D_DoomMain_Internal (void)
OnMenuOpen,
System_LanguageChanged,
OkForLocalization,
[]() ->FConfigFile* { return GameConfig; }
[]() ->FConfigFile* { return GameConfig; },
nullptr,
RemapUserTranslation
};

View file

@ -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();
}

View file

@ -54,6 +54,14 @@
#include "gi.h"
//----------------------------------------------------------------------------
//
// helper stuff for serializing TRANSLATION_User
//
//----------------------------------------------------------------------------
static TArray<std::pair<FTranslationID, FRemapTable>> 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());
}

View file

@ -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