From 41c20663a86ad68d37cd03f7d7113705ebfe3969 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Tue, 28 Mar 2023 16:36:21 -0700 Subject: [PATCH] Client: text channel 0 now contains a message queue, so that multiple messages can stack without overriding one another --- src/client/text.h | 9 +++ src/client/text.qc | 158 ++++++++++++++++++++++++++++++++------------- 2 files changed, 121 insertions(+), 46 deletions(-) diff --git a/src/client/text.h b/src/client/text.h index df2d0ffa..bb834e7d 100644 --- a/src/client/text.h +++ b/src/client/text.h @@ -38,6 +38,15 @@ typedef struct /** Global pool of text channels. */ gametext_t g_textchannels[6]; +#define TEXTQUEUE_MAX 6 + +/** this is reserved for channel 0 */ +gametext_t g_textqueue[TEXTQUEUE_MAX]; + + +int g_textqueue_next; +int g_textqueue_count; + /** Used by Nuclide to draw all active text channels to the screen. */ void GameText_Draw(void); diff --git a/src/client/text.qc b/src/client/text.qc index 868966f2..c7f73e75 100644 --- a/src/client/text.qc +++ b/src/client/text.qc @@ -59,7 +59,7 @@ GameText_DrawString(vector pos, string msg, vector col, float alpha) } static void -GameText_DrawMessage(int i, float timer, int highlight) +GameText_DrawMessage(gametext_t *txt, float timer, int highlight) { float a = 0.0f; vector rpos = [0.0f, 0.0f, 0.0f]; @@ -68,52 +68,79 @@ GameText_DrawMessage(int i, float timer, int highlight) string finalstr; /* typing effect */ - if (g_textchannels[i].m_iEffect == 2) { + if (txt->m_iEffect == 2) { /* scan out */ - finalstr = substring(g_textchannels[i].m_strMessage, 0, - GameText_CharCount(g_textchannels[i].m_flFadeIn, timer, - g_textchannels[i].m_strMessage)); + finalstr = substring(txt->m_strMessage, 0, + GameText_CharCount(txt->m_flFadeIn, timer, + txt->m_strMessage)); } else { - finalstr = g_textchannels[i].m_strMessage; + finalstr = txt->m_strMessage; } timer = max(0, timer); if (highlight) { - btime = g_textchannels[i].m_flFadeIn * \ - strlen(g_textchannels[i].m_strMessage); - mtime = btime + g_textchannels[i].m_flFadeOut; + btime = txt->m_flFadeIn * \ + strlen(txt->m_strMessage); + mtime = btime + txt->m_flFadeOut; } else { - mtime = g_textchannels[i].m_flFadeIn + \ - g_textchannels[i].m_flHoldTime + \ - g_textchannels[i].m_flFadeOut; - btime = g_textchannels[i].m_flFadeIn + \ - g_textchannels[i].m_flHoldTime; + mtime = txt->m_flFadeIn + \ + txt->m_flHoldTime + \ + txt->m_flFadeOut; + btime = txt->m_flFadeIn + \ + txt->m_flHoldTime; } - if (timer > mtime) + if (timer > mtime) { return; + } - if (timer < g_textchannels[i].m_flFadeIn) { - a = (timer / g_textchannels[i].m_flFadeIn); + if (timer < txt->m_flFadeIn) { + a = (timer / txt->m_flFadeIn); } else if (timer < btime) { a = 1.0f; } else if (timer < mtime) { - if (g_textchannels[i].m_flFadeOut) { - a = 1 - (timer - btime) / g_textchannels[i].m_flFadeOut; + if (txt->m_flFadeOut) { + a = 1 - (timer - btime) / txt->m_flFadeOut; } } - rpos[0] = g_textchannels[i].m_flPosX; - rpos[1] = g_textchannels[i].m_flPosY; + rpos[0] = txt->m_flPosX; + rpos[1] = txt->m_flPosY; if (highlight) { - GameText_DrawString(rpos, finalstr, g_textchannels[i].m_vecColor2, a); + GameText_DrawString(rpos, finalstr, txt->m_vecColor2, a); } else { - GameText_DrawString(rpos, finalstr, g_textchannels[i].m_vecColor1, a); + GameText_DrawString(rpos, finalstr, txt->m_vecColor1, a); } } +static void +GameText_Copy(gametext_t *src, gametext_t *dest) +{ + dest->m_strMessage = src->m_strMessage; + dest->m_flTime = src->m_flTime; + dest->m_flPosX = src->m_flPosX; + dest->m_iEffect = src->m_iEffect; + dest->m_vecColor2 = src->m_vecColor2; + dest->m_flFadeIn = src->m_flFadeIn; + dest->m_flFadeOut = src->m_flFadeOut; + dest->m_flHoldTime = src->m_flHoldTime; + dest->m_flFXTime = src->m_flFXTime; + dest->m_vecColor1 = src->m_vecColor1; + dest->m_vecColor2 = src->m_vecColor2; +} + +static void +GameText_QueueNext(void) +{ + for (int i = 0; i < (g_textqueue_count-1); i++) { + GameText_Copy(&g_textqueue[i+1], &g_textqueue[i]); + } + g_textqueue_next--; + g_textqueue_count--; +} + void GameText_Draw(void) { @@ -126,11 +153,11 @@ GameText_Draw(void) for (int i = 0i; i < 6; i++) { /* we'll draw the highlight separately */ - GameText_DrawMessage(i, g_textchannels[i].m_flTime - g_textchannels[i].m_flFXTime, 0); /* first pass */ + GameText_DrawMessage(&g_textchannels[i], g_textchannels[i].m_flTime - g_textchannels[i].m_flFXTime, 0); /* first pass */ /* effect 0 has no highlight */ if (g_textchannels[i].m_iEffect != 0) - GameText_DrawMessage(i, g_textchannels[i].m_flTime, 1); /* second pass */ + GameText_DrawMessage(&g_textchannels[i], g_textchannels[i].m_flTime, 1); /* second pass */ g_textchannels[i].m_flTime += clframetime; @@ -140,6 +167,29 @@ GameText_Draw(void) Font_DrawText(debugPos, sprintf("Chan %i: E %i T: %f/%f", i, g_textchannels[i].m_iEffect, g_textchannels[i].m_flTime, g_textchannels[i].m_flHoldTime), FONT_CON); debugPos[1] += 20; } + + /* process the channel 0 queue */ + if (g_textqueue_count <= 0) { + return; + } + + /* if the message is empty, move the msgs down by 1 */ + if (g_textqueue[0].m_strMessage == __NULL__) { + GameText_QueueNext(); + } + + GameText_DrawMessage(&g_textqueue[0], g_textqueue[0].m_flTime - g_textqueue[0].m_flFXTime, 0); /* first pass */ + + if (g_textqueue[0].m_iEffect != 0) + GameText_DrawMessage(&g_textqueue[0], g_textqueue[0].m_flTime, 1); /* second pass */ + + g_textqueue[0].m_flTime += clframetime; + + float maxTime = g_textqueue[0].m_flFadeIn + g_textqueue[0].m_flFadeOut + g_textqueue[0].m_flHoldTime + g_textqueue[0].m_flFXTime; + + if (g_textqueue[0].m_flTime >= maxTime) + g_textqueue[0].m_strMessage = __NULL__; + } void @@ -199,6 +249,7 @@ GameText_Parse(void) void GameMessage_Setup(string message, int channel) { + gametext_t *next; int findid = -1; for (int i = 0; i < g_titles_count; i++) { @@ -207,27 +258,41 @@ GameMessage_Setup(string message, int channel) } } - if (findid < 0) { - g_textchannels[channel].m_strMessage = Titles_ParseFunString(message); - g_textchannels[channel].m_flTime = 0.0f; - g_textchannels[channel].m_flPosX = -1; - g_textchannels[channel].m_flPosY = 0.75f; - g_textchannels[channel].m_flFadeIn = 0.5f; - g_textchannels[channel].m_flFadeOut = 0.5f; - g_textchannels[channel].m_flHoldTime = 2.0f; - g_textchannels[channel].m_vecColor1 = [1,1,1]; - g_textchannels[channel].m_vecColor2 = [1,1,1]; + /* channel 0 is a rotating queue */ + if (channel == 0) { + /* clear the oldest message if needed */ + if (g_textqueue_next + 1 >= TEXTQUEUE_MAX) + GameText_QueueNext(); + + channel = g_textqueue_next++; + next = &g_textqueue[channel]; + g_textqueue_count++; + } else { - g_textchannels[channel].m_strMessage = g_titles[findid].m_strMessage; - g_textchannels[channel].m_flTime = 0.0f; - g_textchannels[channel].m_flPosX = g_titles[findid].m_flPosX; - g_textchannels[channel].m_flPosY = g_titles[findid].m_flPosY; - g_textchannels[channel].m_flFadeIn = g_titles[findid].m_flFadeIn; - g_textchannels[channel].m_flFadeOut = g_titles[findid].m_flFadeOut; - g_textchannels[channel].m_flHoldTime = g_titles[findid].m_flHoldTime; - g_textchannels[channel].m_vecColor1 = g_titles[findid].m_vecColor1; - g_textchannels[channel].m_vecColor2 = g_titles[findid].m_vecColor2; - g_textchannels[channel].m_iEffect = g_titles[findid].m_iEffect; + next = &g_textchannels[channel]; + } + + if (findid < 0) { + next->m_strMessage = Titles_ParseFunString(message); + next->m_flTime = 0.0f; + next->m_flPosX = -1; + next->m_flPosY = 0.75f; + next->m_flFadeIn = 0.5f; + next->m_flFadeOut = 0.5f; + next->m_flHoldTime = 2.0f; + next->m_vecColor1 = [1,1,1]; + next->m_vecColor2 = [1,1,1]; + } else { + next->m_strMessage = g_titles[findid].m_strMessage; + next->m_flTime = 0.0f; + next->m_flPosX = g_titles[findid].m_flPosX; + next->m_flPosY = g_titles[findid].m_flPosY; + next->m_flFadeIn = g_titles[findid].m_flFadeIn; + next->m_flFadeOut = g_titles[findid].m_flFadeOut; + next->m_flHoldTime = g_titles[findid].m_flHoldTime; + next->m_vecColor1 = g_titles[findid].m_vecColor1; + next->m_vecColor2 = g_titles[findid].m_vecColor2; + next->m_iEffect = g_titles[findid].m_iEffect; } } @@ -246,5 +311,6 @@ GameMessage_Parse(void) flVolume = readfloat(); iAttenuation = readbyte(); - sound(self, CHAN_ITEM, strSound, flVolume, iAttenuation); + if (strSound) + sound(self, CHAN_ITEM, strSound, flVolume, iAttenuation); }