Use text and quad containers for ingame MOTD, refactor variables

Optimize MOTD rendering by caching the round rect and the text.

Align font and rect sizes so exactly 24 lines of text fit in the MOTD rect with margins on all sizes.
This commit is contained in:
Robert Müller 2023-02-14 23:56:47 +01:00
parent a02738bd2e
commit c286f32b17
2 changed files with 45 additions and 12 deletions

View file

@ -13,6 +13,8 @@
void CMotd::Clear()
{
m_ServerMotdTime = 0;
Graphics()->DeleteQuadContainer(m_RectQuadContainer);
TextRender()->DeleteTextContainer(m_TextContainerIndex);
}
bool CMotd::IsActive() const
@ -26,24 +28,51 @@ void CMotd::OnStateChange(int NewState, int OldState)
Clear();
}
void CMotd::OnWindowResize()
{
Graphics()->DeleteQuadContainer(m_RectQuadContainer);
TextRender()->DeleteTextContainer(m_TextContainerIndex);
}
void CMotd::OnRender()
{
if(!IsActive())
return;
float Width = 400 * 3.0f * Graphics()->ScreenAspect();
float Height = 400 * 3.0f;
const float FontSize = 32.0f; // also the size of the margin and rect rounding
const float ScreenHeight = 40.0f * FontSize; // multiple of the font size to get perfect alignment
const float ScreenWidth = ScreenHeight * Graphics()->ScreenAspect();
Graphics()->MapScreen(0.0f, 0.0f, ScreenWidth, ScreenHeight);
Graphics()->MapScreen(0, 0, Width, Height);
const float RectHeight = 26.0f * FontSize;
const float RectWidth = 630.0f + 2.0f * FontSize;
const float RectX = ScreenWidth / 2.0f - RectWidth / 2.0f;
const float RectY = 160.0f;
float h = 800.0f;
float w = 650.0f;
float x = Width / 2 - w / 2;
float y = 150.0f;
if(m_RectQuadContainer == -1)
{
Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.5f);
m_RectQuadContainer = Graphics()->CreateRectQuadContainer(RectX, RectY, RectWidth, RectHeight, FontSize, IGraphics::CORNER_ALL);
Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
}
Graphics()->DrawRect(x, y, w, h, ColorRGBA(0.0f, 0.0f, 0.0f, 0.5f), IGraphics::CORNER_ALL, 40.0f);
if(m_RectQuadContainer != -1)
Graphics()->RenderQuadContainer(m_RectQuadContainer, -1);
TextRender()->Text(x + 40.0f, y + 40.0f, 32.0f, m_aServerMotd, w - 80.0f);
const float TextWidth = RectWidth - 2.0f * FontSize;
const float TextX = RectX + FontSize;
const float TextY = RectY + FontSize;
if(m_TextContainerIndex == -1)
{
CTextCursor Cursor;
TextRender()->SetCursor(&Cursor, TextX, TextY, FontSize, TEXTFLAG_RENDER);
Cursor.m_LineWidth = TextWidth;
TextRender()->CreateTextContainer(m_TextContainerIndex, &Cursor, ServerMotd());
}
if(m_TextContainerIndex != -1)
TextRender()->RenderTextContainer(m_TextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor());
}
void CMotd::OnMessage(int MsgType, void *pRawMsg)
@ -53,13 +82,13 @@ void CMotd::OnMessage(int MsgType, void *pRawMsg)
if(MsgType == NETMSGTYPE_SV_MOTD)
{
CNetMsg_Sv_Motd *pMsg = (CNetMsg_Sv_Motd *)pRawMsg;
const CNetMsg_Sv_Motd *pMsg = static_cast<CNetMsg_Sv_Motd *>(pRawMsg);
// copy it manually to process all \n
const char *pMsgStr = pMsg->m_pMessage;
int MotdLen = str_length(pMsgStr) + 1;
const size_t MotdLen = str_length(pMsgStr) + 1;
const char *pLast = m_aServerMotd; // for console printing
for(int i = 0, k = 0; i < MotdLen && k < (int)sizeof(m_aServerMotd); i++, k++)
for(size_t i = 0, k = 0; i < MotdLen && k < sizeof(m_aServerMotd); i++, k++)
{
// handle incoming "\\n"
if(pMsgStr[i] == '\\' && pMsgStr[i + 1] == 'n')
@ -87,6 +116,7 @@ void CMotd::OnMessage(int MsgType, void *pRawMsg)
m_ServerMotdTime = time() + time_freq() * g_Config.m_ClMotdTime;
else
m_ServerMotdTime = 0;
TextRender()->DeleteTextContainer(m_TextContainerIndex);
}
}

View file

@ -9,6 +9,8 @@ class CMotd : public CComponent
// motd
char m_aServerMotd[900];
int64_t m_ServerMotdTime;
int m_RectQuadContainer = -1;
int m_TextContainerIndex = -1;
public:
virtual int Sizeof() const override { return sizeof(*this); }
@ -19,6 +21,7 @@ public:
virtual void OnRender() override;
virtual void OnStateChange(int NewState, int OldState) override;
virtual void OnWindowResize() override;
virtual void OnMessage(int MsgType, void *pRawMsg) override;
virtual bool OnInput(IInput::CEvent Event) override;
};