Dynamic Mouse Acceleration

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Dynamic Mouse Acceleration

Post by mh »

OK, now that I've owned up to being a weird person who enjoys writing input code, I'm going to show you how to implement mouse acceleration in Win/GL Quake. This is relatively simple to do, and is based entirely on the MSDN description of how mouse acceleration works in Windows (it may be different for other OS's so look up your documentation if you want to do it).

I'll begin by quoting the description:
The system applies two tests to the specified relative mouse motion when applying acceleration. If the specified distance along either the x or y axis is greater than the first mouse threshold value, and the mouse acceleration level is not zero, the operating system doubles the distance. If the specified distance along either the x or y axis is greater than the second mouse threshold value, and the mouse acceleration level is equal to two, the operating system doubles the distance that resulted from applying the first threshold test. It is thus possible for the operating system to multiply relatively-specified mouse motion along the x or y axis by up to four times.
Seems simple enough. I'm using three cvars here, m_accellevel for the mouse acceleration level, m_accelthreshold1 for the first threshold and m_accelthreshold2 for the second. I assume you know how to declare and register these. ;)

I've given them defaults of 0, 0 and 0 respectively, which is what stock Win/GL Quake uses. (Windows itself uses 0/6/10 as defaults).

Most (only!) sensible place to put the actual acceleration code is in IN_MouseMove, so just before the m_filter.value check we slap in this lot:

Code: Select all

	// add acceleration parameters - per mouse_event MSDN description
	if (m_accellevel.value > 0)
	{
		int oldmx = mx;
		int oldmy = my;

		// threshold 1 doubles when movement is > it
		if (oldmx > m_accelthreshold1.value) mx *= 2;
		if (oldmx < -m_accelthreshold1.value) mx *= 2;
		if (oldmy > m_accelthreshold1.value) my *= 2;
		if (oldmy < -m_accelthreshold1.value) my *= 2;

		if (m_accellevel.value > 1)
		{
			// threshold 2 doubles again when movement is > it
			if (oldmx > m_accelthreshold2.value) mx *= 2;
			if (oldmx < -m_accelthreshold2.value) mx *= 2;
			if (oldmy > m_accelthreshold2.value) my *= 2;
			if (oldmy < -m_accelthreshold2.value) my *= 2;
		}
	}
(Edit: corrected not based on original mouse movement, m_accellevel instead of m_accel).

That's about it. As usual I've left some loose ends for each person to tidy up as they see fit. You may want to remove the command-line options, for example, since we're now able to set it at run-time.

Coupla final notes: firstly, playing with acceleration is not a nice experience (to me, anyway). I don't expect many would use it, but it's still nice to have for the sake of completeness. If you do use it, you may want to fine-tune your sensitivity value (somewhere between half and quarter what you normally run at seems good). Secondly, this will work with DirectInput as well as with software.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Team Xlink
Posts: 368
Joined: Thu Jun 25, 2009 4:45 am
Location: Michigan

Post by Team Xlink »

So this could be used to simulate mouse movement?

Would this also apply to touch screen mice found on labtops?
Post Reply