mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
Moved the code over to broadcast.cpp
This commit is contained in:
parent
102a28a48b
commit
8d19f5f8a8
|
@ -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(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(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")
|
MACRO_CONFIG_STR(BrFilterString, br_filter_string, 25, "", CFGFLAG_SAVE|CFGFLAG_CLIENT, "Server browser filtering string")
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,214 @@
|
||||||
|
|
||||||
#include <game/client/gameclient.h>
|
#include <game/client/gameclient.h>
|
||||||
|
|
||||||
#include <game/client/components/motd.h>
|
|
||||||
#include <game/client/components/scoreboard.h>
|
|
||||||
|
|
||||||
#include "broadcast.h"
|
#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()
|
CBroadcast::CBroadcast()
|
||||||
{
|
{
|
||||||
|
@ -27,7 +230,7 @@ void CBroadcast::DoBroadcast(const char *pText)
|
||||||
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect();
|
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect();
|
||||||
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
|
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
|
||||||
m_BroadcastRenderOffset = 150*Graphics()->ScreenAspect()-Cursor.m_X/2;
|
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()
|
void CBroadcast::OnReset()
|
||||||
|
@ -35,6 +238,53 @@ void CBroadcast::OnReset()
|
||||||
m_BroadcastTime = 0;
|
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()
|
void CBroadcast::OnRender()
|
||||||
{
|
{
|
||||||
if(m_pClient->m_pScoreboard->Active() || m_pClient->m_pMotd->IsActive())
|
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);
|
Graphics()->MapScreen(0, 0, 300*Graphics()->ScreenAspect(), 300);
|
||||||
|
|
||||||
if(time_get() < m_BroadcastTime)
|
// client broadcast
|
||||||
|
if(Client()->LocalTime() < m_BroadcastTime)
|
||||||
{
|
{
|
||||||
CTextCursor Cursor;
|
CTextCursor Cursor;
|
||||||
TextRender()->SetCursor(&Cursor, m_BroadcastRenderOffset, 40.0f, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
|
TextRender()->SetCursor(&Cursor, m_BroadcastRenderOffset, 40.0f, 12.0f, TEXTFLAG_RENDER|TEXTFLAG_STOP_AT_END);
|
||||||
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-m_BroadcastRenderOffset;
|
Cursor.m_LineWidth = 300*Graphics()->ScreenAspect()-m_BroadcastRenderOffset;
|
||||||
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
|
TextRender()->TextEx(&Cursor, m_aBroadcastText, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// server broadcast
|
||||||
|
RenderServerBroadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,37 @@
|
||||||
class CBroadcast : public CComponent
|
class CBroadcast : public CComponent
|
||||||
{
|
{
|
||||||
char m_aBroadcastText[128];
|
char m_aBroadcastText[128];
|
||||||
int64 m_BroadcastTime;
|
float m_BroadcastTime;
|
||||||
float m_BroadcastRenderOffset;
|
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:
|
public:
|
||||||
CBroadcast();
|
CBroadcast();
|
||||||
|
|
||||||
void DoBroadcast(const char *pText);
|
void DoBroadcast(const char *pText);
|
||||||
|
|
||||||
virtual void OnReset();
|
virtual void OnReset();
|
||||||
|
virtual void OnMessage(int MsgType, void *pRawMsg);
|
||||||
virtual void OnRender();
|
virtual void OnRender();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "voting.h"
|
#include "voting.h"
|
||||||
#include "binds.h"
|
#include "binds.h"
|
||||||
#include "chat.h"
|
|
||||||
#include "scoreboard.h"
|
|
||||||
#include "motd.h"
|
|
||||||
|
|
||||||
CHud::CHud()
|
CHud::CHud()
|
||||||
{
|
{
|
||||||
|
@ -27,9 +24,6 @@ CHud::CHud()
|
||||||
m_AverageFPS = 1.0f;
|
m_AverageFPS = 1.0f;
|
||||||
|
|
||||||
m_WarmupHideTick = 0;
|
m_WarmupHideTick = 0;
|
||||||
m_BroadcastColorCount = 0;
|
|
||||||
m_aBroadcastMsg[0] = 0;
|
|
||||||
m_BroadcastReceivedTime = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHud::OnReset()
|
void CHud::OnReset()
|
||||||
|
@ -37,58 +31,6 @@ void CHud::OnReset()
|
||||||
m_WarmupHideTick = 0;
|
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()
|
void CHud::RenderGameTimer()
|
||||||
{
|
{
|
||||||
float Half = 300.0f*Graphics()->ScreenAspect()/2.0f;
|
float Half = 300.0f*Graphics()->ScreenAspect()/2.0f;
|
||||||
|
@ -750,7 +692,6 @@ void CHud::OnRender()
|
||||||
RenderSuddenDeath();
|
RenderSuddenDeath();
|
||||||
RenderScoreHud();
|
RenderScoreHud();
|
||||||
RenderWarmupTimer();
|
RenderWarmupTimer();
|
||||||
RenderBroadcast();
|
|
||||||
RenderFps();
|
RenderFps();
|
||||||
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||||
RenderConnectionWarning();
|
RenderConnectionWarning();
|
||||||
|
@ -759,189 +700,3 @@ void CHud::OnRender()
|
||||||
}
|
}
|
||||||
RenderCursor();
|
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,25 +11,6 @@ class CHud : public CComponent
|
||||||
float m_AverageFPS;
|
float m_AverageFPS;
|
||||||
int64 m_WarmupHideTick;
|
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 RenderCursor();
|
||||||
|
|
||||||
void RenderFps();
|
void RenderFps();
|
||||||
|
@ -46,12 +27,11 @@ class CHud : public CComponent
|
||||||
void RenderScoreHud();
|
void RenderScoreHud();
|
||||||
void RenderSpectatorHud();
|
void RenderSpectatorHud();
|
||||||
void RenderWarmupTimer();
|
void RenderWarmupTimer();
|
||||||
void RenderBroadcast();
|
|
||||||
public:
|
public:
|
||||||
CHud();
|
CHud();
|
||||||
|
|
||||||
virtual void OnReset();
|
virtual void OnReset();
|
||||||
virtual void OnMessage(int MsgType, void *pRawMsg);
|
|
||||||
virtual void OnRender();
|
virtual void OnRender();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue