]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_input.c
before calling SetNewParms qc function, set self to world to intentionally cause...
[xonotic/darkplaces.git] / cl_input.c
index 260e73f18614bdcbda20ba2a6e5a98d90c8887a9..b24d8ea186d46da73167eff56d8f14da4fa98281 100644 (file)
@@ -439,6 +439,7 @@ void CL_Move (void)
 
 #include "cl_collision.h"
 
+extern void V_CalcRefdef(void);
 void CL_UpdatePrydonCursor(void)
 {
        vec3_t temp, scale;
@@ -479,28 +480,68 @@ void CL_UpdatePrydonCursor(void)
        // trace distance
        VectorScale(scale, 1000000, scale);
 
-       // FIXME: use something other than renderer variables here
-       // (but they need to match)
-       VectorCopy(r_vieworigin, cl.cmd.cursor_start);
+       // calculate current view matrix
+       V_CalcRefdef();
+       VectorClear(temp);
+       Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_start);
        VectorSet(temp, cl.cmd.cursor_screen[2] * scale[2], cl.cmd.cursor_screen[0] * scale[0], cl.cmd.cursor_screen[1] * scale[1]);
-       Matrix4x4_Transform(&r_view_matrix, temp, cl.cmd.cursor_end);
+       Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_end);
+       // trace from view origin to the cursor
        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);
        // makes sparks where cursor is
        //CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0);
 }
 
-void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
+void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
 {
        int i;
        int n;
+       // remove stale queue items
+       n = cl.movement_numqueue;
+       cl.movement_numqueue = 0;
+       if (cl.servermovesequence)
+       {
+               for (i = 0;i < n;i++)
+                       if (cl.movement_queue[i].sequence > cl.servermovesequence)
+                               cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
+       }
+       else
+       {
+               double simulatedtime = cl.mtime[0] + cl_movement_latency.value / 1000.0;
+               for (i = 0;i < n;i++)
+                       if (cl.movement_queue[i].time >= cl.mtime[0] && cl.movement_queue[i].time <= simulatedtime)
+                               cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
+       }
+       // add to input queue if there is room
+       if (cl_movement.integer && cl.movement_numqueue < sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0]) && cl.mtime[0] > cl.mtime[1])
+       {
+               // add to input queue
+               cl.movement_queue[cl.movement_numqueue].sequence = cl.movesequence;
+               cl.movement_queue[cl.movement_numqueue].time = cl.mtime[0] + cl_movement_latency.value / 1000.0;
+               cl.movement_queue[cl.movement_numqueue].frametime = cl.mtime[0] - cl.mtime[1];
+               VectorCopy(cl.viewangles, cl.movement_queue[cl.movement_numqueue].viewangles);
+               cl.movement_queue[cl.movement_numqueue].move[0] = cl.cmd.forwardmove;
+               cl.movement_queue[cl.movement_numqueue].move[1] = cl.cmd.sidemove;
+               cl.movement_queue[cl.movement_numqueue].move[2] = cl.cmd.upmove;
+               cl.movement_queue[cl.movement_numqueue].jump = buttonjump;
+               cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch;
+               cl.movement_numqueue++;
+       }
+       cl.movement = cl_movement.integer && cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.intermission;
+       // clear queue if client movement is disabled
+       if (!cl.movement)
+               cl.movement_numqueue = 0;
+       cl.movement_replay = true;
+}
+
+void CL_ClientMovement_Replay(void)
+{
+       int i;
        int bump;
        int contents;
        int crouch;
        int onground;
        double edgefriction;
-       double simulatedtime;
-       double currenttime;
-       double newtime;
        double frametime;
        double t;
        vec_t wishspeed;
@@ -523,61 +564,36 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
        trace_t trace;
        trace_t trace2;
        trace_t trace3;
-       // remove stale queue items
-       n = cl.movement_numqueue;
-       cl.movement_numqueue = 0;
-       // calculate time to execute for
-       currenttime = cl.mtime[0];
-       simulatedtime = currenttime + cl_movement_latency.value / 1000.0;
-       for (i = 0;i < n;i++)
-               if (cl.movement_queue[i].time >= cl.mtime[0] && cl.movement_queue[i].time <= simulatedtime)
-                       cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
-       // add to input queue if there is room
-       if (cl.movement_numqueue < sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0]))
-       {
-               // add to input queue
-               cl.movement_queue[cl.movement_numqueue].time = simulatedtime;
-               VectorCopy(cl.viewangles, cl.movement_queue[cl.movement_numqueue].viewangles);
-               cl.movement_queue[cl.movement_numqueue].move[0] = cl.cmd.forwardmove;
-               cl.movement_queue[cl.movement_numqueue].move[1] = cl.cmd.sidemove;
-               cl.movement_queue[cl.movement_numqueue].move[2] = cl.cmd.upmove;
-               cl.movement_queue[cl.movement_numqueue].jump = buttonjump;
-               cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch;
-               cl.movement_numqueue++;
-       }
+       if (!cl.movement_replay)
+               return;
+       cl.movement_replay = false;
+
        // fetch current starting values
        VectorCopy(cl_entities[cl.playerentity].state_current.origin, currentorigin);
        VectorCopy(cl.mvelocity[0], currentvelocity);
-       // check if onground
-       VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + 1);
-       VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
-       trace = CL_TraceBox(currentorigin2, cl_playercrouchmins, cl_playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
-       onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
        // FIXME: try minor nudges in various directions if startsolid to find a
        // safe place to start the walk (due to network compression in some
        // protocols this starts in solid)
        //currentorigin[2] += (1.0 / 32.0); // slight nudge to get out of the floor
        crouch = false; // this will be updated on first move
-       //Con_Printf("%f: ", currenttime);
-       // replay input queue, and remove any stale queue items
+
+       // check if onground
+       VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + 1);
+       VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
+       trace = CL_TraceBox(currentorigin2, cl_playercrouchmins, cl_playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+       onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
+       //Con_Printf("%f: ", cl.mtime[0]);
+
+       // replay the input queue to predict current location
        // note: this relies on the fact there's always one queue item at the end
-       // abort if client movement is disabled
-       cl.movement = cl_movement.integer && cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback;
-       if (!cl.movement)
-               cl.movement_numqueue = 0;
-       for (i = 0;i <= cl.movement_numqueue;i++)
+
+       for (i = 0;i < cl.movement_numqueue;i++)
        {
-               newtime = (i >= cl.movement_numqueue) ? simulatedtime : cl.movement_queue[i].time;
-               frametime = newtime - currenttime;
-               if (frametime <= 0)
-                       continue;
+               client_movementqueue_t *q = cl.movement_queue + bound(0, i, cl.movement_numqueue - 1);
+               frametime = q->frametime;
                //Con_Printf(" %f", frametime);
-               currenttime = newtime;
-               if (i >= 1 && i <= cl.movement_numqueue)
-               if (i > 0 || (cl_movement.integer & 8))
-               if (i < cl.movement_numqueue - 1 || (cl_movement.integer & 16))
+               //if (frametime > 0)
                {
-                       client_movementqueue_t *q = cl.movement_queue + i - 1;
                        if (q->crouch)
                        {
                                // wants to crouch, this always works...
@@ -616,6 +632,8 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
                                wishspeed = VectorLength(wishvel);
                                if (wishspeed)
                                        VectorScale(wishvel, 1 / wishspeed, wishdir);
+                               else
+                                       VectorSet( wishdir, 0.0, 0.0, 0.0 );
                                wishspeed = min(wishspeed, cl_movement_maxspeed.value);
                                if (crouch)
                                        wishspeed *= 0.5;
@@ -656,6 +674,8 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
                                wishspeed = VectorLength(wishvel);
                                if (wishspeed)
                                        VectorScale(wishvel, 1 / wishspeed, wishdir);
+                               else
+                                       VectorSet( wishdir, 0.0, 0.0, 0.0 );
                                wishspeed = min(wishspeed, cl_movement_maxspeed.value);
                                if (crouch)
                                        wishspeed *= 0.5;
@@ -695,8 +715,7 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
                                currentvelocity[2] -= cl_gravity.value * frametime;
                        }
                }
-               if (i > 0 || (cl_movement.integer & 2))
-               if (i < cl.movement_numqueue - 1 || (cl_movement.integer & 4))
+               //if (i < cl.movement_numqueue - 1 || (cl_movement.integer & 4))
                {
                        if (crouch)
                        {
@@ -708,6 +727,7 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
                                playermins = cl_playerstandmins;
                                playermaxs = cl_playerstandmaxs;
                        }
+                       onground = false;
                        for (bump = 0, t = frametime;bump < 8 && VectorLength2(currentvelocity) > 0;bump++)
                        {
                                VectorMA(currentorigin, t, currentvelocity, neworigin);
@@ -746,7 +766,6 @@ void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
                        }
                }
        }
-       //Con_Printf(" :%f\n", currenttime);
        // store replay location
        VectorCopy(cl.movement_origin, cl.movement_oldorigin);
        VectorCopy(currentorigin, cl.movement_origin);
@@ -796,6 +815,8 @@ void CL_SendMove(void)
        upmove = cl.cmd.upmove;
 #endif
 
+       CL_UpdatePrydonCursor();
+
        buf.maxsize = 128;
        buf.cursize = 0;
        buf.data = data;
@@ -825,18 +846,79 @@ void CL_SendMove(void)
        if (++cl.movemessages >= 2)
        {
                // send the movement message
-               // PROTOCOL_QUAKE       clc_move = 16 bytes total
-               // PROTOCOL_DARKPLACES1 clc_move = 19 bytes total
-               // PROTOCOL_DARKPLACES2 clc_move = 25 bytes total
-               // PROTOCOL_DARKPLACES3 clc_move = 25 bytes total
-               // PROTOCOL_DARKPLACES4 clc_move = 19 bytes total
-               // PROTOCOL_DARKPLACES5 clc_move = 19 bytes total
-               // PROTOCOL_DARKPLACES6 clc_move = 52 bytes total
-               // 5 bytes
-               MSG_WriteByte (&buf, clc_move);
-               MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
-               if (cl.protocol == PROTOCOL_DARKPLACES6)
+               // PROTOCOL_QUAKE        clc_move = 16 bytes total
+               // PROTOCOL_QUAKEDP      clc_move = 16 bytes total
+               // PROTOCOL_NEHAHRAMOVIE clc_move = 16 bytes total
+               // PROTOCOL_DARKPLACES1  clc_move = 19 bytes total
+               // PROTOCOL_DARKPLACES2  clc_move = 25 bytes total
+               // PROTOCOL_DARKPLACES3  clc_move = 25 bytes total
+               // PROTOCOL_DARKPLACES4  clc_move = 19 bytes total
+               // PROTOCOL_DARKPLACES5  clc_move = 19 bytes total
+               // PROTOCOL_DARKPLACES6  clc_move = 52 bytes total
+               // PROTOCOL_DARKPLACES7  clc_move = 56 bytes total
+               if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_QUAKEDP || cl.protocol == PROTOCOL_NEHAHRAMOVIE)
                {
+                       // 5 bytes
+                       MSG_WriteByte (&buf, clc_move);
+                       MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
+                       // 3 bytes
+                       for (i = 0;i < 3;i++)
+                               MSG_WriteAngle8i (&buf, cl.viewangles[i]);
+                       // 6 bytes
+                       MSG_WriteCoord16i (&buf, forwardmove);
+                       MSG_WriteCoord16i (&buf, sidemove);
+                       MSG_WriteCoord16i (&buf, upmove);
+                       // 2 bytes
+                       MSG_WriteByte (&buf, bits);
+                       MSG_WriteByte (&buf, in_impulse);
+               }
+               else if (cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
+               {
+                       // 5 bytes
+                       MSG_WriteByte (&buf, clc_move);
+                       MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
+                       // 12 bytes
+                       for (i = 0;i < 3;i++)
+                               MSG_WriteAngle32f (&buf, cl.viewangles[i]);
+                       // 6 bytes
+                       MSG_WriteCoord16i (&buf, forwardmove);
+                       MSG_WriteCoord16i (&buf, sidemove);
+                       MSG_WriteCoord16i (&buf, upmove);
+                       // 2 bytes
+                       MSG_WriteByte (&buf, bits);
+                       MSG_WriteByte (&buf, in_impulse);
+               }
+               else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
+               {
+                       // 5 bytes
+                       MSG_WriteByte (&buf, clc_move);
+                       MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
+                       // 6 bytes
+                       for (i = 0;i < 3;i++)
+                               MSG_WriteAngle16i (&buf, cl.viewangles[i]);
+                       // 6 bytes
+                       MSG_WriteCoord16i (&buf, forwardmove);
+                       MSG_WriteCoord16i (&buf, sidemove);
+                       MSG_WriteCoord16i (&buf, upmove);
+                       // 2 bytes
+                       MSG_WriteByte (&buf, bits);
+                       MSG_WriteByte (&buf, in_impulse);
+               }
+               else
+               {
+                       // 5 bytes
+                       MSG_WriteByte (&buf, clc_move);
+                       if (cl.protocol != PROTOCOL_DARKPLACES6)
+                       {
+                               if (cl_movement.integer)
+                               {
+                                       cl.movesequence++;
+                                       MSG_WriteLong (&buf, cl.movesequence);
+                               }
+                               else
+                                       MSG_WriteLong (&buf, 0);
+                       }
+                       MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
                        // 6 bytes
                        for (i = 0;i < 3;i++)
                                MSG_WriteAngle16i (&buf, cl.viewangles[i]);
@@ -859,36 +941,6 @@ void CL_SendMove(void)
                        MSG_WriteFloat (&buf, cl.cmd.cursor_impact[2]);
                        MSG_WriteShort (&buf, cl.cmd.cursor_entitynumber);
                }
-               else
-               {
-                       if (cl.protocol == PROTOCOL_QUAKE || cl.protocol == PROTOCOL_NEHAHRAMOVIE)
-                       {
-                               // 3 bytes
-                               for (i = 0;i < 3;i++)
-                                       MSG_WriteAngle8i (&buf, cl.viewangles[i]);
-                       }
-                       else if (cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
-                       {
-                               // 12 bytes
-                               for (i = 0;i < 3;i++)
-                                       MSG_WriteAngle32f (&buf, cl.viewangles[i]);
-                       }
-                       else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
-                       {
-                               // 6 bytes
-                               for (i = 0;i < 3;i++)
-                                       MSG_WriteAngle16i (&buf, cl.viewangles[i]);
-                       }
-                       else
-                               Host_Error("CL_SendMove: unknown cl.protocol %i\n", cl.protocol);
-                       // 6 bytes
-                       MSG_WriteCoord16i (&buf, forwardmove);
-                       MSG_WriteCoord16i (&buf, sidemove);
-                       MSG_WriteCoord16i (&buf, upmove);
-                       // 2 bytes
-                       MSG_WriteByte (&buf, bits);
-                       MSG_WriteByte (&buf, in_impulse);
-               }
        }
 
 #if MOVEAVERAGING
@@ -911,6 +963,7 @@ void CL_SendMove(void)
        }
 
        // PROTOCOL_DARKPLACES6 = 67 bytes per packet
+       // PROTOCOL_DARKPLACES7 = 71 bytes per packet
 
        // deliver the message
        if (cls.demoplayback)
@@ -919,8 +972,8 @@ void CL_SendMove(void)
        if (!buf.cursize)
                return;
 
-       // FIXME: bits & 64 is +button5, Nexuiz specific
-       CL_ClientMovement((bits & 2) != 0, (bits & 64) != 0);
+       // FIXME: bits & 16 is +button5, Nexuiz specific
+       CL_ClientMovement_Input((bits & 2) != 0, (bits & 16) != 0);
 
        if (NetConn_SendUnreliableMessage(cls.netcon, &buf) == -1)
        {