MappingCommon.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <string>
  5. #include "Common/Matrix.h"
  6. #include "InputCommon/ControllerEmu/StickGate.h"
  7. #include "InputCommon/ControllerInterface/CoreDevice.h"
  8. namespace ControllerEmu
  9. {
  10. class EmulatedController;
  11. } // namespace ControllerEmu
  12. namespace ciface::MappingCommon
  13. {
  14. enum class Quote
  15. {
  16. On,
  17. Off
  18. };
  19. std::string GetExpressionForControl(const std::string& control_name,
  20. const Core::DeviceQualifier& control_device,
  21. const Core::DeviceQualifier& default_device,
  22. Quote quote = Quote::On);
  23. std::string BuildExpression(const Core::InputDetector::Results&,
  24. const Core::DeviceQualifier& default_device, Quote quote);
  25. void RemoveSpuriousTriggerCombinations(Core::InputDetector::Results*);
  26. void RemoveDetectionsAfterTimePoint(Core::InputDetector::Results*, Clock::time_point after);
  27. bool ContainsCompleteDetection(const Core::InputDetector::Results&);
  28. // class for detecting four directional input mappings in sequence.
  29. class ReshapableInputMapper
  30. {
  31. public:
  32. // Four cardinal directions.
  33. static constexpr std::size_t REQUIRED_INPUT_COUNT = 4;
  34. // Caller should hold the "StateLock".
  35. ReshapableInputMapper(const Core::DeviceContainer& container,
  36. std::span<const std::string> device_strings);
  37. // Reads inputs and updates internal state.
  38. // Returns true if an input was detected in this call.
  39. // (useful for UI animation)
  40. // Caller should hold the "StateLock".
  41. bool Update();
  42. // A counter-clockwise angle in radians for the currently desired input direction.
  43. // Used for a graphical indicator in the UI.
  44. // 0 == East
  45. float GetCurrentAngle() const;
  46. // True if all four directions have been detected or the timer expired.
  47. bool IsComplete() const;
  48. // Returns true if "analog" inputs were detected and calibration should be performed.
  49. // Must use *before* ApplyResults.
  50. bool IsCalibrationNeeded() const;
  51. // Use when IsComplete returns true.
  52. // Updates the mappings on the provided ReshapableInput.
  53. // Caller should hold the "StateLock".
  54. bool ApplyResults(ControllerEmu::EmulatedController*, ControllerEmu::ReshapableInput* stick);
  55. private:
  56. Core::InputDetector m_input_detector;
  57. };
  58. class CalibrationBuilder
  59. {
  60. public:
  61. // Provide nullopt if you want to calibrate the center on first Update.
  62. explicit CalibrationBuilder(std::optional<Common::DVec2> center = Common::DVec2{});
  63. // Updates the calibration data using the provided point and the previous point.
  64. void Update(Common::DVec2 point);
  65. // Returns true when the calibration data seems to be reasonably filled in.
  66. // Used to update the UI to encourage the user to click the "Finish" button.
  67. bool IsCalibrationDataSensible() const;
  68. // Returns true when the calibration data seems sensible,
  69. // and the input then approaches the center position.
  70. bool IsComplete() const;
  71. // Grabs the calibration value at the provided angle.
  72. // Used to render the calibration in the UI while it's in progress.
  73. ControlState GetCalibrationRadiusAtAngle(double angle) const;
  74. // Sets the calibration data of the provided ReshapableInput.
  75. // Caller should hold the "StateLock".
  76. void ApplyResults(ControllerEmu::ReshapableInput* stick);
  77. Common::DVec2 GetCenter() const;
  78. private:
  79. ControllerEmu::ReshapableInput::CalibrationData m_calibration_data;
  80. std::optional<Common::DVec2> m_center = std::nullopt;
  81. Common::DVec2 m_prev_point{};
  82. };
  83. } // namespace ciface::MappingCommon