Merge remote-tracking branch 'origin/master' into vulkan2

This commit is contained in:
Rachael Alexanderson 2019-04-14 06:12:32 -04:00
commit b8dfb3c136
73 changed files with 398 additions and 191 deletions

View file

@ -79,21 +79,6 @@ CUSTOM_CVAR(Int, con_buffersize, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
if (self >= 0 && self < 128) self = 128;
}
bool generic_hud, generic_ui;
EXTERN_CVAR(Bool, ui_generic)
CUSTOM_CVAR(Bool, hud_generic, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // All HUD elements only use generic assets
{
generic_hud = self || ui_generic;
}
CUSTOM_CVAR(Bool, ui_generic, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // The entire UI uses generic assets (this excludes the primary menus)
{
generic_ui = self;
generic_hud = self || hud_generic;
}
FConsoleBuffer *conbuffer;
static void C_TabComplete (bool goForward);
@ -599,13 +584,13 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE)
EColorRange C_GetDefaultFontColor()
{
// Ideally this should analyze the SmallFont and pick a matching color.
if (!generic_hud) return CR_UNTRANSLATED;
if (!generic_ui) return CR_UNTRANSLATED;
return gameinfo.gametype == GAME_Doom ? CR_RED : gameinfo.gametype == GAME_Chex ? CR_GREEN : gameinfo.gametype == GAME_Strife ? CR_GOLD : CR_GRAY;
}
FFont * C_GetDefaultHUDFont()
{
return generic_hud? NewSmallFont : SmallFont;
return generic_ui? NewSmallFont : SmallFont;
}
void C_InitConback()
@ -800,9 +785,9 @@ void FNotifyBuffer::AddString(int printlevel, FString source)
con_notifylines == 0)
return;
width = DisplayWidth / active_con_scaletext(generic_hud);
width = DisplayWidth / active_con_scaletext(generic_ui);
FFont *font = hud_generic ? NewSmallFont : SmallFont;
FFont *font = generic_ui ? NewSmallFont : SmallFont;
if (font == nullptr) return; // Without an initialized font we cannot handle the message (this is for those which come here before the font system is ready.)
if (AddType == APPENDLINE && Text.Size() > 0 && Text[Text.Size() - 1].PrintLevel == printlevel)
@ -1086,7 +1071,7 @@ void FNotifyBuffer::Draw()
line = Top;
canskip = true;
FFont *font = hud_generic ? NewSmallFont : SmallFont;
FFont *font = generic_ui ? NewSmallFont : SmallFont;
lineadv = font->GetHeight ();
for (unsigned i = 0; i < Text.Size(); ++ i)
@ -1109,7 +1094,7 @@ void FNotifyBuffer::Draw()
else
color = PrintColors[notify.PrintLevel];
int scale = active_con_scaletext(generic_hud);
int scale = active_con_scaletext(generic_ui);
if (!center)
screen->DrawText (font, color, 0, line, notify.Text,
DTA_VirtualWidth, screen->GetWidth() / scale,

View file

@ -858,7 +858,7 @@ void D_Display ()
screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE);
if (paused && multiplayer)
{
FFont *font = generic_hud? NewSmallFont : SmallFont;
FFont *font = generic_ui? NewSmallFont : SmallFont;
pstring << ' ' << players[paused - 1].userinfo.GetName();
screen->DrawText(font, CR_RED,
(screen->GetWidth() - font->StringWidth(pstring)*CleanXfac) / 2,

View file

@ -254,6 +254,6 @@ EXTERN_CVAR (Int, compatflags2);
extern FString LumpFilterIWAD;
// These control whether certain items use generic text output instead of game-specific one.
extern bool generic_hud, generic_ui;
extern bool generic_ui;
#endif

View file

@ -132,6 +132,20 @@ CUSTOM_CVAR(Float, teamdamage, 0.f, CVAR_SERVERINFO | CVAR_NOINITCALL)
}
}
bool generic_ui;
void UpdateGenericUI(bool cvar)
{
auto switchstr = GStrings["USE_GENERIC_FONT"];
generic_ui = (cvar || (switchstr && strtoll(switchstr, nullptr, 0)));
}
CUSTOM_CVAR(Bool, ui_generic, false, 0) // This is for allowing to test the generic font system with all languages
{
UpdateGenericUI(self);
}
CUSTOM_CVAR(String, language, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALCONFIG)
{
GStrings.UpdateLanguage();
@ -140,4 +154,5 @@ CUSTOM_CVAR(String, language, "auto", CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOB
// does this even make sense on secondary levels...?
if (Level->info != nullptr) Level->LevelName = Level->info->LookupLevelName();
}
UpdateGenericUI(ui_generic);
}

