Allow queueing of centerprints.
This commit is contained in:
parent
7b5d2745ed
commit
e39b29b130
3 changed files with 112 additions and 47 deletions
|
@ -262,10 +262,11 @@ void *scr_curcursor;
|
||||||
|
|
||||||
static void SCR_CPrint_f(void)
|
static void SCR_CPrint_f(void)
|
||||||
{
|
{
|
||||||
|
int seat = CL_TargettedSplit(false);
|
||||||
if (Cmd_Argc() == 2)
|
if (Cmd_Argc() == 2)
|
||||||
SCR_CenterPrint(0, Cmd_Argv(1), true);
|
SCR_CenterPrint(seat, Cmd_Argv(1), true);
|
||||||
else
|
else
|
||||||
SCR_CenterPrint(0, Cmd_Args(), true);
|
SCR_CenterPrint(seat, Cmd_Args(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char cl_screengroup[];
|
extern char cl_screengroup[];
|
||||||
|
@ -317,7 +318,7 @@ CENTER PRINTING
|
||||||
===============================================================================
|
===============================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct cprint_s {
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
conchar_t *string;
|
conchar_t *string;
|
||||||
|
@ -331,9 +332,11 @@ typedef struct {
|
||||||
int erase_center;
|
int erase_center;
|
||||||
|
|
||||||
int oldmousex, oldmousey; //so the cursorchar can be changed by keyboard without constantly getting stomped on.
|
int oldmousex, oldmousey; //so the cursorchar can be changed by keyboard without constantly getting stomped on.
|
||||||
|
|
||||||
|
struct cprint_s *queue; //switch to the next on timeout.
|
||||||
} cprint_t;
|
} cprint_t;
|
||||||
|
|
||||||
cprint_t scr_centerprint[MAX_SPLITS];
|
static cprint_t *scr_centerprint[MAX_SPLITS];
|
||||||
|
|
||||||
// SCR_StringToRGB: takes in "<index>" or "<r> <g> <b>" and converts to an RGB vector
|
// SCR_StringToRGB: takes in "<index>" or "<r> <g> <b>" and converts to an RGB vector
|
||||||
void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale)
|
void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale)
|
||||||
|
@ -397,6 +400,22 @@ void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale)
|
||||||
} // i contains the crosshair color
|
} // i contains the crosshair color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qboolean SCR_CenterPrintPop(int pnum)
|
||||||
|
{
|
||||||
|
cprint_t *p = scr_centerprint[pnum];
|
||||||
|
if (!p)
|
||||||
|
return false;
|
||||||
|
scr_centerprint[pnum] = p->queue;
|
||||||
|
Z_Free(p->string);
|
||||||
|
Z_Free(p);
|
||||||
|
|
||||||
|
//timers start NOW (not when its first queued, obviously)
|
||||||
|
p = scr_centerprint[pnum];
|
||||||
|
if (p)
|
||||||
|
p->time_start = cl.time;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============
|
==============
|
||||||
SCR_CenterPrint
|
SCR_CenterPrint
|
||||||
|
@ -409,7 +428,9 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
{
|
{
|
||||||
unsigned int pfl = 0;
|
unsigned int pfl = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
cprint_t *p;
|
cprint_t *p, **l;
|
||||||
|
qboolean doqueue = false;
|
||||||
|
qboolean donotify = ((scr_logcenterprint.ival && !cl.deathmatch) || scr_logcenterprint.ival == 2);
|
||||||
#ifdef HAVE_LEGACY
|
#ifdef HAVE_LEGACY
|
||||||
if (scr_usekfont.ival)
|
if (scr_usekfont.ival)
|
||||||
pfl |= PFS_FORCEUTF8;
|
pfl |= PFS_FORCEUTF8;
|
||||||
|
@ -417,11 +438,8 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
if (!str)
|
if (!str)
|
||||||
{
|
{
|
||||||
if (cl.intermissionmode == IM_NONE)
|
if (cl.intermissionmode == IM_NONE)
|
||||||
{
|
while(SCR_CenterPrintPop(pnum))
|
||||||
p = &scr_centerprint[pnum];
|
;
|
||||||
p->flags = 0;
|
|
||||||
p->time_off = 0;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!skipgamecode)
|
if (!skipgamecode)
|
||||||
|
@ -445,10 +463,11 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = &scr_centerprint[pnum];
|
p = Z_Malloc(sizeof(*p));
|
||||||
p->flags = 0;
|
p->flags = 0;
|
||||||
p->titleimage[0] = 0;
|
p->titleimage[0] = 0;
|
||||||
p->cursorchar = NULL;
|
p->cursorchar = NULL;
|
||||||
|
p->time_off = scr_centertime.value;
|
||||||
|
|
||||||
if (*str != '/')
|
if (*str != '/')
|
||||||
{
|
{
|
||||||
|
@ -477,10 +496,22 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
p->flags |= CPRINT_CURSOR; //this can be a little jarring if there's no links, so this forces consistent behaviour.
|
p->flags |= CPRINT_CURSOR; //this can be a little jarring if there's no links, so this forces consistent behaviour.
|
||||||
else if (str[1] == 'W') //wait between each char
|
else if (str[1] == 'W') //wait between each char
|
||||||
p->flags ^= CPRINT_TYPEWRITER;
|
p->flags ^= CPRINT_TYPEWRITER;
|
||||||
|
else if (str[1] == 'Q') //queue
|
||||||
|
doqueue = true;
|
||||||
|
else if (str[1] == 'D') //explicit delay
|
||||||
|
{
|
||||||
|
p->time_off = strtod(str+2, (char**)&str);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (str[1] == 'S') //Stay
|
else if (str[1] == 'S') //Stay
|
||||||
p->flags ^= CPRINT_PERSIST;
|
p->flags ^= CPRINT_PERSIST;
|
||||||
else if (str[1] == 'M') //'Mask' the background so that its readable.
|
else if (str[1] == 'M') //'Mask' the background so that its readable.
|
||||||
p->flags ^= CPRINT_BACKGROUND;
|
p->flags ^= CPRINT_BACKGROUND;
|
||||||
|
else if (str[1] == 'N') //'Notify' spam it to the console even in deathmatch.
|
||||||
|
{
|
||||||
|
donotify = strtol(str+2, (char**)&str, 10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else if (str[1] == 'O') //Obituaries are shown at the bottom, ish.
|
else if (str[1] == 'O') //Obituaries are shown at the bottom, ish.
|
||||||
p->flags ^= CPRINT_OBITUARTY;
|
p->flags ^= CPRINT_OBITUARTY;
|
||||||
else if (str[1] == 'B')
|
else if (str[1] == 'B')
|
||||||
|
@ -549,7 +580,16 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
str += 2;
|
str += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((scr_logcenterprint.ival && !cl.deathmatch) || scr_logcenterprint.ival == 2) && !(p->flags & CPRINT_PERSIST))
|
if (!doqueue) //kill all prior ones if we're not queueing
|
||||||
|
while (SCR_CenterPrintPop(pnum))
|
||||||
|
;
|
||||||
|
//add it to the end
|
||||||
|
for (l = &scr_centerprint[pnum]; *l; l = &(*l)->queue)
|
||||||
|
;
|
||||||
|
*l = p;
|
||||||
|
|
||||||
|
|
||||||
|
if (donotify && !(p->flags & CPRINT_PERSIST))
|
||||||
{
|
{
|
||||||
//don't spam too much.
|
//don't spam too much.
|
||||||
if (*str && strncmp(cl.lastcenterprint, str, sizeof(cl.lastcenterprint)-1))
|
if (*str && strncmp(cl.lastcenterprint, str, sizeof(cl.lastcenterprint)-1))
|
||||||
|
@ -585,7 +625,6 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p->time_off = scr_centertime.value;
|
|
||||||
p->time_start = cl.time;
|
p->time_start = cl.time;
|
||||||
VRUI_SnapAngle();
|
VRUI_SnapAngle();
|
||||||
}
|
}
|
||||||
|
@ -594,16 +633,17 @@ void VARGS Stats_Message(char *msg, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char str[2048];
|
char str[2048];
|
||||||
cprint_t *p = &scr_centerprint[0];
|
cprint_t *p = scr_centerprint[0];
|
||||||
if (!scr_showobituaries.ival)
|
if (!scr_showobituaries.ival)
|
||||||
return;
|
return;
|
||||||
if (p->time_off >= 0)
|
if (p) //don't show if one is shown... FIXME: queue these too (some depth cutoff?)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
va_start (argptr, msg);
|
va_start (argptr, msg);
|
||||||
vsnprintf (str,sizeof(str)-1, msg, argptr);
|
vsnprintf (str,sizeof(str)-1, msg, argptr);
|
||||||
va_end (argptr);
|
va_end (argptr);
|
||||||
|
|
||||||
|
p = scr_centerprint[0] = Z_Malloc(sizeof(*p));
|
||||||
p->flags = CPRINT_OBITUARTY;
|
p->flags = CPRINT_OBITUARTY;
|
||||||
p->titleimage[0] = 0;
|
p->titleimage[0] = 0;
|
||||||
|
|
||||||
|
@ -788,6 +828,7 @@ int SCR_DrawCenterString (vrect_t *playerrect, cprint_t *p, struct font_s *font)
|
||||||
Font_BeginString(font, rect.x, y, &left, &top);
|
Font_BeginString(font, rect.x, y, &left, &top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x = (left+right)/2;
|
||||||
for (l = 0; l < linecount; l++, y += ch)
|
for (l = 0; l < linecount; l++, y += ch)
|
||||||
{
|
{
|
||||||
if (y >= bottom)
|
if (y >= bottom)
|
||||||
|
@ -825,9 +866,11 @@ int SCR_DrawCenterString (vrect_t *playerrect, cprint_t *p, struct font_s *font)
|
||||||
remaining -= line_end[l]-line_start[l];
|
remaining -= line_end[l]-line_start[l];
|
||||||
if (remaining <= 0)
|
if (remaining <= 0)
|
||||||
{
|
{
|
||||||
|
if (p->time_off && (p->flags&(CPRINT_TYPEWRITER|CPRINT_PERSIST))==CPRINT_TYPEWRITER)
|
||||||
|
p->time_off = scr_centertime.value; //reset the timeout while we're still truncating it.
|
||||||
line_end[l] += remaining;
|
line_end[l] += remaining;
|
||||||
if (line_end[l] <= line_start[l])
|
if (line_end[l] <= line_start[l])
|
||||||
break;
|
line_end[l] = line_start[l];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->cursorchar && p->cursorchar >= line_start[l] && p->cursorchar < line_end[l] && *p->cursorchar == CON_LINKSTART)
|
if (p->cursorchar && p->cursorchar >= line_start[l] && p->cursorchar < line_end[l] && *p->cursorchar == CON_LINKSTART)
|
||||||
|
@ -849,6 +892,16 @@ int SCR_DrawCenterString (vrect_t *playerrect, cprint_t *p, struct font_s *font)
|
||||||
}
|
}
|
||||||
|
|
||||||
Font_LineDraw(x, y, line_start[l], line_end[l]);
|
Font_LineDraw(x, y, line_start[l], line_end[l]);
|
||||||
|
|
||||||
|
if (remaining <= 0 || l == linecount-1)
|
||||||
|
{
|
||||||
|
if ((p->flags&(CPRINT_TYPEWRITER|CPRINT_PERSIST))==CPRINT_TYPEWRITER && l < linecount && ((int)(realtime*4)&1))
|
||||||
|
{
|
||||||
|
x = x+Font_LineWidth(line_start[l], line_end[l]);
|
||||||
|
Font_DrawChar(x, y, CON_WHITEMASK, 0xe00b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Font_EndString(font);
|
Font_EndString(font);
|
||||||
|
@ -859,7 +912,7 @@ int SCR_DrawCenterString (vrect_t *playerrect, cprint_t *p, struct font_s *font)
|
||||||
static void Key_CenterPrintActivate(int pnum)
|
static void Key_CenterPrintActivate(int pnum)
|
||||||
{
|
{
|
||||||
char *link;
|
char *link;
|
||||||
cprint_t *p = &scr_centerprint[pnum];
|
cprint_t *p = scr_centerprint[pnum];
|
||||||
link = SCR_CopyCenterPrint(p);
|
link = SCR_CopyCenterPrint(p);
|
||||||
if (link)
|
if (link)
|
||||||
{
|
{
|
||||||
|
@ -915,7 +968,6 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||||
//figure out which player has the cursor
|
//figure out which player has the cursor
|
||||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[pnum];
|
|
||||||
if (cl.playerview[pnum].gamerectknown == cls.framecount)
|
if (cl.playerview[pnum].gamerectknown == cls.framecount)
|
||||||
Key_CenterPrintActivate(pnum);
|
Key_CenterPrintActivate(pnum);
|
||||||
}
|
}
|
||||||
|
@ -925,8 +977,9 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||||
{
|
{
|
||||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[pnum];
|
p = scr_centerprint[pnum];
|
||||||
p->flags &= ~CPRINT_CURSOR;
|
if (p)
|
||||||
|
p->flags &= ~CPRINT_CURSOR;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -934,8 +987,8 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||||
key == K_KP_ENTER ||
|
key == K_KP_ENTER ||
|
||||||
key == K_GP_DIAMOND_RIGHT) && devid < countof(scr_centerprint))
|
key == K_GP_DIAMOND_RIGHT) && devid < countof(scr_centerprint))
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[devid];
|
p = scr_centerprint[devid];
|
||||||
if (p->cursorchar)
|
if (p && p->cursorchar)
|
||||||
Key_CenterPrintActivate(devid);
|
Key_CenterPrintActivate(devid);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -946,15 +999,18 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||||
key == K_GP_DPAD_UP ||
|
key == K_GP_DPAD_UP ||
|
||||||
key == K_GP_DPAD_LEFT) && devid < countof(scr_centerprint))
|
key == K_GP_DPAD_LEFT) && devid < countof(scr_centerprint))
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[devid];
|
p = scr_centerprint[devid];
|
||||||
if (!p->cursorchar)
|
if (p)
|
||||||
p->cursorchar = p->string + p->charcount;
|
|
||||||
while (--p->cursorchar >= p->string)
|
|
||||||
{
|
{
|
||||||
if (*p->cursorchar == CON_LINKSTART)
|
if (!p->cursorchar)
|
||||||
return true; //found one
|
p->cursorchar = p->string + p->charcount;
|
||||||
|
while (--p->cursorchar >= p->string)
|
||||||
|
{
|
||||||
|
if (*p->cursorchar == CON_LINKSTART)
|
||||||
|
return true; //found one
|
||||||
|
}
|
||||||
|
p->cursorchar = NULL;
|
||||||
}
|
}
|
||||||
p->cursorchar = NULL;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if ((key == K_DOWNARROW ||
|
else if ((key == K_DOWNARROW ||
|
||||||
|
@ -964,15 +1020,18 @@ qboolean Key_Centerprint(int key, int unicode, unsigned int devid)
|
||||||
key == K_GP_DPAD_DOWN ||
|
key == K_GP_DPAD_DOWN ||
|
||||||
key == K_GP_DPAD_RIGHT) && devid < countof(scr_centerprint))
|
key == K_GP_DPAD_RIGHT) && devid < countof(scr_centerprint))
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[devid];
|
p = scr_centerprint[devid];
|
||||||
if (!p->cursorchar)
|
if (p)
|
||||||
p->cursorchar = p->string-1;
|
|
||||||
while (++p->cursorchar < p->string + p->charcount)
|
|
||||||
{
|
{
|
||||||
if (*p->cursorchar == CON_LINKSTART)
|
if (!p->cursorchar)
|
||||||
return true; //found one
|
p->cursorchar = p->string-1;
|
||||||
|
while (++p->cursorchar < p->string + p->charcount)
|
||||||
|
{
|
||||||
|
if (*p->cursorchar == CON_LINKSTART)
|
||||||
|
return true; //found one
|
||||||
|
}
|
||||||
|
p->cursorchar = NULL; //hit the end
|
||||||
}
|
}
|
||||||
p->cursorchar = NULL; //hit the end
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,8 +1047,6 @@ void SCR_CheckDrawCenterString (void)
|
||||||
|
|
||||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||||
{
|
{
|
||||||
p = &scr_centerprint[pnum];
|
|
||||||
|
|
||||||
#ifdef QUAKESTATS
|
#ifdef QUAKESTATS
|
||||||
if (IN_DrawWeaponWheel(pnum))
|
if (IN_DrawWeaponWheel(pnum))
|
||||||
{ //we won't draw the cprint, but it also won't fade while the wwheel is shown.
|
{ //we won't draw the cprint, but it also won't fade while the wwheel is shown.
|
||||||
|
@ -997,8 +1054,15 @@ void SCR_CheckDrawCenterString (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (p->time_off <= 0 && !(p->flags & CPRINT_PERSIST))
|
p = scr_centerprint[pnum];
|
||||||
continue; //'/P' prefix doesn't time out
|
if (!p)
|
||||||
|
continue;
|
||||||
|
if (p->time_off <= 0 && !(p->flags & CPRINT_PERSIST)) //'/P' prefix doesn't time out
|
||||||
|
{ //this one is done. move to the next.
|
||||||
|
if (SCR_CenterPrintPop(pnum))
|
||||||
|
pnum++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
p->time_off -= host_frametime;
|
p->time_off -= host_frametime;
|
||||||
|
|
||||||
|
@ -1461,8 +1525,8 @@ void SCR_ShowPic_ClearAll(qboolean persistflag)
|
||||||
|
|
||||||
for (pnum = 0; pnum < MAX_SPLITS; pnum++)
|
for (pnum = 0; pnum < MAX_SPLITS; pnum++)
|
||||||
{
|
{
|
||||||
scr_centerprint[pnum].flags = 0;
|
while (SCR_CenterPrintPop(pnum))
|
||||||
scr_centerprint[pnum].charcount = 0;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!persistflag)
|
if (!persistflag)
|
||||||
|
@ -3415,7 +3479,8 @@ void SCR_BringDownConsole (void)
|
||||||
|
|
||||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||||
{
|
{
|
||||||
scr_centerprint[pnum].charcount = 0;
|
while (SCR_CenterPrintPop(pnum))
|
||||||
|
;
|
||||||
cl.playerview[pnum].cshifts[CSHIFT_CONTENTS].percent = 0; // no area contents palette on next frame
|
cl.playerview[pnum].cshifts[CSHIFT_CONTENTS].percent = 0; // no area contents palette on next frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3571,8 +3636,8 @@ void SCR_DeInit (void)
|
||||||
}
|
}
|
||||||
for (i = 0; i < countof(scr_centerprint); i++)
|
for (i = 0; i < countof(scr_centerprint); i++)
|
||||||
{
|
{
|
||||||
Z_Free(scr_centerprint[i].string);
|
while (SCR_CenterPrintPop(i))
|
||||||
memset(&scr_centerprint[i], 0, sizeof(scr_centerprint[i]));
|
;
|
||||||
}
|
}
|
||||||
if (scr_initialized)
|
if (scr_initialized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -543,7 +543,7 @@ int M_GameType(void);
|
||||||
|
|
||||||
//plugin functions
|
//plugin functions
|
||||||
#ifdef PLUGINS
|
#ifdef PLUGINS
|
||||||
qboolean Plug_CenterPrintMessage(char *buffer, int clientnum);
|
qboolean Plug_CenterPrintMessage(const char *buffer, int clientnum);
|
||||||
qboolean Plug_ChatMessage(char *buffer, int talkernum, int tpflags);
|
qboolean Plug_ChatMessage(char *buffer, int talkernum, int tpflags);
|
||||||
void Plug_Command_f(void);
|
void Plug_Command_f(void);
|
||||||
int Plug_ConnectionlessClientPacket(char *buffer, int size);
|
int Plug_ConnectionlessClientPacket(char *buffer, int size);
|
||||||
|
|
|
@ -1538,7 +1538,7 @@ qboolean Plug_ChatMessage(char *buffer, int talkernum, int tpflags)
|
||||||
return ret; // true to display message, false to supress
|
return ret; // true to display message, false to supress
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean Plug_CenterPrintMessage(char *buffer, int clientnum)
|
qboolean Plug_CenterPrintMessage(const char *buffer, int clientnum)
|
||||||
{
|
{
|
||||||
qboolean ret = true;
|
qboolean ret = true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue