Fix characters or cursor vanishing when cursor is in escaped color code that is expanded
This commit is contained in:
parent
26f2403418
commit
4497b991be
@ -372,6 +372,12 @@ namespace Components
|
|||||||
|
|
||||||
while(*curText && maxLengthRemaining)
|
while(*curText && maxLengthRemaining)
|
||||||
{
|
{
|
||||||
|
if (passes[passIndex] == Game::FONTPASS_NORMAL && renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
||||||
|
{
|
||||||
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
|
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
||||||
|
}
|
||||||
|
|
||||||
auto letter = Game::SEH_ReadCharFromString(&curText, nullptr);
|
auto letter = Game::SEH_ReadCharFromString(&curText, nullptr);
|
||||||
|
|
||||||
if(letter == '^' && *curText >= COLOR_FIRST_CHAR && *curText <= COLOR_LAST_CHAR)
|
if(letter == '^' && *curText >= COLOR_FIRST_CHAR && *curText <= COLOR_LAST_CHAR)
|
||||||
@ -427,16 +433,9 @@ namespace Components
|
|||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
||||||
|
|
||||||
if(passes[passIndex] == Game::FONTPASS_NORMAL)
|
if(passes[passIndex] == Game::FONTPASS_NORMAL)
|
||||||
{
|
xa += DrawFontIcon(fontIconInfo, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, ColorRgba(255, 255, 255, finalColor.array[3]));
|
||||||
const auto fontIconWidth = DrawFontIcon(fontIconInfo, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, ColorRgba(255, 255, 255, finalColor.array[3]));
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
|
||||||
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
|
||||||
xa += fontIconWidth;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
xa += GetFontIconWidth(fontIconInfo, font, xScale);
|
xa += GetFontIconWidth(fontIconInfo, font, xScale);
|
||||||
}
|
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
if (renderFlags & Game::TEXT_RENDERFLAG_PADDING)
|
||||||
xa += xScale * padding;
|
xa += xScale * padding;
|
||||||
@ -513,12 +512,6 @@ namespace Components
|
|||||||
DrawTextFxExtraCharacter(fxMaterial, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, finalColor.packed);
|
DrawTextFxExtraCharacter(fxMaterial, extraFxChar, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, finalColor.packed);
|
||||||
else
|
else
|
||||||
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, finalColor.packed);
|
Game::RB_DrawChar(material, xRot, yRot, static_cast<float>(glyph->pixelWidth) * xScale, static_cast<float>(glyph->pixelHeight) * yScale, sinAngle, cosAngle, glyph, finalColor.packed);
|
||||||
|
|
||||||
if (renderFlags & Game::TEXT_RENDERFLAG_CURSOR && count == cursorPos)
|
|
||||||
{
|
|
||||||
RotateXY(cosAngle, sinAngle, startX, startY, xa, xy, &xRot, &yRot);
|
|
||||||
Game::RB_DrawCursor(material, cursorLetter, xRot, yRot, sinAngle, cosAngle, font, xScale, yScale, color.packed);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(passes[passIndex] == Game::FONTPASS_OUTLINE)
|
else if(passes[passIndex] == Game::FONTPASS_OUTLINE)
|
||||||
{
|
{
|
||||||
@ -785,10 +778,61 @@ namespace Components
|
|||||||
return std::string(buffer);
|
return std::string(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TextRenderer::SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field)
|
||||||
|
{
|
||||||
|
if (!string)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const auto cursorPos = field->cursor;
|
||||||
|
auto len = 0;
|
||||||
|
auto lenWithInvisibleTail = 0;
|
||||||
|
auto count = 0;
|
||||||
|
const auto* curText = string;
|
||||||
|
while(*curText)
|
||||||
|
{
|
||||||
|
const auto c = Game::SEH_ReadCharFromString(&curText, nullptr);
|
||||||
|
lenWithInvisibleTail = len;
|
||||||
|
|
||||||
|
if (c == '^' && *curText >= COLOR_FIRST_CHAR && *curText <= COLOR_LAST_CHAR && !(cursorPos > count && cursorPos < count + 2))
|
||||||
|
{
|
||||||
|
curText++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else if(c != '\r' && c != '\n')
|
||||||
|
{
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
lenWithInvisibleTail++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lenWithInvisibleTail;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(naked) void TextRenderer::Field_AdjustScroll_PrintLen_Stub()
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
push eax
|
||||||
|
pushad
|
||||||
|
|
||||||
|
push esi
|
||||||
|
push [esp + 0x8 + 0x24]
|
||||||
|
call SEH_PrintStrlenWithCursor
|
||||||
|
add esp, 0x8
|
||||||
|
mov [esp + 0x20], eax
|
||||||
|
|
||||||
|
popad
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TextRenderer::PatchColorLimit(const char limit)
|
void TextRenderer::PatchColorLimit(const char limit)
|
||||||
{
|
{
|
||||||
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
||||||
Utils::Hook::Set<char>(0x4C1BE4, limit); // No idea :P
|
Utils::Hook::Set<char>(0x4C1BE4, limit); // SEH_PrintStrlen
|
||||||
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
|
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
|
||||||
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
|
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
|
||||||
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
|
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
|
||||||
@ -894,6 +938,9 @@ namespace Components
|
|||||||
// Replace team colors with colorblind team colors when colorblind is enabled
|
// Replace team colors with colorblind team colors when colorblind is enabled
|
||||||
Utils::Hook(0x406530, GetUnpackedColorByNameStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x406530, GetUnpackedColorByNameStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
PatchColorLimit(COLOR_LAST_CHAR);
|
PatchColorLimit(COLOR_LAST_CHAR);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -94,6 +94,9 @@ namespace Components
|
|||||||
private:
|
private:
|
||||||
static unsigned HsvToRgb(HsvColor hsv);
|
static unsigned HsvToRgb(HsvColor hsv);
|
||||||
|
|
||||||
|
static int SEH_PrintStrlenWithCursor(const char* string, const Game::field_t* field);
|
||||||
|
static void Field_AdjustScroll_PrintLen_Stub();
|
||||||
|
|
||||||
static void PatchColorLimit(char limit);
|
static void PatchColorLimit(char limit);
|
||||||
static bool Dvar_GetUnpackedColorByName(const char* name, float* expandedColor);
|
static bool Dvar_GetUnpackedColorByName(const char* name, float* expandedColor);
|
||||||
static void GetUnpackedColorByNameStub();
|
static void GetUnpackedColorByNameStub();
|
||||||
|
@ -5287,6 +5287,17 @@ namespace Game
|
|||||||
FONTPASS_COUNT = 0x3,
|
FONTPASS_COUNT = 0x3,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct field_t
|
||||||
|
{
|
||||||
|
int cursor;
|
||||||
|
int scroll;
|
||||||
|
int drawWidth;
|
||||||
|
int widthInPixels;
|
||||||
|
float charHeight;
|
||||||
|
int fixedSize;
|
||||||
|
char buffer[256];
|
||||||
|
};
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#ifndef IDA
|
#ifndef IDA
|
||||||
|
Loading…
Reference in New Issue
Block a user