summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar german772021-11-13 23:25:45 -0600
committerGravatar Narr the Reg2021-11-24 20:30:28 -0600
commitb673857d7dfc72f38d9242b315cd590b859795ff (patch)
tree8dbb0823ddfdb827eec99f9f05c678a9d15d6631 /src/core
parentcore/hid: Fix keyboard alignment (diff)
downloadyuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.gz
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.tar.xz
yuzu-b673857d7dfc72f38d9242b315cd590b859795ff.zip
core/hid: Improve accuracy of the keyboard implementation
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hid/emulated_devices.cpp3
-rw-r--r--src/core/hid/hid_types.h398
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp1
-rw-r--r--src/core/hle/service/hid/hid.cpp35
-rw-r--r--src/core/hle/service/hid/hid.h2
5 files changed, 303 insertions, 136 deletions
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index e97470240..0d840a003 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -170,13 +170,14 @@ void EmulatedDevices::SetKeyboardButton(Common::Input::CallbackStatus callback,
170 return; 170 return;
171 } 171 }
172 172
173 // Index should be converted from NativeKeyboard to KeyboardKeyIndex
173 UpdateKey(index, current_status.value); 174 UpdateKey(index, current_status.value);
174 175
175 TriggerOnChange(DeviceTriggerType::Keyboard); 176 TriggerOnChange(DeviceTriggerType::Keyboard);
176} 177}
177 178
178void EmulatedDevices::UpdateKey(std::size_t key_index, bool status) { 179void EmulatedDevices::UpdateKey(std::size_t key_index, bool status) {
179 constexpr u8 KEYS_PER_BYTE = 8; 180 constexpr std::size_t KEYS_PER_BYTE = 8;
180 auto& entry = device_status.keyboard_state.key[key_index / KEYS_PER_BYTE]; 181 auto& entry = device_status.keyboard_state.key[key_index / KEYS_PER_BYTE];
181 const u8 mask = static_cast<u8>(1 << (key_index % KEYS_PER_BYTE)); 182 const u8 mask = static_cast<u8>(1 << (key_index % KEYS_PER_BYTE));
182 if (status) { 183 if (status) {
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 41bc65ce2..af95f3aff 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -12,6 +12,195 @@
12 12
13namespace Core::HID { 13namespace Core::HID {
14 14
15enum class DeviceIndex : u8 {
16 Left = 0,
17 Right = 1,
18 None = 2,
19 MaxDeviceIndex = 3,
20};
21
22// This is nn::hid::NpadButton
23enum class NpadButton : u64 {
24 None = 0,
25 A = 1U << 0,
26 B = 1U << 1,
27 X = 1U << 2,
28 Y = 1U << 3,
29 StickL = 1U << 4,
30 StickR = 1U << 5,
31 L = 1U << 6,
32 R = 1U << 7,
33 ZL = 1U << 8,
34 ZR = 1U << 9,
35 Plus = 1U << 10,
36 Minus = 1U << 11,
37
38 Left = 1U << 12,
39 Up = 1U << 13,
40 Right = 1U << 14,
41 Down = 1U << 15,
42
43 StickLLeft = 1U << 16,
44 StickLUp = 1U << 17,
45 StickLRight = 1U << 18,
46 StickLDown = 1U << 19,
47
48 StickRLeft = 1U << 20,
49 StickRUp = 1U << 21,
50 StickRRight = 1U << 22,
51 StickRDown = 1U << 23,
52
53 LeftSL = 1U << 24,
54 LeftSR = 1U << 25,
55
56 RightSL = 1U << 26,
57 RightSR = 1U << 27,
58
59 Palma = 1U << 28,
60 Verification = 1U << 29,
61 HandheldLeftB = 1U << 30,
62 LagonCLeft = 1U << 31,
63 LagonCUp = 1ULL << 32,
64 LagonCRight = 1ULL << 33,
65 LagonCDown = 1ULL << 34,
66};
67DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
68
69enum class KeyboardKeyIndex : u32 {
70 A = 4,
71 B = 5,
72 C = 6,
73 D = 7,
74 E = 8,
75 F = 9,
76 G = 10,
77 H = 11,
78 I = 12,
79 J = 13,
80 K = 14,
81 L = 15,
82 M = 16,
83 N = 17,
84 O = 18,
85 P = 19,
86 Q = 20,
87 R = 21,
88 S = 22,
89 T = 23,
90 U = 24,
91 V = 25,
92 W = 26,
93 X = 27,
94 Y = 28,
95 Z = 29,
96 D1 = 30,
97 D2 = 31,
98 D3 = 32,
99 D4 = 33,
100 D5 = 34,
101 D6 = 35,
102 D7 = 36,
103 D8 = 37,
104 D9 = 38,
105 D0 = 39,
106 Return = 40,
107 Escape = 41,
108 Backspace = 42,
109 Tab = 43,
110 Space = 44,
111 Minus = 45,
112 Plus = 46,
113 OpenBracket = 47,
114 CloseBracket = 48,
115 Pipe = 49,
116 Tilde = 50,
117 Semicolon = 51,
118 Quote = 52,
119 Backquote = 53,
120 Comma = 54,
121 Period = 55,
122 Slash = 56,
123 CapsLock = 57,
124 F1 = 58,
125 F2 = 59,
126 F3 = 60,
127 F4 = 61,
128 F5 = 62,
129 F6 = 63,
130 F7 = 64,
131 F8 = 65,
132 F9 = 66,
133 F10 = 67,
134 F11 = 68,
135 F12 = 69,
136 PrintScreen = 70,
137 ScrollLock = 71,
138 Pause = 72,
139 Insert = 73,
140 Home = 74,
141 PageUp = 75,
142 Delete = 76,
143 End = 77,
144 PageDown = 78,
145 RightArrow = 79,
146 LeftArrow = 80,
147 DownArrow = 81,
148 UpArrow = 82,
149 NumLock = 83,
150 NumPadDivide = 84,
151 NumPadMultiply = 85,
152 NumPadSubtract = 86,
153 NumPadAdd = 87,
154 NumPadEnter = 88,
155 NumPad1 = 89,
156 NumPad2 = 90,
157 NumPad3 = 91,
158 NumPad4 = 92,
159 NumPad5 = 93,
160 NumPad6 = 94,
161 NumPad7 = 95,
162 NumPad8 = 96,
163 NumPad9 = 97,
164 NumPad0 = 98,
165 NumPadDot = 99,
166 Backslash = 100,
167 Application = 101,
168 Power = 102,
169 NumPadEquals = 103,
170 F13 = 104,
171 F14 = 105,
172 F15 = 106,
173 F16 = 107,
174 F17 = 108,
175 F18 = 109,
176 F19 = 110,
177 F20 = 111,
178 F21 = 112,
179 F22 = 113,
180 F23 = 114,
181 F24 = 115,
182 NumPadComma = 133,
183 Ro = 135,
184 KatakanaHiragana = 136,
185 Yen = 137,
186 Henkan = 138,
187 Muhenkan = 139,
188 NumPadCommaPc98 = 140,
189 HangulEnglish = 144,
190 Hanja = 145,
191 Katakana = 146,
192 Hiragana = 147,
193 ZenkakuHankaku = 148,
194 LeftControl = 224,
195 LeftShift = 225,
196 LeftAlt = 226,
197 LeftGui = 227,
198 RightControl = 228,
199 RightShift = 229,
200 RightAlt = 230,
201 RightGui = 231,
202};
203
15// This is nn::hid::NpadIdType 204// This is nn::hid::NpadIdType
16enum class NpadIdType : u32 { 205enum class NpadIdType : u32 {
17 Player1 = 0x0, 206 Player1 = 0x0,
@@ -28,62 +217,6 @@ enum class NpadIdType : u32 {
28 Invalid = 0xFFFFFFFF, 217 Invalid = 0xFFFFFFFF,
29}; 218};
30 219
31/// Converts a NpadIdType to an array index.
32constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
33 switch (npad_id_type) {
34 case NpadIdType::Player1:
35 return 0;
36 case NpadIdType::Player2:
37 return 1;
38 case NpadIdType::Player3:
39 return 2;
40 case NpadIdType::Player4:
41 return 3;
42 case NpadIdType::Player5:
43 return 4;
44 case NpadIdType::Player6:
45 return 5;
46 case NpadIdType::Player7:
47 return 6;
48 case NpadIdType::Player8:
49 return 7;
50 case NpadIdType::Handheld:
51 return 8;
52 case NpadIdType::Other:
53 return 9;
54 default:
55 return 0;
56 }
57}
58
59/// Converts an array index to a NpadIdType
60constexpr NpadIdType IndexToNpadIdType(size_t index) {
61 switch (index) {
62 case 0:
63 return NpadIdType::Player1;
64 case 1:
65 return NpadIdType::Player2;
66 case 2:
67 return NpadIdType::Player3;
68 case 3:
69 return NpadIdType::Player4;
70 case 4:
71 return NpadIdType::Player5;
72 case 5:
73 return NpadIdType::Player6;
74 case 6:
75 return NpadIdType::Player7;
76 case 7:
77 return NpadIdType::Player8;
78 case 8:
79 return NpadIdType::Handheld;
80 case 9:
81 return NpadIdType::Other;
82 default:
83 return NpadIdType::Invalid;
84 }
85}
86
87// This is nn::hid::NpadStyleIndex 220// This is nn::hid::NpadStyleIndex
88enum class NpadStyleIndex : u8 { 221enum class NpadStyleIndex : u8 {
89 None = 0, 222 None = 0,
@@ -124,6 +257,27 @@ enum class NpadStyleSet : u32 {
124}; 257};
125static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); 258static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
126 259
260// This is nn::hid::VibrationDevicePosition
261enum class VibrationDevicePosition : u32 {
262 None = 0,
263 Left = 1,
264 Right = 2,
265};
266
267// This is nn::hid::VibrationDeviceType
268enum class VibrationDeviceType : u32 {
269 Unknown = 0,
270 LinearResonantActuator = 1,
271 GcErm = 2,
272};
273
274// This is nn::hid::VibrationGcErmCommand
275enum class VibrationGcErmCommand : u64 {
276 Stop = 0,
277 Start = 1,
278 StopHard = 2,
279};
280
127// This is nn::hid::NpadStyleTag 281// This is nn::hid::NpadStyleTag
128struct NpadStyleTag { 282struct NpadStyleTag {
129 union { 283 union {
@@ -220,53 +374,6 @@ struct LedPattern {
220 }; 374 };
221}; 375};
222 376
223// This is nn::hid::NpadButton
224enum class NpadButton : u64 {
225 None = 0,
226 A = 1U << 0,
227 B = 1U << 1,
228 X = 1U << 2,
229 Y = 1U << 3,
230 StickL = 1U << 4,
231 StickR = 1U << 5,
232 L = 1U << 6,
233 R = 1U << 7,
234 ZL = 1U << 8,
235 ZR = 1U << 9,
236 Plus = 1U << 10,
237 Minus = 1U << 11,
238
239 Left = 1U << 12,
240 Up = 1U << 13,
241 Right = 1U << 14,
242 Down = 1U << 15,
243
244 StickLLeft = 1U << 16,
245 StickLUp = 1U << 17,
246 StickLRight = 1U << 18,
247 StickLDown = 1U << 19,
248
249 StickRLeft = 1U << 20,
250 StickRUp = 1U << 21,
251 StickRRight = 1U << 22,
252 StickRDown = 1U << 23,
253
254 LeftSL = 1U << 24,
255 LeftSR = 1U << 25,
256
257 RightSL = 1U << 26,
258 RightSR = 1U << 27,
259
260 Palma = 1U << 28,
261 Verification = 1U << 29,
262 HandheldLeftB = 1U << 30,
263 LagonCLeft = 1U << 31,
264 LagonCUp = 1ULL << 32,
265 LagonCRight = 1ULL << 33,
266 LagonCDown = 1ULL << 34,
267};
268DECLARE_ENUM_FLAG_OPERATORS(NpadButton);
269
270struct NpadButtonState { 377struct NpadButtonState {
271 union { 378 union {
272 NpadButton raw{}; 379 NpadButton raw{};
@@ -342,13 +449,6 @@ struct DebugPadButton {
342}; 449};
343static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size"); 450static_assert(sizeof(DebugPadButton) == 0x4, "DebugPadButton is an invalid size");
344 451
345enum class DeviceIndex : u8 {
346 Left = 0,
347 Right = 1,
348 None = 2,
349 MaxDeviceIndex = 3,
350};
351
352// This is nn::hid::ConsoleSixAxisSensorHandle 452// This is nn::hid::ConsoleSixAxisSensorHandle
353struct ConsoleSixAxisSensorHandle { 453struct ConsoleSixAxisSensorHandle {
354 u8 unknown_1; 454 u8 unknown_1;
@@ -383,20 +483,6 @@ struct VibrationDeviceHandle {
383}; 483};
384static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size"); 484static_assert(sizeof(VibrationDeviceHandle) == 4, "SixAxisSensorHandle is an invalid size");
385 485
386// This is nn::hid::VibrationDeviceType
387enum class VibrationDeviceType : u32 {
388 Unknown = 0,
389 LinearResonantActuator = 1,
390 GcErm = 2,
391};
392
393// This is nn::hid::VibrationDevicePosition
394enum class VibrationDevicePosition : u32 {
395 None = 0,
396 Left = 1,
397 Right = 2,
398};
399
400// This is nn::hid::VibrationValue 486// This is nn::hid::VibrationValue
401struct VibrationValue { 487struct VibrationValue {
402 f32 low_amplitude; 488 f32 low_amplitude;
@@ -406,13 +492,6 @@ struct VibrationValue {
406}; 492};
407static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size."); 493static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");
408 494
409// This is nn::hid::VibrationGcErmCommand
410enum class VibrationGcErmCommand : u64 {
411 Stop = 0,
412 Start = 1,
413 StopHard = 2,
414};
415
416// This is nn::hid::VibrationDeviceInfo 495// This is nn::hid::VibrationDeviceInfo
417struct VibrationDeviceInfo { 496struct VibrationDeviceInfo {
418 VibrationDeviceType type{}; 497 VibrationDeviceType type{};
@@ -482,4 +561,61 @@ struct MouseState {
482 MouseAttribute attribute; 561 MouseAttribute attribute;
483}; 562};
484static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size"); 563static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
564
565/// Converts a NpadIdType to an array index.
566constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
567 switch (npad_id_type) {
568 case NpadIdType::Player1:
569 return 0;
570 case NpadIdType::Player2:
571 return 1;
572 case NpadIdType::Player3:
573 return 2;
574 case NpadIdType::Player4:
575 return 3;
576 case NpadIdType::Player5:
577 return 4;
578 case NpadIdType::Player6:
579 return 5;
580 case NpadIdType::Player7:
581 return 6;
582 case NpadIdType::Player8:
583 return 7;
584 case NpadIdType::Handheld:
585 return 8;
586 case NpadIdType::Other:
587 return 9;
588 default:
589 return 0;
590 }
591}
592
593/// Converts an array index to a NpadIdType
594constexpr NpadIdType IndexToNpadIdType(size_t index) {
595 switch (index) {
596 case 0:
597 return NpadIdType::Player1;
598 case 1:
599 return NpadIdType::Player2;
600 case 2:
601 return NpadIdType::Player3;
602 case 3:
603 return NpadIdType::Player4;
604 case 4:
605 return NpadIdType::Player5;
606 case 5:
607 return NpadIdType::Player6;
608 case 6:
609 return NpadIdType::Player7;
610 case 7:
611 return NpadIdType::Player8;
612 case 8:
613 return NpadIdType::Handheld;
614 case 9:
615 return NpadIdType::Other;
616 default:
617 return NpadIdType::Invalid;
618 }
619}
620
485} // namespace Core::HID 621} // namespace Core::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index d6505dbc5..0ef8af0e6 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -42,6 +42,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
42 42
43 next_state.key = keyboard_state; 43 next_state.key = keyboard_state;
44 next_state.modifier = keyboard_modifier_state; 44 next_state.modifier = keyboard_modifier_state;
45 // This is always enabled on HW. Check what it actually does
45 next_state.modifier.unknown.Assign(1); 46 next_state.modifier.unknown.Assign(1);
46 } 47 }
47 48
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 496b55d0e..e740b4331 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -35,8 +35,9 @@ namespace Service::HID {
35 35
36// Updating period for each HID device. 36// Updating period for each HID device.
37// Period time is obtained by measuring the number of samples in a second on HW using a homebrew 37// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
38constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz) 38constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
39constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) 39constexpr auto keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
40constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
40constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 41constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
41 42
42IAppletResource::IAppletResource(Core::System& system_, 43IAppletResource::IAppletResource(Core::System& system_,
@@ -78,14 +79,21 @@ IAppletResource::IAppletResource(Core::System& system_,
78 const auto guard = LockService(); 79 const auto guard = LockService();
79 UpdateControllers(user_data, ns_late); 80 UpdateControllers(user_data, ns_late);
80 }); 81 });
82 keyboard_update_event = Core::Timing::CreateEvent(
83 "HID::UpdatekeyboardCallback",
84 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
85 const auto guard = LockService();
86 UpdateKeyboard(user_data, ns_late);
87 });
81 motion_update_event = Core::Timing::CreateEvent( 88 motion_update_event = Core::Timing::CreateEvent(
82 "HID::MotionPadCallback", 89 "HID::UpdateMotionCallback",
83 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 90 [this](std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
84 const auto guard = LockService(); 91 const auto guard = LockService();
85 UpdateMotion(user_data, ns_late); 92 UpdateMotion(user_data, ns_late);
86 }); 93 });
87 94
88 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event); 95 system.CoreTiming().ScheduleEvent(pad_update_ns, pad_update_event);
96 system.CoreTiming().ScheduleEvent(keyboard_update_ns, keyboard_update_event);
89 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event); 97 system.CoreTiming().ScheduleEvent(motion_update_ns, motion_update_event);
90 98
91 system.HIDCore().ReloadInputDevices(); 99 system.HIDCore().ReloadInputDevices();
@@ -101,6 +109,7 @@ void IAppletResource::DeactivateController(HidController controller) {
101 109
102IAppletResource::~IAppletResource() { 110IAppletResource::~IAppletResource() {
103 system.CoreTiming().UnscheduleEvent(pad_update_event, 0); 111 system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
112 system.CoreTiming().UnscheduleEvent(keyboard_update_event, 0);
104 system.CoreTiming().UnscheduleEvent(motion_update_event, 0); 113 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
105} 114}
106 115
@@ -117,18 +126,36 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
117 auto& core_timing = system.CoreTiming(); 126 auto& core_timing = system.CoreTiming();
118 127
119 for (const auto& controller : controllers) { 128 for (const auto& controller : controllers) {
129 // Keyboard has it's own update event
130 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
131 continue;
132 }
120 controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), 133 controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(),
121 SHARED_MEMORY_SIZE); 134 SHARED_MEMORY_SIZE);
122 } 135 }
123 136
124 // If ns_late is higher than the update rate ignore the delay 137 // If ns_late is higher than the update rate ignore the delay
125 if (ns_late > motion_update_ns) { 138 if (ns_late > pad_update_ns) {
126 ns_late = {}; 139 ns_late = {};
127 } 140 }
128 141
129 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); 142 core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event);
130} 143}
131 144
145void IAppletResource::UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
146 auto& core_timing = system.CoreTiming();
147
148 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
149 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
150
151 // If ns_late is higher than the update rate ignore the delay
152 if (ns_late > keyboard_update_ns) {
153 ns_late = {};
154 }
155
156 core_timing.ScheduleEvent(keyboard_update_ns - ns_late, keyboard_update_event);
157}
158
132void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 159void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
133 auto& core_timing = system.CoreTiming(); 160 auto& core_timing = system.CoreTiming();
134 161
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 973e6a8ac..bbad165f8 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -70,11 +70,13 @@ private:
70 70
71 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 71 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
72 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 72 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
73 void UpdateKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
73 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); 74 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
74 75
75 KernelHelpers::ServiceContext& service_context; 76 KernelHelpers::ServiceContext& service_context;
76 77
77 std::shared_ptr<Core::Timing::EventType> pad_update_event; 78 std::shared_ptr<Core::Timing::EventType> pad_update_event;
79 std::shared_ptr<Core::Timing::EventType> keyboard_update_event;
78 std::shared_ptr<Core::Timing::EventType> motion_update_event; 80 std::shared_ptr<Core::Timing::EventType> motion_update_event;
79 81
80 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)> 82 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>