Add console fonticon autocomplete
This commit is contained in:
parent
4497b991be
commit
6e0586a335
@ -1,5 +1,10 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Game
|
||||
{
|
||||
float* con_screenMin = reinterpret_cast<float*>(0xA15F48);
|
||||
}
|
||||
|
||||
namespace Components
|
||||
{
|
||||
unsigned TextRenderer::colorTableDefault[TEXT_COLOR_COUNT]
|
||||
@ -35,12 +40,14 @@ namespace Components
|
||||
};
|
||||
|
||||
unsigned(*TextRenderer::currentColorTable)[TEXT_COLOR_COUNT];
|
||||
TextRenderer::FontIconAutocompleteContext TextRenderer::autocompleteContextArray[FONT_ICON_ACI_COUNT]{};
|
||||
|
||||
Dvar::Var TextRenderer::cg_newColors;
|
||||
Game::dvar_t* TextRenderer::sv_customTextColor;
|
||||
Dvar::Var TextRenderer::r_colorBlind;
|
||||
Game::dvar_t* TextRenderer::g_ColorBlind_MyTeam;
|
||||
Game::dvar_t* TextRenderer::g_ColorBlind_EnemyTeam;
|
||||
Game::dvar_t** TextRenderer::con_inputBoxColor = reinterpret_cast<Game::dvar_t**>(0x9FD4BC);
|
||||
|
||||
unsigned TextRenderer::HsvToRgb(HsvColor hsv)
|
||||
{
|
||||
@ -91,6 +98,155 @@ namespace Components
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void TextRenderer::DrawAutocompleteBox(const float x, const float y, const float w, const float h, const float* color)
|
||||
{
|
||||
const float borderColor[4]
|
||||
{
|
||||
color[0] * 0.5f,
|
||||
color[1] * 0.5f,
|
||||
color[2] * 0.5f,
|
||||
color[3]
|
||||
};
|
||||
|
||||
Game::R_AddCmdDrawStretchPic(x, y, w, h, 0.0, 0.0, 0.0, 0.0, color, Game::cls->whiteMaterial);
|
||||
Game::R_AddCmdDrawStretchPic(x, y, 2.0, h, 0.0, 0.0, 0.0, 0.0, borderColor, Game::cls->whiteMaterial);
|
||||
Game::R_AddCmdDrawStretchPic(x + w - 2.0f, y, 2.0, h, 0.0, 0.0, 0.0, 0.0, borderColor, Game::cls->whiteMaterial);
|
||||
Game::R_AddCmdDrawStretchPic(x, y, w, 2.0, 0.0, 0.0, 0.0, 0.0, borderColor, Game::cls->whiteMaterial);
|
||||
Game::R_AddCmdDrawStretchPic(x, y + h - 2.0f, w, 2.0, 0.0, 0.0, 0.0, 0.0, borderColor, Game::cls->whiteMaterial);
|
||||
}
|
||||
|
||||
void TextRenderer::UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font)
|
||||
{
|
||||
context.resultCount = 0;
|
||||
|
||||
const auto* techset2d = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_TECHNIQUE_SET, "2d").techniqueSet;
|
||||
|
||||
Game::DB_EnumXAssetEntries(Game::ASSET_TYPE_MATERIAL, [&context, techset2d](const Game::XAssetEntry* entry)
|
||||
{
|
||||
if (context.resultCount >= FontIconAutocompleteContext::MAX_RESULTS)
|
||||
return;
|
||||
|
||||
const auto* material = entry->asset.header.material;
|
||||
if(material->techniqueSet == techset2d && std::string(material->info.name).rfind(context.lastQuery, 0) == 0)
|
||||
{
|
||||
context.results[context.resultCount++] = {
|
||||
std::string(Utils::String::VA(":%s:", material->info.name)),
|
||||
std::string(material->info.name)
|
||||
};
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
context.maxFontIconWidth = 0;
|
||||
context.maxMaterialNameWidth = 0;
|
||||
for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++)
|
||||
{
|
||||
const auto& result = context.results[resultIndex];
|
||||
const auto fontIconWidth = static_cast<float>(Game::R_TextWidth(result.fontIconName.c_str(), INT_MAX, font));
|
||||
const auto materialNameWidth = static_cast<float>(Game::R_TextWidth(result.materialName.c_str(), INT_MAX, font));
|
||||
|
||||
if (fontIconWidth > context.maxFontIconWidth)
|
||||
context.maxFontIconWidth = fontIconWidth;
|
||||
if (materialNameWidth > context.maxMaterialNameWidth)
|
||||
context.maxMaterialNameWidth = materialNameWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer::UpdateAutocompleteContext(FontIconAutocompleteContext& context, Game::field_t* edit, Game::Font_s* font)
|
||||
{
|
||||
int fontIconStart = -1;
|
||||
for(auto i = edit->cursor - 1; i >= 0; i--)
|
||||
{
|
||||
const auto c = static_cast<unsigned char>(edit->buffer[i]);
|
||||
if (c == ':')
|
||||
{
|
||||
fontIconStart = i + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isspace(c))
|
||||
break;
|
||||
|
||||
if (c == '+')
|
||||
break;
|
||||
}
|
||||
|
||||
if(fontIconStart < 0 || fontIconStart == edit->cursor)
|
||||
{
|
||||
context.autocompleteActive = false;
|
||||
context.lastHash = 0;
|
||||
context.resultCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
context.autocompleteActive = true;
|
||||
const auto currentFontIconHash = Game::R_HashString(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
|
||||
if (currentFontIconHash == context.lastHash && context.lastResultOffset == context.resultOffset)
|
||||
return;
|
||||
|
||||
if(currentFontIconHash != context.lastHash)
|
||||
{
|
||||
context.resultOffset = 0;
|
||||
context.lastHash = currentFontIconHash;
|
||||
}
|
||||
|
||||
context.lastQuery = std::string(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
|
||||
UpdateAutocompleteContextResults(context, font);
|
||||
}
|
||||
|
||||
void TextRenderer::DrawAutocomplete(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font)
|
||||
{
|
||||
const auto* text = Utils::String::VA("Font icons starting with ^2%s^7:", context.lastQuery.c_str());
|
||||
const auto boxWidth = std::max(context.maxFontIconWidth + context.maxMaterialNameWidth + FONT_ICON_AUTOCOMPLETE_COL_SPACING,
|
||||
static_cast<float>(Game::R_TextWidth(text, INT_MAX, font)));
|
||||
|
||||
const auto totalLines = 1u + context.resultCount;
|
||||
DrawAutocompleteBox(x - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
||||
y - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
||||
boxWidth + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
||||
static_cast<float>(font->pixelHeight * totalLines) + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
||||
(*con_inputBoxColor)->current.vector);
|
||||
|
||||
const float textColor[4]
|
||||
{
|
||||
1.0f,
|
||||
1.0f,
|
||||
0.8f,
|
||||
1.0f
|
||||
};
|
||||
|
||||
auto currentY = y + static_cast<float>(font->pixelHeight);
|
||||
Game::R_AddCmdDrawText(text, INT_MAX, font, x, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
||||
currentY += static_cast<float>(font->pixelHeight);
|
||||
|
||||
for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++)
|
||||
{
|
||||
const auto& result = context.results[resultIndex];
|
||||
Game::R_AddCmdDrawText(result.fontIconName.c_str(), INT_MAX, font, x, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
||||
Game::R_AddCmdDrawText(result.materialName.c_str(), INT_MAX, font, x + context.maxFontIconWidth + FONT_ICON_AUTOCOMPLETE_COL_SPACING, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
||||
currentY += static_cast<float>(font->pixelHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer::Con_DrawInput_Hk(const int localClientNum)
|
||||
{
|
||||
// Call original function
|
||||
Utils::Hook::Call<void(int)>(0x5A4480)(localClientNum);
|
||||
|
||||
auto& autocompleteContext = autocompleteContextArray[FONT_ICON_ACI_CONSOLE];
|
||||
UpdateAutocompleteContext(autocompleteContext, Game::g_consoleField, Game::cls->consoleFont);
|
||||
if (autocompleteContext.autocompleteActive)
|
||||
{
|
||||
const auto x = Game::conDrawInputGlob->leftX;
|
||||
const auto y = Game::con_screenMin[1] + 6.0f + static_cast<float>(2 * Game::R_TextHeight(Game::cls->consoleFont));
|
||||
DrawAutocomplete(autocompleteContext, x, y, Game::cls->consoleFont);
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer::Field_Draw_Say(const int localClientNum, Game::field_t* edit, const int x, const int y, const int horzAlign, const int vertAlign)
|
||||
{
|
||||
Game::Field_Draw(localClientNum, edit, x, y, horzAlign, vertAlign);
|
||||
}
|
||||
|
||||
float TextRenderer::GetMonospaceWidth(Game::Font_s* font, int rendererFlags)
|
||||
{
|
||||
if(rendererFlags & Game::TEXT_RENDERFLAG_FORCEMONOSPACE)
|
||||
@ -941,6 +1097,13 @@ namespace Components
|
||||
// Consider the cursor being inside the color escape sequence when getting the print length for a field
|
||||
Utils::Hook(0x488CBD, Field_AdjustScroll_PrintLen_Stub, HOOK_CALL).install()->quick();
|
||||
|
||||
// Draw fonticon autocompletion for say field
|
||||
Utils::Hook(0x4CA1BD, Field_Draw_Say, HOOK_CALL).install()->quick();
|
||||
|
||||
// Draw fonticon autocompletion for console field
|
||||
Utils::Hook(0x5A50A5, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5A50BB, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
||||
|
||||
PatchColorLimit(COLOR_LAST_CHAR);
|
||||
}
|
||||
}
|
@ -56,10 +56,43 @@ namespace Components
|
||||
unsigned char v;
|
||||
};
|
||||
|
||||
enum FontIconAutocompleteInstance
|
||||
{
|
||||
FONT_ICON_ACI_CONSOLE,
|
||||
FONT_ICON_ACI_CHAT,
|
||||
|
||||
FONT_ICON_ACI_COUNT
|
||||
};
|
||||
|
||||
class FontIconAutocompleteResult
|
||||
{
|
||||
public:
|
||||
std::string fontIconName;
|
||||
std::string materialName;
|
||||
};
|
||||
|
||||
class FontIconAutocompleteContext
|
||||
{
|
||||
public:
|
||||
static constexpr auto MAX_RESULTS = 10;
|
||||
|
||||
bool autocompleteActive;
|
||||
unsigned int lastHash;
|
||||
std::string lastQuery;
|
||||
FontIconAutocompleteResult results[MAX_RESULTS];
|
||||
size_t resultCount;
|
||||
size_t resultOffset;
|
||||
size_t lastResultOffset;
|
||||
float maxFontIconWidth;
|
||||
float maxMaterialNameWidth;
|
||||
};
|
||||
|
||||
static constexpr char COLOR_FIRST_CHAR = '0';
|
||||
static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1);
|
||||
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
||||
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
||||
static constexpr auto FONT_ICON_AUTOCOMPLETE_BOX_PADDING = 6.0f;
|
||||
static constexpr auto FONT_ICON_AUTOCOMPLETE_COL_SPACING = 12.0f;
|
||||
static constexpr float MY_OFFSETS[4][2]
|
||||
{
|
||||
{-1.0f, -1.0f},
|
||||
@ -71,12 +104,14 @@ namespace Components
|
||||
static unsigned colorTableDefault[TEXT_COLOR_COUNT];
|
||||
static unsigned colorTableNew[TEXT_COLOR_COUNT];
|
||||
static unsigned(*currentColorTable)[TEXT_COLOR_COUNT];
|
||||
static FontIconAutocompleteContext autocompleteContextArray[FONT_ICON_ACI_COUNT];
|
||||
|
||||
static Dvar::Var cg_newColors;
|
||||
static Game::dvar_t* sv_customTextColor;
|
||||
static Dvar::Var r_colorBlind;
|
||||
static Game::dvar_t* g_ColorBlind_MyTeam;
|
||||
static Game::dvar_t* g_ColorBlind_EnemyTeam;
|
||||
static Game::dvar_t** con_inputBoxColor;
|
||||
|
||||
public:
|
||||
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);
|
||||
@ -94,6 +129,13 @@ namespace Components
|
||||
private:
|
||||
static unsigned HsvToRgb(HsvColor hsv);
|
||||
|
||||
static void DrawAutocompleteBox(float x, float y, float w, float h, const float* color);
|
||||
static void DrawAutocomplete(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font);
|
||||
static void UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font);
|
||||
static void UpdateAutocompleteContext(FontIconAutocompleteContext& context, Game::field_t* edit, Game::Font_s* font);
|
||||
static void Field_Draw_Say(int localClientNum, Game::field_t* edit, int x, int y, int horzAlign, int vertAlign);
|
||||
static void Con_DrawInput_Hk(int localClientNum);
|
||||
|
||||
static int SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field);
|
||||
static void Field_AdjustScroll_PrintLen_Stub();
|
||||
|
||||
|
@ -339,6 +339,8 @@ namespace Game
|
||||
RandWithSeed_t RandWithSeed = RandWithSeed_t(0x495580);
|
||||
GetDecayingLetterInfo_t GetDecayingLetterInfo = GetDecayingLetterInfo_t(0x5351C0);
|
||||
|
||||
Field_Draw_t Field_Draw = Field_Draw_t(0x4F5B40);
|
||||
|
||||
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
||||
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
||||
|
||||
@ -429,6 +431,11 @@ namespace Game
|
||||
|
||||
GfxScene* scene = reinterpret_cast<GfxScene*>(0x6944914);
|
||||
|
||||
ConDrawInputGlob* conDrawInputGlob = reinterpret_cast<ConDrawInputGlob*>(0x9FD6F8);
|
||||
field_t* g_consoleField = reinterpret_cast<field_t*>(0xA1B6B0);
|
||||
|
||||
clientStatic_t* cls = reinterpret_cast<clientStatic_t*>(0xA7FE90);
|
||||
|
||||
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||
{
|
||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||
@ -550,37 +557,32 @@ namespace Game
|
||||
|
||||
while (lock && *reinterpret_cast<volatile long*>(0x16B8A58)) std::this_thread::sleep_for(1ms);
|
||||
|
||||
unsigned int index = 0;
|
||||
do
|
||||
const auto pool = Components::Maps::GetAssetEntryPool();
|
||||
for(auto hash = 0; hash < 37000; hash++)
|
||||
{
|
||||
unsigned short hashIndex = db_hashTable[index];
|
||||
if (hashIndex)
|
||||
auto hashIndex = db_hashTable[hash];
|
||||
while(hashIndex)
|
||||
{
|
||||
do
|
||||
auto* assetEntry = &pool[hashIndex];
|
||||
|
||||
if(assetEntry->asset.type == type)
|
||||
{
|
||||
XAssetEntry* asset = &Components::Maps::GetAssetEntryPool()[hashIndex];
|
||||
hashIndex = asset->nextHash;
|
||||
if (asset->asset.type == type)
|
||||
callback(assetEntry);
|
||||
if (overrides)
|
||||
{
|
||||
callback(asset);
|
||||
if (overrides)
|
||||
auto overrideIndex = assetEntry->nextOverride;
|
||||
while (overrideIndex)
|
||||
{
|
||||
unsigned short overrideIndex = asset->nextOverride;
|
||||
if (asset->nextOverride)
|
||||
{
|
||||
do
|
||||
{
|
||||
asset = &Components::Maps::GetAssetEntryPool()[overrideIndex];
|
||||
callback(asset);
|
||||
overrideIndex = asset->nextOverride;
|
||||
} while (overrideIndex);
|
||||
}
|
||||
auto* overrideEntry = &pool[overrideIndex];
|
||||
callback(overrideEntry);
|
||||
overrideIndex = overrideEntry->nextOverride;
|
||||
}
|
||||
}
|
||||
} while (hashIndex);
|
||||
}
|
||||
|
||||
hashIndex = assetEntry->nextHash;
|
||||
}
|
||||
++index;
|
||||
} while (index < 74000);
|
||||
}
|
||||
|
||||
if(lock) InterlockedDecrement(lockVar);
|
||||
}
|
||||
@ -609,6 +611,20 @@ namespace Game
|
||||
return hash;
|
||||
}
|
||||
|
||||
unsigned int R_HashString(const char* string, size_t maxLen)
|
||||
{
|
||||
unsigned int hash = 0;
|
||||
|
||||
while (*string && maxLen > 0)
|
||||
{
|
||||
hash = (*string | 0x20) ^ (33 * hash);
|
||||
++string;
|
||||
maxLen--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
void SV_KickClientError(client_t* client, const std::string& reason)
|
||||
{
|
||||
if (client->state < 5)
|
||||
|
@ -788,6 +788,9 @@ namespace Game
|
||||
|
||||
typedef void(__cdecl* GetDecayingLetterInfo_t)(unsigned int letter, int* randSeed, int decayTimeElapsed, int fxBirthTime, int fxDecayDuration, unsigned __int8 alpha, bool* resultSkipDrawing, char* resultAlpha, unsigned int* resultLetter, bool* resultDrawExtraFxChar);
|
||||
extern GetDecayingLetterInfo_t GetDecayingLetterInfo;
|
||||
|
||||
typedef void(__cdecl * Field_Draw_t)(int localClientNum, field_t* edit, int x, int y, int horzAlign, int vertAlign);
|
||||
extern Field_Draw_t Field_Draw;
|
||||
|
||||
extern XAssetHeader* DB_XAssetPool;
|
||||
extern unsigned int* g_poolSize;
|
||||
@ -878,6 +881,11 @@ namespace Game
|
||||
|
||||
extern GfxScene* scene;
|
||||
|
||||
extern ConDrawInputGlob* conDrawInputGlob;
|
||||
extern field_t* g_consoleField;
|
||||
|
||||
extern clientStatic_t* cls;
|
||||
|
||||
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
||||
void Menu_FreeItemMemory(Game::itemDef_s* item);
|
||||
const char* TableLookup(StringTable* stringtable, int row, int column);
|
||||
@ -898,6 +906,7 @@ namespace Game
|
||||
void ShowMessageBox(const std::string& message, const std::string& title);
|
||||
|
||||
unsigned int R_HashString(const char* string);
|
||||
unsigned int R_HashString(const char* string, size_t maxLen);
|
||||
void R_LoadSunThroughDvars(const char* mapname, sunflare_t* sun);
|
||||
void R_SetSunFromDvars(sunflare_t* sun);
|
||||
|
||||
|
@ -3720,10 +3720,10 @@ namespace Game
|
||||
{
|
||||
XAsset asset;
|
||||
char zoneIndex;
|
||||
volatile char inuse;
|
||||
volatile char inuseMask;
|
||||
bool printedMissingAsset;
|
||||
unsigned __int16 nextHash;
|
||||
unsigned __int16 nextOverride;
|
||||
unsigned __int16 usageFrame;
|
||||
};
|
||||
|
||||
enum XFileLanguage : unsigned char
|
||||
@ -5298,6 +5298,121 @@ namespace Game
|
||||
char buffer[256];
|
||||
};
|
||||
|
||||
struct clientLogo_t
|
||||
{
|
||||
int startTime;
|
||||
int duration;
|
||||
int fadein;
|
||||
int fadeout;
|
||||
Material* material[2];
|
||||
};
|
||||
|
||||
struct vidConfig_t
|
||||
{
|
||||
unsigned int sceneWidth;
|
||||
unsigned int sceneHeight;
|
||||
unsigned int displayWidth;
|
||||
unsigned int displayHeight;
|
||||
unsigned int displayFrequency;
|
||||
int isFullscreen;
|
||||
float aspectRatioWindow;
|
||||
float aspectRatioScenePixel;
|
||||
float aspectRatioDisplayPixel;
|
||||
unsigned int maxTextureSize;
|
||||
unsigned int maxTextureMaps;
|
||||
bool deviceSupportsGamma;
|
||||
};
|
||||
|
||||
struct trDebugLine_t
|
||||
{
|
||||
float start[3];
|
||||
float end[3];
|
||||
float color[4];
|
||||
int depthTest;
|
||||
};
|
||||
|
||||
struct trDebugString_t
|
||||
{
|
||||
float xyz[3];
|
||||
float color[4];
|
||||
float scale;
|
||||
char text[96];
|
||||
};
|
||||
|
||||
struct clientDebugStringInfo_t
|
||||
{
|
||||
int max;
|
||||
int num;
|
||||
trDebugString_t* strings;
|
||||
int* durations;
|
||||
};
|
||||
|
||||
struct clientDebugLineInfo_t
|
||||
{
|
||||
int max;
|
||||
int num;
|
||||
trDebugLine_t* lines;
|
||||
int* durations;
|
||||
};
|
||||
|
||||
struct clientDebug_t
|
||||
{
|
||||
int prevFromServer;
|
||||
int fromServer;
|
||||
clientDebugStringInfo_t clStrings;
|
||||
clientDebugStringInfo_t svStringsBuffer;
|
||||
clientDebugStringInfo_t svStrings;
|
||||
clientDebugLineInfo_t clLines;
|
||||
clientDebugLineInfo_t svLinesBuffer;
|
||||
clientDebugLineInfo_t svLines;
|
||||
};
|
||||
|
||||
struct ClientMatchData
|
||||
{
|
||||
char def[64];
|
||||
char data[1024];
|
||||
};
|
||||
|
||||
struct clientStatic_t
|
||||
{
|
||||
int quit;
|
||||
int hunkUsersStarted;
|
||||
char servername[256];
|
||||
int rendererStarted;
|
||||
int soundStarted;
|
||||
int uiStarted;
|
||||
int frametime;
|
||||
float frametime_base;
|
||||
int realtime;
|
||||
bool gpuSyncedPrevFrame;
|
||||
bool inputUpdatedPrevFrame;
|
||||
clientLogo_t logo;
|
||||
float mapCenter[3];
|
||||
int lastServerPinged;
|
||||
int pingedServerCount;
|
||||
int totalServersParsed;
|
||||
int pingUpdateSource;
|
||||
Material* whiteMaterial;
|
||||
Material* consoleMaterial;
|
||||
Font_s* consoleFont;
|
||||
// ... tbc
|
||||
};
|
||||
|
||||
struct ConDrawInputGlob
|
||||
{
|
||||
char autoCompleteChoice[64];
|
||||
int matchIndex;
|
||||
int matchCount;
|
||||
const char* inputText;
|
||||
int inputTextLen;
|
||||
bool hasExactMatch;
|
||||
bool mayAutoComplete;
|
||||
float x;
|
||||
float y;
|
||||
float leftX;
|
||||
float fontHeight;
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#ifndef IDA
|
||||
|
Loading…
Reference in New Issue
Block a user