hid.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <atomic>
  5. #include "common/logging/log.h"
  6. #include "core/core_timing.h"
  7. #include "core/core_timing_util.h"
  8. #include "core/frontend/emu_window.h"
  9. #include "core/frontend/input.h"
  10. #include "core/hle/ipc_helpers.h"
  11. #include "core/hle/kernel/client_port.h"
  12. #include "core/hle/kernel/client_session.h"
  13. #include "core/hle/kernel/event.h"
  14. #include "core/hle/kernel/shared_memory.h"
  15. #include "core/hle/service/hid/hid.h"
  16. #include "core/hle/service/hid/irs.h"
  17. #include "core/hle/service/service.h"
  18. namespace Service::HID {
  19. // Updating period for each HID device.
  20. // TODO(shinyquagsire23): These need better values.
  21. constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
  22. constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
  23. constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
  24. class IAppletResource final : public ServiceFramework<IAppletResource> {
  25. public:
  26. IAppletResource() : ServiceFramework("IAppletResource") {
  27. static const FunctionInfo functions[] = {
  28. {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
  29. };
  30. RegisterHandlers(functions);
  31. shared_mem = Kernel::SharedMemory::Create(
  32. nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read,
  33. 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
  34. // Register update callbacks
  35. pad_update_event = CoreTiming::RegisterEvent(
  36. "HID::UpdatePadCallback",
  37. [this](u64 userdata, int cycles_late) { UpdatePadCallback(userdata, cycles_late); });
  38. // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
  39. CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
  40. }
  41. ~IAppletResource() {
  42. CoreTiming::UnscheduleEvent(pad_update_event, 0);
  43. }
  44. private:
  45. void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
  46. IPC::ResponseBuilder rb{ctx, 2, 1};
  47. rb.Push(RESULT_SUCCESS);
  48. rb.PushCopyObjects(shared_mem);
  49. LOG_DEBUG(Service_HID, "called");
  50. }
  51. void LoadInputDevices() {
  52. std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
  53. Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
  54. buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
  55. std::transform(Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
  56. Settings::values.analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
  57. sticks.begin(), Input::CreateDevice<Input::AnalogDevice>);
  58. touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device);
  59. // TODO(shinyquagsire23): gyro, mouse, keyboard
  60. }
  61. void UpdatePadCallback(u64 userdata, int cycles_late) {
  62. SharedMemory mem{};
  63. std::memcpy(&mem, shared_mem->GetPointer(), sizeof(SharedMemory));
  64. if (is_device_reload_pending.exchange(false))
  65. LoadInputDevices();
  66. // Set up controllers as neon red+blue Joy-Con attached to console
  67. ControllerHeader& controller_header = mem.controllers[Controller_Handheld].header;
  68. controller_header.type = ControllerType_Handheld;
  69. controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent;
  70. controller_header.right_color_body = JOYCON_BODY_NEON_RED;
  71. controller_header.right_color_buttons = JOYCON_BUTTONS_NEON_RED;
  72. controller_header.left_color_body = JOYCON_BODY_NEON_BLUE;
  73. controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE;
  74. for (size_t controller = 0; controller < mem.controllers.size(); controller++) {
  75. for (auto& layout : mem.controllers[controller].layouts) {
  76. layout.header.num_entries = HID_NUM_ENTRIES;
  77. layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
  78. // HID shared memory stores the state of the past 17 samples in a circlular buffer,
  79. // each with a timestamp in number of samples since boot.
  80. const ControllerInputEntry& last_entry = layout.entries[layout.header.latest_entry];
  81. layout.header.timestamp_ticks = CoreTiming::GetTicks();
  82. layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES;
  83. ControllerInputEntry& entry = layout.entries[layout.header.latest_entry];
  84. entry.timestamp = last_entry.timestamp + 1;
  85. // TODO(shinyquagsire23): Is this always identical to timestamp?
  86. entry.timestamp_2 = entry.timestamp;
  87. // TODO(shinyquagsire23): More than just handheld input
  88. if (controller != Controller_Handheld)
  89. continue;
  90. entry.connection_state = ConnectionState_Connected | ConnectionState_Wired;
  91. // TODO(shinyquagsire23): Set up some LUTs for each layout mapping in the future?
  92. // For now everything is just the default handheld layout, but split Joy-Con will
  93. // rotate the face buttons and directions for certain layouts.
  94. ControllerPadState& state = entry.buttons;
  95. using namespace Settings::NativeButton;
  96. state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
  97. state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
  98. state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
  99. state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
  100. state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
  101. state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
  102. state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
  103. state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
  104. state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
  105. state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
  106. state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
  107. state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
  108. state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
  109. state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
  110. state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
  111. state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
  112. state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
  113. state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
  114. state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
  115. state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
  116. state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
  117. state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
  118. state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
  119. state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
  120. state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
  121. state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
  122. const auto [stick_l_x_f, stick_l_y_f] = sticks[Joystick_Left]->GetStatus();
  123. const auto [stick_r_x_f, stick_r_y_f] = sticks[Joystick_Right]->GetStatus();
  124. entry.joystick_left_x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
  125. entry.joystick_left_y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
  126. entry.joystick_right_x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
  127. entry.joystick_right_y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
  128. }
  129. }
  130. TouchScreen& touchscreen = mem.touchscreen;
  131. const u64 last_entry = touchscreen.header.latest_entry;
  132. const u64 curr_entry = (last_entry + 1) % touchscreen.entries.size();
  133. const u64 timestamp = CoreTiming::GetTicks();
  134. const u64 sample_counter = touchscreen.entries[last_entry].header.timestamp + 1;
  135. touchscreen.header.timestamp_ticks = timestamp;
  136. touchscreen.header.num_entries = touchscreen.entries.size();
  137. touchscreen.header.latest_entry = curr_entry;
  138. touchscreen.header.max_entry_index = touchscreen.entries.size();
  139. touchscreen.header.timestamp = timestamp;
  140. touchscreen.entries[curr_entry].header.timestamp = sample_counter;
  141. TouchScreenEntryTouch touch_entry{};
  142. auto [x, y, pressed] = touch_device->GetStatus();
  143. touch_entry.timestamp = timestamp;
  144. touch_entry.x = static_cast<u16>(x * Layout::ScreenUndocked::Width);
  145. touch_entry.y = static_cast<u16>(y * Layout::ScreenUndocked::Height);
  146. touch_entry.touch_index = 0;
  147. // TODO(DarkLordZach): Maybe try to derive these from EmuWindow?
  148. touch_entry.diameter_x = 15;
  149. touch_entry.diameter_y = 15;
  150. touch_entry.angle = 0;
  151. // TODO(DarkLordZach): Implement multi-touch support
  152. if (pressed) {
  153. touchscreen.entries[curr_entry].header.num_touches = 1;
  154. touchscreen.entries[curr_entry].touches[0] = touch_entry;
  155. } else {
  156. touchscreen.entries[curr_entry].header.num_touches = 0;
  157. }
  158. // TODO(shinyquagsire23): Properly implement mouse
  159. Mouse& mouse = mem.mouse;
  160. const u64 last_mouse_entry = mouse.header.latest_entry;
  161. const u64 curr_mouse_entry = (mouse.header.latest_entry + 1) % mouse.entries.size();
  162. const u64 mouse_sample_counter = mouse.entries[last_mouse_entry].timestamp + 1;
  163. mouse.header.timestamp_ticks = timestamp;
  164. mouse.header.num_entries = mouse.entries.size();
  165. mouse.header.max_entry_index = mouse.entries.size();
  166. mouse.header.latest_entry = curr_mouse_entry;
  167. mouse.entries[curr_mouse_entry].timestamp = mouse_sample_counter;
  168. mouse.entries[curr_mouse_entry].timestamp_2 = mouse_sample_counter;
  169. // TODO(shinyquagsire23): Properly implement keyboard
  170. Keyboard& keyboard = mem.keyboard;
  171. const u64 last_keyboard_entry = keyboard.header.latest_entry;
  172. const u64 curr_keyboard_entry =
  173. (keyboard.header.latest_entry + 1) % keyboard.entries.size();
  174. const u64 keyboard_sample_counter = keyboard.entries[last_keyboard_entry].timestamp + 1;
  175. keyboard.header.timestamp_ticks = timestamp;
  176. keyboard.header.num_entries = keyboard.entries.size();
  177. keyboard.header.latest_entry = last_keyboard_entry;
  178. keyboard.header.max_entry_index = keyboard.entries.size();
  179. keyboard.entries[curr_keyboard_entry].timestamp = keyboard_sample_counter;
  180. keyboard.entries[curr_keyboard_entry].timestamp_2 = keyboard_sample_counter;
  181. // TODO(shinyquagsire23): Figure out what any of these are
  182. for (auto& input : mem.unk_input_1) {
  183. const u64 last_input_entry = input.header.latest_entry;
  184. const u64 curr_input_entry = (input.header.latest_entry + 1) % input.entries.size();
  185. const u64 input_sample_counter = input.entries[last_input_entry].timestamp + 1;
  186. input.header.timestamp_ticks = timestamp;
  187. input.header.num_entries = input.entries.size();
  188. input.header.latest_entry = last_input_entry;
  189. input.header.max_entry_index = input.entries.size();
  190. input.entries[curr_input_entry].timestamp = input_sample_counter;
  191. input.entries[curr_input_entry].timestamp_2 = input_sample_counter;
  192. }
  193. for (auto& input : mem.unk_input_2) {
  194. input.header.timestamp_ticks = timestamp;
  195. input.header.num_entries = 17;
  196. input.header.latest_entry = 0;
  197. input.header.max_entry_index = 0;
  198. }
  199. UnkInput3& input = mem.unk_input_3;
  200. const u64 last_input_entry = input.header.latest_entry;
  201. const u64 curr_input_entry = (input.header.latest_entry + 1) % input.entries.size();
  202. const u64 input_sample_counter = input.entries[last_input_entry].timestamp + 1;
  203. input.header.timestamp_ticks = timestamp;
  204. input.header.num_entries = input.entries.size();
  205. input.header.latest_entry = last_input_entry;
  206. input.header.max_entry_index = input.entries.size();
  207. input.entries[curr_input_entry].timestamp = input_sample_counter;
  208. input.entries[curr_input_entry].timestamp_2 = input_sample_counter;
  209. // TODO(shinyquagsire23): Signal events
  210. std::memcpy(shared_mem->GetPointer(), &mem, sizeof(SharedMemory));
  211. // Reschedule recurrent event
  212. CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
  213. }
  214. // Handle to shared memory region designated to HID service
  215. Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
  216. // CoreTiming update events
  217. CoreTiming::EventType* pad_update_event;
  218. // Stored input state info
  219. std::atomic<bool> is_device_reload_pending{true};
  220. std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
  221. buttons;
  222. std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID> sticks;
  223. std::unique_ptr<Input::TouchDevice> touch_device;
  224. };
  225. class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
  226. public:
  227. IActiveVibrationDeviceList() : ServiceFramework("IActiveVibrationDeviceList") {
  228. static const FunctionInfo functions[] = {
  229. {0, &IActiveVibrationDeviceList::ActivateVibrationDevice, "ActivateVibrationDevice"},
  230. };
  231. RegisterHandlers(functions);
  232. }
  233. private:
  234. void ActivateVibrationDevice(Kernel::HLERequestContext& ctx) {
  235. IPC::ResponseBuilder rb{ctx, 2};
  236. rb.Push(RESULT_SUCCESS);
  237. LOG_WARNING(Service_HID, "(STUBBED) called");
  238. }
  239. };
  240. class Hid final : public ServiceFramework<Hid> {
  241. public:
  242. Hid() : ServiceFramework("hid") {
  243. static const FunctionInfo functions[] = {
  244. {0, &Hid::CreateAppletResource, "CreateAppletResource"},
  245. {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
  246. {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
  247. {21, &Hid::ActivateMouse, "ActivateMouse"},
  248. {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
  249. {40, nullptr, "AcquireXpadIdEventHandle"},
  250. {41, nullptr, "ReleaseXpadIdEventHandle"},
  251. {51, nullptr, "ActivateXpad"},
  252. {55, nullptr, "GetXpadIds"},
  253. {56, nullptr, "ActivateJoyXpad"},
  254. {58, nullptr, "GetJoyXpadLifoHandle"},
  255. {59, nullptr, "GetJoyXpadIds"},
  256. {60, nullptr, "ActivateSixAxisSensor"},
  257. {61, nullptr, "DeactivateSixAxisSensor"},
  258. {62, nullptr, "GetSixAxisSensorLifoHandle"},
  259. {63, nullptr, "ActivateJoySixAxisSensor"},
  260. {64, nullptr, "DeactivateJoySixAxisSensor"},
  261. {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
  262. {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
  263. {67, nullptr, "StopSixAxisSensor"},
  264. {68, nullptr, "IsSixAxisSensorFusionEnabled"},
  265. {69, nullptr, "EnableSixAxisSensorFusion"},
  266. {70, nullptr, "SetSixAxisSensorFusionParameters"},
  267. {71, nullptr, "GetSixAxisSensorFusionParameters"},
  268. {72, nullptr, "ResetSixAxisSensorFusionParameters"},
  269. {73, nullptr, "SetAccelerometerParameters"},
  270. {74, nullptr, "GetAccelerometerParameters"},
  271. {75, nullptr, "ResetAccelerometerParameters"},
  272. {76, nullptr, "SetAccelerometerPlayMode"},
  273. {77, nullptr, "GetAccelerometerPlayMode"},
  274. {78, nullptr, "ResetAccelerometerPlayMode"},
  275. {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
  276. {80, nullptr, "GetGyroscopeZeroDriftMode"},
  277. {81, nullptr, "ResetGyroscopeZeroDriftMode"},
  278. {82, nullptr, "IsSixAxisSensorAtRest"},
  279. {91, nullptr, "ActivateGesture"},
  280. {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
  281. {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
  282. {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
  283. {103, &Hid::ActivateNpad, "ActivateNpad"},
  284. {104, nullptr, "DeactivateNpad"},
  285. {106, &Hid::AcquireNpadStyleSetUpdateEventHandle,
  286. "AcquireNpadStyleSetUpdateEventHandle"},
  287. {107, nullptr, "DisconnectNpad"},
  288. {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
  289. {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
  290. {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
  291. {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault,
  292. "SetNpadJoyAssignmentModeSingleByDefault"},
  293. {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
  294. {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
  295. {125, nullptr, "MergeSingleJoyAsDualJoy"},
  296. {126, nullptr, "StartLrAssignmentMode"},
  297. {127, nullptr, "StopLrAssignmentMode"},
  298. {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
  299. {129, nullptr, "GetNpadHandheldActivationMode"},
  300. {130, nullptr, "SwapNpadAssignment"},
  301. {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
  302. {132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
  303. {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
  304. {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
  305. {201, &Hid::SendVibrationValue, "SendVibrationValue"},
  306. {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
  307. {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
  308. {204, nullptr, "PermitVibration"},
  309. {205, nullptr, "IsVibrationPermitted"},
  310. {206, &Hid::SendVibrationValues, "SendVibrationValues"},
  311. {207, nullptr, "SendVibrationGcErmCommand"},
  312. {208, nullptr, "GetActualVibrationGcErmCommand"},
  313. {209, nullptr, "BeginPermitVibrationSession"},
  314. {210, nullptr, "EndPermitVibrationSession"},
  315. {300, nullptr, "ActivateConsoleSixAxisSensor"},
  316. {301, nullptr, "StartConsoleSixAxisSensor"},
  317. {302, nullptr, "StopConsoleSixAxisSensor"},
  318. {303, nullptr, "ActivateSevenSixAxisSensor"},
  319. {304, nullptr, "StartSevenSixAxisSensor"},
  320. {305, nullptr, "StopSevenSixAxisSensor"},
  321. {306, nullptr, "InitializeSevenSixAxisSensor"},
  322. {307, nullptr, "FinalizeSevenSixAxisSensor"},
  323. {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
  324. {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
  325. {400, nullptr, "IsUsbFullKeyControllerEnabled"},
  326. {401, nullptr, "EnableUsbFullKeyController"},
  327. {402, nullptr, "IsUsbFullKeyControllerConnected"},
  328. {403, nullptr, "HasBattery"},
  329. {404, nullptr, "HasLeftRightBattery"},
  330. {405, nullptr, "GetNpadInterfaceType"},
  331. {406, nullptr, "GetNpadLeftRightInterfaceType"},
  332. {500, nullptr, "GetPalmaConnectionHandle"},
  333. {501, nullptr, "InitializePalma"},
  334. {502, nullptr, "AcquirePalmaOperationCompleteEvent"},
  335. {503, nullptr, "GetPalmaOperationInfo"},
  336. {504, nullptr, "PlayPalmaActivity"},
  337. {505, nullptr, "SetPalmaFrModeType"},
  338. {506, nullptr, "ReadPalmaStep"},
  339. {507, nullptr, "EnablePalmaStep"},
  340. {508, nullptr, "SuspendPalmaStep"},
  341. {509, nullptr, "ResetPalmaStep"},
  342. {510, nullptr, "ReadPalmaApplicationSection"},
  343. {511, nullptr, "WritePalmaApplicationSection"},
  344. {512, nullptr, "ReadPalmaUniqueCode"},
  345. {513, nullptr, "SetPalmaUniqueCodeInvalid"},
  346. {1000, nullptr, "SetNpadCommunicationMode"},
  347. {1001, nullptr, "GetNpadCommunicationMode"},
  348. };
  349. RegisterHandlers(functions);
  350. event = Kernel::Event::Create(Kernel::ResetType::OneShot, "hid:EventHandle");
  351. }
  352. ~Hid() = default;
  353. private:
  354. std::shared_ptr<IAppletResource> applet_resource;
  355. u32 joy_hold_type{0};
  356. Kernel::SharedPtr<Kernel::Event> event;
  357. void CreateAppletResource(Kernel::HLERequestContext& ctx) {
  358. if (applet_resource == nullptr) {
  359. applet_resource = std::make_shared<IAppletResource>();
  360. }
  361. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  362. rb.Push(RESULT_SUCCESS);
  363. rb.PushIpcInterface<IAppletResource>(applet_resource);
  364. LOG_DEBUG(Service_HID, "called");
  365. }
  366. void ActivateDebugPad(Kernel::HLERequestContext& ctx) {
  367. IPC::ResponseBuilder rb{ctx, 2};
  368. rb.Push(RESULT_SUCCESS);
  369. LOG_WARNING(Service_HID, "(STUBBED) called");
  370. }
  371. void ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
  372. IPC::ResponseBuilder rb{ctx, 2};
  373. rb.Push(RESULT_SUCCESS);
  374. LOG_WARNING(Service_HID, "(STUBBED) called");
  375. }
  376. void ActivateMouse(Kernel::HLERequestContext& ctx) {
  377. IPC::ResponseBuilder rb{ctx, 2};
  378. rb.Push(RESULT_SUCCESS);
  379. LOG_WARNING(Service_HID, "(STUBBED) called");
  380. }
  381. void ActivateKeyboard(Kernel::HLERequestContext& ctx) {
  382. IPC::ResponseBuilder rb{ctx, 2};
  383. rb.Push(RESULT_SUCCESS);
  384. LOG_WARNING(Service_HID, "(STUBBED) called");
  385. }
  386. void StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
  387. IPC::ResponseBuilder rb{ctx, 2};
  388. rb.Push(RESULT_SUCCESS);
  389. LOG_WARNING(Service_HID, "(STUBBED) called");
  390. }
  391. void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
  392. IPC::ResponseBuilder rb{ctx, 2};
  393. rb.Push(RESULT_SUCCESS);
  394. LOG_WARNING(Service_HID, "(STUBBED) called");
  395. }
  396. void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
  397. IPC::ResponseBuilder rb{ctx, 2};
  398. rb.Push(RESULT_SUCCESS);
  399. LOG_WARNING(Service_HID, "(STUBBED) called");
  400. }
  401. void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
  402. IPC::ResponseBuilder rb{ctx, 3};
  403. rb.Push(RESULT_SUCCESS);
  404. rb.Push<u32>(0);
  405. LOG_WARNING(Service_HID, "(STUBBED) called");
  406. }
  407. void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
  408. IPC::ResponseBuilder rb{ctx, 2};
  409. rb.Push(RESULT_SUCCESS);
  410. LOG_WARNING(Service_HID, "(STUBBED) called");
  411. }
  412. void ActivateNpad(Kernel::HLERequestContext& ctx) {
  413. IPC::ResponseBuilder rb{ctx, 2};
  414. rb.Push(RESULT_SUCCESS);
  415. LOG_WARNING(Service_HID, "(STUBBED) called");
  416. }
  417. void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
  418. IPC::ResponseBuilder rb{ctx, 2, 1};
  419. rb.Push(RESULT_SUCCESS);
  420. rb.PushCopyObjects(event);
  421. LOG_WARNING(Service_HID, "(STUBBED) called");
  422. }
  423. void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
  424. IPC::ResponseBuilder rb{ctx, 2};
  425. rb.Push(RESULT_SUCCESS);
  426. LOG_WARNING(Service_HID, "(STUBBED) called");
  427. }
  428. void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
  429. IPC::ResponseBuilder rb{ctx, 2};
  430. rb.Push(RESULT_SUCCESS);
  431. LOG_WARNING(Service_HID, "(STUBBED) called");
  432. }
  433. void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
  434. IPC::ResponseBuilder rb{ctx, 3};
  435. rb.Push(RESULT_SUCCESS);
  436. rb.Push(joy_hold_type);
  437. LOG_WARNING(Service_HID, "(STUBBED) called");
  438. }
  439. void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
  440. IPC::ResponseBuilder rb{ctx, 2};
  441. rb.Push(RESULT_SUCCESS);
  442. LOG_WARNING(Service_HID, "(STUBBED) called");
  443. }
  444. void SendVibrationValue(Kernel::HLERequestContext& ctx) {
  445. IPC::ResponseBuilder rb{ctx, 2};
  446. rb.Push(RESULT_SUCCESS);
  447. LOG_WARNING(Service_HID, "(STUBBED) called");
  448. }
  449. void GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
  450. IPC::ResponseBuilder rb{ctx, 2};
  451. rb.Push(RESULT_SUCCESS);
  452. LOG_WARNING(Service_HID, "(STUBBED) called");
  453. }
  454. void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
  455. IPC::ResponseBuilder rb{ctx, 2};
  456. rb.Push(RESULT_SUCCESS);
  457. LOG_WARNING(Service_HID, "(STUBBED) called");
  458. }
  459. void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
  460. IPC::ResponseBuilder rb{ctx, 2};
  461. rb.Push(RESULT_SUCCESS);
  462. LOG_WARNING(Service_HID, "(STUBBED) called");
  463. }
  464. void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
  465. IPC::ResponseBuilder rb{ctx, 4};
  466. rb.Push(RESULT_SUCCESS);
  467. rb.Push<u64>(0);
  468. LOG_WARNING(Service_HID, "(STUBBED) called");
  469. }
  470. void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
  471. IPC::ResponseBuilder rb{ctx, 2, 0, 1};
  472. rb.Push(RESULT_SUCCESS);
  473. rb.PushIpcInterface<IActiveVibrationDeviceList>();
  474. LOG_DEBUG(Service_HID, "called");
  475. }
  476. void SendVibrationValues(Kernel::HLERequestContext& ctx) {
  477. IPC::ResponseBuilder rb{ctx, 2};
  478. rb.Push(RESULT_SUCCESS);
  479. LOG_WARNING(Service_HID, "(STUBBED) called");
  480. }
  481. };
  482. void ReloadInputDevices() {}
  483. void InstallInterfaces(SM::ServiceManager& service_manager) {
  484. std::make_shared<Hid>()->InstallAsService(service_manager);
  485. std::make_shared<IRS>()->InstallAsService(service_manager);
  486. std::make_shared<IRS_SYS>()->InstallAsService(service_manager);
  487. }
  488. } // namespace Service::HID