From 536c050943e9103d63769c5b46b69e2711d06a50 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 4 Jul 2022 12:49:38 -0700 Subject: [PATCH] Core: Track names of connected pad devices. Rather than just that it's a pad. This tries to get the identifier if possible. --- Core/KeyMap.cpp | 4 ++- Core/KeyMap.h | 2 +- SDL/SDLJoystick.cpp | 15 ++++++++-- UI/NativeApp.cpp | 7 +++-- Windows/DinputDevice.cpp | 8 +++-- Windows/XinputDevice.cpp | 30 +++++++++++++++---- .../org/ppsspp/ppsspp/InputDeviceState.java | 1 + ios/ViewController.mm | 7 +++++ 8 files changed, 60 insertions(+), 14 deletions(-) diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index 2e63fd70d4..1456426ae2 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -40,6 +40,7 @@ KeyMapping g_controllerMap; // Incremented on modification, so we know when to update menus. int g_controllerMapGeneration = 0; std::set g_seenPads; +std::map g_padNames; std::set g_seenDeviceIds; bool g_swapped_keys = false; @@ -762,8 +763,9 @@ bool HasBuiltinController(const std::string &name) { return IsOuya(name) || IsXperiaPlay(name) || IsNvidiaShield(name) || IsMOQII7S(name) || IsRetroid(name); } -void NotifyPadConnected(const std::string &name) { +void NotifyPadConnected(int deviceId, const std::string &name) { g_seenPads.insert(name); + g_padNames[deviceId] = name; } void AutoConfForPad(const std::string &name) { diff --git a/Core/KeyMap.h b/Core/KeyMap.h index 4c0930f5bd..78f2b95987 100644 --- a/Core/KeyMap.h +++ b/Core/KeyMap.h @@ -153,7 +153,7 @@ namespace KeyMap { void SwapAxis(); void UpdateNativeMenuKeys(); - void NotifyPadConnected(const std::string &name); + void NotifyPadConnected(int deviceId, const std::string &name); bool IsNvidiaShield(const std::string &name); bool IsNvidiaShieldTV(const std::string &name); bool IsXperiaPlay(const std::string &name); diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index c129ac821a..0a53ef80b7 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -8,6 +8,7 @@ #include "Common/System/System.h" #include "Core/Config.h" +#include "Core/KeyMap.h" #include "SDL/SDLJoystick.h" using namespace std; @@ -54,11 +55,12 @@ void SDLJoystick::setUpControllers() { } void SDLJoystick::setUpController(int deviceIndex) { + static constexpr int cbGUID = 33; + char pszGUID[cbGUID]; + if (!SDL_IsGameController(deviceIndex)) { cout << "Control pad device " << deviceIndex << " not supported by SDL game controller database, attempting to create default mapping..." << endl; - int cbGUID = 33; - char pszGUID[cbGUID]; - SDL_Joystick* joystick = SDL_JoystickOpen(deviceIndex); + SDL_Joystick *joystick = SDL_JoystickOpen(deviceIndex); if (joystick) { SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), pszGUID, cbGUID); // create default mapping - this is the PS3 dual shock mapping @@ -73,6 +75,12 @@ void SDLJoystick::setUpController(int deviceIndex) { } else { cout << "Failed to get joystick identifier. Read-only device? Control pad device " + std::to_string(deviceIndex) << endl; } + } else { + SDL_Joystick *joystick = SDL_JoystickOpen(deviceIndex); + if (joystick) { + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), pszGUID, cbGUID); + SDL_JoystickClose(joystick); + } } SDL_GameController *controller = SDL_GameControllerOpen(deviceIndex); if (controller) { @@ -80,6 +88,7 @@ void SDLJoystick::setUpController(int deviceIndex) { controllers.push_back(controller); controllerDeviceMap[SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(controller))] = deviceIndex; cout << "found control pad: " << SDL_GameControllerName(controller) << ", loading mapping: "; + KeyMap::NotifyPadConnected(deviceIndex, std::string(pszGUID) + ": " + SDL_GameControllerName(controller)); auto mapping = SDL_GameControllerMapping(controller); if (mapping == NULL) { //cout << "FAILED" << endl; diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index f6fe5d7298..cc1e08ff4d 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -1176,8 +1176,12 @@ void NativeRender(GraphicsContext *graphicsContext) { } void HandleGlobalMessage(const std::string &msg, const std::string &value) { + int nextInputDeviceID = -1; + if (msg == "inputDeviceConnectedID") { + nextInputDeviceID = parseLong(value); + } if (msg == "inputDeviceConnected") { - KeyMap::NotifyPadConnected(value); + KeyMap::NotifyPadConnected(nextInputDeviceID, value); } if (msg == "bgImage_updated") { if (!value.empty()) { @@ -1419,7 +1423,6 @@ bool NativeAxis(const AxisInput &axis) { } void NativeMessageReceived(const char *message, const char *value) { - // We can only have one message queued. std::lock_guard lock(pendingMutex); PendingMessage pendingMessage; pendingMessage.msg = message; diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index bba15bec56..75cb989334 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -23,6 +23,7 @@ #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" +#include "Common/StringUtils.h" #include "Common/System/NativeApp.h" #include "Core/Config.h" #include "Core/HLE/sceCtrl.h" @@ -57,8 +58,6 @@ static const int dinput_buttons[] = { NKCODE_BUTTON_16, }; -static float NormalizedDeadzoneFilter(short value); - #define DIFF (JOY_POVRIGHT - JOY_POVFORWARD) / 2 #define JOY_POVFORWARD_RIGHT JOY_POVFORWARD + DIFF #define JOY_POVRIGHT_BACKWARD JOY_POVRIGHT + DIFF @@ -152,6 +151,11 @@ DinputDevice::DinputDevice(int devnum) { return; } + wchar_t guid[64]; + if (StringFromGUID2(devices.at(devnum).guidProduct, guid, ARRAY_SIZE(guid)) != 0) { + KeyMap::NotifyPadConnected(DEVICE_ID_PAD_0 + pDevNum, StringFromFormat("%S: %S", devices.at(devnum).tszProductName, guid)); + } + if (FAILED(pJoystick->SetDataFormat(&c_dfDIJoystick2))) { pJoystick->Release(); pJoystick = NULL; diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 6d70816748..5dd00c165c 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -4,13 +4,14 @@ #include #include "Common/System/NativeApp.h" -#include "Core/Config.h" #include "Common/CommonWindows.h" #include "Common/Log.h" +#include "Common/StringUtils.h" #include "Common/TimeUtil.h" #include "Common/Input/InputState.h" #include "Common/Input/KeyCodes.h" #include "XinputDevice.h" +#include "Core/Config.h" #include "Core/Core.h" #include "Core/KeyMap.h" #include "Core/HLE/sceCtrl.h" @@ -21,11 +22,21 @@ static double newVibrationTime = 0.0; #if !PPSSPP_PLATFORM(UWP) +struct XINPUT_CAPABILITIES_EX { + XINPUT_CAPABILITIES Capabilities; + WORD vendorId; + WORD productId; + WORD revisionId; + DWORD a4; //unknown +}; + typedef DWORD (WINAPI *XInputGetState_t) (DWORD dwUserIndex, XINPUT_STATE* pState); typedef DWORD (WINAPI *XInputSetState_t) (DWORD dwUserIndex, XINPUT_VIBRATION* pVibration); +typedef DWORD (WINAPI *XInputGetCapabilitiesEx_t) (DWORD unknown, DWORD dwUserIndex, DWORD flags, XINPUT_CAPABILITIES_EX *pCapabilities); static XInputGetState_t PPSSPP_XInputGetState = nullptr; static XInputSetState_t PPSSPP_XInputSetState = nullptr; +static XInputGetCapabilitiesEx_t PPSSPP_XInputGetCapabilitiesEx = nullptr; static DWORD PPSSPP_XInputVersion = 0; static HMODULE s_pXInputDLL = 0; static int s_XInputDLLRefCount = 0; @@ -83,6 +94,10 @@ static int LoadXInputDLL() { return -1; } + if (PPSSPP_XInputVersion >= ((1 << 16) | 4)) { + PPSSPP_XInputGetCapabilitiesEx = (XInputGetCapabilitiesEx_t)GetProcAddress((HMODULE)s_pXInputDLL, (LPCSTR)108); + } + return 0; } @@ -187,10 +202,15 @@ int XinputDevice::UpdateState() { } void XinputDevice::UpdatePad(int pad, const XINPUT_STATE &state, XINPUT_VIBRATION &vibration) { - static bool notified = false; - if (!notified) { - notified = true; - KeyMap::NotifyPadConnected("Xbox 360 Pad"); + static bool notified[XUSER_MAX_COUNT]{}; + if (!notified[pad]) { + notified[pad] = true; + XINPUT_CAPABILITIES_EX caps; + if (PPSSPP_XInputGetCapabilitiesEx != nullptr && PPSSPP_XInputGetCapabilitiesEx(1, pad, 0, &caps) == ERROR_SUCCESS) { + KeyMap::NotifyPadConnected(DEVICE_ID_XINPUT_0 + pad, StringFromFormat("Xbox 360 Pad: %d/%d", caps.vendorId, caps.productId)); + } else { + KeyMap::NotifyPadConnected(DEVICE_ID_XINPUT_0 + pad, "Xbox 360 Pad"); + } } ApplyButtons(pad, state); ApplyVibration(pad, vibration); diff --git a/android/src/org/ppsspp/ppsspp/InputDeviceState.java b/android/src/org/ppsspp/ppsspp/InputDeviceState.java index d117b53167..9c7317fa6c 100644 --- a/android/src/org/ppsspp/ppsspp/InputDeviceState.java +++ b/android/src/org/ppsspp/ppsspp/InputDeviceState.java @@ -128,6 +128,7 @@ public class InputDeviceState { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { logAdvanced(device); } + NativeApp.sendMessage("inputDeviceConnectedID", String.valueOf(this.deviceId)); NativeApp.sendMessage("inputDeviceConnected", device.getName()); } diff --git a/ios/ViewController.mm b/ios/ViewController.mm index 235a133733..c90c30a22a 100644 --- a/ios/ViewController.mm +++ b/ios/ViewController.mm @@ -31,6 +31,7 @@ #include "Core/Config.h" #include "Core/ConfigValues.h" +#include "Core/KeyMap.h" #include "Core/System.h" #include "Core/HLE/sceUsbCam.h" #include "Core/HLE/sceUsbGps.h" @@ -94,6 +95,7 @@ static float dp_yscale = 1.0f; static double lastSelectPress = 0.0f; static double lastStartPress = 0.0f; static bool simulateAnalog = false; +static bool iCadeConnectNotified = false; static bool threadEnabled = true; static bool threadStopped = false; static UITouch *g_touches[10]; @@ -507,6 +509,11 @@ int ToTouchID(UITouch *uiTouch, bool allowAllocate) { - (void)buttonUp:(iCadeState)button { + if (!iCadeConnectNotified) { + iCadeConnectNotified = true; + KeyMap::NotifyPadConnected(DEVICE_ID_PAD_0, "iCade"); + } + if (button == iCadeButtonA) { // Pressing Select twice within 1 second toggles the DPad between // normal operation and simulating the Analog stick.