qtv changes allow you to spectate annother spectator. FTE changes fix independant physics stuff a bit, and fix AVI recording a little also.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2440 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b444ca99ac
commit
acf93f1548
24 changed files with 537 additions and 220 deletions
|
@ -452,40 +452,88 @@ readnext:
|
||||||
CL_StopPlayback ();
|
CL_StopPlayback ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Con_Printf("demo packet %x\n", (int)c);
|
||||||
switch (c&7)
|
switch (c&7)
|
||||||
{
|
{
|
||||||
case dem_cmd :
|
case dem_cmd :
|
||||||
// user sent input
|
/* if (cls.demoplayback == DPB_MVD)
|
||||||
i = cls.netchan.outgoing_sequence & UPDATE_MASK;
|
|
||||||
pcmd = &cl.frames[i].cmd[0];
|
|
||||||
r = readdemobytes (&q1cmd, sizeof(q1cmd));
|
|
||||||
if (r != sizeof(q1cmd))
|
|
||||||
{
|
{
|
||||||
CL_StopPlayback ();
|
unsigned short samps;
|
||||||
|
unsigned char bits;
|
||||||
|
unsigned char rateid;
|
||||||
|
unsigned char audio[8192];
|
||||||
|
|
||||||
|
if (readdemobytes (&samps, 2) == 2)
|
||||||
|
{
|
||||||
|
if (readdemobytes (&bits, 1) == 1)
|
||||||
|
{
|
||||||
|
if (samps > sizeof(audio))
|
||||||
|
{
|
||||||
|
Con_Printf("Corrupted/too large audio chunk\n");
|
||||||
|
CL_StopPlayback();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (readdemobytes (&rateid, 1) == 1)
|
||||||
|
{
|
||||||
|
if (readdemobytes (audio, samps) == samps)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
samps = samps/(bits/8);
|
||||||
|
f = fopen("c:/test.raw", "r+b");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
fwrite(audio, samps, bits/8, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
S_RawAudio(0, audio, 11025, samps, 1, bits/8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unreadbytes(1, &rateid);
|
||||||
|
}
|
||||||
|
unreadbytes(1, &bits);
|
||||||
|
}
|
||||||
|
unreadbytes(1, &samps);
|
||||||
|
}
|
||||||
|
|
||||||
|
unreadbytes(1, &c);
|
||||||
|
r = 0;
|
||||||
|
unreadbytes(1, &r);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// byte order stuff
|
else
|
||||||
for (j = 0; j < 3; j++)
|
{*/
|
||||||
{
|
// user sent input
|
||||||
q1cmd.angles[j] = LittleFloat(q1cmd.angles[j]);
|
i = cls.netchan.outgoing_sequence & UPDATE_MASK;
|
||||||
pcmd->angles[j] = ((int)(q1cmd.angles[j]*65536.0/360)&65535);
|
pcmd = &cl.frames[i].cmd[0];
|
||||||
}
|
r = readdemobytes (&q1cmd, sizeof(q1cmd));
|
||||||
pcmd->forwardmove = q1cmd.forwardmove = LittleShort(q1cmd.forwardmove);
|
if (r != sizeof(q1cmd))
|
||||||
pcmd->sidemove = q1cmd.sidemove = LittleShort(q1cmd.sidemove);
|
{
|
||||||
pcmd->upmove = q1cmd.upmove = LittleShort(q1cmd.upmove);
|
CL_StopPlayback ();
|
||||||
pcmd->msec = q1cmd.msec;
|
return 0;
|
||||||
pcmd->buttons = q1cmd.buttons;
|
}
|
||||||
|
// byte order stuff
|
||||||
|
for (j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
q1cmd.angles[j] = LittleFloat(q1cmd.angles[j]);
|
||||||
|
pcmd->angles[j] = ((int)(q1cmd.angles[j]*65536.0/360)&65535);
|
||||||
|
}
|
||||||
|
pcmd->forwardmove = q1cmd.forwardmove = LittleShort(q1cmd.forwardmove);
|
||||||
|
pcmd->sidemove = q1cmd.sidemove = LittleShort(q1cmd.sidemove);
|
||||||
|
pcmd->upmove = q1cmd.upmove = LittleShort(q1cmd.upmove);
|
||||||
|
pcmd->msec = q1cmd.msec;
|
||||||
|
pcmd->buttons = q1cmd.buttons;
|
||||||
|
|
||||||
|
|
||||||
cl.frames[i].senttime = demotime;
|
cl.frames[i].senttime = demotime;
|
||||||
cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet
|
cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet
|
||||||
cls.netchan.outgoing_sequence++;
|
cls.netchan.outgoing_sequence++;
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
{
|
{
|
||||||
readdemobytes (&f, 4);
|
readdemobytes (&f, 4);
|
||||||
cl.viewangles[0][i] = LittleFloat (f);
|
cl.viewangles[0][i] = LittleFloat (f);
|
||||||
}
|
}
|
||||||
|
/* }*/
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case dem_read:
|
case dem_read:
|
||||||
|
@ -1384,6 +1432,7 @@ void CL_PlayDemo(char *demoname)
|
||||||
|
|
||||||
void CL_QTVPlay (vfsfile_t *newf)
|
void CL_QTVPlay (vfsfile_t *newf)
|
||||||
{
|
{
|
||||||
|
#define BUFFERTIME 10
|
||||||
CL_Disconnect_f ();
|
CL_Disconnect_f ();
|
||||||
|
|
||||||
cls.demofile = newf;
|
cls.demofile = newf;
|
||||||
|
@ -1396,11 +1445,11 @@ void CL_QTVPlay (vfsfile_t *newf)
|
||||||
cls.state = ca_demostart;
|
cls.state = ca_demostart;
|
||||||
net_message.packing = SZ_RAWBYTES;
|
net_message.packing = SZ_RAWBYTES;
|
||||||
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, 0);
|
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, 0);
|
||||||
realtime = -10;
|
realtime = -BUFFERTIME;
|
||||||
cl.gametime = -10;
|
cl.gametime = -BUFFERTIME;
|
||||||
cl.gametimemark = realtime;
|
cl.gametimemark = realtime;
|
||||||
|
|
||||||
Con_Printf("Buffering for ten seconds\n");
|
Con_Printf("Buffering for %i seconds\n", (int)-realtime);
|
||||||
|
|
||||||
cls.netchan.last_received=realtime;
|
cls.netchan.last_received=realtime;
|
||||||
|
|
||||||
|
@ -1416,7 +1465,8 @@ void CL_QTVPoll (void)
|
||||||
{
|
{
|
||||||
char *s, *e, *colon;
|
char *s, *e, *colon;
|
||||||
int len;
|
int len;
|
||||||
qboolean error = false;
|
qboolean streamavailable = false;
|
||||||
|
qboolean saidheader = false;
|
||||||
|
|
||||||
if (!qtvrequest)
|
if (!qtvrequest)
|
||||||
return;
|
return;
|
||||||
|
@ -1451,23 +1501,37 @@ void CL_QTVPoll (void)
|
||||||
{
|
{
|
||||||
*colon++ = '\0';
|
*colon++ = '\0';
|
||||||
if (!strcmp(s, "PERROR"))
|
if (!strcmp(s, "PERROR"))
|
||||||
|
{ //printable error
|
||||||
|
Con_Printf("QTV Error:\n%s\n", colon);
|
||||||
|
}
|
||||||
|
else if (!strcmp(s, "PRINT"))
|
||||||
{ //printable error
|
{ //printable error
|
||||||
Con_Printf("QTV:\n%s\n", colon);
|
Con_Printf("QTV:\n%s\n", colon);
|
||||||
error = true;
|
}
|
||||||
|
else if (!strcmp(s, "TERROR"))
|
||||||
|
{ //printable error
|
||||||
|
Con_Printf("QTV Error:\n%s\n", colon);
|
||||||
}
|
}
|
||||||
else if (!strcmp(s, "ADEMO"))
|
else if (!strcmp(s, "ADEMO"))
|
||||||
{ //printable error
|
{ //printable error
|
||||||
Con_Printf("Demo%s is available\n", colon);
|
Con_Printf("Demo%s is available\n", colon);
|
||||||
error = true; //not really an error, but meh
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(s, "ASOURCE"))
|
else if (!strcmp(s, "ASOURCE"))
|
||||||
{ //printable error
|
{ //printable source
|
||||||
Con_Printf("Source%s is available\n", colon);
|
if (!saidheader)
|
||||||
error = true;
|
{
|
||||||
|
saidheader=true;
|
||||||
|
Con_Printf("Available Sources:\n");
|
||||||
|
}
|
||||||
|
Con_Printf("%s\n", colon);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(s, "BEGIN"))
|
||||||
|
streamavailable = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!strcmp(s, "BEGIN"))
|
||||||
|
streamavailable = true;
|
||||||
}
|
}
|
||||||
//from e to s, we have a line
|
//from e to s, we have a line
|
||||||
s = e+1;
|
s = e+1;
|
||||||
|
@ -1475,7 +1539,7 @@ void CL_QTVPoll (void)
|
||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error)
|
if (streamavailable)
|
||||||
{
|
{
|
||||||
CL_QTVPlay(qtvrequest);
|
CL_QTVPlay(qtvrequest);
|
||||||
qtvrequest = NULL;
|
qtvrequest = NULL;
|
||||||
|
@ -1488,6 +1552,16 @@ void CL_QTVPoll (void)
|
||||||
qtvrequestsize = 0;
|
qtvrequestsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *strchrrev(char *str, char chr)
|
||||||
|
{
|
||||||
|
char *firstchar = str;
|
||||||
|
for (str = str + strlen(str)-1; str>=firstchar; str--)
|
||||||
|
if (*str == chr)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void CL_QTVPlay_f (void)
|
void CL_QTVPlay_f (void)
|
||||||
{
|
{
|
||||||
qboolean raw=0;
|
qboolean raw=0;
|
||||||
|
@ -1495,6 +1569,12 @@ void CL_QTVPlay_f (void)
|
||||||
vfsfile_t *newf;
|
vfsfile_t *newf;
|
||||||
char *host;
|
char *host;
|
||||||
|
|
||||||
|
if (Cmd_Argc() < 2)
|
||||||
|
{
|
||||||
|
Con_Printf("Usage: qtvplay [stream@]hostname[:port] [password]\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
connrequest = Cmd_Argv(1);
|
connrequest = Cmd_Argv(1);
|
||||||
|
|
||||||
if (*connrequest == '#')
|
if (*connrequest == '#')
|
||||||
|
@ -1530,7 +1610,7 @@ void CL_QTVPlay_f (void)
|
||||||
|
|
||||||
host = connrequest;
|
host = connrequest;
|
||||||
|
|
||||||
connrequest = strchr(connrequest, '@');
|
connrequest = strchrrev(connrequest, '@');
|
||||||
if (connrequest)
|
if (connrequest)
|
||||||
host = connrequest+1;
|
host = connrequest+1;
|
||||||
newf = FS_OpenTCP(host);
|
newf = FS_OpenTCP(host);
|
||||||
|
@ -1541,8 +1621,7 @@ void CL_QTVPlay_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
host = connrequest = Cmd_Argv(1);
|
host = Cmd_Argv(1);
|
||||||
connrequest = strchr(connrequest, '@');
|
|
||||||
if (connrequest)
|
if (connrequest)
|
||||||
*connrequest = '\0';
|
*connrequest = '\0';
|
||||||
else
|
else
|
||||||
|
@ -1582,53 +1661,6 @@ void CL_QTVPlay_f (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void CL_QTVPlay_f (void)
|
|
||||||
{
|
|
||||||
char *connrequest;
|
|
||||||
vfsfile_t *newf;
|
|
||||||
newf = FS_OpenTCP(Cmd_Argv(1));
|
|
||||||
|
|
||||||
if (!newf)
|
|
||||||
{
|
|
||||||
Con_Printf("Couldn't connect to proxy\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connrequest = "QTV\n"
|
|
||||||
"VERSION: 1\n"
|
|
||||||
"RAW: 1\n";
|
|
||||||
VFS_WRITE(newf, connrequest, strlen(connrequest));
|
|
||||||
connrequest = "SOURCE: file:test.mvd\n";
|
|
||||||
VFS_WRITE(newf, connrequest, strlen(connrequest));
|
|
||||||
connrequest = "\n";
|
|
||||||
VFS_WRITE(newf, connrequest, strlen(connrequest));
|
|
||||||
|
|
||||||
CL_Disconnect_f ();
|
|
||||||
|
|
||||||
cls.demofile = newf;
|
|
||||||
|
|
||||||
unreadcount = 0; //just in case
|
|
||||||
|
|
||||||
cls.demoplayback = DPB_MVD;
|
|
||||||
cls.findtrack = true;
|
|
||||||
|
|
||||||
cls.state = ca_demostart;
|
|
||||||
net_message.packing = SZ_RAWBYTES;
|
|
||||||
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, 0);
|
|
||||||
realtime = -10;
|
|
||||||
cl.gametime = -10;
|
|
||||||
cl.gametimemark = realtime;
|
|
||||||
|
|
||||||
Con_Printf("Buffering for ten seconds\n");
|
|
||||||
|
|
||||||
cls.netchan.last_received=realtime;
|
|
||||||
|
|
||||||
cls.protocol = CP_QUAKEWORLD;
|
|
||||||
TP_ExecTrigger ("f_demostart");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void CL_QTVList_f (void)
|
void CL_QTVList_f (void)
|
||||||
{
|
{
|
||||||
char *connrequest;
|
char *connrequest;
|
||||||
|
@ -1653,30 +1685,6 @@ void CL_QTVList_f (void)
|
||||||
VFS_CLOSE(qtvrequest);
|
VFS_CLOSE(qtvrequest);
|
||||||
qtvrequest = newf;
|
qtvrequest = newf;
|
||||||
qtvrequestsize = 0;
|
qtvrequestsize = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
CL_Disconnect_f ();
|
|
||||||
|
|
||||||
cls.demofile = newf;
|
|
||||||
|
|
||||||
unreadcount = 0; //just in case
|
|
||||||
|
|
||||||
cls.demoplayback = DPB_MVD;
|
|
||||||
cls.findtrack = true;
|
|
||||||
|
|
||||||
cls.state = ca_demostart;
|
|
||||||
net_message.packing = SZ_RAWBYTES;
|
|
||||||
Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, 0);
|
|
||||||
realtime = 0;
|
|
||||||
cl.gametime = 0;
|
|
||||||
cl.gametimemark = realtime;
|
|
||||||
|
|
||||||
Con_Printf("Querying proxy\n");
|
|
||||||
|
|
||||||
cls.netchan.last_received=realtime;
|
|
||||||
|
|
||||||
cls.protocol = CP_QUAKEWORLD;
|
|
||||||
TP_ExecTrigger ("f_demostart");*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2898,7 +2898,7 @@ void CL_LinkPlayers (void)
|
||||||
ent->origin[0] = cl.simorg[pnum][0];
|
ent->origin[0] = cl.simorg[pnum][0];
|
||||||
ent->origin[1] = cl.simorg[pnum][1];
|
ent->origin[1] = cl.simorg[pnum][1];
|
||||||
ent->origin[2] = cl.simorg[pnum][2]+cl.crouch[pnum];
|
ent->origin[2] = cl.simorg[pnum][2]+cl.crouch[pnum];
|
||||||
ent->flags |= 2;
|
ent->flags |= Q2RF_EXTERNALMODEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -843,7 +843,7 @@ float CL_FilterTime (double time, float wantfps) //now returns the extra time no
|
||||||
if (wantfps < 1)
|
if (wantfps < 1)
|
||||||
fps = fpscap;
|
fps = fpscap;
|
||||||
else
|
else
|
||||||
fps = bound (10.0, wantfps, fpscap);
|
fps = bound (6.7, wantfps, fpscap); //we actually cap ourselves to 150msecs (1000/7 = 142)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (time < 1000 / fps)
|
if (time < 1000 / fps)
|
||||||
|
@ -983,15 +983,21 @@ unsigned long _stdcall CL_IndepPhysicsThread(void *param)
|
||||||
int sleeptime;
|
int sleeptime;
|
||||||
float fps;
|
float fps;
|
||||||
float time, lasttime;
|
float time, lasttime;
|
||||||
|
float spare;
|
||||||
lasttime = Sys_DoubleTime();
|
lasttime = Sys_DoubleTime();
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
EnterCriticalSection(&indepcriticialsection);
|
|
||||||
time = Sys_DoubleTime();
|
time = Sys_DoubleTime();
|
||||||
if (cls.state)
|
spare = CL_FilterTime((time - lasttime)*1000, cl_netfps.value);
|
||||||
CL_SendCmd(time - lasttime);
|
if (spare)
|
||||||
lasttime = time;
|
{
|
||||||
LeaveCriticalSection(&indepcriticialsection);
|
time -= spare/1000.0f;
|
||||||
|
EnterCriticalSection(&indepcriticialsection);
|
||||||
|
if (cls.state)
|
||||||
|
CL_SendCmd(time - lasttime);
|
||||||
|
lasttime = time;
|
||||||
|
LeaveCriticalSection(&indepcriticialsection);
|
||||||
|
}
|
||||||
|
|
||||||
fps = cl_netfps.value;
|
fps = cl_netfps.value;
|
||||||
if (fps < 4)
|
if (fps < 4)
|
||||||
|
@ -1003,6 +1009,8 @@ unsigned long _stdcall CL_IndepPhysicsThread(void *param)
|
||||||
|
|
||||||
if (sleeptime)
|
if (sleeptime)
|
||||||
Sleep(sleeptime);
|
Sleep(sleeptime);
|
||||||
|
else
|
||||||
|
Sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,11 +1022,18 @@ void CL_UseIndepPhysics(qboolean allow)
|
||||||
if (allow)
|
if (allow)
|
||||||
{ //enable it
|
{ //enable it
|
||||||
DWORD tid; //*sigh*...
|
DWORD tid; //*sigh*...
|
||||||
|
|
||||||
|
// TIMECAPS tc;
|
||||||
|
// timeGetDevCaps(&tc, sizeof(TIMECAPS));
|
||||||
|
// Con_Printf("Timer has a resolution of %i millisecond%s\n", tc.wPeriodMin, tc.wPeriodMin!=1?"s":"");
|
||||||
|
|
||||||
InitializeCriticalSection(&indepcriticialsection);
|
InitializeCriticalSection(&indepcriticialsection);
|
||||||
runningindepphys = true;
|
runningindepphys = true;
|
||||||
|
|
||||||
indepphysicsthread = CreateThread(NULL, 8192, CL_IndepPhysicsThread, NULL, 0, &tid);
|
indepphysicsthread = CreateThread(NULL, 8192, CL_IndepPhysicsThread, NULL, 0, &tid);
|
||||||
allowindepphys = 1;
|
allowindepphys = 1;
|
||||||
|
|
||||||
|
SetThreadPriority(independantphysics, HIGH_PRIORITY_CLASS);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1050,6 +1065,7 @@ CL_SendCmd
|
||||||
vec3_t accum[MAX_SPLITS];
|
vec3_t accum[MAX_SPLITS];
|
||||||
void CL_SendCmd (float frametime)
|
void CL_SendCmd (float frametime)
|
||||||
{
|
{
|
||||||
|
extern cvar_t cl_indepphysics;
|
||||||
sizebuf_t buf;
|
sizebuf_t buf;
|
||||||
qbyte data[512];
|
qbyte data[512];
|
||||||
int i, plnum;
|
int i, plnum;
|
||||||
|
@ -1185,10 +1201,17 @@ void CL_SendCmd (float frametime)
|
||||||
independantphysics[plnum].msec = msecstouse;
|
independantphysics[plnum].msec = msecstouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!CL_FilterTime(msecstouse, cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value) && msecstouse<255 && cls.state == ca_active)
|
if (cl_netfps.value && !cl_indepphysics.value)
|
||||||
// {
|
{
|
||||||
// return;
|
int spare;
|
||||||
// }
|
spare = CL_FilterTime(msecstouse, cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value);
|
||||||
|
if (!spare && msecstouse<255 && cls.state == ca_active)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (spare > 0)
|
||||||
|
msecstouse -= spare;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
if (cls.protocol == CP_NETQUAKE)
|
if (cls.protocol == CP_NETQUAKE)
|
||||||
|
|
|
@ -27,10 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "cl_master.h"
|
#include "cl_master.h"
|
||||||
#include "cl_ignore.h"
|
#include "cl_ignore.h"
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(MINGW) && defined(RGLQUAKE)
|
|
||||||
//#define WINAVI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
void CL_Sbar_Callback(struct cvar_s *var, char *oldvalue);
|
void CL_Sbar_Callback(struct cvar_s *var, char *oldvalue);
|
||||||
void Name_Callback(struct cvar_s *var, char *oldvalue);
|
void Name_Callback(struct cvar_s *var, char *oldvalue);
|
||||||
|
@ -1029,6 +1025,7 @@ void CL_Disconnect (void)
|
||||||
qbyte final[12];
|
qbyte final[12];
|
||||||
|
|
||||||
connect_time = -1;
|
connect_time = -1;
|
||||||
|
connect_tries = 0;
|
||||||
|
|
||||||
Cvar_ApplyLatches(CVAR_SERVEROVERRIDE);
|
Cvar_ApplyLatches(CVAR_SERVEROVERRIDE);
|
||||||
|
|
||||||
|
@ -3038,11 +3035,6 @@ Host_Frame
|
||||||
Runs all active servers
|
Runs all active servers
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
#if defined(WINAVI) && !defined(NOMEDIA)
|
|
||||||
extern float recordavi_frametime;
|
|
||||||
qboolean Media_Capturing();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern cvar_t cl_netfps;
|
extern cvar_t cl_netfps;
|
||||||
int nopacketcount;
|
int nopacketcount;
|
||||||
void SNDDMA_SetUnderWater(qboolean underwater);
|
void SNDDMA_SetUnderWater(qboolean underwater);
|
||||||
|
@ -3054,7 +3046,7 @@ void Host_Frame (double time)
|
||||||
static double time3 = 0;
|
static double time3 = 0;
|
||||||
int pass1, pass2, pass3;
|
int pass1, pass2, pass3;
|
||||||
// float fps;
|
// float fps;
|
||||||
float realframetime;
|
double realframetime;
|
||||||
static double spare;
|
static double spare;
|
||||||
|
|
||||||
RSpeedLocals();
|
RSpeedLocals();
|
||||||
|
@ -3062,14 +3054,7 @@ void Host_Frame (double time)
|
||||||
if (setjmp (host_abort) )
|
if (setjmp (host_abort) )
|
||||||
return; // something bad happened, or the server disconnected
|
return; // something bad happened, or the server disconnected
|
||||||
|
|
||||||
realframetime = time;
|
realframetime = time = Media_TweekCaptureFrameTime(time);
|
||||||
|
|
||||||
#if defined(WINAVI) && !defined(NOMEDIA)
|
|
||||||
if (cls.demoplayback && Media_Capturing() && recordavi_frametime>0.01)
|
|
||||||
{
|
|
||||||
realframetime = time = recordavi_frametime;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if (cls.demoplayback && cl_demospeed.value>0)
|
// if (cls.demoplayback && cl_demospeed.value>0)
|
||||||
// realframetime *= cl_demospeed.value; // this probably screws up other timings
|
// realframetime *= cl_demospeed.value; // this probably screws up other timings
|
||||||
|
@ -3117,10 +3102,11 @@ void Host_Frame (double time)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done.
|
Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done.
|
||||||
if (cl_maxfps.value>0 && (cl_netfps.value>0 || cls.demoplayback))
|
if ((cl_netfps.value>0 || cls.demoplayback || cl_indepphysics.value))
|
||||||
{ //limit the fps freely, and expect the netfps to cope.
|
{ //limit the fps freely, and expect the netfps to cope.
|
||||||
if ((realtime - oldrealtime) < 1/cl_maxfps.value)
|
if (cl_maxfps.value > 0)
|
||||||
return;
|
if ((realtime - oldrealtime) < 1/cl_maxfps.value)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -3716,8 +3716,19 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
|
||||||
Cmd_ExecuteString(stufftext, RESTRICT_SERVER+destsplit); //do this NOW so that it's done before any models or anything are loaded
|
Cmd_ExecuteString(stufftext, RESTRICT_SERVER+destsplit); //do this NOW so that it's done before any models or anything are loaded
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!strncmp(stufftext, "//querycmd ", 11))
|
||||||
|
{
|
||||||
|
COM_Parse(stufftext + 11);
|
||||||
|
if (Cmd_Exists(com_token))
|
||||||
|
{
|
||||||
|
Cbuf_AddText ("cmd cmdsupported ", RESTRICT_SERVER+destsplit);
|
||||||
|
Cbuf_AddText (com_token, RESTRICT_SERVER+destsplit);
|
||||||
|
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
#ifdef CSQC_DAT
|
#ifdef CSQC_DAT
|
||||||
if (!CSQC_StuffCmd(stufftext))
|
if (!CSQC_StuffCmd(stufftext))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
Cbuf_AddText (stufftext, RESTRICT_SERVER+destsplit);
|
Cbuf_AddText (stufftext, RESTRICT_SERVER+destsplit);
|
||||||
|
|
|
@ -767,7 +767,7 @@ char *Media_NextTrack(void)
|
||||||
|
|
||||||
//Avi files are specific to windows. Bit of a bummer really.
|
//Avi files are specific to windows. Bit of a bummer really.
|
||||||
#if defined(_WIN32) && !defined(__GNUC__)
|
#if defined(_WIN32) && !defined(__GNUC__)
|
||||||
//#define WINAVI
|
#define WINAVI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1462,7 +1462,7 @@ unsigned long recordavi_codec_fourcc;
|
||||||
soundcardinfo_t *capture_fakesounddevice;
|
soundcardinfo_t *capture_fakesounddevice;
|
||||||
int recordavi_video_frame_counter;
|
int recordavi_video_frame_counter;
|
||||||
int recordavi_audio_frame_counter;
|
int recordavi_audio_frame_counter;
|
||||||
float recordavi_frametime;
|
float recordavi_frametime; //length of a frame in fractional seconds
|
||||||
float recordavi_videotime;
|
float recordavi_videotime;
|
||||||
float recordavi_audiotime;
|
float recordavi_audiotime;
|
||||||
int capturesize;
|
int capturesize;
|
||||||
|
@ -1512,6 +1512,16 @@ qboolean Media_PausedDemo (void)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Media_TweekCaptureFrameTime(double time)
|
||||||
|
{
|
||||||
|
if (cls.demoplayback && Media_Capturing() && recordavi_frametime>0.01)
|
||||||
|
{
|
||||||
|
return time = recordavi_frametime;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
void Media_RecordFrame (void)
|
void Media_RecordFrame (void)
|
||||||
{
|
{
|
||||||
if (!capturetype)
|
if (!capturetype)
|
||||||
|
@ -1546,19 +1556,12 @@ void Media_RecordFrame (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
//time for annother frame?
|
//time for annother frame?
|
||||||
/*if (recordavi_uncompressed_audio_stream) //sync video to the same frame as audio.
|
if (recordavi_videotime > realtime+1)
|
||||||
{
|
recordavi_videotime = realtime; //urm, wrapped?..
|
||||||
if (recordavi_video_frame_counter > recordavi_audio_frame_counter)
|
if (recordavi_videotime > realtime)
|
||||||
goto skipframe;
|
goto skipframe;
|
||||||
}
|
recordavi_videotime += recordavi_frametime;
|
||||||
else*/
|
//audio is mixed to match the video times
|
||||||
{
|
|
||||||
if (recordavi_videotime > realtime+1)
|
|
||||||
recordavi_videotime = realtime; //urm, wrapped?..
|
|
||||||
if (recordavi_videotime > realtime)
|
|
||||||
goto skipframe;
|
|
||||||
recordavi_videotime += recordavi_frametime;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (capturetype)
|
switch (capturetype)
|
||||||
{
|
{
|
||||||
|
@ -1796,7 +1799,7 @@ void Media_RecordFilm_f (void)
|
||||||
!strcmp(fourcc, "pcx"))
|
!strcmp(fourcc, "pcx"))
|
||||||
{
|
{
|
||||||
capturetype = CT_SCREENSHOT;
|
capturetype = CT_SCREENSHOT;
|
||||||
strcpy(capturefilenameprefix, Cmd_Argv(1));
|
Q_strncpyz(capturefilenameprefix, Cmd_Argv(1), sizeof(capturefilenameprefix));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1836,7 +1839,7 @@ void Media_RecordFilm_f (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
snprintf(filename, 192, "%s%s", com_quakedir, Cmd_Argv(1));
|
snprintf(filename, sizeof(filename) - 5, "%s%s", com_quakedir, Cmd_Argv(1));
|
||||||
COM_StripExtension(filename, filename, sizeof(filename));
|
COM_StripExtension(filename, filename, sizeof(filename));
|
||||||
COM_DefaultExtension (filename, ".avi", sizeof(filename));
|
COM_DefaultExtension (filename, ".avi", sizeof(filename));
|
||||||
|
|
||||||
|
@ -1952,6 +1955,7 @@ void Media_RecordFilm_f (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf("That sort of video capturing is not supported in this build\n");
|
Con_Printf("That sort of video capturing is not supported in this build\n");
|
||||||
|
capturetype = CT_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Media_CaptureDemoEnd(void)
|
void Media_CaptureDemoEnd(void)
|
||||||
|
@ -1968,6 +1972,8 @@ void Media_RecordDemo_f(void)
|
||||||
|
|
||||||
if (capturetype != CT_NONE)
|
if (capturetype != CT_NONE)
|
||||||
recordingdemo = true;
|
recordingdemo = true;
|
||||||
|
else
|
||||||
|
CL_Stopdemo_f(); //capturing failed for some reason
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void Media_CaptureDemoEnd(void){}
|
void Media_CaptureDemoEnd(void){}
|
||||||
|
|
|
@ -15,10 +15,12 @@ qboolean M_Script_Key (int key, menu_t *menu)
|
||||||
{
|
{
|
||||||
if (menu->selecteditem && menu->selecteditem->common.type == mt_edit)
|
if (menu->selecteditem && menu->selecteditem->common.type == mt_edit)
|
||||||
return false;
|
return false;
|
||||||
if (key >= '0' && key <= '9')
|
if (key >= '0' && key <= '9' && *menualias.string)
|
||||||
{
|
{
|
||||||
if (key == '0') //specal case so that "hello" < "0"... (plus matches impulses)
|
if (key == '0') //specal case so that "hello" < "0"... (plus matches common impulses)
|
||||||
Cbuf_AddText(va("set option %i\n%s\n", key-'0'+1, menualias.string), RESTRICT_LOCAL);
|
Cbuf_AddText(va("set option %i\n%s\n", 10, menualias.string), RESTRICT_LOCAL);
|
||||||
|
else
|
||||||
|
Cbuf_AddText(va("set option %i\n%s\n", key-'0', menualias.string), RESTRICT_LOCAL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -150,7 +152,10 @@ void M_MenuS_Picture_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MC_AddPicture(menu_script, x, y, picname);
|
if (!strcmp(Cmd_Argv(1), "-"))
|
||||||
|
MC_AddCenterPicture(menu_script, y, picname);
|
||||||
|
else
|
||||||
|
MC_AddPicture(menu_script, x, y, picname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void M_MenuS_Edit_f (void)
|
void M_MenuS_Edit_f (void)
|
||||||
|
|
|
@ -311,6 +311,7 @@ qboolean Media_ShowFilm(void);
|
||||||
void Media_CaptureDemoEnd(void);
|
void Media_CaptureDemoEnd(void);
|
||||||
void Media_RecordFrame (void);
|
void Media_RecordFrame (void);
|
||||||
qboolean Media_PausedDemo (void);
|
qboolean Media_PausedDemo (void);
|
||||||
|
double Media_TweekCaptureFrameTime(double time);
|
||||||
|
|
||||||
void R_SetRenderer(int wanted);
|
void R_SetRenderer(int wanted);
|
||||||
void RQ_Init(void);
|
void RQ_Init(void);
|
||||||
|
|
|
@ -1732,7 +1732,14 @@ void Sbar_Draw (void)
|
||||||
if (scr_viewsize.value != 120)
|
if (scr_viewsize.value != 120)
|
||||||
Cvar_Set(&scr_viewsize, "120");
|
Cvar_Set(&scr_viewsize, "120");
|
||||||
|
|
||||||
Sbar_DrawString (0, -8, va("%i", cl.stats[pnum][STAT_HEALTH]));
|
Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH]));
|
||||||
|
Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR]));
|
||||||
|
|
||||||
|
if (cl.stats[pnum][STAT_H2_BLUEMANA])
|
||||||
|
Sbar_DrawString (0, -24, va(" Blue: %i", cl.stats[pnum][STAT_H2_BLUEMANA]));
|
||||||
|
if (cl.stats[pnum][STAT_H2_GREENMANA])
|
||||||
|
Sbar_DrawString (0, -32, va(" Green: %i", cl.stats[pnum][STAT_H2_GREENMANA]));
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1640,10 +1640,24 @@ void Cmd_ForwardToServer_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Q_strcasecmp(Cmd_Argv(1), "snap") == 0) {
|
if (Q_strcasecmp(Cmd_Argv(1), "snap") == 0)
|
||||||
|
{
|
||||||
if (SCR_RSShot())
|
if (SCR_RSShot())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (Q_strcasecmp(Cmd_Argv(1), "ptrack") == 0)
|
||||||
|
{
|
||||||
|
if (!*Cmd_Argv(2))
|
||||||
|
{
|
||||||
|
Cam_Unlock(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Cam_Lock(0, atoi(Cmd_Argv(2)));
|
||||||
|
autocam[0] = CAM_TRACK;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cls.demoplayback)
|
if (cls.demoplayback)
|
||||||
return; // not really connected
|
return; // not really connected
|
||||||
|
|
|
@ -618,6 +618,7 @@ qboolean CM_CreateBrush ( q2cbrush_t *brush, vec3_t *verts, q2mapsurface_t *surf
|
||||||
static mplane_t mainplane, patchplanes[20];
|
static mplane_t mainplane, patchplanes[20];
|
||||||
qboolean skip[20];
|
qboolean skip[20];
|
||||||
int numpatchplanes = 0;
|
int numpatchplanes = 0;
|
||||||
|
float dot;
|
||||||
|
|
||||||
int matchplane;
|
int matchplane;
|
||||||
|
|
||||||
|
@ -709,10 +710,14 @@ qboolean CM_CreateBrush ( q2cbrush_t *brush, vec3_t *verts, q2mapsurface_t *surf
|
||||||
|
|
||||||
for (matchplane = 0; matchplane < numplanes; matchplane++)
|
for (matchplane = 0; matchplane < numplanes; matchplane++)
|
||||||
{
|
{
|
||||||
if (!memcmp(&map_planes[matchplane], &patchplanes[i], sizeof(patchplanes[i])))
|
if (map_planes[matchplane].dist+0.1 > patchplanes[i].dist && map_planes[matchplane].dist-0.1 < patchplanes[i].dist)
|
||||||
{
|
{
|
||||||
plane = &map_planes[matchplane];
|
dot = DotProduct(map_planes[matchplane].normal, patchplanes[i].normal);
|
||||||
break;
|
if (dot >= 0.98)
|
||||||
|
{
|
||||||
|
plane = &map_planes[matchplane];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (matchplane == numplanes)
|
if (matchplane == numplanes)
|
||||||
|
|
|
@ -400,6 +400,28 @@ char *COM_TrimString(char *str)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#if (_MSC_VER >= 1400)
|
||||||
|
//with MSVC 8, use MS extensions
|
||||||
|
#define snprintf linuxlike_snprintf_vc8
|
||||||
|
int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...);
|
||||||
|
#define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d)
|
||||||
|
#else
|
||||||
|
//msvc crap
|
||||||
|
#define snprintf linuxlike_snprintf
|
||||||
|
int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...);
|
||||||
|
#define vsnprintf linuxlike_vsnprintf
|
||||||
|
int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
//these are provided so we don't use them
|
||||||
|
//but mingw has some defines elsewhere and makes gcc moan
|
||||||
|
#define _vsnprintf unsafe_vsnprintf
|
||||||
|
#define _snprintf unsafe_snprintf
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
|
char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
|
||||||
{
|
{
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
|
@ -509,7 +531,7 @@ char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
|
||||||
if (!func)
|
if (!func)
|
||||||
{
|
{
|
||||||
assignment[-1] = '=';
|
assignment[-1] = '=';
|
||||||
sprintf(buf, "Can't find function %s\n", s);
|
snprintf(buf, sizeof(buf), "Can't find function %s\n", s);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
*(func_t *)val = (func - pr_progstate[i].functions) | (i<<24);
|
*(func_t *)val = (func - pr_progstate[i].functions) | (i<<24);
|
||||||
|
|
|
@ -384,8 +384,8 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable)
|
||||||
}
|
}
|
||||||
|
|
||||||
//oh well, must be a parameter.
|
//oh well, must be a parameter.
|
||||||
if (*(int *)&pr_globals[pr_globaldefs16[num].ofs])
|
// if (*(int *)&pr_globals[pr_globaldefs16[num].ofs])
|
||||||
Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
|
// Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs16[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs16[num].ofs]);
|
||||||
return;
|
return;
|
||||||
case 32:
|
case 32:
|
||||||
for (i=1 ; i<pr_progs->numfielddefs; i++)
|
for (i=1 ; i<pr_progs->numfielddefs; i++)
|
||||||
|
|
|
@ -1183,7 +1183,7 @@ void SV_MVDPings (void);
|
||||||
void SV_MVDWriteToDisk(int type, int to, float time);
|
void SV_MVDWriteToDisk(int type, int to, float time);
|
||||||
void MVDWrite_Begin(qbyte type, int to, int size);
|
void MVDWrite_Begin(qbyte type, int to, int size);
|
||||||
void MVDSetMsgBuf(demobuf_t *prev,demobuf_t *cur);
|
void MVDSetMsgBuf(demobuf_t *prev,demobuf_t *cur);
|
||||||
void SV_MVDStop (int reason);
|
void SV_MVDStop (int reason, qboolean mvdonly);
|
||||||
void SV_MVDStop_f (void);
|
void SV_MVDStop_f (void);
|
||||||
void SV_MVDWritePackets (int num);
|
void SV_MVDWritePackets (int num);
|
||||||
void MVD_Init (void);
|
void MVD_Init (void);
|
||||||
|
|
|
@ -1295,6 +1295,9 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SV_MVD_SendInitialGamestate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -112,7 +112,7 @@ void DestFlush(qboolean compleate)
|
||||||
|
|
||||||
if (!demo.dest)
|
if (!demo.dest)
|
||||||
{
|
{
|
||||||
SV_MVDStop(2);
|
SV_MVDStop(2, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,6 +497,7 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
if (p->hasauthed == true)
|
if (p->hasauthed == true)
|
||||||
{
|
{
|
||||||
e = ("QTVSV 1\n"
|
e = ("QTVSV 1\n"
|
||||||
|
"BEGIN\n"
|
||||||
"\n");
|
"\n");
|
||||||
send(p->socket, e, strlen(e), 0);
|
send(p->socket, e, strlen(e), 0);
|
||||||
e = NULL;
|
e = NULL;
|
||||||
|
@ -531,18 +532,29 @@ void SV_MVD_RunPendingConnections(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestCloseAllFlush(qboolean destroyfiles)
|
int DestCloseAllFlush(qboolean destroyfiles, qboolean mvdonly)
|
||||||
{
|
{
|
||||||
mvddest_t *d;
|
int numclosed = 0;
|
||||||
|
mvddest_t *d, **prev;
|
||||||
DestFlush(true); //make sure it's all written.
|
DestFlush(true); //make sure it's all written.
|
||||||
|
|
||||||
while (demo.dest)
|
prev = &demo.dest;
|
||||||
|
d = demo.dest;
|
||||||
|
while(d)
|
||||||
{
|
{
|
||||||
d = demo.dest;
|
if (!mvdonly || d->desttype != DEST_STREAM)
|
||||||
demo.dest = d->nextdest;
|
{
|
||||||
|
*prev = d->nextdest;
|
||||||
|
DestClose(d, destroyfiles);
|
||||||
|
numclosed++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prev = &d;
|
||||||
|
|
||||||
DestClose(d, destroyfiles);
|
d = (*prev)->nextdest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return numclosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1504,8 +1516,9 @@ SV_Stop
|
||||||
stop recording a demo
|
stop recording a demo
|
||||||
====================
|
====================
|
||||||
*/
|
*/
|
||||||
void SV_MVDStop (int reason)
|
void SV_MVDStop (int reason, qboolean mvdonly)
|
||||||
{
|
{
|
||||||
|
int numclosed;
|
||||||
if (!sv.mvdrecording)
|
if (!sv.mvdrecording)
|
||||||
{
|
{
|
||||||
Con_Printf ("Not recording a demo.\n");
|
Con_Printf ("Not recording a demo.\n");
|
||||||
|
@ -1514,7 +1527,7 @@ void SV_MVDStop (int reason)
|
||||||
|
|
||||||
if (reason == 2)
|
if (reason == 2)
|
||||||
{
|
{
|
||||||
DestCloseAllFlush(true);
|
DestCloseAllFlush(true, mvdonly);
|
||||||
// stop and remove
|
// stop and remove
|
||||||
|
|
||||||
if (!demo.dest)
|
if (!demo.dest)
|
||||||
|
@ -1539,14 +1552,17 @@ void SV_MVDStop (int reason)
|
||||||
SV_MVDWritePackets(demo.parsecount - demo.lastwritten + 1);
|
SV_MVDWritePackets(demo.parsecount - demo.lastwritten + 1);
|
||||||
// finish up
|
// finish up
|
||||||
|
|
||||||
DestCloseAllFlush(false);
|
numclosed = DestCloseAllFlush(false, mvdonly);
|
||||||
|
|
||||||
|
if (!demo.dest)
|
||||||
sv.mvdrecording = false;
|
sv.mvdrecording = false;
|
||||||
if (!reason)
|
if (numclosed)
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server recording completed\n");
|
{
|
||||||
else
|
if (!reason)
|
||||||
SV_BroadcastPrintf (PRINT_CHAT, "Server recording stoped\nMax demo size exceeded\n");
|
SV_BroadcastPrintf (PRINT_CHAT, "Server recording completed\n");
|
||||||
|
else
|
||||||
|
SV_BroadcastPrintf (PRINT_CHAT, "Server recording stoped\nMax demo size exceeded\n");
|
||||||
|
}
|
||||||
|
|
||||||
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), "");
|
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), "");
|
||||||
}
|
}
|
||||||
|
@ -1558,7 +1574,7 @@ SV_Stop_f
|
||||||
*/
|
*/
|
||||||
void SV_MVDStop_f (void)
|
void SV_MVDStop_f (void)
|
||||||
{
|
{
|
||||||
SV_MVDStop(0);
|
SV_MVDStop(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1570,7 +1586,7 @@ Stops recording, and removes the demo
|
||||||
*/
|
*/
|
||||||
void SV_MVD_Cancel_f (void)
|
void SV_MVD_Cancel_f (void)
|
||||||
{
|
{
|
||||||
SV_MVDStop(2);
|
SV_MVDStop(2, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1631,9 +1647,10 @@ void SV_WriteSetMVDMessage (void)
|
||||||
DestFlush(false);
|
DestFlush(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SV_MVD_SendInitialGamestate(mvddest_t *dest);
|
||||||
static qboolean SV_MVD_Record (mvddest_t *dest)
|
static qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
{
|
{
|
||||||
sizebuf_t buf;
|
/* sizebuf_t buf;
|
||||||
char buf_data[MAX_QWMSGLEN];
|
char buf_data[MAX_QWMSGLEN];
|
||||||
int n, i;
|
int n, i;
|
||||||
char *s, info[MAX_INFO_STRING];
|
char *s, info[MAX_INFO_STRING];
|
||||||
|
@ -1641,6 +1658,8 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
client_t *player;
|
client_t *player;
|
||||||
char *gamedir;
|
char *gamedir;
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
|
*/
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!dest)
|
if (!dest)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1663,16 +1682,36 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
|
|
||||||
demo.datagram.maxsize = sizeof(demo.datagram_data);
|
demo.datagram.maxsize = sizeof(demo.datagram_data);
|
||||||
demo.datagram.data = demo.datagram_data;
|
demo.datagram.data = demo.datagram_data;
|
||||||
|
|
||||||
sv.mvdrecording = true;
|
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
||||||
demo.pingtime = demo.time = sv.time;
|
|
||||||
|
|
||||||
dest->nextdest = demo.dest;
|
dest->nextdest = demo.dest;
|
||||||
demo.dest = dest;
|
demo.dest = dest;
|
||||||
|
|
||||||
|
SV_MVD_SendInitialGamestate(dest);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
|
{
|
||||||
|
sizebuf_t buf;
|
||||||
|
char buf_data[MAX_QWMSGLEN];
|
||||||
|
int n, i;
|
||||||
|
char *s, info[MAX_INFO_STRING];
|
||||||
|
|
||||||
|
client_t *player;
|
||||||
|
char *gamedir;
|
||||||
|
int seq = 1;
|
||||||
|
|
||||||
|
if (!demo.dest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sv.mvdrecording = true;
|
||||||
|
|
||||||
|
|
||||||
|
demo.pingtime = demo.time = sv.time;
|
||||||
|
|
||||||
|
|
||||||
singledest = dest;
|
singledest = dest;
|
||||||
|
|
||||||
/*-------------------------------------------------*/
|
/*-------------------------------------------------*/
|
||||||
|
@ -1937,9 +1976,6 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
SV_WriteSetMVDMessage();
|
SV_WriteSetMVDMessage();
|
||||||
|
|
||||||
singledest = NULL;
|
singledest = NULL;
|
||||||
|
|
||||||
// done
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -273,7 +273,7 @@ void Net_SendConnectionMVD(sv_t *qtv, oproxy_t *prox)
|
||||||
|
|
||||||
prox->flushing = false;
|
prox->flushing = false;
|
||||||
|
|
||||||
BuildServerData(qtv, &msg, true, 0, true);
|
BuildServerData(qtv, &msg, 0, NULL);
|
||||||
Prox_SendMessage(qtv->cluster, prox, msg.data, msg.cursize, dem_read, (unsigned)-1);
|
Prox_SendMessage(qtv->cluster, prox, msg.data, msg.cursize, dem_read, (unsigned)-1);
|
||||||
msg.cursize = 0;
|
msg.cursize = 0;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, char *data, netadr_t adr)
|
void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, char *data, netadr_t adr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
Sys_Printf(cluster, "udp send size %i\n", length);
|
||||||
|
if (length > 1000)
|
||||||
|
Sys_Printf(cluster, "udp send size %i\n", length);
|
||||||
|
|
||||||
ret = sendto(sock, data, length, 0, (struct sockaddr *)adr, sizeof(struct sockaddr_in));
|
ret = sendto(sock, data, length, 0, (struct sockaddr *)adr, sizeof(struct sockaddr_in));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -649,10 +649,19 @@ static void ParsePlayerInfo(sv_t *tv, netmsg_t *m, qboolean clearoldplayers)
|
||||||
tv->players[num].current.angles[2] = nonnullcmd.angles[2];
|
tv->players[num].current.angles[2] = nonnullcmd.angles[2];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ //the only reason we'd not get a command is if it's us.
|
||||||
tv->players[num].current.angles[0] = tv->proxyplayerangles[0]/360*65535;
|
if (tv->controller)
|
||||||
tv->players[num].current.angles[1] = tv->proxyplayerangles[1]/360*65535;
|
{
|
||||||
tv->players[num].current.angles[2] = tv->proxyplayerangles[2]/360*65535;
|
tv->players[num].current.angles[0] = tv->controller->ucmds[2].angles[0];
|
||||||
|
tv->players[num].current.angles[1] = tv->controller->ucmds[2].angles[1];
|
||||||
|
tv->players[num].current.angles[2] = tv->controller->ucmds[2].angles[2];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tv->players[num].current.angles[0] = tv->proxyplayerangles[0]/360*65535;
|
||||||
|
tv->players[num].current.angles[1] = tv->proxyplayerangles[1]/360*65535;
|
||||||
|
tv->players[num].current.angles[2] = tv->proxyplayerangles[2]/360*65535;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
|
|
|
@ -412,10 +412,12 @@ typedef struct viewer_s {
|
||||||
unsigned int currentstats[MAX_STATS];
|
unsigned int currentstats[MAX_STATS];
|
||||||
int trackplayer;
|
int trackplayer;
|
||||||
int thisplayer;
|
int thisplayer;
|
||||||
|
int userid;
|
||||||
|
|
||||||
packet_entities_t frame[ENTITY_FRAMES];
|
packet_entities_t frame[ENTITY_FRAMES];
|
||||||
|
|
||||||
struct viewer_s *next;
|
struct viewer_s *next;
|
||||||
|
struct viewer_s *commentator;
|
||||||
|
|
||||||
char name[32];
|
char name[32];
|
||||||
char userinfo[1024];
|
char userinfo[1024];
|
||||||
|
@ -615,6 +617,7 @@ struct cluster_s {
|
||||||
sv_t *servers;
|
sv_t *servers;
|
||||||
int numservers;
|
int numservers;
|
||||||
int nextstreamid;
|
int nextstreamid;
|
||||||
|
int nextuserid;
|
||||||
|
|
||||||
//options
|
//options
|
||||||
int qwlistenportnum;
|
int qwlistenportnum;
|
||||||
|
@ -835,7 +838,7 @@ void WriteData(netmsg_t *b, const char *data, int length);
|
||||||
void Multicast(sv_t *tv, char *buffer, int length, int to, unsigned int playermask,int suitablefor);
|
void Multicast(sv_t *tv, char *buffer, int length, int to, unsigned int playermask,int suitablefor);
|
||||||
void Broadcast(cluster_t *cluster, char *buffer, int length, int suitablefor);
|
void Broadcast(cluster_t *cluster, char *buffer, int length, int suitablefor);
|
||||||
void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask);
|
void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask);
|
||||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qboolean spectatorflag);
|
void BuildServerData(sv_t *tv, netmsg_t *msg, int servercount, viewer_t *spectatorflag);
|
||||||
void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount);
|
void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount);
|
||||||
SOCKET QW_InitUDPSocket(int port);
|
SOCKET QW_InitUDPSocket(int port);
|
||||||
void QW_UpdateUDPStuff(cluster_t *qtv);
|
void QW_UpdateUDPStuff(cluster_t *qtv);
|
||||||
|
|
|
@ -477,6 +477,10 @@ SOURCE=.\parse.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\pmove.c
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\qw.c
|
SOURCE=.\qw.c
|
||||||
|
|
||||||
!IF "$(CFG)" == "qtvprox - Win32 Release"
|
!IF "$(CFG)" == "qtvprox - Win32 Release"
|
||||||
|
|
184
fteqtv/qw.c
184
fteqtv/qw.c
|
@ -205,7 +205,7 @@ SOCKET QW_InitUDPSocket(int port)
|
||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qboolean spectatorflag)
|
void BuildServerData(sv_t *tv, netmsg_t *msg, int servercount, viewer_t *viewer)
|
||||||
{
|
{
|
||||||
movevars_t movevars;
|
movevars_t movevars;
|
||||||
WriteByte(msg, svc_serverdata);
|
WriteByte(msg, svc_serverdata);
|
||||||
|
@ -217,10 +217,10 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qbo
|
||||||
//dummy connection, for choosing a game to watch.
|
//dummy connection, for choosing a game to watch.
|
||||||
WriteString(msg, "qw");
|
WriteString(msg, "qw");
|
||||||
|
|
||||||
if (mvd)
|
if (!viewer)
|
||||||
WriteFloat(msg, 0);
|
WriteFloat(msg, 0);
|
||||||
else
|
else
|
||||||
WriteByte(msg, (MAX_CLIENTS-1) | (spectatorflag?128:0));
|
WriteByte(msg, (MAX_CLIENTS-1) | (128));
|
||||||
WriteString(msg, "FTEQTV Proxy");
|
WriteString(msg, "FTEQTV Proxy");
|
||||||
|
|
||||||
|
|
||||||
|
@ -249,10 +249,15 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount, qbo
|
||||||
{
|
{
|
||||||
WriteString(msg, tv->gamedir);
|
WriteString(msg, tv->gamedir);
|
||||||
|
|
||||||
if (mvd)
|
if (!viewer)
|
||||||
WriteFloat(msg, 0);
|
WriteFloat(msg, 0);
|
||||||
else
|
else
|
||||||
WriteByte(msg, tv->thisplayer | (spectatorflag?128:0));
|
{
|
||||||
|
if (tv->controller == viewer)
|
||||||
|
WriteByte(msg, viewer->thisplayer);
|
||||||
|
else
|
||||||
|
WriteByte(msg, viewer->thisplayer | 128);
|
||||||
|
}
|
||||||
WriteString(msg, tv->mapname);
|
WriteString(msg, tv->mapname);
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,7 +369,7 @@ void SendServerData(sv_t *tv, viewer_t *viewer)
|
||||||
if (viewer->netchan.isnqprotocol)
|
if (viewer->netchan.isnqprotocol)
|
||||||
BuildNQServerData(tv, &msg, false, viewer->thisplayer);
|
BuildNQServerData(tv, &msg, false, viewer->thisplayer);
|
||||||
else
|
else
|
||||||
BuildServerData(tv, &msg, false, viewer->servercount, !tv || tv->controller != viewer);
|
BuildServerData(tv, &msg, viewer->servercount, viewer);
|
||||||
|
|
||||||
SendBufferToViewer(viewer, msg.data, msg.cursize, true);
|
SendBufferToViewer(viewer, msg.data, msg.cursize, true);
|
||||||
|
|
||||||
|
@ -646,6 +651,7 @@ qboolean ChallengePasses(netadr_t *addr, int challenge)
|
||||||
|
|
||||||
void NewClient(cluster_t *cluster, viewer_t *viewer)
|
void NewClient(cluster_t *cluster, viewer_t *viewer)
|
||||||
{
|
{
|
||||||
|
viewer->userid = ++cluster->nextuserid;
|
||||||
viewer->timeout = cluster->curtime + 15*1000;
|
viewer->timeout = cluster->curtime + 15*1000;
|
||||||
viewer->trackplayer = -1;
|
viewer->trackplayer = -1;
|
||||||
|
|
||||||
|
@ -689,7 +695,7 @@ void ParseUserInfo(cluster_t *cluster, viewer_t *viewer)
|
||||||
strcpy(temp, "unnamed");
|
strcpy(temp, "unnamed");
|
||||||
if (!*viewer->name)
|
if (!*viewer->name)
|
||||||
Sys_Printf(cluster, "Viewer %s connected\n", temp);
|
Sys_Printf(cluster, "Viewer %s connected\n", temp);
|
||||||
Q_strncpyz(viewer->name, temp, sizeof(temp));
|
Q_strncpyz(viewer->name, temp, sizeof(viewer->name));
|
||||||
|
|
||||||
Info_ValueForKey(viewer->userinfo, "rate", temp, sizeof(temp));
|
Info_ValueForKey(viewer->userinfo, "rate", temp, sizeof(temp));
|
||||||
rate = atof(temp);
|
rate = atof(temp);
|
||||||
|
@ -815,6 +821,7 @@ void NewQWClient(cluster_t *cluster, netadr_t *addr, char *connectmessage)
|
||||||
memset(viewer, 0, sizeof(viewer_t));
|
memset(viewer, 0, sizeof(viewer_t));
|
||||||
|
|
||||||
Netchan_Setup (cluster->qwdsocket, &viewer->netchan, *addr, atoi(qport), false);
|
Netchan_Setup (cluster->qwdsocket, &viewer->netchan, *addr, atoi(qport), false);
|
||||||
|
viewer->netchan.message.maxsize = 1400;
|
||||||
|
|
||||||
viewer->next = cluster->viewers;
|
viewer->next = cluster->viewers;
|
||||||
cluster->viewers = viewer;
|
cluster->viewers = viewer;
|
||||||
|
@ -1717,12 +1724,15 @@ void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg
|
||||||
|
|
||||||
void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||||
{
|
{
|
||||||
|
viewer_t *cv;
|
||||||
packet_entities_t *e;
|
packet_entities_t *e;
|
||||||
int i;
|
int i;
|
||||||
usercmd_t to;
|
usercmd_t to;
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
short interp;
|
short interp;
|
||||||
float lerp;
|
float lerp;
|
||||||
|
int track;
|
||||||
|
int runaway = 10;
|
||||||
|
|
||||||
|
|
||||||
memset(&to, 0, sizeof(to));
|
memset(&to, 0, sizeof(to));
|
||||||
|
@ -1749,6 +1759,21 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||||
if (tv->controller == v)
|
if (tv->controller == v)
|
||||||
lerp = 1;
|
lerp = 1;
|
||||||
|
|
||||||
|
track = v->trackplayer;
|
||||||
|
for (cv = v; cv && runaway-->0; cv = cv->commentator)
|
||||||
|
{
|
||||||
|
track = cv->trackplayer;
|
||||||
|
if (track != MAX_CLIENTS-2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (v->commentator && track == MAX_CLIENTS-2)
|
||||||
|
{
|
||||||
|
track = v->commentator->trackplayer;
|
||||||
|
if (track < 0)
|
||||||
|
track = MAX_CLIENTS-2;
|
||||||
|
}*/
|
||||||
|
|
||||||
for (i = 0; i < MAX_CLIENTS; i++)
|
for (i = 0; i < MAX_CLIENTS; i++)
|
||||||
{
|
{
|
||||||
if (i == v->thisplayer)
|
if (i == v->thisplayer)
|
||||||
|
@ -1756,14 +1781,56 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||||
SendLocalPlayerState(tv, v, i, msg);
|
SendLocalPlayerState(tv, v, i, msg);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v->commentator)// && track == i)
|
||||||
|
{
|
||||||
|
if (i == MAX_CLIENTS-2)
|
||||||
|
{
|
||||||
|
flags = PF_COMMAND;
|
||||||
|
WriteByte(msg, svc_playerinfo);
|
||||||
|
WriteByte(msg, i);
|
||||||
|
WriteShort(msg, flags);
|
||||||
|
|
||||||
|
|
||||||
|
interp = v->commentator->origin[0]*8;
|
||||||
|
WriteShort(msg, interp);
|
||||||
|
interp = v->commentator->origin[1]*8;
|
||||||
|
WriteShort(msg, interp);
|
||||||
|
interp = v->commentator->origin[2]*8;
|
||||||
|
WriteShort(msg, interp);
|
||||||
|
|
||||||
|
WriteByte(msg, 0);
|
||||||
|
|
||||||
|
if (flags & PF_MSEC)
|
||||||
|
{
|
||||||
|
WriteByte(msg, 0);
|
||||||
|
}
|
||||||
|
if (flags & PF_COMMAND)
|
||||||
|
{
|
||||||
|
to.angles[0] = v->commentator->ucmds[2].angles[0];
|
||||||
|
to.angles[1] = v->commentator->ucmds[2].angles[1];
|
||||||
|
to.angles[2] = v->commentator->ucmds[2].angles[2];
|
||||||
|
WriteDeltaUsercmd(msg, &nullcmd, &to);
|
||||||
|
}
|
||||||
|
if (flags & PF_MODEL)
|
||||||
|
WriteByte(msg, tv->players[i].current.modelindex);
|
||||||
|
if (flags & PF_WEAPONFRAME)
|
||||||
|
WriteByte(msg, tv->players[i].current.weaponframe);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (track == i)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!tv->players[i].active)
|
if (!tv->players[i].active)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (v->trackplayer != i && !BSP_Visible(tv->bsp, tv->players[i].leafcount, tv->players[i].leafs))
|
//bsp cull. currently tracked player is always visible
|
||||||
|
if (track != i && !BSP_Visible(tv->bsp, tv->players[i].leafcount, tv->players[i].leafs))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
flags = PF_COMMAND;
|
flags = PF_COMMAND;
|
||||||
if (v->trackplayer == i && tv->players[i].current.weaponframe)
|
if (track == i && tv->players[i].current.weaponframe)
|
||||||
flags |= PF_WEAPONFRAME;
|
flags |= PF_WEAPONFRAME;
|
||||||
|
|
||||||
WriteByte(msg, svc_playerinfo);
|
WriteByte(msg, svc_playerinfo);
|
||||||
|
@ -1860,6 +1927,7 @@ void SendPlayerStates(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||||
|
|
||||||
void UpdateStats(sv_t *qtv, viewer_t *v)
|
void UpdateStats(sv_t *qtv, viewer_t *v)
|
||||||
{
|
{
|
||||||
|
viewer_t *cv;
|
||||||
netmsg_t msg;
|
netmsg_t msg;
|
||||||
char buf[6];
|
char buf[6];
|
||||||
int i;
|
int i;
|
||||||
|
@ -1869,12 +1937,17 @@ void UpdateStats(sv_t *qtv, viewer_t *v)
|
||||||
|
|
||||||
InitNetMsg(&msg, buf, sizeof(buf));
|
InitNetMsg(&msg, buf, sizeof(buf));
|
||||||
|
|
||||||
if (qtv && qtv->controller == v)
|
if (v->commentator)
|
||||||
|
cv = v->commentator;
|
||||||
|
else
|
||||||
|
cv = v;
|
||||||
|
|
||||||
|
if (qtv && qtv->controller == cv)
|
||||||
stats = qtv->players[qtv->thisplayer].stats;
|
stats = qtv->players[qtv->thisplayer].stats;
|
||||||
else if (v->trackplayer == -1 || !qtv)
|
else if (cv->trackplayer == -1 || !qtv)
|
||||||
stats = nullstats;
|
stats = nullstats;
|
||||||
else
|
else
|
||||||
stats = qtv->players[v->trackplayer].stats;
|
stats = qtv->players[cv->trackplayer].stats;
|
||||||
|
|
||||||
for (i = 0; i < MAX_STATS; i++)
|
for (i = 0; i < MAX_STATS; i++)
|
||||||
{
|
{
|
||||||
|
@ -1986,6 +2059,32 @@ void PMove(viewer_t *v, usercmd_t *cmd)
|
||||||
v->velocity[2] = pmove.velocity[2];
|
v->velocity[2] = pmove.velocity[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QW_SetCommentator(viewer_t *v, viewer_t *commentator)
|
||||||
|
{
|
||||||
|
// if (v->commentator == commentator)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
WriteByte(&v->netchan.message, svc_setinfo);
|
||||||
|
WriteByte(&v->netchan.message, MAX_CLIENTS-2);
|
||||||
|
WriteString(&v->netchan.message, "name");
|
||||||
|
if (commentator)
|
||||||
|
{
|
||||||
|
WriteString(&v->netchan.message, commentator->name);
|
||||||
|
QW_StuffcmdToViewer(v, "cmd ptrack %i\n", MAX_CLIENTS-2);
|
||||||
|
QW_PrintfToViewer(v, "Following commentator %s\n", commentator->name);
|
||||||
|
|
||||||
|
if (v->server != commentator->server)
|
||||||
|
QW_SetViewersServer(v, commentator->server);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WriteString(&v->netchan.message, "");
|
||||||
|
if (v->commentator )
|
||||||
|
QW_PrintfToViewer(v, "Commentator disabled\n");
|
||||||
|
}
|
||||||
|
v->commentator = commentator;
|
||||||
|
}
|
||||||
|
|
||||||
void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean noupwards)
|
void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean noupwards)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
@ -2378,6 +2477,42 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
if (remaining)
|
if (remaining)
|
||||||
QW_PrintfToViewer(v, "%i clients not shown\n", remaining);
|
QW_PrintfToViewer(v, "%i clients not shown\n", remaining);
|
||||||
}
|
}
|
||||||
|
else if (!strncmp(message, ".followid ", 8))
|
||||||
|
{
|
||||||
|
int id = atoi(message+8);
|
||||||
|
viewer_t *cv;
|
||||||
|
|
||||||
|
for (cv = cluster->viewers; cv; cv = cv->next)
|
||||||
|
{
|
||||||
|
if (cv->userid == id)
|
||||||
|
{
|
||||||
|
QW_SetCommentator(v, cv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QW_PrintfToViewer(v, "Couldn't find that player\n");
|
||||||
|
QW_SetCommentator(v, NULL);
|
||||||
|
}
|
||||||
|
else if (!strncmp(message, ".follow ", 8))
|
||||||
|
{
|
||||||
|
char *id = message+8;
|
||||||
|
viewer_t *cv;
|
||||||
|
|
||||||
|
for (cv = cluster->viewers; cv; cv = cv->next)
|
||||||
|
{
|
||||||
|
if (!strcmp(cv->name, id))
|
||||||
|
{
|
||||||
|
QW_SetCommentator(v, cv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QW_PrintfToViewer(v, "Couldn't find that player\n");
|
||||||
|
QW_SetCommentator(v, NULL);
|
||||||
|
}
|
||||||
|
else if (!strncmp(message, ".follow", 7))
|
||||||
|
{
|
||||||
|
QW_SetCommentator(v, NULL);
|
||||||
|
}
|
||||||
else if (!strncmp(message, "proxy:menu up", 13))
|
else if (!strncmp(message, "proxy:menu up", 13))
|
||||||
{
|
{
|
||||||
v->menuop -= 1;
|
v->menuop -= 1;
|
||||||
|
@ -2426,6 +2561,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
QW_StuffcmdToViewer(v, "bind downarrow +proxback\n");
|
QW_StuffcmdToViewer(v, "bind downarrow +proxback\n");
|
||||||
QW_StuffcmdToViewer(v, "bind rightarrow +proxright\n");
|
QW_StuffcmdToViewer(v, "bind rightarrow +proxright\n");
|
||||||
QW_StuffcmdToViewer(v, "bind leftarrow +proxleft\n");
|
QW_StuffcmdToViewer(v, "bind leftarrow +proxleft\n");
|
||||||
|
QW_PrintfToViewer(v, "Keys bound not recognised\n");
|
||||||
}
|
}
|
||||||
else if (!strncmp(message, ".menu bind", 10) || !strncmp(message, "proxy:menu bindstd", 18))
|
else if (!strncmp(message, ".menu bind", 10) || !strncmp(message, "proxy:menu bindstd", 18))
|
||||||
{
|
{
|
||||||
|
@ -2440,6 +2576,8 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
||||||
QW_StuffcmdToViewer(v, "bind end \"proxy:menu end\"\n");
|
QW_StuffcmdToViewer(v, "bind end \"proxy:menu end\"\n");
|
||||||
QW_StuffcmdToViewer(v, "bind pause \"proxy:menu\"\n");
|
QW_StuffcmdToViewer(v, "bind pause \"proxy:menu\"\n");
|
||||||
QW_StuffcmdToViewer(v, "bind backspace \"proxy:menu back\"\n");
|
QW_StuffcmdToViewer(v, "bind backspace \"proxy:menu back\"\n");
|
||||||
|
|
||||||
|
QW_PrintfToViewer(v, "All keys bound not recognised\n");
|
||||||
}
|
}
|
||||||
else if (!strncmp(message, ".", 1) && strncmp(message, "..", 2))
|
else if (!strncmp(message, ".", 1) && strncmp(message, "..", 2))
|
||||||
{
|
{
|
||||||
|
@ -2860,6 +2998,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
}
|
}
|
||||||
else if (!strncmp(buf, "begin", 5))
|
else if (!strncmp(buf, "begin", 5))
|
||||||
{
|
{
|
||||||
|
viewer_t *com;
|
||||||
if (atoi(buf+6) != v->servercount)
|
if (atoi(buf+6) != v->servercount)
|
||||||
SendServerData(qtv, v); //this is unfortunate!
|
SendServerData(qtv, v); //this is unfortunate!
|
||||||
else
|
else
|
||||||
|
@ -2871,6 +3010,10 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
SendBufferToViewer(v, msgb, sizeof(msgb), true);
|
SendBufferToViewer(v, msgb, sizeof(msgb), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
com = v->commentator;
|
||||||
|
v->commentator = NULL;
|
||||||
|
QW_SetCommentator(v, com);
|
||||||
}
|
}
|
||||||
else if (!strncmp(buf, "download", 8))
|
else if (!strncmp(buf, "download", 8))
|
||||||
{
|
{
|
||||||
|
@ -2901,9 +3044,16 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
QW_PrintfToViewer(v, "%s is not on the proxy, sorry\n", buf+5); //the apology is to make the alternatives distinct.
|
QW_PrintfToViewer(v, "%s is not on the proxy, sorry\n", buf+5); //the apology is to make the alternatives distinct.
|
||||||
}
|
}
|
||||||
else if (!strncmp(buf, "ptrack ", 7))
|
else if (!strncmp(buf, "ptrack ", 7))
|
||||||
|
{
|
||||||
v->trackplayer = atoi(buf+7);
|
v->trackplayer = atoi(buf+7);
|
||||||
|
// if (v->trackplayer != MAX_CLIENTS-2)
|
||||||
|
// QW_SetCommentator(v, NULL);
|
||||||
|
}
|
||||||
else if (!strncmp(buf, "ptrack", 6))
|
else if (!strncmp(buf, "ptrack", 6))
|
||||||
|
{
|
||||||
v->trackplayer = -1;
|
v->trackplayer = -1;
|
||||||
|
QW_SetCommentator(v, NULL);
|
||||||
|
}
|
||||||
else if (!strncmp(buf, "pings", 5))
|
else if (!strncmp(buf, "pings", 5))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -3364,6 +3514,7 @@ static const char dropcmd[] = {svc_stufftext, 'd', 'i', 's', 'c', 'o', 'n', 'n',
|
||||||
|
|
||||||
void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
|
void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
|
||||||
{
|
{
|
||||||
|
viewer_t *oview;
|
||||||
int i;
|
int i;
|
||||||
//note: unlink them yourself.
|
//note: unlink them yourself.
|
||||||
|
|
||||||
|
@ -3388,6 +3539,12 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
|
||||||
viewer->server->numviewers--;
|
viewer->server->numviewers--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (oview = cluster->viewers; oview; oview = oview->next)
|
||||||
|
{
|
||||||
|
if (oview->commentator == viewer)
|
||||||
|
QW_SetCommentator(oview, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
free(viewer);
|
free(viewer);
|
||||||
|
|
||||||
cluster->numviewers--;
|
cluster->numviewers--;
|
||||||
|
@ -3436,6 +3593,9 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (rand()&3)
|
||||||
|
// continue;
|
||||||
|
|
||||||
m.data = buffer;
|
m.data = buffer;
|
||||||
m.cursize = read;
|
m.cursize = read;
|
||||||
m.maxsize = MAX_MSGLEN;
|
m.maxsize = MAX_MSGLEN;
|
||||||
|
|
|
@ -518,10 +518,17 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
|
||||||
catbuffer(buffer, sizeofbuffer, "Connected\n");
|
catbuffer(buffer, sizeofbuffer, "Connected\n");
|
||||||
if (qtv->parsingqtvheader || qtv->parsingconnectiondata)
|
if (qtv->parsingqtvheader || qtv->parsingconnectiondata)
|
||||||
catbuffer(buffer, sizeofbuffer, "Waiting for gamestate\n");
|
catbuffer(buffer, sizeofbuffer, "Waiting for gamestate\n");
|
||||||
if (qtv->controller)
|
if (qtv->usequkeworldprotocols)
|
||||||
{
|
{
|
||||||
catbuffer(buffer, sizeofbuffer, "Spectating through %s\n");
|
catbuffer(buffer, sizeofbuffer, "QuakeWorld protocols\n");
|
||||||
|
if (qtv->controller)
|
||||||
|
{
|
||||||
|
catbuffer(buffer, sizeofbuffer, "Controlled by %s\n", qtv->controller->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (qtv->sourcesock == INVALID_SOCKET && !qtv->sourcefile)
|
||||||
|
catbuffer(buffer, sizeofbuffer, "Connection not established\n");
|
||||||
|
|
||||||
if (*qtv->modellist[1].name)
|
if (*qtv->modellist[1].name)
|
||||||
{
|
{
|
||||||
catbuffer(buffer, sizeofbuffer, "Map name %s\n", qtv->modellist[1].name);
|
catbuffer(buffer, sizeofbuffer, "Map name %s\n", qtv->modellist[1].name);
|
||||||
|
|
|
@ -490,7 +490,7 @@ qboolean Net_WriteUpStream(sv_t *qtv)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (qtv->upstreambuffersize)
|
if (qtv->upstreambuffersize && qtv->sourcesock != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
len = send(qtv->sourcesock, qtv->upstreambuffer, qtv->upstreambuffersize, 0);
|
len = send(qtv->sourcesock, qtv->upstreambuffer, qtv->upstreambuffersize, 0);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
|
@ -589,6 +589,7 @@ qboolean Net_ReadStream(sv_t *qtv)
|
||||||
Sys_Printf(qtv->cluster, "Error: server %s refused connection\n", qtv->server);
|
Sys_Printf(qtv->cluster, "Error: server %s refused connection\n", qtv->server);
|
||||||
closesocket(qtv->sourcesock);
|
closesocket(qtv->sourcesock);
|
||||||
qtv->sourcesock = INVALID_SOCKET;
|
qtv->sourcesock = INVALID_SOCKET;
|
||||||
|
qtv->upstreambuffersize = 0; //probably contains initial connection request info
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,7 +1050,7 @@ void QTV_ParseQWStream(sv_t *qtv)
|
||||||
strcpy(qtv->status, "Attemping connection\n");
|
strcpy(qtv->status, "Attemping connection\n");
|
||||||
qtv->challenge = atoi(buffer+5);
|
qtv->challenge = atoi(buffer+5);
|
||||||
if (qtv->controller)
|
if (qtv->controller)
|
||||||
sprintf(buffer, "connect %i %i %i \"%s\\*qtv\\1\\\"", 28, qtv->qport, qtv->challenge, qtv->controller->userinfo);
|
sprintf(buffer, "connect %i %i %i \"%s\\*qtv\\1\"", 28, qtv->qport, qtv->challenge, qtv->controller->userinfo);
|
||||||
else if (qtv->proxyplayer)
|
else if (qtv->proxyplayer)
|
||||||
sprintf(buffer, "connect %i %i %i \"%s\\name\\%s\"", 28, qtv->qport, qtv->challenge, "\\*ver\\fteqtv\\spectator\\0\\rate\\10000", qtv->cluster->hostname);
|
sprintf(buffer, "connect %i %i %i \"%s\\name\\%s\"", 28, qtv->qport, qtv->challenge, "\\*ver\\fteqtv\\spectator\\0\\rate\\10000", qtv->cluster->hostname);
|
||||||
else
|
else
|
||||||
|
@ -1661,6 +1662,8 @@ void QTV_Run(sv_t *qtv)
|
||||||
Net_ReadStream(qtv);
|
Net_ReadStream(qtv);
|
||||||
|
|
||||||
qtv->parsetime += packettime;
|
qtv->parsetime += packettime;
|
||||||
|
|
||||||
|
qtv->nextconnectattempt = qtv->curtime + RECONNECT_TIME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue