fix some demo playback/capture issues.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4887 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
e3939dfb58
commit
1b5b04dfa7
8 changed files with 65 additions and 27 deletions
|
@ -119,7 +119,7 @@ void CL_WriteDemoCmd (usercmd_t *pcmd)
|
||||||
cmd.msec = pcmd->msec;
|
cmd.msec = pcmd->msec;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
cmd.angles[i] = LittleFloat(pcmd->angles[i]*65536/360);
|
cmd.angles[i] = LittleShort((pcmd->angles[i]*360.0)/65535);
|
||||||
|
|
||||||
cmd.forwardmove = LittleShort(pcmd->forwardmove);
|
cmd.forwardmove = LittleShort(pcmd->forwardmove);
|
||||||
cmd.sidemove = LittleShort(pcmd->sidemove);
|
cmd.sidemove = LittleShort(pcmd->sidemove);
|
||||||
|
@ -682,7 +682,7 @@ readnext:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// user sent input
|
// user sent input
|
||||||
i = cls.netchan.outgoing_sequence & UPDATE_MASK;
|
i = cl.movesequence & UPDATE_MASK;
|
||||||
pcmd = &cl.outframes[i].cmd[0];
|
pcmd = &cl.outframes[i].cmd[0];
|
||||||
r = readdemobytes (&demopos, &q1cmd, sizeof(q1cmd));
|
r = readdemobytes (&demopos, &q1cmd, sizeof(q1cmd));
|
||||||
if (r != sizeof(q1cmd))
|
if (r != sizeof(q1cmd))
|
||||||
|
|
|
@ -977,9 +977,12 @@ void CLQW_ParsePacketEntities (qboolean delta)
|
||||||
}
|
}
|
||||||
else if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD)
|
else if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD)
|
||||||
{
|
{
|
||||||
|
extern cvar_t cl_demospeed;
|
||||||
|
float scale = cls.demoplayback?cl_demospeed.value:1;
|
||||||
cl.oldgametime = cl.gametime;
|
cl.oldgametime = cl.gametime;
|
||||||
cl.oldgametimemark = cl.gametimemark;
|
cl.oldgametimemark = cl.gametimemark;
|
||||||
cl.gametime = realtime;//cl.frames[newpacket].senttime - cl.frames[(newpacket-1)&UPDATE_MASK].senttime;
|
if (realtime - cl.gametimemark > 0)
|
||||||
|
cl.gametime += (realtime - cl.gametimemark)*scale;//cl.frames[newpacket].senttime - cl.frames[(newpacket-1)&UPDATE_MASK].senttime;
|
||||||
cl.gametimemark = realtime;
|
cl.gametimemark = realtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3824,7 +3827,7 @@ void CL_MVDUpdateSpectator(void)
|
||||||
|
|
||||||
void CL_ParsePlayerinfo (void)
|
void CL_ParsePlayerinfo (void)
|
||||||
{
|
{
|
||||||
int msec;
|
float msec;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
player_info_t *info;
|
player_info_t *info;
|
||||||
player_state_t *state, *oldstate;
|
player_state_t *state, *oldstate;
|
||||||
|
@ -3990,8 +3993,12 @@ void CL_ParsePlayerinfo (void)
|
||||||
// the exact time it was valid at
|
// the exact time it was valid at
|
||||||
if (flags & PF_MSEC)
|
if (flags & PF_MSEC)
|
||||||
{
|
{
|
||||||
|
extern cvar_t cl_demospeed;
|
||||||
msec = MSG_ReadByte ();
|
msec = MSG_ReadByte ();
|
||||||
state->state_time = parsecounttime - msec*0.001;
|
if (cls.demoplayback)
|
||||||
|
state->state_time = parsecounttime - msec*0.001 * cl_demospeed.value;
|
||||||
|
else
|
||||||
|
state->state_time = parsecounttime - msec*0.001;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4315,8 +4322,8 @@ void CL_LinkPlayers (void)
|
||||||
player_state_t exact;
|
player_state_t exact;
|
||||||
double playertime;
|
double playertime;
|
||||||
entity_t *ent;
|
entity_t *ent;
|
||||||
int msec;
|
float msec;
|
||||||
inframe_t *frame;
|
inframe_t *frame;
|
||||||
int oldphysent;
|
int oldphysent;
|
||||||
vec3_t angles;
|
vec3_t angles;
|
||||||
qboolean predictplayers;
|
qboolean predictplayers;
|
||||||
|
@ -4325,12 +4332,15 @@ void CL_LinkPlayers (void)
|
||||||
static int flicker;
|
static int flicker;
|
||||||
float predictmsmult = 1000*cl_predict_players_frac.value;
|
float predictmsmult = 1000*cl_predict_players_frac.value;
|
||||||
int modelindex2;
|
int modelindex2;
|
||||||
|
extern cvar_t cl_demospeed;
|
||||||
|
|
||||||
if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED)
|
if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (cl.paused)
|
if (cl.paused)
|
||||||
predictmsmult = 0;
|
predictmsmult = 0;
|
||||||
|
if (cls.demoplayback)
|
||||||
|
predictmsmult *= cl_demospeed.value;
|
||||||
|
|
||||||
playertime = realtime - cls.latency + 0.02;
|
playertime = realtime - cls.latency + 0.02;
|
||||||
if (playertime > realtime)
|
if (playertime > realtime)
|
||||||
|
@ -4867,7 +4877,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
|
||||||
int msec;
|
int msec;
|
||||||
inframe_t *frame;
|
inframe_t *frame;
|
||||||
struct predicted_player *pplayer;
|
struct predicted_player *pplayer;
|
||||||
extern cvar_t cl_nopred;
|
extern cvar_t cl_nopred, cl_demospeed;
|
||||||
float predictmsmult = 1000*cl_predict_players_frac.value;
|
float predictmsmult = 1000*cl_predict_players_frac.value;
|
||||||
|
|
||||||
int s;
|
int s;
|
||||||
|
@ -4879,6 +4889,9 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
|
||||||
if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused || cl.worldmodel->loadstate != MLS_LOADED)
|
if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused || cl.worldmodel->loadstate != MLS_LOADED)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (cls.demoplayback)
|
||||||
|
predictmsmult *= cl_demospeed.value;
|
||||||
|
|
||||||
frame = &cl.inframes[cl.parsecount&UPDATE_MASK];
|
frame = &cl.inframes[cl.parsecount&UPDATE_MASK];
|
||||||
|
|
||||||
for (j=0, pplayer = predicted_players, state=frame->playerstate;
|
for (j=0, pplayer = predicted_players, state=frame->playerstate;
|
||||||
|
|
|
@ -4411,7 +4411,7 @@ void CL_ParseClientdata (void)
|
||||||
cl.parsecount = i;
|
cl.parsecount = i;
|
||||||
i &= UPDATE_MASK;
|
i &= UPDATE_MASK;
|
||||||
parsecountmod = i;
|
parsecountmod = i;
|
||||||
parsecounttime = cl.outframes[i].senttime;
|
parsecounttime = realtime;//cl.outframes[i].senttime;
|
||||||
|
|
||||||
if (cls.protocol == CP_QUAKEWORLD)
|
if (cls.protocol == CP_QUAKEWORLD)
|
||||||
CL_AckedInputFrame(cls.netchan.incoming_sequence, cl.parsecount, false);
|
CL_AckedInputFrame(cls.netchan.incoming_sequence, cl.parsecount, false);
|
||||||
|
|
|
@ -842,13 +842,14 @@ void CL_PredictMovePNum (int seat)
|
||||||
int fromframe, toframe;
|
int fromframe, toframe;
|
||||||
outframe_t *backdate;
|
outframe_t *backdate;
|
||||||
player_state_t *fromstate, *tostate, framebuf[2]; //need two framebufs so we can interpolate between two states.
|
player_state_t *fromstate, *tostate, framebuf[2]; //need two framebufs so we can interpolate between two states.
|
||||||
usercmd_t *cmdto;
|
usercmd_t *cmdfrom = NULL, *cmdto = NULL;
|
||||||
double fromtime, totime;
|
double fromtime, totime;
|
||||||
int oldphysent;
|
int oldphysent;
|
||||||
double simtime; //this is server time if nopred is set (lerp-only), and local time if we're predicting
|
double simtime; //this is server time if nopred is set (lerp-only), and local time if we're predicting
|
||||||
extern cvar_t cl_netfps;
|
extern cvar_t cl_netfps;
|
||||||
lerpents_t *le;
|
lerpents_t *le;
|
||||||
qboolean nopred;
|
qboolean nopred;
|
||||||
|
qboolean lerpangles = false;
|
||||||
|
|
||||||
//these are to make svc_viewentity work better
|
//these are to make svc_viewentity work better
|
||||||
float netfps = cl_netfps.value;
|
float netfps = cl_netfps.value;
|
||||||
|
@ -883,6 +884,7 @@ void CL_PredictMovePNum (int seat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simtime -= cls.latency;
|
||||||
simtime += bound(-0.5, cl_predict_timenudge.value, 0.5);
|
simtime += bound(-0.5, cl_predict_timenudge.value, 0.5);
|
||||||
|
|
||||||
pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD);
|
pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD);
|
||||||
|
@ -923,9 +925,15 @@ void CL_PredictMovePNum (int seat)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
VectorCopy(cl.currentpackentities->fixedangles[seat], pv->simangles);
|
VectorCopy(cl.currentpackentities->fixedangles[seat], pv->simangles);
|
||||||
|
|
||||||
|
if (cl.currentpackentities->fixangles[seat] == 2)
|
||||||
|
lerpangles = (cls.demoplayback == DPB_QUAKEWORLD);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
lerpangles = (cls.demoplayback == DPB_QUAKEWORLD);
|
||||||
VectorCopy (pv->viewangles, pv->simangles);
|
VectorCopy (pv->viewangles, pv->simangles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pv->cam_locked && pv->cam_spec_track >= 0)
|
if (pv->cam_locked && pv->cam_spec_track >= 0)
|
||||||
|
@ -1024,8 +1032,10 @@ void CL_PredictMovePNum (int seat)
|
||||||
}
|
}
|
||||||
toframe = fromframe;
|
toframe = fromframe;
|
||||||
totime = fromtime;
|
totime = fromtime;
|
||||||
|
cmdto = cmdfrom;
|
||||||
fromframe = i;
|
fromframe = i;
|
||||||
fromtime = backdate->senttime;
|
fromtime = backdate->senttime;
|
||||||
|
cmdfrom = &backdate->cmd[seat];
|
||||||
if (fromtime < simtime && fromframe != toframe)
|
if (fromtime < simtime && fromframe != toframe)
|
||||||
break; //okay, we found the first frame that is older, no need to continue looking
|
break; //okay, we found the first frame that is older, no need to continue looking
|
||||||
}
|
}
|
||||||
|
@ -1054,6 +1064,11 @@ void CL_PredictMovePNum (int seat)
|
||||||
pv->pmovetype = tostate->pm_type;
|
pv->pmovetype = tostate->pm_type;
|
||||||
le = &cl.lerpplayers[pv->playernum];
|
le = &cl.lerpplayers[pv->playernum];
|
||||||
|
|
||||||
|
if (!cmdfrom)
|
||||||
|
cmdfrom = &cl.outframes[fromframe & UPDATE_MASK].cmd[pv->playernum];
|
||||||
|
if (!cmdto)
|
||||||
|
cmdto = &cl.outframes[toframe & UPDATE_MASK].cmd[pv->playernum];
|
||||||
|
|
||||||
//if our network protocol doesn't have a concept of separate players, make sure our player states are updated from those entities
|
//if our network protocol doesn't have a concept of separate players, make sure our player states are updated from those entities
|
||||||
//fixme: use entity states instead of player states to avoid the extra work here
|
//fixme: use entity states instead of player states to avoid the extra work here
|
||||||
if (pv->nolocalplayer || nopred)
|
if (pv->nolocalplayer || nopred)
|
||||||
|
@ -1103,8 +1118,6 @@ void CL_PredictMovePNum (int seat)
|
||||||
//just in case we don't run any prediction
|
//just in case we don't run any prediction
|
||||||
VectorCopy(tostate->gravitydir, pmove.gravitydir);
|
VectorCopy(tostate->gravitydir, pmove.gravitydir);
|
||||||
|
|
||||||
cmdto = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[seat];
|
|
||||||
|
|
||||||
if (nopred)
|
if (nopred)
|
||||||
{ //still need the player's size for onground detection and bobbing.
|
{ //still need the player's size for onground detection and bobbing.
|
||||||
VectorCopy(tostate->szmins, pmove.player_mins);
|
VectorCopy(tostate->szmins, pmove.player_mins);
|
||||||
|
@ -1140,6 +1153,7 @@ void CL_PredictMovePNum (int seat)
|
||||||
fromtime = totime;
|
fromtime = totime;
|
||||||
fromstate = tostate;
|
fromstate = tostate;
|
||||||
fromframe = toframe; //qw debug
|
fromframe = toframe; //qw debug
|
||||||
|
cmdfrom = cmdto;
|
||||||
|
|
||||||
cmdto = &of->cmd[seat];
|
cmdto = &of->cmd[seat];
|
||||||
totime = of->senttime;
|
totime = of->senttime;
|
||||||
|
@ -1166,6 +1180,7 @@ void CL_PredictMovePNum (int seat)
|
||||||
fromstate = tostate;
|
fromstate = tostate;
|
||||||
fromtime = totime;
|
fromtime = totime;
|
||||||
fromframe = toframe;
|
fromframe = toframe;
|
||||||
|
cmdfrom = cmdto;
|
||||||
|
|
||||||
tostate = &framebuf[i++&1];
|
tostate = &framebuf[i++&1];
|
||||||
if (independantphysics[seat].msec && !cls.demoplayback)
|
if (independantphysics[seat].msec && !cls.demoplayback)
|
||||||
|
@ -1176,6 +1191,12 @@ void CL_PredictMovePNum (int seat)
|
||||||
totime = simtime;
|
totime = simtime;
|
||||||
toframe+=1;
|
toframe+=1;
|
||||||
|
|
||||||
|
if (cls.demoplayback)
|
||||||
|
{
|
||||||
|
extern cvar_t cl_demospeed;
|
||||||
|
msec *= cl_demospeed.value;
|
||||||
|
}
|
||||||
|
|
||||||
cmdto->msec = bound(0, msec, 250);
|
cmdto->msec = bound(0, msec, 250);
|
||||||
|
|
||||||
// Con_DPrintf(" extrap %i: %f-%f (%g)\n", toframe, fromtime, simtime, simtime-fromtime);
|
// Con_DPrintf(" extrap %i: %f-%f (%g)\n", toframe, fromtime, simtime, simtime-fromtime);
|
||||||
|
@ -1219,15 +1240,17 @@ void CL_PredictMovePNum (int seat)
|
||||||
{
|
{
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
{
|
{
|
||||||
|
extern cvar_t temp1;
|
||||||
pv->simorg[i] = (1-f)*fromstate->origin[i] + f*tostate->origin[i];
|
pv->simorg[i] = (1-f)*fromstate->origin[i] + f*tostate->origin[i];
|
||||||
pv->simvel[i] = (1-f)*fromstate->velocity[i] + f*tostate->velocity[i];
|
pv->simvel[i] = (1-f)*fromstate->velocity[i] + f*tostate->velocity[i];
|
||||||
|
|
||||||
|
|
||||||
if (pv->viewentity && pv->viewentity != pv->playernum+1 && pv->cam_locked)
|
if (pv->viewentity && pv->viewentity != pv->playernum+1 && pv->cam_locked)
|
||||||
{
|
{
|
||||||
pv->simangles[i] = LerpAngles360(fromstate->viewangles[i], tostate->viewangles[i], f);// * (360.0/65535);
|
pv->simangles[i] = LerpAngles360(fromstate->viewangles[i], tostate->viewangles[i], f);// * (360.0/65535);
|
||||||
// pv->viewangles[i] = LerpAngles16(fromstate->command.angles[i], tostate->command.angles[i], f) * (360.0/65535);
|
// pv->viewangles[i] = LerpAngles16(fromstate->command.angles[i], tostate->command.angles[i], f) * (360.0/65535);
|
||||||
}
|
}
|
||||||
|
else if (lerpangles)
|
||||||
|
pv->simangles[i] = LerpAngles16(cmdfrom->angles[i], cmdto->angles[i], f) * (360.0/65535);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2716,7 +2716,7 @@ static void *QDECL capture_avi_begin (char *streamname, int videorate, int width
|
||||||
hr = qAVIMakeCompressedStream(&ctx->compressed_video_stream, ctx->uncompressed_video_stream, &opts, NULL);
|
hr = qAVIMakeCompressedStream(&ctx->compressed_video_stream, ctx->uncompressed_video_stream, &opts, NULL);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
Con_Printf("AVIMakeCompressedStream failed. check codec.\n");
|
Con_Printf("AVIMakeCompressedStream failed. check video codec.\n");
|
||||||
capture_avi_end(ctx);
|
capture_avi_end(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -3139,6 +3139,8 @@ void Media_RecordFilm_f (void)
|
||||||
captureframeinterval = 0.001; //no more than 1000 images per second.
|
captureframeinterval = 0.001; //no more than 1000 images per second.
|
||||||
capturelastvideotime = realtime = 0;
|
capturelastvideotime = realtime = 0;
|
||||||
|
|
||||||
|
Con_ClearNotify();
|
||||||
|
|
||||||
captureframe = 0;
|
captureframe = 0;
|
||||||
for (i = 0; i < sizeof(pluginencodersfunc)/sizeof(pluginencodersfunc[0]); i++)
|
for (i = 0; i < sizeof(pluginencodersfunc)/sizeof(pluginencodersfunc[0]); i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -330,7 +330,7 @@ cvar_t gl_smoothcrosshair = SCVAR ("gl_smoothcrosshair", "1");
|
||||||
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
||||||
|
|
||||||
#ifdef SPECULAR
|
#ifdef SPECULAR
|
||||||
cvar_t gl_specular = CVARF ("gl_specular", "1", CVAR_ARCHIVE);
|
cvar_t gl_specular = CVARF ("gl_specular", "0.3", CVAR_ARCHIVE);
|
||||||
cvar_t gl_specular_fallback = CVARF ("gl_specular_fallback", "0.05", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
cvar_t gl_specular_fallback = CVARF ("gl_specular_fallback", "0.05", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||||
cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1133,7 +1133,7 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
|
||||||
MSG_WriteByte (buf, cmd->buttons);
|
MSG_WriteByte (buf, cmd->buttons);
|
||||||
if (bits & Q2CM_IMPULSE)
|
if (bits & Q2CM_IMPULSE)
|
||||||
MSG_WriteByte (buf, cmd->impulse);
|
MSG_WriteByte (buf, cmd->impulse);
|
||||||
MSG_WriteByte (buf, cmd->msec);
|
MSG_WriteByte (buf, bound(0, cmd->msec, 255));
|
||||||
|
|
||||||
MSG_WriteByte (buf, cmd->lightlevel);
|
MSG_WriteByte (buf, cmd->lightlevel);
|
||||||
|
|
||||||
|
@ -1178,7 +1178,7 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd)
|
||||||
MSG_WriteByte (buf, cmd->buttons);
|
MSG_WriteByte (buf, cmd->buttons);
|
||||||
if (bits & CM_IMPULSE)
|
if (bits & CM_IMPULSE)
|
||||||
MSG_WriteByte (buf, cmd->impulse);
|
MSG_WriteByte (buf, cmd->impulse);
|
||||||
MSG_WriteByte (buf, cmd->msec&0xff);
|
MSG_WriteByte (buf, bound(0, cmd->msec, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1046,17 +1046,17 @@ typedef struct usercmd_s
|
||||||
qbyte lightlevel;
|
qbyte lightlevel;
|
||||||
|
|
||||||
//freestyle
|
//freestyle
|
||||||
int msec;
|
float msec;
|
||||||
int buttons;
|
int buttons;
|
||||||
int weapon;
|
int weapon;
|
||||||
int servertime;
|
int servertime;
|
||||||
float fservertime;
|
float fservertime;
|
||||||
float fclienttime;
|
float fclienttime;
|
||||||
|
|
||||||
vec2_t cursor_screen;
|
vec2_t cursor_screen;
|
||||||
vec3_t cursor_start;
|
vec3_t cursor_start;
|
||||||
vec3_t cursor_impact;
|
vec3_t cursor_impact;
|
||||||
int cursor_entitynumber;
|
int cursor_entitynumber;
|
||||||
} usercmd_t;
|
} usercmd_t;
|
||||||
|
|
||||||
typedef struct q2usercmd_s
|
typedef struct q2usercmd_s
|
||||||
|
|
Loading…
Reference in a new issue