View file

@ -197,7 +197,7 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
Top = y;
HoldTics = (int)(holdTime * TICRATE);
Tics = -1; // -1 to compensate for one additional Tick the message will receive.
Font = font? font : generic_hud? NewSmallFont : SmallFont;
Font = font? font : generic_ui? NewSmallFont : SmallFont;
TextColor = textColor;
State = 0;
SourceText = copystring (text);

View file

@ -52,6 +52,8 @@ enum EHudState
HUD_AltHud // Used for passing through popups to the alt hud
};
enum EMonospacing : int;
// HUD Message base object --------------------------------------------------
// This is a mo-op base class to allow derived ZScript message types that can be managed by the status bar.
@ -332,12 +334,12 @@ class DHUDFont : public DObject
public:
FFont *mFont;
int mSpacing;
bool mMonospaced;
EMonospacing mMonospacing;
int mShadowX;
int mShadowY;
DHUDFont(FFont *f, int sp, bool ms, int sx, int sy)
: mFont(f), mSpacing(sp), mMonospaced(ms), mShadowX(sx), mShadowY(sy)
DHUDFont(FFont *f, int sp, EMonospacing ms, int sx, int sy)
: mFont(f), mSpacing(sp), mMonospacing(ms), mShadowX(sx), mShadowY(sy)
{}
};
@ -434,7 +436,7 @@ public:
void DrawAltHUD();
void DrawGraphic(FTextureID texture, double x, double y, int flags, double Alpha, double boxwidth, double boxheight, double scaleX, double scaleY);
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY);
void DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY);
void TransformRect(double &x, double &y, double &w, double &h, int flags = 0);
void Fill(PalEntry color, double x, double y, double w, double h, int flags = 0);
void SetClipRect(double x, double y, double w, double h, int flags = 0);

View file

@ -552,27 +552,10 @@ void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled
void FormatMapName(FLevelLocals *self, int cr, FString *result);
static void DrawAMText(FFont *fnt, int color, const char *text, int vwidth, int vheight, int x, int y)
{
int zerowidth = fnt->GetCharWidth('0');
x += zerowidth / 2;
for (int i = 0; text[i]; i++)
{
int c = text[i];
int width = fnt->GetCharWidth(c);
screen->DrawChar(fnt, color, x, y, c, DTA_KeepRatio, true,
DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight, DTA_LeftOffset, width / 2, TAG_DONE);
x += zerowidth;
}
}
void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight)
{
auto scale = GetUIScale(hud_scale);
auto font = generic_hud ? NewSmallFont : SmallFont;
auto font = generic_ui ? NewSmallFont : SmallFont;
auto vwidth = screen->GetWidth() / scale;
auto vheight = screen->GetHeight() / scale;
auto fheight = font->GetHeight();
@ -580,12 +563,14 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight)
int sec;
int y = 0;
int textdist = 4;
int zerowidth = font->GetCharWidth('0');
if (am_showtime)
{
sec = Tics2Seconds(primaryLevel->time);
textbuffer.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
DrawAMText(font, crdefault, textbuffer, vwidth, vheight, vwidth - font->GetCharWidth('0') * 8 - textdist, y);
screen->DrawText(font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight,
DTA_Monospace, EMonospacing::CellCenter, DTA_Spacing, zerowidth, DTA_KeepRatio, true, TAG_END);
y += fheight;
}
@ -593,7 +578,8 @@ void DBaseStatusBar::DoDrawAutomapHUD(int crdefault, int highlight)
{
sec = Tics2Seconds(primaryLevel->totaltime);
textbuffer.Format("%02d:%02d:%02d", sec / 3600, (sec % 3600) / 60, sec % 60);
DrawAMText(font, crdefault, textbuffer, vwidth, vheight, vwidth - font->GetCharWidth('0') * 8 - textdist, y);
screen->DrawText(font, crdefault, vwidth - zerowidth * 8 - textdist, y, textbuffer, DTA_VirtualWidth, vwidth, DTA_VirtualHeight, vheight,
DTA_Monospace, EMonospacing::CellCenter, DTA_Spacing, zerowidth, DTA_KeepRatio, true, TAG_END);
}
if (!deathmatch)
@ -1168,7 +1154,7 @@ void DBaseStatusBar::DrawLog ()
if (CPlayer->LogText.IsNotEmpty())
{
// This uses the same scaling as regular HUD messages
auto scale = active_con_scaletext(generic_hud);
auto scale = active_con_scaletext(generic_ui);
hudwidth = SCREENWIDTH / scale;
hudheight = SCREENHEIGHT / scale;
FFont *font = C_GetDefaultHUDFont();
@ -1600,8 +1586,10 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla
//
//============================================================================
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, bool monospaced, int shadowX, int shadowY)
void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, double y, int flags, double Alpha, int translation, int spacing, EMonospacing monospacing, int shadowX, int shadowY)
{
bool monospaced = monospacing != EMonospacing::Off;
switch (flags & DI_TEXT_ALIGN)
{
default:
@ -1685,6 +1673,11 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
rw = c->GetDisplayWidthDouble();
rh = c->GetDisplayHeightDouble();
if (monospacing == EMonospacing::CellCenter)
rx += (spacing - rw) / 2;
else if (monospacing == EMonospacing::CellRight)
rx += (spacing - rw);
if (!fullscreenOffsets)
{
StatusbarToRealCoords(rx, ry, rw, rh);
@ -1721,7 +1714,6 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
else
x += spacing;
}
}
void SBar_DrawString(DBaseStatusBar *self, DHUDFont *font, const FString &string, double x, double y, int flags, int trans, double alpha, int wrapwidth, int linespacing)
@ -1743,13 +1735,13 @@ void SBar_DrawString(DBaseStatusBar *self, DHUDFont *font, const FString &string
auto brk = V_BreakLines(font->mFont, wrapwidth, string, true);
for (auto &line : brk)
{
self->DrawString(font->mFont, line.Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
self->DrawString(font->mFont, line.Text, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY);
y += font->mFont->GetHeight() + linespacing;
}
}
else
{
self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospaced, font->mShadowX, font->mShadowY);
self->DrawString(font->mFont, string, x, y, flags, alpha, trans, font->mSpacing, font->mMonospacing, font->mShadowX, font->mShadowY);
}
}

View file

