summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------externals/ffmpeg0
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp347
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h69
-rw-r--r--src/core/hle/service/ssl/ssl.cpp42
-rw-r--r--src/yuzu/configuration/configure_ui.cpp1
5 files changed, 381 insertions, 78 deletions
diff --git a/externals/ffmpeg b/externals/ffmpeg
Subproject 6b6b9e593dd4d3aaf75f48d40a13ef03bdef9fd Subproject 79e8d17024e6c6328a40fcee191ffd70798a9c6
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index bb77d8959..9e5df3bb7 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -1,10 +1,9 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring>
6#include "common/common_types.h"
7#include "common/logging/log.h" 5#include "common/logging/log.h"
6#include "common/math_util.h"
8#include "common/settings.h" 7#include "common/settings.h"
9#include "core/core_timing.h" 8#include "core/core_timing.h"
10#include "core/frontend/emu_window.h" 9#include "core/frontend/emu_window.h"
@@ -12,10 +11,19 @@
12 11
13namespace Service::HID { 12namespace Service::HID {
14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; 13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
15constexpr f32 angle_threshold = 0.08f;
16constexpr f32 pinch_threshold = 100.0f;
17 14
18Controller_Gesture::Controller_Gesture(Core::System& system_) : ControllerBase{system_} {} 15// HW is around 700, value is set to 400 to make it easier to trigger with mouse
16constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s
17constexpr f32 angle_threshold = 0.015f; // Threshold in radians
18constexpr f32 pinch_threshold = 0.5f; // Threshold in pixels
19constexpr f32 press_delay = 0.5f; // Time in seconds
20constexpr f32 double_tap_delay = 0.35f; // Time in seconds
21
22constexpr f32 Square(s32 num) {
23 return static_cast<f32>(num * num);
24}
25
26Controller_Gesture::Controller_Gesture(Core::System& system) : ControllerBase(system) {}
19Controller_Gesture::~Controller_Gesture() = default; 27Controller_Gesture::~Controller_Gesture() = default;
20 28
21void Controller_Gesture::OnInit() { 29void Controller_Gesture::OnInit() {
@@ -24,6 +32,8 @@ void Controller_Gesture::OnInit() {
24 keyboard_finger_id[id] = MAX_POINTS; 32 keyboard_finger_id[id] = MAX_POINTS;
25 udp_finger_id[id] = MAX_POINTS; 33 udp_finger_id[id] = MAX_POINTS;
26 } 34 }
35 shared_memory.header.entry_count = 0;
36 force_update = true;
27} 37}
28 38
29void Controller_Gesture::OnRelease() {} 39void Controller_Gesture::OnRelease() {}
@@ -38,17 +48,23 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
38 shared_memory.header.last_entry_index = 0; 48 shared_memory.header.last_entry_index = 0;
39 return; 49 return;
40 } 50 }
41 shared_memory.header.entry_count = 16;
42 51
43 const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; 52 ReadTouchInput();
44 shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
45 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
46 53
47 cur_entry.sampling_number = last_entry.sampling_number + 1; 54 GestureProperties gesture = GetGestureProperties();
48 cur_entry.sampling_number2 = cur_entry.sampling_number; 55 f32 time_difference = static_cast<f32>(shared_memory.header.timestamp - last_update_timestamp) /
56 (1000 * 1000 * 1000);
49 57
50 // TODO(german77): Implement all gesture types 58 // Only update if necesary
59 if (!ShouldUpdateGesture(gesture, time_difference)) {
60 return;
61 }
51 62
63 last_update_timestamp = shared_memory.header.timestamp;
64 UpdateGestureSharedMemory(data, size, gesture, time_difference);
65}
66
67void Controller_Gesture::ReadTouchInput() {
52 const Input::TouchStatus& mouse_status = touch_mouse_device->GetStatus(); 68 const Input::TouchStatus& mouse_status = touch_mouse_device->GetStatus();
53 const Input::TouchStatus& udp_status = touch_udp_device->GetStatus(); 69 const Input::TouchStatus& udp_status = touch_udp_device->GetStatus();
54 for (std::size_t id = 0; id < mouse_status.size(); ++id) { 70 for (std::size_t id = 0; id < mouse_status.size(); ++id) {
@@ -63,50 +79,71 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
63 UpdateTouchInputEvent(keyboard_status[id], keyboard_finger_id[id]); 79 UpdateTouchInputEvent(keyboard_status[id], keyboard_finger_id[id]);
64 } 80 }
65 } 81 }
82}
66 83
67 TouchType type = TouchType::Idle; 84bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
68 Attribute attributes{}; 85 f32 time_difference) {
69 GestureProperties gesture = GetGestureProperties(); 86 const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
70 if (last_gesture.active_points != gesture.active_points) { 87 if (force_update) {
71 ++last_gesture.detection_count; 88 force_update = false;
89 return true;
72 } 90 }
73 if (gesture.active_points > 0) {
74 if (last_gesture.active_points == 0) {
75 attributes.is_new_touch.Assign(true);
76 last_gesture.average_distance = gesture.average_distance;
77 last_gesture.angle = gesture.angle;
78 }
79 91
80 type = TouchType::Touch; 92 // Update if coordinates change
81 if (gesture.mid_point.x != last_entry.x || gesture.mid_point.y != last_entry.y) { 93 for (size_t id = 0; id < MAX_POINTS; id++) {
82 type = TouchType::Pan; 94 if (gesture.points[id].x != last_gesture.points[id].x ||
83 } 95 gesture.points[id].y != last_gesture.points[id].y) {
84 if (std::abs(gesture.average_distance - last_gesture.average_distance) > pinch_threshold) { 96 return true;
85 type = TouchType::Pinch;
86 }
87 if (std::abs(gesture.angle - last_gesture.angle) > angle_threshold) {
88 type = TouchType::Rotate;
89 } 97 }
98 }
99
100 // Update on press and hold event after 0.5 seconds
101 if (last_entry.type == TouchType::Touch && last_entry.point_count == 1 &&
102 time_difference > press_delay) {
103 return enable_press_and_tap;
104 }
105
106 return false;
107}
108
109void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
110 GestureProperties& gesture,
111 f32 time_difference) {
112 TouchType type = TouchType::Idle;
113 Attribute attributes{};
114
115 const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
116 shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
117 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
90 118
91 cur_entry.delta_x = gesture.mid_point.x - last_entry.x; 119 if (shared_memory.header.entry_count < 16) {
92 cur_entry.delta_y = gesture.mid_point.y - last_entry.y; 120 shared_memory.header.entry_count++;
93 // TODO: Find how velocities are calculated 121 }
94 cur_entry.vel_x = static_cast<float>(cur_entry.delta_x) * 150.1f;
95 cur_entry.vel_y = static_cast<float>(cur_entry.delta_y) * 150.1f;
96 122
97 // Slowdown the rate of change for less flapping 123 cur_entry.sampling_number = last_entry.sampling_number + 1;
98 last_gesture.average_distance = 124 cur_entry.sampling_number2 = cur_entry.sampling_number;
99 (last_gesture.average_distance * 0.9f) + (gesture.average_distance * 0.1f);
100 last_gesture.angle = (last_gesture.angle * 0.9f) + (gesture.angle * 0.1f);
101 125
126 // Reset values to default
127 cur_entry.delta_x = 0;
128 cur_entry.delta_y = 0;
129 cur_entry.vel_x = 0;
130 cur_entry.vel_y = 0;
131 cur_entry.direction = Direction::None;
132 cur_entry.rotation_angle = 0;
133 cur_entry.scale = 0;
134
135 if (gesture.active_points > 0) {
136 if (last_gesture.active_points == 0) {
137 NewGesture(gesture, type, attributes);
138 } else {
139 UpdateExistingGesture(gesture, type, time_difference);
140 }
102 } else { 141 } else {
103 cur_entry.delta_x = 0; 142 EndGesture(gesture, last_gesture, type, attributes, time_difference);
104 cur_entry.delta_y = 0;
105 cur_entry.vel_x = 0;
106 cur_entry.vel_y = 0;
107 } 143 }
108 last_gesture.active_points = gesture.active_points; 144
109 cur_entry.detection_count = last_gesture.detection_count; 145 // Apply attributes
146 cur_entry.detection_count = gesture.detection_count;
110 cur_entry.type = type; 147 cur_entry.type = type;
111 cur_entry.attributes = attributes; 148 cur_entry.attributes = attributes;
112 cur_entry.x = gesture.mid_point.x; 149 cur_entry.x = gesture.mid_point.x;
@@ -116,12 +153,190 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
116 cur_entry.points[id].x = gesture.points[id].x; 153 cur_entry.points[id].x = gesture.points[id].x;
117 cur_entry.points[id].y = gesture.points[id].y; 154 cur_entry.points[id].y = gesture.points[id].y;
118 } 155 }
119 cur_entry.rotation_angle = 0; 156 last_gesture = gesture;
120 cur_entry.scale = 0;
121 157
122 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); 158 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
123} 159}
124 160
161void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type,
162 Attribute& attributes) {
163 const auto& last_entry =
164 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
165 gesture.detection_count++;
166 type = TouchType::Touch;
167
168 // New touch after cancel is not considered new
169 if (last_entry.type != TouchType::Cancel) {
170 attributes.is_new_touch.Assign(1);
171 enable_press_and_tap = true;
172 }
173}
174
175void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, TouchType& type,
176 f32 time_difference) {
177 const auto& last_entry =
178 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
179
180 // Promote to pan type if touch moved
181 for (size_t id = 0; id < MAX_POINTS; id++) {
182 if (gesture.points[id].x != last_gesture.points[id].x ||
183 gesture.points[id].y != last_gesture.points[id].y) {
184 type = TouchType::Pan;
185 break;
186 }
187 }
188
189 // Number of fingers changed cancel the last event and clear data
190 if (gesture.active_points != last_gesture.active_points) {
191 type = TouchType::Cancel;
192 enable_press_and_tap = false;
193 gesture.active_points = 0;
194 gesture.mid_point = {};
195 for (size_t id = 0; id < MAX_POINTS; id++) {
196 gesture.points[id].x = 0;
197 gesture.points[id].y = 0;
198 }
199 return;
200 }
201
202 // Calculate extra parameters of panning
203 if (type == TouchType::Pan) {
204 UpdatePanEvent(gesture, last_gesture, type, time_difference);
205 return;
206 }
207
208 // Promote to press type
209 if (last_entry.type == TouchType::Touch) {
210 type = TouchType::Press;
211 }
212}
213
214void Controller_Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture,
215 TouchType& type, Attribute& attributes, f32 time_difference) {
216 const auto& last_entry =
217 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
218 if (last_gesture.active_points != 0) {
219 switch (last_entry.type) {
220 case TouchType::Touch:
221 if (enable_press_and_tap) {
222 SetTapEvent(gesture, last_gesture, type, attributes);
223 return;
224 }
225 type = TouchType::Cancel;
226 force_update = true;
227 break;
228 case TouchType::Press:
229 case TouchType::Tap:
230 case TouchType::Swipe:
231 case TouchType::Pinch:
232 case TouchType::Rotate:
233 type = TouchType::Complete;
234 force_update = true;
235 break;
236 case TouchType::Pan:
237 EndPanEvent(gesture, last_gesture, type, time_difference);
238 break;
239 default:
240 break;
241 }
242 return;
243 }
244 if (last_entry.type == TouchType::Complete || last_entry.type == TouchType::Cancel) {
245 gesture.detection_count++;
246 }
247}
248
249void Controller_Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture,
250 TouchType& type, Attribute& attributes) {
251 type = TouchType::Tap;
252 gesture = last_gesture;
253 force_update = true;
254 f32 tap_time_difference =
255 static_cast<f32>(last_update_timestamp - last_tap_timestamp) / (1000 * 1000 * 1000);
256 last_tap_timestamp = last_update_timestamp;
257 if (tap_time_difference < double_tap_delay) {
258 attributes.is_double_tap.Assign(1);
259 }
260}
261
262void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture,
263 TouchType& type, f32 time_difference) {
264 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
265 const auto& last_entry =
266 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
267 cur_entry.delta_x = gesture.mid_point.x - last_entry.x;
268 cur_entry.delta_y = gesture.mid_point.y - last_entry.y;
269
270 cur_entry.vel_x = static_cast<f32>(cur_entry.delta_x) / time_difference;
271 cur_entry.vel_y = static_cast<f32>(cur_entry.delta_y) / time_difference;
272 last_pan_time_difference = time_difference;
273
274 // Promote to pinch type
275 if (std::abs(gesture.average_distance - last_gesture.average_distance) > pinch_threshold) {
276 type = TouchType::Pinch;
277 cur_entry.scale = gesture.average_distance / last_gesture.average_distance;
278 }
279
280 const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture.angle) /
281 (1 + (gesture.angle * last_gesture.angle)));
282 // Promote to rotate type
283 if (std::abs(angle_between_two_lines) > angle_threshold) {
284 type = TouchType::Rotate;
285 cur_entry.scale = 0;
286 cur_entry.rotation_angle = angle_between_two_lines * 180.0f / Common::PI;
287 }
288}
289
290void Controller_Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture,
291 TouchType& type, f32 time_difference) {
292 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
293 const auto& last_entry =
294 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
295 cur_entry.vel_x =
296 static_cast<f32>(last_entry.delta_x) / (last_pan_time_difference + time_difference);
297 cur_entry.vel_y =
298 static_cast<f32>(last_entry.delta_y) / (last_pan_time_difference + time_difference);
299 const f32 curr_vel =
300 std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y));
301
302 // Set swipe event with parameters
303 if (curr_vel > swipe_threshold) {
304 SetSwipeEvent(gesture, last_gesture, type);
305 return;
306 }
307
308 // End panning without swipe
309 type = TouchType::Complete;
310 cur_entry.vel_x = 0;
311 cur_entry.vel_y = 0;
312 force_update = true;
313}
314
315void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture,
316 TouchType& type) {
317 auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
318 const auto& last_entry =
319 shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
320 type = TouchType::Swipe;
321 gesture = last_gesture;
322 force_update = true;
323 cur_entry.delta_x = last_entry.delta_x;
324 cur_entry.delta_y = last_entry.delta_y;
325 if (std::abs(cur_entry.delta_x) > std::abs(cur_entry.delta_y)) {
326 if (cur_entry.delta_x > 0) {
327 cur_entry.direction = Direction::Right;
328 return;
329 }
330 cur_entry.direction = Direction::Left;
331 return;
332 }
333 if (cur_entry.delta_y > 0) {
334 cur_entry.direction = Direction::Down;
335 return;
336 }
337 cur_entry.direction = Direction::Up;
338}
339
125void Controller_Gesture::OnLoadInputDevices() { 340void Controller_Gesture::OnLoadInputDevices() {
126 touch_mouse_device = Input::CreateDevice<Input::TouchDevice>("engine:emu_window"); 341 touch_mouse_device = Input::CreateDevice<Input::TouchDevice>("engine:emu_window");
127 touch_udp_device = Input::CreateDevice<Input::TouchDevice>("engine:cemuhookudp"); 342 touch_udp_device = Input::CreateDevice<Input::TouchDevice>("engine:cemuhookudp");
@@ -183,23 +398,33 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties()
183 398
184 for (size_t id = 0; id < gesture.active_points; ++id) { 399 for (size_t id = 0; id < gesture.active_points; ++id) {
185 gesture.points[id].x = 400 gesture.points[id].x =
186 static_cast<int>(active_fingers[id].x * Layout::ScreenUndocked::Width); 401 static_cast<s32>(active_fingers[id].x * Layout::ScreenUndocked::Width);
187 gesture.points[id].y = 402 gesture.points[id].y =
188 static_cast<int>(active_fingers[id].y * Layout::ScreenUndocked::Height); 403 static_cast<s32>(active_fingers[id].y * Layout::ScreenUndocked::Height);
189 gesture.mid_point.x += static_cast<int>(gesture.points[id].x / gesture.active_points); 404
190 gesture.mid_point.y += static_cast<int>(gesture.points[id].y / gesture.active_points); 405 // Hack: There is no touch in docked but games still allow it
406 if (Settings::values.use_docked_mode.GetValue()) {
407 gesture.points[id].x =
408 static_cast<s32>(active_fingers[id].x * Layout::ScreenDocked::Width);
409 gesture.points[id].y =
410 static_cast<s32>(active_fingers[id].y * Layout::ScreenDocked::Height);
411 }
412
413 gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points);
414 gesture.mid_point.y += static_cast<s32>(gesture.points[id].y / gesture.active_points);
191 } 415 }
192 416
193 for (size_t id = 0; id < gesture.active_points; ++id) { 417 for (size_t id = 0; id < gesture.active_points; ++id) {
194 const double distance = 418 const f32 distance = std::sqrt(Square(gesture.mid_point.x - gesture.points[id].x) +
195 std::pow(static_cast<float>(gesture.mid_point.x - gesture.points[id].x), 2) + 419 Square(gesture.mid_point.y - gesture.points[id].y));
196 std::pow(static_cast<float>(gesture.mid_point.y - gesture.points[id].y), 2); 420 gesture.average_distance += distance / static_cast<f32>(gesture.active_points);
197 gesture.average_distance +=
198 static_cast<float>(distance) / static_cast<float>(gesture.active_points);
199 } 421 }
200 422
201 gesture.angle = std::atan2(static_cast<float>(gesture.mid_point.y - gesture.points[0].y), 423 gesture.angle = std::atan2(static_cast<f32>(gesture.mid_point.y - gesture.points[0].y),
202 static_cast<float>(gesture.mid_point.x - gesture.points[0].x)); 424 static_cast<f32>(gesture.mid_point.x - gesture.points[0].x));
425
426 gesture.detection_count = last_gesture.detection_count;
427
203 return gesture; 428 return gesture;
204} 429}
205 430
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 7c357b977..18110a6ad 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -1,4 +1,4 @@
1// Copyright 2018 yuzu emulator team 1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
@@ -7,7 +7,6 @@
7#include <array> 7#include <array>
8#include "common/bit_field.h" 8#include "common/bit_field.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/swap.h"
11#include "core/frontend/input.h" 10#include "core/frontend/input.h"
12#include "core/hle/service/hid/controllers/controller_base.h" 11#include "core/hle/service/hid/controllers/controller_base.h"
13 12
@@ -35,10 +34,10 @@ private:
35 34
36 enum class TouchType : u32 { 35 enum class TouchType : u32 {
37 Idle, // Nothing touching the screen 36 Idle, // Nothing touching the screen
38 Complete, // Unknown. End of touch? 37 Complete, // Set at the end of a touch event
39 Cancel, // Never triggered 38 Cancel, // Set when the number of fingers change
40 Touch, // Pressing without movement 39 Touch, // A finger just touched the screen
41 Press, // Never triggered 40 Press, // Set if last type is touch and the finger hasn't moved
42 Tap, // Fast press then release 41 Tap, // Fast press then release
43 Pan, // All points moving together across the screen 42 Pan, // All points moving together across the screen
44 Swipe, // Fast press movement and release of a single point 43 Swipe, // Fast press movement and release of a single point
@@ -58,8 +57,8 @@ private:
58 union { 57 union {
59 u32_le raw{}; 58 u32_le raw{};
60 59
61 BitField<0, 1, u32> is_new_touch; 60 BitField<4, 1, u32> is_new_touch;
62 BitField<1, 1, u32> is_double_tap; 61 BitField<8, 1, u32> is_double_tap;
63 }; 62 };
64 }; 63 };
65 static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size"); 64 static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size");
@@ -73,10 +72,9 @@ private:
73 struct GestureState { 72 struct GestureState {
74 s64_le sampling_number; 73 s64_le sampling_number;
75 s64_le sampling_number2; 74 s64_le sampling_number2;
76
77 s64_le detection_count; 75 s64_le detection_count;
78 TouchType type; 76 TouchType type;
79 Direction dir; 77 Direction direction;
80 s32_le x; 78 s32_le x;
81 s32_le y; 79 s32_le y;
82 s32_le delta_x; 80 s32_le delta_x;
@@ -84,8 +82,8 @@ private:
84 f32 vel_x; 82 f32 vel_x;
85 f32 vel_y; 83 f32 vel_y;
86 Attribute attributes; 84 Attribute attributes;
87 u32 scale; 85 f32 scale;
88 u32 rotation_angle; 86 f32 rotation_angle;
89 s32_le point_count; 87 s32_le point_count;
90 std::array<Points, 4> points; 88 std::array<Points, 4> points;
91 }; 89 };
@@ -109,10 +107,46 @@ private:
109 Points mid_point{}; 107 Points mid_point{};
110 s64_le detection_count{}; 108 s64_le detection_count{};
111 u64_le delta_time{}; 109 u64_le delta_time{};
112 float average_distance{}; 110 f32 average_distance{};
113 float angle{}; 111 f32 angle{};
114 }; 112 };
115 113
114 // Reads input from all available input engines
115 void ReadTouchInput();
116
117 // Returns true if gesture state needs to be updated
118 bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference);
119
120 // Updates the shared memory to the next state
121 void UpdateGestureSharedMemory(u8* data, std::size_t size, GestureProperties& gesture,
122 f32 time_difference);
123
124 // Initializes new gesture
125 void NewGesture(GestureProperties& gesture, TouchType& type, Attribute& attributes);
126
127 // Updates existing gesture state
128 void UpdateExistingGesture(GestureProperties& gesture, TouchType& type, f32 time_difference);
129
130 // Terminates exiting gesture
131 void EndGesture(GestureProperties& gesture, GestureProperties& last_gesture, TouchType& type,
132 Attribute& attributes, f32 time_difference);
133
134 // Set current event to a tap event
135 void SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture, TouchType& type,
136 Attribute& attributes);
137
138 // Calculates and set the extra parameters related to a pan event
139 void UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture,
140 TouchType& type, f32 time_difference);
141
142 // Terminates the pan event
143 void EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture, TouchType& type,
144 f32 time_difference);
145
146 // Set current event to a swipe event
147 void SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture,
148 TouchType& type);
149
116 // Returns an unused finger id, if there is no fingers avaliable MAX_FINGERS will be returned 150 // Returns an unused finger id, if there is no fingers avaliable MAX_FINGERS will be returned
117 std::optional<size_t> GetUnusedFingerID() const; 151 std::optional<size_t> GetUnusedFingerID() const;
118 152
@@ -134,6 +168,11 @@ private:
134 std::array<size_t, MAX_FINGERS> keyboard_finger_id; 168 std::array<size_t, MAX_FINGERS> keyboard_finger_id;
135 std::array<size_t, MAX_FINGERS> udp_finger_id; 169 std::array<size_t, MAX_FINGERS> udp_finger_id;
136 std::array<Finger, MAX_POINTS> fingers; 170 std::array<Finger, MAX_POINTS> fingers;
137 GestureProperties last_gesture; 171 GestureProperties last_gesture{};
172 s64_le last_update_timestamp{};
173 s64_le last_tap_timestamp{};
174 f32 last_pan_time_difference{};
175 bool force_update{false};
176 bool enable_press_and_tap{false};
138}; 177};
139} // namespace Service::HID 178} // namespace Service::HID
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index dc2baca4a..2c8899ae0 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -10,6 +10,11 @@
10 10
11namespace Service::SSL { 11namespace Service::SSL {
12 12
13enum class CertificateFormat : u32 {
14 Pem = 1,
15 Der = 2,
16};
17
13class ISslConnection final : public ServiceFramework<ISslConnection> { 18class ISslConnection final : public ServiceFramework<ISslConnection> {
14public: 19public:
15 explicit ISslConnection(Core::System& system_) : ServiceFramework{system_, "ISslConnection"} { 20 explicit ISslConnection(Core::System& system_) : ServiceFramework{system_, "ISslConnection"} {
@@ -58,8 +63,8 @@ public:
58 {1, nullptr, "GetOption"}, 63 {1, nullptr, "GetOption"},
59 {2, &ISslContext::CreateConnection, "CreateConnection"}, 64 {2, &ISslContext::CreateConnection, "CreateConnection"},
60 {3, nullptr, "GetConnectionCount"}, 65 {3, nullptr, "GetConnectionCount"},
61 {4, nullptr, "ImportServerPki"}, 66 {4, &ISslContext::ImportServerPki, "ImportServerPki"},
62 {5, nullptr, "ImportClientPki"}, 67 {5, &ISslContext::ImportClientPki, "ImportClientPki"},
63 {6, nullptr, "RemoveServerPki"}, 68 {6, nullptr, "RemoveServerPki"},
64 {7, nullptr, "RemoveClientPki"}, 69 {7, nullptr, "RemoveClientPki"},
65 {8, nullptr, "RegisterInternalPki"}, 70 {8, nullptr, "RegisterInternalPki"},
@@ -94,6 +99,39 @@ private:
94 rb.Push(RESULT_SUCCESS); 99 rb.Push(RESULT_SUCCESS);
95 rb.PushIpcInterface<ISslConnection>(system); 100 rb.PushIpcInterface<ISslConnection>(system);
96 } 101 }
102
103 void ImportServerPki(Kernel::HLERequestContext& ctx) {
104 IPC::RequestParser rp{ctx};
105 const auto certificate_format = rp.PopEnum<CertificateFormat>();
106 const auto pkcs_12_certificates = ctx.ReadBuffer(0);
107
108 constexpr u64 server_id = 0;
109
110 LOG_WARNING(Service_SSL, "(STUBBED) called, certificate_format={}", certificate_format);
111
112 IPC::ResponseBuilder rb{ctx, 4};
113 rb.Push(RESULT_SUCCESS);
114 rb.Push(server_id);
115 }
116
117 void ImportClientPki(Kernel::HLERequestContext& ctx) {
118 const auto pkcs_12_certificate = ctx.ReadBuffer(0);
119 const auto ascii_password = [&ctx] {
120 if (ctx.CanReadBuffer(1)) {
121 return ctx.ReadBuffer(1);
122 }
123
124 return std::vector<u8>{};
125 }();
126
127 constexpr u64 client_id = 0;
128
129 LOG_WARNING(Service_SSL, "(STUBBED) called");
130
131 IPC::ResponseBuilder rb{ctx, 2};
132 rb.Push(RESULT_SUCCESS);
133 rb.Push(client_id);
134 }
97}; 135};
98 136
99class SSL final : public ServiceFramework<SSL> { 137class SSL final : public ServiceFramework<SSL> {
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index f35c89e04..0cdaea8a4 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -46,6 +46,7 @@ ConfigureUi::ConfigureUi(QWidget* parent) : QWidget(parent), ui(new Ui::Configur
46 SetConfiguration(); 46 SetConfiguration();
47 47
48 // Force game list reload if any of the relevant settings are changed. 48 // Force game list reload if any of the relevant settings are changed.
49 connect(ui->show_add_ons, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate);
49 connect(ui->icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 50 connect(ui->icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
50 &ConfigureUi::RequestGameListUpdate); 51 &ConfigureUi::RequestGameListUpdate);
51 connect(ui->row_1_text_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, 52 connect(ui->row_1_text_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,