hid.cpp 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <array>
  5. #include "common/common_types.h"
  6. #include "common/logging/log.h"
  7. #include "core/core.h"
  8. #include "core/core_timing.h"
  9. #include "core/core_timing_util.h"
  10. #include "core/frontend/emu_window.h"
  11. #include "core/frontend/input.h"
  12. #include "core/hle/ipc_helpers.h"
  13. #include "core/hle/kernel/client_port.h"
  14. #include "core/hle/kernel/client_session.h"
  15. #include "core/hle/kernel/readable_event.h"
  16. #include "core/hle/kernel/shared_memory.h"
  17. #include "core/hle/kernel/writable_event.h"
  18. #include "core/hle/service/hid/errors.h"
  19. #include "core/hle/service/hid/hid.h"
  20. #include "core/hle/service/hid/irs.h"
  21. #include "core/hle/service/hid/xcd.h"
  22. #include "core/hle/service/service.h"
  23. #include "core/settings.h"
  24. #include "core/hle/service/hid/controllers/controller_base.h"
  25. #include "core/hle/service/hid/controllers/debug_pad.h"
  26. #include "core/hle/service/hid/controllers/gesture.h"
  27. #include "core/hle/service/hid/controllers/keyboard.h"
  28. #include "core/hle/service/hid/controllers/mouse.h"
  29. #include "core/hle/service/hid/controllers/npad.h"
  30. #include "core/hle/service/hid/controllers/stubbed.h"
  31. #include "core/hle/service/hid/controllers/touchscreen.h"
  32. #include "core/hle/service/hid/controllers/xpad.h"
  33. namespace Service::HID {
  34. // Updating period for each HID device.
  35. // TODO(ogniK): Find actual polling rate of hid
  36. constexpr s64 pad_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 66);
  37. constexpr s64 accelerometer_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100);
  38. constexpr s64 gyroscope_update_ticks = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 100);
  39. constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
  40. IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
  41. static const FunctionInfo functions[] = {
  42. {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
  43. };
  44. RegisterHandlers(functions);
  45. auto& kernel = Core::System::GetInstance().Kernel();
  46. shared_mem = Kernel::SharedMemory::Create(
  47. kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
  48. Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
  49. MakeController<Controller_DebugPad>(HidController::DebugPad);
  50. MakeController<Controller_Touchscreen>(HidController::Touchscreen);
  51. MakeController<Controller_Mouse>(HidController::Mouse);
  52. MakeController<Controller_Keyboard>(HidController::Keyboard);
  53. MakeController<Controller_XPad>(HidController::XPad);
  54. MakeController<Controller_Stubbed>(HidController::Unknown1);
  55. MakeController<Controller_Stubbed>(HidController::Unknown2);
  56. MakeController<Controller_Stubbed>(HidController::Unknown3);
  57. MakeController<Controller_Stubbed>(HidController::SixAxisSensor);
  58. MakeController<Controller_NPad>(HidController::NPad);
  59. MakeController<Controller_Gesture>(HidController::Gesture);
  60. // Homebrew doesn't try to activate some controllers, so we activate them by default
  61. GetController<Controller_NPad>(HidController::NPad).ActivateController();
  62. GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
  63. GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00);
  64. GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00);
  65. GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
  66. // Register update callbacks
  67. auto& core_timing = Core::System::GetInstance().CoreTiming();
  68. pad_update_event =
  69. core_timing.RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, s64 cycles_late) {
  70. UpdateControllers(userdata, cycles_late);
  71. });
  72. // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
  73. core_timing.ScheduleEvent(pad_update_ticks, pad_update_event);
  74. ReloadInputDevices();
  75. }
  76. void IAppletResource::ActivateController(HidController controller) {
  77. controllers[static_cast<size_t>(controller)]->ActivateController();
  78. }
  79. void IAppletResource::DeactivateController(HidController controller) {
  80. controllers[static_cast<size_t>(controller)]->DeactivateController();
  81. }
  82. IAppletResource ::~IAppletResource() {
  83. Core::System::GetInstance().CoreTiming().UnscheduleEvent(pad_update_event, 0);
  84. }
  85. void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
  86. LOG_DEBUG(Service_HID, "called");
  87. IPC::ResponseBuilder rb{ctx, 2, 1};
  88. rb.Push(RESULT_SUCCESS);
  89. rb.PushCopyObjects(shared_mem);
  90. }
  91. void IAppletResource::UpdateControllers(u64 userdata, s64 cycles_late) {
  92. auto& core_timing = Core::System::GetInstance().CoreTiming();
  93. const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
  94. for (const auto& controller : controllers) {
  95. if (should_reload) {
  96. controller->OnLoadInputDevices();
  97. }
  98. controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
  99. }
  100. core_timing.ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
  101. }
  102. class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
  103. public:
  104. IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
  105. static const FunctionInfo functions[] = {
  106. {0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"},
  107. };
  108. RegisterHandlers(functions);
  109. }
  110. private:
  111. void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
  112. LOG_WARNING(Service_HID, "(STUBBED) called");
  113. IPC::ResponseBuilder rb{ctx, 2};
  114. rb.Push(RESULT_SUCCESS);
  115. }
  116. };
  117. std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
  118. if (applet_resource == nullptr) {
  119. applet_resource = std::make_shared<IAppletResource>();
  120. }
  121. return applet_resource;
  122. }
  123. Hid::Hid() : ServiceFramework("hid") {
  124. // clang-format off
  125. static const FunctionInfo functions[] = {
  126. {0, &Hid::CreateAppletResource, "CreateAppletResource"},
  127. {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
  128. {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
  129. {21, &Hid::ActivateMouse, "ActivateMouse"},
  130. {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
  131. {32, nullptr, "SendKeyboardLockKeyEvent"},
  132. {40, nullptr, "AcquireXpadIdEventHandle"},
  133. {41, nullptr, "ReleaseXpadIdEventHandle"},
  134. {51, &Hid::ActivateXpad, "ActivateXpad"},
  135. {55, nullptr, "GetXpadIds"},
  136. {56, nullptr, "ActivateJoyXpad"},
  137. {58, nullptr, "GetJoyXpadLifoHandle"},
  138. {59, nullptr, "GetJoyXpadIds"},
  139. {60, nullptr, "ActivateSixAxisSensor"},
  140. {61, nullptr, "DeactivateSixAxisSensor"},
  141. {62, nullptr, "GetSixAxisSensorLifoHandle"},
  142. {63, nullptr, "ActivateJoySixAxisSensor"},
  143. {64, nullptr, "DeactivateJoySixAxisSensor"},
  144. {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
  145. {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
  146. {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
  147. {68, nullptr, "IsSixAxisSensorFusionEnabled"},
  148. {69, nullptr, "EnableSixAxisSensorFusion"},
  149. {70, nullptr, "SetSixAxisSensorFusionParameters"},
  150. {71, nullptr, "GetSixAxisSensorFusionParameters"},
  151. {72, nullptr, "ResetSixAxisSensorFusionParameters"},
  152. {73, nullptr, "SetAccelerometerParameters"},
  153. {74, nullptr, "GetAccelerometerParameters"},
  154. {75, nullptr, "ResetAccelerometerParameters"},
  155. {76, nullptr, "SetAccelerometerPlayMode"},
  156. {77, nullptr, "GetAccelerometerPlayMode"},
  157. {78, nullptr, "ResetAccelerometerPlayMode"},
  158. {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
  159. {80, nullptr, "GetGyroscopeZeroDriftMode"},
  160. {81, nullptr, "ResetGyroscopeZeroDriftMode"},
  161. {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
  162. {83, nullptr, "IsFirmwareUpdateAvailableForSixAxisSensor"},
  163. {91, &Hid::ActivateGesture, "ActivateGesture"},
  164. {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
  165. {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
  166. {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
  167. {103, &Hid::ActivateNpad, "ActivateNpad"},
  168. {104, nullptr, "DeactivateNpad"},
  169. {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
  170. {107, &Hid::DisconnectNpad, "DisconnectNpad"},
  171. {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
  172. {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
  173. {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
  174. {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
  175. {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
  176. {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
  177. {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
  178. {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
  179. {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
  180. {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
  181. {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
  182. {129, nullptr, "GetNpadHandheldActivationMode"},
  183. {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
  184. {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
  185. {132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
  186. {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
  187. {134, nullptr, "SetNpadAnalogStickUseCenterClamp"},
  188. {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
  189. {201, &Hid::SendVibrationValue, "SendVibrationValue"},
  190. {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
  191. {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
  192. {204, nullptr, "PermitVibration"},
  193. {205, nullptr, "IsVibrationPermitted"},
  194. {206, &Hid::SendVibrationValues, "SendVibrationValues"},
  195. {207, nullptr, "SendVibrationGcErmCommand"},
  196. {208, nullptr, "GetActualVibrationGcErmCommand"},
  197. {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
  198. {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
  199. {211, nullptr, "IsVibrationDeviceMounted"},
  200. {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
  201. {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
  202. {302, nullptr, "StopConsoleSixAxisSensor"},
  203. {303, nullptr, "ActivateSevenSixAxisSensor"},
  204. {304, nullptr, "StartSevenSixAxisSensor"},
  205. {305, nullptr, "StopSevenSixAxisSensor"},
  206. {306, nullptr, "InitializeSevenSixAxisSensor"},
  207. {307, nullptr, "FinalizeSevenSixAxisSensor"},
  208. {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
  209. {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
  210. {310, nullptr, "ResetSevenSixAxisSensorTimestamp"},
  211. {400, nullptr, "IsUsbFullKeyControllerEnabled"},
  212. {401, nullptr, "EnableUsbFullKeyController"},
  213. {402, nullptr, "IsUsbFullKeyControllerConnected"},
  214. {403, nullptr, "HasBattery"},
  215. {404, nullptr, "HasLeftRightBattery"},
  216. {405, nullptr, "GetNpadInterfaceType"},
  217. {406, nullptr, "GetNpadLeftRightInterfaceType"},
  218. {500, nullptr, "GetPalmaConnectionHandle"},
  219. {501, nullptr, "InitializePalma"},
  220. {502, nullptr, "AcquirePalmaOperationCompleteEvent"},
  221. {503, nullptr, "GetPalmaOperationInfo"},
  222. {504, nullptr, "PlayPalmaActivity"},
  223. {505, nullptr, "SetPalmaFrModeType"},
  224. {506, nullptr, "ReadPalmaStep"},
  225. {507, nullptr, "EnablePalmaStep"},
  226. {508, nullptr, "ResetPalmaStep"},
  227. {509, nullptr, "ReadPalmaApplicationSection"},
  228. {510, nullptr, "WritePalmaApplicationSection"},
  229. {511, nullptr, "ReadPalmaUniqueCode"},
  230. {512, nullptr, "SetPalmaUniqueCodeInvalid"},
  231. {513, nullptr, "WritePalmaActivityEntry"},
  232. {514, nullptr, "WritePalmaRgbLedPatternEntry"},
  233. {515, nullptr, "WritePalmaWaveEntry"},
  234. {516, nullptr, "SetPalmaDataBaseIdentificationVersion"},
  235. {517, nullptr, "GetPalmaDataBaseIdentificationVersion"},
  236. {518, nullptr, "SuspendPalmaFeature"},
  237. {519, nullptr, "GetPalmaOperationResult"},
  238. {520, nullptr, "ReadPalmaPlayLog"},
  239. {521, nullptr, "ResetPalmaPlayLog"},
  240. {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
  241. {523, nullptr, "SetIsPalmaPairedConnectable"},
  242. {524, nullptr, "PairPalma"},
  243. {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
  244. {526, nullptr, "CancelWritePalmaWaveEntry"},
  245. {1000, nullptr, "SetNpadCommunicationMode"},
  246. {1001, nullptr, "GetNpadCommunicationMode"},
  247. };
  248. // clang-format on
  249. RegisterHandlers(functions);
  250. }
  251. Hid::~Hid() = default;
  252. void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
  253. IPC::RequestParser rp{ctx};
  254. const auto applet_resource_user_id{rp.Pop<u64>()};
  255. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  256. if (applet_resource == nullptr) {
  257. applet_resource = std::make_shared<IAppletResource>();
  258. }
  259. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  260. rb.Push(RESULT_SUCCESS);
  261. rb.PushIpcInterface<IAppletResource>(applet_resource);
  262. }
  263. void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
  264. IPC::RequestParser rp{ctx};
  265. const auto basic_xpad_id{rp.Pop<u32>()};
  266. const auto applet_resource_user_id{rp.Pop<u64>()};
  267. LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", basic_xpad_id,
  268. applet_resource_user_id);
  269. applet_resource->ActivateController(HidController::XPad);
  270. IPC::ResponseBuilder rb{ctx, 2};
  271. rb.Push(RESULT_SUCCESS);
  272. }
  273. void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
  274. IPC::RequestParser rp{ctx};
  275. const auto applet_resource_user_id{rp.Pop<u64>()};
  276. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  277. applet_resource->ActivateController(HidController::DebugPad);
  278. IPC::ResponseBuilder rb{ctx, 2};
  279. rb.Push(RESULT_SUCCESS);
  280. }
  281. void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
  282. IPC::RequestParser rp{ctx};
  283. const auto applet_resource_user_id{rp.Pop<u64>()};
  284. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  285. applet_resource->ActivateController(HidController::Touchscreen);
  286. IPC::ResponseBuilder rb{ctx, 2};
  287. rb.Push(RESULT_SUCCESS);
  288. }
  289. void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
  290. IPC::RequestParser rp{ctx};
  291. const auto applet_resource_user_id{rp.Pop<u64>()};
  292. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  293. applet_resource->ActivateController(HidController::Mouse);
  294. IPC::ResponseBuilder rb{ctx, 2};
  295. rb.Push(RESULT_SUCCESS);
  296. }
  297. void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
  298. IPC::RequestParser rp{ctx};
  299. const auto applet_resource_user_id{rp.Pop<u64>()};
  300. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  301. applet_resource->ActivateController(HidController::Keyboard);
  302. IPC::ResponseBuilder rb{ctx, 2};
  303. rb.Push(RESULT_SUCCESS);
  304. }
  305. void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
  306. IPC::RequestParser rp{ctx};
  307. const auto unknown{rp.Pop<u32>()};
  308. const auto applet_resource_user_id{rp.Pop<u64>()};
  309. LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
  310. applet_resource_user_id);
  311. applet_resource->ActivateController(HidController::Gesture);
  312. IPC::ResponseBuilder rb{ctx, 2};
  313. rb.Push(RESULT_SUCCESS);
  314. }
  315. void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
  316. // Should have no effect with how our npad sets up the data
  317. IPC::RequestParser rp{ctx};
  318. const auto unknown{rp.Pop<u32>()};
  319. const auto applet_resource_user_id{rp.Pop<u64>()};
  320. LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
  321. applet_resource_user_id);
  322. applet_resource->ActivateController(HidController::NPad);
  323. IPC::ResponseBuilder rb{ctx, 2};
  324. rb.Push(RESULT_SUCCESS);
  325. }
  326. void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
  327. IPC::RequestParser rp{ctx};
  328. const auto handle{rp.Pop<u32>()};
  329. const auto applet_resource_user_id{rp.Pop<u64>()};
  330. LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
  331. applet_resource_user_id);
  332. IPC::ResponseBuilder rb{ctx, 2};
  333. rb.Push(RESULT_SUCCESS);
  334. }
  335. void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
  336. IPC::RequestParser rp{ctx};
  337. const auto handle{rp.Pop<u32>()};
  338. const auto drift_mode{rp.Pop<u32>()};
  339. const auto applet_resource_user_id{rp.Pop<u64>()};
  340. LOG_WARNING(Service_HID,
  341. "(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", handle,
  342. drift_mode, applet_resource_user_id);
  343. IPC::ResponseBuilder rb{ctx, 2};
  344. rb.Push(RESULT_SUCCESS);
  345. }
  346. void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
  347. IPC::RequestParser rp{ctx};
  348. const auto handle{rp.Pop<u32>()};
  349. const auto applet_resource_user_id{rp.Pop<u64>()};
  350. LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
  351. applet_resource_user_id);
  352. IPC::ResponseBuilder rb{ctx, 3};
  353. rb.Push(RESULT_SUCCESS);
  354. // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
  355. rb.Push(true);
  356. }
  357. void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
  358. IPC::RequestParser rp{ctx};
  359. const auto supported_styleset{rp.Pop<u32>()};
  360. LOG_DEBUG(Service_HID, "called, supported_styleset={}", supported_styleset);
  361. applet_resource->GetController<Controller_NPad>(HidController::NPad)
  362. .SetSupportedStyleSet({supported_styleset});
  363. IPC::ResponseBuilder rb{ctx, 2};
  364. rb.Push(RESULT_SUCCESS);
  365. }
  366. void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
  367. IPC::RequestParser rp{ctx};
  368. const auto applet_resource_user_id{rp.Pop<u64>()};
  369. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  370. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  371. IPC::ResponseBuilder rb{ctx, 3};
  372. rb.Push(RESULT_SUCCESS);
  373. rb.Push<u32>(controller.GetSupportedStyleSet().raw);
  374. }
  375. void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
  376. IPC::RequestParser rp{ctx};
  377. const auto applet_resource_user_id{rp.Pop<u64>()};
  378. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  379. applet_resource->GetController<Controller_NPad>(HidController::NPad)
  380. .SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
  381. IPC::ResponseBuilder rb{ctx, 2};
  382. rb.Push(RESULT_SUCCESS);
  383. }
  384. void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
  385. IPC::RequestParser rp{ctx};
  386. const auto applet_resource_user_id{rp.Pop<u64>()};
  387. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  388. IPC::ResponseBuilder rb{ctx, 2};
  389. rb.Push(RESULT_SUCCESS);
  390. applet_resource->ActivateController(HidController::NPad);
  391. }
  392. void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
  393. IPC::RequestParser rp{ctx};
  394. const auto npad_id{rp.Pop<u32>()};
  395. const auto applet_resource_user_id{rp.Pop<u64>()};
  396. const auto unknown{rp.Pop<u64>()};
  397. LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", npad_id,
  398. applet_resource_user_id, unknown);
  399. IPC::ResponseBuilder rb{ctx, 2, 1};
  400. rb.Push(RESULT_SUCCESS);
  401. rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
  402. .GetStyleSetChangedEvent());
  403. }
  404. void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
  405. IPC::RequestParser rp{ctx};
  406. const auto npad_id{rp.Pop<u32>()};
  407. const auto applet_resource_user_id{rp.Pop<u64>()};
  408. LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
  409. applet_resource_user_id);
  410. applet_resource->GetController<Controller_NPad>(HidController::NPad).DisconnectNPad(npad_id);
  411. IPC::ResponseBuilder rb{ctx, 2};
  412. rb.Push(RESULT_SUCCESS);
  413. }
  414. void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
  415. IPC::RequestParser rp{ctx};
  416. const auto npad_id{rp.Pop<u32>()};
  417. LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
  418. IPC::ResponseBuilder rb{ctx, 4};
  419. rb.Push(RESULT_SUCCESS);
  420. rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
  421. .GetLedPattern(npad_id)
  422. .raw);
  423. }
  424. void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
  425. IPC::RequestParser rp{ctx};
  426. const auto applet_resource_user_id{rp.Pop<u64>()};
  427. const auto hold_type{rp.Pop<u64>()};
  428. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
  429. applet_resource_user_id, hold_type);
  430. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  431. controller.SetHoldType(Controller_NPad::NpadHoldType{hold_type});
  432. IPC::ResponseBuilder rb{ctx, 2};
  433. rb.Push(RESULT_SUCCESS);
  434. }
  435. void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
  436. IPC::RequestParser rp{ctx};
  437. const auto applet_resource_user_id{rp.Pop<u64>()};
  438. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  439. const auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  440. IPC::ResponseBuilder rb{ctx, 4};
  441. rb.Push(RESULT_SUCCESS);
  442. rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
  443. }
  444. void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
  445. IPC::RequestParser rp{ctx};
  446. const auto npad_id{rp.Pop<u32>()};
  447. const auto applet_resource_user_id{rp.Pop<u64>()};
  448. LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
  449. applet_resource_user_id);
  450. IPC::ResponseBuilder rb{ctx, 2};
  451. rb.Push(RESULT_SUCCESS);
  452. }
  453. void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
  454. IPC::RequestParser rp{ctx};
  455. const auto applet_resource_user_id{rp.Pop<u64>()};
  456. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  457. applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(true);
  458. IPC::ResponseBuilder rb{ctx, 2};
  459. rb.Push(RESULT_SUCCESS);
  460. }
  461. void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
  462. LOG_DEBUG(Service_HID, "called");
  463. applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(false);
  464. IPC::ResponseBuilder rb{ctx, 2};
  465. rb.Push(RESULT_SUCCESS);
  466. }
  467. void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
  468. IPC::RequestParser rp{ctx};
  469. const auto controller_id{rp.Pop<u32>()};
  470. const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
  471. const auto applet_resource_user_id{rp.Pop<u64>()};
  472. LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
  473. applet_resource_user_id);
  474. IPC::ResponseBuilder rb{ctx, 2};
  475. rb.Push(RESULT_SUCCESS);
  476. applet_resource->GetController<Controller_NPad>(HidController::NPad)
  477. .VibrateController({controller_id}, {vibration_values});
  478. }
  479. void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
  480. IPC::RequestParser rp{ctx};
  481. const auto applet_resource_user_id{rp.Pop<u64>()};
  482. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  483. const auto controllers = ctx.ReadBuffer(0);
  484. const auto vibrations = ctx.ReadBuffer(1);
  485. std::vector<u32> controller_list(controllers.size() / sizeof(u32));
  486. std::vector<Controller_NPad::Vibration> vibration_list(vibrations.size() /
  487. sizeof(Controller_NPad::Vibration));
  488. std::memcpy(controller_list.data(), controllers.data(), controllers.size());
  489. std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
  490. std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(),
  491. [](u32 controller_id) { return controller_id - 3; });
  492. applet_resource->GetController<Controller_NPad>(HidController::NPad)
  493. .VibrateController(controller_list, vibration_list);
  494. IPC::ResponseBuilder rb{ctx, 2};
  495. rb.Push(RESULT_SUCCESS);
  496. }
  497. void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
  498. IPC::RequestParser rp{ctx};
  499. const auto controller_id{rp.Pop<u32>()};
  500. const auto applet_resource_user_id{rp.Pop<u64>()};
  501. LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
  502. applet_resource_user_id);
  503. IPC::ResponseBuilder rb{ctx, 6};
  504. rb.Push(RESULT_SUCCESS);
  505. rb.PushRaw<Controller_NPad::Vibration>(
  506. applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
  507. }
  508. void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
  509. IPC::RequestParser rp{ctx};
  510. const auto npad_id{rp.Pop<u32>()};
  511. const auto applet_resource_user_id{rp.Pop<u64>()};
  512. LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
  513. applet_resource_user_id);
  514. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  515. controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
  516. IPC::ResponseBuilder rb{ctx, 2};
  517. rb.Push(RESULT_SUCCESS);
  518. }
  519. void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
  520. IPC::RequestParser rp{ctx};
  521. const auto unknown_1{rp.Pop<u32>()};
  522. const auto unknown_2{rp.Pop<u32>()};
  523. const auto applet_resource_user_id{rp.Pop<u64>()};
  524. LOG_WARNING(Service_HID,
  525. "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
  526. unknown_1, unknown_2, applet_resource_user_id);
  527. IPC::ResponseBuilder rb{ctx, 2};
  528. rb.Push(RESULT_SUCCESS);
  529. }
  530. void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
  531. IPC::RequestParser rp{ctx};
  532. const auto applet_resource_user_id{rp.Pop<u64>()};
  533. const auto mode{rp.Pop<u64>()};
  534. LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
  535. applet_resource_user_id, mode);
  536. IPC::ResponseBuilder rb{ctx, 2};
  537. rb.Push(RESULT_SUCCESS);
  538. }
  539. void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
  540. LOG_DEBUG(Service_HID, "called");
  541. IPC::ResponseBuilder rb{ctx, 4};
  542. rb.Push(RESULT_SUCCESS);
  543. rb.Push<u32>(1);
  544. rb.Push<u32>(0);
  545. }
  546. void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
  547. LOG_DEBUG(Service_HID, "called");
  548. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  549. rb.Push(RESULT_SUCCESS);
  550. rb.PushIpcInterface<IActiveVibrationDeviceList>();
  551. }
  552. void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
  553. IPC::RequestParser rp{ctx};
  554. const auto applet_resource_user_id{rp.Pop<u64>()};
  555. LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
  556. applet_resource_user_id);
  557. IPC::ResponseBuilder rb{ctx, 2};
  558. rb.Push(RESULT_SUCCESS);
  559. }
  560. void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
  561. IPC::RequestParser rp{ctx};
  562. const auto handle{rp.Pop<u32>()};
  563. const auto applet_resource_user_id{rp.Pop<u64>()};
  564. LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
  565. applet_resource_user_id);
  566. IPC::ResponseBuilder rb{ctx, 2};
  567. rb.Push(RESULT_SUCCESS);
  568. }
  569. void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
  570. IPC::RequestParser rp{ctx};
  571. const auto handle{rp.Pop<u32>()};
  572. LOG_WARNING(Service_HID, "(STUBBED) called, handle={}", handle);
  573. IPC::ResponseBuilder rb{ctx, 2};
  574. rb.Push(RESULT_SUCCESS);
  575. }
  576. void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
  577. IPC::RequestParser rp{ctx};
  578. const auto applet_resource_user_id{rp.Pop<u64>()};
  579. const auto unknown{rp.Pop<u32>()};
  580. LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, unknown={}",
  581. applet_resource_user_id, unknown);
  582. IPC::ResponseBuilder rb{ctx, 2};
  583. rb.Push(RESULT_SUCCESS);
  584. }
  585. void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
  586. IPC::RequestParser rp{ctx};
  587. const auto unknown{rp.Pop<u32>()};
  588. LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}", unknown);
  589. IPC::ResponseBuilder rb{ctx, 2};
  590. rb.Push(RESULT_SUCCESS);
  591. }
  592. void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
  593. IPC::RequestParser rp{ctx};
  594. const auto applet_resource_user_id{rp.Pop<u64>()};
  595. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  596. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  597. controller.StartLRAssignmentMode();
  598. IPC::ResponseBuilder rb{ctx, 2};
  599. rb.Push(RESULT_SUCCESS);
  600. }
  601. void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
  602. IPC::RequestParser rp{ctx};
  603. const auto applet_resource_user_id{rp.Pop<u64>()};
  604. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
  605. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  606. controller.StopLRAssignmentMode();
  607. IPC::ResponseBuilder rb{ctx, 2};
  608. rb.Push(RESULT_SUCCESS);
  609. }
  610. void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
  611. IPC::RequestParser rp{ctx};
  612. const auto npad_1{rp.Pop<u32>()};
  613. const auto npad_2{rp.Pop<u32>()};
  614. const auto applet_resource_user_id{rp.Pop<u64>()};
  615. LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
  616. applet_resource_user_id, npad_1, npad_2);
  617. auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
  618. IPC::ResponseBuilder rb{ctx, 2};
  619. if (controller.SwapNpadAssignment(npad_1, npad_2)) {
  620. rb.Push(RESULT_SUCCESS);
  621. } else {
  622. LOG_ERROR(Service_HID, "Npads are not connected!");
  623. rb.Push(ERR_NPAD_NOT_CONNECTED);
  624. }
  625. }
  626. class HidDbg final : public ServiceFramework<HidDbg> {
  627. public:
  628. explicit HidDbg() : ServiceFramework{"hid:dbg"} {
  629. // clang-format off
  630. static const FunctionInfo functions[] = {
  631. {0, nullptr, "DeactivateDebugPad"},
  632. {1, nullptr, "SetDebugPadAutoPilotState"},
  633. {2, nullptr, "UnsetDebugPadAutoPilotState"},
  634. {10, nullptr, "DeactivateTouchScreen"},
  635. {11, nullptr, "SetTouchScreenAutoPilotState"},
  636. {12, nullptr, "UnsetTouchScreenAutoPilotState"},
  637. {20, nullptr, "DeactivateMouse"},
  638. {21, nullptr, "SetMouseAutoPilotState"},
  639. {22, nullptr, "UnsetMouseAutoPilotState"},
  640. {30, nullptr, "DeactivateKeyboard"},
  641. {31, nullptr, "SetKeyboardAutoPilotState"},
  642. {32, nullptr, "UnsetKeyboardAutoPilotState"},
  643. {50, nullptr, "DeactivateXpad"},
  644. {51, nullptr, "SetXpadAutoPilotState"},
  645. {52, nullptr, "UnsetXpadAutoPilotState"},
  646. {60, nullptr, "DeactivateJoyXpad"},
  647. {91, nullptr, "DeactivateGesture"},
  648. {110, nullptr, "DeactivateHomeButton"},
  649. {111, nullptr, "SetHomeButtonAutoPilotState"},
  650. {112, nullptr, "UnsetHomeButtonAutoPilotState"},
  651. {120, nullptr, "DeactivateSleepButton"},
  652. {121, nullptr, "SetSleepButtonAutoPilotState"},
  653. {122, nullptr, "UnsetSleepButtonAutoPilotState"},
  654. {123, nullptr, "DeactivateInputDetector"},
  655. {130, nullptr, "DeactivateCaptureButton"},
  656. {131, nullptr, "SetCaptureButtonAutoPilotState"},
  657. {132, nullptr, "UnsetCaptureButtonAutoPilotState"},
  658. {133, nullptr, "SetShiftAccelerometerCalibrationValue"},
  659. {134, nullptr, "GetShiftAccelerometerCalibrationValue"},
  660. {135, nullptr, "SetShiftGyroscopeCalibrationValue"},
  661. {136, nullptr, "GetShiftGyroscopeCalibrationValue"},
  662. {140, nullptr, "DeactivateConsoleSixAxisSensor"},
  663. {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
  664. {142, nullptr, "DeactivateSevenSixAxisSensor"},
  665. {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
  666. {201, nullptr, "ActivateFirmwareUpdate"},
  667. {202, nullptr, "DeactivateFirmwareUpdate"},
  668. {203, nullptr, "StartFirmwareUpdate"},
  669. {204, nullptr, "GetFirmwareUpdateStage"},
  670. {205, nullptr, "GetFirmwareVersion"},
  671. {206, nullptr, "GetDestinationFirmwareVersion"},
  672. {207, nullptr, "DiscardFirmwareInfoCacheForRevert"},
  673. {208, nullptr, "StartFirmwareUpdateForRevert"},
  674. {209, nullptr, "GetAvailableFirmwareVersionForRevert"},
  675. {210, nullptr, "IsFirmwareUpdatingDevice"},
  676. {211, nullptr, "StartFirmwareUpdateIndividual"},
  677. {215, nullptr, "SetUsbFirmwareForceUpdateEnabled"},
  678. {216, nullptr, "SetAllKuinaDevicesToFirmwareUpdateMode"},
  679. {221, nullptr, "UpdateControllerColor"},
  680. {222, nullptr, "ConnectUsbPadsAsync"},
  681. {223, nullptr, "DisconnectUsbPadsAsync"},
  682. {224, nullptr, "UpdateDesignInfo"},
  683. {225, nullptr, "GetUniquePadDriverState"},
  684. {226, nullptr, "GetSixAxisSensorDriverStates"},
  685. {227, nullptr, "GetRxPacketHistory"},
  686. {228, nullptr, "AcquireOperationEventHandle"},
  687. {229, nullptr, "ReadSerialFlash"},
  688. {230, nullptr, "WriteSerialFlash"},
  689. {231, nullptr, "GetOperationResult"},
  690. {232, nullptr, "EnableShipmentMode"},
  691. {233, nullptr, "ClearPairingInfo"},
  692. {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
  693. {235, nullptr, "EnableAnalogStickPower"},
  694. {301, nullptr, "GetAbstractedPadHandles"},
  695. {302, nullptr, "GetAbstractedPadState"},
  696. {303, nullptr, "GetAbstractedPadsState"},
  697. {321, nullptr, "SetAutoPilotVirtualPadState"},
  698. {322, nullptr, "UnsetAutoPilotVirtualPadState"},
  699. {323, nullptr, "UnsetAllAutoPilotVirtualPadState"},
  700. {324, nullptr, "AttachHdlsWorkBuffer"},
  701. {325, nullptr, "ReleaseHdlsWorkBuffer"},
  702. {326, nullptr, "DumpHdlsNpadAssignmentState"},
  703. {327, nullptr, "DumpHdlsStates"},
  704. {328, nullptr, "ApplyHdlsNpadAssignmentState"},
  705. {329, nullptr, "ApplyHdlsStateList"},
  706. {330, nullptr, "AttachHdlsVirtualDevice"},
  707. {331, nullptr, "DetachHdlsVirtualDevice"},
  708. {332, nullptr, "SetHdlsState"},
  709. {350, nullptr, "AddRegisteredDevice"},
  710. {400, nullptr, "DisableExternalMcuOnNxDevice"},
  711. {401, nullptr, "DisableRailDeviceFiltering"},
  712. };
  713. // clang-format on
  714. RegisterHandlers(functions);
  715. }
  716. };
  717. class HidSys final : public ServiceFramework<HidSys> {
  718. public:
  719. explicit HidSys() : ServiceFramework{"hid:sys"} {
  720. // clang-format off
  721. static const FunctionInfo functions[] = {
  722. {31, nullptr, "SendKeyboardLockKeyEvent"},
  723. {101, nullptr, "AcquireHomeButtonEventHandle"},
  724. {111, nullptr, "ActivateHomeButton"},
  725. {121, nullptr, "AcquireSleepButtonEventHandle"},
  726. {131, nullptr, "ActivateSleepButton"},
  727. {141, nullptr, "AcquireCaptureButtonEventHandle"},
  728. {151, nullptr, "ActivateCaptureButton"},
  729. {161, nullptr, "GetPlatformConfig"},
  730. {210, nullptr, "AcquireNfcDeviceUpdateEventHandle"},
  731. {211, nullptr, "GetNpadsWithNfc"},
  732. {212, nullptr, "AcquireNfcActivateEventHandle"},
  733. {213, nullptr, "ActivateNfc"},
  734. {214, nullptr, "GetXcdHandleForNpadWithNfc"},
  735. {215, nullptr, "IsNfcActivated"},
  736. {230, nullptr, "AcquireIrSensorEventHandle"},
  737. {231, nullptr, "ActivateIrSensor"},
  738. {301, nullptr, "ActivateNpadSystem"},
  739. {303, nullptr, "ApplyNpadSystemCommonPolicy"},
  740. {304, nullptr, "EnableAssigningSingleOnSlSrPress"},
  741. {305, nullptr, "DisableAssigningSingleOnSlSrPress"},
  742. {306, nullptr, "GetLastActiveNpad"},
  743. {307, nullptr, "GetNpadSystemExtStyle"},
  744. {308, nullptr, "ApplyNpadSystemCommonPolicyFull"},
  745. {309, nullptr, "GetNpadFullKeyGripColor"},
  746. {310, nullptr, "GetMaskedSupportedNpadStyleSet"},
  747. {311, nullptr, "SetNpadPlayerLedBlinkingDevice"},
  748. {312, nullptr, "SetSupportedNpadStyleSetAll"},
  749. {321, nullptr, "GetUniquePadsFromNpad"},
  750. {322, nullptr, "GetIrSensorState"},
  751. {323, nullptr, "GetXcdHandleForNpadWithIrSensor"},
  752. {500, nullptr, "SetAppletResourceUserId"},
  753. {501, nullptr, "RegisterAppletResourceUserId"},
  754. {502, nullptr, "UnregisterAppletResourceUserId"},
  755. {503, nullptr, "EnableAppletToGetInput"},
  756. {504, nullptr, "SetAruidValidForVibration"},
  757. {505, nullptr, "EnableAppletToGetSixAxisSensor"},
  758. {510, nullptr, "SetVibrationMasterVolume"},
  759. {511, nullptr, "GetVibrationMasterVolume"},
  760. {512, nullptr, "BeginPermitVibrationSession"},
  761. {513, nullptr, "EndPermitVibrationSession"},
  762. {520, nullptr, "EnableHandheldHids"},
  763. {521, nullptr, "DisableHandheldHids"},
  764. {540, nullptr, "AcquirePlayReportControllerUsageUpdateEvent"},
  765. {541, nullptr, "GetPlayReportControllerUsages"},
  766. {542, nullptr, "AcquirePlayReportRegisteredDeviceUpdateEvent"},
  767. {543, nullptr, "GetRegisteredDevicesOld"},
  768. {544, nullptr, "AcquireConnectionTriggerTimeoutEvent"},
  769. {545, nullptr, "SendConnectionTrigger"},
  770. {546, nullptr, "AcquireDeviceRegisteredEventForControllerSupport"},
  771. {547, nullptr, "GetAllowedBluetoothLinksCount"},
  772. {548, nullptr, "GetRegisteredDevices"},
  773. {549, nullptr, "GetConnectableRegisteredDevices"},
  774. {700, nullptr, "ActivateUniquePad"},
  775. {702, nullptr, "AcquireUniquePadConnectionEventHandle"},
  776. {703, nullptr, "GetUniquePadIds"},
  777. {751, nullptr, "AcquireJoyDetachOnBluetoothOffEventHandle"},
  778. {800, nullptr, "ListSixAxisSensorHandles"},
  779. {801, nullptr, "IsSixAxisSensorUserCalibrationSupported"},
  780. {802, nullptr, "ResetSixAxisSensorCalibrationValues"},
  781. {803, nullptr, "StartSixAxisSensorUserCalibration"},
  782. {804, nullptr, "CancelSixAxisSensorUserCalibration"},
  783. {805, nullptr, "GetUniquePadBluetoothAddress"},
  784. {806, nullptr, "DisconnectUniquePad"},
  785. {807, nullptr, "GetUniquePadType"},
  786. {808, nullptr, "GetUniquePadInterface"},
  787. {809, nullptr, "GetUniquePadSerialNumber"},
  788. {810, nullptr, "GetUniquePadControllerNumber"},
  789. {811, nullptr, "GetSixAxisSensorUserCalibrationStage"},
  790. {821, nullptr, "StartAnalogStickManualCalibration"},
  791. {822, nullptr, "RetryCurrentAnalogStickManualCalibrationStage"},
  792. {823, nullptr, "CancelAnalogStickManualCalibration"},
  793. {824, nullptr, "ResetAnalogStickManualCalibration"},
  794. {825, nullptr, "GetAnalogStickState"},
  795. {826, nullptr, "GetAnalogStickManualCalibrationStage"},
  796. {827, nullptr, "IsAnalogStickButtonPressed"},
  797. {828, nullptr, "IsAnalogStickInReleasePosition"},
  798. {829, nullptr, "IsAnalogStickInCircumference"},
  799. {830, nullptr, "SetNotificationLedPattern"},
  800. {850, nullptr, "IsUsbFullKeyControllerEnabled"},
  801. {851, nullptr, "EnableUsbFullKeyController"},
  802. {852, nullptr, "IsUsbConnected"},
  803. {870, nullptr, "IsHandheldButtonPressedOnConsoleMode"},
  804. {900, nullptr, "ActivateInputDetector"},
  805. {901, nullptr, "NotifyInputDetector"},
  806. {1000, nullptr, "InitializeFirmwareUpdate"},
  807. {1001, nullptr, "GetFirmwareVersion"},
  808. {1002, nullptr, "GetAvailableFirmwareVersion"},
  809. {1003, nullptr, "IsFirmwareUpdateAvailable"},
  810. {1004, nullptr, "CheckFirmwareUpdateRequired"},
  811. {1005, nullptr, "StartFirmwareUpdate"},
  812. {1006, nullptr, "AbortFirmwareUpdate"},
  813. {1007, nullptr, "GetFirmwareUpdateState"},
  814. {1008, nullptr, "ActivateAudioControl"},
  815. {1009, nullptr, "AcquireAudioControlEventHandle"},
  816. {1010, nullptr, "GetAudioControlStates"},
  817. {1011, nullptr, "DeactivateAudioControl"},
  818. {1050, nullptr, "IsSixAxisSensorAccurateUserCalibrationSupported"},
  819. {1051, nullptr, "StartSixAxisSensorAccurateUserCalibration"},
  820. {1052, nullptr, "CancelSixAxisSensorAccurateUserCalibration"},
  821. {1053, nullptr, "GetSixAxisSensorAccurateUserCalibrationState"},
  822. {1100, nullptr, "GetHidbusSystemServiceObject"},
  823. {1120, nullptr, "SetFirmwareHotfixUpdateSkipEnabled"},
  824. {1130, nullptr, "InitializeUsbFirmwareUpdate"},
  825. {1131, nullptr, "FinalizeUsbFirmwareUpdate"},
  826. {1132, nullptr, "CheckUsbFirmwareUpdateRequired"},
  827. {1133, nullptr, "StartUsbFirmwareUpdate"},
  828. {1134, nullptr, "GetUsbFirmwareUpdateState"},
  829. };
  830. // clang-format on
  831. RegisterHandlers(functions);
  832. }
  833. };
  834. class HidTmp final : public ServiceFramework<HidTmp> {
  835. public:
  836. explicit HidTmp() : ServiceFramework{"hid:tmp"} {
  837. // clang-format off
  838. static const FunctionInfo functions[] = {
  839. {0, nullptr, "GetConsoleSixAxisSensorCalibrationValues"},
  840. };
  841. // clang-format on
  842. RegisterHandlers(functions);
  843. }
  844. };
  845. class HidBus final : public ServiceFramework<HidBus> {
  846. public:
  847. explicit HidBus() : ServiceFramework{"hidbus"} {
  848. // clang-format off
  849. static const FunctionInfo functions[] = {
  850. {1, nullptr, "GetBusHandle"},
  851. {2, nullptr, "IsExternalDeviceConnected"},
  852. {3, nullptr, "Initialize"},
  853. {4, nullptr, "Finalize"},
  854. {5, nullptr, "EnableExternalDevice"},
  855. {6, nullptr, "GetExternalDeviceId"},
  856. {7, nullptr, "SendCommandAsync"},
  857. {8, nullptr, "GetSendCommandAsynceResult"},
  858. {9, nullptr, "SetEventForSendCommandAsycResult"},
  859. {10, nullptr, "GetSharedMemoryHandle"},
  860. {11, nullptr, "EnableJoyPollingReceiveMode"},
  861. {12, nullptr, "DisableJoyPollingReceiveMode"},
  862. {13, nullptr, "GetPollingData"},
  863. {14, nullptr, "SetStatusManagerType"},
  864. };
  865. // clang-format on
  866. RegisterHandlers(functions);
  867. }
  868. };
  869. void ReloadInputDevices() {
  870. Settings::values.is_device_reload_pending.store(true);
  871. }
  872. void InstallInterfaces(SM::ServiceManager& service_manager) {
  873. std::make_shared<Hid>()->InstallAsService(service_manager);
  874. std::make_shared<HidBus>()->InstallAsService(service_manager);
  875. std::make_shared<HidDbg>()->InstallAsService(service_manager);
  876. std::make_shared<HidSys>()->InstallAsService(service_manager);
  877. std::make_shared<HidTmp>()->InstallAsService(service_manager);
  878. std::make_shared<IRS>()->InstallAsService(service_manager);
  879. std::make_shared<IRS_SYS>()->InstallAsService(service_manager);
  880. std::make_shared<XCD_SYS>()->InstallAsService(service_manager);
  881. }
  882. } // namespace Service::HID