Przeglądaj źródła

Massive SDL input cleanups.

* Added support for joyhat events, fixes ds4 d-pad
* Fixed dead-banding and axis events correctly
* Updates to DS4 keymap and Xbox keymap
Tobias Hieta 8 lat temu
rodzic
commit
f592e11a65

+ 65 - 0
resources/inputmaps/dualshock4.json

@@ -0,0 +1,65 @@
+{
+  "name": "Playstation Dual Shock 4",
+  "idmatcher": "Wireless Controller",
+  "mapping": {
+    // D-Pad
+    "KEY_HAT_DOWN": "down",
+    "KEY_HAT_UP": "up",
+    "KEY_HAT_RIGHT": "right",
+    "KEY_HAT_LEFT": "left",
+
+    // Square
+    "KEY_BUTTON_0": "cycle_audio",
+
+    // X
+    "KEY_BUTTON_1": "enter",
+
+    // Circle
+    "KEY_BUTTON_2": {
+      "short": "back",
+      "long": "home"
+    },
+
+    // Triangle
+    "KEY_BUTTON_3": "cycle_subtitles",
+
+    // L1
+    "KEY_BUTTON_4": "seek_backward",
+
+    // L2
+    "KEY_BUTTON_5": "seek_forward",
+
+    // option
+    "KEY_BUTTON_8": "host:toggleDebug",
+
+    // start
+    "KEY_BUTTON_9": "host:fullscreen",
+
+    // press left thumbstick
+    "KEY_BUTTON_10": "",
+
+    // press right thumbstick
+    "KEY_BUTTON_11": "",
+
+    // Playstation button
+    "KEY_BUTTON_12": {
+      "short": "home",
+      "long": "exit"
+    },
+
+    // Trackpad press
+    "KEY_BUTTON_13": "search",
+
+    // left thumbstick axis
+    "KEY_AXIS_0_UP": "left",
+    "KEY_AXIS_0_DOWN": "right",
+    "KEY_AXIS_1_UP": "up",
+    "KEY_AXIS_1_DOWN": "down",
+
+    // right thumbstick axis
+    "KEY_AXIS_5_UP": "increase_volume",
+    "KEY_AXIS_5_DOWN": "decrease_volume",
+    "KEY_AXIS_2_UP": "decrease_audio_delay",
+    "KEY_AXIS_2_DOWN": "increase_audio_delay"
+  }
+}

+ 64 - 34
resources/inputmaps/xbox-controller-windows.json

@@ -1,39 +1,69 @@
 {
   "name": "Xbox Controller",
-  "idmatcher": "XInput.*",
+  "idmatcher": "XInput.*|XBOX360.*|.*360.*Controller",
   "mapping": 
   {
-      // left stick L,R,U,D, click
-      "KEY_AXIS_0_VAL_DOWN": "",
-      "KEY_AXIS_0_VAL_UP": "",
-      "KEY_AXIS_1_VAL_DOWN": "",
-      "KEY_AXIS_1_VAL_UP": "",
-      "KEY_BUTTON_6": "",
-      // right stick L,R,U,D, click
-      "KEY_AXIS_2_VAL_DOWN": "host:player:add volume -1",
-      "KEY_AXIS_2_VAL_UP": "host:player:add volume 1",
-      "KEY_AXIS_3_VAL_DOWN": "host:player:add volume 1",
-      "KEY_AXIS_3_VAL_UP": "host:player:add volume -1",
-      "KEY_BUTTON_7": "host:player:cycle mute",
-      // DPAD U,D,L,R
-      "KEY_BUTTON_0": "up",
-      "KEY_BUTTON_1": "down",
-      "KEY_BUTTON_2": "left",
-      "KEY_BUTTON_3": "right",
-      // BACK, HOME, START
-      "KEY_BUTTON_5": "host:fullscreen",
-      "KEY_BUTTON_14": "host:toggleDebug",
-      "KEY_BUTTON_4": "home",
-      // LB, LT
-      "KEY_BUTTON_8": "host:player:seek -15",
-      "KEY_AXIS_4_VAL_DOWN": "",
-      // RB, RT
-      "KEY_BUTTON_9": "host:player:seek 15",
-      "KEY_AXIS_4_VAL_DOWN": "",
-      // A, B, X, Y
-      "KEY_BUTTON_10": "enter",
-      "KEY_BUTTON_11": "back",
-      "KEY_BUTTON_12": "cycle_subtitles",
-      "KEY_BUTTON_13": "host:player:cycle mute"
+    // A
+    "KEY_BUTTON_0": "enter",
+
+    // B
+    "KEY_BUTTON_1": {
+      "short": "back",
+      "long": "home"
+    },
+
+    // X
+    "KEY_BUTTON_2": "cycle_audio",
+
+    // Y
+    "KEY_BUTTON_3": "cycle_subtitle",
+
+    // LB
+    "KEY_BUTTON_4": "seek_backward",
+
+    // RB
+    "KEY_BUTTON_5": "seek_forward",
+
+    // left thumbstick press
+    "KEY_BUTTON_6": "",
+
+    // right thumbstick press
+    "KEY_BUTTON_7": "",
+
+    // start
+    "KEY_BUTTON_8": "host:fullscreen",
+
+    // back
+    "KEY_BUTTON_9": "host:toggleDebug",
+
+    // Windows button
+    "KEY_BUTTON_10": {
+      "short": "home",
+      "long": "exit"
+    },
+
+    // D-PAD
+    "KEY_BUTTON_11": "up",
+    "KEY_BUTTON_12": "down",
+    "KEY_BUTTON_13": "left",
+    "KEY_BUTTON_14": "right",
+
+    // left thumbstick axis
+    "KEY_AXIS_0_UP": "left",
+    "KEY_AXIS_0_DOWN": "right",
+    "KEY_AXIS_1_UP": "up",
+    "KEY_AXIS_1_DOWN": "down",
+
+    // right thumbstick axis
+    "KEY_AXIS_4_UP": "increase_volume",
+    "KEY_AXIS_4_DOWN": "decrease_volume",
+    "KEY_AXIS_3_UP": "decrease_audio_delay",
+    "KEY_AXIS_3_DOWN": "increase_audio_delay",
+
+    // left trigger
+    "KEY_AXIS_2_UP": "",
+
+    // right trigger
+    "KEY_AXIS_5_UP": ""
   }
-}
+}

