fix spectating issue.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4509 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2013-10-21 05:20:13 +00:00
parent 27debce140
commit df6ee13e90
2 changed files with 47 additions and 15 deletions

View file

@ -1552,6 +1552,8 @@ void CL_SendCmd (double frametime, qboolean mainloop)
cl.ackedmovesequence = cl.movesequence; cl.ackedmovesequence = cl.movesequence;
i = cl.movesequence & UPDATE_MASK; i = cl.movesequence & UPDATE_MASK;
cl.movesequence++; cl.movesequence++;
cl.outframes[i].server_message_num = cl.validsequence;
cl.outframes[i].cmd_sequence = cl.movesequence;
cl.outframes[i].senttime = realtime; // we haven't gotten a reply yet cl.outframes[i].senttime = realtime; // we haven't gotten a reply yet
// cl.outframes[i].receivedtime = -1; // we haven't gotten a reply yet // cl.outframes[i].receivedtime = -1; // we haven't gotten a reply yet
@ -1591,6 +1593,14 @@ void CL_SendCmd (double frametime, qboolean mainloop)
CL_FinishMove(cmd, cmd->msec, plnum); CL_FinishMove(cmd, cmd->msec, plnum);
Cam_FinishMove(&cl.playerview[plnum], cmd); Cam_FinishMove(&cl.playerview[plnum], cmd);
{
player_state_t *from, *to;
playerview_t *pv = &cl.playerview[plnum];
from = &cl.inframes[cl.ackedmovesequence & UPDATE_MASK].playerstate[pv->playernum];
to = &cl.inframes[cl.movesequence & UPDATE_MASK].playerstate[pv->playernum];
CL_PredictUsercmd(pv->playernum, pv->viewentity, from, to, &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[plnum]);
}
} }
while (clientcmdlist) while (clientcmdlist)

View file

