diff --git a/Source/Core/Core/HW/GCPadEmu.cpp b/Source/Core/Core/HW/GCPadEmu.cpp index 26beda9373..b6ed46d0b7 100644 --- a/Source/Core/Core/HW/GCPadEmu.cpp +++ b/Source/Core/Core/HW/GCPadEmu.cpp @@ -83,6 +83,7 @@ GCPad::GCPad(const unsigned int index) : m_index(index) // options groups.emplace_back(m_options = new ControlGroup(_trans("Options"))); m_options->settings.emplace_back(new ControlGroup::BackgroundInputSetting(_trans("Background Input"))); + m_options->settings.emplace_back(new ControlGroup::IterateUI(_trans("Iterative Input"))); } std::string GCPad::GetName() const diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index 682c783a72..eeb0d3b990 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -308,6 +308,7 @@ Wiimote::Wiimote( const unsigned int index ) m_options->settings.emplace_back(new ControlGroup::BackgroundInputSetting(_trans("Background Input"))); m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Sideways Wiimote"), false)); m_options->settings.emplace_back(new ControlGroup::Setting(_trans("Upright Wiimote"), false)); + m_options->settings.emplace_back(new ControlGroup::IterateUI(_trans("Iterative Input"))); // TODO: This value should probably be re-read if SYSCONF gets changed m_sensor_bar_on_top = SConfig::GetInstance().m_SYSCONF->GetData("BT.BAR") != 0; diff --git a/Source/Core/DolphinWX/InputConfigDiag.cpp b/Source/Core/DolphinWX/InputConfigDiag.cpp index a7e477c751..9bd9c68b56 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.cpp +++ b/Source/Core/DolphinWX/InputConfigDiag.cpp @@ -465,6 +465,13 @@ void GamepadPage::AdjustSetting(wxCommandEvent& event) ((PadSetting*)((wxControl*)event.GetEventObject())->GetClientData())->UpdateValue(); } +void GamepadPage::AdjustSettingUI(wxCommandEvent& event) +{ + m_iterate = !m_iterate; + std::lock_guard lk(m_config.controls_lock); + ((PadSetting*)((wxControl*)event.GetEventObject())->GetClientData())->UpdateValue(); +} + void GamepadPage::AdjustControlOption(wxCommandEvent&) { std::lock_guard lk(m_config.controls_lock); @@ -521,18 +528,34 @@ void ControlDialog::DetectControl(wxCommandEvent& event) void GamepadPage::DetectControl(wxCommandEvent& event) { ControlButton* btn = (ControlButton*)event.GetEventObject(); + if (DetectButton(btn) && m_iterate == true) + { + auto it = std::find(control_buttons.begin(), control_buttons.end(), btn); + // std find will never return end since btn will always be found in control_buttons + ++it; + for (; it != control_buttons.end(); ++it) + { + if (!DetectButton(*it)) + break; + } + } +} + +bool GamepadPage::DetectButton(ControlButton* button) +{ + bool success = false; // find device :/ Device* const dev = g_controller_interface.FindDevice(controller->default_device); if (dev) { - btn->SetLabel(_("[ waiting ]")); + button->SetLabel(_("[ waiting ]")); // This makes the "waiting" text work on Linux. true (only if needed) prevents crash on Windows wxTheApp->Yield(true); std::lock_guard lk(m_config.controls_lock); - Device::Control* const ctrl = btn->control_reference->Detect(DETECT_WAIT_TIME, dev); + Device::Control* const ctrl = button->control_reference->Detect(DETECT_WAIT_TIME, dev); // if we got input, update expression and reference if (ctrl) @@ -540,12 +563,15 @@ void GamepadPage::DetectControl(wxCommandEvent& event) wxString control_name = ctrl->GetName(); wxString expr; GetExpressionForControl(expr, control_name); - btn->control_reference->expression = expr; - g_controller_interface.UpdateReference(btn->control_reference, controller->default_device); + button->control_reference->expression = expr; + g_controller_interface.UpdateReference(button->control_reference, controller->default_device); + success = true; } } UpdateGUI(); + + return success; } wxStaticBoxSizer* ControlDialog::CreateControlChooser(GamepadPage* const parent) @@ -740,6 +766,8 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin , control_group(group) { static_bitmap = nullptr; + const std::vector exclude_buttons = {"Mic", "Modifier"}; + const std::vector exclude_groups = {"IR", "Swing", "Tilt", "Shake", "UDP Wiimote", "Extension", "Rumble"}; wxFont m_SmallFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL); for (auto& control : group->controls) @@ -750,6 +778,10 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin control_button->SetFont(m_SmallFont); control_buttons.push_back(control_button); + if (std::find(exclude_groups.begin(), exclude_groups.end(), control_group->name) == exclude_groups.end() && + std::find(exclude_buttons.begin(), exclude_buttons.end(), control->name) == exclude_buttons.end()) + eventsink->control_buttons.push_back(control_button); + if (control->control_ref->is_input) { @@ -880,7 +912,15 @@ ControlGroupBox::ControlGroupBox(ControllerEmu::ControlGroup* const group, wxWin for (auto& groupSetting : group->settings) { PadSettingCheckBox* setting_cbox = new PadSettingCheckBox(parent, groupSetting.get()); - setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSetting, eventsink); + if (groupSetting.get()->is_iterate == true) + { + setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSettingUI, eventsink); + groupSetting.get()->value = 0; + } + else + { + setting_cbox->wxcontrol->Bind(wxEVT_CHECKBOX, &GamepadPage::AdjustSetting, eventsink); + } options.push_back(setting_cbox); Add(setting_cbox->wxcontrol, 0, wxALL|wxLEFT, 5); diff --git a/Source/Core/DolphinWX/InputConfigDiag.h b/Source/Core/DolphinWX/InputConfigDiag.h index afe8d305a3..c5eb0daaa9 100644 --- a/Source/Core/DolphinWX/InputConfigDiag.h +++ b/Source/Core/DolphinWX/InputConfigDiag.h @@ -5,7 +5,7 @@ #pragma once #define SLIDER_TICK_COUNT 100 -#define DETECT_WAIT_TIME 1500 +#define DETECT_WAIT_TIME 2500 #define PREVIEW_UPDATE_TIME 25 // might have to change this setup for wiimote @@ -196,6 +196,7 @@ public: void AdjustControlOption(wxCommandEvent& event); void AdjustSetting(wxCommandEvent& event); + void AdjustSettingUI(wxCommandEvent& event); void GetProfilePath(std::string& path); @@ -203,6 +204,7 @@ public: wxComboBox* device_cbox; std::vector control_groups; + std::vector control_buttons; protected: @@ -213,6 +215,8 @@ private: ControlDialog* m_control_dialog; InputConfigDialog* const m_config_dialog; InputConfig& m_config; + bool DetectButton(ControlButton* button); + bool m_iterate = false; }; class InputConfigDialog : public wxDialog diff --git a/Source/Core/InputCommon/ControllerEmu.cpp b/Source/Core/InputCommon/ControllerEmu.cpp index 420944d713..34a6fade25 100644 --- a/Source/Core/InputCommon/ControllerEmu.cpp +++ b/Source/Core/InputCommon/ControllerEmu.cpp @@ -45,6 +45,8 @@ void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section *sec, const std::s { if (s->is_virtual) continue; + if (s->is_iterate) + continue; sec->Get(group + s->name, &s->value, s->default_value * 100); s->value /= 100; } @@ -104,6 +106,9 @@ void ControllerEmu::ControlGroup::SaveConfig(IniFile::Section *sec, const std::s { if (s->is_virtual) continue; + if (s->is_iterate) + continue; + sec->Set(group + s->name, s->value * 100.0, s->default_value * 100.0); } diff --git a/Source/Core/InputCommon/ControllerEmu.h b/Source/Core/InputCommon/ControllerEmu.h index ec1ab8a2b7..38f8679f44 100644 --- a/Source/Core/InputCommon/ControllerEmu.h +++ b/Source/Core/InputCommon/ControllerEmu.h @@ -28,7 +28,7 @@ enum GROUP_TYPE_TILT, GROUP_TYPE_CURSOR, GROUP_TYPE_TRIGGERS, - GROUP_TYPE_SLIDER, + GROUP_TYPE_SLIDER }; enum @@ -93,13 +93,15 @@ public: , default_value(def_value) , low(_low) , high(_high) - , is_virtual(false) {} + , is_virtual(false) + , is_iterate(false) {} const std::string name; ControlState value; const ControlState default_value; const unsigned int low, high; bool is_virtual; + bool is_iterate; virtual void SetValue(ControlState new_value) { @@ -131,6 +133,15 @@ public: } }; + class IterateUI : public Setting + { + public: + IterateUI(const std::string &_name) : Setting(_name, false) + { + is_iterate = true; + } + }; + ControlGroup(const std::string& _name, const unsigned int _type = GROUP_TYPE_OTHER) : name(_name), type(_type) {} virtual ~ControlGroup() {}