Added initial support for eztv extensions. This is the bulk of the changes. Downloading isn't implemented yet though. Also fixed some demo playback sbar stats, and fixed NQ demo playback.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2852 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2008-01-09 00:52:31 +00:00
parent e7b74777f3
commit 776faf1bc4
9 changed files with 294 additions and 173 deletions

View File

@ -163,7 +163,7 @@ void Cam_Lock(int pnum, int playernum)
Skin_FlushPlayers(); Skin_FlushPlayers();
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
memcpy(&cl.stats[pnum], cl.players[playernum].stats, sizeof(cl.stats[pnum])); memcpy(&cl.stats[pnum], cl.players[playernum].stats, sizeof(cl.stats[pnum]));
} }
@ -569,7 +569,7 @@ void Cam_FinishMove(int pnum, usercmd_t *cmd)
if (cls.state != ca_active) if (cls.state != ca_active)
return; return;
if (!cl.spectator && cls.demoplayback != DPB_MVD) // only in spectator mode if (!cl.spectator && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) // only in spectator mode
return; return;
if (cmd->buttons & BUTTON_ATTACK) if (cmd->buttons & BUTTON_ATTACK)

View File

@ -31,13 +31,15 @@ void CL_PlayDemo(char *demoname);
char lastdemoname[256]; char lastdemoname[256];
extern cvar_t qtvcl_forceversion1; extern cvar_t qtvcl_forceversion1;
extern cvar_t qtvcl_eztvextensions;
unsigned char demobuffer[1024*16]; unsigned char demobuffer[1024*16];
int demobuffersize; int demobuffersize;
int demopreparsedbytes; int demopreparsedbytes;
qboolean disablepreparse; qboolean disablepreparse;
qboolean endofdemo;
#define BUFFERTIME 0.1 #define BUFFERTIME 0.5
/* /*
============================================================================== ==============================================================================
@ -161,7 +163,7 @@ int demo_preparsedemo(unsigned char *buffer, int bytes)
int ofs; int ofs;
unsigned int length; unsigned int length;
#define dem_mask 7 #define dem_mask 7
if (cls.demoplayback != DPB_MVD) if (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)
return bytes; //no need if its not an mvd (this simplifies it a little) return bytes; //no need if its not an mvd (this simplifies it a little)
while (bytes>2) while (bytes>2)
@ -246,7 +248,7 @@ int readdemobytes(int *readpos, void *data, int len)
else if (i < 0) else if (i < 0)
{ //0 means no data available yet { //0 means no data available yet
printf("VFS_READ failed\n"); printf("VFS_READ failed\n");
// CL_StopPlayback(); endofdemo = true;
return 0; return 0;
} }
@ -255,6 +257,7 @@ int readdemobytes(int *readpos, void *data, int len)
if (len > demobuffersize) if (len > demobuffersize)
{ {
len = demobuffersize; len = demobuffersize;
return 0;
} }
memcpy(data, demobuffer+*readpos, len); memcpy(data, demobuffer+*readpos, len);
*readpos += len; *readpos += len;
@ -274,10 +277,14 @@ void demo_flushcache(void)
{ {
demobuffersize = 0; demobuffersize = 0;
demopreparsedbytes = 0; demopreparsedbytes = 0;
//no errors yet
disablepreparse = false;
} }
void demo_resetcache(int bytes, void *data) void demo_resetcache(int bytes, void *data)
{ {
endofdemo = false;
demo_flushcache(); demo_flushcache();
demobuffersize = bytes; demobuffersize = bytes;
@ -373,6 +380,13 @@ qboolean CL_GetDemoMessage (void)
int demopos = 0; int demopos = 0;
int msglength; int msglength;
if (endofdemo)
{
endofdemo = false;
CL_StopPlayback ();
return 0;
}
#ifdef NQPROT #ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE if (cls.demoplayback == DPB_NETQUAKE
#ifdef Q2CLIENT #ifdef Q2CLIENT
@ -451,6 +465,7 @@ qboolean CL_GetDemoMessage (void)
{ {
return 0; return 0;
} }
demo_flushbytes(demopos);
net_message.cursize = msglength; net_message.cursize = msglength;
return 1; return 1;
@ -458,7 +473,7 @@ qboolean CL_GetDemoMessage (void)
#endif #endif
readnext: readnext:
// read the time from the packet // read the time from the packet
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
if (realtime < 0) if (realtime < 0)
{ {
@ -517,7 +532,7 @@ readnext:
else else
realtime = demotime; // we're warping realtime = demotime; // we're warping
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
if (msecsadded || cls.netchan.incoming_sequence < 2) if (msecsadded || cls.netchan.incoming_sequence < 2)
{ {
@ -633,7 +648,7 @@ readit:
} }
net_message.cursize = msglength; net_message.cursize = msglength;
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
switch(cls_lasttype) switch(cls_lasttype)
{ {
@ -665,7 +680,7 @@ readit:
readdemobytes (&demopos, &i, 4); readdemobytes (&demopos, &i, 4);
cls.netchan.incoming_sequence = LittleLong(i); cls.netchan.incoming_sequence = LittleLong(i);
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
cls.netchan.incoming_acknowledged = cls.netchan.incoming_sequence; cls.netchan.incoming_acknowledged = cls.netchan.incoming_sequence;
goto readnext; goto readnext;
@ -1449,7 +1464,7 @@ void CL_PlayDemo(char *demoname)
TP_ExecTrigger ("f_demostart"); TP_ExecTrigger ("f_demostart");
} }
void CL_QTVPlay (vfsfile_t *newf) void CL_QTVPlay (vfsfile_t *newf, qboolean iseztv)
{ {
CL_Disconnect_f (); CL_Disconnect_f ();
@ -1457,7 +1472,11 @@ void CL_QTVPlay (vfsfile_t *newf)
demo_flushcache(); //just in case demo_flushcache(); //just in case
cls.demoplayback = DPB_MVD; if (iseztv)
cls.demoplayback = DPB_EZTV;
else
cls.demoplayback = DPB_MVD;
cls.findtrack = true; cls.findtrack = true;
cls.state = ca_demostart; cls.state = ca_demostart;
@ -1466,7 +1485,8 @@ void CL_QTVPlay (vfsfile_t *newf)
realtime = -BUFFERTIME; realtime = -BUFFERTIME;
cl.gametime = -BUFFERTIME; cl.gametime = -BUFFERTIME;
cl.gametimemark = realtime; cl.gametimemark = realtime;
Con_Printf("Buffering for %i seconds\n", (int)-realtime); if (realtime < -0.5)
Con_Printf("Buffering for %i seconds\n", (int)-realtime);
cls.netchan.last_received=realtime; cls.netchan.last_received=realtime;
@ -1474,6 +1494,18 @@ void CL_QTVPlay (vfsfile_t *newf)
TP_ExecTrigger ("f_demostart"); TP_ExecTrigger ("f_demostart");
} }
void CL_Demo_ClientCommand(char *commandtext)
{
unsigned char b = 1;
unsigned short len = LittleShort(strlen(commandtext) + 4);
#ifndef _MSC_VER
#warning "this needs buffering safely"
#endif
VFS_WRITE(cls.demofile, &len, sizeof(len));
VFS_WRITE(cls.demofile, &b, sizeof(b));
VFS_WRITE(cls.demofile, commandtext, strlen(commandtext)+1);
}
char qtvhostname[1024]; char qtvhostname[1024];
char qtvrequestbuffer[4096]; char qtvrequestbuffer[4096];
int qtvrequestsize; int qtvrequestsize;
@ -1494,6 +1526,7 @@ void CL_QTVPoll (void)
int numviewers = 0; int numviewers = 0;
qboolean init_numplayers = false; qboolean init_numplayers = false;
qboolean init_numviewers = false; qboolean init_numviewers = false;
qboolean iseztv = false;
char srchost[256]; char srchost[256];
@ -1548,88 +1581,98 @@ void CL_QTVPoll (void)
*e = '\0'; *e = '\0';
colon = strchr(s, ':'); colon = strchr(s, ':');
if (colon) if (colon)
{
*colon++ = '\0'; *colon++ = '\0';
if (!strcmp(s, "PERROR"))
{ //printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "PRINT"))
{ //printable error
Con_Printf("QTV:\n%s\n", colon);
}
else if (!strcmp(s, "TERROR"))
{ //printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "ADEMO"))
{ //printable error
Con_Printf("Demo%s is available\n", colon);
}
//generic sourcelist responce
else if (!strcmp(s, "ASOURCE"))
{ //printable source
if (!saidheader)
{
saidheader=true;
Con_Printf("Available Sources:\n");
}
Con_Printf("%s\n", colon);
//we're too lazy to even try and parse this
}
//v1.1 sourcelist responce includes SRCSRV, SRCHOST, SRCPLYRS, SRCVIEWS, SRCID
else if (!strcmp(s, "SRCSRV"))
{
//the proxy's source string (beware of file:blah without file:blah@blah)
}
else if (!strcmp(s, "SRCHOST"))
{
//the hostname from the server the stream came from
Q_strncpyz(srchost, colon, sizeof(srchost));
}
else if (!strcmp(s, "SRCPLYRS"))
{
//number of active players actually playing on that stream
numplayers = atoi(colon);
init_numplayers = true;
}
else if (!strcmp(s, "SRCVIEWS"))
{
//number of people watching this stream on the proxy itself
numviewers = atoi(colon);
init_numviewers = true;
}
else if (!strcmp(s, "SRCID"))
{
streamid = atoi(colon);
//now put it on a menu
if (!sourcesmenu)
{
m_state = m_complex;
key_dest = key_menu;
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, "gfx/qplaque.lmp");
MC_AddCenterPicture(sourcesmenu, 4, "gfx/p_option.lmp");
}
if (init_numplayers == true && init_numviewers == true)
MC_AddConsoleCommand(sourcesmenu, 42, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname));
//else
// FIXME: add error message here
}
//end of sourcelist entry
else if (!strcmp(s, "BEGIN"))
streamavailable = true;
}
else else
{ colon = "";
if (!strcmp(s, "BEGIN"))
streamavailable = true; if (!strcmp(s, "PERROR"))
{ //printable error
Con_Printf("QTV Error:\n%s\n", colon);
} }
else if (!strcmp(s, "PRINT"))
{ //printable error
Con_Printf("QTV:\n%s\n", colon);
}
else if (!strcmp(s, "TERROR"))
{ //printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "ADEMO"))
{ //printable error
Con_Printf("Demo%s is available\n", colon);
}
//generic sourcelist responce
else if (!strcmp(s, "ASOURCE"))
{ //printable source
if (!saidheader)
{
saidheader=true;
Con_Printf("Available Sources:\n");
}
Con_Printf("%s\n", colon);
//we're too lazy to even try and parse this
}
else if (!strcmp(s, "BEGIN"))
{
if (*colon)
Con_Printf("streaming \"%s\" from qtv\n", colon);
else
Con_Printf("qtv connection established\n", colon);
streamavailable = true;
}
//eztv extensions to v1.0
else if (!strcmp(s, "QTV_EZQUAKE_EXT"))
{
iseztv = true;
Con_Printf("Warning: eztv extensions %s\n", colon);
}
//v1.1 sourcelist response includes SRCSRV, SRCHOST, SRCPLYRS, SRCVIEWS, SRCID
else if (!strcmp(s, "SRCSRV"))
{
//the proxy's source string (beware of file:blah without file:blah@blah)
}
else if (!strcmp(s, "SRCHOST"))
{
//the hostname from the server the stream came from
Q_strncpyz(srchost, colon, sizeof(srchost));
}
else if (!strcmp(s, "SRCPLYRS"))
{
//number of active players actually playing on that stream
numplayers = atoi(colon);
init_numplayers = true;
}
else if (!strcmp(s, "SRCVIEWS"))
{
//number of people watching this stream on the proxy itself
numviewers = atoi(colon);
init_numviewers = true;
}
else if (!strcmp(s, "SRCID"))
{
streamid = atoi(colon);
//now put it on a menu
if (!sourcesmenu)
{
m_state = m_complex;
key_dest = key_menu;
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, "gfx/qplaque.lmp");
MC_AddCenterPicture(sourcesmenu, 4, "gfx/p_option.lmp");
}
if (init_numplayers == true && init_numviewers == true)
MC_AddConsoleCommand(sourcesmenu, 42, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname));
//else
// FIXME: add error message here
}
//end of sourcelist entry
//from e to s, we have a line //from e to s, we have a line
s = e+1; s = e+1;
} }
@ -1638,7 +1681,7 @@ void CL_QTVPoll (void)
if (streamavailable) if (streamavailable)
{ {
CL_QTVPlay(qtvrequest); CL_QTVPlay(qtvrequest, iseztv);
qtvrequest = NULL; qtvrequest = NULL;
demo_resetcache(qtvrequestsize - (tail-qtvrequestbuffer), tail); demo_resetcache(qtvrequestsize - (tail-qtvrequestbuffer), tail);
return; return;
@ -1767,7 +1810,13 @@ void CL_QTVPlay_f (void)
} }
VFS_WRITE(newf, connrequest, strlen(connrequest)); VFS_WRITE(newf, connrequest, strlen(connrequest));
if (raw)
if (qtvcl_eztvextensions.value)
{
connrequest = "QTV_EZQUAKE_EXT: 3\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
}
else if (raw)
{ {
connrequest = "RAW: 1\n"; connrequest = "RAW: 1\n";
VFS_WRITE(newf, connrequest, strlen(connrequest)); VFS_WRITE(newf, connrequest, strlen(connrequest));
@ -1791,7 +1840,7 @@ void CL_QTVPlay_f (void)
if (raw) if (raw)
{ {
CL_QTVPlay(newf); CL_QTVPlay(newf, false);
} }
else else
{ {

View File

@ -458,7 +458,7 @@ void CL_ParsePacketEntities (qboolean delta)
// Con_Printf("%i %i from %i\n", cls.netchan.outgoing_sequence, cls.netchan.incoming_sequence, from); // Con_Printf("%i %i from %i\n", cls.netchan.outgoing_sequence, cls.netchan.incoming_sequence, from);
oldpacket = cl.frames[newpacket].delta_sequence; oldpacket = cl.frames[newpacket].delta_sequence;
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
from = oldpacket = cls.netchan.incoming_sequence - 1; from = oldpacket = cls.netchan.incoming_sequence - 1;
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence >= UPDATE_BACKUP - 1) { if (cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence >= UPDATE_BACKUP - 1) {
@ -1548,7 +1548,7 @@ void CL_LinkPacketEntities (void)
CL_CalcClientTime(); CL_CalcClientTime();
servertime = cl.servertime; servertime = cl.servertime;
pack = CL_ProcessPacketEntities(&servertime, !!cl_nolerp.value && cls.demoplayback != DPB_MVD); pack = CL_ProcessPacketEntities(&servertime, !!cl_nolerp.value && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV && cls.demoplayback != DPB_NETQUAKE));
if (!pack) if (!pack)
return; return;
@ -2317,7 +2317,7 @@ void CL_ParsePlayerinfo (void)
oldstate = &cl.frames[oldparsecountmod].playerstate[num]; oldstate = &cl.frames[oldparsecountmod].playerstate[num];
state = &cl.frames[parsecountmod].playerstate[num]; state = &cl.frames[parsecountmod].playerstate[num];
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
player_state_t *prevstate, dummy; player_state_t *prevstate, dummy;
if (!cl.parsecount || info->prevcount > cl.parsecount || cl.parsecount - info->prevcount >= UPDATE_BACKUP - 1) if (!cl.parsecount || info->prevcount > cl.parsecount || cl.parsecount - info->prevcount >= UPDATE_BACKUP - 1)

View File

@ -902,7 +902,7 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
char string[2048]; char string[2048];
clcmdbuf_t *buf, *prev; clcmdbuf_t *buf, *prev;
if (cls.demoplayback) if (cls.demoplayback && cls.demoplayback != DPB_EZTV)
return; //no point. return; //no point.
va_start (argptr, format); va_start (argptr, format);
@ -1218,12 +1218,13 @@ void CL_SendCmd (double frametime)
int clientcount; int clientcount;
extern cvar_t cl_maxfps; extern cvar_t cl_maxfps;
clcmdbuf_t *next;
CL_ProxyMenuHooks(); CL_ProxyMenuHooks();
if (cls.demoplayback != DPB_NONE) if (cls.demoplayback != DPB_NONE)
{ {
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
extern cvar_t cl_splitscreen; extern cvar_t cl_splitscreen;
i = cls.netchan.outgoing_sequence & UPDATE_MASK; i = cls.netchan.outgoing_sequence & UPDATE_MASK;
@ -1260,6 +1261,15 @@ void CL_SendCmd (double frametime)
Cam_FinishMove(plnum, cmd); Cam_FinishMove(plnum, cmd);
} }
while (clientcmdlist)
{
next = clientcmdlist->next;
CL_Demo_ClientCommand(clientcmdlist->command);
Con_DPrintf("Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
}
cls.netchan.outgoing_sequence++; cls.netchan.outgoing_sequence++;
} }
@ -1270,25 +1280,24 @@ void CL_SendCmd (double frametime)
buf.cursize = 0; buf.cursize = 0;
buf.data = data; buf.data = data;
CL_SendDownloadReq(&buf); CL_SendDownloadReq(&buf);
while (clientcmdlist)
{ {
clcmdbuf_t *next; next = clientcmdlist->next;
while (clientcmdlist) if (clientcmdlist->reliable)
{ {
next = clientcmdlist->next; MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
if (clientcmdlist->reliable) MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
{
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, clientcmdlist->command);
}
else
{
MSG_WriteByte (&buf, clc_stringcmd);
MSG_WriteString (&buf, clientcmdlist->command);
}
Con_DPrintf("Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
} }
else
{
MSG_WriteByte (&buf, clc_stringcmd);
MSG_WriteString (&buf, clientcmdlist->command);
}
Con_DPrintf("Sending stringcmd %s\n", clientcmdlist->command);
Z_Free(clientcmdlist);
clientcmdlist = next;
} }
if (msecs>150) //q2 has 200 slop. if (msecs>150) //q2 has 200 slop.

View File

@ -74,6 +74,7 @@ cvar_t cl_solid_players = SCVAR("cl_solid_players", "1");
cvar_t cl_noblink = SCVAR("cl_noblink", "0"); cvar_t cl_noblink = SCVAR("cl_noblink", "0");
cvar_t cl_servername = SCVAR("cl_servername", "none"); cvar_t cl_servername = SCVAR("cl_servername", "none");
cvar_t qtvcl_forceversion1 = SCVAR("qtvcl_forceversion1", "0"); cvar_t qtvcl_forceversion1 = SCVAR("qtvcl_forceversion1", "0");
cvar_t qtvcl_eztvextensions = SCVAR("qtvcl_eztvextensions", "0");
cvar_t cl_demospeed = FCVAR("cl_demospeed", "demo_setspeed", "1", 0); cvar_t cl_demospeed = FCVAR("cl_demospeed", "demo_setspeed", "1", 0);
@ -2456,7 +2457,7 @@ void CL_ReadPackets (void)
continue; continue;
} }
if (net_message.cursize < 6 && cls.demoplayback != DPB_MVD) //MVDs don't have the whole sequence header thing going on if (net_message.cursize < 6 && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) //MVDs don't have the whole sequence header thing going on
{ {
Con_TPrintf (TL_RUNTPACKET,NET_AdrToString(net_from)); Con_TPrintf (TL_RUNTPACKET,NET_AdrToString(net_from));
continue; continue;
@ -2512,7 +2513,7 @@ void CL_ReadPackets (void)
break; break;
break; break;
case CP_QUAKEWORLD: case CP_QUAKEWORLD:
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
MSG_BeginReading(); MSG_BeginReading();
cls.netchan.last_received = realtime; cls.netchan.last_received = realtime;
@ -2547,7 +2548,7 @@ void CL_ReadPackets (void)
return; return;
} }
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
MVD_Interpolate(); MVD_Interpolate();
} }
@ -2905,6 +2906,7 @@ void CL_Init (void)
Cvar_Register (&ruleset_allow_larger_models, cl_controlgroup); Cvar_Register (&ruleset_allow_larger_models, cl_controlgroup);
Cvar_Register (&qtvcl_forceversion1, cl_controlgroup); Cvar_Register (&qtvcl_forceversion1, cl_controlgroup);
Cvar_Register (&qtvcl_eztvextensions, cl_controlgroup);
#ifdef WEBCLIENT #ifdef WEBCLIENT
Cmd_AddCommand ("ftp", CL_FTP_f); Cmd_AddCommand ("ftp", CL_FTP_f);
#endif #endif

View File

@ -872,10 +872,19 @@ void Sound_NextDownload (void)
else else
#endif #endif
{ {
if (CL_RemoveClientCommands("modellist")) if (cls.demoplayback == DPB_EZTV)
Con_Printf("Multiple modellists\n"); {
// CL_SendClientCommand ("modellist %i 0", cl.servercount); if (CL_RemoveClientCommands("qtvmodellist"))
CL_SendClientCommand (true, modellist_name, cl.servercount, 0); Con_Printf("Multiple modellists\n");
CL_SendClientCommand (true, "qtvmodellist %i 0", cl.servercount);
}
else
{
if (CL_RemoveClientCommands("modellist"))
Con_Printf("Multiple modellists\n");
// CL_SendClientCommand ("modellist %i 0", cl.servercount);
CL_SendClientCommand (true, modellist_name, cl.servercount, 0);
}
} }
} }
@ -910,6 +919,11 @@ void CL_RequestNextDownload (void)
return; //not yet return; //not yet
cl.sendprespawn = false; cl.sendprespawn = false;
#ifdef _MSC_VER
//FIXME: timedemo timer should start here.
#else
#warning timedemo timer should start here
#endif
#ifdef Q2CLIENT #ifdef Q2CLIENT
@ -926,11 +940,21 @@ void CL_RequestNextDownload (void)
Con_Printf("\n\n-------------\nCouldn't download %s - cannot fully connect\n", cl.worldmodel->name); Con_Printf("\n\n-------------\nCouldn't download %s - cannot fully connect\n", cl.worldmodel->name);
return; return;
} }
if (cls.demoplayback == DPB_EZTV)
{
if (CL_RemoveClientCommands("qtvspawn"))
Con_Printf("Multiple prespawns\n");
CL_SendClientCommand(true, "qtvspawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2);
}
else
{
// done with modellist, request first of static signon messages // done with modellist, request first of static signon messages
if (CL_RemoveClientCommands("prespawn")) if (CL_RemoveClientCommands("prespawn"))
Con_Printf("Multiple prespawns\n"); Con_Printf("Multiple prespawns\n");
// CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); // CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2);
CL_SendClientCommand(true, prespawn_name, cl.servercount, LittleLong(cl.worldmodel->checksum2)); CL_SendClientCommand(true, prespawn_name, cl.servercount, LittleLong(cl.worldmodel->checksum2));
}
} }
} }
@ -1679,7 +1703,7 @@ void CL_ParseServerData (void)
T_FreeStrings(); T_FreeStrings();
} }
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
int i; int i;
extern float nextdemotime; extern float nextdemotime;
@ -1762,11 +1786,20 @@ void CL_ParseServerData (void)
else else
#endif #endif
{ {
if (CL_RemoveClientCommands("soundlist")) if (cls.demoplayback == DPB_EZTV)
Con_Printf("Multiple soundlists\n"); {
// ask for the sound list next if (CL_RemoveClientCommands("qtvsoundlist"))
// CL_SendClientCommand ("soundlist %i 0", cl.servercount); Con_Printf("Multiple soundlists\n");
CL_SendClientCommand (true, soundlist_name, cl.servercount, 0); CL_SendClientCommand (true, "qtvsoundlist %i 0", cl.servercount);
}
else
{
if (CL_RemoveClientCommands("soundlist"))
Con_Printf("Multiple soundlists\n");
// ask for the sound list next
// CL_SendClientCommand ("soundlist %i 0", cl.servercount);
CL_SendClientCommand (true, soundlist_name, cl.servercount, 0);
}
} }
// now waiting for downloads, etc // now waiting for downloads, etc
@ -2273,10 +2306,13 @@ void CL_ParseSoundlist (void)
if (n) if (n)
{ {
if (CL_RemoveClientCommands("soundlist")) if (cls.demoplayback != DPB_EZTV)
Con_Printf("Multiple soundlists\n"); {
// CL_SendClientCommand("soundlist %i %i", cl.servercount, n); if (CL_RemoveClientCommands("soundlist"))
CL_SendClientCommand(true, soundlist_name, cl.servercount, n); Con_Printf("Multiple soundlists\n");
// CL_SendClientCommand("soundlist %i %i", cl.servercount, n);
CL_SendClientCommand(true, soundlist_name, cl.servercount, n);
}
return; return;
} }
@ -2344,10 +2380,13 @@ void CL_ParseModellist (qboolean lots)
if (n) if (n)
{ {
if (CL_RemoveClientCommands("modellist")) if (cls.demoplayback != DPB_EZTV)
Con_Printf("Multiple modellists\n"); {
// CL_SendClientCommand("modellist %i %i", cl.servercount, n); if (CL_RemoveClientCommands("modellist"))
CL_SendClientCommand(true, modellist_name, cl.servercount, (nummodels&0xff00) + n); Con_Printf("Multiple modellists\n");
// CL_SendClientCommand("modellist %i %i", cl.servercount, n);
CL_SendClientCommand(true, modellist_name, cl.servercount, (nummodels&0xff00) + n);
}
return; return;
} }
@ -2885,13 +2924,13 @@ void CL_ParseClientdata (void)
oldparsecountmod = parsecountmod; oldparsecountmod = parsecountmod;
i = cls.netchan.incoming_acknowledged; i = cls.netchan.incoming_acknowledged;
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
cl.oldparsecount = i - 1; cl.oldparsecount = i - 1;
cl.parsecount = i; cl.parsecount = i;
i &= UPDATE_MASK; i &= UPDATE_MASK;
parsecountmod = i; parsecountmod = i;
frame = &cl.frames[i]; frame = &cl.frames[i];
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
frame->senttime = realtime - host_frametime; frame->senttime = realtime - host_frametime;
parsecounttime = cl.frames[i].senttime; parsecounttime = cl.frames[i].senttime;
@ -3110,21 +3149,9 @@ void CL_ServerInfo (void)
CL_SetStat CL_SetStat
===================== =====================
*/ */
void CL_SetStat (int pnum, int stat, int value) static void CL_SetStat_Internal (int pnum, int stat, int value)
{ {
int j; int j;
if (stat < 0 || stat >= MAX_CL_STATS)
return;
// Host_EndGame ("CL_SetStat: %i is invalid", stat);
if (cls.demoplayback == DPB_MVD)
{
extern int cls_lastto;
cl.players[cls_lastto].stats[stat]=value;
if ( spec_track[pnum] != cls_lastto )
return;
}
if (cl.stats[pnum][stat] != value) if (cl.stats[pnum][stat] != value)
Sbar_Changed (); Sbar_Changed ();
@ -3138,15 +3165,6 @@ void CL_SetStat (int pnum, int stat, int value)
if (stat == STAT_VIEWHEIGHT && cls.z_ext & Z_EXT_VIEWHEIGHT) if (stat == STAT_VIEWHEIGHT && cls.z_ext & Z_EXT_VIEWHEIGHT)
cl.viewheight[pnum] = value; cl.viewheight[pnum] = value;
if (stat == STAT_TIME && (cls.fteprotocolextensions & PEXT_ACCURATETIMINGS))
{
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = value * 0.001;
cl.gametimemark = realtime;
}
if (stat == STAT_WEAPON) if (stat == STAT_WEAPON)
{ {
if (cl.stats[pnum][stat] != value) if (cl.stats[pnum][stat] != value)
@ -3164,6 +3182,34 @@ void CL_SetStat (int pnum, int stat, int value)
TP_StatChanged(stat, value); TP_StatChanged(stat, value);
} }
void CL_SetStat (int pnum, int stat, int value)
{
if (stat < 0 || stat >= MAX_CL_STATS)
return;
// Host_EndGame ("CL_SetStat: %i is invalid", stat);
if (stat == STAT_TIME && (cls.fteprotocolextensions & PEXT_ACCURATETIMINGS))
{
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = value * 0.001;
cl.gametimemark = realtime;
}
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
extern int cls_lastto;
cl.players[cls_lastto].stats[stat]=value;
for (pnum = 0; pnum < cl.splitclients; pnum++)
if (spec_track[pnum] == cls_lastto)
CL_SetStat_Internal(pnum, stat, value);
}
else
CL_SetStat_Internal(pnum, stat, value);
}
/* /*
============== ==============
CL_MuzzleFlash CL_MuzzleFlash
@ -4073,7 +4119,9 @@ void CL_ParseServerMessage (void)
break; break;
case svc_disconnect: case svc_disconnect:
if (cls.state == ca_connected) if (cls.demoplayback == DPB_EZTV) //eztv fails to detect the end of demos.
MSG_ReadString();
else if (cls.state == ca_connected)
{ {
Host_EndGame ("Server disconnected\n" Host_EndGame ("Server disconnected\n"
"Server version may not be compatible"); "Server version may not be compatible");
@ -4144,7 +4192,7 @@ void CL_ParseServerMessage (void)
break; break;
#endif #endif
case svc_setangle: case svc_setangle:
if (cls.demoplayback == DPB_MVD) if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{ {
i = MSG_ReadByte(); i = MSG_ReadByte();
if (i != spec_track[0] || !autocam[0]) if (i != spec_track[0] || !autocam[0])

View File

@ -379,6 +379,14 @@ void CL_PredictUsercmd (int pnum, player_state_t *from, player_state_t *to, user
VectorCopy (u->angles, pmove.angles); VectorCopy (u->angles, pmove.angles);
VectorCopy (from->velocity, pmove.velocity); VectorCopy (from->velocity, pmove.velocity);
if (!(pmove.velocity[0] == 0) && !(pmove.velocity[0] != 0))
{
Con_Printf("nan velocity!\n");
pmove.velocity[0] = 0;
pmove.velocity[1] = 0;
pmove.velocity[2] = 0;
}
pmove.jump_msec = (cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec; pmove.jump_msec = (cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
pmove.jump_held = from->jump_held; pmove.jump_held = from->jump_held;
pmove.waterjumptime = from->waterjumptime; pmove.waterjumptime = from->waterjumptime;
@ -536,7 +544,7 @@ static void CL_LerpMove (int pnum, float msgtime)
int i; int i;
int from, to; int from, to;
if (cl_nolerp.value || cls.demoplayback == DPB_MVD) if (cl_nolerp.value || cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV || cls.demoplayback == DPB_NETQUAKE)
return; return;
if (cls.netchan.outgoing_sequence < lastsequence) { if (cls.netchan.outgoing_sequence < lastsequence) {
@ -642,7 +650,7 @@ void CL_CalcClientTime(void)
cl.servertime = cl.oldgametime; cl.servertime = cl.oldgametime;
} }
if (cls.protocol == CP_NETQUAKE || (cls.demoplayback && cls.demoplayback != DPB_MVD)) if (cls.protocol == CP_NETQUAKE || (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV))
{ {
float want; float want;
// float off; // float off;
@ -706,7 +714,7 @@ void CL_PredictMovePNum (int pnum)
if (cl_pushlatency.value > 0) if (cl_pushlatency.value > 0)
Cvar_Set (&cl_pushlatency, "0"); Cvar_Set (&cl_pushlatency, "0");
if (cl.paused && !cls.demoplayback!=DPB_MVD && (!cl.spectator || !autocam[pnum])) if (cl.paused && !(cls.demoplayback!=DPB_MVD && cls.demoplayback!=DPB_EZTV) && (!cl.spectator || !autocam[pnum]))
return; return;
CL_CalcClientTime(); CL_CalcClientTime();
@ -717,6 +725,11 @@ void CL_PredictMovePNum (int pnum)
return; return;
} }
if (cls.demoplayback == DPB_NETQUAKE)
{
cl.ackedinputsequence = cls.netchan.outgoing_sequence;
}
if (!cl.ackedinputsequence) if (!cl.ackedinputsequence)
{ {
return; return;
@ -787,7 +800,7 @@ void CL_PredictMovePNum (int pnum)
} }
*/ } */ }
#endif #endif
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD)|| cl.fixangle)) if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle))
{ {
fixedorg: fixedorg:
VectorCopy (vel, cl.simvel[pnum]); VectorCopy (vel, cl.simvel[pnum]);
@ -807,7 +820,7 @@ fixedorg:
to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK]; to = &cl.frames[cl.ackedinputsequence & UPDATE_MASK];
if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value && cls.demoplayback != DPB_MVD) if (Cam_TrackNum(pnum)>=0 && !cl_nolerp.value && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV && cls.demoplayback != DPB_NETQUAKE)
{ {
float f; float f;

View File

@ -343,7 +343,7 @@ typedef struct
// demo recording info must be here, because record is started before // demo recording info must be here, because record is started before
// entering a map (and clearing client_state_t) // entering a map (and clearing client_state_t)
qboolean demorecording; qboolean demorecording;
enum{DPB_NONE,DPB_QUAKEWORLD,DPB_MVD, enum{DPB_NONE,DPB_QUAKEWORLD,DPB_MVD,DPB_EZTV,
#ifdef NQPROT #ifdef NQPROT
DPB_NETQUAKE, DPB_NETQUAKE,
#endif #endif

View File

@ -1603,7 +1603,7 @@ void Key_Event (int key, qboolean down)
// during demo playback, most keys bring up the main menu // during demo playback, most keys bring up the main menu
// //
if (cls.demoplayback && cls.demoplayback != DPB_MVD && down && consolekeys[key] && key != K_TAB && key_dest == key_game) if (cls.demoplayback && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV && down && consolekeys[key] && key != K_TAB && key_dest == key_game)
{ {
M_ToggleMenu_f (); M_ToggleMenu_f ();
return; return;