Centralize SDL input subsystem ownership for hotplug recovery
This commit is contained in:
parent
e94f0c5990
commit
d174341b6d
7 changed files with 315 additions and 117 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <Limelight.h>
|
||||
#include "SDL_compat.h"
|
||||
#include "settings/mappingmanager.h"
|
||||
#include "streaming/input/sdlinputsubsystems.h"
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
|
|
@ -26,6 +26,8 @@ static bool isKeyboardMouseInputAllowed()
|
|||
|
||||
#define HOTPLUG_REENUMERATION_INTERVAL_MS 2000
|
||||
#define HOTPLUG_REENUMERATION_MAX_INTERVAL_MS 8000
|
||||
#define HOTPLUG_REENUMERATION_MIN_ZERO_POLLS 4
|
||||
#define HOTPLUG_REENUMERATION_MIN_LAST_SEEN_MS 500
|
||||
|
||||
// Determines how fast the mouse will move each interval
|
||||
#define MOUSE_EMULATION_MOTION_MULTIPLIER 4
|
||||
|
|
@ -105,10 +107,13 @@ void SdlInputHandler::pollForMissingGamepads()
|
|||
static uint32_t s_LastForcedReenumerationTick = 0;
|
||||
static uint32_t s_ReenumerationIntervalMs = HOTPLUG_REENUMERATION_INTERVAL_MS;
|
||||
static uint32_t s_ReenumerationAttempts = 0;
|
||||
static uint32_t s_ConsecutiveZeroPolls = 0;
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
uint32_t now = SDL_GetTicks();
|
||||
|
||||
auto recoverUntrackedGamepads = [this](int joystickCount) {
|
||||
for (int deviceIndex = 0; deviceIndex < joystickCount; deviceIndex++) {
|
||||
if (!SDL_IsGameController(deviceIndex)) {
|
||||
|
|
@ -142,9 +147,14 @@ void SdlInputHandler::pollForMissingGamepads()
|
|||
}
|
||||
|
||||
if (joystickCount > 0) {
|
||||
m_LastNonZeroJoystickTick = now;
|
||||
s_ConsecutiveZeroPolls = 0;
|
||||
s_ReenumerationAttempts = 0;
|
||||
s_ReenumerationIntervalMs = HOTPLUG_REENUMERATION_INTERVAL_MS;
|
||||
}
|
||||
else {
|
||||
s_ConsecutiveZeroPolls++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++) {
|
||||
GamepadState* state = &m_GamepadState[i];
|
||||
|
|
@ -177,54 +187,44 @@ void SdlInputHandler::pollForMissingGamepads()
|
|||
|
||||
recoverUntrackedGamepads(joystickCount);
|
||||
|
||||
if (joystickCount == 0) {
|
||||
uint32_t now = SDL_GetTicks();
|
||||
bool shouldAttemptReenumeration =
|
||||
joystickCount == 0 &&
|
||||
m_LastNonZeroJoystickTick != 0 &&
|
||||
s_ConsecutiveZeroPolls >= HOTPLUG_REENUMERATION_MIN_ZERO_POLLS &&
|
||||
SDL_TICKS_PASSED(now, m_LastNonZeroJoystickTick + HOTPLUG_REENUMERATION_MIN_LAST_SEEN_MS);
|
||||
|
||||
if (shouldAttemptReenumeration) {
|
||||
if (SDL_TICKS_PASSED(now, s_LastForcedReenumerationTick + s_ReenumerationIntervalMs)) {
|
||||
s_LastForcedReenumerationTick = now;
|
||||
s_ReenumerationAttempts++;
|
||||
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"No joysticks visible; forcing SDL joystick/gamecontroller re-enumeration (attempt %u, interval %u ms)",
|
||||
"No joysticks visible after reconciliation; forcing last-resort SDL re-enumeration (attempt %u, interval %u ms)",
|
||||
s_ReenumerationAttempts,
|
||||
s_ReenumerationIntervalMs);
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
if (SdlInputSubsystems::reenumerateGamepadSubsystems("StreamInputHotplug")) {
|
||||
joystickCount = SDL_NumJoysticks();
|
||||
if (joystickCount != m_LastJoystickCount) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Detected joystick count change after re-enumeration: %d -> %d",
|
||||
m_LastJoystickCount,
|
||||
joystickCount);
|
||||
m_LastJoystickCount = joystickCount;
|
||||
}
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_InitSubSystem(SDL_INIT_JOYSTICK) failed during re-enumeration: %s",
|
||||
SDL_GetError());
|
||||
return;
|
||||
}
|
||||
recoverUntrackedGamepads(joystickCount);
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed during re-enumeration: %s",
|
||||
SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
MappingManager mappingManager;
|
||||
mappingManager.applyMappings();
|
||||
|
||||
SDL_JoystickUpdate();
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
joystickCount = SDL_NumJoysticks();
|
||||
if (joystickCount != m_LastJoystickCount) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Detected joystick count change after re-enumeration: %d -> %d",
|
||||
m_LastJoystickCount,
|
||||
joystickCount);
|
||||
m_LastJoystickCount = joystickCount;
|
||||
}
|
||||
|
||||
recoverUntrackedGamepads(joystickCount);
|
||||
|
||||
if (joystickCount > 0) {
|
||||
s_ReenumerationAttempts = 0;
|
||||
s_ReenumerationIntervalMs = HOTPLUG_REENUMERATION_INTERVAL_MS;
|
||||
if (joystickCount > 0) {
|
||||
m_LastNonZeroJoystickTick = now;
|
||||
s_ConsecutiveZeroPolls = 0;
|
||||
s_ReenumerationAttempts = 0;
|
||||
s_ReenumerationIntervalMs = HOTPLUG_REENUMERATION_INTERVAL_MS;
|
||||
}
|
||||
else {
|
||||
s_ReenumerationIntervalMs = qMin(s_ReenumerationIntervalMs * 2,
|
||||
static_cast<uint32_t>(HOTPLUG_REENUMERATION_MAX_INTERVAL_MS));
|
||||
}
|
||||
}
|
||||
else {
|
||||
s_ReenumerationIntervalMs = qMin(s_ReenumerationIntervalMs * 2,
|
||||
|
|
@ -1236,14 +1236,20 @@ QString SdlInputHandler::getUnmappedGamepads()
|
|||
{
|
||||
QString ret;
|
||||
|
||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s",
|
||||
SDL_GetError());
|
||||
}
|
||||
SdlInputSubsystems::LeaseOptions options = {};
|
||||
options.joystick = true;
|
||||
options.gameController = true;
|
||||
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
options.haptic = false;
|
||||
#endif
|
||||
options.applyMappings = true;
|
||||
options.flushControllerDeviceEvents = false;
|
||||
|
||||
MappingManager mappingManager;
|
||||
mappingManager.applyMappings();
|
||||
if (!SdlInputSubsystems::acquire("UnmappedGamepadProbe", options)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to acquire SDL input subsystems for unmapped gamepad probe");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int numJoysticks = SDL_NumJoysticks();
|
||||
for (int i = 0; i < numJoysticks; i++) {
|
||||
|
|
@ -1286,7 +1292,7 @@ QString SdlInputHandler::getUnmappedGamepads()
|
|||
}
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
SdlInputSubsystems::release("UnmappedGamepadProbe", options);
|
||||
|
||||
// Flush stale events so they aren't processed by the main session event loop
|
||||
SDL_FlushEvents(SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue