mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-10 06:31:48 +00:00
the NDP now drops zombie snapshots and pre-time rewind snapshots
This commit is contained in:
parent
9a66155d14
commit
03ba418296
2 changed files with 31 additions and 12 deletions
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue