[Deps]: Rename stb_truetype.h to stb_truetype.hpp (#719)

This commit is contained in:
Edo 2023-01-12 14:55:26 +00:00 committed by GitHub
parent 3ff8486fc3
commit 0d96a0882b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1736 additions and 1661 deletions

View File

@ -2,7 +2,7 @@
#include "IFont_s.hpp" #include "IFont_s.hpp"
#define STB_TRUETYPE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h> #include <stb_truetype.hpp>
#include <json.hpp> #include <json.hpp>

View File

@ -56,6 +56,19 @@ namespace Components
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You are muted\"", 0x65)); Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"You are muted\"", 0x65));
} }
if (sv_disableChat.get<bool>())
{
SendChat = false;
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
}
// Message might be empty after processing the '/'
if (text[msgIndex] == '\0')
{
SendChat = false;
return text;
}
for (const auto& callback : SayCallbacks) for (const auto& callback : SayCallbacks)
{ {
if (!ChatCallback(player, callback.getPos(), (text + msgIndex), mode)) if (!ChatCallback(player, callback.getPos(), (text + msgIndex), mode))
@ -64,12 +77,6 @@ namespace Components
} }
} }
if (sv_disableChat.get<bool>())
{
SendChat = false;
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE, Utils::String::VA("%c \"Chat is disabled\"", 0x65));
}
TextRenderer::StripMaterialTextIcons(text, text, std::strlen(text) + 1); TextRenderer::StripMaterialTextIcons(text, text, std::strlen(text) + 1);
Game::Scr_AddEntity(player); Game::Scr_AddEntity(player);

View File

@ -102,8 +102,6 @@ namespace Components
const char Debug::StrTemplate[] = "%s: %s All those moments will be lost in time, like tears in rain."; const char Debug::StrTemplate[] = "%s: %s All those moments will be lost in time, like tears in rain.";
const float Debug::ColorWhite[] = {1.0f, 1.0f, 1.0f, 1.0f};
std::string Debug::BuildPMFlagsString(const Game::playerState_s* ps) std::string Debug::BuildPMFlagsString(const Game::playerState_s* ps)
{ {
std::string result; std::string result;
@ -163,19 +161,19 @@ namespace Components
auto* const font2 = Game::UI_GetFontHandle(scrPlace, 6, MY_SCALE2); auto* const font2 = Game::UI_GetFontHandle(scrPlace, 6, MY_SCALE2);
Game::UI_DrawText(scrPlace, "Client View of Flags", maxChars, font2, -60.0f, 0, 1, 1, Game::UI_DrawText(scrPlace, "Client View of Flags", maxChars, font2, -60.0f, 0, 1, 1,
MY_SCALE2, ColorWhite, 1); MY_SCALE2, TextRenderer::WHITE_COLOR, 1);
const auto pmf = BuildPMFlagsString(&cgameGlob->predictedPlayerState); const auto pmf = BuildPMFlagsString(&cgameGlob->predictedPlayerState);
Game::UI_DrawText(scrPlace, pmf.data(), maxChars, font1, 30.0f, MY_Y, 1, 1, MY_SCALE_2, ColorWhite, 3); Game::UI_DrawText(scrPlace, pmf.data(), maxChars, font1, 30.0f, MY_Y, 1, 1, MY_SCALE_2, TextRenderer::WHITE_COLOR, 3);
const auto pof = BuildPOFlagsString(&cgameGlob->predictedPlayerState); const auto pof = BuildPOFlagsString(&cgameGlob->predictedPlayerState);
Game::UI_DrawText(scrPlace, pof.data(), maxChars, font1, 350.0f, MY_Y, 1, 1, MY_SCALE_2, ColorWhite, 3); Game::UI_DrawText(scrPlace, pof.data(), maxChars, font1, 350.0f, MY_Y, 1, 1, MY_SCALE_2, TextRenderer::WHITE_COLOR, 3);
const auto plf = BuildPLFlagsString(&cgameGlob->predictedPlayerState); const auto plf = BuildPLFlagsString(&cgameGlob->predictedPlayerState);
Game::UI_DrawText(scrPlace, plf.data(), maxChars, font1, 350.0f, 250.0f, 1, 1, MY_SCALE_2, ColorWhite, 3); Game::UI_DrawText(scrPlace, plf.data(), maxChars, font1, 350.0f, 250.0f, 1, 1, MY_SCALE_2, TextRenderer::WHITE_COLOR, 3);
const auto pef = BuildPEFlagsString(&cgameGlob->predictedPlayerState); const auto pef = BuildPEFlagsString(&cgameGlob->predictedPlayerState);
Game::UI_DrawText(scrPlace, pef.data(), maxChars, font1, 525.0f, MY_Y, 1, 1, MY_SCALE_2, ColorWhite, 3); Game::UI_DrawText(scrPlace, pef.data(), maxChars, font1, 525.0f, MY_Y, 1, 1, MY_SCALE_2, TextRenderer::WHITE_COLOR, 3);
} }
void Debug::CG_DrawDebugPlayerHealth(const int localClientNum) void Debug::CG_DrawDebugPlayerHealth(const int localClientNum)
@ -223,23 +221,23 @@ namespace Components
sprintf_s(strFinal, StrTemplate, font1->fontName, StrButtons); sprintf_s(strFinal, StrTemplate, font1->fontName, StrButtons);
Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal)); Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal));
Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font1, MY_X, 10.0f, 1, 1, 0.4f, ColorWhite, 3); Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font1, MY_X, 10.0f, 1, 1, 0.4f, TextRenderer::WHITE_COLOR, 3);
sprintf_s(strFinal, StrTemplate, font2->fontName, StrButtons); sprintf_s(strFinal, StrTemplate, font2->fontName, StrButtons);
Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal)); Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal));
Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font2, MY_X, 35.0f, 1, 1, 0.4f, ColorWhite, 3); Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font2, MY_X, 35.0f, 1, 1, 0.4f, TextRenderer::WHITE_COLOR, 3);
sprintf_s(strFinal, StrTemplate, font3->fontName, StrButtons); sprintf_s(strFinal, StrTemplate, font3->fontName, StrButtons);
Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal)); Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal));
Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font3, MY_X, 60.0f, 1, 1, 0.4f, ColorWhite, 3); Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font3, MY_X, 60.0f, 1, 1, 0.4f, TextRenderer::WHITE_COLOR, 3);
sprintf_s(strFinal, StrTemplate, font5->fontName, StrButtons); sprintf_s(strFinal, StrTemplate, font5->fontName, StrButtons);
Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal)); Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal));
Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font5, MY_X, 85.0f, 1, 1, 0.4f, ColorWhite, 3); Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font5, MY_X, 85.0f, 1, 1, 0.4f, TextRenderer::WHITE_COLOR, 3);
sprintf_s(strFinal, StrTemplate, font6->fontName, StrButtons); sprintf_s(strFinal, StrTemplate, font6->fontName, StrButtons);
Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal)); Game::UI_FilterStringForButtonAnimation(strFinal, sizeof(strFinal));
Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font6, MY_X, 110.0f, 1, 1, 0.4f, ColorWhite, 3); Game::UI_DrawText(scrPlace, strFinal, std::numeric_limits<int>::max(), font6, MY_X, 110.0f, 1, 1, 0.4f, TextRenderer::WHITE_COLOR, 3);
} }
void Debug::CG_DrawDebugOverlays_Hk(const int localClientNum) void Debug::CG_DrawDebugOverlays_Hk(const int localClientNum)

View File

@ -28,8 +28,6 @@ namespace Components
static constexpr auto MY_X = -25.0f; static constexpr auto MY_X = -25.0f;
static constexpr auto MY_Y = 20.0f; static constexpr auto MY_Y = 20.0f;
static const float ColorWhite[];
static std::string BuildPMFlagsString(const Game::playerState_s* ps); static std::string BuildPMFlagsString(const Game::playerState_s* ps);
static std::string BuildPOFlagsString(const Game::playerState_s* ps); static std::string BuildPOFlagsString(const Game::playerState_s* ps);
static std::string BuildPLFlagsString(const Game::playerState_s* ps); static std::string BuildPLFlagsString(const Game::playerState_s* ps);

View File

