Remove PollControllers from host. Break out a WindowsInputManager from WindowsHost.

This commit is contained in:
Henrik Rydgård 2023-03-24 19:57:24 +01:00
parent 2f09d29698
commit e71be8af2e
11 changed files with 90 additions and 102 deletions

View File

@ -183,6 +183,7 @@ enum class SystemNotification {
IMMERSIVE_MODE_CHANGE,
AUDIO_RESET_DEVICE,
SUSTAINED_PERF_CHANGE,
POLL_CONTROLLERS,
};
std::string System_GetProperty(SystemProperty prop);

View File

@ -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;}

View File

@ -2,6 +2,8 @@
#include "PPSSPP_UWPMain.h"
#include <mutex>
#include <list>
#include <memory>
#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<std::unique_ptr<InputDevice>> 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_ptr<DX::DeviceResourc
const char *argv[2] = { "fake", nullptr };
std::string cacheFolder = ConvertWStringToUTF8(ApplicationData::Current->LocalFolder->Path->Data());
NativeInit(1, argv, "", "", cacheFolder.c_str());
@ -127,6 +132,10 @@ PPSSPP_UWPMain::PPSSPP_UWPMain(App ^app, const std::shared_ptr<DX::DeviceResourc
int height = m_deviceResources->GetScreenViewport().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<XinputDevice>());
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;
}

View File

@ -39,48 +39,12 @@
#include "UWP/UWPHost.h"
UWPHost::UWPHost() {
// add first XInput device to respond
input.push_back(std::make_unique<XinputDevice>());
}
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);
}

View File

@ -2,24 +2,12 @@
#include "Core/Host.h"
#include <list>
#include <memory>
#include "Windows/InputDevice.h"
#include <string>
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<std::unique_ptr<InputDevice>> input;
};

View File

@ -156,6 +156,7 @@ void MainThreadFunc() {
SetCurrentThreadName(useEmuThread ? "Render" : "Emu");
host = new WindowsHost();
System_SetWindowTitle("");
// We convert command line arguments to UTF-8 immediately.

View File

@ -20,6 +20,7 @@
#include <atomic>
#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);
}
}

View File

@ -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,

View File

@ -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<XinputDevice>());
#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<DinputDevice>(static_cast<int>(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<XinputDevice>());
#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<DinputDevice>(static_cast<int>(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());
}

View File

@ -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 <list>
#include <memory>
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<std::unique_ptr<InputDevice>> 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<std::unique_ptr<InputDevice>> input;
float mouseDeltaX_ = 0;
float mouseDeltaY_ = 0;
int checkCounter_ = 0;
};
extern WindowsInputManager g_inputManager;

View File

@ -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.