summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar german772021-10-21 00:49:09 -0500
committerGravatar Narr the Reg2021-11-24 20:30:25 -0600
commit95cf66b6559c3e7a1eb40be919f16217566ffdbc (patch)
tree0219a3e9e5441bf696d38d693a5dba4bfa2e3672 /src
parentservice/hid: Fix gesture input (diff)
downloadyuzu-95cf66b6559c3e7a1eb40be919f16217566ffdbc.tar.gz
yuzu-95cf66b6559c3e7a1eb40be919f16217566ffdbc.tar.xz
yuzu-95cf66b6559c3e7a1eb40be919f16217566ffdbc.zip
service/hid: Use ring buffer for gestures
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp107
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h24
2 files changed, 52 insertions, 79 deletions
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index a26ce5383..a82d04b3b 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -31,7 +31,8 @@ Controller_Gesture::Controller_Gesture(Core::System& system_) : ControllerBase(s
31Controller_Gesture::~Controller_Gesture() = default; 31Controller_Gesture::~Controller_Gesture() = default;
32 32
33void Controller_Gesture::OnInit() { 33void Controller_Gesture::OnInit() {
34 shared_memory.header.entry_count = 0; 34 gesture_lifo.entry_count = 0;
35 gesture_lifo.last_entry_index = 0;
35 force_update = true; 36 force_update = true;
36} 37}
37 38
@@ -39,27 +40,25 @@ void Controller_Gesture::OnRelease() {}
39 40
40void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 41void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
41 std::size_t size) { 42 std::size_t size) {
42 shared_memory.header.timestamp = core_timing.GetCPUTicks();
43 shared_memory.header.total_entry_count = 17;
44
45 if (!IsControllerActivated()) { 43 if (!IsControllerActivated()) {
46 shared_memory.header.entry_count = 0; 44 gesture_lifo.entry_count = 0;
47 shared_memory.header.last_entry_index = 0; 45 gesture_lifo.last_entry_index = 0;
46 std::memcpy(data, &gesture_lifo, sizeof(gesture_lifo));
48 return; 47 return;
49 } 48 }
50 49
51 ReadTouchInput(); 50 ReadTouchInput();
52 51
53 GestureProperties gesture = GetGestureProperties(); 52 GestureProperties gesture = GetGestureProperties();
54 f32 time_difference = static_cast<f32>(shared_memory.header.timestamp - last_update_timestamp) / 53 f32 time_difference =
55 (1000 * 1000 * 1000); 54 static_cast<f32>(gesture_lifo.timestamp - last_update_timestamp) / (1000 * 1000 * 1000);
56 55
57 // Only update if necesary 56 // Only update if necesary
58 if (!ShouldUpdateGesture(gesture, time_difference)) { 57 if (!ShouldUpdateGesture(gesture, time_difference)) {
59 return; 58 return;
60 } 59 }
61 60
62 last_update_timestamp = shared_memory.header.timestamp; 61 last_update_timestamp = gesture_lifo.timestamp;
63 UpdateGestureSharedMemory(data, size, gesture, time_difference); 62 UpdateGestureSharedMemory(data, size, gesture, time_difference);
64} 63}
65 64
@@ -75,7 +74,7 @@ void Controller_Gesture::ReadTouchInput() {
75 74
76bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, 75bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
77 f32 time_difference) { 76 f32 time_difference) {
78 const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; 77 const auto& last_entry = GetLastGestureEntry();
79 if (force_update) { 78 if (force_update) {
80 force_update = false; 79 force_update = false;
81 return true; 80 return true;
@@ -103,24 +102,16 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
103 GestureType type = GestureType::Idle; 102 GestureType type = GestureType::Idle;
104 GestureAttribute attributes{}; 103 GestureAttribute attributes{};
105 104
106 const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; 105 const auto& last_entry = gesture_lifo.ReadCurrentEntry().state;
107 shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
108 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
109
110 if (shared_memory.header.entry_count < 16) {
111 shared_memory.header.entry_count++;
112 }
113 106
114 cur_entry.sampling_number = last_entry.sampling_number + 1; 107 // Reset next state to default
115 cur_entry.sampling_number2 = cur_entry.sampling_number; 108 next_state.sampling_number = last_entry.sampling_number + 1;
116 109 next_state.delta = {};
117 // Reset values to default 110 next_state.vel_x = 0;
118 cur_entry.delta = {}; 111 next_state.vel_y = 0;
119 cur_entry.vel_x = 0; 112 next_state.direction = GestureDirection::None;
120 cur_entry.vel_y = 0; 113 next_state.rotation_angle = 0;
121 cur_entry.direction = GestureDirection::None; 114 next_state.scale = 0;
122 cur_entry.rotation_angle = 0;
123 cur_entry.scale = 0;
124 115
125 if (gesture.active_points > 0) { 116 if (gesture.active_points > 0) {
126 if (last_gesture.active_points == 0) { 117 if (last_gesture.active_points == 0) {
@@ -133,15 +124,16 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
133 } 124 }
134 125
135 // Apply attributes 126 // Apply attributes
136 cur_entry.detection_count = gesture.detection_count; 127 next_state.detection_count = gesture.detection_count;
137 cur_entry.type = type; 128 next_state.type = type;
138 cur_entry.attributes = attributes; 129 next_state.attributes = attributes;
139 cur_entry.pos = gesture.mid_point; 130 next_state.pos = gesture.mid_point;
140 cur_entry.point_count = static_cast<s32>(gesture.active_points); 131 next_state.point_count = static_cast<s32>(gesture.active_points);
141 cur_entry.points = gesture.points; 132 next_state.points = gesture.points;
142 last_gesture = gesture; 133 last_gesture = gesture;
143 134
144 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); 135 gesture_lifo.WriteNextEntry(next_state);
136 std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
145} 137}
146 138
147void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, 139void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
@@ -245,19 +237,18 @@ void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
245void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, 237void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
246 GestureProperties& last_gesture_props, GestureType& type, 238 GestureProperties& last_gesture_props, GestureType& type,
247 f32 time_difference) { 239 f32 time_difference) {
248 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
249 const auto& last_entry = GetLastGestureEntry(); 240 const auto& last_entry = GetLastGestureEntry();
250 241
251 cur_entry.delta = gesture.mid_point - last_entry.pos; 242 next_state.delta = gesture.mid_point - last_entry.pos;
252 cur_entry.vel_x = static_cast<f32>(cur_entry.delta.x) / time_difference; 243 next_state.vel_x = static_cast<f32>(next_state.delta.x) / time_difference;
253 cur_entry.vel_y = static_cast<f32>(cur_entry.delta.y) / time_difference; 244 next_state.vel_y = static_cast<f32>(next_state.delta.y) / time_difference;
254 last_pan_time_difference = time_difference; 245 last_pan_time_difference = time_difference;
255 246
256 // Promote to pinch type 247 // Promote to pinch type
257 if (std::abs(gesture.average_distance - last_gesture_props.average_distance) > 248 if (std::abs(gesture.average_distance - last_gesture_props.average_distance) >
258 pinch_threshold) { 249 pinch_threshold) {
259 type = GestureType::Pinch; 250 type = GestureType::Pinch;
260 cur_entry.scale = gesture.average_distance / last_gesture_props.average_distance; 251 next_state.scale = gesture.average_distance / last_gesture_props.average_distance;
261 } 252 }
262 253
263 const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture_props.angle) / 254 const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture_props.angle) /
@@ -265,22 +256,21 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
265 // Promote to rotate type 256 // Promote to rotate type
266 if (std::abs(angle_between_two_lines) > angle_threshold) { 257 if (std::abs(angle_between_two_lines) > angle_threshold) {
267 type = GestureType::Rotate; 258 type = GestureType::Rotate;
268 cur_entry.scale = 0; 259 next_state.scale = 0;
269 cur_entry.rotation_angle = angle_between_two_lines * 180.0f / Common::PI; 260 next_state.rotation_angle = angle_between_two_lines * 180.0f / Common::PI;
270 } 261 }
271} 262}
272 263
273void Controller_Gesture::EndPanEvent(GestureProperties& gesture, 264void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
274 GestureProperties& last_gesture_props, GestureType& type, 265 GestureProperties& last_gesture_props, GestureType& type,
275 f32 time_difference) { 266 f32 time_difference) {
276 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
277 const auto& last_entry = GetLastGestureEntry(); 267 const auto& last_entry = GetLastGestureEntry();
278 cur_entry.vel_x = 268 next_state.vel_x =
279 static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); 269 static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference);
280 cur_entry.vel_y = 270 next_state.vel_y =
281 static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference); 271 static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference);
282 const f32 curr_vel = 272 const f32 curr_vel =
283 std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y)); 273 std::sqrt((next_state.vel_x * next_state.vel_x) + (next_state.vel_y * next_state.vel_y));
284 274
285 // Set swipe event with parameters 275 // Set swipe event with parameters
286 if (curr_vel > swipe_threshold) { 276 if (curr_vel > swipe_threshold) {
@@ -290,42 +280,37 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
290 280
291 // End panning without swipe 281 // End panning without swipe
292 type = GestureType::Complete; 282 type = GestureType::Complete;
293 cur_entry.vel_x = 0; 283 next_state.vel_x = 0;
294 cur_entry.vel_y = 0; 284 next_state.vel_y = 0;
295 force_update = true; 285 force_update = true;
296} 286}
297 287
298void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, 288void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
299 GestureProperties& last_gesture_props, GestureType& type) { 289 GestureProperties& last_gesture_props, GestureType& type) {
300 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
301 const auto& last_entry = GetLastGestureEntry(); 290 const auto& last_entry = GetLastGestureEntry();
302 291
303 type = GestureType::Swipe; 292 type = GestureType::Swipe;
304 gesture = last_gesture_props; 293 gesture = last_gesture_props;
305 force_update = true; 294 force_update = true;
306 cur_entry.delta = last_entry.delta; 295 next_state.delta = last_entry.delta;
307 296
308 if (std::abs(cur_entry.delta.x) > std::abs(cur_entry.delta.y)) { 297 if (std::abs(next_state.delta.x) > std::abs(next_state.delta.y)) {
309 if (cur_entry.delta.x > 0) { 298 if (next_state.delta.x > 0) {
310 cur_entry.direction = GestureDirection::Right; 299 next_state.direction = GestureDirection::Right;
311 return; 300 return;
312 } 301 }
313 cur_entry.direction = GestureDirection::Left; 302 next_state.direction = GestureDirection::Left;
314 return; 303 return;
315 } 304 }
316 if (cur_entry.delta.y > 0) { 305 if (next_state.delta.y > 0) {
317 cur_entry.direction = GestureDirection::Down; 306 next_state.direction = GestureDirection::Down;
318 return; 307 return;
319 } 308 }
320 cur_entry.direction = GestureDirection::Up; 309 next_state.direction = GestureDirection::Up;
321}
322
323Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() {
324 return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
325} 310}
326 311
327const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { 312const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
328 return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; 313 return gesture_lifo.ReadCurrentEntry().state;
329} 314}
330 315
331Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { 316Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 6128fb0ad..6f5abaa4f 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -71,7 +71,6 @@ private:
71 // This is nn::hid::GestureState 71 // This is nn::hid::GestureState
72 struct GestureState { 72 struct GestureState {
73 s64_le sampling_number; 73 s64_le sampling_number;
74 s64_le sampling_number2;
75 s64_le detection_count; 74 s64_le detection_count;
76 GestureType type; 75 GestureType type;
77 GestureDirection direction; 76 GestureDirection direction;
@@ -85,21 +84,7 @@ private:
85 s32_le point_count; 84 s32_le point_count;
86 std::array<Common::Point<s32_le>, 4> points; 85 std::array<Common::Point<s32_le>, 4> points;
87 }; 86 };
88 static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size"); 87 static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
89
90 struct CommonHeader {
91 s64_le timestamp;
92 s64_le total_entry_count;
93 s64_le last_entry_index;
94 s64_le entry_count;
95 };
96 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
97
98 struct SharedMemory {
99 CommonHeader header;
100 std::array<GestureState, 17> gesture_states;
101 };
102 static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size");
103 88
104 struct Finger { 89 struct Finger {
105 Common::Point<f32> pos{}; 90 Common::Point<f32> pos{};
@@ -153,13 +138,16 @@ private:
153 GestureType& type); 138 GestureType& type);
154 139
155 // Retrieves the last gesture entry, as indicated by shared memory indices. 140 // Retrieves the last gesture entry, as indicated by shared memory indices.
156 [[nodiscard]] GestureState& GetLastGestureEntry();
157 [[nodiscard]] const GestureState& GetLastGestureEntry() const; 141 [[nodiscard]] const GestureState& GetLastGestureEntry() const;
158 142
159 // Returns the average distance, angle and middle point of the active fingers 143 // Returns the average distance, angle and middle point of the active fingers
160 GestureProperties GetGestureProperties(); 144 GestureProperties GetGestureProperties();
161 145
162 SharedMemory shared_memory{}; 146 // This is nn::hid::detail::GestureLifo
147 Lifo<GestureState> gesture_lifo{};
148 static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
149 GestureState next_state{};
150
163 Core::HID::EmulatedConsole* console; 151 Core::HID::EmulatedConsole* console;
164 152
165 std::array<Finger, MAX_POINTS> fingers{}; 153 std::array<Finger, MAX_POINTS> fingers{};