playqtv now plays from an fteqtv proxy (with the 10 secs buffering).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2113 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-03-14 01:25:46 +00:00
parent 4080f29040
commit bfa9db357b
4 changed files with 273 additions and 23 deletions

View file

@ -147,27 +147,32 @@ void CL_WriteDemoMessage (sizebuf_t *msg)
VFS_FLUSH (cls.demofile);
}
int unreaddata;
int unreadbytes;
unsigned char unreaddata[16];
int unreadcount;
int readdemobytes(void *data, int len)
{
int i;
if (unreadbytes)
{
if (len != unreadbytes)
Sys_Error("Demo playback unread the wrong number of bytes\n");
memcpy(data, &unreaddata, len);
// if (rand()&63 == 63)
// return 0;
unreadbytes=0;
if (unreadcount)
{
if (len > unreadcount)
Sys_Error("Demo playback unread the wrong number of bytes\n");
unreadcount -= len;
memcpy(data, unreaddata+unreadcount, len);
return len;
}
i = VFS_READ(cls.demofile, data, len);
memcpy(&unreaddata, data, 4);
return i;
}
void unreadbytes(int count, void *data)
{
memcpy(unreaddata+unreadcount, data, count);
unreadcount += count;
}
void CL_ProgressDemoTime(void)
@ -336,12 +341,15 @@ readnext:
// read the time from the packet
if (cls.demoplayback == DPB_MVD)
{
if (realtime < 0)
return 0;
if (olddemotime > realtime)
olddemotime = realtime;
if (realtime + 1.0 < olddemotime)
realtime = olddemotime - 1.0;
readdemobytes(&msecsadded, sizeof(msecsadded));
if (readdemobytes(&msecsadded, sizeof(msecsadded)) == 0)
return 0;
demotime = olddemotime + msecsadded*(1.0f/1000);
nextdemotime = demotime;
}
@ -361,9 +369,9 @@ readnext:
cls.td_lastframe = demotime;
// rewind back to time
if (cls.demoplayback == DPB_MVD)
unreadbytes = sizeof(msecsadded);
unreadbytes(sizeof(msecsadded), &msecsadded);
else
unreadbytes = sizeof(demotime);
unreadbytes(sizeof(demotime), &demotime);
return 0; // already read this frame's message
}
if (!cls.td_starttime && cls.state == ca_active)
@ -381,18 +389,18 @@ readnext:
realtime = demotime - 1.0;
// rewind back to time
if (cls.demoplayback == DPB_MVD)
unreadbytes = sizeof(msecsadded);
unreadbytes(sizeof(msecsadded), &msecsadded);
else
unreadbytes = sizeof(demotime);
unreadbytes(sizeof(demotime), &demotime);
return 0;
}
else if (realtime < demotime)
{
// rewind back to time
if (cls.demoplayback == DPB_MVD)
unreadbytes = sizeof(msecsadded);
unreadbytes(sizeof(msecsadded), &msecsadded);
else
unreadbytes = sizeof(demotime);
unreadbytes(sizeof(demotime), &demotime);
return 0; // don't need another message yet
}
}
@ -416,7 +424,25 @@ readnext:
Host_Error ("CL_GetDemoMessage: cls.state != ca_active");
// get the msg type
VFS_READ (cls.demofile, &c, sizeof(c));
if (!readdemobytes (&c, sizeof(c)))
{
if (1)//!VFS_GETLEN(cls.demofile))
{
if (cls.demoplayback == DPB_MVD)
{
r = 0;
unreadbytes(1, &r);
}
else
{
demotime = LittleFloat(demotime);
unreadbytes(4, &demotime);
}
}
else
CL_StopPlayback ();
return 0;
}
switch (c&7)
{
@ -456,10 +482,32 @@ readnext:
case dem_read:
readit:
// get the next message
readdemobytes (&net_message.cursize, 4);
if (readdemobytes (&net_message.cursize, 4) != 4)
{
if (1)//!VFS_GETLEN(cls.demofile))
{
if ((c & 7) == dem_multiple)
unreadbytes(4, &i);
unreadbytes(1, &c);
if (cls.demoplayback == DPB_MVD)
{
r = 0;
unreadbytes(1, &r);
}
else
{
demotime = LittleFloat(demotime);
unreadbytes(4, &demotime);
}
}
else
CL_StopPlayback ();
return 0;
}
net_message.cursize = LittleLong (net_message.cursize);
//Con_Printf("read: %ld bytes\n", net_message.cursize);
if (net_message.cursize > MAX_OVERALLMSGLEN)
if ((unsigned int)net_message.cursize > MAX_OVERALLMSGLEN)
{
Con_Printf ("Demo message > MAX_OVERALLMSGLEN\n");
CL_StopPlayback ();
@ -468,6 +516,28 @@ readit:
r = readdemobytes (net_message.data, net_message.cursize);
if (r != net_message.cursize)
{
if (1)//!VFS_GETLEN(cls.demofile))
{
net_message.cursize = LittleLong (net_message.cursize);
unreadbytes(4, &net_message.cursize);
if ((c & 7) == dem_multiple)
unreadbytes(4, &i);
unreadbytes(1, &c);
if (cls.demoplayback == DPB_MVD)
{
r = 0;
unreadbytes(1, &r);
}
else
{
demotime = LittleFloat(demotime);
unreadbytes(4, &demotime);
}
}
else
CL_StopPlayback ();
return 0;
}
@ -505,7 +575,30 @@ readit:
goto readnext;
case dem_multiple:
readdemobytes (&i, sizeof(i));
if (readdemobytes (&i, sizeof(i)) != sizeof(i))
{
if (1)//!VFS_GETLEN(cls.demofile))
{
if ((c & 7) == dem_multiple)
unreadbytes(4, &i);
unreadbytes(1, &c);
if (cls.demoplayback == DPB_MVD)
{
r = 0;
unreadbytes(1, &r);
}
else
{
demotime = LittleFloat(demotime);
unreadbytes(4, &demotime);
}
}
else
CL_StopPlayback ();
return 0;
}
cls_lastto = LittleLong(i);
cls_lasttype = dem_multiple;
goto readit;
@ -1176,7 +1269,7 @@ void CL_PlayDemo(char *demoname)
//
CL_Disconnect_f ();
unreadbytes = 0; //just in case
unreadcount = 0; //just in case
//
// open the demo file
//
@ -1204,6 +1297,15 @@ void CL_PlayDemo(char *demoname)
Q_strncpyz (lastdemoname, demoname, sizeof(lastdemoname));
Con_Printf ("Playing demo from %s.\n", name);
if (!VFS_GETLEN (cls.demofile))
{
VFS_CLOSE(cls.demofile);
cls.demofile = NULL;
Con_Printf ("demo \"%s\" is empty.\n", demoname);
cls.demonum = -1; // stop demo loop
return;
}
if (!Q_strcasecmp(name + strlen(name) - 3, "mvd") ||
!Q_strcasecmp(name + strlen(name) - 6, "mvd.gz"))
{
@ -1271,6 +1373,41 @@ void CL_PlayDemo(char *demoname)
TP_ExecTrigger ("f_demostart");
}
void CL_QTVPlay_f (void)
{
vfsfile_t *newf;
newf = FS_OpenTCP(Cmd_Argv(1));
if (!newf)
{
Con_Printf("Couldn't connect to proxy\n");
return;
}
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");
}
/*
====================
CL_FinishTimeDemo

View file

@ -2683,6 +2683,7 @@ void CL_Init (void)
Cmd_AddCommand ("rerecord", CL_ReRecord_f);
Cmd_AddCommand ("stop", CL_Stop_f);
Cmd_AddCommand ("playdemo", CL_PlayDemo_f);
Cmd_AddCommand ("playqtv", CL_QTVPlay_f);
Cmd_AddCommand ("demo_jump", CL_DemoJump_f);
Cmd_AddCommand ("timedemo", CL_TimeDemo_f);

View file

@ -743,6 +743,7 @@ void CL_Stop_f (void);
void CL_Record_f (void);
void CL_ReRecord_f (void);
void CL_PlayDemo_f (void);
void CL_QTVPlay_f (void);
void CL_DemoJump_f(void);
void CL_ProgressDemoTime(void);
void CL_TimeDemo_f (void);

View file

@ -1675,3 +1675,114 @@ void NET_Shutdown (void)
#endif
}
typedef struct {
vfsfile_t funcs;
int sock;
char readbuffer[65536];
int readbuffered;
} tcpfile_t;
void VFSTCP_Error(tcpfile_t *f)
{
if (f->sock != INVALID_SOCKET)
{
closesocket(f->sock);
f->sock = INVALID_SOCKET;
}
}
int VFSTCP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
tcpfile_t *tf = (tcpfile_t*)file;
int len;
if (tf->sock != INVALID_SOCKET)
{
len = recv(tf->sock, tf->readbuffer + tf->readbuffered, sizeof(tf->readbuffer) - tf->readbuffered, 0);
if (len == -1)
{
//fixme: figure out wouldblock or error
}
else if (len == 0)
VFSTCP_Error(tf);
else
tf->readbuffered += len;
}
if (bytestoread <= tf->readbuffered)
{
memcpy(buffer, tf->readbuffer, bytestoread);
tf->readbuffered -= bytestoread;
memmove(tf->readbuffer, tf->readbuffer+bytestoread, tf->readbuffered);
return bytestoread;
}
else
return 0;
}
int VFSTCP_WriteBytes (struct vfsfile_s *file, void *buffer, int bytestoread)
{
tcpfile_t *tf = (tcpfile_t*)file;
int len;
if (tf->sock == INVALID_SOCKET)
return 0;
len = send(tf->sock, buffer, bytestoread, 0);
if (len == -1 || len == 0)
{
VFSTCP_Error(tf);
return 0;
}
return len;
}
qboolean VFSTCP_Seek (struct vfsfile_s *file, unsigned long pos)
{
VFSTCP_Error((tcpfile_t*)file);
return false;
}
unsigned long VFSTCP_Tell (struct vfsfile_s *file)
{
VFSTCP_Error((tcpfile_t*)file);
return 0;
}
unsigned long VFSTCP_GetLen (struct vfsfile_s *file)
{
return 0;
}
void VFSTCP_Close (struct vfsfile_s *file)
{
VFSTCP_Error((tcpfile_t*)file);
Z_Free(file);
}
vfsfile_t *FS_OpenTCP(char *name)
{
tcpfile_t *newf;
int sock;
netadr_t adr;
if (!NET_StringToAdr(name, &adr))
return NULL;
sock = TCP_OpenStream(adr);
if (sock == INVALID_SOCKET)
return NULL;
newf = Z_Malloc(sizeof(*newf));
newf->sock = sock;
newf->funcs.Close = VFSTCP_Close;
newf->funcs.Flush = NULL;
newf->funcs.GetLen = VFSTCP_GetLen;
newf->funcs.ReadBytes = VFSTCP_ReadBytes;
newf->funcs.Seek = VFSTCP_Seek;
newf->funcs.Tell = VFSTCP_Tell;
newf->funcs.WriteBytes = VFSTCP_WriteBytes;
newf->funcs.seekingisabadplan = true;
return &newf->funcs;
}