@ -60,7 +60,7 @@ namespace Components
Game::dvar_t* TextRenderer::g_ColorBlind_EnemyTeam; Game::dvar_t* TextRenderer::g_ColorBlind_EnemyTeam;
Game::dvar_t** TextRenderer::con_inputBoxColor = reinterpret_cast<Game::dvar_t**>(0x9FD4BC); Game::dvar_t** TextRenderer::con_inputBoxColor = reinterpret_cast<Game::dvar_t**>(0x9FD4BC);
TextRenderer::BufferedLocalizedString::BufferedLocalizedString(const char* reference, const size_t bufferSize) TextRenderer::BufferedLocalizedString::BufferedLocalizedString(const char* reference, const std::size_t bufferSize)
: stringReference(reference), : stringReference(reference),
stringBuffer(std::make_unique<char[]>(bufferSize)), stringBuffer(std::make_unique<char[]>(bufferSize)),
stringBufferSize(bufferSize), stringBufferSize(bufferSize),
@ -75,11 +75,13 @@ namespace Components
if (formattingString != nullptr) if (formattingString != nullptr)
{ {
strncpy(stringBuffer.get(), formattingString, stringBufferSize); strncpy_s(stringBuffer.get(), stringBufferSize, formattingString, _TRUNCATE);
for (auto& width : stringWidth) for (auto& width : stringWidth)
{
width = -1; width = -1;
} }
} }
}
const char* TextRenderer::BufferedLocalizedString::Format(const char* value) const char* TextRenderer::BufferedLocalizedString::Format(const char* value)
{ {
@ -95,7 +97,10 @@ namespace Components
Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer.get(), stringBufferSize); Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer.get(), stringBufferSize);
for (auto& width : stringWidth) for (auto& width : stringWidth)
{
width = -1; width = -1;
}
return stringBuffer.get(); return stringBuffer.get();
} }
@ -108,7 +113,9 @@ namespace Components
{ {
assert(autocompleteInstance < FONT_ICON_ACI_COUNT); assert(autocompleteInstance < FONT_ICON_ACI_COUNT);
if (stringWidth[autocompleteInstance] < 0) if (stringWidth[autocompleteInstance] < 0)
{
stringWidth[autocompleteInstance] = Game::R_TextWidth(GetString(), std::numeric_limits<int>::max(), font); stringWidth[autocompleteInstance] = Game::R_TextWidth(GetString(), std::numeric_limits<int>::max(), font);
}
return stringWidth[autocompleteInstance]; return stringWidth[autocompleteInstance];
} }
@ -117,13 +124,13 @@ namespace Components
: autocompleteActive(false), : autocompleteActive(false),
inModifiers(false), inModifiers(false),
userClosed(false), userClosed(false),
lastHash(0u), lastHash(0),
results{}, results{},
resultCount(0u), resultCount(0),
hasMoreResults(false), hasMoreResults(false),
resultOffset(0u), resultOffset(0),
lastResultOffset(0u), lastResultOffset(0),
selectedOffset(0u), selectedOffset(0),
maxFontIconWidth(0.0f), maxFontIconWidth(0.0f),
maxMaterialNameWidth(0.0f), maxMaterialNameWidth(0.0f),
stringSearchStartWith(REFERENCE_SEARCH_START_WITH, STRING_BUFFER_SIZE_BIG) stringSearchStartWith(REFERENCE_SEARCH_START_WITH, STRING_BUFFER_SIZE_BIG)
@ -182,13 +189,6 @@ namespace Components
void TextRenderer::DrawAutocompleteBox(const FontIconAutocompleteContext& context, const float x, const float y, const float w, const float h, const float* color) void TextRenderer::DrawAutocompleteBox(const FontIconAutocompleteContext& context, const float x, const float y, const float w, const float h, const float* color)
{ {
static constexpr float colorWhite[4]
{
1.0f,
1.0f,
1.0f,
1.0f
};
const float borderColor[4] const float borderColor[4]
{ {
color[0] * 0.5f, color[0] * 0.5f,
@ -209,15 +209,16 @@ namespace Components
y + FONT_ICON_AUTOCOMPLETE_BOX_BORDER, y + FONT_ICON_AUTOCOMPLETE_BOX_BORDER,
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
1.0f, 1.0f, 0.0f, 0.0f, colorWhite, Game::sharedUiInfo->assets.scrollBarArrowDown); 1.0f, 1.0f, 0.0f, 0.0f, WHITE_COLOR, Game::sharedUiInfo->assets.scrollBarArrowDown);
} }
if (context.hasMoreResults) if (context.hasMoreResults)
{ {
Game::R_AddCmdDrawStretchPic(x + w - FONT_ICON_AUTOCOMPLETE_BOX_BORDER - FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, Game::R_AddCmdDrawStretchPic(x + w - FONT_ICON_AUTOCOMPLETE_BOX_BORDER - FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
y + h - FONT_ICON_AUTOCOMPLETE_BOX_BORDER - FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, y + h - FONT_ICON_AUTOCOMPLETE_BOX_BORDER - FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE, FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
1.0f, 1.0f, 0.0f, 0.0f, colorWhite, Game::sharedUiInfo->assets.scrollBarArrowUp); 1.0f, 1.0f, 0.0f, 0.0f, WHITE_COLOR, Game::sharedUiInfo->assets.scrollBarArrowUp);
} }
} }
@ -242,17 +243,22 @@ namespace Components
} }
else if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS) else if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS)
{ {
context.results[context.resultCount++] = { context.results[context.resultCount++] =
{
Utils::String::VA(":%s:", fontIconEntry.iconName.data()), Utils::String::VA(":%s:", fontIconEntry.iconName.data()),
fontIconEntry.iconName fontIconEntry.iconName
}; };
} }
else else
{
context.hasMoreResults = true; context.hasMoreResults = true;
} }
}
else if (compareValue > 0) else if (compareValue > 0)
{
break; break;
} }
}
context.maxFontIconWidth = 0; context.maxFontIconWidth = 0;
context.maxMaterialNameWidth = 0; context.maxMaterialNameWidth = 0;
@ -290,7 +296,7 @@ namespace Components
inModifiers = false; inModifiers = false;
} }
} }
else if(isspace(c)) else if (std::isspace(c))
{ {
fontIconStart = -1; fontIconStart = -1;
inModifiers = false; inModifiers = false;
@ -311,8 +317,8 @@ namespace Components
if (fontIconStart < 0 // Not in fonticon sequence if (fontIconStart < 0 // Not in fonticon sequence
|| fontIconStart == edit->cursor // Did not type the first letter yet || fontIconStart == edit->cursor // Did not type the first letter yet
|| !isalpha(static_cast<unsigned char>(edit->buffer[fontIconStart])) // First letter of the icon is not alphabetic || !std::isalpha(static_cast<unsigned char>(edit->buffer[fontIconStart])) // First letter of the icon is not alphabetic
|| (fontIconStart > 1 && isalnum(static_cast<unsigned char>(edit->buffer[fontIconStart - 2]))) // Letter before sequence is alnum || (fontIconStart > 1 && std::isalnum(static_cast<unsigned char>(edit->buffer[fontIconStart - 2]))) // Letter before sequence is alnum
) )
{ {
context.autocompleteActive = false; context.autocompleteActive = false;
@ -326,24 +332,34 @@ namespace Components
// Update scroll // Update scroll
if (context.selectedOffset < context.resultOffset) if (context.selectedOffset < context.resultOffset)
{
context.resultOffset = context.selectedOffset; context.resultOffset = context.selectedOffset;
}
else if(context.selectedOffset >= context.resultOffset + FontIconAutocompleteContext::MAX_RESULTS) else if(context.selectedOffset >= context.resultOffset + FontIconAutocompleteContext::MAX_RESULTS)
{
context.resultOffset = context.selectedOffset - (FontIconAutocompleteContext::MAX_RESULTS - 1); context.resultOffset = context.selectedOffset - (FontIconAutocompleteContext::MAX_RESULTS - 1);
}
// If the user closed the context do not draw or update // If the user closed the context do not draw or update
if (context.userClosed) if (context.userClosed)
{
return; return;
}
context.autocompleteActive = true; context.autocompleteActive = true;
// No need to update results when in modifiers // No need to update results when in modifiers
if (context.inModifiers) if (context.inModifiers)
{
return; return;
}
// Check if results need updates // Check if results need updates
const auto currentFontIconHash = Game::R_HashString(&edit->buffer[fontIconStart], edit->cursor - fontIconStart); const auto currentFontIconHash = Game::R_HashString(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
if (currentFontIconHash == context.lastHash && context.lastResultOffset == context.resultOffset) if (currentFontIconHash == context.lastHash && context.lastResultOffset == context.resultOffset)
{
return; return;
}
// If query was updated then reset scroll parameters // If query was updated then reset scroll parameters
if (currentFontIconHash != context.lastHash) if (currentFontIconHash != context.lastHash)
@ -512,20 +528,26 @@ namespace Components
void TextRenderer::AutocompleteUp(FontIconAutocompleteContext& context) void TextRenderer::AutocompleteUp(FontIconAutocompleteContext& context)
{ {
if (context.selectedOffset > 0) if (context.selectedOffset > 0)
{
context.selectedOffset--; context.selectedOffset--;
} }
}
void TextRenderer::AutocompleteDown(FontIconAutocompleteContext& context) void TextRenderer::AutocompleteDown(FontIconAutocompleteContext& context)
{ {
if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS) if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS)
{ {
if (context.resultCount > 0 && context.selectedOffset < context.resultOffset + context.resultCount - 1) if (context.resultCount > 0 && context.selectedOffset < context.resultOffset + context.resultCount - 1)
context.selectedOffset++; {
++context.selectedOffset;
}
} }
else if (context.selectedOffset == context.resultOffset + context.resultCount - 1) else if (context.selectedOffset == context.resultOffset + context.resultCount - 1)
{ {
if (context.hasMoreResults) if (context.hasMoreResults)
context.selectedOffset++; {
++context.selectedOffset;
}
} }
else else
{ {
@ -540,13 +562,19 @@ namespace Components
const auto selectedResultIndex = context.selectedOffset - context.resultOffset; const auto selectedResultIndex = context.selectedOffset - context.resultOffset;
std::string remainingFillData = context.results[selectedResultIndex].materialName.substr(context.lastQuery.size()); std::string remainingFillData = context.results[selectedResultIndex].materialName.substr(context.lastQuery.size());
if (closeFontIcon) if (closeFontIcon)
{
remainingFillData += ":"; remainingFillData += ":";
}
const std::string moveData(&edit->buffer[edit->cursor]); const std::string moveData(&edit->buffer[edit->cursor]);
const auto remainingBufferCharacters = std::extent_v<decltype(Game::field_t::buffer)> - edit->cursor - moveData.size() - 1; const auto remainingBufferCharacters = std::extent_v<decltype(Game::field_t::buffer)> - edit->cursor - moveData.size() - 1;
if (remainingFillData.size() > remainingBufferCharacters) if (remainingFillData.size() > remainingBufferCharacters)
{
remainingFillData = remainingFillData.erase(remainingBufferCharacters); remainingFillData = remainingFillData.erase(remainingBufferCharacters);
}
if (!remainingFillData.empty()) if (!remainingFillData.empty())
{ {
@ -659,7 +687,9 @@ namespace Components
float TextRenderer::GetMonospaceWidth(Game::Font_s* font, int rendererFlags) float TextRenderer::GetMonospaceWidth(Game::Font_s* font, int rendererFlags)
{ {
if (rendererFlags & Game::TEXT_RENDERFLAG_FORCEMONOSPACE) if (rendererFlags & Game::TEXT_RENDERFLAG_FORCEMONOSPACE)
{
return Game::R_GetCharacterGlyph(font, 'o')->dx; return Game::R_GetCharacterGlyph(font, 'o')->dx;
}
return 0.0f; return 0.0f;
} }
@ -696,8 +726,10 @@ namespace Components
for (auto i = 0u; i < fontIconMaterial->textureCount; i++) for (auto i = 0u; i < fontIconMaterial->textureCount; i++)
{ {
if (fontIconMaterial->textureTable[i].nameHash == COLOR_MAP_HASH) if (fontIconMaterial->textureTable[i].nameHash == COLOR_MAP_HASH)
{
return fontIconMaterial->textureTable[i].u.image; return fontIconMaterial->textureTable[i].u.image;
} }
}
return nullptr; return nullptr;
} }
@ -742,13 +774,17 @@ namespace Components
} }
if (*curPos != FONT_ICON_SEPARATOR_CHARACTER) if (*curPos != FONT_ICON_SEPARATOR_CHARACTER)
{
return false; return false;
}
const std::string fontIconName(text, nameEnd - text); const std::string fontIconName(text, nameEnd - text);
const auto foundFontIcon = fontIconLookup.find(fontIconName); const auto foundFontIcon = fontIconLookup.find(fontIconName);
if (foundFontIcon == fontIconLookup.end()) if (foundFontIcon == fontIconLookup.end())
{
return false; return false;
}
auto& entry = foundFontIcon->second; auto& entry = foundFontIcon->second;
if (entry.material == nullptr) if (entry.material == nullptr)
@ -760,9 +796,9 @@ namespace Components
if (material == nullptr || material->techniqueSet == nullptr || material->techniqueSet->name == nullptr) if (material == nullptr || material->techniqueSet == nullptr || material->techniqueSet->name == nullptr)
return false; return false;
if(strcmp(material->techniqueSet->name, "2d") != 0) if (std::strcmp(material->techniqueSet->name, "2d") != 0)
{ {
Logger::Print("^1Fonticon material '{}' does not have 2d techset!\n", material->info.name); Logger::PrintError(Game::CON_CHANNEL_ERROR, "Fonticon material '{}' does not have 2d techset!\n", material->info.name);
material = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MATERIAL, "default").material; material = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_MATERIAL, "default").material;
} }
@ -778,7 +814,10 @@ namespace Components
{ {
const auto* colorMap = GetFontIconColorMap(fontIcon.material); const auto* colorMap = GetFontIconColorMap(fontIcon.material);
if (colorMap == nullptr) if (colorMap == nullptr)
return 0; {
return 0.0f;
}
const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f; const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f;
auto colWidth = static_cast<float>(colorMap->width); auto colWidth = static_cast<float>(colorMap->width);
auto colHeight = static_cast<float>(colorMap->height); auto colHeight = static_cast<float>(colorMap->height);
@ -793,7 +832,10 @@ namespace Components
{ {
const auto* colorMap = GetFontIconColorMap(fontIcon.material); const auto* colorMap = GetFontIconColorMap(fontIcon.material);
if (colorMap == nullptr) if (colorMap == nullptr)
return 0; {
return 0.0f;
}
const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f; const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f;
auto colWidth = static_cast<float>(colorMap->width); auto colWidth = static_cast<float>(colorMap->width);
auto colHeight = static_cast<float>(colorMap->height); auto colHeight = static_cast<float>(colorMap->height);
@ -808,7 +850,9 @@ namespace Components
{ {
const auto* colorMap = GetFontIconColorMap(fontIcon.material); const auto* colorMap = GetFontIconColorMap(fontIcon.material);
if (colorMap == nullptr) if (colorMap == nullptr)
return 0; {
return 0.0f;
}
float s0, t0, s1, t1; float s0, t0, s1, t1;
if (fontIcon.flipHorizontal) if (fontIcon.flipHorizontal)
@ -831,6 +875,7 @@ namespace Components
t0 = 0.0f; t0 = 0.0f;
t1 = 1.0f; t1 = 1.0f;
} }
Game::Material_Process2DTextureCoordsForAtlasing(fontIcon.material, &s0, &s1, &t0, &t1); Game::Material_Process2DTextureCoordsForAtlasing(fontIcon.material, &s0, &s1, &t0, &t1);
const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f; const auto sizeMultiplier = fontIcon.big ? 1.5f : 1.0f;
@ -868,23 +913,30 @@ namespace Components
s1 = 0.0; s1 = 0.0;
t1 = 1.0; t1 = 1.0;
} }
text++;
++text;
if (*text == 0) if (*text == 0)
return 0; {
return 0.0f;
}
const auto v12 = font->pixelHeight * (*text - 16) + 16; const auto v12 = font->pixelHeight * (*text - 16) + 16;
const auto w = static_cast<float>((((v12 >> 24) & 0x1F) + v12) >> 5) * xScale; const auto w = static_cast<float>((((v12 >> 24) & 0x1F) + v12) >> 5) * xScale;
text++; ++text;
if (*text == 0) if (*text == 0)
return 0; {
return 0.0f;
}
const auto h = static_cast<float>((font->pixelHeight * (*text - 16) + 16) >> 5) * yScale; const auto h = static_cast<float>((font->pixelHeight * (*text - 16) + 16) >> 5) * yScale;
text++; ++text;
if (*text == 0) if (*text == 0)
return 0; {
return 0.0f;
}
const auto materialNameLen = static_cast<uint8_t>(*text); const auto materialNameLen = static_cast<uint8_t>(*text);
text++; text++;
@ -892,7 +944,9 @@ namespace Components
for (auto i = 0u; i < materialNameLen; i++) for (auto i = 0u; i < materialNameLen; i++)
{ {
if (text[i] == 0) if (text[i] == 0)
return 0; {
return 0.0f;
}
} }
const std::string materialName(text, materialNameLen); const std::string materialName(text, materialNameLen);
@ -1220,11 +1274,15 @@ namespace Components
lineWidth += w; lineWidth += w;
if (lineWidth > maxWidth) if (lineWidth > maxWidth)
{
maxWidth = lineWidth; maxWidth = lineWidth;
}
text += 4; text += 4;
for (auto currentLength = 0; currentLength < materialNameLength && *text; currentLength++) for (auto currentLength = 0; currentLength < materialNameLength && *text; currentLength++)
text++; {
++text;
}
continue; continue;
} }
} }
@ -1237,7 +1295,9 @@ namespace Components
{ {
lineWidth += static_cast<int>(GetFontIconWidth(fontIconInfo, font, 1.0f)); lineWidth += static_cast<int>(GetFontIconWidth(fontIconInfo, font, 1.0f));
if (lineWidth > maxWidth) if (lineWidth > maxWidth)
{
maxWidth = lineWidth; maxWidth = lineWidth;
}
text = fontIconEnd; text = fontIconEnd;
continue; continue;
} }
@ -1245,7 +1305,9 @@ namespace Components
lineWidth += R_GetCharacterGlyph(font, letter)->dx; lineWidth += R_GetCharacterGlyph(font, letter)->dx;
if (lineWidth > maxWidth) if (lineWidth > maxWidth)
{
maxWidth = lineWidth; maxWidth = lineWidth;
}
count++; count++;
} }
} }
@ -1289,15 +1351,15 @@ namespace Components
{ {
char buffer[1024]{}; // 1024 is a lucky number in the engine char buffer[1024]{}; // 1024 is a lucky number in the engine
StripColors(in.data(), buffer, sizeof(buffer)); StripColors(in.data(), buffer, sizeof(buffer));
return std::string(buffer); return {buffer};
} }
void TextRenderer::StripMaterialTextIcons(const char* in, char* out, std::size_t max) void TextRenderer::StripMaterialTextIcons(const char* in, char* out, std::size_t max)
{ {
if (!in || !out) return; if (!in || !out) return;
max--; --max;
size_t current = 0; std::size_t current = 0;
while (*in != 0 && current < max) while (*in != 0 && current < max)
{ {
if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02')) if (*in == '^' && (in[1] == '\x01' || in[1] == '\x02'))
@ -1305,18 +1367,25 @@ namespace Components
in += 2; in += 2;
if (*in) // width if (*in) // width
in++; {
++in;
}
if (*in) // height if (*in) // height
in++; {
++in;
}
if (*in) // material name length + material name characters if (*in) // material name length + material name characters
{ {
const auto materialNameLength = *in; const auto materialNameLength = *in;
in++; ++in;
for (auto i = 0; i < materialNameLength; i++) for (auto i = 0; i < materialNameLength; i++)
{ {
if (*in) if (*in)
in++; {
++in;
}
} }
} }
} }
@ -1334,16 +1403,16 @@ namespace Components
std::string TextRenderer::StripMaterialTextIcons(const std::string& in) std::string TextRenderer::StripMaterialTextIcons(const std::string& in)
{ {
char buffer[1000] = { 0 }; // Should be more than enough char buffer[1000]{}; // Should be more than enough
StripAllTextIcons(in.data(), buffer, sizeof(buffer)); StripAllTextIcons(in.data(), buffer, sizeof(buffer));
return std::string(buffer); return {buffer};
} }
void TextRenderer::StripAllTextIcons(const char* in, char* out, std::size_t max) void TextRenderer::StripAllTextIcons(const char* in, char* out, std::size_t max)
{ {
if (!in || !out) return; if (!in || !out) return;
max--; --max;
size_t current = 0; size_t current = 0;
while (*in != 0 && current < max) while (*in != 0 && current < max)
{ {
@ -1392,15 +1461,17 @@ namespace Components
std::string TextRenderer::StripAllTextIcons(const std::string& in) std::string TextRenderer::StripAllTextIcons(const std::string& in)
{ {
char buffer[1000] = { 0 }; // Should be more than enough char buffer[1000]{}; // Should be more than enough
StripAllTextIcons(in.data(), buffer, sizeof(buffer)); StripAllTextIcons(in.data(), buffer, sizeof(buffer));
return std::string(buffer); return {buffer};
} }
int TextRenderer::SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field) int TextRenderer::SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field)
{ {
if (!string) if (!string)
{
return 0; return 0;
}
const auto cursorPos = field->cursor; const auto cursorPos = field->cursor;
auto len = 0; auto len = 0;
@ -1481,7 +1552,8 @@ namespace Components
expandedColor[3] = static_cast<float>(colorblindEnemy[3]) / 255.0f; expandedColor[3] = static_cast<float>(colorblindEnemy[3]) / 255.0f;
return false; return false;
} }
else if (str == "g_TeamColor_MyTeam")
if (str == "g_TeamColor_MyTeam")
{ {
// Dvar_GetUnpackedColor // Dvar_GetUnpackedColor
const auto* colorblindAlly = g_ColorBlind_MyTeam->current.color; const auto* colorblindAlly = g_ColorBlind_MyTeam->current.color;
@ -1552,7 +1624,7 @@ namespace Components
if (fontIconTable->columnCount < 2 || fontIconTable->rowCount <= 0) if (fontIconTable->columnCount < 2 || fontIconTable->rowCount <= 0)
{ {
Logger::Print("^1Failed to load font icon table\n"); Logger::Error(Game::ERR_FATAL, "\x15" "Failed to load mp/fonticons.csv");
return; return;
} }

View File

@ -42,6 +42,7 @@ namespace Components
class TextRenderer : public Component class TextRenderer : public Component
{ {
public:
static constexpr auto STRING_BUFFER_SIZE_BIG = 1024; static constexpr auto STRING_BUFFER_SIZE_BIG = 1024;
static constexpr auto STRING_BUFFER_SIZE_SMALL = 128; static constexpr auto STRING_BUFFER_SIZE_SMALL = 128;
@ -88,7 +89,6 @@ namespace Components
1.0f 1.0f
}; };
public:
static constexpr char FONT_ICON_SEPARATOR_CHARACTER = ':'; static constexpr char FONT_ICON_SEPARATOR_CHARACTER = ':';
static constexpr char FONT_ICON_MODIFIER_SEPARATOR_CHARACTER = '+'; static constexpr char FONT_ICON_MODIFIER_SEPARATOR_CHARACTER = '+';
static constexpr char FONT_ICON_MODIFIER_FLIP_HORIZONTALLY = 'h'; static constexpr char FONT_ICON_MODIFIER_FLIP_HORIZONTALLY = 'h';
@ -139,7 +139,7 @@ namespace Components
class BufferedLocalizedString class BufferedLocalizedString
{ {
public: public:
BufferedLocalizedString(const char* reference, size_t bufferSize); BufferedLocalizedString(const char* reference, std::size_t bufferSize);
void Cache(); void Cache();
const char* Format(const char* value); const char* Format(const char* value);
const char* GetString() const; const char* GetString() const;
@ -148,7 +148,7 @@ namespace Components
private: private:
const char* stringReference; const char* stringReference;
std::unique_ptr<char[]> stringBuffer; std::unique_ptr<char[]> stringBuffer;
size_t stringBufferSize; std::size_t stringBufferSize;
int stringWidth[FONT_ICON_ACI_COUNT]; int stringWidth[FONT_ICON_ACI_COUNT];
}; };