mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-04-21 15:40:18 +00:00
WIP SDL3 compatibility
This commit is contained in:
@@ -37,7 +37,7 @@ void SdlGamepadKeyNavigation::enable()
|
||||
// arrival events. Additionally, there's a race condition between
|
||||
// our QML objects being destroyed and SDL being deinitialized that
|
||||
// this solves too.
|
||||
if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER))) {
|
||||
if (SDLC_FAILURE(SDL_InitSubSystem(SDL_INIT_GAMEPAD))) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) failed: %s",
|
||||
SDL_GetError());
|
||||
@@ -52,18 +52,18 @@ void SdlGamepadKeyNavigation::enable()
|
||||
// overlapping lifetimes of SdlGamepadKeyNavigation instances, so we
|
||||
// will attach ourselves.
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED);
|
||||
SDL_FlushEvent(SDL_EVENT_GAMEPAD_ADDED);
|
||||
|
||||
// Open all currently attached game controllers
|
||||
int numJoysticks = SDL_NumJoysticks();
|
||||
for (int i = 0; i < numJoysticks; i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
SDL_GameController* gc = SDL_GameControllerOpen(i);
|
||||
if (gc != nullptr) {
|
||||
m_Gamepads.append(gc);
|
||||
}
|
||||
int numGamepads = 0;
|
||||
SDL_JoystickID* gamepads = SDL_GetGamepads(&numGamepads);
|
||||
for (int i = 0; i < numGamepads; i++) {
|
||||
SDL_Gamepad * gc = SDL_OpenGamepad(i);
|
||||
if (gc != nullptr) {
|
||||
m_Gamepads.append(gc);
|
||||
}
|
||||
}
|
||||
SDL_free(gamepads);
|
||||
|
||||
m_Enabled = true;
|
||||
|
||||
@@ -82,11 +82,11 @@ void SdlGamepadKeyNavigation::disable()
|
||||
Q_ASSERT(!m_PollingTimer->isActive());
|
||||
|
||||
while (!m_Gamepads.isEmpty()) {
|
||||
SDL_GameControllerClose(m_Gamepads[0]);
|
||||
SDL_CloseGamepad(m_Gamepads[0]);
|
||||
m_Gamepads.removeAt(0);
|
||||
}
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMEPAD);
|
||||
}
|
||||
|
||||
void SdlGamepadKeyNavigation::notifyWindowFocus(bool hasFocus)
|
||||
@@ -103,47 +103,47 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
// stale input data from the stream session (like the quit combo).
|
||||
if (m_FirstPoll) {
|
||||
SDL_PumpEvents();
|
||||
SDL_FlushEvent(SDL_CONTROLLERBUTTONDOWN);
|
||||
SDL_FlushEvent(SDL_CONTROLLERBUTTONUP);
|
||||
SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_DOWN);
|
||||
SDL_FlushEvent(SDL_EVENT_GAMEPAD_BUTTON_UP);
|
||||
|
||||
m_FirstPoll = false;
|
||||
}
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_QUIT:
|
||||
case SDL_EVENT_QUIT :
|
||||
// SDL may send us a quit event since we initialize
|
||||
// the video subsystem on startup. If we get one,
|
||||
// forward it on for Qt to take care of.
|
||||
QCoreApplication::instance()->quit();
|
||||
break;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN :
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP :
|
||||
{
|
||||
QEvent::Type type =
|
||||
event.type == SDL_CONTROLLERBUTTONDOWN ?
|
||||
event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN ?
|
||||
QEvent::Type::KeyPress : QEvent::Type::KeyRelease;
|
||||
|
||||
// Swap face buttons if needed
|
||||
if (m_Prefs->swapFaceButtons) {
|
||||
switch (event.cbutton.button) {
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
event.cbutton.button = SDL_CONTROLLER_BUTTON_B;
|
||||
switch (event.gbutton.button) {
|
||||
case SDL_GAMEPAD_BUTTON_SOUTH :
|
||||
event.gbutton.button = SDL_GAMEPAD_BUTTON_EAST;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
event.cbutton.button = SDL_CONTROLLER_BUTTON_A;
|
||||
case SDL_GAMEPAD_BUTTON_EAST :
|
||||
event.gbutton.button = SDL_GAMEPAD_BUTTON_SOUTH;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
event.cbutton.button = SDL_CONTROLLER_BUTTON_Y;
|
||||
case SDL_GAMEPAD_BUTTON_WEST :
|
||||
event.gbutton.button = SDL_GAMEPAD_BUTTON_NORTH;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
event.cbutton.button = SDL_CONTROLLER_BUTTON_X;
|
||||
case SDL_GAMEPAD_BUTTON_NORTH :
|
||||
event.gbutton.button = SDL_GAMEPAD_BUTTON_WEST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.cbutton.button) {
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||
switch (event.gbutton.button) {
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_UP :
|
||||
if (m_UiNavMode) {
|
||||
// Back-tab
|
||||
sendKey(type, Qt::Key_Tab, Qt::ShiftModifier);
|
||||
@@ -152,7 +152,7 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
sendKey(type, Qt::Key_Up);
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_DOWN :
|
||||
if (m_UiNavMode) {
|
||||
sendKey(type, Qt::Key_Tab);
|
||||
}
|
||||
@@ -160,13 +160,13 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
sendKey(type, Qt::Key_Down);
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_LEFT :
|
||||
sendKey(type, Qt::Key_Left);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_RIGHT :
|
||||
sendKey(type, Qt::Key_Right);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
case SDL_GAMEPAD_BUTTON_SOUTH :
|
||||
if (m_UiNavMode) {
|
||||
sendKey(type, Qt::Key_Space);
|
||||
}
|
||||
@@ -174,14 +174,14 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
sendKey(type, Qt::Key_Return);
|
||||
}
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
case SDL_GAMEPAD_BUTTON_EAST :
|
||||
sendKey(type, Qt::Key_Escape);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
case SDL_GAMEPAD_BUTTON_WEST :
|
||||
sendKey(type, Qt::Key_Menu);
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
case SDL_CONTROLLER_BUTTON_START:
|
||||
case SDL_GAMEPAD_BUTTON_NORTH :
|
||||
case SDL_GAMEPAD_BUTTON_START :
|
||||
// HACK: We use this keycode to inform main.qml
|
||||
// to show the settings when Key_Menu is handled
|
||||
// by the control in focus.
|
||||
@@ -192,11 +192,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
SDL_GameController* gc = SDL_GameControllerOpen(event.cdevice.which);
|
||||
case SDL_EVENT_GAMEPAD_ADDED :
|
||||
#if SDL_VERSION_ATLEAST(3, 0, 0)
|
||||
SDL_Gamepad* gc = SDL_OpenGamepad(event.gdevice.which);
|
||||
if (gc != nullptr) {
|
||||
SDL_assert(!m_Gamepads.contains(gc));
|
||||
m_Gamepads.append(gc);
|
||||
}
|
||||
#else
|
||||
SDL_Gamepad* gc = SDL_GameControllerOpen(event.cdevice.which);
|
||||
if (gc != nullptr) {
|
||||
// SDL_CONTROLLERDEVICEADDED can be reported multiple times for the same
|
||||
// gamepad in rare cases, because SDL doesn't fixup the device index in
|
||||
// gamepad in rare cases, because SDL2 doesn't fixup the device index in
|
||||
// the SDL_CONTROLLERDEVICEADDED event if an unopened gamepad disappears
|
||||
// before we've processed the add event.
|
||||
if (!m_Gamepads.contains(gc)) {
|
||||
@@ -204,17 +211,18 @@ void SdlGamepadKeyNavigation::onPollingTimerFired()
|
||||
}
|
||||
else {
|
||||
// We already have this game controller open
|
||||
SDL_GameControllerClose(gc);
|
||||
SDL_CloseGamepad(gc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle analog sticks by polling
|
||||
for (auto gc : m_Gamepads) {
|
||||
short leftX = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTX);
|
||||
short leftY = SDL_GameControllerGetAxis(gc, SDL_CONTROLLER_AXIS_LEFTY);
|
||||
short leftX = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTX);
|
||||
short leftY = SDL_GetGamepadAxis(gc, SDL_GAMEPAD_AXIS_LEFTY);
|
||||
if (SDL_GetTicks() - m_LastAxisNavigationEventTime < AXIS_NAVIGATION_REPEAT_DELAY) {
|
||||
// Do nothing
|
||||
}
|
||||
@@ -290,12 +298,6 @@ int SdlGamepadKeyNavigation::getConnectedGamepads()
|
||||
Q_ASSERT(m_Enabled);
|
||||
|
||||
int count = 0;
|
||||
int numJoysticks = SDL_NumJoysticks();
|
||||
for (int i = 0; i < numJoysticks; i++) {
|
||||
if (SDL_IsGameController(i)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(SDL_GetGamepads(&count));
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ private slots:
|
||||
private:
|
||||
StreamingPreferences* m_Prefs;
|
||||
QTimer* m_PollingTimer;
|
||||
QList<SDL_GameController*> m_Gamepads;
|
||||
QList<SDL_Gamepad*> m_Gamepads;
|
||||
bool m_Enabled;
|
||||
bool m_UiNavMode;
|
||||
bool m_FirstPoll;
|
||||
|
||||
Reference in New Issue
Block a user