mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	service: hid: Introduce proper AppletResource emulation
This commit is contained in:
		
							parent
							
								
									167efb2d2b
								
							
						
					
					
						commit
						e445ef9d60
					
				| @ -541,6 +541,8 @@ add_library(core STATIC | ||||
|     hle/service/hid/xcd.cpp | ||||
|     hle/service/hid/xcd.h | ||||
|     hle/service/hid/errors.h | ||||
|     hle/service/hid/controllers/applet_resource.cpp | ||||
|     hle/service/hid/controllers/applet_resource.h | ||||
|     hle/service/hid/controllers/console_six_axis.cpp | ||||
|     hle/service/hid/controllers/console_six_axis.h | ||||
|     hle/service/hid/controllers/controller_base.cpp | ||||
|  | ||||
							
								
								
									
										199
									
								
								src/core/hle/service/hid/controllers/applet_resource.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								src/core/hle/service/hid/controllers/applet_resource.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,199 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_shared_memory.h" | ||||
| #include "core/hle/service/hid/controllers/applet_resource.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| AppletResource::AppletResource(Core::System& system_) : system{system_} {} | ||||
| 
 | ||||
| AppletResource::~AppletResource() = default; | ||||
| 
 | ||||
| Result AppletResource::CreateAppletResource(u64 aruid) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
| 
 | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return ResultAruidNotRegistered; | ||||
|     } | ||||
| 
 | ||||
|     if (data[index].flag.is_assigned) { | ||||
|         return ResultAruidAlreadyRegistered; | ||||
|     } | ||||
| 
 | ||||
|     // TODO: Here shared memory is created for the process we don't quite emulate this part so
 | ||||
|     // obtain this pointer from system
 | ||||
|     auto& shared_memory = system.Kernel().GetHidSharedMem(); | ||||
| 
 | ||||
|     data[index].shared_memory_handle = &shared_memory; | ||||
|     data[index].flag.is_assigned.Assign(true); | ||||
|     // TODO: InitializeSixAxisControllerConfig(false);
 | ||||
|     active_aruid = aruid; | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
| 
 | ||||
|     if (index < AruidIndexMax) { | ||||
|         return ResultAruidAlreadyRegistered; | ||||
|     } | ||||
| 
 | ||||
