From 1dc8636ec98eb4e5be1aa1bcf3ab26bf328c0f1c Mon Sep 17 00:00:00 2001 From: FlavioFS Date: Sat, 4 Mar 2023 14:40:07 -0300 Subject: [PATCH] Manual XInput index fetching --- ParsecSoda/MetadataCache.cpp | 4 ++- ParsecSoda/MetadataCache.h | 1 + ParsecSoda/Widgets/GamepadsWidget.cpp | 43 ++++++++++++++++++--------- ParsecSoda/Widgets/GamepadsWidget.h | 2 +- ParsecSoda/Widgets/VersionWidget.cpp | 2 +- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/ParsecSoda/MetadataCache.cpp b/ParsecSoda/MetadataCache.cpp index 92047c7d..fadc06ef 100644 --- a/ParsecSoda/MetadataCache.cpp +++ b/ParsecSoda/MetadataCache.cpp @@ -165,7 +165,8 @@ MetadataCache::Preferences MetadataCache::loadPreferences() tryLoadUInt("fps", preferences.fps, 60); tryLoadUInt("bandwidth", preferences.bandwidth, 20); tryLoadUInt("xboxPuppetCount", preferences.xboxPuppetCount, 4); - tryLoadUInt("ds4PuppetCount", preferences.ds4PuppetCount, 0); + tryLoadUInt("ds4PuppetCount", preferences.ds4PuppetCount, 0); + tryLoadBool("autoXInputIndexFetching", preferences.autoXInputIndexFetching, false); tryLoadBool("latencyLimiterEnabled", preferences.latencyLimiterEnabled, false); tryLoadUInt("maxLatencyMs", preferences.maxLatencyMs, 100); tryLoadUInt("hotseatDurationSeconds", preferences.hotseatDurationSeconds, 300); @@ -229,6 +230,7 @@ bool MetadataCache::savePreferences(MetadataCache::Preferences preferences) MTY_JSONObjSetUInt(json, "adapter", preferences.adapter); MTY_JSONObjSetUInt(json, "xboxPuppetCount", preferences.xboxPuppetCount); MTY_JSONObjSetUInt(json, "ds4PuppetCount", preferences.ds4PuppetCount); + MTY_JSONObjSetBool(json, "autoXInputIndexFetching", preferences.autoXInputIndexFetching); MTY_JSONObjSetBool(json, "latencyLimiterEnabled", preferences.latencyLimiterEnabled); MTY_JSONObjSetUInt(json, "maxLatencyMs", preferences.maxLatencyMs); MTY_JSONObjSetUInt(json, "hotseatDurationSeconds", preferences.hotseatDurationSeconds); diff --git a/ParsecSoda/MetadataCache.h b/ParsecSoda/MetadataCache.h index ce4cdeb6..f676a446 100644 --- a/ParsecSoda/MetadataCache.h +++ b/ParsecSoda/MetadataCache.h @@ -61,6 +61,7 @@ class MetadataCache uint32_t bandwidth = 20; uint32_t xboxPuppetCount = 4; uint32_t ds4PuppetCount = 0; + bool autoXInputIndexFetching = false; bool latencyLimiterEnabled = false; uint32_t maxLatencyMs = 100; uint32_t hotseatDurationSeconds = 300; diff --git a/ParsecSoda/Widgets/GamepadsWidget.cpp b/ParsecSoda/Widgets/GamepadsWidget.cpp index e6d86a36..83cdec61 100644 --- a/ParsecSoda/Widgets/GamepadsWidget.cpp +++ b/ParsecSoda/Widgets/GamepadsWidget.cpp @@ -11,7 +11,7 @@ bool GamepadsWidget::render() static ImVec2 cursor; static bool isWindowLocked = false; - static bool isConnectionButtonPressed = false; + static bool isConnectionButtonPressed = false, refreshGamepads = false; static ImVec2 dummySize = ImVec2(0.0f, 5.0f); static string name, id, tooltipTitle, tooltipDescription; @@ -42,7 +42,7 @@ bool GamepadsWidget::render() userID = gi->owner.guest.userID; ImGui::BeginGroup(); - renderPadInputTypeIcon(gi); + renderPadInputTypeIcon(gi, i, refreshGamepads); id = "###Connect gamepad" + to_string(i); if (ToggleIconButtonWidget::render(AppIcons::padOn, AppIcons::padOff, gi->isConnected(), id.c_str())) @@ -302,8 +302,9 @@ bool GamepadsWidget::render() AppStyle::pop(); - if (isConnectionButtonPressed) + if (refreshGamepads || (MetadataCache::preferences.autoXInputIndexFetching && isConnectionButtonPressed)) { + refreshGamepads = false; isConnectionButtonPressed = false; for (size_t i = 0; i < _gamepads.size(); ++i) { @@ -408,6 +409,16 @@ void GamepadsWidget::renderOptionsMenu() if (ImGui::BeginPopupContextItem("Gamepad Options", ImGuiPopupFlags_MouseButtonLeft)) { + if (SwitchWidget::render( + MetadataCache::preferences.autoXInputIndexFetching, + "###Auto XInput Fetching switch", "Automatic XInput Fetching", + "Auto XInput Fetch [ON]", "XInput indices will be identified automatically.\n\nBeware! Enabling this may cause BSOD's for some users.", + "Auto XInput Fetch [OFF]", "XInput indices will be identified manually on button press.\n\nManual fetch is the safest option." + )) + { + MetadataCache::savePreferences(); + } + if (SwitchWidget::render( MetadataCache::preferences.defaultMirrorValue, "###Mirror default switch", "Default mirror", @@ -450,7 +461,7 @@ void GamepadsWidget::renderOptionsMenu() ImGui::PopStyleVar(); } -void GamepadsWidget::renderPadInputTypeIcon(AGamepad* pad) +void GamepadsWidget::renderPadInputTypeIcon(AGamepad* pad, const size_t& gamepadIndex, bool& refreshGamepads) { static ImVec2 cursor; static const ImVec2 ICON_SIZE = ImVec2(40, 40); @@ -476,14 +487,16 @@ void GamepadsWidget::renderPadInputTypeIcon(AGamepad* pad) ); ImGui::SetCursorPos(cursor); - ImGui::Image( - xboxIcons[xboxIndex], - ICON_SIZE, ImVec2(0, 0), ImVec2(1, 1), AppColors::primary - ); + if (IconButton::render(xboxIcons[xboxIndex], AppColors::primary, ICON_SIZE, (string("XInput index btn ") + to_string(gamepadIndex)).c_str())) + { + refreshGamepads = true; + } TitleTooltipWidget::render( (string() + "XInput " + to_string(padIndex)).c_str(), ( - string("This controller is using XInput slot ") + to_string(padIndex) + ".\n\n" + + string("") + + "Press to identify XInput indices (this is visual only).\n\n" + + "This controller is using XInput slot " + to_string(padIndex) + ".\n" + "* Remember:\nYour physical controllers may also occupy XInput slots." ).c_str() ); @@ -491,14 +504,16 @@ void GamepadsWidget::renderPadInputTypeIcon(AGamepad* pad) } else { - ImGui::Image( - AppIcons::xinput, - ICON_SIZE, ImVec2(0, 0), ImVec2(1, 1), AppColors::backgroundIcon - ); + if (IconButton::render(AppIcons::xinput, AppColors::backgroundIcon, ICON_SIZE, (string("XInput index btn ") + to_string(gamepadIndex)).c_str())) + { + refreshGamepads = true; + } TitleTooltipWidget::render( (string() + "XBox controller").c_str(), ( - string("This is an XBox controller out of XInput range.") + "\n\n" + + string("") + + + "Press to identify XInput indices (this is visual only).\n\n" + + "This is an XBox controller out of XInput range." + "\n" + "* It still works, but as a generic controller without XInput features." ).c_str() ); diff --git a/ParsecSoda/Widgets/GamepadsWidget.h b/ParsecSoda/Widgets/GamepadsWidget.h index 92514308..8b403270 100644 --- a/ParsecSoda/Widgets/GamepadsWidget.h +++ b/ParsecSoda/Widgets/GamepadsWidget.h @@ -24,7 +24,7 @@ class GamepadsWidget private: void renderTopBar(bool& isWindowLocked, const ImVec2& windowSize); void renderOptionsMenu(); - void renderPadInputTypeIcon(AGamepad* pad); + void renderPadInputTypeIcon(AGamepad* pad, const size_t& gamepadIndex, bool& refreshGamepads); // Dependency injection Hosting& _hosting; diff --git a/ParsecSoda/Widgets/VersionWidget.cpp b/ParsecSoda/Widgets/VersionWidget.cpp index eee59cfb..8bb95ce1 100644 --- a/ParsecSoda/Widgets/VersionWidget.cpp +++ b/ParsecSoda/Widgets/VersionWidget.cpp @@ -19,7 +19,7 @@ bool VersionWidget::render() ImGui::SetNextWindowSize(ImVec2(100, 32)); ImGui::Begin("##Version", (bool*)0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBringToFrontOnFocus); AppStyle::pushLabel(); - ImGui::Text("v. 1.2.7"); + ImGui::Text("v. 1.2.8"); AppStyle::pop(); ImGui::End();