gesture.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include "common/bit_field.h"
  6. #include "common/common_types.h"
  7. #include "common/point.h"
  8. #include "core/hid/emulated_console.h"
  9. #include "core/hle/service/hid/controllers/controller_base.h"
  10. #include "core/hle/service/hid/ring_lifo.h"
  11. namespace Service::HID {
  12. class Gesture final : public ControllerBase {
  13. public:
  14. explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
  15. ~Gesture() override;
  16. // Called when the controller is initialized
  17. void OnInit() override;
  18. // When the controller is released
  19. void OnRelease() override;
  20. // When the controller is requesting an update for the shared memory
  21. void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
  22. private:
  23. static constexpr size_t MAX_FINGERS = 16;
  24. static constexpr size_t MAX_POINTS = 4;
  25. // This is nn::hid::GestureType
  26. enum class GestureType : u32 {
  27. Idle, // Nothing touching the screen
  28. Complete, // Set at the end of a touch event
  29. Cancel, // Set when the number of fingers change
  30. Touch, // A finger just touched the screen
  31. Press, // Set if last type is touch and the finger hasn't moved
  32. Tap, // Fast press then release
  33. Pan, // All points moving together across the screen
  34. Swipe, // Fast press movement and release of a single point
  35. Pinch, // All points moving away/closer to the midpoint
  36. Rotate, // All points rotating from the midpoint
  37. };
  38. // This is nn::hid::GestureDirection
  39. enum class GestureDirection : u32 {
  40. None,
  41. Left,
  42. Up,
  43. Right,
  44. Down,
  45. };
  46. // This is nn::hid::GestureAttribute
  47. struct GestureAttribute {
  48. union {
  49. u32 raw{};
  50. BitField<4, 1, u32> is_new_touch;
  51. BitField<8, 1, u32> is_double_tap;
  52. };
  53. };
  54. static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
  55. // This is nn::hid::GestureState
  56. struct GestureState {
  57. s64 sampling_number{};
  58. s64 detection_count{};
  59. GestureType type{GestureType::Idle};
  60. GestureDirection direction{GestureDirection::None};
  61. Common::Point<s32> pos{};
  62. Common::Point<s32> delta{};
  63. f32 vel_x{};
  64. f32 vel_y{};
  65. GestureAttribute attributes{};
  66. f32 scale{};
  67. f32 rotation_angle{};
  68. s32 point_count{};
  69. std::array<Common::Point<s32>, 4> points{};
  70. };
  71. static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
  72. struct GestureProperties {
  73. std::array<Common::Point<s32>, MAX_POINTS> points{};
  74. std::size_t active_points{};
  75. Common::Point<s32> mid_point{};
  76. s64 detection_count{};
  77. u64 delta_time{};
  78. f32 average_distance{};
  79. f32 angle{};
  80. };
  81. struct GestureSharedMemory {
  82. // This is nn::hid::detail::GestureLifo
  83. Lifo<GestureState, hid_entry_count> gesture_lifo{};
  84. static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
  85. INSERT_PADDING_WORDS(0x3E);
  86. };
  87. static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size");
  88. // Reads input from all available input engines
  89. void ReadTouchInput();
  90. // Returns true if gesture state needs to be updated
  91. bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference);
  92. // Updates the shared memory to the next state
  93. void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference);
  94. // Initializes new gesture
  95. void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes);
  96. // Updates existing gesture state
  97. void UpdateExistingGesture(GestureProperties& gesture, GestureType& type, f32 time_difference);
  98. // Terminates exiting gesture
  99. void EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
  100. GestureType& type, GestureAttribute& attributes, f32 time_difference);
  101. // Set current event to a tap event
  102. void SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
  103. GestureType& type, GestureAttribute& attributes);
  104. // Calculates and set the extra parameters related to a pan event
  105. void UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
  106. GestureType& type, f32 time_difference);
  107. // Terminates the pan event
  108. void EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
  109. GestureType& type, f32 time_difference);
  110. // Set current event to a swipe event
  111. void SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
  112. GestureType& type);
  113. // Retrieves the last gesture entry, as indicated by shared memory indices.
  114. [[nodiscard]] const GestureState& GetLastGestureEntry() const;
  115. // Returns the average distance, angle and middle point of the active fingers
  116. GestureProperties GetGestureProperties();
  117. GestureState next_state{};
  118. GestureSharedMemory* shared_memory = nullptr;
  119. Core::HID::EmulatedConsole* console = nullptr;
  120. std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
  121. GestureProperties last_gesture{};
  122. s64 last_update_timestamp{};
  123. s64 last_tap_timestamp{};
  124. f32 last_pan_time_difference{};
  125. bool force_update{false};
  126. bool enable_press_and_tap{false};
  127. };
  128. } // namespace Service::HID