]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_input.c
removed trailing comments on cvar declarations and Cmd_AddCommand calls
[xonotic/darkplaces.git] / cl_input.c
index 0fc37a56b7ed77fa0e598d4119186c42e3cd319a..569740bb829dcc79f05875acd3ab403a1d761b92 100644 (file)
@@ -337,8 +337,8 @@ cvar_t cl_movement_airaccel_sideways_friction = {0, "cl_movement_airaccel_sidewa
 cvar_t cl_gravity = {0, "cl_gravity", "800", "how much gravity to apply in client physics (should match sv_gravity)"};
 cvar_t cl_slowmo = {0, "cl_slowmo", "1", "speed of game time (should match slowmo)"};
 
-cvar_t in_pitch_min = {0, "in_pitch_min", "-90", "how far downward you can aim (quake used -70"}; // quake used -70
-cvar_t in_pitch_max = {0, "in_pitch_max", "90", "how far upward you can aim (quake used 80"}; // quake used 80
+cvar_t in_pitch_min = {0, "in_pitch_min", "-90", "how far downward you can aim (quake used -70"};
+cvar_t in_pitch_max = {0, "in_pitch_max", "90", "how far upward you can aim (quake used 80"};
 
 cvar_t m_filter = {CVAR_SAVE, "m_filter","0", "smoothes mouse movement, less responsive but smoother aiming"};
 
@@ -560,8 +560,6 @@ void CL_UpdatePrydonCursor(void)
        cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber, (chase_active.integer || cl.intermission) ? &cl.entities[cl.playerentity].render : NULL);
 }
 
-void CL_ClientMovement_Replay(void);
-
 void CL_ClientMovement_InputQW(void)
 {
        int i;
@@ -594,7 +592,8 @@ void CL_ClientMovement_InputQW(void)
                cl.movement_queue[cl.movement_numqueue].crouch = false;
                cl.movement_numqueue++;
        }
-       CL_ClientMovement_Replay();
+
+       cl.movement_replay = true;
 }
 
 void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
@@ -607,11 +606,11 @@ void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
        // remove stale queue items
        n = cl.movement_numqueue;
        cl.movement_numqueue = 0;
-       if (cl.servermovesequence)
+       if (cls.servermovesequence)
        {
                for (i = 0;i < n;i++)
                {
-                       if (cl.movement_queue[i].sequence > cl.servermovesequence)
+                       if (cl.movement_queue[i].sequence > cls.servermovesequence)
                                cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
                        else if (i == 0)
                                cl.movement_replay_canjump = !cl.movement_queue[i].jump; // FIXME: this logic is quite broken
@@ -631,7 +630,7 @@ void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
        if (cl.movement_numqueue < (int)(sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0])))
        {
                // add to input queue
-               cl.movement_queue[cl.movement_numqueue].sequence = cl.movesequence;
+               cl.movement_queue[cl.movement_numqueue].sequence = cls.movesequence;
                cl.movement_queue[cl.movement_numqueue].time = cl.movecmd[0].time;
                cl.movement_queue[cl.movement_numqueue].frametime = bound(0, cl.movecmd[0].time - cl.movecmd[1].time, 0.1);
                VectorCopy(cl.viewangles, cl.movement_queue[cl.movement_numqueue].viewangles);
@@ -642,7 +641,8 @@ void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
                cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch;
                cl.movement_numqueue++;
        }
-       CL_ClientMovement_Replay();
+
+       cl.movement_replay = true;
 }
 
 typedef enum waterlevel_e
@@ -781,7 +781,7 @@ void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s)
        VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + 1);
        VectorSet(origin2, s->origin[0], s->origin[1], s->origin[2] - 2);
        trace = CL_Move(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, false);
-       s->onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7 && s->velocity[2] < cl_gravity.value * s->q.frametime;
+       s->onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
 
        // set watertype/waterlevel
        VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + s->mins[2] + 1);
@@ -1147,7 +1147,7 @@ void CL_ClientMovement_Replay(void)
                s.movevars_airaccel_sideways_friction = cl_movement_airaccel_sideways_friction.value;
        }
 
