From a78d38ced02678ed6f9c28fa1bd5b889f47a7d41 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 23 Mar 2014 22:18:54 -0700 Subject: [PATCH] Poll controllers on a separate thread on Windows. This means controllers will sample more than the game fps, and will work whenever keyboards do. --- Core/Core.cpp | 17 ++------ Windows/InputDevice.cpp | 83 +++++++++++++++++++++++++++++++++++++-- Windows/InputDevice.h | 25 ++++++++++-- Windows/WndMainWindow.cpp | 1 + Windows/main.cpp | 2 + 5 files changed, 108 insertions(+), 20 deletions(-) diff --git a/Core/Core.cpp b/Core/Core.cpp index 1116300d7811..844a3e118662 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -129,22 +129,13 @@ void UpdateScreenScale(int width, int height) { } static inline void UpdateRunLoop() { + NativeUpdate(input_state); + { - { -#ifdef _WIN32 - lock_guard guard(input_state.lock); - input_state.pad_buttons = 0; - input_state.pad_lstick_x = 0; - input_state.pad_lstick_y = 0; - input_state.pad_rstick_x = 0; - input_state.pad_rstick_y = 0; - host->PollControllers(input_state); - UpdateInputState(&input_state); -#endif - } - NativeUpdate(input_state); + lock_guard guard(input_state.lock); EndInputState(&input_state); } + if (globalUIState != UISTATE_EXIT) { NativeRender(); } diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index a3cc337ab190..c09cb5cbbaa1 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -1,7 +1,82 @@ -#include "InputDevice.h" -#include "XinputDevice.h" -#include "DinputDevice.h" -#include "KeyboardDevice.h" +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #include #include +#include "base/mutex.h" +#include "input/input_state.h" +#include "thread/thread.h" +#include "thread/threadutil.h" +#include "Core/Host.h" +#include "Windows/InputDevice.h" +#include "Windows/XinputDevice.h" +#include "Windows/DinputDevice.h" +#include "Windows/KeyboardDevice.h" +#include "Windows/WindowsHost.h" + +static volatile bool inputThreadStatus = false; +static volatile bool inputThreadEnabled = false; +static std::thread *inputThread = NULL; +static recursive_mutex inputMutex; +static condition_variable inputEndCond; + +extern InputState input_state; + +inline static void ExecuteInputPoll() { + lock_guard guard(input_state.lock); + input_state.pad_buttons = 0; + input_state.pad_lstick_x = 0; + input_state.pad_lstick_y = 0; + input_state.pad_rstick_x = 0; + input_state.pad_rstick_y = 0; + host->PollControllers(input_state); + UpdateInputState(&input_state); +} + +static void RunInputThread() { + setCurrentThreadName("InputThread"); + + // NOTE: The keyboard and mouse buttons are handled via raw input, not here. + // This is mainly for controllers which need to be polled, instead of generating events. + + while (inputThreadEnabled) { + ExecuteInputPoll(); + + // Update 250 times per second. + Sleep(4); + } + + lock_guard guard(inputMutex); + inputThreadStatus = false; + inputEndCond.notify_one(); +} + +void InputDevice::BeginPolling() { + lock_guard guard(inputMutex); + inputThreadEnabled = true; + inputThread = new std::thread(&RunInputThread); +} + +void InputDevice::StopPolling() { + inputThreadEnabled = false; + lock_guard guard(inputMutex); + if (inputThreadStatus) { + inputEndCond.wait(inputMutex); + } + delete inputThread; +} \ No newline at end of file diff --git a/Windows/InputDevice.h b/Windows/InputDevice.h index 07b4d9672975..a2bc3bf84294 100644 --- a/Windows/InputDevice.h +++ b/Windows/InputDevice.h @@ -1,16 +1,35 @@ +// Copyright (c) 2014- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + #pragma once #include #include -#include "../Common/CommonTypes.h" +#include "Common/CommonTypes.h" struct InputState; -class InputDevice -{ +class InputDevice { public: enum { UPDATESTATE_SKIP_PAD = 0x1234}; virtual int UpdateState(InputState &input_state) = 0; virtual bool IsPad() = 0; + + static void BeginPolling(); + static void StopPolling(); }; diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 43fac2d704f4..9e0378d3139a 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -1563,6 +1563,7 @@ namespace MainWindow case WM_CLOSE: EmuThread_Stop(); + InputDevice::StopPolling(); WindowsRawInput::Shutdown(); return DefWindowProc(hWnd,message,wParam,lParam); diff --git a/Windows/main.cpp b/Windows/main.cpp index c81310ae0b5e..90371eca27b3 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -383,6 +383,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin // Emu thread is always running! EmuThread_Start(); + InputDevice::BeginPolling(); HACCEL hAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_ACCELS); HACCEL hDebugAccelTable = LoadAccelerators(_hInstance, (LPCTSTR)IDR_DEBUGACCELS); @@ -433,6 +434,7 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin VFSShutdown(); + InputDevice::StopPolling(); EmuThread_Stop(); MainWindow::DestroyDebugWindows();