|     std::size_t data_index = AruidIndexMax; | ||||
|     for (std::size_t i = 0; i < AruidIndexMax; i++) { | ||||
|         if (!data[i].flag.is_initialized) { | ||||
|             data_index = i; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (data_index == AruidIndexMax) { | ||||
|         return ResultAruidNoAvailableEntries; | ||||
|     } | ||||
| 
 | ||||
|     AruidData& aruid_data = data[data_index]; | ||||
| 
 | ||||
|     aruid_data.aruid = aruid; | ||||
|     aruid_data.flag.is_initialized.Assign(true); | ||||
|     if (enable_input) { | ||||
|         aruid_data.flag.enable_pad_input.Assign(true); | ||||
|         aruid_data.flag.enable_six_axis_sensor.Assign(true); | ||||
|         aruid_data.flag.bit_18.Assign(true); | ||||
|         aruid_data.flag.enable_touchscreen.Assign(true); | ||||
|     } | ||||
| 
 | ||||
|     data_index = AruidIndexMax; | ||||
|     for (std::size_t i = 0; i < AruidIndexMax; i++) { | ||||
|         if (registration_list.flag[i] == RegistrationStatus::Initialized) { | ||||
|             if (registration_list.aruid[i] != aruid) { | ||||
|                 continue; | ||||
|             } | ||||
|             data_index = i; | ||||
|             break; | ||||
|         } | ||||
|         if (registration_list.flag[i] == RegistrationStatus::None) { | ||||
|             data_index = i; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (data_index == AruidIndexMax) { | ||||
|         return ResultSuccess; | ||||
|     } | ||||
| 
 | ||||
|     registration_list.flag[data_index] = RegistrationStatus::Initialized; | ||||
|     registration_list.aruid[data_index] = aruid; | ||||
| 
 | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { | ||||
|     u64 index = GetIndexFromAruid(aruid); | ||||
| 
 | ||||
|     if (index < AruidIndexMax) { | ||||
|         if (data[index].flag.is_assigned) { | ||||
|             data[index].shared_memory_handle = nullptr; | ||||
|             data[index].flag.is_assigned.Assign(false); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     index = GetIndexFromAruid(aruid); | ||||
|     if (index < AruidIndexMax) { | ||||
|         DestroySevenSixAxisTransferMemory(); | ||||
|         data[index].flag.raw = 0; | ||||
|         data[index].aruid = 0; | ||||
| 
 | ||||
|         index = GetIndexFromAruid(aruid); | ||||
|         if (index < AruidIndexMax) { | ||||
|             registration_list.flag[index] = RegistrationStatus::PendingDelete; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| u64 AppletResource::GetActiveAruid() { | ||||
|     return active_aruid; | ||||
| } | ||||
| 
 | ||||
| Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { | ||||
|     u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return ResultAruidNotRegistered; | ||||
|     } | ||||
| 
 | ||||
|     *out_handle = data[index].shared_memory_handle; | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| u64 AppletResource::GetIndexFromAruid(u64 aruid) { | ||||
|     for (std::size_t i = 0; i < AruidIndexMax; i++) { | ||||
|         if (registration_list.flag[i] == RegistrationStatus::Initialized && | ||||
|             registration_list.aruid[i] == aruid) { | ||||
|             return i; | ||||
|         } | ||||
|     } | ||||
|     return AruidIndexMax; | ||||
| } | ||||
| 
 | ||||
| Result AppletResource::DestroySevenSixAxisTransferMemory() { | ||||
|     // TODO
 | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| void AppletResource::EnableInput(u64 aruid, bool is_enabled) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.enable_pad_input.Assign(is_enabled); | ||||
|     data[index].flag.enable_touchscreen.Assign(is_enabled); | ||||
| } | ||||
| 
 | ||||
| void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.enable_six_axis_sensor.Assign(is_enabled); | ||||
| } | ||||
| 
 | ||||
| void AppletResource::EnablePadInput(u64 aruid, bool is_enabled) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.enable_pad_input.Assign(is_enabled); | ||||
| } | ||||
| 
 | ||||
| void AppletResource::EnableTouchScreen(u64 aruid, bool is_enabled) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.enable_touchscreen.Assign(is_enabled); | ||||
| } | ||||
| 
 | ||||
| void AppletResource::SetIsPalmaConnectable(u64 aruid, bool is_connectable) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.is_palma_connectable.Assign(is_connectable); | ||||
| } | ||||
| 
 | ||||
| void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) { | ||||
|     const u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     data[index].flag.enable_palma_boost_mode.Assign(is_enabled); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										87
									
								
								src/core/hle/service/hid/controllers/applet_resource.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/core/hle/service/hid/controllers/applet_resource.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,87 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/result.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
| 
 | ||||
| namespace Kernel { | ||||
| class KSharedMemory; | ||||
| } | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| class AppletResource { | ||||
| public: | ||||
|     explicit AppletResource(Core::System& system_); | ||||
|     ~AppletResource(); | ||||
| 
 | ||||
|     Result CreateAppletResource(u64 aruid); | ||||
| 
 | ||||
|     Result RegisterAppletResourceUserId(u64 aruid, bool enable_input); | ||||
|     void UnregisterAppletResourceUserId(u64 aruid); | ||||
| 
 | ||||
|     u64 GetActiveAruid(); | ||||
|     Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); | ||||
| 
 | ||||
|     u64 GetIndexFromAruid(u64 aruid); | ||||
| 
 | ||||
|     Result DestroySevenSixAxisTransferMemory(); | ||||
| 
 | ||||
|     void EnableInput(u64 aruid, bool is_enabled); | ||||
|     void EnableSixAxisSensor(u64 aruid, bool is_enabled); | ||||
|     void EnablePadInput(u64 aruid, bool is_enabled); | ||||
|     void EnableTouchScreen(u64 aruid, bool is_enabled); | ||||
|     void SetIsPalmaConnectable(u64 aruid, bool is_connectable); | ||||
|     void EnablePalmaBoostMode(u64 aruid, bool is_enabled); | ||||
| 
 | ||||
| private: | ||||
|     static constexpr std::size_t AruidIndexMax = 0x20; | ||||
| 
 | ||||
|     enum RegistrationStatus : u32 { | ||||
|         None, | ||||
|         Initialized, | ||||
|         PendingDelete, | ||||
|     }; | ||||
| 
 | ||||
|     struct DataStatusFlag { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
| 
 | ||||
|             BitField<0, 1, u32> is_initialized; | ||||
|             BitField<1, 1, u32> is_assigned; | ||||
|             BitField<16, 1, u32> enable_pad_input; | ||||
|             BitField<17, 1, u32> enable_six_axis_sensor; | ||||
|             BitField<18, 1, u32> bit_18; | ||||
|             BitField<19, 1, u32> is_palma_connectable; | ||||
|             BitField<20, 1, u32> enable_palma_boost_mode; | ||||
|             BitField<21, 1, u32> enable_touchscreen; | ||||
|         }; | ||||
|     }; | ||||
| 
 | ||||
|     struct AruidRegisterList { | ||||
|         std::array<RegistrationStatus, AruidIndexMax> flag{}; | ||||
|         std::array<u64, AruidIndexMax> aruid{}; | ||||
|     }; | ||||
|     static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size"); | ||||
| 
 | ||||
|     struct AruidData { | ||||
|         DataStatusFlag flag{}; | ||||
|         u64 aruid{}; | ||||
|         Kernel::KSharedMemory* shared_memory_handle{nullptr}; | ||||
|     }; | ||||
| 
 | ||||
|     u64 active_aruid{}; | ||||
|     AruidRegisterList registration_list{}; | ||||
|     std::array<AruidData, AruidIndexMax> data{}; | ||||
| 
 | ||||
|     Core::System& system; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
| @ -19,6 +19,11 @@ constexpr Result NpadIsSameType{ErrorModule::HID, 602}; | ||||
| constexpr Result InvalidNpadId{ErrorModule::HID, 709}; | ||||
| constexpr Result NpadNotConnected{ErrorModule::HID, 710}; | ||||
| constexpr Result InvalidArraySize{ErrorModule::HID, 715}; | ||||
| 
 | ||||
| constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044}; | ||||
| constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046}; | ||||
| constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047}; | ||||
| 
 | ||||
| constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/hid/hid.h" | ||||
| #include "core/hle/service/hid/hid_debug_server.h" | ||||
| #include "core/hle/service/hid/hid_firmware_settings.h" | ||||
| @ -20,6 +22,12 @@ void LoopProcess(Core::System& system) { | ||||
|     std::shared_ptr<HidFirmwareSettings> firmware_settings = | ||||
|         std::make_shared<HidFirmwareSettings>(); | ||||
| 
 | ||||
|     // TODO: Remove this hack until this service is emulated properly.
 | ||||
|     const auto process_list = system.Kernel().GetProcessList(); | ||||
|     if (!process_list.empty()) { | ||||
|         resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true); | ||||
|     } | ||||
| 
 | ||||
|     server_manager->RegisterNamedService( | ||||
|         "hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings)); | ||||
|     server_manager->RegisterNamedService( | ||||
|  | ||||
| @ -224,8 +224,13 @@ void IHidServer::CreateAppletResource(HLERequestContext& ctx) { | ||||
| 
 | ||||
|     LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||||
| 
 | ||||
|     Result result = GetResourceManager()->CreateAppletResource(applet_resource_user_id); | ||||
|     if (result.IsSuccess()) { | ||||
|         result = GetResourceManager()->GetNpad()->Activate(applet_resource_user_id); | ||||
|     } | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.Push(result); | ||||
|     rb.PushIpcInterface<IAppletResource>(system, resource_manager); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -3,6 +3,7 @@ | ||||
| 
 | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/npad.h" | ||||
| #include "core/hle/service/hid/controllers/palma.h" | ||||
| #include "core/hle/service/hid/controllers/touchscreen.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| #include "core/hle/service/hid/hid_system_server.h" | ||||
| @ -63,13 +64,13 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour | ||||
|         {329, nullptr, "DetachAbstractedPadAll"}, | ||||
|         {330, nullptr, "CheckAbstractedPadConnection"}, | ||||
|         {500, nullptr, "SetAppletResourceUserId"}, | ||||
|         {501, nullptr, "RegisterAppletResourceUserId"}, | ||||
|         {502, nullptr, "UnregisterAppletResourceUserId"}, | ||||
|         {503, nullptr, "EnableAppletToGetInput"}, | ||||
|         {501, &IHidSystemServer::RegisterAppletResourceUserId, "RegisterAppletResourceUserId"}, | ||||
|         {502, &IHidSystemServer::UnregisterAppletResourceUserId, "UnregisterAppletResourceUserId"}, | ||||
|         {503, &IHidSystemServer::EnableAppletToGetInput, "EnableAppletToGetInput"}, | ||||
|         {504, nullptr, "SetAruidValidForVibration"}, | ||||
|         {505, nullptr, "EnableAppletToGetSixAxisSensor"}, | ||||
|         {506, nullptr, "EnableAppletToGetPadInput"}, | ||||
|         {507, nullptr, "EnableAppletToGetTouchScreen"}, | ||||
|         {505, &IHidSystemServer::EnableAppletToGetSixAxisSensor, "EnableAppletToGetSixAxisSensor"}, | ||||
|         {506, &IHidSystemServer::EnableAppletToGetPadInput, "EnableAppletToGetPadInput"}, | ||||
|         {507, &IHidSystemServer::EnableAppletToGetTouchScreen, "EnableAppletToGetTouchScreen"}, | ||||
|         {510, nullptr, "SetVibrationMasterVolume"}, | ||||
|         {511, nullptr, "GetVibrationMasterVolume"}, | ||||
|         {512, nullptr, "BeginPermitVibrationSession"}, | ||||
| @ -420,6 +421,129 @@ void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) { | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| void IHidSystemServer::RegisterAppletResourceUserId(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         bool enable_input; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||||
| 
 | ||||
|     const auto parameters{rp.PopRaw<Parameters>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, enable_input={}, applet_resource_user_id={}", | ||||
|              parameters.enable_input, parameters.applet_resource_user_id); | ||||
| 
 | ||||
|     Result result = GetResourceManager()->RegisterAppletResourceUserId( | ||||
|         parameters.applet_resource_user_id, parameters.enable_input); | ||||
| 
 | ||||
|     if (result.IsSuccess()) { | ||||
|         // result = GetResourceManager()->GetNpad()->RegisterAppletResourceUserId(
 | ||||
|         //     parameters.applet_resource_user_id);
 | ||||
|     } | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::UnregisterAppletResourceUserId(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     u64 applet_resource_user_id{rp.Pop<u64>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); | ||||
| 
 | ||||
|     GetResourceManager()->UnregisterAppletResourceUserId(applet_resource_user_id); | ||||
|     // GetResourceManager()->GetNpad()->UnregisterAppletResourceUserId(applet_resource_user_id);
 | ||||
|     // GetResourceManager()->GetPalma()->UnregisterAppletResourceUserId(applet_resource_user_id);
 | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::EnableAppletToGetInput(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         bool is_enabled; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||||
| 
 | ||||
|     const auto parameters{rp.PopRaw<Parameters>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}", | ||||
|              parameters.is_enabled, parameters.applet_resource_user_id); | ||||
| 
 | ||||
|     GetResourceManager()->EnableInput(parameters.applet_resource_user_id, parameters.is_enabled); | ||||
|     // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
 | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::EnableAppletToGetSixAxisSensor(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         bool is_enabled; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||||
| 
 | ||||
|     const auto parameters{rp.PopRaw<Parameters>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}", | ||||
|              parameters.is_enabled, parameters.applet_resource_user_id); | ||||
| 
 | ||||
|     GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id, | ||||
|                                             parameters.is_enabled); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::EnableAppletToGetPadInput(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         bool is_enabled; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||||
| 
 | ||||
|     const auto parameters{rp.PopRaw<Parameters>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}", | ||||
|              parameters.is_enabled, parameters.applet_resource_user_id); | ||||
| 
 | ||||
|     GetResourceManager()->EnablePadInput(parameters.applet_resource_user_id, parameters.is_enabled); | ||||
|     // GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
 | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         bool is_enabled; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size."); | ||||
| 
 | ||||
|     const auto parameters{rp.PopRaw<Parameters>()}; | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}", | ||||
|              parameters.is_enabled, parameters.applet_resource_user_id); | ||||
| 
 | ||||
|     GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id, | ||||
|                                             parameters.is_enabled); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
| 
 | ||||
| void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) { | ||||
|     LOG_INFO(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
| @ -38,6 +38,12 @@ private: | ||||
|     void HasLeftRightBattery(HLERequestContext& ctx); | ||||
|     void GetUniquePadsFromNpad(HLERequestContext& ctx); | ||||
|     void GetIrSensorState(HLERequestContext& ctx); | ||||
|     void RegisterAppletResourceUserId(HLERequestContext& ctx); | ||||
|     void UnregisterAppletResourceUserId(HLERequestContext& ctx); | ||||
|     void EnableAppletToGetInput(HLERequestContext& ctx); | ||||
|     void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx); | ||||
|     void EnableAppletToGetPadInput(HLERequestContext& ctx); | ||||
|     void EnableAppletToGetTouchScreen(HLERequestContext& ctx); | ||||
|     void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); | ||||
|     void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); | ||||
|     void GetRegisteredDevices(HLERequestContext& ctx); | ||||
|  | ||||
| @ -9,6 +9,7 @@ | ||||
| #include "core/hle/service/hid/resource_manager.h" | ||||
| #include "core/hle/service/ipc_helpers.h" | ||||
| 
 | ||||
