From 70bc28ee7b58ef60558f83e4812c78fb4d731c84 Mon Sep 17 00:00:00 2001 From: Jan Date: Wed, 22 Sep 2021 22:50:22 +0200 Subject: [PATCH] Rewrite fonticon localized string caching to fix strings being reallocated --- src/Components/Modules/TextRenderer.cpp | 158 ++++++++++++---- src/Components/Modules/TextRenderer.hpp | 236 +++++++++++------------- 2 files changed, 223 insertions(+), 171 deletions(-) diff --git a/src/Components/Modules/TextRenderer.cpp b/src/Components/Modules/TextRenderer.cpp index 595a1944..599244d8 100644 --- a/src/Components/Modules/TextRenderer.cpp +++ b/src/Components/Modules/TextRenderer.cpp @@ -40,17 +40,16 @@ namespace Components }; unsigned(*TextRenderer::currentColorTable)[TEXT_COLOR_COUNT]; - TextRenderer::FontIconAutocompleteContext TextRenderer::autocompleteContextArray[FONT_ICON_ACI_COUNT]{}; + TextRenderer::FontIconAutocompleteContext TextRenderer::autocompleteContextArray[FONT_ICON_ACI_COUNT]; std::map TextRenderer::fontIconLookup; std::vector TextRenderer::fontIconList; - - TextRenderer::FormattedStringBuffer TextRenderer::stringSearchStartWith; - TextRenderer::FormattedStringBuffer TextRenderer::stringHintAutoComplete; - TextRenderer::FormattedStringBuffer TextRenderer::stringHintModifier; - TextRenderer::FormattedStringBuffer TextRenderer::stringListHeader; - TextRenderer::FormattedStringBuffer TextRenderer::stringListFlipHorizontal; - TextRenderer::FormattedStringBuffer TextRenderer::stringListFlipVertical; - TextRenderer::FormattedStringBuffer TextRenderer::stringListBig; + + TextRenderer::BufferedLocalizedString TextRenderer::stringHintAutoComplete(REFERENCE_HINT_AUTO_COMPLETE, STRING_BUFFER_SIZE_SMALL); + TextRenderer::BufferedLocalizedString TextRenderer::stringHintModifier(REFERENCE_HINT_MODIFIER, STRING_BUFFER_SIZE_SMALL); + TextRenderer::BufferedLocalizedString TextRenderer::stringListHeader(REFERENCE_MODIFIER_LIST_HEADER, STRING_BUFFER_SIZE_SMALL); + TextRenderer::BufferedLocalizedString TextRenderer::stringListFlipHorizontal(REFERENCE_MODIFIER_LIST_FLIP_HORIZONTAL, STRING_BUFFER_SIZE_SMALL); + TextRenderer::BufferedLocalizedString TextRenderer::stringListFlipVertical(REFERENCE_MODIFIER_LIST_FLIP_VERTICAL, STRING_BUFFER_SIZE_SMALL); + TextRenderer::BufferedLocalizedString TextRenderer::stringListBig(REFERENCE_MODIFIER_LIST_BIG, STRING_BUFFER_SIZE_SMALL); Dvar::Var TextRenderer::cg_newColors; Dvar::Var TextRenderer::cg_fontIconAutocomplete; @@ -61,6 +60,77 @@ namespace Components Game::dvar_t* TextRenderer::g_ColorBlind_EnemyTeam; Game::dvar_t** TextRenderer::con_inputBoxColor = reinterpret_cast(0x9FD4BC); + TextRenderer::BufferedLocalizedString::BufferedLocalizedString(const char* reference, const size_t bufferSize) + : stringReference(reference), + stringBuffer(std::make_unique(bufferSize)), + stringBufferSize(bufferSize), + stringWidth{-1} + { + + } + + void TextRenderer::BufferedLocalizedString::Cache() + { + const auto* formattingString = Game::UI_SafeTranslateString(stringReference); + + if (formattingString != nullptr) + { + strncpy(stringBuffer.get(), formattingString, stringBufferSize); + for (auto& width : stringWidth) + width = -1; + } + } + + const char* TextRenderer::BufferedLocalizedString::Format(const char* value) + { + const auto* formattingString = Game::UI_SafeTranslateString(stringReference); + if (formattingString == nullptr) + { + stringBuffer[0] = '\0'; + return stringBuffer.get(); + } + + Game::ConversionArguments conversionArguments{}; + conversionArguments.args[conversionArguments.argCount++] = value; + Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer.get(), stringBufferSize); + + for (auto& width : stringWidth) + width = -1; + return stringBuffer.get(); + } + + const char* TextRenderer::BufferedLocalizedString::GetString() const + { + return stringBuffer.get(); + } + + int TextRenderer::BufferedLocalizedString::GetWidth(const FontIconAutocompleteInstance autocompleteInstance, Game::Font_s* font) + { + assert(autocompleteInstance < FONT_ICON_ACI_COUNT); + if (stringWidth[autocompleteInstance] < 0) + stringWidth[autocompleteInstance] = Game::R_TextWidth(GetString(), std::numeric_limits::max(), font); + + return stringWidth[autocompleteInstance]; + } + + TextRenderer::FontIconAutocompleteContext::FontIconAutocompleteContext() + : autocompleteActive(false), + inModifiers(false), + userClosed(false), + lastHash(0u), + results{}, + resultCount(0u), + hasMoreResults(false), + resultOffset(0u), + lastResultOffset(0u), + selectedOffset(0u), + maxFontIconWidth(0.0f), + maxMaterialNameWidth(0.0f), + stringSearchStartWith(REFERENCE_SEARCH_START_WITH, STRING_BUFFER_SIZE_BIG) + { + + } + unsigned TextRenderer::HsvToRgb(HsvColor hsv) { unsigned rgb; @@ -199,7 +269,7 @@ namespace Components } } - void TextRenderer::UpdateAutocompleteContext(TextRenderer::FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale) + void TextRenderer::UpdateAutocompleteContext(FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale) { int fontIconStart = -1; auto inModifiers = false; @@ -283,18 +353,24 @@ namespace Components context.lastHash = currentFontIconHash; } - // Update results for query and scroll + // Update results for query and scroll and update search string context.lastQuery = std::string(&edit->buffer[fontIconStart], edit->cursor - fontIconStart); - stringSearchStartWith.Format(context.lastQuery.c_str()); + context.stringSearchStartWith.Format(context.lastQuery.c_str()); UpdateAutocompleteContextResults(context, font, textXScale); } - void TextRenderer::DrawAutocompleteModifiers(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, float textXScale, float textYScale) + void TextRenderer::DrawAutocompleteModifiers(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale) { - const auto textWidth = std::max(std::max(std::max(stringListHeader.GetWidth(font), stringListFlipHorizontal.GetWidth(font)), - stringListFlipVertical.GetWidth(font)), - stringListBig.GetWidth(font)); - const auto boxWidth = static_cast(textWidth) * textXScale; + assert(instance < FONT_ICON_ACI_COUNT); + const auto& context = autocompleteContextArray[instance]; + + // Check which is the longest string to be able to calculate how big the box needs to be + const auto longestStringLength = std::max(std::max(std::max(stringListHeader.GetWidth(instance, font), stringListFlipHorizontal.GetWidth(instance, font)), + stringListFlipVertical.GetWidth(instance, font)), + stringListBig.GetWidth(instance, font)); + + // Draw background box + const auto boxWidth = static_cast(longestStringLength) * textXScale; constexpr auto totalLines = 4u; const auto lineHeight = static_cast(font->pixelHeight) * textYScale; DrawAutocompleteBox(context, @@ -306,8 +382,11 @@ namespace Components auto currentY = y + lineHeight; + // Draw header line: "Following modifiers are available:" Game::R_AddCmdDrawText(stringListHeader.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); currentY += lineHeight; + + // Draw modifier hints Game::R_AddCmdDrawText(stringListFlipHorizontal.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); currentY += lineHeight; Game::R_AddCmdDrawText(stringListFlipVertical.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); @@ -315,18 +394,23 @@ namespace Components Game::R_AddCmdDrawText(stringListBig.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); } - void TextRenderer::DrawAutocompleteResults(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale) + void TextRenderer::DrawAutocompleteResults(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale) { + assert(instance < FONT_ICON_ACI_COUNT); + auto& context = autocompleteContextArray[instance]; + const auto hintEnabled = cg_fontIconAutocompleteHint.get(); - auto longestStringLength = stringSearchStartWith.GetWidth(font); + // Check which is the longest string to be able to calculate how big the box needs to be + auto longestStringLength = context.stringSearchStartWith.GetWidth(instance, font); if(hintEnabled) - longestStringLength = std::max(std::max(longestStringLength, stringHintAutoComplete.GetWidth(font)), stringHintModifier.GetWidth(font)); + longestStringLength = std::max(std::max(longestStringLength, stringHintAutoComplete.GetWidth(instance, font)), stringHintModifier.GetWidth(instance, font)); const auto colSpacing = FONT_ICON_AUTOCOMPLETE_COL_SPACING * textXScale; const auto boxWidth = std::max(context.maxFontIconWidth + context.maxMaterialNameWidth + colSpacing, static_cast(longestStringLength) * textXScale); const auto lineHeight = static_cast(font->pixelHeight) * textYScale; + // Draw background box const auto totalLines = 1u + context.resultCount + (hintEnabled ? 2u : 0u); const auto arrowPadding = context.resultOffset > 0 || context.hasMoreResults ? FONT_ICON_AUTOCOMPLETE_ARROW_SIZE : 0.0f; DrawAutocompleteBox(context, @@ -335,11 +419,13 @@ namespace Components boxWidth + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2 + arrowPadding, static_cast(totalLines) * lineHeight + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2, (*con_inputBoxColor)->current.vector); - + + // Draw header line "Search results for: xyz" auto currentY = y + lineHeight; - Game::R_AddCmdDrawText(stringSearchStartWith.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); + Game::R_AddCmdDrawText(context.stringSearchStartWith.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0); currentY += lineHeight; + // Draw search results const auto selectedIndex = context.selectedOffset - context.resultOffset; for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++) { @@ -353,6 +439,7 @@ namespace Components currentY += lineHeight; } + // Draw extra hint if enabled if(hintEnabled) { Game::R_AddCmdDrawText(stringHintAutoComplete.GetString(), std::numeric_limits::max(), font, x, currentY, textXScale, textYScale, 0.0, HINT_COLOR, 0); @@ -361,12 +448,15 @@ namespace Components } } - void TextRenderer::DrawAutocomplete(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale) + void TextRenderer::DrawAutocomplete(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale) { + assert(instance < FONT_ICON_ACI_COUNT); + const auto& context = autocompleteContextArray[instance]; + if (context.inModifiers) - DrawAutocompleteModifiers(context, x, y, font, textXScale, textYScale); + DrawAutocompleteModifiers(instance, x, y, font, textXScale, textYScale); else - DrawAutocompleteResults(context, x, y, font, textXScale, textYScale); + DrawAutocompleteResults(instance, x, y, font, textXScale, textYScale); } void TextRenderer::Con_DrawInput_Hk(const int localClientNum) @@ -386,7 +476,7 @@ namespace Components { const auto x = Game::conDrawInputGlob->leftX; const auto y = Game::con_screenMin[1] + 6.0f + static_cast(2 * Game::R_TextHeight(Game::cls->consoleFont)); - DrawAutocomplete(autocompleteContext, x, y, Game::cls->consoleFont, 1.0f, 1.0f); + DrawAutocomplete(FONT_ICON_ACI_CONSOLE, x, y, Game::cls->consoleFont, 1.0f, 1.0f); } } @@ -415,7 +505,7 @@ namespace Components UpdateAutocompleteContext(autocompleteContext, edit, font, ww); if (autocompleteContext.autocompleteActive) { - DrawAutocomplete(autocompleteContext, std::floor(xx), std::floor(yy), font, ww, hh); + DrawAutocomplete(FONT_ICON_ACI_CHAT, std::floor(xx), std::floor(yy), font, ww, hh); } } @@ -1442,23 +1532,11 @@ namespace Components void TextRenderer::InitFontIconStrings() { - stringSearchStartWith.Load("FONT_ICON_SEARCH_START_WITH"); - - stringHintAutoComplete.Load("FONT_ICON_HINT_AUTO_COMPLETE"); stringHintAutoComplete.Format("TAB"); - - stringHintModifier.Load("FONT_ICON_HINT_MODIFIER"); stringHintModifier.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_SEPARATOR_CHARACTER)); - - stringListHeader.Load("FONT_ICON_MODIFIER_LIST_HEADER"); - - stringListFlipHorizontal.Load("FONT_ICON_MODIFIER_LIST_FLIP_HORIZONTAL"); + stringListHeader.Cache(); stringListFlipHorizontal.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_FLIP_HORIZONTALLY)); - - stringListFlipVertical.Load("FONT_ICON_MODIFIER_LIST_FLIP_VERTICAL"); stringListFlipVertical.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_FLIP_VERTICALLY)); - - stringListBig.Load("FONT_ICON_MODIFIER_LIST_BIG"); stringListBig.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_BIG)); } diff --git a/src/Components/Modules/TextRenderer.hpp b/src/Components/Modules/TextRenderer.hpp index 32676c7d..2ffe44f2 100644 --- a/src/Components/Modules/TextRenderer.hpp +++ b/src/Components/Modules/TextRenderer.hpp @@ -42,108 +42,16 @@ namespace Components class TextRenderer : public Component { - public: - enum FontIconAutocompleteInstance : unsigned - { - FONT_ICON_ACI_CONSOLE, - FONT_ICON_ACI_CHAT, + static constexpr auto STRING_BUFFER_SIZE_BIG = 1024; + static constexpr auto STRING_BUFFER_SIZE_SMALL = 128; - FONT_ICON_ACI_COUNT - }; - - private: - struct FontIconTableEntry - { - std::string iconName; - std::string materialName; - Game::Material* material; - }; - - struct HsvColor - { - unsigned char h; - unsigned char s; - unsigned char v; - }; - - class FontIconAutocompleteResult - { - public: - std::string fontIconName; - std::string materialName; - }; - - class FontIconAutocompleteContext - { - public: - static constexpr auto MAX_RESULTS = 10; - - bool autocompleteActive; - bool inModifiers; - bool userClosed; - unsigned int lastHash; - std::string lastQuery; - FontIconAutocompleteResult results[MAX_RESULTS]; - size_t resultCount; - bool hasMoreResults; - size_t resultOffset; - size_t lastResultOffset; - size_t selectedOffset; - float maxFontIconWidth; - float maxMaterialNameWidth; - }; - - template - class FormattedStringBuffer - { - public: - FormattedStringBuffer() - : formattingString(nullptr), - stringBuffer{0}, - stringWidth(-1) - { - } - - void Load(const char* reference) - { - formattingString = Game::UI_SafeTranslateString(reference); - } - - const char* Format(const char* value) - { - if (formattingString == nullptr) - return stringBuffer; - - Game::ConversionArguments conversionArguments{}; - conversionArguments.args[conversionArguments.argCount++] = value; - Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer, sizeof(stringBuffer)); - - stringWidth = -1; - return stringBuffer; - } - - const char* GetString() const - { - if(stringBuffer[0] != '\0') - return stringBuffer; - if(formattingString) - return formattingString; - return stringBuffer; - } - - int GetWidth(Game::Font_s* font) - { - if (stringWidth < 0) - stringWidth = Game::R_TextWidth(GetString(), std::numeric_limits::max(), font); - - return stringWidth; - } - - private: - const char* formattingString; - char stringBuffer[S]; - int stringWidth; - }; + static constexpr auto REFERENCE_SEARCH_START_WITH = "FONT_ICON_SEARCH_START_WITH"; + static constexpr auto REFERENCE_HINT_AUTO_COMPLETE = "FONT_ICON_HINT_AUTO_COMPLETE"; + static constexpr auto REFERENCE_HINT_MODIFIER = "FONT_ICON_HINT_MODIFIER"; + static constexpr auto REFERENCE_MODIFIER_LIST_HEADER = "FONT_ICON_MODIFIER_LIST_HEADER"; + static constexpr auto REFERENCE_MODIFIER_LIST_FLIP_HORIZONTAL = "FONT_ICON_MODIFIER_LIST_FLIP_HORIZONTAL"; + static constexpr auto REFERENCE_MODIFIER_LIST_FLIP_VERTICAL = "FONT_ICON_MODIFIER_LIST_FLIP_VERTICAL"; + static constexpr auto REFERENCE_MODIFIER_LIST_BIG = "FONT_ICON_MODIFIER_LIST_BIG"; static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6; static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041; @@ -180,6 +88,93 @@ namespace Components 1.0f }; + public: + static constexpr char FONT_ICON_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_VERTICALLY = 'v'; + static constexpr char FONT_ICON_MODIFIER_BIG = 'b'; + + static constexpr char COLOR_FIRST_CHAR = '0'; + static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1); + + enum FontIconAutocompleteInstance : unsigned + { + FONT_ICON_ACI_CONSOLE, + FONT_ICON_ACI_CHAT, + + FONT_ICON_ACI_COUNT + }; + + struct FontIconInfo + { + Game::Material* material; + bool flipHorizontal; + bool flipVertical; + bool big; + }; + + private: + struct FontIconTableEntry + { + std::string iconName; + std::string materialName; + Game::Material* material; + }; + + struct HsvColor + { + unsigned char h; + unsigned char s; + unsigned char v; + }; + + class FontIconAutocompleteResult + { + public: + std::string fontIconName; + std::string materialName; + }; + + class BufferedLocalizedString + { + public: + BufferedLocalizedString(const char* reference, size_t bufferSize); + void Cache(); + const char* Format(const char* value); + const char* GetString() const; + int GetWidth(FontIconAutocompleteInstance autocompleteInstance, Game::Font_s* font); + + private: + const char* stringReference; + std::unique_ptr stringBuffer; + size_t stringBufferSize; + int stringWidth[FONT_ICON_ACI_COUNT]; + }; + + class FontIconAutocompleteContext + { + public: + static constexpr auto MAX_RESULTS = 10; + + bool autocompleteActive; + bool inModifiers; + bool userClosed; + unsigned int lastHash; + std::string lastQuery; + FontIconAutocompleteResult results[MAX_RESULTS]; + size_t resultCount; + bool hasMoreResults; + size_t resultOffset; + size_t lastResultOffset; + size_t selectedOffset; + float maxFontIconWidth; + float maxMaterialNameWidth; + BufferedLocalizedString stringSearchStartWith; + + FontIconAutocompleteContext(); + }; + static unsigned colorTableDefault[TEXT_COLOR_COUNT]; static unsigned colorTableNew[TEXT_COLOR_COUNT]; static unsigned(*currentColorTable)[TEXT_COLOR_COUNT]; @@ -187,16 +182,12 @@ namespace Components static std::map fontIconLookup; static std::vector fontIconList; - static constexpr auto STRING_BUFFER_SIZE_BIG = 1024; - static constexpr auto STRING_BUFFER_SIZE_SMALL = 128; - static constexpr auto STRING_BUFFER_SIZE_NONE = 1; - static FormattedStringBuffer stringSearchStartWith; - static FormattedStringBuffer stringHintAutoComplete; - static FormattedStringBuffer stringHintModifier; - static FormattedStringBuffer stringListHeader; - static FormattedStringBuffer stringListFlipHorizontal; - static FormattedStringBuffer stringListFlipVertical; - static FormattedStringBuffer stringListBig; + static BufferedLocalizedString stringHintAutoComplete; + static BufferedLocalizedString stringHintModifier; + static BufferedLocalizedString stringListHeader; + static BufferedLocalizedString stringListFlipHorizontal; + static BufferedLocalizedString stringListFlipVertical; + static BufferedLocalizedString stringListBig; static Dvar::Var cg_newColors; static Dvar::Var cg_fontIconAutocomplete; @@ -208,23 +199,6 @@ namespace Components static Game::dvar_t** con_inputBoxColor; public: - static constexpr char FONT_ICON_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_VERTICALLY = 'v'; - static constexpr char FONT_ICON_MODIFIER_BIG = 'b'; - - static constexpr char COLOR_FIRST_CHAR = '0'; - static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1); - - struct FontIconInfo - { - Game::Material* material; - bool flipHorizontal; - bool flipVertical; - bool big; - }; - static void DrawText2D(const char* text, float x, float y, Game::Font_s* font, float xScale, float yScale, float sinAngle, float cosAngle, Game::GfxColor color, int maxLength, int renderFlags, int cursorPos, char cursorLetter, float padding, Game::GfxColor glowForcedColor, int fxBirthTime, int fxLetterTime, int fxDecayStartTime, int fxDecayDuration, Game::Material* fxMaterial, Game::Material* fxMaterialGlow); static int R_TextWidth_Hk(const char* text, int maxChars, Game::Font_s* font); static unsigned int ColorIndex(char index); @@ -247,9 +221,9 @@ namespace Components static unsigned HsvToRgb(HsvColor hsv); static void DrawAutocompleteBox(const FontIconAutocompleteContext& context, float x, float y, float w, float h, const float* color); - static void DrawAutocompleteModifiers(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale); - static void DrawAutocompleteResults(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale); - static void DrawAutocomplete(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale); + static void DrawAutocompleteModifiers(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale); + static void DrawAutocompleteResults(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale); + static void DrawAutocomplete(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale); static void UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font, float textXScale); static void UpdateAutocompleteContext(FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale); static void Field_Draw_Say(int localClientNum, Game::field_t* edit, int x, int y, int horzAlign, int vertAlign);