mirror of
https://github.com/encounter/SDL.git
synced 2025-12-21 02:39:10 +00:00
Added a hint SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE to control whether to use system mouse acceleration on raw relative motion.
This is currently only implemented on Windows, and "Enhanced pointer precision" mode is not quite correct.
This commit is contained in:
@@ -1628,6 +1628,13 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETTINGCHANGE:
|
||||
if (wParam == SPI_SETMOUSE || wParam == SPI_SETMOUSESPEED) {
|
||||
WIN_UpdateMouseSystemScale();
|
||||
}
|
||||
break;
|
||||
|
||||
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +363,8 @@ WIN_InitMouse(_THIS)
|
||||
SDL_SetDefaultCursor(WIN_CreateDefaultCursor());
|
||||
|
||||
SDL_blank_cursor = WIN_CreateBlankCursor();
|
||||
|
||||
WIN_UpdateMouseSystemScale();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -379,6 +381,109 @@ WIN_QuitMouse(_THIS)
|
||||
}
|
||||
}
|
||||
|
||||
/* For a great description of how the enhanced mouse curve works, see:
|
||||
* https://superuser.com/questions/278362/windows-mouse-acceleration-curve-smoothmousexcurve-and-smoothmouseycurve
|
||||
* http://www.esreality.com/?a=post&id=1846538/
|
||||
*/
|
||||
static SDL_bool
|
||||
LoadFiveFixedPointFloats(BYTE *bytes, float *values)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 5; ++i) {
|
||||
float fraction = (float)((Uint16) bytes[1] << 8 | bytes[0]) / 65535.0f;
|
||||
float value = (float)(((Uint16)bytes[3] << 8) | bytes[2]) + fraction;
|
||||
*values++ = value;
|
||||
bytes += 8;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
WIN_SetEnhancedMouseScale(int mouse_speed)
|
||||
{
|
||||
float scale = (float) mouse_speed / 10.0f;
|
||||
HKEY hKey;
|
||||
DWORD dwType = REG_BINARY;
|
||||
BYTE value[40];
|
||||
DWORD length = sizeof(value);
|
||||
int i;
|
||||
float xpoints[5];
|
||||
float ypoints[5];
|
||||
float scale_points[10];
|
||||
const int dpi = 96; // FIXME, how do we handle different monitors with different DPI?
|
||||
const float display_factor = 3.5f * (150.0f / dpi);
|
||||
|
||||
if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Mouse", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
|
||||
if (RegQueryValueExW(hKey, L"SmoothMouseXCurve", 0, &dwType, value, &length) == ERROR_SUCCESS &&
|
||||
LoadFiveFixedPointFloats(value, xpoints) &&
|
||||
RegQueryValueExW(hKey, L"SmoothMouseYCurve", 0, &dwType, value, &length) == ERROR_SUCCESS &&
|
||||
LoadFiveFixedPointFloats(value, ypoints)) {
|
||||
for (i = 0; i < 5; ++i) {
|
||||
float gain;
|
||||
if (xpoints[i] > 0.0f) {
|
||||
gain = (ypoints[i] / xpoints[i]) * scale;
|
||||
} else {
|
||||
gain = 0.0f;
|
||||
}
|
||||
scale_points[i * 2] = xpoints[i];
|
||||
scale_points[i * 2 + 1] = gain / display_factor;
|
||||
//SDL_Log("Point %d = %f,%f\n", i, scale_points[i * 2], scale_points[i * 2 + 1]);
|
||||
}
|
||||
SDL_SetMouseSystemScale(SDL_arraysize(scale_points), scale_points);
|
||||
}
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WIN_SetLinearMouseScale(int mouse_speed)
|
||||
{
|
||||
static float mouse_speed_scale[] = {
|
||||
0.0f,
|
||||
1 / 32.0f,
|
||||
1 / 16.0f,
|
||||
1 / 8.0f,
|
||||
2 / 8.0f,
|
||||
3 / 8.0f,
|
||||
4 / 8.0f,
|
||||
5 / 8.0f,
|
||||
6 / 8.0f,
|
||||
7 / 8.0f,
|
||||
1.0f,
|
||||
1.25f,
|
||||
1.5f,
|
||||
1.75f,
|
||||
2.0f,
|
||||
2.25f,
|
||||
2.5f,
|
||||
2.75f,
|
||||
3.0f,
|
||||
3.25f,
|
||||
3.5f
|
||||
};
|
||||
|
||||
if (mouse_speed > 0 && mouse_speed < SDL_arraysize(mouse_speed_scale)) {
|
||||
SDL_SetMouseSystemScale(1, &mouse_speed_scale[mouse_speed]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WIN_UpdateMouseSystemScale()
|
||||
{
|
||||
int mouse_speed;
|
||||
int params[3] = { 0, 0, 0 };
|
||||
|
||||
if (SystemParametersInfo(SPI_GETMOUSESPEED, 0, &mouse_speed, 0) &&
|
||||
SystemParametersInfo(SPI_GETMOUSE, 0, params, 0)) {
|
||||
if (params[2]) {
|
||||
WIN_SetEnhancedMouseScale(mouse_speed);
|
||||
} else {
|
||||
WIN_SetLinearMouseScale(mouse_speed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
@@ -29,6 +29,7 @@ extern HCURSOR SDL_cursor;
|
||||
extern void WIN_InitMouse(_THIS);
|
||||
extern void WIN_QuitMouse(_THIS);
|
||||
extern void WIN_SetCursorPos(int x, int y);
|
||||
extern void WIN_UpdateMouseSystemScale();
|
||||
|
||||
#endif /* SDL_windowsmouse_h_ */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user