From 3b0c0885757d3a43be1a040b2169fd1c7d59ad2f Mon Sep 17 00:00:00 2001 From: LordSk Date: Sat, 24 Nov 2018 20:43:48 +0100 Subject: [PATCH 01/10] Setting up the display part --- src/game/client/components/hud.cpp | 147 +++++++++++++++++++++++++++++ src/game/client/components/hud.h | 20 ++++ 2 files changed, 167 insertions(+) diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 77c843c43..1219d127e 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -17,6 +17,9 @@ #include "hud.h" #include "voting.h" #include "binds.h" +#include "chat.h" +#include "scoreboard.h" +#include "motd.h" CHud::CHud() { @@ -24,6 +27,9 @@ CHud::CHud() m_AverageFPS = 1.0f; m_WarmupHideTick = 0; + m_BroadcastColorCount = 0; + m_aBroadcastMsg[0] = 0; + m_BroadcastReceivedTime = 0; } void CHud::OnReset() @@ -31,6 +37,21 @@ void CHud::OnReset() m_WarmupHideTick = 0; } +void CHud::OnMessage(int MsgType, void* pRawMsg) +{ + if(MsgType == NETMSGTYPE_SV_CHAT) + { + CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; + + // new broadcast message + int MsgLen = min((int)MAX_BROADCAST_MSG_LENGTH-1, str_length(pMsg->m_pMessage)); + mem_copy(m_aBroadcastMsg, pMsg->m_pMessage, MsgLen); + m_aBroadcastMsg[MsgLen] = 0; + m_BroadcastColorCount = 0; + m_BroadcastReceivedTime = Client()->LocalTime(); + } +} + void CHud::RenderGameTimer() { float Half = 300.0f*Graphics()->ScreenAspect()/2.0f; @@ -691,6 +712,7 @@ void CHud::OnRender() RenderSuddenDeath(); RenderScoreHud(); RenderWarmupTimer(); + RenderBroadcast(); RenderFps(); if(Client()->State() != IClient::STATE_DEMOPLAYBACK) RenderConnectionWarning(); @@ -699,3 +721,128 @@ void CHud::OnRender() } RenderCursor(); } + +inline int WordLengthBack(const char *pText, int MaxChars) +{ + int s = 0; + while(MaxChars--) + { + if(*pText == '\n' || *pText == '\t' || *pText == ' ') + return s; + pText--; + s++; + } + return s; +} + +void CHud::RenderBroadcast() +{ + const float DisplayDuration = 10.0f; + const float DisplayStartFade = 9.0f; + const float DeltaTime = Client()->LocalTime() - m_BroadcastReceivedTime; + + if(m_aBroadcastMsg[0] == 0 || DeltaTime > DisplayDuration) + return; + + if(m_pClient->m_pScoreboard->Active() || m_pClient->m_pMotd->IsActive() || + m_pClient->m_pChat->IsActive()) + return; + + const float Fade = 1.0f - max(0.0f, (DeltaTime - DisplayStartFade) / (DisplayDuration - DisplayStartFade)); + + CUIRect ScreenRect = {0, 0, m_Width, m_Height}; + const bool IsSpecMode = m_pClient->m_Snap.m_SpecInfo.m_Active; + if(IsSpecMode) + ScreenRect.y -= 20.0f; + + CUIRect BcView = ScreenRect; + BcView.x += m_Width * 0.25f; + BcView.y += m_Height * 0.8f; + BcView.w *= 0.5f; + BcView.h *= 0.2f; + + float FontSize = 11.0f; + + vec4 ColorTop(0, 0, 0, 0); + vec4 ColorBot(0, 0, 0, (IsSpecMode ? 0.2f : 0.4f) * Fade); + CUIRect BgRect; + BcView.HSplitBottom(10.0f, 0, &BgRect); + + RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop, + ColorBot, ColorBot, IsSpecMode ? CUI::CORNER_B:0, + IsSpecMode ? 2.0f:0); + + // server broadcast line + CUIRect TitleRect; + BcView.HSplitBottom(10.0f, &BcView, &TitleRect); + TitleRect.y += 1.5f; + TextRender()->TextColor(1, 1, 1, 0.6f * Fade); + UI()->DoLabel(&TitleRect, Localize("Server broadcast"), 5.5f, CUI::ALIGN_CENTER); + + BcView.VMargin(5.0f, &BcView); + BcView.HSplitBottom(2.0f, &BcView, 0); + + //const char* BroadcastTestMsg = "This is a broadcast message from a server HELLO is anyone here? This is a reaaaaaaallllyyyyy long message wow, perhaps TOO loooooong"; + const char* BroadcastTestMsg = m_aBroadcastMsg; + const int MsgLen = str_length(BroadcastTestMsg); + + // broadcast message + // one line == big font + // > one line == small font + + TextRender()->TextColor(1, 1, 1, 1 * Fade); + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, BroadcastTestMsg, MsgLen); + + if(Cursor.m_LineCount > 1) + { + FontSize = 6.5f; // smaller font + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, BroadcastTestMsg, MsgLen); + } + + const int LineCount = Cursor.m_LineCount; + float y = BcView.y + BcView.h - LineCount * FontSize; + int CurCharCount = 0; + //int i = 0; + while(CurCharCount < MsgLen/* && i++ < 1000*/) + { + const char* RemainingMsg = BroadcastTestMsg + CurCharCount; + + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + + TextRender()->TextEx(&Cursor, RemainingMsg, MsgLen-CurCharCount); + int StrLen = Cursor.m_CharCount; + + if(CurCharCount + StrLen < MsgLen) + { + const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); + if(WorldLen > 0 && WorldLen < StrLen) + { + StrLen -= WorldLen; + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + } + } + + const float TextWidth = Cursor.m_X-Cursor.m_StartX; + CurCharCount += StrLen; + + TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - TextWidth) * 0.5f, y, + FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + + TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + y += FontSize; + + /*dbg_msg("broadcast", "CurCharCount=%d StrLen=%d '%.*s'", CurCharCount, StrLen, + min(MsgLen-CurCharCount, 10), RemainingMsg);*/ + } + + TextRender()->TextColor(1, 1, 1, 1); +} diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 68b1b1770..9d53cf98b 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -3,6 +3,7 @@ #ifndef GAME_CLIENT_COMPONENTS_HUD_H #define GAME_CLIENT_COMPONENTS_HUD_H #include +#include class CHud : public CComponent { @@ -10,6 +11,23 @@ class CHud : public CComponent float m_AverageFPS; int64 m_WarmupHideTick; + // broadcast + typedef unsigned char u8; + struct BcColor + { + u8 r,g,b; + }; + + enum { + MAX_BROADCAST_COLORS = 256, + MAX_BROADCAST_MSG_LENGTH = 256 + }; + + BcColor m_aBroadcastColorList[MAX_BROADCAST_COLORS]; + char m_aBroadcastMsg[MAX_BROADCAST_MSG_LENGTH]; + int m_BroadcastColorCount; + float m_BroadcastReceivedTime; + void RenderCursor(); void RenderFps(); @@ -26,10 +44,12 @@ class CHud : public CComponent void RenderScoreHud(); void RenderSpectatorHud(); void RenderWarmupTimer(); + void RenderBroadcast(); public: CHud(); virtual void OnReset(); + virtual void OnMessage(int MsgType, void *pRawMsg); virtual void OnRender(); }; From 549470980ad830bee73420ebae010da50a749eb2 Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 00:26:18 +0100 Subject: [PATCH 02/10] Fixed some utf8 issues (m_CharCount/m_GlyphCount), added color parsing --- src/engine/client/text.cpp | 15 ++-- src/engine/textrender.h | 1 + src/game/client/components/hud.cpp | 115 +++++++++++++++++++++++++---- src/game/client/components/hud.h | 10 ++- 4 files changed, 115 insertions(+), 26 deletions(-) diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index b3683b1bf..48472a232 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -498,6 +498,7 @@ public: pCursor->m_LineCount = 1; pCursor->m_LineWidth = -1; pCursor->m_Flags = Flags; + pCursor->m_GlyphCount = 0; pCursor->m_CharCount = 0; } @@ -672,7 +673,7 @@ public: { // word can't be fitted in one line, cut it CTextCursor Cutter = *pCursor; - Cutter.m_CharCount = 0; + Cutter.m_GlyphCount = 0; Cutter.m_X = DrawX; Cutter.m_Y = DrawY; Cutter.m_Flags &= ~TEXTFLAG_RENDER; @@ -680,7 +681,7 @@ public: TextDeferredRenderEx(&Cutter, (const char *)pCurrent, Wlen, aQuadChar, QuadCharMaxCount, pQuadCharCount, pFontTexture); - Wlen = Cutter.m_CharCount; + Wlen = Cutter.m_GlyphCount; NewLine = 1; if(Wlen <= 3) // if we can't place 3 chars of the word on this line, take the next @@ -742,7 +743,8 @@ public: } DrawX += Advance*Size; - pCursor->m_CharCount++; + pCursor->m_GlyphCount++; + pCursor->m_CharCount += pTmp-pCurrent; } } @@ -861,14 +863,14 @@ public: { // word can't be fitted in one line, cut it CTextCursor Cutter = *pCursor; - Cutter.m_CharCount = 0; + Cutter.m_GlyphCount = 0; Cutter.m_X = DrawX; Cutter.m_Y = DrawY; Cutter.m_Flags &= ~TEXTFLAG_RENDER; Cutter.m_Flags |= TEXTFLAG_STOP_AT_END; TextEx(&Cutter, (const char *)pCurrent, Wlen); - Wlen = Cutter.m_CharCount; + Wlen = Cutter.m_GlyphCount; NewLine = 1; if(Wlen <= 3) // if we can't place 3 chars of the word on this line, take the next @@ -922,7 +924,8 @@ public: } DrawX += Advance*Size; - pCursor->m_CharCount++; + pCursor->m_GlyphCount++; + pCursor->m_CharCount += pTmp-pCurrent; } } diff --git a/src/engine/textrender.h b/src/engine/textrender.h index a7654e92b..f6e216561 100644 --- a/src/engine/textrender.h +++ b/src/engine/textrender.h @@ -20,6 +20,7 @@ class CTextCursor public: int m_Flags; int m_LineCount; + int m_GlyphCount; int m_CharCount; int m_MaxLines; diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 1219d127e..a1c8369dd 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -37,6 +37,11 @@ void CHud::OnReset() m_WarmupHideTick = 0; } +inline bool IsCharANum(char c) +{ + return c >= '0' && c <= '9'; +} + void CHud::OnMessage(int MsgType, void* pRawMsg) { if(MsgType == NETMSGTYPE_SV_CHAT) @@ -44,11 +49,45 @@ void CHud::OnMessage(int MsgType, void* pRawMsg) CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; // new broadcast message - int MsgLen = min((int)MAX_BROADCAST_MSG_LENGTH-1, str_length(pMsg->m_pMessage)); - mem_copy(m_aBroadcastMsg, pMsg->m_pMessage, MsgLen); - m_aBroadcastMsg[MsgLen] = 0; - m_BroadcastColorCount = 0; + int MsgLen = str_length(pMsg->m_pMessage); + mem_zero(m_aBroadcastMsg, sizeof(m_aBroadcastMsg)); + m_aBroadcastMsgLen = 0; m_BroadcastReceivedTime = Client()->LocalTime(); + + const BcColor White = { 255, 255, 255, 0 }; + m_aBroadcastColorList[0] = White; + m_BroadcastColorCount = 1; + + for(int i = 0; i < MsgLen; i++) + { + const char* c = pMsg->m_pMessage + i; + const char* pTmp = c; + int CharUtf8 = str_utf8_decode(&pTmp); + + if(*c == CharUtf8 && *c == '^') + { + if(i+3 < MsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3])) + { + u8 r = (c[1] - '0') * 24 + 39; + u8 g = (c[2] - '0') * 24 + 39; + u8 b = (c[3] - '0') * 24 + 39; + BcColor Color = { r, g, b, m_aBroadcastMsgLen }; + if(m_BroadcastColorCount < MAX_BROADCAST_COLORS) + m_aBroadcastColorList[m_BroadcastColorCount++] = Color; + i += 3; + continue; + } + } + + if(m_aBroadcastMsgLen < MAX_BROADCAST_MSG_LENGTH) + m_aBroadcastMsg[m_aBroadcastMsgLen++] = *c; + } + + /*for(int i = 0; i < m_BroadcastColorCount; i++) + { + BcColor c = m_aBroadcastColorList[i]; + dbg_msg("colors", "%d %d %d - %d", c.m_R, c.m_G, c.m_B, c.m_CharPos); + }*/ } } @@ -727,12 +766,17 @@ inline int WordLengthBack(const char *pText, int MaxChars) int s = 0; while(MaxChars--) { - if(*pText == '\n' || *pText == '\t' || *pText == ' ') + if((*pText == '\n' || *pText == '\t' || *pText == ' ')) return s; pText--; s++; } - return s; + return 0; +} + +inline bool IsCharWhitespace(char c) +{ + return c == '\n' || c == '\t' || c == ' '; } void CHud::RenderBroadcast() @@ -783,39 +827,39 @@ void CHud::RenderBroadcast() BcView.HSplitBottom(2.0f, &BcView, 0); //const char* BroadcastTestMsg = "This is a broadcast message from a server HELLO is anyone here? This is a reaaaaaaallllyyyyy long message wow, perhaps TOO loooooong"; - const char* BroadcastTestMsg = m_aBroadcastMsg; - const int MsgLen = str_length(BroadcastTestMsg); + const char* BroadcastMsg = m_aBroadcastMsg; + const int MsgLen = str_length(m_aBroadcastMsg);//m_aBroadcastMsgLen; // broadcast message // one line == big font // > one line == small font - TextRender()->TextColor(1, 1, 1, 1 * Fade); CTextCursor Cursor; - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, BroadcastTestMsg, MsgLen); + TextRender()->TextEx(&Cursor, BroadcastMsg, -1); if(Cursor.m_LineCount > 1) { FontSize = 6.5f; // smaller font TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, BroadcastTestMsg, MsgLen); + TextRender()->TextEx(&Cursor, BroadcastMsg, -1); } const int LineCount = Cursor.m_LineCount; float y = BcView.y + BcView.h - LineCount * FontSize; int CurCharCount = 0; + //int i = 0; while(CurCharCount < MsgLen/* && i++ < 1000*/) { - const char* RemainingMsg = BroadcastTestMsg + CurCharCount; + const char* RemainingMsg = BroadcastMsg + CurCharCount; TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, RemainingMsg, MsgLen-CurCharCount); + TextRender()->TextEx(&Cursor, RemainingMsg, -1); int StrLen = Cursor.m_CharCount; if(CurCharCount + StrLen < MsgLen) @@ -831,18 +875,57 @@ void CHud::RenderBroadcast() } const float TextWidth = Cursor.m_X-Cursor.m_StartX; - CurCharCount += StrLen; TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - TextWidth) * 0.5f, y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + int DrawnStrLen = 0; + while(DrawnStrLen < StrLen) + { + int StartColorID = -1; + int ColorStrLen = -1; + + for(int j = 0; j < m_BroadcastColorCount; j++) + { + if((CurCharCount+DrawnStrLen) >= m_aBroadcastColorList[j].m_CharPos) + { + StartColorID = j; + } + else if(StartColorID >= 0) + { + ColorStrLen = m_aBroadcastColorList[j].m_CharPos - m_aBroadcastColorList[StartColorID].m_CharPos; + break; + } + } + + dbg_assert(StartColorID >= 0, "This should not be -1, color not found"); + + if(ColorStrLen == -1) + ColorStrLen = StrLen-DrawnStrLen; + + //dbg_msg("color", "StartColorID=%d ColorStrLen=%d", StartColorID, ColorStrLen); + const BcColor& TextColor = m_aBroadcastColorList[StartColorID]; + int AvgLum = (TextColor.m_R+TextColor.m_G+TextColor.m_B)/3; + + if(AvgLum < 100) + TextRender()->TextOutlineColor(1, 1, 1, 0.8f); + else + TextRender()->TextOutlineColor(0, 0, 0, 0.3f); + + TextRender()->TextColor(TextColor.m_R/255.f, TextColor.m_G/255.f, TextColor.m_B/255.f, Fade); + + TextRender()->TextEx(&Cursor, RemainingMsg+DrawnStrLen, ColorStrLen); + DrawnStrLen += ColorStrLen; + } + y += FontSize; + CurCharCount += StrLen; /*dbg_msg("broadcast", "CurCharCount=%d StrLen=%d '%.*s'", CurCharCount, StrLen, min(MsgLen-CurCharCount, 10), RemainingMsg);*/ } TextRender()->TextColor(1, 1, 1, 1); + TextRender()->TextOutlineColor(0, 0, 0, 0.3f); } diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 9d53cf98b..6077c232b 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -15,16 +15,18 @@ class CHud : public CComponent typedef unsigned char u8; struct BcColor { - u8 r,g,b; + u8 m_R,m_G,m_B; + int m_CharPos; }; enum { - MAX_BROADCAST_COLORS = 256, - MAX_BROADCAST_MSG_LENGTH = 256 + MAX_BROADCAST_COLORS = 128, + MAX_BROADCAST_MSG_LENGTH = 127 }; BcColor m_aBroadcastColorList[MAX_BROADCAST_COLORS]; - char m_aBroadcastMsg[MAX_BROADCAST_MSG_LENGTH]; + char m_aBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; + int m_aBroadcastMsgLen; int m_BroadcastColorCount; float m_BroadcastReceivedTime; From af49073f5579116f4ac09a01c8323d4082bcbbaf Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 01:51:30 +0100 Subject: [PATCH 03/10] A few more fixes, better luminance calculation --- src/engine/client/text.cpp | 4 +- src/game/client/components/hud.cpp | 88 +++++++++++++++++------------- src/game/client/components/hud.h | 4 +- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/engine/client/text.cpp b/src/engine/client/text.cpp index 48472a232..b941f7dc3 100644 --- a/src/engine/client/text.cpp +++ b/src/engine/client/text.cpp @@ -700,6 +700,7 @@ public: int NextCharacter = str_utf8_decode(&pTmp); while(pCurrent < pBatchEnd) { + pCursor->m_CharCount += pTmp-pCurrent; int Character = NextCharacter; pCurrent = pTmp; NextCharacter = str_utf8_decode(&pTmp); @@ -744,7 +745,6 @@ public: DrawX += Advance*Size; pCursor->m_GlyphCount++; - pCursor->m_CharCount += pTmp-pCurrent; } } @@ -889,6 +889,7 @@ public: int NextCharacter = str_utf8_decode(&pTmp); while(pCurrent < pBatchEnd) { + pCursor->m_CharCount += pTmp-pCurrent; int Character = NextCharacter; pCurrent = pTmp; NextCharacter = str_utf8_decode(&pTmp); @@ -925,7 +926,6 @@ public: DrawX += Advance*Size; pCursor->m_GlyphCount++; - pCursor->m_CharCount += pTmp-pCurrent; } } diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index a1c8369dd..e4048a97a 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -54,15 +54,17 @@ void CHud::OnMessage(int MsgType, void* pRawMsg) m_aBroadcastMsgLen = 0; m_BroadcastReceivedTime = Client()->LocalTime(); - const BcColor White = { 255, 255, 255, 0 }; + const CBcColor White = { 255, 255, 255, 0 }; m_aBroadcastColorList[0] = White; m_BroadcastColorCount = 1; + // parse colors for(int i = 0; i < MsgLen; i++) { const char* c = pMsg->m_pMessage + i; const char* pTmp = c; int CharUtf8 = str_utf8_decode(&pTmp); + const int Utf8Len = pTmp-c; if(*c == CharUtf8 && *c == '^') { @@ -71,7 +73,7 @@ void CHud::OnMessage(int MsgType, void* pRawMsg) u8 r = (c[1] - '0') * 24 + 39; u8 g = (c[2] - '0') * 24 + 39; u8 b = (c[3] - '0') * 24 + 39; - BcColor Color = { r, g, b, m_aBroadcastMsgLen }; + CBcColor Color = { r, g, b, m_aBroadcastMsgLen }; if(m_BroadcastColorCount < MAX_BROADCAST_COLORS) m_aBroadcastColorList[m_BroadcastColorCount++] = Color; i += 3; @@ -79,15 +81,9 @@ void CHud::OnMessage(int MsgType, void* pRawMsg) } } - if(m_aBroadcastMsgLen < MAX_BROADCAST_MSG_LENGTH) + if(m_aBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH) m_aBroadcastMsg[m_aBroadcastMsgLen++] = *c; } - - /*for(int i = 0; i < m_BroadcastColorCount; i++) - { - BcColor c = m_aBroadcastColorList[i]; - dbg_msg("colors", "%d %d %d - %d", c.m_R, c.m_G, c.m_B, c.m_CharPos); - }*/ } } @@ -826,9 +822,8 @@ void CHud::RenderBroadcast() BcView.VMargin(5.0f, &BcView); BcView.HSplitBottom(2.0f, &BcView, 0); - //const char* BroadcastTestMsg = "This is a broadcast message from a server HELLO is anyone here? This is a reaaaaaaallllyyyyy long message wow, perhaps TOO loooooong"; - const char* BroadcastMsg = m_aBroadcastMsg; - const int MsgLen = str_length(m_aBroadcastMsg);//m_aBroadcastMsgLen; + const char* pBroadcastMsg = m_aBroadcastMsg; + const int MsgLen = m_aBroadcastMsgLen; // broadcast message // one line == big font @@ -837,24 +832,32 @@ void CHud::RenderBroadcast() CTextCursor Cursor; TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, BroadcastMsg, -1); + TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); + // can't fit on one line, reduce size if(Cursor.m_LineCount > 1) { FontSize = 6.5f; // smaller font - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, BroadcastMsg, -1); + TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); } - const int LineCount = Cursor.m_LineCount; - float y = BcView.y + BcView.h - LineCount * FontSize; - int CurCharCount = 0; - - //int i = 0; - while(CurCharCount < MsgLen/* && i++ < 1000*/) + // make lines + struct CLineInfo { - const char* RemainingMsg = BroadcastMsg + CurCharCount; + const char* m_pStrStart; + int m_StrLen; + float m_Width; + }; + + CLineInfo aLines[10]; + int CurCharCount = 0; + int LineCount = 0; + + while(CurCharCount < MsgLen) + { + const char* RemainingMsg = pBroadcastMsg + CurCharCount; TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; @@ -862,6 +865,7 @@ void CHud::RenderBroadcast() TextRender()->TextEx(&Cursor, RemainingMsg, -1); int StrLen = Cursor.m_CharCount; + // don't cut words if(CurCharCount + StrLen < MsgLen) { const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); @@ -876,19 +880,31 @@ void CHud::RenderBroadcast() const float TextWidth = Cursor.m_X-Cursor.m_StartX; - TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - TextWidth) * 0.5f, y, + CLineInfo Line = { RemainingMsg, StrLen, TextWidth }; + aLines[LineCount++] = Line; + CurCharCount += StrLen; + } + + // draw lines + float y = BcView.y + BcView.h - LineCount * FontSize; + for(int l = 0; l < LineCount; l++) + { + const CLineInfo& Line = aLines[l]; + TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; + // draw colored text int DrawnStrLen = 0; - while(DrawnStrLen < StrLen) + int ThisCharPos = Line.m_pStrStart - pBroadcastMsg; + while(DrawnStrLen < Line.m_StrLen) { int StartColorID = -1; int ColorStrLen = -1; for(int j = 0; j < m_BroadcastColorCount; j++) { - if((CurCharCount+DrawnStrLen) >= m_aBroadcastColorList[j].m_CharPos) + if((ThisCharPos+DrawnStrLen) >= m_aBroadcastColorList[j].m_CharPos) { StartColorID = j; } @@ -902,28 +918,26 @@ void CHud::RenderBroadcast() dbg_assert(StartColorID >= 0, "This should not be -1, color not found"); if(ColorStrLen == -1) - ColorStrLen = StrLen-DrawnStrLen; + ColorStrLen = Line.m_StrLen-DrawnStrLen; - //dbg_msg("color", "StartColorID=%d ColorStrLen=%d", StartColorID, ColorStrLen); - const BcColor& TextColor = m_aBroadcastColorList[StartColorID]; - int AvgLum = (TextColor.m_R+TextColor.m_G+TextColor.m_B)/3; + const CBcColor& TextColor = m_aBroadcastColorList[StartColorID]; + float r = TextColor.m_R/255.f; + float g = TextColor.m_G/255.f; + float b = TextColor.m_B/255.f; + float AvgLum = 0.2126*r + 0.7152*g + 0.0722*b; - if(AvgLum < 100) - TextRender()->TextOutlineColor(1, 1, 1, 0.8f); + if(AvgLum < 0.25f) + TextRender()->TextOutlineColor(1, 1, 1, 0.6f); else TextRender()->TextOutlineColor(0, 0, 0, 0.3f); - TextRender()->TextColor(TextColor.m_R/255.f, TextColor.m_G/255.f, TextColor.m_B/255.f, Fade); + TextRender()->TextColor(r, g, b, Fade); - TextRender()->TextEx(&Cursor, RemainingMsg+DrawnStrLen, ColorStrLen); + TextRender()->TextEx(&Cursor, Line.m_pStrStart+DrawnStrLen, ColorStrLen); DrawnStrLen += ColorStrLen; } y += FontSize; - CurCharCount += StrLen; - - /*dbg_msg("broadcast", "CurCharCount=%d StrLen=%d '%.*s'", CurCharCount, StrLen, - min(MsgLen-CurCharCount, 10), RemainingMsg);*/ } TextRender()->TextColor(1, 1, 1, 1); diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 6077c232b..25551258c 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -13,7 +13,7 @@ class CHud : public CComponent // broadcast typedef unsigned char u8; - struct BcColor + struct CBcColor { u8 m_R,m_G,m_B; int m_CharPos; @@ -24,7 +24,7 @@ class CHud : public CComponent MAX_BROADCAST_MSG_LENGTH = 127 }; - BcColor m_aBroadcastColorList[MAX_BROADCAST_COLORS]; + CBcColor m_aBroadcastColorList[MAX_BROADCAST_COLORS]; char m_aBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; int m_aBroadcastMsgLen; int m_BroadcastColorCount; From dc449f84e5016542deea5bef2a306d05e668e64f Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 02:43:52 +0100 Subject: [PATCH 04/10] Adjusted spectator bottom-right box, broadcast network back-end, options to disable/mute it --- datasrc/network.py | 4 ++++ src/engine/shared/config_variables.h | 2 ++ src/game/client/components/hud.cpp | 22 +++++++++++---------- src/game/client/components/hud.h | 4 ++-- src/game/client/components/menus_ingame.cpp | 11 +++++++++++ src/game/client/gameclient.cpp | 13 ++++++------ src/game/client/gameclient.h | 5 +++-- src/game/server/gamecontext.cpp | 14 +++++++++++++ src/game/server/gamecontext.h | 2 ++ 9 files changed, 57 insertions(+), 20 deletions(-) diff --git a/datasrc/network.py b/datasrc/network.py index 237d5d16a..f59bd48a6 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -242,6 +242,10 @@ Messages = [ NetMessage("Sv_Motd", [ NetString("m_pMessage"), ]), + + NetMessage("Sv_Broadcast", [ + NetString("m_pMessage"), + ]), NetMessage("Sv_Chat", [ NetIntRange("m_Mode", 0, 'NUM_CHATS-1'), diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index f4a5966f5..a02e49ad5 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -24,6 +24,8 @@ MACRO_CONFIG_INT(ClAutoDemoMax, cl_auto_demo_max, 10, 0, 1000, CFGFLAG_SAVE|CFGF MACRO_CONFIG_INT(ClAutoScreenshot, cl_auto_screenshot, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Automatically take game over screenshot") MACRO_CONFIG_INT(ClAutoScreenshotMax, cl_auto_screenshot_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically created screenshots (0 = no limit)") +MACRO_CONFIG_INT(ClShowServerBroadcast, cl_show_server_broadcast, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show server broadcast") + MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string") MACRO_CONFIG_INT(BrSort, br_sort, 0, 0, 256, CFGFLAG_SAVE|CFGFLAG_CLIENT, "") diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index e4048a97a..86e8cf4a8 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -44,9 +44,11 @@ inline bool IsCharANum(char c) void CHud::OnMessage(int MsgType, void* pRawMsg) { - if(MsgType == NETMSGTYPE_SV_CHAT) + // process server broadcast message + if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast && + !m_pClient->m_MuteServerBroadcast) { - CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; + CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; // new broadcast message int MsgLen = str_length(pMsg->m_pMessage); @@ -674,7 +676,8 @@ void CHud::RenderHealthAndAmmo(const CNetObj_Character *pCharacter) void CHud::RenderSpectatorHud() { // draw the box - CUIRect Rect = {m_Width-180.0f, m_Height-15.0f, 180.0f, 15.0f}; + const float Width = m_Width * 0.25f - 2.0f; + CUIRect Rect = {m_Width-Width, m_Height-15.0f, Width, 15.0f}; RenderTools()->DrawUIRect(&Rect, vec4(0.0f, 0.0f, 0.0f, 0.4f), CUI::CORNER_TL, 5.0f); // draw the text @@ -685,7 +688,7 @@ void CHud::RenderSpectatorHud() char aBuf[128]; CTextCursor Cursor; - TextRender()->SetCursor(&Cursor, m_Width-174.0f, m_Height-13.0f, 8.0f, TEXTFLAG_RENDER); + TextRender()->SetCursor(&Cursor, m_Width-Width+6.0f, m_Height-13.0f, 8.0f, TEXTFLAG_RENDER); str_format(aBuf, sizeof(aBuf), "%s: ", Localize("Spectate")); TextRender()->TextEx(&Cursor, aBuf, -1); @@ -777,6 +780,9 @@ inline bool IsCharWhitespace(char c) void CHud::RenderBroadcast() { + if(!g_Config.m_ClShowServerBroadcast || m_pClient->m_MuteServerBroadcast) + return; + const float DisplayDuration = 10.0f; const float DisplayStartFade = 9.0f; const float DeltaTime = Client()->LocalTime() - m_BroadcastReceivedTime; @@ -791,9 +797,6 @@ void CHud::RenderBroadcast() const float Fade = 1.0f - max(0.0f, (DeltaTime - DisplayStartFade) / (DisplayDuration - DisplayStartFade)); CUIRect ScreenRect = {0, 0, m_Width, m_Height}; - const bool IsSpecMode = m_pClient->m_Snap.m_SpecInfo.m_Active; - if(IsSpecMode) - ScreenRect.y -= 20.0f; CUIRect BcView = ScreenRect; BcView.x += m_Width * 0.25f; @@ -804,13 +807,12 @@ void CHud::RenderBroadcast() float FontSize = 11.0f; vec4 ColorTop(0, 0, 0, 0); - vec4 ColorBot(0, 0, 0, (IsSpecMode ? 0.2f : 0.4f) * Fade); + vec4 ColorBot(0, 0, 0, 0.4f * Fade); CUIRect BgRect; BcView.HSplitBottom(10.0f, 0, &BgRect); RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop, - ColorBot, ColorBot, IsSpecMode ? CUI::CORNER_B:0, - IsSpecMode ? 2.0f:0); + ColorBot, ColorBot, 0, 0); // server broadcast line CUIRect TitleRect; diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 25551258c..444a0c023 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -11,11 +11,11 @@ class CHud : public CComponent float m_AverageFPS; int64 m_WarmupHideTick; - // broadcast + // server broadcast typedef unsigned char u8; struct CBcColor { - u8 m_R,m_G,m_B; + u8 m_R, m_G, m_B; int m_CharPos; }; diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index 448e2748e..04b56427e 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -363,6 +363,17 @@ void CMenus::RenderServerInfo(CUIRect MainView) ServerBrowser()->AddFavorite(&CurrentServerInfo); } + { + CUIRect Button; + ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button); + static int s_MuteBroadcast = 0; + if(DoButton_CheckBox(&s_MuteBroadcast, Localize("Mute broadcast"), + m_pClient->m_MuteServerBroadcast, &Button)) + { + m_pClient->m_MuteServerBroadcast ^= 1; + } + } + // gameinfo GameInfo.VSplitLeft(1.0f, 0, &GameInfo); RenderTools()->DrawUIRect(&GameInfo, vec4(0.0, 0.0, 0.0, 0.25f), CUI::CORNER_ALL, 5.0f); diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 366de9531..fc1ef8967 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -249,7 +249,7 @@ void CGameClient::OnInit() m_UI.SetGraphics(Graphics(), TextRender()); m_RenderTools.m_pGraphics = Graphics(); m_RenderTools.m_pUI = UI(); - + int64 Start = time_get(); // set the language @@ -369,6 +369,7 @@ void CGameClient::OnReset() m_DemoSpecMode = SPEC_FREEVIEW; m_DemoSpecID = -1; m_Tuning = CTuningParams(); + m_MuteServerBroadcast = false; } @@ -633,7 +634,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker) if(m_LocalClientID != -1 && !pMsg->m_Silent) { DoEnterMessage(pMsg->m_pName, pMsg->m_ClientID, pMsg->m_Team); - + if(m_pDemoRecorder->IsRecording()) { CNetMsg_De_ClientEnter Msg; @@ -746,7 +747,7 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker) if(pMsg->m_Silent == 0) { DoTeamChangeMessage(m_aClients[pMsg->m_ClientID].m_aName, pMsg->m_ClientID, pMsg->m_Team); - } + } } else if(MsgId == NETMSGTYPE_SV_READYTOENTER) { @@ -983,7 +984,7 @@ void CGameClient::OnNewSnapshot() m_ServerMode = SERVERMODE_PURE; } } - + // network items if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { @@ -1018,7 +1019,7 @@ void CGameClient::OnNewSnapshot() // clamp ammo count for non ninja weapon if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Weapon != WEAPON_NINJA) m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount = clamp(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_AmmoCount, 0, 10); - + if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; @@ -1199,7 +1200,7 @@ void CGameClient::OnDemoRecSnap() CNetObj_De_GameInfo *pGameInfo = static_cast(Client()->SnapNewItem(NETOBJTYPE_DE_GAMEINFO, 0, sizeof(CNetObj_De_GameInfo))); if(!pGameInfo) return; - + pGameInfo->m_GameFlags = m_GameInfo.m_GameFlags; pGameInfo->m_ScoreLimit = m_GameInfo.m_ScoreLimit; pGameInfo->m_TimeLimit = m_GameInfo.m_TimeLimit; diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 75d1c03cd..05dd360d4 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -87,7 +87,7 @@ public: const char *NetobjFailedOn() { return m_NetObjHandler.FailedObjOn(); }; int NetobjNumFailures() { return m_NetObjHandler.NumObjFailures(); }; const char *NetmsgFailedOn() { return m_NetObjHandler.FailedMsgOn(); }; - + bool m_SuppressEvents; // TODO: move this @@ -129,7 +129,7 @@ public: const CNetObj_GameDataTeam *m_pGameDataTeam; const CNetObj_GameDataFlag *m_pGameDataFlag; int m_GameDataFlagSnapID; - + int m_NotReadyCount; int m_AliveCount[NUM_TEAMS]; @@ -194,6 +194,7 @@ public: CClientData m_aClients[MAX_CLIENTS]; int m_LocalClientID; int m_TeamCooldownTick; + bool m_MuteServerBroadcast; struct CGameInfo { diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index bd6336163..fa54bcc44 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -241,6 +241,13 @@ void CGameContext::SendChat(int ChatterClientID, int Mode, int To, const char *p } } +void CGameContext::SendBroadcast(const char* pText, int ClientID) +{ + CNetMsg_Sv_Broadcast Msg; + Msg.m_pMessage = pText; + Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID); +} + void CGameContext::SendEmoticon(int ClientID, int Emoticon) { CNetMsg_Sv_Emoticon Msg; @@ -1094,6 +1101,12 @@ void CGameContext::ConSay(IConsole::IResult *pResult, void *pUserData) pSelf->SendChat(-1, CHAT_ALL, -1, pResult->GetString(0)); } +void CGameContext::ConBroadcast(IConsole::IResult* pResult, void* pUserData) +{ + CGameContext *pSelf = (CGameContext *)pUserData; + pSelf->SendBroadcast(pResult->GetString(0), -1); +} + void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; @@ -1381,6 +1394,7 @@ void CGameContext::OnConsoleInit() Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, "Change map"); Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, "Restart in x seconds (0 = abort)"); Console()->Register("say", "r", CFGFLAG_SERVER, ConSay, this, "Say in chat"); + Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "Broadcast message"); Console()->Register("set_team", "ii?i", CFGFLAG_SERVER, ConSetTeam, this, "Set team of player to team"); Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team"); Console()->Register("swap_teams", "", CFGFLAG_SERVER, ConSwapTeams, this, "Swap the current teams"); diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index cc0682411..9c9c03d78 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -49,6 +49,7 @@ class CGameContext : public IGameServer static void ConChangeMap(IConsole::IResult *pResult, void *pUserData); static void ConRestart(IConsole::IResult *pResult, void *pUserData); static void ConSay(IConsole::IResult *pResult, void *pUserData); + static void ConBroadcast(IConsole::IResult *pResult, void *pUserData); static void ConSetTeam(IConsole::IResult *pResult, void *pUserData); static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData); static void ConSwapTeams(IConsole::IResult *pResult, void *pUserData); @@ -132,6 +133,7 @@ public: // network void SendChat(int ChatterClientID, int Mode, int To, const char *pText); + void SendBroadcast(const char *pText, int ClientID); void SendEmoticon(int ClientID, int Emoticon); void SendWeaponPickup(int ClientID, int Weapon); void SendMotd(int ClientID); From 102a28a48b611867000aad3def1064c2c61266b2 Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 02:46:13 +0100 Subject: [PATCH 05/10] Fixed a tab issue --- datasrc/network.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datasrc/network.py b/datasrc/network.py index f59bd48a6..ed561c0e5 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -242,8 +242,8 @@ Messages = [ NetMessage("Sv_Motd", [ NetString("m_pMessage"), ]), - - NetMessage("Sv_Broadcast", [ + + NetMessage("Sv_Broadcast", [ NetString("m_pMessage"), ]), From 8d19f5f8a8085b35a1401e9fd0be5f1a2be8c55d Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 16:22:41 +0100 Subject: [PATCH 06/10] Moved the code over to broadcast.cpp --- src/engine/shared/config_variables.h | 1 + src/game/client/components/broadcast.cpp | 264 ++++++++++++++++++++++- src/game/client/components/broadcast.h | 24 ++- src/game/client/components/hud.cpp | 245 --------------------- src/game/client/components/hud.h | 22 +- 5 files changed, 284 insertions(+), 272 deletions(-) diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index a02e49ad5..16b42d758 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -25,6 +25,7 @@ MACRO_CONFIG_INT(ClAutoScreenshot, cl_auto_screenshot, 0, 0, 1, CFGFLAG_SAVE|CFG MACRO_CONFIG_INT(ClAutoScreenshotMax, cl_auto_screenshot_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically created screenshots (0 = no limit)") MACRO_CONFIG_INT(ClShowServerBroadcast, cl_show_server_broadcast, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show server broadcast") +MACRO_CONFIG_INT(ClEnableColoredBroadcast, cl_enable_colored_broadcast, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Eanble colored server broadcasts") MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string") diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index 84bd3882c..82fe80b3a 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -8,11 +8,214 @@ #include -#include -#include - #include "broadcast.h" +#include "chat.h" +#include "scoreboard.h" +#include "motd.h" +inline bool IsCharANum(char c) +{ + return c >= '0' && c <= '9'; +} + +inline int WordLengthBack(const char *pText, int MaxChars) +{ + int s = 0; + while(MaxChars--) + { + if((*pText == '\n' || *pText == '\t' || *pText == ' ')) + return s; + pText--; + s++; + } + return 0; +} + +inline bool IsCharWhitespace(char c) +{ + return c == '\n' || c == '\t' || c == ' '; +} + +void CBroadcast::RenderServerBroadcast() +{ + if(!g_Config.m_ClShowServerBroadcast || m_pClient->m_MuteServerBroadcast) + return; + + const bool ColoredBroadcastEnabled = g_Config.m_ClEnableColoredBroadcast; + const float Height = 300; + const float Width = Height*Graphics()->ScreenAspect(); + + const float DisplayDuration = 10.0f; + const float DisplayStartFade = 9.0f; + const float DeltaTime = Client()->LocalTime() - m_SrvBroadcastReceivedTime; + + if(m_aSrvBroadcastMsg[0] == 0 || DeltaTime > DisplayDuration) + return; + + if(m_pClient->m_pChat->IsActive()) + return; + + const float Fade = 1.0f - max(0.0f, (DeltaTime - DisplayStartFade) / (DisplayDuration - DisplayStartFade)); + + CUIRect ScreenRect = {0, 0, Width, Height}; + + CUIRect BcView = ScreenRect; + BcView.x += Width * 0.25f; + BcView.y += Height * 0.8f; + BcView.w *= 0.5f; + BcView.h *= 0.2f; + + float FontSize = 11.0f; + + vec4 ColorTop(0, 0, 0, 0); + vec4 ColorBot(0, 0, 0, 0.4f * Fade); + CUIRect BgRect; + BcView.HSplitBottom(10.0f, 0, &BgRect); + + RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop, + ColorBot, ColorBot, 0, 0); + + // server broadcast line + CUIRect TitleRect; + BcView.HSplitBottom(10.0f, &BcView, &TitleRect); + TitleRect.y += 1.5f; + TextRender()->TextColor(1, 1, 1, 0.6f * Fade); + UI()->DoLabel(&TitleRect, Localize("Server broadcast"), 5.5f, CUI::ALIGN_CENTER); + + BcView.VMargin(5.0f, &BcView); + BcView.HSplitBottom(2.0f, &BcView, 0); + + const char* pBroadcastMsg = m_aSrvBroadcastMsg; + const int MsgLen = m_aSrvBroadcastMsgLen; + + // broadcast message + // one line == big font + // > one line == small font + + CTextCursor Cursor; + TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); + + // can't fit on one line, reduce size + if(Cursor.m_LineCount > 1) + { + FontSize = 6.5f; // smaller font + TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); + } + + // make lines + struct CLineInfo + { + const char* m_pStrStart; + int m_StrLen; + float m_Width; + }; + + CLineInfo aLines[10]; + int CurCharCount = 0; + int LineCount = 0; + + while(CurCharCount < MsgLen) + { + const char* RemainingMsg = pBroadcastMsg + CurCharCount; + + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + + TextRender()->TextEx(&Cursor, RemainingMsg, -1); + int StrLen = Cursor.m_CharCount; + + // don't cut words + if(CurCharCount + StrLen < MsgLen) + { + const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); + if(WorldLen > 0 && WorldLen < StrLen) + { + StrLen -= WorldLen; + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + } + } + + const float TextWidth = Cursor.m_X-Cursor.m_StartX; + + CLineInfo Line = { RemainingMsg, StrLen, TextWidth }; + aLines[LineCount++] = Line; + CurCharCount += StrLen; + } + + // draw lines + TextRender()->TextColor(1, 1, 1, 1); + TextRender()->TextOutlineColor(0, 0, 0, 0.3f); + float y = BcView.y + BcView.h - LineCount * FontSize; + + for(int l = 0; l < LineCount; l++) + { + const CLineInfo& Line = aLines[l]; + TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y, + FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = BcView.w; + + // draw colored text + if(ColoredBroadcastEnabled) + { + int DrawnStrLen = 0; + int ThisCharPos = Line.m_pStrStart - pBroadcastMsg; + while(DrawnStrLen < Line.m_StrLen) + { + int StartColorID = -1; + int ColorStrLen = -1; + + for(int j = 0; j < m_SrvBroadcastColorCount; j++) + { + if((ThisCharPos+DrawnStrLen) >= m_aSrvBroadcastColorList[j].m_CharPos) + { + StartColorID = j; + } + else if(StartColorID >= 0) + { + ColorStrLen = m_aSrvBroadcastColorList[j].m_CharPos - m_aSrvBroadcastColorList[StartColorID].m_CharPos; + break; + } + } + + dbg_assert(StartColorID >= 0, "This should not be -1, color not found"); + + if(ColorStrLen == -1) + ColorStrLen = Line.m_StrLen-DrawnStrLen; + + const CBcColor& TextColor = m_aSrvBroadcastColorList[StartColorID]; + float r = TextColor.m_R/255.f; + float g = TextColor.m_G/255.f; + float b = TextColor.m_B/255.f; + float AvgLum = 0.2126*r + 0.7152*g + 0.0722*b; + + if(AvgLum < 0.25f) + TextRender()->TextOutlineColor(1, 1, 1, 0.6f); + else + TextRender()->TextOutlineColor(0, 0, 0, 0.3f); + + TextRender()->TextColor(r, g, b, Fade); + + TextRender()->TextEx(&Cursor, Line.m_pStrStart+DrawnStrLen, ColorStrLen); + DrawnStrLen += ColorStrLen; + } + } + else + { + TextRender()->TextEx(&Cursor, Line.m_pStrStart, Line.m_StrLen); + } + + y += FontSize; + } + + TextRender()->TextColor(1, 1, 1, 1); + TextRender()->TextOutlineColor(0, 0, 0, 0.3f); +} CBroadcast::CBroadcast() { @@ -27,7 +230,7 @@ void CBroadcast::DoBroadcast(const char *pText) Cursor.m_LineWidth = 300*Graphics()->ScreenAspect(); TextRender()->TextEx(&Cursor, m_aBroadcastText, -1); m_BroadcastRenderOffset = 150*Graphics()->ScreenAspect()-Cursor.m_X/2; - m_BroadcastTime = time_get()+time_freq()*10; + m_BroadcastTime = Client()->LocalTime() + 10.0f; } void CBroadcast::OnReset() @@ -35,6 +238,53 @@ void CBroadcast::OnReset() m_BroadcastTime = 0; } +void CBroadcast::OnMessage(int MsgType, void* pRawMsg) +{ + // process server broadcast message + if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast && + !m_pClient->m_MuteServerBroadcast) + { + CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; + + // new broadcast message + int MsgLen = str_length(pMsg->m_pMessage); + mem_zero(m_aSrvBroadcastMsg, sizeof(m_aSrvBroadcastMsg)); + m_aSrvBroadcastMsgLen = 0; + m_SrvBroadcastReceivedTime = Client()->LocalTime(); + + const CBcColor White = { 255, 255, 255, 0 }; + m_aSrvBroadcastColorList[0] = White; + m_SrvBroadcastColorCount = 1; + + // parse colors + for(int i = 0; i < MsgLen; i++) + { + const char* c = pMsg->m_pMessage + i; + const char* pTmp = c; + int CharUtf8 = str_utf8_decode(&pTmp); + const int Utf8Len = pTmp-c; + + if(*c == CharUtf8 && *c == '^') + { + if(i+3 < MsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3])) + { + u8 r = (c[1] - '0') * 24 + 39; + u8 g = (c[2] - '0') * 24 + 39; + u8 b = (c[3] - '0') * 24 + 39; + CBcColor Color = { r, g, b, m_aSrvBroadcastMsgLen }; + if(m_SrvBroadcastColorCount < MAX_BROADCAST_COLORS) + m_aSrvBroadcastColorList[m_SrvBroadcastColorCount++] = Color; + i += 3; + continue; + } + } + + if(m_aSrvBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH) + m_aSrvBroadcastMsg[m_aSrvBroadcastMsgLen++] = *c; + } + } +} + void CBroadcast::OnRender() { if(m_pClient->m_pScoreboard->Active() || m_pClient->m_pMotd->IsActive()) @@ -42,12 +292,16 @@ void CBroadcast::OnRender() Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300); - if(time_get() < m_BroadcastTime) + // client broadcast + if(Client()->LocalTime() < m_BroadcastTime) { CTextCursor Cursor; TextRender()->SetCursor(&Cursor, m_BroadcastRenderOffset, 40.0f, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-m_BroadcastRenderOffset; TextRender()->TextEx(&Cursor, m_aBroadcastText, -1); } + + // server broadcast + RenderServerBroadcast(); } diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h index 8d514af39..943e3f517 100644 --- a/src/game/client/components/broadcast.h +++ b/src/game/client/components/broadcast.h @@ -7,15 +7,37 @@ class CBroadcast : public CComponent { char m_aBroadcastText[128]; - int64 m_BroadcastTime; + float m_BroadcastTime; float m_BroadcastRenderOffset; + // server broadcast + typedef unsigned char u8; + struct CBcColor + { + u8 m_R, m_G, m_B; + int m_CharPos; + }; + + enum { + MAX_BROADCAST_COLORS = 128, + MAX_BROADCAST_MSG_LENGTH = 127 + }; + + CBcColor m_aSrvBroadcastColorList[MAX_BROADCAST_COLORS]; + char m_aSrvBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; + int m_aSrvBroadcastMsgLen; + int m_SrvBroadcastColorCount; + float m_SrvBroadcastReceivedTime; + + void RenderServerBroadcast(); + public: CBroadcast(); void DoBroadcast(const char *pText); virtual void OnReset(); + virtual void OnMessage(int MsgType, void *pRawMsg); virtual void OnRender(); }; diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index 86e8cf4a8..9511dd482 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -17,9 +17,6 @@ #include "hud.h" #include "voting.h" #include "binds.h" -#include "chat.h" -#include "scoreboard.h" -#include "motd.h" CHud::CHud() { @@ -27,9 +24,6 @@ CHud::CHud() m_AverageFPS = 1.0f; m_WarmupHideTick = 0; - m_BroadcastColorCount = 0; - m_aBroadcastMsg[0] = 0; - m_BroadcastReceivedTime = 0; } void CHud::OnReset() @@ -37,58 +31,6 @@ void CHud::OnReset() m_WarmupHideTick = 0; } -inline bool IsCharANum(char c) -{ - return c >= '0' && c <= '9'; -} - -void CHud::OnMessage(int MsgType, void* pRawMsg) -{ - // process server broadcast message - if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast && - !m_pClient->m_MuteServerBroadcast) - { - CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; - - // new broadcast message - int MsgLen = str_length(pMsg->m_pMessage); - mem_zero(m_aBroadcastMsg, sizeof(m_aBroadcastMsg)); - m_aBroadcastMsgLen = 0; - m_BroadcastReceivedTime = Client()->LocalTime(); - - const CBcColor White = { 255, 255, 255, 0 }; - m_aBroadcastColorList[0] = White; - m_BroadcastColorCount = 1; - - // parse colors - for(int i = 0; i < MsgLen; i++) - { - const char* c = pMsg->m_pMessage + i; - const char* pTmp = c; - int CharUtf8 = str_utf8_decode(&pTmp); - const int Utf8Len = pTmp-c; - - if(*c == CharUtf8 && *c == '^') - { - if(i+3 < MsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3])) - { - u8 r = (c[1] - '0') * 24 + 39; - u8 g = (c[2] - '0') * 24 + 39; - u8 b = (c[3] - '0') * 24 + 39; - CBcColor Color = { r, g, b, m_aBroadcastMsgLen }; - if(m_BroadcastColorCount < MAX_BROADCAST_COLORS) - m_aBroadcastColorList[m_BroadcastColorCount++] = Color; - i += 3; - continue; - } - } - - if(m_aBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH) - m_aBroadcastMsg[m_aBroadcastMsgLen++] = *c; - } - } -} - void CHud::RenderGameTimer() { float Half = 300.0f*Graphics()->ScreenAspect()/2.0f; @@ -750,7 +692,6 @@ void CHud::OnRender() RenderSuddenDeath(); RenderScoreHud(); RenderWarmupTimer(); - RenderBroadcast(); RenderFps(); if(Client()->State() != IClient::STATE_DEMOPLAYBACK) RenderConnectionWarning(); @@ -759,189 +700,3 @@ void CHud::OnRender() } RenderCursor(); } - -inline int WordLengthBack(const char *pText, int MaxChars) -{ - int s = 0; - while(MaxChars--) - { - if((*pText == '\n' || *pText == '\t' || *pText == ' ')) - return s; - pText--; - s++; - } - return 0; -} - -inline bool IsCharWhitespace(char c) -{ - return c == '\n' || c == '\t' || c == ' '; -} - -void CHud::RenderBroadcast() -{ - if(!g_Config.m_ClShowServerBroadcast || m_pClient->m_MuteServerBroadcast) - return; - - const float DisplayDuration = 10.0f; - const float DisplayStartFade = 9.0f; - const float DeltaTime = Client()->LocalTime() - m_BroadcastReceivedTime; - - if(m_aBroadcastMsg[0] == 0 || DeltaTime > DisplayDuration) - return; - - if(m_pClient->m_pScoreboard->Active() || m_pClient->m_pMotd->IsActive() || - m_pClient->m_pChat->IsActive()) - return; - - const float Fade = 1.0f - max(0.0f, (DeltaTime - DisplayStartFade) / (DisplayDuration - DisplayStartFade)); - - CUIRect ScreenRect = {0, 0, m_Width, m_Height}; - - CUIRect BcView = ScreenRect; - BcView.x += m_Width * 0.25f; - BcView.y += m_Height * 0.8f; - BcView.w *= 0.5f; - BcView.h *= 0.2f; - - float FontSize = 11.0f; - - vec4 ColorTop(0, 0, 0, 0); - vec4 ColorBot(0, 0, 0, 0.4f * Fade); - CUIRect BgRect; - BcView.HSplitBottom(10.0f, 0, &BgRect); - - RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop, - ColorBot, ColorBot, 0, 0); - - // server broadcast line - CUIRect TitleRect; - BcView.HSplitBottom(10.0f, &BcView, &TitleRect); - TitleRect.y += 1.5f; - TextRender()->TextColor(1, 1, 1, 0.6f * Fade); - UI()->DoLabel(&TitleRect, Localize("Server broadcast"), 5.5f, CUI::ALIGN_CENTER); - - BcView.VMargin(5.0f, &BcView); - BcView.HSplitBottom(2.0f, &BcView, 0); - - const char* pBroadcastMsg = m_aBroadcastMsg; - const int MsgLen = m_aBroadcastMsgLen; - - // broadcast message - // one line == big font - // > one line == small font - - CTextCursor Cursor; - TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); - - // can't fit on one line, reduce size - if(Cursor.m_LineCount > 1) - { - FontSize = 6.5f; // smaller font - TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); - } - - // make lines - struct CLineInfo - { - const char* m_pStrStart; - int m_StrLen; - float m_Width; - }; - - CLineInfo aLines[10]; - int CurCharCount = 0; - int LineCount = 0; - - while(CurCharCount < MsgLen) - { - const char* RemainingMsg = pBroadcastMsg + CurCharCount; - - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = BcView.w; - - TextRender()->TextEx(&Cursor, RemainingMsg, -1); - int StrLen = Cursor.m_CharCount; - - // don't cut words - if(CurCharCount + StrLen < MsgLen) - { - const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); - if(WorldLen > 0 && WorldLen < StrLen) - { - StrLen -= WorldLen; - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); - } - } - - const float TextWidth = Cursor.m_X-Cursor.m_StartX; - - CLineInfo Line = { RemainingMsg, StrLen, TextWidth }; - aLines[LineCount++] = Line; - CurCharCount += StrLen; - } - - // draw lines - float y = BcView.y + BcView.h - LineCount * FontSize; - for(int l = 0; l < LineCount; l++) - { - const CLineInfo& Line = aLines[l]; - TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y, - FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = BcView.w; - - // draw colored text - int DrawnStrLen = 0; - int ThisCharPos = Line.m_pStrStart - pBroadcastMsg; - while(DrawnStrLen < Line.m_StrLen) - { - int StartColorID = -1; - int ColorStrLen = -1; - - for(int j = 0; j < m_BroadcastColorCount; j++) - { - if((ThisCharPos+DrawnStrLen) >= m_aBroadcastColorList[j].m_CharPos) - { - StartColorID = j; - } - else if(StartColorID >= 0) - { - ColorStrLen = m_aBroadcastColorList[j].m_CharPos - m_aBroadcastColorList[StartColorID].m_CharPos; - break; - } - } - - dbg_assert(StartColorID >= 0, "This should not be -1, color not found"); - - if(ColorStrLen == -1) - ColorStrLen = Line.m_StrLen-DrawnStrLen; - - const CBcColor& TextColor = m_aBroadcastColorList[StartColorID]; - float r = TextColor.m_R/255.f; - float g = TextColor.m_G/255.f; - float b = TextColor.m_B/255.f; - float AvgLum = 0.2126*r + 0.7152*g + 0.0722*b; - - if(AvgLum < 0.25f) - TextRender()->TextOutlineColor(1, 1, 1, 0.6f); - else - TextRender()->TextOutlineColor(0, 0, 0, 0.3f); - - TextRender()->TextColor(r, g, b, Fade); - - TextRender()->TextEx(&Cursor, Line.m_pStrStart+DrawnStrLen, ColorStrLen); - DrawnStrLen += ColorStrLen; - } - - y += FontSize; - } - - TextRender()->TextColor(1, 1, 1, 1); - TextRender()->TextOutlineColor(0, 0, 0, 0.3f); -} diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 444a0c023..228e2b3f1 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -11,25 +11,6 @@ class CHud : public CComponent float m_AverageFPS; int64 m_WarmupHideTick; - // server broadcast - typedef unsigned char u8; - struct CBcColor - { - u8 m_R, m_G, m_B; - int m_CharPos; - }; - - enum { - MAX_BROADCAST_COLORS = 128, - MAX_BROADCAST_MSG_LENGTH = 127 - }; - - CBcColor m_aBroadcastColorList[MAX_BROADCAST_COLORS]; - char m_aBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; - int m_aBroadcastMsgLen; - int m_BroadcastColorCount; - float m_BroadcastReceivedTime; - void RenderCursor(); void RenderFps(); @@ -46,12 +27,11 @@ class CHud : public CComponent void RenderScoreHud(); void RenderSpectatorHud(); void RenderWarmupTimer(); - void RenderBroadcast(); + public: CHud(); virtual void OnReset(); - virtual void OnMessage(int MsgType, void *pRawMsg); virtual void OnRender(); }; From 23d1cc395396fbd4a0b434770e1afa505ea51d43 Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 18:14:27 +0100 Subject: [PATCH 07/10] Save lines state instead of calculating every frame --- src/game/client/components/broadcast.cpp | 146 ++++++++++++----------- src/game/client/components/broadcast.h | 10 ++ 2 files changed, 85 insertions(+), 71 deletions(-) diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index 82fe80b3a..3f66619c6 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -13,6 +13,9 @@ #include "scoreboard.h" #include "motd.h" +#define BROADCAST_FONTSIZE_BIG 11.0f +#define BROADCAST_FONTSIZE_SMALL 6.5f + inline bool IsCharANum(char c) { return c >= '0' && c <= '9'; @@ -65,8 +68,6 @@ void CBroadcast::RenderServerBroadcast() BcView.w *= 0.5f; BcView.h *= 0.2f; - float FontSize = 11.0f; - vec4 ColorTop(0, 0, 0, 0); vec4 ColorBot(0, 0, 0, 0.4f * Fade); CUIRect BgRect; @@ -85,77 +86,20 @@ void CBroadcast::RenderServerBroadcast() BcView.VMargin(5.0f, &BcView); BcView.HSplitBottom(2.0f, &BcView, 0); - const char* pBroadcastMsg = m_aSrvBroadcastMsg; - const int MsgLen = m_aSrvBroadcastMsgLen; - - // broadcast message - // one line == big font - // > one line == small font - - CTextCursor Cursor; - TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); - - // can't fit on one line, reduce size - if(Cursor.m_LineCount > 1) - { - FontSize = 6.5f; // smaller font - TextRender()->SetCursor(&Cursor, BcView.x, BcView.y, FontSize, 0); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, pBroadcastMsg, -1); - } - - // make lines - struct CLineInfo - { - const char* m_pStrStart; - int m_StrLen; - float m_Width; - }; - - CLineInfo aLines[10]; - int CurCharCount = 0; - int LineCount = 0; - - while(CurCharCount < MsgLen) - { - const char* RemainingMsg = pBroadcastMsg + CurCharCount; - - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = BcView.w; - - TextRender()->TextEx(&Cursor, RemainingMsg, -1); - int StrLen = Cursor.m_CharCount; - - // don't cut words - if(CurCharCount + StrLen < MsgLen) - { - const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); - if(WorldLen > 0 && WorldLen < StrLen) - { - StrLen -= WorldLen; - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = BcView.w; - TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); - } - } - - const float TextWidth = Cursor.m_X-Cursor.m_StartX; - - CLineInfo Line = { RemainingMsg, StrLen, TextWidth }; - aLines[LineCount++] = Line; - CurCharCount += StrLen; - } - // draw lines + const float FontSize = m_SrvBroadcastFontSize; + const int LineCount = m_SrvBroadcastLineCount; + const CBcLineInfo* aLines = m_aSrvBroadcastLines; + const char* pBroadcastMsg = m_aSrvBroadcastMsg; + CTextCursor Cursor; + TextRender()->TextColor(1, 1, 1, 1); TextRender()->TextOutlineColor(0, 0, 0, 0.3f); float y = BcView.y + BcView.h - LineCount * FontSize; for(int l = 0; l < LineCount; l++) { - const CLineInfo& Line = aLines[l]; + const CBcLineInfo& Line = aLines[l]; TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; @@ -241,13 +185,14 @@ void CBroadcast::OnReset() void CBroadcast::OnMessage(int MsgType, void* pRawMsg) { // process server broadcast message - if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast && + if(MsgType == NETMSGTYPE_SV_CHAT && g_Config.m_ClShowServerBroadcast && !m_pClient->m_MuteServerBroadcast) { - CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; + //CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; + CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; // new broadcast message - int MsgLen = str_length(pMsg->m_pMessage); + int RcvMsgLen = str_length(pMsg->m_pMessage); mem_zero(m_aSrvBroadcastMsg, sizeof(m_aSrvBroadcastMsg)); m_aSrvBroadcastMsgLen = 0; m_SrvBroadcastReceivedTime = Client()->LocalTime(); @@ -257,7 +202,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) m_SrvBroadcastColorCount = 1; // parse colors - for(int i = 0; i < MsgLen; i++) + for(int i = 0; i < RcvMsgLen; i++) { const char* c = pMsg->m_pMessage + i; const char* pTmp = c; @@ -266,7 +211,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) if(*c == CharUtf8 && *c == '^') { - if(i+3 < MsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3])) + if(i+3 < RcvMsgLen && IsCharANum(c[1]) && IsCharANum(c[2]) && IsCharANum(c[3])) { u8 r = (c[1] - '0') * 24 + 39; u8 g = (c[2] - '0') * 24 + 39; @@ -282,6 +227,65 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) if(m_aSrvBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH) m_aSrvBroadcastMsg[m_aSrvBroadcastMsgLen++] = *c; } + + const float Height = 300; + const float Width = Height*Graphics()->ScreenAspect(); + const float LineMaxWidth = Width * 0.5f - 10.0f; + + // process boradcast message + const char* pBroadcastMsg = m_aSrvBroadcastMsg; + const int MsgLen = m_aSrvBroadcastMsgLen; + + // one line == big font + // 2+ lines == small font + float FontSize = BROADCAST_FONTSIZE_BIG; + CTextCursor Cursor; + Graphics()->MapScreen(0, 0, Width, Height); + + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + Cursor.m_LineWidth = LineMaxWidth; + TextRender()->TextEx(&Cursor, pBroadcastMsg, MsgLen); + + // can't fit on one line, reduce size + if(Cursor.m_LineCount > 1) + FontSize = BROADCAST_FONTSIZE_SMALL; // smaller font + + m_SrvBroadcastFontSize = FontSize; + + // make lines + CBcLineInfo* aLines = m_aSrvBroadcastLines; + int CurCharCount = 0; + m_SrvBroadcastLineCount = 0; + + while(CurCharCount < MsgLen) + { + const char* RemainingMsg = pBroadcastMsg + CurCharCount; + + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = LineMaxWidth; + + TextRender()->TextEx(&Cursor, RemainingMsg, -1); + int StrLen = Cursor.m_CharCount; + + // don't cut words + if(CurCharCount + StrLen < MsgLen) + { + const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); + if(WorldLen > 0 && WorldLen < StrLen) + { + StrLen -= WorldLen; + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = LineMaxWidth; + TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + } + } + + const float TextWidth = Cursor.m_X-Cursor.m_StartX; + + CBcLineInfo Line = { RemainingMsg, StrLen, TextWidth }; + aLines[m_SrvBroadcastLineCount++] = Line; + CurCharCount += StrLen; + } } } diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h index 943e3f517..d674942a2 100644 --- a/src/game/client/components/broadcast.h +++ b/src/game/client/components/broadcast.h @@ -18,16 +18,26 @@ class CBroadcast : public CComponent int m_CharPos; }; + struct CBcLineInfo + { + const char* m_pStrStart; + int m_StrLen; + float m_Width; + }; + enum { MAX_BROADCAST_COLORS = 128, MAX_BROADCAST_MSG_LENGTH = 127 }; CBcColor m_aSrvBroadcastColorList[MAX_BROADCAST_COLORS]; + CBcLineInfo m_aSrvBroadcastLines[10]; char m_aSrvBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; int m_aSrvBroadcastMsgLen; int m_SrvBroadcastColorCount; + int m_SrvBroadcastLineCount; float m_SrvBroadcastReceivedTime; + float m_SrvBroadcastFontSize; void RenderServerBroadcast(); From bd1ef7cb547b854c0f8b6e8b01bbe190bdf612e4 Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 19:56:52 +0100 Subject: [PATCH 08/10] User defined lines support --- src/game/client/components/broadcast.cpp | 144 +++++++++++++++-------- src/game/client/components/broadcast.h | 2 +- 2 files changed, 97 insertions(+), 49 deletions(-) diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index 3f66619c6..3e9c645b6 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -89,7 +89,6 @@ void CBroadcast::RenderServerBroadcast() // draw lines const float FontSize = m_SrvBroadcastFontSize; const int LineCount = m_SrvBroadcastLineCount; - const CBcLineInfo* aLines = m_aSrvBroadcastLines; const char* pBroadcastMsg = m_aSrvBroadcastMsg; CTextCursor Cursor; @@ -99,7 +98,7 @@ void CBroadcast::RenderServerBroadcast() for(int l = 0; l < LineCount; l++) { - const CBcLineInfo& Line = aLines[l]; + const CBcLineInfo& Line = m_aSrvBroadcastLines[l]; TextRender()->SetCursor(&Cursor, BcView.x + (BcView.w - Line.m_Width) * 0.5f, y, FontSize, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = BcView.w; @@ -114,6 +113,7 @@ void CBroadcast::RenderServerBroadcast() int StartColorID = -1; int ColorStrLen = -1; + // find color for(int j = 0; j < m_SrvBroadcastColorCount; j++) { if((ThisCharPos+DrawnStrLen) >= m_aSrvBroadcastColorList[j].m_CharPos) @@ -122,15 +122,17 @@ void CBroadcast::RenderServerBroadcast() } else if(StartColorID >= 0) { - ColorStrLen = m_aSrvBroadcastColorList[j].m_CharPos - m_aSrvBroadcastColorList[StartColorID].m_CharPos; + ColorStrLen = m_aSrvBroadcastColorList[j].m_CharPos - + max(m_aSrvBroadcastColorList[StartColorID].m_CharPos, ThisCharPos); break; } } dbg_assert(StartColorID >= 0, "This should not be -1, color not found"); - if(ColorStrLen == -1) + if(ColorStrLen < 0) ColorStrLen = Line.m_StrLen-DrawnStrLen; + ColorStrLen = min(ColorStrLen, Line.m_StrLen-DrawnStrLen); const CBcColor& TextColor = m_aSrvBroadcastColorList[StartColorID]; float r = TextColor.m_R/255.f; @@ -201,6 +203,10 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) m_aSrvBroadcastColorList[0] = White; m_SrvBroadcastColorCount = 1; + CBcLineInfo UserLines[3]; + int UserLineCount = 0; + int LastUserLineStartPoint = 0; + // parse colors for(int i = 0; i < RcvMsgLen; i++) { @@ -224,10 +230,33 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) } } + if(*c == CharUtf8 && *c == '\\') + { + if(i+1 < RcvMsgLen && c[1] == 'n' && UserLineCount < 3) + { + CBcLineInfo Line = { m_aSrvBroadcastMsg+LastUserLineStartPoint, + m_aSrvBroadcastMsgLen-LastUserLineStartPoint, 0 }; + if(Line.m_StrLen > 0) + UserLines[UserLineCount++] = Line; + LastUserLineStartPoint = m_aSrvBroadcastMsgLen; + i++; + continue; + } + } + if(m_aSrvBroadcastMsgLen+Utf8Len < MAX_BROADCAST_MSG_LENGTH) m_aSrvBroadcastMsg[m_aSrvBroadcastMsgLen++] = *c; } + // last user defined line + if(LastUserLineStartPoint > 0 && UserLineCount < 3) + { + CBcLineInfo Line = { m_aSrvBroadcastMsg+LastUserLineStartPoint, + m_aSrvBroadcastMsgLen-LastUserLineStartPoint, 0 }; + if(Line.m_StrLen > 0) + UserLines[UserLineCount++] = Line; + } + const float Height = 300; const float Width = Height*Graphics()->ScreenAspect(); const float LineMaxWidth = Width * 0.5f - 10.0f; @@ -236,56 +265,75 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) const char* pBroadcastMsg = m_aSrvBroadcastMsg; const int MsgLen = m_aSrvBroadcastMsgLen; - // one line == big font - // 2+ lines == small font - float FontSize = BROADCAST_FONTSIZE_BIG; CTextCursor Cursor; Graphics()->MapScreen(0, 0, Width, Height); - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); - Cursor.m_LineWidth = LineMaxWidth; - TextRender()->TextEx(&Cursor, pBroadcastMsg, MsgLen); + // one line == big font + // 2+ lines == small font + m_SrvBroadcastLineCount = 0; + float FontSize = BROADCAST_FONTSIZE_BIG; - // can't fit on one line, reduce size - if(Cursor.m_LineCount > 1) - FontSize = BROADCAST_FONTSIZE_SMALL; // smaller font + if(UserLineCount <= 1) // auto mode + { + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, 0); + Cursor.m_LineWidth = LineMaxWidth; + TextRender()->TextEx(&Cursor, pBroadcastMsg, MsgLen); + + // can't fit on one line, reduce size + if(Cursor.m_LineCount > 1) + FontSize = BROADCAST_FONTSIZE_SMALL; // smaller font + + // make lines + int CurCharCount = 0; + while(CurCharCount < MsgLen && m_SrvBroadcastLineCount < 3) + { + const char* RemainingMsg = pBroadcastMsg + CurCharCount; + + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = LineMaxWidth; + + TextRender()->TextEx(&Cursor, RemainingMsg, -1); + int StrLen = Cursor.m_CharCount; + + // don't cut words + if(CurCharCount + StrLen < MsgLen) + { + const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); + if(WorldLen > 0 && WorldLen < StrLen) + { + StrLen -= WorldLen; + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = LineMaxWidth; + TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); + } + } + + const float TextWidth = Cursor.m_X-Cursor.m_StartX; + + CBcLineInfo Line = { RemainingMsg, StrLen, TextWidth }; + m_aSrvBroadcastLines[m_SrvBroadcastLineCount++] = Line; + CurCharCount += StrLen; + } + } + else // user defined lines mode + { + FontSize = BROADCAST_FONTSIZE_SMALL; + + for(int i = 0; i < UserLineCount && m_SrvBroadcastLineCount < 3; i++) + { + TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); + Cursor.m_LineWidth = LineMaxWidth; + TextRender()->TextEx(&Cursor, UserLines[i].m_pStrStart, UserLines[i].m_StrLen); + + const float TextWidth = Cursor.m_X-Cursor.m_StartX; + const int StrLen = Cursor.m_CharCount; + + CBcLineInfo Line = { UserLines[i].m_pStrStart, StrLen, TextWidth }; + m_aSrvBroadcastLines[m_SrvBroadcastLineCount++] = Line; + } + } m_SrvBroadcastFontSize = FontSize; - - // make lines - CBcLineInfo* aLines = m_aSrvBroadcastLines; - int CurCharCount = 0; - m_SrvBroadcastLineCount = 0; - - while(CurCharCount < MsgLen) - { - const char* RemainingMsg = pBroadcastMsg + CurCharCount; - - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = LineMaxWidth; - - TextRender()->TextEx(&Cursor, RemainingMsg, -1); - int StrLen = Cursor.m_CharCount; - - // don't cut words - if(CurCharCount + StrLen < MsgLen) - { - const int WorldLen = WordLengthBack(RemainingMsg + StrLen, StrLen); - if(WorldLen > 0 && WorldLen < StrLen) - { - StrLen -= WorldLen; - TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); - Cursor.m_LineWidth = LineMaxWidth; - TextRender()->TextEx(&Cursor, RemainingMsg, StrLen); - } - } - - const float TextWidth = Cursor.m_X-Cursor.m_StartX; - - CBcLineInfo Line = { RemainingMsg, StrLen, TextWidth }; - aLines[m_SrvBroadcastLineCount++] = Line; - CurCharCount += StrLen; - } } } diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h index d674942a2..7aa4e1eda 100644 --- a/src/game/client/components/broadcast.h +++ b/src/game/client/components/broadcast.h @@ -31,7 +31,7 @@ class CBroadcast : public CComponent }; CBcColor m_aSrvBroadcastColorList[MAX_BROADCAST_COLORS]; - CBcLineInfo m_aSrvBroadcastLines[10]; + CBcLineInfo m_aSrvBroadcastLines[3]; char m_aSrvBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; int m_aSrvBroadcastMsgLen; int m_SrvBroadcastColorCount; From 8c905013b53f8f849954a1bd4d10dac684db77c4 Mon Sep 17 00:00:00 2001 From: LordSk Date: Sun, 25 Nov 2018 20:33:10 +0100 Subject: [PATCH 09/10] Soft bottom bar corners, option do disable colors --- src/engine/shared/config_variables.h | 2 +- src/game/client/components/broadcast.cpp | 45 ++++++++++++++----- src/game/client/components/menus_ingame.cpp | 2 +- src/game/client/components/menus_settings.cpp | 13 ++++-- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index 16b42d758..f84b69b8e 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -25,7 +25,7 @@ MACRO_CONFIG_INT(ClAutoScreenshot, cl_auto_screenshot, 0, 0, 1, CFGFLAG_SAVE|CFG MACRO_CONFIG_INT(ClAutoScreenshotMax, cl_auto_screenshot_max, 10, 0, 1000, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Maximum number of automatically created screenshots (0 = no limit)") MACRO_CONFIG_INT(ClShowServerBroadcast, cl_show_server_broadcast, 1, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Show server broadcast") -MACRO_CONFIG_INT(ClEnableColoredBroadcast, cl_enable_colored_broadcast, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Eanble colored server broadcasts") +MACRO_CONFIG_INT(ClColoredBroadcast, cl_colored_broadcast, 0, 0, 1, CFGFLAG_SAVE|CFGFLAG_CLIENT, "Enable colored server broadcasts") MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string") diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index 3e9c645b6..0e378dabf 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -44,7 +44,7 @@ void CBroadcast::RenderServerBroadcast() if(!g_Config.m_ClShowServerBroadcast || m_pClient->m_MuteServerBroadcast) return; - const bool ColoredBroadcastEnabled = g_Config.m_ClEnableColoredBroadcast; + const bool ColoredBroadcastEnabled = g_Config.m_ClColoredBroadcast; const float Height = 300; const float Width = Height*Graphics()->ScreenAspect(); @@ -72,16 +72,42 @@ void CBroadcast::RenderServerBroadcast() vec4 ColorBot(0, 0, 0, 0.4f * Fade); CUIRect BgRect; BcView.HSplitBottom(10.0f, 0, &BgRect); + BcView.HSplitBottom(8.0f, &BcView, 0); + + // draw bottom bar + const float CornerWidth = 12.0f; + BgRect.VMargin(CornerWidth, &BgRect); + + Graphics()->TextureClear(); + Graphics()->QuadsBegin(); + IGraphics::CFreeformItem LeftCorner( + BgRect.x - CornerWidth, BgRect.y + BgRect.h, + BgRect.x, BgRect.y, + BgRect.x, BgRect.y + BgRect.h, + BgRect.x, BgRect.y + BgRect.h + ); + IGraphics::CColorVertex aColorVert[4] = { + IGraphics::CColorVertex(0, 0,0,0, 0.0f), + IGraphics::CColorVertex(1, 0,0,0, 0.0f), + IGraphics::CColorVertex(2, 0,0,0, 0.4f * Fade), + IGraphics::CColorVertex(3, 0,0,0, 0.4f * Fade)}; + Graphics()->SetColorVertex(aColorVert, 4); + Graphics()->QuadsDrawFreeform(&LeftCorner, 1); + + IGraphics::CFreeformItem RightCorner( + BgRect.x+BgRect.w + CornerWidth, BgRect.y + BgRect.h, + BgRect.x+BgRect.w, BgRect.y, + BgRect.x+BgRect.w, BgRect.y + BgRect.h, + BgRect.x+BgRect.w, BgRect.y + BgRect.h + ); + Graphics()->SetColorVertex(aColorVert, 4); + Graphics()->QuadsDrawFreeform(&RightCorner, 1); + + Graphics()->QuadsEnd(); RenderTools()->DrawUIRect4(&BgRect, ColorTop, ColorTop, ColorBot, ColorBot, 0, 0); - // server broadcast line - CUIRect TitleRect; - BcView.HSplitBottom(10.0f, &BcView, &TitleRect); - TitleRect.y += 1.5f; - TextRender()->TextColor(1, 1, 1, 0.6f * Fade); - UI()->DoLabel(&TitleRect, Localize("Server broadcast"), 5.5f, CUI::ALIGN_CENTER); BcView.VMargin(5.0f, &BcView); BcView.HSplitBottom(2.0f, &BcView, 0); @@ -187,11 +213,10 @@ void CBroadcast::OnReset() void CBroadcast::OnMessage(int MsgType, void* pRawMsg) { // process server broadcast message - if(MsgType == NETMSGTYPE_SV_CHAT && g_Config.m_ClShowServerBroadcast && + if(MsgType == NETMSGTYPE_SV_BROADCAST && g_Config.m_ClShowServerBroadcast && !m_pClient->m_MuteServerBroadcast) { - //CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; - CNetMsg_Sv_Chat *pMsg = (CNetMsg_Sv_Chat *)pRawMsg; + CNetMsg_Sv_Broadcast *pMsg = (CNetMsg_Sv_Broadcast *)pRawMsg; // new broadcast message int RcvMsgLen = str_length(pMsg->m_pMessage); diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index 04b56427e..4401b6e22 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -367,7 +367,7 @@ void CMenus::RenderServerInfo(CUIRect MainView) CUIRect Button; ServerInfo.HSplitBottom(20.0f, &ServerInfo, &Button); static int s_MuteBroadcast = 0; - if(DoButton_CheckBox(&s_MuteBroadcast, Localize("Mute broadcast"), + if(DoButton_CheckBox(&s_MuteBroadcast, Localize("Mute broadcasts"), m_pClient->m_MuteServerBroadcast, &Button)) { m_pClient->m_MuteServerBroadcast ^= 1; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index c7dacf23e..aac126984 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -596,7 +596,7 @@ int CMenus::ThemeScan(const char *pName, int IsDir, int DirType, void *pUser) if(str_comp(aThemeName, "none") == 0) // "none" is reserved, disallowed for maps return 0; - + // try to edit an existing theme for(int i = 0; i < pSelf->m_lThemes.size(); i++) { @@ -628,7 +628,7 @@ int CMenus::ThemeIconScan(const char *pName, int IsDir, int DirType, void *pUser return 0; char aThemeName[128]; str_copy(aThemeName, pName, min((int)sizeof(aThemeName),l-3)); - + // save icon for an existing theme for(sorted_array::range r = pSelf->m_lThemes.all(); !r.empty(); r.pop_front()) // bit slow but whatever { @@ -804,7 +804,7 @@ void CMenus::RenderThemeSelection(CUIRect MainView, bool Header) Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } - + Item.m_Rect.y += 2.0f; char aName[128]; if(r.front().m_Name[0]) @@ -995,6 +995,13 @@ void CMenus::RenderSettingsGeneral(CUIRect MainView) g_Config.m_ClFilterchat = (g_Config.m_ClFilterchat + 1) % 3; } + GameRight.HSplitTop(Spacing, 0, &GameRight); + GameRight.HSplitTop(ButtonHeight, &Button, &GameRight); + static int s_EnableColoredBroadcasts = 0; + if(DoButton_CheckBox(&s_EnableColoredBroadcasts, Localize("Enable colored server broadcasts"), + g_Config.m_ClColoredBroadcast, &Button)) + g_Config.m_ClColoredBroadcast ^= 1; + // render client menu Client.HSplitTop(ButtonHeight, &Label, &Client); Label.y += 2.0f; From 1895d1a3faa031dd9cddade52d3c277f125ccf01 Mon Sep 17 00:00:00 2001 From: LordSk Date: Mon, 26 Nov 2018 17:56:07 +0100 Subject: [PATCH 10/10] Removed magic value, reverted hud.h --- src/game/client/components/broadcast.cpp | 8 ++++---- src/game/client/components/broadcast.h | 5 +++-- src/game/client/components/hud.h | 2 -- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/game/client/components/broadcast.cpp b/src/game/client/components/broadcast.cpp index 0e378dabf..bcf40145c 100644 --- a/src/game/client/components/broadcast.cpp +++ b/src/game/client/components/broadcast.cpp @@ -228,7 +228,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) m_aSrvBroadcastColorList[0] = White; m_SrvBroadcastColorCount = 1; - CBcLineInfo UserLines[3]; + CBcLineInfo UserLines[MAX_BROADCAST_LINES]; int UserLineCount = 0; int LastUserLineStartPoint = 0; @@ -257,7 +257,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) if(*c == CharUtf8 && *c == '\\') { - if(i+1 < RcvMsgLen && c[1] == 'n' && UserLineCount < 3) + if(i+1 < RcvMsgLen && c[1] == 'n' && UserLineCount < MAX_BROADCAST_LINES) { CBcLineInfo Line = { m_aSrvBroadcastMsg+LastUserLineStartPoint, m_aSrvBroadcastMsgLen-LastUserLineStartPoint, 0 }; @@ -310,7 +310,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) // make lines int CurCharCount = 0; - while(CurCharCount < MsgLen && m_SrvBroadcastLineCount < 3) + while(CurCharCount < MsgLen && m_SrvBroadcastLineCount < MAX_BROADCAST_LINES) { const char* RemainingMsg = pBroadcastMsg + CurCharCount; @@ -344,7 +344,7 @@ void CBroadcast::OnMessage(int MsgType, void* pRawMsg) { FontSize = BROADCAST_FONTSIZE_SMALL; - for(int i = 0; i < UserLineCount && m_SrvBroadcastLineCount < 3; i++) + for(int i = 0; i < UserLineCount && m_SrvBroadcastLineCount < MAX_BROADCAST_LINES; i++) { TextRender()->SetCursor(&Cursor, 0, 0, FontSize, TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = LineMaxWidth; diff --git a/src/game/client/components/broadcast.h b/src/game/client/components/broadcast.h index 7aa4e1eda..1893904a3 100644 --- a/src/game/client/components/broadcast.h +++ b/src/game/client/components/broadcast.h @@ -27,11 +27,12 @@ class CBroadcast : public CComponent enum { MAX_BROADCAST_COLORS = 128, - MAX_BROADCAST_MSG_LENGTH = 127 + MAX_BROADCAST_MSG_LENGTH = 127, + MAX_BROADCAST_LINES = 3, }; CBcColor m_aSrvBroadcastColorList[MAX_BROADCAST_COLORS]; - CBcLineInfo m_aSrvBroadcastLines[3]; + CBcLineInfo m_aSrvBroadcastLines[MAX_BROADCAST_LINES]; char m_aSrvBroadcastMsg[MAX_BROADCAST_MSG_LENGTH+1]; int m_aSrvBroadcastMsgLen; int m_SrvBroadcastColorCount; diff --git a/src/game/client/components/hud.h b/src/game/client/components/hud.h index 228e2b3f1..68b1b1770 100644 --- a/src/game/client/components/hud.h +++ b/src/game/client/components/hud.h @@ -3,7 +3,6 @@ #ifndef GAME_CLIENT_COMPONENTS_HUD_H #define GAME_CLIENT_COMPONENTS_HUD_H #include -#include class CHud : public CComponent { @@ -27,7 +26,6 @@ class CHud : public CComponent void RenderScoreHud(); void RenderSpectatorHud(); void RenderWarmupTimer(); - public: CHud();