Add fonticon autocompletion inputs and improve rendering
This commit is contained in:
parent
7b70a1c62c
commit
68acf467b1
@ -98,8 +98,15 @@ namespace Components
|
|||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRenderer::DrawAutocompleteBox(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,
|
||||||
@ -109,32 +116,61 @@ namespace Components
|
|||||||
};
|
};
|
||||||
|
|
||||||
Game::R_AddCmdDrawStretchPic(x, y, w, h, 0.0, 0.0, 0.0, 0.0, color, Game::cls->whiteMaterial);
|
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, y, FONT_ICON_AUTOCOMPLETE_BOX_BORDER, 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 + w - FONT_ICON_AUTOCOMPLETE_BOX_BORDER, y, FONT_ICON_AUTOCOMPLETE_BOX_BORDER, 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, w, FONT_ICON_AUTOCOMPLETE_BOX_BORDER, 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);
|
Game::R_AddCmdDrawStretchPic(x, y + h - FONT_ICON_AUTOCOMPLETE_BOX_BORDER, w, FONT_ICON_AUTOCOMPLETE_BOX_BORDER, 0.0, 0.0, 0.0, 0.0, borderColor, Game::cls->whiteMaterial);
|
||||||
|
|
||||||
|
if (context.resultOffset > 0)
|
||||||
|
{
|
||||||
|
Game::R_AddCmdDrawStretchPic(x + w - FONT_ICON_AUTOCOMPLETE_BOX_BORDER - FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
|
||||||
|
y + FONT_ICON_AUTOCOMPLETE_BOX_BORDER,
|
||||||
|
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
|
||||||
|
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
|
||||||
|
1.0f, 1.0f, 0.0f, 0.0f, colorWhite, Game::sharedUiInfo->assets.scrollBarArrowDown);
|
||||||
|
}
|
||||||
|
if(context.hasMoreResults)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
|
||||||
|
FONT_ICON_AUTOCOMPLETE_ARROW_SIZE,
|
||||||
|
1.0f, 1.0f, 0.0f, 0.0f, colorWhite, Game::sharedUiInfo->assets.scrollBarArrowUp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextRenderer::UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font)
|
void TextRenderer::UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font)
|
||||||
{
|
{
|
||||||
context.resultCount = 0;
|
context.resultCount = 0;
|
||||||
|
context.hasMoreResults = false;
|
||||||
|
context.lastResultOffset = context.resultOffset;
|
||||||
|
|
||||||
const auto* techset2d = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_TECHNIQUE_SET, "2d").techniqueSet;
|
const auto* techset2d = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_TECHNIQUE_SET, "2d").techniqueSet;
|
||||||
|
auto skipCount = context.resultOffset;
|
||||||
|
|
||||||
Game::DB_EnumXAssetEntries(Game::ASSET_TYPE_MATERIAL, [&context, techset2d](const Game::XAssetEntry* entry)
|
Game::DB_EnumXAssetEntries(Game::ASSET_TYPE_MATERIAL, [&context, techset2d, &skipCount](const Game::XAssetEntry* entry)
|
||||||
{
|
{
|
||||||
if (context.resultCount >= FontIconAutocompleteContext::MAX_RESULTS)
|
if (context.resultCount >= FontIconAutocompleteContext::MAX_RESULTS && context.hasMoreResults)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto* material = entry->asset.header.material;
|
const auto* material = entry->asset.header.material;
|
||||||
if(material->techniqueSet == techset2d && std::string(material->info.name).rfind(context.lastQuery, 0) == 0)
|
if(material->techniqueSet == techset2d && std::string(material->info.name).rfind(context.lastQuery, 0) == 0)
|
||||||
{
|
{
|
||||||
context.results[context.resultCount++] = {
|
if (skipCount > 0)
|
||||||
std::string(Utils::String::VA(":%s:", material->info.name)),
|
{
|
||||||
std::string(material->info.name)
|
skipCount--;
|
||||||
};
|
}
|
||||||
|
else if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS)
|
||||||
|
{
|
||||||
|
context.results[context.resultCount++] = {
|
||||||
|
std::string(Utils::String::VA(":%s:", material->info.name)),
|
||||||
|
std::string(material->info.name)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
context.hasMoreResults = true;
|
||||||
}
|
}
|
||||||
}, true, true);
|
}, false, false);
|
||||||
|
|
||||||
context.maxFontIconWidth = 0;
|
context.maxFontIconWidth = 0;
|
||||||
context.maxMaterialNameWidth = 0;
|
context.maxMaterialNameWidth = 0;
|
||||||
@ -178,17 +214,28 @@ namespace Components
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update scroll
|
||||||
|
if(context.selectedOffset < context.resultOffset)
|
||||||
|
context.resultOffset = context.selectedOffset;
|
||||||
|
else if(context.selectedOffset >= context.resultOffset + FontIconAutocompleteContext::MAX_RESULTS)
|
||||||
|
context.resultOffset = context.selectedOffset - (FontIconAutocompleteContext::MAX_RESULTS - 1);
|
||||||
|
|
||||||
context.autocompleteActive = true;
|
context.autocompleteActive = true;
|
||||||
|
|
||||||
|
// 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(currentFontIconHash != context.lastHash)
|
if(currentFontIconHash != context.lastHash)
|
||||||
{
|
{
|
||||||
context.resultOffset = 0;
|
context.resultOffset = 0;
|
||||||
|
context.selectedOffset = 0;
|
||||||
context.lastHash = currentFontIconHash;
|
context.lastHash = currentFontIconHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update results for query and scroll
|
||||||
context.lastQuery = std::string(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
|
context.lastQuery = std::string(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
|
||||||
UpdateAutocompleteContextResults(context, font);
|
UpdateAutocompleteContextResults(context, font);
|
||||||
}
|
}
|
||||||
@ -200,9 +247,11 @@ namespace Components
|
|||||||
static_cast<float>(Game::R_TextWidth(text, INT_MAX, font)));
|
static_cast<float>(Game::R_TextWidth(text, INT_MAX, font)));
|
||||||
|
|
||||||
const auto totalLines = 1u + context.resultCount;
|
const auto totalLines = 1u + context.resultCount;
|
||||||
DrawAutocompleteBox(x - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
const auto arrowPadding = context.resultOffset > 0 || context.hasMoreResults ? FONT_ICON_AUTOCOMPLETE_ARROW_SIZE : 0.0f;
|
||||||
|
DrawAutocompleteBox(context,
|
||||||
|
x - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
||||||
y - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
y - FONT_ICON_AUTOCOMPLETE_BOX_PADDING,
|
||||||
boxWidth + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
boxWidth + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2 + arrowPadding,
|
||||||
static_cast<float>(font->pixelHeight * totalLines) + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
static_cast<float>(font->pixelHeight * totalLines) + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
||||||
(*con_inputBoxColor)->current.vector);
|
(*con_inputBoxColor)->current.vector);
|
||||||
|
|
||||||
@ -218,11 +267,16 @@ namespace Components
|
|||||||
Game::R_AddCmdDrawText(text, INT_MAX, font, x, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
Game::R_AddCmdDrawText(text, INT_MAX, font, x, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
||||||
currentY += static_cast<float>(font->pixelHeight);
|
currentY += static_cast<float>(font->pixelHeight);
|
||||||
|
|
||||||
|
const auto selectedIndex = context.selectedOffset - context.resultOffset;
|
||||||
for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++)
|
for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++)
|
||||||
{
|
{
|
||||||
const auto& result = context.results[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.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);
|
|
||||||
|
if(selectedIndex == resultIndex)
|
||||||
|
Game::R_AddCmdDrawText(Utils::String::VA("^2%s", result.materialName.c_str()), INT_MAX, font, x + context.maxFontIconWidth + FONT_ICON_AUTOCOMPLETE_COL_SPACING, currentY, 1.0f, 1.0f, 0.0, textColor, 0);
|
||||||
|
else
|
||||||
|
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);
|
currentY += static_cast<float>(font->pixelHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,6 +315,116 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextRenderer::AutocompleteUp(FontIconAutocompleteContext& context)
|
||||||
|
{
|
||||||
|
if (context.selectedOffset > 0)
|
||||||
|
context.selectedOffset--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRenderer::AutocompleteDown(FontIconAutocompleteContext& context)
|
||||||
|
{
|
||||||
|
if (context.resultCount < FontIconAutocompleteContext::MAX_RESULTS)
|
||||||
|
{
|
||||||
|
if (context.resultCount > 0 && context.selectedOffset < context.resultOffset + context.resultCount - 1)
|
||||||
|
context.selectedOffset++;
|
||||||
|
}
|
||||||
|
else if (context.selectedOffset == context.resultOffset + context.resultCount - 1)
|
||||||
|
{
|
||||||
|
if (context.hasMoreResults)
|
||||||
|
context.selectedOffset++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.selectedOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRenderer::AutocompleteFill(const FontIconAutocompleteContext& context, Game::ScreenPlacement* scrPlace, Game::field_t* edit)
|
||||||
|
{
|
||||||
|
if (context.selectedOffset >= context.resultOffset + context.resultCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto selectedResultIndex = context.selectedOffset - context.resultOffset;
|
||||||
|
std::string remainingFillData = context.results[selectedResultIndex].materialName.substr(context.lastQuery.size());
|
||||||
|
const std::string moveData(&edit->buffer[edit->cursor]);
|
||||||
|
|
||||||
|
const auto remainingBufferCharacters = std::extent_v<decltype(Game::field_t::buffer)> - edit->cursor - moveData.size() - 1;
|
||||||
|
if(remainingFillData.size() > remainingBufferCharacters)
|
||||||
|
remainingFillData = remainingFillData.erase(remainingBufferCharacters);
|
||||||
|
|
||||||
|
if(!remainingFillData.empty())
|
||||||
|
{
|
||||||
|
strncpy(&edit->buffer[edit->cursor], remainingFillData.c_str(), remainingFillData.size());
|
||||||
|
strncpy(&edit->buffer[edit->cursor + remainingFillData.size()], moveData.c_str(), moveData.size());
|
||||||
|
edit->buffer[std::extent_v<decltype(Game::field_t::buffer)> - 1] = '\0';
|
||||||
|
edit->cursor += static_cast<int>(remainingFillData.size());
|
||||||
|
Game::Field_AdjustScroll(scrPlace, edit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextRenderer::AutocompleteHandleKeyDown(FontIconAutocompleteContext& context, const int key, Game::ScreenPlacement* scrPlace, Game::field_t* edit)
|
||||||
|
{
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case Game::K_UPARROW:
|
||||||
|
case Game::K_KP_UPARROW:
|
||||||
|
AutocompleteUp(context);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Game::K_DOWNARROW:
|
||||||
|
case Game::K_KP_DOWNARROW:
|
||||||
|
AutocompleteDown(context);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Game::K_TAB:
|
||||||
|
AutocompleteFill(context, scrPlace, edit);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextRenderer::Console_Key_Hk(const int localClientNum, const int key)
|
||||||
|
{
|
||||||
|
auto& autocompleteContext = autocompleteContextArray[FONT_ICON_ACI_CONSOLE];
|
||||||
|
if (autocompleteContext.autocompleteActive && AutocompleteHandleKeyDown(autocompleteContext, key, Game::scrPlaceFull, Game::g_consoleField))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Utils::Hook::Call<void(int, int)>(0x4311E0)(localClientNum, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextRenderer::ChatHandleKeyDown(const int localClientNum, const int key)
|
||||||
|
{
|
||||||
|
auto& autocompleteContext = autocompleteContextArray[FONT_ICON_ACI_CHAT];
|
||||||
|
return autocompleteContext.autocompleteActive && AutocompleteHandleKeyDown(autocompleteContext, key, &Game::scrPlaceView[localClientNum], &Game::playerKeys[localClientNum].chatField);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto Message_Key = 0x5A7E50;
|
||||||
|
__declspec(naked) void TextRenderer::Message_Key_Stub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push eax
|
||||||
|
push edi
|
||||||
|
call ChatHandleKeyDown
|
||||||
|
add esp, 0x8
|
||||||
|
test al,al
|
||||||
|
jnz skipHandling
|
||||||
|
|
||||||
|
popad
|
||||||
|
call Message_Key
|
||||||
|
ret
|
||||||
|
|
||||||
|
skipHandling:
|
||||||
|
popad
|
||||||
|
mov al, 1
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -1124,6 +1288,11 @@ namespace Components
|
|||||||
Utils::Hook(0x5A50A5, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A50A5, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x5A50BB, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
Utils::Hook(0x5A50BB, Con_DrawInput_Hk, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
|
// Handle key inputs for console and chat
|
||||||
|
Utils::Hook(0x4F685C, Console_Key_Hk, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x4F6694, Message_Key_Stub, HOOK_CALL).install()->quick();
|
||||||
|
Utils::Hook(0x4F684C, Message_Key_Stub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
PatchColorLimit(COLOR_LAST_CHAR);
|
PatchColorLimit(COLOR_LAST_CHAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -82,8 +82,10 @@ namespace Components
|
|||||||
std::string lastQuery;
|
std::string lastQuery;
|
||||||
FontIconAutocompleteResult results[MAX_RESULTS];
|
FontIconAutocompleteResult results[MAX_RESULTS];
|
||||||
size_t resultCount;
|
size_t resultCount;
|
||||||
|
bool hasMoreResults;
|
||||||
size_t resultOffset;
|
size_t resultOffset;
|
||||||
size_t lastResultOffset;
|
size_t lastResultOffset;
|
||||||
|
size_t selectedOffset;
|
||||||
float maxFontIconWidth;
|
float maxFontIconWidth;
|
||||||
float maxMaterialNameWidth;
|
float maxMaterialNameWidth;
|
||||||
};
|
};
|
||||||
@ -93,7 +95,9 @@ namespace Components
|
|||||||
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
||||||
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
||||||
static constexpr auto FONT_ICON_AUTOCOMPLETE_BOX_PADDING = 6.0f;
|
static constexpr auto FONT_ICON_AUTOCOMPLETE_BOX_PADDING = 6.0f;
|
||||||
|
static constexpr auto FONT_ICON_AUTOCOMPLETE_BOX_BORDER = 2.0f;
|
||||||
static constexpr auto FONT_ICON_AUTOCOMPLETE_COL_SPACING = 12.0f;
|
static constexpr auto FONT_ICON_AUTOCOMPLETE_COL_SPACING = 12.0f;
|
||||||
|
static constexpr auto FONT_ICON_AUTOCOMPLETE_ARROW_SIZE = 12.0f;
|
||||||
static constexpr float MY_OFFSETS[4][2]
|
static constexpr float MY_OFFSETS[4][2]
|
||||||
{
|
{
|
||||||
{-1.0f, -1.0f},
|
{-1.0f, -1.0f},
|
||||||
@ -130,13 +134,21 @@ namespace Components
|
|||||||
private:
|
private:
|
||||||
static unsigned HsvToRgb(HsvColor hsv);
|
static unsigned HsvToRgb(HsvColor hsv);
|
||||||
|
|
||||||
static void DrawAutocompleteBox(float x, float y, float w, float h, const float* color);
|
static void DrawAutocompleteBox(const FontIconAutocompleteContext& context, 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 DrawAutocomplete(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font);
|
||||||
static void UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, 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 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 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 void Con_DrawInput_Hk(int localClientNum);
|
||||||
|
|
||||||
|
static void AutocompleteUp(FontIconAutocompleteContext& context);
|
||||||
|
static void AutocompleteDown(FontIconAutocompleteContext& context);
|
||||||
|
static void AutocompleteFill(const FontIconAutocompleteContext& context, Game::ScreenPlacement* scrPlace, Game::field_t* edit);
|
||||||
|
static bool AutocompleteHandleKeyDown(FontIconAutocompleteContext& context, int key, Game::ScreenPlacement* scrPlace, Game::field_t* edit);
|
||||||
|
static void Console_Key_Hk(int localClientNum, int key);
|
||||||
|
static bool ChatHandleKeyDown(int localClientNum, int key);
|
||||||
|
static void Message_Key_Stub();
|
||||||
|
|
||||||
static int SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field);
|
static int SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field);
|
||||||
static void Field_AdjustScroll_PrintLen_Stub();
|
static void Field_AdjustScroll_PrintLen_Stub();
|
||||||
|
|
||||||
|
@ -341,6 +341,7 @@ namespace Game
|
|||||||
GetDecayingLetterInfo_t GetDecayingLetterInfo = GetDecayingLetterInfo_t(0x5351C0);
|
GetDecayingLetterInfo_t GetDecayingLetterInfo = GetDecayingLetterInfo_t(0x5351C0);
|
||||||
|
|
||||||
Field_Draw_t Field_Draw = Field_Draw_t(0x4F5B40);
|
Field_Draw_t Field_Draw = Field_Draw_t(0x4F5B40);
|
||||||
|
Field_AdjustScroll_t Field_AdjustScroll = Field_AdjustScroll_t(0x488C10);
|
||||||
|
|
||||||
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
XAssetHeader* DB_XAssetPool = reinterpret_cast<XAssetHeader*>(0x7998A8);
|
||||||
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
unsigned int* g_poolSize = reinterpret_cast<unsigned int*>(0x7995E8);
|
||||||
@ -437,6 +438,12 @@ namespace Game
|
|||||||
|
|
||||||
clientStatic_t* cls = reinterpret_cast<clientStatic_t*>(0xA7FE90);
|
clientStatic_t* cls = reinterpret_cast<clientStatic_t*>(0xA7FE90);
|
||||||
|
|
||||||
|
sharedUiInfo_t* sharedUiInfo = reinterpret_cast<sharedUiInfo_t*>(0x62E4B78);
|
||||||
|
ScreenPlacement* scrPlaceFull = reinterpret_cast<ScreenPlacement*>(0x10843F0);
|
||||||
|
ScreenPlacement* scrPlaceView = reinterpret_cast<ScreenPlacement*>(0x1084378);
|
||||||
|
|
||||||
|
PlayerKeyState* playerKeys = reinterpret_cast<PlayerKeyState*>(0xA1B7D0);
|
||||||
|
|
||||||
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||||
{
|
{
|
||||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||||
|
@ -795,6 +795,9 @@ namespace Game
|
|||||||
typedef void(__cdecl * Field_Draw_t)(int localClientNum, field_t* edit, int x, int y, int horzAlign, int vertAlign);
|
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 Field_Draw_t Field_Draw;
|
||||||
|
|
||||||
|
typedef void(__cdecl * Field_AdjustScroll_t)(ScreenPlacement* scrPlace, field_t* edit);
|
||||||
|
extern Field_AdjustScroll_t Field_AdjustScroll;
|
||||||
|
|
||||||
extern XAssetHeader* DB_XAssetPool;
|
extern XAssetHeader* DB_XAssetPool;
|
||||||
extern unsigned int* g_poolSize;
|
extern unsigned int* g_poolSize;
|
||||||
|
|
||||||
@ -889,6 +892,12 @@ namespace Game
|
|||||||
|
|
||||||
extern clientStatic_t* cls;
|
extern clientStatic_t* cls;
|
||||||
|
|
||||||
|
extern sharedUiInfo_t* sharedUiInfo;
|
||||||
|
extern ScreenPlacement* scrPlaceFull;
|
||||||
|
extern ScreenPlacement* scrPlaceView;
|
||||||
|
|
||||||
|
extern PlayerKeyState* playerKeys;
|
||||||
|
|
||||||
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
XAssetHeader ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
||||||
void Menu_FreeItemMemory(Game::itemDef_s* item);
|
void Menu_FreeItemMemory(Game::itemDef_s* item);
|
||||||
const char* TableLookup(StringTable* stringtable, int row, int column);
|
const char* TableLookup(StringTable* stringtable, int row, int column);
|
||||||
|
@ -5431,6 +5431,272 @@ namespace Game
|
|||||||
float subScreenLeft;
|
float subScreenLeft;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct serverStatusInfo_t
|
||||||
|
{
|
||||||
|
char address[64];
|
||||||
|
const char* lines[128][4];
|
||||||
|
char text[1024];
|
||||||
|
char pings[54];
|
||||||
|
int numLines;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pendingServer_t
|
||||||
|
{
|
||||||
|
char adrstr[64];
|
||||||
|
char name[64];
|
||||||
|
int startTime;
|
||||||
|
int serverNum;
|
||||||
|
int valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pendingServerStatus_t
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
pendingServer_t server[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pinglist_t
|
||||||
|
{
|
||||||
|
char adrstr[64];
|
||||||
|
int start;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct serverStatus_s
|
||||||
|
{
|
||||||
|
pinglist_t pingList[16];
|
||||||
|
int numqueriedservers;
|
||||||
|
int currentping;
|
||||||
|
int nextpingtime;
|
||||||
|
int maxservers;
|
||||||
|
int refreshtime;
|
||||||
|
int numServers;
|
||||||
|
int sortKey;
|
||||||
|
int sortDir;
|
||||||
|
int lastCount;
|
||||||
|
int refreshActive;
|
||||||
|
int currentServer;
|
||||||
|
int displayServers[20000];
|
||||||
|
int numDisplayServers;
|
||||||
|
int serverCount;
|
||||||
|
int numPlayersOnServers;
|
||||||
|
int nextDisplayRefresh;
|
||||||
|
int nextSortTime;
|
||||||
|
int motdLen;
|
||||||
|
int motdWidth;
|
||||||
|
int motdPaintX;
|
||||||
|
int motdPaintX2;
|
||||||
|
int motdOffset;
|
||||||
|
int motdTime;
|
||||||
|
char motd[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mapInfo
|
||||||
|
{
|
||||||
|
char mapName[32];
|
||||||
|
char mapLoadName[16];
|
||||||
|
char mapDescription[32];
|
||||||
|
char mapLoadImage[32];
|
||||||
|
char mapCustomKey[32][16];
|
||||||
|
char mapCustomValue[32][64];
|
||||||
|
int mapCustomCount;
|
||||||
|
int teamMembers;
|
||||||
|
int typeBits;
|
||||||
|
int timeToBeat[32];
|
||||||
|
int active;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gameTypeInfo
|
||||||
|
{
|
||||||
|
char gameType[12];
|
||||||
|
char gameTypeName[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CachedAssets_t
|
||||||
|
{
|
||||||
|
Material* scrollBarArrowUp;
|
||||||
|
Material* scrollBarArrowDown;
|
||||||
|
Material* scrollBarArrowLeft;
|
||||||
|
Material* scrollBarArrowRight;
|
||||||
|
Material* scrollBar;
|
||||||
|
Material* scrollBarThumb;
|
||||||
|
Material* sliderBar;
|
||||||
|
Material* sliderThumb;
|
||||||
|
Material* whiteMaterial;
|
||||||
|
Material* cursor;
|
||||||
|
Material* textDecodeCharacters;
|
||||||
|
Material* textDecodeCharactersGlow;
|
||||||
|
Font_s* bigFont;
|
||||||
|
Font_s* smallFont;
|
||||||
|
Font_s* consoleFont;
|
||||||
|
Font_s* boldFont;
|
||||||
|
Font_s* textFont;
|
||||||
|
Font_s* extraBigFont;
|
||||||
|
Font_s* objectiveFont;
|
||||||
|
Font_s* hudBigFont;
|
||||||
|
Font_s* hudSmallFont;
|
||||||
|
snd_alias_list_t* itemFocusSound;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sharedUiInfo_t
|
||||||
|
{
|
||||||
|
CachedAssets_t assets;
|
||||||
|
int playerCount;
|
||||||
|
char playerNames[18][32];
|
||||||
|
char teamNames[18][32];
|
||||||
|
int playerClientNums[18];
|
||||||
|
volatile int updateGameTypeList;
|
||||||
|
int numGameTypes;
|
||||||
|
gameTypeInfo gameTypes[32];
|
||||||
|
int numCustomGameTypes;
|
||||||
|
gameTypeInfo customGameTypes[32];
|
||||||
|
char customGameTypeCancelState[2048];
|
||||||
|
int numJoinGameTypes;
|
||||||
|
gameTypeInfo joinGameTypes[32];
|
||||||
|
volatile int updateArenas;
|
||||||
|
int mapCount;
|
||||||
|
mapInfo mapList[128];
|
||||||
|
int mapIndexSorted[128];
|
||||||
|
bool mapsAreSorted;
|
||||||
|
Material* serverHardwareIconList[9];
|
||||||
|
unsigned __int64 partyMemberXuid;
|
||||||
|
Material* talkingIcons[2];
|
||||||
|
serverStatus_s serverStatus;
|
||||||
|
char serverStatusAddress[64];
|
||||||
|
serverStatusInfo_t serverStatusInfo;
|
||||||
|
int nextServerStatusRefresh;
|
||||||
|
pendingServerStatus_t pendingServerStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum keyNum_t
|
||||||
|
{
|
||||||
|
K_NONE = 0x0,
|
||||||
|
K_TAB = 0x9,
|
||||||
|
K_ENTER = 0xD,
|
||||||
|
K_ESCAPE = 0x1B,
|
||||||
|
K_SPACE = 0x20,
|
||||||
|
K_BACKSPACE = 0x7F,
|
||||||
|
K_ASCII_FIRST = 0x80,
|
||||||
|
K_ASCII_181 = 0x80,
|
||||||
|
K_ASCII_191 = 0x81,
|
||||||
|
K_ASCII_223 = 0x82,
|
||||||
|
K_ASCII_224 = 0x83,
|
||||||
|
K_ASCII_225 = 0x84,
|
||||||
|
K_ASCII_228 = 0x85,
|
||||||
|
K_ASCII_229 = 0x86,
|
||||||
|
K_ASCII_230 = 0x87,
|
||||||
|
K_ASCII_231 = 0x88,
|
||||||
|
K_ASCII_232 = 0x89,
|
||||||
|
K_ASCII_233 = 0x8A,
|
||||||
|
K_ASCII_236 = 0x8B,
|
||||||
|
K_ASCII_241 = 0x8C,
|
||||||
|
K_ASCII_242 = 0x8D,
|
||||||
|
K_ASCII_243 = 0x8E,
|
||||||
|
K_ASCII_246 = 0x8F,
|
||||||
|
K_ASCII_248 = 0x90,
|
||||||
|
K_ASCII_249 = 0x91,
|
||||||
|
K_ASCII_250 = 0x92,
|
||||||
|
K_ASCII_252 = 0x93,
|
||||||
|
K_END_ASCII_CHARS = 0x94,
|
||||||
|
K_COMMAND = 0x96,
|
||||||
|
K_CAPSLOCK = 0x97,
|
||||||
|
K_POWER = 0x98,
|
||||||
|
K_PAUSE = 0x99,
|
||||||
|
K_UPARROW = 0x9A,
|
||||||
|
K_DOWNARROW = 0x9B,
|
||||||
|
K_LEFTARROW = 0x9C,
|
||||||
|
K_RIGHTARROW = 0x9D,
|
||||||
|
K_ALT = 0x9E,
|
||||||
|
K_CTRL = 0x9F,
|
||||||
|
K_SHIFT = 0xA0,
|
||||||
|
K_INS = 0xA1,
|
||||||
|
K_DEL = 0xA2,
|
||||||
|
K_PGDN = 0xA3,
|
||||||
|
K_PGUP = 0xA4,
|
||||||
|
K_HOME = 0xA5,
|
||||||
|
K_END = 0xA6,
|
||||||
|
K_F1 = 0xA7,
|
||||||
|
K_F2 = 0xA8,
|
||||||
|
K_F3 = 0xA9,
|
||||||
|
K_F4 = 0xAA,
|
||||||
|
K_F5 = 0xAB,
|
||||||
|
K_F6 = 0xAC,
|
||||||
|
K_F7 = 0xAD,
|
||||||
|
K_F8 = 0xAE,
|
||||||
|
K_F9 = 0xAF,
|
||||||
|
K_F10 = 0xB0,
|
||||||
|
K_F11 = 0xB1,
|
||||||
|
K_F12 = 0xB2,
|
||||||
|
K_F13 = 0xB3,
|
||||||
|
K_F14 = 0xB4,
|
||||||
|
K_F15 = 0xB5,
|
||||||
|
K_KP_HOME = 0xB6,
|
||||||
|
K_KP_UPARROW = 0xB7,
|
||||||
|
K_KP_PGUP = 0xB8,
|
||||||
|
K_KP_LEFTARROW = 0xB9,
|
||||||
|
K_KP_5 = 0xBA,
|
||||||
|
K_KP_RIGHTARROW = 0xBB,
|
||||||
|
K_KP_END = 0xBC,
|
||||||
|
K_KP_DOWNARROW = 0xBD,
|
||||||
|
K_KP_PGDN = 0xBE,
|
||||||
|
K_KP_ENTER = 0xBF,
|
||||||
|
K_KP_INS = 0xC0,
|
||||||
|
K_KP_DEL = 0xC1,
|
||||||
|
K_KP_SLASH = 0xC2,
|
||||||
|
K_KP_MINUS = 0xC3,
|
||||||
|
K_KP_PLUS = 0xC4,
|
||||||
|
K_KP_NUMLOCK = 0xC5,
|
||||||
|
K_KP_STAR = 0xC6,
|
||||||
|
K_KP_EQUALS = 0xC7,
|
||||||
|
K_MOUSE1 = 0xC8,
|
||||||
|
K_MOUSE2 = 0xC9,
|
||||||
|
K_MOUSE3 = 0xCA,
|
||||||
|
K_MOUSE4 = 0xCB,
|
||||||
|
K_MOUSE5 = 0xCC,
|
||||||
|
K_MWHEELDOWN = 0xCD,
|
||||||
|
K_MWHEELUP = 0xCE,
|
||||||
|
K_AUX1 = 0xCF,
|
||||||
|
K_AUX2 = 0xD0,
|
||||||
|
K_AUX3 = 0xD1,
|
||||||
|
K_AUX4 = 0xD2,
|
||||||
|
K_AUX5 = 0xD3,
|
||||||
|
K_AUX6 = 0xD4,
|
||||||
|
K_AUX7 = 0xD5,
|
||||||
|
K_AUX8 = 0xD6,
|
||||||
|
K_AUX9 = 0xD7,
|
||||||
|
K_AUX10 = 0xD8,
|
||||||
|
K_AUX11 = 0xD9,
|
||||||
|
K_AUX12 = 0xDA,
|
||||||
|
K_AUX13 = 0xDB,
|
||||||
|
K_AUX14 = 0xDC,
|
||||||
|
K_AUX15 = 0xDD,
|
||||||
|
K_AUX16 = 0xDE,
|
||||||
|
K_LAST_KEY = 0xDF,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KeyState
|
||||||
|
{
|
||||||
|
int down;
|
||||||
|
int repeats;
|
||||||
|
const char* binding;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LocSelInputState
|
||||||
|
{
|
||||||
|
LOC_SEL_INPUT_NONE = 0x0,
|
||||||
|
LOC_SEL_INPUT_CONFIRM = 0x1,
|
||||||
|
LOC_SEL_INPUT_CANCEL = 0x2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerKeyState
|
||||||
|
{
|
||||||
|
field_t chatField;
|
||||||
|
int chat_team;
|
||||||
|
int overstrikeMode;
|
||||||
|
int anyKeyDown;
|
||||||
|
KeyState keys[256];
|
||||||
|
LocSelInputState locSelInputState;
|
||||||
|
};
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#ifndef IDA
|
#ifndef IDA
|
||||||
|
Loading…
Reference in New Issue
Block a user