summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/hid/controllers/gesture.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/hid/controllers/gesture.h')
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h92
1 files changed, 84 insertions, 8 deletions
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index f650b8338..60ecc7822 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -5,8 +5,10 @@
#pragma once
#include <array>
+#include "common/bit_field.h"
#include "common/common_types.h"
#include "common/swap.h"
+#include "core/frontend/input.h"
#include "core/hle/service/hid/controllers/controller_base.h"
namespace Service::HID {
@@ -28,29 +30,64 @@ public:
void OnLoadInputDevices() override;
private:
- struct Locations {
+ static constexpr size_t MAX_FINGERS = 16;
+ static constexpr size_t MAX_POINTS = 4;
+
+ enum class TouchType : u32 {
+ Idle, // Nothing touching the screen
+ Complete, // Unknown. End of touch?
+ Cancel, // Never triggered
+ Touch, // Pressing without movement
+ Press, // Never triggered
+ Tap, // Fast press then release
+ Pan, // All points moving together across the screen
+ Swipe, // Fast press movement and release of a single point
+ Pinch, // All points moving away/closer to the midpoint
+ Rotate, // All points rotating from the midpoint
+ };
+
+ enum class Direction : u32 {
+ None,
+ Left,
+ Up,
+ Right,
+ Down,
+ };
+
+ struct Attribute {
+ union {
+ u32_le raw{};
+
+ BitField<0, 1, u32> is_new_touch;
+ BitField<1, 1, u32> is_double_tap;
+ };
+ };
+ static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size");
+
+ struct Points {
s32_le x;
s32_le y;
};
+ static_assert(sizeof(Points) == 8, "Points is an invalid size");
struct GestureState {
s64_le sampling_number;
s64_le sampling_number2;
s64_le detection_count;
- s32_le type;
- s32_le dir;
+ TouchType type;
+ Direction dir;
s32_le x;
s32_le y;
s32_le delta_x;
s32_le delta_y;
f32 vel_x;
f32 vel_y;
- s32_le attributes;
- f32 scale;
- f32 rotation;
- s32_le location_count;
- std::array<Locations, 4> locations;
+ Attribute attributes;
+ u32 scale;
+ u32 rotation_angle;
+ s32_le point_count;
+ std::array<Points, 4> points;
};
static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size");
@@ -58,6 +95,45 @@ private:
CommonHeader header;
std::array<GestureState, 17> gesture_states;
};
+ static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size");
+
+ struct Finger {
+ f32 x{};
+ f32 y{};
+ bool pressed{};
+ };
+
+ struct GestureProperties {
+ std::array<Points, MAX_POINTS> points{};
+ std::size_t active_points{};
+ Points mid_point{};
+ s64_le detection_count{};
+ u64_le delta_time{};
+ float average_distance{};
+ float angle{};
+ };
+
+ // Returns an unused finger id, if there is no fingers avaliable MAX_FINGERS will be returned
+ std::optional<size_t> GetUnusedFingerID() const;
+
+ /** If the touch is new it tries to assing a new finger id, if there is no fingers avaliable no
+ * changes will be made. Updates the coordinates if the finger id it's already set. If the touch
+ * ends delays the output by one frame to set the end_touch flag before finally freeing the
+ * finger id */
+ size_t UpdateTouchInputEvent(const std::tuple<float, float, bool>& touch_input,
+ size_t finger_id);
+
+ // Returns the average distance, angle and middle point of the active fingers
+ GestureProperties GetGestureProperties();
+
SharedMemory shared_memory{};
+ std::unique_ptr<Input::TouchDevice> touch_mouse_device;
+ std::unique_ptr<Input::TouchDevice> touch_udp_device;
+ std::unique_ptr<Input::TouchDevice> touch_btn_device;
+ std::array<size_t, MAX_FINGERS> mouse_finger_id;
+ std::array<size_t, MAX_FINGERS> keyboard_finger_id;
+ std::array<size_t, MAX_FINGERS> udp_finger_id;
+ std::array<Finger, MAX_POINTS> fingers;
+ GestureProperties last_gesture;
};
} // namespace Service::HID