From 8c185b2f3ad40492e0e7ada90e76581c772e635f Mon Sep 17 00:00:00 2001 From: zhyk Date: Wed, 1 Feb 2017 14:14:04 +0800 Subject: [PATCH 1/2] Add Qt with SDL support to CMake. Fixes #9157. --- CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 20182a4ebfb8..ceef5a200b89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -682,6 +682,16 @@ elseif(USING_QT_UI) include_directories(${CMAKE_CURRENT_BINARY_DIR} Qt Qt/Debugger) set(nativeExtraLibs ${nativeExtraLibs} Qt5::Multimedia Qt5::OpenGL Qt5::Gui Qt5::Core) set(TargetBin PPSSPPQt) + + # Enable SDL if found + if (SDL2_FOUND) + add_definitions(-DSDL) + set(nativeExtra ${nativeExtra} + SDL/SDLJoystick.h + SDL/SDLJoystick.cpp) + set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2) + endif() + elseif(TARGET SDL2::SDL2) set(TargetBin PPSSPPSDL) # Require SDL From 06290547832e34cc4e762ab8bd90a3cf8121ef10 Mon Sep 17 00:00:00 2001 From: zhyk Date: Wed, 1 Feb 2017 14:19:18 +0800 Subject: [PATCH 2/2] Do not create thread to handle SDL joystick events in Qt build. Caused crashes on MacOS Sierra (10.12). --- SDL/SDLJoystick.cpp | 35 ++++++++++------------------------- SDL/SDLJoystick.h | 12 ++---------- ext/native/base/QtMain.cpp | 5 ++++- 3 files changed, 16 insertions(+), 36 deletions(-) diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index cff72bf28d86..36576d03b381 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -7,15 +7,13 @@ using namespace std; -extern "C" { - int SDLJoystickThreadWrapper(void *SDLJoy){ - SDLJoystick *stick = static_cast(SDLJoy); - stick->runLoop(); - return 0; - } +static int SDLJoystickEventHandlerWrapper(void* userdata, SDL_Event* event) +{ + static_cast(userdata)->ProcessInput(*event); + return 0; } -SDLJoystick::SDLJoystick(bool init_SDL ): thread(NULL), running(true) { +SDLJoystick::SDLJoystick(bool init_SDL ) : registeredAsEventHandler(false) { if (init_SDL) { SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1"); SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER); @@ -81,20 +79,17 @@ void SDLJoystick::setUpController(int deviceIndex) { } SDLJoystick::~SDLJoystick() { - if (thread) { - running = false; - SDL_Event evt; - evt.type = SDL_USEREVENT; - SDL_PushEvent(&evt); - SDL_WaitThread(thread,0); + if (registeredAsEventHandler) { + SDL_DelEventWatch(SDLJoystickEventHandlerWrapper, this); } for (auto & controller : controllers) { SDL_GameControllerClose(controller); } } -void SDLJoystick::startEventLoop() { - thread = SDL_CreateThread(SDLJoystickThreadWrapper, "joystick",static_cast(this)); +void SDLJoystick::registerEventHandler() { + SDL_AddEventWatch(SDLJoystickEventHandlerWrapper, this); + registeredAsEventHandler = true; } keycode_t SDLJoystick::getKeycodeForButton(SDL_GameControllerButton button) { @@ -199,13 +194,3 @@ int SDLJoystick::getDeviceIndex(int instanceId) { } return it->second; } - -void SDLJoystick::runLoop() { - while (running) { - SDL_Event evt; - int res = SDL_WaitEvent(&evt); - if (res) { - ProcessInput(evt); - } - } -} diff --git a/SDL/SDLJoystick.h b/SDL/SDLJoystick.h index c91ac90bbbbb..c5d8113efc55 100644 --- a/SDL/SDLJoystick.h +++ b/SDL/SDLJoystick.h @@ -12,28 +12,20 @@ #include "net/resolve.h" #include "base/NativeApp.h" -extern "C" { - int SDLJoystickThreadWrapper(void *SDLJoy); -} - class SDLJoystick{ - friend int ::SDLJoystickThreadWrapper(void *); public: SDLJoystick(bool init_SDL = false); ~SDLJoystick(); - void startEventLoop(); + void registerEventHandler(); void ProcessInput(SDL_Event &event); private: - - void runLoop(); void setUpController(int deviceIndex); void setUpControllers(); keycode_t getKeycodeForButton(SDL_GameControllerButton button); int getDeviceIndex(int instanceId); - SDL_Thread *thread ; - bool running ; + bool registeredAsEventHandler; std::vector controllers; std::map controllerDeviceMap; }; diff --git a/ext/native/base/QtMain.cpp b/ext/native/base/QtMain.cpp index 8ca17d9945c0..cf4ea3c8838e 100644 --- a/ext/native/base/QtMain.cpp +++ b/ext/native/base/QtMain.cpp @@ -139,7 +139,7 @@ static int mainInternal(QApplication &a) #ifdef SDL SDLJoystick joy(true); - joy.startEventLoop(); + joy.registerEventHandler(); SDL_Init(SDL_INIT_AUDIO); SDL_AudioSpec fmt, ret_fmt; memset(&fmt, 0, sizeof(fmt)); @@ -334,6 +334,9 @@ void MainUI::initializeGL() void MainUI::paintGL() { +#ifdef SDL + SDL_PumpEvents(); +#endif updateAccelerometer(); UpdateInputState(&input_state); time_update();