diff --git a/README b/README index b348b6a4..18ab581b 100644 --- a/README +++ b/README @@ -107,6 +107,9 @@ New cvars cl_cURLLib - filename of cURL library to load cl_consoleKeys - space delimited list of key names or characters that toggle the console + cl_mouseAccelStyle - Set to 1 for QuakeLive mouse acceleration + behaviour, 0 for standard q3 + cl_mouseAccelOffset - Tuning the acceleration curve, see below s_useOpenAL - use the OpenAL sound backend if available s_alPrecache - cache OpenAL sounds before use @@ -126,26 +129,28 @@ New cvars s_alDriver - which OpenAL library to use s_alDevice - which OpenAL device to use s_alAvailableDevices - list of available OpenAL devices - s_sdlBits - SDL bit resolution s_sdlSpeed - SDL sample rate s_sdlChannels - SDL number of channels s_sdlDevSamps - SDL DMA buffer size override s_sdlMixSamps - SDL mix buffer size override + s_backend - read only, indicates the current sound + backend + s_muteWhenMinimized - mute sound when minimized com_ansiColor - enable use of ANSI escape codes in the tty com_altivec - enable use of altivec on PowerPC systems com_standalone - Run in standalone mode com_maxfpsUnfocused - Maximum frames per second when unfocused com_maxfpsMinimized - Maximum frames per second when minimized - s_backend - read only, indicates the current sound - backend - s_muteWhenMinimized - mute sound when minimized + in_joystickNo - select which joystick to use in_keyboardDebug - print keyboard debug info - r_ext_texture_filter_anisotropic - anisotropic texture filtering + sv_dlURL - the base of the HTTP or FTP site that holds custom pk3 files for your server + sv_banFile - Name of the file that is used for storing + the server bans. net_ip6 - IPv6 address to bind to net_port6 - port to bind to using the ipv6 address @@ -160,6 +165,7 @@ New cvars net_mcastiface - outgoing interface to use for scan r_allowResize - make window resizable (SDL only) + r_ext_texture_filter_anisotropic - anisotropic texture filtering r_zProj - distance of observer camera to projection plane in quake3 standard units r_greyscale - render black and white images @@ -186,8 +192,6 @@ New cvars intend to use this. r_sdlDriver - read only, indicates the SDL driver backend being used - sv_banFile - Name of the file that is used for storing - the server bans. New commands video [filename] - start video capture (use with demo command) @@ -225,6 +229,51 @@ Using Demo Data Files data, nor is it something that we like to spend much time maintaining or supporting. +QuakeLive mouse acceleration (patch and this text written by TTimo from id) + I've been using an experimental mouse acceleration code for a while, and + decided to make it available to everyone. Don't be too worried if you don't + understand the explanations below, this is mostly intended for advanced + players: + To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior) + + New style is controlled with 3 cvars: + + sensitivity + cl_mouseAccel + cl_mouseAccelOffset + + The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if + you have a base sensitivity setup, as soon as you set a non zero acceleration + your base sensitivity at low speeds will change as well. The other problem + with style 0 is that you are stuck on a square (power of two) acceleration + curve. + + The new code tries to solve both problems: + + Once you setup your sensitivity to feel comfortable and accurate enough for + low mouse deltas with no acceleration (cl_mouseAccel 0), you can start + increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the + amplification you want for high deltas with little effect on low mouse deltas. + + cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve + as style 0. The higher the value, the faster the amplification grows with the + mouse delta. + + cl_mouseAccelOffset sets how much base mouse delta will be doubled by + acceleration. The closer to zero you bring it, the more acceleration will + happen at low speeds. This is also very useful if you are changing to a new + mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your + cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely + gain in precision when you do that, but that is not related to mouse + acceleration). + + Mouse acceleration is tricky to configure, and when you do you'll have to + re-learn your aiming. But you will find that it's very much forth it in the + long run. + + If you try the new acceleration code and start using it, I'd be very + interested by your feedback. + 64bit mods If you wish to compile external mods as shared libraries on a 64bit platform, and the mod source is derived from the id Q3 SDK, you will need to modify the diff --git a/code/client/cl_input.c b/code/client/cl_input.c index f0147682..a42030da 100644 --- a/code/client/cl_input.c +++ b/code/client/cl_input.c @@ -435,52 +435,88 @@ void CL_JoystickMove( usercmd_t *cmd ) { CL_MouseMove ================= */ -void CL_MouseMove( usercmd_t *cmd ) { - float mx, my; - float accelSensitivity; - float rate; + +void CL_MouseMove(usercmd_t *cmd) +{ + float mx, my; // allow mouse smoothing - if ( m_filter->integer ) { - mx = ( cl.mouseDx[0] + cl.mouseDx[1] ) * 0.5; - my = ( cl.mouseDy[0] + cl.mouseDy[1] ) * 0.5; - } else { + if (m_filter->integer) + { + mx = (cl.mouseDx[0] + cl.mouseDx[1]) * 0.5f; + my = (cl.mouseDy[0] + cl.mouseDy[1]) * 0.5f; + } + else + { mx = cl.mouseDx[cl.mouseIndex]; my = cl.mouseDy[cl.mouseIndex]; } + cl.mouseIndex ^= 1; cl.mouseDx[cl.mouseIndex] = 0; cl.mouseDy[cl.mouseIndex] = 0; - rate = sqrt( mx * mx + my * my ) / (float)frame_msec; - accelSensitivity = cl_sensitivity->value + rate * cl_mouseAccel->value; - - // scale by FOV - accelSensitivity *= cl.cgameSensitivity; - - if ( rate && cl_showMouseRate->integer ) { - Com_Printf( "%f : %f\n", rate, accelSensitivity ); - } - - mx *= accelSensitivity; - my *= accelSensitivity; - - if (!mx && !my) { + if (mx == 0.0f && my == 0.0f) return; + + if (cl_mouseAccel->value != 0.0f) + { + if(cl_mouseAccelStyle->integer == 0) + { + float accelSensitivity; + float rate; + + rate = sqrt(mx * mx + my * my) / (float) frame_msec; + + accelSensitivity = cl_sensitivity->value + rate * cl_mouseAccel->value; + mx *= accelSensitivity; + my *= accelSensitivity; + + if(cl_showMouseRate->integer) + Com_Printf("rate: %f, accelSensitivity: %f\n", rate, accelSensitivity); + } + else + { + float rate[2]; + float power[2]; + + // sensitivity remains pretty much unchanged at low speeds + // cl_mouseAccel is a power value to how the acceleration is shaped + // cl_mouseAccelOffset is the rate for which the acceleration will have doubled the non accelerated amplification + // NOTE: decouple the config cvars for independent acceleration setup along X and Y? + + rate[0] = fabs(mx) / (float) frame_msec; + rate[1] = fabs(my) / (float) frame_msec; + power[0] = powf(rate[0] / cl_mouseAccelOffset->value, cl_mouseAccel->value); + power[1] = powf(rate[1] / cl_mouseAccelOffset->value, cl_mouseAccel->value); + + mx = cl_sensitivity->value * (mx + ((mx < 0) ? -power[0] : power[0]) * cl_mouseAccelOffset->value); + my = cl_sensitivity->value * (my + ((my < 0) ? -power[1] : power[1]) * cl_mouseAccelOffset->value); + + if(cl_showMouseRate->integer) + Com_Printf("ratex: %f, ratey: %f, powx: %f, powy: %f\n", rate[0], rate[1], power[0], power[1]); + } } + else + { + mx *= cl_sensitivity->value; + my *= cl_sensitivity->value; + } + + // ingame FOV + mx *= cl.cgameSensitivity; + my *= cl.cgameSensitivity; // add mouse X/Y movement to cmd - if ( in_strafe.active ) { - cmd->rightmove = ClampChar( cmd->rightmove + m_side->value * mx ); - } else { + if(in_strafe.active) + cmd->rightmove = ClampChar(cmd->rightmove + m_side->value * mx); + else cl.viewangles[YAW] -= m_yaw->value * mx; - } - if ( (in_mlooking || cl_freelook->integer) && !in_strafe.active ) { + if ((in_mlooking || cl_freelook->integer) && !in_strafe.active) cl.viewangles[PITCH] += m_pitch->value * my; - } else { - cmd->forwardmove = ClampChar( cmd->forwardmove - m_forward->value * my ); - } + else + cmd->forwardmove = ClampChar(cmd->forwardmove - m_forward->value * my); } diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 029dba48..be4d1bc9 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -73,6 +73,8 @@ cvar_t *cl_freelook; cvar_t *cl_sensitivity; cvar_t *cl_mouseAccel; +cvar_t *cl_mouseAccelOffset; +cvar_t *cl_mouseAccelStyle; cvar_t *cl_showMouseRate; cvar_t *m_pitch; @@ -3101,6 +3103,13 @@ void CL_Init( void ) { cl_mouseAccel = Cvar_Get ("cl_mouseAccel", "0", CVAR_ARCHIVE); cl_freelook = Cvar_Get( "cl_freelook", "1", CVAR_ARCHIVE ); + // 0: legacy mouse acceleration + // 1: new implementation + cl_mouseAccelStyle = Cvar_Get( "cl_mouseAccelStyle", "0", CVAR_ARCHIVE ); + // offset for the power function (for style 1, ignored otherwise) + // this should be set to the max rate value + cl_mouseAccelOffset = Cvar_Get( "cl_mouseAccelOffset", "5", CVAR_ARCHIVE ); + cl_showMouseRate = Cvar_Get ("cl_showmouserate", "0", 0); cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE); diff --git a/code/client/client.h b/code/client/client.h index d3707782..7891a83f 100644 --- a/code/client/client.h +++ b/code/client/client.h @@ -379,6 +379,8 @@ extern cvar_t *cl_sensitivity; extern cvar_t *cl_freelook; extern cvar_t *cl_mouseAccel; +extern cvar_t *cl_mouseAccelOffset; +extern cvar_t *cl_mouseAccelStyle; extern cvar_t *cl_showMouseRate; extern cvar_t *m_pitch;