IHidServer.cs 72 KB

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