+ 61 - 28
src/input/InputSDL.cpp

@@ -26,6 +26,7 @@ bool InputSDLWorker::initialize()
     return false;
   }
 
+  SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
   SDL_JoystickEventState(SDL_ENABLE);
 
   refreshJoystickList();
@@ -42,9 +43,7 @@ void InputSDLWorker::close()
 
     // we need to close all the openned joysticks here and then exit the thread
     for (int joyid = 0; joyid < m_joysticks.size(); joyid++)
-    {
       SDL_JoystickClose(m_joysticks[joyid]);
-    }
 
     SDL_Quit();
   }
@@ -81,21 +80,13 @@ void InputSDLWorker::run()
 
         case SDL_JOYBUTTONDOWN:
         {
-          QLOG_DEBUG() << "SDL Got button down for button #" << event.jbutton.button
-                       << " on Joystick #" << event.jbutton.which;
-
           emit receivedInput(nameForId(event.jbutton.which), QString("KEY_BUTTON_%1").arg(event.jbutton.button, true));
-          
           break;
         }
 
         case SDL_JOYBUTTONUP:
         {
-          QLOG_DEBUG() << "SDL Got button up for button #" << event.jbutton.button
-                       << " on Joystick #" << event.jbutton.which;
-
           emit receivedInput(nameForId(event.jbutton.which), QString("KEY_BUTTON_%1").arg(event.jbutton.button), false);
-
           break;
         }
 
@@ -113,33 +104,76 @@ void InputSDLWorker::run()
           break;
         }
 
+        case SDL_JOYHATMOTION:
+        {
+
+          QString hatName("KEY_HAT_");
+          bool pressed = true;
+
+          switch (event.jhat.value)
+          {
+            case SDL_HAT_CENTERED:
+              if (!m_lastHat.isEmpty())
+                hatName = m_lastHat;
+              else
+                hatName += "CENTERED";
+              pressed = false;
+              break;
+            case SDL_HAT_UP:
+              hatName += "UP";
+              break;
+            case SDL_HAT_DOWN:
+              hatName += "DOWN";
+              break;
+            case SDL_HAT_RIGHT:
+              hatName += "RIGHT";
+              break;
+            case SDL_HAT_LEFT:
+              hatName += "LEFT";
+              break;
+            default:
+              break;
+          }
+
+          m_lastHat = hatName;
+
+          emit receivedInput(nameForId(event.jhat.which), hatName, pressed);
+
+          break;
+        }
+
         case SDL_JOYAXISMOTION:
         {
+          auto axis = event.jaxis.axis;
+          auto value = event.jaxis.value;
+
+          QLOG_DEBUG() << "JoyAxisMotion:" << axis << value;
 
           // handle the Digital conversion of the analog axis
-          if (std::abs(event.jaxis.value) > 32768 / 2)
+          if (std::abs(value) > 32768 / 2)
           {
-            if (!m_axisState[event.jaxis.axis])
+            bool up = value < 0;
+            if (!m_axisState.contains(axis))
             {
-              m_axisState[event.jaxis.axis] = 1;
-
-              if (event.jaxis.value > 0)
-                emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_UP").arg(event.jaxis.axis), true);
-              else
-                emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_DOWN").arg(event.jaxis.axis), true);
+              emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_%2").arg(axis).arg(up ? "UP" : "DOWN"), true);
+              m_axisState.insert(axis, up);
             }
-          }
-          else
-          {
-            if (m_axisState[event.jaxis.axis])
+            else if (m_axisState.value(axis) != up)
             {
-              emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_UP").arg(event.jaxis.axis), false);
-              emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_DOWN").arg(event.jaxis.axis), false);
+              emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_%2").arg(axis).arg(m_axisState.value(axis) ? "UP" : "DOWN"), false);
+              m_axisState.remove(axis);
             }
-
-            m_axisState[event.jaxis.axis] = 0;
           }
-
+          else if (std::abs(value) < 10000 && m_axisState.contains(axis)) // back to the center.
+          {
+            emit receivedInput(nameForId(event.jaxis.which), QString("KEY_AXIS_%1_%2").arg(axis).arg(m_axisState.value(axis) ? "UP" : "DOWN"), false);
+            m_axisState.remove(axis);
+          }
+          break;
+        }
+        default:
+        {
+          QLOG_WARN() << "Unhandled SDL event:" << event.type;
           break;
         }
       }
@@ -181,7 +215,6 @@ void InputSDLWorker::refreshJoystickList()
                   << "axes";
       m_joysticks[instanceid] = joystick;
       m_axisState.clear();
-      m_axisState.resize(SDL_JoystickNumAxes(joystick));
     }
   }
 }

+ 4 - 1
src/input/InputSDL.h

@@ -47,7 +47,10 @@ private:
   QString nameForId(SDL_JoystickID id);
 
   SDLJoystickMap m_joysticks;
-  QByteArray  m_axisState;
+
+  // map axis to up = true or down = false
+  QHash<quint8, bool> m_axisState;
+  QString m_lastHat;
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////