X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=cl_input.c;h=651e9d28ee56f6b4e928cde0458d76266de82786;hb=e2e22c8380e0e9e6be93a25ebf201ca932a8b7bc;hp=a1e8cb85b6fa3912a51c9f24888340a461281951;hpb=d6dc18d3bd0af73f03a5856c8f7472b6f8caab08;p=xonotic%2Fdarkplaces.git diff --git a/cl_input.c b/cl_input.c index a1e8cb85..651e9d28 100644 --- a/cl_input.c +++ b/cl_input.c @@ -1294,13 +1294,30 @@ static void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t VectorMA( s->velocity, accelspeed, acceldir, s->velocity ); } +static void CL_ClientMovement_Physics_CheckJump(cl_clientmovement_state_t *s) +{ + // jump if on ground with jump button pressed but only if it has been + // released at least once since the last jump + if (s->cmd.jump) + { + if (s->onground && (s->cmd.canjump || !cl_movement_track_canjump.integer)) + { + s->velocity[2] += cl.movevars_jumpvelocity; + s->onground = false; + s->cmd.canjump = false; + } + } + else + s->cmd.canjump = true; +} + static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) { vec_t friction; vec_t wishspeed; vec_t addspeed; vec_t accelspeed; - vec_t f; + vec_t speed; vec_t gravity; vec3_t forward; vec3_t right; @@ -1310,19 +1327,7 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) vec3_t yawangles; trace_t trace; - // jump if on ground with jump button pressed but only if it has been - // released at least once since the last jump - if (s->cmd.jump) - { - if (s->onground && (s->cmd.canjump || !cl_movement_track_canjump.integer)) - { - s->velocity[2] += cl.movevars_jumpvelocity; - s->onground = false; - s->cmd.canjump = false; - } - } - else - s->cmd.canjump = true; + CL_ClientMovement_Physics_CheckJump(s); // calculate movement vector VectorSet(yawangles, 0, s->cmd.viewangles[1], 0); @@ -1341,8 +1346,8 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) wishspeed *= 0.5; // apply edge friction - f = sqrt(s->velocity[0] * s->velocity[0] + s->velocity[1] * s->velocity[1]); - if (f > 0) + speed = VectorLength2(s->velocity); + if (speed > 0) { friction = cl.movevars_friction; if (cl.movevars_edgefriction != 1) @@ -1352,7 +1357,7 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) // note: QW uses the full player box for the trace, and yet still // uses s->origin[2] + s->mins[2], which is clearly an bug, but // this mimics it for compatibility - VectorSet(neworigin2, s->origin[0] + s->velocity[0]*(16/f), s->origin[1] + s->velocity[1]*(16/f), s->origin[2] + s->mins[2]); + VectorSet(neworigin2, s->origin[0] + s->velocity[0]*(16/speed), s->origin[1] + s->velocity[1]*(16/speed), s->origin[2] + s->mins[2]); VectorSet(neworigin3, neworigin2[0], neworigin2[1], neworigin2[2] - 34); if (cls.protocol == PROTOCOL_QUAKEWORLD) trace = CL_TraceBox(neworigin2, s->mins, s->maxs, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); @@ -1362,9 +1367,9 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) friction *= cl.movevars_edgefriction; } // apply ground friction - f = 1 - s->cmd.frametime * friction * ((f < cl.movevars_stopspeed) ? (cl.movevars_stopspeed / f) : 1); - f = max(f, 0); - VectorScale(s->velocity, f, s->velocity); + speed = 1 - s->cmd.frametime * friction * ((speed < cl.movevars_stopspeed) ? (cl.movevars_stopspeed / speed) : 1); + speed = max(speed, 0); + VectorScale(s->velocity, speed, s->velocity); } addspeed = wishspeed - DotProduct(s->velocity, wishdir); if (addspeed > 0) @@ -1512,7 +1517,7 @@ void CL_UpdateMoveVars(void) else { cl.moveflags = 0; - cl.movevars_ticrate = (cls.demoplayback ? 1.0f : host_timescale.value) / bound(1.0f, cl_netfps.value, 1000.0f); + cl.movevars_ticrate = (cls.demoplayback ? 1.0f : host_timescale.value) / bound(10.0f, cl_netfps.value, 1000.0f); cl.movevars_timescale = (cls.demoplayback ? 1.0f : host_timescale.value); cl.movevars_gravity = sv_gravity.value; cl.movevars_stopspeed = cl_movement_stopspeed.value; @@ -1751,8 +1756,7 @@ void CL_SendMove(void) usercmd_t *cmd; sizebuf_t buf; unsigned char data[1024]; - double packettime; - int msecdelta; + float packettime; qbool quemove; qbool important; @@ -1808,12 +1812,14 @@ void CL_SendMove(void) // set viewangles VectorCopy(cl.viewangles, cl.cmd.viewangles); - msecdelta = (int)(floor(cl.cmd.time * 1000) - floor(cl.movecmd[1].time * 1000)); - cl.cmd.msec = (unsigned char)bound(0, msecdelta, 255); + // bones_was_here: previously cl.cmd.frametime was floored to nearest millisec + // this meant the smoothest async movement required integer millisec + // client and server frame times (eg 125fps) + cl.cmd.frametime = bound(0.0, cl.cmd.time - cl.movecmd[1].time, 0.255); // ridiculous value rejection (matches qw) - if (cl.cmd.msec > 250) - cl.cmd.msec = 100; - cl.cmd.frametime = cl.cmd.msec * (1.0 / 1000.0); + if (cl.cmd.frametime > 0.25) + cl.cmd.frametime = 0.1; + cl.cmd.msec = (unsigned char)floor(cl.cmd.frametime * 1000); switch(cls.protocol) { @@ -1865,30 +1871,47 @@ void CL_SendMove(void) cl.movecmd[0] = cl.cmd; // don't predict more than 200fps - if (host.realtime >= cl.lastpackettime + 0.005) + if (cl.timesincepacket >= 0.005) cl.movement_replay = true; // redo the prediction // now decide whether to actually send this move // (otherwise it is only for prediction) + // do not send 0ms packets because they mess up physics + if(cl.cmd.msec == 0 && cl.time > cl.oldtime && (cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon == SIGNONS)) + return; + // don't send too often or else network connections can get clogged by a // high renderer framerate - packettime = 1.0 / bound(1, cl_netfps.value, 1000); + packettime = 1.0f / bound(10.0f, cl_netfps.value, 1000.0f); if (cl.movevars_timescale && cl.movevars_ticrate) { + // try to ensure at least 1 packet per server frame + // and apply soft limit of 2, hard limit < 4 (packettime reduced further below) float maxtic = cl.movevars_ticrate / cl.movevars_timescale; - packettime = min(packettime, maxtic); + packettime = bound(maxtic * 0.5f, packettime, maxtic); } + // bones_was_here: reduce packettime to (largest multiple of realframetime) <= packettime + // prevents packet rates lower than cl_netfps or server frame rate + // eg: cl_netfps 60 and cl_maxfps 250 would otherwise send only 50 netfps + // with this line that config sends 62.5 netfps + // (this causes it to emit packets at a steady beat) + packettime = floor(packettime / (float)cl.realframetime) * (float)cl.realframetime; - // do not send 0ms packets because they mess up physics - if(cl.cmd.msec == 0 && cl.time > cl.oldtime && (cls.protocol == PROTOCOL_QUAKEWORLD || cls.signon == SIGNONS)) - return; // always send if buttons changed or an impulse is pending // even if it violates the rate limit! important = (cl.cmd.impulse || (cl_netimmediatebuttons.integer && cl.cmd.buttons != cl.movecmd[1].buttons)); - // don't send too often (cl_netfps) - if (!important && host.realtime < cl.lastpackettime + packettime) + + // don't send too often (cl_netfps), allowing a small margin for float error + // bones_was_here: accumulate realframetime to prevent low packet rates + // previously with cl_maxfps == cl_netfps it did not send every frame as + // host.realtime - cl.lastpackettime was often well below (or above) packettime + if (!important && cl.timesincepacket < packettime * 0.99999f) + { + cl.timesincepacket += cl.realframetime; return; + } + // don't choke the connection with packets (obey rate limit) // it is important that this check be last, because it adds a new // frame to the shownetgraph output and any cancelation after this @@ -1896,12 +1919,9 @@ void CL_SendMove(void) // we also still send if it is important if (!NetConn_CanSend(cls.netcon) && !important) return; - // try to round off the lastpackettime to a multiple of the packet interval - // (this causes it to emit packets at a steady beat) - if (packettime > 0) - cl.lastpackettime = floor(host.realtime / packettime) * packettime; - else - cl.lastpackettime = host.realtime; + + // reset the packet timing accumulator + cl.timesincepacket = cl.realframetime; buf.maxsize = sizeof(data); buf.cursize = 0; @@ -2146,9 +2166,6 @@ void CL_SendMove(void) { Con_Print("CL_SendMove: lost server connection\n"); CL_Disconnect(); - SV_LockThreadMutex(); - SV_Shutdown(); - SV_UnlockThreadMutex(); } }