From 0b8fb3ac1a29289b81448b00973fe34081b322fd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 12 Feb 2019 00:19:44 +0100 Subject: [PATCH] - cleanup of font init to have less special cases To make things easier, DBIGFONT, SBIGFONT and HBIGFONT will now be renamed in the lump directory to make things a bit easier to handle. Another change is to make font folders atomic units to prevent cross-pollution between incompatible fonts. The only exception to this are the def* folders because they need to piece together their fonts from both zd_extra.pk3 and the IWADs. --- src/gamedata/g_mapinfo.cpp | 2 +- src/gamedata/w_wad.cpp | 32 ++++++++- src/gamedata/w_wad.h | 2 +- src/menu/menudef.cpp | 2 +- src/v_font.cpp | 67 +++++++++--------- src/v_font.h | 2 +- .../game-doomstrifechex/bigfont.lmp} | Bin wadsrc/static/sbigfont.lmp | Bin 6253 -> 0 bytes 8 files changed, 66 insertions(+), 41 deletions(-) rename wadsrc/static/{dbigfont.lmp => filter/game-doomstrifechex/bigfont.lmp} (100%) delete mode 100644 wadsrc/static/sbigfont.lmp diff --git a/src/gamedata/g_mapinfo.cpp b/src/gamedata/g_mapinfo.cpp index 77a942127..c7e20de09 100644 --- a/src/gamedata/g_mapinfo.cpp +++ b/src/gamedata/g_mapinfo.cpp @@ -51,7 +51,7 @@ #include "events.h" #include "i_system.h" -TArray wadclusterinfos; +static TArray wadclusterinfos; TArray wadlevelinfos; level_info_t TheDefaultLevelInfo; diff --git a/src/gamedata/w_wad.cpp b/src/gamedata/w_wad.cpp index 505796396..3ef9a7640 100644 --- a/src/gamedata/w_wad.cpp +++ b/src/gamedata/w_wad.cpp @@ -759,6 +759,7 @@ void FWadCollection::RenameSprites () { bool renameAll; bool MNTRZfound = false; + const char *altbigfont = gameinfo.gametype == GAME_Strife? "SBIGFONT" : (gameinfo.gametype & GAME_Raven)? "HBIGFONT" : "DBIGFONT"; static const uint32_t HereticRenames[] = { MAKE_ID('H','E','A','D'), MAKE_ID('L','I','C','H'), // Ironlich @@ -889,6 +890,11 @@ void FWadCollection::RenameSprites () } } } + else if (LumpInfo[i].lump->Namespace == ns_global) + { + // Rename the game specific big font lumps so that the font manager does not have to do problematic special checks for them. + if (!strcmp(LumpInfo[i].lump->Name, altbigfont)) strcpy(LumpInfo[i].lump->Name, "BIGFONT"); + } } } @@ -1265,6 +1271,8 @@ FResourceLump *FWadCollection::GetLumpRecord(int lump) const // GetLumpsInFolder // // Gets all lumps within a single folder in the hierarchy. +// If 'atomic' is set, it treats folders as atomic, i.e. only the +// content of the last found resource file having the given folder name gets used. // //========================================================================== @@ -1275,7 +1283,7 @@ static int folderentrycmp(const void *a, const void *b) return strcmp(A->name, B->name); } -unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray &result) const +unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray &result, bool atomic) const { FString path = inpath; FixPathSeperator(path); @@ -1287,13 +1295,31 @@ unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArrayFullName.IndexOf(path) == 0) { // Only if it hasn't been replaced. - if (Wads.CheckNumForFullName(LumpInfo[i].lump->FullName) == i) + if ((unsigned)Wads.CheckNumForFullName(LumpInfo[i].lump->FullName) == i) { result.Push({ LumpInfo[i].lump->FullName.GetChars(), i }); } } } - qsort(result.Data(), result.Size(), sizeof(FolderEntry), folderentrycmp); + if (result.Size()) + { + int maxfile = -1; + if (atomic) + { + // Find the highest resource file having content in the given folder. + for (auto & entry : result) + { + int thisfile = Wads.GetLumpFile(entry.lumpnum); + if (thisfile > maxfile) maxfile = thisfile; + } + // Delete everything from older files. + for (int i = result.Size() - 1; i >= 0; i--) + { + if ((int)result[i].lumpnum != maxfile) result.Delete(i); + } + } + qsort(result.Data(), result.Size(), sizeof(FolderEntry), folderentrycmp); + } return result.Size(); } diff --git a/src/gamedata/w_wad.h b/src/gamedata/w_wad.h index 469b3f668..4f6740a0e 100644 --- a/src/gamedata/w_wad.h +++ b/src/gamedata/w_wad.h @@ -179,7 +179,7 @@ public: int GetLumpIndexNum (int lump) const; // Returns the RFF index number for this lump FResourceLump *GetLumpRecord(int lump) const; // Returns the FResourceLump, in case the caller wants to have direct access to the lump cache. bool CheckLumpName (int lump, const char *name) const; // [RH] Returns true if the names match - unsigned GetLumpsInFolder(const char *path, TArray &result) const; + unsigned GetLumpsInFolder(const char *path, TArray &result, bool atomic) const; bool IsEncryptedFile(int lump) const; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 409db4ba3..2b6301653 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -404,7 +404,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc) } else if (args[i] == TypeFont) { - auto f = FFont::FindFont(sc.String); + auto f = V_GetFont(sc.String); if (f == nullptr) { sc.ScriptError("Unknown font %s", sc.String); diff --git a/src/v_font.cpp b/src/v_font.cpp index e7b2fd522..598f7d6ea 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -955,7 +955,7 @@ static int stripaccent(int code) return code; } -FFont *V_GetFont(const char *name) +FFont *V_GetFont(const char *name, const char *fontlumpname) { FFont *font = FFont::FindFont (name); if (font == nullptr) @@ -967,14 +967,14 @@ FFont *V_GetFont(const char *name) FStringf path("fonts/%s/", name); // Use a folder-based font only if it comes from a later file than the single lump version. - if (Wads.GetLumpsInFolder(path, folderdata)) + if (Wads.GetLumpsInFolder(path, folderdata, true)) { // This assumes that any custom font comes in one piece and not distributed across multiple resource files. folderfile = Wads.GetLumpFile(folderdata[0].lumpnum); } - lump = Wads.CheckNumForFullName(name, true); + lump = Wads.CheckNumForFullName(fontlumpname? fontlumpname : name, true); if (lump != -1 && Wads.GetLumpFile(lump) >= folderfile) { @@ -1003,7 +1003,7 @@ FFont *V_GetFont(const char *name) return new FFont(name, nullptr, path, HU_FONTSTART, HU_FONTSIZE, 1, -1); } } - return nullptr; + return font; } //========================================================================== @@ -1073,7 +1073,9 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla { TArray folderdata; FStringf path("fonts/%s/", filetemplate); - if (Wads.GetLumpsInFolder(path, folderdata)) + // If a name template is given, collect data from all resource files. + // For anything else, each folder is being treated as an atomic, self-contained unit and mixing from different glyph sets is blocked. + if (Wads.GetLumpsInFolder(path, folderdata, nametemplate == nullptr)) { // all valid lumps must be named with a hex number that represents its Unicode character index. for (auto &entry : folderdata) @@ -2962,20 +2964,14 @@ void V_InitFonts() V_InitCustomFonts (); // load the heads-up font - if (!(SmallFont = V_GetFont("SmallFont"))) + if (!(SmallFont = V_GetFont("SmallFont", "SMALLFNT"))) { - int i; - - if ((i = Wads.CheckNumForName("SMALLFNT")) >= 0) - { - SmallFont = new FSingleLumpFont("SmallFont", i); - } - else if (Wads.CheckNumForName ("FONTA_S") >= 0) + if (Wads.CheckNumForName ("FONTA_S") >= 0) { SmallFont = new FFont ("SmallFont", "FONTA%02u", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, 1, -1); SmallFont->SetCursor('['); } - else + else if (Wads.CheckNumForName ("STCFN033", ns_graphics) >= 0) { SmallFont = new FFont ("SmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } @@ -2986,33 +2982,17 @@ void V_InitFonts() { SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", "defsmallfont2", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } - else - { - SmallFont2 = SmallFont; - } } if (!(BigFont = V_GetFont("BigFont"))) { - const char *bigfontname = (gameinfo.gametype & GAME_DoomChex)? "DBIGFONT" : (gameinfo.gametype == GAME_Strife)? "SBIGFONT" : "HBIGFONT"; - try + if (gameinfo.gametype & GAME_Raven) { - BigFont = new FSingleLumpFont ("BigFont", Wads.CheckNumForName(bigfontname)); - } - catch (CRecoverableError &err) - { - BigFont = new FFont ("BigFont", (gameinfo.gametype & GAME_Raven)? "FONTB%02u" : nullptr, "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1); + BigFont = new FFont ("BigFont", "FONTB%02u", "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1); } } - if (!(ConFont = V_GetFont("ConsoleFont"))) + if (!(ConFont = V_GetFont("ConsoleFont", "CONFONT"))) { - try - { - ConFont = new FSingleLumpFont ("ConsoleFont", Wads.GetNumForName ("CONFONT")); - } - catch (CRecoverableError &err) - { - ConFont = new FFont ("ConsoleFont", nullptr, "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1); - } + ConFont = SmallFont; } if (!(IntermissionFont = FFont::FindFont("IntermissionFont"))) { @@ -3025,6 +3005,25 @@ void V_InitFonts() IntermissionFont = BigFont; } } + // This can only happen if gzdoom.pk3 is corrupted. ConFont should always be present. + if (ConFont == nullptr) + { + I_FatalError("Console font not found."); + } + // SmallFont and SmallFont2 have no default provided by the engine. BigFont only has in non-Raven games. + if (SmallFont == nullptr) + { + SmallFont = ConFont; + } + if (SmallFont2 == nullptr) + { + SmallFont2 = SmallFont; + } + if (BigFont == nullptr) + { + BigFont = SmallFont; + } + } void V_ClearFonts() diff --git a/src/v_font.h b/src/v_font.h index d67b1d899..de2482d99 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -150,7 +150,7 @@ void V_ClearFonts(); EColorRange V_FindFontColor (FName name); PalEntry V_LogColorFromColorRange (EColorRange range); EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int boldcolor); -FFont *V_GetFont(const char *); +FFont *V_GetFont(const char *fontname, const char *fontlumpname = nullptr); void V_InitFontColors(); #endif //__V_FONT_H__ diff --git a/wadsrc/static/dbigfont.lmp b/wadsrc/static/filter/game-doomstrifechex/bigfont.lmp similarity index 100% rename from wadsrc/static/dbigfont.lmp rename to wadsrc/static/filter/game-doomstrifechex/bigfont.lmp diff --git a/wadsrc/static/sbigfont.lmp b/wadsrc/static/sbigfont.lmp deleted file mode 100644 index 6502551e3bd6539a67667feed0a7fc97675b52ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6253 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