Browse Source

Add support for SDL2 GameControllers

Jordan Patterson 12 years ago
parent
commit
1a49c6ebfc

+ 1 - 1
Source/Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -204,7 +204,7 @@ Graphics::Graphics(Context* context) :
     SetTextureUnitMappings();
     
     // Initialize SDL now. Graphics should be the first SDL-using subsystem to be created
-    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
+    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_NOPARACHUTE);
     
     // Register Graphics library object factories
     RegisterGraphicsLibrary(context_);

+ 1 - 1
Source/Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -189,7 +189,7 @@ Graphics::Graphics(Context* context_) :
     ResetCachedState();
     
     // Initialize SDL now. Graphics should be the first SDL-using subsystem to be created
-    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE);
+    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_NOPARACHUTE);
     
     // Register Graphics library object factories
     RegisterGraphicsLibrary(context_);

+ 61 - 0
Source/Engine/Input/Input.cpp

@@ -255,6 +255,10 @@ bool Input::OpenJoystick(unsigned index)
 
         JoystickState& state = joysticks_[index];
         state.joystick_ = joystick;
+        if (SDL_IsGameController(index))
+        {
+            state.controller_ = SDL_GameControllerOpen(index);
+        }
         state.buttons_.Resize(SDL_JoystickNumButtons(joystick));
         state.buttonPress_.Resize(state.buttons_.Size());
         state.axes_.Resize(SDL_JoystickNumAxes(joystick));
@@ -846,6 +850,63 @@ void Input::HandleSDLEvent(void* sdlEvent)
         }
         break;
 
