aboutsummaryrefslogtreecommitdiff
path: root/backends/events/sdl/sdl-events.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/events/sdl/sdl-events.cpp')
-rw-r--r--backends/events/sdl/sdl-events.cpp144
1 files changed, 102 insertions, 42 deletions
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 5fb66a7ec4..469f1d5a44 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -30,6 +30,10 @@
#include "common/config-manager.h"
#include "common/textconsole.h"
+#ifdef JOY_ANALOG
+#include "math.h"
+#endif
+
// FIXME move joystick defines out and replace with confile file options
// we should really allow users to map any key to a joystick button
#define JOY_DEADZONE 3200
@@ -175,15 +179,20 @@ void SdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
}
// Update the "keyboard mouse" coords
- _km.x = x;
- _km.y = y;
+ _km.x = x * MULTIPLIER;
+ _km.y = y * MULTIPLIER;
}
-void SdlEventSource::handleKbdMouse() {
+bool SdlEventSource::handleKbdMouse(Common::Event &event) {
+ // returns true if an event is generated
// Skip recording of these events
uint32 curTime = g_system->getMillis(true);
if (curTime >= _km.last_time + _km.delay_time) {
+
+ int16 oldKmX = _km.x;
+ int16 oldKmY = _km.y;
+
_km.last_time = curTime;
if (_km.x_down_count == 1) {
_km.x_down_time = curTime;
@@ -196,60 +205,84 @@ void SdlEventSource::handleKbdMouse() {
if (_km.x_vel || _km.y_vel) {
if (_km.x_down_count) {
- if (curTime > _km.x_down_time + _km.delay_time * 12) {
+ if (curTime > _km.x_down_time + 300) {
if (_km.x_vel > 0)
- _km.x_vel++;
+ _km.x_vel += MULTIPLIER;
else
- _km.x_vel--;
- } else if (curTime > _km.x_down_time + _km.delay_time * 8) {
+ _km.x_vel -= MULTIPLIER;
+ } else if (curTime > _km.x_down_time + 200) {
if (_km.x_vel > 0)
- _km.x_vel = 5;
+ _km.x_vel = 5 * MULTIPLIER;
else
- _km.x_vel = -5;
+ _km.x_vel = -5 * MULTIPLIER;
}
}
if (_km.y_down_count) {
- if (curTime > _km.y_down_time + _km.delay_time * 12) {
+ if (curTime > _km.y_down_time + 300) {
if (_km.y_vel > 0)
- _km.y_vel++;
+ _km.y_vel += MULTIPLIER;
else
- _km.y_vel--;
- } else if (curTime > _km.y_down_time + _km.delay_time * 8) {
+ _km.y_vel -= MULTIPLIER;
+ } else if (curTime > _km.y_down_time + 200) {
if (_km.y_vel > 0)
- _km.y_vel = 5;
+ _km.y_vel = 5 * MULTIPLIER;
else
- _km.y_vel = -5;
+ _km.y_vel = -5 * MULTIPLIER;
}
}
- _km.x += _km.x_vel;
- _km.y += _km.y_vel;
+ // - The modifier key makes the mouse movement slower
+ // - The extra factor "delay/25" 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;
+ } else {
+ _km.x += (_km.x_vel * ((int16)_km.delay_time)) / 25;
+ _km.y += (_km.y_vel * ((int16)_km.delay_time)) / 25;
+ }
if (_km.x < 0) {
_km.x = 0;
- _km.x_vel = -1;
+ _km.x_vel = -1 * MULTIPLIER;
_km.x_down_count = 1;
- } else if (_km.x > _km.x_max) {
- _km.x = _km.x_max;
- _km.x_vel = 1;
+ } else if (_km.x > _km.x_max * MULTIPLIER) {
+ _km.x = _km.x_max * MULTIPLIER;
+ _km.x_vel = 1 * MULTIPLIER;
_km.x_down_count = 1;
}
if (_km.y < 0) {
_km.y = 0;
- _km.y_vel = -1;
+ _km.y_vel = -1 * MULTIPLIER;
_km.y_down_count = 1;
- } else if (_km.y > _km.y_max) {
- _km.y = _km.y_max;
- _km.y_vel = 1;
+ } else if (_km.y > _km.y_max * MULTIPLIER) {
+ _km.y = _km.y_max * MULTIPLIER;
+ _km.y_vel = 1 * MULTIPLIER;
_km.y_down_count = 1;
}
if (_graphicsManager) {
- _graphicsManager->getWindow()->warpMouseInWindow((Uint16)_km.x, (Uint16)_km.y);
+ _graphicsManager->getWindow()->warpMouseInWindow((Uint16)(_km.x / MULTIPLIER), (Uint16)(_km.y / MULTIPLIER));
+ }
+
+ if (_km.x != oldKmX || _km.y != oldKmY) {
+ // keep hi-res coordinates since
+ // processMouseEvent will overwrite them with lo-res numbers
+ oldKmX = _km.x;
+ oldKmY = _km.y;
+ event.type = Common::EVENT_MOUSEMOVE;
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
+ _km.x = oldKmX;
+ _km.y = oldKmY;
+ return true;
}
}
}
+ return false;
}
void SdlEventSource::SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event) {
@@ -425,7 +458,6 @@ Common::KeyCode SdlEventSource::SDLToOSystemKeycode(const SDLKey key) {
}
bool SdlEventSource::pollEvent(Common::Event &event) {
- handleKbdMouse();
#if SDL_VERSION_ATLEAST(2, 0, 0)
// In case we still need to send a key up event for a key down from a
@@ -451,6 +483,12 @@ bool SdlEventSource::pollEvent(Common::Event &event) {
if (dispatchSDLEvent(ev, event))
return true;
}
+
+ // Handle mouse control via analog joystick and keyboard
+ if (handleKbdMouse(event)) {
+ return true;
+ }
+
return false;
}
@@ -485,7 +523,7 @@ bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) {
// with a mouse wheel event. However, SDL2 does not supply
// these, thus we use whatever we got last time. It seems
// these are always stored in _km.x, _km.y.
- processMouseEvent(event, _km.x, _km.y);
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
if (yDir < 0) {
event.type = Common::EVENT_WHEELDOWN;
return true;
@@ -712,10 +750,10 @@ bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) {
bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONDOWN;
- processMouseEvent(event, _km.x, _km.y);
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONDOWN;
- processMouseEvent(event, _km.x, _km.y);
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYDOWN;
switch (ev.jbutton.button) {
@@ -743,10 +781,10 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONUP;
- processMouseEvent(event, _km.x, _km.y);
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
event.type = Common::EVENT_RBUTTONUP;
- processMouseEvent(event, _km.x, _km.y);
+ processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
} else {
event.type = Common::EVENT_KEYUP;
switch (ev.jbutton.button) {
@@ -772,23 +810,27 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
}
bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
+
int axis = ev.jaxis.value;
+#ifdef JOY_ANALOG
+ // conversion factor between keyboard mouse and joy axis value
+ int vel_to_axis = (1500 / MULTIPLIER);
+#else
if (axis > JOY_DEADZONE) {
axis -= JOY_DEADZONE;
- event.type = Common::EVENT_MOUSEMOVE;
} else if (axis < -JOY_DEADZONE) {
axis += JOY_DEADZONE;
- event.type = Common::EVENT_MOUSEMOVE;
} else
axis = 0;
+#endif
if (ev.jaxis.axis == JOY_XAXIS) {
#ifdef JOY_ANALOG
- _km.x_vel = axis / 2000;
+ _km.x_vel = axis / vel_to_axis;
_km.x_down_count = 0;
#else
if (axis != 0) {
- _km.x_vel = (axis > 0) ? 1:-1;
+ _km.x_vel = (axis > 0) ? 1 * MULTIPLIER:-1 * MULTIPLIER;
_km.x_down_count = 1;
} else {
_km.x_vel = 0;
@@ -800,11 +842,11 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
axis = -axis;
#endif
#ifdef JOY_ANALOG
- _km.y_vel = -axis / 2000;
+ _km.y_vel = -axis / vel_to_axis;
_km.y_down_count = 0;
#else
if (axis != 0) {
- _km.y_vel = (-axis > 0) ? 1: -1;
+ _km.y_vel = (-axis > 0) ? 1 * MULTIPLIER: -1 * MULTIPLIER;
_km.y_down_count = 1;
} else {
_km.y_vel = 0;
@@ -812,10 +854,27 @@ bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
}
#endif
}
+#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 scalingFactor = 1.0f;
+ float magnitude = 0.0f;
+
+ magnitude = sqrt(analogX * analogX + analogY * analogY);
+
+ if (magnitude >= deadZone) {
+ 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);
+ } else {
+ _km.y_vel = 0;
+ _km.x_vel = 0;
+ }
+#endif
- processMouseEvent(event, _km.x, _km.y);
-
- return true;
+ return false;
}
bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
@@ -889,8 +948,9 @@ bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) {
void SdlEventSource::resetKeyboardEmulation(int16 x_max, int16 y_max) {
_km.x_max = x_max;
_km.y_max = y_max;
- _km.delay_time = 25;
+ _km.delay_time = 12;
_km.last_time = 0;
+ _km.modifier = false;
}
bool SdlEventSource::handleResizeEvent(Common::Event &event, int w, int h) {