aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Brown <themagnificentmrb@gmail.com>2024-06-26 23:31:20 -0700
committerGitHub <noreply@github.com>2024-06-26 23:31:20 -0700
commit8a90f175f53fa3f86415e6a376aed54d244cad0e (patch)
tree7fd24a9b6171b4a70d1c2492b90a5f896ee48ea5
parent85dcca1fd4932c104ebba40f91756ab66895ef55 (diff)
parent78de029d6bc0fab890eef93d17863664eb411316 (diff)
Merge pull request #25177 from garbear/android-fix-generic
Android: Fix generic controllers in UI
-rw-r--r--xbmc/platform/android/peripherals/AndroidJoystickState.cpp127
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)