@ -282,6 +282,7 @@ static int PatchSize;
static char *Line1, *Line2;
static int dversion, pversion;
static bool including, includenotext;
static int LumpFileNum;
static const char *unknown_str = "Unknown key %s encountered in %s %d.\n";
@ -2169,7 +2170,7 @@ static int PatchMusic (int dummy)
keystring << "MUSIC_" << Line1;
TableElement te = { newname, newname, newname, newname };
TableElement te = { LumpFileNum, { newname, newname, newname, newname } };
DehStrings.Insert(keystring, te);
DPrintf (DMSG_SPAMMY, "Music %s set to:\n%s\n", keystring.GetChars(), newname.GetChars());
}
@ -2285,7 +2286,7 @@ static int PatchText (int oldSize)
if (str != NULL)
{
FString newname = newStr;
TableElement te = { newname, newname, newname, newname };
TableElement te = { LumpFileNum, { newname, newname, newname, newname } };
DehStrings.Insert(str, te);
EnglishStrings.Remove(str); // remove entry so that it won't get found again by the next iteration or by another replacement later
good = true;
@ -2340,7 +2341,7 @@ static int PatchStrings (int dummy)
// Account for a discrepancy between Boom's and ZDoom's name for the red skull key pickup message
const char *ll = Line1;
if (!stricmp(ll, "GOTREDSKULL")) ll = "GOTREDSKUL";
TableElement te = { holdstring, holdstring, holdstring, holdstring };
TableElement te = { LumpFileNum, { holdstring, holdstring, holdstring, holdstring } };
DehStrings.Insert(ll, te);
DPrintf (DMSG_SPAMMY, "%s set to:\n%s\n", Line1, holdstring.GetChars());
}
@ -2496,13 +2497,19 @@ int D_LoadDehLumps(DehLumpSource source)
bool D_LoadDehLump(int lumpnum)
{
auto ls = LumpFileNum;
LumpFileNum = Wads.GetLumpFile(lumpnum);
PatchSize = Wads.LumpLength(lumpnum);
PatchName = copystring(Wads.GetLumpFullPath(lumpnum));
PatchFile = new char[PatchSize + 1];
Wads.ReadLump(lumpnum, PatchFile);
PatchFile[PatchSize] = '\0'; // terminate with a '\0' character
return DoDehPatch();
auto res = DoDehPatch();
LumpFileNum = ls;
return res;
}
bool D_LoadDehFile(const char *patchfile)

View file

@ -67,8 +67,8 @@ void FStringTable::LoadStrings ()
{
auto lumpdata = Wads.ReadLumpIntoArray(lump);
if (!ParseLanguageCSV(lumpdata))
LoadLanguage (lumpdata);
if (!ParseLanguageCSV(lump, lumpdata))
LoadLanguage (lump, lumpdata);
}
UpdateLanguage();
allMacros.Clear();
@ -191,7 +191,7 @@ bool FStringTable::readMacros(int lumpnum)
//
//==========================================================================
bool FStringTable::ParseLanguageCSV(const TArray<uint8_t> &buffer)
bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray<uint8_t> &buffer)
{
if (memcmp(buffer.Data(), "default,", 8)) return false;
auto data = parseCSV(buffer);
@ -199,6 +199,7 @@ bool FStringTable::ParseLanguageCSV(const TArray<uint8_t> &buffer)
int labelcol = -1;
int filtercol = -1;
TArray<std::pair<int, unsigned>> langrows;
bool hasDefaultEntry = false;
if (data.Size() > 0)
{
@ -221,6 +222,7 @@ bool FStringTable::ParseLanguageCSV(const TArray<uint8_t> &buffer)
if (lang.CompareNoCase("default") == 0)
{
langrows.Push(std::make_pair(column, default_table));
hasDefaultEntry = true;
}
else if (lang.Len() < 4)
{
@ -243,12 +245,16 @@ bool FStringTable::ParseLanguageCSV(const TArray<uint8_t> &buffer)
}
FName strName = row[labelcol];
if (hasDefaultEntry)
{
DeleteForLabel(lumpnum, strName);
}
for (auto &langentry : langrows)
{
auto str = row[langentry.first];
if (str.Len() > 0)
{
InsertString(langentry.second, strName, str);
InsertString(lumpnum, langentry.second, strName, str);
}
else
{
@ -266,7 +272,7 @@ bool FStringTable::ParseLanguageCSV(const TArray<uint8_t> &buffer)
//
//==========================================================================
void FStringTable::LoadLanguage (const TArray<uint8_t> &buffer)
void FStringTable::LoadLanguage (int lumpnum, const TArray<uint8_t> &buffer)
{
bool errordone = false;
TArray<uint32_t> activeMaps;
@ -293,10 +299,12 @@ void FStringTable::LoadLanguage (const TArray<uint8_t> &buffer)
}
if (len == 1 && sc.String[0] == '*')
{
activeMaps.Clear();
activeMaps.Push(global_table);
}
else if (len == 7 && stricmp (sc.String, "default") == 0)
{
activeMaps.Clear();
activeMaps.Push(default_table);
}
else
@ -307,7 +315,8 @@ void FStringTable::LoadLanguage (const TArray<uint8_t> &buffer)
}
else
{
activeMaps.Push(MAKE_ID(tolower(sc.String[0]), tolower(sc.String[1]), tolower(sc.String[2]), 0));
if (activeMaps.Size() != 1 || (activeMaps[0] != default_table && activeMaps[0] != global_table))
activeMaps.Push(MAKE_ID(tolower(sc.String[0]), tolower(sc.String[1]), tolower(sc.String[2]), 0));
}
sc.MustGetString ();
} while (!sc.Compare ("]"));
@ -360,10 +369,14 @@ void FStringTable::LoadLanguage (const TArray<uint8_t> &buffer)
}
if (!skip)
{
if (activeMaps[0] == default_table)
{
DeleteForLabel(lumpnum, strName);
}
// Insert the string into all relevant tables.
for (auto map : activeMaps)
{
InsertString(map, strName, strText);
InsertString(lumpnum, map, strName, strText);
}
}
}
@ -381,16 +394,40 @@ void FStringTable::DeleteString(int langid, FName label)
allStrings[langid].Remove(label);
}
//==========================================================================
//
// This deletes all older entries for a given label. This gets called
// when a string in the default table gets updated.
//
//==========================================================================
void FStringTable::DeleteForLabel(int lumpnum, FName label)
{
decltype(allStrings)::Iterator it(allStrings);
decltype(allStrings)::Pair *pair;
auto filenum = Wads.GetLumpFile(lumpnum);
while (it.NextPair(pair))
{
auto entry = pair->Value.CheckKey(label);
if (entry && entry->filenum < filenum)
{
pair->Value.Remove(label);
}
}
}
//==========================================================================
//
//
//
//==========================================================================
void FStringTable::InsertString(int langid, FName label, const FString &string)
void FStringTable::InsertString(int lumpnum, int langid, FName label, const FString &string)
{
const char *strlangid = (const char *)&langid;
TableElement te = { string, string, string, string };
TableElement te = { lumpnum, { string, string, string, string } };
long index;
while ((index = te.strings[0].IndexOf("@[")) >= 0)
{

View file

@ -49,6 +49,7 @@
struct TableElement
{
int filenum;
FString strings[4];
};
@ -104,14 +105,15 @@ private:
LangMap allStrings;
TArray<std::pair<uint32_t, StringMap*>> currentLanguageSet;
void LoadLanguage (const TArray<uint8_t> &buffer);
void LoadLanguage (int lumpnum, const TArray<uint8_t> &buffer);
TArray<TArray<FString>> parseCSV(const TArray<uint8_t> &buffer);
bool ParseLanguageCSV(const TArray<uint8_t> &buffer);
bool ParseLanguageCSV(int lumpnum, const TArray<uint8_t> &buffer);
bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray<uint8_t> &buffer);
bool readMacros(int lumpnum);
void InsertString(int langid, FName label, const FString &string);
void InsertString(int lumpnum, int langid, FName label, const FString &string);
void DeleteString(int langid, FName label);
void DeleteForLabel(int lumpnum, FName label);
static size_t ProcessEscapes (char *str);
};

View file

