diff options
author | Fernando S <fsahmkow27@gmail.com> | 2021-11-27 11:52:08 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-27 11:52:08 +0100 |
commit | 564f10527745f870621c08bbb5d16badee0ed861 (patch) | |
tree | e8ac8dee60086facf1837393882865f5df18c95e /src/input_common/analog_from_button.cpp | |
parent | Merge pull request #7431 from liushuyu/fix-linux-decoding (diff) | |
parent | config: Remove vibration configuration (diff) | |
download | yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.gz yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.bz2 yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.lz yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.xz yuzu-564f10527745f870621c08bbb5d16badee0ed861.tar.zst yuzu-564f10527745f870621c08bbb5d16badee0ed861.zip |
Diffstat (limited to 'src/input_common/analog_from_button.cpp')
-rwxr-xr-x | src/input_common/analog_from_button.cpp | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/src/input_common/analog_from_button.cpp b/src/input_common/analog_from_button.cpp deleted file mode 100755 index 2fafd077f..000000000 --- a/src/input_common/analog_from_button.cpp +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2017 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <atomic> -#include <chrono> -#include <cmath> -#include <thread> -#include "common/math_util.h" -#include "common/settings.h" -#include "input_common/analog_from_button.h" - -namespace InputCommon { - -class Analog final : public Input::AnalogDevice { -public: - using Button = std::unique_ptr<Input::ButtonDevice>; - - Analog(Button up_, Button down_, Button left_, Button right_, Button modifier_, - float modifier_scale_, float modifier_angle_) - : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)), - right(std::move(right_)), modifier(std::move(modifier_)), modifier_scale(modifier_scale_), - modifier_angle(modifier_angle_) { - Input::InputCallback<bool> callbacks{ - [this]([[maybe_unused]] bool status) { UpdateStatus(); }}; - up->SetCallback(callbacks); - down->SetCallback(callbacks); - left->SetCallback(callbacks); - right->SetCallback(callbacks); - modifier->SetCallback(callbacks); - } - - bool IsAngleGreater(float old_angle, float new_angle) const { - constexpr float TAU = Common::PI * 2.0f; - // Use wider angle to ease the transition. - constexpr float aperture = TAU * 0.15f; - const float top_limit = new_angle + aperture; - return (old_angle > new_angle && old_angle <= top_limit) || - (old_angle + TAU > new_angle && old_angle + TAU <= top_limit); - } - - bool IsAngleSmaller(float old_angle, float new_angle) const { - constexpr float TAU = Common::PI * 2.0f; - // Use wider angle to ease the transition. - constexpr float aperture = TAU * 0.15f; - const float bottom_limit = new_angle - aperture; - return (old_angle >= bottom_limit && old_angle < new_angle) || - (old_angle - TAU >= bottom_limit && old_angle - TAU < new_angle); - } - - float GetAngle(std::chrono::time_point<std::chrono::steady_clock> now) const { - constexpr float TAU = Common::PI * 2.0f; - float new_angle = angle; - - auto time_difference = static_cast<float>( - std::chrono::duration_cast<std::chrono::microseconds>(now - last_update).count()); - time_difference /= 1000.0f * 1000.0f; - if (time_difference > 0.5f) { - time_difference = 0.5f; - } - - if (IsAngleGreater(new_angle, goal_angle)) { - new_angle -= modifier_angle * time_difference; - if (new_angle < 0) { - new_angle += TAU; - } - if (!IsAngleGreater(new_angle, goal_angle)) { - return goal_angle; - } - } else if (IsAngleSmaller(new_angle, goal_angle)) { - new_angle += modifier_angle * time_difference; - if (new_angle >= TAU) { - new_angle -= TAU; - } - if (!IsAngleSmaller(new_angle, goal_angle)) { - return goal_angle; - } - } else { - return goal_angle; - } - return new_angle; - } - - void SetGoalAngle(bool r, bool l, bool u, bool d) { - // Move to the right - if (r && !u && !d) { - goal_angle = 0.0f; - } - - // Move to the upper right - if (r && u && !d) { - goal_angle = Common::PI * 0.25f; - } - - // Move up - if (u && !l && !r) { - goal_angle = Common::PI * 0.5f; - } - - // Move to the upper left - if (l && u && !d) { - goal_angle = Common::PI * 0.75f; - } - - // Move to the left - if (l && !u && !d) { - goal_angle = Common::PI; - } - - // Move to the bottom left - if (l && !u && d) { - goal_angle = Common::PI * 1.25f; - } - - // Move down - if (d && !l && !r) { - goal_angle = Common::PI * 1.5f; - } - - // Move to the bottom right - if (r && !u && d) { - goal_angle = Common::PI * 1.75f; - } - } - - void UpdateStatus() { - const float coef = modifier->GetStatus() ? modifier_scale : 1.0f; - - bool r = right->GetStatus(); - bool l = left->GetStatus(); - bool u = up->GetStatus(); - bool d = down->GetStatus(); - - // Eliminate contradictory movements - if (r && l) { - r = false; - l = false; - } - if (u && d) { - u = false; - d = false; - } - - // Move if a key is pressed - if (r || l || u || d) { - amplitude = coef; - } else { - amplitude = 0; - } - - const auto now = std::chrono::steady_clock::now(); - const auto time_difference = static_cast<u64>( - std::chrono::duration_cast<std::chrono::milliseconds>(now - last_update).count()); - - if (time_difference < 10) { - // Disable analog mode if inputs are too fast - SetGoalAngle(r, l, u, d); - angle = goal_angle; - } else { - angle = GetAngle(now); - SetGoalAngle(r, l, u, d); - } - - last_update = now; - } - - std::tuple<float, float> GetStatus() const override { - if (Settings::values.emulate_analog_keyboard) { - const auto now = std::chrono::steady_clock::now(); - float angle_ = GetAngle(now); - return std::make_tuple(std::cos(angle_) * amplitude, std::sin(angle_) * amplitude); - } - constexpr float SQRT_HALF = 0.707106781f; - int x = 0, y = 0; - if (right->GetStatus()) { - ++x; - } - if (left->GetStatus()) { - --x; - } - if (up->GetStatus()) { - ++y; - } - if (down->GetStatus()) { - --y; - } - const float coef = modifier->GetStatus() ? modifier_scale : 1.0f; - return std::make_tuple(static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF), - static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF)); - } - - Input::AnalogProperties GetAnalogProperties() const override { - return {modifier_scale, 1.0f, 0.5f}; - } - - bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override { - switch (direction) { - case Input::AnalogDirection::RIGHT: - return right->GetStatus(); - case Input::AnalogDirection::LEFT: - return left->GetStatus(); - case Input::AnalogDirection::UP: - return up->GetStatus(); - case Input::AnalogDirection::DOWN: - return down->GetStatus(); - } - return false; - } - -private: - Button up; - Button down; - Button left; - Button right; - Button modifier; - float modifier_scale; - float modifier_angle; - float angle{}; - float goal_angle{}; - float amplitude{}; - std::chrono::time_point<std::chrono::steady_clock> last_update; -}; - -std::unique_ptr<Input::AnalogDevice> AnalogFromButton::Create(const Common::ParamPackage& params) { - const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); - auto up = Input::CreateDevice<Input::ButtonDevice>(params.Get("up", null_engine)); - auto down = Input::CreateDevice<Input::ButtonDevice>(params.Get("down", null_engine)); - auto left = Input::CreateDevice<Input::ButtonDevice>(params.Get("left", null_engine)); - auto right = Input::CreateDevice<Input::ButtonDevice>(params.Get("right", null_engine)); - auto modifier = Input::CreateDevice<Input::ButtonDevice>(params.Get("modifier", null_engine)); - auto modifier_scale = params.Get("modifier_scale", 0.5f); - auto modifier_angle = params.Get("modifier_angle", 5.5f); - return std::make_unique<Analog>(std::move(up), std::move(down), std::move(left), - std::move(right), std::move(modifier), modifier_scale, - modifier_angle); -} - -} // namespace InputCommon |