-       cl.movement_predicted = (cl_movement.integer && !cls.demoplayback && cls.signon == SIGNONS && cl.stats[STAT_HEALTH] > 0 && !cl.intermission) && ((cls.protocol != PROTOCOL_DARKPLACES6 && cls.protocol != PROTOCOL_DARKPLACES7) || cl.servermovesequence);
+       cl.movement_predicted = (cl_movement.integer && !cls.demoplayback && cls.signon == SIGNONS && cl.stats[STAT_HEALTH] > 0 && !cl.intermission) && ((cls.protocol != PROTOCOL_DARKPLACES6 && cls.protocol != PROTOCOL_DARKPLACES7) || cls.servermovesequence);
        if (cl.movement_predicted)
        {
                //Con_Printf("%f: ", cl.movecmd[0].time);
@@ -1174,39 +1174,54 @@ void CL_ClientMovement_Replay(void)
        }
        CL_ClientMovement_UpdateStatus(&s);
 
-       // store replay location
-       if (cl.movecmd[0].time > cl.movecmd[1].time)
+       if (cl.movement_replay)
        {
-               cl.movement_time[1] = cl.movecmd[1].time;
-               cl.movement_time[0] = cl.movecmd[0].time;
-               cl.movement_time[2] = cl.time;
-               VectorCopy(cl.movement_origin, cl.movement_oldorigin);
+               cl.movement_replay = false;
+               // update interpolation timestamps if time has passed
+               if (cl.movecmd[0].time != cl.movecmd[1].time)
+               {
+                       cl.movement_time[1] = cl.movecmd[1].time;
+                       cl.movement_time[0] = cl.movecmd[0].time;
+                       cl.movement_time[2] = cl.time;
+                       VectorCopy(cl.movement_origin, cl.movement_oldorigin);
+                       //VectorCopy(s.origin, cl.entities[cl.playerentity].state_current.origin);
+                       //VectorSet(cl.entities[cl.playerentity].state_current.angles, 0, cl.viewangles[1], 0);
+               }
+
+               // update the interpolation target position and velocity
                VectorCopy(s.origin, cl.movement_origin);
                VectorCopy(s.velocity, cl.movement_velocity);
-               //VectorCopy(s.origin, cl.entities[cl.playerentity].state_current.origin);
-               //VectorSet(cl.entities[cl.playerentity].state_current.angles, 0, cl.viewangles[1], 0);
-
-               // update the onground flag if appropriate
-               // when not predicted, cl.onground is only cleared by cl_parse.c, but can
-               // be set forcefully here to hide server inconsistencies in the onground
-               // flag (such as when stepping up stairs, the onground flag tends to turn
-               // off briefly due to precision errors, particularly at high framerates),
-               // such inconsistencies can mess up the gun bobbing and stair smoothing,
-               // so they must be avoided.
-               if (cl.movement_predicted)
-                       cl.onground = s.onground;
-               else if (s.onground)
+       }
+
+       // update the onground flag if appropriate
+       if (cl.movement_predicted)
+       {
+               // when predicted we simply set the flag according to the UpdateStatus
+               cl.onground = s.onground;
+       }
+       else
+       {
+               // when not predicted, cl.onground is cleared by cl_parse.c each time
+               // an update packet is received, but can be forced on here to hide
+               // server inconsistencies in the onground flag
+               // (which mostly occur when stepping up stairs at very high framerates
+               //  where after the step up the move continues forward and not
+               //  downward so the ground is not detected)
+               //
+               // such onground inconsistencies can cause jittery gun bobbing and
+               // stair smoothing, so we set onground if UpdateStatus says so
+               if (s.onground)
                        cl.onground = true;
+       }
 
-               // react to onground state changes (for gun bob)
-               if (cl.onground)
-               {
-                       if (!cl.oldonground)
-                               cl.hitgroundtime = cl.movecmd[0].time;
-                       cl.lastongroundtime = cl.movecmd[0].time;
-               }
-               cl.oldonground = cl.onground;
+       // react to onground state changes (for gun bob)
+       if (cl.onground)
+       {
+               if (!cl.oldonground)
+                       cl.hitgroundtime = cl.movecmd[0].time;
+               cl.lastongroundtime = cl.movecmd[0].time;
        }
+       cl.oldonground = cl.onground;
 }
 
 void QW_MSG_WriteDeltaUsercmd(sizebuf_t *buf, usercmd_t *from, usercmd_t *to)
@@ -1272,37 +1287,35 @@ void CL_SendMove(void)
        if (!cls.netcon)
                return;
 
+       // don't send too often or else network connections can get clogged by a high renderer framerate
        packettime = 1.0 / bound(10, cl_netinputpacketspersecond.value, 100);
-       // on quakeworld servers the server replies to client input, so we send
-       // packets whenever we want to
-       // on non-quakeworld servers the client replies to server updates
+       // quakeworld servers take only frametimes
+       // predicted dp7 servers take current interpolation time
+       // unpredicted servers take an echo of the latest server timestamp
        if (cls.protocol == PROTOCOL_QUAKEWORLD)
        {
-               // don't send too often or else network connections can get clogged by a high renderer framerate
                if (realtime < lastsendtime + packettime)
                        return;
                cl.cmd.time = realtime;
        }
-       else if (cl.movement_predicted || cls.signon < SIGNONS)
+       else if (cl.movement_predicted)
        {
-               // don't send too often or else network connections can get clogged by a high renderer framerate
                if (realtime < lastsendtime + packettime)
                        return;
-               cl.cmd.time = cls.protocol == PROTOCOL_QUAKEWORLD ? realtime : cl.time;
+               cl.cmd.time = cl.time;
        }
        else
        {
-               // if not predicted, we should just reply to server packets, and
-               // report the real latest packet time rather than our interpolated
-               // time
+               // unpredicted movement should be sent immediately whenever a server
+               // packet is received, to minimize ping times
                if (!cl.movement_needupdate && realtime < lastsendtime + packettime)
                        return;
-               cl.cmd.time = cls.protocol == PROTOCOL_QUAKEWORLD ? realtime : cl.mtime[0];
+               cl.cmd.time = cl.mtime[0];
        }
        // don't let it fall behind if CL_SendMove hasn't been called recently
        // (such is the case when framerate is too low for instance)
        lastsendtime = bound(realtime, lastsendtime + packettime, realtime + packettime);
-       // clear the note down that we sent a packet recently
+       // set the flag indicating that we sent a packet recently
        cl.movement_needupdate = false;
 
 
@@ -1374,9 +1387,9 @@ void CL_SendMove(void)
                        cl.cmd.msec = 100;
                oldmsectime = msectime;
 
-               cl.movesequence++;
+               cls.movesequence++;
                if (cl_movement.integer)
-                       cl.cmd.sequence = cl.movesequence;
+                       cl.cmd.sequence = cls.movesequence;
                else
                        cl.cmd.sequence = 0;
 
@@ -1384,7 +1397,7 @@ void CL_SendMove(void)
                CL_UpdatePrydonCursor();
 
                // always dump the first two messages, because they may contain leftover inputs from the last level
-               if (cl.movesequence > 2)
+               if (cls.movesequence > 2)
                {
                        // update the cl.movecmd array which holds the most recent moves
                        for (i = CL_MAX_USERCMDS - 1;i >= 1;i--)
@@ -1507,7 +1520,7 @@ void CL_SendMove(void)
                                for (j = 0, cmd = &cl.movecmd[maxusercmds-1];j < maxusercmds;j++, cmd--)
                                {
                                        // don't repeat any stale moves
-                                       if (cmd->sequence && cmd->sequence < cl.servermovesequence)
+                                       if (cmd->sequence && cmd->sequence < cls.servermovesequence)
                                                continue;
                                        // 5/9 bytes
                                        MSG_WriteByte (&buf, clc_move);
@@ -1607,7 +1620,7 @@ void CL_InitInput (void)
        Cmd_AddCommand ("-lookup", IN_LookupUp, "stop looking upward");
        Cmd_AddCommand ("+lookdown", IN_LookdownDown, "look downward");
        Cmd_AddCommand ("-lookdown", IN_LookdownUp, "stop looking downward");
-       Cmd_AddCommand ("+strafe", IN_StrafeDown, "activate strafing mode (move instead of turn)\n");
+       Cmd_AddCommand ("+strafe", IN_StrafeDown, "activate strafing mode (move instead of turn)");
        Cmd_AddCommand ("-strafe", IN_StrafeUp, "deactivate strafing mode");
        Cmd_AddCommand ("+moveleft", IN_MoveleftDown, "strafe left");
        Cmd_AddCommand ("-moveleft", IN_MoveleftUp, "stop strafing left");