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. _vibrationPermitted = true;
  48. }
  49. [CommandHipc(0)]
  50. // CreateAppletResource(nn::applet::AppletResourceUserId) -> object<nn::hid::IAppletResource>
  51. public ResultCode CreateAppletResource(ServiceCtx context)
  52. {
  53. long appletResourceUserId = context.RequestData.ReadInt64();
  54. MakeObject(context, new IAppletResource(context.Device.System.HidSharedMem));
  55. return ResultCode.Success;
  56. }
  57. [CommandHipc(1)]
  58. // ActivateDebugPad(nn::applet::AppletResourceUserId)
  59. public ResultCode ActivateDebugPad(ServiceCtx context)
  60. {
  61. long appletResourceUserId = context.RequestData.ReadInt64();
  62. // Initialize entries to avoid issues with some games.
  63. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  64. {
  65. context.Device.Hid.DebugPad.Update();
  66. }
  67. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  68. return ResultCode.Success;
  69. }
  70. [CommandHipc(11)]
  71. // ActivateTouchScreen(nn::applet::AppletResourceUserId)
  72. public ResultCode ActivateTouchScreen(ServiceCtx context)
  73. {
  74. long appletResourceUserId = context.RequestData.ReadInt64();
  75. context.Device.Hid.Touchscreen.Active = true;
  76. // Initialize entries to avoid issues with some games.
  77. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  78. {
  79. context.Device.Hid.Touchscreen.Update();
  80. }
  81. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  82. return ResultCode.Success;
  83. }
  84. [CommandHipc(21)]
  85. // ActivateMouse(nn::applet::AppletResourceUserId)
  86. public ResultCode ActivateMouse(ServiceCtx context)
  87. {
  88. long appletResourceUserId = context.RequestData.ReadInt64();
  89. context.Device.Hid.Mouse.Active = true;
  90. // Initialize entries to avoid issues with some games.
  91. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  92. {
  93. context.Device.Hid.Mouse.Update(0, 0);
  94. }
  95. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  96. return ResultCode.Success;
  97. }
  98. [CommandHipc(31)]
  99. // ActivateKeyboard(nn::applet::AppletResourceUserId)
  100. public ResultCode ActivateKeyboard(ServiceCtx context)
  101. {
  102. long appletResourceUserId = context.RequestData.ReadInt64();
  103. context.Device.Hid.Keyboard.Active = true;
  104. // Initialize entries to avoid issues with some games.
  105. KeyboardInput emptyInput = new KeyboardInput();
  106. emptyInput.Keys = new ulong[4];
  107. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  108. {
  109. context.Device.Hid.Keyboard.Update(emptyInput);
  110. }
  111. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  112. return ResultCode.Success;
  113. }
  114. [CommandHipc(32)]
  115. // SendKeyboardLockKeyEvent(uint flags, pid)
  116. public ResultCode SendKeyboardLockKeyEvent(ServiceCtx context)
  117. {
  118. uint flags = context.RequestData.ReadUInt32();
  119. // NOTE: This signal the keyboard driver about lock events.
  120. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { flags });
  121. return ResultCode.Success;
  122. }
  123. [CommandHipc(40)]
  124. // AcquireXpadIdEventHandle(ulong XpadId) -> nn::sf::NativeHandle
  125. public ResultCode AcquireXpadIdEventHandle(ServiceCtx context)
  126. {
  127. long xpadId = context.RequestData.ReadInt64();
  128. if (context.Process.HandleTable.GenerateHandle(_xpadIdEvent.ReadableEvent, out _xpadIdEventHandle) != KernelResult.Success)
  129. {
  130. throw new InvalidOperationException("Out of handles!");
  131. }
  132. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_xpadIdEventHandle);
  133. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
  134. return ResultCode.Success;
  135. }
  136. [CommandHipc(41)]
  137. // ReleaseXpadIdEventHandle(ulong XpadId)
  138. public ResultCode ReleaseXpadIdEventHandle(ServiceCtx context)
  139. {
  140. long xpadId = context.RequestData.ReadInt64();
  141. context.Process.HandleTable.CloseHandle(_xpadIdEventHandle);
  142. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { xpadId });
  143. return ResultCode.Success;
  144. }
  145. [CommandHipc(51)]
  146. // ActivateXpad(nn::hid::BasicXpadId, nn::applet::AppletResourceUserId)
  147. public ResultCode ActivateXpad(ServiceCtx context)
  148. {
  149. int basicXpadId = context.RequestData.ReadInt32();
  150. long appletResourceUserId = context.RequestData.ReadInt64();
  151. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, basicXpadId });
  152. return ResultCode.Success;
  153. }
  154. [CommandHipc(55)]
  155. // GetXpadIds() -> long IdsCount, buffer<array<nn::hid::BasicXpadId>, type: 0xa>
  156. public ResultCode GetXpadIds(ServiceCtx context)
  157. {
  158. // There is any Xpad, so we return 0 and write nothing inside the type-0xa buffer.
  159. context.ResponseData.Write(0L);
  160. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  161. return ResultCode.Success;
  162. }
  163. [CommandHipc(56)]
  164. // ActivateJoyXpad(nn::hid::JoyXpadId)
  165. public ResultCode ActivateJoyXpad(ServiceCtx context)
  166. {
  167. int joyXpadId = context.RequestData.ReadInt32();
  168. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  169. return ResultCode.Success;
  170. }
  171. [CommandHipc(58)]
  172. // GetJoyXpadLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
  173. public ResultCode GetJoyXpadLifoHandle(ServiceCtx context)
  174. {
  175. int joyXpadId = context.RequestData.ReadInt32();
  176. int handle = 0;
  177. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  178. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  179. return ResultCode.Success;
  180. }
  181. [CommandHipc(59)]
  182. // GetJoyXpadIds() -> long IdsCount, buffer<array<nn::hid::JoyXpadId>, type: 0xa>
  183. public ResultCode GetJoyXpadIds(ServiceCtx context)
  184. {
  185. // There is any JoyXpad, so we return 0 and write nothing inside the type-0xa buffer.
  186. context.ResponseData.Write(0L);
  187. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  188. return ResultCode.Success;
  189. }
  190. [CommandHipc(60)]
  191. // ActivateSixAxisSensor(nn::hid::BasicXpadId)
  192. public ResultCode ActivateSixAxisSensor(ServiceCtx context)
  193. {
  194. int basicXpadId = context.RequestData.ReadInt32();
  195. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  196. return ResultCode.Success;
  197. }
  198. [CommandHipc(61)]
  199. // DeactivateSixAxisSensor(nn::hid::BasicXpadId)
  200. public ResultCode DeactivateSixAxisSensor(ServiceCtx context)
  201. {
  202. int basicXpadId = context.RequestData.ReadInt32();
  203. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  204. return ResultCode.Success;
  205. }
  206. [CommandHipc(62)]
  207. // GetSixAxisSensorLifoHandle(nn::hid::BasicXpadId) -> nn::sf::NativeHandle
  208. public ResultCode GetSixAxisSensorLifoHandle(ServiceCtx context)
  209. {
  210. int basicXpadId = context.RequestData.ReadInt32();
  211. int handle = 0;
  212. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  213. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { basicXpadId });
  214. return ResultCode.Success;
  215. }
  216. [CommandHipc(63)]
  217. // ActivateJoySixAxisSensor(nn::hid::JoyXpadId)
  218. public ResultCode ActivateJoySixAxisSensor(ServiceCtx context)
  219. {
  220. int joyXpadId = context.RequestData.ReadInt32();
  221. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  222. return ResultCode.Success;
  223. }
  224. [CommandHipc(64)]
  225. // DeactivateJoySixAxisSensor(nn::hid::JoyXpadId)
  226. public ResultCode DeactivateJoySixAxisSensor(ServiceCtx context)
  227. {
  228. int joyXpadId = context.RequestData.ReadInt32();
  229. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  230. return ResultCode.Success;
  231. }
  232. [CommandHipc(65)]
  233. // GetJoySixAxisSensorLifoHandle(nn::hid::JoyXpadId) -> nn::sf::NativeHandle
  234. public ResultCode GetJoySixAxisSensorLifoHandle(ServiceCtx context)
  235. {
  236. int joyXpadId = context.RequestData.ReadInt32();
  237. int handle = 0;
  238. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  239. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { joyXpadId });
  240. return ResultCode.Success;
  241. }
  242. [CommandHipc(66)]
  243. // StartSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  244. public ResultCode StartSixAxisSensor(ServiceCtx context)
  245. {
  246. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  247. long appletResourceUserId = context.RequestData.ReadInt64();
  248. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
  249. return ResultCode.Success;
  250. }
  251. [CommandHipc(67)]
  252. // StopSixAxisSensor(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  253. public ResultCode StopSixAxisSensor(ServiceCtx context)
  254. {
  255. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  256. long appletResourceUserId = context.RequestData.ReadInt64();
  257. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle });
  258. return ResultCode.Success;
  259. }
  260. [CommandHipc(68)]
  261. // IsSixAxisSensorFusionEnabled(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsEnabled
  262. public ResultCode IsSixAxisSensorFusionEnabled(ServiceCtx context)
  263. {
  264. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  265. long appletResourceUserId = context.RequestData.ReadInt64();
  266. context.ResponseData.Write(_sixAxisSensorFusionEnabled);
  267. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
  268. return ResultCode.Success;
  269. }
  270. [CommandHipc(69)]
  271. // EnableSixAxisSensorFusion(bool Enabled, nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  272. public ResultCode EnableSixAxisSensorFusion(ServiceCtx context)
  273. {
  274. _sixAxisSensorFusionEnabled = context.RequestData.ReadBoolean();
  275. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  276. long appletResourceUserId = context.RequestData.ReadInt64();
  277. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sixAxisSensorFusionEnabled });
  278. return ResultCode.Success;
  279. }
  280. [CommandHipc(70)]
  281. // SetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, float RevisePower, float ReviseRange, nn::applet::AppletResourceUserId)
  282. public ResultCode SetSixAxisSensorFusionParameters(ServiceCtx context)
  283. {
  284. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  285. _sensorFusionParams = new HidSensorFusionParameters
  286. {
  287. RevisePower = context.RequestData.ReadInt32(),
  288. ReviseRange = context.RequestData.ReadInt32()
  289. };
  290. long appletResourceUserId = context.RequestData.ReadInt64();
  291. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  292. return ResultCode.Success;
  293. }
  294. [CommandHipc(71)]
  295. // GetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float RevisePower, float ReviseRange)
  296. public ResultCode GetSixAxisSensorFusionParameters(ServiceCtx context)
  297. {
  298. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  299. long appletResourceUserId = context.RequestData.ReadInt64();
  300. context.ResponseData.Write(_sensorFusionParams.RevisePower);
  301. context.ResponseData.Write(_sensorFusionParams.ReviseRange);
  302. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  303. return ResultCode.Success;
  304. }
  305. [CommandHipc(72)]
  306. // ResetSixAxisSensorFusionParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  307. public ResultCode ResetSixAxisSensorFusionParameters(ServiceCtx context)
  308. {
  309. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  310. long appletResourceUserId = context.RequestData.ReadInt64();
  311. _sensorFusionParams.RevisePower = 0;
  312. _sensorFusionParams.ReviseRange = 0;
  313. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _sensorFusionParams.RevisePower, _sensorFusionParams.ReviseRange });
  314. return ResultCode.Success;
  315. }
  316. [CommandHipc(73)]
  317. // SetAccelerometerParameters(nn::hid::SixAxisSensorHandle, float X, float Y, nn::applet::AppletResourceUserId)
  318. public ResultCode SetAccelerometerParameters(ServiceCtx context)
  319. {
  320. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  321. _accelerometerParams = new HidAccelerometerParameters
  322. {
  323. X = context.RequestData.ReadInt32(),
  324. Y = context.RequestData.ReadInt32()
  325. };
  326. long appletResourceUserId = context.RequestData.ReadInt64();
  327. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  328. return ResultCode.Success;
  329. }
  330. [CommandHipc(74)]
  331. // GetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> float X, float Y
  332. public ResultCode GetAccelerometerParameters(ServiceCtx context)
  333. {
  334. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  335. long appletResourceUserId = context.RequestData.ReadInt64();
  336. context.ResponseData.Write(_accelerometerParams.X);
  337. context.ResponseData.Write(_accelerometerParams.Y);
  338. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  339. return ResultCode.Success;
  340. }
  341. [CommandHipc(75)]
  342. // ResetAccelerometerParameters(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  343. public ResultCode ResetAccelerometerParameters(ServiceCtx context)
  344. {
  345. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  346. long appletResourceUserId = context.RequestData.ReadInt64();
  347. _accelerometerParams.X = 0;
  348. _accelerometerParams.Y = 0;
  349. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerParams.X, _accelerometerParams.Y });
  350. return ResultCode.Success;
  351. }
  352. [CommandHipc(76)]
  353. // SetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, uint PlayMode, nn::applet::AppletResourceUserId)
  354. public ResultCode SetAccelerometerPlayMode(ServiceCtx context)
  355. {
  356. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  357. _accelerometerPlayMode = context.RequestData.ReadUInt32();
  358. long appletResourceUserId = context.RequestData.ReadInt64();
  359. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  360. return ResultCode.Success;
  361. }
  362. [CommandHipc(77)]
  363. // GetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> uint PlayMode
  364. public ResultCode GetAccelerometerPlayMode(ServiceCtx context)
  365. {
  366. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  367. long appletResourceUserId = context.RequestData.ReadInt64();
  368. context.ResponseData.Write(_accelerometerPlayMode);
  369. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  370. return ResultCode.Success;
  371. }
  372. [CommandHipc(78)]
  373. // ResetAccelerometerPlayMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  374. public ResultCode ResetAccelerometerPlayMode(ServiceCtx context)
  375. {
  376. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  377. long appletResourceUserId = context.RequestData.ReadInt64();
  378. _accelerometerPlayMode = 0;
  379. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _accelerometerPlayMode });
  380. return ResultCode.Success;
  381. }
  382. [CommandHipc(79)]
  383. // SetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, uint GyroscopeZeroDriftMode, nn::applet::AppletResourceUserId)
  384. public ResultCode SetGyroscopeZeroDriftMode(ServiceCtx context)
  385. {
  386. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  387. _gyroscopeZeroDriftMode = (HidGyroscopeZeroDriftMode)context.RequestData.ReadInt32();
  388. long appletResourceUserId = context.RequestData.ReadInt64();
  389. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  390. return ResultCode.Success;
  391. }
  392. [CommandHipc(80)]
  393. // GetGyroscopeZeroDriftMode(nn::applet::AppletResourceUserId, nn::hid::SixAxisSensorHandle) -> int GyroscopeZeroDriftMode
  394. public ResultCode GetGyroscopeZeroDriftMode(ServiceCtx context)
  395. {
  396. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  397. long appletResourceUserId = context.RequestData.ReadInt64();
  398. context.ResponseData.Write((int)_gyroscopeZeroDriftMode);
  399. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  400. return ResultCode.Success;
  401. }
  402. [CommandHipc(81)]
  403. // ResetGyroscopeZeroDriftMode(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId)
  404. public ResultCode ResetGyroscopeZeroDriftMode(ServiceCtx context)
  405. {
  406. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  407. long appletResourceUserId = context.RequestData.ReadInt64();
  408. _gyroscopeZeroDriftMode = HidGyroscopeZeroDriftMode.Standard;
  409. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _gyroscopeZeroDriftMode });
  410. return ResultCode.Success;
  411. }
  412. [CommandHipc(82)]
  413. // IsSixAxisSensorAtRest(nn::hid::SixAxisSensorHandle, nn::applet::AppletResourceUserId) -> bool IsAsRest
  414. public ResultCode IsSixAxisSensorAtRest(ServiceCtx context)
  415. {
  416. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  417. long appletResourceUserId = context.RequestData.ReadInt64();
  418. bool isAtRest = true;
  419. context.ResponseData.Write(isAtRest);
  420. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, isAtRest });
  421. return ResultCode.Success;
  422. }
  423. [CommandHipc(83)] // 6.0.0+
  424. // IsFirmwareUpdateAvailableForSixAxisSensor(nn::hid::AppletResourceUserId, nn::hid::SixAxisSensorHandle, pid) -> bool UpdateAvailable
  425. public ResultCode IsFirmwareUpdateAvailableForSixAxisSensor(ServiceCtx context)
  426. {
  427. int sixAxisSensorHandle = context.RequestData.ReadInt32();
  428. context.RequestData.BaseStream.Position += 4;
  429. long appletResourceUserId = context.RequestData.ReadInt64();
  430. context.ResponseData.Write(_isFirmwareUpdateAvailableForSixAxisSensor);
  431. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, sixAxisSensorHandle, _isFirmwareUpdateAvailableForSixAxisSensor });
  432. return ResultCode.Success;
  433. }
  434. [CommandHipc(91)]
  435. // ActivateGesture(nn::applet::AppletResourceUserId, int Unknown0)
  436. public ResultCode ActivateGesture(ServiceCtx context)
  437. {
  438. long appletResourceUserId = context.RequestData.ReadInt64();
  439. int unknown0 = context.RequestData.ReadInt32();
  440. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0 });
  441. return ResultCode.Success;
  442. }
  443. [CommandHipc(100)]
  444. // SetSupportedNpadStyleSet(nn::applet::AppletResourceUserId, nn::hid::NpadStyleTag)
  445. public ResultCode SetSupportedNpadStyleSet(ServiceCtx context)
  446. {
  447. ControllerType type = (ControllerType)context.RequestData.ReadInt32();
  448. long appletResourceUserId = context.RequestData.ReadInt64();
  449. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  450. appletResourceUserId,
  451. type
  452. });
  453. context.Device.Hid.Npads.SupportedStyleSets = type;
  454. return ResultCode.Success;
  455. }
  456. [CommandHipc(101)]
  457. // GetSupportedNpadStyleSet(nn::applet::AppletResourceUserId) -> uint nn::hid::NpadStyleTag
  458. public ResultCode GetSupportedNpadStyleSet(ServiceCtx context)
  459. {
  460. long appletResourceUserId = context.RequestData.ReadInt64();
  461. context.ResponseData.Write((int)context.Device.Hid.Npads.SupportedStyleSets);
  462. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  463. appletResourceUserId,
  464. context.Device.Hid.Npads.SupportedStyleSets
  465. });
  466. return ResultCode.Success;
  467. }
  468. [CommandHipc(102)]
  469. // SetSupportedNpadIdType(nn::applet::AppletResourceUserId, array<NpadIdType, 9>)
  470. public ResultCode SetSupportedNpadIdType(ServiceCtx context)
  471. {
  472. long appletResourceUserId = context.RequestData.ReadInt64();
  473. ulong arrayPosition = context.Request.PtrBuff[0].Position;
  474. ulong arraySize = context.Request.PtrBuff[0].Size;
  475. ReadOnlySpan<NpadIdType> supportedPlayerIds = MemoryMarshal.Cast<byte, NpadIdType>(context.Memory.GetSpan(arrayPosition, (int)arraySize));
  476. context.Device.Hid.Npads.ClearSupportedPlayers();
  477. for (int i = 0; i < supportedPlayerIds.Length; ++i)
  478. {
  479. if (supportedPlayerIds[i] >= 0)
  480. {
  481. context.Device.Hid.Npads.SetSupportedPlayer(HidUtils.GetIndexFromNpadIdType(supportedPlayerIds[i]));
  482. }
  483. }
  484. Logger.Stub?.PrintStub(LogClass.ServiceHid, $"{supportedPlayerIds.Length} " + string.Join(",", supportedPlayerIds.ToArray()));
  485. return ResultCode.Success;
  486. }
  487. [CommandHipc(103)]
  488. // ActivateNpad(nn::applet::AppletResourceUserId)
  489. public ResultCode ActivateNpad(ServiceCtx context)
  490. {
  491. return ActiveNpadImpl(context);
  492. }
  493. [CommandHipc(104)]
  494. // DeactivateNpad(nn::applet::AppletResourceUserId)
  495. public ResultCode DeactivateNpad(ServiceCtx context)
  496. {
  497. long appletResourceUserId = context.RequestData.ReadInt64();
  498. context.Device.Hid.Npads.Active = false;
  499. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  500. return ResultCode.Success;
  501. }
  502. [CommandHipc(106)]
  503. // AcquireNpadStyleSetUpdateEventHandle(nn::applet::AppletResourceUserId, uint, ulong) -> nn::sf::NativeHandle
  504. public ResultCode AcquireNpadStyleSetUpdateEventHandle(ServiceCtx context)
  505. {
  506. PlayerIndex npadId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
  507. long appletResourceUserId = context.RequestData.ReadInt64();
  508. long npadStyleSet = context.RequestData.ReadInt64();
  509. KEvent evnt = context.Device.Hid.Npads.GetStyleSetUpdateEvent(npadId);
  510. if (context.Process.HandleTable.GenerateHandle(evnt.ReadableEvent, out int handle) != KernelResult.Success)
  511. {
  512. throw new InvalidOperationException("Out of handles!");
  513. }
  514. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  515. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadId, npadStyleSet });
  516. return ResultCode.Success;
  517. }
  518. [CommandHipc(107)]
  519. // DisconnectNpad(nn::applet::AppletResourceUserId, uint NpadIdType)
  520. public ResultCode DisconnectNpad(ServiceCtx context)
  521. {
  522. NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
  523. long appletResourceUserId = context.RequestData.ReadInt64();
  524. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType });
  525. return ResultCode.Success;
  526. }
  527. [CommandHipc(108)]
  528. // GetPlayerLedPattern(u32 npad_id) -> u64 led_pattern
  529. public ResultCode GetPlayerLedPattern(ServiceCtx context)
  530. {
  531. NpadIdType npadId = (NpadIdType)context.RequestData.ReadUInt32();
  532. ulong ledPattern = npadId switch
  533. {
  534. NpadIdType.Player1 => 0b0001,
  535. NpadIdType.Player2 => 0b0011,
  536. NpadIdType.Player3 => 0b0111,
  537. NpadIdType.Player4 => 0b1111,
  538. NpadIdType.Player5 => 0b1001,
  539. NpadIdType.Player6 => 0b0101,
  540. NpadIdType.Player7 => 0b1101,
  541. NpadIdType.Player8 => 0b0110,
  542. NpadIdType.Unknown => 0b0000,
  543. NpadIdType.Handheld => 0b0000,
  544. _ => throw new ArgumentOutOfRangeException(nameof(npadId))
  545. };
  546. context.ResponseData.Write(ledPattern);
  547. return ResultCode.Success;
  548. }
  549. [CommandHipc(109)] // 5.0.0+
  550. // ActivateNpadWithRevision(nn::applet::AppletResourceUserId, ulong revision)
  551. public ResultCode ActivateNpadWithRevision(ServiceCtx context)
  552. {
  553. ulong revision = context.RequestData.ReadUInt64();
  554. return ActiveNpadImpl(context, revision);
  555. }
  556. private ResultCode ActiveNpadImpl(ServiceCtx context, ulong revision = 0)
  557. {
  558. long appletResourceUserId = context.RequestData.ReadInt64();
  559. context.Device.Hid.Npads.Active = true;
  560. // Initialize entries to avoid issues with some games.
  561. List<GamepadInput> emptyGamepadInputs = new List<GamepadInput>();
  562. List<SixAxisInput> emptySixAxisInputs = new List<SixAxisInput>();
  563. for (int player = 0; player < NpadDevices.MaxControllers; player++)
  564. {
  565. GamepadInput gamepadInput = new GamepadInput();
  566. SixAxisInput sixaxisInput = new SixAxisInput();
  567. gamepadInput.PlayerId = (PlayerIndex)player;
  568. sixaxisInput.PlayerId = (PlayerIndex)player;
  569. sixaxisInput.Orientation = new float[9];
  570. emptyGamepadInputs.Add(gamepadInput);
  571. emptySixAxisInputs.Add(sixaxisInput);
  572. }
  573. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  574. {
  575. context.Device.Hid.Npads.Update(emptyGamepadInputs);
  576. context.Device.Hid.Npads.UpdateSixAxis(emptySixAxisInputs);
  577. }
  578. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, revision });
  579. return ResultCode.Success;
  580. }
  581. [CommandHipc(120)]
  582. // SetNpadJoyHoldType(nn::applet::AppletResourceUserId, ulong NpadJoyHoldType)
  583. public ResultCode SetNpadJoyHoldType(ServiceCtx context)
  584. {
  585. long appletResourceUserId = context.RequestData.ReadInt64();
  586. NpadJoyHoldType npadJoyHoldType = (NpadJoyHoldType)context.RequestData.ReadUInt64();
  587. if (npadJoyHoldType > NpadJoyHoldType.Horizontal)
  588. {
  589. throw new ArgumentOutOfRangeException(nameof(npadJoyHoldType));
  590. }
  591. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  592. {
  593. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  594. {
  595. return ResultCode.InvalidNpadIdType;
  596. }
  597. }
  598. context.Device.Hid.Npads.JoyHold = npadJoyHoldType;
  599. return ResultCode.Success;
  600. }
  601. [CommandHipc(121)]
  602. // GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> ulong NpadJoyHoldType
  603. public ResultCode GetNpadJoyHoldType(ServiceCtx context)
  604. {
  605. long appletResourceUserId = context.RequestData.ReadInt64();
  606. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  607. {
  608. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  609. {
  610. return ResultCode.InvalidNpadIdType;
  611. }
  612. }
  613. context.ResponseData.Write((ulong)context.Device.Hid.Npads.JoyHold);
  614. return ResultCode.Success;
  615. }
  616. [CommandHipc(122)]
  617. // SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId)
  618. public ResultCode SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context)
  619. {
  620. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  621. long appletResourceUserId = context.RequestData.ReadInt64();
  622. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  623. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  624. return ResultCode.Success;
  625. }
  626. [CommandHipc(123)]
  627. // SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType)
  628. public ResultCode SetNpadJoyAssignmentModeSingle(ServiceCtx context)
  629. {
  630. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  631. long appletResourceUserId = context.RequestData.ReadInt64();
  632. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  633. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  634. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, hidNpadJoyDeviceType, _npadJoyAssignmentMode });
  635. return ResultCode.Success;
  636. }
  637. [CommandHipc(124)]
  638. // SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId)
  639. public ResultCode SetNpadJoyAssignmentModeDual(ServiceCtx context)
  640. {
  641. PlayerIndex hidControllerId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
  642. long appletResourceUserId = context.RequestData.ReadInt64();
  643. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
  644. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  645. return ResultCode.Success;
  646. }
  647. [CommandHipc(125)]
  648. // MergeSingleJoyAsDualJoy(uint SingleJoyId0, uint SingleJoyId1, nn::applet::AppletResourceUserId)
  649. public ResultCode MergeSingleJoyAsDualJoy(ServiceCtx context)
  650. {
  651. long singleJoyId0 = context.RequestData.ReadInt32();
  652. long singleJoyId1 = context.RequestData.ReadInt32();
  653. long appletResourceUserId = context.RequestData.ReadInt64();
  654. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, singleJoyId0, singleJoyId1 });
  655. return ResultCode.Success;
  656. }
  657. [CommandHipc(126)]
  658. // StartLrAssignmentMode(nn::applet::AppletResourceUserId)
  659. public ResultCode StartLrAssignmentMode(ServiceCtx context)
  660. {
  661. long appletResourceUserId = context.RequestData.ReadInt64();
  662. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  663. return ResultCode.Success;
  664. }
  665. [CommandHipc(127)]
  666. // StopLrAssignmentMode(nn::applet::AppletResourceUserId)
  667. public ResultCode StopLrAssignmentMode(ServiceCtx context)
  668. {
  669. long appletResourceUserId = context.RequestData.ReadInt64();
  670. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  671. return ResultCode.Success;
  672. }
  673. [CommandHipc(128)]
  674. // SetNpadHandheldActivationMode(nn::applet::AppletResourceUserId, long HidNpadHandheldActivationMode)
  675. public ResultCode SetNpadHandheldActivationMode(ServiceCtx context)
  676. {
  677. long appletResourceUserId = context.RequestData.ReadInt64();
  678. _npadHandheldActivationMode = (HidNpadHandheldActivationMode)context.RequestData.ReadInt64();
  679. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  680. return ResultCode.Success;
  681. }
  682. [CommandHipc(129)]
  683. // GetNpadHandheldActivationMode(nn::applet::AppletResourceUserId) -> long HidNpadHandheldActivationMode
  684. public ResultCode GetNpadHandheldActivationMode(ServiceCtx context)
  685. {
  686. long appletResourceUserId = context.RequestData.ReadInt64();
  687. context.ResponseData.Write((long)_npadHandheldActivationMode);
  688. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  689. return ResultCode.Success;
  690. }
  691. [CommandHipc(130)]
  692. // SwapNpadAssignment(uint OldNpadAssignment, uint NewNpadAssignment, nn::applet::AppletResourceUserId)
  693. public ResultCode SwapNpadAssignment(ServiceCtx context)
  694. {
  695. int oldNpadAssignment = context.RequestData.ReadInt32();
  696. int newNpadAssignment = context.RequestData.ReadInt32();
  697. long appletResourceUserId = context.RequestData.ReadInt64();
  698. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, oldNpadAssignment, newNpadAssignment });
  699. return ResultCode.Success;
  700. }
  701. [CommandHipc(131)]
  702. // IsUnintendedHomeButtonInputProtectionEnabled(uint Unknown0, nn::applet::AppletResourceUserId) -> bool IsEnabled
  703. public ResultCode IsUnintendedHomeButtonInputProtectionEnabled(ServiceCtx context)
  704. {
  705. uint unknown0 = context.RequestData.ReadUInt32();
  706. long appletResourceUserId = context.RequestData.ReadInt64();
  707. context.ResponseData.Write(_unintendedHomeButtonInputProtectionEnabled);
  708. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  709. return ResultCode.Success;
  710. }
  711. [CommandHipc(132)]
  712. // EnableUnintendedHomeButtonInputProtection(bool Enable, uint Unknown0, nn::applet::AppletResourceUserId)
  713. public ResultCode EnableUnintendedHomeButtonInputProtection(ServiceCtx context)
  714. {
  715. _unintendedHomeButtonInputProtectionEnabled = context.RequestData.ReadBoolean();
  716. uint unknown0 = context.RequestData.ReadUInt32();
  717. long appletResourceUserId = context.RequestData.ReadInt64();
  718. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  719. return ResultCode.Success;
  720. }
  721. [CommandHipc(133)] // 5.0.0+
  722. // SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1
  723. public ResultCode SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context)
  724. {
  725. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  726. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  727. long appletResourceUserId = context.RequestData.ReadInt64();
  728. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  729. context.ResponseData.Write(0); //Unknown0
  730. context.ResponseData.Write(0); //Unknown1
  731. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  732. appletResourceUserId,
  733. hidControllerId,
  734. hidNpadJoyDeviceType,
  735. _npadJoyAssignmentMode,
  736. Unknown0 = 0,
  737. Unknown1 = 0
  738. });
  739. return ResultCode.Success;
  740. }
  741. [CommandHipc(200)]
  742. // GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo
  743. public ResultCode GetVibrationDeviceInfo(ServiceCtx context)
  744. {
  745. HidVibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct<HidVibrationDeviceHandle>();
  746. NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType;
  747. NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId;
  748. if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
  749. {
  750. if (npadIdType >= (NpadIdType.Player8 + 1) && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
  751. {
  752. return ResultCode.InvalidNpadIdType;
  753. }
  754. if (deviceHandle.Position > 1)
  755. {
  756. return ResultCode.InvalidDeviceIndex;
  757. }
  758. HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None;
  759. if (Enum.IsDefined(typeof(NpadStyleIndex), deviceType))
  760. {
  761. vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator;
  762. }
  763. else if ((uint)deviceType == 8)
  764. {
  765. vibrationDeviceType = HidVibrationDeviceType.GcErm;
  766. }
  767. HidVibrationDevicePosition vibrationDevicePosition = HidVibrationDevicePosition.None;
  768. if (vibrationDeviceType == HidVibrationDeviceType.LinearResonantActuator)
  769. {
  770. if (deviceHandle.Position == 0)
  771. {
  772. vibrationDevicePosition = HidVibrationDevicePosition.Left;
  773. }
  774. else if (deviceHandle.Position == 1)
  775. {
  776. vibrationDevicePosition = HidVibrationDevicePosition.Right;
  777. }
  778. else
  779. {
  780. throw new ArgumentOutOfRangeException(nameof(deviceHandle.Position));
  781. }
  782. }
  783. HidVibrationDeviceValue deviceInfo = new HidVibrationDeviceValue
  784. {
  785. DeviceType = vibrationDeviceType,
  786. Position = vibrationDevicePosition
  787. };
  788. context.ResponseData.WriteStruct(deviceInfo);
  789. return ResultCode.Success;
  790. }
  791. return ResultCode.InvalidNpadDeviceType;
  792. }
  793. [CommandHipc(201)]
  794. // SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId)
  795. public ResultCode SendVibrationValue(ServiceCtx context)
  796. {
  797. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  798. {
  799. DeviceType = context.RequestData.ReadByte(),
  800. PlayerId = context.RequestData.ReadByte(),
  801. Position = context.RequestData.ReadByte(),
  802. Reserved = context.RequestData.ReadByte()
  803. };
  804. HidVibrationValue vibrationValue = new HidVibrationValue
  805. {
  806. AmplitudeLow = context.RequestData.ReadSingle(),
  807. FrequencyLow = context.RequestData.ReadSingle(),
  808. AmplitudeHigh = context.RequestData.ReadSingle(),
  809. FrequencyHigh = context.RequestData.ReadSingle()
  810. };
  811. long appletResourceUserId = context.RequestData.ReadInt64();
  812. Dictionary<byte, HidVibrationValue> dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  813. dualVibrationValues[deviceHandle.Position] = vibrationValue;
  814. context.Device.Hid.Npads.UpdateRumbleQueue((PlayerIndex)deviceHandle.PlayerId, dualVibrationValues);
  815. return ResultCode.Success;
  816. }
  817. [CommandHipc(202)]
  818. // GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue
  819. public ResultCode GetActualVibrationValue(ServiceCtx context)
  820. {
  821. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  822. {
  823. DeviceType = context.RequestData.ReadByte(),
  824. PlayerId = context.RequestData.ReadByte(),
  825. Position = context.RequestData.ReadByte(),
  826. Reserved = context.RequestData.ReadByte()
  827. };
  828. long appletResourceUserId = context.RequestData.ReadInt64();
  829. HidVibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position);
  830. context.ResponseData.Write(vibrationValue.AmplitudeLow);
  831. context.ResponseData.Write(vibrationValue.FrequencyLow);
  832. context.ResponseData.Write(vibrationValue.AmplitudeHigh);
  833. context.ResponseData.Write(vibrationValue.FrequencyHigh);
  834. return ResultCode.Success;
  835. }
  836. [CommandHipc(203)]
  837. // CreateActiveVibrationDeviceList() -> object<nn::hid::IActiveVibrationDeviceList>
  838. public ResultCode CreateActiveVibrationDeviceList(ServiceCtx context)
  839. {
  840. MakeObject(context, new IActiveApplicationDeviceList());
  841. return ResultCode.Success;
  842. }
  843. [CommandHipc(204)]
  844. // PermitVibration(bool Enable)
  845. public ResultCode PermitVibration(ServiceCtx context)
  846. {
  847. _vibrationPermitted = context.RequestData.ReadBoolean();
  848. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
  849. return ResultCode.Success;
  850. }
  851. [CommandHipc(205)]
  852. // IsVibrationPermitted() -> bool IsEnabled
  853. public ResultCode IsVibrationPermitted(ServiceCtx context)
  854. {
  855. context.ResponseData.Write(_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. }