X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=cl_input.c;h=cae0e1250aabd5d6c9501123222d28d110920f9d;hp=2dd21acd06d6a296af379bc67e10cfd42781b988;hb=a7c9a3c360206d8c02edab293ac4d9a0fdd825a7;hpb=22e2d9b2dfe473fce6580cbe4fd191850eddd687 diff --git a/cl_input.c b/cl_input.c index 2dd21acd..cae0e125 100644 --- a/cl_input.c +++ b/cl_input.c @@ -423,7 +423,7 @@ cvar_t cl_pitchspeed = {CVAR_SAVE, "cl_pitchspeed","150","keyboard pitch turning cvar_t cl_anglespeedkey = {CVAR_SAVE, "cl_anglespeedkey","1.5","how much +speed multiplies keyboard turning speed"}; -cvar_t cl_movement = {CVAR_SAVE, "cl_movement", "0", "enables clientside prediction of your player movement"}; +cvar_t cl_movement = {CVAR_SAVE, "cl_movement", "0", "enables clientside prediction of your player movement on DP servers (use cl_nopred for QWSV servers)"}; cvar_t cl_movement_replay = {0, "cl_movement_replay", "1", "use engine prediction"}; cvar_t cl_movement_nettimeout = {CVAR_SAVE, "cl_movement_nettimeout", "0.3", "stops predicting moves when server is lagging badly (avoids major performance problems), timeout in seconds"}; cvar_t cl_movement_minping = {CVAR_SAVE, "cl_movement_minping", "0", "whether to use prediction when ping is lower than this value in milliseconds"}; @@ -442,9 +442,10 @@ cvar_t cl_movement_wateraccelerate = {0, "cl_movement_wateraccelerate", "-1", "h cvar_t cl_movement_jumpvelocity = {0, "cl_movement_jumpvelocity", "270", "how fast you move upward when you begin a jump (should match the quakec code)"}; cvar_t cl_movement_airaccel_qw = {0, "cl_movement_airaccel_qw", "1", "ratio of QW-style air control as opposed to simple acceleration (reduces speed gain when zigzagging) (should match sv_airaccel_qw); when < 0, the speed is clamped against the maximum allowed forward speed after the move"}; cvar_t cl_movement_airaccel_sideways_friction = {0, "cl_movement_airaccel_sideways_friction", "0", "anti-sideways movement stabilization (should match sv_airaccel_sideways_friction); when < 0, only so much friction is applied that braking (by accelerating backwards) cannot be stronger"}; +cvar_t cl_nopred = {CVAR_SAVE, "cl_nopred", "0", "(QWSV only) disables player movement prediction when playing on QWSV servers (this setting is separate from cl_movement because player expectations are different when playing on DP vs QW servers)"}; -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 in_pitch_min = {0, "in_pitch_min", "-90", "how far you can aim upward (quake used -70)"}; +cvar_t in_pitch_max = {0, "in_pitch_max", "90", "how far you can aim downward (quake used 80)"}; cvar_t m_filter = {CVAR_SAVE, "m_filter","0", "smoothes mouse movement, less responsive but smoother aiming"}; cvar_t m_accelerate = {CVAR_SAVE, "m_accelerate","1", "mouse acceleration factor (try 2)"}; @@ -506,6 +507,8 @@ static void CL_AdjustAngles (void) cl.viewangles[YAW] -= 360; if (cl.viewangles[PITCH] >= 180) cl.viewangles[PITCH] -= 360; + // TODO: honor serverinfo minpitch and maxpitch values in PROTOCOL_QUAKEWORLD + // TODO: honor proquake pq_fullpitch cvar when playing on proquake server (server stuffcmd's this to 0 usually) cl.viewangles[PITCH] = bound(in_pitch_min.value, cl.viewangles[PITCH], in_pitch_max.value); cl.viewangles[ROLL] = bound(-180, cl.viewangles[ROLL], 180); } @@ -574,7 +577,7 @@ void CL_Input (void) static int oldwindowmouse[2]; if (oldwindowmouse[0] != in_windowmouse_x || oldwindowmouse[1] != in_windowmouse_y) { - CL_VM_InputEvent(3, in_windowmouse_x * vid_conwidth.integer / vid.width, in_windowmouse_y * vid_conheight.integer / vid.height); + CL_VM_InputEvent(3, in_windowmouse_x * vid_conwidth.value / vid.width, in_windowmouse_y * vid_conheight.value / vid.height); oldwindowmouse[0] = in_windowmouse_x; oldwindowmouse[1] = in_windowmouse_y; } @@ -582,7 +585,7 @@ void CL_Input (void) else { if (in_mouse_x || in_mouse_y) - CL_VM_InputEvent(2, in_mouse_x * vid_conwidth.integer / vid.width, in_mouse_y * vid_conheight.integer / vid.height); + CL_VM_InputEvent(2, in_mouse_x, in_mouse_y); } } @@ -697,7 +700,6 @@ void CL_Input (void) { // digital direction, analog amount vec_t wishvel_x, wishvel_y; - f *= max(cl_sidespeed.value, max(cl_forwardspeed.value, cl_backspeed.value)); wishvel_x = fabs(cl.cmd.forwardmove); wishvel_y = fabs(cl.cmd.sidemove); if(wishvel_x != 0 && wishvel_y != 0 && wishvel_x != wishvel_y) @@ -837,7 +839,7 @@ static qboolean CL_ClientMovement_Unstick(cl_clientmovement_state_t *s) for (i = 0;i < NUMOFFSETS;i++) { VectorAdd(offsets[i], s->origin, neworigin); - if (!CL_TraceBox(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true).startsolid) + if (!CL_TraceBox(neworigin, cl.playercrouchmins, cl.playercrouchmaxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true).startsolid) { VectorCopy(neworigin, s->origin); return true; @@ -869,7 +871,7 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s) // low ceiling first if (s->crouched) { - trace = CL_TraceBox(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true); + trace = CL_TraceBox(s->origin, cl.playerstandmins, cl.playerstandmaxs, s->origin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); if (!trace.startsolid) s->crouched = false; } @@ -888,7 +890,7 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s) // set onground VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + 1); VectorSet(origin2, s->origin[0], s->origin[1], s->origin[2] - 1); // -2 causes clientside doublejump bug at above 150fps, raising that to 300fps :) - trace = CL_TraceBox(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true); + trace = CL_TraceBox(origin1, s->mins, s->maxs, origin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); if(trace.fraction < 1 && trace.plane.normal[2] > 0.7) { s->onground = true; @@ -904,16 +906,16 @@ static void CL_ClientMovement_UpdateStatus(cl_clientmovement_state_t *s) // set watertype/waterlevel VectorSet(origin1, s->origin[0], s->origin[1], s->origin[2] + s->mins[2] + 1); s->waterlevel = WATERLEVEL_NONE; - s->watertype = CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK; + s->watertype = CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK; if (s->watertype) { s->waterlevel = WATERLEVEL_WETFEET; origin1[2] = s->origin[2] + (s->mins[2] + s->maxs[2]) * 0.5f; - if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK) + if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK) { s->waterlevel = WATERLEVEL_SWIMMING; origin1[2] = s->origin[2] + 22; - if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK) + if (CL_TracePoint(origin1, MOVE_NOMONSTERS, s->self, 0, 0, 0, true, false, NULL, false).startsupercontents & SUPERCONTENTS_LIQUIDSMASK) s->waterlevel = WATERLEVEL_SUBMERGED; } } @@ -940,20 +942,20 @@ static void CL_ClientMovement_Move(cl_clientmovement_state_t *s) for (bump = 0, t = s->cmd.frametime;bump < 8 && VectorLength2(s->velocity) > 0;bump++) { VectorMA(s->origin, t, s->velocity, neworigin); - trace = CL_TraceBox(s->origin, s->mins, s->maxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true); + trace = CL_TraceBox(s->origin, s->mins, s->maxs, neworigin, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); if (trace.fraction < 1 && trace.plane.normal[2] == 0) { // may be a step or wall, try stepping up // first move forward at a higher level VectorSet(currentorigin2, s->origin[0], s->origin[1], s->origin[2] + cl.movevars_stepheight); VectorSet(neworigin2, neworigin[0], neworigin[1], s->origin[2] + cl.movevars_stepheight); - trace2 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true); + trace2 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); if (!trace2.startsolid) { // then move down from there VectorCopy(trace2.endpos, currentorigin2); VectorSet(neworigin2, trace2.endpos[0], trace2.endpos[1], s->origin[2]); - trace3 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true); + trace3 = CL_TraceBox(currentorigin2, s->mins, s->maxs, neworigin2, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true); //Con_Printf("%f %f %f %f : %f %f %f %f : %f %f %f %f\n", trace.fraction, trace.endpos[0], trace.endpos[1], trace.endpos[2], trace2.fraction, trace2.endpos[0], trace2.endpos[1], trace2.endpos[2], trace3.fraction, trace3.endpos[0], trace3.endpos[1], trace3.endpos[2]); // accept the new trace if it made some progress if (fabs(trace3.endpos[0] - trace.endpos[0]) >= 0.03125 || fabs(trace3.endpos[1] - trace.endpos[1]) >= 0.03125) @@ -1007,10 +1009,10 @@ static void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s) AngleVectors(yawangles, forward, NULL, NULL); VectorMA(s->origin, 24, forward, spot); spot[2] += 8; - if (CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsolid) + if (CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, 0, 0, true, false, NULL, false).startsolid) { spot[2] += 24; - if (!CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, true, false, NULL, false).startsolid) + if (!CL_TracePoint(spot, MOVE_NOMONSTERS, s->self, 0, 0, 0, true, false, NULL, false).startsolid) { VectorScale(forward, 50, s->velocity); s->velocity[2] = 310; @@ -1073,7 +1075,7 @@ static void CL_ClientMovement_Physics_Swim(cl_clientmovement_state_t *s) s->velocity[2] = 80; else { - if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC) + if (IS_NEXUIZ_DERIVED(gamemode)) s->velocity[2] = 200; else s->velocity[2] = 100; @@ -1260,9 +1262,9 @@ static void CL_ClientMovement_Physics_PM_AirAccelerate(cl_clientmovement_state_t if( wishspeed > curspeed * 1.01f ) { - float accelspeed = curspeed + airforwardaccel * cl.movevars_maxairspeed * s->cmd.frametime; - if( accelspeed < wishspeed ) - wishspeed = accelspeed; + float faccelspeed = curspeed + airforwardaccel * cl.movevars_maxairspeed * s->cmd.frametime; + if( faccelspeed < wishspeed ) + wishspeed = faccelspeed; } else { @@ -1353,9 +1355,9 @@ static void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s) 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(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, true, true, NULL, true); + 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); else - trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true, true, NULL, true, false); + trace = CL_TraceLine(neworigin2, neworigin3, MOVE_NORMAL, s->self, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, 0, 0, collision_extendmovelength.value, true, true, NULL, true, false); if (trace.fraction == 1 && !trace.startsolid) friction *= cl.movevars_edgefriction; } @@ -1510,8 +1512,8 @@ void CL_UpdateMoveVars(void) else { cl.moveflags = 0; - cl.movevars_ticrate = slowmo.value / bound(1.0f, cl_netfps.value, 1000.0f); - cl.movevars_timescale = slowmo.value; + cl.movevars_ticrate = (cls.demoplayback ? 1.0f : slowmo.value) / bound(1.0f, cl_netfps.value, 1000.0f); + cl.movevars_timescale = (cls.demoplayback ? 1.0f : slowmo.value); cl.movevars_gravity = sv_gravity.value; cl.movevars_stopspeed = cl_movement_stopspeed.value; cl.movevars_maxspeed = cl_movement_maxspeed.value; @@ -1547,7 +1549,7 @@ void CL_UpdateMoveVars(void) if(!(cl.moveflags & MOVEFLAG_VALID)) { - if(gamemode == GAME_NEXUIZ) + if(gamemode == GAME_NEXUIZ) // Legacy hack to work with old servers of Nexuiz. cl.moveflags = MOVEFLAG_Q2AIRACCELERATE; } @@ -1602,7 +1604,7 @@ void CL_ClientMovement_Replay(void) if (cl.movecmd[i].sequence > cls.servermovesequence) totalmovemsec += cl.movecmd[i].msec; cl.movement_predicted = totalmovemsec >= cl_movement_minping.value && cls.servermovesequence && (cl_movement.integer && !cls.demoplayback && cls.signon == SIGNONS && cl.stats[STAT_HEALTH] > 0 && !cl.intermission); - //Con_Printf("%i = %.0f >= %.0f && %i && (%i && %i && %i == %i && %i > 0 && %i\n", cl.movement_predicted, totalmovemsec, cl_movement_minping.value, cls.servermovesequence, cl_movement.integer, !cls.demoplayback, cls.signon, SIGNONS, cl.stats[STAT_HEALTH], !cl.intermission); + //Con_Printf("%i = %.0f >= %.0f && %u && (%i && %i && %i == %i && %i > 0 && %i\n", cl.movement_predicted, totalmovemsec, cl_movement_minping.value, cls.servermovesequence, cl_movement.integer, !cls.demoplayback, cls.signon, SIGNONS, cl.stats[STAT_HEALTH], !cl.intermission); if (cl.movement_predicted) { //Con_Printf("%ims\n", cl.movecmd[0].msec); @@ -1813,7 +1815,20 @@ void CL_SendMove(void) cl.cmd.msec = 100; cl.cmd.frametime = cl.cmd.msec * (1.0 / 1000.0); - cl.cmd.predicted = cl_movement.integer != 0; + switch(cls.protocol) + { + case PROTOCOL_QUAKEWORLD: + // quakeworld uses a different cvar with opposite meaning, for compatibility + cl.cmd.predicted = cl_nopred.integer == 0; + break; + case PROTOCOL_DARKPLACES6: + case PROTOCOL_DARKPLACES7: + cl.cmd.predicted = cl_movement.integer != 0; + break; + default: + cl.cmd.predicted = false; + break; + } // movement is set by input code (forwardmove/sidemove/upmove) // always dump the first two moves, because they may contain leftover inputs from the last level @@ -2060,9 +2075,11 @@ void CL_SendMove(void) // if cl_netrepeatinput is 1 and client framerate matches server // framerate, this is 10 bytes, if client framerate is lower this // will be more... - int i, j; - int oldsequence = cl.cmd.sequence - bound(1, cl_netrepeatinput.integer + 1, 3); - if (oldsequence < 1) + unsigned int oldsequence = cl.cmd.sequence; + unsigned int delta = bound(1, cl_netrepeatinput.integer + 1, 3); + if (oldsequence > delta) + oldsequence = oldsequence - delta; + else oldsequence = 1; for (i = 0;i < LATESTFRAMENUMS;i++) { @@ -2092,7 +2109,7 @@ void CL_SendMove(void) // send the reliable message (forwarded commands) if there is one if (buf.cursize || cls.netcon->message.cursize) - NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, max(20*(buf.cursize+40), cl_rate.integer), false); + NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, max(20*(buf.cursize+40), cl_rate.integer), cl_rate_burstsize.integer, false); if (quemove) { @@ -2237,6 +2254,7 @@ void CL_InitInput (void) Cvar_RegisterVariable(&cl_movement_jumpvelocity); Cvar_RegisterVariable(&cl_movement_airaccel_qw); Cvar_RegisterVariable(&cl_movement_airaccel_sideways_friction); + Cvar_RegisterVariable(&cl_nopred); Cvar_RegisterVariable(&in_pitch_min); Cvar_RegisterVariable(&in_pitch_max);