mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-22 02:24:17 +00:00
de99fecaa0
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.
140 lines
4.2 KiB
C++
140 lines
4.2 KiB
C++
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
|
#include <engine/graphics.h>
|
|
#include <engine/keys.h>
|
|
#include <engine/shared/config.h>
|
|
#include <engine/textrender.h>
|
|
|
|
#include <game/client/gameclient.h>
|
|
#include <game/generated/protocol.h>
|
|
|
|
#include "motd.h"
|
|
|
|
CMotd::CMotd()
|
|
{
|
|
m_aServerMotd[0] = '\0';
|
|
m_ServerMotdTime = 0;
|
|
m_ServerMotdUpdateTime = 0;
|
|
}
|
|
|
|
void CMotd::Clear()
|
|
{
|
|
m_ServerMotdTime = 0;
|
|
Graphics()->DeleteQuadContainer(m_RectQuadContainer);
|
|
TextRender()->DeleteTextContainer(m_TextContainerIndex);
|
|
}
|
|
|
|
bool CMotd::IsActive() const
|
|
{
|
|
return time() < m_ServerMotdTime;
|
|
}
|
|
|
|
void CMotd::OnStateChange(int NewState, int OldState)
|
|
{
|
|
if(OldState == IClient::STATE_ONLINE || OldState == IClient::STATE_OFFLINE)
|
|
Clear();
|
|
}
|
|
|
|
void CMotd::OnWindowResize()
|
|
{
|
|
Graphics()->DeleteQuadContainer(m_RectQuadContainer);
|
|
TextRender()->DeleteTextContainer(m_TextContainerIndex);
|
|
}
|
|
|
|
void CMotd::OnRender()
|
|
{
|
|
if(!IsActive())
|
|
return;
|
|
|
|
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);
|
|
|
|
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;
|
|
|
|
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);
|
|
}
|
|
|
|
if(m_RectQuadContainer != -1)
|
|
Graphics()->RenderQuadContainer(m_RectQuadContainer, -1);
|
|
|
|
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)
|
|
{
|
|
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
|
return;
|
|
|
|
if(MsgType == NETMSGTYPE_SV_MOTD)
|
|
{
|
|
const CNetMsg_Sv_Motd *pMsg = static_cast<CNetMsg_Sv_Motd *>(pRawMsg);
|
|
|
|
// copy it manually to process all \n
|
|
const char *pMsgStr = pMsg->m_pMessage;
|
|
const size_t MotdLen = str_length(pMsgStr) + 1;
|
|
const char *pLast = m_aServerMotd; // for console printing
|
|
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')
|
|
{
|
|
m_aServerMotd[k] = '\n';
|
|
i++; // skip the 'n'
|
|
}
|
|
else
|
|
m_aServerMotd[k] = pMsgStr[i];
|
|
|
|
// print the line to the console when receiving the newline character
|
|
if(g_Config.m_ClPrintMotd && m_aServerMotd[k] == '\n')
|
|
{
|
|
m_aServerMotd[k] = '\0';
|
|
m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageHighlightColor)));
|
|
m_aServerMotd[k] = '\n';
|
|
pLast = m_aServerMotd + k + 1;
|
|
}
|
|
}
|
|
m_aServerMotd[sizeof(m_aServerMotd) - 1] = '\0';
|
|
if(g_Config.m_ClPrintMotd && *pLast != '\0')
|
|
m_pClient->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "motd", pLast, color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageHighlightColor)));
|
|
|
|
m_ServerMotdUpdateTime = time();
|
|
if(m_aServerMotd[0] && g_Config.m_ClMotdTime)
|
|
m_ServerMotdTime = m_ServerMotdUpdateTime + time_freq() * g_Config.m_ClMotdTime;
|
|
else
|
|
m_ServerMotdTime = 0;
|
|
TextRender()->DeleteTextContainer(m_TextContainerIndex);
|
|
}
|
|
}
|
|
|
|
bool CMotd::OnInput(IInput::CEvent Event)
|
|
{
|
|
if(IsActive() && Event.m_Flags & IInput::FLAG_PRESS && Event.m_Key == KEY_ESCAPE)
|
|
{
|
|
Clear();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|