From f1408bfb5bd58940338048845e0f607d9661b659 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 9 Apr 2019 00:21:06 +0200 Subject: [PATCH] - allow retroactive substitution of cluster texts This is needed to localize Harmony without swapping out the MAPINFO. --- src/gamedata/g_mapinfo.cpp | 22 ++++++++++++++++++++-- src/gamedata/stringtable.cpp | 31 ++++++++++++++++++++++++++++++- src/gamedata/stringtable.h | 2 ++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index 5757703d2..9e3b1a444 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -765,12 +765,30 @@ void FMapInfoParser::ParseCluster() ParseAssign(); if (ParseLookupName(clusterinfo->EnterText)) clusterinfo->flags |= CLUSTER_LOOKUPENTERTEXT; + else + { + FStringf testlabel("CLUSTERENTER%d", clusterinfo->cluster); + if (GStrings.MatchDefaultString(testlabel, clusterinfo->EnterText)) + { + clusterinfo->EnterText = testlabel; + clusterinfo->flags |= CLUSTER_LOOKUPENTERTEXT; + } + } } else if (sc.Compare("exittext")) { ParseAssign(); if (ParseLookupName(clusterinfo->ExitText)) clusterinfo->flags |= CLUSTER_LOOKUPEXITTEXT; + else + { + FStringf testlabel("CLUSTEREXIT%d", clusterinfo->cluster); + if (GStrings.MatchDefaultString(testlabel, clusterinfo->ExitText)) + { + clusterinfo->ExitText = testlabel; + clusterinfo->flags |= CLUSTER_LOOKUPEXITTEXT; + } + } } else if (sc.Compare("music")) { @@ -1933,8 +1951,8 @@ level_info_t *FMapInfoParser::ParseMapHeader(level_info_t &defaultinfo) // Workaround to allow localizazion of IWADs which do not have a string label here (e.g. HACX.WAD) // This checks for a string labelled with the MapName and if that is identical to what got parsed here // the string table entry will be used. - auto c = GStrings.GetLanguageString(levelinfo->MapName, FStringTable::default_table); - if (c && !strcmp(c, sc.String)) + + if (GStrings.MatchDefaultString(levelinfo->MapName, sc.String)) { levelinfo->flags |= LEVEL_LOOKUPLEVELNAME; levelinfo->LevelName = levelinfo->MapName; diff --git a/src/gamedata/stringtable.cpp b/src/gamedata/stringtable.cpp index 3505470c2..2e249a0f9 100644 --- a/src/gamedata/stringtable.cpp +++ b/src/gamedata/stringtable.cpp @@ -250,6 +250,10 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) { InsertString(langentry.second, strName, str); } + else + { + DeleteString(langentry.second, strName); + } } } } @@ -372,6 +376,17 @@ void FStringTable::LoadLanguage (const TArray &buffer) // //========================================================================== +void FStringTable::DeleteString(int langid, FName label) +{ + allStrings[langid].Remove(label); +} + +//========================================================================== +// +// +// +//========================================================================== + void FStringTable::InsertString(int langid, FName label, const FString &string) { const char *strlangid = (const char *)&langid; @@ -386,7 +401,7 @@ void FStringTable::InsertString(int langid, FName label, const FString &string) break; } FString macroname(te.strings[0].GetChars() + index + 2, endindex - index - 2); - FStringf lookupstr("%s/%s", strlangid, macroname.GetChars()); + FStringf lookupstr("%s/%s", strlangid, macroname.GetChars()); FStringf replacee("@[%s]", macroname.GetChars()); FName lookupname(lookupstr, true); auto replace = allMacros.CheckKey(lookupname); @@ -550,6 +565,20 @@ const char *FStringTable::GetLanguageString(const char *name, uint32_t langtable return nullptr; } +bool FStringTable::MatchDefaultString(const char *name, const char *content) const +{ + // This only compares the first line to avoid problems with bad linefeeds. For the few cases where this feature is needed it is sufficient. + auto c = GetLanguageString(name, FStringTable::default_table); + if (!c) return false; + + // Check a secondary key, in case the text comparison cannot be done due to needed orthographic fixes (see Harmony's exit text) + FStringf checkkey("%s_CHECK", name); + auto cc = GetLanguageString(checkkey, FStringTable::default_table); + if (cc) c = cc; + + return (c && !strnicmp(c, content, strcspn(content, "\n\r\t"))); +} + //========================================================================== // // Finds a string by name and returns its value. If the string does diff --git a/src/gamedata/stringtable.h b/src/gamedata/stringtable.h index f4fcfa09f..e96d29c58 100644 --- a/src/gamedata/stringtable.h +++ b/src/gamedata/stringtable.h @@ -89,6 +89,7 @@ public: } const char *GetLanguageString(const char *name, uint32_t langtable, int gender = -1) const; + bool MatchDefaultString(const char *name, const char *content) const; const char *GetString(const char *name, uint32_t *langtable, int gender = -1) const; const char *operator() (const char *name) const; // Never returns NULL const char *operator[] (const char *name) const @@ -110,6 +111,7 @@ private: bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray &buffer); bool readMacros(int lumpnum); void InsertString(int langid, FName label, const FString &string); + void DeleteString(int langid, FName label); static size_t ProcessEscapes (char *str); };