diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index b99123ca9..f404aaea6 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -119,7 +119,7 @@ void CL_WriteDemoCmd (usercmd_t *pcmd) cmd.msec = pcmd->msec; 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.sidemove = LittleShort(pcmd->sidemove); @@ -682,7 +682,7 @@ readnext: else { // user sent input - i = cls.netchan.outgoing_sequence & UPDATE_MASK; + i = cl.movesequence & UPDATE_MASK; pcmd = &cl.outframes[i].cmd[0]; r = readdemobytes (&demopos, &q1cmd, sizeof(q1cmd)); if (r != sizeof(q1cmd)) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 840c2e8c8..50029849d 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -977,9 +977,12 @@ void CLQW_ParsePacketEntities (qboolean delta) } 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.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; } @@ -3824,7 +3827,7 @@ void CL_MVDUpdateSpectator(void) void CL_ParsePlayerinfo (void) { - int msec; + float msec; unsigned int flags; player_info_t *info; player_state_t *state, *oldstate; @@ -3990,8 +3993,12 @@ void CL_ParsePlayerinfo (void) // the exact time it was valid at if (flags & PF_MSEC) { + extern cvar_t cl_demospeed; 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 { @@ -4315,8 +4322,8 @@ void CL_LinkPlayers (void) player_state_t exact; double playertime; entity_t *ent; - int msec; - inframe_t *frame; + float msec; + inframe_t *frame; int oldphysent; vec3_t angles; qboolean predictplayers; @@ -4325,12 +4332,15 @@ void CL_LinkPlayers (void) static int flicker; float predictmsmult = 1000*cl_predict_players_frac.value; int modelindex2; + extern cvar_t cl_demospeed; if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED) return; if (cl.paused) predictmsmult = 0; + if (cls.demoplayback) + predictmsmult *= cl_demospeed.value; playertime = realtime - cls.latency + 0.02; if (playertime > realtime) @@ -4867,7 +4877,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) int msec; inframe_t *frame; struct predicted_player *pplayer; - extern cvar_t cl_nopred; + extern cvar_t cl_nopred, cl_demospeed; float predictmsmult = 1000*cl_predict_players_frac.value; int s; @@ -4879,6 +4889,9 @@ void CL_SetUpPlayerPrediction(qboolean dopred) if (cl_nopred.value || /*cls.demoplayback ||*/ cl.paused || cl.worldmodel->loadstate != MLS_LOADED) return; + if (cls.demoplayback) + predictmsmult *= cl_demospeed.value; + frame = &cl.inframes[cl.parsecount&UPDATE_MASK]; for (j=0, pplayer = predicted_players, state=frame->playerstate; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 453d398e0..e34b96315 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -4411,7 +4411,7 @@ void CL_ParseClientdata (void) cl.parsecount = i; i &= UPDATE_MASK; parsecountmod = i; - parsecounttime = cl.outframes[i].senttime; + parsecounttime = realtime;//cl.outframes[i].senttime; if (cls.protocol == CP_QUAKEWORLD) CL_AckedInputFrame(cls.netchan.incoming_sequence, cl.parsecount, false); diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 931b1885e..42df73f3c 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -842,13 +842,14 @@ void CL_PredictMovePNum (int seat) int fromframe, toframe; outframe_t *backdate; 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; int oldphysent; double simtime; //this is server time if nopred is set (lerp-only), and local time if we're predicting extern cvar_t cl_netfps; lerpents_t *le; qboolean nopred; + qboolean lerpangles = false; //these are to make svc_viewentity work better 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); pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD); @@ -923,9 +925,15 @@ void CL_PredictMovePNum (int seat) } else VectorCopy(cl.currentpackentities->fixedangles[seat], pv->simangles); + + if (cl.currentpackentities->fixangles[seat] == 2) + lerpangles = (cls.demoplayback == DPB_QUAKEWORLD); } else + { + lerpangles = (cls.demoplayback == DPB_QUAKEWORLD); VectorCopy (pv->viewangles, pv->simangles); + } } if (pv->cam_locked && pv->cam_spec_track >= 0) @@ -1024,8 +1032,10 @@ void CL_PredictMovePNum (int seat) } toframe = fromframe; totime = fromtime; + cmdto = cmdfrom; fromframe = i; fromtime = backdate->senttime; + cmdfrom = &backdate->cmd[seat]; if (fromtime < simtime && fromframe != toframe) 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; 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 //fixme: use entity states instead of player states to avoid the extra work here if (pv->nolocalplayer || nopred) @@ -1103,8 +1118,6 @@ void CL_PredictMovePNum (int seat) //just in case we don't run any prediction VectorCopy(tostate->gravitydir, pmove.gravitydir); - cmdto = &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[seat]; - if (nopred) { //still need the player's size for onground detection and bobbing. VectorCopy(tostate->szmins, pmove.player_mins); @@ -1140,6 +1153,7 @@ void CL_PredictMovePNum (int seat) fromtime = totime; fromstate = tostate; fromframe = toframe; //qw debug + cmdfrom = cmdto; cmdto = &of->cmd[seat]; totime = of->senttime; @@ -1166,6 +1180,7 @@ void CL_PredictMovePNum (int seat) fromstate = tostate; fromtime = totime; fromframe = toframe; + cmdfrom = cmdto; tostate = &framebuf[i++&1]; if (independantphysics[seat].msec && !cls.demoplayback) @@ -1176,6 +1191,12 @@ void CL_PredictMovePNum (int seat) totime = simtime; toframe+=1; + if (cls.demoplayback) + { + extern cvar_t cl_demospeed; + msec *= cl_demospeed.value; + } + cmdto->msec = bound(0, msec, 250); // 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++) { + extern cvar_t temp1; pv->simorg[i] = (1-f)*fromstate->origin[i] + f*tostate->origin[i]; pv->simvel[i] = (1-f)*fromstate->velocity[i] + f*tostate->velocity[i]; - 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->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); } } } diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 8ff436320..d3d16c892 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -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); if (FAILED(hr)) { - Con_Printf("AVIMakeCompressedStream failed. check codec.\n"); + Con_Printf("AVIMakeCompressedStream failed. check video codec.\n"); capture_avi_end(ctx); return NULL; } @@ -3139,6 +3139,8 @@ void Media_RecordFilm_f (void) captureframeinterval = 0.001; //no more than 1000 images per second. capturelastvideotime = realtime = 0; + Con_ClearNotify(); + captureframe = 0; for (i = 0; i < sizeof(pluginencodersfunc)/sizeof(pluginencodersfunc[0]); i++) { diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 9a2624690..2a1e1b142 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -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."); #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_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR_ARCHIVE|CVAR_RENDERERLATCH); #endif diff --git a/engine/common/common.c b/engine/common/common.c index de2297960..486abeaea 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1133,7 +1133,7 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) MSG_WriteByte (buf, cmd->buttons); if (bits & Q2CM_IMPULSE) MSG_WriteByte (buf, cmd->impulse); - MSG_WriteByte (buf, cmd->msec); + MSG_WriteByte (buf, bound(0, cmd->msec, 255)); 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); if (bits & CM_IMPULSE) MSG_WriteByte (buf, cmd->impulse); - MSG_WriteByte (buf, cmd->msec&0xff); + MSG_WriteByte (buf, bound(0, cmd->msec, 255)); } } diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 8ffbe1dc7..98965d31a 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -1046,17 +1046,17 @@ typedef struct usercmd_s qbyte lightlevel; //freestyle - int msec; - int buttons; - int weapon; - int servertime; - float fservertime; - float fclienttime; + float msec; + int buttons; + int weapon; + int servertime; + float fservertime; + float fclienttime; - vec2_t cursor_screen; - vec3_t cursor_start; - vec3_t cursor_impact; - int cursor_entitynumber; + vec2_t cursor_screen; + vec3_t cursor_start; + vec3_t cursor_impact; + int cursor_entitynumber; } usercmd_t; typedef struct q2usercmd_s