the NDP now drops zombie snapshots and pre-time rewind snapshots

This commit is contained in:
myT 2024-01-21 03:11:24 +01:00
parent 9a66155d14
commit 03ba418296
2 changed files with 31 additions and 12 deletions

View file

@ -100,6 +100,9 @@ add: Cinematic Rendering Pipeline CVars
1 - 1/4 pixel count, 9 samples total
2 - 1/16 pixel count, 25 samples total
fix: the new demo player now drops zombie snapshots and snapshots from before a server time rewind
these problematic snapshots happen right before and after gamestate changes
chg: dropped 32-bit support
chg: dropped Linux/FreeBSD client

View file

@ -1,6 +1,6 @@
/*
===========================================================================
Copyright (C) 2022 Gian 'myT' Schellenbaum
Copyright (C) 2022-2024 Gian 'myT' Schellenbaum
This file is part of Challenge Quake 3 (CNQ3).
@ -176,6 +176,7 @@ struct parser_t {
int nextFullSnapshotTime; // when server time is bigger, write a full snapshot
int serverCommandSequence; // the command number of the latest command we decoded
int progress;
int numGamestates;
};
struct demoIndex_t {
@ -435,7 +436,8 @@ static void ParseServerCommand()
const int commandNumber = MSG_ReadLong(inMsg);
const char* const s = MSG_ReadString(inMsg);
if (commandNumber <= parser.serverCommandSequence) {
if (commandNumber <= parser.serverCommandSequence ||
parser.numGamestates <= 0) {
return;
}
parser.serverCommandSequence = commandNumber;
@ -468,7 +470,7 @@ static void ParseServerCommand()
static void ParseGamestate()
{
msg_t* const inMsg = &parser.inMsg;
MSG_ReadLong(inMsg); // skip message sequence
parser.serverCommandSequence = MSG_ReadLong(inMsg);
ndpSnapshot_t* const currSnap = parser.currSnap;
for (;;) {
@ -607,7 +609,7 @@ static void ParseSnapshot()
newSnap->numEntities++;
}
if (!newSnap->valid) {
if (!newSnap->valid || parser.numGamestates <= 0) {
return;
}
@ -620,7 +622,19 @@ static void ParseSnapshot()
}
parser.lastMessageNum = newSnap->messageNum + 1;
if (currServerTime <= parser.prevServerTime) {
// some servers reset the server time
// some snapshots are to be ignored entirely at the start of a demo
if (currServerTime < parser.prevServerTime ||
(newSnap->snapFlags & SNAPFLAG_NOT_ACTIVE) != 0) {
// ignore all previous snapshots and the current one too
parser.prevServerTime = currServerTime;
parser.lastMessageNum = newSnap->messageNum + 1;
demo.firstServerTime = INT_MAX;
demo.lastServerTime = INT_MIN;
demo.buffer.numBytes = 0;
demo.numCommands = 0;
demo.numSnapshots = 0;
demo.numIndices = 0;
return;
}
@ -725,7 +739,6 @@ static void ParseDemo()
byte oldData[MAX_MSGLEN];
msg_t* const msg = &parser.inMsg;
const int fh = clc.demofile;
int numGamestates = 0;
Com_Memset(&parser, 0, sizeof(parser));
parser.currSnap = &parser.ndpSnapshots[0];
@ -791,8 +804,8 @@ static void ParseDemo()
break;
case svc_gamestate:
++numGamestates;
if (numGamestates >= 2) {
++parser.numGamestates;
if (parser.numGamestates >= 2) {
Warning("More than 1 gamestate found, only the first one was loaded");
return;
}
@ -1065,15 +1078,18 @@ after_parse:
demo.nextSnap = &demo.snapshots[1];
MB_InitRead(&demo.buffer);
// finalize CGame load and set any extra info needed now
// CGame will also restore previous state when videoRestart is qtrue
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
demo.commands[0].command[0] = '\0';
demo.commands[1].command[0] = '\0';
demo.numCommands = 1;
// finalize CGame load and set any extra info needed now
// CGame will also restore previous state when videoRestart is qtrue
CL_CGNDP_EndAnalysis(clc.demoName, demo.firstServerTime, demo.lastServerTime, videoRestart);
// seek to make sure we're synchronized as if the user had manually asked for said time
CL_NDP_Seek(videoRestart ? demo.currSnap->serverTime : demo.firstServerTime);
const int duration = Sys_Milliseconds() - startTime;
Com_Printf("New Demo Player: loaded demo in %d.%03d seconds\n", duration / 1000, duration % 1000);
Com_DPrintf("New Demo Player: I-frame delay %d ms, %s -> %s (%.2fx)\n",