mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2024-11-14 00:11:01 +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
|
1 - 1/4 pixel count, 9 samples total
|
||||||
2 - 1/16 pixel count, 25 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 32-bit support
|
||||||
|
|
||||||
chg: dropped Linux/FreeBSD client
|
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).
|
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 nextFullSnapshotTime; // when server time is bigger, write a full snapshot
|
||||||
int serverCommandSequence; // the command number of the latest command we decoded
|
int serverCommandSequence; // the command number of the latest command we decoded
|
||||||
int progress;
|
int progress;
|
||||||
|
int numGamestates;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct demoIndex_t {
|
struct demoIndex_t {
|
||||||
|
@ -435,7 +436,8 @@ static void ParseServerCommand()
|
||||||
|
|
||||||
const int commandNumber = MSG_ReadLong(inMsg);
|
const int commandNumber = MSG_ReadLong(inMsg);
|
||||||
const char* const s = MSG_ReadString(inMsg);
|
const char* const s = MSG_ReadString(inMsg);
|
||||||
if (commandNumber <= parser.serverCommandSequence) {
|
if (commandNumber <= parser.serverCommandSequence ||
|
||||||
|
parser.numGamestates <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
parser.serverCommandSequence = commandNumber;
|
parser.serverCommandSequence = commandNumber;
|
||||||
|
@ -468,7 +470,7 @@ static void ParseServerCommand()
|
||||||
static void ParseGamestate()
|
static void ParseGamestate()
|
||||||
{
|
{
|
||||||
msg_t* const inMsg = &parser.inMsg;
|
msg_t* const inMsg = &parser.inMsg;
|
||||||
MSG_ReadLong(inMsg); // skip message sequence
|
parser.serverCommandSequence = MSG_ReadLong(inMsg);
|
||||||
|
|
||||||
ndpSnapshot_t* const currSnap = parser.currSnap;
|
ndpSnapshot_t* const currSnap = parser.currSnap;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -607,7 +609,7 @@ static void ParseSnapshot()
|
||||||
newSnap->numEntities++;
|
newSnap->numEntities++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newSnap->valid) {
|
if (!newSnap->valid || parser.numGamestates <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +622,19 @@ static void ParseSnapshot()
|
||||||
}
|
}
|
||||||
parser.lastMessageNum = newSnap->messageNum + 1;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,7 +739,6 @@ static void ParseDemo()
|
||||||
byte oldData[MAX_MSGLEN];
|
byte oldData[MAX_MSGLEN];
|
||||||
msg_t* const msg = &parser.inMsg;
|
msg_t* const msg = &parser.inMsg;
|
||||||
const int fh = clc.demofile;
|
const int fh = clc.demofile;
|
||||||
int numGamestates = 0;
|
|
||||||
|
|
||||||
Com_Memset(&parser, 0, sizeof(parser));
|
Com_Memset(&parser, 0, sizeof(parser));
|
||||||
parser.currSnap = &parser.ndpSnapshots[0];
|
parser.currSnap = &parser.ndpSnapshots[0];
|
||||||
|
@ -791,8 +804,8 @@ static void ParseDemo()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case svc_gamestate:
|
case svc_gamestate:
|
||||||
++numGamestates;
|
++parser.numGamestates;
|
||||||
if (numGamestates >= 2) {
|
if (parser.numGamestates >= 2) {
|
||||||
Warning("More than 1 gamestate found, only the first one was loaded");
|
Warning("More than 1 gamestate found, only the first one was loaded");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1065,15 +1078,18 @@ after_parse:
|
||||||
demo.nextSnap = &demo.snapshots[1];
|
demo.nextSnap = &demo.snapshots[1];
|
||||||
MB_InitRead(&demo.buffer);
|
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
|
// make sure we don't execute commands from the end of the demo when starting up
|
||||||
demo.commands[0].command[0] = '\0';
|
demo.commands[0].command[0] = '\0';
|
||||||
demo.commands[1].command[0] = '\0';
|
demo.commands[1].command[0] = '\0';
|
||||||
demo.numCommands = 1;
|
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;
|
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);
|
||||||
Com_DPrintf("New Demo Player: I-frame delay %d ms, %s -> %s (%.2fx)\n",
|
Com_DPrintf("New Demo Player: I-frame delay %d ms, %s -> %s (%.2fx)\n",
|
||||||
|
|
Loading…
Reference in a new issue