buffer ingame chat

This commit is contained in:
Jupeyy 2018-03-13 21:50:49 +01:00
parent 62c3074c88
commit 59f9d021ce
2 changed files with 198 additions and 116 deletions

View file

@ -27,6 +27,11 @@
CChat::CChat()
{
for(int i = 0; i < MAX_LINES; i++)
{
// reset the container indices, so the text containers can be deleted on reset
m_aLines[i].m_TextContainerIndex = -1;
}
OnReset();
}
@ -34,11 +39,16 @@ void CChat::OnReset()
{
for(int i = 0; i < MAX_LINES; i++)
{
if(m_aLines[i].m_TextContainerIndex != -1)
TextRender()->DeleteTextContainer(m_aLines[i].m_TextContainerIndex);
m_aLines[i].m_Time = 0;
m_aLines[i].m_aText[0] = 0;
m_aLines[i].m_aName[0] = 0;
m_aLines[i].m_Friend = false;
m_aLines[i].m_TextContainerIndex = -1;
}
m_PrevScoreBoardShowed = false;
m_PrevShowChat = false;
m_ReverseTAB = false;
m_Mode = MODE_NONE;
@ -69,7 +79,9 @@ void CChat::OnStateChange(int NewState, int OldState)
m_Mode = MODE_NONE;
Input()->SetIMEState(false);
for(int i = 0; i < MAX_LINES; i++)
{
m_aLines[i].m_Time = 0;
}
m_CurrentLine = 0;
}
}
@ -176,7 +188,7 @@ bool CChat::OnInput(IInput::CEvent Event)
(m_Input.GetString()[Next] >= 91 && m_Input.GetString()[Next] <= 96))
{
FoundAt = i;
if (SearchDirection < 0)
if(SearchDirection < 0)
FoundAt++;
break;
}
@ -383,12 +395,12 @@ bool CChat::OnInput(IInput::CEvent Event)
if(m_pHistoryEntry)
m_Input.Set(m_pHistoryEntry->m_aText);
}
else if (Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_DOWN)
else if(Event.m_Flags&IInput::FLAG_PRESS && Event.m_Key == KEY_DOWN)
{
if(m_pHistoryEntry)
m_pHistoryEntry = m_History.Next(m_pHistoryEntry);
if (m_pHistoryEntry)
if(m_pHistoryEntry)
m_Input.Set(m_pHistoryEntry->m_aText);
else
m_Input.Clear();
@ -430,7 +442,7 @@ bool CChat::LineShouldHighlight(const char *pLine, const char *pName)
{
const char *pHL = str_find_nocase(pLine, pName);
if (pHL)
if(pHL)
{
int Length = str_length(pName);
@ -502,13 +514,17 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
m_aLines[m_CurrentLine].m_Team = Team;
m_aLines[m_CurrentLine].m_NameColor = -2;
if(m_aLines[m_CurrentLine].m_TextContainerIndex != -1)
TextRender()->DeleteTextContainer(m_aLines[m_CurrentLine].m_TextContainerIndex);
m_aLines[m_CurrentLine].m_TextContainerIndex = -1;
// check for highlighted name
if (Client()->State() != IClient::STATE_DEMOPLAYBACK)
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
{
if(ClientID != m_pClient->m_LocalIDs[0])
{
// main character
if (LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_LocalIDs[0]].m_aName))
if(LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_LocalIDs[0]].m_aName))
Highlighted = true;
// dummy
if(m_pClient->Client()->DummyConnected() && LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_LocalIDs[1]].m_aName))
@ -519,7 +535,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
{
// on demo playback use local id from snap directly,
// since m_LocalIDs isn't valid there
if (LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_aName))
if(LineShouldHighlight(pLine, m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_aName))
Highlighted = true;
}
@ -544,7 +560,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
m_aLines[m_CurrentLine].m_NameColor = TEAM_BLUE;
}
if (Team == 2) // whisper send
if(Team == 2) // whisper send
{
str_format(m_aLines[m_CurrentLine].m_aName, sizeof(m_aLines[m_CurrentLine].m_aName), "→ %s", m_pClient->m_aClients[ClientID].m_aName);
m_aLines[m_CurrentLine].m_NameColor = TEAM_BLUE;
@ -552,7 +568,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
m_aLines[m_CurrentLine].m_Team = 0;
Highlighted = false;
}
else if (Team == 3) // whisper recv
else if(Team == 3) // whisper recv
{
str_format(m_aLines[m_CurrentLine].m_aName, sizeof(m_aLines[m_CurrentLine].m_aName), "← %s", m_pClient->m_aClients[ClientID].m_aName);
m_aLines[m_CurrentLine].m_NameColor = TEAM_RED;
@ -613,7 +629,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
{
if(Now-m_aLastSoundPlayed[CHAT_CLIENT] >= time_freq()*3/10)
{
if ((g_Config.m_SndTeamChat || !m_aLines[m_CurrentLine].m_Team)
if((g_Config.m_SndTeamChat || !m_aLines[m_CurrentLine].m_Team)
&& (g_Config.m_SndChat || m_aLines[m_CurrentLine].m_Team))
{
m_pClient->m_pSounds->Play(CSounds::CHN_GUI, SOUND_CHAT_CLIENT, 0);
@ -623,6 +639,162 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
}
}
void CChat::OnPrepareLines()
{
float x = 5.0f;
float y = 300.0f - 28.0f;
#if defined(__ANDROID__)
x += 120.0f;
#endif
#if defined(__ANDROID__)
float FontSize = 10.0f;
#else
float FontSize = 6.0f;
#endif
bool ForceRecreate = m_pClient->m_pScoreboard->Active() != m_PrevScoreBoardShowed;
ForceRecreate |= m_Show != m_PrevShowChat;
m_PrevScoreBoardShowed = m_pClient->m_pScoreboard->Active();
m_PrevShowChat = m_Show;
int64 Now = time_get();
float LineWidth = m_pClient->m_pScoreboard->Active() ? 90.0f : 200.0f;
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 230.0f : m_Show ? 50.0f : 200.0f;
float Begin = x;
CTextCursor Cursor;
int OffsetType = m_pClient->m_pScoreboard->Active() ? 1 : 0;
for(int i = 0; i < MAX_LINES; i++)
{
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_Show)
break;
if(m_aLines[r].m_TextContainerIndex != -1 && !ForceRecreate)
continue;
if(m_aLines[r].m_TextContainerIndex != -1)
TextRender()->DeleteTextContainer(m_aLines[r].m_TextContainerIndex);
m_aLines[r].m_TextContainerIndex = -1;
char aName[64] = "";
if(g_Config.m_ClShowIDs && m_aLines[r].m_ClientID != -1 && m_aLines[r].m_aName[0] != '\0')
{
if(m_aLines[r].m_ClientID >= 10)
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
else
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
str_append(aName, m_aLines[r].m_aName, sizeof(aName));
}
else
{
str_copy(aName, m_aLines[r].m_aName, sizeof(aName));
}
// get the y offset (calculate it if we haven't done that yet)
if(m_aLines[r].m_YOffset[OffsetType] < 0.0f)
{
TextRender()->SetCursor(&Cursor, Begin, 0.0f, FontSize, 0);
Cursor.m_LineWidth = LineWidth;
TextRender()->TextEx(&Cursor, "", -1);
TextRender()->TextEx(&Cursor, aName, -1);
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
m_aLines[r].m_YOffset[OffsetType] = Cursor.m_Y + Cursor.m_FontSize;
}
y -= m_aLines[r].m_YOffset[OffsetType];
// cut off if msgs waste too much space
if(y < HeightLimit)
break;
// the position the text was created
m_aLines[r].m_TextYOffset = y;
// reset the cursor
TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER);
Cursor.m_LineWidth = LineWidth;
if(g_Config.m_ClMessageFriend)
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageFriendHue / 255.0f, g_Config.m_ClMessageFriendSat / 255.0f, g_Config.m_ClMessageFriendLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, m_aLines[r].m_Friend ? 1.f : 0.f); //Less ugly hack to align messages
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, "");
}
// render name
if(m_aLines[r].m_ClientID == -1) // system
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageSystemHue / 255.0f, g_Config.m_ClMessageSystemSat / 255.0f, g_Config.m_ClMessageSystemLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else if(m_aLines[r].m_ClientID == -2) // client
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageClientHue / 255.0f, g_Config.m_ClMessageClientSat / 255.0f, g_Config.m_ClMessageClientLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else if(m_aLines[r].m_Team)
{
vec3 rgb = CalculateNameColor(vec3(g_Config.m_ClMessageTeamHue / 255.0f, g_Config.m_ClMessageTeamSat / 255.0f, g_Config.m_ClMessageTeamLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f); // team message
}
else if(m_aLines[r].m_NameColor == TEAM_RED)
TextRender()->TextColor(1.0f, 0.5f, 0.5f, 1.f); // red
else if(m_aLines[r].m_NameColor == TEAM_BLUE)
TextRender()->TextColor(0.7f, 0.7f, 1.0f, 1.f); // blue
else if(m_aLines[r].m_NameColor == TEAM_SPECTATORS)
TextRender()->TextColor(0.75f, 0.5f, 0.75f, 1.f); // spectator
else if(m_aLines[r].m_ClientID >= 0 && g_Config.m_ClChatTeamColors && m_pClient->m_Teams.Team(m_aLines[r].m_ClientID))
{
vec3 rgb = HslToRgb(vec3(m_pClient->m_Teams.Team(m_aLines[r].m_ClientID) / 64.0f, 1.0f, 0.75f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else
TextRender()->TextColor(0.8f, 0.8f, 0.8f, 1.f);
if(m_aLines[r].m_TextContainerIndex == -1)
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, aName);
else
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, aName);
// render line
if(m_aLines[r].m_ClientID == -1) // system
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageSystemHue / 255.0f, g_Config.m_ClMessageSystemSat / 255.0f, g_Config.m_ClMessageSystemLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else if(m_aLines[r].m_ClientID == -2) // client
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageClientHue / 255.0f, g_Config.m_ClMessageClientSat / 255.0f, g_Config.m_ClMessageClientLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else if(m_aLines[r].m_Highlighted) // highlighted
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageHighlightHue / 255.0f, g_Config.m_ClMessageHighlightSat / 255.0f, g_Config.m_ClMessageHighlightLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else if(m_aLines[r].m_Team) // team message
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageTeamHue / 255.0f, g_Config.m_ClMessageTeamSat / 255.0f, g_Config.m_ClMessageTeamLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
else // regular message
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageHue / 255.0f, g_Config.m_ClMessageSat / 255.0f, g_Config.m_ClMessageLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, 1.f);
}
if(m_aLines[r].m_TextContainerIndex == -1)
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, m_aLines[r].m_aText);
else
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, m_aLines[r].m_aText);
}
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void CChat::OnRender()
{
// send pending chat messages
@ -664,7 +836,7 @@ void CChat::OnRender()
// IME candidate editing
bool Editing = false;
int EditingCursor = Input()->GetEditingCursor();
if (Input()->GetIMEState())
if(Input()->GetIMEState())
{
if(str_length(Input()->GetIMECandidate()))
{
@ -707,7 +879,7 @@ void CChat::OnRender()
TextRender()->TextEx(&Cursor, m_Input.GetString(Editing)+m_Input.GetCursorOffset(Editing), -1);
}
if (!g_Config.m_ClShowChat)
if(!g_Config.m_ClShowChat)
return;
y -= 8.0f;
@ -715,16 +887,10 @@ void CChat::OnRender()
x += 120.0f;
#endif
#if defined(__ANDROID__)
float FontSize = 10.0f;
#else
float FontSize = 6.0f;
#endif
OnPrepareLines();
int64 Now = time_get();
float LineWidth = m_pClient->m_pScoreboard->Active() ? 90.0f : 200.0f;
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 230.0f : m_Show ? 50.0f : 200.0f;
float Begin = x;
CTextCursor Cursor;
int OffsetType = m_pClient->m_pScoreboard->Active() ? 1 : 0;
for(int i = 0; i < MAX_LINES; i++)
{
@ -732,113 +898,22 @@ void CChat::OnRender()
if(Now > m_aLines[r].m_Time+16*time_freq() && !m_Show)
break;
char aName[64] = "";
if(g_Config.m_ClShowIDs && m_aLines[r].m_ClientID != -1 && m_aLines[r].m_aName[0] != '\0')
{
if (m_aLines[r].m_ClientID >= 10)
str_format(aName, sizeof(aName),"%d: ", m_aLines[r].m_ClientID);
else
str_format(aName, sizeof(aName),"%d: ", m_aLines[r].m_ClientID);
str_append(aName, m_aLines[r].m_aName,sizeof(aName));
}
else
{
str_copy(aName, m_aLines[r].m_aName, sizeof(aName));
}
// get the y offset (calculate it if we haven't done that yet)
if(m_aLines[r].m_YOffset[OffsetType] < 0.0f)
{
TextRender()->SetCursor(&Cursor, Begin, 0.0f, FontSize, 0);
Cursor.m_LineWidth = LineWidth;
TextRender()->TextEx(&Cursor, "", -1);
TextRender()->TextEx(&Cursor, aName, -1);
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
m_aLines[r].m_YOffset[OffsetType] = Cursor.m_Y + Cursor.m_FontSize;
}
y -= m_aLines[r].m_YOffset[OffsetType];
// cut off if msgs waste too much space
if(y < HeightLimit)
break;
float Blend = Now > m_aLines[r].m_Time+14*time_freq() && !m_Show ? 1.0f-(Now-m_aLines[r].m_Time-14*time_freq())/(2.0f*time_freq()) : 1.0f;
float Blend = Now > m_aLines[r].m_Time + 14 * time_freq() && !m_Show ? 1.0f - (Now - m_aLines[r].m_Time - 14 * time_freq()) / (2.0f*time_freq()) : 1.0f;
// reset the cursor
TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER);
Cursor.m_LineWidth = LineWidth;
if(g_Config.m_ClMessageFriend)
if(m_aLines[r].m_TextContainerIndex != -1)
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageFriendHue / 255.0f, g_Config.m_ClMessageFriendSat / 255.0f, g_Config.m_ClMessageFriendLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, m_aLines[r].m_Friend ? Blend : 0); //Less ugly hack to align messages
TextRender()->TextEx(&Cursor, "", -1);
STextRenderColor TextOutline(0.f, 0.f, 0.f, 0.3f * Blend);
STextRenderColor Text(1.f, 1.f, 1.f, Blend);
TextRender()->RenderTextContainer(m_aLines[r].m_TextContainerIndex, &Text, &TextOutline, 0, y - m_aLines[r].m_TextYOffset);
}
// render name
if (m_aLines[r].m_ClientID == -1) // system
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageSystemHue / 255.0f, g_Config.m_ClMessageSystemSat / 255.0f, g_Config.m_ClMessageSystemLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else if (m_aLines[r].m_ClientID == -2) // client
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageClientHue / 255.0f, g_Config.m_ClMessageClientSat / 255.0f, g_Config.m_ClMessageClientLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else if (m_aLines[r].m_Team)
{
vec3 rgb = CalculateNameColor(vec3(g_Config.m_ClMessageTeamHue / 255.0f, g_Config.m_ClMessageTeamSat / 255.0f, g_Config.m_ClMessageTeamLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend); // team message
}
else if(m_aLines[r].m_NameColor == TEAM_RED)
TextRender()->TextColor(1.0f, 0.5f, 0.5f, Blend); // red
else if(m_aLines[r].m_NameColor == TEAM_BLUE)
TextRender()->TextColor(0.7f, 0.7f, 1.0f, Blend); // blue
else if(m_aLines[r].m_NameColor == TEAM_SPECTATORS)
TextRender()->TextColor(0.75f, 0.5f, 0.75f, Blend); // spectator
else if(m_aLines[r].m_ClientID >= 0 && g_Config.m_ClChatTeamColors && m_pClient->m_Teams.Team(m_aLines[r].m_ClientID))
{
vec3 rgb = HslToRgb(vec3(m_pClient->m_Teams.Team(m_aLines[r].m_ClientID) / 64.0f, 1.0f, 0.75f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else
TextRender()->TextColor(0.8f, 0.8f, 0.8f, Blend);
TextRender()->TextEx(&Cursor, aName, -1);
// render line
if (m_aLines[r].m_ClientID == -1) // system
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageSystemHue / 255.0f, g_Config.m_ClMessageSystemSat / 255.0f, g_Config.m_ClMessageSystemLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else if (m_aLines[r].m_ClientID == -2) // client
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageClientHue / 255.0f, g_Config.m_ClMessageClientSat / 255.0f, g_Config.m_ClMessageClientLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else if (m_aLines[r].m_Highlighted) // highlighted
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageHighlightHue / 255.0f, g_Config.m_ClMessageHighlightSat / 255.0f, g_Config.m_ClMessageHighlightLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else if (m_aLines[r].m_Team) // team message
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageTeamHue / 255.0f, g_Config.m_ClMessageTeamSat / 255.0f, g_Config.m_ClMessageTeamLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
else // regular message
{
vec3 rgb = HslToRgb(vec3(g_Config.m_ClMessageHue / 255.0f, g_Config.m_ClMessageSat / 255.0f, g_Config.m_ClMessageLht / 255.0f));
TextRender()->TextColor(rgb.r, rgb.g, rgb.b, Blend);
}
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
}
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
#if defined(__ANDROID__)
static int deferEvent = 0;
if( UI()->AndroidTextInputShown() )

View file

@ -26,8 +26,14 @@ class CChat : public CComponent
char m_aText[512];
bool m_Friend;
bool m_Highlighted;
int m_TextContainerIndex;
float m_TextYOffset;
};
bool m_PrevScoreBoardShowed;
bool m_PrevShowChat;
CLine m_aLines[MAX_LINES];
int m_CurrentLine;
@ -92,6 +98,7 @@ public:
virtual void OnConsoleInit();
virtual void OnStateChange(int NewState, int OldState);
virtual void OnRender();
virtual void OnPrepareLines();
virtual void OnRelease();
virtual void OnMessage(int MsgType, void *pRawMsg);
virtual bool OnInput(IInput::CEvent Event);