summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure3
-rw-r--r--source/cl_demo.c67
-rw-r--r--source/cl_local.h2
-rw-r--r--source/cl_main.c31
-rw-r--r--source/cl_parse.c8
-rw-r--r--source/protocol.h3
-rw-r--r--source/sv_local.h9
-rw-r--r--source/sv_mvd.c4
8 files changed, 90 insertions, 37 deletions
diff --git a/configure b/configure
index a66bf7f..dc8a41e 100755
--- a/configure
+++ b/configure
@@ -55,7 +55,7 @@ tmpc="/tmp/q2pro-${RANDOM}.c"
tmpo="/tmp/q2pro-${RANDOM}.o"
if [ -z "$CFLAGS" ]; then
- CFLAGS="-O2"
+ CFLAGS="-ffast-math -O2"
fi
# detect host CPU
@@ -430,6 +430,7 @@ if [ "$asm" = "yes" ]; then
fi
echo "#define USE_MAPCHECKSUM 1" >> $config_h
+echo "#define USE_AUTOREPLY 1" >> $config_h
if [ "$hardlink" = "yes" ]; then
echo "REF_HARD_LINKED=yes" >> $config_mk
diff --git a/source/cl_demo.c b/source/cl_demo.c
index 24c1f9b..aa5c38e 100644
--- a/source/cl_demo.c
+++ b/source/cl_demo.c
@@ -41,6 +41,9 @@ void CL_WriteDemoMessage( sizebuf_t *buf ) {
Com_WPrintf( "Demo message overflowed.\n" );
return;
}
+ if( !buf->cursize ) {
+ return;
+ }
length = LittleLong( buf->cursize );
FS_Write( &length, 4, cls.demorecording );
@@ -128,6 +131,10 @@ void CL_EmitDemoFrame( void ) {
player_state_t *oldstate;
int lastframe;
+ if( cls.demopaused ) {
+ return;
+ }
+
if( cl.demoframe < 0 ) {
oldframe = NULL;
oldstate = NULL;
@@ -174,7 +181,7 @@ void CL_EmitDemoFrame( void ) {
}
void CL_EmitZeroFrame( void ) {
- cl.demodelta++;
+ cl.demodelta++; // insert new zero frame
MSG_WriteByte( svc_frame );
MSG_WriteLong( cl.frame.number + cl.demodelta );
@@ -230,6 +237,7 @@ void CL_Stop_f( void ) {
// close demofile
FS_FCloseFile( cls.demorecording );
cls.demorecording = 0;
+ cls.demopaused = qfalse;
Com_Printf( "Stopped demo (%d bytes written).\n", length );
}
@@ -295,9 +303,11 @@ void CL_Record_f( void ) {
Com_Printf( "Recording client demo to %s.\n", name );
cls.demorecording = demofile;
+ cls.demopaused = qfalse;
// the first frame will be delta uncompressed
cl.demoframe = -1;
+ cl.demodelta = 0;
if( cls.netchan && cls.serverProtocol >= PROTOCOL_VERSION_R1Q2 ) {
// tell the server we are recording
@@ -366,6 +376,54 @@ void CL_Record_f( void ) {
// the rest of the demo file will be individual frames
}
+static void CL_Suspend_f( void ) {
+ int i, j, index;
+ int length, total = 0;
+
+ if( !cls.demorecording ) {
+ Com_Printf( "Not recording a demo.\n" );
+ return;
+ }
+ if( !cls.demopaused ) {
+ Com_Printf( "Suspended demo.\n" );
+ cls.demopaused = qtrue;
+ return;
+ }
+
+ // XXX: embed these in frame instead?
+ for( i = 0; i < CS_BITMAP_LONGS; i++ ) {
+ if( (( uint32 * )cl.dcs)[i] == 0 ) {
+ continue;
+ }
+ index = i << 5;
+ for( j = 0; j < 32; j++, index++ ) {
+ if( !Q_IsBitSet( cl.dcs, index ) ) {
+ continue;
+ }
+ length = strlen( cl.configstrings[index] );
+ if( length > MAX_QPATH ) {
+ length = MAX_QPATH;
+ }
+ if( msg_write.cursize + length + 4 > MAX_PACKETLEN_WRITABLE_DEFAULT ) {
+ CL_WriteDemoMessage( &msg_write );
+ }
+ MSG_WriteByte( svc_configstring );
+ MSG_WriteShort( index );
+ MSG_WriteData( cl.configstrings[index], length );
+ MSG_WriteByte( 0 );
+ total += length + 4;
+ }
+ }
+
+ // write it to the demo file
+ CL_WriteDemoMessage( &msg_write );
+
+ Com_Printf( "Resumed demo (%d bytes flushed).\n", total );
+
+ cl.demodelta += cl.demoframe - cl.frame.number; // do not create holes
+ cls.demopaused = qfalse;
+}
+
/*
====================
CL_ReadNextDemoMessage
@@ -376,6 +434,7 @@ static qboolean CL_ReadNextDemoMessage( fileHandle_t f ) {
// read msglen
if( FS_Read( &msglen, 4, f ) != 4 ) {
+ Com_DPrintf( "%s: short read of msglen\n", __func__ );
return qfalse;
}
@@ -384,7 +443,8 @@ static qboolean CL_ReadNextDemoMessage( fileHandle_t f ) {
}
msglen = LittleLong( msglen );
- if( msglen < 1 || msglen >= msg_read.maxsize ) {
+ if( msglen < 0 || msglen >= msg_read.maxsize ) {
+ Com_DPrintf( "%s: bad msglen\n", __func__ );
return qfalse;
}
@@ -393,11 +453,11 @@ static qboolean CL_ReadNextDemoMessage( fileHandle_t f ) {
// read packet data
if( FS_Read( msg_read.data, msglen, f ) != msglen ) {
+ Com_DPrintf( "%s: short read of data\n", __func__ );
return qfalse;
}
return qtrue;
-
}
/*
@@ -645,6 +705,7 @@ static const cmdreg_t c_demo[] = {
{ "demo", CL_PlayDemo_f, CL_PlayDemo_g },
{ "record", CL_Record_f, CL_PlayDemo_g },
{ "stop", CL_Stop_f },
+ { "suspend", CL_Suspend_f },
{ NULL }
};
diff --git a/source/cl_local.h b/source/cl_local.h
index c9ed33c..996a57f 100644
--- a/source/cl_local.h
+++ b/source/cl_local.h
@@ -128,6 +128,7 @@ typedef struct client_state_s {
int demoframe;
int demodelta;
+ byte dcs[CS_BITMAP_BYTES];
// the client maintains its own idea of view angles, which are
// sent to the server each frame. It is cleared to 0 upon entering each level.
@@ -273,6 +274,7 @@ typedef struct client_static_s {
int demofileFrameOffset;
int demofilePercent;
sizebuf_t demobuff;
+ qboolean demopaused;
} client_static_t;
extern client_static_t cls;
diff --git a/source/cl_main.c b/source/cl_main.c
index fa31834..71312d3 100644
--- a/source/cl_main.c
+++ b/source/cl_main.c
@@ -2391,39 +2391,26 @@ CL_SetClientTime
==================
*/
static void CL_SetClientTime( void ) {
- int prevtime;
-
- prevtime = cl.oldframe.number * 100;
- if ( prevtime >= cl.serverTime ) {
- /* this may happen on a very first frame */
- cl.lerpfrac = 0;
- return;
- }
- if( sv_paused->integer ) {
- return;
- }
-
if ( cl.time > cl.serverTime ) {
if ( cl_showclamp->integer )
Com_Printf( "high clamp %i\n", cl.time - cl.serverTime );
cl.time = cl.serverTime;
- cl.lerpfrac = 1.0;
- } else if ( cl.time < prevtime ) {
+ cl.lerpfrac = 1.0f;
+ } else if ( cl.time < cl.serverTime - 100 ) {
if ( cl_showclamp->integer )
- Com_Printf( "low clamp %i\n", cl.serverTime - prevtime );
- cl.time = prevtime;
+ Com_Printf( "low clamp %i\n", cl.time - cl.serverTime + 100 );
+ cl.time = cl.serverTime - 100;
cl.lerpfrac = 0;
} else {
- cl.lerpfrac = ( float ) ( cl.time - prevtime ) / ( float ) ( cl.serverTime - prevtime );
+ cl.lerpfrac = ( cl.time - cl.serverTime + 100 ) * 0.01f;
}
if ( com_timedemo->integer ) {
- cl.lerpfrac = 1.0;
+ cl.lerpfrac = 1.0f;
}
if ( cl_showclamp->integer == 2 )
Com_Printf( "time %i, lerpfrac %.3f\n", cl.time, cl.lerpfrac );
-
}
static void CL_MeasureStats( void ) {
@@ -2606,7 +2593,7 @@ void CL_Frame( int msec ) {
// read next demo frame
if( cls.demoplayback ) {
- if( cls.demorecording && cl_paused->integer == 2 ) {
+ if( cls.demorecording && cl_paused->integer == 2 && !cls.demopaused ) {
static int demo_extra;
// XXX: record zero frames when manually paused
@@ -2622,7 +2609,9 @@ void CL_Frame( int msec ) {
}
// calculate local time
- CL_SetClientTime();
+ if( cls.state == ca_active && !sv_paused->integer ) {
+ CL_SetClientTime();
+ }
#if USE_AUTOREPLY
// check for version reply
diff --git a/source/cl_parse.c b/source/cl_parse.c
index d9dde76..fdba906 100644
--- a/source/cl_parse.c
+++ b/source/cl_parse.c
@@ -1081,6 +1081,10 @@ static void CL_ParseConfigString (void) {
Com_Printf( " %i \"%s\"\n", i, Q_FormatString( s ) );
}
+ if( cls.demorecording && cls.demopaused ) {
+ Q_SetBit( cl.dcs, i );
+ }
+
CL_ConfigString( i, s );
}
@@ -1526,7 +1530,7 @@ void CL_ParseServerMessage( void ) {
}
// copy protocol invariant stuff
- if( cls.demorecording ) {
+ if( cls.demorecording && !cls.demopaused ) {
SZ_Write( &cls.demobuff, msg_read.data + readcount,
msg_read.readcount - readcount );
}
@@ -1535,7 +1539,7 @@ void CL_ParseServerMessage( void ) {
//
// if recording demos, write the message out
//
- if( cls.demorecording ) {
+ if( cls.demorecording && !cls.demopaused ) {
CL_WriteDemoMessage( &cls.demobuff );
}
}
diff --git a/source/protocol.h b/source/protocol.h
index 2e988fe..51e21c3 100644
--- a/source/protocol.h
+++ b/source/protocol.h
@@ -81,6 +81,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_PACKET_STRINGCMDS 8
#define MAX_PACKET_USERINFOS 8
+#define CS_BITMAP_BYTES (MAX_CONFIGSTRINGS/8) // 260
+#define CS_BITMAP_LONGS (CS_BITMAP_BYTES/4)
+
//
// server to client
//
diff --git a/source/sv_local.h b/source/sv_local.h
index ee23dc0..0479928 100644
--- a/source/sv_local.h
+++ b/source/sv_local.h
@@ -42,13 +42,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SV_BASELINES_MASK ( SV_BASELINES_PER_CHUNK - 1 )
#define SV_BASELINES_CHUNKS ( MAX_EDICTS >> SV_BASELINES_SHIFT )
-#define DCS_BYTES 260
-#define DCS_DWORDS (DCS_BYTES/4)
-
-#if( DCS_BYTES != MAX_CONFIGSTRINGS/8 )
-#error Invalid DCS_BYTES
-#endif
-
typedef struct {
uint32 numEntities;
uint32 firstEntity;
@@ -79,7 +72,7 @@ typedef struct server_s {
int framenum;
sizebuf_t datagram;
sizebuf_t message; // reliable
- byte dcs[DCS_BYTES];
+ byte dcs[CS_BITMAP_BYTES];
} mvd;
uint32 tracecount;
diff --git a/source/sv_mvd.c b/source/sv_mvd.c
index 4d62ec6..1741de1 100644
--- a/source/sv_mvd.c
+++ b/source/sv_mvd.c
@@ -442,7 +442,7 @@ void SV_MvdBeginFrame( void ) {
if( !found ) {
if( sv.mvd.paused == PAUSED_FRAMES ) {
Com_Printf( "MVD stream paused, no active clients.\n" );
- for( i = 0; i < DCS_DWORDS; i++ ) {
+ for( i = 0; i < CS_BITMAP_LONGS; i++ ) {
(( uint32 * )sv.mvd.dcs)[i] = 0;
}
}
@@ -452,7 +452,7 @@ void SV_MvdBeginFrame( void ) {
}
if( sv.mvd.paused >= PAUSED_FRAMES ) {
- for( i = 0; i < DCS_DWORDS; i++ ) {
+ for( i = 0; i < CS_BITMAP_LONGS; i++ ) {
if( (( uint32 * )sv.mvd.dcs)[i] == 0 ) {
continue;
}