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:
parent
4080f29040
commit
bfa9db357b
4 changed files with 273 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue