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 6502551e3..000000000 Binary files a/wadsrc/static/sbigfont.lmp and /dev/null differ