Skip to content

Commit

Permalink
Support PRINT_TYPEWRITER and centerprint queue.
Browse files Browse the repository at this point in the history
  • Loading branch information
skullernet committed Dec 11, 2023
1 parent 6204d3f commit e020bdc
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 30 deletions.
14 changes: 10 additions & 4 deletions inc/shared/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,16 @@ q_noreturn q_printf(2, 3);
do { if (!(expr)) Com_Error(ERR_FATAL, "%s: assertion `%s' failed", __func__, #expr); } while (0)

// game print flags
#define PRINT_LOW 0 // pickup messages
#define PRINT_MEDIUM 1 // death messages
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
enum {
PRINT_LOW, // pickup messages
PRINT_MEDIUM, // death messages
PRINT_HIGH, // critical messages
PRINT_CHAT, // chat messages
// KEX
PRINT_TYPEWRITER,
PRINT_CENTER,
// KEX
};

// destination class for gi.multicast()
typedef enum {
Expand Down
3 changes: 2 additions & 1 deletion src/client/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,8 @@ extern vrect_t scr_vrect; // position of render window
void SCR_Init(void);
void SCR_Shutdown(void);
void SCR_UpdateScreen(void);
void SCR_CenterPrint(const char *str);
void SCR_CenterPrint(const char *str, bool typewrite);
void SCR_ClearCenterPrints(void);
void SCR_BeginLoadingPlaque(void);
void SCR_EndLoadingPlaque(void);
void SCR_RegisterMedia(void);
Expand Down
1 change: 1 addition & 0 deletions src/client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ void CL_ClearState(void)
S_StopAllSounds();
OGG_Stop();
SCR_StopCinematic();
SCR_ClearCenterPrints();
CL_ClearEffects();
CL_ClearTEnts();
LOC_FreeLocations();
Expand Down
7 changes: 5 additions & 2 deletions src/client/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,10 @@ static void CL_ParsePrint(void)
SHOWNET(2, " %i \"%s\"\n", level, Com_MakePrintable(s));

if (level != PRINT_CHAT) {
Com_Printf("%s", s);
if (cl.csr.extended && (level == PRINT_TYPEWRITER || level == PRINT_CENTER))
SCR_CenterPrint(s, level == PRINT_TYPEWRITER);
else
Com_Printf("%s", s);
if (!cls.demo.playback && cl.serverstate != ss_broadcast) {
COM_strclr(s);
Cmd_ExecTrigger(s);
Expand Down Expand Up @@ -1060,7 +1063,7 @@ static void CL_ParseCenterPrint(void)

MSG_ReadString(s, sizeof(s));
SHOWNET(2, " \"%s\"\n", Com_MakePrintable(s));
SCR_CenterPrint(s);
SCR_CenterPrint(s, false);

if (!cls.demo.playback && cl.serverstate != ss_broadcast) {
COM_strclr(s);
Expand Down
109 changes: 86 additions & 23 deletions src/client/screen.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ static struct {

static cvar_t *scr_viewsize;
static cvar_t *scr_centertime;
static cvar_t *scr_printspeed;
static cvar_t *scr_showpause;
#if USE_DEBUG
static cvar_t *scr_showstats;
Expand Down Expand Up @@ -168,18 +169,16 @@ void SCR_DrawStringMulti(int x, int y, int flags, size_t maxlen,
char *p;
size_t len;

while (*s) {
while (*s && maxlen) {
p = strchr(s, '\n');
if (!p) {
SCR_DrawStringEx(x, y, flags, maxlen, s, font);
break;
}

len = p - s;
if (len > maxlen) {
len = maxlen;
}
len = min(p - s, maxlen);
SCR_DrawStringEx(x, y, flags, len, s, font);
maxlen -= len;

y += CHAR_HEIGHT;
s = p + 1;
Expand Down Expand Up @@ -379,9 +378,24 @@ CENTER PRINTING
===============================================================================
*/

static char scr_centerstring[MAX_STRING_CHARS];
static unsigned scr_centertime_start; // for slow victory printing
static int scr_center_lines;
#define MAX_CENTERPRINTS_REAL 4
#define MAX_CENTERPRINTS (cl.csr.extended ? MAX_CENTERPRINTS_REAL : 1)

typedef struct {
char string[MAX_STRING_CHARS - 8];
uint32_t start;
uint16_t lines;
uint16_t typewrite; // msec to typewrite (0 if instant)
} centerprint_t;

static centerprint_t scr_centerprints[MAX_CENTERPRINTS_REAL];
static unsigned scr_centerhead, scr_centertail;

void SCR_ClearCenterPrints(void)
{
memset(scr_centerprints, 0, sizeof(scr_centerprints));
scr_centerhead = scr_centertail = 0;
}

/*
==============
Expand All @@ -391,53 +405,99 @@ Called for important messages that should stay in the center of the screen
for a few moments
==============
*/
void SCR_CenterPrint(const char *str)
void SCR_CenterPrint(const char *str, bool typewrite)
{
const char *s;
centerprint_t *cp;
const char *s;

scr_centertime_start = cls.realtime;
if (!strcmp(scr_centerstring, str)) {
// refresh duplicate message
cp = &scr_centerprints[(scr_centerhead - 1) & (MAX_CENTERPRINTS - 1)];
if (!strcmp(cp->string, str)) {
if (cp->start)
cp->start = cls.realtime;
if (scr_centertail == scr_centerhead)
scr_centertail--;
return;
}

Q_strlcpy(scr_centerstring, str, sizeof(scr_centerstring));
cp = &scr_centerprints[scr_centerhead & (MAX_CENTERPRINTS - 1)];
Q_strlcpy(cp->string, str, sizeof(cp->string));

// count the number of lines for centering
scr_center_lines = 1;
s = str;
cp->lines = 1;
s = cp->string;
while (*s) {
if (*s == '\n')
scr_center_lines++;
cp->lines++;
s++;
}

cp->start = 0; // not yet displayed
cp->typewrite = 0;

// for typewritten strings set minimum display time,
// but no longer than 30 sec
if (typewrite && scr_printspeed->value > 0) {
size_t nb_chars = strlen(cp->string) - cp->lines + 2;
cp->typewrite = min(nb_chars * 1000 / scr_printspeed->value + 300, 30000);
}

// echo it to the console
Com_Printf("%s\n", scr_centerstring);
Com_Printf("%s\n", cp->string);
Con_ClearNotify_f();

scr_centerhead++;
if (scr_centerhead - scr_centertail > MAX_CENTERPRINTS)
scr_centertail++;
}

static void SCR_DrawCenterString(void)
{
centerprint_t *cp;
int y;
float alpha;
size_t maxlen;

Cvar_ClampValue(scr_centertime, 0.3f, 10.0f);

alpha = SCR_FadeAlpha(scr_centertime_start, scr_centertime->value * 1000, 300);
if (!alpha) {
if (!scr_centertime->integer) {
scr_centertail = scr_centerhead;
return;
}

while (1) {
if (scr_centertail == scr_centerhead)
return;
cp = &scr_centerprints[scr_centertail & (MAX_CENTERPRINTS - 1)];
if (!cp->start)
cp->start = cls.realtime;
alpha = SCR_FadeAlpha(cp->start, max(scr_centertime->integer, cp->typewrite), 300);
if (alpha > 0)
break;
scr_centertail++;
}

R_SetAlpha(alpha * scr_alpha->value);

y = scr.hud_height / 4 - scr_center_lines * 8 / 2;
y = scr.hud_height / 4 - cp->lines * CHAR_HEIGHT / 2;

if (cp->typewrite)
maxlen = scr_printspeed->value * 0.001f * (cls.realtime - cp->start);
else
maxlen = MAX_STRING_CHARS;

SCR_DrawStringMulti(scr.hud_width / 2, y, UI_CENTER,
MAX_STRING_CHARS, scr_centerstring, scr.font_pic);
maxlen, cp->string, scr.font_pic);

R_SetAlpha(scr_alpha->value);
}

static void scr_centertime_changed(cvar_t *self)
{
if (self->value > 0)
self->integer = 1000 * Cvar_ClampValue(self, 1.0f, 30.0f);
else
self->integer = 0;
}

/*
===============================================================================
Expand Down Expand Up @@ -1250,6 +1310,9 @@ void SCR_Init(void)
scr_viewsize = Cvar_Get("viewsize", "100", CVAR_ARCHIVE);
scr_showpause = Cvar_Get("scr_showpause", "1", 0);
scr_centertime = Cvar_Get("scr_centertime", "2.5", 0);
scr_centertime->changed = scr_centertime_changed;
scr_centertime->changed(scr_centertime);
scr_printspeed = Cvar_Get("scr_printspeed", "16", 0);
scr_demobar = Cvar_Get("scr_demobar", "1", 0);
scr_font = Cvar_Get("scr_font", "conchars", 0);
scr_font->changed = scr_font_changed;
Expand Down

0 comments on commit e020bdc

Please sign in to comment.