summaryrefslogtreecommitdiff
path: root/src/hid_core/resource_manager.cpp
diff options
context:
space:
mode:
authorGravatar Narr the Reg2024-01-04 20:37:43 -0600
committerGravatar Narr the Reg2024-01-05 11:41:15 -0600
commitee847f8ff0b1b0aec39c1b78c010bc0c08a0a613 (patch)
tree3b95cbb74be05f0ce7a007353f1f9f95e1ed3901 /src/hid_core/resource_manager.cpp
parentMerge pull request #12437 from ameerj/gl-amd-fixes (diff)
downloadyuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.tar.gz
yuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.tar.xz
yuzu-ee847f8ff0b1b0aec39c1b78c010bc0c08a0a613.zip
hid_core: Move hid to it's own subproject
Diffstat (limited to 'src/hid_core/resource_manager.cpp')
-rw-r--r--src/hid_core/resource_manager.cpp362
1 files changed, 362 insertions, 0 deletions
diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp
new file mode 100644
index 000000000..17dacef6e
--- /dev/null
+++ b/src/hid_core/resource_manager.cpp
@@ -0,0 +1,362 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "common/logging/log.h"
5#include "core/core.h"
6#include "core/core_timing.h"
7#include "core/hle/kernel/k_shared_memory.h"
8#include "core/hle/service/ipc_helpers.h"
9#include "hid_core/hid_core.h"
10#include "hid_core/resource_manager.h"
11
12#include "hid_core/resources/applet_resource.h"
13#include "hid_core/resources/debug_pad/debug_pad.h"
14#include "hid_core/resources/digitizer/digitizer.h"
15#include "hid_core/resources/keyboard/keyboard.h"
16#include "hid_core/resources/mouse/debug_mouse.h"
17#include "hid_core/resources/mouse/mouse.h"
18#include "hid_core/resources/npad/npad.h"
19#include "hid_core/resources/palma/palma.h"
20#include "hid_core/resources/shared_memory_format.h"
21#include "hid_core/resources/six_axis/console_six_axis.h"
22#include "hid_core/resources/six_axis/seven_six_axis.h"
23#include "hid_core/resources/six_axis/six_axis.h"
24#include "hid_core/resources/system_buttons/capture_button.h"
25#include "hid_core/resources/system_buttons/home_button.h"
26#include "hid_core/resources/system_buttons/sleep_button.h"
27#include "hid_core/resources/touch_screen/gesture.h"
28#include "hid_core/resources/touch_screen/touch_screen.h"
29#include "hid_core/resources/unique_pad/unique_pad.h"
30
31namespace Service::HID {
32
33// Updating period for each HID device.
34// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
35// Correct npad_update_ns is 4ms this is overclocked to lower input lag
36constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
37constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
38constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
39constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
40
41ResourceManager::ResourceManager(Core::System& system_)
42 : system{system_}, service_context{system_, "hid"} {
43 applet_resource = std::make_shared<AppletResource>(system);
44}
45
46ResourceManager::~ResourceManager() = default;
47
48void ResourceManager::Initialize() {
49 if (is_initialized) {
50 return;
51 }
52
53 system.HIDCore().ReloadInputDevices();
54
55 InitializeHidCommonSampler();
56 InitializeTouchScreenSampler();
57 InitializeConsoleSixAxisSampler();
58 InitializeAHidSampler();
59
60 is_initialized = true;
61}
62
63std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
64 return applet_resource;
65}
66
67std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
68 return capture_button;
69}
70
71std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const {
72 return console_six_axis;
73}
74
75std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const {
76 return debug_mouse;
77}
78
79std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
80 return debug_pad;
81}
82
83std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const {
84 return digitizer;
85}
86
87std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
88 return gesture;
89}
90
91std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const {
92 return home_button;
93}
94
95std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const {
96 return keyboard;
97}
98
99std::shared_ptr<Mouse> ResourceManager::GetMouse() const {
100 return mouse;
101}
102
103std::shared_ptr<NPad> ResourceManager::GetNpad() const {
104 return npad;
105}
106
107std::shared_ptr<Palma> ResourceManager::GetPalma() const {
108 return palma;
109}
110
111std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const {
112 return seven_six_axis;
113}
114
115std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const {
116 return six_axis;
117}
118
119std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const {
120 return sleep_button;
121}
122
123std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const {
124 return touch_screen;
125}
126
127std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
128 return unique_pad;
129}
130
131Result ResourceManager::CreateAppletResource(u64 aruid) {
132 if (aruid == SystemAruid) {
133 const auto result = RegisterCoreAppletResource();
134 if (result.IsError()) {
135 return result;
136 }
137 return GetNpad()->ActivateNpadResource();
138 }
139
140 const auto result = CreateAppletResourceImpl(aruid);
141 if (result.IsError()) {
142 return result;
143 }
144
145 // Homebrew doesn't try to activate some controllers, so we activate them by default
146 npad->Activate();
147 six_axis->Activate();
148 touch_screen->Activate();
149
150 return GetNpad()->ActivateNpadResource(aruid);
151}
152
153Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
154 std::scoped_lock lock{shared_mutex};
155 return applet_resource->CreateAppletResource(aruid);
156}
157
158void ResourceManager::InitializeHidCommonSampler() {
159 debug_pad = std::make_shared<DebugPad>(system.HIDCore());
160 mouse = std::make_shared<Mouse>(system.HIDCore());
161 debug_mouse = std::make_shared<DebugMouse>(system.HIDCore());
162 keyboard = std::make_shared<Keyboard>(system.HIDCore());
163 unique_pad = std::make_shared<UniquePad>(system.HIDCore());
164 npad = std::make_shared<NPad>(system.HIDCore(), service_context);
165 gesture = std::make_shared<Gesture>(system.HIDCore());
166 home_button = std::make_shared<HomeButton>(system.HIDCore());
167 sleep_button = std::make_shared<SleepButton>(system.HIDCore());
168 capture_button = std::make_shared<CaptureButton>(system.HIDCore());
169 digitizer = std::make_shared<Digitizer>(system.HIDCore());
170
171 palma = std::make_shared<Palma>(system.HIDCore(), service_context);
172 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
173
174 debug_pad->SetAppletResource(applet_resource, &shared_mutex);
175 digitizer->SetAppletResource(applet_resource, &shared_mutex);
176 keyboard->SetAppletResource(applet_resource, &shared_mutex);
177 npad->SetNpadExternals(applet_resource, &shared_mutex);
178 six_axis->SetAppletResource(applet_resource, &shared_mutex);
179 mouse->SetAppletResource(applet_resource, &shared_mutex);
180 debug_mouse->SetAppletResource(applet_resource, &shared_mutex);
181 home_button->SetAppletResource(applet_resource, &shared_mutex);
182 sleep_button->SetAppletResource(applet_resource, &shared_mutex);
183 capture_button->SetAppletResource(applet_resource, &shared_mutex);
184}
185
186void ResourceManager::InitializeTouchScreenSampler() {
187 gesture = std::make_shared<Gesture>(system.HIDCore());
188 touch_screen = std::make_shared<TouchScreen>(system.HIDCore());
189
190 touch_screen->SetAppletResource(applet_resource, &shared_mutex);
191 gesture->SetAppletResource(applet_resource, &shared_mutex);
192}
193
194void ResourceManager::InitializeConsoleSixAxisSampler() {
195 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore());
196 seven_six_axis = std::make_shared<SevenSixAxis>(system);
197
198 console_six_axis->SetAppletResource(applet_resource, &shared_mutex);
199}
200
201void ResourceManager::InitializeAHidSampler() {
202 // TODO
203}
204
205Result ResourceManager::RegisterCoreAppletResource() {
206 std::scoped_lock lock{shared_mutex};
207 return applet_resource->RegisterCoreAppletResource();
208}
209
210Result ResourceManager::UnregisterCoreAppletResource() {
211 std::scoped_lock lock{shared_mutex};
212 return applet_resource->UnregisterCoreAppletResource();
213}
214
215Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
216 std::scoped_lock lock{shared_mutex};
217 auto result = applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
218 if (result.IsSuccess()) {
219 result = npad->RegisterAppletResourceUserId(aruid);
220 }
221 return result;
222}
223
224void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
225 std::scoped_lock lock{shared_mutex};
226 applet_resource->UnregisterAppletResourceUserId(aruid);
227}
228
229Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
230 std::scoped_lock lock{shared_mutex};
231 return applet_resource->GetSharedMemoryHandle(out_handle, aruid);
232}
233
234void ResourceManager::FreeAppletResourceId(u64 aruid) {
235 std::scoped_lock lock{shared_mutex};
236 applet_resource->FreeAppletResourceId(aruid);
237}
238
239void ResourceManager::EnableInput(u64 aruid, bool is_enabled) {
240 std::scoped_lock lock{shared_mutex};
241 applet_resource->EnableInput(aruid, is_enabled);
242}
243
244void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
245 std::scoped_lock lock{shared_mutex};
246 applet_resource->EnableSixAxisSensor(aruid, is_enabled);
247}
248
249void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) {
250 std::scoped_lock lock{shared_mutex};
251 applet_resource->EnablePadInput(aruid, is_enabled);
252}
253
254void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
255 std::scoped_lock lock{shared_mutex};
256 applet_resource->EnableTouchScreen(aruid, is_enabled);
257}
258
259void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) {
260 auto& core_timing = system.CoreTiming();
261 debug_pad->OnUpdate(core_timing);
262 digitizer->OnUpdate(core_timing);
263 unique_pad->OnUpdate(core_timing);
264 gesture->OnUpdate(core_timing);
265 touch_screen->OnUpdate(core_timing);
266 palma->OnUpdate(core_timing);
267 home_button->OnUpdate(core_timing);
268 sleep_button->OnUpdate(core_timing);
269 capture_button->OnUpdate(core_timing);
270}
271
272void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) {
273 auto& core_timing = system.CoreTiming();
274 npad->OnUpdate(core_timing);
275}
276
277void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) {
278 auto& core_timing = system.CoreTiming();
279 mouse->OnUpdate(core_timing);
280 debug_mouse->OnUpdate(core_timing);
281 keyboard->OnUpdate(core_timing);
282}
283
284void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
285 auto& core_timing = system.CoreTiming();
286 six_axis->OnUpdate(core_timing);
287 seven_six_axis->OnUpdate(core_timing);
288 console_six_axis->OnUpdate(core_timing);
289}
290
291IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
292 u64 applet_resource_user_id)
293 : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id},
294 resource_manager{resource} {
295 static const FunctionInfo functions[] = {
296 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
297 };
298 RegisterHandlers(functions);
299
300 // Register update callbacks
301 npad_update_event = Core::Timing::CreateEvent(
302 "HID::UpdatePadCallback",
303 [this, resource](
304 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
305 const auto guard = LockService();
306 resource->UpdateNpad(ns_late);
307 return std::nullopt;
308 });
309 default_update_event = Core::Timing::CreateEvent(
310 "HID::UpdateDefaultCallback",
311 [this, resource](
312 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
313 const auto guard = LockService();
314 resource->UpdateControllers(ns_late);
315 return std::nullopt;
316 });
317 mouse_keyboard_update_event = Core::Timing::CreateEvent(
318 "HID::UpdateMouseKeyboardCallback",
319 [this, resource](
320 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
321 const auto guard = LockService();
322 resource->UpdateMouseKeyboard(ns_late);
323 return std::nullopt;
324 });
325 motion_update_event = Core::Timing::CreateEvent(
326 "HID::UpdateMotionCallback",
327 [this, resource](
328 s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
329 const auto guard = LockService();
330 resource->UpdateMotion(ns_late);
331 return std::nullopt;
332 });
333
334 system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
335 system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
336 default_update_event);
337 system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
338 mouse_keyboard_update_event);
339 system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
340 motion_update_event);
341}
342
343IAppletResource::~IAppletResource() {
344 system.CoreTiming().UnscheduleEvent(npad_update_event);
345 system.CoreTiming().UnscheduleEvent(default_update_event);
346 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event);
347 system.CoreTiming().UnscheduleEvent(motion_update_event);
348 resource_manager->FreeAppletResourceId(aruid);
349}
350
351void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
352 Kernel::KSharedMemory* handle;
353 const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid);
354
355 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw);
356
357 IPC::ResponseBuilder rb{ctx, 2, 1};
358 rb.Push(result);
359 rb.PushCopyObjects(handle);
360}
361
362} // namespace Service::HID