@ -901,7 +901,7 @@ void CL_PredictMovePNum (int seat)
//these things also force-disable prediction //these things also force-disable prediction
if ((cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV) || if ((cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV) ||
cl.paused || pv->pmovetype == PM_NONE || pv->pmovetype == PM_FREEZE) cl.paused || pv->pmovetype == PM_NONE || pv->pmovetype == PM_FREEZE || pv->cam_locked)
{ {
nopred = true; nopred = true;
} }
@ -932,14 +932,14 @@ void CL_PredictMovePNum (int seat)
//we're only interested in inbound frames, not outbound, but its outbound frames that contain the prediction timing, so we need to look that up //we're only interested in inbound frames, not outbound, but its outbound frames that contain the prediction timing, so we need to look that up
//(note that in qw, inframe[i].ack==i holds true, but this code tries to be generic for unsyncronised protocols) //(note that in qw, inframe[i].ack==i holds true, but this code tries to be generic for unsyncronised protocols)
//(note that in nq, using outbound times means we'll skip over dupe states without noticing, and input packets with dupes should also be handled gracefully) //(note that in nq, using outbound times means we'll skip over dupe states without noticing, and input packets with dupes should also be handled gracefully)
Con_DPrintf("in:%i:%i out:%i:%i ack:%i\n", cls.netchan.incoming_sequence, cl.validsequence, cls.netchan.outgoing_sequence,cl.movesequence, cl.ackedmovesequence); // Con_DPrintf("in:%i:%i out:%i:%i ack:%i\n", cls.netchan.incoming_sequence, cl.validsequence, cls.netchan.outgoing_sequence,cl.movesequence, cl.ackedmovesequence);
for (i = cl.validsequence; i >= cls.netchan.incoming_sequence - UPDATE_MASK; i--) for (i = cl.validsequence; i >= cls.netchan.incoming_sequence - UPDATE_MASK; i--)
{ {
int out; int out;
//skip frames which were not received, or are otherwise invalid. yay packetloss //skip frames which were not received, or are otherwise invalid. yay packetloss
if (cl.inframes[i & UPDATE_MASK].frameid != i || cl.inframes[i & UPDATE_MASK].invalid) if (cl.inframes[i & UPDATE_MASK].frameid != i || cl.inframes[i & UPDATE_MASK].invalid)
{ {
Con_DPrintf("stale incoming command %i\n", i); // Con_DPrintf("stale incoming command %i\n", i);
continue; continue;
} }
@ -948,7 +948,7 @@ void CL_PredictMovePNum (int seat)
backdate = &cl.outframes[out & UPDATE_MASK]; backdate = &cl.outframes[out & UPDATE_MASK];
if (backdate->cmd_sequence != out) if (backdate->cmd_sequence != out)
{ {
Con_DPrintf("stale outgoing command %i (%i:%i:%i)\n", i, out, backdate->cmd_sequence, backdate->server_message_num); // Con_DPrintf("stale outgoing command %i (%i:%i:%i)\n", i, out, backdate->cmd_sequence, backdate->server_message_num);
continue; continue;
} }
//okay, looks valid //okay, looks valid
@ -968,10 +968,26 @@ void CL_PredictMovePNum (int seat)
} }
} }
Con_DPrintf("sim%f, %i(%i-%i): old%f, cur%f\n", simtime, cl.ackedmovesequence, fromframe, toframe, fromtime, totime); // Con_DPrintf("sim%f, %i(%i-%i): old%f, cur%f\n", simtime, cl.ackedmovesequence, fromframe, toframe, fromtime, totime);
if (pv->cam_locked && cl.spectator && pv->viewentity && pv->viewentity <= cl.allocated_client_slots)
{
fromstate = &cl.inframes[fromframe & UPDATE_MASK].playerstate[pv->viewentity-1];
tostate = &cl.inframes[toframe & UPDATE_MASK].playerstate[pv->viewentity-1];
}
else
{
if (cls.demoplayback==DPB_MVD || cls.demoplayback == DPB_EZTV)
{
fromstate = &cl.inframes[cl.ackedmovesequence & UPDATE_MASK].playerstate[pv->playernum];
tostate = &cl.inframes[cl.movesequence & UPDATE_MASK].playerstate[pv->playernum];
}
else
{
fromstate = &cl.inframes[fromframe & UPDATE_MASK].playerstate[pv->playernum]; fromstate = &cl.inframes[fromframe & UPDATE_MASK].playerstate[pv->playernum];
tostate = &cl.inframes[toframe & UPDATE_MASK].playerstate[pv->playernum]; tostate = &cl.inframes[toframe & UPDATE_MASK].playerstate[pv->playernum];
}
}
pv->pmovetype = tostate->pm_type; pv->pmovetype = tostate->pm_type;
le = &cl.lerpplayers[pv->playernum]; le = &cl.lerpplayers[pv->playernum];
@ -1020,6 +1036,9 @@ void CL_PredictMovePNum (int seat)
CL_SetSolidPlayers(); CL_SetSolidPlayers();
pmove.skipent = pv->viewentity; pmove.skipent = pv->viewentity;
//just in case we don't run any prediction
VectorCopy(tostate->gravitydir, pmove.gravitydir);
cmdfrom = cmdto = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[seat]; cmdfrom = cmdto = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[seat];
if (!nopred) if (!nopred)
@ -1034,14 +1053,14 @@ void CL_PredictMovePNum (int seat)
//we must always predict a frame, just to ensure that the playerstate's jump status etc is valid for the next frame, even if we're not going to use it for interpolation. //we must always predict a frame, just to ensure that the playerstate's jump status etc is valid for the next frame, even if we're not going to use it for interpolation.
//this assumes that we always have at least one video frame to each network frame, of course. //this assumes that we always have at least one video frame to each network frame, of course.
//note that q2 updates its values via networking rather than propagation. //note that q2 updates its values via networking rather than propagation.
Con_DPrintf(" propagate %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime); // Con_DPrintf(" propagate %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime);
CL_PredictUsercmd (seat, pv->viewentity, tostate, &cl.inframes[(toframe+i) & UPDATE_MASK].playerstate[pv->playernum], &of->cmd[seat]); CL_PredictUsercmd (seat, pv->viewentity, tostate, &cl.inframes[(toframe+i) & UPDATE_MASK].playerstate[pv->playernum], &of->cmd[seat]);
} }
break; break;
} }
if (of->cmd_sequence != cl.ackedmovesequence+i) if (of->cmd_sequence != cl.ackedmovesequence+i)
{ {
Con_DPrintf("trying to predict a frame which is no longer valid\n"); // Con_DPrintf("trying to predict a frame which is no longer valid\n");
break; break;
} }
fromtime = totime; fromtime = totime;
@ -1058,7 +1077,7 @@ void CL_PredictMovePNum (int seat)
else else
tostate = &framebuf[i&1]; tostate = &framebuf[i&1];
Con_DPrintf(" pred %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime); // Con_DPrintf(" pred %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime);
CL_PredictUsercmd (seat, pv->viewentity, fromstate, tostate, cmdto); CL_PredictUsercmd (seat, pv->viewentity, fromstate, tostate, cmdto);
} }
@ -1087,7 +1106,7 @@ void CL_PredictMovePNum (int seat)
cmdto->msec = bound(0, msec, 250); cmdto->msec = bound(0, msec, 250);
Con_DPrintf(" extrap %i: %f-%f\n", toframe, fromtime, simtime); // Con_DPrintf(" extrap %i: %f-%f\n", toframe, fromtime, simtime);
CL_PredictUsercmd (seat, pv->viewentity, fromstate, tostate, cmdto); CL_PredictUsercmd (seat, pv->viewentity, fromstate, tostate, cmdto);
} }
} }
@ -1101,7 +1120,10 @@ void CL_PredictMovePNum (int seat)
{ {
VectorCopy (tostate->velocity, pv->simvel); VectorCopy (tostate->velocity, pv->simvel);
VectorCopy (tostate->origin, pv->simorg); VectorCopy (tostate->origin, pv->simorg);
Con_DPrintf("%f %f %f\n", fromtime, simtime, totime);
if (pv->viewentity && pv->viewentity != pv->playernum+1)
VectorCopy(tostate->viewangles, pv->simangles);
//Con_DPrintf("%f %f %f\n", fromtime, simtime, totime);
} }
else else
{ {
@ -1113,7 +1135,7 @@ Con_DPrintf("%f %f %f\n", fromtime, simtime, totime);
f = 0; f = 0;
if (f > 1) if (f > 1)
f = 1; f = 1;
Con_DPrintf("%i:%f %f %i:%f (%f)\n", fromframe, fromtime, simtime, toframe, totime, f); //Con_DPrintf("%i:%f %f %i:%f (%f)\n", fromframe, fromtime, simtime, toframe, totime, f);
VectorSubtract(tostate->origin, fromstate->origin, move); VectorSubtract(tostate->origin, fromstate->origin, move);
if (DotProduct(move, move) > 128*128) if (DotProduct(move, move) > 128*128)
{ {
@ -1129,7 +1151,7 @@ Con_DPrintf("%i:%f %f %i:%f (%f)\n", fromframe, fromtime, simtime, toframe, toti
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->playernum+1) if (pv->viewentity && pv->viewentity != pv->playernum+1)
{ {
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);