diff options
author | Garrett Brown <themagnificentmrb@gmail.com> | 2024-06-26 23:31:20 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-26 23:31:20 -0700 |
commit | 8a90f175f53fa3f86415e6a376aed54d244cad0e (patch) | |
tree | 7fd24a9b6171b4a70d1c2492b90a5f896ee48ea5 | |
parent | 85dcca1fd4932c104ebba40f91756ab66895ef55 (diff) | |
parent | 78de029d6bc0fab890eef93d17863664eb411316 (diff) |
Merge pull request #25177 from garbear/android-fix-generic
Android: Fix generic controllers in UI
-rw-r--r-- | xbmc/platform/android/peripherals/AndroidJoystickState.cpp | 127 |
1 files changed, 82 insertions, 45 deletions
diff --git a/xbmc/platform/android/peripherals/AndroidJoystickState.cpp b/xbmc/platform/android/peripherals/AndroidJoystickState.cpp index c3032b4352..9e622d4d73 100644 --- a/xbmc/platform/android/peripherals/AndroidJoystickState.cpp +++ b/xbmc/platform/android/peripherals/AndroidJoystickState.cpp @@ -55,33 +55,63 @@ static const std::vector<int> ButtonKeycodes{ AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_CENTER, + // add generic gamepad buttons for controllers that Android doesn't know + // how to map + AKEYCODE_BUTTON_1, + AKEYCODE_BUTTON_2, + AKEYCODE_BUTTON_3, + AKEYCODE_BUTTON_4, + AKEYCODE_BUTTON_5, + AKEYCODE_BUTTON_6, + AKEYCODE_BUTTON_7, + AKEYCODE_BUTTON_8, + AKEYCODE_BUTTON_9, + AKEYCODE_BUTTON_10, + AKEYCODE_BUTTON_11, + AKEYCODE_BUTTON_12, + AKEYCODE_BUTTON_13, + AKEYCODE_BUTTON_14, + AKEYCODE_BUTTON_15, + AKEYCODE_BUTTON_16, // only add additional buttons at the end of the list }; // clang-format on -} // namespace - -static std::string PrintAxisIds(const std::vector<int>& axisIds) -{ - if (axisIds.empty()) - return ""; - - if (axisIds.size() == 1) - return std::to_string(axisIds.front()); - - std::string strAxisIds; - for (const auto& axisId : axisIds) - { - if (strAxisIds.empty()) - strAxisIds = "["; - else - strAxisIds += " | "; - strAxisIds += std::to_string(axisId); - } - strAxisIds += "]"; - - return strAxisIds; -} +// clang-format off +static const std::vector<int> AxisIDs{ + AMOTION_EVENT_AXIS_HAT_X, + AMOTION_EVENT_AXIS_HAT_Y, + AMOTION_EVENT_AXIS_X, + AMOTION_EVENT_AXIS_Y, + AMOTION_EVENT_AXIS_Z, + AMOTION_EVENT_AXIS_RX, + AMOTION_EVENT_AXIS_RY, + AMOTION_EVENT_AXIS_RZ, + AMOTION_EVENT_AXIS_LTRIGGER, + AMOTION_EVENT_AXIS_RTRIGGER, + AMOTION_EVENT_AXIS_GAS, + AMOTION_EVENT_AXIS_BRAKE, + AMOTION_EVENT_AXIS_THROTTLE, + AMOTION_EVENT_AXIS_RUDDER, + AMOTION_EVENT_AXIS_WHEEL, + AMOTION_EVENT_AXIS_GENERIC_1, + AMOTION_EVENT_AXIS_GENERIC_2, + AMOTION_EVENT_AXIS_GENERIC_3, + AMOTION_EVENT_AXIS_GENERIC_4, + AMOTION_EVENT_AXIS_GENERIC_5, + AMOTION_EVENT_AXIS_GENERIC_6, + AMOTION_EVENT_AXIS_GENERIC_7, + AMOTION_EVENT_AXIS_GENERIC_8, + AMOTION_EVENT_AXIS_GENERIC_9, + AMOTION_EVENT_AXIS_GENERIC_10, + AMOTION_EVENT_AXIS_GENERIC_11, + AMOTION_EVENT_AXIS_GENERIC_12, + AMOTION_EVENT_AXIS_GENERIC_13, + AMOTION_EVENT_AXIS_GENERIC_14, + AMOTION_EVENT_AXIS_GENERIC_15, + AMOTION_EVENT_AXIS_GENERIC_16, +}; +// clang-format on static void MapAxisIds(int axisId, int primaryAxisId, @@ -105,6 +135,7 @@ static void MapAxisIds(int axisId, else if (axisId == secondaryAxisId) axisIds.insert(axisIds.begin(), primaryAxisId); } +} // namespace CAndroidJoystickState::CAndroidJoystickState(CAndroidJoystickState&& other) noexcept : m_deviceId(other.m_deviceId), @@ -139,10 +170,9 @@ bool CAndroidJoystickState::Initialize(const CJNIViewInputDevice& inputDevice) !motionRange.isFromSource(CJNIViewInputDevice::SOURCE_GAMEPAD)) { CLog::Log(LOGDEBUG, - "CAndroidJoystickState: ignoring axis {} from source {} for input device \"{}\" " + "CAndroidJoystickState: axis {} has unexpected source {} for input device \"{}\" " "with ID {}", motionRange.getAxis(), motionRange.getSource(), deviceName, m_deviceId); - continue; } int axisId = motionRange.getAxis(); @@ -154,24 +184,16 @@ bool CAndroidJoystickState::Initialize(const CJNIViewInputDevice& inputDevice) motionRange.getRange(), motionRange.getResolution()}; - // check if the axis ID belongs to a D-pad, analogue stick or trigger - if (axisId == AMOTION_EVENT_AXIS_HAT_X || axisId == AMOTION_EVENT_AXIS_HAT_Y || - axisId == AMOTION_EVENT_AXIS_X || axisId == AMOTION_EVENT_AXIS_Y || - axisId == AMOTION_EVENT_AXIS_Z || axisId == AMOTION_EVENT_AXIS_RX || - axisId == AMOTION_EVENT_AXIS_RY || axisId == AMOTION_EVENT_AXIS_RZ || - axisId == AMOTION_EVENT_AXIS_LTRIGGER || axisId == AMOTION_EVENT_AXIS_RTRIGGER || - axisId == AMOTION_EVENT_AXIS_GAS || axisId == AMOTION_EVENT_AXIS_BRAKE || - axisId == AMOTION_EVENT_AXIS_THROTTLE || axisId == AMOTION_EVENT_AXIS_RUDDER || - axisId == AMOTION_EVENT_AXIS_WHEEL) + // check if the axis ID belongs to a D-pad, analogue stick, trigger or + // generic axis + if (std::find(AxisIDs.begin(), AxisIDs.end(), axisId) != AxisIDs.end()) { + CLog::Log(LOGDEBUG, "CAndroidJoystickState: axis found: {} ({})", + CAndroidJoystickTranslator::TranslateAxis(axisId), axisId); + // check if this axis is already known if (ContainsAxis(axisId, m_axes)) - { - CLog::Log(LOGWARNING, - "CAndroidJoystickState: duplicate axis {} on input device \"{}\" with ID {}", - PrintAxisIds(axis.ids), deviceName, m_deviceId); continue; - } // map AMOTION_EVENT_AXIS_GAS to AMOTION_EVENT_AXIS_RTRIGGER and // AMOTION_EVENT_AXIS_BRAKE to AMOTION_EVENT_AXIS_LTRIGGER @@ -180,9 +202,6 @@ bool CAndroidJoystickState::Initialize(const CJNIViewInputDevice& inputDevice) MapAxisIds(axisId, AMOTION_EVENT_AXIS_RTRIGGER, AMOTION_EVENT_AXIS_GAS, axis.ids); m_axes.emplace_back(std::move(axis)); - CLog::Log(LOGDEBUG, - "CAndroidJoystickState: axis {} on input device \"{}\" with ID {} detected", - PrintAxisIds(m_axes.back().ids), deviceName, m_deviceId); } else CLog::Log(LOGWARNING, @@ -190,9 +209,27 @@ bool CAndroidJoystickState::Initialize(const CJNIViewInputDevice& inputDevice) axisId, deviceName, m_deviceId); } - // map buttons - for (int buttonKeycode : ButtonKeycodes) - m_buttons.emplace_back(JoystickAxis{{buttonKeycode}}); + // check for presence of buttons + auto results = inputDevice.hasKeys(ButtonKeycodes); + + if (results.size() != ButtonKeycodes.size()) + { + CLog::Log(LOGERROR, "CAndroidJoystickState: failed to get key status for {} buttons", + ButtonKeycodes.size()); + return false; + } + + // log positive results and assign results to buttons + for (unsigned int i = 0; i < ButtonKeycodes.size(); ++i) + { + if (results[i]) + { + const int buttonKeycode = ButtonKeycodes[i]; + CLog::Log(LOGDEBUG, "CAndroidJoystickState: button found: {} ({})", + CAndroidJoystickTranslator::TranslateKeyCode(buttonKeycode), buttonKeycode); + m_buttons.emplace_back(JoystickAxis{{buttonKeycode}}); + } + } // check if there are no buttons or axes at all if (GetButtonCount() == 0 && GetAxisCount() == 0) |