Make text container index type-safe

Use `STextContainerIndex` wrapper instead of `int` for text container index for type-safety.

Add missing checks to ensure valid text container index before rendering FPS and finish time text containers.
This commit is contained in:
Robert Müller 2023-05-05 15:58:17 +02:00
parent 493f47515c
commit 0c32eacbab
16 changed files with 120 additions and 103 deletions

View file

@ -242,30 +242,30 @@ class CTextRender : public IEngineTextRender
} }
} }
void FreeTextContainerIndex(int &Index) void FreeTextContainerIndex(STextContainerIndex &Index)
{ {
m_vTextContainerIndices[Index] = m_FirstFreeTextContainerIndex; m_vTextContainerIndices[Index.m_Index] = m_FirstFreeTextContainerIndex;
m_FirstFreeTextContainerIndex = Index; m_FirstFreeTextContainerIndex = Index.m_Index;
Index = -1; Index.Reset();
} }
void FreeTextContainer(int &Index) void FreeTextContainer(STextContainerIndex &Index)
{ {
m_vpTextContainers[Index]->Reset(); m_vpTextContainers[Index.m_Index]->Reset();
FreeTextContainerIndex(Index); FreeTextContainerIndex(Index);
} }
STextContainer &GetTextContainer(int Index) STextContainer &GetTextContainer(STextContainerIndex Index)
{ {
dbg_assert(Index >= 0, "Text container index was invalid."); dbg_assert(Index.Valid(), "Text container index was invalid.");
if(Index >= (int)m_vpTextContainers.size()) if(Index.m_Index >= (int)m_vpTextContainers.size())
{ {
int Size = (int)m_vpTextContainers.size(); int Size = (int)m_vpTextContainers.size();
for(int i = 0; i < (Index + 1) - Size; ++i) for(int i = 0; i < (Index.m_Index + 1) - Size; ++i)
m_vpTextContainers.push_back(new STextContainer()); m_vpTextContainers.push_back(new STextContainer());
} }
return *m_vpTextContainers[Index]; return *m_vpTextContainers[Index.m_Index];
} }
int WordLength(const char *pText) const int WordLength(const char *pText) const
@ -921,10 +921,10 @@ public:
{ {
const unsigned OldRenderFlags = m_RenderFlags; const unsigned OldRenderFlags = m_RenderFlags;
m_RenderFlags |= TEXT_RENDER_FLAG_ONE_TIME_USE; m_RenderFlags |= TEXT_RENDER_FLAG_ONE_TIME_USE;
int TextCont = -1; STextContainerIndex TextCont;
CreateTextContainer(TextCont, pCursor, pText, Length); CreateTextContainer(TextCont, pCursor, pText, Length);
m_RenderFlags = OldRenderFlags; m_RenderFlags = OldRenderFlags;
if(TextCont != -1) if(TextCont.Valid())
{ {
if((pCursor->m_Flags & TEXTFLAG_RENDER) != 0) if((pCursor->m_Flags & TEXTFLAG_RENDER) != 0)
{ {
@ -936,10 +936,10 @@ public:
} }
} }
bool CreateTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override bool CreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
{ {
dbg_assert(TextContainerIndex == -1, "Text container index was not cleared."); dbg_assert(!TextContainerIndex.Valid(), "Text container index was not cleared.");
TextContainerIndex = -1; TextContainerIndex.Reset();
CFont *pFont = pCursor->m_pFont; CFont *pFont = pCursor->m_pFont;
@ -952,7 +952,7 @@ public:
const bool IsRendered = (pCursor->m_Flags & TEXTFLAG_RENDER) != 0; const bool IsRendered = (pCursor->m_Flags & TEXTFLAG_RENDER) != 0;
TextContainerIndex = GetFreeTextContainerIndex(); TextContainerIndex.m_Index = GetFreeTextContainerIndex();
STextContainer &TextContainer = GetTextContainer(TextContainerIndex); STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
TextContainer.m_pFont = pFont; TextContainer.m_pFont = pFont;
@ -1018,7 +1018,7 @@ public:
} }
} }
void AppendTextContainer(int TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override void AppendTextContainer(STextContainerIndex TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
{ {
STextContainer &TextContainer = GetTextContainer(TextContainerIndex); STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
str_append(TextContainer.m_aDebugText, pText, sizeof(TextContainer.m_aDebugText)); str_append(TextContainer.m_aDebugText, pText, sizeof(TextContainer.m_aDebugText));
@ -1530,27 +1530,27 @@ public:
TextContainer.m_BoundingBox = pCursor->BoundingBox(); TextContainer.m_BoundingBox = pCursor->BoundingBox();
} }
bool CreateOrAppendTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override bool CreateOrAppendTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
{ {
if(TextContainerIndex == -1) if(TextContainerIndex.Valid())
{
return CreateTextContainer(TextContainerIndex, pCursor, pText, Length);
}
else
{ {
AppendTextContainer(TextContainerIndex, pCursor, pText, Length); AppendTextContainer(TextContainerIndex, pCursor, pText, Length);
return true; return true;
} }
else
{
return CreateTextContainer(TextContainerIndex, pCursor, pText, Length);
}
} }
// just deletes and creates text container // just deletes and creates text container
void RecreateTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override void RecreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
{ {
DeleteTextContainer(TextContainerIndex); DeleteTextContainer(TextContainerIndex);
CreateTextContainer(TextContainerIndex, pCursor, pText, Length); CreateTextContainer(TextContainerIndex, pCursor, pText, Length);
} }
void RecreateTextContainerSoft(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override void RecreateTextContainerSoft(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) override
{ {
STextContainer &TextContainer = GetTextContainer(TextContainerIndex); STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
TextContainer.m_StringInfo.m_vCharacterQuads.clear(); TextContainer.m_StringInfo.m_vCharacterQuads.clear();
@ -1559,9 +1559,9 @@ public:
AppendTextContainer(TextContainerIndex, pCursor, pText, Length); AppendTextContainer(TextContainerIndex, pCursor, pText, Length);
} }
void DeleteTextContainer(int &TextContainerIndex) override void DeleteTextContainer(STextContainerIndex &TextContainerIndex) override
{ {
if(TextContainerIndex == -1) if(!TextContainerIndex.Valid())
return; return;
STextContainer &TextContainer = GetTextContainer(TextContainerIndex); STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
@ -1571,7 +1571,7 @@ public:
FreeTextContainer(TextContainerIndex); FreeTextContainer(TextContainerIndex);
} }
void UploadTextContainer(int TextContainerIndex) override void UploadTextContainer(STextContainerIndex TextContainerIndex) override
{ {
if(Graphics()->IsTextBufferingEnabled()) if(Graphics()->IsTextBufferingEnabled())
{ {
@ -1587,7 +1587,7 @@ public:
} }
} }
void RenderTextContainer(int TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) override void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) override
{ {
const STextContainer &TextContainer = GetTextContainer(TextContainerIndex); const STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
const CFont *pFont = TextContainer.m_pFont; const CFont *pFont = TextContainer.m_pFont;
@ -1678,7 +1678,7 @@ public:
} }
} }
void RenderTextContainer(int TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, float X, float Y) override void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, float X, float Y) override
{ {
STextContainer &TextContainer = GetTextContainer(TextContainerIndex); STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
@ -1706,7 +1706,7 @@ public:
Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1); Graphics()->MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
} }
STextBoundingBox GetBoundingBoxTextContainer(int TextContainerIndex) override STextBoundingBox GetBoundingBoxTextContainer(STextContainerIndex TextContainerIndex) override
{ {
const STextContainer &TextContainer = GetTextContainer(TextContainerIndex); const STextContainer &TextContainer = GetTextContainer(TextContainerIndex);
return TextContainer.m_BoundingBox; return TextContainer.m_BoundingBox;

View file

@ -212,6 +212,15 @@ public:
} }
}; };
struct STextContainerIndex
{
int m_Index;
STextContainerIndex() { Reset(); }
bool Valid() const { return m_Index >= 0; }
void Reset() { m_Index = -1; }
};
class ITextRender : public IInterface class ITextRender : public IInterface
{ {
MACRO_INTERFACE("textrender", 0) MACRO_INTERFACE("textrender", 0)
@ -237,21 +246,21 @@ public:
// //
virtual void TextEx(CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual void TextEx(CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
virtual bool CreateTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual bool CreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
virtual void AppendTextContainer(int TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual void AppendTextContainer(STextContainerIndex TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
// either creates a new text container or appends to a existing one // either creates a new text container or appends to a existing one
virtual bool CreateOrAppendTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual bool CreateOrAppendTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
// just deletes and creates text container // just deletes and creates text container
virtual void RecreateTextContainer(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual void RecreateTextContainer(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
virtual void RecreateTextContainerSoft(int &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0; virtual void RecreateTextContainerSoft(STextContainerIndex &TextContainerIndex, CTextCursor *pCursor, const char *pText, int Length = -1) = 0;
virtual void DeleteTextContainer(int &TextContainerIndex) = 0; virtual void DeleteTextContainer(STextContainerIndex &TextContainerIndex) = 0;
virtual void UploadTextContainer(int TextContainerIndex) = 0; virtual void UploadTextContainer(STextContainerIndex TextContainerIndex) = 0;
virtual void RenderTextContainer(int TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) = 0; virtual void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor) = 0;
virtual void RenderTextContainer(int TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, float X, float Y) = 0; virtual void RenderTextContainer(STextContainerIndex TextContainerIndex, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, float X, float Y) = 0;
virtual STextBoundingBox GetBoundingBoxTextContainer(int TextContainerIndex) = 0; virtual STextBoundingBox GetBoundingBoxTextContainer(STextContainerIndex TextContainerIndex) = 0;
virtual void UploadEntityLayerText(void *pTexBuff, size_t ImageColorChannelCount, int TexWidth, int TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontHeight) = 0; virtual void UploadEntityLayerText(void *pTexBuff, size_t ImageColorChannelCount, int TexWidth, int TexHeight, int TexSubWidth, int TexSubHeight, const char *pText, int Length, float x, float y, int FontHeight) = 0;
virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const = 0; virtual int AdjustFontSize(const char *pText, int TextLength, int MaxSize, int MaxWidth) const = 0;

View file

@ -26,7 +26,7 @@ CChat::CChat()
for(auto &Line : m_aLines) for(auto &Line : m_aLines)
{ {
// reset the container indices, so the text containers can be deleted on reset // reset the container indices, so the text containers can be deleted on reset
Line.m_TextContainerIndex = -1; Line.m_TextContainerIndex.Reset();
Line.m_QuadContainerIndex = -1; Line.m_QuadContainerIndex = -1;
} }
@ -867,7 +867,7 @@ void CChat::OnPrepareLines()
if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_PrevShowChat) if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_PrevShowChat)
break; break;
if(m_aLines[r].m_TextContainerIndex != -1 && !ForceRecreate) if(m_aLines[r].m_TextContainerIndex.Valid() && !ForceRecreate)
continue; continue;
TextRender()->DeleteTextContainer(m_aLines[r].m_TextContainerIndex); TextRender()->DeleteTextContainer(m_aLines[r].m_TextContainerIndex);
@ -1033,7 +1033,7 @@ void CChat::OnPrepareLines()
} }
TextRender()->SetRenderFlags(CurRenderFlags); TextRender()->SetRenderFlags(CurRenderFlags);
if(m_aLines[r].m_TextContainerIndex != -1) if(m_aLines[r].m_TextContainerIndex.Valid())
TextRender()->UploadTextContainer(m_aLines[r].m_TextContainerIndex); TextRender()->UploadTextContainer(m_aLines[r].m_TextContainerIndex);
} }
@ -1159,7 +1159,7 @@ void CChat::OnRender()
} }
} }
if(m_aLines[r].m_TextContainerIndex != -1) if(m_aLines[r].m_TextContainerIndex.Valid())
{ {
if(!g_Config.m_ClChatOld && m_aLines[r].m_HasRenderTee) if(!g_Config.m_ClChatOld && m_aLines[r].m_HasRenderTee)
{ {

View file

@ -40,7 +40,7 @@ class CChat : public CComponent
bool m_Friend; bool m_Friend;
bool m_Highlighted; bool m_Highlighted;
int m_TextContainerIndex; STextContainerIndex m_TextContainerIndex;
int m_QuadContainerIndex; int m_QuadContainerIndex;
char m_aSkinName[std::size(g_Config.m_ClPlayerSkin)]; char m_aSkinName[std::size(g_Config.m_ClPlayerSkin)];

View file

@ -26,7 +26,8 @@ CHud::CHud()
{ {
// won't work if zero // won't work if zero
m_FrameTimeAvg = 0.0f; m_FrameTimeAvg = 0.0f;
m_FPSTextContainerIndex = -1; m_FPSTextContainerIndex.Reset();
m_DDRaceEffectsTextContainerIndex.Reset();
} }
void CHud::ResetHudContainers() void CHud::ResetHudContainers()
@ -219,7 +220,7 @@ void CHud::RenderScoreHud()
Cursor.m_LineWidth = -1; Cursor.m_LineWidth = -1;
TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextScoreContainerIndex, &Cursor, aScoreTeam[t]); TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextScoreContainerIndex, &Cursor, aScoreTeam[t]);
} }
if(m_aScoreInfo[t].m_TextScoreContainerIndex != -1) if(m_aScoreInfo[t].m_TextScoreContainerIndex.Valid())
{ {
ColorRGBA TColor(1.f, 1.f, 1.f, 1.f); ColorRGBA TColor(1.f, 1.f, 1.f, 1.f);
ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f); ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f);
@ -256,7 +257,7 @@ void CHud::RenderScoreHud()
TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_OptionalNameTextContainerIndex, &Cursor, pName); TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_OptionalNameTextContainerIndex, &Cursor, pName);
} }
if(m_aScoreInfo[t].m_OptionalNameTextContainerIndex != -1) if(m_aScoreInfo[t].m_OptionalNameTextContainerIndex.Valid())
{ {
ColorRGBA TColor(1.f, 1.f, 1.f, 1.f); ColorRGBA TColor(1.f, 1.f, 1.f, 1.f);
ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f); ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f);
@ -394,7 +395,7 @@ void CHud::RenderScoreHud()
TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextScoreContainerIndex, &Cursor, aScore[t]); TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextScoreContainerIndex, &Cursor, aScore[t]);
} }
// draw score // draw score
if(m_aScoreInfo[t].m_TextScoreContainerIndex != -1) if(m_aScoreInfo[t].m_TextScoreContainerIndex.Valid())
{ {
ColorRGBA TColor(1.f, 1.f, 1.f, 1.f); ColorRGBA TColor(1.f, 1.f, 1.f, 1.f);
ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f); ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f);
@ -419,7 +420,7 @@ void CHud::RenderScoreHud()
TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_OptionalNameTextContainerIndex, &Cursor, pName); TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_OptionalNameTextContainerIndex, &Cursor, pName);
} }
if(m_aScoreInfo[t].m_OptionalNameTextContainerIndex != -1) if(m_aScoreInfo[t].m_OptionalNameTextContainerIndex.Valid())
{ {
ColorRGBA TColor(1.f, 1.f, 1.f, 1.f); ColorRGBA TColor(1.f, 1.f, 1.f, 1.f);
ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f); ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f);
@ -455,7 +456,7 @@ void CHud::RenderScoreHud()
Cursor.m_LineWidth = -1; Cursor.m_LineWidth = -1;
TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextRankContainerIndex, &Cursor, aBuf); TextRender()->RecreateTextContainer(m_aScoreInfo[t].m_TextRankContainerIndex, &Cursor, aBuf);
} }
if(m_aScoreInfo[t].m_TextRankContainerIndex != -1) if(m_aScoreInfo[t].m_TextRankContainerIndex.Valid())
{ {
ColorRGBA TColor(1.f, 1.f, 1.f, 1.f); ColorRGBA TColor(1.f, 1.f, 1.f, 1.f);
ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f); ColorRGBA TOutlineColor(0.f, 0.f, 0.f, 0.3f);
@ -513,14 +514,17 @@ void CHud::RenderTextInfo()
Cursor.m_LineWidth = -1; Cursor.m_LineWidth = -1;
auto OldFlags = TextRender()->GetRenderFlags(); auto OldFlags = TextRender()->GetRenderFlags();
TextRender()->SetRenderFlags(OldFlags | TEXT_RENDER_FLAG_ONE_TIME_USE); TextRender()->SetRenderFlags(OldFlags | TEXT_RENDER_FLAG_ONE_TIME_USE);
if(m_FPSTextContainerIndex == -1) if(m_FPSTextContainerIndex.Valid())
TextRender()->CreateTextContainer(m_FPSTextContainerIndex, &Cursor, "0");
else
TextRender()->RecreateTextContainerSoft(m_FPSTextContainerIndex, &Cursor, aBuf); TextRender()->RecreateTextContainerSoft(m_FPSTextContainerIndex, &Cursor, aBuf);
else
TextRender()->CreateTextContainer(m_FPSTextContainerIndex, &Cursor, "0");
TextRender()->SetRenderFlags(OldFlags); TextRender()->SetRenderFlags(OldFlags);
ColorRGBA TColor(1, 1, 1, 1); if(m_FPSTextContainerIndex.Valid())
ColorRGBA TOutColor(0, 0, 0, 0.3f); {
TextRender()->RenderTextContainer(m_FPSTextContainerIndex, TColor, TOutColor); ColorRGBA TColor(1, 1, 1, 1);
ColorRGBA TOutColor(0, 0, 0, 0.3f);
TextRender()->RenderTextContainer(m_FPSTextContainerIndex, TColor, TOutColor);
}
} }
if(g_Config.m_ClShowpred) if(g_Config.m_ClShowpred)
{ {
@ -1644,10 +1648,13 @@ void CHud::RenderDDRaceEffects()
Cursor.m_LineWidth = -1.0f; Cursor.m_LineWidth = -1.0f;
TextRender()->AppendTextContainer(m_DDRaceEffectsTextContainerIndex, &Cursor, aBuf); TextRender()->AppendTextContainer(m_DDRaceEffectsTextContainerIndex, &Cursor, aBuf);
} }
auto OutlineColor = TextRender()->DefaultTextOutlineColor(); if(m_DDRaceEffectsTextContainerIndex.Valid())
OutlineColor.a *= Alpha; {
TextRender()->RenderTextContainer(m_DDRaceEffectsTextContainerIndex, TextRender()->DefaultTextColor(), OutlineColor); auto OutlineColor = TextRender()->DefaultTextOutlineColor();
TextRender()->TextColor(1, 1, 1, 1); OutlineColor.a *= Alpha;
TextRender()->RenderTextContainer(m_DDRaceEffectsTextContainerIndex, TextRender()->DefaultTextColor(), OutlineColor);
TextRender()->TextColor(1, 1, 1, 1);
}
} }
else if(!m_ShowFinishTime && m_TimeCpLastReceivedTick + Client()->GameTickSpeed() * 6 > Client()->GameTick(g_Config.m_ClDummy)) else if(!m_ShowFinishTime && m_TimeCpLastReceivedTick + Client()->GameTickSpeed() * 6 > Client()->GameTick(g_Config.m_ClDummy))
{ {
@ -1682,10 +1689,13 @@ void CHud::RenderDDRaceEffects()
Cursor.m_LineWidth = -1.0f; Cursor.m_LineWidth = -1.0f;
TextRender()->RecreateTextContainer(m_DDRaceEffectsTextContainerIndex, &Cursor, aBuf); TextRender()->RecreateTextContainer(m_DDRaceEffectsTextContainerIndex, &Cursor, aBuf);
auto OutlineColor = TextRender()->DefaultTextOutlineColor(); if(m_DDRaceEffectsTextContainerIndex.Valid())
OutlineColor.a *= Alpha; {
TextRender()->RenderTextContainer(m_DDRaceEffectsTextContainerIndex, TextRender()->DefaultTextColor(), OutlineColor); auto OutlineColor = TextRender()->DefaultTextOutlineColor();
TextRender()->TextColor(1, 1, 1, 1); OutlineColor.a *= Alpha;
TextRender()->RenderTextContainer(m_DDRaceEffectsTextContainerIndex, TextRender()->DefaultTextColor(), OutlineColor);
TextRender()->TextColor(1, 1, 1, 1);
}
} }
} }
} }

