From de99fecaa0150ea7c2236d09f4d9f8504b8622bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sun, 19 Feb 2023 12:17:56 +0100 Subject: [PATCH] Use text container for ingame server info MOTD Optimize MOTD rendering in ingame menu by caching the text. Use the correct text height based on the aligned font size instead of the original font size, to fix the discrepancy between the scrollable height and the text height. --- src/game/client/components/menus.cpp | 8 ++++++ src/game/client/components/menus.h | 3 +++ src/game/client/components/menus_ingame.cpp | 27 ++++++++++++++++++--- src/game/client/components/motd.cpp | 10 +++++++- src/game/client/components/motd.h | 4 ++- 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 176bf7fac..cbcbcf1fe 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -2332,6 +2332,9 @@ void CMenus::OnStateChange(int NewState, int OldState) // reset active item UI()->SetActiveItem(nullptr); + if(OldState == IClient::STATE_ONLINE || OldState == IClient::STATE_OFFLINE) + TextRender()->DeleteTextContainer(m_MotdTextContainerIndex); + if(NewState == IClient::STATE_OFFLINE) { if(OldState >= IClient::STATE_ONLINE && NewState < IClient::STATE_QUITTING) @@ -2370,6 +2373,11 @@ void CMenus::OnStateChange(int NewState, int OldState) } } +void CMenus::OnWindowResize() +{ + TextRender()->DeleteTextContainer(m_MotdTextContainerIndex); +} + void CMenus::OnRender() { UI()->StartCheck(); diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 3cd05b500..1e28a672a 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -513,11 +513,13 @@ protected: void RenderStartMenu(CUIRect MainView); // found in menus_ingame.cpp + int m_MotdTextContainerIndex = -1; void RenderGame(CUIRect MainView); void PopupConfirmDisconnect(); void PopupConfirmDisconnectDummy(); void RenderPlayers(CUIRect MainView); void RenderServerInfo(CUIRect MainView); + void RenderServerInfoMotd(CUIRect Motd); void RenderServerControl(CUIRect MainView); bool RenderServerControlKick(CUIRect MainView, bool FilterSpectators); bool RenderServerControlServer(CUIRect MainView); @@ -590,6 +592,7 @@ public: void OnConsoleInit() override; virtual void OnStateChange(int NewState, int OldState) override; + virtual void OnWindowResize() override; virtual void OnReset() override; virtual void OnRender() override; virtual bool OnInput(IInput::CEvent Event) override; diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index 511dd29a0..3af56ab90 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -475,7 +475,11 @@ void CMenus::RenderServerInfo(CUIRect MainView) TextRender()->Text(GameInfo.x + x, GameInfo.y + y, 20, aBuf, GameInfo.w - 10.0f); } - // motd + RenderServerInfoMotd(Motd); +} + +void CMenus::RenderServerInfoMotd(CUIRect Motd) +{ const float MotdFontSize = 16.0f; Motd.HSplitTop(10.0f, nullptr, &Motd); Motd.Draw(ColorRGBA(1, 1, 1, 0.25f), IGraphics::CORNER_ALL, 10.0f); @@ -487,6 +491,9 @@ void CMenus::RenderServerInfo(CUIRect MainView) Motd.HSplitTop(5.0f, nullptr, &Motd); TextRender()->Text(MotdHeader.x, MotdHeader.y, 2.0f * MotdFontSize, Localize("MOTD"), -1.0f); + if(!m_pClient->m_Motd.ServerMotd()[0]) + return; + static CScrollRegion s_ScrollRegion; vec2 ScrollOffset(0.0f, 0.0f); CScrollRegionParams ScrollParams; @@ -494,10 +501,24 @@ void CMenus::RenderServerInfo(CUIRect MainView) s_ScrollRegion.Begin(&Motd, &ScrollOffset, &ScrollParams); Motd.y += ScrollOffset.y; + static float s_MotdHeight = 0.0f; + static int64_t s_MotdLastUpdateTime = -1; + if(m_MotdTextContainerIndex == -1 || s_MotdLastUpdateTime == -1 || s_MotdLastUpdateTime != m_pClient->m_Motd.ServerMotdUpdateTime()) + { + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, 0.0f, 0.0f, MotdFontSize, TEXTFLAG_RENDER); + Cursor.m_LineWidth = Motd.w; + TextRender()->RecreateTextContainer(m_MotdTextContainerIndex, &Cursor, m_pClient->m_Motd.ServerMotd()); + s_MotdHeight = Cursor.Height(); + s_MotdLastUpdateTime = m_pClient->m_Motd.ServerMotdUpdateTime(); + } + CUIRect MotdTextArea; - Motd.HSplitTop((str_countchr(m_pClient->m_Motd.ServerMotd(), '\n') + 1) * MotdFontSize, &MotdTextArea, &Motd); + Motd.HSplitTop(s_MotdHeight, &MotdTextArea, &Motd); s_ScrollRegion.AddRect(MotdTextArea); - TextRender()->Text(MotdTextArea.x, MotdTextArea.y, MotdFontSize, m_pClient->m_Motd.ServerMotd(), MotdTextArea.w); + + if(m_MotdTextContainerIndex != -1) + TextRender()->RenderTextContainer(m_MotdTextContainerIndex, TextRender()->DefaultTextColor(), TextRender()->DefaultTextOutlineColor(), MotdTextArea.x, MotdTextArea.y); s_ScrollRegion.End(); } diff --git a/src/game/client/components/motd.cpp b/src/game/client/components/motd.cpp index 9c250c133..23db5cbb6 100644 --- a/src/game/client/components/motd.cpp +++ b/src/game/client/components/motd.cpp @@ -10,6 +10,13 @@ #include "motd.h" +CMotd::CMotd() +{ + m_aServerMotd[0] = '\0'; + m_ServerMotdTime = 0; + m_ServerMotdUpdateTime = 0; +} + void CMotd::Clear() { m_ServerMotdTime = 0; @@ -112,8 +119,9 @@ void CMotd::OnMessage(int MsgType, void *pRawMsg) if(g_Config.m_ClPrintMotd && *pLast != '\0') m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast(ColorHSLA(g_Config.m_ClMessageHighlightColor))); + m_ServerMotdUpdateTime = time(); if(m_aServerMotd[0] && g_Config.m_ClMotdTime) - m_ServerMotdTime = time() + time_freq() * g_Config.m_ClMotdTime; + m_ServerMotdTime = m_ServerMotdUpdateTime + time_freq() * g_Config.m_ClMotdTime; else m_ServerMotdTime = 0; TextRender()->DeleteTextContainer(m_TextContainerIndex); diff --git a/src/game/client/components/motd.h b/src/game/client/components/motd.h index db1b3675a..8dc48c66c 100644 --- a/src/game/client/components/motd.h +++ b/src/game/client/components/motd.h @@ -6,16 +6,18 @@ class CMotd : public CComponent { - // motd char m_aServerMotd[900]; int64_t m_ServerMotdTime; + int64_t m_ServerMotdUpdateTime; int m_RectQuadContainer = -1; int m_TextContainerIndex = -1; public: + CMotd(); virtual int Sizeof() const override { return sizeof(*this); } const char *ServerMotd() const { return m_aServerMotd; } + int64_t ServerMotdUpdateTime() const { return m_ServerMotdUpdateTime; } void Clear(); bool IsActive() const;