From c43957d385b81aa3a62ccce190aea926df4787fb Mon Sep 17 00:00:00 2001 From: Connor McLaughlin <stenzek@gmail.com> Date: Sun, 16 May 2021 03:25:28 +1000 Subject: [PATCH] FullscreenUI: Add controller autofire settings --- src/frontend-common/fullscreen_ui.cpp | 109 ++++++++++++++++++++++---- 1 file changed, 92 insertions(+), 17 deletions(-) diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 158968a0c..1ce422842 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -817,7 +817,7 @@ static ImGuiFullscreen::ChoiceDialogOptions GetGameListDirectoryOptions(bool rec } static void DrawInputBindingButton(InputBindingType type, const char* section, const char* name, - const char* display_name) + const char* display_name, bool show_type = true) { TinyString title; title.Format("%s/%s", section, name); @@ -833,23 +833,28 @@ static void DrawInputBindingButton(InputBindingType type, const char* section, c const ImRect title_bb(bb.Min, ImVec2(bb.Max.x, midpoint)); const ImRect summary_bb(ImVec2(bb.Min.x, midpoint), bb.Max); - switch (type) + if (show_type) { - case InputBindingType::Button: - title.Format(ICON_FA_CIRCLE " %s Button", display_name); - break; - case InputBindingType::Axis: - title.Format(ICON_FA_BULLSEYE " %s Axis", display_name); - break; - case InputBindingType::Rumble: - title.Format(ICON_FA_BELL " %s", display_name); - break; - default: - title = display_name; - break; + switch (type) + { + case InputBindingType::Button: + title.Format(ICON_FA_CIRCLE " %s Button", display_name); + break; + case InputBindingType::Axis: + title.Format(ICON_FA_BULLSEYE " %s Axis", display_name); + break; + case InputBindingType::Rumble: + title.Format(ICON_FA_BELL " %s", display_name); + break; + default: + title = display_name; + break; + } } + ImGui::PushFont(g_large_font); - ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, title, nullptr, nullptr, ImVec2(0.0f, 0.0f), &title_bb); + ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, show_type ? title.GetCharArray() : display_name, nullptr, + nullptr, ImVec2(0.0f, 0.0f), &title_bb); ImGui::PopFont(); // eek, potential heap allocation :/ @@ -1732,6 +1737,9 @@ void DrawSettingsWindow() static std::array<Controller::ButtonList, NUM_CONTROLLER_AND_CARD_PORTS> button_cache; static std::array<Controller::AxisList, NUM_CONTROLLER_AND_CARD_PORTS> axis_cache; static std::array<Controller::SettingList, NUM_CONTROLLER_AND_CARD_PORTS> setting_cache; + static std::array<std::string, + NUM_CONTROLLER_AND_CARD_PORTS * CommonHostInterface::NUM_CONTROLLER_AUTOFIRE_BUTTONS> + autofire_buttons_cache; TinyString section; TinyString key; @@ -1749,6 +1757,8 @@ void DrawSettingsWindow() "Determines the simulated controller plugged into this port.", &s_settings_copy.controller_types[port], &Settings::GetControllerTypeDisplayName, ControllerType::Count); + section.Format("Controller%u", port + 1); + const ControllerType ctype = s_settings_copy.controller_types[port]; if (ctype != type_cache[port]) { @@ -1756,9 +1766,13 @@ void DrawSettingsWindow() button_cache[port] = Controller::GetButtonNames(ctype); axis_cache[port] = Controller::GetAxisNames(ctype); setting_cache[port] = Controller::GetSettings(ctype); - } - section.Format("Controller%u", port + 1); + for (u32 i = 0; i < CommonHostInterface::NUM_CONTROLLER_AUTOFIRE_BUTTONS; i++) + { + autofire_buttons_cache[port * CommonHostInterface::NUM_CONTROLLER_AUTOFIRE_BUTTONS + i] = + s_host_interface->GetStringSettingValue(section, TinyString::FromFormat("AutoFire%uButton", i + 1)); + } + } for (const auto& it : button_cache[port]) { @@ -1777,6 +1791,67 @@ void DrawSettingsWindow() for (const SettingInfo& it : setting_cache[port]) settings_changed |= SettingInfoButton(it, section); + + for (u32 autofire_index = 0; autofire_index < CommonHostInterface::NUM_CONTROLLER_AUTOFIRE_BUTTONS; + autofire_index++) + { + const u32 cache_index = port * CommonHostInterface::NUM_CONTROLLER_AUTOFIRE_BUTTONS + autofire_index; + + if (MenuButtonWithValue(TinyString::FromFormat("Auto Fire %u", autofire_index + 1), + "Selects the button to toggle with this auto fire binding.", + autofire_buttons_cache[cache_index].c_str())) + + { + auto callback = [port, autofire_index, cache_index](s32 index, const std::string& title, bool checked) { + if (index < 0) + return; + + auto lock = s_host_interface->GetSettingsLock(); + if (index == 0) + { + s_host_interface->GetSettingsInterface()->DeleteValue( + TinyString::FromFormat("Controller%u", port + 1), + TinyString::FromFormat("AutoFire%uButton", autofire_index + 1)); + std::string().swap(autofire_buttons_cache[cache_index]); + } + else + { + s_host_interface->GetSettingsInterface()->SetStringValue( + TinyString::FromFormat("Controller%u", port + 1), + TinyString::FromFormat("AutoFire%uButton", autofire_index + 1), + button_cache[port][index - 1].first.c_str()); + autofire_buttons_cache[cache_index] = button_cache[port][index - 1].first; + } + + // needs a reload... + s_host_interface->RunLater(SaveAndApplySettings); + CloseChoiceDialog(); + }; + + ImGuiFullscreen::ChoiceDialogOptions options; + options.reserve(button_cache[port].size() + 1); + options.emplace_back("(None)", autofire_buttons_cache[cache_index].empty()); + for (const auto& it : button_cache[port]) + options.emplace_back(it.first, autofire_buttons_cache[cache_index] == it.first); + + OpenChoiceDialog(ICON_FA_GAMEPAD " Select Auto Fire Button", false, std::move(options), + std::move(callback)); + } + + if (autofire_buttons_cache[cache_index].empty()) + continue; + + key.Format("AutoFire%u", autofire_index + 1); + DrawInputBindingButton(InputBindingType::Button, section, key, + TinyString::FromFormat("Auto Fire %u Binding", autofire_index + 1), false); + + key.Format("AutoFire%uFrequency", autofire_index + 1); + int frequency = s_host_interface->GetSettingsInterface()->GetIntValue( + section, key, CommonHostInterface::DEFAULT_AUTOFIRE_FREQUENCY); + settings_changed |= RangeButton(TinyString::FromFormat("Auto Fire %u Frequency", autofire_index + 1), + "Sets the rate at which the auto fire will trigger on and off.", &frequency, + 1, 255, 1, "%d Frames"); + } } EndMenuButtons();