irs.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <algorithm>
  4. #include <random>
  5. #include "core/core.h"
  6. #include "core/core_timing.h"
  7. #include "core/hid/emulated_controller.h"
  8. #include "core/hid/hid_core.h"
  9. #include "core/hle/kernel/k_shared_memory.h"
  10. #include "core/hle/kernel/k_transfer_memory.h"
  11. #include "core/hle/kernel/kernel.h"
  12. #include "core/hle/service/hid/errors.h"
  13. #include "core/hle/service/hid/irs.h"
  14. #include "core/hle/service/hid/irsensor/clustering_processor.h"
  15. #include "core/hle/service/hid/irsensor/image_transfer_processor.h"
  16. #include "core/hle/service/hid/irsensor/ir_led_processor.h"
  17. #include "core/hle/service/hid/irsensor/moment_processor.h"
  18. #include "core/hle/service/hid/irsensor/pointing_processor.h"
  19. #include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
  20. #include "core/hle/service/ipc_helpers.h"
  21. #include "core/memory.h"
  22. namespace Service::IRS {
  23. IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
  24. // clang-format off
  25. static const FunctionInfo functions[] = {
  26. {302, &IRS::ActivateIrsensor, "ActivateIrsensor"},
  27. {303, &IRS::DeactivateIrsensor, "DeactivateIrsensor"},
  28. {304, &IRS::GetIrsensorSharedMemoryHandle, "GetIrsensorSharedMemoryHandle"},
  29. {305, &IRS::StopImageProcessor, "StopImageProcessor"},
  30. {306, &IRS::RunMomentProcessor, "RunMomentProcessor"},
  31. {307, &IRS::RunClusteringProcessor, "RunClusteringProcessor"},
  32. {308, &IRS::RunImageTransferProcessor, "RunImageTransferProcessor"},
  33. {309, &IRS::GetImageTransferProcessorState, "GetImageTransferProcessorState"},
  34. {310, &IRS::RunTeraPluginProcessor, "RunTeraPluginProcessor"},
  35. {311, &IRS::GetNpadIrCameraHandle, "GetNpadIrCameraHandle"},
  36. {312, &IRS::RunPointingProcessor, "RunPointingProcessor"},
  37. {313, &IRS::SuspendImageProcessor, "SuspendImageProcessor"},
  38. {314, &IRS::CheckFirmwareVersion, "CheckFirmwareVersion"},
  39. {315, &IRS::SetFunctionLevel, "SetFunctionLevel"},
  40. {316, &IRS::RunImageTransferExProcessor, "RunImageTransferExProcessor"},
  41. {317, &IRS::RunIrLedProcessor, "RunIrLedProcessor"},
  42. {318, &IRS::StopImageProcessorAsync, "StopImageProcessorAsync"},
  43. {319, &IRS::ActivateIrsensorWithFunctionLevel, "ActivateIrsensorWithFunctionLevel"},
  44. };
  45. // clang-format on
  46. u8* raw_shared_memory = system.Kernel().GetIrsSharedMem().GetPointer();
  47. RegisterHandlers(functions);
  48. shared_memory = std::construct_at(reinterpret_cast<StatusManager*>(raw_shared_memory));
  49. npad_device = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
  50. }
  51. IRS::~IRS() = default;
  52. void IRS::ActivateIrsensor(HLERequestContext& ctx) {
  53. IPC::RequestParser rp{ctx};
  54. const auto applet_resource_user_id{rp.Pop<u64>()};
  55. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
  56. applet_resource_user_id);
  57. IPC::ResponseBuilder rb{ctx, 2};
  58. rb.Push(ResultSuccess);
  59. }
  60. void IRS::DeactivateIrsensor(HLERequestContext& ctx) {
  61. IPC::RequestParser rp{ctx};
  62. const auto applet_resource_user_id{rp.Pop<u64>()};
  63. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
  64. applet_resource_user_id);
  65. IPC::ResponseBuilder rb{ctx, 2};
  66. rb.Push(ResultSuccess);
  67. }
  68. void IRS::GetIrsensorSharedMemoryHandle(HLERequestContext& ctx) {
  69. IPC::RequestParser rp{ctx};
  70. const auto applet_resource_user_id{rp.Pop<u64>()};
  71. LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id);
  72. IPC::ResponseBuilder rb{ctx, 2, 1};
  73. rb.Push(ResultSuccess);
  74. rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem());
  75. }
  76. void IRS::StopImageProcessor(HLERequestContext& ctx) {
  77. IPC::RequestParser rp{ctx};
  78. struct Parameters {
  79. Core::IrSensor::IrCameraHandle camera_handle;
  80. INSERT_PADDING_WORDS_NOINIT(1);
  81. u64 applet_resource_user_id;
  82. };
  83. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  84. const auto parameters{rp.PopRaw<Parameters>()};
  85. LOG_WARNING(Service_IRS,
  86. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  87. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  88. parameters.applet_resource_user_id);
  89. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  90. if (result.IsSuccess()) {
  91. // TODO: Stop Image processor
  92. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  93. Common::Input::PollingMode::Active);
  94. result = ResultSuccess;
  95. }
  96. IPC::ResponseBuilder rb{ctx, 2};
  97. rb.Push(result);
  98. }
  99. void IRS::RunMomentProcessor(HLERequestContext& ctx) {
  100. IPC::RequestParser rp{ctx};
  101. struct Parameters {
  102. Core::IrSensor::IrCameraHandle camera_handle;
  103. INSERT_PADDING_WORDS_NOINIT(1);
  104. u64 applet_resource_user_id;
  105. Core::IrSensor::PackedMomentProcessorConfig processor_config;
  106. };
  107. static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
  108. const auto parameters{rp.PopRaw<Parameters>()};
  109. LOG_WARNING(Service_IRS,
  110. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  111. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  112. parameters.applet_resource_user_id);
  113. const auto result = IsIrCameraHandleValid(parameters.camera_handle);
  114. if (result.IsSuccess()) {
  115. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  116. MakeProcessorWithCoreContext<MomentProcessor>(parameters.camera_handle, device);
  117. auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
  118. image_transfer_processor.SetConfig(parameters.processor_config);
  119. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  120. Common::Input::PollingMode::IR);
  121. }
  122. IPC::ResponseBuilder rb{ctx, 2};
  123. rb.Push(result);
  124. }
  125. void IRS::RunClusteringProcessor(HLERequestContext& ctx) {
  126. IPC::RequestParser rp{ctx};
  127. struct Parameters {
  128. Core::IrSensor::IrCameraHandle camera_handle;
  129. INSERT_PADDING_WORDS_NOINIT(1);
  130. u64 applet_resource_user_id;
  131. Core::IrSensor::PackedClusteringProcessorConfig processor_config;
  132. };
  133. static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
  134. const auto parameters{rp.PopRaw<Parameters>()};
  135. LOG_WARNING(Service_IRS,
  136. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  137. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  138. parameters.applet_resource_user_id);
  139. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  140. if (result.IsSuccess()) {
  141. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  142. MakeProcessorWithCoreContext<ClusteringProcessor>(parameters.camera_handle, device);
  143. auto& image_transfer_processor =
  144. GetProcessor<ClusteringProcessor>(parameters.camera_handle);
  145. image_transfer_processor.SetConfig(parameters.processor_config);
  146. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  147. Common::Input::PollingMode::IR);
  148. }
  149. IPC::ResponseBuilder rb{ctx, 2};
  150. rb.Push(result);
  151. }
  152. void IRS::RunImageTransferProcessor(HLERequestContext& ctx) {
  153. IPC::RequestParser rp{ctx};
  154. struct Parameters {
  155. Core::IrSensor::IrCameraHandle camera_handle;
  156. INSERT_PADDING_WORDS_NOINIT(1);
  157. u64 applet_resource_user_id;
  158. Core::IrSensor::PackedImageTransferProcessorConfig processor_config;
  159. u32 transfer_memory_size;
  160. };
  161. static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
  162. const auto parameters{rp.PopRaw<Parameters>()};
  163. const auto t_mem_handle{ctx.GetCopyHandle(0)};
  164. auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
  165. t_mem_handle);
  166. if (t_mem.IsNull()) {
  167. LOG_ERROR(Service_IRS, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
  168. IPC::ResponseBuilder rb{ctx, 2};
  169. rb.Push(ResultUnknown);
  170. return;
  171. }
  172. ASSERT_MSG(t_mem->GetSize() == parameters.transfer_memory_size, "t_mem has incorrect size");
  173. LOG_INFO(Service_IRS,
  174. "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, "
  175. "applet_resource_user_id={}",
  176. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  177. parameters.transfer_memory_size, t_mem->GetSize(), parameters.applet_resource_user_id);
  178. const auto result = IsIrCameraHandleValid(parameters.camera_handle);
  179. if (result.IsSuccess()) {
  180. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  181. MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device);
  182. auto& image_transfer_processor =
  183. GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
  184. image_transfer_processor.SetConfig(parameters.processor_config);
  185. image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
  186. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  187. Common::Input::PollingMode::IR);
  188. }
  189. IPC::ResponseBuilder rb{ctx, 2};
  190. rb.Push(result);
  191. }
  192. void IRS::GetImageTransferProcessorState(HLERequestContext& ctx) {
  193. IPC::RequestParser rp{ctx};
  194. struct Parameters {
  195. Core::IrSensor::IrCameraHandle camera_handle;
  196. INSERT_PADDING_WORDS_NOINIT(1);
  197. u64 applet_resource_user_id;
  198. };
  199. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  200. const auto parameters{rp.PopRaw<Parameters>()};
  201. LOG_DEBUG(Service_IRS, "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  202. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  203. parameters.applet_resource_user_id);
  204. const auto result = IsIrCameraHandleValid(parameters.camera_handle);
  205. if (result.IsError()) {
  206. IPC::ResponseBuilder rb{ctx, 2};
  207. rb.Push(result);
  208. return;
  209. }
  210. const auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  211. if (device.mode != Core::IrSensor::IrSensorMode::ImageTransferProcessor) {
  212. IPC::ResponseBuilder rb{ctx, 2};
  213. rb.Push(InvalidProcessorState);
  214. return;
  215. }
  216. std::vector<u8> data{};
  217. const auto& image_transfer_processor =
  218. GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
  219. const auto& state = image_transfer_processor.GetState(data);
  220. ctx.WriteBuffer(data);
  221. IPC::ResponseBuilder rb{ctx, 6};
  222. rb.Push(ResultSuccess);
  223. rb.PushRaw(state);
  224. }
  225. void IRS::RunTeraPluginProcessor(HLERequestContext& ctx) {
  226. IPC::RequestParser rp{ctx};
  227. struct Parameters {
  228. Core::IrSensor::IrCameraHandle camera_handle;
  229. Core::IrSensor::PackedTeraPluginProcessorConfig processor_config;
  230. INSERT_PADDING_WORDS_NOINIT(1);
  231. u64 applet_resource_user_id;
  232. };
  233. static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
  234. const auto parameters{rp.PopRaw<Parameters>()};
  235. LOG_WARNING(
  236. Service_IRS,
  237. "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, "
  238. "applet_resource_user_id={}",
  239. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  240. parameters.processor_config.mode, parameters.processor_config.required_mcu_version.major,
  241. parameters.processor_config.required_mcu_version.minor, parameters.applet_resource_user_id);
  242. const auto result = IsIrCameraHandleValid(parameters.camera_handle);
  243. if (result.IsSuccess()) {
  244. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  245. MakeProcessor<TeraPluginProcessor>(parameters.camera_handle, device);
  246. auto& image_transfer_processor =
  247. GetProcessor<TeraPluginProcessor>(parameters.camera_handle);
  248. image_transfer_processor.SetConfig(parameters.processor_config);
  249. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  250. Common::Input::PollingMode::IR);
  251. }
  252. IPC::ResponseBuilder rb{ctx, 2};
  253. rb.Push(result);
  254. }
  255. void IRS::GetNpadIrCameraHandle(HLERequestContext& ctx) {
  256. IPC::RequestParser rp{ctx};
  257. const auto npad_id{rp.PopEnum<Core::HID::NpadIdType>()};
  258. if (npad_id > Core::HID::NpadIdType::Player8 && npad_id != Core::HID::NpadIdType::Invalid &&
  259. npad_id != Core::HID::NpadIdType::Handheld) {
  260. IPC::ResponseBuilder rb{ctx, 2};
  261. rb.Push(Service::HID::InvalidNpadId);
  262. return;
  263. }
  264. Core::IrSensor::IrCameraHandle camera_handle{
  265. .npad_id = static_cast<u8>(NpadIdTypeToIndex(npad_id)),
  266. .npad_type = Core::HID::NpadStyleIndex::None,
  267. };
  268. LOG_INFO(Service_IRS, "called, npad_id={}, camera_npad_id={}, camera_npad_type={}", npad_id,
  269. camera_handle.npad_id, camera_handle.npad_type);
  270. IPC::ResponseBuilder rb{ctx, 3};
  271. rb.Push(ResultSuccess);
  272. rb.PushRaw(camera_handle);
  273. }
  274. void IRS::RunPointingProcessor(HLERequestContext& ctx) {
  275. IPC::RequestParser rp{ctx};
  276. const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
  277. const auto processor_config{rp.PopRaw<Core::IrSensor::PackedPointingProcessorConfig>()};
  278. const auto applet_resource_user_id{rp.Pop<u64>()};
  279. LOG_WARNING(
  280. Service_IRS,
  281. "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}",
  282. camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
  283. processor_config.required_mcu_version.minor, applet_resource_user_id);
  284. auto result = IsIrCameraHandleValid(camera_handle);
  285. if (result.IsSuccess()) {
  286. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  287. MakeProcessor<PointingProcessor>(camera_handle, device);
  288. auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
  289. image_transfer_processor.SetConfig(processor_config);
  290. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  291. Common::Input::PollingMode::IR);
  292. }
  293. IPC::ResponseBuilder rb{ctx, 2};
  294. rb.Push(result);
  295. }
  296. void IRS::SuspendImageProcessor(HLERequestContext& ctx) {
  297. IPC::RequestParser rp{ctx};
  298. struct Parameters {
  299. Core::IrSensor::IrCameraHandle camera_handle;
  300. INSERT_PADDING_WORDS_NOINIT(1);
  301. u64 applet_resource_user_id;
  302. };
  303. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  304. const auto parameters{rp.PopRaw<Parameters>()};
  305. LOG_WARNING(Service_IRS,
  306. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  307. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  308. parameters.applet_resource_user_id);
  309. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  310. if (result.IsSuccess()) {
  311. // TODO: Suspend image processor
  312. result = ResultSuccess;
  313. }
  314. IPC::ResponseBuilder rb{ctx, 2};
  315. rb.Push(result);
  316. }
  317. void IRS::CheckFirmwareVersion(HLERequestContext& ctx) {
  318. IPC::RequestParser rp{ctx};
  319. const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
  320. const auto mcu_version{rp.PopRaw<Core::IrSensor::PackedMcuVersion>()};
  321. const auto applet_resource_user_id{rp.Pop<u64>()};
  322. LOG_WARNING(
  323. Service_IRS,
  324. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}",
  325. camera_handle.npad_type, camera_handle.npad_id, applet_resource_user_id, mcu_version.major,
  326. mcu_version.minor);
  327. auto result = IsIrCameraHandleValid(camera_handle);
  328. if (result.IsSuccess()) {
  329. // TODO: Check firmware version
  330. result = ResultSuccess;
  331. }
  332. IPC::ResponseBuilder rb{ctx, 2};
  333. rb.Push(result);
  334. }
  335. void IRS::SetFunctionLevel(HLERequestContext& ctx) {
  336. IPC::RequestParser rp{ctx};
  337. const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
  338. const auto function_level{rp.PopRaw<Core::IrSensor::PackedFunctionLevel>()};
  339. const auto applet_resource_user_id{rp.Pop<u64>()};
  340. LOG_WARNING(
  341. Service_IRS,
  342. "(STUBBED) called, npad_type={}, npad_id={}, function_level={}, applet_resource_user_id={}",
  343. camera_handle.npad_type, camera_handle.npad_id, function_level.function_level,
  344. applet_resource_user_id);
  345. auto result = IsIrCameraHandleValid(camera_handle);
  346. if (result.IsSuccess()) {
  347. // TODO: Set Function level
  348. result = ResultSuccess;
  349. }
  350. IPC::ResponseBuilder rb{ctx, 2};
  351. rb.Push(result);
  352. }
  353. void IRS::RunImageTransferExProcessor(HLERequestContext& ctx) {
  354. IPC::RequestParser rp{ctx};
  355. struct Parameters {
  356. Core::IrSensor::IrCameraHandle camera_handle;
  357. INSERT_PADDING_WORDS_NOINIT(1);
  358. u64 applet_resource_user_id;
  359. Core::IrSensor::PackedImageTransferProcessorExConfig processor_config;
  360. u64 transfer_memory_size;
  361. };
  362. static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
  363. const auto parameters{rp.PopRaw<Parameters>()};
  364. const auto t_mem_handle{ctx.GetCopyHandle(0)};
  365. auto t_mem = system.ApplicationProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(
  366. t_mem_handle);
  367. LOG_INFO(Service_IRS,
  368. "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
  369. "applet_resource_user_id={}",
  370. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  371. parameters.transfer_memory_size, parameters.applet_resource_user_id);
  372. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  373. if (result.IsSuccess()) {
  374. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  375. MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device);
  376. auto& image_transfer_processor =
  377. GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
  378. image_transfer_processor.SetConfig(parameters.processor_config);
  379. image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
  380. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  381. Common::Input::PollingMode::IR);
  382. }
  383. IPC::ResponseBuilder rb{ctx, 2};
  384. rb.Push(result);
  385. }
  386. void IRS::RunIrLedProcessor(HLERequestContext& ctx) {
  387. IPC::RequestParser rp{ctx};
  388. const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
  389. const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()};
  390. const auto applet_resource_user_id{rp.Pop<u64>()};
  391. LOG_WARNING(Service_IRS,
  392. "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
  393. "applet_resource_user_id={}",
  394. camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
  395. processor_config.required_mcu_version.major,
  396. processor_config.required_mcu_version.minor, applet_resource_user_id);
  397. auto result = IsIrCameraHandleValid(camera_handle);
  398. if (result.IsSuccess()) {
  399. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  400. MakeProcessor<IrLedProcessor>(camera_handle, device);
  401. auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
  402. image_transfer_processor.SetConfig(processor_config);
  403. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  404. Common::Input::PollingMode::IR);
  405. }
  406. IPC::ResponseBuilder rb{ctx, 2};
  407. rb.Push(result);
  408. }
  409. void IRS::StopImageProcessorAsync(HLERequestContext& ctx) {
  410. IPC::RequestParser rp{ctx};
  411. struct Parameters {
  412. Core::IrSensor::IrCameraHandle camera_handle;
  413. INSERT_PADDING_WORDS_NOINIT(1);
  414. u64 applet_resource_user_id;
  415. };
  416. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  417. const auto parameters{rp.PopRaw<Parameters>()};
  418. LOG_WARNING(Service_IRS,
  419. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  420. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  421. parameters.applet_resource_user_id);
  422. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  423. if (result.IsSuccess()) {
  424. // TODO: Stop image processor async
  425. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  426. Common::Input::PollingMode::Active);
  427. result = ResultSuccess;
  428. }
  429. IPC::ResponseBuilder rb{ctx, 2};
  430. rb.Push(result);
  431. }
  432. void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
  433. IPC::RequestParser rp{ctx};
  434. struct Parameters {
  435. Core::IrSensor::PackedFunctionLevel function_level;
  436. INSERT_PADDING_WORDS_NOINIT(1);
  437. u64 applet_resource_user_id;
  438. };
  439. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  440. const auto parameters{rp.PopRaw<Parameters>()};
  441. LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
  442. parameters.function_level.function_level, parameters.applet_resource_user_id);
  443. IPC::ResponseBuilder rb{ctx, 2};
  444. rb.Push(ResultSuccess);
  445. }
  446. Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
  447. if (camera_handle.npad_id >
  448. static_cast<u8>(NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
  449. return InvalidIrCameraHandle;
  450. }
  451. if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
  452. return InvalidIrCameraHandle;
  453. }
  454. return ResultSuccess;
  455. }
  456. Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
  457. const Core::IrSensor::IrCameraHandle& camera_handle) {
  458. const auto npad_id_max_index = static_cast<u8>(sizeof(StatusManager::device));
  459. ASSERT_MSG(camera_handle.npad_id < npad_id_max_index, "invalid npad_id");
  460. return shared_memory->device[camera_handle.npad_id];
  461. }
  462. IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
  463. // clang-format off
  464. static const FunctionInfo functions[] = {
  465. {500, nullptr, "SetAppletResourceUserId"},
  466. {501, nullptr, "RegisterAppletResourceUserId"},
  467. {502, nullptr, "UnregisterAppletResourceUserId"},
  468. {503, nullptr, "EnableAppletToGetInput"},
  469. };
  470. // clang-format on
  471. RegisterHandlers(functions);
  472. }
  473. IRS_SYS::~IRS_SYS() = default;
  474. } // namespace Service::IRS