+    case SDL_CONTROLLERBUTTONDOWN:
+        {
+            using namespace ControllerButtonDown;
+
+            unsigned button = evt.cbutton.button;
+            unsigned joystickIndex = joystickIDMap_[evt.cbutton.which];
+
+            VariantMap eventData;
+            eventData[P_JOYSTICK] = joystickIndex;
+            eventData[P_BUTTON] = button;
+
+            if (joystickIndex < joysticks_.Size() && button < joysticks_[joystickIndex].buttons_.Size()) {
+                joysticks_[joystickIndex].buttons_[button] = true;
+                joysticks_[joystickIndex].buttonPress_[button] = true;
+                SendEvent(E_CONTROLLERBUTTONDOWN, eventData);
+            }
+        }
+        break;
+
+    case SDL_CONTROLLERBUTTONUP:
+        {
+            using namespace ControllerButtonUp;
+
+            unsigned button = evt.cbutton.button;
+            unsigned joystickIndex = joystickIDMap_[evt.cbutton.which];
+
+            VariantMap eventData;
+            eventData[P_JOYSTICK] = joystickIndex;
+            eventData[P_BUTTON] = button;
+
+            if (joystickIndex < joysticks_.Size() && button < joysticks_[joystickIndex].buttons_.Size()) {
+                joysticks_[joystickIndex].buttons_[button] = false;
+                SendEvent(E_CONTROLLERBUTTONUP, eventData);
+            }
+        }
+        break;
+
+    case SDL_CONTROLLERAXISMOTION:
+        {
+            using namespace ControllerAxisMove;
+
+            unsigned joystickIndex = joystickIDMap_[evt.caxis.which];
+
+            VariantMap eventData;
+            eventData[P_JOYSTICK] = joystickIndex;
+            eventData[P_AXIS] = evt.caxis.axis;
+            eventData[P_POSITION] = Clamp((float)evt.caxis.value / 32767.0f, -1.0f, 1.0f);
+
+            if (joystickIndex < joysticks_.Size() && evt.caxis.axis <
+                joysticks_[joystickIndex].axes_.Size())
+            {
+                joysticks_[joystickIndex].axes_[evt.caxis.axis] = eventData[P_POSITION].GetFloat();
+                SendEvent(E_CONTROLLERAXISMOVE, eventData);
+            }
+        }
+        break;
+
     case SDL_WINDOWEVENT:
         {
             switch (evt.window.event)

+ 3 - 1
Source/Engine/Input/Input.h

@@ -52,7 +52,7 @@ struct JoystickState
 {
     /// Construct with defaults.
     JoystickState() :
-        joystick_(0)
+        joystick_(0), controller_(0)
     {
     }
     
@@ -101,6 +101,8 @@ struct JoystickState
     
     /// SDL joystick.
     SDL_Joystick* joystick_;
+    /// SDL game controller
+    SDL_GameController* controller_;
     /// Joystick name.
     String name_;
     /// Button up/down state.

+ 46 - 0
Source/Engine/Input/InputEvents.h

@@ -25,6 +25,7 @@
 #include "Object.h"
 
 #include <SDL_joystick.h>
+#include <SDL_gamecontroller.h>
 #include <SDL_keycode.h>
 
 namespace Urho3D
@@ -148,6 +149,28 @@ EVENT(E_JOYSTICKHATMOVE, JoystickHatMove)
     PARAM(P_POSITION, Position);            // int
 }
 
+/// Controller button pressed
+EVENT(E_CONTROLLERBUTTONDOWN, ControllerButtonDown)
+{
+    PARAM(P_JOYSTICK, Joystick);            // int
+    PARAM(P_BUTTON, Button);                // int
+}
+
+/// Controller button released.
+EVENT(E_CONTROLLERBUTTONUP, ControllerButtonUp)
+{
+    PARAM(P_JOYSTICK, Joystick);            // int
+    PARAM(P_BUTTON, Button);                // int
+}
+
+/// Controller axis moved.
+EVENT(E_CONTROLLERAXISMOVE, ControllerAxisMove)
+{
+    PARAM(P_JOYSTICK, Joystick);            // int
+    PARAM(P_AXIS, Button);                  // int
+    PARAM(P_POSITION, Position);            // float
+}
+
 /// A file was drag-dropped into the application window.
 EVENT(E_DROPFILE, DropFile)
 {
@@ -262,4 +285,27 @@ static const int HAT_RIGHT = SDL_HAT_RIGHT;
 static const int HAT_DOWN = SDL_HAT_DOWN;
 static const int HAT_LEFT = SDL_HAT_LEFT;
 
+static const int CONTROLLER_BUTTON_A = SDL_CONTROLLER_BUTTON_A;
+static const int CONTROLLER_BUTTON_B = SDL_CONTROLLER_BUTTON_B;
+static const int CONTROLLER_BUTTON_X = SDL_CONTROLLER_BUTTON_X;
+static const int CONTROLLER_BUTTON_Y = SDL_CONTROLLER_BUTTON_Y;
+static const int CONTROLLER_BUTTON_BACK = SDL_CONTROLLER_BUTTON_BACK;
+static const int CONTROLLER_BUTTON_GUIDE = SDL_CONTROLLER_BUTTON_GUIDE;
+static const int CONTROLLER_BUTTON_START = SDL_CONTROLLER_BUTTON_START;
+static const int CONTROLLER_BUTTON_LEFTSTICK = SDL_CONTROLLER_BUTTON_LEFTSTICK;
+static const int CONTROLLER_BUTTON_RIGHTSTICK = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
+static const int CONTROLLER_BUTTON_LEFTSHOULDER = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
+static const int CONTROLLER_BUTTON_RIGHTSHOULDER = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
+static const int CONTROLLER_BUTTON_DPAD_UP = SDL_CONTROLLER_BUTTON_DPAD_UP;
+static const int CONTROLLER_BUTTON_DPAD_DOWN = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
+static const int CONTROLLER_BUTTON_DPAD_LEFT = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
+static const int CONTROLLER_BUTTON_DPAD_RIGHT = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
+
+static const int CONTROLLER_AXIS_LEFTX = SDL_CONTROLLER_AXIS_LEFTX;
+static const int CONTROLLER_AXIS_LEFTY = SDL_CONTROLLER_AXIS_LEFTY;
+static const int CONTROLLER_AXIS_RIGHTX = SDL_CONTROLLER_AXIS_RIGHTX;
+static const int CONTROLLER_AXIS_RIGHTY = SDL_CONTROLLER_AXIS_RIGHTY;
+static const int CONTROLLER_AXIS_TRIGGERLEFT = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
+static const int CONTROLLER_AXIS_TRIGGERRIGHT = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
+
 }