Merge pull request #7797 from Robyt3/Chat-Render-Improvements

Various minor refactoring of chat rendering, fix chat background size
This commit is contained in:
Dennis Felsing 2024-01-13 22:54:36 +00:00 committed by GitHub
commit 3b10500e99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -949,9 +949,7 @@ void CChat::OnPrepareLines(float y)
float x = 5.0f;
float FontSize = this->FontSize();
float ScreenRatio = Graphics()->ScreenAspect();
const bool IsScoreBoardOpen = m_pClient->m_Scoreboard.Active() && (ScreenRatio > 1.7f); // only assume scoreboard when screen ratio is widescreen(something around 16:9)
const bool IsScoreBoardOpen = m_pClient->m_Scoreboard.Active() && (Graphics()->ScreenAspect() > 1.7f); // only assume scoreboard when screen ratio is widescreen(something around 16:9)
const bool ShowLargeArea = m_Show || (m_Mode != MODE_NONE && g_Config.m_ClShowChat == 1) || g_Config.m_ClShowChat == 2;
const bool ForceRecreate = IsScoreBoardOpen != m_PrevScoreBoardShowed || ShowLargeArea != m_PrevShowChat;
m_PrevScoreBoardShowed = IsScoreBoardOpen;
@ -980,63 +978,76 @@ void CChat::OnPrepareLines(float y)
for(int i = 0; i < MAX_LINES; i++)
{
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
CLine &Line = m_aLines[((m_CurrentLine - i) + MAX_LINES) % MAX_LINES];
if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_PrevShowChat)
if(Now > Line.m_Time + 16 * time_freq() && !m_PrevShowChat)
break;
if(m_aLines[r].m_TextContainerIndex.Valid() && !ForceRecreate)
if(Line.m_TextContainerIndex.Valid() && !ForceRecreate)
continue;
TextRender()->DeleteTextContainer(m_aLines[r].m_TextContainerIndex);
Graphics()->DeleteQuadContainer(m_aLines[r].m_QuadContainerIndex);
TextRender()->DeleteTextContainer(Line.m_TextContainerIndex);
Graphics()->DeleteQuadContainer(Line.m_QuadContainerIndex);
char aName[64 + 12] = "";
if(g_Config.m_ClShowIDs && m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
if(g_Config.m_ClShowIDs && Line.m_ClientID >= 0 && Line.m_aName[0] != '\0')
{
if(m_aLines[r].m_ClientID < 10)
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
if(Line.m_ClientID < 10)
str_format(aName, sizeof(aName), "%d: ", Line.m_ClientID);
else
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
str_format(aName, sizeof(aName), "%d: ", Line.m_ClientID);
}
str_append(aName, m_aLines[r].m_aName);
str_append(aName, Line.m_aName);
char aCount[12];
if(m_aLines[r].m_ClientID < 0)
str_format(aCount, sizeof(aCount), "[%d] ", m_aLines[r].m_TimesRepeated + 1);
if(Line.m_ClientID < 0)
str_format(aCount, sizeof(aCount), "[%d] ", Line.m_TimesRepeated + 1);
else
str_format(aCount, sizeof(aCount), " [%d]", m_aLines[r].m_TimesRepeated + 1);
str_format(aCount, sizeof(aCount), " [%d]", Line.m_TimesRepeated + 1);
const char *pText = Line.m_aText;
if(Config()->m_ClStreamerMode && Line.m_ClientID == SERVER_MSG)
{
if(str_startswith(Line.m_aText, "Team save in progress. You'll be able to load with '/load") && str_endswith(Line.m_aText, "if it fails"))
{
pText = "Team save in progress. You'll be able to load with '/load ***' if save is successful or with '/load *** *** ***' if it fails";
}
else if(str_startswith(Line.m_aText, "Team successfully saved by ") && str_endswith(Line.m_aText, " to continue"))
{
pText = "Team successfully saved by ***. Use '/load ***' to continue";
}
}
if(g_Config.m_ClChatOld)
{
m_aLines[r].m_HasRenderTee = false;
Line.m_HasRenderTee = false;
}
// get the y offset (calculate it if we haven't done that yet)
if(m_aLines[r].m_aYOffset[OffsetType] < 0.0f)
if(Line.m_aYOffset[OffsetType] < 0.0f)
{
TextRender()->SetCursor(&Cursor, TextBegin, 0.0f, FontSize, 0);
Cursor.m_LineWidth = LineWidth;
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
if(Line.m_ClientID >= 0 && Line.m_aName[0] != '\0')
{
Cursor.m_X += RealMsgPaddingTee;
if(m_aLines[r].m_Friend && g_Config.m_ClMessageFriend)
if(Line.m_Friend && g_Config.m_ClMessageFriend)
{
TextRender()->TextEx(&Cursor, "", -1);
TextRender()->TextEx(&Cursor, "");
}
}
TextRender()->TextEx(&Cursor, aName, -1);
if(m_aLines[r].m_TimesRepeated > 0)
TextRender()->TextEx(&Cursor, aCount, -1);
TextRender()->TextEx(&Cursor, aName);
if(Line.m_TimesRepeated > 0)
TextRender()->TextEx(&Cursor, aCount);
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
if(Line.m_ClientID >= 0 && Line.m_aName[0] != '\0')
{
TextRender()->TextEx(&Cursor, ": ", -1);
TextRender()->TextEx(&Cursor, ": ");
}
CTextCursor AppendCursor = Cursor;
@ -1047,84 +1058,82 @@ void CChat::OnPrepareLines(float y)
AppendCursor.m_LineWidth -= Cursor.m_LongestLineWidth;
}
TextRender()->TextEx(&AppendCursor, m_aLines[r].m_aText, -1);
TextRender()->TextEx(&AppendCursor, pText);
m_aLines[r].m_aYOffset[OffsetType] = AppendCursor.m_Y + AppendCursor.m_FontSize + RealMsgPaddingY;
Line.m_aYOffset[OffsetType] = AppendCursor.Height() + RealMsgPaddingY;
}
y -= m_aLines[r].m_aYOffset[OffsetType];
y -= Line.m_aYOffset[OffsetType];
// cut off if msgs waste too much space
if(y < HeightLimit)
break;
// the position the text was created
m_aLines[r].m_TextYOffset = y + RealMsgPaddingY / 2.f;
Line.m_TextYOffset = y + RealMsgPaddingY / 2.f;
int CurRenderFlags = TextRender()->GetRenderFlags();
TextRender()->SetRenderFlags(CurRenderFlags | ETextRenderFlags::TEXT_RENDER_FLAG_NO_AUTOMATIC_QUAD_UPLOAD);
// reset the cursor
TextRender()->SetCursor(&Cursor, TextBegin, m_aLines[r].m_TextYOffset, FontSize, TEXTFLAG_RENDER);
TextRender()->SetCursor(&Cursor, TextBegin, Line.m_TextYOffset, FontSize, TEXTFLAG_RENDER);
Cursor.m_LineWidth = LineWidth;
// Message is from valid player
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
if(Line.m_ClientID >= 0 && Line.m_aName[0] != '\0')
{
Cursor.m_X += RealMsgPaddingTee;
if(m_aLines[r].m_Friend && g_Config.m_ClMessageFriend)
if(Line.m_Friend && g_Config.m_ClMessageFriend)
{
const char *pHeartStr = "";
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageFriendColor));
TextRender()->TextColor(rgb.WithAlpha(1.f));
TextRender()->CreateOrAppendTextContainer(m_aLines[r].m_TextContainerIndex, &Cursor, pHeartStr);
TextRender()->TextColor(color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageFriendColor)).WithAlpha(1.f));
TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, "");
}
}
// render name
ColorRGBA NameColor;
if(m_aLines[r].m_ClientID == SERVER_MSG)
if(Line.m_ClientID == SERVER_MSG)
NameColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageSystemColor));
else if(m_aLines[r].m_ClientID == CLIENT_MSG)
else if(Line.m_ClientID == CLIENT_MSG)
NameColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageClientColor));
else if(m_aLines[r].m_Team)
else if(Line.m_Team)
NameColor = CalculateNameColor(ColorHSLA(g_Config.m_ClMessageTeamColor));
else if(m_aLines[r].m_NameColor == TEAM_RED)
else if(Line.m_NameColor == TEAM_RED)
NameColor = ColorRGBA(1.0f, 0.5f, 0.5f, 1.f);
else if(m_aLines[r].m_NameColor == TEAM_BLUE)
else if(Line.m_NameColor == TEAM_BLUE)
NameColor = ColorRGBA(0.7f, 0.7f, 1.0f, 1.f);
else if(m_aLines[r].m_NameColor == TEAM_SPECTATORS)
else if(Line.m_NameColor == TEAM_SPECTATORS)
NameColor = ColorRGBA(0.75f, 0.5f, 0.75f, 1.f);
else if(m_aLines[r].m_ClientID >= 0 && g_Config.m_ClChatTeamColors && m_pClient->m_Teams.Team(m_aLines[r].m_ClientID))
NameColor = m_pClient->GetDDTeamColor(m_pClient->m_Teams.Team(m_aLines[r].m_ClientID), 0.75f);
else if(Line.m_ClientID >= 0 && g_Config.m_ClChatTeamColors && m_pClient->m_Teams.Team(Line.m_ClientID))
NameColor = m_pClient->GetDDTeamColor(m_pClient->m_Teams.Team(Line.m_ClientID), 0.75f);
else
NameColor = ColorRGBA(0.8f, 0.8f, 0.8f, 1.f);
TextRender()->TextColor(NameColor);
TextRender()->CreateOrAppendTextContainer(m_aLines[r].m_TextContainerIndex, &Cursor, aName);
TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, aName);
if(m_aLines[r].m_TimesRepeated > 0)
if(Line.m_TimesRepeated > 0)
{
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 0.3f);
TextRender()->CreateOrAppendTextContainer(m_aLines[r].m_TextContainerIndex, &Cursor, aCount);
TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, aCount);
}
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
if(Line.m_ClientID >= 0 && Line.m_aName[0] != '\0')
{
TextRender()->TextColor(NameColor);
TextRender()->CreateOrAppendTextContainer(m_aLines[r].m_TextContainerIndex, &Cursor, ": ");
TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &Cursor, ": ");
}
// render line
ColorRGBA Color;
if(m_aLines[r].m_ClientID == SERVER_MSG)
if(Line.m_ClientID == SERVER_MSG)
Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageSystemColor));
else if(m_aLines[r].m_ClientID == CLIENT_MSG)
else if(Line.m_ClientID == CLIENT_MSG)
Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageClientColor));
else if(m_aLines[r].m_Highlighted)
else if(Line.m_Highlighted)
Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageHighlightColor));
else if(m_aLines[r].m_Team)
else if(Line.m_Team)
Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageTeamColor));
else // regular message
Color = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageColor));
@ -1133,34 +1142,32 @@ void CChat::OnPrepareLines(float y)
CTextCursor AppendCursor = Cursor;
AppendCursor.m_LongestLineWidth = 0.0f;
float OriginalWidth = 0.0f;
if(!IsScoreBoardOpen && !g_Config.m_ClChatOld)
{
AppendCursor.m_StartX = Cursor.m_X;
AppendCursor.m_LineWidth -= Cursor.m_LongestLineWidth;
OriginalWidth = Cursor.m_LongestLineWidth;
}
const char *pText = m_aLines[r].m_aText;
if(Config()->m_ClStreamerMode && m_aLines[r].m_ClientID == SERVER_MSG)
{
if(str_startswith(m_aLines[r].m_aText, "Team save in progress. You'll be able to load with '/load") && str_endswith(m_aLines[r].m_aText, "if it fails"))
pText = "Team save in progress. You'll be able to load with '/load ***' if save is successful or with '/load *** *** ***' if it fails";
else if(str_startswith(m_aLines[r].m_aText, "Team successfully saved by ") && str_endswith(m_aLines[r].m_aText, " to continue"))
pText = "Team successfully saved by ***. Use '/load ***' to continue";
}
TextRender()->CreateOrAppendTextContainer(m_aLines[r].m_TextContainerIndex, &AppendCursor, pText);
TextRender()->CreateOrAppendTextContainer(Line.m_TextContainerIndex, &AppendCursor, pText);
if(!g_Config.m_ClChatOld && (m_aLines[r].m_aText[0] != '\0' || m_aLines[r].m_aName[0] != '\0'))
if(!g_Config.m_ClChatOld && (Line.m_aText[0] != '\0' || Line.m_aName[0] != '\0'))
{
float Height = m_aLines[r].m_aYOffset[OffsetType];
float FullWidth = RealMsgPaddingX * 1.5f;
if(!IsScoreBoardOpen && !g_Config.m_ClChatOld)
{
FullWidth += Cursor.m_LongestLineWidth + AppendCursor.m_LongestLineWidth;
}
else
{
FullWidth += maximum(Cursor.m_LongestLineWidth, AppendCursor.m_LongestLineWidth);
}
Graphics()->SetColor(1, 1, 1, 1);
m_aLines[r].m_QuadContainerIndex = Graphics()->CreateRectQuadContainer(Begin, y, OriginalWidth + AppendCursor.m_LongestLineWidth + RealMsgPaddingX * 1.5f, Height, MessageRounding(), IGraphics::CORNER_ALL);
Line.m_QuadContainerIndex = Graphics()->CreateRectQuadContainer(Begin, y, FullWidth, Line.m_aYOffset[OffsetType], MessageRounding(), IGraphics::CORNER_ALL);
}
TextRender()->SetRenderFlags(CurRenderFlags);
if(m_aLines[r].m_TextContainerIndex.Valid())
TextRender()->UploadTextContainer(m_aLines[r].m_TextContainerIndex);
if(Line.m_TextContainerIndex.Valid())
TextRender()->UploadTextContainer(Line.m_TextContainerIndex);
}
TextRender()->TextColor(TextRender()->DefaultTextColor());
@ -1198,13 +1205,13 @@ void CChat::OnRender()
Cursor.m_LineWidth = Width - 190.0f;
if(m_Mode == MODE_ALL)
TextRender()->TextEx(&Cursor, Localize("All"), -1);
TextRender()->TextEx(&Cursor, Localize("All"));
else if(m_Mode == MODE_TEAM)
TextRender()->TextEx(&Cursor, Localize("Team"), -1);
TextRender()->TextEx(&Cursor, Localize("Team"));
else
TextRender()->TextEx(&Cursor, Localize("Chat"), -1);
TextRender()->TextEx(&Cursor, Localize("Chat"));
TextRender()->TextEx(&Cursor, ": ", -1);
TextRender()->TextEx(&Cursor, ": ");
const float MessageMaxWidth = Cursor.m_LineWidth - (Cursor.m_X - Cursor.m_StartX);
const CUIRect ClippingRect = {Cursor.m_X, Cursor.m_Y, MessageMaxWidth, 2.25f * Cursor.m_FontSize};
@ -1248,8 +1255,7 @@ void CChat::OnRender()
OnPrepareLines(y);
float ScreenRatio = Graphics()->ScreenAspect();
bool IsScoreBoardOpen = m_pClient->m_Scoreboard.Active() && (ScreenRatio > 1.7f); // only assume scoreboard when screen ratio is widescreen(something around 16:9)
bool IsScoreBoardOpen = m_pClient->m_Scoreboard.Active() && (Graphics()->ScreenAspect() > 1.7f); // only assume scoreboard when screen ratio is widescreen(something around 16:9)
int64_t Now = time();
float HeightLimit = IsScoreBoardOpen ? 180.0f : (m_PrevShowChat ? 50.0f : 200.0f);
@ -1266,44 +1272,44 @@ void CChat::OnRender()
for(int i = 0; i < MAX_LINES; i++)
{
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_PrevShowChat)
CLine &Line = m_aLines[((m_CurrentLine - i) + MAX_LINES) % MAX_LINES];
if(Now > Line.m_Time + 16 * time_freq() && !m_PrevShowChat)
break;
y -= m_aLines[r].m_aYOffset[OffsetType];
y -= Line.m_aYOffset[OffsetType];
// cut off if msgs waste too much space
if(y < HeightLimit)
break;
float Blend = Now > m_aLines[r].m_Time + 14 * time_freq() && !m_PrevShowChat ? 1.0f - (Now - m_aLines[r].m_Time - 14 * time_freq()) / (2.0f * time_freq()) : 1.0f;
float Blend = Now > Line.m_Time + 14 * time_freq() && !m_PrevShowChat ? 1.0f - (Now - Line.m_Time - 14 * time_freq()) / (2.0f * time_freq()) : 1.0f;
// Draw backgrounds for messages in one batch
if(!g_Config.m_ClChatOld)
{
Graphics()->TextureClear();
if(m_aLines[r].m_QuadContainerIndex != -1)
if(Line.m_QuadContainerIndex != -1)
{
Graphics()->SetColor(0, 0, 0, 0.12f * Blend);
Graphics()->RenderQuadContainerEx(m_aLines[r].m_QuadContainerIndex, 0, -1, 0, ((y + RealMsgPaddingY / 2.0f) - m_aLines[r].m_TextYOffset));
Graphics()->RenderQuadContainerEx(Line.m_QuadContainerIndex, 0, -1, 0, ((y + RealMsgPaddingY / 2.0f) - Line.m_TextYOffset));
}
}
if(m_aLines[r].m_TextContainerIndex.Valid())
if(Line.m_TextContainerIndex.Valid())
{
if(!g_Config.m_ClChatOld && m_aLines[r].m_HasRenderTee)
if(!g_Config.m_ClChatOld && Line.m_HasRenderTee)
{
const int TeeSize = MessageTeeSize();
CTeeRenderInfo RenderInfo;
RenderInfo.m_CustomColoredSkin = m_aLines[r].m_CustomColoredSkin;
if(m_aLines[r].m_CustomColoredSkin)
RenderInfo.m_ColorableRenderSkin = m_aLines[r].m_RenderSkin;
RenderInfo.m_CustomColoredSkin = Line.m_CustomColoredSkin;
if(Line.m_CustomColoredSkin)
RenderInfo.m_ColorableRenderSkin = Line.m_RenderSkin;
else
RenderInfo.m_OriginalRenderSkin = m_aLines[r].m_RenderSkin;
RenderInfo.m_SkinMetrics = m_aLines[r].m_RenderSkinMetrics;
RenderInfo.m_OriginalRenderSkin = Line.m_RenderSkin;
RenderInfo.m_SkinMetrics = Line.m_RenderSkinMetrics;
RenderInfo.m_ColorBody = m_aLines[r].m_ColorBody;
RenderInfo.m_ColorFeet = m_aLines[r].m_ColorFeet;
RenderInfo.m_ColorBody = Line.m_ColorBody;
RenderInfo.m_ColorFeet = Line.m_ColorFeet;
RenderInfo.m_Size = TeeSize;
float RowHeight = FontSize() + RealMsgPaddingY;
@ -1319,7 +1325,7 @@ void CChat::OnRender()
const ColorRGBA TextColor = TextRender()->DefaultTextColor().WithMultipliedAlpha(Blend);
const ColorRGBA TextOutlineColor = TextRender()->DefaultTextOutlineColor().WithMultipliedAlpha(Blend);
TextRender()->RenderTextContainer(m_aLines[r].m_TextContainerIndex, TextColor, TextOutlineColor, 0, (y + RealMsgPaddingY / 2.0f) - m_aLines[r].m_TextYOffset);
TextRender()->RenderTextContainer(Line.m_TextContainerIndex, TextColor, TextOutlineColor, 0, (y + RealMsgPaddingY / 2.0f) - Line.m_TextYOffset);
}
}
}