From 45bd7a8b75ebd8227ec4a09e427a66b1bb2796d1 Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Sun, 19 Feb 2017 20:14:51 -0600 Subject: SDL: Fix erratic analog pointer + control options Fixes erratic speeds in analog pointer motion Implemented option to set analog/keyboard pointer speed and control the analog joystick deadzone. The deadzone option appears only if the build supports analog joystick (via JOY_ANALOG define) --- backends/events/sdl/sdl-events.cpp | 75 ++++++++++++++++++++++++++++++-------- backends/events/sdl/sdl-events.h | 2 +- backends/platform/sdl/sdl.cpp | 14 +++++++ 3 files changed, 75 insertions(+), 16 deletions(-) (limited to 'backends') diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp index 469f1d5a44..8c1194419f 100644 --- a/backends/events/sdl/sdl-events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -231,18 +231,59 @@ bool SdlEventSource::handleKbdMouse(Common::Event &event) { } } + int16 speedFactor = 25; + + if (g_system->hasFeature(OSystem::kFeatureKbdMouseSpeed)) { + switch (ConfMan.getInt("kbdmouse_speed")) { + // 0.25 keyboard pointer speed + case 0: + speedFactor = 100; + break; + // 0.5 speed + case 1: + speedFactor = 50; + break; + // 0.75 speed + case 2: + speedFactor = 37; + break; + // 1.0 speed + case 3: + speedFactor = 25; + break; + // 1.25 speed + case 4: + speedFactor = 20; + break; + // 1.5 speed + case 5: + speedFactor = 17; + break; + // 1.75 speed + case 6: + speedFactor = 14; + break; + // 2.0 speed + case 7: + speedFactor = 12; + break; + default: + speedFactor = 25; + } + } + // - The modifier key makes the mouse movement slower - // - The extra factor "delay/25" ensures velocities + // - The extra factor "delay/speedFactor" ensures velocities // are independent of the kbdMouse update rate // - all velocities were originally chosen // at a delay of 25, so that is the reference used here // - note: operator order is important to avoid overflow if (_km.modifier) { - _km.x += ((_km.x_vel / 10) * ((int16)_km.delay_time)) / 25; - _km.y += ((_km.y_vel / 10) * ((int16)_km.delay_time)) / 25; + _km.x += ((_km.x_vel / 10) * ((int16)_km.delay_time)) / speedFactor; + _km.y += ((_km.y_vel / 10) * ((int16)_km.delay_time)) / speedFactor; } else { - _km.x += (_km.x_vel * ((int16)_km.delay_time)) / 25; - _km.y += (_km.y_vel * ((int16)_km.delay_time)) / 25; + _km.x += (_km.x_vel * ((int16)_km.delay_time)) / speedFactor; + _km.y += (_km.y_vel * ((int16)_km.delay_time)) / speedFactor; } if (_km.x < 0) { @@ -826,8 +867,7 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { if (ev.jaxis.axis == JOY_XAXIS) { #ifdef JOY_ANALOG - _km.x_vel = axis / vel_to_axis; - _km.x_down_count = 0; + _km.joy_x = axis; #else if (axis != 0) { _km.x_vel = (axis > 0) ? 1 * MULTIPLIER:-1 * MULTIPLIER; @@ -842,8 +882,7 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { axis = -axis; #endif #ifdef JOY_ANALOG - _km.y_vel = -axis / vel_to_axis; - _km.y_down_count = 0; + _km.joy_y = -axis; #else if (axis != 0) { _km.y_vel = (-axis > 0) ? 1 * MULTIPLIER: -1 * MULTIPLIER; @@ -856,21 +895,25 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { } #ifdef JOY_ANALOG // radial and scaled analog joystick deadzone - float analogX = (float) (_km.x_vel * vel_to_axis); - float analogY = (float) (_km.y_vel * vel_to_axis); - float deadZone = (float) JOY_DEADZONE; + float analogX = (float)_km.joy_x; + float analogY = (float)_km.joy_y; + float deadZone = (float)JOY_DEADZONE; + if (g_system->hasFeature(OSystem::kFeatureJoystickDeadzone)) + deadZone = (float)ConfMan.getInt("joystick_deadzone") * 1000.0f; float scalingFactor = 1.0f; float magnitude = 0.0f; magnitude = sqrt(analogX * analogX + analogY * analogY); if (magnitude >= deadZone) { + _km.x_down_count = 0; + _km.y_down_count = 0; scalingFactor = 1.0f / magnitude * (magnitude - deadZone) / (32769.0f - deadZone); - _km.x_vel = (int16) (analogX * scalingFactor * 32768.0f / vel_to_axis); - _km.y_vel = (int16) (analogY * scalingFactor * 32768.0f / vel_to_axis); + _km.x_vel = (int16)(analogX * scalingFactor * 32768.0f / vel_to_axis); + _km.y_vel = (int16)(analogY * scalingFactor * 32768.0f / vel_to_axis); } else { - _km.y_vel = 0; _km.x_vel = 0; + _km.y_vel = 0; } #endif @@ -951,6 +994,8 @@ void SdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) { _km.delay_time = 12; _km.last_time = 0; _km.modifier = false; + _km.joy_x = 0; + _km.joy_y = 0; } bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) { diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h index 334bf8acfc..cf445e9e2c 100644 --- a/backends/events/sdl/sdl-events.h +++ b/backends/events/sdl/sdl-events.h @@ -60,7 +60,7 @@ protected: //@{ struct KbdMouse { - int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count; + int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count, joy_x, joy_y; uint32 last_time, delay_time, x_down_time, y_down_time; bool modifier; }; diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 74c40ade10..1c5a7c2cbf 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -179,6 +179,10 @@ bool OSystem_SDL::hasFeature(Feature f) { #if SDL_VERSION_ATLEAST(2, 0, 0) if (f == kFeatureClipboardSupport) return true; #endif +#ifdef JOY_ANALOG + if (f == kFeatureJoystickDeadzone) return true; +#endif + if (f == kFeatureKbdMouseSpeed) return true; return ModularBackend::hasFeature(f); } @@ -274,6 +278,16 @@ void OSystem_SDL::initBackend() { _inited = true; + if (!ConfMan.hasKey("kbdmouse_speed")) { + ConfMan.registerDefault("kbdmouse_speed", 3); + ConfMan.setInt("kbdmouse_speed", 3); + } +#ifdef JOY_ANALOG + if (!ConfMan.hasKey("joystick_deadzone")) { + ConfMan.registerDefault("joystick_deadzone", 3); + ConfMan.setInt("joystick_deadzone", 3); + } +#endif ModularBackend::initBackend(); // We have to initialize the graphics manager before the event manager -- cgit v1.2.3