Permalink
Browse files

- reworked font loader to make adding multi-lump fonts easier.

A multi-lump font can be created by putting all characters into a subdirectory of fonts/ with the intended name. Each character needs to be named by its character index as hex number.
So far this is only active for the predefined small fonts
  • Loading branch information...
coelckers committed Feb 7, 2019
1 parent 4952980 commit 4d2bb11317e1b6a9b0c774cc8b902f00b914d153
Showing with 123 additions and 47 deletions.
  1. +37 −0 src/gamedata/w_wad.cpp
  2. +7 −0 src/gamedata/w_wad.h
  3. +3 −2 src/scripting/thingdef_data.cpp
  4. +1 −1 src/scripting/vm/jit_move.cpp
  5. +1 −1 src/scripting/vm/vm.h
  6. +1 −1 src/scripting/vmthunks.cpp
  7. +4 −4 src/utility/zstring.cpp
  8. +2 −2 src/utility/zstring.h
  9. +66 −35 src/v_font.cpp
  10. +1 −1 src/v_font.h
  11. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn159.lmp → fonts/defsmallfont/009F.lmp}
  12. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/00AB.lmp
  13. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/00BB.lmp
  14. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn191.lmp → fonts/defsmallfont/00BF.lmp}
  15. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn192.lmp → fonts/defsmallfont/00C0.lmp}
  16. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn193.lmp → fonts/defsmallfont/00C1.lmp}
  17. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn194.lmp → fonts/defsmallfont/00C2.lmp}
  18. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn195.lmp → fonts/defsmallfont/00C3.lmp}
  19. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn196.lmp → fonts/defsmallfont/00C4.lmp}
  20. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn197.lmp → fonts/defsmallfont/00C5.lmp}
  21. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn199.lmp → fonts/defsmallfont/00C7.lmp}
  22. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn200.lmp → fonts/defsmallfont/00C8.lmp}
  23. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn201.lmp → fonts/defsmallfont/00C9.lmp}
  24. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn202.lmp → fonts/defsmallfont/00CA.lmp}
  25. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn205.lmp → fonts/defsmallfont/00CD.lmp}
  26. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn206.lmp → fonts/defsmallfont/00CE.lmp}
  27. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn207.lmp → fonts/defsmallfont/00CF.lmp}
  28. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn209.lmp → fonts/defsmallfont/00D1.lmp}
  29. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn211.lmp → fonts/defsmallfont/00D3.lmp}
  30. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn212.lmp → fonts/defsmallfont/00D4.lmp}
  31. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn213.lmp → fonts/defsmallfont/00D5.lmp}
  32. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn214.lmp → fonts/defsmallfont/00D6.lmp}
  33. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn217.lmp → fonts/defsmallfont/00D9.lmp}
  34. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn218.lmp → fonts/defsmallfont/00DA.lmp}
  35. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn219.lmp → fonts/defsmallfont/00DB.lmp}
  36. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn220.lmp → fonts/defsmallfont/00DC.lmp}
  37. BIN wadsrc_extra/static/filter/game-doom/{graphics/stcfn223.lmp → fonts/defsmallfont/00DF.lmp}
  38. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0178.lmp
  39. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0401.lmp
  40. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0410.lmp
  41. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0411.lmp
  42. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0412.lmp
  43. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0413.lmp
  44. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0414.lmp
  45. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0415.lmp
  46. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0416.lmp
  47. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0417.lmp
  48. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0418.lmp
  49. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0419.lmp
  50. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041A.lmp
  51. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041B.lmp
  52. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041C.lmp
  53. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041D.lmp
  54. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041E.lmp
  55. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/041F.lmp
  56. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0420.lmp
  57. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0421.lmp
  58. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0422.lmp
  59. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0423.lmp
  60. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0424.lmp
  61. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0425.lmp
  62. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0426.lmp
  63. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0427.lmp
  64. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0428.lmp
  65. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/0429.lmp
  66. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042A.lmp
  67. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042B.lmp
  68. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042C.lmp
  69. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042D.lmp
  70. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042E.lmp
  71. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/042F.lmp
  72. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/2014.lmp
  73. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/201C.lmp
  74. BIN wadsrc_extra/static/filter/game-doom/fonts/defsmallfont/201E.lmp
  75. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta60.lmp → fonts/defsmallfont/005C.lmp}
  76. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta61.lmp → fonts/defsmallfont/005D.lmp}
  77. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta62.lmp → fonts/defsmallfont/005E.lmp}
  78. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta63.lmp → fonts/defsmallfont/005F.lmp}
  79. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta164.lmp → fonts/defsmallfont/00C4.lmp}
  80. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta165.lmp → fonts/defsmallfont/00C5.lmp}
  81. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta182.lmp → fonts/defsmallfont/00D6.lmp}
  82. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta188.lmp → fonts/defsmallfont/00DC.lmp}
  83. BIN wadsrc_extra/static/filter/game-raven/{graphics/fonta191.lmp → fonts/defsmallfont/00DF.lmp}
