summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cl_demo.c33
-rw-r--r--src/common.c49
-rw-r--r--src/common.h4
-rw-r--r--src/mvd_client.c32
-rw-r--r--src/mvd_local.h2
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;