| #include "core/hle/service/hid/controllers/applet_resource.h" | ||||
| #include "core/hle/service/hid/controllers/console_six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/debug_pad.h" | ||||
| #include "core/hle/service/hid/controllers/gesture.h" | ||||
| @ -33,7 +34,9 @@ constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 10 | ||||
| constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000};         // (5ms, 200Hz)
 | ||||
| 
 | ||||
| ResourceManager::ResourceManager(Core::System& system_) | ||||
|     : system{system_}, service_context{system_, "hid"} {} | ||||
|     : system{system_}, service_context{system_, "hid"} { | ||||
|     applet_resource = std::make_shared<AppletResource>(system); | ||||
| } | ||||
| 
 | ||||
| ResourceManager::~ResourceManager() = default; | ||||
| 
 | ||||
| @ -77,6 +80,11 @@ void ResourceManager::Initialize() { | ||||
|     system.HIDCore().ReloadInputDevices(); | ||||
|     is_initialized = true; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { | ||||
|     return applet_resource; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const { | ||||
|     return capture_button; | ||||
| } | ||||
| @ -137,6 +145,46 @@ std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const { | ||||
|     return unique_pad; | ||||
| } | ||||
| 
 | ||||
| Result ResourceManager::CreateAppletResource(u64 aruid) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     return applet_resource->CreateAppletResource(aruid); | ||||
| } | ||||
| 
 | ||||
| Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     return applet_resource->RegisterAppletResourceUserId(aruid, bool_value); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     applet_resource->UnregisterAppletResourceUserId(aruid); | ||||
| } | ||||
| 
 | ||||
| Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     return applet_resource->GetSharedMemoryHandle(out_handle, aruid); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::EnableInput(u64 aruid, bool is_enabled) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     applet_resource->EnableInput(aruid, is_enabled); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     applet_resource->EnableSixAxisSensor(aruid, is_enabled); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     applet_resource->EnablePadInput(aruid, is_enabled); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     applet_resource->EnableTouchScreen(aruid, is_enabled); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::UpdateControllers(std::uintptr_t user_data, | ||||
|                                         std::chrono::nanoseconds ns_late) { | ||||
|     auto& core_timing = system.CoreTiming(); | ||||
| @ -172,14 +220,12 @@ void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose | ||||
| } | ||||
| 
 | ||||
| IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource) | ||||
|     : ServiceFramework{system_, "IAppletResource"} { | ||||
|     : ServiceFramework{system_, "IAppletResource"}, resource_manager{resource} { | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | ||||
|     }; | ||||
|     RegisterHandlers(functions); | ||||
| 
 | ||||
|     resource->Initialize(); | ||||
| 
 | ||||
|     // Register update callbacks
 | ||||
|     npad_update_event = Core::Timing::CreateEvent( | ||||
|         "HID::UpdatePadCallback", | ||||
| @ -233,9 +279,13 @@ IAppletResource::~IAppletResource() { | ||||
| void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_HID, "called"); | ||||
| 
 | ||||
|     Kernel::KSharedMemory* handle; | ||||
|     const u64 applet_resource_user_id = resource_manager->GetAppletResource()->GetActiveAruid(); | ||||
|     const auto result = resource_manager->GetSharedMemoryHandle(&handle, applet_resource_user_id); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); | ||||
|     rb.Push(result); | ||||
|     rb.PushCopyObjects(handle); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -6,11 +6,20 @@ | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
| 
 | ||||
| namespace Core::Timing { | ||||
| struct EventType; | ||||
| } | ||||
| 
 | ||||
| namespace Kernel { | ||||
| class KSharedMemory; | ||||
| } | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| class AppletResource; | ||||
| class Controller_Stubbed; | ||||
| class ConsoleSixAxis; | ||||
| class DebugPad; | ||||
| @ -38,6 +47,7 @@ public: | ||||
| 
 | ||||
|     void Initialize(); | ||||
| 
 | ||||
|     std::shared_ptr<AppletResource> GetAppletResource() const; | ||||
|     std::shared_ptr<CaptureButton> GetCaptureButton() const; | ||||
|     std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; | ||||
|     std::shared_ptr<DebugMouse> GetDebugMouse() const; | ||||
| @ -54,6 +64,18 @@ public: | ||||
|     std::shared_ptr<TouchScreen> GetTouchScreen() const; | ||||
|     std::shared_ptr<UniquePad> GetUniquePad() const; | ||||
| 
 | ||||
|     Result CreateAppletResource(u64 aruid); | ||||
| 
 | ||||
|     Result RegisterAppletResourceUserId(u64 aruid, bool bool_value); | ||||
|     void UnregisterAppletResourceUserId(u64 aruid); | ||||
| 
 | ||||
|     Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); | ||||
| 
 | ||||
|     void EnableInput(u64 aruid, bool is_enabled); | ||||
|     void EnableSixAxisSensor(u64 aruid, bool is_enabled); | ||||
|     void EnablePadInput(u64 aruid, bool is_enabled); | ||||
|     void EnableTouchScreen(u64 aruid, bool is_enabled); | ||||
| 
 | ||||
|     void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||||
|     void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||||
|     void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); | ||||
| @ -62,6 +84,9 @@ public: | ||||
| private: | ||||
|     bool is_initialized{false}; | ||||
| 
 | ||||
|     mutable std::mutex shared_mutex; | ||||
|     std::shared_ptr<AppletResource> applet_resource = nullptr; | ||||
| 
 | ||||
|     std::shared_ptr<CaptureButton> capture_button = nullptr; | ||||
|     std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; | ||||
|     std::shared_ptr<DebugMouse> debug_mouse = nullptr; | ||||
| @ -106,6 +131,8 @@ private: | ||||
|     std::shared_ptr<Core::Timing::EventType> default_update_event; | ||||
|     std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; | ||||
|     std::shared_ptr<Core::Timing::EventType> motion_update_event; | ||||
| 
 | ||||
|     std::shared_ptr<ResourceManager> resource_manager; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user