From 4668fa95e35d002f3d0fdc2d208c4452969f6018 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 13 Apr 2019 14:43:49 +0200 Subject: [PATCH] - when altering the default string table, make sure that all existing text for the given label is removed that comes from an older resource file. If this isn't done there can be a mix of content from different sources, depending on the language. It's better to have correct English text than unfitting localized versions. --- src/gamedata/d_dehacked.cpp | 15 ++++++++--- src/gamedata/stringtable.cpp | 50 ++++++++++++++++++++++++++++++------ src/gamedata/stringtable.h | 8 +++--- 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index c7105117d2..7156796db1 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -282,6 +282,7 @@ static int PatchSize; static char *Line1, *Line2; static int dversion, pversion; static bool including, includenotext; +static int LumpFileNum; static const char *unknown_str = "Unknown key %s encountered in %s %d.\n"; @@ -2169,7 +2170,7 @@ static int PatchMusic (int dummy) keystring << "MUSIC_" << Line1; - TableElement te = { newname, newname, newname, newname }; + TableElement te = { LumpFileNum, { newname, newname, newname, newname } }; DehStrings.Insert(keystring, te); DPrintf (DMSG_SPAMMY, "Music %s set to:\n%s\n", keystring.GetChars(), newname.GetChars()); } @@ -2285,7 +2286,7 @@ static int PatchText (int oldSize) if (str != NULL) { FString newname = newStr; - TableElement te = { newname, newname, newname, newname }; + TableElement te = { LumpFileNum, { newname, newname, newname, newname } }; DehStrings.Insert(str, te); EnglishStrings.Remove(str); // remove entry so that it won't get found again by the next iteration or by another replacement later good = true; @@ -2340,7 +2341,7 @@ static int PatchStrings (int dummy) // Account for a discrepancy between Boom's and ZDoom's name for the red skull key pickup message const char *ll = Line1; if (!stricmp(ll, "GOTREDSKULL")) ll = "GOTREDSKUL"; - TableElement te = { holdstring, holdstring, holdstring, holdstring }; + TableElement te = { LumpFileNum, { holdstring, holdstring, holdstring, holdstring } }; DehStrings.Insert(ll, te); DPrintf (DMSG_SPAMMY, "%s set to:\n%s\n", Line1, holdstring.GetChars()); } @@ -2496,13 +2497,19 @@ int D_LoadDehLumps(DehLumpSource source) bool D_LoadDehLump(int lumpnum) { + auto ls = LumpFileNum; + LumpFileNum = Wads.GetLumpFile(lumpnum); + PatchSize = Wads.LumpLength(lumpnum); PatchName = copystring(Wads.GetLumpFullPath(lumpnum)); PatchFile = new char[PatchSize + 1]; Wads.ReadLump(lumpnum, PatchFile); PatchFile[PatchSize] = '\0'; // terminate with a '\0' character - return DoDehPatch(); + auto res = DoDehPatch(); + LumpFileNum = ls; + + return res; } bool D_LoadDehFile(const char *patchfile) diff --git a/src/gamedata/stringtable.cpp b/src/gamedata/stringtable.cpp index ea8fa074bd..724951c22c 100644 --- a/src/gamedata/stringtable.cpp +++ b/src/gamedata/stringtable.cpp @@ -67,8 +67,8 @@ void FStringTable::LoadStrings () { auto lumpdata = Wads.ReadLumpIntoArray(lump); - if (!ParseLanguageCSV(lumpdata)) - LoadLanguage (lumpdata); + if (!ParseLanguageCSV(lump, lumpdata)) + LoadLanguage (lump, lumpdata); } UpdateLanguage(); allMacros.Clear(); @@ -191,7 +191,7 @@ bool FStringTable::readMacros(int lumpnum) // //========================================================================== -bool FStringTable::ParseLanguageCSV(const TArray &buffer) +bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) { if (memcmp(buffer.Data(), "default,", 8)) return false; auto data = parseCSV(buffer); @@ -199,6 +199,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) int labelcol = -1; int filtercol = -1; TArray> langrows; + bool hasDefaultEntry = false; if (data.Size() > 0) { @@ -221,6 +222,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) if (lang.CompareNoCase("default") == 0) { langrows.Push(std::make_pair(column, default_table)); + hasDefaultEntry = true; } else if (lang.Len() < 4) { @@ -243,12 +245,16 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) } FName strName = row[labelcol]; + if (hasDefaultEntry) + { + DeleteForLabel(lumpnum, strName); + } for (auto &langentry : langrows) { auto str = row[langentry.first]; if (str.Len() > 0) { - InsertString(langentry.second, strName, str); + InsertString(lumpnum, langentry.second, strName, str); } else { @@ -266,7 +272,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) // //========================================================================== -void FStringTable::LoadLanguage (const TArray &buffer) +void FStringTable::LoadLanguage (int lumpnum, const TArray &buffer) { bool errordone = false; TArray activeMaps; @@ -363,10 +369,14 @@ void FStringTable::LoadLanguage (const TArray &buffer) } if (!skip) { + if (activeMaps[0] == default_table) + { + DeleteForLabel(lumpnum, strName); + } // Insert the string into all relevant tables. for (auto map : activeMaps) { - InsertString(map, strName, strText); + InsertString(lumpnum, map, strName, strText); } } } @@ -384,16 +394,40 @@ void FStringTable::DeleteString(int langid, FName label) allStrings[langid].Remove(label); } +//========================================================================== +// +// This deletes all older entries for a given label. This gets called +// when a string in the default table gets updated. +// +//========================================================================== + +void FStringTable::DeleteForLabel(int lumpnum, FName label) +{ + decltype(allStrings)::Iterator it(allStrings); + decltype(allStrings)::Pair *pair; + auto filenum = Wads.GetLumpFile(lumpnum); + + while (it.NextPair(pair)) + { + auto entry = pair->Value.CheckKey(label); + if (entry && entry->filenum < filenum) + { + pair->Value.Remove(label); + } + } + +} + //========================================================================== // // // //========================================================================== -void FStringTable::InsertString(int langid, FName label, const FString &string) +void FStringTable::InsertString(int lumpnum, int langid, FName label, const FString &string) { const char *strlangid = (const char *)&langid; - TableElement te = { string, string, string, string }; + TableElement te = { lumpnum, { string, string, string, string } }; long index; while ((index = te.strings[0].IndexOf("@[")) >= 0) { diff --git a/src/gamedata/stringtable.h b/src/gamedata/stringtable.h index e96d29c58e..37dac5553e 100644 --- a/src/gamedata/stringtable.h +++ b/src/gamedata/stringtable.h @@ -49,6 +49,7 @@ struct TableElement { + int filenum; FString strings[4]; }; @@ -104,14 +105,15 @@ private: LangMap allStrings; TArray> currentLanguageSet; - void LoadLanguage (const TArray &buffer); + void LoadLanguage (int lumpnum, const TArray &buffer); TArray> parseCSV(const TArray &buffer); - bool ParseLanguageCSV(const TArray &buffer); + bool ParseLanguageCSV(int lumpnum, const TArray &buffer); bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray &buffer); bool readMacros(int lumpnum); - void InsertString(int langid, FName label, const FString &string); + void InsertString(int lumpnum, int langid, FName label, const FString &string); void DeleteString(int langid, FName label); + void DeleteForLabel(int lumpnum, FName label); static size_t ProcessEscapes (char *str); };