IHidServer.cs 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782
  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. // Games expect this event to be signaled after calling this function
  571. evnt.ReadableEvent.Signal();
  572. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  573. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadId, npadStyleSet });
  574. return ResultCode.Success;
  575. }
  576. [CommandHipc(107)]
  577. // DisconnectNpad(nn::applet::AppletResourceUserId, uint NpadIdType)
  578. public ResultCode DisconnectNpad(ServiceCtx context)
  579. {
  580. NpadIdType npadIdType = (NpadIdType)context.RequestData.ReadInt32();
  581. long appletResourceUserId = context.RequestData.ReadInt64();
  582. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, npadIdType });
  583. return ResultCode.Success;
  584. }
  585. [CommandHipc(108)]
  586. // GetPlayerLedPattern(u32 npad_id) -> u64 led_pattern
  587. public ResultCode GetPlayerLedPattern(ServiceCtx context)
  588. {
  589. NpadIdType npadId = (NpadIdType)context.RequestData.ReadUInt32();
  590. ulong ledPattern = npadId switch
  591. {
  592. NpadIdType.Player1 => 0b0001,
  593. NpadIdType.Player2 => 0b0011,
  594. NpadIdType.Player3 => 0b0111,
  595. NpadIdType.Player4 => 0b1111,
  596. NpadIdType.Player5 => 0b1001,
  597. NpadIdType.Player6 => 0b0101,
  598. NpadIdType.Player7 => 0b1101,
  599. NpadIdType.Player8 => 0b0110,
  600. NpadIdType.Unknown => 0b0000,
  601. NpadIdType.Handheld => 0b0000,
  602. _ => throw new ArgumentOutOfRangeException(nameof(npadId))
  603. };
  604. context.ResponseData.Write(ledPattern);
  605. return ResultCode.Success;
  606. }
  607. [CommandHipc(109)] // 5.0.0+
  608. // ActivateNpadWithRevision(nn::applet::AppletResourceUserId, ulong revision)
  609. public ResultCode ActivateNpadWithRevision(ServiceCtx context)
  610. {
  611. ulong revision = context.RequestData.ReadUInt64();
  612. return ActiveNpadImpl(context, revision);
  613. }
  614. private ResultCode ActiveNpadImpl(ServiceCtx context, ulong revision = 0)
  615. {
  616. long appletResourceUserId = context.RequestData.ReadInt64();
  617. context.Device.Hid.Npads.Active = true;
  618. // Initialize entries to avoid issues with some games.
  619. List<GamepadInput> emptyGamepadInputs = new List<GamepadInput>();
  620. List<SixAxisInput> emptySixAxisInputs = new List<SixAxisInput>();
  621. for (int player = 0; player < NpadDevices.MaxControllers; player++)
  622. {
  623. GamepadInput gamepadInput = new GamepadInput();
  624. SixAxisInput sixaxisInput = new SixAxisInput();
  625. gamepadInput.PlayerId = (PlayerIndex)player;
  626. sixaxisInput.PlayerId = (PlayerIndex)player;
  627. sixaxisInput.Orientation = new float[9];
  628. emptyGamepadInputs.Add(gamepadInput);
  629. emptySixAxisInputs.Add(sixaxisInput);
  630. }
  631. for (int entry = 0; entry < Hid.SharedMemEntryCount; entry++)
  632. {
  633. context.Device.Hid.Npads.Update(emptyGamepadInputs);
  634. context.Device.Hid.Npads.UpdateSixAxis(emptySixAxisInputs);
  635. }
  636. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, revision });
  637. return ResultCode.Success;
  638. }
  639. [CommandHipc(120)]
  640. // SetNpadJoyHoldType(nn::applet::AppletResourceUserId, ulong NpadJoyHoldType)
  641. public ResultCode SetNpadJoyHoldType(ServiceCtx context)
  642. {
  643. long appletResourceUserId = context.RequestData.ReadInt64();
  644. NpadJoyHoldType npadJoyHoldType = (NpadJoyHoldType)context.RequestData.ReadUInt64();
  645. if (npadJoyHoldType > NpadJoyHoldType.Horizontal)
  646. {
  647. throw new ArgumentOutOfRangeException(nameof(npadJoyHoldType));
  648. }
  649. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  650. {
  651. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  652. {
  653. return ResultCode.InvalidNpadIdType;
  654. }
  655. }
  656. context.Device.Hid.Npads.JoyHold = npadJoyHoldType;
  657. return ResultCode.Success;
  658. }
  659. [CommandHipc(121)]
  660. // GetNpadJoyHoldType(nn::applet::AppletResourceUserId) -> ulong NpadJoyHoldType
  661. public ResultCode GetNpadJoyHoldType(ServiceCtx context)
  662. {
  663. long appletResourceUserId = context.RequestData.ReadInt64();
  664. foreach (PlayerIndex playerIndex in context.Device.Hid.Npads.GetSupportedPlayers())
  665. {
  666. if (HidUtils.GetNpadIdTypeFromIndex(playerIndex) > NpadIdType.Handheld)
  667. {
  668. return ResultCode.InvalidNpadIdType;
  669. }
  670. }
  671. context.ResponseData.Write((ulong)context.Device.Hid.Npads.JoyHold);
  672. return ResultCode.Success;
  673. }
  674. [CommandHipc(122)]
  675. // SetNpadJoyAssignmentModeSingleByDefault(uint HidControllerId, nn::applet::AppletResourceUserId)
  676. public ResultCode SetNpadJoyAssignmentModeSingleByDefault(ServiceCtx context)
  677. {
  678. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  679. long appletResourceUserId = context.RequestData.ReadInt64();
  680. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  681. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  682. return ResultCode.Success;
  683. }
  684. [CommandHipc(123)]
  685. // SetNpadJoyAssignmentModeSingle(uint HidControllerId, nn::applet::AppletResourceUserId, long HidNpadJoyDeviceType)
  686. public ResultCode SetNpadJoyAssignmentModeSingle(ServiceCtx context)
  687. {
  688. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  689. long appletResourceUserId = context.RequestData.ReadInt64();
  690. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  691. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  692. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, hidNpadJoyDeviceType, _npadJoyAssignmentMode });
  693. return ResultCode.Success;
  694. }
  695. [CommandHipc(124)]
  696. // SetNpadJoyAssignmentModeDual(uint HidControllerId, nn::applet::AppletResourceUserId)
  697. public ResultCode SetNpadJoyAssignmentModeDual(ServiceCtx context)
  698. {
  699. PlayerIndex hidControllerId = HidUtils.GetIndexFromNpadIdType((NpadIdType)context.RequestData.ReadInt32());
  700. long appletResourceUserId = context.RequestData.ReadInt64();
  701. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Dual;
  702. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, hidControllerId, _npadJoyAssignmentMode });
  703. return ResultCode.Success;
  704. }
  705. [CommandHipc(125)]
  706. // MergeSingleJoyAsDualJoy(uint SingleJoyId0, uint SingleJoyId1, nn::applet::AppletResourceUserId)
  707. public ResultCode MergeSingleJoyAsDualJoy(ServiceCtx context)
  708. {
  709. long singleJoyId0 = context.RequestData.ReadInt32();
  710. long singleJoyId1 = context.RequestData.ReadInt32();
  711. long appletResourceUserId = context.RequestData.ReadInt64();
  712. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, singleJoyId0, singleJoyId1 });
  713. return ResultCode.Success;
  714. }
  715. [CommandHipc(126)]
  716. // StartLrAssignmentMode(nn::applet::AppletResourceUserId)
  717. public ResultCode StartLrAssignmentMode(ServiceCtx context)
  718. {
  719. long appletResourceUserId = context.RequestData.ReadInt64();
  720. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  721. return ResultCode.Success;
  722. }
  723. [CommandHipc(127)]
  724. // StopLrAssignmentMode(nn::applet::AppletResourceUserId)
  725. public ResultCode StopLrAssignmentMode(ServiceCtx context)
  726. {
  727. long appletResourceUserId = context.RequestData.ReadInt64();
  728. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  729. return ResultCode.Success;
  730. }
  731. [CommandHipc(128)]
  732. // SetNpadHandheldActivationMode(nn::applet::AppletResourceUserId, long HidNpadHandheldActivationMode)
  733. public ResultCode SetNpadHandheldActivationMode(ServiceCtx context)
  734. {
  735. long appletResourceUserId = context.RequestData.ReadInt64();
  736. _npadHandheldActivationMode = (HidNpadHandheldActivationMode)context.RequestData.ReadInt64();
  737. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  738. return ResultCode.Success;
  739. }
  740. [CommandHipc(129)]
  741. // GetNpadHandheldActivationMode(nn::applet::AppletResourceUserId) -> long HidNpadHandheldActivationMode
  742. public ResultCode GetNpadHandheldActivationMode(ServiceCtx context)
  743. {
  744. long appletResourceUserId = context.RequestData.ReadInt64();
  745. context.ResponseData.Write((long)_npadHandheldActivationMode);
  746. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadHandheldActivationMode });
  747. return ResultCode.Success;
  748. }
  749. [CommandHipc(130)]
  750. // SwapNpadAssignment(uint OldNpadAssignment, uint NewNpadAssignment, nn::applet::AppletResourceUserId)
  751. public ResultCode SwapNpadAssignment(ServiceCtx context)
  752. {
  753. int oldNpadAssignment = context.RequestData.ReadInt32();
  754. int newNpadAssignment = context.RequestData.ReadInt32();
  755. long appletResourceUserId = context.RequestData.ReadInt64();
  756. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, oldNpadAssignment, newNpadAssignment });
  757. return ResultCode.Success;
  758. }
  759. [CommandHipc(131)]
  760. // IsUnintendedHomeButtonInputProtectionEnabled(uint Unknown0, nn::applet::AppletResourceUserId) -> bool IsEnabled
  761. public ResultCode IsUnintendedHomeButtonInputProtectionEnabled(ServiceCtx context)
  762. {
  763. uint unknown0 = context.RequestData.ReadUInt32();
  764. long appletResourceUserId = context.RequestData.ReadInt64();
  765. context.ResponseData.Write(_unintendedHomeButtonInputProtectionEnabled);
  766. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  767. return ResultCode.Success;
  768. }
  769. [CommandHipc(132)]
  770. // EnableUnintendedHomeButtonInputProtection(bool Enable, uint Unknown0, nn::applet::AppletResourceUserId)
  771. public ResultCode EnableUnintendedHomeButtonInputProtection(ServiceCtx context)
  772. {
  773. _unintendedHomeButtonInputProtectionEnabled = context.RequestData.ReadBoolean();
  774. uint unknown0 = context.RequestData.ReadUInt32();
  775. long appletResourceUserId = context.RequestData.ReadInt64();
  776. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknown0, _unintendedHomeButtonInputProtectionEnabled });
  777. return ResultCode.Success;
  778. }
  779. [CommandHipc(133)] // 5.0.0+
  780. // SetNpadJoyAssignmentModeSingleWithDestination(uint HidControllerId, long HidNpadJoyDeviceType, nn::applet::AppletResourceUserId) -> bool Unknown0, uint Unknown1
  781. public ResultCode SetNpadJoyAssignmentModeSingleWithDestination(ServiceCtx context)
  782. {
  783. PlayerIndex hidControllerId = (PlayerIndex)context.RequestData.ReadInt32();
  784. HidNpadJoyDeviceType hidNpadJoyDeviceType = (HidNpadJoyDeviceType)context.RequestData.ReadInt64();
  785. long appletResourceUserId = context.RequestData.ReadInt64();
  786. _npadJoyAssignmentMode = HidNpadJoyAssignmentMode.Single;
  787. context.ResponseData.Write(0); //Unknown0
  788. context.ResponseData.Write(0); //Unknown1
  789. Logger.Stub?.PrintStub(LogClass.ServiceHid, new {
  790. appletResourceUserId,
  791. hidControllerId,
  792. hidNpadJoyDeviceType,
  793. _npadJoyAssignmentMode,
  794. Unknown0 = 0,
  795. Unknown1 = 0
  796. });
  797. return ResultCode.Success;
  798. }
  799. [CommandHipc(200)]
  800. // GetVibrationDeviceInfo(nn::hid::VibrationDeviceHandle) -> nn::hid::VibrationDeviceInfo
  801. public ResultCode GetVibrationDeviceInfo(ServiceCtx context)
  802. {
  803. HidVibrationDeviceHandle deviceHandle = context.RequestData.ReadStruct<HidVibrationDeviceHandle>();
  804. NpadStyleIndex deviceType = (NpadStyleIndex)deviceHandle.DeviceType;
  805. NpadIdType npadIdType = (NpadIdType)deviceHandle.PlayerId;
  806. if (deviceType < NpadStyleIndex.System || deviceType >= NpadStyleIndex.FullKey)
  807. {
  808. if (npadIdType >= (NpadIdType.Player8 + 1) && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
  809. {
  810. return ResultCode.InvalidNpadIdType;
  811. }
  812. if (deviceHandle.Position > 1)
  813. {
  814. return ResultCode.InvalidDeviceIndex;
  815. }
  816. HidVibrationDeviceType vibrationDeviceType = HidVibrationDeviceType.None;
  817. if (Enum.IsDefined<NpadStyleIndex>(deviceType))
  818. {
  819. vibrationDeviceType = HidVibrationDeviceType.LinearResonantActuator;
  820. }
  821. else if ((uint)deviceType == 8)
  822. {
  823. vibrationDeviceType = HidVibrationDeviceType.GcErm;
  824. }
  825. HidVibrationDevicePosition vibrationDevicePosition = HidVibrationDevicePosition.None;
  826. if (vibrationDeviceType == HidVibrationDeviceType.LinearResonantActuator)
  827. {
  828. if (deviceHandle.Position == 0)
  829. {
  830. vibrationDevicePosition = HidVibrationDevicePosition.Left;
  831. }
  832. else if (deviceHandle.Position == 1)
  833. {
  834. vibrationDevicePosition = HidVibrationDevicePosition.Right;
  835. }
  836. else
  837. {
  838. throw new ArgumentOutOfRangeException(nameof(deviceHandle.Position));
  839. }
  840. }
  841. HidVibrationDeviceValue deviceInfo = new HidVibrationDeviceValue
  842. {
  843. DeviceType = vibrationDeviceType,
  844. Position = vibrationDevicePosition
  845. };
  846. context.ResponseData.WriteStruct(deviceInfo);
  847. return ResultCode.Success;
  848. }
  849. return ResultCode.InvalidNpadDeviceType;
  850. }
  851. [CommandHipc(201)]
  852. // SendVibrationValue(nn::hid::VibrationDeviceHandle, nn::hid::VibrationValue, nn::applet::AppletResourceUserId)
  853. public ResultCode SendVibrationValue(ServiceCtx context)
  854. {
  855. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  856. {
  857. DeviceType = context.RequestData.ReadByte(),
  858. PlayerId = context.RequestData.ReadByte(),
  859. Position = context.RequestData.ReadByte(),
  860. Reserved = context.RequestData.ReadByte()
  861. };
  862. HidVibrationValue vibrationValue = new HidVibrationValue
  863. {
  864. AmplitudeLow = context.RequestData.ReadSingle(),
  865. FrequencyLow = context.RequestData.ReadSingle(),
  866. AmplitudeHigh = context.RequestData.ReadSingle(),
  867. FrequencyHigh = context.RequestData.ReadSingle()
  868. };
  869. long appletResourceUserId = context.RequestData.ReadInt64();
  870. Dictionary<byte, HidVibrationValue> dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  871. dualVibrationValues[deviceHandle.Position] = vibrationValue;
  872. context.Device.Hid.Npads.UpdateRumbleQueue((PlayerIndex)deviceHandle.PlayerId, dualVibrationValues);
  873. return ResultCode.Success;
  874. }
  875. [CommandHipc(202)]
  876. // GetActualVibrationValue(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationValue
  877. public ResultCode GetActualVibrationValue(ServiceCtx context)
  878. {
  879. HidVibrationDeviceHandle deviceHandle = new HidVibrationDeviceHandle
  880. {
  881. DeviceType = context.RequestData.ReadByte(),
  882. PlayerId = context.RequestData.ReadByte(),
  883. Position = context.RequestData.ReadByte(),
  884. Reserved = context.RequestData.ReadByte()
  885. };
  886. long appletResourceUserId = context.RequestData.ReadInt64();
  887. HidVibrationValue vibrationValue = context.Device.Hid.Npads.GetLastVibrationValue((PlayerIndex)deviceHandle.PlayerId, deviceHandle.Position);
  888. context.ResponseData.Write(vibrationValue.AmplitudeLow);
  889. context.ResponseData.Write(vibrationValue.FrequencyLow);
  890. context.ResponseData.Write(vibrationValue.AmplitudeHigh);
  891. context.ResponseData.Write(vibrationValue.FrequencyHigh);
  892. return ResultCode.Success;
  893. }
  894. [CommandHipc(203)]
  895. // CreateActiveVibrationDeviceList() -> object<nn::hid::IActiveVibrationDeviceList>
  896. public ResultCode CreateActiveVibrationDeviceList(ServiceCtx context)
  897. {
  898. MakeObject(context, new IActiveApplicationDeviceList());
  899. return ResultCode.Success;
  900. }
  901. [CommandHipc(204)]
  902. // PermitVibration(bool Enable)
  903. public ResultCode PermitVibration(ServiceCtx context)
  904. {
  905. _vibrationPermitted = context.RequestData.ReadBoolean();
  906. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _vibrationPermitted });
  907. return ResultCode.Success;
  908. }
  909. [CommandHipc(205)]
  910. // IsVibrationPermitted() -> bool IsEnabled
  911. public ResultCode IsVibrationPermitted(ServiceCtx context)
  912. {
  913. context.ResponseData.Write(_vibrationPermitted);
  914. return ResultCode.Success;
  915. }
  916. [CommandHipc(206)]
  917. // SendVibrationValues(nn::applet::AppletResourceUserId, buffer<array<nn::hid::VibrationDeviceHandle>, type: 9>, buffer<array<nn::hid::VibrationValue>, type: 9>)
  918. public ResultCode SendVibrationValues(ServiceCtx context)
  919. {
  920. long appletResourceUserId = context.RequestData.ReadInt64();
  921. byte[] vibrationDeviceHandleBuffer = new byte[context.Request.PtrBuff[0].Size];
  922. context.Memory.Read(context.Request.PtrBuff[0].Position, vibrationDeviceHandleBuffer);
  923. byte[] vibrationValueBuffer = new byte[context.Request.PtrBuff[1].Size];
  924. context.Memory.Read(context.Request.PtrBuff[1].Position, vibrationValueBuffer);
  925. Span<HidVibrationDeviceHandle> deviceHandles = MemoryMarshal.Cast<byte, HidVibrationDeviceHandle>(vibrationDeviceHandleBuffer);
  926. Span<HidVibrationValue> vibrationValues = MemoryMarshal.Cast<byte, HidVibrationValue>(vibrationValueBuffer);
  927. if (!deviceHandles.IsEmpty && vibrationValues.Length == deviceHandles.Length)
  928. {
  929. Dictionary<byte, HidVibrationValue> dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  930. PlayerIndex currentIndex = (PlayerIndex)deviceHandles[0].PlayerId;
  931. for (int deviceCounter = 0; deviceCounter < deviceHandles.Length; deviceCounter++)
  932. {
  933. PlayerIndex index = (PlayerIndex)deviceHandles[deviceCounter].PlayerId;
  934. byte position = deviceHandles[deviceCounter].Position;
  935. if (index != currentIndex || dualVibrationValues.Count == 2)
  936. {
  937. context.Device.Hid.Npads.UpdateRumbleQueue(currentIndex, dualVibrationValues);
  938. dualVibrationValues = new Dictionary<byte, HidVibrationValue>();
  939. }
  940. dualVibrationValues[position] = vibrationValues[deviceCounter];
  941. currentIndex = index;
  942. }
  943. context.Device.Hid.Npads.UpdateRumbleQueue(currentIndex, dualVibrationValues);
  944. }
  945. return ResultCode.Success;
  946. }
  947. [CommandHipc(207)] // 4.0.0+
  948. // SendVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::hid::VibrationGcErmCommand, nn::applet::AppletResourceUserId)
  949. public ResultCode SendVibrationGcErmCommand(ServiceCtx context)
  950. {
  951. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  952. long vibrationGcErmCommand = context.RequestData.ReadInt64();
  953. long appletResourceUserId = context.RequestData.ReadInt64();
  954. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, vibrationGcErmCommand });
  955. return ResultCode.Success;
  956. }
  957. [CommandHipc(208)] // 4.0.0+
  958. // GetActualVibrationGcErmCommand(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId) -> nn::hid::VibrationGcErmCommand
  959. public ResultCode GetActualVibrationGcErmCommand(ServiceCtx context)
  960. {
  961. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  962. long appletResourceUserId = context.RequestData.ReadInt64();
  963. context.ResponseData.Write(_vibrationGcErmCommand);
  964. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, vibrationDeviceHandle, _vibrationGcErmCommand });
  965. return ResultCode.Success;
  966. }
  967. [CommandHipc(209)] // 4.0.0+
  968. // BeginPermitVibrationSession(nn::applet::AppletResourceUserId)
  969. public ResultCode BeginPermitVibrationSession(ServiceCtx context)
  970. {
  971. long appletResourceUserId = context.RequestData.ReadInt64();
  972. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  973. return ResultCode.Success;
  974. }
  975. [CommandHipc(210)] // 4.0.0+
  976. // EndPermitVibrationSession()
  977. public ResultCode EndPermitVibrationSession(ServiceCtx context)
  978. {
  979. Logger.Stub?.PrintStub(LogClass.ServiceHid);
  980. return ResultCode.Success;
  981. }
  982. [CommandHipc(211)] // 7.0.0+
  983. // IsVibrationDeviceMounted(nn::hid::VibrationDeviceHandle, nn::applet::AppletResourceUserId)
  984. public ResultCode IsVibrationDeviceMounted(ServiceCtx context)
  985. {
  986. int vibrationDeviceHandle = context.RequestData.ReadInt32();
  987. long appletResourceUserId = context.RequestData.ReadInt64();
  988. // NOTE: Service use vibrationDeviceHandle to get the PlayerIndex.
  989. // And return false if (npadIdType >= (NpadIdType)8 && npadIdType != NpadIdType.Handheld && npadIdType != NpadIdType.Unknown)
  990. context.ResponseData.Write(true);
  991. return ResultCode.Success;
  992. }
  993. [CommandHipc(300)]
  994. // ActivateConsoleSixAxisSensor(nn::applet::AppletResourceUserId)
  995. public ResultCode ActivateConsoleSixAxisSensor(ServiceCtx context)
  996. {
  997. long appletResourceUserId = context.RequestData.ReadInt64();
  998. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  999. return ResultCode.Success;
  1000. }
  1001. [CommandHipc(301)]
  1002. // StartConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
  1003. public ResultCode StartConsoleSixAxisSensor(ServiceCtx context)
  1004. {
  1005. int consoleSixAxisSensorHandle = context.RequestData.ReadInt32();
  1006. long appletResourceUserId = context.RequestData.ReadInt64();
  1007. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, consoleSixAxisSensorHandle });
  1008. return ResultCode.Success;
  1009. }
  1010. [CommandHipc(302)]
  1011. // StopConsoleSixAxisSensor(nn::hid::ConsoleSixAxisSensorHandle, nn::applet::AppletResourceUserId)
  1012. public ResultCode StopConsoleSixAxisSensor(ServiceCtx context)
  1013. {
  1014. int consoleSixAxisSensorHandle = context.RequestData.ReadInt32();
  1015. long appletResourceUserId = context.RequestData.ReadInt64();
  1016. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, consoleSixAxisSensorHandle });
  1017. return ResultCode.Success;
  1018. }
  1019. [CommandHipc(303)] // 5.0.0+
  1020. // ActivateSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  1021. public ResultCode ActivateSevenSixAxisSensor(ServiceCtx context)
  1022. {
  1023. long appletResourceUserId = context.RequestData.ReadInt64();
  1024. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1025. return ResultCode.Success;
  1026. }
  1027. [CommandHipc(304)] // 5.0.0+
  1028. // StartSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  1029. public ResultCode StartSevenSixAxisSensor(ServiceCtx context)
  1030. {
  1031. long appletResourceUserId = context.RequestData.ReadInt64();
  1032. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1033. return ResultCode.Success;
  1034. }
  1035. [CommandHipc(305)] // 5.0.0+
  1036. // StopSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  1037. public ResultCode StopSevenSixAxisSensor(ServiceCtx context)
  1038. {
  1039. long appletResourceUserId = context.RequestData.ReadInt64();
  1040. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1041. return ResultCode.Success;
  1042. }
  1043. [CommandHipc(306)] // 5.0.0+
  1044. // InitializeSevenSixAxisSensor(array<nn::sf::NativeHandle>, ulong Counter0, array<nn::sf::NativeHandle>, ulong Counter1, nn::applet::AppletResourceUserId)
  1045. public ResultCode InitializeSevenSixAxisSensor(ServiceCtx context)
  1046. {
  1047. long appletResourceUserId = context.RequestData.ReadInt64();
  1048. long counter0 = context.RequestData.ReadInt64();
  1049. long counter1 = context.RequestData.ReadInt64();
  1050. // TODO: Determine if array<nn::sf::NativeHandle> is a buffer or not...
  1051. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, counter0, counter1 });
  1052. return ResultCode.Success;
  1053. }
  1054. [CommandHipc(307)] // 5.0.0+
  1055. // FinalizeSevenSixAxisSensor(nn::applet::AppletResourceUserId)
  1056. public ResultCode FinalizeSevenSixAxisSensor(ServiceCtx context)
  1057. {
  1058. long appletResourceUserId = context.RequestData.ReadInt64();
  1059. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1060. return ResultCode.Success;
  1061. }
  1062. [CommandHipc(308)] // 5.0.0+
  1063. // SetSevenSixAxisSensorFusionStrength(float Strength, nn::applet::AppletResourceUserId)
  1064. public ResultCode SetSevenSixAxisSensorFusionStrength(ServiceCtx context)
  1065. {
  1066. _sevenSixAxisSensorFusionStrength = context.RequestData.ReadSingle();
  1067. long appletResourceUserId = context.RequestData.ReadInt64();
  1068. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _sevenSixAxisSensorFusionStrength });
  1069. return ResultCode.Success;
  1070. }
  1071. [CommandHipc(309)] // 5.0.0+
  1072. // GetSevenSixAxisSensorFusionStrength(nn::applet::AppletResourceUserId) -> float Strength
  1073. public ResultCode GetSevenSixAxisSensorFusionStrength(ServiceCtx context)
  1074. {
  1075. long appletResourceUserId = context.RequestData.ReadInt64();
  1076. context.ResponseData.Write(_sevenSixAxisSensorFusionStrength);
  1077. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _sevenSixAxisSensorFusionStrength });
  1078. return ResultCode.Success;
  1079. }
  1080. [CommandHipc(310)] // 6.0.0+
  1081. // ResetSevenSixAxisSensorTimestamp(pid, nn::applet::AppletResourceUserId)
  1082. public ResultCode ResetSevenSixAxisSensorTimestamp(ServiceCtx context)
  1083. {
  1084. long appletResourceUserId = context.RequestData.ReadInt64();
  1085. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId });
  1086. return ResultCode.Success;
  1087. }
  1088. [CommandHipc(400)]
  1089. // IsUsbFullKeyControllerEnabled() -> bool IsEnabled
  1090. public ResultCode IsUsbFullKeyControllerEnabled(ServiceCtx context)
  1091. {
  1092. context.ResponseData.Write(_usbFullKeyControllerEnabled);
  1093. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _usbFullKeyControllerEnabled });
  1094. return ResultCode.Success;
  1095. }
  1096. [CommandHipc(401)]
  1097. // EnableUsbFullKeyController(bool Enable)
  1098. public ResultCode EnableUsbFullKeyController(ServiceCtx context)
  1099. {
  1100. _usbFullKeyControllerEnabled = context.RequestData.ReadBoolean();
  1101. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _usbFullKeyControllerEnabled });
  1102. return ResultCode.Success;
  1103. }
  1104. [CommandHipc(402)]
  1105. // IsUsbFullKeyControllerConnected(uint Unknown0) -> bool Connected
  1106. public ResultCode IsUsbFullKeyControllerConnected(ServiceCtx context)
  1107. {
  1108. int unknown0 = context.RequestData.ReadInt32();
  1109. context.ResponseData.Write(true); //FullKeyController is always connected ?
  1110. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { unknown0, Connected = true });
  1111. return ResultCode.Success;
  1112. }
  1113. [CommandHipc(403)] // 4.0.0+
  1114. // HasBattery(uint NpadId) -> bool HasBattery
  1115. public ResultCode HasBattery(ServiceCtx context)
  1116. {
  1117. int npadId = context.RequestData.ReadInt32();
  1118. context.ResponseData.Write(true); //Npad always got a battery ?
  1119. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, HasBattery = true });
  1120. return ResultCode.Success;
  1121. }
  1122. [CommandHipc(404)] // 4.0.0+
  1123. // HasLeftRightBattery(uint NpadId) -> bool HasLeftBattery, bool HasRightBattery
  1124. public ResultCode HasLeftRightBattery(ServiceCtx context)
  1125. {
  1126. int npadId = context.RequestData.ReadInt32();
  1127. context.ResponseData.Write(true); //Npad always got a left battery ?
  1128. context.ResponseData.Write(true); //Npad always got a right battery ?
  1129. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, HasLeftBattery = true, HasRightBattery = true });
  1130. return ResultCode.Success;
  1131. }
  1132. [CommandHipc(405)] // 4.0.0+
  1133. // GetNpadInterfaceType(uint NpadId) -> uchar InterfaceType
  1134. public ResultCode GetNpadInterfaceType(ServiceCtx context)
  1135. {
  1136. int npadId = context.RequestData.ReadInt32();
  1137. context.ResponseData.Write((byte)0);
  1138. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, NpadInterfaceType = 0 });
  1139. return ResultCode.Success;
  1140. }
  1141. [CommandHipc(406)] // 4.0.0+
  1142. // GetNpadLeftRightInterfaceType(uint NpadId) -> uchar LeftInterfaceType, uchar RightInterfaceType
  1143. public ResultCode GetNpadLeftRightInterfaceType(ServiceCtx context)
  1144. {
  1145. int npadId = context.RequestData.ReadInt32();
  1146. context.ResponseData.Write((byte)0);
  1147. context.ResponseData.Write((byte)0);
  1148. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { npadId, LeftInterfaceType = 0, RightInterfaceType = 0 });
  1149. return ResultCode.Success;
  1150. }
  1151. [CommandHipc(500)] // 5.0.0+
  1152. // GetPalmaConnectionHandle(uint Unknown0, nn::applet::AppletResourceUserId) -> nn::hid::PalmaConnectionHandle
  1153. public ResultCode GetPalmaConnectionHandle(ServiceCtx context)
  1154. {
  1155. int unknown0 = context.RequestData.ReadInt32();
  1156. long appletResourceUserId = context.RequestData.ReadInt64();
  1157. int palmaConnectionHandle = 0;
  1158. context.ResponseData.Write(palmaConnectionHandle);
  1159. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId , unknown0, palmaConnectionHandle });
  1160. return ResultCode.Success;
  1161. }
  1162. [CommandHipc(501)] // 5.0.0+
  1163. // InitializePalma(nn::hid::PalmaConnectionHandle)
  1164. public ResultCode InitializePalma(ServiceCtx context)
  1165. {
  1166. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1167. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1168. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1169. return ResultCode.Success;
  1170. }
  1171. [CommandHipc(502)] // 5.0.0+
  1172. // AcquirePalmaOperationCompleteEvent(nn::hid::PalmaConnectionHandle) -> nn::sf::NativeHandle
  1173. public ResultCode AcquirePalmaOperationCompleteEvent(ServiceCtx context)
  1174. {
  1175. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1176. if (context.Process.HandleTable.GenerateHandle(_palmaOperationCompleteEvent.ReadableEvent, out int handle) != KernelResult.Success)
  1177. {
  1178. throw new InvalidOperationException("Out of handles!");
  1179. }
  1180. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  1181. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1182. return ResultCode.Success;
  1183. }
  1184. [CommandHipc(503)] // 5.0.0+
  1185. // GetPalmaOperationInfo(nn::hid::PalmaConnectionHandle) -> long Unknown0, buffer<Unknown>
  1186. public ResultCode GetPalmaOperationInfo(ServiceCtx context)
  1187. {
  1188. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1189. long unknown0 = 0; //Counter?
  1190. context.ResponseData.Write(unknown0);
  1191. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0 });
  1192. return ResultCode.Success;
  1193. }
  1194. [CommandHipc(504)] // 5.0.0+
  1195. // PlayPalmaActivity(nn::hid::PalmaConnectionHandle, ulong Unknown0)
  1196. public ResultCode PlayPalmaActivity(ServiceCtx context)
  1197. {
  1198. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1199. long unknown0 = context.RequestData.ReadInt64();
  1200. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0 });
  1201. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1202. return ResultCode.Success;
  1203. }
  1204. [CommandHipc(505)] // 5.0.0+
  1205. // SetPalmaFrModeType(nn::hid::PalmaConnectionHandle, ulong FrModeType)
  1206. public ResultCode SetPalmaFrModeType(ServiceCtx context)
  1207. {
  1208. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1209. long frModeType = context.RequestData.ReadInt64();
  1210. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, frModeType });
  1211. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1212. return ResultCode.Success;
  1213. }
  1214. [CommandHipc(506)] // 5.0.0+
  1215. // ReadPalmaStep(nn::hid::PalmaConnectionHandle)
  1216. public ResultCode ReadPalmaStep(ServiceCtx context)
  1217. {
  1218. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1219. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1220. return ResultCode.Success;
  1221. }
  1222. [CommandHipc(507)] // 5.0.0+
  1223. // EnablePalmaStep(nn::hid::PalmaConnectionHandle, bool Enable)
  1224. public ResultCode EnablePalmaStep(ServiceCtx context)
  1225. {
  1226. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1227. bool enabledPalmaStep = context.RequestData.ReadBoolean();
  1228. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, enabledPalmaStep });
  1229. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1230. return ResultCode.Success;
  1231. }
  1232. [CommandHipc(508)] // 5.0.0+
  1233. // ResetPalmaStep(nn::hid::PalmaConnectionHandle)
  1234. public ResultCode ResetPalmaStep(ServiceCtx context)
  1235. {
  1236. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1237. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1238. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1239. return ResultCode.Success;
  1240. }
  1241. [CommandHipc(509)] // 5.0.0+
  1242. // ReadPalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1)
  1243. public ResultCode ReadPalmaApplicationSection(ServiceCtx context)
  1244. {
  1245. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1246. long unknown0 = context.RequestData.ReadInt64();
  1247. long unknown1 = context.RequestData.ReadInt64();
  1248. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0, unknown1 });
  1249. return ResultCode.Success;
  1250. }
  1251. [CommandHipc(510)] // 5.0.0+
  1252. // WritePalmaApplicationSection(nn::hid::PalmaConnectionHandle, ulong Unknown0, ulong Unknown1, nn::hid::PalmaApplicationSectionAccessBuffer)
  1253. public ResultCode WritePalmaApplicationSection(ServiceCtx context)
  1254. {
  1255. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1256. long unknown0 = context.RequestData.ReadInt64();
  1257. long unknown1 = context.RequestData.ReadInt64();
  1258. // nn::hid::PalmaApplicationSectionAccessBuffer cast is unknown
  1259. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle, unknown0, unknown1 });
  1260. _palmaOperationCompleteEvent.ReadableEvent.Signal();
  1261. return ResultCode.Success;
  1262. }
  1263. [CommandHipc(511)] // 5.0.0+
  1264. // ReadPalmaUniqueCode(nn::hid::PalmaConnectionHandle)
  1265. public ResultCode ReadPalmaUniqueCode(ServiceCtx context)
  1266. {
  1267. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1268. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1269. return ResultCode.Success;
  1270. }
  1271. [CommandHipc(512)] // 5.0.0+
  1272. // SetPalmaUniqueCodeInvalid(nn::hid::PalmaConnectionHandle)
  1273. public ResultCode SetPalmaUniqueCodeInvalid(ServiceCtx context)
  1274. {
  1275. int palmaConnectionHandle = context.RequestData.ReadInt32();
  1276. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { palmaConnectionHandle });
  1277. return ResultCode.Success;
  1278. }
  1279. [CommandHipc(522)] // 5.1.0+
  1280. // SetIsPalmaAllConnectable(nn::applet::AppletResourceUserId, bool, pid)
  1281. public ResultCode SetIsPalmaAllConnectable(ServiceCtx context)
  1282. {
  1283. long appletResourceUserId = context.RequestData.ReadInt64();
  1284. long unknownBool = context.RequestData.ReadInt64();
  1285. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, unknownBool });
  1286. return ResultCode.Success;
  1287. }
  1288. [CommandHipc(525)] // 5.1.0+
  1289. // SetPalmaBoostMode(bool)
  1290. public ResultCode SetPalmaBoostMode(ServiceCtx context)
  1291. {
  1292. // NOTE: Stubbed in system module.
  1293. return ResultCode.Success;
  1294. }
  1295. [CommandHipc(1000)]
  1296. // SetNpadCommunicationMode(long CommunicationMode, nn::applet::AppletResourceUserId)
  1297. public ResultCode SetNpadCommunicationMode(ServiceCtx context)
  1298. {
  1299. _npadCommunicationMode = context.RequestData.ReadInt64();
  1300. long appletResourceUserId = context.RequestData.ReadInt64();
  1301. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, _npadCommunicationMode });
  1302. return ResultCode.Success;
  1303. }
  1304. [CommandHipc(1001)]
  1305. // GetNpadCommunicationMode() -> long CommunicationMode
  1306. public ResultCode GetNpadCommunicationMode(ServiceCtx context)
  1307. {
  1308. context.ResponseData.Write(_npadCommunicationMode);
  1309. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { _npadCommunicationMode });
  1310. return ResultCode.Success;
  1311. }
  1312. [CommandHipc(1002)] // 9.0.0+
  1313. // SetTouchScreenConfiguration(nn::hid::TouchScreenConfigurationForNx, nn::applet::AppletResourceUserId)
  1314. public ResultCode SetTouchScreenConfiguration(ServiceCtx context)
  1315. {
  1316. long touchScreenConfigurationForNx = context.RequestData.ReadInt64();
  1317. long appletResourceUserId = context.RequestData.ReadInt64();
  1318. Logger.Stub?.PrintStub(LogClass.ServiceHid, new { appletResourceUserId, touchScreenConfigurationForNx });
  1319. return ResultCode.Success;
  1320. }
  1321. }
  1322. }