analog_from_button.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "input_common/analog_from_button.h"
  5. namespace InputCommon {
  6. class Analog final : public Input::AnalogDevice {
  7. public:
  8. using Button = std::unique_ptr<Input::ButtonDevice>;
  9. Analog(Button up_, Button down_, Button left_, Button right_, Button modifier_,
  10. float modifier_scale_)
  11. : up(std::move(up_)), down(std::move(down_)), left(std::move(left_)),
  12. right(std::move(right_)), modifier(std::move(modifier_)),
  13. modifier_scale(modifier_scale_) {}
  14. std::tuple<float, float> GetStatus() const override {
  15. constexpr float SQRT_HALF = 0.707106781f;
  16. int x = 0, y = 0;
  17. if (right->GetStatus()) {
  18. ++x;
  19. }
  20. if (left->GetStatus()) {
  21. --x;
  22. }
  23. if (up->GetStatus()) {
  24. ++y;
  25. }
  26. if (down->GetStatus()) {
  27. --y;
  28. }
  29. const float coef = modifier->GetStatus() ? modifier_scale : 1.0f;
  30. return std::make_tuple(static_cast<float>(x) * coef * (y == 0 ? 1.0f : SQRT_HALF),
  31. static_cast<float>(y) * coef * (x == 0 ? 1.0f : SQRT_HALF));
  32. }
  33. bool GetAnalogDirectionStatus(Input::AnalogDirection direction) const override {
  34. switch (direction) {
  35. case Input::AnalogDirection::RIGHT:
  36. return right->GetStatus();
  37. case Input::AnalogDirection::LEFT:
  38. return left->GetStatus();
  39. case Input::AnalogDirection::UP:
  40. return up->GetStatus();
  41. case Input::AnalogDirection::DOWN:
  42. return down->GetStatus();
  43. }
  44. return false;
  45. }
  46. private:
  47. Button up;
  48. Button down;
  49. Button left;
  50. Button right;
  51. Button modifier;
  52. float modifier_scale;
  53. };
  54. std::unique_ptr<Input::AnalogDevice> AnalogFromButton::Create(const Common::ParamPackage& params) {
  55. const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
  56. auto up = Input::CreateDevice<Input::ButtonDevice>(params.Get("up", null_engine));
  57. auto down = Input::CreateDevice<Input::ButtonDevice>(params.Get("down", null_engine));
  58. auto left = Input::CreateDevice<Input::ButtonDevice>(params.Get("left", null_engine));
  59. auto right = Input::CreateDevice<Input::ButtonDevice>(params.Get("right", null_engine));
  60. auto modifier = Input::CreateDevice<Input::ButtonDevice>(params.Get("modifier", null_engine));
  61. auto modifier_scale = params.Get("modifier_scale", 0.5f);
  62. return std::make_unique<Analog>(std::move(up), std::move(down), std::move(left),
  63. std::move(right), std::move(modifier), modifier_scale);
  64. }
  65. } // namespace InputCommon