diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp | 274 |
1 files changed, 24 insertions, 250 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp index 62501494e6..2aa65b3d42 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControllerEmu.cpp @@ -3,23 +3,36 @@ // Refer to the license.txt file included. #include "InputCommon/ControllerEmu/ControllerEmu.h" + #include <memory> -#include "Common/Common.h" -#include "VideoCommon/OnScreenDisplay.h" +#include <mutex> +#include <string> + +#include "Common/IniFile.h" + +#include "InputCommon/ControlReference/ControlReference.h" +#include "InputCommon/ControllerEmu/Control/Control.h" +#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/ControlGroup/Extension.h" + +namespace ControllerEmu +{ +static std::recursive_mutex s_get_state_mutex; + +EmulatedController::~EmulatedController() = default; // This should be called before calling GetState() or State() on a control reference // to prevent a race condition. // This is a recursive mutex because UpdateReferences is recursive. -static std::recursive_mutex s_get_state_mutex; -std::unique_lock<std::recursive_mutex> ControllerEmu::GetStateLock() +std::unique_lock<std::recursive_mutex> EmulatedController::GetStateLock() { std::unique_lock<std::recursive_mutex> lock(s_get_state_mutex); return lock; } -void ControllerEmu::UpdateReferences(ControllerInterface& devi) +void EmulatedController::UpdateReferences(ControllerInterface& devi) { - auto lock = ControllerEmu::GetStateLock(); + const auto lock = GetStateLock(); for (auto& ctrlGroup : groups) { for (auto& control : ctrlGroup->controls) @@ -34,7 +47,7 @@ void ControllerEmu::UpdateReferences(ControllerInterface& devi) } } -void ControllerEmu::UpdateDefaultDevice() +void EmulatedController::UpdateDefaultDevice() { for (auto& ctrlGroup : groups) { @@ -50,62 +63,7 @@ void ControllerEmu::UpdateDefaultDevice() } } -void ControllerEmu::ControlGroup::LoadConfig(IniFile::Section* sec, const std::string& defdev, - const std::string& base) -{ - std::string group(base + name + "/"); - - // settings - for (auto& s : numeric_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - sec->Get(group + s->m_name, &s->m_value, s->m_default_value * 100); - s->m_value /= 100; - } - for (auto& s : boolean_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - sec->Get(group + s->m_name, &s->m_value, s->m_default_value); - } - - for (auto& c : controls) - { - // control expression - sec->Get(group + c->name, &c->control_ref->expression, ""); - - // range - sec->Get(group + c->name + "/Range", &c->control_ref->range, 100.0); - c->control_ref->range /= 100; - } - - // extensions - if (type == GROUP_TYPE_EXTENSION) - { - Extension* const ext = (Extension*)this; - - ext->switch_extension = 0; - unsigned int n = 0; - std::string extname; - sec->Get(base + name, &extname, ""); - - for (auto& ai : ext->attachments) - { - ai->default_device.FromString(defdev); - ai->LoadConfig(sec, base + ai->GetName() + "/"); - - if (ai->GetName() == extname) - ext->switch_extension = n; - - n++; - } - } -} - -ControllerEmu::ControlGroup::BooleanSetting::~BooleanSetting() = default; - -void ControllerEmu::LoadConfig(IniFile::Section* sec, const std::string& base) +void EmulatedController::LoadConfig(IniFile::Section* sec, const std::string& base) { std::string defdev = default_device.ToString(); if (base.empty()) @@ -118,45 +76,7 @@ void ControllerEmu::LoadConfig(IniFile::Section* sec, const std::string& base) cg->LoadConfig(sec, defdev, base); } -void ControllerEmu::ControlGroup::SaveConfig(IniFile::Section* sec, const std::string& defdev, - const std::string& base) -{ - std::string group(base + name + "/"); - - for (auto& s : numeric_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - sec->Set(group + s->m_name, s->m_value * 100.0, s->m_default_value * 100.0); - } - for (auto& s : boolean_settings) - { - if (s->m_type == SettingType::VIRTUAL) - continue; - sec->Set(group + s->m_name, s->m_value, s->m_default_value); - } - - for (auto& c : controls) - { - // control expression - sec->Set(group + c->name, c->control_ref->expression, ""); - - // range - sec->Set(group + c->name + "/Range", c->control_ref->range * 100.0, 100.0); - } - - // extensions - if (type == GROUP_TYPE_EXTENSION) - { - Extension* const ext = (Extension*)this; - sec->Set(base + name, ext->attachments[ext->switch_extension]->GetName(), "None"); - - for (auto& ai : ext->attachments) - ai->SaveConfig(sec, base + ai->GetName() + "/"); - } -} - -void ControllerEmu::SaveConfig(IniFile::Section* sec, const std::string& base) +void EmulatedController::SaveConfig(IniFile::Section* sec, const std::string& base) { const std::string defdev = default_device.ToString(); if (base.empty()) @@ -166,154 +86,7 @@ void ControllerEmu::SaveConfig(IniFile::Section* sec, const std::string& base) ctrlGroup->SaveConfig(sec, defdev, base); } -void ControllerEmu::ControlGroup::SetControlExpression(int index, const std::string& expression) -{ - controls.at(index)->control_ref->expression = expression; -} - -ControllerEmu::AnalogStick::AnalogStick(const char* const _name, ControlState default_radius) - : AnalogStick(_name, _name, default_radius) -{ -} - -ControllerEmu::AnalogStick::AnalogStick(const char* const _name, const char* const _ui_name, - ControlState default_radius) - : ControlGroup(_name, _ui_name, GROUP_TYPE_STICK) -{ - for (auto& named_direction : named_directions) - controls.emplace_back(std::make_unique<Input>(named_direction)); - - controls.emplace_back(std::make_unique<Input>(_trans("Modifier"))); - numeric_settings.emplace_back( - std::make_unique<NumericSetting>(_trans("Radius"), default_radius, 0, 100)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); -} - -ControllerEmu::Buttons::Buttons(const std::string& _name) - : ControlGroup(_name, _name, GROUP_TYPE_BUTTONS) -{ - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Threshold"), 0.5)); -} - -ControllerEmu::Buttons::Buttons(const std::string& ini_name, const std::string& group_name) - : ControlGroup(ini_name, group_name, GROUP_TYPE_BUTTONS) -{ - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Threshold"), 0.5)); -} - -ControllerEmu::ModifySettingsButton::ModifySettingsButton(std::string button_name) - : Buttons(std::move(button_name)) -{ - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Threshold"), 0.5)); -} - -void ControllerEmu::ModifySettingsButton::AddInput(std::string button_name, bool toggle) -{ - controls.emplace_back(new ControlGroup::Input(std::move(button_name))); - threshold_exceeded.emplace_back(false); - associated_settings.emplace_back(false); - associated_settings_toggle.emplace_back(toggle); -} - -void ControllerEmu::ModifySettingsButton::GetState() -{ - for (size_t i = 0; i < controls.size(); ++i) - { - ControlState state = controls[i]->control_ref->State(); - - if (!associated_settings_toggle[i]) - { - // not toggled - associated_settings[i] = state > numeric_settings[0]->GetValue(); - } - else - { - // toggle (loading savestates does not en-/disable toggle) - // after we passed the threshold, we en-/disable. but after that, we don't change it - // anymore - if (!threshold_exceeded[i] && state > numeric_settings[0]->GetValue()) - { - associated_settings[i] = !associated_settings[i]; - if (associated_settings[i]) - OSD::AddMessage(controls[i]->name + ": " + _trans("on")); - else - OSD::AddMessage(controls[i]->name + ": " + _trans("off")); - threshold_exceeded[i] = true; - } - if (state < numeric_settings[0]->GetValue()) - threshold_exceeded[i] = false; - } - } -} - -ControllerEmu::MixedTriggers::MixedTriggers(const std::string& _name) - : ControlGroup(_name, GROUP_TYPE_MIXED_TRIGGERS) -{ - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Threshold"), 0.9)); -} - -ControllerEmu::Triggers::Triggers(const std::string& _name) - : ControlGroup(_name, GROUP_TYPE_TRIGGERS) -{ - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); -} - -ControllerEmu::Slider::Slider(const std::string& _name) : ControlGroup(_name, GROUP_TYPE_SLIDER) -{ - controls.emplace_back(std::make_unique<Input>("Left")); - controls.emplace_back(std::make_unique<Input>("Right")); - - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); -} - -ControllerEmu::Force::Force(const std::string& _name) : ControlGroup(_name, GROUP_TYPE_FORCE) -{ - memset(m_swing, 0, sizeof(m_swing)); - - controls.emplace_back(std::make_unique<Input>(_trans("Up"))); - controls.emplace_back(std::make_unique<Input>(_trans("Down"))); - controls.emplace_back(std::make_unique<Input>(_trans("Left"))); - controls.emplace_back(std::make_unique<Input>(_trans("Right"))); - controls.emplace_back(std::make_unique<Input>(_trans("Forward"))); - controls.emplace_back(std::make_unique<Input>(_trans("Backward"))); - - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); -} - -ControllerEmu::Tilt::Tilt(const std::string& _name) : ControlGroup(_name, GROUP_TYPE_TILT) -{ - memset(m_tilt, 0, sizeof(m_tilt)); - - controls.emplace_back(std::make_unique<Input>("Forward")); - controls.emplace_back(std::make_unique<Input>("Backward")); - controls.emplace_back(std::make_unique<Input>("Left")); - controls.emplace_back(std::make_unique<Input>("Right")); - - controls.emplace_back(std::make_unique<Input>(_trans("Modifier"))); - - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 50)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Circle Stick"), 0)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180)); -} - -ControllerEmu::Cursor::Cursor(const std::string& _name) - : ControlGroup(_name, GROUP_TYPE_CURSOR), m_z(0) -{ - for (auto& named_direction : named_directions) - controls.emplace_back(std::make_unique<Input>(named_direction)); - controls.emplace_back(std::make_unique<Input>("Forward")); - controls.emplace_back(std::make_unique<Input>("Backward")); - controls.emplace_back(std::make_unique<Input>(_trans("Hide"))); - controls.emplace_back(std::make_unique<Input>("Recenter")); - - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Center"), 0.5)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Width"), 0.5)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Height"), 0.5)); - numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 20)); - boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Relative Input"), false)); -} - -void ControllerEmu::LoadDefaults(const ControllerInterface& ciface) +void EmulatedController::LoadDefaults(const ControllerInterface& ciface) { // load an empty inifile section, clears everything IniFile::Section sec; @@ -326,3 +99,4 @@ void ControllerEmu::LoadDefaults(const ControllerInterface& ciface) UpdateDefaultDevice(); } } +} // namespace ControllerEmu |