@ -499,7 +499,7 @@ unsigned FSavegameManager::ExtractSaveData(int index)
{
SavePic = PNGTexture_CreateFromFile(png, node->Filename);
delete png;
if (SavePic->GetDisplayWidth() == 1 && SavePic->GetDisplayHeight() == 1)
if (SavePic && SavePic->GetDisplayWidth() == 1 && SavePic->GetDisplayHeight() == 1)
{
delete SavePic;
SavePic = nullptr;

View file

@ -545,6 +545,8 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
parms->srcwidth = 1.;
parms->srcheight = 1.;
parms->burn = false;
parms->monospace = EMonospacing::Off;
parms->spacing = 0;
// Parse the tag list for attributes. (For floating point attributes,
// consider that the C ABI dictates that all floats be promoted to
@ -896,7 +898,15 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
case DTA_CellY:
parms->celly = ListGetInt(tags);
break;
case DTA_Monospace:
parms->monospace = ListGetInt(tags);
break;
case DTA_Spacing:
parms->spacing = ListGetInt(tags);
break;
case DTA_Burn:
parms->burn = true;
break;

View file

@ -296,6 +296,11 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
cx = x;
cy = y;
if (parms.monospace == EMonospacing::CellCenter)
cx += parms.spacing / 2;
else if (parms.monospace == EMonospacing::CellRight)
cx += parms.spacing;
auto currentcolor = normalcolor;
while (ch - string < parms.maxstrlen)
@ -334,9 +339,24 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
parms.destwidth = parms.cellx;
parms.destheight = parms.celly;
}
if (parms.monospace == EMonospacing::CellLeft)
parms.left = 0;
else if (parms.monospace == EMonospacing::CellCenter)
parms.left = w / 2.;
else if (parms.monospace == EMonospacing::CellRight)
parms.left = w;
DrawTextureParms(pic, parms);
}
cx += (w + kerning) * parms.scalex;
if (parms.monospace == EMonospacing::Off)
{
cx += (w + kerning + parms.spacing) * parms.scalex;
}
else
{
cx += (parms.spacing) * parms.scalex;
}
}
}

View file

@ -50,6 +50,7 @@
#include "am_map.h"
#include "v_video.h"
#include "gi.h"
#include "fontinternals.h"
#include "intermission/intermission.h"
DVector2 AM_GetPosition();
@ -176,6 +177,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, CharCodeAt, StringCharCodeAt)
ACTION_RETURN_INT(StringCharCodeAt(self, pos));
}
static int StringByteAt(FString *self, int pos)
{
if ((unsigned)pos >= self->Len()) return 0;
else return (uint8_t)((*self)[pos]);
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ByteAt, StringByteAt)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
PARAM_INT(pos);
ACTION_RETURN_INT(StringByteAt(self, pos));
}
static void StringFilter(FString *self, FString *result)
{
*result = strbin1(*self);
@ -250,6 +264,53 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, ToLower, StringToLower)
return 0;
}
static void StringMakeUpper(FString *self, FString *out)
{
*out = self->MakeUpper();
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, MakeUpper, StringMakeUpper)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
ACTION_RETURN_STRING(self->MakeUpper());
}
static void StringMakeLower(FString *self, FString *out)
{
*out = self->MakeLower();
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, MakeLower, StringMakeLower)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
ACTION_RETURN_STRING(self->MakeLower());
}
static int StringCharUpper(int ch)
{
return ch >= 0 && ch < 65536 ? upperforlower[ch] : ch;
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, CharUpper, StringCharUpper)
{
PARAM_PROLOGUE;
PARAM_INT(ch);
ACTION_RETURN_INT(StringCharUpper(ch));
}
static int StringCharLower(int ch)
{
return ch >= 0 && ch < 65536 ? lowerforupper[ch] : ch;
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, CharLower, StringCharLower)
{
PARAM_PROLOGUE;
PARAM_INT(ch);
ACTION_RETURN_INT(StringCharLower(ch));
}
static int StringToInt(FString *self, int base)
{
return (int)self->ToLong(base);
@ -288,6 +349,34 @@ DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, Split, StringSplit)
return 0;
}
static int StringCodePointCount(FString *self)
{
return (int)self->CharacterCount();
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, CodePointCount, StringCodePointCount)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
ACTION_RETURN_INT(StringCodePointCount(self));
}
static int StringNextCodePoint(FString *self, int inposition, int *position)
{
int codepoint = self->GetNextCharacter(inposition);
if (position) *position = inposition;
return codepoint;
}
DEFINE_ACTION_FUNCTION_NATIVE(FStringStruct, GetNextCodePoint, StringNextCodePoint)
{
PARAM_SELF_STRUCT_PROLOGUE(FString);
PARAM_INT(pos);
if (numret > 0) ret[0].SetInt(self->GetNextCharacter(pos));
if (numret > 1) ret[1].SetInt(pos);
return numret;
}
//=====================================================================================
//
// sector_t exports
@ -2543,9 +2632,9 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetInventoryIcon, GetInventoryIcon
//
//=====================================================================================
DHUDFont *CreateHudFont(FFont *fnt, int spac, bool mono, int sx, int sy)
DHUDFont *CreateHudFont(FFont *fnt, int spac, int mono, int sx, int sy)
{
return (Create<DHUDFont>(fnt, spac, mono, sy, sy));
return (Create<DHUDFont>(fnt, spac, EMonospacing(mono), sy, sy));
}
DEFINE_ACTION_FUNCTION_NATIVE(DHUDFont, Create, CreateHudFont)
@ -2553,10 +2642,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DHUDFont, Create, CreateHudFont)
PARAM_PROLOGUE;
PARAM_POINTER(fnt, FFont);
PARAM_INT(spac);
PARAM_BOOL(mono);
PARAM_INT(mono);
PARAM_INT(sx);
PARAM_INT(sy);
ACTION_RETURN_POINTER(Create<DHUDFont>(fnt, spac, mono, sy, sy));
ACTION_RETURN_POINTER(Create<DHUDFont>(fnt, spac, EMonospacing(mono), sy, sy));
}

