diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6c6a7387..95df313e 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -247,6 +247,7 @@ add_library(skyline SHARED ${source_DIR}/skyline/services/hid/IHidServer.cpp ${source_DIR}/skyline/services/hid/IAppletResource.cpp ${source_DIR}/skyline/services/hid/IActiveVibrationDeviceList.cpp + ${source_DIR}/skyline/services/irs/IIrSensorServer.cpp ${source_DIR}/skyline/services/timesrv/common.cpp ${source_DIR}/skyline/services/timesrv/core.cpp ${source_DIR}/skyline/services/timesrv/time_shared_memory.cpp diff --git a/app/src/main/cpp/skyline/services/irs/IIrSensorServer.cpp b/app/src/main/cpp/skyline/services/irs/IIrSensorServer.cpp new file mode 100644 index 00000000..747f6a5a --- /dev/null +++ b/app/src/main/cpp/skyline/services/irs/IIrSensorServer.cpp @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#include "IIrSensorServer.h" +#include +#include +#include "iirsensor_core.h" +using namespace skyline::input; +namespace skyline::service::irs { + IIrSensorServer::IIrSensorServer(const DeviceState &state, ServiceManager &manager, SharedIirCore &core) : BaseService(state, manager), core(core) {} + + Result IIrSensorServer::GetNpadIrCameraHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + auto id{request.Pop()}; + if (id > NpadId::Player8 && id != NpadId::Handheld && id != NpadId::Unknown) + return result::InvalidNpadId; + return {}; + } + + Result IIrSensorServer::ActivateIrsensorWithFunctionLevel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + return {}; + } + + Result IIrSensorServer::GetIrsensorSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + auto handle{state.process->InsertItem(core.sharedIirMemory)}; + + response.copyHandles.push_back(handle); + return {}; + } + +} diff --git a/app/src/main/cpp/skyline/services/irs/IIrSensorServer.h b/app/src/main/cpp/skyline/services/irs/IIrSensorServer.h new file mode 100644 index 00000000..572573db --- /dev/null +++ b/app/src/main/cpp/skyline/services/irs/IIrSensorServer.h @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#pragma once + +#include +#include + +namespace skyline::service::irs { + struct SharedIirCore; + + namespace result { + constexpr Result InvalidNpadId(205, 709); + } + class IIrSensorServer : public BaseService { + private: + SharedIirCore &core; + + public: + IIrSensorServer(const DeviceState &state, ServiceManager &manager, SharedIirCore &core); + + /** + * @brief Returns an IirCameraHandle given the NpadIdType + * @url https://switchbrew.org/wiki/HID_services#GetNpadIrCameraHandle + */ + Result GetNpadIrCameraHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** + * @brief Requests a PID and Fuction Level and activates the IR sensor + * @url https://switchbrew.org/wiki/HID_services#ActivateIrsensorWithFunctionLevel + */ + Result ActivateIrsensorWithFunctionLevel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + /** + * @brief Returns the shared memory handle for the IR sensor + * @url https://switchbrew.org/wiki/HID_services#GetIrsensorSharedMemoryHandle + */ + Result GetIrsensorSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + + SERVICE_DECL( + SFUNC(0x130, IIrSensorServer, GetIrsensorSharedMemoryHandle), + SFUNC(0x137, IIrSensorServer, GetNpadIrCameraHandle), + SFUNC(0x13F, IIrSensorServer, ActivateIrsensorWithFunctionLevel) + ); + }; +} + diff --git a/app/src/main/cpp/skyline/services/irs/iirsensor_core.h b/app/src/main/cpp/skyline/services/irs/iirsensor_core.h new file mode 100644 index 00000000..6186c0d4 --- /dev/null +++ b/app/src/main/cpp/skyline/services/irs/iirsensor_core.h @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#pragma once + +#include +#include + +namespace skyline::service::irs { + struct SharedIirCore { + static constexpr u32 IirSharedMemSize{0x8000}; + std::shared_ptr sharedIirMemory; + + SharedIirCore(const DeviceState &state) : sharedIirMemory(std::make_shared(state, IirSharedMemSize)) {} + }; +} \ No newline at end of file diff --git a/app/src/main/cpp/skyline/services/serviceman.cpp b/app/src/main/cpp/skyline/services/serviceman.cpp index 86720a2d..0cdc816d 100644 --- a/app/src/main/cpp/skyline/services/serviceman.cpp +++ b/app/src/main/cpp/skyline/services/serviceman.cpp @@ -14,6 +14,8 @@ #include "codec/IHardwareOpusDecoderManager.h" #include "fatalsrv/IService.h" #include "hid/IHidServer.h" +#include "irs/IIrSensorServer.h" +#include "irs/iirsensor_core.h" #include "timesrv/IStaticService.h" #include "glue/IStaticService.h" #include "glue/IWriterForSystem.h" @@ -52,9 +54,10 @@ namespace skyline::service { struct GlobalServiceState { timesrv::core::TimeServiceObject timesrv; pl::SharedFontCore sharedFontCore; + irs::SharedIirCore sharedIirCore; nvdrv::Driver nvdrv; - explicit GlobalServiceState(const DeviceState &state) : timesrv(state), sharedFontCore(state), nvdrv(state) {} + explicit GlobalServiceState(const DeviceState &state) : timesrv(state), sharedFontCore(state), sharedIirCore(state), nvdrv(state) {} }; ServiceManager::ServiceManager(const DeviceState &state) : state(state), smUserInterface(std::make_shared(state, *this)), globalServiceState(std::make_shared(state)) {} @@ -75,6 +78,7 @@ namespace skyline::service { SERVICE_CASE(audio::IAudioRendererManager, "audren:u") SERVICE_CASE(codec::IHardwareOpusDecoderManager, "hwopus") SERVICE_CASE(hid::IHidServer, "hid") + SERVICE_CASE(irs::IIrSensorServer, "irs", globalServiceState->sharedIirCore) SERVICE_CASE(timesrv::IStaticService, "time:s", globalServiceState->timesrv, timesrv::constant::StaticServiceSystemPermissions) // Both of these would be registered after TimeServiceManager::Setup normally but we call that in the GlobalServiceState constructor so can just list them here directly SERVICE_CASE(timesrv::IStaticService, "time:su", globalServiceState->timesrv, timesrv::constant::StaticServiceSystemUpdatePermissions) SERVICE_CASE(glue::IStaticService, "time:a", globalServiceState->timesrv.managerServer.GetStaticServiceAsAdmin(state, *this), globalServiceState->timesrv, timesrv::constant::StaticServiceAdminPermissions)