From 7e7e9a0452e8674f2cf39af5efbf7b09d9726df8 Mon Sep 17 00:00:00 2001 From: "Diogo Franco (Kovensky)" Date: Mon, 12 Nov 2012 17:32:35 +0000 Subject: [PATCH] Add a class for keyboard input Removes the windows-specific hack from sceCtrl to read keyboard input and instead add a hack to PPSSPPWindows. The input mapping is still hardcoded and is the same as it was in sceCtrl. Add an std::list to WindowsHost that, curretly, contains a hardcoded list of preferred `InputDevice`s. Devices are tried in-order until one of them reports success. Xinput is preferred over Keyboard. Keyboard always returns success. Pointers are stored in the std::list for polymorphism. Change XinputDevice to report failure as soon as a device can't be queried, instead of only a frame later. --- Core/HLE/sceCtrl.cpp | 42 ------------------------------- Windows/InputDevice.cpp | 13 ++++++++++ Windows/InputDevice.h | 3 +++ Windows/KeyboardDevice.cpp | 46 ++++++++++++++++++++++++++++++++++ Windows/KeyboardDevice.h | 7 ++++++ Windows/PPSSPP.vcxproj | 3 +++ Windows/PPSSPP.vcxproj.filters | 9 +++++++ Windows/WindowsHost.cpp | 4 ++- Windows/WindowsHost.h | 7 ++++-- Windows/XinputDevice.cpp | 3 ++- 10 files changed, 91 insertions(+), 46 deletions(-) create mode 100644 Windows/InputDevice.cpp create mode 100644 Windows/KeyboardDevice.cpp create mode 100644 Windows/KeyboardDevice.h diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index 83ba95ff71..04b3107b70 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -66,48 +66,6 @@ void SampleControls() { _ctrl_data &data = ctrl; data.frame=1;//frame; frame++; -#ifdef _WIN32 - // TODO: Move this outta here! - data.buttons = 0; - int analogX = 128; - int analogY = 128; - if (GetAsyncKeyState(VK_SPACE)) - data.buttons|=CTRL_START; - if (GetAsyncKeyState('V')) - data.buttons|=CTRL_SELECT; - if (GetAsyncKeyState('A')) - data.buttons|=CTRL_SQUARE; - if (GetAsyncKeyState('S')) - data.buttons|=CTRL_TRIANGLE; - if (GetAsyncKeyState('X')) - data.buttons|=CTRL_CIRCLE; - if (GetAsyncKeyState('Z')) - data.buttons|=CTRL_CROSS; - if (GetAsyncKeyState('Q')) - data.buttons|=CTRL_LTRIGGER; - if (GetAsyncKeyState('W')) - data.buttons|=CTRL_RTRIGGER; - if (GetAsyncKeyState(VK_UP)) { - data.buttons|=CTRL_UP; - analogY -= 100; - } - if (GetAsyncKeyState(VK_DOWN)) { - data.buttons|=CTRL_DOWN; - analogY += 100; - } - if (GetAsyncKeyState(VK_LEFT)) { - data.buttons|=CTRL_LEFT; - analogX -= 100; - } - if (GetAsyncKeyState(VK_RIGHT)) - { - data.buttons|=CTRL_RIGHT; - analogX += 100; - } - - data.analog[0] = analogX; - data.analog[1] = analogY; -#endif } diff --git a/Windows/InputDevice.cpp b/Windows/InputDevice.cpp new file mode 100644 index 0000000000..ad882a2c73 --- /dev/null +++ b/Windows/InputDevice.cpp @@ -0,0 +1,13 @@ +#include "InputDevice.h" +#include "XinputDevice.h" +#include "KeyboardDevice.h" +#include +#include + +#define PUSH_BACK(Cls) do { list.push_back(std::shared_ptr(new Cls())); } while (0) +std::list> getInputDevices() { + std::list> list; + PUSH_BACK(XinputDevice); + PUSH_BACK(KeyboardDevice); + return list; +} diff --git a/Windows/InputDevice.h b/Windows/InputDevice.h index 8598f4d7ef..8c50214dfc 100644 --- a/Windows/InputDevice.h +++ b/Windows/InputDevice.h @@ -8,3 +8,6 @@ public: virtual int UpdateState() = 0; }; +#include +#include +std::list> getInputDevices(); diff --git a/Windows/KeyboardDevice.cpp b/Windows/KeyboardDevice.cpp new file mode 100644 index 0000000000..c69f97b90c --- /dev/null +++ b/Windows/KeyboardDevice.cpp @@ -0,0 +1,46 @@ +#include "KeyboardDevice.h" +#include "../Common/CommonTypes.h" +#include "../Core/HLE/sceCtrl.h" +#include "WinUser.h" + +static const unsigned short key_ctrl_map[] = { + VK_SPACE, CTRL_START, + 'V', CTRL_SELECT, + 'A', CTRL_SQUARE, + 'S', CTRL_TRIANGLE, + 'X', CTRL_CIRCLE, + 'Z', CTRL_CROSS, + 'Q', CTRL_LTRIGGER, + 'W', CTRL_RTRIGGER, + VK_UP, CTRL_UP, + VK_DOWN, CTRL_DOWN, + VK_LEFT, CTRL_LEFT, + VK_RIGHT, CTRL_RIGHT, +}; +int KeyboardDevice::UpdateState() { + float analogX = 0; + float analogY = 0; + for (int i = 0; i < sizeof(key_ctrl_map)/sizeof(key_ctrl_map[0]); i += 2) { + if (!GetAsyncKeyState(key_ctrl_map[i])) + __CtrlButtonUp(key_ctrl_map[i+1]); + else { + __CtrlButtonDown(key_ctrl_map[i+1]); + switch (key_ctrl_map[i]) { + case VK_UP: + analogY -= .8f; + break; + case VK_DOWN: + analogY += .8f; + break; + case VK_LEFT: + analogX -= .8f; + break; + case VK_RIGHT: + analogX += .8f; + break; + } + } + } + __CtrlSetAnalog(analogX, analogY); + return 0; +} \ No newline at end of file diff --git a/Windows/KeyboardDevice.h b/Windows/KeyboardDevice.h new file mode 100644 index 0000000000..79d238348c --- /dev/null +++ b/Windows/KeyboardDevice.h @@ -0,0 +1,7 @@ +#pragma once +#include "InputDevice.h" + +class KeyboardDevice : public InputDevice { +public: + virtual int UpdateState(); +}; diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index fc3ec58516..ea240ed01b 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -364,6 +364,8 @@ + + $(IntDir)%(Filename)2.obj @@ -405,6 +407,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index e4b591299f..7df8759760 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -98,6 +98,12 @@ Windows\Input + + Windows\Input + + + Windows\Input + @@ -173,6 +179,9 @@ Windows\Input + + Windows\Input + diff --git a/Windows/WindowsHost.cpp b/Windows/WindowsHost.cpp index fdbfc2bad1..1ae42e6b08 100644 --- a/Windows/WindowsHost.cpp +++ b/Windows/WindowsHost.cpp @@ -85,7 +85,9 @@ void WindowsHost::SetDebugMode(bool mode) void WindowsHost::BeginFrame() { - xinput.UpdateState(); + for (auto iter = this->input.begin(); iter != this->input.end(); iter++) + if ((*iter)->UpdateState() == 0) + break; // *iter is std::shared_ptr, **iter is InputDevice GL_BeginFrame(); } void WindowsHost::EndFrame() diff --git a/Windows/WindowsHost.h b/Windows/WindowsHost.h index 636211df49..adbb24a876 100644 --- a/Windows/WindowsHost.h +++ b/Windows/WindowsHost.h @@ -1,5 +1,7 @@ #include "../Core/Host.h" -#include "XinputDevice.h" +#include "InputDevice.h" +#include +#include class WindowsHost : public Host { @@ -7,6 +9,7 @@ public: WindowsHost(HWND _displayWindow) { displayWindow = _displayWindow; + input = getInputDevices(); } void UpdateMemView(); void UpdateDisassembly(); @@ -31,5 +34,5 @@ public: private: HWND displayWindow; - XinputDevice xinput; + std::list> input; }; \ No newline at end of file diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index d6130a594e..3c1ac1041f 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -40,12 +40,13 @@ int XinputDevice::UpdateState() { __CtrlSetAnalog(left.x, left.y); this->prevState = state; this->check_delay = 0; + return 0; } else { // wait check_delay frames before polling the controller again this->gamepad_idx = -1; this->check_delay = 100; + return -1; } - return 0; } // We only filter the left stick since PSP has no analog triggers or right stick