]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - cl_input.c
fix crash in SDL mode listing
[xonotic/darkplaces.git] / cl_input.c
index 2e87ef2c2bab853444448ec9f98dd3043225566a..803bd6711243f73610066b672ce63dd8c00c5c33 100644 (file)
@@ -441,6 +441,10 @@ cvar_t in_pitch_min = {0, "in_pitch_min", "-90", "how far downward you can aim (
 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"};
+cvar_t m_accelerate = {CVAR_SAVE, "m_accelerate","1", "mouse acceleration factor (try 2)"};
+cvar_t m_accelerate_minspeed = {CVAR_SAVE, "m_accelerate_minspeed","5000", "below this speed, no acceleration is done"};
+cvar_t m_accelerate_maxspeed = {CVAR_SAVE, "m_accelerate_maxspeed","10000", "above this speed, full acceleration is done"};
+cvar_t m_accelerate_filter = {CVAR_SAVE, "m_accelerate_filter","0.1", "mouse acceleration factor filtering"};
 
 cvar_t cl_netfps = {CVAR_SAVE, "cl_netfps","20", "how many input packets to send to server each second"};
 cvar_t cl_netrepeatinput = {CVAR_SAVE, "cl_netrepeatinput", "1", "how many packets in a row can be lost without movement issues when using cl_movement (technically how many input messages to repeat in each packet that have not yet been acknowledged by the server), only affects DP7 and later servers (Quake uses 0, QuakeWorld uses 2, and just for comparison Quake3 uses 1)"};
@@ -553,6 +557,47 @@ void CL_Input (void)
        // allow mice or other external controllers to add to the move
        IN_Move ();
 
+       // apply m_accelerate if it is on
+       if(m_accelerate.value > 1)
+       {
+               static float averagespeed = 0;
+               float speed, f, mi, ma;
+
+               speed = sqrt(in_mouse_x * in_mouse_x + in_mouse_y * in_mouse_y) / cl.realframetime;
+               if(m_accelerate_filter.value > 0)
+                       f = bound(0, cl.realframetime / m_accelerate_filter.value, 1);
+               else
+                       f = 1;
+               averagespeed = speed * f + averagespeed * (1 - f);
+
+               mi = max(1, m_accelerate_minspeed.value);
+               ma = max(m_accelerate_minspeed.value + 1, m_accelerate_maxspeed.value);
+
+               if(averagespeed <= mi)
+               {
+                       f = 1;
+               }
+               else if(averagespeed >= ma)
+               {
+                       f = m_accelerate.value;
+               }
+               else
+               {
+                       /*
+                       f = log(averagespeed);
+                       mi = log(mi);
+                       ma = log(ma);
+                       */
+                       f = averagespeed;
+                       mi = mi;
+                       ma = ma;
+                       f = (f - mi) / (ma - mi) * (m_accelerate.value - 1) + 1;
+               }
+
+               in_mouse_x *= f;
+               in_mouse_y *= f;
+       }
+
        // apply m_filter if it is on
        mx = in_mouse_x;
        my = in_mouse_y;
@@ -781,7 +826,7 @@ 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] - 2);
+       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_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;
 
@@ -1151,69 +1196,53 @@ void CL_ClientMovement_Physics_Walk(cl_clientmovement_state_t *s)
                if (s->waterjumptime <= 0)
                {
                        // apply air speed limit
-                       vec_t accel, wishspeed2;
+                       vec_t accel, wishspeed2, accelqw;
+                       qboolean accelerating;
+
+                       accelqw = cl.movevars_airaccel_qw;
                        wishspeed = min(wishspeed, cl.movevars_maxairspeed);
                        if (s->crouched)
                                wishspeed *= 0.5;
                        accel = cl.movevars_airaccelerate;
+
+                       accelerating = (DotProduct(s->velocity, wishdir) > 0);
                        wishspeed2 = wishspeed;
 
-                       if(cl.movevars_warsowbunny_turnaccel)
+                       // CPM: air control
+                       if(cl.movevars_airstopaccelerate != 0)
+                               if(DotProduct(s->velocity, wishdir) < 0)
+                                       accel = cl.movevars_airstopaccelerate;
+                       if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
                        {
-                               qboolean accelerating, decelerating;
-                               //qboolean aircontrol;
-                               accelerating = (DotProduct(s->velocity, wishdir) > 0);
-                               decelerating = (DotProduct(s->velocity, wishdir) < 0);
-                               //aircontrol = false;
-
-                               if(accelerating && s->cmd.sidemove == 0 && s->cmd.forwardmove != 0)
+                               if(cl.movevars_maxairstrafespeed)
                                {
-                                       CL_ClientMovement_Physics_PM_AirAccelerate(s, wishdir, wishspeed2);
+                                       if(wishspeed > cl.movevars_maxairstrafespeed)
+                                               wishspeed = cl.movevars_maxairstrafespeed;
+                                       if(cl.movevars_maxairstrafespeed < cl.movevars_maxairspeed)
+                                               accelqw = 1;
+                                               // otherwise, CPMA-style air acceleration misbehaves a lot
+                                               // if partially non-QW acceleration is used (as in, strafing
+                                               // would get faster than moving forward straight)
                                }
-                               else
+                               if(cl.movevars_airstrafeaccelerate)
                                {
-                                       // CPM: air control
-                                       if(cl.movevars_airstopaccelerate != 0)
-                                               if(DotProduct(s->velocity, wishdir) < 0)
-                                                       accel = cl.movevars_airstopaccelerate;
-                                       if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
-                                       {
-                                               if(cl.movevars_maxairstrafespeed)
-                                                       if(wishspeed > cl.movevars_maxairstrafespeed)
-                                                               wishspeed = cl.movevars_maxairstrafespeed;
-                                               if(cl.movevars_airstrafeaccelerate)
-                                                       accel = cl.movevars_airstrafeaccelerate;
-                                               //if(cl.movevars_aircontrol)
-                                                       //aircontrol = true;
-                                       }
-                                       // !CPM
-                                       
-                                       CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, accel, cl.movevars_airaccel_qw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
-                                       //if(aircontrol)
-                                               //CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
-                                               // div0: this never kicks in, as aircontrol is only set to TRUE if self.movement_x == 0 && self.movement_y != 0, but then the function does nothing
+                                       accel = cl.movevars_airstrafeaccelerate;
+                                       if(cl.movevars_airstrafeaccelerate > cl.movevars_airaccelerate)
+                                               accelqw = 1;
+                                               // otherwise, CPMA-style air acceleration misbehaves a lot
+                                               // if partially non-QW acceleration is used (as in, strafing
+                                               // would get faster than moving forward straight)
                                }
                        }
+                       // !CPM
+
+                       if(cl.movevars_warsowbunny_turnaccel && accelerating && s->cmd.sidemove == 0 && s->cmd.forwardmove != 0)
+                               CL_ClientMovement_Physics_PM_AirAccelerate(s, wishdir, wishspeed2);
                        else
-                       {
-                               // CPM: air control
-                               if(cl.movevars_airstopaccelerate != 0)
-                                       if(DotProduct(s->velocity, wishdir) < 0)
-                                               accel = cl.movevars_airstopaccelerate;
-                               if(s->cmd.forwardmove == 0 && s->cmd.sidemove != 0)
-                               {
-                                       if(cl.movevars_maxairstrafespeed)
-                                               if(wishspeed > cl.movevars_maxairstrafespeed)
-                                                       wishspeed = cl.movevars_maxairstrafespeed;
-                                       if(cl.movevars_airstrafeaccelerate)
-                                               accel = cl.movevars_airstrafeaccelerate;
-                               }
-                               // !CPM
+                               CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, accel, accelqw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
 
-                               CL_ClientMovement_Physics_PM_Accelerate(s, wishdir, wishspeed, accel, cl.movevars_airaccel_qw, cl.movevars_airaccel_sideways_friction / cl.movevars_maxairspeed);
-                               if(cl.movevars_aircontrol)
-                                       CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
-                       }
+                       if(cl.movevars_aircontrol)
+                               CL_ClientMovement_Physics_CPM_PM_Aircontrol(s, wishdir, wishspeed2);
                }
                s->velocity[2] -= cl.movevars_gravity * cl.movevars_entgravity * s->cmd.frametime;
                CL_ClientMovement_Move(s);
@@ -1907,6 +1936,10 @@ void CL_InitInput (void)
        Cvar_RegisterVariable(&in_pitch_min);
        Cvar_RegisterVariable(&in_pitch_max);
        Cvar_RegisterVariable(&m_filter);
+       Cvar_RegisterVariable(&m_accelerate);
+       Cvar_RegisterVariable(&m_accelerate_minspeed);
+       Cvar_RegisterVariable(&m_accelerate_maxspeed);
+       Cvar_RegisterVariable(&m_accelerate_filter);
 
        Cvar_RegisterVariable(&cl_netfps);
        Cvar_RegisterVariable(&cl_netrepeatinput);