// Copyright 2017 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. #include "InputCommon/ControllerEmu/ControlGroup/Cursor.h" #include #include #include #include #include "Common/Common.h" #include "Common/MathUtil.h" #include "InputCommon/ControlReference/ControlReference.h" #include "InputCommon/ControllerEmu/Control/Control.h" #include "InputCommon/ControllerEmu/Control/Input.h" #include "InputCommon/ControllerEmu/ControllerEmu.h" #include "InputCommon/ControllerEmu/Setting/BooleanSetting.h" #include "InputCommon/ControllerEmu/Setting/NumericSetting.h" namespace ControllerEmu { Cursor::Cursor(const std::string& name_) : ControlGroup(name_, GroupType::Cursor) { for (auto& named_direction : named_directions) controls.emplace_back(std::make_unique(Translate, named_direction)); controls.emplace_back(std::make_unique(Translate, _trans("Forward"))); controls.emplace_back(std::make_unique(Translate, _trans("Backward"))); controls.emplace_back(std::make_unique(Translate, _trans("Hide"))); controls.emplace_back(std::make_unique(Translate, _trans("Recenter"))); numeric_settings.emplace_back(std::make_unique(_trans("Center"), 0.5)); numeric_settings.emplace_back(std::make_unique(_trans("Width"), 0.5)); numeric_settings.emplace_back(std::make_unique(_trans("Height"), 0.5)); numeric_settings.emplace_back(std::make_unique(_trans("Dead Zone"), 0, 0, 20)); boolean_settings.emplace_back(std::make_unique(_trans("Relative Input"), false)); boolean_settings.emplace_back(std::make_unique(_trans("Auto-Hide"), false)); } void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState* const z, const bool adjusted) { const ControlState zz = controls[4]->control_ref->State() - controls[5]->control_ref->State(); // silly being here if (zz > m_z) m_z = std::min(m_z + 0.1, zz); else if (zz < m_z) m_z = std::max(m_z - 0.1, zz); *z = m_z; if (m_autohide_timer > -1) { --m_autohide_timer; } ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); const ControlState deadzone = numeric_settings[3]->GetValue(); // reset auto-hide timer if (std::abs(m_prev_xx - xx) > deadzone || std::abs(m_prev_yy - yy) > deadzone) { m_autohide_timer = TIMER_VALUE; } // hide bool autohide = boolean_settings[1]->GetValue() && m_autohide_timer < 0; if (controls[6]->control_ref->State() > 0.5 || autohide) { *x = 10000; *y = 0; } else { // adjust cursor according to settings if (adjusted) { xx *= (numeric_settings[1]->GetValue() * 2); yy *= (numeric_settings[2]->GetValue() * 2); yy += (numeric_settings[0]->GetValue() - 0.5); } // relative input if (boolean_settings[0]->GetValue()) { // deadzone to avoid the cursor slowly drifting if (std::abs(xx) > deadzone) m_x = MathUtil::Clamp(m_x + xx * SPEED_MULTIPLIER, -1.0, 1.0); if (std::abs(yy) > deadzone) m_y = MathUtil::Clamp(m_y + yy * SPEED_MULTIPLIER, -1.0, 1.0); // recenter if (controls[7]->control_ref->State() > 0.5) { m_x = 0.0; m_y = 0.0; } } else { m_x = xx; m_y = yy; } *x = m_x; *y = m_y; } m_prev_xx = xx; m_prev_yy = yy; } } // namespace ControllerEmu