diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cl_demo.c | 33 | ||||
-rw-r--r-- | src/common.c | 49 | ||||
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/mvd_client.c | 32 | ||||
-rw-r--r-- | src/mvd_local.h | 2 |
5 files changed, 105 insertions, 15 deletions
diff --git a/src/cl_demo.c b/src/cl_demo.c index 4ae67cd..1da5edb 100644 --- a/src/cl_demo.c +++ b/src/cl_demo.c @@ -729,8 +729,6 @@ static void CL_Demo_c( genctx_t *ctx, int argnum ) { } } -#define DEMO_FPS 10 - typedef struct { list_t entry; int framenum; @@ -758,7 +756,7 @@ void CL_EmitDemoSnapshot( void ) { if( cl_demosnaps->integer <= 0 ) return; - if( cl.frame.number < cls.demo.last_snapshot + cl_demosnaps->integer * DEMO_FPS ) + if( cl.frame.number < cls.demo.last_snapshot + cl_demosnaps->integer * 10 ) return; if( !cls.demo.file_size ) @@ -880,7 +878,7 @@ static void CL_Seek_f( void ) { char *from, *to; if( Cmd_Argc() < 2 ) { - Com_Printf( "Usage: %s [+-]<seconds>\n", Cmd_Argv( 0 ) ); + Com_Printf( "Usage: %s [+-]<timespec>\n", Cmd_Argv( 0 ) ); return; } @@ -896,8 +894,29 @@ static void CL_Seek_f( void ) { return; } - frames = atoi( Cmd_Argv( 1 ) ) * DEMO_FPS; + to = Cmd_Argv( 1 ); + + if( *to == '-' || *to == '+' ) { + // relative to current frame + if( !Com_ParseTimespec( to + 1, &frames ) ) { + Com_Printf( "Invalid relative timespec.\n" ); + return; + } + if( *to == '-' ) + frames = -frames; + dest = cl.frame.number + frames; + } else { + // relative to first frame + if( !Com_ParseTimespec( to, &frames ) ) { + Com_Printf( "Invalid absolute timespec.\n" ); + return; + } + dest = cls.demo.first_frame + frames; + frames = dest - cl.frame.number; + } + if( !frames ) + // already there return; // disable effects processing @@ -906,7 +925,7 @@ static void CL_Seek_f( void ) { // clear dirty configstrings memset( cl.dcs, 0, sizeof( cl.dcs ) ); - dest = cl.frame.number + frames; + // save previous position prev = cl.frame.number; Com_DPrintf( "[%d] seeking to %d\n", cl.frame.number, dest ); @@ -984,6 +1003,8 @@ static void CL_Seek_f( void ) { update_status(); + cl.frameflags = 0; + done: cls.demo.seeking = qfalse; } diff --git a/src/common.c b/src/common.c index 8a0e859..adb384e 100644 --- a/src/common.c +++ b/src/common.c @@ -1470,6 +1470,55 @@ void Com_PlayerToEntityState( const player_state_t *ps, entity_state_t *es ) { es->angles[ROLL] = 0; } +#if USE_CLIENT || USE_MVD_CLIENT +/* +================ +Com_ParseTimespec + +Parses time/frame specification for seeking in demos. +Does not check for integer overflow... +================ +*/ +qboolean Com_ParseTimespec( const char *s, int *frames ) { + unsigned long c1, c2, c3; + char *p; + + c1 = strtoul( s, &p, 10 ); + if( !*p ) { + *frames = c1 * 10; // sec + return qtrue; + } + + if( *p == '.' ) { + c2 = strtoul( p + 1, &p, 10 ); + if( *p ) + return qfalse; + *frames = c1 * 10 + c2; // sec.frac + return qtrue; + } + + if( *p == ':' ) { + c2 = strtoul( p + 1, &p, 10 ); + if( !*p ) { + *frames = c1 * 600 + c2 * 10; // min:sec + return qtrue; + } + + if( *p == '.' ) { + c3 = strtoul( p + 1, &p, 10 ); + if( *p ) + return qfalse; + *frames = c1 * 600 + c2 * 10 + c3; // min:sec.frac + return qtrue; + } + + return qfalse; + } + + return qfalse; +} +#endif + /* ================ Com_HashString diff --git a/src/common.h b/src/common.h index e0c7c1f..9daff8c 100644 --- a/src/common.h +++ b/src/common.h @@ -521,6 +521,10 @@ void Com_Color_g( genctx_t *ctx ); #endif void Com_PlayerToEntityState( const player_state_t *ps, entity_state_t *es ); +#if USE_CLIENT || USE_MVD_CLIENT +qboolean Com_ParseTimespec( const char *s, int *frames ); +#endif + qboolean Com_WildCmpEx( const char *filter, const char *string, int term, qboolean ignorecase ); #define Com_WildCmp( filter, string ) Com_WildCmpEx( filter, string, 0, qfalse ) diff --git a/src/mvd_client.c b/src/mvd_client.c index c780ddc..eec8d16 100644 --- a/src/mvd_client.c +++ b/src/mvd_client.c @@ -548,7 +548,7 @@ static void demo_emit_snapshot( mvd_t *mvd ) { if( mvd_snaps->integer <= 0 ) return; - if( mvd->framenum < mvd->last_snapshot + mvd_snaps->integer * MVD_FPS ) + if( mvd->framenum < mvd->last_snapshot + mvd_snaps->integer * 10 ) return; gtv = mvd->gtv; @@ -2062,13 +2062,13 @@ static void MVD_Seek_f( void ) { mvd_t *mvd; gtv_t *gtv; mvd_snap_t *snap; - int i, j, ret, index, frames, dest, prev; + int i, j, ret, index, frames, dest; char *from, *to; edict_t *ent; qboolean gamestate; if( Cmd_Argc() < 2 ) { - Com_Printf( "Usage: %s [+-]<seconds> [chanid]\n", Cmd_Argv( 0 ) ); + Com_Printf( "Usage: %s [+-]<timespec> [chanid]\n", Cmd_Argv( 0 ) ); return; } @@ -2089,8 +2089,29 @@ static void MVD_Seek_f( void ) { return; } - frames = atoi( Cmd_Argv( 1 ) ) * MVD_FPS; + to = Cmd_Argv( 1 ); + + if( *to == '-' || *to == '+' ) { + // relative to current frame + if( !Com_ParseTimespec( to + 1, &frames ) ) { + Com_Printf( "Invalid relative timespec.\n" ); + return; + } + if( *to == '-' ) + frames = -frames; + dest = mvd->framenum + frames; + } else { + // relative to first frame + if( !Com_ParseTimespec( to, &frames ) ) { + Com_Printf( "Invalid absolute timespec.\n" ); + return; + } + dest = frames; + frames = dest - mvd->framenum; + } + if( !frames ) + // already there return; if( setjmp( mvd_jmpbuf ) ) @@ -2102,9 +2123,6 @@ static void MVD_Seek_f( void ) { // clear dirty configstrings memset( mvd->dcs, 0, sizeof( mvd->dcs ) ); - dest = mvd->framenum + frames; - prev = mvd->framenum; - Com_DPrintf( "[%d] seeking to %d\n", mvd->framenum, dest ); // seek to the previous most recent snapshot diff --git a/src/mvd_local.h b/src/mvd_local.h index 41376f1..c2e177b 100644 --- a/src/mvd_local.h +++ b/src/mvd_local.h @@ -108,8 +108,6 @@ typedef enum { MVD_NUM_STATES } mvd_state_t; -#define MVD_FPS 10 - typedef struct { list_t entry; int framenum; |