Reported in version: 2.0.10 Reported for operating system, platform: All, All
Comments on the original bug report:
On 2019-09-30 10:45:56 +0000, hmk wrote:
When scaling is enabled (e.g. via SDL_RenderSetLogicalSize, size not equal to window size), mouse motion events are also scaled. Small motions are rounded up (SDL_max() when the value after scaling is less than 1), while larger motions are truncated by the floating point -> integer conversion.
The end result feels something like mouse reverse mouse acceleration + angle snapping at low speeds, but less consistent (amount of truncation & rounding depends on how fast the mouse is moved) and potentially much worse if the scaling factor is large. This pretty much makes it useless for anything where you need precise mouse aiming (think of games). I suspect this is why aiming gets so terrible in some games that let you use scaling to reduce the render resolution (e.g. Ion Fury).
With 4x4 scaling, I can reproduce a situation where it takes three fast flicks of the mouse across the pad to undo one slow sweep across the pad. In other words, extreme reverse acceleration. This does not happen when scaling is disabled.
Furthermore, any game that uses relative mouse motion events for 3D camera rotation probably wants the raw mouse deltas and not a value that depends on scaling and resolution and rounding and truncation. Ideal camera rotation just takes mouse input, multiplies it by sensitivity, and adds it to the angle-in-radians or whatever measure is used for yaw & pitch. Pixels and screen resolution or window dimensions should not be a part of the equation at all, even if it could be implemented without rounding errors.
A couple ideas:
add raw values in the event (ABI break I guess, so not an option?)
add a hint to disable scaling of mouse motion (perhaps only for relative motion? I don't know, I haven't thought about absolute motion)
Furthermore, behavior of existing applications that do not use the supposed hint or new fields could be improved by storing the fractional part of the scaled motion somewhere, and adding it to the next motion event. This way you can also remove the max() and avoid rounding up (slow motion will have correct sensitivity; a number of scaled deltas smaller than one will eventually add to 1 or more).
On 2019-09-30 19:18:25 +0000, hmk wrote:
Created attachment 3975
Patch: keep track of xrel/yrel remainder and don't round so madly
PoC for what I proposed at the end.
This completely eliminates angle snapping for me, and makes sensitivity consistent. In other words, it's completely usable for, say, aiming in a first person shooter.
I still don't like that sensitivity changes with scale, but I don't know if changing that would break existing applications
On 2019-09-30 19:58:03 +0000, hmk wrote:
Created attachment 3976
add a hint for toggling relative scaling
Add a hint (SDL_HINT_MOUSE_RELATIVE_SCALING) that can be used to turn off scaling. Should apply on top of the previous patch.
On 2020-04-10 05:27:35 +0000, Ryan C. Gordon wrote:
This looks good to me. I'm going to clean up the truncf call to use an SDL equivalent in the morning and apply this patch.
On 2020-04-10 16:43:37 +0000, Ryan C. Gordon wrote:
(In reply to Ryan C. Gordon from comment # 3)
This looks good to me. I'm going to clean up the truncf call to use an SDL
equivalent in the morning and apply this patch.
Ok, these patches (and an initial SDL_truncf implementation) are in revision control, thanks!