mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-13 19:40:43 +00:00
- use GZDoom's font code to fix the crash issues and moved around some files in the PK3.
This pulls in a lot of Doom specific font setup, this can be sorted out later as it won't get into the way. # Conflicts: # source/CMakeLists.txt # Conflicts: # source/glbackend/hw_draw2d.cpp # Conflicts: # source/CMakeLists.txt # Conflicts: # source/glbackend/gl_texture.cpp # Conflicts: # source/CMakeLists.txt # Conflicts: # source/build/src/palette.cpp # source/core/gamecontrol.cpp
This commit is contained in:
parent
a70b7fa698
commit
531c68edfe
24 changed files with 1154 additions and 230 deletions
|
@ -605,7 +605,6 @@ file( GLOB HEADER_FILES
|
|||
libxmp-lite/src/*.h
|
||||
core/*.h
|
||||
core/2d/*.h
|
||||
core/fonts/*.h
|
||||
core/utility/*.h
|
||||
core/utility/rapidjson/*.h
|
||||
core/console/*.h
|
||||
|
@ -626,6 +625,7 @@ file( GLOB HEADER_FILES
|
|||
common/console/*.h
|
||||
common/utility/*.h
|
||||
common/engine/*.h
|
||||
common/fonts/*.h
|
||||
common/objects/*.h
|
||||
common/filesystem/*.h
|
||||
common/textures/*.h
|
||||
|
@ -756,11 +756,6 @@ set (PCH_SOURCES
|
|||
core/2d/v_drawtext.cpp
|
||||
core/2d/screentext.cpp
|
||||
|
||||
core/fonts/font.cpp
|
||||
core/fonts/hexfont.cpp
|
||||
core/fonts/singlelumpfont.cpp
|
||||
core/fonts/v_font.cpp
|
||||
|
||||
core/console/c_console.cpp
|
||||
core/console/d_event.cpp
|
||||
|
||||
|
@ -774,8 +769,12 @@ set (PCH_SOURCES
|
|||
common/audio/music/i_soundfont.cpp
|
||||
common/audio/music/music_config.cpp
|
||||
common/thirdparty/sfmt/SFMT.cpp
|
||||
common/textures/texture.cpp
|
||||
common/textures/animtexture.cpp
|
||||
common/fonts/singlelumpfont.cpp
|
||||
common/fonts/singlepicfont.cpp
|
||||
common/fonts/specialfont.cpp
|
||||
common/fonts/font.cpp
|
||||
common/fonts/hexfont.cpp
|
||||
common/fonts/v_font.cpp
|
||||
common/textures/hw_ihwtexture.cpp
|
||||
common/textures/hw_material.cpp
|
||||
common/fonts/v_text.cpp
|
||||
|
@ -787,6 +786,7 @@ set (PCH_SOURCES
|
|||
common/textures/texturemanager.cpp
|
||||
common/textures/multipatchtexturebuilder.cpp
|
||||
common/textures/skyboxtexture.cpp
|
||||
common/textures/animtexture.cpp
|
||||
common/textures/formats/automaptexture.cpp
|
||||
common/textures/formats/brightmaptexture.cpp
|
||||
common/textures/formats/buildtexture.cpp
|
||||
|
@ -1019,6 +1019,7 @@ include_directories(
|
|||
common/utility
|
||||
common/console
|
||||
common/engine
|
||||
common/fonts
|
||||
common/objects
|
||||
common/rendering
|
||||
common/rendering/gl_load
|
||||
|
@ -1123,7 +1124,6 @@ source_group("Core\\Textures\\Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOUR
|
|||
source_group("Core\\Utility" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/utility/.+")
|
||||
source_group("Core\\2D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/2d/.+")
|
||||
source_group("Core\\Console" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/console/.+")
|
||||
source_group("Core\\Fonts" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/fonts/.+")
|
||||
source_group("Core\\DObject" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/dobject/.+")
|
||||
source_group("Core\\Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/menu/.+")
|
||||
source_group("Core\\Rendering" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/core/rendering/.+")
|
||||
|
|
|
@ -49,7 +49,7 @@ inline void paletteClearLookupTable(int num)
|
|||
|
||||
enum
|
||||
{
|
||||
Translation_BasePalettes,
|
||||
Translation_BasePalettes = 1,
|
||||
Translation_Remap,
|
||||
};
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "colormatcher.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_colortables.h"
|
||||
#include "v_font.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
// FString is a nice and convenient way to have automatically managed shared storage.
|
||||
|
@ -40,6 +41,7 @@ palette_t palookupfog[MAXPALOOKUPS];
|
|||
// NOTE: g_noFloorPal[0] is irrelevant as it's never checked.
|
||||
int8_t g_noFloorPal[MAXPALOOKUPS];
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Adds a palette to the global list of base palettes
|
||||
|
@ -262,7 +264,7 @@ void palettePostLoadLookups(void)
|
|||
remap.Palette[j] = palette->Palette[remap.Remap[j]];
|
||||
}
|
||||
remap.NumEntries = 256;
|
||||
GPalette.UpdateTranslation(TRANSLATION(i + 1, l), &remap);
|
||||
GPalette.UpdateTranslation(TRANSLATION(i + Translation_Remap, l), &remap);
|
||||
}
|
||||
if (palette != basepalette) palette->Inactive = false; // clear the marker flag
|
||||
}
|
||||
|
@ -287,7 +289,7 @@ void palettePostLoadLookups(void)
|
|||
|
||||
for (auto remap : GPalette.uniqueRemaps)
|
||||
{
|
||||
colorswap(remap);
|
||||
if (!remap->ForFont) colorswap(remap);
|
||||
}
|
||||
colorswap(&GPalette.GlobalBrightmap);
|
||||
std::swap(GPalette.BaseColors[0], GPalette.BaseColors[255]);
|
||||
|
|
|
@ -53,14 +53,15 @@ extern uint8_t IcePalette[16][3];
|
|||
|
||||
void PaletteContainer::Init(int numslots) // This cannot be a constructor!!!
|
||||
{
|
||||
if (numslots < 1) numslots = 1;
|
||||
Clear();
|
||||
HasGlobalBrightmap = false;
|
||||
// Make sure that index 0 is always the identity translation.
|
||||
FRemapTable remap;
|
||||
remap.MakeIdentity();
|
||||
remap.Inactive = true;
|
||||
AddRemap(&remap);
|
||||
TranslationTables.Resize(numslots);
|
||||
StoreTranslation(0, &remap); // make sure that translation ID 0 is the identity.
|
||||
ColorMatcher.SetPalette(BaseColors);
|
||||
}
|
||||
|
||||
|
@ -263,7 +264,7 @@ FRemapTable *PaletteContainer::TranslationToTable(int translation)
|
|||
unsigned int type = GetTranslationType(translation);
|
||||
unsigned int index = GetTranslationIndex(translation);
|
||||
|
||||
if (type <= 0 || type >= TranslationTables.Size() || index >= NumTranslations(type))
|
||||
if (type < 0 || type >= TranslationTables.Size() || index >= NumTranslations(type))
|
||||
{
|
||||
return uniqueRemaps[0]; // this is the identity table.
|
||||
}
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
class FileReader;
|
||||
|
||||
enum
|
||||
{
|
||||
TRANSLATION_Internal = 0
|
||||
};
|
||||
|
||||
|
||||
struct FRemapTable
|
||||
{
|
||||
FRemapTable(int count = 256) { NumEntries = count; }
|
||||
|
@ -28,6 +34,7 @@ struct FRemapTable
|
|||
int Index;
|
||||
int NumEntries; // # of elements in this table (usually 256)
|
||||
bool Inactive = false; // This table is inactive and should be treated as if it was passed as NULL
|
||||
bool ForFont = false; // Mark font translations because they may require different handling than the ones for sprites-
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -38,28 +38,441 @@
|
|||
#include <cwctype>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "templates.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_font.h"
|
||||
#include "printf.h"
|
||||
#include "textures.h"
|
||||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
#include "sc_man.h"
|
||||
#include "v_text.h"
|
||||
#include "gstrings.h"
|
||||
#include "image.h"
|
||||
#include "utf8.h"
|
||||
#include "myiswalpha.h"
|
||||
#include "fontchars.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
#include "palettecontainer.h"
|
||||
#include "textures.h"
|
||||
#include "multipatchtexture.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: FFont
|
||||
//
|
||||
// Loads a multi-texture font.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont::FFont (const char *name, const char *nametemplate, const char *filetemplate, int lfirst, int lcount, int start, int fdlump, int spacewidth, bool notranslate, bool iwadonly, bool doomtemplate)
|
||||
{
|
||||
int i;
|
||||
FTextureID lump;
|
||||
char buffer[12];
|
||||
int maxyoffs;
|
||||
DVector2 Scale = { 1, 1 };
|
||||
|
||||
noTranslate = notranslate;
|
||||
Lump = fdlump;
|
||||
GlobalKerning = false;
|
||||
FontName = name;
|
||||
Next = FirstFont;
|
||||
FirstFont = this;
|
||||
Cursor = '_';
|
||||
ActiveColors = 0;
|
||||
SpaceWidth = 0;
|
||||
FontHeight = 0;
|
||||
uint8_t pp = 0;
|
||||
for (auto &p : PatchRemap) p = pp++;
|
||||
translateUntranslated = false;
|
||||
int FixedWidth = 0;
|
||||
|
||||
maxyoffs = 0;
|
||||
|
||||
TMap<int, FTexture*> charMap;
|
||||
int minchar = INT_MAX;
|
||||
int maxchar = INT_MIN;
|
||||
|
||||
// Read the font's configuration.
|
||||
// This will not be done for the default fonts, because they are not atomic and the default content does not need it.
|
||||
|
||||
TArray<FolderEntry> folderdata;
|
||||
if (filetemplate != nullptr)
|
||||
{
|
||||
FStringf path("fonts/%s/", filetemplate);
|
||||
// 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.
|
||||
fileSystem.GetFilesInFolder(path, folderdata, nametemplate == nullptr);
|
||||
|
||||
//if (nametemplate == nullptr)
|
||||
{
|
||||
FStringf infpath("fonts/%s/font.inf", filetemplate);
|
||||
|
||||
unsigned index = folderdata.FindEx([=](const FolderEntry &entry)
|
||||
{
|
||||
return infpath.CompareNoCase(entry.name) == 0;
|
||||
});
|
||||
|
||||
if (index < folderdata.Size())
|
||||
{
|
||||
FScanner sc;
|
||||
sc.OpenLumpNum(folderdata[index].lumpnum);
|
||||
while (sc.GetToken())
|
||||
{
|
||||
sc.TokenMustBe(TK_Identifier);
|
||||
if (sc.Compare("Kerning"))
|
||||
{
|
||||
sc.MustGetValue(false);
|
||||
GlobalKerning = sc.Number;
|
||||
}
|
||||
else if (sc.Compare("Scale"))
|
||||
{
|
||||
sc.MustGetValue(true);
|
||||
Scale.Y = Scale.X = sc.Float;
|
||||
if (sc.CheckToken(','))
|
||||
{
|
||||
sc.MustGetValue(true);
|
||||
Scale.Y = sc.Float;
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("SpaceWidth"))
|
||||
{
|
||||
sc.MustGetValue(false);
|
||||
SpaceWidth = sc.Number;
|
||||
}
|
||||
else if (sc.Compare("FontHeight"))
|
||||
{
|
||||
sc.MustGetValue(false);
|
||||
FontHeight = sc.Number;
|
||||
}
|
||||
else if (sc.Compare("CellSize"))
|
||||
{
|
||||
sc.MustGetValue(false);
|
||||
FixedWidth = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetValue(false);
|
||||
FontHeight = sc.Number;
|
||||
}
|
||||
else if (sc.Compare("Translationtype"))
|
||||
{
|
||||
sc.MustGetToken(TK_Identifier);
|
||||
if (sc.Compare("console"))
|
||||
{
|
||||
TranslationType = 1;
|
||||
}
|
||||
else if (sc.Compare("standard"))
|
||||
{
|
||||
TranslationType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptError("Unknown translation type %s", sc.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FixedWidth > 0)
|
||||
{
|
||||
ReadSheetFont(folderdata, FixedWidth, FontHeight, Scale);
|
||||
Type = Folder;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nametemplate != nullptr)
|
||||
{
|
||||
if (!iwadonly)
|
||||
{
|
||||
for (i = 0; i < lcount; i++)
|
||||
{
|
||||
int position = lfirst + i;
|
||||
mysnprintf(buffer, countof(buffer), nametemplate, i + start);
|
||||
|
||||
lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch);
|
||||
if (doomtemplate && lump.isValid() && i + start == 121)
|
||||
{ // HACKHACK: Don't load STCFN121 in doom(2), because
|
||||
// it's not really a lower-case 'y' but a '|'.
|
||||
// Because a lot of wads with their own font seem to foolishly
|
||||
// copy STCFN121 and make it a '|' themselves, wads must
|
||||
// provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load as a 'y'.
|
||||
FStringf c120("%s120", nametemplate);
|
||||
FStringf c122("%s122", nametemplate);
|
||||
if (!TexMan.CheckForTexture(c120, ETextureType::MiscPatch).isValid() ||
|
||||
!TexMan.CheckForTexture(c122, ETextureType::MiscPatch).isValid())
|
||||
{
|
||||
// insert the incorrectly named '|' graphic in its correct position.
|
||||
position = 124;
|
||||
}
|
||||
}
|
||||
if (lump.isValid())
|
||||
{
|
||||
Type = Multilump;
|
||||
if (position < minchar) minchar = position;
|
||||
if (position > maxchar) maxchar = position;
|
||||
charMap.Insert(position, TexMan.GetTexture(lump));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FTexture *texs[256] = {};
|
||||
if (lcount > 256 - start) lcount = 256 - start;
|
||||
for (i = 0; i < lcount; i++)
|
||||
{
|
||||
TArray<FTextureID> array;
|
||||
mysnprintf(buffer, countof(buffer), nametemplate, i + start);
|
||||
|
||||
TexMan.ListTextures(buffer, array, true);
|
||||
for (auto entry : array)
|
||||
{
|
||||
FTexture *tex = TexMan.GetTexture(entry, false);
|
||||
if (tex && tex->GetSourceLump() >= 0 && fileSystem.GetFileContainer(tex->GetSourceLump()) <= fileSystem.GetMaxIwadNum() && tex->GetUseType() == ETextureType::MiscPatch)
|
||||
{
|
||||
texs[i] = tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doomtemplate)
|
||||
{
|
||||
// Handle the misplaced '|'.
|
||||
if (texs[121 - '!'] && !texs[120 - '!'] && !texs[122 - '!'] && !texs[124 - '!'])
|
||||
{
|
||||
texs[124 - '!'] = texs[121 - '!'];
|
||||
texs[121 - '!'] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < lcount; i++)
|
||||
{
|
||||
if (texs[i])
|
||||
{
|
||||
int position = lfirst + i;
|
||||
Type = Multilump;
|
||||
if (position < minchar) minchar = position;
|
||||
if (position > maxchar) maxchar = position;
|
||||
charMap.Insert(position, texs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (folderdata.Size() > 0)
|
||||
{
|
||||
// all valid lumps must be named with a hex number that represents its Unicode character index.
|
||||
for (auto &entry : folderdata)
|
||||
{
|
||||
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;
|
||||
auto tex = TexMan.GetTexture(lump);
|
||||
tex->SetScale(Scale);
|
||||
charMap.Insert((int)position, tex);
|
||||
Type = Folder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FirstChar = minchar;
|
||||
LastChar = maxchar;
|
||||
auto count = maxchar - minchar + 1;
|
||||
Chars.Resize(count);
|
||||
int fontheight = 0;
|
||||
int asciiheight = 0;
|
||||
|
||||
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);
|
||||
if (height > fontheight)
|
||||
{
|
||||
fontheight = height;
|
||||
}
|
||||
if (height > asciiheight && FirstChar + 1 < 128)
|
||||
{
|
||||
asciiheight = height;
|
||||
}
|
||||
}
|
||||
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
|
||||
if (!noTranslate)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1(pic->GetImage()), "");
|
||||
Chars[i].TranslatedPic->CopySize(pic);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
||||
}
|
||||
|
||||
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = nullptr;
|
||||
Chars[i].XMove = INT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
if (SpaceWidth == 0) // An explicit override from the .inf file must always take precedence
|
||||
{
|
||||
if (spacewidth != -1)
|
||||
{
|
||||
SpaceWidth = spacewidth;
|
||||
}
|
||||
else if ('N' - FirstChar >= 0 && 'N' - FirstChar < count && Chars['N' - FirstChar].TranslatedPic != nullptr)
|
||||
{
|
||||
SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpaceWidth = 4;
|
||||
}
|
||||
}
|
||||
if (FontHeight == 0) FontHeight = fontheight;
|
||||
if (AsciiHeight == 0) AsciiHeight = asciiheight;
|
||||
|
||||
FixXMoves();
|
||||
}
|
||||
|
||||
if (!noTranslate) LoadTranslations();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale)
|
||||
{
|
||||
// all valid lumps must be named with a hex number that represents the Unicode character index for its first character,
|
||||
TArray<TexPart> part(1, true);
|
||||
TMap<int, FTexture*> charMap;
|
||||
int minchar = INT_MAX;
|
||||
int maxchar = INT_MIN;
|
||||
for (auto &entry : folderdata)
|
||||
{
|
||||
char *endp;
|
||||
auto base = ExtractFileBase(entry.name);
|
||||
auto position = strtoll(base.GetChars(), &endp, 16);
|
||||
if ((*endp == 0 || (*endp == '.' && position >= 0 && position < 0xffff))) // Sheet fonts may fill in the low control chars.
|
||||
{
|
||||
auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch);
|
||||
if (lump.isValid())
|
||||
{
|
||||
auto tex = TexMan.GetTexture(lump);
|
||||
int numtex_x = tex->GetTexelWidth() / width;
|
||||
int numtex_y = tex->GetTexelHeight() / height;
|
||||
int maxinsheet = int(position) + numtex_x * numtex_y - 1;
|
||||
if (minchar > position) minchar = int(position);
|
||||
if (maxchar < maxinsheet) maxchar = maxinsheet;
|
||||
|
||||
for (int y = 0; y < numtex_y; y++)
|
||||
{
|
||||
for (int x = 0; x < numtex_x; x++)
|
||||
{
|
||||
part[0].OriginX = -width * x;
|
||||
part[0].OriginY = -height * y;
|
||||
part[0].Image = tex->GetImage();
|
||||
FMultiPatchTexture *image = new FMultiPatchTexture(width, height, part, false, false);
|
||||
FImageTexture *tex = new FImageTexture(image, "");
|
||||
tex->SetUseType(ETextureType::FontChar);
|
||||
tex->bMultiPatch = true;
|
||||
tex->Width = width;
|
||||
tex->Height = height;
|
||||
tex->_LeftOffset[0] =
|
||||
tex->_LeftOffset[1] =
|
||||
tex->_TopOffset[0] =
|
||||
tex->_TopOffset[1] = 0;
|
||||
tex->Scale = Scale;
|
||||
tex->bMasked = true;
|
||||
tex->bTranslucent = -1;
|
||||
tex->bWorldPanning = true;
|
||||
tex->bNoDecals = false;
|
||||
tex->SourceLump = -1; // We do not really care.
|
||||
TexMan.AddTexture(tex);
|
||||
charMap.Insert(int(position) + x + y * numtex_x, tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FirstChar = minchar;
|
||||
bool map1252 = false;
|
||||
if (minchar < 0x80 && maxchar >= 0xa0) // should be a settable option, but that'd probably cause more problems than it'd solve.
|
||||
{
|
||||
if (maxchar < 0x2122) maxchar = 0x2122;
|
||||
map1252 = true;
|
||||
}
|
||||
LastChar = maxchar;
|
||||
auto count = maxchar - minchar + 1;
|
||||
Chars.Resize(count);
|
||||
int fontheight = 0;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
auto lump = charMap.CheckKey(FirstChar + i);
|
||||
if (lump != nullptr)
|
||||
{
|
||||
FTexture *pic = *lump;
|
||||
|
||||
auto b = pic->Get8BitPixels(false);
|
||||
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1(pic->GetImage()), "");
|
||||
Chars[i].TranslatedPic->CopySize(pic);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
Chars[i].XMove = width;
|
||||
}
|
||||
|
||||
if (map1252)
|
||||
{
|
||||
// Move the Windows-1252 characters to their proper place.
|
||||
for (int i = 0x80; i < 0xa0; i++)
|
||||
{
|
||||
if (win1252map[i - 0x80] != i && Chars[i - minchar].TranslatedPic != nullptr && Chars[win1252map[i - 0x80] - minchar].TranslatedPic == nullptr)
|
||||
{
|
||||
std::swap(Chars[i - minchar], Chars[win1252map[i - 0x80] - minchar]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpaceWidth = width;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: ~FFont
|
||||
|
@ -224,6 +637,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
|
|||
FRemapTable remap(ActiveColors);
|
||||
remap.Remap[0] = 0;
|
||||
remap.Palette[0] = 0;
|
||||
remap.ForFont = true;
|
||||
|
||||
for (unsigned l = 1; l < myluminosity.Size(); l++)
|
||||
{
|
||||
|
@ -251,7 +665,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
|
|||
}
|
||||
}
|
||||
}
|
||||
Ranges[CR_UNTRANSLATED] = GLInterface.GetPaletteIndex(remap.Palette);
|
||||
Translations[CR_UNTRANSLATED] = GPalette.StoreTranslation(TRANSLATION_Internal, &remap);
|
||||
forceremap = true;
|
||||
}
|
||||
|
||||
|
@ -354,44 +768,49 @@ int FFont::SimpleTranslation (uint32_t *colorsused, uint8_t *translation, uint8_
|
|||
//==========================================================================
|
||||
|
||||
void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity,
|
||||
const void *ranges, int total_colors, const PalEntry *palette)
|
||||
const void *ranges, int total_colors, const PalEntry *palette, std::function<void(FRemapTable*)> post)
|
||||
{
|
||||
int i, j;
|
||||
const TranslationParm *parmstart = (const TranslationParm *)ranges;
|
||||
|
||||
FRemapTable remap;
|
||||
FRemapTable remap(total_colors);
|
||||
remap.ForFont = true;
|
||||
|
||||
// Create different translations for different color ranges
|
||||
Ranges.Clear();
|
||||
Translations.Clear();
|
||||
for (i = 0; i < NumTextColors; i++)
|
||||
{
|
||||
if (i == CR_UNTRANSLATED)
|
||||
{
|
||||
if (identity != nullptr)
|
||||
{
|
||||
memcpy(remap.Remap, identity, ActiveColors);
|
||||
if (palette != nullptr)
|
||||
{
|
||||
memcpy (remap.Palette, palette, ActiveColors*sizeof(PalEntry));
|
||||
memcpy(remap.Palette, palette, ActiveColors * sizeof(PalEntry));
|
||||
}
|
||||
else
|
||||
{
|
||||
remap.Palette[0] = GPalette.BaseColors[identity[0]] & MAKEARGB(0,255,255,255);
|
||||
remap.Palette[0] = GPalette.BaseColors[identity[0]] & MAKEARGB(0, 255, 255, 255);
|
||||
for (j = 1; j < ActiveColors; ++j)
|
||||
{
|
||||
remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255,0,0,0);
|
||||
remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
Translations.Push(GPalette.StoreTranslation(TRANSLATION_Internal, &remap));
|
||||
}
|
||||
else
|
||||
{
|
||||
Translations.Push(Translations[0]);
|
||||
}
|
||||
Ranges.Push(GLInterface.GetPaletteIndex(remap.Palette));
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(parmstart->RangeStart >= 0);
|
||||
|
||||
remap.Remap[0] = 0;
|
||||
remap.Palette[0] = 0;
|
||||
remap.ForFont = true;
|
||||
|
||||
for (j = 1; j < ActiveColors; j++)
|
||||
{
|
||||
|
@ -415,10 +834,11 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
|||
r = clamp(r, 0, 255);
|
||||
g = clamp(g, 0, 255);
|
||||
b = clamp(b, 0, 255);
|
||||
remap.Remap[j] = ColorMatcher.Pick(r, g, b);
|
||||
remap.Palette[j] = PalEntry(255,r,g,b);
|
||||
}
|
||||
|
||||
Ranges.Push(GLInterface.GetPaletteIndex(remap.Palette));
|
||||
if (post) post(&remap);
|
||||
Translations.Push(GPalette.StoreTranslation(TRANSLATION_Internal, &remap));
|
||||
|
||||
// Advance to the next color range.
|
||||
while (parmstart[1].RangeStart > parmstart[0].RangeEnd)
|
||||
|
@ -452,7 +872,7 @@ int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
|
|||
else if (range >= NumTextColors)
|
||||
range = CR_UNTRANSLATED;
|
||||
//if (range == CR_UNTRANSLATED && !translateUntranslated) return nullptr;
|
||||
return Ranges[range];
|
||||
return Translations[range];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -581,11 +1001,11 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: CharWidth
|
||||
// FFont :: GetCharWidth
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FFont::CharWidth (int code) const
|
||||
int FFont::GetCharWidth (int code) const
|
||||
{
|
||||
code = GetCharCode(code, true);
|
||||
if (code >= 0) return Chars[code - FirstChar].XMove;
|
||||
|
@ -641,7 +1061,7 @@ bool FFont::CanPrint(const uint8_t *string) const
|
|||
else if (chr != '\n')
|
||||
{
|
||||
int cc = GetCharCode(chr, true);
|
||||
if (chr != cc && myiswalpha(chr))// && cc != getAlternative(chr))
|
||||
if (chr != cc && myiswalpha(chr) && cc != getAlternative(chr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -689,11 +1109,11 @@ int FFont::StringWidth(const uint8_t *string) const
|
|||
}
|
||||
else
|
||||
{
|
||||
w += CharWidth(chr) + GlobalKerning;
|
||||
w += GetCharWidth(chr) + GlobalKerning;
|
||||
}
|
||||
}
|
||||
|
||||
return std::max(maxw, w);
|
||||
return MAX(maxw, w);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -786,8 +1206,9 @@ void FFont::LoadTranslations()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont::FFont ()
|
||||
FFont::FFont (int lump)
|
||||
{
|
||||
Lump = lump;
|
||||
FontName = NAME_None;
|
||||
Cursor = '_';
|
||||
noTranslate = false;
|
||||
|
@ -807,6 +1228,19 @@ FFont::FFont ()
|
|||
|
||||
void FFont::FixXMoves()
|
||||
{
|
||||
if (FirstChar < 'a' && LastChar >= 'z')
|
||||
{
|
||||
MixedCase = true;
|
||||
// First check if this is a mixed case font.
|
||||
// For this the basic Latin small characters all need to be present.
|
||||
for (int i = 'a'; i <= 'z'; i++)
|
||||
if (Chars[i - FirstChar].OriginalPic == nullptr)
|
||||
{
|
||||
MixedCase = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i <= LastChar - FirstChar; ++i)
|
||||
{
|
||||
if (Chars[i].XMove == INT_MIN)
|
|
@ -34,13 +34,7 @@ struct TranslationMap
|
|||
extern TArray<TranslationParm> TranslationParms[2];
|
||||
extern TArray<TranslationMap> TranslationLookup;
|
||||
extern TArray<PalEntry> TranslationColors;
|
||||
extern uint16_t lowerforupper[65536];
|
||||
extern uint16_t upperforlower[65536];
|
||||
|
||||
class FImageSource;
|
||||
|
||||
void RecordTextureColors (FImageSource *pic, uint32_t *usedcolors);
|
||||
bool myislower(int code);
|
||||
bool myisupper(int code);
|
||||
int stripaccent(int code);
|
||||
int getAlternative(int code);
|
|
@ -32,15 +32,13 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include "engineerrors.h"
|
||||
#include "textures.h"
|
||||
#include "image.h"
|
||||
#include "v_font.h"
|
||||
#include "filesystem.h"
|
||||
#include "utf8.h"
|
||||
#include "sc_man.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "v_draw.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
#include "palettecontainer.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
@ -58,10 +56,11 @@ struct HexDataSource
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void ParseDefinition(const char *fname)
|
||||
void ParseDefinition(int lumpnum)
|
||||
{
|
||||
FScanner sc;
|
||||
sc.Open(fname);
|
||||
|
||||
sc.OpenLumpNum(lumpnum);
|
||||
sc.SetCMode(true);
|
||||
glyphdata.Push(0); // ensure that index 0 can be used as 'not present'.
|
||||
while (sc.GetString())
|
||||
|
@ -243,8 +242,11 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FHexFont (const char *fontname, const char *lump)
|
||||
FHexFont (const char *fontname, int lump)
|
||||
: FFont(lump)
|
||||
{
|
||||
assert(lump >= 0);
|
||||
|
||||
FontName = fontname;
|
||||
|
||||
FirstChar = hexdata.FirstChar;
|
||||
|
@ -313,9 +315,10 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FHexFont2(const char *fontname, const char *lump)
|
||||
FHexFont2(const char *fontname, int lump)
|
||||
: FFont(lump)
|
||||
{
|
||||
assert(lump != nullptr);
|
||||
assert(lump >= 0);
|
||||
|
||||
FontName = fontname;
|
||||
|
||||
|
@ -388,6 +391,7 @@ public:
|
|||
FRemapTable remap(ActiveColors);
|
||||
remap.Remap[0] = 0;
|
||||
remap.Palette[0] = 0;
|
||||
remap.ForFont = true;
|
||||
|
||||
for (unsigned l = 1; l < 18; l++)
|
||||
{
|
||||
|
@ -415,8 +419,8 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
Translations[CR_UNTRANSLATED] = GPalette.StoreTranslation(TRANSLATION_Internal, &remap);
|
||||
forceremap = true;
|
||||
Ranges[CR_UNTRANSLATED] = GLInterface.GetPaletteIndex(remap.Palette);
|
||||
|
||||
}
|
||||
|
||||
|
@ -429,7 +433,7 @@ public:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont *CreateHexLumpFont (const char *fontname, const char * lump)
|
||||
FFont *CreateHexLumpFont (const char *fontname, int lump)
|
||||
{
|
||||
if (hexdata.FirstChar == INT_MAX) hexdata.ParseDefinition(lump);
|
||||
return new FHexFont(fontname, lump);
|
||||
|
@ -441,7 +445,7 @@ FFont *CreateHexLumpFont (const char *fontname, const char * lump)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFont *CreateHexLumpFont2(const char *fontname, const char* lump)
|
||||
FFont *CreateHexLumpFont2(const char *fontname, int lump)
|
||||
{
|
||||
if (hexdata.FirstChar == INT_MAX) hexdata.ParseDefinition(lump);
|
||||
return new FHexFont2(fontname, lump);
|
|
@ -33,16 +33,14 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include "engineerrors.h"
|
||||
#include "textures.h"
|
||||
#include "image.h"
|
||||
#include "v_font.h"
|
||||
#include "filesystem.h"
|
||||
#include "utf8.h"
|
||||
#include "fontchars.h"
|
||||
#include "texturemanager.h"
|
||||
#include "printf.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "filesystem.h"
|
||||
#include "colormatcher.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
||||
|
@ -88,7 +86,7 @@ The FON2 header is followed by variable length data:
|
|||
class FSingleLumpFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSingleLumpFont (const char *fontname, const char * lump);
|
||||
FSingleLumpFont (const char *fontname, int lump);
|
||||
|
||||
protected:
|
||||
void CheckFON1Chars (double *luminosity);
|
||||
|
@ -96,9 +94,10 @@ protected:
|
|||
void FixupPalette (uint8_t *identity, double *luminosity, const uint8_t *palette,
|
||||
bool rescale, PalEntry *out_palette);
|
||||
void LoadTranslations ();
|
||||
void LoadFON1 (const char * lump, const uint8_t *data);
|
||||
void LoadFON2 (const char* lump, const uint8_t *data);
|
||||
void LoadBMF (const char* lump, const uint8_t *data);
|
||||
void LoadFON1 (int lump, const uint8_t *data);
|
||||
void LoadFON2 (int lump, const uint8_t *data);
|
||||
void LoadBMF (int lump, const uint8_t *data);
|
||||
void CreateFontFromPic (FTextureID picnum);
|
||||
|
||||
static int BMFCompare(const void *a, const void *b);
|
||||
|
||||
|
@ -121,18 +120,18 @@ protected:
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FSingleLumpFont::FSingleLumpFont (const char *name, const char * lump)
|
||||
FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
|
||||
{
|
||||
assert(lump != nullptr);
|
||||
assert(lump >= 0);
|
||||
|
||||
FontName = name;
|
||||
|
||||
rawData = fileSystem.LoadFile(lump, 0);
|
||||
auto& data = rawData;
|
||||
FileData data1 = fileSystem.ReadFile (lump);
|
||||
const uint8_t *data = (const uint8_t *)data1.GetMem();
|
||||
|
||||
if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A)
|
||||
{
|
||||
LoadBMF(name, data.Data());
|
||||
LoadBMF(lump, data);
|
||||
Type = BMF;
|
||||
}
|
||||
else if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
|
||||
|
@ -145,12 +144,12 @@ FSingleLumpFont::FSingleLumpFont (const char *name, const char * lump)
|
|||
switch (data[3])
|
||||
{
|
||||
case '1':
|
||||
LoadFON1 (name, data.Data());
|
||||
LoadFON1 (lump, data);
|
||||
Type = Fon1;
|
||||
break;
|
||||
|
||||
case '2':
|
||||
LoadFON2 (name, data.Data());
|
||||
LoadFON2 (lump, data);
|
||||
Type = Fon2;
|
||||
break;
|
||||
}
|
||||
|
@ -160,6 +159,28 @@ FSingleLumpFont::FSingleLumpFont (const char *name, const char * lump)
|
|||
FirstFont = this;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSingleLumpFont :: CreateFontFromPic
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
|
||||
{
|
||||
FTexture *pic = TexMan.GetTexture(picnum);
|
||||
|
||||
FontHeight = pic->GetDisplayHeight ();
|
||||
SpaceWidth = pic->GetDisplayWidth ();
|
||||
GlobalKerning = 0;
|
||||
|
||||
FirstChar = LastChar = 'A';
|
||||
Chars.Resize(1);
|
||||
Chars[0].TranslatedPic = pic;
|
||||
|
||||
// Only one color range. Don't bother with the others.
|
||||
ActiveColors = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSingleLumpFont :: LoadTranslations
|
||||
|
@ -215,7 +236,7 @@ void FSingleLumpFont::LoadTranslations()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::LoadFON1 (const char * lump, const uint8_t *data)
|
||||
void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
|
@ -256,7 +277,7 @@ void FSingleLumpFont::LoadFON1 (const char * lump, const uint8_t *data)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::LoadFON2 (const char * lump, const uint8_t *data)
|
||||
void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
|
||||
{
|
||||
int count, i, totalwidth;
|
||||
uint16_t *widths;
|
||||
|
@ -332,7 +353,7 @@ void FSingleLumpFont::LoadFON2 (const char * lump, const uint8_t *data)
|
|||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (fileSystem.FindFile(lump), int(data_p - data), widths2[i], FontHeight));
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
do
|
||||
|
@ -369,7 +390,7 @@ void FSingleLumpFont::LoadFON2 (const char * lump, const uint8_t *data)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSingleLumpFont::LoadBMF(const char *lump, const uint8_t *data)
|
||||
void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
||||
{
|
||||
const uint8_t *chardata;
|
||||
int numchars, count, totalwidth, nwidth;
|
||||
|
@ -462,7 +483,7 @@ void FSingleLumpFont::LoadBMF(const char *lump, const uint8_t *data)
|
|||
{ // Empty character: skip it.
|
||||
continue;
|
||||
}
|
||||
auto tex = new FImageTexture(new FFontChar2(fileSystem.FindFile(lump), int(chardata + chari + 6 - data),
|
||||
auto tex = new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data),
|
||||
chardata[chari+1], // width
|
||||
chardata[chari+2], // height
|
||||
-(int8_t)chardata[chari+3], // x offset
|
||||
|
@ -519,15 +540,15 @@ int FSingleLumpFont::BMFCompare(const void *a, const void *b)
|
|||
|
||||
void FSingleLumpFont::CheckFON1Chars (double *luminosity)
|
||||
{
|
||||
auto &data = rawData;
|
||||
if (data.Size() < 8) return;
|
||||
FileData memLump = fileSystem.ReadFile(Lump);
|
||||
const uint8_t* data = (const uint8_t*) memLump.GetMem();
|
||||
|
||||
uint8_t used[256], reverse[256];
|
||||
const uint8_t *data_p;
|
||||
int i, j;
|
||||
|
||||
memset (used, 0, 256);
|
||||
data_p = data.Data() + 8;
|
||||
data_p = data + 8;
|
||||
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
|
@ -535,7 +556,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
|
|||
|
||||
if(!Chars[i].TranslatedPic)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (0, int(data_p - data.Data()), SpaceWidth, FontHeight));
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].XMove = SpaceWidth;
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
|
@ -630,7 +651,7 @@ void FSingleLumpFont::FixupPalette (uint8_t *identity, double *luminosity, const
|
|||
}
|
||||
}
|
||||
|
||||
FFont *CreateSingleLumpFont (const char *fontname, const char * lump)
|
||||
FFont *CreateSingleLumpFont (const char *fontname, int lump)
|
||||
{
|
||||
return new FSingleLumpFont(fontname, lump);
|
||||
}
|
128
source/common/fonts/singlepicfont.cpp
Normal file
128
source/common/fonts/singlepicfont.cpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
** v_font.cpp
|
||||
** Font management
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2016 Randy Heit
|
||||
** Copyright 2005-2019 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "engineerrors.h"
|
||||
#include "textures.h"
|
||||
#include "v_font.h"
|
||||
#include "filesystem.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
class FSinglePicFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSinglePicFont(const char *picname);
|
||||
|
||||
// FFont interface
|
||||
FTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override;
|
||||
int GetCharWidth (int code) const;
|
||||
|
||||
protected:
|
||||
FTextureID PicNum;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSinglePicFont :: FSinglePicFont
|
||||
//
|
||||
// Creates a font to wrap a texture so that you can use hudmessage as if it
|
||||
// were a hudpic command. It does not support translation, but animation
|
||||
// is supported, unlike all the real fonts.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FSinglePicFont::FSinglePicFont(const char *picname) :
|
||||
FFont(-1) // Since lump is only needed for priority information we don't need to worry about this here.
|
||||
{
|
||||
FTextureID picnum = TexMan.CheckForTexture (picname, ETextureType::Any);
|
||||
|
||||
if (!picnum.isValid())
|
||||
{
|
||||
I_FatalError ("%s is not a font or texture", picname);
|
||||
}
|
||||
|
||||
FTexture *pic = TexMan.GetTexture(picnum);
|
||||
|
||||
FontName = picname;
|
||||
FontHeight = pic->GetDisplayHeight();
|
||||
SpaceWidth = pic->GetDisplayWidth();
|
||||
GlobalKerning = 0;
|
||||
FirstChar = LastChar = 'A';
|
||||
ActiveColors = 0;
|
||||
PicNum = picnum;
|
||||
|
||||
Next = FirstFont;
|
||||
FirstFont = this;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSinglePicFont :: GetChar
|
||||
//
|
||||
// Returns the texture if code is 'a' or 'A', otherwise nullptr.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const
|
||||
{
|
||||
*width = SpaceWidth;
|
||||
if (redirected) *redirected = false;
|
||||
if (code == 'a' || code == 'A')
|
||||
{
|
||||
return TexMan.GetPalettedTexture(PicNum, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSinglePicFont :: GetCharWidth
|
||||
//
|
||||
// Don't expect the text functions to work properly if I actually allowed
|
||||
// the character width to vary depending on the animation frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FSinglePicFont::GetCharWidth (int code) const
|
||||
{
|
||||
return SpaceWidth;
|
||||
}
|
||||
|
||||
FFont *CreateSinglePicFont(const char *picname)
|
||||
{
|
||||
return new FSinglePicFont(picname);
|
||||
}
|
223
source/common/fonts/specialfont.cpp
Normal file
223
source/common/fonts/specialfont.cpp
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
** v_font.cpp
|
||||
** Font management
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2016 Randy Heit
|
||||
** Copyright 2005-2019 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "v_font.h"
|
||||
#include "textures.h"
|
||||
#include "image.h"
|
||||
#include "fontchars.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
||||
// Essentially a normal multilump font but with an explicit list of character patches
|
||||
class FSpecialFont : public FFont
|
||||
{
|
||||
public:
|
||||
FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate);
|
||||
|
||||
void LoadTranslations();
|
||||
|
||||
protected:
|
||||
bool notranslate[256];
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSpecialFont :: FSpecialFont
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
: FFont(lump)
|
||||
{
|
||||
int i;
|
||||
TArray<FTexture *> charlumps(count, true);
|
||||
int maxyoffs;
|
||||
FTexture *pic;
|
||||
|
||||
memcpy(this->notranslate, notranslate, 256*sizeof(bool));
|
||||
|
||||
noTranslate = donttranslate;
|
||||
FontName = name;
|
||||
Chars.Resize(count);
|
||||
FirstChar = first;
|
||||
LastChar = first + count - 1;
|
||||
FontHeight = 0;
|
||||
GlobalKerning = false;
|
||||
Next = FirstFont;
|
||||
FirstFont = this;
|
||||
|
||||
maxyoffs = 0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
pic = charlumps[i] = lumplist[i];
|
||||
if (pic != nullptr)
|
||||
{
|
||||
int height = pic->GetDisplayHeight();
|
||||
int yoffs = pic->GetDisplayTopOffset();
|
||||
|
||||
if (yoffs > maxyoffs)
|
||||
{
|
||||
maxyoffs = yoffs;
|
||||
}
|
||||
height += abs (yoffs);
|
||||
if (height > FontHeight)
|
||||
{
|
||||
FontHeight = height;
|
||||
}
|
||||
}
|
||||
|
||||
if (charlumps[i] != nullptr)
|
||||
{
|
||||
auto pic = charlumps[i];
|
||||
Chars[i].OriginalPic = new FImageTexture(pic->GetImage(), "");
|
||||
Chars[i].OriginalPic->SetUseType(ETextureType::FontChar);
|
||||
Chars[i].OriginalPic->CopySize(pic);
|
||||
TexMan.AddTexture(Chars[i].OriginalPic);
|
||||
|
||||
if (!noTranslate)
|
||||
{
|
||||
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), "");
|
||||
Chars[i].TranslatedPic->CopySize(charlumps[i]);
|
||||
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
|
||||
TexMan.AddTexture(Chars[i].TranslatedPic);
|
||||
}
|
||||
else Chars[i].TranslatedPic = Chars[i].OriginalPic;
|
||||
Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
Chars[i].TranslatedPic = nullptr;
|
||||
Chars[i].XMove = INT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
// Special fonts normally don't have all characters so be careful here!
|
||||
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr)
|
||||
{
|
||||
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpaceWidth = 4;
|
||||
}
|
||||
|
||||
FixXMoves();
|
||||
|
||||
if (noTranslate)
|
||||
{
|
||||
ActiveColors = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadTranslations();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FSpecialFont :: LoadTranslations
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FSpecialFont::LoadTranslations()
|
||||
{
|
||||
int count = LastChar - FirstChar + 1;
|
||||
uint32_t usedcolors[256] = {};
|
||||
uint8_t identity[256];
|
||||
TArray<double> Luminosity;
|
||||
int TotalColors;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (Chars[i].TranslatedPic)
|
||||
{
|
||||
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
|
||||
if (pic)
|
||||
{
|
||||
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
|
||||
RecordTextureColors(pic, usedcolors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// exclude the non-translated colors from the translation calculation
|
||||
for (i = 0; i < 256; i++)
|
||||
if (notranslate[i])
|
||||
usedcolors[i] = false;
|
||||
|
||||
TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity);
|
||||
|
||||
// Map all untranslated colors into the table of used colors
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (notranslate[i])
|
||||
{
|
||||
PatchRemap[i] = TotalColors;
|
||||
identity[TotalColors] = i;
|
||||
TotalColors++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if(Chars[i].TranslatedPic)
|
||||
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
|
||||
}
|
||||
|
||||
BuildTranslations(Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr, [=](FRemapTable* remap)
|
||||
{
|
||||
// add the untranslated colors to the Ranges tables
|
||||
if (ActiveColors < TotalColors)
|
||||
{
|
||||
for (int j = ActiveColors; j < TotalColors; ++j)
|
||||
{
|
||||
remap->Remap[j] = identity[j];
|
||||
remap->Palette[j] = GPalette.BaseColors[identity[j]];
|
||||
remap->Palette[j].a = 0xff;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ActiveColors = TotalColors;
|
||||
}
|
||||
|
||||
FFont *CreateSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate)
|
||||
{
|
||||
return new FSpecialFont(name, first, count, lumplist, notranslate, lump, donttranslate);
|
||||
}
|
|
@ -42,15 +42,17 @@
|
|||
#include "templates.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_font.h"
|
||||
#include "filesystem.h"
|
||||
#include "cmdlib.h"
|
||||
#include "sc_man.h"
|
||||
#include "v_text.h"
|
||||
#include "gstrings.h"
|
||||
#include "image.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#include "m_png.h"
|
||||
#include "fontchars.h"
|
||||
#include "textures.h"
|
||||
#include "texturemanager.h"
|
||||
#include "printf.h"
|
||||
#include "filesystem.h"
|
||||
#include "palentry.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
||||
|
@ -58,24 +60,32 @@
|
|||
|
||||
#define DEFAULT_LOG_COLOR PalEntry(223,223,223)
|
||||
|
||||
//
|
||||
// Globally visible constants.
|
||||
//
|
||||
#define HU_FONTSTART uint8_t('!') // the first font characters
|
||||
#define HU_FONTEND uint8_t('\377') // the last font characters
|
||||
|
||||
// Calculate # of glyphs in font.
|
||||
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
|
||||
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
int V_GetColor(const char* cstr);
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont, * CurrentConsoleFont, * OriginalSmallFont, * AlternativeSmallFont, * OriginalBigFont;
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static int TranslationMapCompare (const void *a, const void *b);
|
||||
//void UpdateGenericUI(bool cvar);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern int PrintColors[];
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
FFont* SmallFont, * SmallFont2, * BigFont, * BigUpper, * ConFont, * IntermissionFont, * NewConsoleFont, * NewSmallFont, * CurrentConsoleFont, * OriginalSmallFont, * AlternativeSmallFont, * OriginalBigFont;
|
||||
|
||||
FFont *FFont::FirstFont = nullptr;
|
||||
int NumTextColors;
|
||||
|
@ -90,19 +100,60 @@ TArray<PalEntry> TranslationColors;
|
|||
|
||||
FFont *V_GetFont(const char *name, const char *fontlumpname)
|
||||
{
|
||||
if (!stricmp(name, "DBIGFONT")) name = "BigFont";
|
||||
else if (!stricmp(name, "CONFONT")) name = "ConsoleFont"; // several mods have used the name CONFONT directly and effectively duplicated the font.
|
||||
FFont *font = FFont::FindFont (name);
|
||||
if (font == nullptr)
|
||||
{
|
||||
auto lumpy = fileSystem.OpenFileReader(fontlumpname);
|
||||
if (!lumpy.isOpen()) return nullptr;
|
||||
uint32_t head;
|
||||
lumpy.Read (&head, 4);
|
||||
if ((head & MAKE_ID(255,255,255,0)) == MAKE_ID('F','O','N',0) ||
|
||||
head == MAKE_ID(0xE1,0xE6,0xD5,0x1A))
|
||||
if (!stricmp(name, "BIGUPPER"))
|
||||
{
|
||||
FFont *CreateSingleLumpFont (const char *fontname, const char *lump);
|
||||
lumpy.Close();
|
||||
return CreateSingleLumpFont (name, fontlumpname);
|
||||
font = FFont::FindFont("BIGFONT");
|
||||
if (font) return font;
|
||||
}
|
||||
|
||||
int lump = -1;
|
||||
int folderfile = -1;
|
||||
|
||||
TArray<FolderEntry> folderdata;
|
||||
FStringf path("fonts/%s/", name);
|
||||
|
||||
// Use a folder-based font only if it comes from a later file than the single lump version.
|
||||
if (fileSystem.GetFilesInFolder(path, folderdata, true))
|
||||
{
|
||||
// This assumes that any custom font comes in one piece and not distributed across multiple resource files.
|
||||
folderfile = fileSystem.GetFileContainer(folderdata[0].lumpnum);
|
||||
}
|
||||
|
||||
|
||||
lump = fileSystem.CheckNumForFullName(fontlumpname? fontlumpname : name, true);
|
||||
|
||||
if (lump != -1 && fileSystem.GetFileContainer(lump) >= folderfile)
|
||||
{
|
||||
uint32_t head;
|
||||
{
|
||||
auto lumpy = fileSystem.OpenFileReader (lump);
|
||||
lumpy.Read (&head, 4);
|
||||
}
|
||||
if ((head & MAKE_ID(255,255,255,0)) == MAKE_ID('F','O','N',0) ||
|
||||
head == MAKE_ID(0xE1,0xE6,0xD5,0x1A))
|
||||
{
|
||||
FFont *CreateSingleLumpFont (const char *fontname, int lump);
|
||||
return CreateSingleLumpFont (name, lump);
|
||||
}
|
||||
}
|
||||
FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any);
|
||||
if (picnum.isValid())
|
||||
{
|
||||
FTexture *tex = TexMan.GetTexture(picnum);
|
||||
if (tex && tex->GetSourceLump() >= folderfile)
|
||||
{
|
||||
FFont *CreateSinglePicFont(const char *name);
|
||||
return CreateSinglePicFont (name);
|
||||
}
|
||||
}
|
||||
if (folderdata.Size() > 0)
|
||||
{
|
||||
return new FFont(name, nullptr, name, HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
}
|
||||
}
|
||||
return font;
|
||||
|
@ -118,7 +169,6 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
|||
|
||||
void V_InitCustomFonts()
|
||||
{
|
||||
#if 0
|
||||
FScanner sc;
|
||||
FTexture *lumplist[256];
|
||||
bool notranslate[256];
|
||||
|
@ -134,7 +184,7 @@ void V_InitCustomFonts()
|
|||
int kerning;
|
||||
char cursor = '_';
|
||||
|
||||
while ((llump = Wads.FindLump ("FONTDEFS", &lastlump)) != -1)
|
||||
while ((llump = fileSystem.FindLump ("FONTDEFS", &lastlump)) != -1)
|
||||
{
|
||||
sc.OpenLumpNum(llump);
|
||||
while (sc.GetString())
|
||||
|
@ -223,7 +273,7 @@ void V_InitCustomFonts()
|
|||
{
|
||||
*p = TexMan.GetTexture(texid);
|
||||
}
|
||||
else if (Wads.GetLumpFile(sc.LumpNum) >= Wads.GetIwadNum())
|
||||
else if (fileSystem.GetFileContainer(sc.LumpNum) >= fileSystem.GetIwadNum())
|
||||
{
|
||||
// Print a message only if this isn't in zdoom.pk3
|
||||
sc.ScriptMessage("%s: Unable to find texture in font definition for %s", sc.String, namebuffer.GetChars());
|
||||
|
@ -271,107 +321,6 @@ void V_InitCustomFonts()
|
|||
|
||||
wrong:
|
||||
sc.ScriptError ("Invalid combination of properties in font '%s'", namebuffer.GetChars());
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// V_GetColorFromString
|
||||
//
|
||||
// Passed a string of the form "#RGB", "#RRGGBB", "R G B", or "RR GG BB",
|
||||
// returns a number representing that color. If palette is non-NULL, the
|
||||
// index of the best match in the palette is returned, otherwise the
|
||||
// RRGGBB value is returned directly.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int V_GetColor(const char* cstr)
|
||||
{
|
||||
int c[3], i, p;
|
||||
char val[3];
|
||||
|
||||
val[2] = '\0';
|
||||
|
||||
// Check for HTML-style #RRGGBB or #RGB color string
|
||||
if (cstr[0] == '#')
|
||||
{
|
||||
size_t len = strlen(cstr);
|
||||
|
||||
if (len == 7)
|
||||
{
|
||||
// Extract each eight-bit component into c[].
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[0] = cstr[1 + i * 2];
|
||||
val[1] = cstr[2 + i * 2];
|
||||
c[i] = ParseHex(val, nullptr);
|
||||
}
|
||||
}
|
||||
else if (len == 4)
|
||||
{
|
||||
// Extract each four-bit component into c[], expanding to eight bits.
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
val[1] = val[0] = cstr[1 + i];
|
||||
c[i] = ParseHex(val, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bad HTML-style; pretend it's black.
|
||||
c[2] = c[1] = c[0] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strlen(cstr) == 6)
|
||||
{
|
||||
char* p;
|
||||
int color = strtol(cstr, &p, 16);
|
||||
if (*p == 0)
|
||||
{
|
||||
// RRGGBB string
|
||||
c[0] = (color & 0xff0000) >> 16;
|
||||
c[1] = (color & 0xff00) >> 8;
|
||||
c[2] = (color & 0xff);
|
||||
}
|
||||
else goto normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal:
|
||||
// Treat it as a space-delimited hexadecimal string
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
// Skip leading whitespace
|
||||
while (*cstr <= ' ' && *cstr != '\0')
|
||||
{
|
||||
cstr++;
|
||||
}
|
||||
// Extract a component and convert it to eight-bit
|
||||
for (p = 0; *cstr > ' '; ++p, ++cstr)
|
||||
{
|
||||
if (p < 2)
|
||||
{
|
||||
val[p] = *cstr;
|
||||
}
|
||||
}
|
||||
if (p == 0)
|
||||
{
|
||||
c[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p == 1)
|
||||
{
|
||||
val[1] = val[0];
|
||||
}
|
||||
c[i] = ParseHex(val, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return MAKERGB(c[0], c[1], c[2]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -404,7 +353,7 @@ void V_InitFontColors ()
|
|||
TranslationLookup.Clear();
|
||||
TranslationColors.Clear();
|
||||
|
||||
while ((lump = fileSystem.FindLumpFullName("engine/textcolors.txt", &lastlump)) != -1)
|
||||
while ((lump = fileSystem.FindLump ("TEXTCOLO", &lastlump)) != -1)
|
||||
{
|
||||
FScanner sc(lump);
|
||||
while (sc.GetString())
|
||||
|
@ -447,19 +396,19 @@ void V_InitFontColors ()
|
|||
else if (sc.Compare ("Flat:"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
logcolor = V_GetColor (sc.String);
|
||||
logcolor = V_GetColor (nullptr, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get first color
|
||||
c = V_GetColor (sc.String);
|
||||
c = V_GetColor (nullptr, sc);
|
||||
tparm.Start[0] = RPART(c);
|
||||
tparm.Start[1] = GPART(c);
|
||||
tparm.Start[2] = BPART(c);
|
||||
|
||||
// Get second color
|
||||
sc.MustGetString();
|
||||
c = V_GetColor (sc.String);
|
||||
c = V_GetColor (nullptr, sc);
|
||||
tparm.End[0] = RPART(c);
|
||||
tparm.End[1] = GPART(c);
|
||||
tparm.End[2] = BPART(c);
|
||||
|
@ -670,6 +619,14 @@ EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int
|
|||
{
|
||||
newcolor = boldcolor;
|
||||
}
|
||||
else if (newcolor == '!') // Team chat
|
||||
{
|
||||
newcolor = PrintColors[PRINT_TEAMCHAT];
|
||||
}
|
||||
else if (newcolor == '*') // Chat
|
||||
{
|
||||
newcolor = PrintColors[PRINT_CHAT];
|
||||
}
|
||||
else if (newcolor == '[') // Named
|
||||
{
|
||||
const uint8_t *namestart = ch;
|
||||
|
@ -705,23 +662,170 @@ EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int
|
|||
//
|
||||
// V_InitFonts
|
||||
//
|
||||
// Fixme: This really needs to be a bit more flexible
|
||||
// and less rigidly tied to the original game data.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void V_InitFonts()
|
||||
{
|
||||
V_InitCustomFonts();
|
||||
|
||||
FFont *CreateHexLumpFont(const char *fontname, const char* lump);
|
||||
FFont *CreateHexLumpFont2(const char *fontname, const char * lump);
|
||||
FFont *CreateHexLumpFont(const char *fontname, int lump);
|
||||
FFont *CreateHexLumpFont2(const char *fontname, int lump);
|
||||
|
||||
if (fileSystem.FindFile("engine/newconsolefont.hex") < 0)
|
||||
I_Error("newconsolefont.hex not found"); // This font is needed - do not start up without it.
|
||||
NewConsoleFont = CreateHexLumpFont("NewConsoleFont", "engine/newconsolefont.hex");
|
||||
NewSmallFont = CreateHexLumpFont2("NewSmallFont", "engine/newconsolefont.hex");
|
||||
auto lump = fileSystem.CheckNumForFullName("newconsolefont.hex", 0); // This is always loaded from gzdoom.pk3 to prevent overriding it with incomplete replacements.
|
||||
if (lump == -1) I_FatalError("newconsolefont.hex not found"); // This font is needed - do not start up without it.
|
||||
NewConsoleFont = CreateHexLumpFont("NewConsoleFont", lump);
|
||||
NewSmallFont = CreateHexLumpFont2("NewSmallFont", lump);
|
||||
CurrentConsoleFont = NewConsoleFont;
|
||||
|
||||
ConFont = V_GetFont("ConsoleFont", "engine/confont.lmp"); // The con font is needed for the slider graphics
|
||||
SmallFont = ConFont; // This is so that it doesn't crash and that it immediately gets seen as a proble. The SmallFont should later be mapped to the small game font.
|
||||
// load the heads-up font
|
||||
if (!(SmallFont = V_GetFont("SmallFont", "SMALLFNT")))
|
||||
{
|
||||
if (fileSystem.CheckNumForName("FONTA_S") >= 0)
|
||||
{
|
||||
int wadfile = -1;
|
||||
auto a = fileSystem.CheckNumForName("FONTA33", ns_graphics);
|
||||
if (a != -1) wadfile = fileSystem.GetFileContainer(a);
|
||||
if (wadfile > fileSystem.GetIwadNum())
|
||||
{
|
||||
// The font has been replaced, so we need to create a copy of the original as well.
|
||||
SmallFont = new FFont("SmallFont", "FONTA%02u", nullptr, HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
SmallFont->SetCursor('[');
|
||||
}
|
||||
else
|
||||
{
|
||||
SmallFont = new FFont("SmallFont", "FONTA%02u", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
SmallFont->SetCursor('[');
|
||||
}
|
||||
}
|
||||
else if (fileSystem.CheckNumForName("STCFN033", ns_graphics) >= 0)
|
||||
{
|
||||
int wadfile = -1;
|
||||
auto a = fileSystem.CheckNumForName("STCFN065", ns_graphics);
|
||||
if (a != -1) wadfile = fileSystem.GetFileContainer(a);
|
||||
if (wadfile > fileSystem.GetIwadNum())
|
||||
{
|
||||
// The font has been replaced, so we need to create a copy of the original as well.
|
||||
SmallFont = new FFont("SmallFont", "STCFN%.3d", nullptr, HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SmallFont = new FFont("SmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the original small font as a fallback for incomplete definitions.
|
||||
if (fileSystem.CheckNumForName("FONTA_S") >= 0)
|
||||
{
|
||||
OriginalSmallFont = new FFont("OriginalSmallFont", "FONTA%02u", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true);
|
||||
OriginalSmallFont->SetCursor('[');
|
||||
}
|
||||
else if (fileSystem.CheckNumForName("STCFN033", ns_graphics) >= 0)
|
||||
{
|
||||
OriginalSmallFont = new FFont("OriginalSmallFont", "STCFN%.3d", "defsmallfont", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1, -1, false, true);
|
||||
}
|
||||
|
||||
if (SmallFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
SmallFont->RecordAllTextureColors(colors);
|
||||
if (OriginalSmallFont != nullptr) OriginalSmallFont->SetDefaultTranslation(colors);
|
||||
NewSmallFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
|
||||
if (!(SmallFont2 = V_GetFont("SmallFont2"))) // Only used by Strife
|
||||
{
|
||||
if (fileSystem.CheckNumForName("STBFN033", ns_graphics) >= 0)
|
||||
{
|
||||
SmallFont2 = new FFont("SmallFont2", "STBFN%.3d", "defsmallfont2", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1);
|
||||
}
|
||||
}
|
||||
|
||||
//This must be read before BigFont so that it can be properly substituted.
|
||||
BigUpper = V_GetFont("BigUpper");
|
||||
|
||||
if (!(BigFont = V_GetFont("BigFont")))
|
||||
{
|
||||
if (fileSystem.CheckNumForName("FONTB_S") >= 0)
|
||||
{
|
||||
BigFont = new FFont("BigFont", "FONTB%02u", "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!BigFont)
|
||||
{
|
||||
// Load the generic fallback if no BigFont is found.
|
||||
BigFont = V_GetFont("BigFont", "ZBIGFONT");
|
||||
}
|
||||
|
||||
if (fileSystem.CheckNumForName("FONTB_S") >= 0)
|
||||
{
|
||||
OriginalBigFont = new FFont("OriginalBigFont", "FONTB%02u", "defbigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
OriginalBigFont = new FFont("OriginalBigFont", nullptr, "bigfont", HU_FONTSTART, HU_FONTSIZE, 1, -1, -1, false, true);
|
||||
}
|
||||
|
||||
if (BigFont)
|
||||
{
|
||||
uint32_t colors[256] = {};
|
||||
BigFont->RecordAllTextureColors(colors);
|
||||
if (OriginalBigFont != nullptr) OriginalBigFont->SetDefaultTranslation(colors);
|
||||
}
|
||||
|
||||
// let PWAD BIGFONTs override the stock BIGUPPER font. (This check needs to be made smarter.)
|
||||
if (BigUpper && BigFont->Type != FFont::Folder && BigUpper->Type == FFont::Folder)
|
||||
{
|
||||
delete BigUpper;
|
||||
BigUpper = BigFont;
|
||||
}
|
||||
|
||||
if (BigUpper == nullptr)
|
||||
{
|
||||
BigUpper = BigFont;
|
||||
}
|
||||
if (!(ConFont = V_GetFont("ConsoleFont", "CONFONT")))
|
||||
{
|
||||
ConFont = SmallFont;
|
||||
}
|
||||
if (!(IntermissionFont = FFont::FindFont("IntermissionFont")))
|
||||
{
|
||||
if (fileSystem.CheckNumForName("WINUM0") >= 0)
|
||||
{
|
||||
IntermissionFont = FFont::FindFont("IntermissionFont_Doom");
|
||||
}
|
||||
if (IntermissionFont == nullptr)
|
||||
{
|
||||
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 (OriginalSmallFont == nullptr)
|
||||
{
|
||||
OriginalSmallFont = ConFont;
|
||||
}
|
||||
if (SmallFont == nullptr)
|
||||
{
|
||||
SmallFont = OriginalSmallFont;
|
||||
}
|
||||
if (SmallFont2 == nullptr)
|
||||
{
|
||||
SmallFont2 = SmallFont;
|
||||
}
|
||||
if (BigFont == nullptr)
|
||||
{
|
||||
BigFont = OriginalBigFont;
|
||||
}
|
||||
AlternativeSmallFont = OriginalSmallFont;
|
||||
}
|
||||
|
||||
void V_ClearFonts()
|
|
@ -34,15 +34,14 @@
|
|||
#ifndef __V_FONT_H__
|
||||
#define __V_FONT_H__
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "vectors.h"
|
||||
#include "name.h"
|
||||
#include "palentry.h"
|
||||
#include "tarray.h"
|
||||
#include "zstring.h"
|
||||
#include "name.h"
|
||||
|
||||
class DCanvas;
|
||||
struct FRemapTable;
|
||||
class FTexture;
|
||||
struct FRemapTable;
|
||||
|
||||
enum EColorRange : int
|
||||
{
|
||||
|
@ -95,11 +94,13 @@ public:
|
|||
Custom
|
||||
};
|
||||
|
||||
FFont (const char *fontname, const char *nametemplate, const char *filetemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false, bool iwadonly = false, bool doomtemplate = false);
|
||||
virtual ~FFont ();
|
||||
|
||||
virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
|
||||
virtual int CharWidth (int code) const;
|
||||
virtual int GetCharWidth (int code) const;
|
||||
int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
||||
int GetLump() const { return Lump; }
|
||||
int GetSpaceWidth () const { return SpaceWidth; }
|
||||
int GetHeight () const { return FontHeight; }
|
||||
int GetDefaultKerning () const { return GlobalKerning; }
|
||||
|
@ -134,15 +135,17 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
FFont ();
|
||||
FFont (int lump);
|
||||
|
||||
void BuildTranslations (const double *luminosity, const uint8_t *identity,
|
||||
const void *ranges, int total_colors, const PalEntry *palette);
|
||||
const void *ranges, int total_colors, const PalEntry *palette, std::function<void(FRemapTable*)> post = nullptr);
|
||||
void FixXMoves();
|
||||
|
||||
static int SimpleTranslation (uint32_t *colorsused, uint8_t *translation,
|
||||
uint8_t *identity, TArray<double> &Luminosity);
|
||||
|
||||
void ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height, const DVector2 &Scale);
|
||||
|
||||
EFontType Type = EFontType::Unknown;
|
||||
int FirstChar, LastChar;
|
||||
int SpaceWidth;
|
||||
|
@ -164,11 +167,11 @@ protected:
|
|||
};
|
||||
TArray<CharData> Chars;
|
||||
int ActiveColors;
|
||||
TArray<int> Ranges;
|
||||
TArray<int> Translations;
|
||||
uint8_t PatchRemap[256];
|
||||
|
||||
int Lump;
|
||||
FName FontName = NAME_None;
|
||||
TArray<uint8_t> rawData;
|
||||
FFont *Next;
|
||||
|
||||
static FFont *FirstFont;
|
||||
|
@ -190,4 +193,5 @@ FFont *V_GetFont(const char *fontname, const char *fontlumpname = nullptr);
|
|||
void V_InitFontColors();
|
||||
char* CleanseString(char* str);
|
||||
|
||||
|
||||
#endif //__V_FONT_H__
|
|
@ -119,7 +119,7 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
|||
lastWasSpace = false;
|
||||
}
|
||||
|
||||
nw = font->CharWidth (c);
|
||||
nw = font->GetCharWidth (c);
|
||||
|
||||
if ((w > 0 && w + nw > maxwidth) || c == '\n')
|
||||
{ // Time to break the line
|
||||
|
|
|
@ -432,7 +432,7 @@ protected:
|
|||
uint16_t Width, Height;
|
||||
int16_t _LeftOffset[2], _TopOffset[2];
|
||||
|
||||
FTexture(const char *name = NULL, int lumpnum = -1);
|
||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
||||
|
||||
public:
|
||||
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||
|
|
|
@ -202,13 +202,13 @@ public:
|
|||
if (scale == 1)
|
||||
{
|
||||
DrawChar(twod, CurrentConsoleFont, CR_ORANGE, x, y, '\x1c', TAG_DONE);
|
||||
DrawText(twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->CharWidth(0x1c), y,
|
||||
DrawText(twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y,
|
||||
&Text[StartPos], TAG_DONE);
|
||||
|
||||
if (cursor)
|
||||
{
|
||||
DrawChar(twod, CurrentConsoleFont, CR_YELLOW,
|
||||
x + CurrentConsoleFont->CharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->CharWidth(0xb),
|
||||
x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb),
|
||||
y, '\xb', TAG_DONE);
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ public:
|
|||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||
DTA_KeepRatio, true, TAG_DONE);
|
||||
|
||||
DrawText(twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->CharWidth(0x1c), y,
|
||||
DrawText(twod, CurrentConsoleFont, CR_ORANGE, x + CurrentConsoleFont->GetCharWidth(0x1c), y,
|
||||
&Text[StartPos],
|
||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||
|
@ -228,7 +228,7 @@ public:
|
|||
if (cursor)
|
||||
{
|
||||
DrawChar(twod, CurrentConsoleFont, CR_YELLOW,
|
||||
x + CurrentConsoleFont->CharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->CharWidth(0xb),
|
||||
x + CurrentConsoleFont->GetCharWidth(0x1c) + (CursorPosCells - StartPosCells) * CurrentConsoleFont->GetCharWidth(0xb),
|
||||
y, '\xb',
|
||||
DTA_VirtualWidth, screen->GetWidth() / scale,
|
||||
DTA_VirtualHeight, screen->GetHeight() / scale,
|
||||
|
@ -612,7 +612,7 @@ void C_InitConsole (int width, int height, bool ingame)
|
|||
vidactive = ingame;
|
||||
if (CurrentConsoleFont != NULL)
|
||||
{
|
||||
cwidth = CurrentConsoleFont->CharWidth ('M');
|
||||
cwidth = CurrentConsoleFont->GetCharWidth ('M');
|
||||
cheight = CurrentConsoleFont->GetHeight();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -712,6 +712,7 @@ int RunGame()
|
|||
{
|
||||
playername = userConfig.CommandName;
|
||||
}
|
||||
GPalette.Init(MAXPALOOKUPS + 2); // one slot for each translation, plus a separate one for the base palettes and the internal one
|
||||
TexMan.Init([]() {}, [](BuildInfo &) {});
|
||||
V_InitFonts();
|
||||
TileFiles.Init();
|
||||
|
|
|
@ -255,7 +255,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
applytint = true;
|
||||
if (!(h.f & HICTINT_APPLYOVERPALSWAP)) usepalswap = 0;
|
||||
}
|
||||
lookuppal = palmanager.LookupPalette(usepalette, usepalswap, false, 0);
|
||||
lookuppal = TRANSLATION(usepalette + Translation_Remap, usepalswap);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -177,7 +177,8 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
|
|||
auto saved = curbasepal; // screw Build's dependencies on global state variables. We only need to change this for the following SetTexture call.
|
||||
curbasepal = (cmd.mRemapIndex >> 8) & 0xff;
|
||||
auto savedf = globalflags;
|
||||
if (curbasepal > 0) globalflags |= GLOBAL_NO_GL_FULLBRIGHT; // temp. hack to disable brightmaps.
|
||||
if (curbasepal > 0)
|
||||
globalflags |= GLOBAL_NO_GL_FULLBRIGHT; // temp. hack to disable brightmaps.
|
||||
SetTexture(-1, tex, cmd.mRemapIndex & 0xff, 4/*DAMETH_CLAMPED*/, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
||||
curbasepal = saved;
|
||||
globalflags = savedf;
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue