diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp | 90 |
1 files changed, 36 insertions, 54 deletions
diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp index 9221b90243..b00ae5a4c9 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/Tilt.cpp @@ -17,7 +17,8 @@ namespace ControllerEmu { -Tilt::Tilt(const std::string& name_) : ControlGroup(name_, GroupType::Tilt) +Tilt::Tilt(const std::string& name_) + : ReshapableInput(name_, name_, GroupType::Tilt), m_last_update(Clock::now()) { controls.emplace_back(std::make_unique<Input>(Translate, _trans("Forward"))); controls.emplace_back(std::make_unique<Input>(Translate, _trans("Backward"))); @@ -26,71 +27,52 @@ Tilt::Tilt(const std::string& name_) : ControlGroup(name_, GroupType::Tilt) controls.emplace_back(std::make_unique<Input>(Translate, _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)); + // Set default input radius to the full 1.0 (no resizing) + // Set default input shape to a square (no reshaping) + // Max deadzone to 50% + AddReshapingSettings(1.0, 0.5, 50); + numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Angle"), 0.9, 0, 180)); } -Tilt::StateData Tilt::GetState(const bool step) +Tilt::StateData Tilt::GetState(bool adjusted) { - // this is all a mess - - ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State(); - ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State(); - - ControlState deadzone = numeric_settings[0]->GetValue(); - ControlState circle = numeric_settings[1]->GetValue(); - auto const angle = numeric_settings[2]->GetValue() / 1.8; - ControlState m = controls[4]->control_ref->State(); - - // deadzone / circle stick code - // this section might be all wrong, but its working good enough, I think - - ControlState ang = atan2(yy, xx); - ControlState ang_sin = sin(ang); - ControlState ang_cos = cos(ang); + ControlState y = controls[0]->control_ref->State() - controls[1]->control_ref->State(); + ControlState x = controls[3]->control_ref->State() - controls[2]->control_ref->State(); - // the amt a full square stick would have at current angle - ControlState square_full = - std::min(ang_sin ? 1 / fabs(ang_sin) : 2, ang_cos ? 1 / fabs(ang_cos) : 2); + // Return raw values. (used in UI) + if (!adjusted) + return {x, y}; - // the amt a full stick would have that was (user setting circular) at current angle - // I think this is more like a pointed circle rather than a rounded square like it should be - ControlState stick_full = (square_full * (1 - circle)) + (circle); + const ControlState modifier = controls[4]->control_ref->State(); - ControlState dist = sqrt(xx * xx + yy * yy); + // Compute desired tilt: + StateData target = Reshape(x, y, modifier); - // dead zone code - dist = std::max(0.0, dist - deadzone * stick_full); - dist /= (1 - deadzone); + // Step the simulation. This is pretty ugly being here. + const auto now = Clock::now(); + const auto ms_since_update = + std::chrono::duration_cast<std::chrono::milliseconds>(now - m_last_update).count(); + m_last_update = now; - // circle stick code - ControlState amt = dist / stick_full; - dist += (square_full - 1) * amt * circle; + constexpr int MAX_DEG_PER_SEC = 360 * 2; + const double MAX_STEP = MAX_DEG_PER_SEC / 180.0 * ms_since_update / 1000; - if (m) - dist *= 0.5; + // TODO: Allow wrap around from 1.0 to -1.0 + // (take the fastest route to target) - yy = std::max(-1.0, std::min(1.0, ang_sin * dist)); - xx = std::max(-1.0, std::min(1.0, ang_cos * dist)); + const double diff_x = (target.x - m_tilt.x); + m_tilt.x += std::min(MAX_STEP, std::abs(diff_x)) * ((diff_x < 0) ? -1 : 1); + const double diff_y = (target.y - m_tilt.y); + m_tilt.y += std::min(MAX_STEP, std::abs(diff_y)) * ((diff_y < 0) ? -1 : 1); - // this is kinda silly here - // gui being open will make this happen 2x as fast, o well - - // silly - if (step) - { - if (xx > m_tilt.x) - m_tilt.x = std::min(m_tilt.x + 0.1, xx); - else if (xx < m_tilt.x) - m_tilt.x = std::max(m_tilt.x - 0.1, xx); - - if (yy > m_tilt.y) - m_tilt.y = std::min(m_tilt.y + 0.1, yy); - else if (yy < m_tilt.y) - m_tilt.y = std::max(m_tilt.y - 0.1, yy); - } + return m_tilt; +} - return {m_tilt.x * angle, m_tilt.y * angle}; +ControlState Tilt::GetGateRadiusAtAngle(double ang) const +{ + const ControlState max_tilt_angle = numeric_settings[SETTING_MAX_ANGLE]->GetValue() / 1.8; + return SquareStickGate(max_tilt_angle).GetRadiusAtAngle(ang); } + } // namespace ControllerEmu |
