mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
added NDP server pause tracking and improved command sequence handling
This commit is contained in:
parent
db25062b05
commit
23ce3e0982
3 changed files with 34 additions and 9 deletions
|
@ -1031,11 +1031,11 @@ qbool CL_CGNDP_IsConfigStringNeeded( int csIndex )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CL_CGNDP_AnalyzeSnapshot( int progress )
|
qbool CL_CGNDP_AnalyzeSnapshot( int progress )
|
||||||
{
|
{
|
||||||
Q_assert(cls.cgameNewDemoPlayer);
|
Q_assert(cls.cgameNewDemoPlayer);
|
||||||
Q_assert(progress >= 0 && progress < 100);
|
Q_assert(progress >= 0 && progress < 100);
|
||||||
VM_Call(cgvm, cls.cgvmCalls[CGVM_NDP_ANALYZE_SNAPSHOT], progress);
|
return (qbool)VM_Call(cgvm, cls.cgvmCalls[CGVM_NDP_ANALYZE_SNAPSHOT], progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ There's no need to make the player more complex for such an edge case.
|
||||||
|
|
||||||
#define FULL_SNAPSHOT_INTERVAL_MS (8 * 1000)
|
#define FULL_SNAPSHOT_INTERVAL_MS (8 * 1000)
|
||||||
|
|
||||||
#define MAX_COMMANDS ARRAY_LEN(demo.commands)
|
#define MAX_COMMANDS 256
|
||||||
|
|
||||||
#define VERBOSE_DEBUGGING 0
|
#define VERBOSE_DEBUGGING 0
|
||||||
|
|
||||||
|
@ -155,6 +155,7 @@ struct ndpSnapshot_t {
|
||||||
int snapFlags;
|
int snapFlags;
|
||||||
int ping;
|
int ping;
|
||||||
qbool isFullSnap;
|
qbool isFullSnap;
|
||||||
|
qbool isServerPaused;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct parser_t {
|
struct parser_t {
|
||||||
|
@ -198,7 +199,7 @@ struct command_t {
|
||||||
struct demo_t {
|
struct demo_t {
|
||||||
ndpSnapshot_t snapshots[2]; // current one and next one for CGame requests
|
ndpSnapshot_t snapshots[2]; // current one and next one for CGame requests
|
||||||
demoIndex_t indices[4096];
|
demoIndex_t indices[4096];
|
||||||
command_t commands[256];
|
command_t commands[MAX_COMMANDS];
|
||||||
memoryBuffer_t buffer;
|
memoryBuffer_t buffer;
|
||||||
ndpSnapshot_t* currSnap;
|
ndpSnapshot_t* currSnap;
|
||||||
ndpSnapshot_t* nextSnap;
|
ndpSnapshot_t* nextSnap;
|
||||||
|
@ -213,6 +214,9 @@ struct demo_t {
|
||||||
|
|
||||||
struct newDemoPlayer_t {
|
struct newDemoPlayer_t {
|
||||||
jmp_buf abortLoad;
|
jmp_buf abortLoad;
|
||||||
|
qbool trackServerPause;
|
||||||
|
qbool isServerPaused;
|
||||||
|
int serverPauseDelay; // total duration in server pause since the full snapshot
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,13 +311,14 @@ static void MB_Seek( memoryBuffer_t* mb, int position )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void WriteNDPSnapshot( msg_t* outMsg, const ndpSnapshot_t* prevSnap, ndpSnapshot_t* currSnap )
|
static void WriteNDPSnapshot( msg_t* outMsg, const ndpSnapshot_t* prevSnap, ndpSnapshot_t* currSnap, qbool isServerPaused )
|
||||||
{
|
{
|
||||||
const qbool isFullSnap = prevSnap == NULL;
|
const qbool isFullSnap = prevSnap == NULL;
|
||||||
|
|
||||||
// header
|
// header
|
||||||
MSG_WriteBits(outMsg, isFullSnap, 1);
|
MSG_WriteBits(outMsg, isFullSnap, 1);
|
||||||
MSG_WriteLong(outMsg, currSnap->serverTime);
|
MSG_WriteLong(outMsg, currSnap->serverTime);
|
||||||
|
MSG_WriteBits(outMsg, !!isServerPaused, 1);
|
||||||
|
|
||||||
// player state
|
// player state
|
||||||
const playerState_t* const oldPS = !prevSnap ? &nullPlayerState : &prevSnap->ps;
|
const playerState_t* const oldPS = !prevSnap ? &nullPlayerState : &prevSnap->ps;
|
||||||
|
@ -660,7 +665,7 @@ static void ParseSnapshot()
|
||||||
// let CGame analyze the snapshot so it can do cool stuff
|
// let CGame analyze the snapshot so it can do cool stuff
|
||||||
// e.g. store events of interest for the timeline overlay
|
// e.g. store events of interest for the timeline overlay
|
||||||
demo.currSnap = currNDPSnap;
|
demo.currSnap = currNDPSnap;
|
||||||
CL_CGNDP_AnalyzeSnapshot(parser.progress);
|
const qbool isServerPaused = CL_CGNDP_AnalyzeSnapshot(parser.progress);
|
||||||
|
|
||||||
// draw the current progress once in a while...
|
// draw the current progress once in a while...
|
||||||
static int lastRefreshTime = Sys_Milliseconds();
|
static int lastRefreshTime = Sys_Milliseconds();
|
||||||
|
@ -676,7 +681,7 @@ static void ParseSnapshot()
|
||||||
MSG_Clear(&writeMsg);
|
MSG_Clear(&writeMsg);
|
||||||
MSG_Bitstream(&writeMsg);
|
MSG_Bitstream(&writeMsg);
|
||||||
ndpSnapshot_t* const prevNDPSnap = parser.prevSnap;
|
ndpSnapshot_t* const prevNDPSnap = parser.prevSnap;
|
||||||
WriteNDPSnapshot(&writeMsg, isFullSnap ? NULL : prevNDPSnap, currNDPSnap);
|
WriteNDPSnapshot(&writeMsg, isFullSnap ? NULL : prevNDPSnap, currNDPSnap, isServerPaused);
|
||||||
MB_Write(&demo.buffer, &writeMsg.cursize, 4);
|
MB_Write(&demo.buffer, &writeMsg.cursize, 4);
|
||||||
MB_Write(&demo.buffer, writeMsg.data, writeMsg.cursize);
|
MB_Write(&demo.buffer, writeMsg.data, writeMsg.cursize);
|
||||||
|
|
||||||
|
@ -835,6 +840,7 @@ static void ReadNextSnapshot()
|
||||||
}
|
}
|
||||||
currSnap->isFullSnap = isFullSnap;
|
currSnap->isFullSnap = isFullSnap;
|
||||||
currSnap->serverTime = MSG_ReadLong(&inMsg);
|
currSnap->serverTime = MSG_ReadLong(&inMsg);
|
||||||
|
currSnap->isServerPaused = MSG_ReadBits(&inMsg, 1);
|
||||||
|
|
||||||
// player state
|
// player state
|
||||||
MSG_ReadDeltaPlayerstate(&inMsg, prevSnap ? &prevSnap->ps : &nullPlayerState, &currSnap->ps);
|
MSG_ReadDeltaPlayerstate(&inMsg, prevSnap ? &prevSnap->ps : &nullPlayerState, &currSnap->ps);
|
||||||
|
@ -925,6 +931,14 @@ static void ReadNextSnapshot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ndp.trackServerPause) {
|
||||||
|
if (currSnap->isServerPaused && ndp.isServerPaused && prevSnap != NULL) {
|
||||||
|
const int delta = currSnap->serverTime - prevSnap->serverTime;
|
||||||
|
ndp.serverPauseDelay += delta;
|
||||||
|
}
|
||||||
|
ndp.isServerPaused = currSnap->isServerPaused;
|
||||||
|
}
|
||||||
|
|
||||||
demo.snapshotIndex++;
|
demo.snapshotIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1056,7 +1070,9 @@ after_parse:
|
||||||
CL_CGNDP_EndAnalysis(clc.demoName, demo.firstServerTime, demo.lastServerTime, videoRestart);
|
CL_CGNDP_EndAnalysis(clc.demoName, demo.firstServerTime, demo.lastServerTime, videoRestart);
|
||||||
|
|
||||||
// make sure we don't execute commands from the end of the demo when starting up
|
// make sure we don't execute commands from the end of the demo when starting up
|
||||||
demo.numCommands = 0;
|
demo.commands[0].command[0] = '\0';
|
||||||
|
demo.commands[1].command[0] = '\0';
|
||||||
|
demo.numCommands = 1;
|
||||||
|
|
||||||
const int duration = Sys_Milliseconds() - startTime;
|
const int duration = Sys_Milliseconds() - startTime;
|
||||||
Com_Printf("New Demo Player: loaded demo in %d.%03d seconds\n", duration / 1000, duration % 1000);
|
Com_Printf("New Demo Player: loaded demo in %d.%03d seconds\n", duration / 1000, duration % 1000);
|
||||||
|
@ -1200,6 +1216,10 @@ int CL_NDP_Seek( int serverTime )
|
||||||
demo.commands[i].command[0] = '\0';
|
demo.commands[i].command[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ndp.trackServerPause = qtrue;
|
||||||
|
ndp.isServerPaused = qfalse;
|
||||||
|
ndp.serverPauseDelay = 0;
|
||||||
|
|
||||||
SeekToIndex(index);
|
SeekToIndex(index);
|
||||||
|
|
||||||
// read more snapshots until we're close to the target time for more precise jumps
|
// read more snapshots until we're close to the target time for more precise jumps
|
||||||
|
@ -1218,6 +1238,11 @@ int CL_NDP_Seek( int serverTime )
|
||||||
numSnapshotsRead++;
|
numSnapshotsRead++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ndp.serverPauseDelay > 0) {
|
||||||
|
AddCommand(va("server_pause_delay %d", ndp.serverPauseDelay));
|
||||||
|
}
|
||||||
|
ndp.trackServerPause = qfalse;
|
||||||
|
|
||||||
Com_DPrintf("New Demo Player: sought and read %d snaps in %d ms\n",
|
Com_DPrintf("New Demo Player: sought and read %d snaps in %d ms\n",
|
||||||
numSnapshotsRead, Sys_Milliseconds() - seekStartTime);
|
numSnapshotsRead, Sys_Milliseconds() - seekStartTime);
|
||||||
|
|
||||||
|
|
|
@ -522,7 +522,7 @@ void CL_CGameRendering( stereoFrame_t stereo );
|
||||||
void CL_SetCGameTime();
|
void CL_SetCGameTime();
|
||||||
void CL_ConfigstringModified();
|
void CL_ConfigstringModified();
|
||||||
void CL_CGNDP_EndAnalysis( const char* filePath, int firstServerTime, int lastServerTime, qbool videoRestart );
|
void CL_CGNDP_EndAnalysis( const char* filePath, int firstServerTime, int lastServerTime, qbool videoRestart );
|
||||||
void CL_CGNDP_AnalyzeSnapshot( int progress );
|
qbool CL_CGNDP_AnalyzeSnapshot( int progress ); // qtrue when a server pause is active
|
||||||
void CL_CGNDP_AnalyzeCommand( int serverTime );
|
void CL_CGNDP_AnalyzeCommand( int serverTime );
|
||||||
void CL_CGNDP_GenerateCommands( const char** commands, int* numCommandBytes );
|
void CL_CGNDP_GenerateCommands( const char** commands, int* numCommandBytes );
|
||||||
qbool CL_CGNDP_IsConfigStringNeeded( int csIndex );
|
qbool CL_CGNDP_IsConfigStringNeeded( int csIndex );
|
||||||
|
|
Loading…
Reference in a new issue