From e71be8af2ed533a9294a726a1263f6d5e68ced6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 24 Mar 2023 19:57:24 +0100 Subject: [PATCH] Remove PollControllers from host. Break out a WindowsInputManager from WindowsHost. --- Common/System/System.h | 1 + Core/Host.h | 1 - UWP/PPSSPP_UWPMain.cpp | 20 ++++++++++++++- UWP/UWPHost.cpp | 36 --------------------------- UWP/UWPHost.h | 14 +---------- Windows/EmuThread.cpp | 1 + Windows/InputDevice.cpp | 3 ++- Windows/RawInput.cpp | 14 +++++------ Windows/WindowsHost.cpp | 55 +++++++++++++++++++---------------------- Windows/WindowsHost.h | 40 ++++++++++++++++++++---------- Windows/main.cpp | 7 ++++++ 11 files changed, 90 insertions(+), 102 deletions(-) diff --git a/Common/System/System.h b/Common/System/System.h index 6c4922a6c7..229adce957 100644 --- a/Common/System/System.h +++ b/Common/System/System.h @@ -183,6 +183,7 @@ enum class SystemNotification { IMMERSIVE_MODE_CHANGE, AUDIO_RESET_DEVICE, SUSTAINED_PERF_CHANGE, + POLL_CONTROLLERS, }; std::string System_GetProperty(SystemProperty prop); diff --git a/Core/Host.h b/Core/Host.h index d62d6e27dd..52e5d21152 100644 --- a/Core/Host.h +++ b/Core/Host.h @@ -28,7 +28,6 @@ public: virtual ~Host() {} virtual void UpdateSound() {} // still needed for libretro, will need a proper effort. - virtual void PollControllers() {} virtual void ToggleDebugConsoleVisibility() {} virtual bool CreateDesktopShortcut(std::string argumentPath, std::string title) {return false;} diff --git a/UWP/PPSSPP_UWPMain.cpp b/UWP/PPSSPP_UWPMain.cpp index c469029c76..6a8ab7a526 100644 --- a/UWP/PPSSPP_UWPMain.cpp +++ b/UWP/PPSSPP_UWPMain.cpp @@ -2,6 +2,8 @@ #include "PPSSPP_UWPMain.h" #include +#include +#include #include "Common/File/FileUtil.h" #include "Common/Net/HTTPClient.h" @@ -28,6 +30,7 @@ #include "Core/Loaders.h" #include "Core/Config.h" +#include "Windows/InputDevice.h" #include "NKCodeFromWindowsSystem.h" #include "XAudioSoundStream.h" #include "UWPHost.h" @@ -47,6 +50,9 @@ using namespace Concurrency; PPSSPP_UWPMain *g_main; extern WindowsAudioBackend *winAudioBackend; std::string langRegion; +std::list> g_input; + + // TODO: Use Microsoft::WRL::ComPtr<> for D3D11 objects? // TODO: See https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/WindowsAudioSession for WASAPI with UWP // TODO: Low latency input: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/LowLatencyInput/cpp @@ -115,7 +121,6 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrLocalFolder->Path->Data()); NativeInit(1, argv, "", "", cacheFolder.c_str()); @@ -127,6 +132,10 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptrGetScreenViewport().Height; ctx_->GetDrawContext()->HandleEvent(Draw::Event::GOT_BACKBUFFER, width, height, m_deviceResources->GetBackBufferRenderTargetView()); + + // add first XInput device to respond + g_input.push_back(std::make_unique()); + InputDevice::BeginPolling(); } @@ -438,6 +447,15 @@ bool System_GetPropertyBool(SystemProperty prop) { void System_Notify(SystemNotification notification) { switch (notification) { + case SystemNotification::POLL_CONTROLLERS: + { + for (const auto &device : g_input) + { + if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD) + break; + } + break; + } default: break; } diff --git a/UWP/UWPHost.cpp b/UWP/UWPHost.cpp index d03c78eb65..735e486b53 100644 --- a/UWP/UWPHost.cpp +++ b/UWP/UWPHost.cpp @@ -39,48 +39,12 @@ #include "UWP/UWPHost.h" UWPHost::UWPHost() { - - // add first XInput device to respond - input.push_back(std::make_unique()); } UWPHost::~UWPHost() { } -void UWPHost::UpdateSound() { -} - -void UWPHost::PollControllers() { - for (const auto& device : this->input) - { - if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD) - break; - } - - /* - g_mouseDeltaX *= 0.9f; - g_mouseDeltaY *= 0.9f; - - // TODO: Tweak! - float scaleFactor = g_dpi_scale * 0.01f; - - float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor)); - float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor)); - AxisInput axisX, axisY; - axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X; - axisX.deviceId = DEVICE_ID_MOUSE; - axisX.value = mx; - axisY.axisId = JOYSTICK_AXIS_MOUSE_REL_Y; - axisY.deviceId = DEVICE_ID_MOUSE; - axisY.value = my; - */ -} - -void UWPHost::ToggleDebugConsoleVisibility() { - // N/A -} - void UWPHost::NotifyUserMessage(const std::string &message, float duration, u32 color, const char *id) { osm.Show(message, duration, color, -1, true, id); } diff --git a/UWP/UWPHost.h b/UWP/UWPHost.h index 9341ce2bdd..0bd81b3082 100644 --- a/UWP/UWPHost.h +++ b/UWP/UWPHost.h @@ -2,24 +2,12 @@ #include "Core/Host.h" -#include -#include - -#include "Windows/InputDevice.h" +#include class UWPHost : public Host { public: UWPHost(); ~UWPHost(); - void PollControllers() override; - - void UpdateSound() override; - - void ToggleDebugConsoleVisibility() override; - void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override; - -private: - std::list> input; }; diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 459bb5ce34..2616428696 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -156,6 +156,7 @@ void MainThreadFunc() { SetCurrentThreadName(useEmuThread ? "Render" : "Emu"); host = new WindowsHost(); + System_SetWindowTitle(""); // We convert command line arguments to UTF-8 immediately. diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp index 850108a4b8..d297bf739b 100644 --- a/Windows/InputDevice.cpp +++ b/Windows/InputDevice.cpp @@ -20,6 +20,7 @@ #include #include "Common/Input/InputState.h" +#include "Common/System/System.h" #include "Common/Thread/ThreadUtil.h" #include "Core/Config.h" #include "Core/Host.h" @@ -31,7 +32,7 @@ static std::atomic_bool focused = ATOMIC_VAR_INIT(true); inline static void ExecuteInputPoll() { if (host && (focused.load(std::memory_order_relaxed) || !g_Config.bGamepadOnlyFocused)) { - host->PollControllers(); + System_Notify(SystemNotification::POLL_CONTROLLERS); } } diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 071640d281..db8b8518c2 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -318,27 +318,27 @@ namespace WindowsRawInput { KeyInput key; key.deviceId = DEVICE_ID_MOUSE; - g_mouseDeltaX += raw->data.mouse.lLastX; - g_mouseDeltaY += raw->data.mouse.lLastY; + float mx, my; + g_inputManager.AccumulateMouseDeltas(raw->data.mouse.lLastX, raw->data.mouse.lLastY, &mx, &my); - HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_X] = g_mouseDeltaX; - HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_Y] = g_mouseDeltaY; + HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_X] = mx; + HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_Y] = my; - const int rawInputDownID[5] = { + static const int rawInputDownID[5] = { RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_RIGHT_BUTTON_DOWN, RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_5_DOWN }; - const int rawInputUpID[5] = { + static const int rawInputUpID[5] = { RI_MOUSE_LEFT_BUTTON_UP, RI_MOUSE_RIGHT_BUTTON_UP, RI_MOUSE_BUTTON_3_UP, RI_MOUSE_BUTTON_4_UP, RI_MOUSE_BUTTON_5_UP }; - const int vkInputID[5] = { + static const int vkInputID[5] = { VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index f737c585e0..c69c04acd4 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -66,26 +66,11 @@ #include "Windows/main.h" -float g_mouseDeltaX = 0; -float g_mouseDeltaY = 0; - static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, LPARAM lParam = 0) { return PostMessage(dialog->GetDlgHandle(), message, wParam, lParam); } WindowsHost::WindowsHost() { - g_mouseDeltaX = 0; - g_mouseDeltaY = 0; - - //add first XInput device to respond - input.push_back(std::make_unique()); -#ifndef _M_ARM - //find all connected DInput devices of class GamePad - numDinputDevices_ = DinputDevice::getNumPads(); - for (size_t i = 0; i < numDinputDevices_; i++) { - input.push_back(std::make_unique(static_cast(i))); - } -#endif SetConsolePosition(); } @@ -105,10 +90,24 @@ void WindowsHost::UpdateConsolePosition() { } } -void WindowsHost::PollControllers() { - static int checkCounter = 0; +void WindowsInputManager::Init() { + mouseDeltaX_ = 0; + mouseDeltaY_ = 0; + + //add first XInput device to respond + input.push_back(std::make_unique()); +#ifndef _M_ARM + //find all connected DInput devices of class GamePad + numDinputDevices_ = DinputDevice::getNumPads(); + for (size_t i = 0; i < numDinputDevices_; i++) { + input.push_back(std::make_unique(static_cast(i))); + } +#endif +} + +void WindowsInputManager::PollControllers() { static const int CHECK_FREQUENCY = 71; - if (checkCounter++ > CHECK_FREQUENCY) { + if (checkCounter_++ > CHECK_FREQUENCY) { #ifndef _M_ARM size_t newCount = DinputDevice::getNumPads(); if (newCount > numDinputDevices_) { @@ -119,7 +118,7 @@ void WindowsHost::PollControllers() { numDinputDevices_ = newCount; } #endif - checkCounter = 0; + checkCounter_ = 0; } for (const auto &device : input) { @@ -132,9 +131,9 @@ void WindowsHost::PollControllers() { float scaleFactor_x = g_display.dpi_scale_x * 0.1 * g_Config.fMouseSensitivity; float scaleFactor_y = g_display.dpi_scale_y * 0.1 * g_Config.fMouseSensitivity; - float mx = std::max(-1.0f, std::min(1.0f, g_mouseDeltaX * scaleFactor_x)); - float my = std::max(-1.0f, std::min(1.0f, g_mouseDeltaY * scaleFactor_y)); - AxisInput axisX, axisY; + float mx = std::max(-1.0f, std::min(1.0f, mouseDeltaX_ * scaleFactor_x)); + float my = std::max(-1.0f, std::min(1.0f, mouseDeltaY_ * scaleFactor_y)); + AxisInput axisX{}, axisY{}; axisX.axisId = JOYSTICK_AXIS_MOUSE_REL_X; axisX.deviceId = DEVICE_ID_MOUSE; axisX.value = mx; @@ -148,11 +147,11 @@ void WindowsHost::PollControllers() { } } - g_mouseDeltaX *= g_Config.fMouseSmoothing; - g_mouseDeltaY *= g_Config.fMouseSmoothing; + mouseDeltaX_ *= g_Config.fMouseSmoothing; + mouseDeltaY_ *= g_Config.fMouseSmoothing; - HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_X] = g_mouseDeltaX; - HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_Y] = g_mouseDeltaY; + HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_X] = mouseDeltaX_; + HLEPlugins::PluginDataAxis[JOYSTICK_AXIS_MOUSE_REL_Y] = mouseDeltaY_; } // http://msdn.microsoft.com/en-us/library/aa969393.aspx @@ -236,7 +235,3 @@ void WindowsHost::ToggleDebugConsoleVisibility() { void WindowsHost::NotifyUserMessage(const std::string &message, float duration, u32 color, const char *id) { osm.Show(message, duration, color, -1, true, id); } - -void WindowsHost::SendUIMessage(const std::string &message, const std::string &value) { - NativeMessageReceived(message.c_str(), value.c_str()); -} diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 353996987a..dae5c330e4 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -15,37 +15,51 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "../Core/Host.h" -#include "InputDevice.h" -#include "Common/CommonWindows.h" #include #include -extern float g_mouseDeltaX; -extern float g_mouseDeltaY; +#include "Common/CommonWindows.h" +#include "Core/Host.h" +#include "Windows/InputDevice.h" class WindowsHost : public Host { public: WindowsHost(); - ~WindowsHost() { UpdateConsolePosition(); } - void PollControllers() override; - void ToggleDebugConsoleVisibility() override; bool CreateDesktopShortcut(std::string argumentPath, std::string title) override; void NotifyUserMessage(const std::string &message, float duration = 1.0f, u32 color = 0x00FFFFFF, const char *id = nullptr) override; - void SendUIMessage(const std::string &message, const std::string &value) override; private: void SetConsolePosition(); void UpdateConsolePosition(); - - size_t numDinputDevices_ = 0; - - std::list> input; }; + +class WindowsInputManager { +public: + void Init(); + void PollControllers(); + + void AccumulateMouseDeltas(float dx, float dy, float *outX, float *outY) { + mouseDeltaX_ += dx; + mouseDeltaY_ += dy; + *outX = mouseDeltaX_; + *outY = mouseDeltaX_; + } + +private: + size_t numDinputDevices_ = 0; + std::list> input; + + float mouseDeltaX_ = 0; + float mouseDeltaY_ = 0; + + int checkCounter_ = 0; +}; + +extern WindowsInputManager g_inputManager; diff --git a/Windows/main.cpp b/Windows/main.cpp index b78970e879..305177745b 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -115,6 +115,8 @@ int g_activeWindow = 0; static std::thread g_dialogThread; static bool g_dialogRunning = false; +WindowsInputManager g_inputManager; + int g_lastNumInstances = 0; void System_ShowFileInFolder(const char *path) { @@ -431,6 +433,9 @@ void System_Notify(SystemNotification notification) { if (disasmWindow) PostDialogMessage(disasmWindow, WM_DEB_SETDEBUGLPARAM, 0, (LPARAM)Core_IsStepping()); break; + case SystemNotification::POLL_CONTROLLERS: + g_inputManager.PollControllers(); + break; } } @@ -904,6 +909,8 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin MainWindow::Minimize(); } + g_inputManager.Init(); + // Emu thread (and render thread, if any) is always running! // Only OpenGL uses an externally managed render thread (due to GL's single-threaded context design). Vulkan // manages its own render thread.