diff options
author | Andrey Nazarov <skuller@skuller.net> | 2007-11-26 19:03:18 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2007-11-26 19:03:18 +0000 |
commit | 9c8761e1acd38ca7b8b4acdd460c1b61a37a635f (patch) | |
tree | 14484e1a903862eccb221b1219def5f1492db6cc | |
parent | 85f8d29b968454e29280bb5819742c570ef6c41b (diff) |
Added `suspend' command useful for temporary pausing demo recording.
Brought CL_SetClientTime back to original Q2 style. This removed delays
during demo playback caused by several frames dropped in a row.
Make sure empty demo messages are never written.
Enabled USE_AUTOREPLY flag in `configure' script.
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | source/cl_demo.c | 67 | ||||
-rw-r--r-- | source/cl_local.h | 2 | ||||
-rw-r--r-- | source/cl_main.c | 31 | ||||
-rw-r--r-- | source/cl_parse.c | 8 | ||||
-rw-r--r-- | source/protocol.h | 3 | ||||
-rw-r--r-- | source/sv_local.h | 9 | ||||
-rw-r--r-- | source/sv_mvd.c | 4 |
8 files changed, 90 insertions, 37 deletions
@@ -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; } |