aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/events/sdl/sdl-events.cpp101
-rw-r--r--backends/events/sdl/sdl-events.h4
-rw-r--r--common/events.h53
-rw-r--r--engines/engine.h10
4 files changed, 166 insertions, 2 deletions
diff --git a/backends/events/sdl/sdl-events.cpp b/backends/events/sdl/sdl-events.cpp
index 29be7d4e74..494e1bf8cd 100644
--- a/backends/events/sdl/sdl-events.cpp
+++ b/backends/events/sdl/sdl-events.cpp
@@ -30,6 +30,8 @@
#include "common/config-manager.h"
#include "common/textconsole.h"
#include "common/fs.h"
+#include "engines/engine.h"
+#include "gui/gui-manager.h"
// FIXME move joystick defines out and replace with confile file options
// we should really allow users to map any key to a joystick button
@@ -902,7 +904,45 @@ void SdlEventSource::closeJoystick() {
}
}
+bool SdlEventSource::shouldGenerateMouseEvents() {
+ // Engine doesn't support joystick -> emulate mouse events
+ if (g_engine && !g_engine->hasFeature(Engine::kSupportsJoystick)) {
+ return true;
+ }
+ if (g_gui.isActive()) {
+ return true;
+ }
+ return false;
+}
+
+int SdlEventSource::mapSDLJoystickButtonToOSystem(Uint8 sdlButton) {
+ Common::JoystickButton osystemButtons[] = {
+ Common::JOYSTICK_BUTTON_A,
+ Common::JOYSTICK_BUTTON_B,
+ Common::JOYSTICK_BUTTON_X,
+ Common::JOYSTICK_BUTTON_Y,
+ Common::JOYSTICK_BUTTON_LEFT_SHOULDER,
+ Common::JOYSTICK_BUTTON_RIGHT_SHOULDER,
+ Common::JOYSTICK_BUTTON_BACK,
+ Common::JOYSTICK_BUTTON_START,
+ Common::JOYSTICK_BUTTON_LEFT_STICK,
+ Common::JOYSTICK_BUTTON_RIGHT_STICK
+ };
+
+ if (sdlButton >= ARRAYSIZE(osystemButtons)) {
+ return -1;
+ }
+
+ return osystemButtons[sdlButton];
+}
+
bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
+ if (!shouldGenerateMouseEvents()) {
+ event.type = Common::EVENT_JOYBUTTON_DOWN;
+ event.joystick.button = mapSDLJoystickButtonToOSystem(ev.jbutton.button);
+ return true;
+ }
+
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONDOWN;
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
@@ -939,6 +979,12 @@ bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) {
}
bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
+ if (!shouldGenerateMouseEvents()) {
+ event.type = Common::EVENT_JOYBUTTON_UP;
+ event.joystick.button = mapSDLJoystickButtonToOSystem(ev.jbutton.button);
+ return true;
+ }
+
if (ev.jbutton.button == JOY_BUT_LMOUSE) {
event.type = Common::EVENT_LBUTTONUP;
return processMouseEvent(event, _km.x / MULTIPLIER, _km.y / MULTIPLIER);
@@ -975,6 +1021,16 @@ bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) {
}
bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) {
+ // TODO: move handleAxisToMouseMotion to Common?
+#if 0
+ if (!shouldGenerateMouseEvents()) {
+ event.type = Common::EVENT_JOYAXIS_MOTION;
+ event.joystick.axis = ev.jaxis.axis;
+ event.joystick.position = ev.jaxis.value;
+ return true;
+ }
+#endif
+
if (ev.jaxis.axis == JOY_XAXIS) {
_km.joy_x = ev.jaxis.value;
return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
@@ -1024,6 +1080,32 @@ bool SdlEventSource::handleJoystickRemoved(const SDL_JoyDeviceEvent &device) {
return false;
}
+int SdlEventSource::mapSDLControllerButtonToOSystem(Uint8 sdlButton) {
+ Common::JoystickButton osystemButtons[] = {
+ Common::JOYSTICK_BUTTON_A,
+ Common::JOYSTICK_BUTTON_B,
+ Common::JOYSTICK_BUTTON_X,
+ Common::JOYSTICK_BUTTON_Y,
+ Common::JOYSTICK_BUTTON_BACK,
+ Common::JOYSTICK_BUTTON_GUIDE,
+ Common::JOYSTICK_BUTTON_START,
+ Common::JOYSTICK_BUTTON_LEFT_STICK,
+ Common::JOYSTICK_BUTTON_RIGHT_STICK,
+ Common::JOYSTICK_BUTTON_LEFT_SHOULDER,
+ Common::JOYSTICK_BUTTON_RIGHT_SHOULDER,
+ Common::JOYSTICK_BUTTON_DPAD_UP,
+ Common::JOYSTICK_BUTTON_DPAD_DOWN,
+ Common::JOYSTICK_BUTTON_DPAD_LEFT,
+ Common::JOYSTICK_BUTTON_DPAD_RIGHT
+ };
+
+ if (sdlButton >= ARRAYSIZE(osystemButtons)) {
+ return -1;
+ }
+
+ return osystemButtons[sdlButton];
+}
+
bool SdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp) {
using namespace Common;
@@ -1071,6 +1153,15 @@ bool SdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &
{ EVENT_KEYDOWN, KeyState(KEYCODE_KP6, 0), EVENT_KEYDOWN, KeyState(KEYCODE_KP3, 0) }
};
+ if (!shouldGenerateMouseEvents()) {
+ event.type = buttonUp ? Common::EVENT_JOYBUTTON_UP : Common::EVENT_JOYBUTTON_DOWN;
+ event.joystick.button = mapSDLControllerButtonToOSystem(ev.cbutton.button);
+ if (event.joystick.button == -1)
+ return false;
+
+ return true;
+ }
+
if (ev.cbutton.button > SDL_CONTROLLER_BUTTON_DPAD_RIGHT) {
warning("Unknown SDL controller button: '%d'", ev.cbutton.button);
return false;
@@ -1115,6 +1206,16 @@ bool SdlEventSource::handleControllerButton(const SDL_Event &ev, Common::Event &
}
bool SdlEventSource::handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event) {
+ // TODO: move handleAxisToMouseMotion to Common?
+#if 0
+ if (!shouldGenerateMouseEvents()) {
+ event.type = Common::EVENT_JOYAXIS_MOTION;
+ event.joystick.axis = ev.caxis.axis;
+ event.joystick.position = ev.caxis.value;
+ return true;
+ }
+#endif
+
if (ev.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) {
_km.joy_x = ev.caxis.value;
return handleAxisToMouseMotion(_km.joy_x, _km.joy_y);
diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h
index c2ae0023ce..6050c80297 100644
--- a/backends/events/sdl/sdl-events.h
+++ b/backends/events/sdl/sdl-events.h
@@ -139,6 +139,7 @@ protected:
virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleSysWMEvent(SDL_Event &ev, Common::Event &event);
+ virtual int mapSDLJoystickButtonToOSystem(Uint8 sdlButton);
virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event);
virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event);
@@ -148,10 +149,13 @@ protected:
#if SDL_VERSION_ATLEAST(2, 0, 0)
virtual bool handleJoystickAdded(const SDL_JoyDeviceEvent &event);
virtual bool handleJoystickRemoved(const SDL_JoyDeviceEvent &device);
+ virtual int mapSDLControllerButtonToOSystem(Uint8 sdlButton);
virtual bool handleControllerButton(const SDL_Event &ev, Common::Event &event, bool buttonUp);
virtual bool handleControllerAxisMotion(const SDL_Event &ev, Common::Event &event);
#endif
+ bool shouldGenerateMouseEvents();
+
//@}
/**
diff --git a/common/events.h b/common/events.h
index 4b35725225..ff5d2874f4 100644
--- a/common/events.h
+++ b/common/events.h
@@ -86,7 +86,52 @@ enum EventType {
EVENT_VIRTUAL_KEYBOARD = 20,
#endif
- EVENT_DROP_FILE = 23
+ EVENT_DROP_FILE = 23,
+
+ EVENT_JOYAXIS_MOTION = 24,
+ EVENT_JOYBUTTON_DOWN = 25,
+ EVENT_JOYBUTTON_UP = 26
+};
+
+const int16 JOYAXIS_MIN = -32768;
+const int16 JOYAXIS_MAX = 32767;
+
+/**
+ * Data structure for joystick events
+ */
+struct JoystickState {
+ /** The axis for EVENT_JOYAXIS_MOTION events */
+ byte axis;
+ /** The new axis position for EVENT_JOYAXIS_MOTION events */
+ int16 position;
+ /**
+ * The button index for EVENT_JOYBUTTON_DOWN/UP events
+ *
+ * Some of the button indices match well-known game controller
+ * buttons. See JoystickButton.
+ */
+ byte button;
+};
+
+/**
+ * The list named buttons available from a joystick
+ */
+enum JoystickButton {
+ JOYSTICK_BUTTON_A,
+ JOYSTICK_BUTTON_B,
+ JOYSTICK_BUTTON_X,
+ JOYSTICK_BUTTON_Y,
+ JOYSTICK_BUTTON_BACK,
+ JOYSTICK_BUTTON_GUIDE,
+ JOYSTICK_BUTTON_START,
+ JOYSTICK_BUTTON_LEFT_STICK,
+ JOYSTICK_BUTTON_RIGHT_STICK,
+ JOYSTICK_BUTTON_LEFT_SHOULDER,
+ JOYSTICK_BUTTON_RIGHT_SHOULDER,
+ JOYSTICK_BUTTON_DPAD_UP,
+ JOYSTICK_BUTTON_DPAD_DOWN,
+ JOYSTICK_BUTTON_DPAD_LEFT,
+ JOYSTICK_BUTTON_DPAD_RIGHT
};
typedef uint32 CustomEventType;
@@ -130,6 +175,12 @@ struct Event {
/* The path of the file or directory dragged to the ScummVM window */
Common::String path;
+ /**
+ * Joystick data; only valid for joystick events (EVENT_JOYAXIS_MOTION,
+ * EVENT_JOYBUTTON_DOWN and EVENT_JOYBUTTON_UP).
+ */
+ JoystickState joystick;
+
Event() : type(EVENT_INVALID), kbdRepeat(false) {
#ifdef ENABLE_KEYMAPPER
customType = 0;
diff --git a/engines/engine.h b/engines/engine.h
index d004c29f84..cc7994e047 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -132,7 +132,15 @@ public:
* If this feature is supported, then the corresponding MetaEngine *must*
* support the kSupportsListSaves feature.
*/
- kSupportsSavingDuringRuntime
+ kSupportsSavingDuringRuntime,
+
+ /**
+ * Engine must receive joystick events because the game uses them.
+ * For engines which have not this feature, joystick events are converted
+ * to mouse events.
+ */
+ kSupportsJoystick
+
};