View file

@ -13,7 +13,10 @@ struct SScoreInfo
void Reset() void Reset()
{ {
m_TextRankContainerIndex = m_TextScoreContainerIndex = m_RoundRectQuadContainerIndex = m_OptionalNameTextContainerIndex = -1; m_TextRankContainerIndex.Reset();
m_TextScoreContainerIndex.Reset();
m_RoundRectQuadContainerIndex = -1;
m_OptionalNameTextContainerIndex.Reset();
m_aScoreText[0] = 0; m_aScoreText[0] = 0;
m_aRankText[0] = 0; m_aRankText[0] = 0;
m_aPlayerNameText[0] = 0; m_aPlayerNameText[0] = 0;
@ -21,14 +24,14 @@ struct SScoreInfo
m_Initialized = false; m_Initialized = false;
} }
int m_TextRankContainerIndex; STextContainerIndex m_TextRankContainerIndex;
int m_TextScoreContainerIndex; STextContainerIndex m_TextScoreContainerIndex;
float m_ScoreTextWidth; float m_ScoreTextWidth;
char m_aScoreText[16]; char m_aScoreText[16];
char m_aRankText[16]; char m_aRankText[16];
char m_aPlayerNameText[MAX_NAME_LENGTH]; char m_aPlayerNameText[MAX_NAME_LENGTH];
int m_RoundRectQuadContainerIndex; int m_RoundRectQuadContainerIndex;
int m_OptionalNameTextContainerIndex; STextContainerIndex m_OptionalNameTextContainerIndex;
bool m_Initialized; bool m_Initialized;
}; };
@ -40,9 +43,8 @@ class CHud : public CComponent
int m_HudQuadContainerIndex; int m_HudQuadContainerIndex;
SScoreInfo m_aScoreInfo[2]; SScoreInfo m_aScoreInfo[2];
int m_FPSTextContainerIndex; STextContainerIndex m_FPSTextContainerIndex;
STextContainerIndex m_DDRaceEffectsTextContainerIndex;
int m_DDRaceEffectsTextContainerIndex = -1;
void RenderCursor(); void RenderCursor();