View file

@ -40,6 +40,7 @@
#include "zstring.h"
#include "v_text.h"
#include "utf8.h"
#include "fontinternals.h"
FNullStringData FString::NullString =
{
@ -680,22 +681,30 @@ void FString::ToLower ()
UnlockBuffer();
}
void FString::SwapCase ()
FString FString::MakeLower() const
{
LockBuffer();
size_t max = Len();
for (size_t i = 0; i < max; ++i)
TArray<uint8_t> builder(Len());
int pos = 0;
while (int c = GetNextCharacter(pos))
{
if (isupper(Chars[i]))
{
Chars[i] = (char)tolower(Chars[i]);
}
else
{
Chars[i] = (char)toupper(Chars[i]);
}
if (c < 65536) c = lowerforupper[c];
auto cp = MakeUTF8(c);
while (auto uc = *cp++) builder.Push(uc);
}
UnlockBuffer();
return FString(builder);
}
FString FString::MakeUpper() const
{
TArray<uint8_t> builder(Len());
int pos = 0;
while (int c = GetNextCharacter(pos))
{
if (c < 65536) c = upperforlower[c];
auto cp = MakeUTF8(c);
while (auto uc = *cp++) builder.Push(uc);
}
return FString(builder);
}
void FString::StripLeft ()

View file

@ -238,7 +238,8 @@ public:
void ToUpper ();
void ToLower ();
void SwapCase ();
FString MakeUpper() const;
FString MakeLower() const;
void StripLeft ();
void StripLeft (const FString &charset);

View file

@ -926,5 +926,4 @@ DEFINE_GLOBAL(CleanXfac_1)
DEFINE_GLOBAL(CleanYfac_1)
DEFINE_GLOBAL(CleanWidth_1)
DEFINE_GLOBAL(CleanHeight_1)
DEFINE_GLOBAL(generic_hud)
DEFINE_GLOBAL(generic_ui)

View file

@ -235,6 +235,16 @@ enum
DTA_SrcHeight,
DTA_LegacyRenderStyle, // takes an old-style STYLE_* constant instead of an FRenderStyle
DTA_Burn, // activates the burn shader for this element
DTA_Spacing, // Strings only: Additional spacing between characters
DTA_Monospace, // Fonts only: Use a fixed distance between characters.
};
enum EMonospacing : int
{
Off = 0,
CellLeft = 1,
CellCenter = 2,
CellRight = 3
};
enum
@ -285,6 +295,8 @@ struct DrawParms
int desaturate;
int scalex, scaley;
int cellx, celly;
int monospace;
int spacing;
int maxstrlen;
bool fortext;
bool virtBottom;