irs.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  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/hid_util.h"
  14. #include "core/hle/service/hid/irs.h"
  15. #include "core/hle/service/hid/irsensor/clustering_processor.h"
  16. #include "core/hle/service/hid/irsensor/image_transfer_processor.h"
  17. #include "core/hle/service/hid/irsensor/ir_led_processor.h"
  18. #include "core/hle/service/hid/irsensor/moment_processor.h"
  19. #include "core/hle/service/hid/irsensor/pointing_processor.h"
  20. #include "core/hle/service/hid/irsensor/tera_plugin_processor.h"
  21. #include "core/hle/service/ipc_helpers.h"
  22. #include "core/memory.h"
  23. namespace Service::IRS {
  24. IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
  25. // clang-format off
  26. static const FunctionInfo functions[] = {
  27. {302, &IRS::ActivateIrsensor, "ActivateIrsensor"},
  28. {303, &IRS::DeactivateIrsensor, "DeactivateIrsensor"},
  29. {304, &IRS::GetIrsensorSharedMemoryHandle, "GetIrsensorSharedMemoryHandle"},
  30. {305, &IRS::StopImageProcessor, "StopImageProcessor"},
  31. {306, &IRS::RunMomentProcessor, "RunMomentProcessor"},
  32. {307, &IRS::RunClusteringProcessor, "RunClusteringProcessor"},
  33. {308, &IRS::RunImageTransferProcessor, "RunImageTransferProcessor"},
  34. {309, &IRS::GetImageTransferProcessorState, "GetImageTransferProcessorState"},
  35. {310, &IRS::RunTeraPluginProcessor, "RunTeraPluginProcessor"},
  36. {311, &IRS::GetNpadIrCameraHandle, "GetNpadIrCameraHandle"},
  37. {312, &IRS::RunPointingProcessor, "RunPointingProcessor"},
  38. {313, &IRS::SuspendImageProcessor, "SuspendImageProcessor"},
  39. {314, &IRS::CheckFirmwareVersion, "CheckFirmwareVersion"},
  40. {315, &IRS::SetFunctionLevel, "SetFunctionLevel"},
  41. {316, &IRS::RunImageTransferExProcessor, "RunImageTransferExProcessor"},
  42. {317, &IRS::RunIrLedProcessor, "RunIrLedProcessor"},
  43. {318, &IRS::StopImageProcessorAsync, "StopImageProcessorAsync"},
  44. {319, &IRS::ActivateIrsensorWithFunctionLevel, "ActivateIrsensorWithFunctionLevel"},
  45. };
  46. // clang-format on
  47. u8* raw_shared_memory = system.Kernel().GetIrsSharedMem().GetPointer();
  48. RegisterHandlers(functions);
  49. shared_memory = std::construct_at(reinterpret_cast<StatusManager*>(raw_shared_memory));
  50. npad_device = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
  51. }
  52. IRS::~IRS() = default;
  53. void IRS::ActivateIrsensor(HLERequestContext& ctx) {
  54. IPC::RequestParser rp{ctx};
  55. const auto applet_resource_user_id{rp.Pop<u64>()};
  56. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
  57. applet_resource_user_id);
  58. IPC::ResponseBuilder rb{ctx, 2};
  59. rb.Push(ResultSuccess);
  60. }
  61. void IRS::DeactivateIrsensor(HLERequestContext& ctx) {
  62. IPC::RequestParser rp{ctx};
  63. const auto applet_resource_user_id{rp.Pop<u64>()};
  64. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}",
  65. applet_resource_user_id);
  66. IPC::ResponseBuilder rb{ctx, 2};
  67. rb.Push(ResultSuccess);
  68. }
  69. void IRS::GetIrsensorSharedMemoryHandle(HLERequestContext& ctx) {
  70. IPC::RequestParser rp{ctx};
  71. const auto applet_resource_user_id{rp.Pop<u64>()};
  72. LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", applet_resource_user_id);
  73. IPC::ResponseBuilder rb{ctx, 2, 1};
  74. rb.Push(ResultSuccess);
  75. rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem());
  76. }
  77. void IRS::StopImageProcessor(HLERequestContext& ctx) {
  78. IPC::RequestParser rp{ctx};
  79. struct Parameters {
  80. Core::IrSensor::IrCameraHandle camera_handle;
  81. INSERT_PADDING_WORDS_NOINIT(1);
  82. u64 applet_resource_user_id;
  83. };
  84. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  85. const auto parameters{rp.PopRaw<Parameters>()};
  86. LOG_WARNING(Service_IRS,
  87. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  88. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  89. parameters.applet_resource_user_id);
  90. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  91. if (result.IsSuccess()) {
  92. // TODO: Stop Image processor
  93. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  94. Common::Input::PollingMode::Active);
  95. result = ResultSuccess;
  96. }
  97. IPC::ResponseBuilder rb{ctx, 2};
  98. rb.Push(result);
  99. }
  100. void IRS::RunMomentProcessor(HLERequestContext& ctx) {
  101. IPC::RequestParser rp{ctx};
  102. struct Parameters {
  103. Core::IrSensor::IrCameraHandle camera_handle;
  104. INSERT_PADDING_WORDS_NOINIT(1);
  105. u64 applet_resource_user_id;
  106. Core::IrSensor::PackedMomentProcessorConfig processor_config;
  107. };
  108. static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
  109. const auto parameters{rp.PopRaw<Parameters>()};
  110. LOG_WARNING(Service_IRS,
  111. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  112. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  113. parameters.applet_resource_user_id);
  114. const auto result = IsIrCameraHandleValid(parameters.camera_handle);
  115. if (result.IsSuccess()) {
  116. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  117. MakeProcessorWithCoreContext<MomentProcessor>(parameters.camera_handle, device);
  118. auto& image_transfer_processor = GetProcessor<MomentProcessor>(parameters.camera_handle);
  119. image_transfer_processor.SetConfig(parameters.processor_config);
  120. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  121. Common::Input::PollingMode::IR);
  122. }
  123. IPC::ResponseBuilder rb{ctx, 2};
  124. rb.Push(result);
  125. }
  126. void IRS::RunClusteringProcessor(HLERequestContext& ctx) {
  127. IPC::RequestParser rp{ctx};
  128. struct Parameters {
  129. Core::IrSensor::IrCameraHandle camera_handle;
  130. INSERT_PADDING_WORDS_NOINIT(1);
  131. u64 applet_resource_user_id;
  132. Core::IrSensor::PackedClusteringProcessorConfig processor_config;
  133. };
  134. static_assert(sizeof(Parameters) == 0x38, "Parameters has incorrect size.");
  135. const auto parameters{rp.PopRaw<Parameters>()};
  136. LOG_WARNING(Service_IRS,
  137. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  138. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  139. parameters.applet_resource_user_id);
  140. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  141. if (result.IsSuccess()) {
  142. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  143. MakeProcessorWithCoreContext<ClusteringProcessor>(parameters.camera_handle, device);
  144. auto& image_transfer_processor =
  145. GetProcessor<ClusteringProcessor>(parameters.camera_handle);
  146. image_transfer_processor.SetConfig(parameters.processor_config);
  147. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  148. Common::Input::PollingMode::IR);
  149. }
  150. IPC::ResponseBuilder rb{ctx, 2};
  151. rb.Push(result);
  152. }
  153. void IRS::RunImageTransferProcessor(HLERequestContext& ctx) {
  154. IPC::RequestParser rp{ctx};
  155. struct Parameters {
  156. Core::IrSensor::IrCameraHandle camera_handle;
  157. INSERT_PADDING_WORDS_NOINIT(1);
  158. u64 applet_resource_user_id;
  159. Core::IrSensor::PackedImageTransferProcessorConfig processor_config;
  160. u32 transfer_memory_size;
  161. };
  162. static_assert(sizeof(Parameters) == 0x30, "Parameters has incorrect size.");
  163. const auto parameters{rp.PopRaw<Parameters>()};
  164. const auto t_mem_handle{ctx.GetCopyHandle(0)};
  165. auto t_mem = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(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>(HID::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 = ctx.GetObjectFromHandle<Kernel::KTransferMemory>(t_mem_handle);
  366. LOG_INFO(Service_IRS,
  367. "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
  368. "applet_resource_user_id={}",
  369. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  370. parameters.transfer_memory_size, parameters.applet_resource_user_id);
  371. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  372. if (result.IsSuccess()) {
  373. auto& device = GetIrCameraSharedMemoryDeviceEntry(parameters.camera_handle);
  374. MakeProcessorWithCoreContext<ImageTransferProcessor>(parameters.camera_handle, device);
  375. auto& image_transfer_processor =
  376. GetProcessor<ImageTransferProcessor>(parameters.camera_handle);
  377. image_transfer_processor.SetConfig(parameters.processor_config);
  378. image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
  379. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  380. Common::Input::PollingMode::IR);
  381. }
  382. IPC::ResponseBuilder rb{ctx, 2};
  383. rb.Push(result);
  384. }
  385. void IRS::RunIrLedProcessor(HLERequestContext& ctx) {
  386. IPC::RequestParser rp{ctx};
  387. const auto camera_handle{rp.PopRaw<Core::IrSensor::IrCameraHandle>()};
  388. const auto processor_config{rp.PopRaw<Core::IrSensor::PackedIrLedProcessorConfig>()};
  389. const auto applet_resource_user_id{rp.Pop<u64>()};
  390. LOG_WARNING(Service_IRS,
  391. "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
  392. "applet_resource_user_id={}",
  393. camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
  394. processor_config.required_mcu_version.major,
  395. processor_config.required_mcu_version.minor, applet_resource_user_id);
  396. auto result = IsIrCameraHandleValid(camera_handle);
  397. if (result.IsSuccess()) {
  398. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  399. MakeProcessor<IrLedProcessor>(camera_handle, device);
  400. auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
  401. image_transfer_processor.SetConfig(processor_config);
  402. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  403. Common::Input::PollingMode::IR);
  404. }
  405. IPC::ResponseBuilder rb{ctx, 2};
  406. rb.Push(result);
  407. }
  408. void IRS::StopImageProcessorAsync(HLERequestContext& ctx) {
  409. IPC::RequestParser rp{ctx};
  410. struct Parameters {
  411. Core::IrSensor::IrCameraHandle camera_handle;
  412. INSERT_PADDING_WORDS_NOINIT(1);
  413. u64 applet_resource_user_id;
  414. };
  415. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  416. const auto parameters{rp.PopRaw<Parameters>()};
  417. LOG_WARNING(Service_IRS,
  418. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  419. parameters.camera_handle.npad_type, parameters.camera_handle.npad_id,
  420. parameters.applet_resource_user_id);
  421. auto result = IsIrCameraHandleValid(parameters.camera_handle);
  422. if (result.IsSuccess()) {
  423. // TODO: Stop image processor async
  424. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  425. Common::Input::PollingMode::Active);
  426. result = ResultSuccess;
  427. }
  428. IPC::ResponseBuilder rb{ctx, 2};
  429. rb.Push(result);
  430. }
  431. void IRS::ActivateIrsensorWithFunctionLevel(HLERequestContext& ctx) {
  432. IPC::RequestParser rp{ctx};
  433. struct Parameters {
  434. Core::IrSensor::PackedFunctionLevel function_level;
  435. INSERT_PADDING_WORDS_NOINIT(1);
  436. u64 applet_resource_user_id;
  437. };
  438. static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
  439. const auto parameters{rp.PopRaw<Parameters>()};
  440. LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
  441. parameters.function_level.function_level, parameters.applet_resource_user_id);
  442. IPC::ResponseBuilder rb{ctx, 2};
  443. rb.Push(ResultSuccess);
  444. }
  445. Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
  446. if (camera_handle.npad_id >
  447. static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
  448. return InvalidIrCameraHandle;
  449. }
  450. if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
  451. return InvalidIrCameraHandle;
  452. }
  453. return ResultSuccess;
  454. }
  455. Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
  456. const Core::IrSensor::IrCameraHandle& camera_handle) {
  457. const auto npad_id_max_index = static_cast<u8>(sizeof(StatusManager::device));
  458. ASSERT_MSG(camera_handle.npad_id < npad_id_max_index, "invalid npad_id");
  459. return shared_memory->device[camera_handle.npad_id];
  460. }
  461. IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
  462. // clang-format off
  463. static const FunctionInfo functions[] = {
  464. {500, nullptr, "SetAppletResourceUserId"},
  465. {501, nullptr, "RegisterAppletResourceUserId"},
  466. {502, nullptr, "UnregisterAppletResourceUserId"},
  467. {503, nullptr, "EnableAppletToGetInput"},
  468. };
  469. // clang-format on
  470. RegisterHandlers(functions);
  471. }
  472. IRS_SYS::~IRS_SYS() = default;
  473. } // namespace Service::IRS