View file

@ -64,7 +64,7 @@ void CKillMessages::OnInit()
void CKillMessages::CreateKillmessageNamesIfNotCreated(CKillMsg &Kill) void CKillMessages::CreateKillmessageNamesIfNotCreated(CKillMsg &Kill)
{ {
const float FontSize = 36.0f; const float FontSize = 36.0f;
if(Kill.m_VictimTextContainerIndex == -1 && Kill.m_aVictimName[0] != 0) if(!Kill.m_VictimTextContainerIndex.Valid() && Kill.m_aVictimName[0] != 0)
{ {
Kill.m_VictimTextWidth = TextRender()->TextWidth(FontSize, Kill.m_aVictimName, -1, -1.0f); Kill.m_VictimTextWidth = TextRender()->TextWidth(FontSize, Kill.m_aVictimName, -1, -1.0f);
@ -82,7 +82,7 @@ void CKillMessages::CreateKillmessageNamesIfNotCreated(CKillMsg &Kill)
TextRender()->CreateTextContainer(Kill.m_VictimTextContainerIndex, &Cursor, Kill.m_aVictimName); TextRender()->CreateTextContainer(Kill.m_VictimTextContainerIndex, &Cursor, Kill.m_aVictimName);
} }
if(Kill.m_KillerTextContainerIndex == -1 && Kill.m_aKillerName[0] != 0) if(!Kill.m_KillerTextContainerIndex.Valid() && Kill.m_aKillerName[0] != 0)
{ {
Kill.m_KillerTextWidth = TextRender()->TextWidth(FontSize, Kill.m_aKillerName, -1, -1.0f); Kill.m_KillerTextWidth = TextRender()->TextWidth(FontSize, Kill.m_aKillerName, -1, -1.0f);
@ -281,7 +281,7 @@ void CKillMessages::OnRender()
CreateKillmessageNamesIfNotCreated(m_aKillmsgs[r]); CreateKillmessageNamesIfNotCreated(m_aKillmsgs[r]);
if(m_aKillmsgs[r].m_VictimTextContainerIndex != -1) if(m_aKillmsgs[r].m_VictimTextContainerIndex.Valid())
TextRender()->RenderTextContainer(m_aKillmsgs[r].m_VictimTextContainerIndex, TColor, TOutlineColor, x, y + (46.f - 36.f) / 2.f); TextRender()->RenderTextContainer(m_aKillmsgs[r].m_VictimTextContainerIndex, TColor, TOutlineColor, x, y + (46.f - 36.f) / 2.f);
// render victim tee // render victim tee
@ -369,7 +369,7 @@ void CKillMessages::OnRender()
// render killer name // render killer name
x -= m_aKillmsgs[r].m_KillerTextWidth; x -= m_aKillmsgs[r].m_KillerTextWidth;
if(m_aKillmsgs[r].m_KillerTextContainerIndex != -1) if(m_aKillmsgs[r].m_KillerTextContainerIndex.Valid())
TextRender()->RenderTextContainer(m_aKillmsgs[r].m_KillerTextContainerIndex, TColor, TOutlineColor, x, y + (46.f - 36.f) / 2.f); TextRender()->RenderTextContainer(m_aKillmsgs[r].m_KillerTextContainerIndex, TColor, TOutlineColor, x, y + (46.f - 36.f) / 2.f);
} }

View file

@ -18,24 +18,19 @@ public:
// kill messages // kill messages
struct CKillMsg struct CKillMsg
{ {
CKillMsg()
{
m_KillerTextContainerIndex = m_VictimTextContainerIndex = -1;
}
int m_Weapon; int m_Weapon;
int m_VictimID; int m_VictimID;
int m_VictimTeam; int m_VictimTeam;
int m_VictimDDTeam; int m_VictimDDTeam;
char m_aVictimName[64]; char m_aVictimName[64];
int m_VictimTextContainerIndex; STextContainerIndex m_VictimTextContainerIndex;
float m_VictimTextWidth; float m_VictimTextWidth;
CTeeRenderInfo m_VictimRenderInfo[MAX_KILLMSG_TEAM_MEMBERS]; CTeeRenderInfo m_VictimRenderInfo[MAX_KILLMSG_TEAM_MEMBERS];
int m_KillerID; int m_KillerID;
int m_KillerTeam; int m_KillerTeam;
char m_aKillerName[64]; char m_aKillerName[64];
int m_KillerTextContainerIndex; STextContainerIndex m_KillerTextContainerIndex;
float m_KillerTextWidth; float m_KillerTextWidth;
CTeeRenderInfo m_KillerRenderInfo; CTeeRenderInfo m_KillerRenderInfo;

View file

@ -115,9 +115,9 @@ class CMenus : public CComponent
Text.HMargin(pRect->h >= 20.0f ? 2.0f : 1.0f, &Text); Text.HMargin(pRect->h >= 20.0f ? 2.0f : 1.0f, &Text);
Text.HMargin((Text.h * FontFactor) / 2.0f, &Text); Text.HMargin((Text.h * FontFactor) / 2.0f, &Text);
if(!UIElement.AreRectsInit() || HintRequiresStringCheck || HintCanChangePositionOrSize || UIElement.Rect(0)->m_UITextContainer == -1) if(!UIElement.AreRectsInit() || HintRequiresStringCheck || HintCanChangePositionOrSize || !UIElement.Rect(0)->m_UITextContainer.Valid())
{ {
bool NeedsRecalc = !UIElement.AreRectsInit() || UIElement.Rect(0)->m_UITextContainer == -1; bool NeedsRecalc = !UIElement.AreRectsInit() || !UIElement.Rect(0)->m_UITextContainer.Valid();
if(HintCanChangePositionOrSize) if(HintCanChangePositionOrSize)
{ {
if(UIElement.AreRectsInit()) if(UIElement.AreRectsInit())
@ -188,7 +188,7 @@ class CMenus : public CComponent
Graphics()->RenderQuadContainer(UIElement.Rect(Index)->m_UIRectQuadContainer, -1); Graphics()->RenderQuadContainer(UIElement.Rect(Index)->m_UIRectQuadContainer, -1);
ColorRGBA ColorText(TextRender()->DefaultTextColor()); ColorRGBA ColorText(TextRender()->DefaultTextColor());
ColorRGBA ColorTextOutline(TextRender()->DefaultTextOutlineColor()); ColorRGBA ColorTextOutline(TextRender()->DefaultTextOutlineColor());
if(UIElement.Rect(0)->m_UITextContainer != -1) if(UIElement.Rect(0)->m_UITextContainer.Valid())
TextRender()->RenderTextContainer(UIElement.Rect(0)->m_UITextContainer, ColorText, ColorTextOutline); TextRender()->RenderTextContainer(UIElement.Rect(0)->m_UITextContainer, ColorText, ColorTextOutline);
return UI()->DoButtonLogic(pID, Checked, pRect); return UI()->DoButtonLogic(pID, Checked, pRect);
} }
@ -505,7 +505,7 @@ protected:
void RenderStartMenu(CUIRect MainView); void RenderStartMenu(CUIRect MainView);
// found in menus_ingame.cpp // found in menus_ingame.cpp
int m_MotdTextContainerIndex = -1; STextContainerIndex m_MotdTextContainerIndex;
void RenderGame(CUIRect MainView); void RenderGame(CUIRect MainView);
void PopupConfirmDisconnect(); void PopupConfirmDisconnect();
void PopupConfirmDisconnectDummy(); void PopupConfirmDisconnectDummy();

View file

@ -504,7 +504,7 @@ void CMenus::RenderServerInfoMotd(CUIRect Motd)
static float s_MotdHeight = 0.0f; static float s_MotdHeight = 0.0f;
static int64_t s_MotdLastUpdateTime = -1; static int64_t s_MotdLastUpdateTime = -1;
if(m_MotdTextContainerIndex == -1 || s_MotdLastUpdateTime == -1 || s_MotdLastUpdateTime != m_pClient->m_Motd.ServerMotdUpdateTime()) if(!m_MotdTextContainerIndex.Valid() || s_MotdLastUpdateTime == -1 || s_MotdLastUpdateTime != m_pClient->m_Motd.ServerMotdUpdateTime())
{ {
CTextCursor Cursor; CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, MotdFontSize, TEXTFLAG_RENDER); TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, MotdFontSize, TEXTFLAG_RENDER);
@ -518,7 +518,7 @@ void CMenus::RenderServerInfoMotd(CUIRect Motd)
Motd.HSplitTop(s_MotdHeight, &MotdTextArea, &Motd); Motd.HSplitTop(s_MotdHeight, &MotdTextArea, &Motd);
s_ScrollRegion.AddRect(MotdTextArea); s_ScrollRegion.AddRect(MotdTextArea);
if(m_MotdTextContainerIndex != -1) if(m_MotdTextContainerIndex.Valid())
TextRender()->RenderTextContainer(m_MotdTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), MotdTextArea.x, MotdTextArea.y); TextRender()->RenderTextContainer(m_MotdTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), MotdTextArea.x, MotdTextArea.y);
s_ScrollRegion.End(); s_ScrollRegion.End();

View file

@ -73,7 +73,7 @@ void CMotd::OnRender()
const float TextX = RectX + FontSize; const float TextX = RectX + FontSize;
const float TextY = RectY + FontSize; const float TextY = RectY + FontSize;
if(m_TextContainerIndex == -1) if(!m_TextContainerIndex.Valid())
{ {
CTextCursor Cursor; CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, TextX, TextY, FontSize, TEXTFLAG_RENDER); TextRender()->SetCursor(&Cursor, TextX, TextY, FontSize, TEXTFLAG_RENDER);
@ -81,7 +81,7 @@ void CMotd::OnRender()
TextRender()->CreateTextContainer(m_TextContainerIndex, &Cursor, ServerMotd()); TextRender()->CreateTextContainer(m_TextContainerIndex, &Cursor, ServerMotd());
} }
if(m_TextContainerIndex != -1) if(m_TextContainerIndex.Valid())
TextRender()->RenderTextContainer(m_TextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor()); TextRender()->RenderTextContainer(m_TextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor());
} }

View file

@ -13,7 +13,7 @@ class CMotd : public CComponent
int64_t m_ServerMotdTime; int64_t m_ServerMotdTime;
int64_t m_ServerMotdUpdateTime; int64_t m_ServerMotdUpdateTime;
int m_RectQuadContainer = -1; int m_RectQuadContainer = -1;
int m_TextContainerIndex = -1; STextContainerIndex m_TextContainerIndex;
public: public:
CMotd(); CMotd();

View file

@ -159,7 +159,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP
TOutlineColor.a *= Alpha; TOutlineColor.a *= Alpha;
TColor.a *= Alpha; TColor.a *= Alpha;
if(m_aNamePlates[ClientID].m_NameTextContainerIndex != -1) if(m_aNamePlates[ClientID].m_NameTextContainerIndex.Valid())
{ {
YOffset -= FontSize; YOffset -= FontSize;
TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_NameTextContainerIndex, TColor, TOutlineColor, Position.x - tw / 2.0f, YOffset); TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_NameTextContainerIndex, TColor, TOutlineColor, Position.x - tw / 2.0f, YOffset);
@ -168,7 +168,7 @@ void CNamePlates::RenderNameplatePos(vec2 Position, const CNetObj_PlayerInfo *pP
if(g_Config.m_ClNameplatesClan) if(g_Config.m_ClNameplatesClan)
{ {
YOffset -= FontSizeClan; YOffset -= FontSizeClan;
if(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex != -1) if(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex.Valid())
TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex, TColor, TOutlineColor, Position.x - m_aNamePlates[ClientID].m_ClanNameTextWidth / 2.0f, YOffset); TextRender()->RenderTextContainer(m_aNamePlates[ClientID].m_ClanNameTextContainerIndex, TColor, TOutlineColor, Position.x - m_aNamePlates[ClientID].m_ClanNameTextWidth / 2.0f, YOffset);
} }

View file

@ -20,7 +20,8 @@ struct SPlayerNamePlate
void Reset() void Reset()
{ {
m_NameTextContainerIndex = m_ClanNameTextContainerIndex = -1; m_NameTextContainerIndex.Reset();
m_ClanNameTextContainerIndex.Reset();
m_aName[0] = 0; m_aName[0] = 0;
m_aClanName[0] = 0; m_aClanName[0] = 0;
m_NameTextWidth = m_ClanNameTextWidth = 0.f; m_NameTextWidth = m_ClanNameTextWidth = 0.f;
@ -29,12 +30,12 @@ struct SPlayerNamePlate
char m_aName[MAX_NAME_LENGTH]; char m_aName[MAX_NAME_LENGTH];
float m_NameTextWidth; float m_NameTextWidth;
int m_NameTextContainerIndex; STextContainerIndex m_NameTextContainerIndex;
float m_NameTextFontSize; float m_NameTextFontSize;
char m_aClanName[MAX_CLAN_LENGTH]; char m_aClanName[MAX_CLAN_LENGTH];
float m_ClanNameTextWidth; float m_ClanNameTextWidth;
int m_ClanNameTextContainerIndex; STextContainerIndex m_ClanNameTextContainerIndex;
float m_ClanNameTextFontSize; float m_ClanNameTextFontSize;
}; };

View file

@ -36,7 +36,7 @@ CUIElement::SUIElementRect::SUIElementRect() { Reset(); }
void CUIElement::SUIElementRect::Reset() void CUIElement::SUIElementRect::Reset()
{ {
m_UIRectQuadContainer = -1; m_UIRectQuadContainer = -1;
m_UITextContainer = -1; m_UITextContainer.Reset();
m_X = -1; m_X = -1;
m_Y = -1; m_Y = -1;
m_Width = -1; m_Width = -1;
@ -634,7 +634,7 @@ void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRe
{ {
bool NeedsRecreate = false; bool NeedsRecreate = false;
bool ColorChanged = RectEl.m_TextColor != TextRender()->GetTextColor() || RectEl.m_TextOutlineColor != TextRender()->GetTextOutlineColor(); bool ColorChanged = RectEl.m_TextColor != TextRender()->GetTextColor() || RectEl.m_TextOutlineColor != TextRender()->GetTextOutlineColor();
if(RectEl.m_UITextContainer == -1 || RectEl.m_Width != pRect->w || RectEl.m_Height != pRect->h || ColorChanged) if(!RectEl.m_UITextContainer.Valid() || RectEl.m_Width != pRect->w || RectEl.m_Height != pRect->h || ColorChanged)
{ {
NeedsRecreate = true; NeedsRecreate = true;
} }
@ -681,7 +681,7 @@ void CUI::DoLabelStreamed(CUIElement::SUIElementRect &RectEl, const CUIRect *pRe
ColorRGBA ColorText(RectEl.m_TextColor); ColorRGBA ColorText(RectEl.m_TextColor);
ColorRGBA ColorTextOutline(RectEl.m_TextOutlineColor); ColorRGBA ColorTextOutline(RectEl.m_TextOutlineColor);
if(RectEl.m_UITextContainer != -1) if(RectEl.m_UITextContainer.Valid())
{ {
const vec2 CursorPos = CalcAlignedCursorPos(pRect, vec2(RectEl.m_Cursor.m_LongestLineWidth, RectEl.m_Cursor.Height()), Align); const vec2 CursorPos = CalcAlignedCursorPos(pRect, vec2(RectEl.m_Cursor.m_LongestLineWidth, RectEl.m_Cursor.Height()), Align);
TextRender()->RenderTextContainer(RectEl.m_UITextContainer, ColorText, ColorTextOutline, CursorPos.x, CursorPos.y); TextRender()->RenderTextContainer(RectEl.m_UITextContainer, ColorText, ColorTextOutline, CursorPos.x, CursorPos.y);

View file

@ -143,7 +143,7 @@ public:
public: public:
int m_UIRectQuadContainer; int m_UIRectQuadContainer;
int m_UITextContainer; STextContainerIndex m_UITextContainer;
float m_X; float m_X;
float m_Y; float m_Y;