Tweak splitscreen a little to work around a KTX issue.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5967 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
e90a0b3945
commit
9735064a89
11 changed files with 73 additions and 75 deletions
|
@ -547,7 +547,7 @@ void Cam_Unlock(playerview_t *pv)
|
|||
{
|
||||
if (pv->cam_state)
|
||||
{
|
||||
CL_SendClientCommand(true, "ptrack");
|
||||
CL_SendSeatClientCommand(true, pv-cl.playerview, "ptrack");
|
||||
pv->cam_state = CAM_FREECAM;
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1); //free floating
|
||||
SCR_CenterPrint(pv-cl.playerview, NULL, true);
|
||||
|
@ -564,7 +564,7 @@ void Cam_Lock(playerview_t *pv, int playernum)
|
|||
{
|
||||
pv->cam_lastviewtime = -1000; //allow the wallcam to re-snap as soon as it can
|
||||
|
||||
CL_SendClientCommand(true, "ptrack %i", playernum);
|
||||
CL_SendSeatClientCommand(true, pv-cl.playerview, "ptrack %i", playernum);
|
||||
|
||||
if (pv->cam_spec_track != playernum)
|
||||
{ //flashgrens suck
|
||||
|
|
|
@ -1563,10 +1563,11 @@ typedef struct clcmdbuf_s {
|
|||
struct clcmdbuf_s *next;
|
||||
int len;
|
||||
qboolean reliable;
|
||||
unsigned int seat;
|
||||
char command[4]; //this is dynamically allocated, so this is variably sized.
|
||||
} clcmdbuf_t;
|
||||
clcmdbuf_t *clientcmdlist;
|
||||
void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
|
||||
static clcmdbuf_t *clientcmdlist;
|
||||
void VARGS CL_SendSeatClientCommand(qboolean reliable, unsigned int seat, char *format, ...)
|
||||
{
|
||||
qboolean oldallow;
|
||||
va_list argptr;
|
||||
|
@ -1594,6 +1595,7 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
|
|||
strcpy(buf->command, string);
|
||||
buf->len = strlen(buf->command);
|
||||
buf->reliable = reliable;
|
||||
buf->seat = seat;
|
||||
|
||||
//add to end of the list so that the first of the list is the first to be sent.
|
||||
if (!clientcmdlist)
|
||||
|
@ -1607,6 +1609,17 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
|
|||
|
||||
CL_AllowIndependantSendCmd(oldallow);
|
||||
}
|
||||
void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char string[2048];
|
||||
|
||||
va_start (argptr, format);
|
||||
Q_vsnprintfz (string,sizeof(string), format,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
CL_SendSeatClientCommand(reliable, 0, "%s", string);
|
||||
}
|
||||
|
||||
//sometimes a server will quickly restart twice.
|
||||
//connected clients will then receive TWO 'new' commands - both with the same servercount value.
|
||||
|
@ -2090,13 +2103,6 @@ static void CL_SendUserinfoUpdate(void)
|
|||
qboolean final = true;
|
||||
char enckey[2048];
|
||||
char encval[2048];
|
||||
//handle splitscreen
|
||||
char pl[64];
|
||||
|
||||
if (seat)
|
||||
Q_snprintfz(pl, sizeof(pl), "%i ", seat);
|
||||
else
|
||||
*pl = 0;
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
if (cls.protocol == CP_QUAKE3)
|
||||
|
@ -2121,7 +2127,6 @@ static void CL_SendUserinfoUpdate(void)
|
|||
InfoBuf_ToString(info, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
MSG_WriteByte (&cls.netchan.message, clcq2_userinfo);
|
||||
SZ_Write(&cls.netchan.message, pl, strlen(pl));
|
||||
MSG_WriteString (&cls.netchan.message, userinfo);
|
||||
}
|
||||
return;
|
||||
|
@ -2145,24 +2150,27 @@ static void CL_SendUserinfoUpdate(void)
|
|||
|
||||
if (final && !bloboffset && *encval != '\xff' && *encval != '\xff')
|
||||
{ //vanilla-compatible info.
|
||||
s = va("%ssetinfo \"%s\" \"%s\"", pl, enckey, encval);
|
||||
s = va("setinfo \"%s\" \"%s\"", enckey, encval);
|
||||
}
|
||||
else if (cls.fteprotocolextensions2 & PEXT2_INFOBLOBS)
|
||||
{ //only flood servers that actually support it.
|
||||
if (final)
|
||||
s = va("%ssetinfo \"%s\" \"%s\" %u", pl, enckey, encval, (unsigned int)bloboffset);
|
||||
s = va("setinfo \"%s\" \"%s\" %u", enckey, encval, (unsigned int)bloboffset);
|
||||
else
|
||||
s = va("%ssetinfo \"%s\" \"%s\" %u+", pl, enckey, encval, (unsigned int)bloboffset);
|
||||
s = va("setinfo \"%s\" \"%s\" %u+", enckey, encval, (unsigned int)bloboffset);
|
||||
}
|
||||
else
|
||||
{ //server doesn't support it, just ignore the key
|
||||
InfoSync_Remove(&cls.userinfosync, 0);
|
||||
return;
|
||||
}
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
MSG_WriteByte (&cls.netchan.message, clcq2_stringcmd);
|
||||
if (seat && (cls.fteprotocolextensions&PEXT_SPLITSCREEN))
|
||||
{
|
||||
MSG_WriteByte (&cls.netchan.message, (cls.protocol == CP_QUAKE2)?clcq2_stringcmd_seat:clcfte_stringcmd_seat);
|
||||
MSG_WriteByte (&cls.netchan.message, seat);
|
||||
}
|
||||
else
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteByte (&cls.netchan.message, (cls.protocol == CP_QUAKE2)?clcq2_stringcmd:clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message, s);
|
||||
}
|
||||
|
||||
|
@ -2462,14 +2470,26 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
break;
|
||||
if (!strncmp(clientcmdlist->command, "spawn", 5) && cls.userinfosync.numkeys && cl.haveserverinfo)
|
||||
break; //HACK: don't send the spawn until all pending userinfos have been flushed.
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
if (clientcmdlist->seat && (cls.fteprotocolextensions&PEXT_SPLITSCREEN))
|
||||
{
|
||||
MSG_WriteByte (&cls.netchan.message, clcfte_stringcmd_seat);
|
||||
MSG_WriteByte (&cls.netchan.message, clientcmdlist->seat);
|
||||
}
|
||||
else
|
||||
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buf.cursize + 2+strlen(clientcmdlist->command)+100 <= buf.maxsize)
|
||||
{
|
||||
MSG_WriteByte (&buf, clc_stringcmd);
|
||||
if (clientcmdlist->seat && (cls.fteprotocolextensions&PEXT_SPLITSCREEN))
|
||||
{
|
||||
MSG_WriteByte (&cls.netchan.message, clcfte_stringcmd_seat);
|
||||
MSG_WriteByte (&cls.netchan.message, clientcmdlist->seat);
|
||||
}
|
||||
else
|
||||
MSG_WriteByte (&buf, clc_stringcmd);
|
||||
MSG_WriteString (&buf, clientcmdlist->command);
|
||||
}
|
||||
}
|
||||
|
@ -2653,7 +2673,7 @@ void CL_SendCvar_f (void)
|
|||
val = "";
|
||||
else
|
||||
val = var->string;
|
||||
CL_SendClientCommand(true, "sentcvar %s \"%s\"", name, val);
|
||||
CL_SendSeatClientCommand(true, CL_TargettedSplit(false), "sentcvar %s \"%s\"", name, val);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -7118,7 +7118,7 @@ void CLQW_ParseServerMessage (void)
|
|||
for (; i < cl.splitclients; i++)
|
||||
{ //svcfte_choosesplitclient has a modulo that is also broken, but at least there's no parse errors this way
|
||||
MSG_ReadByte();
|
||||
// CL_SendClientCommand(true, va("%i drop", i+1));
|
||||
// CL_SendSeatClientCommand(true, i, drop");
|
||||
}
|
||||
cl.splitclients = MAX_SPLITS;
|
||||
}
|
||||
|
|
|
@ -1275,6 +1275,7 @@ qboolean CL_AllowIndependantSendCmd(qboolean allow); //returns previous state.
|
|||
|
||||
void CL_FlushClientCommands(void);
|
||||
void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...) LIKEPRINTF(2);
|
||||
void VARGS CL_SendSeatClientCommand(qboolean reliable, unsigned int seat, char *format, ...) LIKEPRINTF(3);
|
||||
float CL_FilterTime (double time, float wantfps, float limit, qboolean ignoreserver);
|
||||
int CL_RemoveClientCommands(char *command);
|
||||
|
||||
|
|
|
@ -811,7 +811,7 @@ static void Sbar_Hexen2InvLeft_f(void)
|
|||
#endif
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invprev");
|
||||
CL_SendSeatClientCommand(true, seat, "invprev");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -838,7 +838,7 @@ static void Sbar_Hexen2InvRight_f(void)
|
|||
#endif
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invnext");
|
||||
CL_SendSeatClientCommand(true, seat, "invnext");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -866,7 +866,7 @@ static void Sbar_Hexen2InvUse_f(void)
|
|||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
CL_SendClientCommand(true, "invuse");
|
||||
CL_SendSeatClientCommand(true, seat, "invuse");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -3883,10 +3883,10 @@ void CL_Say (qboolean team, char *extra)
|
|||
//the server is expected to use Cmd_Args and to strip first+last chars if the first is a quote. this is annoying and clumsy for mods to parse.
|
||||
#ifdef HAVE_LEGACY
|
||||
if (!dpcompat_console.ival)
|
||||
CL_SendClientCommand(true, "%s%s \"%s%s\"", split?va("%i ", split+1):"", team ? "say_team" : "say", extra?extra:"", sendtext);
|
||||
CL_SendSeatClientCommand(true, split, "%s \"%s%s\"", team ? "say_team" : "say", extra?extra:"", sendtext);
|
||||
else
|
||||
#endif
|
||||
CL_SendClientCommand(true, "%s%s %s%s", split?va("%i ", split+1):"", team ? "say_team" : "say", extra?extra:"", sendtext);
|
||||
CL_SendSeatClientCommand(true, split, "%s %s%s", team ? "say_team" : "say", extra?extra:"", sendtext);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2638,20 +2638,10 @@ void Cmd_ForwardToServer (void)
|
|||
#endif
|
||||
|
||||
sp = CL_TargettedSplit(false);
|
||||
if (sp)
|
||||
{
|
||||
if (Cmd_Argc() > 1)
|
||||
CL_SendClientCommand(true, "%i %s %s", sp+1, Cmd_Argv(0), Cmd_Args());
|
||||
else
|
||||
CL_SendClientCommand(true, "%i %s", sp+1, Cmd_Argv(0));
|
||||
}
|
||||
if (Cmd_Argc() > 1)
|
||||
CL_SendSeatClientCommand(true, sp, "%s %s", Cmd_Argv(0), Cmd_Args());
|
||||
else
|
||||
{
|
||||
if (Cmd_Argc() > 1)
|
||||
CL_SendClientCommand(true, "%s %s", Cmd_Argv(0), Cmd_Args());
|
||||
else
|
||||
CL_SendClientCommand(true, "%s", Cmd_Argv(0));
|
||||
}
|
||||
CL_SendSeatClientCommand(true, sp, "%s", Cmd_Argv(0));
|
||||
}
|
||||
|
||||
// don't forward the first argument
|
||||
|
@ -2713,10 +2703,7 @@ static void Cmd_ForwardToServer_f (void)
|
|||
if (Cmd_Argc() > 1)
|
||||
{
|
||||
int split = CL_TargettedSplit(false);
|
||||
if (split)
|
||||
CL_SendClientCommand(true, "%i %s", split+1, Cmd_Args());
|
||||
else
|
||||
CL_SendClientCommand(true, "%s", Cmd_Args());
|
||||
CL_SendSeatClientCommand(true, split, "%s", Cmd_Args());
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -1497,10 +1497,7 @@ qboolean Cvar_Command (int level)
|
|||
if (Cmd_FromGamecode() && cls.protocol == CP_QUAKEWORLD)
|
||||
{ //don't bother even changing the cvar locally, just update the server's version.
|
||||
//fixme: quake2/quake3 latching.
|
||||
if (seat)
|
||||
CL_SendClientCommand(true, "%i setinfo %s %s", seat+1, v->name, COM_QuotedString(str, buffer, sizeof(buffer), false));
|
||||
else
|
||||
CL_SendClientCommand(true, "setinfo %s %s", v->name, COM_QuotedString(str, buffer, sizeof(buffer), false));
|
||||
CL_SendSeatClientCommand(true, seat, "setinfo %s %s", v->name, COM_QuotedString(str, buffer, sizeof(buffer), false));
|
||||
}
|
||||
else
|
||||
CL_SetInfo(seat, v->name, str);
|
||||
|
|
|
@ -465,6 +465,7 @@ enum clcq2_ops_e
|
|||
clcr1q2_multimoves = 6, // for crappy clients that can't lerp
|
||||
|
||||
//fte-extended
|
||||
clcq2_stringcmd_seat = 30,
|
||||
clcq2_voicechat = 31
|
||||
};
|
||||
|
||||
|
@ -502,6 +503,7 @@ enum {
|
|||
#define clcfte_voicechat 83
|
||||
#define clcfte_brushedit 84
|
||||
#define clcfte_move 85 //part of PEXT2_VRINPUTS. replaces clc_move+clcfte_prydoncursor+clcdp_ackframe
|
||||
#define clcfte_stringcmd_seat 86
|
||||
|
||||
#define VRM_LOSS (1u<<0) //for server packetloss reports
|
||||
#define VRM_DELAY (1u<<1) //for server to compute lag properly.
|
||||
|
|
|
@ -1424,10 +1424,10 @@ static void SVC_Log (void)
|
|||
seq = seq+1; //they will get the next sequence from the one they already have
|
||||
}
|
||||
else
|
||||
seq = 0;
|
||||
seq = svs.logsequence-1;
|
||||
|
||||
if (!fraglog_public.ival)
|
||||
{ //frag logs are not public (for DoS protection perhaps?.
|
||||
{ //frag logs are not public (for DoS protection perhaps?)
|
||||
data[0] = A2A_NACK;
|
||||
NET_SendPacket (svs.sockets, 1, data, &net_from);
|
||||
return;
|
||||
|
@ -2372,6 +2372,8 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
|||
Q_strncpyz(cl->guid, "", sizeof(cl->guid));
|
||||
cl->name = cl->namebuf;
|
||||
cl->team = cl->teambuf;
|
||||
cl->userinfo.ChangeCB = svs.info.ChangeCB;
|
||||
cl->userinfo.ChangeCTX = &cl->userinfo;
|
||||
|
||||
if (!cl->userid || !loadgame)
|
||||
cl->userid = ++nextuserid;
|
||||
|
|
|
@ -6459,31 +6459,6 @@ void SV_ExecuteUserCommand (const char *s, qboolean fromQC)
|
|||
|
||||
Cmd_ExecLevel=1;
|
||||
|
||||
if (!fromQC && host_client->controlled) //now see if it's meant to be from a slave client
|
||||
{ //'cmd 2 say hi' should
|
||||
char *a=Cmd_Argv(0), *e;
|
||||
int pnum = strtoul(a, &e, 10);
|
||||
|
||||
//commands might be in the form of eg '2on2' so make sure that its fully numeric.
|
||||
//KTX uses eg 'cmd 231', so don't take it if it can't be a seat, but there may be race conditions so we don't want error messages when it might have been a seat.
|
||||
if (!*e && pnum >= 1 && pnum <= MAX_SPLITS)
|
||||
{
|
||||
client_t *sp;
|
||||
for (sp = host_client; sp; sp = sp->controlled)
|
||||
{
|
||||
if (!--pnum)
|
||||
{
|
||||
host_client = sp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sv_player = host_client->edict;
|
||||
s = Cmd_Args();
|
||||
Cmd_ShiftArgs(1, false);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Q2SERVER
|
||||
if (ISQ2CLIENT(host_client))
|
||||
u = ucmdsq2;
|
||||
|
@ -8330,6 +8305,13 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
break;
|
||||
#endif
|
||||
|
||||
case clcfte_stringcmd_seat:
|
||||
c = MSG_ReadByte();
|
||||
host_client = cl;
|
||||
while (c --> 0 && host_client->controlled)
|
||||
host_client = host_client->controlled;
|
||||
sv_player = host_client->edict;
|
||||
//fall through
|
||||
case clc_stringcmd:
|
||||
s = MSG_ReadString ();
|
||||
SV_ExecuteUserCommand (s, false);
|
||||
|
@ -8576,6 +8558,13 @@ void SVQ2_ExecuteClientMessage (client_t *cl)
|
|||
ge->ClientUserinfoChanged (cl->q2edict, s); //tell the gamecode
|
||||
break;
|
||||
|
||||
case clcq2_stringcmd_seat:
|
||||
c = MSG_ReadByte();
|
||||
host_client = cl;
|
||||
while (c --> 0 && host_client->controlled)
|
||||
host_client = host_client->controlled;
|
||||
sv_player = host_client->edict;
|
||||
//fall through
|
||||
case clcq2_stringcmd:
|
||||
s = MSG_ReadString ();
|
||||
SV_ExecuteUserCommand (s, false);
|
||||
|
|
Loading…
Reference in a new issue