summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Narr the Reg2023-11-14 21:34:27 -0600
committerGravatar Narr the Reg2023-11-15 09:59:54 -0600
commitc9cd938dfd8fc40ec58d61dc453bc31d3b811496 (patch)
tree212bc48872c33d21a9cf47b8c779a71cb04051f5
parentMerge pull request #12032 from liamwhite/fruit-compiler (diff)
downloadyuzu-c9cd938dfd8fc40ec58d61dc453bc31d3b811496.tar.gz
yuzu-c9cd938dfd8fc40ec58d61dc453bc31d3b811496.tar.xz
yuzu-c9cd938dfd8fc40ec58d61dc453bc31d3b811496.zip
service: hid: Split hid.cpp into individual interfaces
-rw-r--r--src/core/CMakeLists.txt8
-rw-r--r--src/core/hid/emulated_console.h8
-rw-r--r--src/core/hid/hid_types.h8
-rw-r--r--src/core/hid/input_interpreter.cpp7
-rw-r--r--src/core/hle/service/hid/hid.cpp2856
-rw-r--r--src/core/hle/service/hid/hid.h212
-rw-r--r--src/core/hle/service/hid/hid_debug_server.cpp159
-rw-r--r--src/core/hle/service/hid/hid_debug_server.h26
-rw-r--r--src/core/hle/service/hid/hid_server.cpp2269
-rw-r--r--src/core/hle/service/hid/hid_server.h138
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp304
-rw-r--r--src/core/hle/service/hid/hid_system_server.h40
-rw-r--r--src/core/hle/service/hid/irs.h5
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp192
-rw-r--r--src/core/hle/service/hid/resource_manager.h106
-rw-r--r--src/core/memory/cheat_engine.cpp7
-rw-r--r--src/yuzu/applets/qt_controller.cpp1
17 files changed, 3276 insertions, 3070 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8be3bdd08..3aa2e4340 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -521,11 +521,19 @@ add_library(core STATIC
521 hle/service/grc/grc.h 521 hle/service/grc/grc.h
522 hle/service/hid/hid.cpp 522 hle/service/hid/hid.cpp
523 hle/service/hid/hid.h 523 hle/service/hid/hid.h
524 hle/service/hid/hid_debug_server.cpp
525 hle/service/hid/hid_debug_server.h
526 hle/service/hid/hid_server.cpp
527 hle/service/hid/hid_server.h
528 hle/service/hid/hid_system_server.cpp
529 hle/service/hid/hid_system_server.h
524 hle/service/hid/hidbus.cpp 530 hle/service/hid/hidbus.cpp
525 hle/service/hid/hidbus.h 531 hle/service/hid/hidbus.h
526 hle/service/hid/irs.cpp 532 hle/service/hid/irs.cpp
527 hle/service/hid/irs.h 533 hle/service/hid/irs.h
528 hle/service/hid/irs_ring_lifo.h 534 hle/service/hid/irs_ring_lifo.h
535 hle/service/hid/resource_manager.cpp
536 hle/service/hid/resource_manager.h
529 hle/service/hid/ring_lifo.h 537 hle/service/hid/ring_lifo.h
530 hle/service/hid/xcd.cpp 538 hle/service/hid/xcd.cpp
531 hle/service/hid/xcd.h 539 hle/service/hid/xcd.h
diff --git a/src/core/hid/emulated_console.h b/src/core/hid/emulated_console.h
index 79114bb6d..fae15a556 100644
--- a/src/core/hid/emulated_console.h
+++ b/src/core/hid/emulated_console.h
@@ -38,14 +38,6 @@ using TouchParams = std::array<Common::ParamPackage, MaxTouchDevices>;
38using ConsoleMotionValues = ConsoleMotionInfo; 38using ConsoleMotionValues = ConsoleMotionInfo;
39using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>; 39using TouchValues = std::array<Common::Input::TouchStatus, MaxTouchDevices>;
40 40
41struct TouchFinger {
42 u64 last_touch{};
43 Common::Point<float> position{};
44 u32 id{};
45 TouchAttribute attribute{};
46 bool pressed{};
47};
48
49// Contains all motion related data that is used on the services 41// Contains all motion related data that is used on the services
50struct ConsoleMotion { 42struct ConsoleMotion {
51 Common::Vec3f accel{}; 43 Common::Vec3f accel{};
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h
index 7ba75a50c..9d48cd90e 100644
--- a/src/core/hid/hid_types.h
+++ b/src/core/hid/hid_types.h
@@ -356,6 +356,14 @@ struct TouchState {
356}; 356};
357static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size"); 357static_assert(sizeof(TouchState) == 0x28, "Touchstate is an invalid size");
358 358
359struct TouchFinger {
360 u64 last_touch{};
361 Common::Point<float> position{};
362 u32 id{};
363 TouchAttribute attribute{};
364 bool pressed{};
365};
366
359// This is nn::hid::TouchScreenConfigurationForNx 367// This is nn::hid::TouchScreenConfigurationForNx
360struct TouchScreenConfigurationForNx { 368struct TouchScreenConfigurationForNx {
361 TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting}; 369 TouchScreenModeForNx mode{TouchScreenModeForNx::UseSystemSetting};
diff --git a/src/core/hid/input_interpreter.cpp b/src/core/hid/input_interpreter.cpp
index 76d6b8ab0..11359f318 100644
--- a/src/core/hid/input_interpreter.cpp
+++ b/src/core/hid/input_interpreter.cpp
@@ -5,13 +5,14 @@
5#include "core/hid/hid_types.h" 5#include "core/hid/hid_types.h"
6#include "core/hid/input_interpreter.h" 6#include "core/hid/input_interpreter.h"
7#include "core/hle/service/hid/controllers/npad.h" 7#include "core/hle/service/hid/controllers/npad.h"
8#include "core/hle/service/hid/hid.h" 8#include "core/hle/service/hid/hid_server.h"
9#include "core/hle/service/hid/resource_manager.h"
9#include "core/hle/service/sm/sm.h" 10#include "core/hle/service/sm/sm.h"
10 11
11InputInterpreter::InputInterpreter(Core::System& system) 12InputInterpreter::InputInterpreter(Core::System& system)
12 : npad{system.ServiceManager() 13 : npad{system.ServiceManager()
13 .GetService<Service::HID::Hid>("hid") 14 .GetService<Service::HID::IHidServer>("hid")
14 ->GetAppletResource() 15 ->GetResourceManager()
15 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} { 16 ->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
16 ResetButtonStates(); 17 ResetButtonStates();
17} 18}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 1d4101be9..801a4d08f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -1,2862 +1,36 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <array>
5#include "common/common_types.h"
6#include "common/logging/log.h"
7#include "common/settings.h"
8#include "core/core.h"
9#include "core/core_timing.h"
10#include "core/hid/hid_core.h"
11#include "core/hle/kernel/k_readable_event.h"
12#include "core/hle/kernel/k_shared_memory.h"
13#include "core/hle/kernel/k_transfer_memory.h"
14#include "core/hle/kernel/kernel.h"
15#include "core/hle/service/hid/errors.h"
16#include "core/hle/service/hid/hid.h" 4#include "core/hle/service/hid/hid.h"
5#include "core/hle/service/hid/hid_debug_server.h"
6#include "core/hle/service/hid/hid_server.h"
7#include "core/hle/service/hid/hid_system_server.h"
17#include "core/hle/service/hid/hidbus.h" 8#include "core/hle/service/hid/hidbus.h"
18#include "core/hle/service/hid/irs.h" 9#include "core/hle/service/hid/irs.h"
10#include "core/hle/service/hid/resource_manager.h"
19#include "core/hle/service/hid/xcd.h" 11#include "core/hle/service/hid/xcd.h"
20#include "core/hle/service/ipc_helpers.h"
21#include "core/hle/service/server_manager.h" 12#include "core/hle/service/server_manager.h"
22#include "core/memory.h"
23
24#include "core/hle/service/hid/controllers/console_sixaxis.h"
25#include "core/hle/service/hid/controllers/controller_base.h"
26#include "core/hle/service/hid/controllers/debug_pad.h"
27#include "core/hle/service/hid/controllers/gesture.h"
28#include "core/hle/service/hid/controllers/keyboard.h"
29#include "core/hle/service/hid/controllers/mouse.h"
30#include "core/hle/service/hid/controllers/npad.h"
31#include "core/hle/service/hid/controllers/palma.h"
32#include "core/hle/service/hid/controllers/stubbed.h"
33#include "core/hle/service/hid/controllers/touchscreen.h"
34#include "core/hle/service/hid/controllers/xpad.h"
35 13
36namespace Service::HID { 14namespace Service::HID {
37 15
38// Updating period for each HID device.
39// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
40// Correct npad_update_ns is 4ms this is overclocked to lower input lag
41constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
42constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
43constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
44constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
45
46IAppletResource::IAppletResource(Core::System& system_,
47 KernelHelpers::ServiceContext& service_context_)
48 : ServiceFramework{system_, "IAppletResource"}, service_context{service_context_} {
49 static const FunctionInfo functions[] = {
50 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
51 };
52 RegisterHandlers(functions);
53 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
54 MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
55 MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
56 MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
57 MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
58 MakeController<Controller_XPad>(HidController::XPad, shared_memory);
59 MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
60 MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
61 MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
62 MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
63 MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
64 MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
65 MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
66 MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
67 MakeController<Controller_Stubbed>(HidController::DebugMouse, shared_memory);
68 MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
69
70 // Homebrew doesn't try to activate some controllers, so we activate them by default
71 GetController<Controller_NPad>(HidController::NPad).ActivateController();
72 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
73
74 GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
75 GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
76 GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
77 GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
78 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
79 GetController<Controller_Stubbed>(HidController::DebugMouse).SetCommonHeaderOffset(0x3DC00);
80
81 // Register update callbacks
82 npad_update_event = Core::Timing::CreateEvent(
83 "HID::UpdatePadCallback",
84 [this](std::uintptr_t user_data, s64 time,
85 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
86 const auto guard = LockService();
87 UpdateNpad(user_data, ns_late);
88 return std::nullopt;
89 });
90 default_update_event = Core::Timing::CreateEvent(
91 "HID::UpdateDefaultCallback",
92 [this](std::uintptr_t user_data, s64 time,
93 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
94 const auto guard = LockService();
95 UpdateControllers(user_data, ns_late);
96 return std::nullopt;
97 });
98 mouse_keyboard_update_event = Core::Timing::CreateEvent(
99 "HID::UpdateMouseKeyboardCallback",
100 [this](std::uintptr_t user_data, s64 time,
101 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
102 const auto guard = LockService();
103 UpdateMouseKeyboard(user_data, ns_late);
104 return std::nullopt;
105 });
106 motion_update_event = Core::Timing::CreateEvent(
107 "HID::UpdateMotionCallback",
108 [this](std::uintptr_t user_data, s64 time,
109 std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
110 const auto guard = LockService();
111 UpdateMotion(user_data, ns_late);
112 return std::nullopt;
113 });
114
115 system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
116 system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
117 default_update_event);
118 system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
119 mouse_keyboard_update_event);
120 system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
121 motion_update_event);
122
123 system.HIDCore().ReloadInputDevices();
124}
125
126void IAppletResource::ActivateController(HidController controller) {
127 controllers[static_cast<size_t>(controller)]->ActivateController();
128}
129
130void IAppletResource::DeactivateController(HidController controller) {
131 controllers[static_cast<size_t>(controller)]->DeactivateController();
132}
133
134IAppletResource::~IAppletResource() {
135 system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
136 system.CoreTiming().UnscheduleEvent(default_update_event, 0);
137 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
138 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
139}
140
141void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
142 LOG_DEBUG(Service_HID, "called");
143
144 IPC::ResponseBuilder rb{ctx, 2, 1};
145 rb.Push(ResultSuccess);
146 rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
147}
148
149void IAppletResource::UpdateControllers(std::uintptr_t user_data,
150 std::chrono::nanoseconds ns_late) {
151 auto& core_timing = system.CoreTiming();
152
153 for (const auto& controller : controllers) {
154 // Keyboard has it's own update event
155 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
156 continue;
157 }
158 // Mouse has it's own update event
159 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
160 continue;
161 }
162 // Npad has it's own update event
163 if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
164 continue;
165 }
166 controller->OnUpdate(core_timing);
167 }
168}
169
170void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
171 auto& core_timing = system.CoreTiming();
172
173 controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
174}
175
176void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
177 std::chrono::nanoseconds ns_late) {
178 auto& core_timing = system.CoreTiming();
179
180 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
181 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
182}
183
184void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
185 auto& core_timing = system.CoreTiming();
186
187 controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
188}
189
190class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
191public:
192 explicit IActiveVibrationDeviceList(Core::System& system_,
193 std::shared_ptr<IAppletResource> applet_resource_)
194 : ServiceFramework{system_, "IActiveVibrationDeviceList"},
195 applet_resource(applet_resource_) {
196 // clang-format off
197 static const FunctionInfo functions[] = {
198 {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
199 };
200 // clang-format on
201
202 RegisterHandlers(functions);
203 }
204
205private:
206 void InitializeVibrationDevice(HLERequestContext& ctx) {
207 IPC::RequestParser rp{ctx};
208 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
209
210 if (applet_resource != nullptr) {
211 applet_resource->GetController<Controller_NPad>(HidController::NPad)
212 .InitializeVibrationDevice(vibration_device_handle);
213 }
214
215 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
216 vibration_device_handle.npad_type, vibration_device_handle.npad_id,
217 vibration_device_handle.device_index);
218
219 IPC::ResponseBuilder rb{ctx, 2};
220 rb.Push(ResultSuccess);
221 }
222
223 std::shared_ptr<IAppletResource> applet_resource;
224};
225
226std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
227 if (applet_resource == nullptr) {
228 applet_resource = std::make_shared<IAppletResource>(system, service_context);
229 }
230
231 return applet_resource;
232}
233
234Hid::Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
235 : ServiceFramework{system_, "hid"}, applet_resource{applet_resource_}, service_context{
236 system_,
237 service_name} {
238 // clang-format off
239 static const FunctionInfo functions[] = {
240 {0, &Hid::CreateAppletResource, "CreateAppletResource"},
241 {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
242 {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
243 {21, &Hid::ActivateMouse, "ActivateMouse"},
244 {26, nullptr, "ActivateDebugMouse"},
245 {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
246 {32, &Hid::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"},
247 {40, nullptr, "AcquireXpadIdEventHandle"},
248 {41, nullptr, "ReleaseXpadIdEventHandle"},
249 {51, &Hid::ActivateXpad, "ActivateXpad"},
250 {55, &Hid::GetXpadIDs, "GetXpadIds"},
251 {56, nullptr, "ActivateJoyXpad"},
252 {58, nullptr, "GetJoyXpadLifoHandle"},
253 {59, nullptr, "GetJoyXpadIds"},
254 {60, &Hid::ActivateSixAxisSensor, "ActivateSixAxisSensor"},
255 {61, &Hid::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"},
256 {62, nullptr, "GetSixAxisSensorLifoHandle"},
257 {63, nullptr, "ActivateJoySixAxisSensor"},
258 {64, nullptr, "DeactivateJoySixAxisSensor"},
259 {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
260 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
261 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
262 {68, &Hid::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"},
263 {69, &Hid::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
264 {70, &Hid::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"},
265 {71, &Hid::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"},
266 {72, &Hid::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"},
267 {73, nullptr, "SetAccelerometerParameters"},
268 {74, nullptr, "GetAccelerometerParameters"},
269 {75, nullptr, "ResetAccelerometerParameters"},
270 {76, nullptr, "SetAccelerometerPlayMode"},
271 {77, nullptr, "GetAccelerometerPlayMode"},
272 {78, nullptr, "ResetAccelerometerPlayMode"},
273 {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
274 {80, &Hid::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"},
275 {81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
276 {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
277 {83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
278 {84, &Hid::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"},
279 {85, &Hid::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"},
280 {86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
281 {87, &Hid::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"},
282 {88, &Hid::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"},
283 {89, &Hid::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
284 {91, &Hid::ActivateGesture, "ActivateGesture"},
285 {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
286 {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
287 {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
288 {103, &Hid::ActivateNpad, "ActivateNpad"},
289 {104, &Hid::DeactivateNpad, "DeactivateNpad"},
290 {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
291 {107, &Hid::DisconnectNpad, "DisconnectNpad"},
292 {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
293 {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
294 {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
295 {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
296 {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
297 {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
298 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
299 {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
300 {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
301 {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
302 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
303 {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
304 {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
305 {131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
306 {132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
307 {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"},
308 {134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
309 {135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"},
310 {136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"},
311 {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
312 {201, &Hid::SendVibrationValue, "SendVibrationValue"},
313 {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
314 {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
315 {204, &Hid::PermitVibration, "PermitVibration"},
316 {205, &Hid::IsVibrationPermitted, "IsVibrationPermitted"},
317 {206, &Hid::SendVibrationValues, "SendVibrationValues"},
318 {207, &Hid::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"},
319 {208, &Hid::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"},
320 {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
321 {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
322 {211, &Hid::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
323 {212, nullptr, "SendVibrationValueInBool"},
324 {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
325 {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
326 {302, &Hid::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
327 {303, &Hid::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"},
328 {304, &Hid::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"},
329 {305, &Hid::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"},
330 {306, &Hid::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"},
331 {307, &Hid::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"},
332 {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
333 {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
334 {310, &Hid::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"},
335 {400, &Hid::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
336 {401, nullptr, "EnableUsbFullKeyController"},
337 {402, nullptr, "IsUsbFullKeyControllerConnected"},
338 {403, nullptr, "HasBattery"},
339 {404, nullptr, "HasLeftRightBattery"},
340 {405, nullptr, "GetNpadInterfaceType"},
341 {406, nullptr, "GetNpadLeftRightInterfaceType"},
342 {407, nullptr, "GetNpadOfHighestBatteryLevel"},
343 {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
344 {500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
345 {501, &Hid::InitializePalma, "InitializePalma"},
346 {502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
347 {503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
348 {504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"},
349 {505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"},
350 {506, &Hid::ReadPalmaStep, "ReadPalmaStep"},
351 {507, &Hid::EnablePalmaStep, "EnablePalmaStep"},
352 {508, &Hid::ResetPalmaStep, "ResetPalmaStep"},
353 {509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
354 {510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
355 {511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
356 {512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
357 {513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
358 {514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
359 {515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
360 {516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
361 {517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
362 {518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"},
363 {519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"},
364 {520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
365 {521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
366 {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
367 {523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
368 {524, &Hid::PairPalma, "PairPalma"},
369 {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
370 {526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
371 {527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
372 {528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
373 {529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
374 {1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
375 {1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
376 {1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
377 {1003, &Hid::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"},
378 {2000, nullptr, "ActivateDigitizer"},
379 };
380 // clang-format on
381
382 RegisterHandlers(functions);
383}
384
385Hid::~Hid() = default;
386
387void Hid::CreateAppletResource(HLERequestContext& ctx) {
388 IPC::RequestParser rp{ctx};
389 const auto applet_resource_user_id{rp.Pop<u64>()};
390
391 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
392
393 if (applet_resource == nullptr) {
394 applet_resource = std::make_shared<IAppletResource>(system, service_context);
395 }
396
397 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
398 rb.Push(ResultSuccess);
399 rb.PushIpcInterface<IAppletResource>(applet_resource);
400}
401
402void Hid::ActivateDebugPad(HLERequestContext& ctx) {
403 IPC::RequestParser rp{ctx};
404 const auto applet_resource_user_id{rp.Pop<u64>()};
405
406 applet_resource->ActivateController(HidController::DebugPad);
407
408 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
409
410 IPC::ResponseBuilder rb{ctx, 2};
411 rb.Push(ResultSuccess);
412}
413
414void Hid::ActivateTouchScreen(HLERequestContext& ctx) {
415 IPC::RequestParser rp{ctx};
416 const auto applet_resource_user_id{rp.Pop<u64>()};
417
418 applet_resource->ActivateController(HidController::Touchscreen);
419
420 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
421
422 IPC::ResponseBuilder rb{ctx, 2};
423 rb.Push(ResultSuccess);
424}
425
426void Hid::ActivateMouse(HLERequestContext& ctx) {
427 IPC::RequestParser rp{ctx};
428 const auto applet_resource_user_id{rp.Pop<u64>()};
429
430 applet_resource->ActivateController(HidController::Mouse);
431
432 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
433
434 IPC::ResponseBuilder rb{ctx, 2};
435 rb.Push(ResultSuccess);
436}
437
438void Hid::ActivateKeyboard(HLERequestContext& ctx) {
439 IPC::RequestParser rp{ctx};
440 const auto applet_resource_user_id{rp.Pop<u64>()};
441
442 applet_resource->ActivateController(HidController::Keyboard);
443
444 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
445
446 IPC::ResponseBuilder rb{ctx, 2};
447 rb.Push(ResultSuccess);
448}
449
450void Hid::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
451 IPC::RequestParser rp{ctx};
452 const auto flags{rp.Pop<u32>()};
453
454 LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
455
456 IPC::ResponseBuilder rb{ctx, 2};
457 rb.Push(ResultSuccess);
458}
459
460void Hid::ActivateXpad(HLERequestContext& ctx) {
461 IPC::RequestParser rp{ctx};
462 struct Parameters {
463 u32 basic_xpad_id;
464 INSERT_PADDING_WORDS_NOINIT(1);
465 u64 applet_resource_user_id;
466 };
467 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
468
469 const auto parameters{rp.PopRaw<Parameters>()};
470
471 applet_resource->ActivateController(HidController::XPad);
472
473 LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
474 parameters.basic_xpad_id, parameters.applet_resource_user_id);
475
476 IPC::ResponseBuilder rb{ctx, 2};
477 rb.Push(ResultSuccess);
478}
479
480void Hid::GetXpadIDs(HLERequestContext& ctx) {
481 IPC::RequestParser rp{ctx};
482 const auto applet_resource_user_id{rp.Pop<u64>()};
483
484 LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
485
486 IPC::ResponseBuilder rb{ctx, 3};
487 rb.Push(ResultSuccess);
488 rb.Push(0);
489}
490
491void Hid::ActivateSixAxisSensor(HLERequestContext& ctx) {
492 IPC::RequestParser rp{ctx};
493 struct Parameters {
494 u32 basic_xpad_id;
495 INSERT_PADDING_WORDS_NOINIT(1);
496 u64 applet_resource_user_id;
497 };
498 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
499
500 const auto parameters{rp.PopRaw<Parameters>()};
501
502 // This function does nothing on 10.0.0+
503
504 LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
505 parameters.basic_xpad_id, parameters.applet_resource_user_id);
506
507 IPC::ResponseBuilder rb{ctx, 2};
508 rb.Push(ResultSuccess);
509}
510
511void Hid::DeactivateSixAxisSensor(HLERequestContext& ctx) {
512 IPC::RequestParser rp{ctx};
513 struct Parameters {
514 u32 basic_xpad_id;
515 INSERT_PADDING_WORDS_NOINIT(1);
516 u64 applet_resource_user_id;
517 };
518 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
519
520 const auto parameters{rp.PopRaw<Parameters>()};
521
522 // This function does nothing on 10.0.0+
523
524 LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
525 parameters.basic_xpad_id, parameters.applet_resource_user_id);
526
527 IPC::ResponseBuilder rb{ctx, 2};
528 rb.Push(ResultSuccess);
529}
530
531void Hid::StartSixAxisSensor(HLERequestContext& ctx) {
532 IPC::RequestParser rp{ctx};
533 struct Parameters {
534 Core::HID::SixAxisSensorHandle sixaxis_handle;
535 INSERT_PADDING_WORDS_NOINIT(1);
536 u64 applet_resource_user_id;
537 };
538 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
539
540 const auto parameters{rp.PopRaw<Parameters>()};
541
542 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
543 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
544
545 LOG_DEBUG(Service_HID,
546 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
547 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
548 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
549
550 IPC::ResponseBuilder rb{ctx, 2};
551 rb.Push(result);
552}
553
554void Hid::StopSixAxisSensor(HLERequestContext& ctx) {
555 IPC::RequestParser rp{ctx};
556 struct Parameters {
557 Core::HID::SixAxisSensorHandle sixaxis_handle;
558 INSERT_PADDING_WORDS_NOINIT(1);
559 u64 applet_resource_user_id;
560 };
561 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
562
563 const auto parameters{rp.PopRaw<Parameters>()};
564
565 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
566 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
567
568 LOG_DEBUG(Service_HID,
569 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
570 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
571 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
572
573 IPC::ResponseBuilder rb{ctx, 2};
574 rb.Push(result);
575}
576
577void Hid::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
578 IPC::RequestParser rp{ctx};
579 struct Parameters {
580 Core::HID::SixAxisSensorHandle sixaxis_handle;
581 INSERT_PADDING_WORDS_NOINIT(1);
582 u64 applet_resource_user_id;
583 };
584 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
585
586 const auto parameters{rp.PopRaw<Parameters>()};
587
588 bool is_enabled{};
589 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
590 const auto result =
591 controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
592
593 LOG_DEBUG(Service_HID,
594 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
595 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
596 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
597
598 IPC::ResponseBuilder rb{ctx, 3};
599 rb.Push(result);
600 rb.Push(is_enabled);
601}
602
603void Hid::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
604 IPC::RequestParser rp{ctx};
605 struct Parameters {
606 bool enable_sixaxis_sensor_fusion;
607 INSERT_PADDING_BYTES_NOINIT(3);
608 Core::HID::SixAxisSensorHandle sixaxis_handle;
609 u64 applet_resource_user_id;
610 };
611 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
612
613 const auto parameters{rp.PopRaw<Parameters>()};
614
615 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
616 const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
617 parameters.enable_sixaxis_sensor_fusion);
618
619 LOG_DEBUG(Service_HID,
620 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
621 "device_index={}, applet_resource_user_id={}",
622 parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
623 parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
624 parameters.applet_resource_user_id);
625
626 IPC::ResponseBuilder rb{ctx, 2};
627 rb.Push(result);
628}
629
630void Hid::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
631 IPC::RequestParser rp{ctx};
632 struct Parameters {
633 Core::HID::SixAxisSensorHandle sixaxis_handle;
634 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion;
635 INSERT_PADDING_WORDS_NOINIT(1);
636 u64 applet_resource_user_id;
637 };
638 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
639
640 const auto parameters{rp.PopRaw<Parameters>()};
641
642 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
643 const auto result =
644 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
645
646 LOG_DEBUG(Service_HID,
647 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
648 "parameter2={}, applet_resource_user_id={}",
649 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
650 parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1,
651 parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id);
652
653 IPC::ResponseBuilder rb{ctx, 2};
654 rb.Push(result);
655}
656
657void Hid::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
658 IPC::RequestParser rp{ctx};
659 struct Parameters {
660 Core::HID::SixAxisSensorHandle sixaxis_handle;
661 INSERT_PADDING_WORDS_NOINIT(1);
662 u64 applet_resource_user_id;
663 };
664 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
665
666 const auto parameters{rp.PopRaw<Parameters>()};
667
668 Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
669 const auto& controller =
670 GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
671 const auto result =
672 controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
673
674 LOG_DEBUG(Service_HID,
675 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
676 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
677 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
678
679 IPC::ResponseBuilder rb{ctx, 4};
680 rb.Push(result);
681 rb.PushRaw(fusion_parameters);
682}
683
684void Hid::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
685 IPC::RequestParser rp{ctx};
686 struct Parameters {
687 Core::HID::SixAxisSensorHandle sixaxis_handle;
688 INSERT_PADDING_WORDS_NOINIT(1);
689 u64 applet_resource_user_id;
690 };
691 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
692
693 const auto parameters{rp.PopRaw<Parameters>()};
694
695 // Since these parameters are unknown just use what HW outputs
696 const Core::HID::SixAxisSensorFusionParameters fusion_parameters{
697 .parameter1 = 0.03f,
698 .parameter2 = 0.4f,
699 };
700 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
701 const auto result1 =
702 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
703 const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
704
705 LOG_DEBUG(Service_HID,
706 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
707 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
708 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
709
710 IPC::ResponseBuilder rb{ctx, 2};
711 if (result1.IsError()) {
712 rb.Push(result1);
713 return;
714 }
715 rb.Push(result2);
716}
717
718void Hid::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
719 IPC::RequestParser rp{ctx};
720 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
721 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
722 const auto applet_resource_user_id{rp.Pop<u64>()};
723
724 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
725 const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
726
727 LOG_DEBUG(Service_HID,
728 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
729 "applet_resource_user_id={}",
730 sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
731 drift_mode, applet_resource_user_id);
732
733 IPC::ResponseBuilder rb{ctx, 2};
734 rb.Push(result);
735}
736
737void Hid::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
738 IPC::RequestParser rp{ctx};
739 struct Parameters {
740 Core::HID::SixAxisSensorHandle sixaxis_handle;
741 INSERT_PADDING_WORDS_NOINIT(1);
742 u64 applet_resource_user_id;
743 };
744 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
745
746 const auto parameters{rp.PopRaw<Parameters>()};
747
748 auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
749 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
750 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
751
752 LOG_DEBUG(Service_HID,
753 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
754 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
755 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
756
757 IPC::ResponseBuilder rb{ctx, 3};
758 rb.Push(result);
759 rb.PushEnum(drift_mode);
760}
761
762void Hid::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
763 IPC::RequestParser rp{ctx};
764 struct Parameters {
765 Core::HID::SixAxisSensorHandle sixaxis_handle;
766 INSERT_PADDING_WORDS_NOINIT(1);
767 u64 applet_resource_user_id;
768 };
769 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
770
771 const auto parameters{rp.PopRaw<Parameters>()};
772
773 const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
774 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
775 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
776
777 LOG_DEBUG(Service_HID,
778 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
779 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
780 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
781
782 IPC::ResponseBuilder rb{ctx, 2};
783 rb.Push(result);
784}
785
786void Hid::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
787 IPC::RequestParser rp{ctx};
788 struct Parameters {
789 Core::HID::SixAxisSensorHandle sixaxis_handle;
790 INSERT_PADDING_WORDS_NOINIT(1);
791 u64 applet_resource_user_id;
792 };
793 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
794
795 const auto parameters{rp.PopRaw<Parameters>()};
796
797 bool is_at_rest{};
798 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
799 controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
800
801 LOG_DEBUG(Service_HID,
802 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
803 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
804 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
805
806 IPC::ResponseBuilder rb{ctx, 3};
807 rb.Push(ResultSuccess);
808 rb.Push(is_at_rest);
809}
810
811void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) {
812 IPC::RequestParser rp{ctx};
813 struct Parameters {
814 Core::HID::SixAxisSensorHandle sixaxis_handle;
815 INSERT_PADDING_WORDS_NOINIT(1);
816 u64 applet_resource_user_id;
817 };
818 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
819
820 const auto parameters{rp.PopRaw<Parameters>()};
821
822 bool is_firmware_available{};
823 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
824 controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
825 is_firmware_available);
826
827 LOG_WARNING(
828 Service_HID,
829 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
830 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
831 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
832
833 IPC::ResponseBuilder rb{ctx, 3};
834 rb.Push(ResultSuccess);
835 rb.Push(is_firmware_available);
836}
837
838void Hid::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) {
839 IPC::RequestParser rp{ctx};
840 struct Parameters {
841 bool enabled;
842 Core::HID::SixAxisSensorHandle sixaxis_handle;
843 u64 applet_resource_user_id;
844 };
845 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
846
847 const auto parameters{rp.PopRaw<Parameters>()};
848
849 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
850 const auto result = controller.EnableSixAxisSensorUnalteredPassthrough(
851 parameters.sixaxis_handle, parameters.enabled);
852
853 LOG_DEBUG(Service_HID,
854 "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
855 "applet_resource_user_id={}",
856 parameters.enabled, parameters.sixaxis_handle.npad_type,
857 parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
858 parameters.applet_resource_user_id);
859
860 IPC::ResponseBuilder rb{ctx, 2};
861 rb.Push(result);
862}
863
864void Hid::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) {
865 IPC::RequestParser rp{ctx};
866 struct Parameters {
867 Core::HID::SixAxisSensorHandle sixaxis_handle;
868 INSERT_PADDING_WORDS_NOINIT(1);
869 u64 applet_resource_user_id;
870 };
871 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
872
873 const auto parameters{rp.PopRaw<Parameters>()};
874
875 bool is_unaltered_sisxaxis_enabled{};
876 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
877 const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled(
878 parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
879
880 LOG_DEBUG(
881 Service_HID,
882 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
883 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
884 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
885
886 IPC::ResponseBuilder rb{ctx, 3};
887 rb.Push(result);
888 rb.Push(is_unaltered_sisxaxis_enabled);
889}
890
891void Hid::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
892 IPC::RequestParser rp{ctx};
893 struct Parameters {
894 Core::HID::SixAxisSensorHandle sixaxis_handle;
895 INSERT_PADDING_WORDS_NOINIT(1);
896 u64 applet_resource_user_id;
897 };
898 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
899
900 const auto parameters{rp.PopRaw<Parameters>()};
901
902 Core::HID::SixAxisSensorCalibrationParameter calibration{};
903 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
904 const auto result =
905 controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
906
907 LOG_WARNING(
908 Service_HID,
909 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
910 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
911 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
912
913 if (result.IsSuccess()) {
914 ctx.WriteBuffer(calibration);
915 }
916
917 IPC::ResponseBuilder rb{ctx, 2};
918 rb.Push(result);
919}
920
921void Hid::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
922 IPC::RequestParser rp{ctx};
923 struct Parameters {
924 Core::HID::SixAxisSensorHandle sixaxis_handle;
925 INSERT_PADDING_WORDS_NOINIT(1);
926 u64 applet_resource_user_id;
927 };
928 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
929
930 const auto parameters{rp.PopRaw<Parameters>()};
931
932 Core::HID::SixAxisSensorIcInformation ic_information{};
933 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
934 const auto result =
935 controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
936
937 LOG_WARNING(
938 Service_HID,
939 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
940 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
941 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
942
943 if (result.IsSuccess()) {
944 ctx.WriteBuffer(ic_information);
945 }
946
947 IPC::ResponseBuilder rb{ctx, 2};
948 rb.Push(result);
949}
950
951void Hid::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) {
952 IPC::RequestParser rp{ctx};
953 struct Parameters {
954 Core::HID::SixAxisSensorHandle sixaxis_handle;
955 INSERT_PADDING_WORDS_NOINIT(1);
956 u64 applet_resource_user_id;
957 };
958 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
959
960 const auto parameters{rp.PopRaw<Parameters>()};
961
962 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
963 const auto result =
964 controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
965
966 LOG_WARNING(
967 Service_HID,
968 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
969 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
970 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
971
972 IPC::ResponseBuilder rb{ctx, 2};
973 rb.Push(result);
974}
975
976void Hid::ActivateGesture(HLERequestContext& ctx) {
977 IPC::RequestParser rp{ctx};
978 struct Parameters {
979 u32 unknown;
980 INSERT_PADDING_WORDS_NOINIT(1);
981 u64 applet_resource_user_id;
982 };
983 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
984
985 const auto parameters{rp.PopRaw<Parameters>()};
986
987 applet_resource->ActivateController(HidController::Gesture);
988
989 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
990 parameters.unknown, parameters.applet_resource_user_id);
991
992 IPC::ResponseBuilder rb{ctx, 2};
993 rb.Push(ResultSuccess);
994}
995
996void Hid::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
997 IPC::RequestParser rp{ctx};
998 struct Parameters {
999 Core::HID::NpadStyleSet supported_styleset;
1000 INSERT_PADDING_WORDS_NOINIT(1);
1001 u64 applet_resource_user_id;
1002 };
1003 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1004
1005 const auto parameters{rp.PopRaw<Parameters>()};
1006
1007 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1008 .SetSupportedStyleSet({parameters.supported_styleset});
1009
1010 LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
1011 parameters.supported_styleset, parameters.applet_resource_user_id);
1012
1013 IPC::ResponseBuilder rb{ctx, 2};
1014 rb.Push(ResultSuccess);
1015}
1016
1017void Hid::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
1018 IPC::RequestParser rp{ctx};
1019 const auto applet_resource_user_id{rp.Pop<u64>()};
1020
1021 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1022
1023 IPC::ResponseBuilder rb{ctx, 3};
1024 rb.Push(ResultSuccess);
1025 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1026 .GetSupportedStyleSet()
1027 .raw);
1028}
1029
1030void Hid::SetSupportedNpadIdType(HLERequestContext& ctx) {
1031 IPC::RequestParser rp{ctx};
1032 const auto applet_resource_user_id{rp.Pop<u64>()};
1033
1034 const auto result = applet_resource->GetController<Controller_NPad>(HidController::NPad)
1035 .SetSupportedNpadIdTypes(ctx.ReadBuffer());
1036
1037 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1038
1039 IPC::ResponseBuilder rb{ctx, 2};
1040 rb.Push(result);
1041}
1042
1043void Hid::ActivateNpad(HLERequestContext& ctx) {
1044 IPC::RequestParser rp{ctx};
1045 const auto applet_resource_user_id{rp.Pop<u64>()};
1046
1047 applet_resource->ActivateController(HidController::NPad);
1048
1049 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1050
1051 IPC::ResponseBuilder rb{ctx, 2};
1052 rb.Push(ResultSuccess);
1053}
1054
1055void Hid::DeactivateNpad(HLERequestContext& ctx) {
1056 IPC::RequestParser rp{ctx};
1057 const auto applet_resource_user_id{rp.Pop<u64>()};
1058
1059 applet_resource->DeactivateController(HidController::NPad);
1060
1061 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1062
1063 IPC::ResponseBuilder rb{ctx, 2};
1064 rb.Push(ResultSuccess);
1065}
1066
1067void Hid::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
1068 IPC::RequestParser rp{ctx};
1069 struct Parameters {
1070 Core::HID::NpadIdType npad_id;
1071 INSERT_PADDING_WORDS_NOINIT(1);
1072 u64 applet_resource_user_id;
1073 u64 unknown;
1074 };
1075 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1076
1077 const auto parameters{rp.PopRaw<Parameters>()};
1078
1079 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
1080 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
1081
1082 // Games expect this event to be signaled after calling this function
1083 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1084 .SignalStyleSetChangedEvent(parameters.npad_id);
1085
1086 IPC::ResponseBuilder rb{ctx, 2, 1};
1087 rb.Push(ResultSuccess);
1088 rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1089 .GetStyleSetChangedEvent(parameters.npad_id));
1090}
1091
1092void Hid::DisconnectNpad(HLERequestContext& ctx) {
1093 IPC::RequestParser rp{ctx};
1094 struct Parameters {
1095 Core::HID::NpadIdType npad_id;
1096 INSERT_PADDING_WORDS_NOINIT(1);
1097 u64 applet_resource_user_id;
1098 };
1099 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1100
1101 const auto parameters{rp.PopRaw<Parameters>()};
1102
1103 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1104 controller.DisconnectNpad(parameters.npad_id);
1105
1106 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1107 parameters.applet_resource_user_id);
1108
1109 IPC::ResponseBuilder rb{ctx, 2};
1110 rb.Push(ResultSuccess);
1111}
1112
1113void Hid::GetPlayerLedPattern(HLERequestContext& ctx) {
1114 IPC::RequestParser rp{ctx};
1115 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
1116
1117 Core::HID::LedPattern pattern{0, 0, 0, 0};
1118 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1119 const auto result = controller.GetLedPattern(npad_id, pattern);
1120
1121 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
1122
1123 IPC::ResponseBuilder rb{ctx, 4};
1124 rb.Push(result);
1125 rb.Push(pattern.raw);
1126}
1127
1128void Hid::ActivateNpadWithRevision(HLERequestContext& ctx) {
1129 // Should have no effect with how our npad sets up the data
1130 IPC::RequestParser rp{ctx};
1131 struct Parameters {
1132 s32 revision;
1133 INSERT_PADDING_WORDS_NOINIT(1);
1134 u64 applet_resource_user_id;
1135 };
1136 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1137
1138 const auto parameters{rp.PopRaw<Parameters>()};
1139
1140 applet_resource->ActivateController(HidController::NPad);
1141
1142 LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
1143 parameters.applet_resource_user_id);
1144
1145 IPC::ResponseBuilder rb{ctx, 2};
1146 rb.Push(ResultSuccess);
1147}
1148
1149void Hid::SetNpadJoyHoldType(HLERequestContext& ctx) {
1150 IPC::RequestParser rp{ctx};
1151 const auto applet_resource_user_id{rp.Pop<u64>()};
1152 const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()};
1153
1154 applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type);
1155
1156 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
1157 applet_resource_user_id, hold_type);
1158
1159 IPC::ResponseBuilder rb{ctx, 2};
1160 rb.Push(ResultSuccess);
1161}
1162
1163void Hid::GetNpadJoyHoldType(HLERequestContext& ctx) {
1164 IPC::RequestParser rp{ctx};
1165 const auto applet_resource_user_id{rp.Pop<u64>()};
1166
1167 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1168
1169 IPC::ResponseBuilder rb{ctx, 4};
1170 rb.Push(ResultSuccess);
1171 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
1172}
1173
1174void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
1175 IPC::RequestParser rp{ctx};
1176 struct Parameters {
1177 Core::HID::NpadIdType npad_id;
1178 INSERT_PADDING_WORDS_NOINIT(1);
1179 u64 applet_resource_user_id;
1180 };
1181 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1182
1183 const auto parameters{rp.PopRaw<Parameters>()};
1184
1185 Core::HID::NpadIdType new_npad_id{};
1186 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1187 controller.SetNpadMode(new_npad_id, parameters.npad_id,
1188 Controller_NPad::NpadJoyDeviceType::Left,
1189 Controller_NPad::NpadJoyAssignmentMode::Single);
1190
1191 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1192 parameters.applet_resource_user_id);
1193
1194 IPC::ResponseBuilder rb{ctx, 2};
1195 rb.Push(ResultSuccess);
1196}
1197
1198void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1199 IPC::RequestParser rp{ctx};
1200 struct Parameters {
1201 Core::HID::NpadIdType npad_id;
1202 INSERT_PADDING_WORDS_NOINIT(1);
1203 u64 applet_resource_user_id;
1204 Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
1205 };
1206 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1207
1208 const auto parameters{rp.PopRaw<Parameters>()};
1209
1210 Core::HID::NpadIdType new_npad_id{};
1211 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1212 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1213 Controller_NPad::NpadJoyAssignmentMode::Single);
1214
1215 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1216 parameters.npad_id, parameters.applet_resource_user_id,
1217 parameters.npad_joy_device_type);
1218
1219 IPC::ResponseBuilder rb{ctx, 2};
1220 rb.Push(ResultSuccess);
1221}
1222
1223void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1224 IPC::RequestParser rp{ctx};
1225 struct Parameters {
1226 Core::HID::NpadIdType npad_id;
1227 INSERT_PADDING_WORDS_NOINIT(1);
1228 u64 applet_resource_user_id;
1229 };
1230 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1231
1232 const auto parameters{rp.PopRaw<Parameters>()};
1233
1234 Core::HID::NpadIdType new_npad_id{};
1235 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1236 controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
1237 Controller_NPad::NpadJoyAssignmentMode::Dual);
1238
1239 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1240 parameters.applet_resource_user_id);
1241
1242 IPC::ResponseBuilder rb{ctx, 2};
1243 rb.Push(ResultSuccess);
1244}
1245
1246void Hid::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
1247 IPC::RequestParser rp{ctx};
1248 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1249 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1250 const auto applet_resource_user_id{rp.Pop<u64>()};
1251
1252 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1253 const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
1254
1255 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1256 npad_id_1, npad_id_2, applet_resource_user_id);
1257
1258 IPC::ResponseBuilder rb{ctx, 2};
1259 rb.Push(result);
1260}
1261
1262void Hid::StartLrAssignmentMode(HLERequestContext& ctx) {
1263 IPC::RequestParser rp{ctx};
1264 const auto applet_resource_user_id{rp.Pop<u64>()};
1265
1266 applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode();
1267
1268 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1269
1270 IPC::ResponseBuilder rb{ctx, 2};
1271 rb.Push(ResultSuccess);
1272}
1273
1274void Hid::StopLrAssignmentMode(HLERequestContext& ctx) {
1275 IPC::RequestParser rp{ctx};
1276 const auto applet_resource_user_id{rp.Pop<u64>()};
1277
1278 applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode();
1279
1280 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1281
1282 IPC::ResponseBuilder rb{ctx, 2};
1283 rb.Push(ResultSuccess);
1284}
1285
1286void Hid::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1287 IPC::RequestParser rp{ctx};
1288 const auto applet_resource_user_id{rp.Pop<u64>()};
1289 const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()};
1290
1291 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1292 .SetNpadHandheldActivationMode(activation_mode);
1293
1294 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
1295 applet_resource_user_id, activation_mode);
1296
1297 IPC::ResponseBuilder rb{ctx, 2};
1298 rb.Push(ResultSuccess);
1299}
1300
1301void Hid::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
1302 IPC::RequestParser rp{ctx};
1303 const auto applet_resource_user_id{rp.Pop<u64>()};
1304
1305 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1306
1307 IPC::ResponseBuilder rb{ctx, 4};
1308 rb.Push(ResultSuccess);
1309 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1310 .GetNpadHandheldActivationMode());
1311}
1312
1313void Hid::SwapNpadAssignment(HLERequestContext& ctx) {
1314 IPC::RequestParser rp{ctx};
1315 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1316 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1317 const auto applet_resource_user_id{rp.Pop<u64>()};
1318
1319 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1320 const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2);
1321
1322 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1323 npad_id_1, npad_id_2, applet_resource_user_id);
1324
1325 IPC::ResponseBuilder rb{ctx, 2};
1326 rb.Push(result);
1327}
1328
1329void Hid::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
1330 IPC::RequestParser rp{ctx};
1331 struct Parameters {
1332 Core::HID::NpadIdType npad_id;
1333 INSERT_PADDING_WORDS_NOINIT(1);
1334 u64 applet_resource_user_id;
1335 };
1336 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1337
1338 const auto parameters{rp.PopRaw<Parameters>()};
1339
1340 bool is_enabled = false;
1341 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1342 const auto result =
1343 controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
1344
1345 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1346 parameters.npad_id, parameters.applet_resource_user_id);
1347
1348 IPC::ResponseBuilder rb{ctx, 3};
1349 rb.Push(result);
1350 rb.Push(is_enabled);
1351}
1352
1353void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
1354 IPC::RequestParser rp{ctx};
1355 struct Parameters {
1356 bool is_enabled;
1357 INSERT_PADDING_BYTES_NOINIT(3);
1358 Core::HID::NpadIdType npad_id;
1359 u64 applet_resource_user_id;
1360 };
1361 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1362
1363 const auto parameters{rp.PopRaw<Parameters>()};
1364
1365 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1366 const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled(
1367 parameters.is_enabled, parameters.npad_id);
1368
1369 LOG_DEBUG(Service_HID,
1370 "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
1371 parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
1372
1373 IPC::ResponseBuilder rb{ctx, 2};
1374 rb.Push(result);
1375}
1376
1377void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) {
1378 IPC::RequestParser rp{ctx};
1379 struct Parameters {
1380 Core::HID::NpadIdType npad_id;
1381 INSERT_PADDING_WORDS_NOINIT(1);
1382 u64 applet_resource_user_id;
1383 Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
1384 };
1385 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1386
1387 const auto parameters{rp.PopRaw<Parameters>()};
1388
1389 Core::HID::NpadIdType new_npad_id{};
1390 auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1391 const auto is_reassigned =
1392 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1393 Controller_NPad::NpadJoyAssignmentMode::Single);
1394
1395 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1396 parameters.npad_id, parameters.applet_resource_user_id,
1397 parameters.npad_joy_device_type);
1398
1399 IPC::ResponseBuilder rb{ctx, 4};
1400 rb.Push(ResultSuccess);
1401 rb.Push(is_reassigned);
1402 rb.PushEnum(new_npad_id);
1403}
1404
1405void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1406 IPC::RequestParser rp{ctx};
1407 struct Parameters {
1408 bool analog_stick_use_center_clamp;
1409 INSERT_PADDING_BYTES_NOINIT(7);
1410 u64 applet_resource_user_id;
1411 };
1412 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1413
1414 const auto parameters{rp.PopRaw<Parameters>()};
1415
1416 GetAppletResource()
1417 ->GetController<Controller_NPad>(HidController::NPad)
1418 .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp);
1419
1420 LOG_WARNING(Service_HID,
1421 "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
1422 parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
1423
1424 IPC::ResponseBuilder rb{ctx, 2};
1425 rb.Push(ResultSuccess);
1426}
1427
1428void Hid::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1429 IPC::RequestParser rp{ctx};
1430 struct Parameters {
1431 Core::HID::NpadStyleSet npad_styleset;
1432 INSERT_PADDING_WORDS_NOINIT(1);
1433 u64 applet_resource_user_id;
1434 Core::HID::NpadButton button;
1435 };
1436 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1437
1438 const auto parameters{rp.PopRaw<Parameters>()};
1439
1440 LOG_WARNING(Service_HID,
1441 "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
1442 parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
1443
1444 IPC::ResponseBuilder rb{ctx, 2};
1445 rb.Push(ResultSuccess);
1446}
1447
1448void Hid::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1449 IPC::RequestParser rp{ctx};
1450 const auto applet_resource_user_id{rp.Pop<u64>()};
1451
1452 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1453 applet_resource_user_id);
1454
1455 IPC::ResponseBuilder rb{ctx, 2};
1456 rb.Push(ResultSuccess);
1457}
1458
1459void Hid::GetVibrationDeviceInfo(HLERequestContext& ctx) {
1460 IPC::RequestParser rp{ctx};
1461 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
1462 const auto& controller =
1463 GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
1464
1465 Core::HID::VibrationDeviceInfo vibration_device_info;
1466 bool check_device_index = false;
1467
1468 switch (vibration_device_handle.npad_type) {
1469 case Core::HID::NpadStyleIndex::ProController:
1470 case Core::HID::NpadStyleIndex::Handheld:
1471 case Core::HID::NpadStyleIndex::JoyconDual:
1472 case Core::HID::NpadStyleIndex::JoyconLeft:
1473 case Core::HID::NpadStyleIndex::JoyconRight:
1474 vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
1475 check_device_index = true;
1476 break;
1477 case Core::HID::NpadStyleIndex::GameCube:
1478 vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
1479 break;
1480 case Core::HID::NpadStyleIndex::N64:
1481 vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
1482 break;
1483 default:
1484 vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
1485 break;
1486 }
1487
1488 vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
1489 if (check_device_index) {
1490 switch (vibration_device_handle.device_index) {
1491 case Core::HID::DeviceIndex::Left:
1492 vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
1493 break;
1494 case Core::HID::DeviceIndex::Right:
1495 vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
1496 break;
1497 case Core::HID::DeviceIndex::None:
1498 default:
1499 ASSERT_MSG(false, "DeviceIndex should never be None!");
1500 break;
1501 }
1502 }
1503
1504 LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
1505 vibration_device_info.type, vibration_device_info.position);
1506
1507 const auto result = controller.IsDeviceHandleValid(vibration_device_handle);
1508 if (result.IsError()) {
1509 IPC::ResponseBuilder rb{ctx, 2};
1510 rb.Push(result);
1511 return;
1512 }
1513
1514 IPC::ResponseBuilder rb{ctx, 4};
1515 rb.Push(ResultSuccess);
1516 rb.PushRaw(vibration_device_info);
1517}
1518
1519void Hid::SendVibrationValue(HLERequestContext& ctx) {
1520 IPC::RequestParser rp{ctx};
1521 struct Parameters {
1522 Core::HID::VibrationDeviceHandle vibration_device_handle;
1523 Core::HID::VibrationValue vibration_value;
1524 INSERT_PADDING_WORDS_NOINIT(1);
1525 u64 applet_resource_user_id;
1526 };
1527 static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
1528
1529 const auto parameters{rp.PopRaw<Parameters>()};
1530
1531 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1532 .VibrateController(parameters.vibration_device_handle, parameters.vibration_value);
1533
1534 LOG_DEBUG(Service_HID,
1535 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1536 parameters.vibration_device_handle.npad_type,
1537 parameters.vibration_device_handle.npad_id,
1538 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1539
1540 IPC::ResponseBuilder rb{ctx, 2};
1541 rb.Push(ResultSuccess);
1542}
1543
1544void Hid::GetActualVibrationValue(HLERequestContext& ctx) {
1545 IPC::RequestParser rp{ctx};
1546 struct Parameters {
1547 Core::HID::VibrationDeviceHandle vibration_device_handle;
1548 INSERT_PADDING_WORDS_NOINIT(1);
1549 u64 applet_resource_user_id;
1550 };
1551 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1552
1553 const auto parameters{rp.PopRaw<Parameters>()};
1554
1555 LOG_DEBUG(Service_HID,
1556 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1557 parameters.vibration_device_handle.npad_type,
1558 parameters.vibration_device_handle.npad_id,
1559 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1560
1561 IPC::ResponseBuilder rb{ctx, 6};
1562 rb.Push(ResultSuccess);
1563 rb.PushRaw(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1564 .GetLastVibration(parameters.vibration_device_handle));
1565}
1566
1567void Hid::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
1568 LOG_DEBUG(Service_HID, "called");
1569
1570 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1571 rb.Push(ResultSuccess);
1572 rb.PushIpcInterface<IActiveVibrationDeviceList>(system, applet_resource);
1573}
1574
1575void Hid::PermitVibration(HLERequestContext& ctx) {
1576 IPC::RequestParser rp{ctx};
1577 const auto can_vibrate{rp.Pop<bool>()};
1578
1579 // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
1580 // by converting it to a bool
1581 Settings::values.vibration_enabled.SetValue(can_vibrate);
1582
1583 LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
1584
1585 IPC::ResponseBuilder rb{ctx, 2};
1586 rb.Push(ResultSuccess);
1587}
1588
1589void Hid::IsVibrationPermitted(HLERequestContext& ctx) {
1590 LOG_DEBUG(Service_HID, "called");
1591
1592 // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
1593 const auto is_enabled = Settings::values.vibration_enabled.GetValue();
1594
1595 IPC::ResponseBuilder rb{ctx, 3};
1596 rb.Push(ResultSuccess);
1597 rb.Push(is_enabled);
1598}
1599
1600void Hid::SendVibrationValues(HLERequestContext& ctx) {
1601 IPC::RequestParser rp{ctx};
1602 const auto applet_resource_user_id{rp.Pop<u64>()};
1603
1604 const auto handle_data = ctx.ReadBuffer(0);
1605 const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0);
1606 const auto vibration_data = ctx.ReadBuffer(1);
1607 const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1);
1608
1609 auto vibration_device_handles =
1610 std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()),
1611 handle_count);
1612 auto vibration_values = std::span(
1613 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
1614
1615 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1616 .VibrateControllers(vibration_device_handles, vibration_values);
1617
1618 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1619
1620 IPC::ResponseBuilder rb{ctx, 2};
1621 rb.Push(ResultSuccess);
1622}
1623
1624void Hid::SendVibrationGcErmCommand(HLERequestContext& ctx) {
1625 IPC::RequestParser rp{ctx};
1626 struct Parameters {
1627 Core::HID::VibrationDeviceHandle vibration_device_handle;
1628 INSERT_PADDING_WORDS_NOINIT(1);
1629 u64 applet_resource_user_id;
1630 Core::HID::VibrationGcErmCommand gc_erm_command;
1631 };
1632 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1633
1634 const auto parameters{rp.PopRaw<Parameters>()};
1635
1636 /**
1637 * Note: This uses yuzu-specific behavior such that the StopHard command produces
1638 * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below,
1639 * in order to differentiate between Stop and StopHard commands.
1640 * This is done to reuse the controller vibration functions made for regular controllers.
1641 */
1642 const auto vibration_value = [parameters] {
1643 switch (parameters.gc_erm_command) {
1644 case Core::HID::VibrationGcErmCommand::Stop:
1645 return Core::HID::VibrationValue{
1646 .low_amplitude = 0.0f,
1647 .low_frequency = 160.0f,
1648 .high_amplitude = 0.0f,
1649 .high_frequency = 320.0f,
1650 };
1651 case Core::HID::VibrationGcErmCommand::Start:
1652 return Core::HID::VibrationValue{
1653 .low_amplitude = 1.0f,
1654 .low_frequency = 160.0f,
1655 .high_amplitude = 1.0f,
1656 .high_frequency = 320.0f,
1657 };
1658 case Core::HID::VibrationGcErmCommand::StopHard:
1659 return Core::HID::VibrationValue{
1660 .low_amplitude = 0.0f,
1661 .low_frequency = 0.0f,
1662 .high_amplitude = 0.0f,
1663 .high_frequency = 0.0f,
1664 };
1665 default:
1666 return Core::HID::DEFAULT_VIBRATION_VALUE;
1667 }
1668 }();
1669
1670 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1671 .VibrateController(parameters.vibration_device_handle, vibration_value);
1672
1673 LOG_DEBUG(Service_HID,
1674 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
1675 "gc_erm_command={}",
1676 parameters.vibration_device_handle.npad_type,
1677 parameters.vibration_device_handle.npad_id,
1678 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
1679 parameters.gc_erm_command);
1680
1681 IPC::ResponseBuilder rb{ctx, 2};
1682 rb.Push(ResultSuccess);
1683}
1684
1685void Hid::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
1686 IPC::RequestParser rp{ctx};
1687 struct Parameters {
1688 Core::HID::VibrationDeviceHandle vibration_device_handle;
1689 INSERT_PADDING_WORDS_NOINIT(1);
1690 u64 applet_resource_user_id;
1691 };
1692
1693 const auto parameters{rp.PopRaw<Parameters>()};
1694
1695 const auto last_vibration = applet_resource->GetController<Controller_NPad>(HidController::NPad)
1696 .GetLastVibration(parameters.vibration_device_handle);
1697
1698 const auto gc_erm_command = [last_vibration] {
1699 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
1700 return Core::HID::VibrationGcErmCommand::Start;
1701 }
1702
1703 /**
1704 * Note: This uses yuzu-specific behavior such that the StopHard command produces
1705 * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function
1706 * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands.
1707 * This is done to reuse the controller vibration functions made for regular controllers.
1708 */
1709 if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) {
1710 return Core::HID::VibrationGcErmCommand::StopHard;
1711 }
1712
1713 return Core::HID::VibrationGcErmCommand::Stop;
1714 }();
1715
1716 LOG_DEBUG(Service_HID,
1717 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1718 parameters.vibration_device_handle.npad_type,
1719 parameters.vibration_device_handle.npad_id,
1720 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1721
1722 IPC::ResponseBuilder rb{ctx, 4};
1723 rb.Push(ResultSuccess);
1724 rb.PushEnum(gc_erm_command);
1725}
1726
1727void Hid::BeginPermitVibrationSession(HLERequestContext& ctx) {
1728 IPC::RequestParser rp{ctx};
1729 const auto applet_resource_user_id{rp.Pop<u64>()};
1730
1731 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1732 .SetPermitVibrationSession(true);
1733
1734 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1735
1736 IPC::ResponseBuilder rb{ctx, 2};
1737 rb.Push(ResultSuccess);
1738}
1739
1740void Hid::EndPermitVibrationSession(HLERequestContext& ctx) {
1741 applet_resource->GetController<Controller_NPad>(HidController::NPad)
1742 .SetPermitVibrationSession(false);
1743
1744 LOG_DEBUG(Service_HID, "called");
1745
1746 IPC::ResponseBuilder rb{ctx, 2};
1747 rb.Push(ResultSuccess);
1748}
1749
1750void Hid::IsVibrationDeviceMounted(HLERequestContext& ctx) {
1751 IPC::RequestParser rp{ctx};
1752 struct Parameters {
1753 Core::HID::VibrationDeviceHandle vibration_device_handle;
1754 INSERT_PADDING_WORDS_NOINIT(1);
1755 u64 applet_resource_user_id;
1756 };
1757 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1758
1759 const auto parameters{rp.PopRaw<Parameters>()};
1760
1761 LOG_DEBUG(Service_HID,
1762 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1763 parameters.vibration_device_handle.npad_type,
1764 parameters.vibration_device_handle.npad_id,
1765 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1766
1767 IPC::ResponseBuilder rb{ctx, 3};
1768 rb.Push(ResultSuccess);
1769 rb.Push(applet_resource->GetController<Controller_NPad>(HidController::NPad)
1770 .IsVibrationDeviceMounted(parameters.vibration_device_handle));
1771}
1772
1773void Hid::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
1774 IPC::RequestParser rp{ctx};
1775 const auto applet_resource_user_id{rp.Pop<u64>()};
1776
1777 applet_resource->ActivateController(HidController::ConsoleSixAxisSensor);
1778
1779 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1780
1781 IPC::ResponseBuilder rb{ctx, 2};
1782 rb.Push(ResultSuccess);
1783}
1784
1785void Hid::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
1786 IPC::RequestParser rp{ctx};
1787 struct Parameters {
1788 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
1789 INSERT_PADDING_WORDS_NOINIT(1);
1790 u64 applet_resource_user_id;
1791 };
1792 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1793
1794 const auto parameters{rp.PopRaw<Parameters>()};
1795
1796 LOG_WARNING(Service_HID,
1797 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
1798 parameters.console_sixaxis_handle.unknown_1,
1799 parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
1800
1801 IPC::ResponseBuilder rb{ctx, 2};
1802 rb.Push(ResultSuccess);
1803}
1804
1805void Hid::StopConsoleSixAxisSensor(HLERequestContext& ctx) {
1806 IPC::RequestParser rp{ctx};
1807 struct Parameters {
1808 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
1809 INSERT_PADDING_WORDS_NOINIT(1);
1810 u64 applet_resource_user_id;
1811 };
1812 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1813
1814 const auto parameters{rp.PopRaw<Parameters>()};
1815
1816 LOG_WARNING(Service_HID,
1817 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
1818 parameters.console_sixaxis_handle.unknown_1,
1819 parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
1820
1821 IPC::ResponseBuilder rb{ctx, 2};
1822 rb.Push(ResultSuccess);
1823}
1824
1825void Hid::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
1826 IPC::RequestParser rp{ctx};
1827 const auto applet_resource_user_id{rp.Pop<u64>()};
1828
1829 applet_resource->ActivateController(HidController::ConsoleSixAxisSensor);
1830
1831 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1832
1833 IPC::ResponseBuilder rb{ctx, 2};
1834 rb.Push(ResultSuccess);
1835}
1836
1837void Hid::StartSevenSixAxisSensor(HLERequestContext& ctx) {
1838 IPC::RequestParser rp{ctx};
1839 const auto applet_resource_user_id{rp.Pop<u64>()};
1840
1841 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1842 applet_resource_user_id);
1843
1844 IPC::ResponseBuilder rb{ctx, 2};
1845 rb.Push(ResultSuccess);
1846}
1847
1848void Hid::StopSevenSixAxisSensor(HLERequestContext& ctx) {
1849 IPC::RequestParser rp{ctx};
1850 const auto applet_resource_user_id{rp.Pop<u64>()};
1851
1852 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1853 applet_resource_user_id);
1854
1855 IPC::ResponseBuilder rb{ctx, 2};
1856 rb.Push(ResultSuccess);
1857}
1858
1859void Hid::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
1860 IPC::RequestParser rp{ctx};
1861 const auto applet_resource_user_id{rp.Pop<u64>()};
1862 const auto t_mem_1_size{rp.Pop<u64>()};
1863 const auto t_mem_2_size{rp.Pop<u64>()};
1864 const auto t_mem_1_handle{ctx.GetCopyHandle(0)};
1865 const auto t_mem_2_handle{ctx.GetCopyHandle(1)};
1866
1867 ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
1868 ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
1869
1870 auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1871 t_mem_1_handle);
1872
1873 if (t_mem_1.IsNull()) {
1874 LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
1875 IPC::ResponseBuilder rb{ctx, 2};
1876 rb.Push(ResultUnknown);
1877 return;
1878 }
1879
1880 auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1881 t_mem_2_handle);
1882
1883 if (t_mem_2.IsNull()) {
1884 LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
1885 IPC::ResponseBuilder rb{ctx, 2};
1886 rb.Push(ResultUnknown);
1887 return;
1888 }
1889
1890 ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size");
1891 ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
1892
1893 // Activate console six axis controller
1894 applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1895 .ActivateController();
1896
1897 applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1898 .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
1899
1900 LOG_WARNING(Service_HID,
1901 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
1902 "applet_resource_user_id={}",
1903 t_mem_1_handle, t_mem_2_handle, applet_resource_user_id);
1904
1905 IPC::ResponseBuilder rb{ctx, 2};
1906 rb.Push(ResultSuccess);
1907}
1908
1909void Hid::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) {
1910 IPC::RequestParser rp{ctx};
1911 const auto applet_resource_user_id{rp.Pop<u64>()};
1912
1913 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1914 applet_resource_user_id);
1915
1916 IPC::ResponseBuilder rb{ctx, 2};
1917 rb.Push(ResultSuccess);
1918}
1919
1920void Hid::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
1921 IPC::RequestParser rp{ctx};
1922 const auto applet_resource_user_id{rp.Pop<u64>()};
1923
1924 applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1925 .ResetTimestamp();
1926
1927 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1928
1929 IPC::ResponseBuilder rb{ctx, 2};
1930 rb.Push(ResultSuccess);
1931}
1932
1933void Hid::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
1934 IPC::RequestParser rp{ctx};
1935
1936 LOG_WARNING(Service_HID, "(STUBBED) called");
1937
1938 IPC::ResponseBuilder rb{ctx, 3};
1939 rb.Push(ResultSuccess);
1940 rb.Push(false);
1941}
1942
1943void Hid::GetPalmaConnectionHandle(HLERequestContext& ctx) {
1944 IPC::RequestParser rp{ctx};
1945 struct Parameters {
1946 Core::HID::NpadIdType npad_id;
1947 INSERT_PADDING_WORDS_NOINIT(1);
1948 u64 applet_resource_user_id;
1949 };
1950 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1951
1952 const auto parameters{rp.PopRaw<Parameters>()};
1953
1954 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1955 parameters.npad_id, parameters.applet_resource_user_id);
1956
1957 Controller_Palma::PalmaConnectionHandle handle;
1958 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
1959 const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle);
1960
1961 IPC::ResponseBuilder rb{ctx, 4};
1962 rb.Push(result);
1963 rb.PushRaw(handle);
1964}
1965
1966void Hid::InitializePalma(HLERequestContext& ctx) {
1967 IPC::RequestParser rp{ctx};
1968 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1969
1970 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1971
1972 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
1973 const auto result = controller.InitializePalma(connection_handle);
1974
1975 IPC::ResponseBuilder rb{ctx, 2};
1976 rb.Push(result);
1977}
1978
1979void Hid::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
1980 IPC::RequestParser rp{ctx};
1981 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1982
1983 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1984
1985 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
1986
1987 IPC::ResponseBuilder rb{ctx, 2, 1};
1988 rb.Push(ResultSuccess);
1989 rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
1990}
1991
1992void Hid::GetPalmaOperationInfo(HLERequestContext& ctx) {
1993 IPC::RequestParser rp{ctx};
1994 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1995
1996 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1997
1998 Controller_Palma::PalmaOperationType operation_type;
1999 Controller_Palma::PalmaOperationData data;
2000 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2001 const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data);
2002
2003 if (result.IsError()) {
2004 IPC::ResponseBuilder rb{ctx, 2};
2005 rb.Push(result);
2006 }
2007
2008 ctx.WriteBuffer(data);
2009 IPC::ResponseBuilder rb{ctx, 4};
2010 rb.Push(result);
2011 rb.Push(static_cast<u64>(operation_type));
2012}
2013
2014void Hid::PlayPalmaActivity(HLERequestContext& ctx) {
2015 IPC::RequestParser rp{ctx};
2016 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2017 const auto palma_activity{rp.Pop<u64>()};
2018
2019 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
2020 connection_handle.npad_id, palma_activity);
2021
2022 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2023 const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity);
2024
2025 IPC::ResponseBuilder rb{ctx, 2};
2026 rb.Push(result);
2027}
2028
2029void Hid::SetPalmaFrModeType(HLERequestContext& ctx) {
2030 IPC::RequestParser rp{ctx};
2031 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2032 const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
2033
2034 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
2035 connection_handle.npad_id, fr_mode);
2036
2037 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2038 const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode);
2039
2040 IPC::ResponseBuilder rb{ctx, 2};
2041 rb.Push(result);
2042}
2043
2044void Hid::ReadPalmaStep(HLERequestContext& ctx) {
2045 IPC::RequestParser rp{ctx};
2046 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2047
2048 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2049
2050 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2051 const auto result = controller.ReadPalmaStep(connection_handle);
2052
2053 IPC::ResponseBuilder rb{ctx, 2};
2054 rb.Push(result);
2055}
2056
2057void Hid::EnablePalmaStep(HLERequestContext& ctx) {
2058 IPC::RequestParser rp{ctx};
2059 struct Parameters {
2060 bool is_enabled;
2061 INSERT_PADDING_WORDS_NOINIT(1);
2062 Controller_Palma::PalmaConnectionHandle connection_handle;
2063 };
2064 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2065
2066 const auto parameters{rp.PopRaw<Parameters>()};
2067
2068 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
2069 parameters.connection_handle.npad_id, parameters.is_enabled);
2070
2071 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2072 const auto result =
2073 controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
2074
2075 IPC::ResponseBuilder rb{ctx, 2};
2076 rb.Push(result);
2077}
2078
2079void Hid::ResetPalmaStep(HLERequestContext& ctx) {
2080 IPC::RequestParser rp{ctx};
2081 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2082
2083 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2084
2085 auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
2086 const auto result = controller.ResetPalmaStep(connection_handle);
2087
2088 IPC::ResponseBuilder rb{ctx, 2};
2089 rb.Push(result);
2090}
2091
2092void Hid::ReadPalmaApplicationSection(HLERequestContext& ctx) {
2093 LOG_WARNING(Service_HID, "(STUBBED) called");
2094
2095 IPC::ResponseBuilder rb{ctx, 2};
2096 rb.Push(ResultSuccess);
2097}
2098
2099void Hid::WritePalmaApplicationSection(HLERequestContext& ctx) {
2100 LOG_WARNING(Service_HID, "(STUBBED) called");
2101
2102 IPC::ResponseBuilder rb{ctx, 2};
2103 rb.Push(ResultSuccess);
2104}
2105
2106void Hid::ReadPalmaUniqueCode(HLERequestContext& ctx) {
2107 IPC::RequestParser rp{ctx};
2108 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2109
2110 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2111
2112 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2113 .ReadPalmaUniqueCode(connection_handle);
2114
2115 IPC::ResponseBuilder rb{ctx, 2};
2116 rb.Push(ResultSuccess);
2117}
2118
2119void Hid::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
2120 IPC::RequestParser rp{ctx};
2121 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2122
2123 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2124
2125 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2126 .SetPalmaUniqueCodeInvalid(connection_handle);
2127
2128 IPC::ResponseBuilder rb{ctx, 2};
2129 rb.Push(ResultSuccess);
2130}
2131
2132void Hid::WritePalmaActivityEntry(HLERequestContext& ctx) {
2133 LOG_CRITICAL(Service_HID, "(STUBBED) called");
2134
2135 IPC::ResponseBuilder rb{ctx, 2};
2136 rb.Push(ResultSuccess);
2137}
2138
2139void Hid::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
2140 IPC::RequestParser rp{ctx};
2141 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2142 const auto unknown{rp.Pop<u64>()};
2143
2144 [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
2145
2146 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
2147 connection_handle.npad_id, unknown);
2148
2149 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2150 .WritePalmaRgbLedPatternEntry(connection_handle, unknown);
2151
2152 IPC::ResponseBuilder rb{ctx, 2};
2153 rb.Push(ResultSuccess);
2154}
2155
2156void Hid::WritePalmaWaveEntry(HLERequestContext& ctx) {
2157 IPC::RequestParser rp{ctx};
2158 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2159 const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
2160 const auto unknown{rp.Pop<u64>()};
2161 const auto t_mem_size{rp.Pop<u64>()};
2162 const auto t_mem_handle{ctx.GetCopyHandle(0)};
2163 const auto size{rp.Pop<u64>()};
2164
2165 ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
2166
2167 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
2168 t_mem_handle);
2169
2170 if (t_mem.IsNull()) {
2171 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
2172 IPC::ResponseBuilder rb{ctx, 2};
2173 rb.Push(ResultUnknown);
2174 return;
2175 }
2176
2177 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
2178
2179 LOG_WARNING(Service_HID,
2180 "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
2181 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
2182 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2183
2184 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2185 .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
2186
2187 IPC::ResponseBuilder rb{ctx, 2};
2188 rb.Push(ResultSuccess);
2189}
2190
2191void Hid::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2192 IPC::RequestParser rp{ctx};
2193 struct Parameters {
2194 s32 database_id_version;
2195 INSERT_PADDING_WORDS_NOINIT(1);
2196 Controller_Palma::PalmaConnectionHandle connection_handle;
2197 };
2198 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2199
2200 const auto parameters{rp.PopRaw<Parameters>()};
2201
2202 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
2203 parameters.connection_handle.npad_id, parameters.database_id_version);
2204
2205 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2206 .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
2207 parameters.database_id_version);
2208
2209 IPC::ResponseBuilder rb{ctx, 2};
2210 rb.Push(ResultSuccess);
2211}
2212
2213void Hid::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2214 IPC::RequestParser rp{ctx};
2215 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2216
2217 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2218
2219 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2220 .GetPalmaDataBaseIdentificationVersion(connection_handle);
2221
2222 IPC::ResponseBuilder rb{ctx, 2};
2223 rb.Push(ResultSuccess);
2224}
2225
2226void Hid::SuspendPalmaFeature(HLERequestContext& ctx) {
2227 LOG_WARNING(Service_HID, "(STUBBED) called");
2228
2229 IPC::ResponseBuilder rb{ctx, 2};
2230 rb.Push(ResultSuccess);
2231}
2232
2233void Hid::GetPalmaOperationResult(HLERequestContext& ctx) {
2234 IPC::RequestParser rp{ctx};
2235 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2236
2237 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2238
2239 const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma)
2240 .GetPalmaOperationResult(connection_handle);
2241
2242 IPC::ResponseBuilder rb{ctx, 2};
2243 rb.Push(result);
2244}
2245
2246void Hid::ReadPalmaPlayLog(HLERequestContext& ctx) {
2247 LOG_WARNING(Service_HID, "(STUBBED) called");
2248
2249 IPC::ResponseBuilder rb{ctx, 2};
2250 rb.Push(ResultSuccess);
2251}
2252
2253void Hid::ResetPalmaPlayLog(HLERequestContext& ctx) {
2254 LOG_WARNING(Service_HID, "(STUBBED) called");
2255
2256 IPC::ResponseBuilder rb{ctx, 2};
2257 rb.Push(ResultSuccess);
2258}
2259
2260void Hid::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
2261 IPC::RequestParser rp{ctx};
2262 struct Parameters {
2263 bool is_palma_all_connectable;
2264 INSERT_PADDING_BYTES_NOINIT(7);
2265 u64 applet_resource_user_id;
2266 };
2267 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2268
2269 const auto parameters{rp.PopRaw<Parameters>()};
2270
2271 LOG_WARNING(Service_HID,
2272 "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
2273 parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
2274
2275 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2276 .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
2277
2278 IPC::ResponseBuilder rb{ctx, 2};
2279 rb.Push(ResultSuccess);
2280}
2281
2282void Hid::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
2283 LOG_WARNING(Service_HID, "(STUBBED) called");
2284
2285 IPC::ResponseBuilder rb{ctx, 2};
2286 rb.Push(ResultSuccess);
2287}
2288
2289void Hid::PairPalma(HLERequestContext& ctx) {
2290 IPC::RequestParser rp{ctx};
2291 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2292
2293 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2294
2295 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2296 .PairPalma(connection_handle);
2297
2298 IPC::ResponseBuilder rb{ctx, 2};
2299 rb.Push(ResultSuccess);
2300}
2301
2302void Hid::SetPalmaBoostMode(HLERequestContext& ctx) {
2303 IPC::RequestParser rp{ctx};
2304 const auto palma_boost_mode{rp.Pop<bool>()};
2305
2306 LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
2307
2308 applet_resource->GetController<Controller_Palma>(HidController::Palma)
2309 .SetPalmaBoostMode(palma_boost_mode);
2310
2311 IPC::ResponseBuilder rb{ctx, 2};
2312 rb.Push(ResultSuccess);
2313}
2314
2315void Hid::CancelWritePalmaWaveEntry(HLERequestContext& ctx) {
2316 LOG_WARNING(Service_HID, "(STUBBED) called");
2317
2318 IPC::ResponseBuilder rb{ctx, 2};
2319 rb.Push(ResultSuccess);
2320}
2321
2322void Hid::EnablePalmaBoostMode(HLERequestContext& ctx) {
2323 LOG_WARNING(Service_HID, "(STUBBED) called");
2324
2325 IPC::ResponseBuilder rb{ctx, 2};
2326 rb.Push(ResultSuccess);
2327}
2328
2329void Hid::GetPalmaBluetoothAddress(HLERequestContext& ctx) {
2330 LOG_WARNING(Service_HID, "(STUBBED) called");
2331
2332 IPC::ResponseBuilder rb{ctx, 2};
2333 rb.Push(ResultSuccess);
2334}
2335
2336void Hid::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
2337 LOG_WARNING(Service_HID, "(STUBBED) called");
2338
2339 IPC::ResponseBuilder rb{ctx, 2};
2340 rb.Push(ResultSuccess);
2341}
2342
2343void Hid::SetNpadCommunicationMode(HLERequestContext& ctx) {
2344 IPC::RequestParser rp{ctx};
2345 const auto applet_resource_user_id{rp.Pop<u64>()};
2346 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()};
2347
2348 applet_resource->GetController<Controller_NPad>(HidController::NPad)
2349 .SetNpadCommunicationMode(communication_mode);
2350
2351 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
2352 applet_resource_user_id, communication_mode);
2353
2354 IPC::ResponseBuilder rb{ctx, 2};
2355 rb.Push(ResultSuccess);
2356}
2357
2358void Hid::GetNpadCommunicationMode(HLERequestContext& ctx) {
2359 IPC::RequestParser rp{ctx};
2360
2361 LOG_WARNING(Service_HID, "(STUBBED) called");
2362
2363 IPC::ResponseBuilder rb{ctx, 4};
2364 rb.Push(ResultSuccess);
2365 rb.PushEnum(applet_resource->GetController<Controller_NPad>(HidController::NPad)
2366 .GetNpadCommunicationMode());
2367}
2368
2369void Hid::SetTouchScreenConfiguration(HLERequestContext& ctx) {
2370 IPC::RequestParser rp{ctx};
2371 const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()};
2372 const auto applet_resource_user_id{rp.Pop<u64>()};
2373
2374 LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}",
2375 touchscreen_mode.mode, applet_resource_user_id);
2376
2377 IPC::ResponseBuilder rb{ctx, 2};
2378 rb.Push(ResultSuccess);
2379}
2380
2381void Hid::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) {
2382 IPC::RequestParser rp{ctx};
2383 struct Parameters {
2384 s32 unknown;
2385 INSERT_PADDING_WORDS_NOINIT(1);
2386 u64 applet_resource_user_id;
2387 };
2388 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2389
2390 const auto parameters{rp.PopRaw<Parameters>()};
2391
2392 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
2393 parameters.unknown, parameters.applet_resource_user_id);
2394
2395 IPC::ResponseBuilder rb{ctx, 3};
2396 rb.Push(ResultSuccess);
2397 rb.Push(false);
2398}
2399
2400class HidDbg final : public ServiceFramework<HidDbg> {
2401public:
2402 explicit HidDbg(Core::System& system_) : ServiceFramework{system_, "hid:dbg"} {
2403 // clang-format off
2404 static const FunctionInfo functions[] = {
2405 {0, nullptr, "DeactivateDebugPad"},
2406 {1, nullptr, "SetDebugPadAutoPilotState"},
2407 {2, nullptr, "UnsetDebugPadAutoPilotState"},
2408 {10, nullptr, "DeactivateTouchScreen"},
2409 {11, nullptr, "SetTouchScreenAutoPilotState"},
2410 {12, nullptr, "UnsetTouchScreenAutoPilotState"},
2411 {13, nullptr, "GetTouchScreenConfiguration"},
2412 {14, nullptr, "ProcessTouchScreenAutoTune"},
2413 {15, nullptr, "ForceStopTouchScreenManagement"},
2414 {16, nullptr, "ForceRestartTouchScreenManagement"},
2415 {17, nullptr, "IsTouchScreenManaged"},
2416 {20, nullptr, "DeactivateMouse"},
2417 {21, nullptr, "SetMouseAutoPilotState"},
2418 {22, nullptr, "UnsetMouseAutoPilotState"},
2419 {25, nullptr, "SetDebugMouseAutoPilotState"},
2420 {26, nullptr, "UnsetDebugMouseAutoPilotState"},
2421 {30, nullptr, "DeactivateKeyboard"},
2422 {31, nullptr, "SetKeyboardAutoPilotState"},
2423 {32, nullptr, "UnsetKeyboardAutoPilotState"},
2424 {50, nullptr, "DeactivateXpad"},
2425 {51, nullptr, "SetXpadAutoPilotState"},
2426 {52, nullptr, "UnsetXpadAutoPilotState"},
2427 {53, nullptr, "DeactivateJoyXpad"},
2428 {60, nullptr, "ClearNpadSystemCommonPolicy"},
2429 {61, nullptr, "DeactivateNpad"},
2430 {62, nullptr, "ForceDisconnectNpad"},
2431 {91, nullptr, "DeactivateGesture"},
2432 {110, nullptr, "DeactivateHomeButton"},
2433 {111, nullptr, "SetHomeButtonAutoPilotState"},
2434 {112, nullptr, "UnsetHomeButtonAutoPilotState"},
2435 {120, nullptr, "DeactivateSleepButton"},
2436 {121, nullptr, "SetSleepButtonAutoPilotState"},
2437 {122, nullptr, "UnsetSleepButtonAutoPilotState"},
2438 {123, nullptr, "DeactivateInputDetector"},
2439 {130, nullptr, "DeactivateCaptureButton"},
2440 {131, nullptr, "SetCaptureButtonAutoPilotState"},
2441 {132, nullptr, "UnsetCaptureButtonAutoPilotState"},
2442 {133, nullptr, "SetShiftAccelerometerCalibrationValue"},
2443 {134, nullptr, "GetShiftAccelerometerCalibrationValue"},
2444 {135, nullptr, "SetShiftGyroscopeCalibrationValue"},
2445 {136, nullptr, "GetShiftGyroscopeCalibrationValue"},
2446 {140, nullptr, "DeactivateConsoleSixAxisSensor"},
2447 {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
2448 {142, nullptr, "DeactivateSevenSixAxisSensor"},
2449 {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
2450 {144, nullptr, "GetAccelerometerFsr"},
2451 {145, nullptr, "SetAccelerometerFsr"},
2452 {146, nullptr, "GetAccelerometerOdr"},
2453 {147, nullptr, "SetAccelerometerOdr"},
2454 {148, nullptr, "GetGyroscopeFsr"},
2455 {149, nullptr, "SetGyroscopeFsr"},
2456 {150, nullptr, "GetGyroscopeOdr"},
2457 {151, nullptr, "SetGyroscopeOdr"},
2458 {152, nullptr, "GetWhoAmI"},
2459 {201, nullptr, "ActivateFirmwareUpdate"},
2460 {202, nullptr, "DeactivateFirmwareUpdate"},
2461 {203, nullptr, "StartFirmwareUpdate"},
2462 {204, nullptr, "GetFirmwareUpdateStage"},
2463 {205, nullptr, "GetFirmwareVersion"},
2464 {206, nullptr, "GetDestinationFirmwareVersion"},
2465 {207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
2466 {208, nullptr, "StartFirmwareUpdateForRevert"},
2467 {209, nullptr, "GetAvailableFirmwareVersionForRevert"},
2468 {210, nullptr, "IsFirmwareUpdatingDevice"},
2469 {211, nullptr, "StartFirmwareUpdateIndividual"},
2470 {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
2471 {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
2472 {221, nullptr, "UpdateControllerColor"},
2473 {222, nullptr, "ConnectUsbPadsAsync"},
2474 {223, nullptr, "DisconnectUsbPadsAsync"},
2475 {224, nullptr, "UpdateDesignInfo"},
2476 {225, nullptr, "GetUniquePadDriverState"},
2477 {226, nullptr, "GetSixAxisSensorDriverStates"},
2478 {227, nullptr, "GetRxPacketHistory"},
2479 {228, nullptr, "AcquireOperationEventHandle"},
2480 {229, nullptr, "ReadSerialFlash"},
2481 {230, nullptr, "WriteSerialFlash"},
2482 {231, nullptr, "GetOperationResult"},
2483 {232, nullptr, "EnableShipmentMode"},
2484 {233, nullptr, "ClearPairingInfo"},
2485 {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
2486 {235, nullptr, "EnableAnalogStickPower"},
2487 {236, nullptr, "RequestKuinaUartClockCal"},
2488 {237, nullptr, "GetKuinaUartClockCal"},
2489 {238, nullptr, "SetKuinaUartClockTrim"},
2490 {239, nullptr, "KuinaLoopbackTest"},
2491 {240, nullptr, "RequestBatteryVoltage"},
2492 {241, nullptr, "GetBatteryVoltage"},
2493 {242, nullptr, "GetUniquePadPowerInfo"},
2494 {243, nullptr, "RebootUniquePad"},
2495 {244, nullptr, "RequestKuinaFirmwareVersion"},
2496 {245, nullptr, "GetKuinaFirmwareVersion"},
2497 {246, nullptr, "GetVidPid"},
2498 {247, nullptr, "GetAnalogStickCalibrationValue"},
2499 {248, nullptr, "GetUniquePadIdsFull"},
2500 {249, nullptr, "ConnectUniquePad"},
2501 {250, nullptr, "IsVirtual"},
2502 {251, nullptr, "GetAnalogStickModuleParam"},
2503 {301, nullptr, "GetAbstractedPadHandles"},
2504 {302, nullptr, "GetAbstractedPadState"},
2505 {303, nullptr, "GetAbstractedPadsState"},
2506 {321, nullptr, "SetAutoPilotVirtualPadState"},
2507 {322, nullptr, "UnsetAutoPilotVirtualPadState"},
2508 {323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
2509 {324, nullptr, "AttachHdlsWorkBuffer"},
2510 {325, nullptr, "ReleaseHdlsWorkBuffer"},
2511 {326, nullptr, "DumpHdlsNpadAssignmentState"},
2512 {327, nullptr, "DumpHdlsStates"},
2513 {328, nullptr, "ApplyHdlsNpadAssignmentState"},
2514 {329, nullptr, "ApplyHdlsStateList"},
2515 {330, nullptr, "AttachHdlsVirtualDevice"},
2516 {331, nullptr, "DetachHdlsVirtualDevice"},
2517 {332, nullptr, "SetHdlsState"},
2518 {350, nullptr, "AddRegisteredDevice"},
2519 {400, nullptr, "DisableExternalMcuOnNxDevice"},
2520 {401, nullptr, "DisableRailDeviceFiltering"},
2521 {402, nullptr, "EnableWiredPairing"},
2522 {403, nullptr, "EnableShipmentModeAutoClear"},
2523 {404, nullptr, "SetRailEnabled"},
2524 {500, nullptr, "SetFactoryInt"},
2525 {501, nullptr, "IsFactoryBootEnabled"},
2526 {550, nullptr, "SetAnalogStickModelDataTemporarily"},
2527 {551, nullptr, "GetAnalogStickModelData"},
2528 {552, nullptr, "ResetAnalogStickModelData"},
2529 {600, nullptr, "ConvertPadState"},
2530 {650, nullptr, "AddButtonPlayData"},
2531 {651, nullptr, "StartButtonPlayData"},
2532 {652, nullptr, "StopButtonPlayData"},
2533 {2000, nullptr, "DeactivateDigitizer"},
2534 {2001, nullptr, "SetDigitizerAutoPilotState"},
2535 {2002, nullptr, "UnsetDigitizerAutoPilotState"},
2536 {2002, nullptr, "ReloadFirmwareDebugSettings"},
2537 };
2538 // clang-format on
2539
2540 RegisterHandlers(functions);
2541 }
2542};
2543
2544class HidSys final : public ServiceFramework<HidSys> {
2545public:
2546 explicit HidSys(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_)
2547 : ServiceFramework{system_, "hid:sys"}, service_context{system_, "hid:sys"},
2548 applet_resource{applet_resource_} {
2549 // clang-format off
2550 static const FunctionInfo functions[] = {
2551 {31, nullptr, "SendKeyboardLockKeyEvent"},
2552 {101, nullptr, "AcquireHomeButtonEventHandle"},
2553 {111, nullptr, "ActivateHomeButton"},
2554 {121, nullptr, "AcquireSleepButtonEventHandle"},
2555 {131, nullptr, "ActivateSleepButton"},
2556 {141, nullptr, "AcquireCaptureButtonEventHandle"},
2557 {151, nullptr, "ActivateCaptureButton"},
2558 {161, nullptr, "GetPlatformConfig"},
2559 {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
2560 {211, nullptr, "GetNpadsWithNfc"},
2561 {212, nullptr, "AcquireNfcActivateEventHandle"},
2562 {213, nullptr, "ActivateNfc"},
2563 {214, nullptr, "GetXcdHandleForNpadWithNfc"},
2564 {215, nullptr, "IsNfcActivated"},
2565 {230, nullptr, "AcquireIrSensorEventHandle"},
2566 {231, nullptr, "ActivateIrSensor"},
2567 {232, nullptr, "GetIrSensorState"},
2568 {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
2569 {301, nullptr, "ActivateNpadSystem"},
2570 {303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
2571 {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
2572 {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
2573 {306, &HidSys::GetLastActiveNpad, "GetLastActiveNpad"},
2574 {307, nullptr, "GetNpadSystemExtStyle"},
2575 {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
2576 {309, nullptr, "GetNpadFullKeyGripColor"},
2577 {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
2578 {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
2579 {312, nullptr, "SetSupportedNpadStyleSetAll"},
2580 {313, nullptr, "GetNpadCaptureButtonAssignment"},
2581 {314, nullptr, "GetAppletFooterUiType"},
2582 {315, nullptr, "GetAppletDetailedUiType"},
2583 {316, nullptr, "GetNpadInterfaceType"},
2584 {317, nullptr, "GetNpadLeftRightInterfaceType"},
2585 {318, nullptr, "HasBattery"},
2586 {319, nullptr, "HasLeftRightBattery"},
2587 {321, &HidSys::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
2588 {322, nullptr, "GetIrSensorState"},
2589 {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
2590 {324, nullptr, "GetUniquePadButtonSet"},
2591 {325, nullptr, "GetUniquePadColor"},
2592 {326, nullptr, "GetUniquePadAppletDetailedUiType"},
2593 {327, nullptr, "GetAbstractedPadIdDataFromNpad"},
2594 {328, nullptr, "AttachAbstractedPadToNpad"},
2595 {329, nullptr, "DetachAbstractedPadAll"},
2596 {330, nullptr, "CheckAbstractedPadConnection"},
2597 {500, nullptr, "SetAppletResourceUserId"},
2598 {501, nullptr, "RegisterAppletResourceUserId"},
2599 {502, nullptr, "UnregisterAppletResourceUserId"},
2600 {503, nullptr, "EnableAppletToGetInput"},
2601 {504, nullptr, "SetAruidValidForVibration"},
2602 {505, nullptr, "EnableAppletToGetSixAxisSensor"},
2603 {506, nullptr, "EnableAppletToGetPadInput"},
2604 {507, nullptr, "EnableAppletToGetTouchScreen"},
2605 {510, nullptr, "SetVibrationMasterVolume"},
2606 {511, nullptr, "GetVibrationMasterVolume"},
2607 {512, nullptr, "BeginPermitVibrationSession"},
2608 {513, nullptr, "EndPermitVibrationSession"},
2609 {514, nullptr, "Unknown514"},
2610 {520, nullptr, "EnableHandheldHids"},
2611 {521, nullptr, "DisableHandheldHids"},
2612 {522, nullptr, "SetJoyConRailEnabled"},
2613 {523, nullptr, "IsJoyConRailEnabled"},
2614 {524, nullptr, "IsHandheldHidsEnabled"},
2615 {525, nullptr, "IsJoyConAttachedOnAllRail"},
2616 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
2617 {541, nullptr, "GetPlayReportControllerUsages"},
2618 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
2619 {543, nullptr, "GetRegisteredDevicesOld"},
2620 {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
2621 {545, nullptr, "SendConnectionTrigger"},
2622 {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
2623 {547, nullptr, "GetAllowedBluetoothLinksCount"},
2624 {548, nullptr, "GetRegisteredDevices"},
2625 {549, nullptr, "GetConnectableRegisteredDevices"},
2626 {700, nullptr, "ActivateUniquePad"},
2627 {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
2628 {703, nullptr, "GetUniquePadIds"},
2629 {751, &HidSys::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
2630 {800, nullptr, "ListSixAxisSensorHandles"},
2631 {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
2632 {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
2633 {803, nullptr, "StartSixAxisSensorUserCalibration"},
2634 {804, nullptr, "CancelSixAxisSensorUserCalibration"},
2635 {805, nullptr, "GetUniquePadBluetoothAddress"},
2636 {806, nullptr, "DisconnectUniquePad"},
2637 {807, nullptr, "GetUniquePadType"},
2638 {808, nullptr, "GetUniquePadInterface"},
2639 {809, nullptr, "GetUniquePadSerialNumber"},
2640 {810, nullptr, "GetUniquePadControllerNumber"},
2641 {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
2642 {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
2643 {821, nullptr, "StartAnalogStickManualCalibration"},
2644 {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
2645 {823, nullptr, "CancelAnalogStickManualCalibration"},
2646 {824, nullptr, "ResetAnalogStickManualCalibration"},
2647 {825, nullptr, "GetAnalogStickState"},
2648 {826, nullptr, "GetAnalogStickManualCalibrationStage"},
2649 {827, nullptr, "IsAnalogStickButtonPressed"},
2650 {828, nullptr, "IsAnalogStickInReleasePosition"},
2651 {829, nullptr, "IsAnalogStickInCircumference"},
2652 {830, nullptr, "SetNotificationLedPattern"},
2653 {831, nullptr, "SetNotificationLedPatternWithTimeout"},
2654 {832, nullptr, "PrepareHidsForNotificationWake"},
2655 {850, &HidSys::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
2656 {851, nullptr, "EnableUsbFullKeyController"},
2657 {852, nullptr, "IsUsbConnected"},
2658 {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
2659 {900, nullptr, "ActivateInputDetector"},
2660 {901, nullptr, "NotifyInputDetector"},
2661 {1000, nullptr, "InitializeFirmwareUpdate"},
2662 {1001, nullptr, "GetFirmwareVersion"},
2663 {1002, nullptr, "GetAvailableFirmwareVersion"},
2664 {1003, nullptr, "IsFirmwareUpdateAvailable"},
2665 {1004, nullptr, "CheckFirmwareUpdateRequired"},
2666 {1005, nullptr, "StartFirmwareUpdate"},
2667 {1006, nullptr, "AbortFirmwareUpdate"},
2668 {1007, nullptr, "GetFirmwareUpdateState"},
2669 {1008, nullptr, "ActivateAudioControl"},
2670 {1009, nullptr, "AcquireAudioControlEventHandle"},
2671 {1010, nullptr, "GetAudioControlStates"},
2672 {1011, nullptr, "DeactivateAudioControl"},
2673 {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
2674 {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
2675 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
2676 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
2677 {1100, nullptr, "GetHidbusSystemServiceObject"},
2678 {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
2679 {1130, nullptr, "InitializeUsbFirmwareUpdate"},
2680 {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
2681 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
2682 {1133, nullptr, "StartUsbFirmwareUpdate"},
2683 {1134, nullptr, "GetUsbFirmwareUpdateState"},
2684 {1150, nullptr, "SetTouchScreenMagnification"},
2685 {1151, nullptr, "GetTouchScreenFirmwareVersion"},
2686 {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
2687 {1153, &HidSys::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
2688 {1154, nullptr, "IsFirmwareAvailableForNotification"},
2689 {1155, nullptr, "SetForceHandheldStyleVibration"},
2690 {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
2691 {1157, nullptr, "CancelConnectionTrigger"},
2692 {1200, nullptr, "IsButtonConfigSupported"},
2693 {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
2694 {1202, nullptr, "DeleteButtonConfig"},
2695 {1203, nullptr, "DeleteButtonConfigEmbedded"},
2696 {1204, nullptr, "SetButtonConfigEnabled"},
2697 {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
2698 {1206, nullptr, "IsButtonConfigEnabled"},
2699 {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
2700 {1208, nullptr, "SetButtonConfigEmbedded"},
2701 {1209, nullptr, "SetButtonConfigFull"},
2702 {1210, nullptr, "SetButtonConfigLeft"},
2703 {1211, nullptr, "SetButtonConfigRight"},
2704 {1212, nullptr, "GetButtonConfigEmbedded"},
2705 {1213, nullptr, "GetButtonConfigFull"},
2706 {1214, nullptr, "GetButtonConfigLeft"},
2707 {1215, nullptr, "GetButtonConfigRight"},
2708 {1250, nullptr, "IsCustomButtonConfigSupported"},
2709 {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
2710 {1252, nullptr, "IsDefaultButtonConfigFull"},
2711 {1253, nullptr, "IsDefaultButtonConfigLeft"},
2712 {1254, nullptr, "IsDefaultButtonConfigRight"},
2713 {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
2714 {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
2715 {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
2716 {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
2717 {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
2718 {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
2719 {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
2720 {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
2721 {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
2722 {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
2723 {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
2724 {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
2725 {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
2726 {1268, nullptr, "DeleteButtonConfigStorageFull"},
2727 {1269, nullptr, "DeleteButtonConfigStorageLeft"},
2728 {1270, nullptr, "DeleteButtonConfigStorageRight"},
2729 {1271, nullptr, "IsUsingCustomButtonConfig"},
2730 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
2731 {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
2732 {1274, nullptr, "SetDefaultButtonConfig"},
2733 {1275, nullptr, "SetAllDefaultButtonConfig"},
2734 {1276, nullptr, "SetHidButtonConfigEmbedded"},
2735 {1277, nullptr, "SetHidButtonConfigFull"},
2736 {1278, nullptr, "SetHidButtonConfigLeft"},
2737 {1279, nullptr, "SetHidButtonConfigRight"},
2738 {1280, nullptr, "GetHidButtonConfigEmbedded"},
2739 {1281, nullptr, "GetHidButtonConfigFull"},
2740 {1282, nullptr, "GetHidButtonConfigLeft"},
2741 {1283, nullptr, "GetHidButtonConfigRight"},
2742 {1284, nullptr, "GetButtonConfigStorageEmbedded"},
2743 {1285, nullptr, "GetButtonConfigStorageFull"},
2744 {1286, nullptr, "GetButtonConfigStorageLeft"},
2745 {1287, nullptr, "GetButtonConfigStorageRight"},
2746 {1288, nullptr, "SetButtonConfigStorageEmbedded"},
2747 {1289, nullptr, "SetButtonConfigStorageFull"},
2748 {1290, nullptr, "DeleteButtonConfigStorageRight"},
2749 {1291, nullptr, "DeleteButtonConfigStorageRight"},
2750 };
2751 // clang-format on
2752
2753 RegisterHandlers(functions);
2754
2755 joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
2756 }
2757
2758 ~HidSys() {
2759 service_context.CloseEvent(joy_detach_event);
2760 };
2761
2762private:
2763 void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
2764 LOG_WARNING(Service_HID, "called");
2765
2766 GetAppletResource()
2767 ->GetController<Controller_NPad>(HidController::NPad)
2768 .ApplyNpadSystemCommonPolicy();
2769
2770 IPC::ResponseBuilder rb{ctx, 2};
2771 rb.Push(ResultSuccess);
2772 }
2773
2774 void GetLastActiveNpad(HLERequestContext& ctx) {
2775 LOG_DEBUG(Service_HID, "(STUBBED) called");
2776
2777 IPC::ResponseBuilder rb{ctx, 3};
2778 rb.Push(ResultSuccess);
2779 rb.PushEnum(system.HIDCore().GetLastActiveController());
2780 }
2781
2782 void GetUniquePadsFromNpad(HLERequestContext& ctx) {
2783 IPC::RequestParser rp{ctx};
2784 const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
2785
2786 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
2787
2788 const std::vector<Core::HID::UniquePadId> unique_pads{};
2789
2790 ctx.WriteBuffer(unique_pads);
2791
2792 IPC::ResponseBuilder rb{ctx, 3};
2793 rb.Push(ResultSuccess);
2794 rb.Push(static_cast<u32>(unique_pads.size()));
2795 }
2796
2797 void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
2798 LOG_INFO(Service_AM, "called");
2799
2800 IPC::ResponseBuilder rb{ctx, 2, 1};
2801 rb.Push(ResultSuccess);
2802 rb.PushCopyObjects(joy_detach_event->GetReadableEvent());
2803 }
2804
2805 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
2806 const bool is_enabled = false;
2807
2808 LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
2809
2810 IPC::ResponseBuilder rb{ctx, 3};
2811 rb.Push(ResultSuccess);
2812 rb.Push(is_enabled);
2813 }
2814
2815 void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
2816 LOG_WARNING(Service_HID, "(STUBBED) called");
2817
2818 Core::HID::TouchScreenConfigurationForNx touchscreen_config{
2819 .mode = Core::HID::TouchScreenModeForNx::Finger,
2820 };
2821
2822 if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
2823 touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
2824 touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
2825 }
2826
2827 IPC::ResponseBuilder rb{ctx, 6};
2828 rb.Push(ResultSuccess);
2829 rb.PushRaw(touchscreen_config);
2830 }
2831
2832 std::shared_ptr<IAppletResource> GetAppletResource() {
2833 if (applet_resource == nullptr) {
2834 applet_resource = std::make_shared<IAppletResource>(system, service_context);
2835 }
2836
2837 return applet_resource;
2838 }
2839
2840 Kernel::KEvent* joy_detach_event;
2841 KernelHelpers::ServiceContext service_context;
2842 std::shared_ptr<IAppletResource> applet_resource;
2843};
2844
2845void LoopProcess(Core::System& system) { 16void LoopProcess(Core::System& system) {
2846 auto server_manager = std::make_unique<ServerManager>(system); 17 auto server_manager = std::make_unique<ServerManager>(system);
2847 std::shared_ptr<IAppletResource> applet_resource; 18 std::shared_ptr<ResourceManager> resouce_manager = std::make_shared<ResourceManager>(system);
19
20 server_manager->RegisterNamedService("hid",
21 std::make_shared<IHidServer>(system, resouce_manager));
22 server_manager->RegisterNamedService(
23 "hid:dbg", std::make_shared<IHidDebugServer>(system, resouce_manager));
24 server_manager->RegisterNamedService(
25 "hid:sys", std::make_shared<IHidSystemServer>(system, resouce_manager));
2848 26
2849 server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system, applet_resource));
2850 server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system)); 27 server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
2851 server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system));
2852 server_manager->RegisterNamedService("hid:sys",
2853 std::make_shared<HidSys>(system, applet_resource));
2854 28
2855 server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system)); 29 server_manager->RegisterNamedService("irs", std::make_shared<IRS::IRS>(system));
2856 server_manager->RegisterNamedService("irs:sys", 30 server_manager->RegisterNamedService("irs:sys", std::make_shared<IRS::IRS_SYS>(system));
2857 std::make_shared<Service::IRS::IRS_SYS>(system));
2858 31
2859 server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system)); 32 server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system));
33
2860 system.RunServer(std::move(server_manager)); 34 system.RunServer(std::move(server_manager));
2861} 35}
2862 36
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 0ca43de93..ec5463f4e 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -3,220 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <chrono> 6namespace Core {
7 7class System;
8#include "core/hle/service/hid/controllers/controller_base.h"
9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/service.h"
11
12namespace Core::Timing {
13struct EventType;
14}
15
16namespace Service::SM {
17class ServiceManager;
18} 8}
19 9
20namespace Service::HID { 10namespace Service::HID {
21 11
22enum class HidController : std::size_t {
23 DebugPad,
24 Touchscreen,
25 Mouse,
26 Keyboard,
27 XPad,
28 HomeButton,
29 SleepButton,
30 CaptureButton,
31 InputDetector,
32 UniquePad,
33 NPad,
34 Gesture,
35 ConsoleSixAxisSensor,
36 DebugMouse,
37 Palma,
38
39 MaxControllers,
40};
41
42class IAppletResource final : public ServiceFramework<IAppletResource> {
43public:
44 explicit IAppletResource(Core::System& system_,
45 KernelHelpers::ServiceContext& service_context_);
46 ~IAppletResource() override;
47
48 void ActivateController(HidController controller);
49 void DeactivateController(HidController controller);
50
51 template <typename T>
52 T& GetController(HidController controller) {
53 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
54 }
55
56 template <typename T>
57 const T& GetController(HidController controller) const {
58 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
59 }
60
61private:
62 template <typename T>
63 void MakeController(HidController controller, u8* shared_memory) {
64 if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
65 controllers[static_cast<std::size_t>(controller)] =
66 std::make_unique<T>(system, shared_memory);
67 } else {
68 controllers[static_cast<std::size_t>(controller)] =
69 std::make_unique<T>(system.HIDCore(), shared_memory);
70 }
71 }
72
73 template <typename T>
74 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
75 controllers[static_cast<std::size_t>(controller)] =
76 std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
77 }
78
79 void GetSharedMemoryHandle(HLERequestContext& ctx);
80 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
81 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
82 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
83 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
84
85 KernelHelpers::ServiceContext& service_context;
86
87 std::shared_ptr<Core::Timing::EventType> npad_update_event;
88 std::shared_ptr<Core::Timing::EventType> default_update_event;
89 std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
90 std::shared_ptr<Core::Timing::EventType> motion_update_event;
91
92 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
93 controllers{};
94};
95
96class Hid final : public ServiceFramework<Hid> {
97public:
98 explicit Hid(Core::System& system_, std::shared_ptr<IAppletResource> applet_resource_);
99 ~Hid() override;
100
101 std::shared_ptr<IAppletResource> GetAppletResource();
102
103private:
104 void CreateAppletResource(HLERequestContext& ctx);
105 void ActivateDebugPad(HLERequestContext& ctx);
106 void ActivateTouchScreen(HLERequestContext& ctx);
107 void ActivateMouse(HLERequestContext& ctx);
108 void ActivateKeyboard(HLERequestContext& ctx);
109 void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
110 void ActivateXpad(HLERequestContext& ctx);
111 void GetXpadIDs(HLERequestContext& ctx);
112 void ActivateSixAxisSensor(HLERequestContext& ctx);
113 void DeactivateSixAxisSensor(HLERequestContext& ctx);
114 void StartSixAxisSensor(HLERequestContext& ctx);
115 void StopSixAxisSensor(HLERequestContext& ctx);
116 void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
117 void EnableSixAxisSensorFusion(HLERequestContext& ctx);
118 void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
119 void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
120 void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
121 void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
122 void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
123 void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
124 void IsSixAxisSensorAtRest(HLERequestContext& ctx);
125 void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
126 void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
127 void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
128 void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
129 void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
130 void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
131 void ActivateGesture(HLERequestContext& ctx);
132 void SetSupportedNpadStyleSet(HLERequestContext& ctx);
133 void GetSupportedNpadStyleSet(HLERequestContext& ctx);
134 void SetSupportedNpadIdType(HLERequestContext& ctx);
135 void ActivateNpad(HLERequestContext& ctx);
136 void DeactivateNpad(HLERequestContext& ctx);
137 void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
138 void DisconnectNpad(HLERequestContext& ctx);
139 void GetPlayerLedPattern(HLERequestContext& ctx);
140 void ActivateNpadWithRevision(HLERequestContext& ctx);
141 void SetNpadJoyHoldType(HLERequestContext& ctx);
142 void GetNpadJoyHoldType(HLERequestContext& ctx);
143 void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
144 void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
145 void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
146 void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
147 void StartLrAssignmentMode(HLERequestContext& ctx);
148 void StopLrAssignmentMode(HLERequestContext& ctx);
149 void SetNpadHandheldActivationMode(HLERequestContext& ctx);
150 void GetNpadHandheldActivationMode(HLERequestContext& ctx);
151 void SwapNpadAssignment(HLERequestContext& ctx);
152 void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
153 void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
154 void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
155 void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
156 void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
157 void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
158 void GetVibrationDeviceInfo(HLERequestContext& ctx);
159 void SendVibrationValue(HLERequestContext& ctx);
160 void GetActualVibrationValue(HLERequestContext& ctx);
161 void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
162 void PermitVibration(HLERequestContext& ctx);
163 void IsVibrationPermitted(HLERequestContext& ctx);
164 void SendVibrationValues(HLERequestContext& ctx);
165 void SendVibrationGcErmCommand(HLERequestContext& ctx);
166 void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
167 void BeginPermitVibrationSession(HLERequestContext& ctx);
168 void EndPermitVibrationSession(HLERequestContext& ctx);
169 void IsVibrationDeviceMounted(HLERequestContext& ctx);
170 void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
171 void StartConsoleSixAxisSensor(HLERequestContext& ctx);
172 void StopConsoleSixAxisSensor(HLERequestContext& ctx);
173 void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
174 void StartSevenSixAxisSensor(HLERequestContext& ctx);
175 void StopSevenSixAxisSensor(HLERequestContext& ctx);
176 void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
177 void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
178 void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
179 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
180 void GetPalmaConnectionHandle(HLERequestContext& ctx);
181 void InitializePalma(HLERequestContext& ctx);
182 void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
183 void GetPalmaOperationInfo(HLERequestContext& ctx);
184 void PlayPalmaActivity(HLERequestContext& ctx);
185 void SetPalmaFrModeType(HLERequestContext& ctx);
186 void ReadPalmaStep(HLERequestContext& ctx);
187 void EnablePalmaStep(HLERequestContext& ctx);
188 void ResetPalmaStep(HLERequestContext& ctx);
189 void ReadPalmaApplicationSection(HLERequestContext& ctx);
190 void WritePalmaApplicationSection(HLERequestContext& ctx);
191 void ReadPalmaUniqueCode(HLERequestContext& ctx);
192 void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
193 void WritePalmaActivityEntry(HLERequestContext& ctx);
194 void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
195 void WritePalmaWaveEntry(HLERequestContext& ctx);
196 void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
197 void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
198 void SuspendPalmaFeature(HLERequestContext& ctx);
199 void GetPalmaOperationResult(HLERequestContext& ctx);
200 void ReadPalmaPlayLog(HLERequestContext& ctx);
201 void ResetPalmaPlayLog(HLERequestContext& ctx);
202 void SetIsPalmaAllConnectable(HLERequestContext& ctx);
203 void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
204 void PairPalma(HLERequestContext& ctx);
205 void SetPalmaBoostMode(HLERequestContext& ctx);
206 void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
207 void EnablePalmaBoostMode(HLERequestContext& ctx);
208 void GetPalmaBluetoothAddress(HLERequestContext& ctx);
209 void SetDisallowedPalmaConnection(HLERequestContext& ctx);
210 void SetNpadCommunicationMode(HLERequestContext& ctx);
211 void GetNpadCommunicationMode(HLERequestContext& ctx);
212 void SetTouchScreenConfiguration(HLERequestContext& ctx);
213 void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
214
215 std::shared_ptr<IAppletResource> applet_resource;
216
217 KernelHelpers::ServiceContext service_context;
218};
219
220void LoopProcess(Core::System& system); 12void LoopProcess(Core::System& system);
221 13
222} // namespace Service::HID 14} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp
new file mode 100644
index 000000000..6294f3dfb
--- /dev/null
+++ b/src/core/hle/service/hid/hid_debug_server.cpp
@@ -0,0 +1,159 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hle/service/hid/hid_debug_server.h"
5#include "core/hle/service/hid/resource_manager.h"
6#include "core/hle/service/ipc_helpers.h"
7
8namespace Service::HID {
9
10IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
11 : ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} {
12 // clang-format off
13 static const FunctionInfo functions[] = {
14 {0, nullptr, "DeactivateDebugPad"},
15 {1, nullptr, "SetDebugPadAutoPilotState"},
16 {2, nullptr, "UnsetDebugPadAutoPilotState"},
17 {10, nullptr, "DeactivateTouchScreen"},
18 {11, nullptr, "SetTouchScreenAutoPilotState"},
19 {12, nullptr, "UnsetTouchScreenAutoPilotState"},
20 {13, nullptr, "GetTouchScreenConfiguration"},
21 {14, nullptr, "ProcessTouchScreenAutoTune"},
22 {15, nullptr, "ForceStopTouchScreenManagement"},
23 {16, nullptr, "ForceRestartTouchScreenManagement"},
24 {17, nullptr, "IsTouchScreenManaged"},
25 {20, nullptr, "DeactivateMouse"},
26 {21, nullptr, "SetMouseAutoPilotState"},
27 {22, nullptr, "UnsetMouseAutoPilotState"},
28 {25, nullptr, "SetDebugMouseAutoPilotState"},
29 {26, nullptr, "UnsetDebugMouseAutoPilotState"},
30 {30, nullptr, "DeactivateKeyboard"},
31 {31, nullptr, "SetKeyboardAutoPilotState"},
32 {32, nullptr, "UnsetKeyboardAutoPilotState"},
33 {50, nullptr, "DeactivateXpad"},
34 {51, nullptr, "SetXpadAutoPilotState"},
35 {52, nullptr, "UnsetXpadAutoPilotState"},
36 {53, nullptr, "DeactivateJoyXpad"},
37 {60, nullptr, "ClearNpadSystemCommonPolicy"},
38 {61, nullptr, "DeactivateNpad"},
39 {62, nullptr, "ForceDisconnectNpad"},
40 {91, nullptr, "DeactivateGesture"},
41 {110, nullptr, "DeactivateHomeButton"},
42 {111, nullptr, "SetHomeButtonAutoPilotState"},
43 {112, nullptr, "UnsetHomeButtonAutoPilotState"},
44 {120, nullptr, "DeactivateSleepButton"},
45 {121, nullptr, "SetSleepButtonAutoPilotState"},
46 {122, nullptr, "UnsetSleepButtonAutoPilotState"},
47 {123, nullptr, "DeactivateInputDetector"},
48 {130, nullptr, "DeactivateCaptureButton"},
49 {131, nullptr, "SetCaptureButtonAutoPilotState"},
50 {132, nullptr, "UnsetCaptureButtonAutoPilotState"},
51 {133, nullptr, "SetShiftAccelerometerCalibrationValue"},
52 {134, nullptr, "GetShiftAccelerometerCalibrationValue"},
53 {135, nullptr, "SetShiftGyroscopeCalibrationValue"},
54 {136, nullptr, "GetShiftGyroscopeCalibrationValue"},
55 {140, nullptr, "DeactivateConsoleSixAxisSensor"},
56 {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
57 {142, nullptr, "DeactivateSevenSixAxisSensor"},
58 {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
59 {144, nullptr, "GetAccelerometerFsr"},
60 {145, nullptr, "SetAccelerometerFsr"},
61 {146, nullptr, "GetAccelerometerOdr"},
62 {147, nullptr, "SetAccelerometerOdr"},
63 {148, nullptr, "GetGyroscopeFsr"},
64 {149, nullptr, "SetGyroscopeFsr"},
65 {150, nullptr, "GetGyroscopeOdr"},
66 {151, nullptr, "SetGyroscopeOdr"},
67 {152, nullptr, "GetWhoAmI"},
68 {201, nullptr, "ActivateFirmwareUpdate"},
69 {202, nullptr, "DeactivateFirmwareUpdate"},
70 {203, nullptr, "StartFirmwareUpdate"},
71 {204, nullptr, "GetFirmwareUpdateStage"},
72 {205, nullptr, "GetFirmwareVersion"},
73 {206, nullptr, "GetDestinationFirmwareVersion"},
74 {207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
75 {208, nullptr, "StartFirmwareUpdateForRevert"},
76 {209, nullptr, "GetAvailableFirmwareVersionForRevert"},
77 {210, nullptr, "IsFirmwareUpdatingDevice"},
78 {211, nullptr, "StartFirmwareUpdateIndividual"},
79 {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
80 {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
81 {221, nullptr, "UpdateControllerColor"},
82 {222, nullptr, "ConnectUsbPadsAsync"},
83 {223, nullptr, "DisconnectUsbPadsAsync"},
84 {224, nullptr, "UpdateDesignInfo"},
85 {225, nullptr, "GetUniquePadDriverState"},
86 {226, nullptr, "GetSixAxisSensorDriverStates"},
87 {227, nullptr, "GetRxPacketHistory"},
88 {228, nullptr, "AcquireOperationEventHandle"},
89 {229, nullptr, "ReadSerialFlash"},
90 {230, nullptr, "WriteSerialFlash"},
91 {231, nullptr, "GetOperationResult"},
92 {232, nullptr, "EnableShipmentMode"},
93 {233, nullptr, "ClearPairingInfo"},
94 {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
95 {235, nullptr, "EnableAnalogStickPower"},
96 {236, nullptr, "RequestKuinaUartClockCal"},
97 {237, nullptr, "GetKuinaUartClockCal"},
98 {238, nullptr, "SetKuinaUartClockTrim"},
99 {239, nullptr, "KuinaLoopbackTest"},
100 {240, nullptr, "RequestBatteryVoltage"},
101 {241, nullptr, "GetBatteryVoltage"},
102 {242, nullptr, "GetUniquePadPowerInfo"},
103 {243, nullptr, "RebootUniquePad"},
104 {244, nullptr, "RequestKuinaFirmwareVersion"},
105 {245, nullptr, "GetKuinaFirmwareVersion"},
106 {246, nullptr, "GetVidPid"},
107 {247, nullptr, "GetAnalogStickCalibrationValue"},
108 {248, nullptr, "GetUniquePadIdsFull"},
109 {249, nullptr, "ConnectUniquePad"},
110 {250, nullptr, "IsVirtual"},
111 {251, nullptr, "GetAnalogStickModuleParam"},
112 {301, nullptr, "GetAbstractedPadHandles"},
113 {302, nullptr, "GetAbstractedPadState"},
114 {303, nullptr, "GetAbstractedPadsState"},
115 {321, nullptr, "SetAutoPilotVirtualPadState"},
116 {322, nullptr, "UnsetAutoPilotVirtualPadState"},
117 {323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
118 {324, nullptr, "AttachHdlsWorkBuffer"},
119 {325, nullptr, "ReleaseHdlsWorkBuffer"},
120 {326, nullptr, "DumpHdlsNpadAssignmentState"},
121 {327, nullptr, "DumpHdlsStates"},
122 {328, nullptr, "ApplyHdlsNpadAssignmentState"},
123 {329, nullptr, "ApplyHdlsStateList"},
124 {330, nullptr, "AttachHdlsVirtualDevice"},
125 {331, nullptr, "DetachHdlsVirtualDevice"},
126 {332, nullptr, "SetHdlsState"},
127 {350, nullptr, "AddRegisteredDevice"},
128 {400, nullptr, "DisableExternalMcuOnNxDevice"},
129 {401, nullptr, "DisableRailDeviceFiltering"},
130 {402, nullptr, "EnableWiredPairing"},
131 {403, nullptr, "EnableShipmentModeAutoClear"},
132 {404, nullptr, "SetRailEnabled"},
133 {500, nullptr, "SetFactoryInt"},
134 {501, nullptr, "IsFactoryBootEnabled"},
135 {550, nullptr, "SetAnalogStickModelDataTemporarily"},
136 {551, nullptr, "GetAnalogStickModelData"},
137 {552, nullptr, "ResetAnalogStickModelData"},
138 {600, nullptr, "ConvertPadState"},
139 {650, nullptr, "AddButtonPlayData"},
140 {651, nullptr, "StartButtonPlayData"},
141 {652, nullptr, "StopButtonPlayData"},
142 {2000, nullptr, "DeactivateDigitizer"},
143 {2001, nullptr, "SetDigitizerAutoPilotState"},
144 {2002, nullptr, "UnsetDigitizerAutoPilotState"},
145 {2002, nullptr, "ReloadFirmwareDebugSettings"},
146 };
147 // clang-format on
148
149 RegisterHandlers(functions);
150}
151
152IHidDebugServer::~IHidDebugServer() = default;
153
154std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() {
155 resource_manager->Initialize();
156 return resource_manager;
157}
158
159} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_debug_server.h b/src/core/hle/service/hid/hid_debug_server.h
new file mode 100644
index 000000000..406db2211
--- /dev/null
+++ b/src/core/hle/service/hid/hid_debug_server.h
@@ -0,0 +1,26 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::HID {
13class ResourceManager;
14
15class IHidDebugServer final : public ServiceFramework<IHidDebugServer> {
16public:
17 explicit IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
18 ~IHidDebugServer() override;
19
20private:
21 std::shared_ptr<ResourceManager> GetResourceManager();
22
23 std::shared_ptr<ResourceManager> resource_manager;
24};
25
26} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
new file mode 100644
index 000000000..348dc98d9
--- /dev/null
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -0,0 +1,2269 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include <array>
5#include "common/common_types.h"
6#include "common/logging/log.h"
7#include "common/settings.h"
8#include "core/hid/hid_core.h"
9#include "core/hle/kernel/k_shared_memory.h"
10#include "core/hle/kernel/k_transfer_memory.h"
11#include "core/hle/kernel/kernel.h"
12#include "core/hle/service/hid/errors.h"
13#include "core/hle/service/hid/hid_server.h"
14#include "core/hle/service/hid/resource_manager.h"
15#include "core/hle/service/ipc_helpers.h"
16#include "core/memory.h"
17
18#include "core/hle/service/hid/controllers/console_sixaxis.h"
19#include "core/hle/service/hid/controllers/controller_base.h"
20#include "core/hle/service/hid/controllers/debug_pad.h"
21#include "core/hle/service/hid/controllers/gesture.h"
22#include "core/hle/service/hid/controllers/keyboard.h"
23#include "core/hle/service/hid/controllers/mouse.h"
24#include "core/hle/service/hid/controllers/npad.h"
25#include "core/hle/service/hid/controllers/palma.h"
26#include "core/hle/service/hid/controllers/stubbed.h"
27#include "core/hle/service/hid/controllers/touchscreen.h"
28#include "core/hle/service/hid/controllers/xpad.h"
29
30namespace Service::HID {
31
32class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
33public:
34 explicit IActiveVibrationDeviceList(Core::System& system_,
35 std::shared_ptr<ResourceManager> resource)
36 : ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
37 // clang-format off
38 static const FunctionInfo functions[] = {
39 {0, &IActiveVibrationDeviceList::InitializeVibrationDevice, "InitializeVibrationDevice"},
40 };
41 // clang-format on
42
43 RegisterHandlers(functions);
44 }
45
46private:
47 void InitializeVibrationDevice(HLERequestContext& ctx) {
48 IPC::RequestParser rp{ctx};
49 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
50
51 if (resource_manager != nullptr) {
52 resource_manager->GetController<Controller_NPad>(HidController::NPad)
53 .InitializeVibrationDevice(vibration_device_handle);
54 }
55
56 LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
57 vibration_device_handle.npad_type, vibration_device_handle.npad_id,
58 vibration_device_handle.device_index);
59
60 IPC::ResponseBuilder rb{ctx, 2};
61 rb.Push(ResultSuccess);
62 }
63
64 std::shared_ptr<ResourceManager> resource_manager;
65};
66
67IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
68 : ServiceFramework{system_, "hid"}, resource_manager{resource} {
69 // clang-format off
70 static const FunctionInfo functions[] = {
71 {0, &IHidServer::CreateAppletResource, "CreateAppletResource"},
72 {1, &IHidServer::ActivateDebugPad, "ActivateDebugPad"},
73 {11, &IHidServer::ActivateTouchScreen, "ActivateTouchScreen"},
74 {21, &IHidServer::ActivateMouse, "ActivateMouse"},
75 {26, nullptr, "ActivateDebugMouse"},
76 {31, &IHidServer::ActivateKeyboard, "ActivateKeyboard"},
77 {32, &IHidServer::SendKeyboardLockKeyEvent, "SendKeyboardLockKeyEvent"},
78 {40, nullptr, "AcquireXpadIdEventHandle"},
79 {41, nullptr, "ReleaseXpadIdEventHandle"},
80 {51, &IHidServer::ActivateXpad, "ActivateXpad"},
81 {55, &IHidServer::GetXpadIds, "GetXpadIds"},
82 {56, nullptr, "ActivateJoyXpad"},
83 {58, nullptr, "GetJoyXpadLifoHandle"},
84 {59, nullptr, "GetJoyXpadIds"},
85 {60, &IHidServer::ActivateSixAxisSensor, "ActivateSixAxisSensor"},
86 {61, &IHidServer::DeactivateSixAxisSensor, "DeactivateSixAxisSensor"},
87 {62, nullptr, "GetSixAxisSensorLifoHandle"},
88 {63, nullptr, "ActivateJoySixAxisSensor"},
89 {64, nullptr, "DeactivateJoySixAxisSensor"},
90 {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
91 {66, &IHidServer::StartSixAxisSensor, "StartSixAxisSensor"},
92 {67, &IHidServer::StopSixAxisSensor, "StopSixAxisSensor"},
93 {68, &IHidServer::IsSixAxisSensorFusionEnabled, "IsSixAxisSensorFusionEnabled"},
94 {69, &IHidServer::EnableSixAxisSensorFusion, "EnableSixAxisSensorFusion"},
95 {70, &IHidServer::SetSixAxisSensorFusionParameters, "SetSixAxisSensorFusionParameters"},
96 {71, &IHidServer::GetSixAxisSensorFusionParameters, "GetSixAxisSensorFusionParameters"},
97 {72, &IHidServer::ResetSixAxisSensorFusionParameters, "ResetSixAxisSensorFusionParameters"},
98 {73, nullptr, "SetAccelerometerParameters"},
99 {74, nullptr, "GetAccelerometerParameters"},
100 {75, nullptr, "ResetAccelerometerParameters"},
101 {76, nullptr, "SetAccelerometerPlayMode"},
102 {77, nullptr, "GetAccelerometerPlayMode"},
103 {78, nullptr, "ResetAccelerometerPlayMode"},
104 {79, &IHidServer::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
105 {80, &IHidServer::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"},
106 {81, &IHidServer::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
107 {82, &IHidServer::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
108 {83, &IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
109 {84, &IHidServer::EnableSixAxisSensorUnalteredPassthrough, "EnableSixAxisSensorUnalteredPassthrough"},
110 {85, &IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled, "IsSixAxisSensorUnalteredPassthroughEnabled"},
111 {86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
112 {87, &IHidServer::LoadSixAxisSensorCalibrationParameter, "LoadSixAxisSensorCalibrationParameter"},
113 {88, &IHidServer::GetSixAxisSensorIcInformation, "GetSixAxisSensorIcInformation"},
114 {89, &IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
115 {91, &IHidServer::ActivateGesture, "ActivateGesture"},
116 {100, &IHidServer::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
117 {101, &IHidServer::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
118 {102, &IHidServer::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
119 {103, &IHidServer::ActivateNpad, "ActivateNpad"},
120 {104, &IHidServer::DeactivateNpad, "DeactivateNpad"},
121 {106, &IHidServer::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
122 {107, &IHidServer::DisconnectNpad, "DisconnectNpad"},
123 {108, &IHidServer::GetPlayerLedPattern, "GetPlayerLedPattern"},
124 {109, &IHidServer::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
125 {120, &IHidServer::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
126 {121, &IHidServer::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
127 {122, &IHidServer::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
128 {123, &IHidServer::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"},
129 {124, &IHidServer::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
130 {125, &IHidServer::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
131 {126, &IHidServer::StartLrAssignmentMode, "StartLrAssignmentMode"},
132 {127, &IHidServer::StopLrAssignmentMode, "StopLrAssignmentMode"},
133 {128, &IHidServer::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
134 {129, &IHidServer::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"},
135 {130, &IHidServer::SwapNpadAssignment, "SwapNpadAssignment"},
136 {131, &IHidServer::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
137 {132, &IHidServer::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
138 {133, &IHidServer::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"},
139 {134, &IHidServer::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
140 {135, &IHidServer::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"},
141 {136, &IHidServer::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"},
142 {200, &IHidServer::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
143 {201, &IHidServer::SendVibrationValue, "SendVibrationValue"},
144 {202, &IHidServer::GetActualVibrationValue, "GetActualVibrationValue"},
145 {203, &IHidServer::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
146 {204, &IHidServer::PermitVibration, "PermitVibration"},
147 {205, &IHidServer::IsVibrationPermitted, "IsVibrationPermitted"},
148 {206, &IHidServer::SendVibrationValues, "SendVibrationValues"},
149 {207, &IHidServer::SendVibrationGcErmCommand, "SendVibrationGcErmCommand"},
150 {208, &IHidServer::GetActualVibrationGcErmCommand, "GetActualVibrationGcErmCommand"},
151 {209, &IHidServer::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
152 {210, &IHidServer::EndPermitVibrationSession, "EndPermitVibrationSession"},
153 {211, &IHidServer::IsVibrationDeviceMounted, "IsVibrationDeviceMounted"},
154 {212, nullptr, "SendVibrationValueInBool"},
155 {300, &IHidServer::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
156 {301, &IHidServer::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
157 {302, &IHidServer::StopConsoleSixAxisSensor, "StopConsoleSixAxisSensor"},
158 {303, &IHidServer::ActivateSevenSixAxisSensor, "ActivateSevenSixAxisSensor"},
159 {304, &IHidServer::StartSevenSixAxisSensor, "StartSevenSixAxisSensor"},
160 {305, &IHidServer::StopSevenSixAxisSensor, "StopSevenSixAxisSensor"},
161 {306, &IHidServer::InitializeSevenSixAxisSensor, "InitializeSevenSixAxisSensor"},
162 {307, &IHidServer::FinalizeSevenSixAxisSensor, "FinalizeSevenSixAxisSensor"},
163 {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
164 {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
165 {310, &IHidServer::ResetSevenSixAxisSensorTimestamp, "ResetSevenSixAxisSensorTimestamp"},
166 {400, &IHidServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
167 {401, nullptr, "EnableUsbFullKeyController"},
168 {402, nullptr, "IsUsbFullKeyControllerConnected"},
169 {403, nullptr, "HasBattery"},
170 {404, nullptr, "HasLeftRightBattery"},
171 {405, nullptr, "GetNpadInterfaceType"},
172 {406, nullptr, "GetNpadLeftRightInterfaceType"},
173 {407, nullptr, "GetNpadOfHighestBatteryLevel"},
174 {408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
175 {500, &IHidServer::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
176 {501, &IHidServer::InitializePalma, "InitializePalma"},
177 {502, &IHidServer::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
178 {503, &IHidServer::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
179 {504, &IHidServer::PlayPalmaActivity, "PlayPalmaActivity"},
180 {505, &IHidServer::SetPalmaFrModeType, "SetPalmaFrModeType"},
181 {506, &IHidServer::ReadPalmaStep, "ReadPalmaStep"},
182 {507, &IHidServer::EnablePalmaStep, "EnablePalmaStep"},
183 {508, &IHidServer::ResetPalmaStep, "ResetPalmaStep"},
184 {509, &IHidServer::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
185 {510, &IHidServer::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
186 {511, &IHidServer::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
187 {512, &IHidServer::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
188 {513, &IHidServer::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
189 {514, &IHidServer::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
190 {515, &IHidServer::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
191 {516, &IHidServer::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
192 {517, &IHidServer::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
193 {518, &IHidServer::SuspendPalmaFeature, "SuspendPalmaFeature"},
194 {519, &IHidServer::GetPalmaOperationResult, "GetPalmaOperationResult"},
195 {520, &IHidServer::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
196 {521, &IHidServer::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
197 {522, &IHidServer::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
198 {523, &IHidServer::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
199 {524, &IHidServer::PairPalma, "PairPalma"},
200 {525, &IHidServer::SetPalmaBoostMode, "SetPalmaBoostMode"},
201 {526, &IHidServer::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
202 {527, &IHidServer::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
203 {528, &IHidServer::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
204 {529, &IHidServer::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
205 {1000, &IHidServer::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
206 {1001, &IHidServer::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
207 {1002, &IHidServer::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
208 {1003, &IHidServer::IsFirmwareUpdateNeededForNotification, "IsFirmwareUpdateNeededForNotification"},
209 {2000, nullptr, "ActivateDigitizer"},
210 };
211 // clang-format on
212
213 RegisterHandlers(functions);
214}
215
216IHidServer::~IHidServer() = default;
217
218void IHidServer::CreateAppletResource(HLERequestContext& ctx) {
219 IPC::RequestParser rp{ctx};
220 const auto applet_resource_user_id{rp.Pop<u64>()};
221
222 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
223
224 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
225 rb.Push(ResultSuccess);
226 rb.PushIpcInterface<IAppletResource>(system, resource_manager);
227}
228
229void IHidServer::ActivateDebugPad(HLERequestContext& ctx) {
230 IPC::RequestParser rp{ctx};
231 const auto applet_resource_user_id{rp.Pop<u64>()};
232
233 GetResourceManager()->ActivateController(HidController::DebugPad);
234
235 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
236
237 IPC::ResponseBuilder rb{ctx, 2};
238 rb.Push(ResultSuccess);
239}
240
241void IHidServer::ActivateTouchScreen(HLERequestContext& ctx) {
242 IPC::RequestParser rp{ctx};
243 const auto applet_resource_user_id{rp.Pop<u64>()};
244
245 GetResourceManager()->ActivateController(HidController::Touchscreen);
246
247 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
248
249 IPC::ResponseBuilder rb{ctx, 2};
250 rb.Push(ResultSuccess);
251}
252
253void IHidServer::ActivateMouse(HLERequestContext& ctx) {
254 IPC::RequestParser rp{ctx};
255 const auto applet_resource_user_id{rp.Pop<u64>()};
256
257 GetResourceManager()->ActivateController(HidController::Mouse);
258
259 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
260
261 IPC::ResponseBuilder rb{ctx, 2};
262 rb.Push(ResultSuccess);
263}
264
265void IHidServer::ActivateKeyboard(HLERequestContext& ctx) {
266 IPC::RequestParser rp{ctx};
267 const auto applet_resource_user_id{rp.Pop<u64>()};
268
269 GetResourceManager()->ActivateController(HidController::Keyboard);
270
271 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
272
273 IPC::ResponseBuilder rb{ctx, 2};
274 rb.Push(ResultSuccess);
275}
276
277void IHidServer::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
278 IPC::RequestParser rp{ctx};
279 const auto flags{rp.Pop<u32>()};
280
281 LOG_WARNING(Service_HID, "(STUBBED) called. flags={}", flags);
282
283 IPC::ResponseBuilder rb{ctx, 2};
284 rb.Push(ResultSuccess);
285}
286
287void IHidServer::ActivateXpad(HLERequestContext& ctx) {
288 IPC::RequestParser rp{ctx};
289 struct Parameters {
290 u32 basic_xpad_id;
291 INSERT_PADDING_WORDS_NOINIT(1);
292 u64 applet_resource_user_id;
293 };
294 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
295
296 const auto parameters{rp.PopRaw<Parameters>()};
297
298 GetResourceManager()->ActivateController(HidController::XPad);
299
300 LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
301 parameters.basic_xpad_id, parameters.applet_resource_user_id);
302
303 IPC::ResponseBuilder rb{ctx, 2};
304 rb.Push(ResultSuccess);
305}
306
307void IHidServer::GetXpadIds(HLERequestContext& ctx) {
308 IPC::RequestParser rp{ctx};
309 const auto applet_resource_user_id{rp.Pop<u64>()};
310
311 LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
312
313 IPC::ResponseBuilder rb{ctx, 3};
314 rb.Push(ResultSuccess);
315 rb.Push(0);
316}
317
318void IHidServer::ActivateSixAxisSensor(HLERequestContext& ctx) {
319 IPC::RequestParser rp{ctx};
320 struct Parameters {
321 u32 basic_xpad_id;
322 INSERT_PADDING_WORDS_NOINIT(1);
323 u64 applet_resource_user_id;
324 };
325 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
326
327 const auto parameters{rp.PopRaw<Parameters>()};
328
329 // This function does nothing on 10.0.0+
330
331 LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
332 parameters.basic_xpad_id, parameters.applet_resource_user_id);
333
334 IPC::ResponseBuilder rb{ctx, 2};
335 rb.Push(ResultSuccess);
336}
337
338void IHidServer::DeactivateSixAxisSensor(HLERequestContext& ctx) {
339 IPC::RequestParser rp{ctx};
340 struct Parameters {
341 u32 basic_xpad_id;
342 INSERT_PADDING_WORDS_NOINIT(1);
343 u64 applet_resource_user_id;
344 };
345 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
346
347 const auto parameters{rp.PopRaw<Parameters>()};
348
349 // This function does nothing on 10.0.0+
350
351 LOG_WARNING(Service_HID, "(STUBBED) called, basic_xpad_id={}, applet_resource_user_id={}",
352 parameters.basic_xpad_id, parameters.applet_resource_user_id);
353
354 IPC::ResponseBuilder rb{ctx, 2};
355 rb.Push(ResultSuccess);
356}
357
358void IHidServer::StartSixAxisSensor(HLERequestContext& ctx) {
359 IPC::RequestParser rp{ctx};
360 struct Parameters {
361 Core::HID::SixAxisSensorHandle sixaxis_handle;
362 INSERT_PADDING_WORDS_NOINIT(1);
363 u64 applet_resource_user_id;
364 };
365 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
366
367 const auto parameters{rp.PopRaw<Parameters>()};
368
369 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
370 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
371
372 LOG_DEBUG(Service_HID,
373 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
374 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
375 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
376
377 IPC::ResponseBuilder rb{ctx, 2};
378 rb.Push(result);
379}
380
381void IHidServer::StopSixAxisSensor(HLERequestContext& ctx) {
382 IPC::RequestParser rp{ctx};
383 struct Parameters {
384 Core::HID::SixAxisSensorHandle sixaxis_handle;
385 INSERT_PADDING_WORDS_NOINIT(1);
386 u64 applet_resource_user_id;
387 };
388 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
389
390 const auto parameters{rp.PopRaw<Parameters>()};
391
392 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
393 const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
394
395 LOG_DEBUG(Service_HID,
396 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
397 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
398 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
399
400 IPC::ResponseBuilder rb{ctx, 2};
401 rb.Push(result);
402}
403
404void IHidServer::IsSixAxisSensorFusionEnabled(HLERequestContext& ctx) {
405 IPC::RequestParser rp{ctx};
406 struct Parameters {
407 Core::HID::SixAxisSensorHandle sixaxis_handle;
408 INSERT_PADDING_WORDS_NOINIT(1);
409 u64 applet_resource_user_id;
410 };
411 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
412
413 const auto parameters{rp.PopRaw<Parameters>()};
414
415 bool is_enabled{};
416 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
417 const auto result =
418 controller.IsSixAxisSensorFusionEnabled(parameters.sixaxis_handle, is_enabled);
419
420 LOG_DEBUG(Service_HID,
421 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
422 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
423 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
424
425 IPC::ResponseBuilder rb{ctx, 3};
426 rb.Push(result);
427 rb.Push(is_enabled);
428}
429
430void IHidServer::EnableSixAxisSensorFusion(HLERequestContext& ctx) {
431 IPC::RequestParser rp{ctx};
432 struct Parameters {
433 bool enable_sixaxis_sensor_fusion;
434 INSERT_PADDING_BYTES_NOINIT(3);
435 Core::HID::SixAxisSensorHandle sixaxis_handle;
436 u64 applet_resource_user_id;
437 };
438 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
439
440 const auto parameters{rp.PopRaw<Parameters>()};
441
442 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
443 const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
444 parameters.enable_sixaxis_sensor_fusion);
445
446 LOG_DEBUG(Service_HID,
447 "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
448 "device_index={}, applet_resource_user_id={}",
449 parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
450 parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
451 parameters.applet_resource_user_id);
452
453 IPC::ResponseBuilder rb{ctx, 2};
454 rb.Push(result);
455}
456
457void IHidServer::SetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
458 IPC::RequestParser rp{ctx};
459 struct Parameters {
460 Core::HID::SixAxisSensorHandle sixaxis_handle;
461 Core::HID::SixAxisSensorFusionParameters sixaxis_fusion;
462 INSERT_PADDING_WORDS_NOINIT(1);
463 u64 applet_resource_user_id;
464 };
465 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
466
467 const auto parameters{rp.PopRaw<Parameters>()};
468
469 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
470 const auto result =
471 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
472
473 LOG_DEBUG(Service_HID,
474 "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
475 "parameter2={}, applet_resource_user_id={}",
476 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
477 parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1,
478 parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id);
479
480 IPC::ResponseBuilder rb{ctx, 2};
481 rb.Push(result);
482}
483
484void IHidServer::GetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
485 IPC::RequestParser rp{ctx};
486 struct Parameters {
487 Core::HID::SixAxisSensorHandle sixaxis_handle;
488 INSERT_PADDING_WORDS_NOINIT(1);
489 u64 applet_resource_user_id;
490 };
491 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
492
493 const auto parameters{rp.PopRaw<Parameters>()};
494
495 Core::HID::SixAxisSensorFusionParameters fusion_parameters{};
496 const auto& controller =
497 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
498 const auto result =
499 controller.GetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
500
501 LOG_DEBUG(Service_HID,
502 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
503 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
504 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
505
506 IPC::ResponseBuilder rb{ctx, 4};
507 rb.Push(result);
508 rb.PushRaw(fusion_parameters);
509}
510
511void IHidServer::ResetSixAxisSensorFusionParameters(HLERequestContext& ctx) {
512 IPC::RequestParser rp{ctx};
513 struct Parameters {
514 Core::HID::SixAxisSensorHandle sixaxis_handle;
515 INSERT_PADDING_WORDS_NOINIT(1);
516 u64 applet_resource_user_id;
517 };
518 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
519
520 const auto parameters{rp.PopRaw<Parameters>()};
521
522 // Since these parameters are unknown just use what HW outputs
523 const Core::HID::SixAxisSensorFusionParameters fusion_parameters{
524 .parameter1 = 0.03f,
525 .parameter2 = 0.4f,
526 };
527 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
528 const auto result1 =
529 controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
530 const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
531
532 LOG_DEBUG(Service_HID,
533 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
534 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
535 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
536
537 IPC::ResponseBuilder rb{ctx, 2};
538 if (result1.IsError()) {
539 rb.Push(result1);
540 return;
541 }
542 rb.Push(result2);
543}
544
545void IHidServer::SetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
546 IPC::RequestParser rp{ctx};
547 const auto sixaxis_handle{rp.PopRaw<Core::HID::SixAxisSensorHandle>()};
548 const auto drift_mode{rp.PopEnum<Core::HID::GyroscopeZeroDriftMode>()};
549 const auto applet_resource_user_id{rp.Pop<u64>()};
550
551 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
552 const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
553
554 LOG_DEBUG(Service_HID,
555 "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
556 "applet_resource_user_id={}",
557 sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
558 drift_mode, applet_resource_user_id);
559
560 IPC::ResponseBuilder rb{ctx, 2};
561 rb.Push(result);
562}
563
564void IHidServer::GetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
565 IPC::RequestParser rp{ctx};
566 struct Parameters {
567 Core::HID::SixAxisSensorHandle sixaxis_handle;
568 INSERT_PADDING_WORDS_NOINIT(1);
569 u64 applet_resource_user_id;
570 };
571 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
572
573 const auto parameters{rp.PopRaw<Parameters>()};
574
575 auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
576 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
577 const auto result = controller.GetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
578
579 LOG_DEBUG(Service_HID,
580 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
581 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
582 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
583
584 IPC::ResponseBuilder rb{ctx, 3};
585 rb.Push(result);
586 rb.PushEnum(drift_mode);
587}
588
589void IHidServer::ResetGyroscopeZeroDriftMode(HLERequestContext& ctx) {
590 IPC::RequestParser rp{ctx};
591 struct Parameters {
592 Core::HID::SixAxisSensorHandle sixaxis_handle;
593 INSERT_PADDING_WORDS_NOINIT(1);
594 u64 applet_resource_user_id;
595 };
596 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
597
598 const auto parameters{rp.PopRaw<Parameters>()};
599
600 const auto drift_mode{Core::HID::GyroscopeZeroDriftMode::Standard};
601 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
602 const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
603
604 LOG_DEBUG(Service_HID,
605 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
606 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
607 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
608
609 IPC::ResponseBuilder rb{ctx, 2};
610 rb.Push(result);
611}
612
613void IHidServer::IsSixAxisSensorAtRest(HLERequestContext& ctx) {
614 IPC::RequestParser rp{ctx};
615 struct Parameters {
616 Core::HID::SixAxisSensorHandle sixaxis_handle;
617 INSERT_PADDING_WORDS_NOINIT(1);
618 u64 applet_resource_user_id;
619 };
620 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
621
622 const auto parameters{rp.PopRaw<Parameters>()};
623
624 bool is_at_rest{};
625 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
626 controller.IsSixAxisSensorAtRest(parameters.sixaxis_handle, is_at_rest);
627
628 LOG_DEBUG(Service_HID,
629 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
630 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
631 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
632
633 IPC::ResponseBuilder rb{ctx, 3};
634 rb.Push(ResultSuccess);
635 rb.Push(is_at_rest);
636}
637
638void IHidServer::IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx) {
639 IPC::RequestParser rp{ctx};
640 struct Parameters {
641 Core::HID::SixAxisSensorHandle sixaxis_handle;
642 INSERT_PADDING_WORDS_NOINIT(1);
643 u64 applet_resource_user_id;
644 };
645 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
646
647 const auto parameters{rp.PopRaw<Parameters>()};
648
649 bool is_firmware_available{};
650 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
651 controller.IsFirmwareUpdateAvailableForSixAxisSensor(parameters.sixaxis_handle,
652 is_firmware_available);
653
654 LOG_WARNING(
655 Service_HID,
656 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
657 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
658 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
659
660 IPC::ResponseBuilder rb{ctx, 3};
661 rb.Push(ResultSuccess);
662 rb.Push(is_firmware_available);
663}
664
665void IHidServer::EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx) {
666 IPC::RequestParser rp{ctx};
667 struct Parameters {
668 bool enabled;
669 Core::HID::SixAxisSensorHandle sixaxis_handle;
670 u64 applet_resource_user_id;
671 };
672 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
673
674 const auto parameters{rp.PopRaw<Parameters>()};
675
676 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
677 const auto result = controller.EnableSixAxisSensorUnalteredPassthrough(
678 parameters.sixaxis_handle, parameters.enabled);
679
680 LOG_DEBUG(Service_HID,
681 "(STUBBED) called, enabled={}, npad_type={}, npad_id={}, device_index={}, "
682 "applet_resource_user_id={}",
683 parameters.enabled, parameters.sixaxis_handle.npad_type,
684 parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index,
685 parameters.applet_resource_user_id);
686
687 IPC::ResponseBuilder rb{ctx, 2};
688 rb.Push(result);
689}
690
691void IHidServer::IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx) {
692 IPC::RequestParser rp{ctx};
693 struct Parameters {
694 Core::HID::SixAxisSensorHandle sixaxis_handle;
695 INSERT_PADDING_WORDS_NOINIT(1);
696 u64 applet_resource_user_id;
697 };
698 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
699
700 const auto parameters{rp.PopRaw<Parameters>()};
701
702 bool is_unaltered_sisxaxis_enabled{};
703 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
704 const auto result = controller.IsSixAxisSensorUnalteredPassthroughEnabled(
705 parameters.sixaxis_handle, is_unaltered_sisxaxis_enabled);
706
707 LOG_DEBUG(
708 Service_HID,
709 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
710 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
711 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
712
713 IPC::ResponseBuilder rb{ctx, 3};
714 rb.Push(result);
715 rb.Push(is_unaltered_sisxaxis_enabled);
716}
717
718void IHidServer::LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx) {
719 IPC::RequestParser rp{ctx};
720 struct Parameters {
721 Core::HID::SixAxisSensorHandle sixaxis_handle;
722 INSERT_PADDING_WORDS_NOINIT(1);
723 u64 applet_resource_user_id;
724 };
725 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
726
727 const auto parameters{rp.PopRaw<Parameters>()};
728
729 Core::HID::SixAxisSensorCalibrationParameter calibration{};
730 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
731 const auto result =
732 controller.LoadSixAxisSensorCalibrationParameter(parameters.sixaxis_handle, calibration);
733
734 LOG_WARNING(
735 Service_HID,
736 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
737 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
738 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
739
740 if (result.IsSuccess()) {
741 ctx.WriteBuffer(calibration);
742 }
743
744 IPC::ResponseBuilder rb{ctx, 2};
745 rb.Push(result);
746}
747
748void IHidServer::GetSixAxisSensorIcInformation(HLERequestContext& ctx) {
749 IPC::RequestParser rp{ctx};
750 struct Parameters {
751 Core::HID::SixAxisSensorHandle sixaxis_handle;
752 INSERT_PADDING_WORDS_NOINIT(1);
753 u64 applet_resource_user_id;
754 };
755 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
756
757 const auto parameters{rp.PopRaw<Parameters>()};
758
759 Core::HID::SixAxisSensorIcInformation ic_information{};
760 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
761 const auto result =
762 controller.GetSixAxisSensorIcInformation(parameters.sixaxis_handle, ic_information);
763
764 LOG_WARNING(
765 Service_HID,
766 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
767 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
768 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
769
770 if (result.IsSuccess()) {
771 ctx.WriteBuffer(ic_information);
772 }
773
774 IPC::ResponseBuilder rb{ctx, 2};
775 rb.Push(result);
776}
777
778void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx) {
779 IPC::RequestParser rp{ctx};
780 struct Parameters {
781 Core::HID::SixAxisSensorHandle sixaxis_handle;
782 INSERT_PADDING_WORDS_NOINIT(1);
783 u64 applet_resource_user_id;
784 };
785 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
786
787 const auto parameters{rp.PopRaw<Parameters>()};
788
789 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
790 const auto result =
791 controller.ResetIsSixAxisSensorDeviceNewlyAssigned(parameters.sixaxis_handle);
792
793 LOG_WARNING(
794 Service_HID,
795 "(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
796 parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
797 parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
798
799 IPC::ResponseBuilder rb{ctx, 2};
800 rb.Push(result);
801}
802
803void IHidServer::ActivateGesture(HLERequestContext& ctx) {
804 IPC::RequestParser rp{ctx};
805 struct Parameters {
806 u32 unknown;
807 INSERT_PADDING_WORDS_NOINIT(1);
808 u64 applet_resource_user_id;
809 };
810 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
811
812 const auto parameters{rp.PopRaw<Parameters>()};
813
814 GetResourceManager()->ActivateController(HidController::Gesture);
815
816 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
817 parameters.unknown, parameters.applet_resource_user_id);
818
819 IPC::ResponseBuilder rb{ctx, 2};
820 rb.Push(ResultSuccess);
821}
822
823void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
824 IPC::RequestParser rp{ctx};
825 struct Parameters {
826 Core::HID::NpadStyleSet supported_styleset;
827 INSERT_PADDING_WORDS_NOINIT(1);
828 u64 applet_resource_user_id;
829 };
830 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
831
832 const auto parameters{rp.PopRaw<Parameters>()};
833
834 GetResourceManager()
835 ->GetController<Controller_NPad>(HidController::NPad)
836 .SetSupportedStyleSet({parameters.supported_styleset});
837
838 LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
839 parameters.supported_styleset, parameters.applet_resource_user_id);
840
841 IPC::ResponseBuilder rb{ctx, 2};
842 rb.Push(ResultSuccess);
843}
844
845void IHidServer::GetSupportedNpadStyleSet(HLERequestContext& ctx) {
846 IPC::RequestParser rp{ctx};
847 const auto applet_resource_user_id{rp.Pop<u64>()};
848
849 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
850
851 IPC::ResponseBuilder rb{ctx, 3};
852 rb.Push(ResultSuccess);
853 rb.PushEnum(GetResourceManager()
854 ->GetController<Controller_NPad>(HidController::NPad)
855 .GetSupportedStyleSet()
856 .raw);
857}
858
859void IHidServer::SetSupportedNpadIdType(HLERequestContext& ctx) {
860 IPC::RequestParser rp{ctx};
861 const auto applet_resource_user_id{rp.Pop<u64>()};
862
863 const auto result = GetResourceManager()
864 ->GetController<Controller_NPad>(HidController::NPad)
865 .SetSupportedNpadIdTypes(ctx.ReadBuffer());
866
867 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
868
869 IPC::ResponseBuilder rb{ctx, 2};
870 rb.Push(result);
871}
872
873void IHidServer::ActivateNpad(HLERequestContext& ctx) {
874 IPC::RequestParser rp{ctx};
875 const auto applet_resource_user_id{rp.Pop<u64>()};
876
877 GetResourceManager()->ActivateController(HidController::NPad);
878
879 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
880
881 IPC::ResponseBuilder rb{ctx, 2};
882 rb.Push(ResultSuccess);
883}
884
885void IHidServer::DeactivateNpad(HLERequestContext& ctx) {
886 IPC::RequestParser rp{ctx};
887 const auto applet_resource_user_id{rp.Pop<u64>()};
888
889 GetResourceManager()->DeactivateController(HidController::NPad);
890
891 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
892
893 IPC::ResponseBuilder rb{ctx, 2};
894 rb.Push(ResultSuccess);
895}
896
897void IHidServer::AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx) {
898 IPC::RequestParser rp{ctx};
899 struct Parameters {
900 Core::HID::NpadIdType npad_id;
901 INSERT_PADDING_WORDS_NOINIT(1);
902 u64 applet_resource_user_id;
903 u64 unknown;
904 };
905 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
906
907 const auto parameters{rp.PopRaw<Parameters>()};
908
909 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
910 parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
911
912 // Games expect this event to be signaled after calling this function
913 GetResourceManager()
914 ->GetController<Controller_NPad>(HidController::NPad)
915 .SignalStyleSetChangedEvent(parameters.npad_id);
916
917 IPC::ResponseBuilder rb{ctx, 2, 1};
918 rb.Push(ResultSuccess);
919 rb.PushCopyObjects(GetResourceManager()
920 ->GetController<Controller_NPad>(HidController::NPad)
921 .GetStyleSetChangedEvent(parameters.npad_id));
922}
923
924void IHidServer::DisconnectNpad(HLERequestContext& ctx) {
925 IPC::RequestParser rp{ctx};
926 struct Parameters {
927 Core::HID::NpadIdType npad_id;
928 INSERT_PADDING_WORDS_NOINIT(1);
929 u64 applet_resource_user_id;
930 };
931 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
932
933 const auto parameters{rp.PopRaw<Parameters>()};
934
935 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
936 controller.DisconnectNpad(parameters.npad_id);
937
938 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
939 parameters.applet_resource_user_id);
940
941 IPC::ResponseBuilder rb{ctx, 2};
942 rb.Push(ResultSuccess);
943}
944
945void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
946 IPC::RequestParser rp{ctx};
947 const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
948
949 Core::HID::LedPattern pattern{0, 0, 0, 0};
950 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
951 const auto result = controller.GetLedPattern(npad_id, pattern);
952
953 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
954
955 IPC::ResponseBuilder rb{ctx, 4};
956 rb.Push(result);
957 rb.Push(pattern.raw);
958}
959
960void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
961 // Should have no effect with how our npad sets up the data
962 IPC::RequestParser rp{ctx};
963 struct Parameters {
964 s32 revision;
965 INSERT_PADDING_WORDS_NOINIT(1);
966 u64 applet_resource_user_id;
967 };
968 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
969
970 const auto parameters{rp.PopRaw<Parameters>()};
971
972 GetResourceManager()->ActivateController(HidController::NPad);
973
974 LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
975 parameters.applet_resource_user_id);
976
977 IPC::ResponseBuilder rb{ctx, 2};
978 rb.Push(ResultSuccess);
979}
980
981void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
982 IPC::RequestParser rp{ctx};
983 const auto applet_resource_user_id{rp.Pop<u64>()};
984 const auto hold_type{rp.PopEnum<Controller_NPad::NpadJoyHoldType>()};
985
986 GetResourceManager()
987 ->GetController<Controller_NPad>(HidController::NPad)
988 .SetHoldType(hold_type);
989
990 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
991 applet_resource_user_id, hold_type);
992
993 IPC::ResponseBuilder rb{ctx, 2};
994 rb.Push(ResultSuccess);
995}
996
997void IHidServer::GetNpadJoyHoldType(HLERequestContext& ctx) {
998 IPC::RequestParser rp{ctx};
999 const auto applet_resource_user_id{rp.Pop<u64>()};
1000
1001 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1002
1003 IPC::ResponseBuilder rb{ctx, 4};
1004 rb.Push(ResultSuccess);
1005 rb.PushEnum(
1006 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad).GetHoldType());
1007}
1008
1009void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
1010 IPC::RequestParser rp{ctx};
1011 struct Parameters {
1012 Core::HID::NpadIdType npad_id;
1013 INSERT_PADDING_WORDS_NOINIT(1);
1014 u64 applet_resource_user_id;
1015 };
1016 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1017
1018 const auto parameters{rp.PopRaw<Parameters>()};
1019
1020 Core::HID::NpadIdType new_npad_id{};
1021 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1022 controller.SetNpadMode(new_npad_id, parameters.npad_id,
1023 Controller_NPad::NpadJoyDeviceType::Left,
1024 Controller_NPad::NpadJoyAssignmentMode::Single);
1025
1026 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1027 parameters.applet_resource_user_id);
1028
1029 IPC::ResponseBuilder rb{ctx, 2};
1030 rb.Push(ResultSuccess);
1031}
1032
1033void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1034 IPC::RequestParser rp{ctx};
1035 struct Parameters {
1036 Core::HID::NpadIdType npad_id;
1037 INSERT_PADDING_WORDS_NOINIT(1);
1038 u64 applet_resource_user_id;
1039 Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
1040 };
1041 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1042
1043 const auto parameters{rp.PopRaw<Parameters>()};
1044
1045 Core::HID::NpadIdType new_npad_id{};
1046 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1047 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1048 Controller_NPad::NpadJoyAssignmentMode::Single);
1049
1050 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1051 parameters.npad_id, parameters.applet_resource_user_id,
1052 parameters.npad_joy_device_type);
1053
1054 IPC::ResponseBuilder rb{ctx, 2};
1055 rb.Push(ResultSuccess);
1056}
1057
1058void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1059 IPC::RequestParser rp{ctx};
1060 struct Parameters {
1061 Core::HID::NpadIdType npad_id;
1062 INSERT_PADDING_WORDS_NOINIT(1);
1063 u64 applet_resource_user_id;
1064 };
1065 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1066
1067 const auto parameters{rp.PopRaw<Parameters>()};
1068
1069 Core::HID::NpadIdType new_npad_id{};
1070 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1071 controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
1072 Controller_NPad::NpadJoyAssignmentMode::Dual);
1073
1074 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1075 parameters.applet_resource_user_id);
1076
1077 IPC::ResponseBuilder rb{ctx, 2};
1078 rb.Push(ResultSuccess);
1079}
1080
1081void IHidServer::MergeSingleJoyAsDualJoy(HLERequestContext& ctx) {
1082 IPC::RequestParser rp{ctx};
1083 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1084 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1085 const auto applet_resource_user_id{rp.Pop<u64>()};
1086
1087 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1088 const auto result = controller.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
1089
1090 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1091 npad_id_1, npad_id_2, applet_resource_user_id);
1092
1093 IPC::ResponseBuilder rb{ctx, 2};
1094 rb.Push(result);
1095}
1096
1097void IHidServer::StartLrAssignmentMode(HLERequestContext& ctx) {
1098 IPC::RequestParser rp{ctx};
1099 const auto applet_resource_user_id{rp.Pop<u64>()};
1100
1101 GetResourceManager()
1102 ->GetController<Controller_NPad>(HidController::NPad)
1103 .StartLRAssignmentMode();
1104
1105 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1106
1107 IPC::ResponseBuilder rb{ctx, 2};
1108 rb.Push(ResultSuccess);
1109}
1110
1111void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
1112 IPC::RequestParser rp{ctx};
1113 const auto applet_resource_user_id{rp.Pop<u64>()};
1114
1115 GetResourceManager()
1116 ->GetController<Controller_NPad>(HidController::NPad)
1117 .StopLRAssignmentMode();
1118
1119 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1120
1121 IPC::ResponseBuilder rb{ctx, 2};
1122 rb.Push(ResultSuccess);
1123}
1124
1125void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1126 IPC::RequestParser rp{ctx};
1127 const auto applet_resource_user_id{rp.Pop<u64>()};
1128 const auto activation_mode{rp.PopEnum<Controller_NPad::NpadHandheldActivationMode>()};
1129
1130 GetResourceManager()
1131 ->GetController<Controller_NPad>(HidController::NPad)
1132 .SetNpadHandheldActivationMode(activation_mode);
1133
1134 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
1135 applet_resource_user_id, activation_mode);
1136
1137 IPC::ResponseBuilder rb{ctx, 2};
1138 rb.Push(ResultSuccess);
1139}
1140
1141void IHidServer::GetNpadHandheldActivationMode(HLERequestContext& ctx) {
1142 IPC::RequestParser rp{ctx};
1143 const auto applet_resource_user_id{rp.Pop<u64>()};
1144
1145 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1146
1147 IPC::ResponseBuilder rb{ctx, 4};
1148 rb.Push(ResultSuccess);
1149 rb.PushEnum(GetResourceManager()
1150 ->GetController<Controller_NPad>(HidController::NPad)
1151 .GetNpadHandheldActivationMode());
1152}
1153
1154void IHidServer::SwapNpadAssignment(HLERequestContext& ctx) {
1155 IPC::RequestParser rp{ctx};
1156 const auto npad_id_1{rp.PopEnum<Core::HID::NpadIdType>()};
1157 const auto npad_id_2{rp.PopEnum<Core::HID::NpadIdType>()};
1158 const auto applet_resource_user_id{rp.Pop<u64>()};
1159
1160 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1161 const auto result = controller.SwapNpadAssignment(npad_id_1, npad_id_2);
1162
1163 LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
1164 npad_id_1, npad_id_2, applet_resource_user_id);
1165
1166 IPC::ResponseBuilder rb{ctx, 2};
1167 rb.Push(result);
1168}
1169
1170void IHidServer::IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx) {
1171 IPC::RequestParser rp{ctx};
1172 struct Parameters {
1173 Core::HID::NpadIdType npad_id;
1174 INSERT_PADDING_WORDS_NOINIT(1);
1175 u64 applet_resource_user_id;
1176 };
1177 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1178
1179 const auto parameters{rp.PopRaw<Parameters>()};
1180
1181 bool is_enabled = false;
1182 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1183 const auto result =
1184 controller.IsUnintendedHomeButtonInputProtectionEnabled(parameters.npad_id, is_enabled);
1185
1186 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1187 parameters.npad_id, parameters.applet_resource_user_id);
1188
1189 IPC::ResponseBuilder rb{ctx, 3};
1190 rb.Push(result);
1191 rb.Push(is_enabled);
1192}
1193
1194void IHidServer::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
1195 IPC::RequestParser rp{ctx};
1196 struct Parameters {
1197 bool is_enabled;
1198 INSERT_PADDING_BYTES_NOINIT(3);
1199 Core::HID::NpadIdType npad_id;
1200 u64 applet_resource_user_id;
1201 };
1202 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1203
1204 const auto parameters{rp.PopRaw<Parameters>()};
1205
1206 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1207 const auto result = controller.SetUnintendedHomeButtonInputProtectionEnabled(
1208 parameters.is_enabled, parameters.npad_id);
1209
1210 LOG_DEBUG(Service_HID,
1211 "(STUBBED) called, is_enabled={}, npad_id={}, applet_resource_user_id={}",
1212 parameters.is_enabled, parameters.npad_id, parameters.applet_resource_user_id);
1213
1214 IPC::ResponseBuilder rb{ctx, 2};
1215 rb.Push(result);
1216}
1217
1218void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) {
1219 IPC::RequestParser rp{ctx};
1220 struct Parameters {
1221 Core::HID::NpadIdType npad_id;
1222 INSERT_PADDING_WORDS_NOINIT(1);
1223 u64 applet_resource_user_id;
1224 Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
1225 };
1226 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1227
1228 const auto parameters{rp.PopRaw<Parameters>()};
1229
1230 Core::HID::NpadIdType new_npad_id{};
1231 auto& controller = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1232 const auto is_reassigned =
1233 controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1234 Controller_NPad::NpadJoyAssignmentMode::Single);
1235
1236 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1237 parameters.npad_id, parameters.applet_resource_user_id,
1238 parameters.npad_joy_device_type);
1239
1240 IPC::ResponseBuilder rb{ctx, 4};
1241 rb.Push(ResultSuccess);
1242 rb.Push(is_reassigned);
1243 rb.PushEnum(new_npad_id);
1244}
1245
1246void IHidServer::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
1247 IPC::RequestParser rp{ctx};
1248 struct Parameters {
1249 bool analog_stick_use_center_clamp;
1250 INSERT_PADDING_BYTES_NOINIT(7);
1251 u64 applet_resource_user_id;
1252 };
1253 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1254
1255 const auto parameters{rp.PopRaw<Parameters>()};
1256
1257 GetResourceManager()
1258 ->GetController<Controller_NPad>(HidController::NPad)
1259 .SetAnalogStickUseCenterClamp(parameters.analog_stick_use_center_clamp);
1260
1261 LOG_WARNING(Service_HID,
1262 "(STUBBED) called, analog_stick_use_center_clamp={}, applet_resource_user_id={}",
1263 parameters.analog_stick_use_center_clamp, parameters.applet_resource_user_id);
1264
1265 IPC::ResponseBuilder rb{ctx, 2};
1266 rb.Push(ResultSuccess);
1267}
1268
1269void IHidServer::SetNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1270 IPC::RequestParser rp{ctx};
1271 struct Parameters {
1272 Core::HID::NpadStyleSet npad_styleset;
1273 INSERT_PADDING_WORDS_NOINIT(1);
1274 u64 applet_resource_user_id;
1275 Core::HID::NpadButton button;
1276 };
1277 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1278
1279 const auto parameters{rp.PopRaw<Parameters>()};
1280
1281 LOG_WARNING(Service_HID,
1282 "(STUBBED) called, npad_styleset={}, applet_resource_user_id={}, button={}",
1283 parameters.npad_styleset, parameters.applet_resource_user_id, parameters.button);
1284
1285 IPC::ResponseBuilder rb{ctx, 2};
1286 rb.Push(ResultSuccess);
1287}
1288
1289void IHidServer::ClearNpadCaptureButtonAssignment(HLERequestContext& ctx) {
1290 IPC::RequestParser rp{ctx};
1291 const auto applet_resource_user_id{rp.Pop<u64>()};
1292
1293 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1294 applet_resource_user_id);
1295
1296 IPC::ResponseBuilder rb{ctx, 2};
1297 rb.Push(ResultSuccess);
1298}
1299
1300void IHidServer::GetVibrationDeviceInfo(HLERequestContext& ctx) {
1301 IPC::RequestParser rp{ctx};
1302 const auto vibration_device_handle{rp.PopRaw<Core::HID::VibrationDeviceHandle>()};
1303 const auto& controller =
1304 GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
1305
1306 Core::HID::VibrationDeviceInfo vibration_device_info;
1307 bool check_device_index = false;
1308
1309 switch (vibration_device_handle.npad_type) {
1310 case Core::HID::NpadStyleIndex::ProController:
1311 case Core::HID::NpadStyleIndex::Handheld:
1312 case Core::HID::NpadStyleIndex::JoyconDual:
1313 case Core::HID::NpadStyleIndex::JoyconLeft:
1314 case Core::HID::NpadStyleIndex::JoyconRight:
1315 vibration_device_info.type = Core::HID::VibrationDeviceType::LinearResonantActuator;
1316 check_device_index = true;
1317 break;
1318 case Core::HID::NpadStyleIndex::GameCube:
1319 vibration_device_info.type = Core::HID::VibrationDeviceType::GcErm;
1320 break;
1321 case Core::HID::NpadStyleIndex::N64:
1322 vibration_device_info.type = Core::HID::VibrationDeviceType::N64;
1323 break;
1324 default:
1325 vibration_device_info.type = Core::HID::VibrationDeviceType::Unknown;
1326 break;
1327 }
1328
1329 vibration_device_info.position = Core::HID::VibrationDevicePosition::None;
1330 if (check_device_index) {
1331 switch (vibration_device_handle.device_index) {
1332 case Core::HID::DeviceIndex::Left:
1333 vibration_device_info.position = Core::HID::VibrationDevicePosition::Left;
1334 break;
1335 case Core::HID::DeviceIndex::Right:
1336 vibration_device_info.position = Core::HID::VibrationDevicePosition::Right;
1337 break;
1338 case Core::HID::DeviceIndex::None:
1339 default:
1340 ASSERT_MSG(false, "DeviceIndex should never be None!");
1341 break;
1342 }
1343 }
1344
1345 LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
1346 vibration_device_info.type, vibration_device_info.position);
1347
1348 const auto result = controller.IsDeviceHandleValid(vibration_device_handle);
1349 if (result.IsError()) {
1350 IPC::ResponseBuilder rb{ctx, 2};
1351 rb.Push(result);
1352 return;
1353 }
1354
1355 IPC::ResponseBuilder rb{ctx, 4};
1356 rb.Push(ResultSuccess);
1357 rb.PushRaw(vibration_device_info);
1358}
1359
1360void IHidServer::SendVibrationValue(HLERequestContext& ctx) {
1361 IPC::RequestParser rp{ctx};
1362 struct Parameters {
1363 Core::HID::VibrationDeviceHandle vibration_device_handle;
1364 Core::HID::VibrationValue vibration_value;
1365 INSERT_PADDING_WORDS_NOINIT(1);
1366 u64 applet_resource_user_id;
1367 };
1368 static_assert(sizeof(Parameters) == 0x20, "Parameters has incorrect size.");
1369
1370 const auto parameters{rp.PopRaw<Parameters>()};
1371
1372 GetResourceManager()
1373 ->GetController<Controller_NPad>(HidController::NPad)
1374 .VibrateController(parameters.vibration_device_handle, parameters.vibration_value);
1375
1376 LOG_DEBUG(Service_HID,
1377 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1378 parameters.vibration_device_handle.npad_type,
1379 parameters.vibration_device_handle.npad_id,
1380 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1381
1382 IPC::ResponseBuilder rb{ctx, 2};
1383 rb.Push(ResultSuccess);
1384}
1385
1386void IHidServer::GetActualVibrationValue(HLERequestContext& ctx) {
1387 IPC::RequestParser rp{ctx};
1388 struct Parameters {
1389 Core::HID::VibrationDeviceHandle vibration_device_handle;
1390 INSERT_PADDING_WORDS_NOINIT(1);
1391 u64 applet_resource_user_id;
1392 };
1393 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1394
1395 const auto parameters{rp.PopRaw<Parameters>()};
1396
1397 LOG_DEBUG(Service_HID,
1398 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1399 parameters.vibration_device_handle.npad_type,
1400 parameters.vibration_device_handle.npad_id,
1401 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1402
1403 IPC::ResponseBuilder rb{ctx, 6};
1404 rb.Push(ResultSuccess);
1405 rb.PushRaw(GetResourceManager()
1406 ->GetController<Controller_NPad>(HidController::NPad)
1407 .GetLastVibration(parameters.vibration_device_handle));
1408}
1409
1410void IHidServer::CreateActiveVibrationDeviceList(HLERequestContext& ctx) {
1411 LOG_DEBUG(Service_HID, "called");
1412
1413 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1414 rb.Push(ResultSuccess);
1415 rb.PushIpcInterface<IActiveVibrationDeviceList>(system, resource_manager);
1416}
1417
1418void IHidServer::PermitVibration(HLERequestContext& ctx) {
1419 IPC::RequestParser rp{ctx};
1420 const auto can_vibrate{rp.Pop<bool>()};
1421
1422 // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value
1423 // by converting it to a bool
1424 Settings::values.vibration_enabled.SetValue(can_vibrate);
1425
1426 LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
1427
1428 IPC::ResponseBuilder rb{ctx, 2};
1429 rb.Push(ResultSuccess);
1430}
1431
1432void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) {
1433 LOG_DEBUG(Service_HID, "called");
1434
1435 // nnSDK checks if a float is greater than zero. We return the bool we stored earlier
1436 const auto is_enabled = Settings::values.vibration_enabled.GetValue();
1437
1438 IPC::ResponseBuilder rb{ctx, 3};
1439 rb.Push(ResultSuccess);
1440 rb.Push(is_enabled);
1441}
1442
1443void IHidServer::SendVibrationValues(HLERequestContext& ctx) {
1444 IPC::RequestParser rp{ctx};
1445 const auto applet_resource_user_id{rp.Pop<u64>()};
1446
1447 const auto handle_data = ctx.ReadBuffer(0);
1448 const auto handle_count = ctx.GetReadBufferNumElements<Core::HID::VibrationDeviceHandle>(0);
1449 const auto vibration_data = ctx.ReadBuffer(1);
1450 const auto vibration_count = ctx.GetReadBufferNumElements<Core::HID::VibrationValue>(1);
1451
1452 auto vibration_device_handles =
1453 std::span(reinterpret_cast<const Core::HID::VibrationDeviceHandle*>(handle_data.data()),
1454 handle_count);
1455 auto vibration_values = std::span(
1456 reinterpret_cast<const Core::HID::VibrationValue*>(vibration_data.data()), vibration_count);
1457
1458 GetResourceManager()
1459 ->GetController<Controller_NPad>(HidController::NPad)
1460 .VibrateControllers(vibration_device_handles, vibration_values);
1461
1462 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1463
1464 IPC::ResponseBuilder rb{ctx, 2};
1465 rb.Push(ResultSuccess);
1466}
1467
1468void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) {
1469 IPC::RequestParser rp{ctx};
1470 struct Parameters {
1471 Core::HID::VibrationDeviceHandle vibration_device_handle;
1472 INSERT_PADDING_WORDS_NOINIT(1);
1473 u64 applet_resource_user_id;
1474 Core::HID::VibrationGcErmCommand gc_erm_command;
1475 };
1476 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1477
1478 const auto parameters{rp.PopRaw<Parameters>()};
1479
1480 /**
1481 * Note: This uses yuzu-specific behavior such that the StopHard command produces
1482 * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined below,
1483 * in order to differentiate between Stop and StopHard commands.
1484 * This is done to reuse the controller vibration functions made for regular controllers.
1485 */
1486 const auto vibration_value = [parameters] {
1487 switch (parameters.gc_erm_command) {
1488 case Core::HID::VibrationGcErmCommand::Stop:
1489 return Core::HID::VibrationValue{
1490 .low_amplitude = 0.0f,
1491 .low_frequency = 160.0f,
1492 .high_amplitude = 0.0f,
1493 .high_frequency = 320.0f,
1494 };
1495 case Core::HID::VibrationGcErmCommand::Start:
1496 return Core::HID::VibrationValue{
1497 .low_amplitude = 1.0f,
1498 .low_frequency = 160.0f,
1499 .high_amplitude = 1.0f,
1500 .high_frequency = 320.0f,
1501 };
1502 case Core::HID::VibrationGcErmCommand::StopHard:
1503 return Core::HID::VibrationValue{
1504 .low_amplitude = 0.0f,
1505 .low_frequency = 0.0f,
1506 .high_amplitude = 0.0f,
1507 .high_frequency = 0.0f,
1508 };
1509 default:
1510 return Core::HID::DEFAULT_VIBRATION_VALUE;
1511 }
1512 }();
1513
1514 GetResourceManager()
1515 ->GetController<Controller_NPad>(HidController::NPad)
1516 .VibrateController(parameters.vibration_device_handle, vibration_value);
1517
1518 LOG_DEBUG(Service_HID,
1519 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}, "
1520 "gc_erm_command={}",
1521 parameters.vibration_device_handle.npad_type,
1522 parameters.vibration_device_handle.npad_id,
1523 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id,
1524 parameters.gc_erm_command);
1525
1526 IPC::ResponseBuilder rb{ctx, 2};
1527 rb.Push(ResultSuccess);
1528}
1529
1530void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) {
1531 IPC::RequestParser rp{ctx};
1532 struct Parameters {
1533 Core::HID::VibrationDeviceHandle vibration_device_handle;
1534 INSERT_PADDING_WORDS_NOINIT(1);
1535 u64 applet_resource_user_id;
1536 };
1537
1538 const auto parameters{rp.PopRaw<Parameters>()};
1539
1540 const auto last_vibration = GetResourceManager()
1541 ->GetController<Controller_NPad>(HidController::NPad)
1542 .GetLastVibration(parameters.vibration_device_handle);
1543
1544 const auto gc_erm_command = [last_vibration] {
1545 if (last_vibration.low_amplitude != 0.0f || last_vibration.high_amplitude != 0.0f) {
1546 return Core::HID::VibrationGcErmCommand::Start;
1547 }
1548
1549 /**
1550 * Note: This uses yuzu-specific behavior such that the StopHard command produces
1551 * vibrations where freq_low == 0.0f and freq_high == 0.0f, as defined in the HID function
1552 * SendVibrationGcErmCommand, in order to differentiate between Stop and StopHard commands.
1553 * This is done to reuse the controller vibration functions made for regular controllers.
1554 */
1555 if (last_vibration.low_frequency == 0.0f && last_vibration.high_frequency == 0.0f) {
1556 return Core::HID::VibrationGcErmCommand::StopHard;
1557 }
1558
1559 return Core::HID::VibrationGcErmCommand::Stop;
1560 }();
1561
1562 LOG_DEBUG(Service_HID,
1563 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1564 parameters.vibration_device_handle.npad_type,
1565 parameters.vibration_device_handle.npad_id,
1566 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1567
1568 IPC::ResponseBuilder rb{ctx, 4};
1569 rb.Push(ResultSuccess);
1570 rb.PushEnum(gc_erm_command);
1571}
1572
1573void IHidServer::BeginPermitVibrationSession(HLERequestContext& ctx) {
1574 IPC::RequestParser rp{ctx};
1575 const auto applet_resource_user_id{rp.Pop<u64>()};
1576
1577 GetResourceManager()
1578 ->GetController<Controller_NPad>(HidController::NPad)
1579 .SetPermitVibrationSession(true);
1580
1581 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1582
1583 IPC::ResponseBuilder rb{ctx, 2};
1584 rb.Push(ResultSuccess);
1585}
1586
1587void IHidServer::EndPermitVibrationSession(HLERequestContext& ctx) {
1588 GetResourceManager()
1589 ->GetController<Controller_NPad>(HidController::NPad)
1590 .SetPermitVibrationSession(false);
1591
1592 LOG_DEBUG(Service_HID, "called");
1593
1594 IPC::ResponseBuilder rb{ctx, 2};
1595 rb.Push(ResultSuccess);
1596}
1597
1598void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) {
1599 IPC::RequestParser rp{ctx};
1600 struct Parameters {
1601 Core::HID::VibrationDeviceHandle vibration_device_handle;
1602 INSERT_PADDING_WORDS_NOINIT(1);
1603 u64 applet_resource_user_id;
1604 };
1605 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1606
1607 const auto parameters{rp.PopRaw<Parameters>()};
1608
1609 LOG_DEBUG(Service_HID,
1610 "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
1611 parameters.vibration_device_handle.npad_type,
1612 parameters.vibration_device_handle.npad_id,
1613 parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id);
1614
1615 IPC::ResponseBuilder rb{ctx, 3};
1616 rb.Push(ResultSuccess);
1617 rb.Push(GetResourceManager()
1618 ->GetController<Controller_NPad>(HidController::NPad)
1619 .IsVibrationDeviceMounted(parameters.vibration_device_handle));
1620}
1621
1622void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
1623 IPC::RequestParser rp{ctx};
1624 const auto applet_resource_user_id{rp.Pop<u64>()};
1625
1626 GetResourceManager()->ActivateController(HidController::ConsoleSixAxisSensor);
1627
1628 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1629
1630 IPC::ResponseBuilder rb{ctx, 2};
1631 rb.Push(ResultSuccess);
1632}
1633
1634void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
1635 IPC::RequestParser rp{ctx};
1636 struct Parameters {
1637 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
1638 INSERT_PADDING_WORDS_NOINIT(1);
1639 u64 applet_resource_user_id;
1640 };
1641 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1642
1643 const auto parameters{rp.PopRaw<Parameters>()};
1644
1645 LOG_WARNING(Service_HID,
1646 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
1647 parameters.console_sixaxis_handle.unknown_1,
1648 parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
1649
1650 IPC::ResponseBuilder rb{ctx, 2};
1651 rb.Push(ResultSuccess);
1652}
1653
1654void IHidServer::StopConsoleSixAxisSensor(HLERequestContext& ctx) {
1655 IPC::RequestParser rp{ctx};
1656 struct Parameters {
1657 Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle;
1658 INSERT_PADDING_WORDS_NOINIT(1);
1659 u64 applet_resource_user_id;
1660 };
1661 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1662
1663 const auto parameters{rp.PopRaw<Parameters>()};
1664
1665 LOG_WARNING(Service_HID,
1666 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
1667 parameters.console_sixaxis_handle.unknown_1,
1668 parameters.console_sixaxis_handle.unknown_2, parameters.applet_resource_user_id);
1669
1670 IPC::ResponseBuilder rb{ctx, 2};
1671 rb.Push(ResultSuccess);
1672}
1673
1674void IHidServer::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
1675 IPC::RequestParser rp{ctx};
1676 const auto applet_resource_user_id{rp.Pop<u64>()};
1677
1678 GetResourceManager()->ActivateController(HidController::ConsoleSixAxisSensor);
1679
1680 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1681
1682 IPC::ResponseBuilder rb{ctx, 2};
1683 rb.Push(ResultSuccess);
1684}
1685
1686void IHidServer::StartSevenSixAxisSensor(HLERequestContext& ctx) {
1687 IPC::RequestParser rp{ctx};
1688 const auto applet_resource_user_id{rp.Pop<u64>()};
1689
1690 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1691 applet_resource_user_id);
1692
1693 IPC::ResponseBuilder rb{ctx, 2};
1694 rb.Push(ResultSuccess);
1695}
1696
1697void IHidServer::StopSevenSixAxisSensor(HLERequestContext& ctx) {
1698 IPC::RequestParser rp{ctx};
1699 const auto applet_resource_user_id{rp.Pop<u64>()};
1700
1701 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1702 applet_resource_user_id);
1703
1704 IPC::ResponseBuilder rb{ctx, 2};
1705 rb.Push(ResultSuccess);
1706}
1707
1708void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
1709 IPC::RequestParser rp{ctx};
1710 const auto applet_resource_user_id{rp.Pop<u64>()};
1711 const auto t_mem_1_size{rp.Pop<u64>()};
1712 const auto t_mem_2_size{rp.Pop<u64>()};
1713 const auto t_mem_1_handle{ctx.GetCopyHandle(0)};
1714 const auto t_mem_2_handle{ctx.GetCopyHandle(1)};
1715
1716 ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes");
1717 ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
1718
1719 auto t_mem_1 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1720 t_mem_1_handle);
1721
1722 if (t_mem_1.IsNull()) {
1723 LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
1724 IPC::ResponseBuilder rb{ctx, 2};
1725 rb.Push(ResultUnknown);
1726 return;
1727 }
1728
1729 auto t_mem_2 = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
1730 t_mem_2_handle);
1731
1732 if (t_mem_2.IsNull()) {
1733 LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
1734 IPC::ResponseBuilder rb{ctx, 2};
1735 rb.Push(ResultUnknown);
1736 return;
1737 }
1738
1739 ASSERT_MSG(t_mem_1->GetSize() == 0x1000, "t_mem_1 has incorrect size");
1740 ASSERT_MSG(t_mem_2->GetSize() == 0x7F000, "t_mem_2 has incorrect size");
1741
1742 // Activate console six axis controller
1743 GetResourceManager()
1744 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1745 .ActivateController();
1746
1747 GetResourceManager()
1748 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1749 .SetTransferMemoryAddress(t_mem_1->GetSourceAddress());
1750
1751 LOG_WARNING(Service_HID,
1752 "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "
1753 "applet_resource_user_id={}",
1754 t_mem_1_handle, t_mem_2_handle, applet_resource_user_id);
1755
1756 IPC::ResponseBuilder rb{ctx, 2};
1757 rb.Push(ResultSuccess);
1758}
1759
1760void IHidServer::FinalizeSevenSixAxisSensor(HLERequestContext& ctx) {
1761 IPC::RequestParser rp{ctx};
1762 const auto applet_resource_user_id{rp.Pop<u64>()};
1763
1764 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
1765 applet_resource_user_id);
1766
1767 IPC::ResponseBuilder rb{ctx, 2};
1768 rb.Push(ResultSuccess);
1769}
1770
1771void IHidServer::ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx) {
1772 IPC::RequestParser rp{ctx};
1773 const auto applet_resource_user_id{rp.Pop<u64>()};
1774
1775 GetResourceManager()
1776 ->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
1777 .ResetTimestamp();
1778
1779 LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
1780
1781 IPC::ResponseBuilder rb{ctx, 2};
1782 rb.Push(ResultSuccess);
1783}
1784
1785void IHidServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
1786 IPC::RequestParser rp{ctx};
1787
1788 LOG_WARNING(Service_HID, "(STUBBED) called");
1789
1790 IPC::ResponseBuilder rb{ctx, 3};
1791 rb.Push(ResultSuccess);
1792 rb.Push(false);
1793}
1794
1795void IHidServer::GetPalmaConnectionHandle(HLERequestContext& ctx) {
1796 IPC::RequestParser rp{ctx};
1797 struct Parameters {
1798 Core::HID::NpadIdType npad_id;
1799 INSERT_PADDING_WORDS_NOINIT(1);
1800 u64 applet_resource_user_id;
1801 };
1802 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1803
1804 const auto parameters{rp.PopRaw<Parameters>()};
1805
1806 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
1807 parameters.npad_id, parameters.applet_resource_user_id);
1808
1809 Controller_Palma::PalmaConnectionHandle handle;
1810 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1811 const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle);
1812
1813 IPC::ResponseBuilder rb{ctx, 4};
1814 rb.Push(result);
1815 rb.PushRaw(handle);
1816}
1817
1818void IHidServer::InitializePalma(HLERequestContext& ctx) {
1819 IPC::RequestParser rp{ctx};
1820 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1821
1822 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1823
1824 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1825 const auto result = controller.InitializePalma(connection_handle);
1826
1827 IPC::ResponseBuilder rb{ctx, 2};
1828 rb.Push(result);
1829}
1830
1831void IHidServer::AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx) {
1832 IPC::RequestParser rp{ctx};
1833 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1834
1835 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1836
1837 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1838
1839 IPC::ResponseBuilder rb{ctx, 2, 1};
1840 rb.Push(ResultSuccess);
1841 rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
1842}
1843
1844void IHidServer::GetPalmaOperationInfo(HLERequestContext& ctx) {
1845 IPC::RequestParser rp{ctx};
1846 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1847
1848 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1849
1850 Controller_Palma::PalmaOperationType operation_type;
1851 Controller_Palma::PalmaOperationData data;
1852 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1853 const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data);
1854
1855 if (result.IsError()) {
1856 IPC::ResponseBuilder rb{ctx, 2};
1857 rb.Push(result);
1858 }
1859
1860 ctx.WriteBuffer(data);
1861 IPC::ResponseBuilder rb{ctx, 4};
1862 rb.Push(result);
1863 rb.Push(static_cast<u64>(operation_type));
1864}
1865
1866void IHidServer::PlayPalmaActivity(HLERequestContext& ctx) {
1867 IPC::RequestParser rp{ctx};
1868 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1869 const auto palma_activity{rp.Pop<u64>()};
1870
1871 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
1872 connection_handle.npad_id, palma_activity);
1873
1874 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1875 const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity);
1876
1877 IPC::ResponseBuilder rb{ctx, 2};
1878 rb.Push(result);
1879}
1880
1881void IHidServer::SetPalmaFrModeType(HLERequestContext& ctx) {
1882 IPC::RequestParser rp{ctx};
1883 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1884 const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
1885
1886 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
1887 connection_handle.npad_id, fr_mode);
1888
1889 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1890 const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode);
1891
1892 IPC::ResponseBuilder rb{ctx, 2};
1893 rb.Push(result);
1894}
1895
1896void IHidServer::ReadPalmaStep(HLERequestContext& ctx) {
1897 IPC::RequestParser rp{ctx};
1898 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1899
1900 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1901
1902 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1903 const auto result = controller.ReadPalmaStep(connection_handle);
1904
1905 IPC::ResponseBuilder rb{ctx, 2};
1906 rb.Push(result);
1907}
1908
1909void IHidServer::EnablePalmaStep(HLERequestContext& ctx) {
1910 IPC::RequestParser rp{ctx};
1911 struct Parameters {
1912 bool is_enabled;
1913 INSERT_PADDING_WORDS_NOINIT(1);
1914 Controller_Palma::PalmaConnectionHandle connection_handle;
1915 };
1916 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
1917
1918 const auto parameters{rp.PopRaw<Parameters>()};
1919
1920 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
1921 parameters.connection_handle.npad_id, parameters.is_enabled);
1922
1923 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1924 const auto result =
1925 controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
1926
1927 IPC::ResponseBuilder rb{ctx, 2};
1928 rb.Push(result);
1929}
1930
1931void IHidServer::ResetPalmaStep(HLERequestContext& ctx) {
1932 IPC::RequestParser rp{ctx};
1933 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1934
1935 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1936
1937 auto& controller = GetResourceManager()->GetController<Controller_Palma>(HidController::Palma);
1938 const auto result = controller.ResetPalmaStep(connection_handle);
1939
1940 IPC::ResponseBuilder rb{ctx, 2};
1941 rb.Push(result);
1942}
1943
1944void IHidServer::ReadPalmaApplicationSection(HLERequestContext& ctx) {
1945 LOG_WARNING(Service_HID, "(STUBBED) called");
1946
1947 IPC::ResponseBuilder rb{ctx, 2};
1948 rb.Push(ResultSuccess);
1949}
1950
1951void IHidServer::WritePalmaApplicationSection(HLERequestContext& ctx) {
1952 LOG_WARNING(Service_HID, "(STUBBED) called");
1953
1954 IPC::ResponseBuilder rb{ctx, 2};
1955 rb.Push(ResultSuccess);
1956}
1957
1958void IHidServer::ReadPalmaUniqueCode(HLERequestContext& ctx) {
1959 IPC::RequestParser rp{ctx};
1960 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1961
1962 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1963
1964 GetResourceManager()
1965 ->GetController<Controller_Palma>(HidController::Palma)
1966 .ReadPalmaUniqueCode(connection_handle);
1967
1968 IPC::ResponseBuilder rb{ctx, 2};
1969 rb.Push(ResultSuccess);
1970}
1971
1972void IHidServer::SetPalmaUniqueCodeInvalid(HLERequestContext& ctx) {
1973 IPC::RequestParser rp{ctx};
1974 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1975
1976 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
1977
1978 GetResourceManager()
1979 ->GetController<Controller_Palma>(HidController::Palma)
1980 .SetPalmaUniqueCodeInvalid(connection_handle);
1981
1982 IPC::ResponseBuilder rb{ctx, 2};
1983 rb.Push(ResultSuccess);
1984}
1985
1986void IHidServer::WritePalmaActivityEntry(HLERequestContext& ctx) {
1987 LOG_CRITICAL(Service_HID, "(STUBBED) called");
1988
1989 IPC::ResponseBuilder rb{ctx, 2};
1990 rb.Push(ResultSuccess);
1991}
1992
1993void IHidServer::WritePalmaRgbLedPatternEntry(HLERequestContext& ctx) {
1994 IPC::RequestParser rp{ctx};
1995 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
1996 const auto unknown{rp.Pop<u64>()};
1997
1998 [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
1999
2000 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
2001 connection_handle.npad_id, unknown);
2002
2003 GetResourceManager()
2004 ->GetController<Controller_Palma>(HidController::Palma)
2005 .WritePalmaRgbLedPatternEntry(connection_handle, unknown);
2006
2007 IPC::ResponseBuilder rb{ctx, 2};
2008 rb.Push(ResultSuccess);
2009}
2010
2011void IHidServer::WritePalmaWaveEntry(HLERequestContext& ctx) {
2012 IPC::RequestParser rp{ctx};
2013 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2014 const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
2015 const auto unknown{rp.Pop<u64>()};
2016 const auto t_mem_size{rp.Pop<u64>()};
2017 const auto t_mem_handle{ctx.GetCopyHandle(0)};
2018 const auto size{rp.Pop<u64>()};
2019
2020 ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
2021
2022 auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
2023 t_mem_handle);
2024
2025 if (t_mem.IsNull()) {
2026 LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
2027 IPC::ResponseBuilder rb{ctx, 2};
2028 rb.Push(ResultUnknown);
2029 return;
2030 }
2031
2032 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
2033
2034 LOG_WARNING(Service_HID,
2035 "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
2036 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
2037 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2038
2039 GetResourceManager()
2040 ->GetController<Controller_Palma>(HidController::Palma)
2041 .WritePalmaWaveEntry(connection_handle, wave_set, t_mem->GetSourceAddress(), t_mem_size);
2042
2043 IPC::ResponseBuilder rb{ctx, 2};
2044 rb.Push(ResultSuccess);
2045}
2046
2047void IHidServer::SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2048 IPC::RequestParser rp{ctx};
2049 struct Parameters {
2050 s32 database_id_version;
2051 INSERT_PADDING_WORDS_NOINIT(1);
2052 Controller_Palma::PalmaConnectionHandle connection_handle;
2053 };
2054 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2055
2056 const auto parameters{rp.PopRaw<Parameters>()};
2057
2058 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
2059 parameters.connection_handle.npad_id, parameters.database_id_version);
2060
2061 GetResourceManager()
2062 ->GetController<Controller_Palma>(HidController::Palma)
2063 .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
2064 parameters.database_id_version);
2065
2066 IPC::ResponseBuilder rb{ctx, 2};
2067 rb.Push(ResultSuccess);
2068}
2069
2070void IHidServer::GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx) {
2071 IPC::RequestParser rp{ctx};
2072 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2073
2074 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2075
2076 GetResourceManager()
2077 ->GetController<Controller_Palma>(HidController::Palma)
2078 .GetPalmaDataBaseIdentificationVersion(connection_handle);
2079
2080 IPC::ResponseBuilder rb{ctx, 2};
2081 rb.Push(ResultSuccess);
2082}
2083
2084void IHidServer::SuspendPalmaFeature(HLERequestContext& ctx) {
2085 LOG_WARNING(Service_HID, "(STUBBED) called");
2086
2087 IPC::ResponseBuilder rb{ctx, 2};
2088 rb.Push(ResultSuccess);
2089}
2090
2091void IHidServer::GetPalmaOperationResult(HLERequestContext& ctx) {
2092 IPC::RequestParser rp{ctx};
2093 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2094
2095 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2096
2097 const auto result = GetResourceManager()
2098 ->GetController<Controller_Palma>(HidController::Palma)
2099 .GetPalmaOperationResult(connection_handle);
2100
2101 IPC::ResponseBuilder rb{ctx, 2};
2102 rb.Push(result);
2103}
2104
2105void IHidServer::ReadPalmaPlayLog(HLERequestContext& ctx) {
2106 LOG_WARNING(Service_HID, "(STUBBED) called");
2107
2108 IPC::ResponseBuilder rb{ctx, 2};
2109 rb.Push(ResultSuccess);
2110}
2111
2112void IHidServer::ResetPalmaPlayLog(HLERequestContext& ctx) {
2113 LOG_WARNING(Service_HID, "(STUBBED) called");
2114
2115 IPC::ResponseBuilder rb{ctx, 2};
2116 rb.Push(ResultSuccess);
2117}
2118
2119void IHidServer::SetIsPalmaAllConnectable(HLERequestContext& ctx) {
2120 IPC::RequestParser rp{ctx};
2121 struct Parameters {
2122 bool is_palma_all_connectable;
2123 INSERT_PADDING_BYTES_NOINIT(7);
2124 u64 applet_resource_user_id;
2125 };
2126 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2127
2128 const auto parameters{rp.PopRaw<Parameters>()};
2129
2130 LOG_WARNING(Service_HID,
2131 "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
2132 parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
2133
2134 GetResourceManager()
2135 ->GetController<Controller_Palma>(HidController::Palma)
2136 .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
2137
2138 IPC::ResponseBuilder rb{ctx, 2};
2139 rb.Push(ResultSuccess);
2140}
2141
2142void IHidServer::SetIsPalmaPairedConnectable(HLERequestContext& ctx) {
2143 LOG_WARNING(Service_HID, "(STUBBED) called");
2144
2145 IPC::ResponseBuilder rb{ctx, 2};
2146 rb.Push(ResultSuccess);
2147}
2148
2149void IHidServer::PairPalma(HLERequestContext& ctx) {
2150 IPC::RequestParser rp{ctx};
2151 const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
2152
2153 LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
2154
2155 GetResourceManager()
2156 ->GetController<Controller_Palma>(HidController::Palma)
2157 .PairPalma(connection_handle);
2158
2159 IPC::ResponseBuilder rb{ctx, 2};
2160 rb.Push(ResultSuccess);
2161}
2162
2163void IHidServer::SetPalmaBoostMode(HLERequestContext& ctx) {
2164 IPC::RequestParser rp{ctx};
2165 const auto palma_boost_mode{rp.Pop<bool>()};
2166
2167 LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
2168
2169 GetResourceManager()
2170 ->GetController<Controller_Palma>(HidController::Palma)
2171 .SetPalmaBoostMode(palma_boost_mode);
2172
2173 IPC::ResponseBuilder rb{ctx, 2};
2174 rb.Push(ResultSuccess);
2175}
2176
2177void IHidServer::CancelWritePalmaWaveEntry(HLERequestContext& ctx) {
2178 LOG_WARNING(Service_HID, "(STUBBED) called");
2179
2180 IPC::ResponseBuilder rb{ctx, 2};
2181 rb.Push(ResultSuccess);
2182}
2183
2184void IHidServer::EnablePalmaBoostMode(HLERequestContext& ctx) {
2185 LOG_WARNING(Service_HID, "(STUBBED) called");
2186
2187 IPC::ResponseBuilder rb{ctx, 2};
2188 rb.Push(ResultSuccess);
2189}
2190
2191void IHidServer::GetPalmaBluetoothAddress(HLERequestContext& ctx) {
2192 LOG_WARNING(Service_HID, "(STUBBED) called");
2193
2194 IPC::ResponseBuilder rb{ctx, 2};
2195 rb.Push(ResultSuccess);
2196}
2197
2198void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
2199 LOG_WARNING(Service_HID, "(STUBBED) called");
2200
2201 IPC::ResponseBuilder rb{ctx, 2};
2202 rb.Push(ResultSuccess);
2203}
2204
2205void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
2206 IPC::RequestParser rp{ctx};
2207 const auto applet_resource_user_id{rp.Pop<u64>()};
2208 const auto communication_mode{rp.PopEnum<Controller_NPad::NpadCommunicationMode>()};
2209
2210 GetResourceManager()
2211 ->GetController<Controller_NPad>(HidController::NPad)
2212 .SetNpadCommunicationMode(communication_mode);
2213
2214 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, communication_mode={}",
2215 applet_resource_user_id, communication_mode);
2216
2217 IPC::ResponseBuilder rb{ctx, 2};
2218 rb.Push(ResultSuccess);
2219}
2220
2221void IHidServer::GetNpadCommunicationMode(HLERequestContext& ctx) {
2222 IPC::RequestParser rp{ctx};
2223
2224 LOG_WARNING(Service_HID, "(STUBBED) called");
2225
2226 IPC::ResponseBuilder rb{ctx, 4};
2227 rb.Push(ResultSuccess);
2228 rb.PushEnum(GetResourceManager()
2229 ->GetController<Controller_NPad>(HidController::NPad)
2230 .GetNpadCommunicationMode());
2231}
2232
2233void IHidServer::SetTouchScreenConfiguration(HLERequestContext& ctx) {
2234 IPC::RequestParser rp{ctx};
2235 const auto touchscreen_mode{rp.PopRaw<Core::HID::TouchScreenConfigurationForNx>()};
2236 const auto applet_resource_user_id{rp.Pop<u64>()};
2237
2238 LOG_WARNING(Service_HID, "(STUBBED) called, touchscreen_mode={}, applet_resource_user_id={}",
2239 touchscreen_mode.mode, applet_resource_user_id);
2240
2241 IPC::ResponseBuilder rb{ctx, 2};
2242 rb.Push(ResultSuccess);
2243}
2244
2245void IHidServer::IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx) {
2246 IPC::RequestParser rp{ctx};
2247 struct Parameters {
2248 s32 unknown;
2249 INSERT_PADDING_WORDS_NOINIT(1);
2250 u64 applet_resource_user_id;
2251 };
2252 static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
2253
2254 const auto parameters{rp.PopRaw<Parameters>()};
2255
2256 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
2257 parameters.unknown, parameters.applet_resource_user_id);
2258
2259 IPC::ResponseBuilder rb{ctx, 3};
2260 rb.Push(ResultSuccess);
2261 rb.Push(false);
2262}
2263
2264std::shared_ptr<ResourceManager> IHidServer::GetResourceManager() {
2265 resource_manager->Initialize();
2266 return resource_manager;
2267}
2268
2269} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h
new file mode 100644
index 000000000..3d25ea1bc
--- /dev/null
+++ b/src/core/hle/service/hid/hid_server.h
@@ -0,0 +1,138 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/service.h"
7
8namespace Core {
9class System;
10}
11
12namespace Service::HID {
13class ResourceManager;
14
15class IHidServer final : public ServiceFramework<IHidServer> {
16public:
17 explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
18 ~IHidServer() override;
19
20 std::shared_ptr<ResourceManager> GetResourceManager();
21
22private:
23 void CreateAppletResource(HLERequestContext& ctx);
24 void ActivateDebugPad(HLERequestContext& ctx);
25 void ActivateTouchScreen(HLERequestContext& ctx);
26 void ActivateMouse(HLERequestContext& ctx);
27 void ActivateKeyboard(HLERequestContext& ctx);
28 void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
29 void ActivateXpad(HLERequestContext& ctx);
30 void GetXpadIds(HLERequestContext& ctx);
31 void GetJoyXpadIds(HLERequestContext& ctx);
32 void ActivateSixAxisSensor(HLERequestContext& ctx);
33 void DeactivateSixAxisSensor(HLERequestContext& ctx);
34 void StartSixAxisSensor(HLERequestContext& ctx);
35 void StopSixAxisSensor(HLERequestContext& ctx);
36 void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
37 void EnableSixAxisSensorFusion(HLERequestContext& ctx);
38 void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
39 void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
40 void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
41 void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
42 void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
43 void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
44 void IsSixAxisSensorAtRest(HLERequestContext& ctx);
45 void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
46 void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
47 void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
48 void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
49 void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
50 void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
51 void ActivateGesture(HLERequestContext& ctx);
52 void SetSupportedNpadStyleSet(HLERequestContext& ctx);
53 void GetSupportedNpadStyleSet(HLERequestContext& ctx);
54 void SetSupportedNpadIdType(HLERequestContext& ctx);
55 void ActivateNpad(HLERequestContext& ctx);
56 void DeactivateNpad(HLERequestContext& ctx);
57 void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
58 void DisconnectNpad(HLERequestContext& ctx);
59 void GetPlayerLedPattern(HLERequestContext& ctx);
60 void ActivateNpadWithRevision(HLERequestContext& ctx);
61 void SetNpadJoyHoldType(HLERequestContext& ctx);
62 void GetNpadJoyHoldType(HLERequestContext& ctx);
63 void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
64 void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
65 void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
66 void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
67 void StartLrAssignmentMode(HLERequestContext& ctx);
68 void StopLrAssignmentMode(HLERequestContext& ctx);
69 void SetNpadHandheldActivationMode(HLERequestContext& ctx);
70 void GetNpadHandheldActivationMode(HLERequestContext& ctx);
71 void SwapNpadAssignment(HLERequestContext& ctx);
72 void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
73 void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
74 void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
75 void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
76 void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
77 void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
78 void GetVibrationDeviceInfo(HLERequestContext& ctx);
79 void SendVibrationValue(HLERequestContext& ctx);
80 void GetActualVibrationValue(HLERequestContext& ctx);
81 void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
82 void PermitVibration(HLERequestContext& ctx);
83 void IsVibrationPermitted(HLERequestContext& ctx);
84 void SendVibrationValues(HLERequestContext& ctx);
85 void SendVibrationGcErmCommand(HLERequestContext& ctx);
86 void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
87 void BeginPermitVibrationSession(HLERequestContext& ctx);
88 void EndPermitVibrationSession(HLERequestContext& ctx);
89 void IsVibrationDeviceMounted(HLERequestContext& ctx);
90 void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
91 void StartConsoleSixAxisSensor(HLERequestContext& ctx);
92 void StopConsoleSixAxisSensor(HLERequestContext& ctx);
93 void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
94 void StartSevenSixAxisSensor(HLERequestContext& ctx);
95 void StopSevenSixAxisSensor(HLERequestContext& ctx);
96 void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
97 void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
98 void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
99 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
100 void GetPalmaConnectionHandle(HLERequestContext& ctx);
101 void InitializePalma(HLERequestContext& ctx);
102 void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
103 void GetPalmaOperationInfo(HLERequestContext& ctx);
104 void PlayPalmaActivity(HLERequestContext& ctx);
105 void SetPalmaFrModeType(HLERequestContext& ctx);
106 void ReadPalmaStep(HLERequestContext& ctx);
107 void EnablePalmaStep(HLERequestContext& ctx);
108 void ResetPalmaStep(HLERequestContext& ctx);
109 void ReadPalmaApplicationSection(HLERequestContext& ctx);
110 void WritePalmaApplicationSection(HLERequestContext& ctx);
111 void ReadPalmaUniqueCode(HLERequestContext& ctx);
112 void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
113 void WritePalmaActivityEntry(HLERequestContext& ctx);
114 void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
115 void WritePalmaWaveEntry(HLERequestContext& ctx);
116 void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
117 void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
118 void SuspendPalmaFeature(HLERequestContext& ctx);
119 void GetPalmaOperationResult(HLERequestContext& ctx);
120 void ReadPalmaPlayLog(HLERequestContext& ctx);
121 void ResetPalmaPlayLog(HLERequestContext& ctx);
122 void SetIsPalmaAllConnectable(HLERequestContext& ctx);
123 void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
124 void PairPalma(HLERequestContext& ctx);
125 void SetPalmaBoostMode(HLERequestContext& ctx);
126 void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
127 void EnablePalmaBoostMode(HLERequestContext& ctx);
128 void GetPalmaBluetoothAddress(HLERequestContext& ctx);
129 void SetDisallowedPalmaConnection(HLERequestContext& ctx);
130 void SetNpadCommunicationMode(HLERequestContext& ctx);
131 void GetNpadCommunicationMode(HLERequestContext& ctx);
132 void SetTouchScreenConfiguration(HLERequestContext& ctx);
133 void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
134
135 std::shared_ptr<ResourceManager> resource_manager;
136};
137
138} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
new file mode 100644
index 000000000..83cfadada
--- /dev/null
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -0,0 +1,304 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/hid/hid_core.h"
5#include "core/hle/service/hid/controllers/npad.h"
6#include "core/hle/service/hid/controllers/touchscreen.h"
7#include "core/hle/service/hid/errors.h"
8#include "core/hle/service/hid/hid_system_server.h"
9#include "core/hle/service/hid/resource_manager.h"
10#include "core/hle/service/ipc_helpers.h"
11
12namespace Service::HID {
13
14IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
15 : ServiceFramework{system_, "hid:sys"}, service_context{system_, service_name},
16 resource_manager{resource} {
17 // clang-format off
18 static const FunctionInfo functions[] = {
19 {31, nullptr, "SendKeyboardLockKeyEvent"},
20 {101, nullptr, "AcquireHomeButtonEventHandle"},
21 {111, nullptr, "ActivateHomeButton"},
22 {121, nullptr, "AcquireSleepButtonEventHandle"},
23 {131, nullptr, "ActivateSleepButton"},
24 {141, nullptr, "AcquireCaptureButtonEventHandle"},
25 {151, nullptr, "ActivateCaptureButton"},
26 {161, nullptr, "GetPlatformConfig"},
27 {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
28 {211, nullptr, "GetNpadsWithNfc"},
29 {212, nullptr, "AcquireNfcActivateEventHandle"},
30 {213, nullptr, "ActivateNfc"},
31 {214, nullptr, "GetXcdHandleForNpadWithNfc"},
32 {215, nullptr, "IsNfcActivated"},
33 {230, nullptr, "AcquireIrSensorEventHandle"},
34 {231, nullptr, "ActivateIrSensor"},
35 {232, nullptr, "GetIrSensorState"},
36 {233, nullptr, "GetXcdHandleForNpadWithIrSensor"},
37 {301, nullptr, "ActivateNpadSystem"},
38 {303, &IHidSystemServer::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"},
39 {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
40 {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
41 {306, &IHidSystemServer::GetLastActiveNpad, "GetLastActiveNpad"},
42 {307, nullptr, "GetNpadSystemExtStyle"},
43 {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
44 {309, nullptr, "GetNpadFullKeyGripColor"},
45 {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
46 {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
47 {312, nullptr, "SetSupportedNpadStyleSetAll"},
48 {313, nullptr, "GetNpadCaptureButtonAssignment"},
49 {314, nullptr, "GetAppletFooterUiType"},
50 {315, nullptr, "GetAppletDetailedUiType"},
51 {316, nullptr, "GetNpadInterfaceType"},
52 {317, nullptr, "GetNpadLeftRightInterfaceType"},
53 {318, nullptr, "HasBattery"},
54 {319, nullptr, "HasLeftRightBattery"},
55 {321, &IHidSystemServer::GetUniquePadsFromNpad, "GetUniquePadsFromNpad"},
56 {322, nullptr, "GetIrSensorState"},
57 {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
58 {324, nullptr, "GetUniquePadButtonSet"},
59 {325, nullptr, "GetUniquePadColor"},
60 {326, nullptr, "GetUniquePadAppletDetailedUiType"},
61 {327, nullptr, "GetAbstractedPadIdDataFromNpad"},
62 {328, nullptr, "AttachAbstractedPadToNpad"},
63 {329, nullptr, "DetachAbstractedPadAll"},
64 {330, nullptr, "CheckAbstractedPadConnection"},
65 {500, nullptr, "SetAppletResourceUserId"},
66 {501, nullptr, "RegisterAppletResourceUserId"},
67 {502, nullptr, "UnregisterAppletResourceUserId"},
68 {503, nullptr, "EnableAppletToGetInput"},
69 {504, nullptr, "SetAruidValidForVibration"},
70 {505, nullptr, "EnableAppletToGetSixAxisSensor"},
71 {506, nullptr, "EnableAppletToGetPadInput"},
72 {507, nullptr, "EnableAppletToGetTouchScreen"},
73 {510, nullptr, "SetVibrationMasterVolume"},
74 {511, nullptr, "GetVibrationMasterVolume"},
75 {512, nullptr, "BeginPermitVibrationSession"},
76 {513, nullptr, "EndPermitVibrationSession"},
77 {514, nullptr, "Unknown514"},
78 {520, nullptr, "EnableHandheldHids"},
79 {521, nullptr, "DisableHandheldHids"},
80 {522, nullptr, "SetJoyConRailEnabled"},
81 {523, nullptr, "IsJoyConRailEnabled"},
82 {524, nullptr, "IsHandheldHidsEnabled"},
83 {525, nullptr, "IsJoyConAttachedOnAllRail"},
84 {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
85 {541, nullptr, "GetPlayReportControllerUsages"},
86 {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
87 {543, nullptr, "GetRegisteredDevicesOld"},
88 {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
89 {545, nullptr, "SendConnectionTrigger"},
90 {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
91 {547, nullptr, "GetAllowedBluetoothLinksCount"},
92 {548, nullptr, "GetRegisteredDevices"},
93 {549, nullptr, "GetConnectableRegisteredDevices"},
94 {700, nullptr, "ActivateUniquePad"},
95 {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
96 {703, nullptr, "GetUniquePadIds"},
97 {751, &IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle, "AcquireJoyDetachOnBluetoothOffEventHandle"},
98 {800, nullptr, "ListSixAxisSensorHandles"},
99 {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
100 {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
101 {803, nullptr, "StartSixAxisSensorUserCalibration"},
102 {804, nullptr, "CancelSixAxisSensorUserCalibration"},
103 {805, nullptr, "GetUniquePadBluetoothAddress"},
104 {806, nullptr, "DisconnectUniquePad"},
105 {807, nullptr, "GetUniquePadType"},
106 {808, nullptr, "GetUniquePadInterface"},
107 {809, nullptr, "GetUniquePadSerialNumber"},
108 {810, nullptr, "GetUniquePadControllerNumber"},
109 {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
110 {812, nullptr, "GetConsoleUniqueSixAxisSensorHandle"},
111 {821, nullptr, "StartAnalogStickManualCalibration"},
112 {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
113 {823, nullptr, "CancelAnalogStickManualCalibration"},
114 {824, nullptr, "ResetAnalogStickManualCalibration"},
115 {825, nullptr, "GetAnalogStickState"},
116 {826, nullptr, "GetAnalogStickManualCalibrationStage"},
117 {827, nullptr, "IsAnalogStickButtonPressed"},
118 {828, nullptr, "IsAnalogStickInReleasePosition"},
119 {829, nullptr, "IsAnalogStickInCircumference"},
120 {830, nullptr, "SetNotificationLedPattern"},
121 {831, nullptr, "SetNotificationLedPatternWithTimeout"},
122 {832, nullptr, "PrepareHidsForNotificationWake"},
123 {850, &IHidSystemServer::IsUsbFullKeyControllerEnabled, "IsUsbFullKeyControllerEnabled"},
124 {851, nullptr, "EnableUsbFullKeyController"},
125 {852, nullptr, "IsUsbConnected"},
126 {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
127 {900, nullptr, "ActivateInputDetector"},
128 {901, nullptr, "NotifyInputDetector"},
129 {1000, nullptr, "InitializeFirmwareUpdate"},
130 {1001, nullptr, "GetFirmwareVersion"},
131 {1002, nullptr, "GetAvailableFirmwareVersion"},
132 {1003, nullptr, "IsFirmwareUpdateAvailable"},
133 {1004, nullptr, "CheckFirmwareUpdateRequired"},
134 {1005, nullptr, "StartFirmwareUpdate"},
135 {1006, nullptr, "AbortFirmwareUpdate"},
136 {1007, nullptr, "GetFirmwareUpdateState"},
137 {1008, nullptr, "ActivateAudioControl"},
138 {1009, nullptr, "AcquireAudioControlEventHandle"},
139 {1010, nullptr, "GetAudioControlStates"},
140 {1011, nullptr, "DeactivateAudioControl"},
141 {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
142 {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
143 {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
144 {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
145 {1100, nullptr, "GetHidbusSystemServiceObject"},
146 {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
147 {1130, nullptr, "InitializeUsbFirmwareUpdate"},
148 {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
149 {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
150 {1133, nullptr, "StartUsbFirmwareUpdate"},
151 {1134, nullptr, "GetUsbFirmwareUpdateState"},
152 {1150, nullptr, "SetTouchScreenMagnification"},
153 {1151, nullptr, "GetTouchScreenFirmwareVersion"},
154 {1152, nullptr, "SetTouchScreenDefaultConfiguration"},
155 {1153, &IHidSystemServer::GetTouchScreenDefaultConfiguration, "GetTouchScreenDefaultConfiguration"},
156 {1154, nullptr, "IsFirmwareAvailableForNotification"},
157 {1155, nullptr, "SetForceHandheldStyleVibration"},
158 {1156, nullptr, "SendConnectionTriggerWithoutTimeoutEvent"},
159 {1157, nullptr, "CancelConnectionTrigger"},
160 {1200, nullptr, "IsButtonConfigSupported"},
161 {1201, nullptr, "IsButtonConfigEmbeddedSupported"},
162 {1202, nullptr, "DeleteButtonConfig"},
163 {1203, nullptr, "DeleteButtonConfigEmbedded"},
164 {1204, nullptr, "SetButtonConfigEnabled"},
165 {1205, nullptr, "SetButtonConfigEmbeddedEnabled"},
166 {1206, nullptr, "IsButtonConfigEnabled"},
167 {1207, nullptr, "IsButtonConfigEmbeddedEnabled"},
168 {1208, nullptr, "SetButtonConfigEmbedded"},
169 {1209, nullptr, "SetButtonConfigFull"},
170 {1210, nullptr, "SetButtonConfigLeft"},
171 {1211, nullptr, "SetButtonConfigRight"},
172 {1212, nullptr, "GetButtonConfigEmbedded"},
173 {1213, nullptr, "GetButtonConfigFull"},
174 {1214, nullptr, "GetButtonConfigLeft"},
175 {1215, nullptr, "GetButtonConfigRight"},
176 {1250, nullptr, "IsCustomButtonConfigSupported"},
177 {1251, nullptr, "IsDefaultButtonConfigEmbedded"},
178 {1252, nullptr, "IsDefaultButtonConfigFull"},
179 {1253, nullptr, "IsDefaultButtonConfigLeft"},
180 {1254, nullptr, "IsDefaultButtonConfigRight"},
181 {1255, nullptr, "IsButtonConfigStorageEmbeddedEmpty"},
182 {1256, nullptr, "IsButtonConfigStorageFullEmpty"},
183 {1257, nullptr, "IsButtonConfigStorageLeftEmpty"},
184 {1258, nullptr, "IsButtonConfigStorageRightEmpty"},
185 {1259, nullptr, "GetButtonConfigStorageEmbeddedDeprecated"},
186 {1260, nullptr, "GetButtonConfigStorageFullDeprecated"},
187 {1261, nullptr, "GetButtonConfigStorageLeftDeprecated"},
188 {1262, nullptr, "GetButtonConfigStorageRightDeprecated"},
189 {1263, nullptr, "SetButtonConfigStorageEmbeddedDeprecated"},
190 {1264, nullptr, "SetButtonConfigStorageFullDeprecated"},
191 {1265, nullptr, "SetButtonConfigStorageLeftDeprecated"},
192 {1266, nullptr, "SetButtonConfigStorageRightDeprecated"},
193 {1267, nullptr, "DeleteButtonConfigStorageEmbedded"},
194 {1268, nullptr, "DeleteButtonConfigStorageFull"},
195 {1269, nullptr, "DeleteButtonConfigStorageLeft"},
196 {1270, nullptr, "DeleteButtonConfigStorageRight"},
197 {1271, nullptr, "IsUsingCustomButtonConfig"},
198 {1272, nullptr, "IsAnyCustomButtonConfigEnabled"},
199 {1273, nullptr, "SetAllCustomButtonConfigEnabled"},
200 {1274, nullptr, "SetDefaultButtonConfig"},
201 {1275, nullptr, "SetAllDefaultButtonConfig"},
202 {1276, nullptr, "SetHidButtonConfigEmbedded"},
203 {1277, nullptr, "SetHidButtonConfigFull"},
204 {1278, nullptr, "SetHidButtonConfigLeft"},
205 {1279, nullptr, "SetHidButtonConfigRight"},
206 {1280, nullptr, "GetHidButtonConfigEmbedded"},
207 {1281, nullptr, "GetHidButtonConfigFull"},
208 {1282, nullptr, "GetHidButtonConfigLeft"},
209 {1283, nullptr, "GetHidButtonConfigRight"},
210 {1284, nullptr, "GetButtonConfigStorageEmbedded"},
211 {1285, nullptr, "GetButtonConfigStorageFull"},
212 {1286, nullptr, "GetButtonConfigStorageLeft"},
213 {1287, nullptr, "GetButtonConfigStorageRight"},
214 {1288, nullptr, "SetButtonConfigStorageEmbedded"},
215 {1289, nullptr, "SetButtonConfigStorageFull"},
216 {1290, nullptr, "DeleteButtonConfigStorageRight"},
217 {1291, nullptr, "DeleteButtonConfigStorageRight"},
218 };
219 // clang-format on
220
221 RegisterHandlers(functions);
222
223 joy_detach_event = service_context.CreateEvent("HidSys::JoyDetachEvent");
224}
225
226IHidSystemServer::~IHidSystemServer() {
227 service_context.CloseEvent(joy_detach_event);
228};
229
230void IHidSystemServer::ApplyNpadSystemCommonPolicy(HLERequestContext& ctx) {
231 LOG_WARNING(Service_HID, "called");
232
233 GetResourceManager()
234 ->GetController<Controller_NPad>(HidController::NPad)
235 .ApplyNpadSystemCommonPolicy();
236
237 IPC::ResponseBuilder rb{ctx, 2};
238 rb.Push(ResultSuccess);
239}
240
241void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) {
242 LOG_DEBUG(Service_HID, "(STUBBED) called");
243
244 IPC::ResponseBuilder rb{ctx, 3};
245 rb.Push(ResultSuccess);
246 rb.PushEnum(system.HIDCore().GetLastActiveController());
247}
248
249void IHidSystemServer::GetUniquePadsFromNpad(HLERequestContext& ctx) {
250 IPC::RequestParser rp{ctx};
251 const auto npad_id_type{rp.PopEnum<Core::HID::NpadIdType>()};
252
253 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id_type={}", npad_id_type);
254
255 const std::vector<Core::HID::UniquePadId> unique_pads{};
256
257 ctx.WriteBuffer(unique_pads);
258
259 IPC::ResponseBuilder rb{ctx, 3};
260 rb.Push(ResultSuccess);
261 rb.Push(static_cast<u32>(unique_pads.size()));
262}
263
264void IHidSystemServer::AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx) {
265 LOG_INFO(Service_AM, "called");
266
267 IPC::ResponseBuilder rb{ctx, 2, 1};
268 rb.Push(ResultSuccess);
269 rb.PushCopyObjects(joy_detach_event->GetReadableEvent());
270}
271
272void IHidSystemServer::IsUsbFullKeyControllerEnabled(HLERequestContext& ctx) {
273 const bool is_enabled = false;
274
275 LOG_WARNING(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled);
276
277 IPC::ResponseBuilder rb{ctx, 3};
278 rb.Push(ResultSuccess);
279 rb.Push(is_enabled);
280}
281
282void IHidSystemServer::GetTouchScreenDefaultConfiguration(HLERequestContext& ctx) {
283 LOG_WARNING(Service_HID, "(STUBBED) called");
284
285 Core::HID::TouchScreenConfigurationForNx touchscreen_config{
286 .mode = Core::HID::TouchScreenModeForNx::Finger,
287 };
288
289 if (touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Heat2 &&
290 touchscreen_config.mode != Core::HID::TouchScreenModeForNx::Finger) {
291 touchscreen_config.mode = Core::HID::TouchScreenModeForNx::UseSystemSetting;
292 }
293
294 IPC::ResponseBuilder rb{ctx, 6};
295 rb.Push(ResultSuccess);
296 rb.PushRaw(touchscreen_config);
297}
298
299std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() {
300 resource_manager->Initialize();
301 return resource_manager;
302}
303
304} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h
new file mode 100644
index 000000000..d4b3910fa
--- /dev/null
+++ b/src/core/hle/service/hid/hid_system_server.h
@@ -0,0 +1,40 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "core/hle/service/kernel_helpers.h"
7#include "core/hle/service/service.h"
8
9namespace Core {
10class System;
11}
12
13namespace Kernel {
14class KEvent;
15}
16
17namespace Service::HID {
18class ResourceManager;
19
20class IHidSystemServer final : public ServiceFramework<IHidSystemServer> {
21public:
22 explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
23 ~IHidSystemServer() override;
24
25private:
26 void ApplyNpadSystemCommonPolicy(HLERequestContext& ctx);
27 void GetLastActiveNpad(HLERequestContext& ctx);
28 void GetUniquePadsFromNpad(HLERequestContext& ctx);
29 void AcquireJoyDetachOnBluetoothOffEventHandle(HLERequestContext& ctx);
30 void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
31 void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx);
32
33 std::shared_ptr<ResourceManager> GetResourceManager();
34
35 Kernel::KEvent* joy_detach_event;
36 KernelHelpers::ServiceContext service_context;
37 std::shared_ptr<ResourceManager> resource_manager;
38};
39
40} // namespace Service::HID
diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h
index a8fa19025..c8e6dab17 100644
--- a/src/core/hle/service/hid/irs.h
+++ b/src/core/hle/service/hid/irs.h
@@ -3,15 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "core/core.h"
6#include "core/hid/hid_types.h" 7#include "core/hid/hid_types.h"
7#include "core/hid/irs_types.h" 8#include "core/hid/irs_types.h"
8#include "core/hle/service/hid/irsensor/processor_base.h" 9#include "core/hle/service/hid/irsensor/processor_base.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10 11
11namespace Core {
12class System;
13}
14
15namespace Core::HID { 12namespace Core::HID {
16class EmulatedController; 13class EmulatedController;
17} // namespace Core::HID 14} // namespace Core::HID
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
new file mode 100644
index 000000000..4e462f3b3
--- /dev/null
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -0,0 +1,192 @@
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/hid/hid_core.h"
8#include "core/hle/kernel/k_shared_memory.h"
9#include "core/hle/service/hid/resource_manager.h"
10#include "core/hle/service/ipc_helpers.h"
11
12#include "core/hle/service/hid/controllers/console_sixaxis.h"
13#include "core/hle/service/hid/controllers/controller_base.h"
14#include "core/hle/service/hid/controllers/debug_pad.h"
15#include "core/hle/service/hid/controllers/gesture.h"
16#include "core/hle/service/hid/controllers/keyboard.h"
17#include "core/hle/service/hid/controllers/mouse.h"
18#include "core/hle/service/hid/controllers/npad.h"
19#include "core/hle/service/hid/controllers/palma.h"
20#include "core/hle/service/hid/controllers/stubbed.h"
21#include "core/hle/service/hid/controllers/touchscreen.h"
22#include "core/hle/service/hid/controllers/xpad.h"
23
24namespace Service::HID {
25
26// Updating period for each HID device.
27// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
28// Correct npad_update_ns is 4ms this is overclocked to lower input lag
29constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
30constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz)
31constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
32constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
33
34ResourceManager::ResourceManager(Core::System& system_)
35 : system{system_}, service_context{system_, "hid"} {}
36
37ResourceManager::~ResourceManager() = default;
38
39void ResourceManager::Initialize() {
40 if (is_initialized) {
41 return;
42 }
43
44 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
45 MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
46 MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
47 MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
48 MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
49 MakeController<Controller_XPad>(HidController::XPad, shared_memory);
50 MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
51 MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
52 MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
53 MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
54 MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
55 MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
56 MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
57 MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
58 MakeController<Controller_Stubbed>(HidController::DebugMouse, shared_memory);
59 MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
60
61 // Homebrew doesn't try to activate some controllers, so we activate them by default
62 GetController<Controller_NPad>(HidController::NPad).ActivateController();
63 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
64
65 GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
66 GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
67 GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
68 GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
69 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
70 GetController<Controller_Stubbed>(HidController::DebugMouse).SetCommonHeaderOffset(0x3DC00);
71
72 system.HIDCore().ReloadInputDevices();
73 is_initialized = true;
74}
75
76void ResourceManager::ActivateController(HidController controller) {
77 controllers[static_cast<size_t>(controller)]->ActivateController();
78}
79
80void ResourceManager::DeactivateController(HidController controller) {
81 controllers[static_cast<size_t>(controller)]->DeactivateController();
82}
83
84void ResourceManager::UpdateControllers(std::uintptr_t user_data,
85 std::chrono::nanoseconds ns_late) {
86 auto& core_timing = system.CoreTiming();
87
88 for (const auto& controller : controllers) {
89 // Keyboard has it's own update event
90 if (controller == controllers[static_cast<size_t>(HidController::Keyboard)]) {
91 continue;
92 }
93 // Mouse has it's own update event
94 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
95 continue;
96 }
97 // Npad has it's own update event
98 if (controller == controllers[static_cast<size_t>(HidController::NPad)]) {
99 continue;
100 }
101 controller->OnUpdate(core_timing);
102 }
103}
104
105void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
106 auto& core_timing = system.CoreTiming();
107
108 controllers[static_cast<size_t>(HidController::NPad)]->OnUpdate(core_timing);
109}
110
111void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data,
112 std::chrono::nanoseconds ns_late) {
113 auto& core_timing = system.CoreTiming();
114
115 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
116 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
117}
118
119void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
120 auto& core_timing = system.CoreTiming();
121
122 controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
123}
124
125IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
126 : ServiceFramework{system_, "IAppletResource"} {
127 static const FunctionInfo functions[] = {
128 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
129 };
130 RegisterHandlers(functions);
131
132 resource->Initialize();
133
134 // Register update callbacks
135 npad_update_event = Core::Timing::CreateEvent(
136 "HID::UpdatePadCallback",
137 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
138 -> std::optional<std::chrono::nanoseconds> {
139 const auto guard = LockService();
140 resource->UpdateNpad(user_data, ns_late);
141 return std::nullopt;
142 });
143 default_update_event = Core::Timing::CreateEvent(
144 "HID::UpdateDefaultCallback",
145 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
146 -> std::optional<std::chrono::nanoseconds> {
147 const auto guard = LockService();
148 resource->UpdateControllers(user_data, ns_late);
149 return std::nullopt;
150 });
151 mouse_keyboard_update_event = Core::Timing::CreateEvent(
152 "HID::UpdateMouseKeyboardCallback",
153 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
154 -> std::optional<std::chrono::nanoseconds> {
155 const auto guard = LockService();
156 resource->UpdateMouseKeyboard(user_data, ns_late);
157 return std::nullopt;
158 });
159 motion_update_event = Core::Timing::CreateEvent(
160 "HID::UpdateMotionCallback",
161 [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
162 -> std::optional<std::chrono::nanoseconds> {
163 const auto guard = LockService();
164 resource->UpdateMotion(user_data, ns_late);
165 return std::nullopt;
166 });
167
168 system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event);
169 system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns,
170 default_update_event);
171 system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns,
172 mouse_keyboard_update_event);
173 system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns,
174 motion_update_event);
175}
176
177IAppletResource::~IAppletResource() {
178 system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
179 system.CoreTiming().UnscheduleEvent(default_update_event, 0);
180 system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
181 system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
182}
183
184void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
185 LOG_DEBUG(Service_HID, "called");
186
187 IPC::ResponseBuilder rb{ctx, 2, 1};
188 rb.Push(ResultSuccess);
189 rb.PushCopyObjects(&system.Kernel().GetHidSharedMem());
190}
191
192} // namespace Service::HID
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
new file mode 100644
index 000000000..81b17f9a9
--- /dev/null
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -0,0 +1,106 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <chrono>
7
8#include "core/core.h"
9#include "core/hle/service/hid/controllers/controller_base.h"
10#include "core/hle/service/kernel_helpers.h"
11#include "core/hle/service/service.h"
12
13namespace Core::Timing {
14struct EventType;
15}
16
17namespace Core::HID {
18class HIDCore;
19}
20
21namespace Service::HID {
22
23enum class HidController : std::size_t {
24 DebugPad,
25 Touchscreen,
26 Mouse,
27 Keyboard,
28 XPad,
29 HomeButton,
30 SleepButton,
31 CaptureButton,
32 InputDetector,
33 UniquePad,
34 NPad,
35 Gesture,
36 ConsoleSixAxisSensor,
37 DebugMouse,
38 Palma,
39
40 MaxControllers,
41};
42class ResourceManager {
43public:
44 explicit ResourceManager(Core::System& system_);
45 ~ResourceManager();
46
47 template <typename T>
48 T& GetController(HidController controller) {
49 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
50 }
51
52 template <typename T>
53 const T& GetController(HidController controller) const {
54 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
55 }
56
57 void Initialize();
58 void ActivateController(HidController controller);
59 void DeactivateController(HidController controller);
60
61 void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
62 void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
63 void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
64 void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
65
66private:
67 template <typename T>
68 void MakeController(HidController controller, u8* shared_memory) {
69 if constexpr (std::is_constructible_v<T, Core::System&, u8*>) {
70 controllers[static_cast<std::size_t>(controller)] =
71 std::make_unique<T>(system, shared_memory);
72 } else {
73 controllers[static_cast<std::size_t>(controller)] =
74 std::make_unique<T>(system.HIDCore(), shared_memory);
75 }
76 }
77
78 template <typename T>
79 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
80 controllers[static_cast<std::size_t>(controller)] =
81 std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
82 }
83
84 bool is_initialized{false};
85 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
86 controllers{};
87
88 Core::System& system;
89 KernelHelpers::ServiceContext service_context;
90};
91
92class IAppletResource final : public ServiceFramework<IAppletResource> {
93public:
94 explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource);
95 ~IAppletResource() override;
96
97private:
98 void GetSharedMemoryHandle(HLERequestContext& ctx);
99
100 std::shared_ptr<Core::Timing::EventType> npad_update_event;
101 std::shared_ptr<Core::Timing::EventType> default_update_event;
102 std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
103 std::shared_ptr<Core::Timing::EventType> motion_update_event;
104};
105
106} // namespace Service::HID
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 53a89cc8f..da140c01c 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -10,7 +10,8 @@
10#include "core/hle/kernel/k_page_table.h" 10#include "core/hle/kernel/k_page_table.h"
11#include "core/hle/kernel/k_process.h" 11#include "core/hle/kernel/k_process.h"
12#include "core/hle/service/hid/controllers/npad.h" 12#include "core/hle/service/hid/controllers/npad.h"
13#include "core/hle/service/hid/hid.h" 13#include "core/hle/service/hid/hid_server.h"
14#include "core/hle/service/hid/resource_manager.h"
14#include "core/hle/service/sm/sm.h" 15#include "core/hle/service/sm/sm.h"
15#include "core/memory.h" 16#include "core/memory.h"
16#include "core/memory/cheat_engine.h" 17#include "core/memory/cheat_engine.h"
@@ -54,13 +55,13 @@ void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size)
54} 55}
55 56
56u64 StandardVmCallbacks::HidKeysDown() { 57u64 StandardVmCallbacks::HidKeysDown() {
57 const auto hid = system.ServiceManager().GetService<Service::HID::Hid>("hid"); 58 const auto hid = system.ServiceManager().GetService<Service::HID::IHidServer>("hid");
58 if (hid == nullptr) { 59 if (hid == nullptr) {
59 LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!"); 60 LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!");
60 return 0; 61 return 0;
61 } 62 }
62 63
63 const auto applet_resource = hid->GetAppletResource(); 64 const auto applet_resource = hid->GetResourceManager();
64 if (applet_resource == nullptr) { 65 if (applet_resource == nullptr) {
65 LOG_WARNING(CheatEngine, 66 LOG_WARNING(CheatEngine,
66 "Attempted to read input state, but applet resource is not initialized!"); 67 "Attempted to read input state, but applet resource is not initialized!");
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 515cb7ce6..9e5319716 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -13,7 +13,6 @@
13#include "core/hid/hid_core.h" 13#include "core/hid/hid_core.h"
14#include "core/hid/hid_types.h" 14#include "core/hid/hid_types.h"
15#include "core/hle/service/hid/controllers/npad.h" 15#include "core/hle/service/hid/controllers/npad.h"
16#include "core/hle/service/hid/hid.h"
17#include "core/hle/service/sm/sm.h" 16#include "core/hle/service/sm/sm.h"
18#include "ui_qt_controller.h" 17#include "ui_qt_controller.h"
19#include "yuzu/applets/qt_controller.h" 18#include "yuzu/applets/qt_controller.h"