Alright, so I am trying to use the analog stick on a gamepad to move the desktop mouse cursor around. The problem is that I need to be able to get the same smoothness as Attempt 2, but without using an absolute mouse position. The cursor needs to be moved relative to its current position. The reason for this is that many applications (mainly video games) also set the mouse to an absolute position. This causes the application and attempt 2 to fight one another for control of the mouse.
Attempt 1 (relative)
// keep updating the controller state and mouse position
while (true)
{
// getState returns a 2d float vector with normalized values from [-1, 1]
// The cursor is being set relative to its current position here.
SetCursorPosition(GetCursorPosition() + analogStick->getState());
}
This solution works, but suffers from a rounding issue because GetCursorPosition and SetCursorPosition are based on integers. As a result, small movements are not registered because smaller analog movements will always get truncated. Visually speaking, small movements on the analog stick will only move the mouse along the X or Y axis even if you are try to make a diagonal movement.
Attempt 2 (absolute)
vec2 mouseTargetPosition = GetCursorPosition(); // global cursor position
while (true)
{
mouseTargetPosition += leftStick->getState();
vec2 newPosition = lerp(GetCursorPos(), mouseTargetPosition, 0.8f);
SetCursorPos(round(newPosition.x), round(newPosition.y));
}
This solution works great, the mouse responds to the smallest of movements and moves very naturally as a result of interpolating the accumulated analog movements. But, it sets the mouse to an absolute position (mouseTargetPosition), making this solution a deal breaker.