Skip to content
Snippets Groups Projects
Commit 804115b2 authored by Tobias's avatar Tobias Committed by bunnei
Browse files

Port #4141 from citra: Joystick hotplug support (#1275)

* Joystick hotplug support (#4141)

* use SDL_PollEvent instead of SDL_JoystickUpdate

Register hot plugged controller by GUID if they were configured in a previous session

* Move SDL_PollEvent into its own thread

* Don't store SDLJoystick pointer in Input Device; Get pointer on each GetStatus call

* Fix that joystick_list gets cleared after SDL_Quit

* Add VirtualJoystick for InputDevices thats never nullptr

* fixup! Add VirtualJoystick for InputDevices thats never nullptr

* fixup! fixup! Add VirtualJoystick for InputDevices thats never nullptr

* Remove SDL_GameController, make SDL_Joystick* unique_ptr

* fixup! Remove SDL_GameController, make SDL_Joystick* unique_ptr

* Adressed feedback; fixed handling of same guid reconnects

* fixup! Adressed feedback; fixed handling of same guid reconnects

* merge the two joystick_lists into one

* make SDLJoystick a member of VirtualJoystick

* fixup! make SDLJoystick a member of VirtualJoystick

* fixup! make SDLJoystick a member of VirtualJoystick

* fixup! fixup! make SDLJoystick a member of VirtualJoystick

* SDLJoystick: Addressed review comments

* Address one missed review comment
parent d6e8e16a
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <memory>
#include <thread>
#include "common/param_package.h"
#include "input_common/analog_from_button.h"
#include "input_common/keyboard.h"
......@@ -17,6 +18,10 @@ namespace InputCommon {
static std::shared_ptr<Keyboard> keyboard;
static std::shared_ptr<MotionEmu> motion_emu;
#ifdef HAVE_SDL2
static std::thread poll_thread;
#endif
void Init() {
keyboard = std::make_shared<Keyboard>();
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
......@@ -30,6 +35,12 @@ void Init() {
#endif
}
void StartJoystickEventHandler() {
#ifdef HAVE_SDL2
poll_thread = std::thread(SDL::PollLoop);
#endif
}
void Shutdown() {
Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
keyboard.reset();
......@@ -39,6 +50,7 @@ void Shutdown() {
#ifdef HAVE_SDL2
SDL::Shutdown();
poll_thread.join();
#endif
}
......
......@@ -20,6 +20,8 @@ void Init();
/// Deregisters all built-in input device factories and shuts them down.
void Shutdown();
void StartJoystickEventHandler();
class Keyboard;
/// Gets the keyboard button device factory.
......
This diff is collapsed.
......@@ -28,6 +28,15 @@ void Init();
/// Unresisters SDL device factories and shut them down.
void Shutdown();
/// Needs to be called before SDL_QuitSubSystem.
void CloseSDLJoysticks();
/// Handle SDL_Events for joysticks from SDL_PollEvent
void HandleGameControllerEvent(const SDL_Event& event);
/// A Loop that calls HandleGameControllerEvent until Shutdown is called
void PollLoop();
/// Creates a ParamPackage from an SDL_Event that can directly be used to create a ButtonDevice
Common::ParamPackage SDLEventToButtonParamPackage(const SDL_Event& event);
......
......@@ -112,6 +112,7 @@ GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
setWindowTitle(QString::fromStdString(window_title));
InputCommon::Init();
InputCommon::StartJoystickEventHandler();
}
GRenderWindow::~GRenderWindow() {
......
// Copyright 2016 Citra Emulator Project
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
......@@ -53,19 +53,18 @@ static QString ButtonToText(const Common::ParamPackage& param) {
} else if (param.Get("engine", "") == "keyboard") {
return getKeyName(param.Get("code", 0));
} else if (param.Get("engine", "") == "sdl") {
QString text = QString(QObject::tr("Joystick %1")).arg(param.Get("joystick", "").c_str());
if (param.Has("hat")) {
text += QString(QObject::tr(" Hat %1 %2"))
.arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str());
return QString(QObject::tr("Hat %1 %2"))
.arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str());
}
if (param.Has("axis")) {
text += QString(QObject::tr(" Axis %1%2"))
.arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str());
return QString(QObject::tr("Axis %1%2"))
.arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str());
}
if (param.Has("button")) {
text += QString(QObject::tr(" Button %1")).arg(param.Get("button", "").c_str());
return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str());
}
return text;
return QString();
} else {
return QObject::tr("[unknown]");
}
......@@ -81,13 +80,12 @@ static QString AnalogToText(const Common::ParamPackage& param, const std::string
return QString(QObject::tr("[unused]"));
}
QString text = QString(QObject::tr("Joystick %1")).arg(param.Get("joystick", "").c_str());
if (dir == "left" || dir == "right") {
text += QString(QObject::tr(" Axis %1")).arg(param.Get("axis_x", "").c_str());
return QString(QObject::tr("Axis %1")).arg(param.Get("axis_x", "").c_str());
} else if (dir == "up" || dir == "down") {
text += QString(QObject::tr(" Axis %1")).arg(param.Get("axis_y", "").c_str());
return QString(QObject::tr("Axis %1")).arg(param.Get("axis_y", "").c_str());
}
return text;
return QString();
} else {
return QObject::tr("[unknown]");
}
......
......@@ -16,6 +16,7 @@
#include "input_common/keyboard.h"
#include "input_common/main.h"
#include "input_common/motion_emu.h"
#include "input_common/sdl/sdl.h"
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
......@@ -116,7 +117,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
SDL_SetMainReady();
// Initialize the window
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
exit(1);
}
......@@ -176,6 +177,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
}
EmuWindow_SDL2::~EmuWindow_SDL2() {
InputCommon::SDL::CloseSDLJoysticks();
SDL_GL_DeleteContext(gl_context);
SDL_Quit();
......@@ -220,6 +222,9 @@ void EmuWindow_SDL2::PollEvents() {
case SDL_QUIT:
is_open = false;
break;
default:
InputCommon::SDL::HandleGameControllerEvent(event);
break;
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment