IHidServer.cs 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708
  1. using Ryujinx.Common;
  2. using Ryujinx.Common.Logging;
  3. using Ryujinx.HLE.HOS.Ipc;
  4. using Ryujinx.HLE.HOS.Kernel.Common;
  5. using Ryujinx.HLE.HOS.Kernel.Threading;
  6. using Ryujinx.HLE.HOS.Services.Hid.HidServer;
  7. using Ryujinx.HLE.HOS.Services.Hid.Types;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Runtime.InteropServices;
  11. namespace Ryujinx.HLE.HOS.Services.Hid
  12. {
  13. [Service("hid")]
  14. class IHidServer : IpcService
  15. {
  16. private KEvent _xpadIdEvent;
  17. private KEvent _palmaOperationCompleteEvent;
  18. private int _xpadIdEventHandle;
  19. private bool _sixAxisSensorFusionEnabled;
  20. private bool _unintendedHomeButtonInputProtectionEnabled;
  21. private bool _vibrationPermitted;
  22. private bool _usbFullKeyControllerEnabled;
  23. private bool _isFirmwareUpdateAvailableForSixAxisSensor;
  24. private HidNpadJoyAssignmentMode _npadJoyAssignmentMode;
  25. private HidNpadHandheldActivationMode _npadHandheldActivationMode;
  26. private HidGyroscopeZeroDriftMode _gyroscopeZeroDriftMode;
  27. private long _npadCommunicationMode;
  28. private uint _accelerometerPlayMode;
  29. #pragma warning disable CS0649
  30. private long _vibrationGcErmCommand;
  31. #pragma warning restore CS0649
  32. private float _sevenSixAxisSensorFusionStrength;
  33. private HidSensorFusionParameters _sensorFusionParams;
  34. private HidAccelerometerParameters _accelerometerParams;
  35. public IHidServer(ServiceCtx context) : base(context.Device.System.HidServer)
  36. {
  37. _xpadIdEvent = new KEvent(context.Device.System.KernelContext);
  38. _palmaOperationCompleteEvent = new KEvent(context.Device.System.KernelContext);
  39. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
  40. _npadHandheldActivationMode = HidNpadHandheldActivationMode.Dual;
  41. _gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard;
  42. _isFirmwareUpdateAvailableForSixAxisSensor = false;
  43. _sensorFusionParams = new HidSensorFusionParameters();
  44. _accelerometerParams = new HidAccelerometerParameters();
  45. // TODO: signal event at right place
  46. _xpadIdEvent.ReadableEvent.Signal();
  47. }
  48. [CommandHipc(0)]
  49. // CreateAppletResource(nn::applet::AppletResourceUserId) -> object<nn::hid::IAppletResource>
  50. public ResultCode CreateAppletResource(ServiceCtx context)
  51. {
  52. long appletResourceUserId = context.RequestData.ReadInt64();
  53. MakeObject(context, new IAppletResource(context.Device.System.HidSharedMem));
  54. return ResultCode.Success;
  55. }
  56. [CommandHipc(1)]
  57. // ActivateDebugPad(nn::applet::AppletResourceUserId)
  58. public ResultCode ActivateDebugPad(ServiceCtx context)
  59. {
  60. long appletResourceUserId = context.RequestData.ReadInt64();
  61. // Initialize entries to avoid issues with some games.
  62. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  63. {
  64. context.Device.Hid.DebugPad.Update();
  65. }
  66. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  67. return ResultCode.Success;
  68. }
  69. [CommandHipc(11)]
  70. // ActivateTouchScreen(nn::applet::AppletResourceUserId)
  71. public ResultCode ActivateTouchScreen(ServiceCtx context)
  72. {
  73. long appletResourceUserId = context.RequestData.ReadInt64();
  74. context.Device.Hid.Touchscreen.Active = true;
  75. // Initialize entries to avoid issues with some games.
  76. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  77. {
  78. context.Device.Hid.Touchscreen.Update();
  79. }
  80. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  81. return ResultCode.Success;
  82. }
  83. [CommandHipc(21)]
  84. // ActivateMouse(nn::applet::AppletResourceUserId)
  85. public ResultCode ActivateMouse(ServiceCtx context)
  86. {
  87. long appletResourceUserId = context.RequestData.ReadInt64();
  88. context.Device.Hid.Mouse.Active = true;
  89. // Initialize entries to avoid issues with some games.
  90. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  91. {
  92. context.Device.Hid.Mouse.Update(0, 0);
  93. }
  94. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  95. return ResultCode.Success;
  96. }
  97. [CommandHipc(31)]
  98. // ActivateKeyboard(nn::applet::AppletResourceUserId)
  99. public ResultCode ActivateKeyboard(ServiceCtx context)
  100. {
  101. long appletResourceUserId = context.RequestData.ReadInt64();
  102. context.Device.Hid.Keyboard.Active = true;
  103. // Initialize entries to avoid issues with some games.
  104. KeyboardInput emptyInput = new KeyboardInput();
  105. emptyInput.Keys = new ulong[4];
  106. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  107. {
  108. context.Device.Hid.Keyboard.Update(emptyInput);
  109. }
  110. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  111. return ResultCode.Success;
  112. }
  113. [CommandHipc(32)]
  114. // SendKeyboardLockKeyEvent(uint flags, pid)
  115. public ResultCode SendKeyboardLockKeyEvent(ServiceCtx context)
  116. {
  117. uint flags = context.RequestData.ReadUInt32();
  118. // NOTE: This signal the keyboard driver about lock events.
  119. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { flags });
  120. return ResultCode.Success;
  121. }
  122. [CommandHipc(40)]
  123. // AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
  124. public ResultCode AcquireXpadIdEventHandle(ServiceCtx context)
  125. {
  126. long xpadId = context.RequestData.ReadInt64();
  127. if (context.Process.HandleTable.GenerateHandle(_xpadIdEvent.ReadableEvent, out _xpadIdEventHandle) != KernelResult.Success)
  128. {
  129. throw new InvalidOperationException("Out of handles!");
  130. }
  131. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_xpadIdEventHandle);
  132. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
  133. return ResultCode.Success;
  134. }
  135. [CommandHipc(41)]
  136. // ReleaseXpadIdEventHandle(ulong XpadId)
  137. public ResultCode ReleaseXpadIdEventHandle(ServiceCtx context)
  138. {
  139. long xpadId = context.RequestData.ReadInt64();
  140. context.Process.HandleTable.CloseHandle(_xpadIdEventHandle);
  141. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
  142. return ResultCode.Success;
  143. }
  144. [CommandHipc(51)]
  145. // ActivateXpad(nn::hid::BasicXpadId, nn::applet::AppletResourceUserId)
  146. public ResultCode ActivateXpad(ServiceCtx context)
  147. {
  148. int basicXpadId = context.RequestData.ReadInt32();
  149. long appletResourceUserId = context.RequestData.ReadInt64();
  150. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, basicXpadId });
  151. return ResultCode.Success;
  152. }
  153. [CommandHipc(55)]
  154. // GetXpadIds() -> long IdsCount, buffer<array<nn::hid::BasicXpadId>, type: 0xa>
  155. public ResultCode GetXpadIds(ServiceCtx context)
  156. {
  157. // There is any Xpad, so we return 0 and write nothing inside the type-0xa buffer.
  158. context.ResponseData.Write(0L);
  159. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  160. return ResultCode.Success;
  161. }
  162. [CommandHipc(56)]
  163. // ActivateJoyXpad(nn::hid::JoyXpadId)
  164. public ResultCode ActivateJoyXpad(ServiceCtx context)
  165. {
  166. int joyXpadId = context.RequestData.ReadInt32();
  167. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  168. return ResultCode.Success;
  169. }
  170. [CommandHipc(58)]
  171. // GetJoyXpadLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
  172. public ResultCode GetJoyXpadLifoHandle(ServiceCtx context)
  173. {
  174. int joyXpadId = context.RequestData.ReadInt32();
  175. int handle = 0;
  176. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  177. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  178. return ResultCode.Success;
  179. }
  180. [CommandHipc(59)]
  181. // GetJoyXpadIds() -> long IdsCount, buffer<array<nn::hid::JoyXpadId>, type: 0xa>
  182. public ResultCode GetJoyXpadIds(ServiceCtx context)
  183. {
  184. // There is any JoyXpad, so we return 0 and write nothing inside the type-0xa buffer.
  185. context.ResponseData.Write(0L);
  186. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  187. return ResultCode.Success;
  188. }
  189. [CommandHipc(60)]
  190. // ActivateSixAxisSensor(nn::hid::BasicXpadId)
  191. public ResultCode ActivateSixAxisSensor(ServiceCtx context)
  192. {
  193. int basicXpadId = context.RequestData.ReadInt32();
  194. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  195. return ResultCode.Success;
  196. }
  197. [CommandHipc(61)]
  198. // DeactivateSixAxisSensor(nn::hid::BasicXpadId)
  199. public ResultCode DeactivateSixAxisSensor(ServiceCtx context)
  200. {
  201. int basicXpadId = context.RequestData.ReadInt32();
  202. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  203. return ResultCode.Success;
  204. }
  205. [CommandHipc(62)]
  206. // GetSixAxisSensorLifoHandle(nn::hid::BasicXpadId) -> nn::sf::NativeHandle
  207. public ResultCode GetSixAxisSensorLifoHandle(ServiceCtx context)
  208. {
  209. int basicXpadId = context.RequestData.ReadInt32();
  210. int handle = 0;
  211. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  212. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  213. return ResultCode.Success;
  214. }
  215. [CommandHipc(63)]
  216. // ActivateJoySixAxisSensor(nn::hid::JoyXpadId)
  217. public ResultCode ActivateJoySixAxisSensor(ServiceCtx context)
  218. {
  219. int joyXpadId = context.RequestData.ReadInt32();
  220. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  221. return ResultCode.Success;
  222. }
  223. [CommandHipc(64)]
  224. // DeactivateJoySixAxisSensor(nn::hid::JoyXpadId)
  225. public ResultCode DeactivateJoySixAxisSensor(ServiceCtx context)
  226. {
  227. int joyXpadId = context.RequestData.ReadInt32();
  228. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  229. return ResultCode.Success;
  230. }
  231. [CommandHipc(65)]
  232. // GetJoySixAxisSensorLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
  233. public ResultCode GetJoySixAxisSensorLifoHandle(ServiceCtx context)
  234. {
  235. int joyXpadId = context.RequestData.ReadInt32();
  236. int handle = 0;
  237. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  238. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  239. return ResultCode.Success;
  240. }
  241. [CommandHipc(66)]
  242. // StartSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  243. public ResultCode StartSixAxisSensor(ServiceCtx context)
  244. {
  245. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  246. long appletResourceUserId = context.RequestData.ReadInt64();
  247. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
  248. return ResultCode.Success;
  249. }
  250. [CommandHipc(67)]
  251. // StopSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  252. public ResultCode StopSixAxisSensor(ServiceCtx context)
  253. {
  254. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  255. long appletResourceUserId = context.RequestData.ReadInt64();
  256. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
  257. return ResultCode.Success;
  258. }
  259. [CommandHipc(68)]
  260. // IsSixAxisSensorFusionEnabled(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsEnabled
  261. public ResultCode IsSixAxisSensorFusionEnabled(ServiceCtx context)
  262. {
  263. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  264. long appletResourceUserId = context.RequestData.ReadInt64();
  265. context.ResponseData.Write(_sixAxisSensorFusionEnabled);
  266. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
  267. return ResultCode.Success;
  268. }
  269. [CommandHipc(69)]
  270. // EnableSixAxisSensorFusion(bool Enabled, nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  271. public ResultCode EnableSixAxisSensorFusion(ServiceCtx context)
  272. {
  273. _sixAxisSensorFusionEnabled = context.RequestData.ReadBoolean();
  274. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  275. long appletResourceUserId = context.RequestData.ReadInt64();
  276. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
  277. return ResultCode.Success;
  278. }
  279. [CommandHipc(70)]
  280. // SetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, float RevisePower, float ReviseRange, nn::applet::AppletResourceUserId)
  281. public ResultCode SetSixAxisSensorFusionParameters(ServiceCtx context)
  282. {
  283. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  284. _sensorFusionParams = new HidSensorFusionParameters
  285. {
  286. RevisePower = context.RequestData.ReadInt32(),
  287. ReviseRange = context.RequestData.ReadInt32()
  288. };
  289. long appletResourceUserId = context.RequestData.ReadInt64();
  290. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  291. return ResultCode.Success;
  292. }
  293. [CommandHipc(71)]
  294. // GetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float RevisePower, float ReviseRange)
  295. public ResultCode GetSixAxisSensorFusionParameters(ServiceCtx context)
  296. {
  297. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  298. long appletResourceUserId = context.RequestData.ReadInt64();
  299. context.ResponseData.Write(_sensorFusionParams.RevisePower);
  300. context.ResponseData.Write(_sensorFusionParams.ReviseRange);
  301. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  302. return ResultCode.Success;
  303. }
  304. [CommandHipc(72)]
  305. // ResetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  306. public ResultCode ResetSixAxisSensorFusionParameters(ServiceCtx context)
  307. {
  308. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  309. long appletResourceUserId = context.RequestData.ReadInt64();
  310. _sensorFusionParams.RevisePower = 0;
  311. _sensorFusionParams.ReviseRange = 0;
  312. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  313. return ResultCode.Success;
  314. }
  315. [CommandHipc(73)]
  316. // SetAccelerometerParameters(nn::hid::SixAxisSensorHandle, float X, float Y, nn::applet::AppletResourceUserId)
  317. public ResultCode SetAccelerometerParameters(ServiceCtx context)
  318. {
  319. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  320. _accelerometerParams = new HidAccelerometerParameters
  321. {
  322. X = context.RequestData.ReadInt32(),
  323. Y = context.RequestData.ReadInt32()
  324. };
  325. long appletResourceUserId = context.RequestData.ReadInt64();
  326. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  327. return ResultCode.Success;
  328. }
  329. [CommandHipc(74)]
  330. // GetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float X, float Y
  331. public ResultCode GetAccelerometerParameters(ServiceCtx context)
  332. {
  333. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  334. long appletResourceUserId = context.RequestData.ReadInt64();
  335. context.ResponseData.Write(_accelerometerParams.X);
  336. context.ResponseData.Write(_accelerometerParams.Y);
  337. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  338. return ResultCode.Success;
  339. }
  340. [CommandHipc(75)]
  341. // ResetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  342. public ResultCode ResetAccelerometerParameters(ServiceCtx context)
  343. {
  344. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  345. long appletResourceUserId = context.RequestData.ReadInt64();
  346. _accelerometerParams.X = 0;
  347. _accelerometerParams.Y = 0;
  348. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  349. return ResultCode.Success;
  350. }
  351. [CommandHipc(76)]
  352. // SetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, uint PlayMode, nn::applet::AppletResourceUserId)
  353. public ResultCode SetAccelerometerPlayMode(ServiceCtx context)
  354. {
  355. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  356. _accelerometerPlayMode = context.RequestData.ReadUInt32();
  357. long appletResourceUserId = context.RequestData.ReadInt64();
  358. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  359. return ResultCode.Success;
  360. }
  361. [CommandHipc(77)]
  362. // GetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> uint PlayMode
  363. public ResultCode GetAccelerometerPlayMode(ServiceCtx context)
  364. {
  365. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  366. long appletResourceUserId = context.RequestData.ReadInt64();
  367. context.ResponseData.Write(_accelerometerPlayMode);
  368. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  369. return ResultCode.Success;
  370. }
  371. [CommandHipc(78)]
  372. // ResetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  373. public ResultCode ResetAccelerometerPlayMode(ServiceCtx context)
  374. {
  375. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  376. long appletResourceUserId = context.RequestData.ReadInt64();
  377. _accelerometerPlayMode = 0;
  378. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  379. return ResultCode.Success;
  380. }
  381. [CommandHipc(79)]
  382. // SetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, uint GyroscopeZeroDriftMode, nn::applet::AppletResourceUserId)
  383. public ResultCode SetGyroscopeZeroDriftMode(ServiceCtx context)
  384. {
  385. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  386. _gyroscopeZeroDriftMode = (HidGyroscopeZeroDriftMode)context.RequestData.ReadInt32();
  387. long appletResourceUserId = context.RequestData.ReadInt64();
  388. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  389. return ResultCode.Success;
  390. }
  391. [CommandHipc(80)]
  392. // GetGyroscopeZeroDriftMode(nn::applet::AppletResourceUserId, nn::hid::SixAxisSensorHandle) -> int GyroscopeZeroDriftMode
  393. public ResultCode GetGyroscopeZeroDriftMode(ServiceCtx context)
  394. {
  395. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  396. long appletResourceUserId = context.RequestData.ReadInt64();
  397. context.ResponseData.Write((int)_gyroscopeZeroDriftMode);
  398. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  399. return ResultCode.Success;
  400. }
  401. [CommandHipc(81)]
  402. // ResetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  403. public ResultCode ResetGyroscopeZeroDriftMode(ServiceCtx context)
  404. {
  405. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  406. long appletResourceUserId = context.RequestData.ReadInt64();
  407. _gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard;
  408. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  409. return ResultCode.Success;
  410. }
  411. [CommandHipc(82)]
  412. // IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
  413. public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
  414. {
  415. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  416. long appletResourceUserId = context.RequestData.ReadInt64();
  417. bool isAtRest = true;
  418. context.ResponseData.Write(isAtRest);
  419. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
  420. return ResultCode.Success;
  421. }
  422. [CommandHipc(83)] // 6.0.0+
  423. // IsFirmwareUpdateAvailableForSixAxisSensor(nn::hid::AppletResourceUserId, nn::hid::SixAxisSensorHandle, pid) -> bool UpdateAvailable
  424. public ResultCode IsFirmwareUpdateAvailableForSixAxisSensor(ServiceCtx context)
  425. {
  426. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  427. context.RequestData.BaseStream.Position += 4;
  428. long appletResourceUserId = context.RequestData.ReadInt64();
  429. context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
  430. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
  431. return ResultCode.Success;
  432. }
  433. [CommandHipc(91)]
  434. // ActivateGesture(nn::applet::AppletResourceUserId, int Unknown0)
  435. public ResultCode ActivateGesture(ServiceCtx context)
  436. {
  437. long appletResourceUserId = context.RequestData.ReadInt64();
  438. int unknown0 = context.RequestData.ReadInt32();
  439. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0 });
  440. return ResultCode.Success;
  441. }
  442. [CommandHipc(100)]
  443. // SetSupportedNpadStyleSet(nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag)
  444. public ResultCode SetSupportedNpadStyleSet(ServiceCtx context)
  445. {
  446. ControllerType type = (ControllerType)context.RequestData.ReadInt32();
  447. long appletResourceUserId = context.RequestData.ReadInt64();
  448. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  449. appletResourceUserId,
  450. type
  451. });
  452. context.Device.Hid.Npads.SupportedStyleSets = type;
  453. return ResultCode.Success;
  454. }
  455. [CommandHipc(101)]
  456. // GetSupportedNpadStyleSet(nn::applet::AppletResourceUserId) -> uint nn::hid::NpadStyleTag
  457. public ResultCode GetSupportedNpadStyleSet(ServiceCtx context)
  458. {
  459. long appletResourceUserId = context.RequestData.ReadInt64();
  460. context.ResponseData.Write((int)context.Device.Hid.Npads.SupportedStyleSets);
  461. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  462. appletResourceUserId,
  463. context.Device.Hid.Npads.SupportedStyleSets
  464. });
  465. return ResultCode.Success;
  466. }
  467. [CommandHipc(102)]
  468. // SetSupportedNpadIdType(nn::applet::AppletResourceUserId, array<NpadIdType, 9>)
  469. public ResultCode SetSupportedNpadIdType(ServiceCtx context)
  470. {
  471. long appletResourceUserId = context.RequestData.ReadInt64();
  472. ulong arrayPosition = context.Request.PtrBuff[0].Position;
  473. ulong arraySize = context.Request.PtrBuff[0].Size;
  474. ReadOnlySpan<NpadIdType> supportedPlayerIds = MemoryMarshal.Cast<byte, NpadIdType>(context.Memory.GetSpan(arrayPosition, (int)arraySize));
  475. context.Device.Hid.Npads.ClearSupportedPlayers();
  476. for (int i = 0; i < supportedPlayerIds.Length; ++i)
  477. {
  478. if (supportedPlayerIds[i] >= 0)
  479. {
  480. context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(supportedPlayerIds[i]));
  481. }
  482. }
  483. Logger.Stub?.PrintStub(LogClass.ServiceHid, $"{supportedPlayerIds.Length} " + string.Join(",", supportedPlayerIds.ToArray()));
  484. return ResultCode.Success;
  485. }
  486. [CommandHipc(103)]
  487. // ActivateNpad(nn::applet::AppletResourceUserId)
  488. public ResultCode ActivateNpad(ServiceCtx context)
  489. {
  490. return ActiveNpadImpl(context);
  491. }
  492. [CommandHipc(104)]
  493. // DeactivateNpad(nn::applet::AppletResourceUserId)
  494. public ResultCode DeactivateNpad(ServiceCtx context)
  495. {
  496. long appletResourceUserId = context.RequestData.ReadInt64();
  497. context.Device.Hid.Npads.Active = false;
  498. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  499. return ResultCode.Success;
  500. }
  501. [CommandHipc(106)]
  502. // AcquireNpadStyleSetUpdateEventHandle(nn::applet::AppletResourceUserId, uint, ulong) -> nn::sf::NativeHandle
  503. public ResultCode AcquireNpadStyleSetUpdateEventHandle(ServiceCtx context)
  504. {
  505. PlayerIndex npadId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
  506. long appletResourceUserId = context.RequestData.ReadInt64();
  507. long npadStyleSet = context.RequestData.ReadInt64();
  508. KEvent evnt = context.Device.Hid.Npads.GetStyleSetUpdateEvent(npadId);
  509. if (context.Process.HandleTable.GenerateHandle(evnt.ReadableEvent, out int handle) != KernelResult.Success)
  510. {
  511. throw new InvalidOperationException("Out of handles!");
  512. }
  513. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  514. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadId, npadStyleSet });
  515. return ResultCode.Success;
  516. }
  517. [CommandHipc(107)]
  518. // DisconnectNpad(nn::applet::AppletResourceUserId, uint NpadIdType)
  519. public ResultCode DisconnectNpad(ServiceCtx context)
  520. {
  521. NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
  522. long appletResourceUserId = context.RequestData.ReadInt64();
  523. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType });
  524. return ResultCode.Success;
  525. }
  526. [CommandHipc(108)]
  527. // GetPlayerLedPattern(u32 npad_id) -> u64 led_pattern
  528. public ResultCode GetPlayerLedPattern(ServiceCtx context)
  529. {
  530. NpadIdType npadId = (NpadIdType)context.RequestData.ReadUInt32();
  531. ulong ledPattern = npadId switch
  532. {
  533. NpadIdType.Player1 => 0b0001,
  534. NpadIdType.Player2 => 0b0011,
  535. NpadIdType.Player3 => 0b0111,
  536. NpadIdType.Player4 => 0b1111,
  537. NpadIdType.Player5 => 0b1001,
  538. NpadIdType.Player6 => 0b0101,
  539. NpadIdType.Player7 => 0b1101,
  540. NpadIdType.Player8 => 0b0110,
  541. NpadIdType.Unknown => 0b0000,
  542. NpadIdType.Handheld => 0b0000,
  543. _ => throw new ArgumentOutOfRangeException(nameof(npadId))
  544. };
  545. context.ResponseData.Write(ledPattern);
  546. return ResultCode.Success;
  547. }
  548. [CommandHipc(109)] // 5.0.0+
  549. // ActivateNpadWithRevision(nn::applet::AppletResourceUserId, ulong revision)
  550. public ResultCode ActivateNpadWithRevision(ServiceCtx context)
  551. {
  552. ulong revision = context.RequestData.ReadUInt64();
  553. return ActiveNpadImpl(context, revision);
  554. }
  555. private ResultCode ActiveNpadImpl(ServiceCtx context, ulong revision = 0)
  556. {
  557. long appletResourceUserId = context.RequestData.ReadInt64();
  558. context.Device.Hid.Npads.Active = true;
  559. // Initialize entries to avoid issues with some games.
  560. List<GamepadInput> emptyGamepadInputs = new List<GamepadInput>();
  561. List<SixAxisInput> emptySixAxisInputs = new List<SixAxisInput>();
  562. for (int player = 0; player < NpadDevices.MaxControllers; player++)
  563. {
  564. GamepadInput gamepadInput = new GamepadInput();
  565. SixAxisInput sixaxisInput = new SixAxisInput();
  566. gamepadInput.PlayerId = (PlayerIndex)player;
  567. sixaxisInput.PlayerId = (PlayerIndex)player;
  568. sixaxisInput.Orientation = new float[9];
  569. emptyGamepadInputs.Add(gamepadInput);
  570. emptySixAxisInputs.Add(sixaxisInput);
  571. }
  572. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  573. {
  574. context.Device.Hid.Npads.Update(emptyGamepadInputs);
  575. context.Device.Hid.Npads.UpdateSixAxis(emptySixAxisInputs);
  576. }
  577. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, revision });
  578. return ResultCode.Success;
  579. }
  580. [CommandHipc(120)]
  581. // SetNpadJoyHoldType(nn::applet::AppletResourceUserId, ulong NpadJoyHoldType)
  582. public ResultCode SetNpadJoyHoldType(ServiceCtx context)
  583. {
  584. long appletResourceUserId = context.RequestData.ReadInt64();
  585. NpadJoyHoldType npadJoyHoldType = (NpadJoyHoldType)context.RequestData.ReadUInt64();
  586. if (npadJoyHoldType > NpadJoyHoldType.Horizontal)
  587. {
  588. throw new ArgumentOutOfRangeException(nameof(npadJoyHoldType));
  589. }
  590. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  591. {
  592. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  593. {
  594. return ResultCode.InvalidNpadIdType;
  595. }
  596. }
  597. context.Device.Hid.Npads.JoyHold = npadJoyHoldType;
  598. return ResultCode.Success;
  599. }
  600. [CommandHipc(121)]
  601. // GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> ulong NpadJoyHoldType
  602. public ResultCode GetNpadJoyHoldType(ServiceCtx context)
  603. {
  604. long appletResourceUserId = context.RequestData.ReadInt64();
  605. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  606. {
  607. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  608. {
  609. return ResultCode.InvalidNpadIdType;
  610. }
  611. }
  612. context.ResponseData.Write((ulong)context.Device.Hid.Npads.JoyHold);
  613. return ResultCode.Success;
  614. }
  615. [CommandHipc(122)]
  616. // SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId)
  617. public ResultCode SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context)
  618. {
  619. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  620. long appletResourceUserId = context.RequestData.ReadInt64();
  621. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  622. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  623. return ResultCode.Success;
  624. }
  625. [CommandHipc(123)]
  626. // SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType)
  627. public ResultCode SetNpadJoyAssignmentModeSingle(ServiceCtx context)
  628. {
  629. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  630. long appletResourceUserId = context.RequestData.ReadInt64();
  631. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  632. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  633. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, hidNpadJoyDeviceType, _npadJoyAssignmentMode });
  634. return ResultCode.Success;
  635. }
  636. [CommandHipc(124)]
  637. // SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId)
  638. public ResultCode SetNpadJoyAssignmentModeDual(ServiceCtx context)
  639. {
  640. PlayerIndex hidControllerId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
  641. long appletResourceUserId = context.RequestData.ReadInt64();
  642. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
  643. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  644. return ResultCode.Success;
  645. }
  646. [CommandHipc(125)]
  647. // MergeSingleJoyAsDualJoy(uint SingleJoyId0, uint SingleJoyId1, nn::applet::AppletResourceUserId)
  648. public ResultCode MergeSingleJoyAsDualJoy(ServiceCtx context)
  649. {
  650. long singleJoyId0 = context.RequestData.ReadInt32();
  651. long singleJoyId1 = context.RequestData.ReadInt32();
  652. long appletResourceUserId = context.RequestData.ReadInt64();
  653. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, singleJoyId0, singleJoyId1 });
  654. return ResultCode.Success;
  655. }
  656. [CommandHipc(126)]
  657. // StartLrAssignmentMode(nn::applet::AppletResourceUserId)
  658. public ResultCode StartLrAssignmentMode(ServiceCtx context)
  659. {
  660. long appletResourceUserId = context.RequestData.ReadInt64();
  661. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  662. return ResultCode.Success;
  663. }
  664. [CommandHipc(127)]
  665. // StopLrAssignmentMode(nn::applet::AppletResourceUserId)
  666. public ResultCode StopLrAssignmentMode(ServiceCtx context)
  667. {
  668. long appletResourceUserId = context.RequestData.ReadInt64();
  669. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  670. return ResultCode.Success;
  671. }
  672. [CommandHipc(128)]
  673. // SetNpadHandheldActivationMode(nn::applet::AppletResourceUserId, long HidNpadHandheldActivationMode)
  674. public ResultCode SetNpadHandheldActivationMode(ServiceCtx context)
  675. {
  676. long appletResourceUserId = context.RequestData.ReadInt64();
  677. _npadHandheldActivationMode = (HidNpadHandheldActivationMode)context.RequestData.ReadInt64();
  678. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  679. return ResultCode.Success;
  680. }
  681. [CommandHipc(129)]
  682. // GetNpadHandheldActivationMode(nn::applet::AppletResourceUserId) -> long HidNpadHandheldActivationMode
  683. public ResultCode GetNpadHandheldActivationMode(ServiceCtx context)
  684. {
  685. long appletResourceUserId = context.RequestData.ReadInt64();
  686. context.ResponseData.Write((long)_npadHandheldActivationMode);
  687. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  688. return ResultCode.Success;
  689. }
  690. [CommandHipc(130)]
  691. // SwapNpadAssignment(uint OldNpadAssignment, uint NewNpadAssignment, nn::applet::AppletResourceUserId)
  692. public ResultCode SwapNpadAssignment(ServiceCtx context)
  693. {
  694. int oldNpadAssignment = context.RequestData.ReadInt32();
  695. int newNpadAssignment = context.RequestData.ReadInt32();
  696. long appletResourceUserId = context.RequestData.ReadInt64();
  697. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, oldNpadAssignment, newNpadAssignment });
  698. return ResultCode.Success;
  699. }
  700. [CommandHipc(131)]
  701. // IsUnintendedHomeButtonInputProtectionEnabled(uint Unknown0, nn::applet::AppletResourceUserId) -> bool IsEnabled
  702. public ResultCode IsUnintendedHomeButtonInputProtectionEnabled(ServiceCtx context)
  703. {
  704. uint unknown0 = context.RequestData.ReadUInt32();
  705. long appletResourceUserId = context.RequestData.ReadInt64();
  706. context.ResponseData.Write(_unintendedHomeButtonInputProtectionEnabled);
  707. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  708. return ResultCode.Success;
  709. }
  710. [CommandHipc(132)]
  711. // EnableUnintendedHomeButtonInputProtection(bool Enable, uint Unknown0, nn::applet::AppletResourceUserId)
  712. public ResultCode EnableUnintendedHomeButtonInputProtection(ServiceCtx context)
  713. {
  714. _unintendedHomeButtonInputProtectionEnabled = context.RequestData.ReadBoolean();
  715. uint unknown0 = context.RequestData.ReadUInt32();
  716. long appletResourceUserId = context.RequestData.ReadInt64();
  717. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  718. return ResultCode.Success;
  719. }
  720. [CommandHipc(133)] // 5.0.0+
  721. // SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1
  722. public ResultCode SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context)
  723. {
  724. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  725. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  726. long appletResourceUserId = context.RequestData.ReadInt64();
  727. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  728. context.ResponseData.Write(0); //Unknown0
  729. context.ResponseData.Write(0); //Unknown1
  730. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  731. appletResourceUserId,
  732. hidControllerId,
  733. hidNpadJoyDeviceType,
  734. _npadJoyAssignmentMode,
  735. Unknown0 = 0,
  736. Unknown1 = 0
  737. });
  738. return ResultCode.Success;
  739. }
  740. [CommandHipc(200)]
  741. // GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo
  742. public ResultCode GetVibrationDeviceInfo(ServiceCtx context)
  743. {
  744. HidVibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct<HidVibrationDeviceHandle>();
  745. NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType;
  746. NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId;
  747. if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
  748. {
  749. if (npadIdType >= (NpadIdType.Player8 + 1) && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
  750. {
  751. return ResultCode.InvalidNpadIdType;
  752. }
  753. if (deviceHandle.Position > 1)
  754. {
  755. return ResultCode.InvalidDeviceIndex;
  756. }
  757. HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None;
  758. if (Enum.IsDefined(typeof(NpadStyleIndex), deviceType))
  759. {
  760. vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator;
  761. }
  762. else if ((uint)deviceType == 8)
  763. {
  764. vibrationDeviceType = HidVibrationDeviceType.GcErm;
  765. }
  766. HidVibrationDevicePosition vibrationDevicePosition = HidVibrationDevicePosition.None;
  767. if (vibrationDeviceType == HidVibrationDeviceType.LinearResonantActuator)
  768. {
  769. if (deviceHandle.Position == 0)
  770. {
  771. vibrationDevicePosition = HidVibrationDevicePosition.Left;
  772. }
  773. else if (deviceHandle.Position == 1)
  774. {
  775. vibrationDevicePosition = HidVibrationDevicePosition.Right;
  776. }
  777. else
  778. {
  779. throw new ArgumentOutOfRangeException(nameof(deviceHandle.Position));
  780. }
  781. }
  782. HidVibrationDeviceValue deviceInfo = new HidVibrationDeviceValue
  783. {
  784. DeviceType = vibrationDeviceType,
  785. Position = vibrationDevicePosition
  786. };
  787. context.ResponseData.WriteStruct(deviceInfo);
  788. return ResultCode.Success;
  789. }
  790. return ResultCode.InvalidNpadDeviceType;
  791. }
  792. [CommandHipc(201)]
  793. // SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId)
  794. public ResultCode SendVibrationValue(ServiceCtx context)
  795. {
  796. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  797. {
  798. DeviceType = context.RequestData.ReadByte(),
  799. PlayerId = context.RequestData.ReadByte(),
  800. Position = context.RequestData.ReadByte(),
  801. Reserved = context.RequestData.ReadByte()
  802. };
  803. HidVibrationValue vibrationValue = new HidVibrationValue
  804. {
  805. AmplitudeLow = context.RequestData.ReadSingle(),
  806. FrequencyLow = context.RequestData.ReadSingle(),
  807. AmplitudeHigh = context.RequestData.ReadSingle(),
  808. FrequencyHigh = context.RequestData.ReadSingle()
  809. };
  810. long appletResourceUserId = context.RequestData.ReadInt64();
  811. Dictionary<byte, HidVibrationValue> dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  812. dualVibrationValues[deviceHandle.Position] = vibrationValue;
  813. context.Device.Hid.Npads.UpdateRumbleQueue((PlayerIndex)deviceHandle.PlayerId, dualVibrationValues);
  814. return ResultCode.Success;
  815. }
  816. [CommandHipc(202)]
  817. // GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue
  818. public ResultCode GetActualVibrationValue(ServiceCtx context)
  819. {
  820. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  821. {
  822. DeviceType = context.RequestData.ReadByte(),
  823. PlayerId = context.RequestData.ReadByte(),
  824. Position = context.RequestData.ReadByte(),
  825. Reserved = context.RequestData.ReadByte()
  826. };
  827. long appletResourceUserId = context.RequestData.ReadInt64();
  828. HidVibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position);
  829. context.ResponseData.Write(vibrationValue.AmplitudeLow);
  830. context.ResponseData.Write(vibrationValue.FrequencyLow);
  831. context.ResponseData.Write(vibrationValue.AmplitudeHigh);
  832. context.ResponseData.Write(vibrationValue.FrequencyHigh);
  833. return ResultCode.Success;
  834. }
  835. [CommandHipc(203)]
  836. // CreateActiveVibrationDeviceList() -> object<nn::hid::IActiveVibrationDeviceList>
  837. public ResultCode CreateActiveVibrationDeviceList(ServiceCtx context)
  838. {
  839. MakeObject(context, new IActiveApplicationDeviceList());
  840. return ResultCode.Success;
  841. }
  842. [CommandHipc(204)]
  843. // PermitVibration(bool Enable)
  844. public ResultCode PermitVibration(ServiceCtx context)
  845. {
  846. _vibrationPermitted = context.RequestData.ReadBoolean();
  847. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
  848. return ResultCode.Success;
  849. }
  850. [CommandHipc(205)]
  851. // IsVibrationPermitted() -> bool IsEnabled
  852. public ResultCode IsVibrationPermitted(ServiceCtx context)
  853. {
  854. context.ResponseData.Write(_vibrationPermitted);
  855. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
  856. return ResultCode.Success;
  857. }
  858. [CommandHipc(206)]
  859. // SendVibrationValues(nn::applet::AppletResourceUserId, buffer<array<nn::hid::VibrationDeviceHandle>, type: 9>, buffer<array<nn::hid::VibrationValue>, type: 9>)
  860. public ResultCode SendVibrationValues(ServiceCtx context)
  861. {
  862. long appletResourceUserId = context.RequestData.ReadInt64();
  863. byte[] vibrationDeviceHandleBuffer = new byte[context.Request.PtrBuff[0].Size];
  864. context.Memory.Read(context.Request.PtrBuff[0].Position, vibrationDeviceHandleBuffer);
  865. byte[] vibrationValueBuffer = new byte[context.Request.PtrBuff[1].Size];
  866. context.Memory.Read(context.Request.PtrBuff[1].Position, vibrationValueBuffer);
  867. Span<HidVibrationDeviceHandle> deviceHandles = MemoryMarshal.Cast<byte, HidVibrationDeviceHandle>(vibrationDeviceHandleBuffer);
  868. Span<HidVibrationValue> vibrationValues = MemoryMarshal.Cast<byte, HidVibrationValue>(vibrationValueBuffer);
  869. if (!deviceHandles.IsEmpty && vibrationValues.Length == deviceHandles.Length)
  870. {
  871. Dictionary<byte, HidVibrationValue> dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  872. PlayerIndex currentIndex = (PlayerIndex)deviceHandles[0].PlayerId;
  873. for (int deviceCounter = 0; deviceCounter < deviceHandles.Length; deviceCounter++)
  874. {
  875. PlayerIndex index = (PlayerIndex)deviceHandles[deviceCounter].PlayerId;
  876. byte position = deviceHandles[deviceCounter].Position;
  877. if (index != currentIndex || dualVibrationValues.Count == 2)
  878. {
  879. context.Device.Hid.Npads.UpdateRumbleQueue(currentIndex, dualVibrationValues);
  880. dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  881. }
  882. dualVibrationValues[position] = vibrationValues[deviceCounter];
  883. currentIndex = index;
  884. }
  885. context.Device.Hid.Npads.UpdateRumbleQueue(currentIndex, dualVibrationValues);
  886. }
  887. return ResultCode.Success;
  888. }
  889. [CommandHipc(207)] // 4.0.0+
  890. // SendVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::hid::VibrationGcErmCommand, nn::applet::AppletResourceUserId)
  891. public ResultCode SendVibrationGcErmCommand(ServiceCtx context)
  892. {
  893. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  894. long vibrationGcErmCommand = context.RequestData.ReadInt64();
  895. long appletResourceUserId = context.RequestData.ReadInt64();
  896. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, vibrationGcErmCommand });
  897. return ResultCode.Success;
  898. }
  899. [CommandHipc(208)] // 4.0.0+
  900. // GetActualVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationGcErmCommand
  901. public ResultCode GetActualVibrationGcErmCommand(ServiceCtx context)
  902. {
  903. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  904. long appletResourceUserId = context.RequestData.ReadInt64();
  905. context.ResponseData.Write(_vibrationGcErmCommand);
  906. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, _vibrationGcErmCommand });
  907. return ResultCode.Success;
  908. }
  909. [CommandHipc(209)] // 4.0.0+
  910. // BeginPermitVibrationSession(nn::applet::AppletResourceUserId)
  911. public ResultCode BeginPermitVibrationSession(ServiceCtx context)
  912. {
  913. long appletResourceUserId = context.RequestData.ReadInt64();
  914. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  915. return ResultCode.Success;
  916. }
  917. [CommandHipc(210)] // 4.0.0+
  918. // EndPermitVibrationSession()
  919. public ResultCode EndPermitVibrationSession(ServiceCtx context)
  920. {
  921. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  922. return ResultCode.Success;
  923. }
  924. [CommandHipc(211)] // 7.0.0+
  925. // IsVibrationDeviceMounted(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId)
  926. public ResultCode IsVibrationDeviceMounted(ServiceCtx context)
  927. {
  928. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  929. long appletResourceUserId = context.RequestData.ReadInt64();
  930. // NOTE: Service use vibrationDeviceHandle to get the PlayerIndex.
  931. // And return false if (npadIdType >= (NpadIdType)8 && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
  932. context.ResponseData.Write(true);
  933. return ResultCode.Success;
  934. }
  935. [CommandHipc(300)]
  936. // ActivateConsoleSixAxisSensor(nn::applet::AppletResourceUserId)
  937. public ResultCode ActivateConsoleSixAxisSensor(ServiceCtx context)
  938. {
  939. long appletResourceUserId = context.RequestData.ReadInt64();
  940. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  941. return ResultCode.Success;
  942. }
  943. [CommandHipc(301)]
  944. // StartConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
  945. public ResultCode StartConsoleSixAxisSensor(ServiceCtx context)
  946. {
  947. int consoleSixAxisSensorHandle = context.RequestData.ReadInt32();
  948. long appletResourceUserId = context.RequestData.ReadInt64();
  949. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, consoleSixAxisSensorHandle });
  950. return ResultCode.Success;
  951. }
  952. [CommandHipc(302)]
  953. // StopConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
  954. public ResultCode StopConsoleSixAxisSensor(ServiceCtx context)
  955. {
  956. int consoleSixAxisSensorHandle = context.RequestData.ReadInt32();
  957. long appletResourceUserId = context.RequestData.ReadInt64();
  958. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, consoleSixAxisSensorHandle });
  959. return ResultCode.Success;
  960. }
  961. [CommandHipc(303)] // 5.0.0+
  962. // ActivateSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  963. public ResultCode ActivateSevenSixAxisSensor(ServiceCtx context)
  964. {
  965. long appletResourceUserId = context.RequestData.ReadInt64();
  966. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  967. return ResultCode.Success;
  968. }
  969. [CommandHipc(304)] // 5.0.0+
  970. // StartSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  971. public ResultCode StartSevenSixAxisSensor(ServiceCtx context)
  972. {
  973. long appletResourceUserId = context.RequestData.ReadInt64();
  974. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  975. return ResultCode.Success;
  976. }
  977. [CommandHipc(305)] // 5.0.0+
  978. // StopSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  979. public ResultCode StopSevenSixAxisSensor(ServiceCtx context)
  980. {
  981. long appletResourceUserId = context.RequestData.ReadInt64();
  982. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  983. return ResultCode.Success;
  984. }
  985. [CommandHipc(306)] // 5.0.0+
  986. // InitializeSevenSixAxisSensor(array<nn::sf::NativeHandle>, ulong Counter0, array<nn::sf::NativeHandle>, ulong Counter1, nn::applet::AppletResourceUserId)
  987. public ResultCode InitializeSevenSixAxisSensor(ServiceCtx context)
  988. {
  989. long appletResourceUserId = context.RequestData.ReadInt64();
  990. long counter0 = context.RequestData.ReadInt64();
  991. long counter1 = context.RequestData.ReadInt64();
  992. // TODO: Determine if array<nn::sf::NativeHandle> is a buffer or not...
  993. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, counter0, counter1 });
  994. return ResultCode.Success;
  995. }
  996. [CommandHipc(307)] // 5.0.0+
  997. // FinalizeSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  998. public ResultCode FinalizeSevenSixAxisSensor(ServiceCtx context)
  999. {
  1000. long appletResourceUserId = context.RequestData.ReadInt64();
  1001. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1002. return ResultCode.Success;
  1003. }
  1004. [CommandHipc(308)] // 5.0.0+
  1005. // SetSevenSixAxisSensorFusionStrength(float Strength, nn::applet::AppletResourceUserId)
  1006. public ResultCode SetSevenSixAxisSensorFusionStrength(ServiceCtx context)
  1007. {
  1008. _sevenSixAxisSensorFusionStrength = context.RequestData.ReadSingle();
  1009. long appletResourceUserId = context.RequestData.ReadInt64();
  1010. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _sevenSixAxisSensorFusionStrength });
  1011. return ResultCode.Success;
  1012. }
  1013. [CommandHipc(309)] // 5.0.0+
  1014. // GetSevenSixAxisSensorFusionStrength(nn::applet::AppletResourceUserId) -> float Strength
  1015. public ResultCode GetSevenSixAxisSensorFusionStrength(ServiceCtx context)
  1016. {
  1017. long appletResourceUserId = context.RequestData.ReadInt64();
  1018. context.ResponseData.Write(_sevenSixAxisSensorFusionStrength);
  1019. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _sevenSixAxisSensorFusionStrength });
  1020. return ResultCode.Success;
  1021. }
  1022. [CommandHipc(310)] // 6.0.0+
  1023. // ResetSevenSixAxisSensorTimestamp(pid, nn::applet::AppletResourceUserId)
  1024. public ResultCode ResetSevenSixAxisSensorTimestamp(ServiceCtx context)
  1025. {
  1026. long appletResourceUserId = context.RequestData.ReadInt64();
  1027. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1028. return ResultCode.Success;
  1029. }
  1030. [CommandHipc(400)]
  1031. // IsUsbFullKeyControllerEnabled() -> bool IsEnabled
  1032. public ResultCode IsUsbFullKeyControllerEnabled(ServiceCtx context)
  1033. {
  1034. context.ResponseData.Write(_usbFullKeyControllerEnabled);
  1035. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _usbFullKeyControllerEnabled });
  1036. return ResultCode.Success;
  1037. }
  1038. [CommandHipc(401)]
  1039. // EnableUsbFullKeyController(bool Enable)
  1040. public ResultCode EnableUsbFullKeyController(ServiceCtx context)
  1041. {
  1042. _usbFullKeyControllerEnabled = context.RequestData.ReadBoolean();
  1043. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _usbFullKeyControllerEnabled });
  1044. return ResultCode.Success;
  1045. }
  1046. [CommandHipc(402)]
  1047. // IsUsbFullKeyControllerConnected(uint Unknown0) -> bool Connected
  1048. public ResultCode IsUsbFullKeyControllerConnected(ServiceCtx context)
  1049. {
  1050. int unknown0 = context.RequestData.ReadInt32();
  1051. context.ResponseData.Write(true); //FullKeyController is always connected ?
  1052. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { unknown0, Connected = true });
  1053. return ResultCode.Success;
  1054. }
  1055. [CommandHipc(403)] // 4.0.0+
  1056. // HasBattery(uint NpadId) -> bool HasBattery
  1057. public ResultCode HasBattery(ServiceCtx context)
  1058. {
  1059. int npadId = context.RequestData.ReadInt32();
  1060. context.ResponseData.Write(true); //Npad always got a battery ?
  1061. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, HasBattery = true });
  1062. return ResultCode.Success;
  1063. }
  1064. [CommandHipc(404)] // 4.0.0+
  1065. // HasLeftRightBattery(uint NpadId) -> bool HasLeftBattery, bool HasRightBattery
  1066. public ResultCode HasLeftRightBattery(ServiceCtx context)
  1067. {
  1068. int npadId = context.RequestData.ReadInt32();
  1069. context.ResponseData.Write(true); //Npad always got a left battery ?
  1070. context.ResponseData.Write(true); //Npad always got a right battery ?
  1071. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, HasLeftBattery = true, HasRightBattery = true });
  1072. return ResultCode.Success;
  1073. }
  1074. [CommandHipc(405)] // 4.0.0+
  1075. // GetNpadInterfaceType(uint NpadId) -> uchar InterfaceType
  1076. public ResultCode GetNpadInterfaceType(ServiceCtx context)
  1077. {
  1078. int npadId = context.RequestData.ReadInt32();
  1079. context.ResponseData.Write((byte)0);
  1080. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, NpadInterfaceType = 0 });
  1081. return ResultCode.Success;
  1082. }
  1083. [CommandHipc(406)] // 4.0.0+
  1084. // GetNpadLeftRightInterfaceType(uint NpadId) -> uchar LeftInterfaceType, uchar RightInterfaceType
  1085. public ResultCode GetNpadLeftRightInterfaceType(ServiceCtx context)
  1086. {
  1087. int npadId = context.RequestData.ReadInt32();
  1088. context.ResponseData.Write((byte)0);
  1089. context.ResponseData.Write((byte)0);
  1090. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, LeftInterfaceType = 0, RightInterfaceType = 0 });
  1091. return ResultCode.Success;
  1092. }
  1093. [CommandHipc(500)] // 5.0.0+
  1094. // GetPalmaConnectionHandle(uint Unknown0, nn::applet::AppletResourceUserId) -> nn::hid::PalmaConnectionHandle
  1095. public ResultCode GetPalmaConnectionHandle(ServiceCtx context)
  1096. {
  1097. int unknown0 = context.RequestData.ReadInt32();
  1098. long appletResourceUserId = context.RequestData.ReadInt64();
  1099. int palmaConnectionHandle = 0;
  1100. context.ResponseData.Write(palmaConnectionHandle);
  1101. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId , unknown0, palmaConnectionHandle });
  1102. return ResultCode.Success;
  1103. }
  1104. [CommandHipc(501)] // 5.0.0+
  1105. // InitializePalma(nn::hid::PalmaConnectionHandle)
  1106. public ResultCode InitializePalma(ServiceCtx context)
  1107. {
  1108. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1109. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1110. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1111. return ResultCode.Success;
  1112. }
  1113. [CommandHipc(502)] // 5.0.0+
  1114. // AcquirePalmaOperationCompleteEvent(nn::hid::PalmaConnectionHandle) -> nn::sf::NativeHandle
  1115. public ResultCode AcquirePalmaOperationCompleteEvent(ServiceCtx context)
  1116. {
  1117. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1118. if (context.Process.HandleTable.GenerateHandle(_palmaOperationCompleteEvent.ReadableEvent, out int handle) != KernelResult.Success)
  1119. {
  1120. throw new InvalidOperationException("Out of handles!");
  1121. }
  1122. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  1123. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1124. return ResultCode.Success;
  1125. }
  1126. [CommandHipc(503)] // 5.0.0+
  1127. // GetPalmaOperationInfo(nn::hid::PalmaConnectionHandle) -> long Unknown0, buffer<Unknown>
  1128. public ResultCode GetPalmaOperationInfo(ServiceCtx context)
  1129. {
  1130. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1131. long unknown0 = 0; //Counter?
  1132. context.ResponseData.Write(unknown0);
  1133. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0 });
  1134. return ResultCode.Success;
  1135. }
  1136. [CommandHipc(504)] // 5.0.0+
  1137. // PlayPalmaActivity(nn::hid::PalmaConnectionHandle, ulong Unknown0)
  1138. public ResultCode PlayPalmaActivity(ServiceCtx context)
  1139. {
  1140. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1141. long unknown0 = context.RequestData.ReadInt64();
  1142. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0 });
  1143. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1144. return ResultCode.Success;
  1145. }
  1146. [CommandHipc(505)] // 5.0.0+
  1147. // SetPalmaFrModeType(nn::hid::PalmaConnectionHandle, ulong FrModeType)
  1148. public ResultCode SetPalmaFrModeType(ServiceCtx context)
  1149. {
  1150. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1151. long frModeType = context.RequestData.ReadInt64();
  1152. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, frModeType });
  1153. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1154. return ResultCode.Success;
  1155. }
  1156. [CommandHipc(506)] // 5.0.0+
  1157. // ReadPalmaStep(nn::hid::PalmaConnectionHandle)
  1158. public ResultCode ReadPalmaStep(ServiceCtx context)
  1159. {
  1160. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1161. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1162. return ResultCode.Success;
  1163. }
  1164. [CommandHipc(507)] // 5.0.0+
  1165. // EnablePalmaStep(nn::hid::PalmaConnectionHandle, bool Enable)
  1166. public ResultCode EnablePalmaStep(ServiceCtx context)
  1167. {
  1168. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1169. bool enabledPalmaStep = context.RequestData.ReadBoolean();
  1170. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, enabledPalmaStep });
  1171. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1172. return ResultCode.Success;
  1173. }
  1174. [CommandHipc(508)] // 5.0.0+
  1175. // ResetPalmaStep(nn::hid::PalmaConnectionHandle)
  1176. public ResultCode ResetPalmaStep(ServiceCtx context)
  1177. {
  1178. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1179. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1180. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1181. return ResultCode.Success;
  1182. }
  1183. [CommandHipc(509)] // 5.0.0+
  1184. // ReadPalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1)
  1185. public ResultCode ReadPalmaApplicationSection(ServiceCtx context)
  1186. {
  1187. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1188. long unknown0 = context.RequestData.ReadInt64();
  1189. long unknown1 = context.RequestData.ReadInt64();
  1190. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0, unknown1 });
  1191. return ResultCode.Success;
  1192. }
  1193. [CommandHipc(510)] // 5.0.0+
  1194. // WritePalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1, nn::hid::PalmaApplicationSectionAccessBuffer)
  1195. public ResultCode WritePalmaApplicationSection(ServiceCtx context)
  1196. {
  1197. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1198. long unknown0 = context.RequestData.ReadInt64();
  1199. long unknown1 = context.RequestData.ReadInt64();
  1200. // nn::hid::PalmaApplicationSectionAccessBuffer cast is unknown
  1201. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0, unknown1 });
  1202. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1203. return ResultCode.Success;
  1204. }
  1205. [CommandHipc(511)] // 5.0.0+
  1206. // ReadPalmaUniqueCode(nn::hid::PalmaConnectionHandle)
  1207. public ResultCode ReadPalmaUniqueCode(ServiceCtx context)
  1208. {
  1209. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1210. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1211. return ResultCode.Success;
  1212. }
  1213. [CommandHipc(512)] // 5.0.0+
  1214. // SetPalmaUniqueCodeInvalid(nn::hid::PalmaConnectionHandle)
  1215. public ResultCode SetPalmaUniqueCodeInvalid(ServiceCtx context)
  1216. {
  1217. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1218. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1219. return ResultCode.Success;
  1220. }
  1221. [CommandHipc(522)] // 5.1.0+
  1222. // SetIsPalmaAllConnectable(nn::applet::AppletResourceUserId, bool, pid)
  1223. public ResultCode SetIsPalmaAllConnectable(ServiceCtx context)
  1224. {
  1225. long appletResourceUserId = context.RequestData.ReadInt64();
  1226. long unknownBool = context.RequestData.ReadInt64();
  1227. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknownBool });
  1228. return ResultCode.Success;
  1229. }
  1230. [CommandHipc(525)] // 5.1.0+
  1231. // SetPalmaBoostMode(bool)
  1232. public ResultCode SetPalmaBoostMode(ServiceCtx context)
  1233. {
  1234. // NOTE: Stubbed in system module.
  1235. return ResultCode.Success;
  1236. }
  1237. [CommandHipc(1000)]
  1238. // SetNpadCommunicationMode(long CommunicationMode, nn::applet::AppletResourceUserId)
  1239. public ResultCode SetNpadCommunicationMode(ServiceCtx context)
  1240. {
  1241. _npadCommunicationMode = context.RequestData.ReadInt64();
  1242. long appletResourceUserId = context.RequestData.ReadInt64();
  1243. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadCommunicationMode });
  1244. return ResultCode.Success;
  1245. }
  1246. [CommandHipc(1001)]
  1247. // GetNpadCommunicationMode() -> long CommunicationMode
  1248. public ResultCode GetNpadCommunicationMode(ServiceCtx context)
  1249. {
  1250. context.ResponseData.Write(_npadCommunicationMode);
  1251. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _npadCommunicationMode });
  1252. return ResultCode.Success;
  1253. }
  1254. [CommandHipc(1002)] // 9.0.0+
  1255. // SetTouchScreenConfiguration(nn::hid::TouchScreenConfigurationForNx, nn::applet::AppletResourceUserId)
  1256. public ResultCode SetTouchScreenConfiguration(ServiceCtx context)
  1257. {
  1258. long touchScreenConfigurationForNx = context.RequestData.ReadInt64();
  1259. long appletResourceUserId = context.RequestData.ReadInt64();
  1260. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, touchScreenConfigurationForNx });
  1261. return ResultCode.Success;
  1262. }
  1263. }
  1264. }