@@ -1260,6 +1260,43 @@ FResourceLump *FWadCollection::GetLumpRecord(int lump) const
return LumpInfo[lump].lump;
}

//==========================================================================
//
// GetLumpsInFolder
//
// Gets all lumps within a single folder in the hierarchy.
//
//==========================================================================

static int folderentrycmp(const void *a, const void *b)
{
auto A = (FolderEntry*)a;
auto B = (FolderEntry*)b;
return strcmp(A->name, B->name);
}

unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray<FolderEntry> &result) const
{
FString path = inpath;
FixPathSeperator(path);
path.ToLower();
if (path[path.Len() - 1] != '/') path += '/';
result.Clear();
for (unsigned i = 0; i < LumpInfo.Size(); i++)
{
if (LumpInfo[i].lump->FullName.IndexOf(path) == 0)
{
// Only if it hasn't been replaced.
if (Wads.CheckNumForFullName(LumpInfo[i].lump->FullName) == i)
{
result.Push({ LumpInfo[i].lump->FullName.GetChars(), i });
}
}
}
qsort(result.Data(), result.Size(), sizeof(FolderEntry), folderentrycmp);
return result.Size();
}

//==========================================================================
//
// W_ReadLump
@@ -101,6 +101,12 @@ class FMemLump
friend class FWadCollection;
};

struct FolderEntry
{
const char *name;
unsigned lumpnum;
};

class FWadCollection
{
public:
@@ -173,6 +179,7 @@ class FWadCollection
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<FolderEntry> &result) const;

bool IsEncryptedFile(int lump) const;

@@ -987,10 +987,11 @@ FString FStringFormat(VM_ARGS, int offset)
ThrowAbortException(X_FORMAT_ERROR, "Cannot mix explicit and implicit arguments.");
FString argnumstr = fmt_current.Mid(1);
if (!argnumstr.IsInt()) ThrowAbortException(X_FORMAT_ERROR, "Expected a numeric value for argument number, got '%s'.", argnumstr.GetChars());
argnum = argnumstr.ToLong();
if (argnum < 1 || argnum >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format (tried to access argument %d, %d total).", argnum, numparam);
auto argnum64 = argnumstr.ToLong();
if (argnum64 < 1 || argnum64 >= numparam) ThrowAbortException(X_FORMAT_ERROR, "Not enough arguments for format (tried to access argument %d, %d total).", argnum64, numparam);
fmt_current = "%";
haveargnums = true;
argnum = int(argnum64);
}
else
{
@@ -44,7 +44,7 @@ static void CastF2S(FString *a, double b) { a->Format("%.5f", b); }
static void CastV22S(FString *a, double b, double b1) { a->Format("(%.5f, %.5f)", b, b1); }
static void CastV32S(FString *a, double b, double b1, double b2) { a->Format("(%.5f, %.5f, %.5f)", b, b1, b2); }
static void CastP2S(FString *a, void *b) { if (b == nullptr) *a = "null"; else a->Format("%p", b); }
static int CastS2I(FString *b) { return (VM_SWORD)b->ToLong(); }
static int CastS2I(FString *b) { return (int)b->ToLong(); }
static double CastS2F(FString *b) { return b->ToDouble(); }
static int CastS2N(FString *b) { return b->Len() == 0 ? FName(NAME_None) : FName(*b); }
static void CastN2S(FString *a, int b) { FName name = FName(ENamedName(b)); *a = name.IsValidName() ? name.GetChars() : ""; }
@@ -369,7 +369,7 @@ struct VMValue
}
if (Type == REGT_STRING)
{
return s().ToLong();
return (int)s().ToLong();
}
// FIXME
return 0;
@@ -257,7 +257,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ToInt, StringToInt)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
PARAM_INT(base);
ACTION_RETURN_INT(self->ToLong(base));
ACTION_RETURN_INT((int)self->ToLong(base));
}

static double StringToDbl(FString *self)
@@ -1130,14 +1130,14 @@ digits = [0-9];
return yych == '\0';
}

long FString::ToLong (int base) const
int64_t FString::ToLong (int base) const
{
return (long)strtoll (Chars, NULL, base);
return strtoll (Chars, NULL, base);
}

unsigned long FString::ToULong (int base) const
uint64_t FString::ToULong (int base) const
{
return (unsigned long)strtoull (Chars, NULL, base);
return strtoull (Chars, NULL, base);
}

double FString::ToDouble () const
@@ -299,8 +299,8 @@ class FString

bool IsInt () const;
bool IsFloat () const;
long ToLong (int base=0) const;
unsigned long ToULong (int base=0) const;
int64_t ToLong (int base=0) const;
uint64_t ToULong (int base=0) const;
double ToDouble () const;

size_t Len() const { return Data()->Len; }
@@ -305,21 +305,16 @@ FFont *V_GetFont(const char *name)
//
//==========================================================================

FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump, int spacewidth, bool notranslate)
FFont::FFont (const char *name, const char *nametemplate, const char *filetemplate, int lfirst, int lcount, int start, int fdlump, int spacewidth, bool notranslate)
{
int i;
FTextureID lump;
char buffer[12];
TArray<FTexture*> charLumps(count, true);
int maxyoffs;
bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false;
bool stcfn121 = false;

noTranslate = notranslate;
Lump = fdlump;
Chars.Resize(count);
FirstChar = first;
LastChar = first + count - 1;
FontHeight = 0;
GlobalKerning = false;
FontName = name;
@@ -333,10 +328,13 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,

maxyoffs = 0;

for (i = 0; i < count; i++)
TMap<int, FTexture*> charMap;
int minchar = INT_MAX;
int maxchar = INT_MIN;
for (i = 0; i < lcount; i++)
{
charLumps[i] = nullptr;
mysnprintf (buffer, countof(buffer), nametemplate, i + start);
int position = '!' + i;
mysnprintf(buffer, countof(buffer), nametemplate, i + start);

lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch);
if (doomtemplate && lump.isValid() && i + start == 121)
@@ -349,49 +347,82 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
!TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid())
{
// insert the incorrectly named '|' graphic in its correct position.
if (count > 124-start) charLumps[124-start] = TexMan.GetTexture(lump);
lump.SetInvalid();
stcfn121 = true;
position = 124;
}
}

if (lump.isValid())
{
FTexture *pic = TexMan.GetTexture(lump);
if (pic != nullptr)
if (position < minchar) minchar = position;
if (position > maxchar) maxchar = position;
charMap.Insert(position, TexMan.GetTexture(lump));
}
}
if (filetemplate != nullptr)
{
TArray<FolderEntry> folderdata;
FStringf path("fonts/%s/", filetemplate);
if (Wads.GetLumpsInFolder(path, folderdata))
{
// all valid lumps must be named with a hex number that represents its Unicode character index.
for (auto &entry : folderdata)
{
// set the lump here only if it represents a valid texture
if (i != 124-start || !stcfn121)
charLumps[i] = pic;
char *endp;
auto base = ExtractFileBase(entry.name);
auto position = strtoll(base.GetChars(), &endp, 16);
if ((*endp == 0 || *endp == '.' && position >= '!' && position < 0xffff))
{
auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch);
if (lump.isValid())
{
if ((int)position < minchar) minchar = (int)position;
if ((int)position > maxchar) maxchar = (int)position;
charMap.Insert((int)position, TexMan.GetTexture(lump));
}
}
}
}
}

FirstChar = minchar;
LastChar = maxchar;
auto count = maxchar - minchar + 1;
Chars.Resize(count);

for (i = 0; i < count; i++)
{
auto lump = charMap.CheckKey(FirstChar + i);
if (lump != nullptr)
{
FTexture *pic = *lump;
if (pic != nullptr)
{
int height = pic->GetDisplayHeight();
int yoffs = pic->GetDisplayTopOffset();

if (yoffs > maxyoffs)
{
maxyoffs = yoffs;
}
height += abs (yoffs);
height += abs(yoffs);
if (height > FontHeight)
{
FontHeight = height;
}
}
}

if (charLumps[i] != nullptr)
{
charLumps[i]->SetUseType(ETextureType::FontChar);

pic->SetUseType(ETextureType::FontChar);
if (!noTranslate)
{
Chars[i].OriginalPic = charLumps[i];
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), "");
Chars[i].TranslatedPic->Scale = charLumps[i]->Scale;
Chars[i].OriginalPic = pic;
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (pic->GetImage()), "");
Chars[i].TranslatedPic->Scale = pic->Scale;
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
TexMan.AddTexture(Chars[i].TranslatedPic);
}
else Chars[i].TranslatedPic = charLumps[i];
else
{
Chars[i].TranslatedPic = pic;
}

Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
}
@@ -406,9 +437,9 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
{
SpaceWidth = spacewidth;
}
else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr)
else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].TranslatedPic != nullptr)
{
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2;
}
else
{
@@ -1826,7 +1857,7 @@ void V_InitCustomFonts()
}
if (format == 1)
{
FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump, spacewidth, donttranslate);
FFont *fnt = new FFont (namebuffer, templatebuf, nullptr, first, count, start, llump, spacewidth, donttranslate);
fnt->SetCursor(cursor);
}
else if (format == 2)
@@ -2228,19 +2259,19 @@ void V_InitFonts()
}
else if (Wads.CheckNumForName ("FONTA_S") >= 0)
{
SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1);
SmallFont = new FFont ("SmallFont", "FONTA%02u", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, 1, -1);
SmallFont->SetCursor('[');
}
else
{
SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
SmallFont = new FFont ("SmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
}
}
if (!(SmallFont2 = FFont::FindFont("SmallFont2"))) // Only used by Strife
{
if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0)
{
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", "defsmallfont2", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
}
else
{
@@ -2271,7 +2302,7 @@ void V_InitFonts()
}
else
{
BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1);
BigFont = new FFont ("BigFont", "FONTB%02u", "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1);
}
}
}
@@ -79,7 +79,7 @@ extern int NumTextColors;
class FFont
{
public:
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false);
FFont (const char *fontname, const char *nametemplate, const char *filetemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false);
virtual ~FFont ();

virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 4d2bb11

Please sign in to comment.