irs.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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/hle/kernel/k_shared_memory.h"
  8. #include "core/hle/kernel/k_transfer_memory.h"
  9. #include "core/hle/kernel/kernel.h"
  10. #include "core/hle/service/cmif_serialization.h"
  11. #include "core/hle/service/hid/irs.h"
  12. #include "core/hle/service/ipc_helpers.h"
  13. #include "core/memory.h"
  14. #include "hid_core/frontend/emulated_controller.h"
  15. #include "hid_core/hid_core.h"
  16. #include "hid_core/hid_result.h"
  17. #include "hid_core/hid_util.h"
  18. #include "hid_core/irsensor/clustering_processor.h"
  19. #include "hid_core/irsensor/image_transfer_processor.h"
  20. #include "hid_core/irsensor/ir_led_processor.h"
  21. #include "hid_core/irsensor/moment_processor.h"
  22. #include "hid_core/irsensor/pointing_processor.h"
  23. #include "hid_core/irsensor/tera_plugin_processor.h"
  24. namespace Service::IRS {
  25. IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
  26. // clang-format off
  27. static const FunctionInfo functions[] = {
  28. {302, C<&IRS::ActivateIrsensor>, "ActivateIrsensor"},
  29. {303, C<&IRS::DeactivateIrsensor>, "DeactivateIrsensor"},
  30. {304, C<&IRS::GetIrsensorSharedMemoryHandle>, "GetIrsensorSharedMemoryHandle"},
  31. {305, C<&IRS::StopImageProcessor>, "StopImageProcessor"},
  32. {306, C<&IRS::RunMomentProcessor>, "RunMomentProcessor"},
  33. {307, C<&IRS::RunClusteringProcessor>, "RunClusteringProcessor"},
  34. {308, C<&IRS::RunImageTransferProcessor>, "RunImageTransferProcessor"},
  35. {309, C<&IRS::GetImageTransferProcessorState>, "GetImageTransferProcessorState"},
  36. {310, C<&IRS::RunTeraPluginProcessor>, "RunTeraPluginProcessor"},
  37. {311, C<&IRS::GetNpadIrCameraHandle>, "GetNpadIrCameraHandle"},
  38. {312, C<&IRS::RunPointingProcessor>, "RunPointingProcessor"},
  39. {313, C<&IRS::SuspendImageProcessor>, "SuspendImageProcessor"},
  40. {314, C<&IRS::CheckFirmwareVersion>, "CheckFirmwareVersion"},
  41. {315, C<&IRS::SetFunctionLevel>, "SetFunctionLevel"},
  42. {316, C<&IRS::RunImageTransferExProcessor>, "RunImageTransferExProcessor"},
  43. {317, C<&IRS::RunIrLedProcessor>, "RunIrLedProcessor"},
  44. {318, C<&IRS::StopImageProcessorAsync>, "StopImageProcessorAsync"},
  45. {319, C<&IRS::ActivateIrsensorWithFunctionLevel>, "ActivateIrsensorWithFunctionLevel"},
  46. };
  47. // clang-format on
  48. u8* raw_shared_memory = system.Kernel().GetIrsSharedMem().GetPointer();
  49. RegisterHandlers(functions);
  50. shared_memory = std::construct_at(reinterpret_cast<StatusManager*>(raw_shared_memory));
  51. npad_device = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
  52. }
  53. IRS::~IRS() = default;
  54. Result IRS::ActivateIrsensor(ClientAppletResourceUserId aruid) {
  55. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
  56. R_SUCCEED();
  57. }
  58. Result IRS::DeactivateIrsensor(ClientAppletResourceUserId aruid) {
  59. LOG_WARNING(Service_IRS, "(STUBBED) called, applet_resource_user_id={}", aruid.pid);
  60. R_SUCCEED();
  61. }
  62. Result IRS::GetIrsensorSharedMemoryHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory,
  63. ClientAppletResourceUserId aruid) {
  64. LOG_DEBUG(Service_IRS, "called, applet_resource_user_id={}", aruid.pid);
  65. *out_shared_memory = &system.Kernel().GetIrsSharedMem();
  66. R_SUCCEED();
  67. }
  68. Result IRS::StopImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
  69. ClientAppletResourceUserId aruid) {
  70. LOG_WARNING(Service_IRS,
  71. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  72. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  73. R_TRY(IsIrCameraHandleValid(camera_handle));
  74. // TODO: Stop Image processor
  75. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  76. Common::Input::PollingMode::Active);
  77. R_SUCCEED();
  78. }
  79. Result IRS::RunMomentProcessor(
  80. Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
  81. const Core::IrSensor::PackedMomentProcessorConfig& processor_config) {
  82. LOG_WARNING(Service_IRS,
  83. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  84. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  85. R_TRY(IsIrCameraHandleValid(camera_handle));
  86. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  87. MakeProcessorWithCoreContext<MomentProcessor>(camera_handle, device);
  88. auto& image_transfer_processor = GetProcessor<MomentProcessor>(camera_handle);
  89. image_transfer_processor.SetConfig(processor_config);
  90. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  91. Common::Input::PollingMode::IR);
  92. R_SUCCEED();
  93. }
  94. Result IRS::RunClusteringProcessor(
  95. Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
  96. const Core::IrSensor::PackedClusteringProcessorConfig& processor_config) {
  97. LOG_WARNING(Service_IRS,
  98. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  99. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  100. R_TRY(IsIrCameraHandleValid(camera_handle));
  101. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  102. MakeProcessorWithCoreContext<ClusteringProcessor>(camera_handle, device);
  103. auto& image_transfer_processor = GetProcessor<ClusteringProcessor>(camera_handle);
  104. image_transfer_processor.SetConfig(processor_config);
  105. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  106. Common::Input::PollingMode::IR);
  107. R_SUCCEED();
  108. }
  109. Result IRS::RunImageTransferProcessor(
  110. Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
  111. const Core::IrSensor::PackedImageTransferProcessorConfig& processor_config,
  112. u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem) {
  113. ASSERT_MSG(t_mem->GetSize() == transfer_memory_size, "t_mem has incorrect size");
  114. LOG_INFO(Service_IRS,
  115. "called, npad_type={}, npad_id={}, transfer_memory_size={}, transfer_memory_size={}, "
  116. "applet_resource_user_id={}",
  117. camera_handle.npad_type, camera_handle.npad_id, transfer_memory_size, t_mem->GetSize(),
  118. aruid.pid);
  119. R_TRY(IsIrCameraHandleValid(camera_handle));
  120. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  121. MakeProcessorWithCoreContext<ImageTransferProcessor>(camera_handle, device);
  122. auto& image_transfer_processor = GetProcessor<ImageTransferProcessor>(camera_handle);
  123. image_transfer_processor.SetConfig(processor_config);
  124. image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
  125. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  126. Common::Input::PollingMode::IR);
  127. R_SUCCEED();
  128. }
  129. Result IRS::GetImageTransferProcessorState(
  130. Out<Core::IrSensor::ImageTransferProcessorState> out_state,
  131. Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
  132. OutBuffer<BufferAttr_HipcMapAlias> out_buffer_data) {
  133. LOG_DEBUG(Service_IRS, "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  134. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  135. R_TRY(IsIrCameraHandleValid(camera_handle));
  136. const auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  137. R_TRY(IsIrCameraHandleValid(camera_handle));
  138. R_UNLESS(device.mode == Core::IrSensor::IrSensorMode::ImageTransferProcessor,
  139. InvalidProcessorState);
  140. *out_state = GetProcessor<ImageTransferProcessor>(camera_handle).GetState(out_buffer_data);
  141. R_SUCCEED();
  142. }
  143. Result IRS::RunTeraPluginProcessor(Core::IrSensor::IrCameraHandle camera_handle,
  144. Core::IrSensor::PackedTeraPluginProcessorConfig processor_config,
  145. ClientAppletResourceUserId aruid) {
  146. LOG_WARNING(Service_IRS,
  147. "(STUBBED) called, npad_type={}, npad_id={}, mode={}, mcu_version={}.{}, "
  148. "applet_resource_user_id={}",
  149. camera_handle.npad_type, camera_handle.npad_id, processor_config.mode,
  150. processor_config.required_mcu_version.major,
  151. processor_config.required_mcu_version.minor, aruid.pid);
  152. R_TRY(IsIrCameraHandleValid(camera_handle));
  153. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  154. MakeProcessor<TeraPluginProcessor>(camera_handle, device);
  155. auto& image_transfer_processor = GetProcessor<TeraPluginProcessor>(camera_handle);
  156. image_transfer_processor.SetConfig(processor_config);
  157. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  158. Common::Input::PollingMode::IR);
  159. R_SUCCEED();
  160. }
  161. Result IRS::GetNpadIrCameraHandle(Out<Core::IrSensor::IrCameraHandle> out_camera_handle,
  162. Core::HID::NpadIdType npad_id) {
  163. R_UNLESS(HID::IsNpadIdValid(npad_id), HID::ResultInvalidNpadId);
  164. *out_camera_handle = {
  165. .npad_id = static_cast<u8>(HID::NpadIdTypeToIndex(npad_id)),
  166. .npad_type = Core::HID::NpadStyleIndex::None,
  167. };
  168. LOG_INFO(Service_IRS, "called, npad_id={}, camera_npad_id={}, camera_npad_type={}", npad_id,
  169. out_camera_handle->npad_id, out_camera_handle->npad_type);
  170. R_SUCCEED();
  171. }
  172. Result IRS::RunPointingProcessor(
  173. Core::IrSensor::IrCameraHandle camera_handle,
  174. const Core::IrSensor::PackedPointingProcessorConfig& processor_config,
  175. ClientAppletResourceUserId aruid) {
  176. LOG_WARNING(
  177. Service_IRS,
  178. "(STUBBED) called, npad_type={}, npad_id={}, mcu_version={}.{}, applet_resource_user_id={}",
  179. camera_handle.npad_type, camera_handle.npad_id, processor_config.required_mcu_version.major,
  180. processor_config.required_mcu_version.minor, aruid.pid);
  181. R_TRY(IsIrCameraHandleValid(camera_handle));
  182. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  183. MakeProcessor<PointingProcessor>(camera_handle, device);
  184. auto& image_transfer_processor = GetProcessor<PointingProcessor>(camera_handle);
  185. image_transfer_processor.SetConfig(processor_config);
  186. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  187. Common::Input::PollingMode::IR);
  188. R_SUCCEED();
  189. }
  190. Result IRS::SuspendImageProcessor(Core::IrSensor::IrCameraHandle camera_handle,
  191. ClientAppletResourceUserId aruid) {
  192. LOG_WARNING(Service_IRS,
  193. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  194. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  195. R_TRY(IsIrCameraHandleValid(camera_handle));
  196. // TODO: Suspend image processor
  197. R_SUCCEED();
  198. }
  199. Result IRS::CheckFirmwareVersion(Core::IrSensor::IrCameraHandle camera_handle,
  200. Core::IrSensor::PackedMcuVersion mcu_version,
  201. ClientAppletResourceUserId aruid) {
  202. LOG_WARNING(
  203. Service_IRS,
  204. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}, mcu_version={}.{}",
  205. camera_handle.npad_type, camera_handle.npad_id, aruid.pid, mcu_version.major,
  206. mcu_version.minor);
  207. R_TRY(IsIrCameraHandleValid(camera_handle));
  208. // TODO: Check firmware version
  209. R_SUCCEED();
  210. }
  211. Result IRS::SetFunctionLevel(Core::IrSensor::IrCameraHandle camera_handle,
  212. Core::IrSensor::PackedFunctionLevel function_level,
  213. ClientAppletResourceUserId aruid) {
  214. LOG_WARNING(
  215. Service_IRS,
  216. "(STUBBED) called, npad_type={}, npad_id={}, function_level={}, applet_resource_user_id={}",
  217. camera_handle.npad_type, camera_handle.npad_id, function_level.function_level, aruid.pid);
  218. R_TRY(IsIrCameraHandleValid(camera_handle));
  219. // TODO: Set Function level
  220. R_SUCCEED();
  221. }
  222. Result IRS::RunImageTransferExProcessor(
  223. Core::IrSensor::IrCameraHandle camera_handle, ClientAppletResourceUserId aruid,
  224. const Core::IrSensor::PackedImageTransferProcessorExConfig& processor_config,
  225. u64 transfer_memory_size, InCopyHandle<Kernel::KTransferMemory> t_mem) {
  226. ASSERT_MSG(t_mem->GetSize() == transfer_memory_size, "t_mem has incorrect size");
  227. LOG_INFO(Service_IRS,
  228. "called, npad_type={}, npad_id={}, transfer_memory_size={}, "
  229. "applet_resource_user_id={}",
  230. camera_handle.npad_type, camera_handle.npad_id, transfer_memory_size, aruid.pid);
  231. R_TRY(IsIrCameraHandleValid(camera_handle));
  232. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  233. MakeProcessorWithCoreContext<ImageTransferProcessor>(camera_handle, device);
  234. auto& image_transfer_processor = GetProcessor<ImageTransferProcessor>(camera_handle);
  235. image_transfer_processor.SetConfig(processor_config);
  236. image_transfer_processor.SetTransferMemoryAddress(t_mem->GetSourceAddress());
  237. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  238. Common::Input::PollingMode::IR);
  239. R_SUCCEED();
  240. }
  241. Result IRS::RunIrLedProcessor(Core::IrSensor::IrCameraHandle camera_handle,
  242. Core::IrSensor::PackedIrLedProcessorConfig processor_config,
  243. ClientAppletResourceUserId aruid) {
  244. LOG_WARNING(Service_IRS,
  245. "(STUBBED) called, npad_type={}, npad_id={}, light_target={}, mcu_version={}.{} "
  246. "applet_resource_user_id={}",
  247. camera_handle.npad_type, camera_handle.npad_id, processor_config.light_target,
  248. processor_config.required_mcu_version.major,
  249. processor_config.required_mcu_version.minor, aruid.pid);
  250. R_TRY(IsIrCameraHandleValid(camera_handle));
  251. auto& device = GetIrCameraSharedMemoryDeviceEntry(camera_handle);
  252. MakeProcessor<IrLedProcessor>(camera_handle, device);
  253. auto& image_transfer_processor = GetProcessor<IrLedProcessor>(camera_handle);
  254. image_transfer_processor.SetConfig(processor_config);
  255. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  256. Common::Input::PollingMode::IR);
  257. R_SUCCEED();
  258. }
  259. Result IRS::StopImageProcessorAsync(Core::IrSensor::IrCameraHandle camera_handle,
  260. ClientAppletResourceUserId aruid) {
  261. LOG_WARNING(Service_IRS,
  262. "(STUBBED) called, npad_type={}, npad_id={}, applet_resource_user_id={}",
  263. camera_handle.npad_type, camera_handle.npad_id, aruid.pid);
  264. R_TRY(IsIrCameraHandleValid(camera_handle));
  265. // TODO: Stop image processor async
  266. npad_device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex,
  267. Common::Input::PollingMode::Active);
  268. R_SUCCEED();
  269. }
  270. Result IRS::ActivateIrsensorWithFunctionLevel(Core::IrSensor::PackedFunctionLevel function_level,
  271. ClientAppletResourceUserId aruid) {
  272. LOG_WARNING(Service_IRS, "(STUBBED) called, function_level={}, applet_resource_user_id={}",
  273. function_level.function_level, aruid.pid);
  274. R_SUCCEED();
  275. }
  276. Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_handle) const {
  277. if (camera_handle.npad_id >
  278. static_cast<u8>(HID::NpadIdTypeToIndex(Core::HID::NpadIdType::Handheld))) {
  279. return InvalidIrCameraHandle;
  280. }
  281. if (camera_handle.npad_type != Core::HID::NpadStyleIndex::None) {
  282. return InvalidIrCameraHandle;
  283. }
  284. return ResultSuccess;
  285. }
  286. Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
  287. const Core::IrSensor::IrCameraHandle& camera_handle) {
  288. const auto npad_id_max_index = static_cast<u8>(sizeof(StatusManager::device));
  289. ASSERT_MSG(camera_handle.npad_id < npad_id_max_index, "invalid npad_id");
  290. return shared_memory->device[camera_handle.npad_id];
  291. }
  292. IRS_SYS::IRS_SYS(Core::System& system_) : ServiceFramework{system_, "irs:sys"} {
  293. // clang-format off
  294. static const FunctionInfo functions[] = {
  295. {500, nullptr, "SetAppletResourceUserId"},
  296. {501, nullptr, "RegisterAppletResourceUserId"},
  297. {502, nullptr, "UnregisterAppletResourceUserId"},
  298. {503, nullptr, "EnableAppletToGetInput"},
  299. };
  300. // clang-format on
  301. RegisterHandlers(functions);
  302. }
  303. IRS_SYS::~IRS_SYS() = default;
  304. } // namespace Service::IRS