X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=cl_input.c;h=b24d8ea186d46da73167eff56d8f14da4fa98281;hb=9176bd39d627c6c595248482662f50acee8d3942;hp=260e73f18614bdcbda20ba2a6e5a98d90c8887a9;hpb=b052bcd30dcb6147647dd344db6bb0fa5ef32255;p=xonotic%2Fdarkplaces.git diff --git a/cl_input.c b/cl_input.c index 260e73f1..b24d8ea1 100644 --- a/cl_input.c +++ b/cl_input.c @@ -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) {