Merge pull request #12836 from german77/im_home
service: hid: Implement home, capture and sleep buttons
This commit is contained in:
		| @@ -96,6 +96,7 @@ add_library(hid_core STATIC | ||||
|     resources/system_buttons/home_button.h | ||||
|     resources/system_buttons/sleep_button.cpp | ||||
|     resources/system_buttons/sleep_button.h | ||||
|     resources/system_buttons/system_button_types.h | ||||
|     resources/touch_screen/gesture.cpp | ||||
|     resources/touch_screen/gesture.h | ||||
|     resources/touch_screen/gesture_types.h | ||||
|   | ||||
| @@ -437,6 +437,16 @@ struct LedPattern { | ||||
|     }; | ||||
| }; | ||||
|  | ||||
| struct SleepButtonState { | ||||
|     union { | ||||
|         u64 raw{}; | ||||
|  | ||||
|         // Buttons | ||||
|         BitField<0, 1, u64> sleep; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(SleepButtonState) == 0x8, "SleepButtonState has incorrect size."); | ||||
|  | ||||
| struct HomeButtonState { | ||||
|     union { | ||||
|         u64 raw{}; | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| #include "hid_core/resources/mouse/mouse_types.h" | ||||
| #include "hid_core/resources/npad/npad_types.h" | ||||
| #include "hid_core/resources/ring_lifo.h" | ||||
| #include "hid_core/resources/system_buttons/system_button_types.h" | ||||
| #include "hid_core/resources/touch_screen/touch_types.h" | ||||
|  | ||||
| namespace Service::HID { | ||||
| @@ -75,24 +76,24 @@ static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, | ||||
|  | ||||
| // This is nn::hid::detail::HomeButtonSharedMemoryFormat | ||||
| struct HomeButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
|     Lifo<HomeButtonState, HidEntryCount> home_lifo{}; | ||||
|     INSERT_PADDING_BYTES(0x48); | ||||
| }; | ||||
| static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, | ||||
|               "HomeButtonSharedMemoryFormat is an invalid size"); | ||||
|  | ||||
| // This is nn::hid::detail::SleepButtonSharedMemoryFormat | ||||
| struct SleepButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
|     Lifo<SleepButtonState, HidEntryCount> sleep_lifo{}; | ||||
|     INSERT_PADDING_BYTES(0x48); | ||||
| }; | ||||
| static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, | ||||
|               "SleepButtonSharedMemoryFormat is an invalid size"); | ||||
|  | ||||
| // This is nn::hid::detail::CaptureButtonSharedMemoryFormat | ||||
| struct CaptureButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
|     Lifo<CaptureButtonState, HidEntryCount> capture_lifo{}; | ||||
|     INSERT_PADDING_BYTES(0x48); | ||||
| }; | ||||
| static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, | ||||
|               "CaptureButtonSharedMemoryFormat is an invalid size"); | ||||
|   | ||||
| @@ -2,6 +2,8 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "core/core_timing.h" | ||||
| #include "hid_core/frontend/emulated_controller.h" | ||||
| #include "hid_core/hid_core.h" | ||||
| #include "hid_core/resources/applet_resource.h" | ||||
| #include "hid_core/resources/shared_memory_format.h" | ||||
| #include "hid_core/resources/system_buttons/capture_button.h" | ||||
| @@ -17,10 +19,6 @@ void CaptureButton::OnInit() {} | ||||
| void CaptureButton::OnRelease() {} | ||||
|  | ||||
| void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!smart_update) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::scoped_lock shared_lock{*shared_mutex}; | ||||
|     const u64 aruid = applet_resource->GetActiveAruid(); | ||||
|     auto* data = applet_resource->GetAruidData(aruid); | ||||
| @@ -29,11 +27,21 @@ void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto& header = data->shared_memory_format->capture_button.header; | ||||
|     header.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     header.total_entry_count = 17; | ||||
|     header.entry_count = 0; | ||||
|     header.last_entry_index = 0; | ||||
|     auto& shared_memory = data->shared_memory_format->capture_button; | ||||
|  | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory.capture_lifo.buffer_count = 0; | ||||
|         shared_memory.capture_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto& last_entry = shared_memory.capture_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
|  | ||||
|     auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|     next_state.buttons.raw = controller->GetHomeButtons().raw; | ||||
|  | ||||
|     shared_memory.capture_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
|  | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "hid_core/resources/controller_base.h" | ||||
| #include "hid_core/resources/system_buttons/system_button_types.h" | ||||
|  | ||||
| namespace Service::HID { | ||||
|  | ||||
| @@ -22,6 +23,6 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
|  | ||||
| private: | ||||
|     bool smart_update{}; | ||||
|     CaptureButtonState next_state{}; | ||||
| }; | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -2,6 +2,8 @@ | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| #include "core/core_timing.h" | ||||
| #include "hid_core/frontend/emulated_controller.h" | ||||
| #include "hid_core/hid_core.h" | ||||
| #include "hid_core/resources/applet_resource.h" | ||||
| #include "hid_core/resources/shared_memory_format.h" | ||||
| #include "hid_core/resources/system_buttons/home_button.h" | ||||
| @@ -17,10 +19,6 @@ void HomeButton::OnInit() {} | ||||
| void HomeButton::OnRelease() {} | ||||
|  | ||||
| void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!smart_update) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::scoped_lock shared_lock{*shared_mutex}; | ||||
|     const u64 aruid = applet_resource->GetActiveAruid(); | ||||
|     auto* data = applet_resource->GetAruidData(aruid); | ||||
| @@ -29,11 +27,21 @@ void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto& header = data->shared_memory_format->home_button.header; | ||||
|     header.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     header.total_entry_count = 17; | ||||
|     header.entry_count = 0; | ||||
|     header.last_entry_index = 0; | ||||
|     auto& shared_memory = data->shared_memory_format->home_button; | ||||
|  | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory.home_lifo.buffer_count = 0; | ||||
|         shared_memory.home_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto& last_entry = shared_memory.home_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
|  | ||||
|     auto* controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); | ||||
|     next_state.buttons.raw = controller->GetHomeButtons().raw; | ||||
|  | ||||
|     shared_memory.home_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
|  | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "hid_core/resources/controller_base.h" | ||||
| #include "hid_core/resources/system_buttons/system_button_types.h" | ||||
|  | ||||
| namespace Service::HID { | ||||
|  | ||||
| @@ -22,6 +23,6 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
|  | ||||
| private: | ||||
|     bool smart_update{}; | ||||
|     HomeButtonState next_state{}; | ||||
| }; | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -17,10 +17,6 @@ void SleepButton::OnInit() {} | ||||
| void SleepButton::OnRelease() {} | ||||
|  | ||||
| void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!smart_update) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     std::scoped_lock shared_lock{*shared_mutex}; | ||||
|     const u64 aruid = applet_resource->GetActiveAruid(); | ||||
|     auto* data = applet_resource->GetAruidData(aruid); | ||||
| @@ -29,11 +25,20 @@ void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto& header = data->shared_memory_format->capture_button.header; | ||||
|     header.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     header.total_entry_count = 17; | ||||
|     header.entry_count = 0; | ||||
|     header.last_entry_index = 0; | ||||
|     auto& shared_memory = data->shared_memory_format->sleep_button; | ||||
|  | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory.sleep_lifo.buffer_count = 0; | ||||
|         shared_memory.sleep_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto& last_entry = shared_memory.sleep_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
|  | ||||
|     next_state.buttons.raw = 0; | ||||
|  | ||||
|     shared_memory.sleep_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
|  | ||||
| } // namespace Service::HID | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "hid_core/resources/controller_base.h" | ||||
| #include "hid_core/resources/system_buttons/system_button_types.h" | ||||
|  | ||||
| namespace Service::HID { | ||||
|  | ||||
| @@ -22,6 +23,6 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
|  | ||||
| private: | ||||
|     bool smart_update{}; | ||||
|     SleepButtonState next_state{}; | ||||
| }; | ||||
| } // namespace Service::HID | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/hid_core/resources/system_buttons/system_button_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/hid_core/resources/system_buttons/system_button_types.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "hid_core/hid_types.h" | ||||
|  | ||||
| namespace Service::HID { | ||||
|  | ||||
| // This is nn::hid::system::SleepButtonState | ||||
| struct SleepButtonState { | ||||
|     s64 sampling_number{}; | ||||
|     Core::HID::SleepButtonState buttons; | ||||
| }; | ||||
| static_assert(sizeof(SleepButtonState) == 0x10, "SleepButtonState is an invalid size"); | ||||
|  | ||||
| // This is nn::hid::system::HomeButtonState | ||||
| struct HomeButtonState { | ||||
|     s64 sampling_number{}; | ||||
|     Core::HID::HomeButtonState buttons; | ||||
| }; | ||||
| static_assert(sizeof(HomeButtonState) == 0x10, "HomeButtonState is an invalid size"); | ||||
|  | ||||
| // This is nn::hid::system::SleepButtonState | ||||
| struct CaptureButtonState { | ||||
|     s64 sampling_number{}; | ||||
|     Core::HID::CaptureButtonState buttons; | ||||
| }; | ||||
| static_assert(sizeof(CaptureButtonState) == 0x10, "CaptureButtonState is an invalid size"); | ||||
|  | ||||
| } // namespace Service::HID | ||||
| @@ -28,7 +28,7 @@ void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     auto& header = data->shared_memory_format->capture_button.header; | ||||
|     auto& header = data->shared_memory_format->unique_pad.header; | ||||
|     header.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     header.total_entry_count = 17; | ||||
|     header.entry_count = 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 liamwhite
					liamwhite