mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-10-31 23:06:43 +08:00 
			
		
		
		
	service: hid: Allow to create multiple instances of shared memory
This commit is contained in:
		
							parent
							
								
									d590cfb9d0
								
							
						
					
					
						commit
						64f68e9635
					
				| @ -549,6 +549,11 @@ add_library(core STATIC | ||||
|     hle/service/hid/xcd.cpp | ||||
|     hle/service/hid/xcd.h | ||||
|     hle/service/hid/errors.h | ||||
|     hle/service/hid/controllers/types/debug_pad_types.h | ||||
|     hle/service/hid/controllers/types/keyboard_types.h | ||||
|     hle/service/hid/controllers/types/mouse_types.h | ||||
|     hle/service/hid/controllers/types/npad_types.h | ||||
|     hle/service/hid/controllers/types/touch_types.h | ||||
|     hle/service/hid/controllers/applet_resource.cpp | ||||
|     hle/service/hid/controllers/applet_resource.h | ||||
|     hle/service/hid/controllers/console_six_axis.cpp | ||||
| @ -569,14 +574,15 @@ add_library(core STATIC | ||||
|     hle/service/hid/controllers/palma.h | ||||
|     hle/service/hid/controllers/seven_six_axis.cpp | ||||
|     hle/service/hid/controllers/seven_six_axis.h | ||||
|     hle/service/hid/controllers/shared_memory_format.h | ||||
|     hle/service/hid/controllers/shared_memory_holder.cpp | ||||
|     hle/service/hid/controllers/shared_memory_holder.h | ||||
|     hle/service/hid/controllers/six_axis.cpp | ||||
|     hle/service/hid/controllers/six_axis.h | ||||
|     hle/service/hid/controllers/stubbed.cpp | ||||
|     hle/service/hid/controllers/stubbed.h | ||||
|     hle/service/hid/controllers/touchscreen.cpp | ||||
|     hle/service/hid/controllers/touchscreen.h | ||||
|     hle/service/hid/controllers/xpad.cpp | ||||
|     hle/service/hid/controllers/xpad.h | ||||
|     hle/service/hid/hidbus/hidbus_base.cpp | ||||
|     hle/service/hid/hidbus/hidbus_base.h | ||||
|     hle/service/hid/hidbus/ringcon.cpp | ||||
|  | ||||
| @ -135,7 +135,6 @@ struct KernelCore::Impl { | ||||
|                 obj = nullptr; | ||||
|             } | ||||
|         }; | ||||
|         CleanupObject(hid_shared_mem); | ||||
|         CleanupObject(font_shared_mem); | ||||
|         CleanupObject(irs_shared_mem); | ||||
|         CleanupObject(time_shared_mem); | ||||
| @ -744,22 +743,16 @@ struct KernelCore::Impl { | ||||
|     void InitializeHackSharedMemory(KernelCore& kernel) { | ||||
|         // Setup memory regions for emulated processes
 | ||||
|         // TODO(bunnei): These should not be hardcoded regions initialized within the kernel
 | ||||
|         constexpr std::size_t hid_size{0x40000}; | ||||
|         constexpr std::size_t font_size{0x1100000}; | ||||
|         constexpr std::size_t irs_size{0x8000}; | ||||
|         constexpr std::size_t time_size{0x1000}; | ||||
|         constexpr std::size_t hidbus_size{0x1000}; | ||||
| 
 | ||||
|         hid_shared_mem = KSharedMemory::Create(system.Kernel()); | ||||
|         font_shared_mem = KSharedMemory::Create(system.Kernel()); | ||||
|         irs_shared_mem = KSharedMemory::Create(system.Kernel()); | ||||
|         time_shared_mem = KSharedMemory::Create(system.Kernel()); | ||||
|         hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); | ||||
| 
 | ||||
|         hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, | ||||
|                                    Svc::MemoryPermission::Read, hid_size); | ||||
|         KSharedMemory::Register(kernel, hid_shared_mem); | ||||
| 
 | ||||
|         font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, | ||||
|                                     Svc::MemoryPermission::Read, font_size); | ||||
|         KSharedMemory::Register(kernel, font_shared_mem); | ||||
| @ -1190,14 +1183,6 @@ const KSystemResource& KernelCore::GetSystemSystemResource() const { | ||||
|     return *impl->sys_system_resource; | ||||
| } | ||||
| 
 | ||||
| Kernel::KSharedMemory& KernelCore::GetHidSharedMem() { | ||||
|     return *impl->hid_shared_mem; | ||||
| } | ||||
| 
 | ||||
| const Kernel::KSharedMemory& KernelCore::GetHidSharedMem() const { | ||||
|     return *impl->hid_shared_mem; | ||||
| } | ||||
| 
 | ||||
| Kernel::KSharedMemory& KernelCore::GetFontSharedMem() { | ||||
|     return *impl->font_shared_mem; | ||||
| } | ||||
|  | ||||
| @ -239,12 +239,6 @@ public: | ||||
|     /// Gets the system resource manager.
 | ||||
|     const KSystemResource& GetSystemSystemResource() const; | ||||
| 
 | ||||
|     /// Gets the shared memory object for HID services.
 | ||||
|     Kernel::KSharedMemory& GetHidSharedMem(); | ||||
| 
 | ||||
|     /// Gets the shared memory object for HID services.
 | ||||
|     const Kernel::KSharedMemory& GetHidSharedMem() const; | ||||
| 
 | ||||
|     /// Gets the shared memory object for font services.
 | ||||
|     Kernel::KSharedMemory& GetFontSharedMem(); | ||||
| 
 | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| #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/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| @ -23,11 +24,24 @@ Result AppletResource::CreateAppletResource(u64 aruid) { | ||||
|         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(); | ||||
|     auto& shared_memory = shared_memory_holder[index]; | ||||
|     if (!shared_memory.IsMapped()) { | ||||
|         const Result result = shared_memory.Initialize(system); | ||||
|         if (result.IsError()) { | ||||
|             return result; | ||||
|         } | ||||
|         if (shared_memory.GetAddress() == nullptr) { | ||||
|             shared_memory.Finalize(); | ||||
|             return ResultSharedMemoryNotInitialized; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     data[index].shared_memory_handle = &shared_memory; | ||||
|     auto* shared_memory_format = shared_memory.GetAddress(); | ||||
|     if (shared_memory_format != nullptr) { | ||||
|         shared_memory_format->Initialize(); | ||||
|     } | ||||
| 
 | ||||
|     data[index].shared_memory_format = shared_memory_format; | ||||
|     data[index].flag.is_assigned.Assign(true); | ||||
|     // TODO: InitializeSixAxisControllerConfig(false);
 | ||||
|     active_aruid = aruid; | ||||
| @ -94,7 +108,7 @@ void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { | ||||
| 
 | ||||
|     if (index < AruidIndexMax) { | ||||
|         if (data[index].flag.is_assigned) { | ||||
|             data[index].shared_memory_handle = nullptr; | ||||
|             data[index].shared_memory_format = nullptr; | ||||
|             data[index].flag.is_assigned.Assign(false); | ||||
|         } | ||||
|     } | ||||
| @ -120,7 +134,7 @@ void AppletResource::FreeAppletResourceId(u64 aruid) { | ||||
| 
 | ||||
|     auto& aruid_data = data[index]; | ||||
|     if (aruid_data.flag.is_assigned) { | ||||
|         aruid_data.shared_memory_handle = nullptr; | ||||
|         aruid_data.shared_memory_format = nullptr; | ||||
|         aruid_data.flag.is_assigned.Assign(false); | ||||
|     } | ||||
| } | ||||
| @ -135,7 +149,18 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, | ||||
|         return ResultAruidNotRegistered; | ||||
|     } | ||||
| 
 | ||||
|     *out_handle = data[index].shared_memory_handle; | ||||
|     *out_handle = shared_memory_holder[index].GetHandle(); | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, | ||||
|                                              u64 aruid) { | ||||
|     u64 index = GetIndexFromAruid(aruid); | ||||
|     if (index >= AruidIndexMax) { | ||||
|         return ResultAruidNotRegistered; | ||||
|     } | ||||
| 
 | ||||
|     *out_shared_memory_format = data[index].shared_memory_format; | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -8,6 +8,7 @@ | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_holder.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| @ -18,6 +19,8 @@ class KSharedMemory; | ||||
| } | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct SharedMemoryFormat; | ||||
| 
 | ||||
| class AppletResource { | ||||
| public: | ||||
|     explicit AppletResource(Core::System& system_); | ||||
| @ -32,6 +35,7 @@ public: | ||||
| 
 | ||||
|     u64 GetActiveAruid(); | ||||
|     Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); | ||||
|     Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid); | ||||
| 
 | ||||
|     u64 GetIndexFromAruid(u64 aruid); | ||||
| 
 | ||||
| @ -80,12 +84,13 @@ private: | ||||
|     struct AruidData { | ||||
|         DataStatusFlag flag{}; | ||||
|         u64 aruid{}; | ||||
|         Kernel::KSharedMemory* shared_memory_handle{nullptr}; | ||||
|         SharedMemoryFormat* shared_memory_format{nullptr}; | ||||
|     }; | ||||
| 
 | ||||
|     u64 active_aruid{}; | ||||
|     AruidRegisterList registration_list{}; | ||||
|     std::array<AruidData, AruidIndexMax> data{}; | ||||
|     std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{}; | ||||
|     s32 ref_counter{}; | ||||
| 
 | ||||
|     Core::System& system; | ||||
|  | ||||
| @ -6,18 +6,15 @@ | ||||
| #include "core/hid/emulated_console.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/console_six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/memory.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; | ||||
| 
 | ||||
| ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase{hid_core_} { | ||||
| ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, | ||||
|                                ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory) | ||||
|     : ControllerBase{hid_core_}, shared_memory{console_shared_memory} { | ||||
|     console = hid_core.GetEmulatedConsole(); | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size, | ||||
|                   "ConsoleSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| } | ||||
| 
 | ||||
| ConsoleSixAxis::~ConsoleSixAxis() = default; | ||||
| @ -33,10 +30,10 @@ void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
| 
 | ||||
|     const auto motion_status = console->GetMotion(); | ||||
| 
 | ||||
|     shared_memory->sampling_number++; | ||||
|     shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | ||||
|     shared_memory->verticalization_error = motion_status.verticalization_error; | ||||
|     shared_memory->gyro_bias = motion_status.gyro_bias; | ||||
|     shared_memory.sampling_number++; | ||||
|     shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; | ||||
|     shared_memory.verticalization_error = motion_status.verticalization_error; | ||||
|     shared_memory.gyro_bias = motion_status.gyro_bias; | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -3,7 +3,6 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| 
 | ||||
| namespace Core::HID { | ||||
| @ -11,9 +10,12 @@ class EmulatedConsole; | ||||
| } // namespace Core::HID
 | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct ConsoleSixAxisSensorSharedMemoryFormat; | ||||
| 
 | ||||
| class ConsoleSixAxis final : public ControllerBase { | ||||
| public: | ||||
|     explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, | ||||
|                             ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory); | ||||
|     ~ConsoleSixAxis() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -26,18 +28,7 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
 | ||||
|     struct ConsoleSharedMemory { | ||||
|         u64 sampling_number{}; | ||||
|         bool is_seven_six_axis_sensor_at_rest{}; | ||||
|         INSERT_PADDING_BYTES(3); // padding
 | ||||
|         f32 verticalization_error{}; | ||||
|         Common::Vec3f gyro_bias{}; | ||||
|         INSERT_PADDING_BYTES(4); // padding
 | ||||
|     }; | ||||
|     static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     ConsoleSharedMemory* shared_memory = nullptr; | ||||
|     ConsoleSixAxisSensorSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedConsole* console = nullptr; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -39,9 +39,6 @@ public: | ||||
| 
 | ||||
|     bool IsControllerActivated() const; | ||||
| 
 | ||||
|     static const std::size_t hid_entry_count = 17; | ||||
|     static const std::size_t shared_memory_size = 0x40000; | ||||
| 
 | ||||
| protected: | ||||
|     bool is_activated{false}; | ||||
| 
 | ||||
|  | ||||
| @ -9,16 +9,13 @@ | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/controllers/debug_pad.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; | ||||
| 
 | ||||
| DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase{hid_core_} { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size, | ||||
|                   "DebugPadSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<DebugPadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, | ||||
|                    DebugPadSharedMemoryFormat& debug_pad_shared_memory) | ||||
|     : ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} { | ||||
|     controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | ||||
| } | ||||
| 
 | ||||
| @ -30,12 +27,12 @@ void DebugPad::OnRelease() {} | ||||
| 
 | ||||
| void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->debug_pad_lifo.buffer_count = 0; | ||||
|         shared_memory->debug_pad_lifo.buffer_tail = 0; | ||||
|         shared_memory.debug_pad_lifo.buffer_count = 0; | ||||
|         shared_memory.debug_pad_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state; | ||||
|     const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
| 
 | ||||
|     if (Settings::values.debug_pad_enabled) { | ||||
| @ -49,7 +46,7 @@ void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         next_state.r_stick = stick_state.right; | ||||
|     } | ||||
| 
 | ||||
|     shared_memory->debug_pad_lifo.WriteNextEntry(next_state); | ||||
|     shared_memory.debug_pad_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -3,21 +3,25 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| #include "core/hle/service/hid/controllers/types/debug_pad_types.h" | ||||
| 
 | ||||
| namespace Core::HID { | ||||
| class EmulatedController; | ||||
| struct DebugPadButton; | ||||
| struct AnalogStickState; | ||||
| } // namespace Core::HID
 | ||||
| class HIDCore; | ||||
| } | ||||
| 
 | ||||
| namespace Core::Timing { | ||||
| class CoreTiming; | ||||
| } | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct DebugPadSharedMemoryFormat; | ||||
| 
 | ||||
| class DebugPad final : public ControllerBase { | ||||
| public: | ||||
|     explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit DebugPad(Core::HID::HIDCore& hid_core_, | ||||
|                       DebugPadSharedMemoryFormat& debug_pad_shared_memory); | ||||
|     ~DebugPad() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -30,35 +34,8 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     // This is nn::hid::DebugPadAttribute
 | ||||
|     struct DebugPadAttribute { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
|             BitField<0, 1, u32> connected; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::DebugPadState
 | ||||
|     struct DebugPadState { | ||||
|         s64 sampling_number{}; | ||||
|         DebugPadAttribute attribute{}; | ||||
|         Core::HID::DebugPadButton pad_state{}; | ||||
|         Core::HID::AnalogStickState r_stick{}; | ||||
|         Core::HID::AnalogStickState l_stick{}; | ||||
|     }; | ||||
|     static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); | ||||
| 
 | ||||
|     struct DebugPadSharedMemory { | ||||
|         // This is nn::hid::detail::DebugPadLifo
 | ||||
|         Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; | ||||
|         static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0x4E); | ||||
|     }; | ||||
|     static_assert(sizeof(DebugPadSharedMemory) == 0x400, "DebugPadSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     DebugPadState next_state{}; | ||||
|     DebugPadSharedMemory* shared_memory = nullptr; | ||||
|     DebugPadSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedController* controller = nullptr; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -8,10 +8,9 @@ | ||||
| #include "core/frontend/emu_window.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/gesture.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00; | ||||
| 
 | ||||
| // HW is around 700, value is set to 400 to make it easier to trigger with mouse
 | ||||
| constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s
 | ||||
| constexpr f32 angle_threshold = 0.015f; // Threshold in radians
 | ||||
| @ -23,19 +22,15 @@ constexpr f32 Square(s32 num) { | ||||
|     return static_cast<f32>(num * num); | ||||
| } | ||||
| 
 | ||||
| Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase(hid_core_) { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size, | ||||
|                   "GestureSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory) | ||||
|     : ControllerBase(hid_core_), shared_memory{gesture_shared_memory} { | ||||
|     console = hid_core.GetEmulatedConsole(); | ||||
| } | ||||
| Gesture::~Gesture() = default; | ||||
| 
 | ||||
| void Gesture::OnInit() { | ||||
|     shared_memory->gesture_lifo.buffer_count = 0; | ||||
|     shared_memory->gesture_lifo.buffer_tail = 0; | ||||
|     shared_memory.gesture_lifo.buffer_count = 0; | ||||
|     shared_memory.gesture_lifo.buffer_tail = 0; | ||||
|     force_update = true; | ||||
| } | ||||
| 
 | ||||
| @ -43,8 +38,8 @@ void Gesture::OnRelease() {} | ||||
| 
 | ||||
| void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->gesture_lifo.buffer_count = 0; | ||||
|         shared_memory->gesture_lifo.buffer_tail = 0; | ||||
|         shared_memory.gesture_lifo.buffer_count = 0; | ||||
|         shared_memory.gesture_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| @ -52,7 +47,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
| 
 | ||||
|     GestureProperties gesture = GetGestureProperties(); | ||||
|     f32 time_difference = | ||||
|         static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / | ||||
|         static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) / | ||||
|         (1000 * 1000 * 1000); | ||||
| 
 | ||||
|     // Only update if necessary
 | ||||
| @ -60,7 +55,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     last_update_timestamp = shared_memory->gesture_lifo.timestamp; | ||||
|     last_update_timestamp = shared_memory.gesture_lifo.timestamp; | ||||
|     UpdateGestureSharedMemory(gesture, time_difference); | ||||
| } | ||||
| 
 | ||||
| @ -103,7 +98,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif | ||||
|     GestureType type = GestureType::Idle; | ||||
|     GestureAttribute attributes{}; | ||||
| 
 | ||||
|     const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; | ||||
|     const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state; | ||||
| 
 | ||||
|     // Reset next state to default
 | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
| @ -133,7 +128,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif | ||||
|     next_state.points = gesture.points; | ||||
|     last_gesture = gesture; | ||||
| 
 | ||||
|     shared_memory->gesture_lifo.WriteNextEntry(next_state); | ||||
|     shared_memory.gesture_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, | ||||
| @ -305,11 +300,11 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_ | ||||
|     next_state.direction = GestureDirection::Up; | ||||
| } | ||||
| 
 | ||||
| const Gesture::GestureState& Gesture::GetLastGestureEntry() const { | ||||
|     return shared_memory->gesture_lifo.ReadCurrentEntry().state; | ||||
| const GestureState& Gesture::GetLastGestureEntry() const { | ||||
|     return shared_memory.gesture_lifo.ReadCurrentEntry().state; | ||||
| } | ||||
| 
 | ||||
| Gesture::GestureProperties Gesture::GetGestureProperties() { | ||||
| GestureProperties Gesture::GetGestureProperties() { | ||||
|     GestureProperties gesture; | ||||
|     std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; | ||||
|     const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), | ||||
|  | ||||
| @ -4,17 +4,19 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| #include "common/bit_field.h" | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "common/point.h" | ||||
| #include "core/hid/emulated_console.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| #include "core/hle/service/hid/controllers/types/touch_types.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct GestureSharedMemoryFormat; | ||||
| 
 | ||||
| class Gesture final : public ControllerBase { | ||||
| public: | ||||
|     explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit Gesture(Core::HID::HIDCore& hid_core_, | ||||
|                      GestureSharedMemoryFormat& gesture_shared_memory); | ||||
|     ~Gesture() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -27,79 +29,6 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     static constexpr size_t MAX_FINGERS = 16; | ||||
|     static constexpr size_t MAX_POINTS = 4; | ||||
| 
 | ||||
|     // This is nn::hid::GestureType
 | ||||
|     enum class GestureType : u32 { | ||||
|         Idle,     // Nothing touching the screen
 | ||||
|         Complete, // Set at the end of a touch event
 | ||||
|         Cancel,   // Set when the number of fingers change
 | ||||
|         Touch,    // A finger just touched the screen
 | ||||
|         Press,    // Set if last type is touch and the finger hasn't moved
 | ||||
|         Tap,      // Fast press then release
 | ||||
|         Pan,      // All points moving together across the screen
 | ||||
|         Swipe,    // Fast press movement and release of a single point
 | ||||
|         Pinch,    // All points moving away/closer to the midpoint
 | ||||
|         Rotate,   // All points rotating from the midpoint
 | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::GestureDirection
 | ||||
|     enum class GestureDirection : u32 { | ||||
|         None, | ||||
|         Left, | ||||
|         Up, | ||||
|         Right, | ||||
|         Down, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::GestureAttribute
 | ||||
|     struct GestureAttribute { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
| 
 | ||||
|             BitField<4, 1, u32> is_new_touch; | ||||
|             BitField<8, 1, u32> is_double_tap; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::GestureState
 | ||||
|     struct GestureState { | ||||
|         s64 sampling_number{}; | ||||
|         s64 detection_count{}; | ||||
|         GestureType type{GestureType::Idle}; | ||||
|         GestureDirection direction{GestureDirection::None}; | ||||
|         Common::Point<s32> pos{}; | ||||
|         Common::Point<s32> delta{}; | ||||
|         f32 vel_x{}; | ||||
|         f32 vel_y{}; | ||||
|         GestureAttribute attributes{}; | ||||
|         f32 scale{}; | ||||
|         f32 rotation_angle{}; | ||||
|         s32 point_count{}; | ||||
|         std::array<Common::Point<s32>, 4> points{}; | ||||
|     }; | ||||
|     static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||||
| 
 | ||||
|     struct GestureProperties { | ||||
|         std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||||
|         std::size_t active_points{}; | ||||
|         Common::Point<s32> mid_point{}; | ||||
|         s64 detection_count{}; | ||||
|         u64 delta_time{}; | ||||
|         f32 average_distance{}; | ||||
|         f32 angle{}; | ||||
|     }; | ||||
| 
 | ||||
|     struct GestureSharedMemory { | ||||
|         // This is nn::hid::detail::GestureLifo
 | ||||
|         Lifo<GestureState, hid_entry_count> gesture_lifo{}; | ||||
|         static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0x3E); | ||||
|     }; | ||||
|     static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     // Reads input from all available input engines
 | ||||
|     void ReadTouchInput(); | ||||
| 
 | ||||
| @ -142,7 +71,7 @@ private: | ||||
|     GestureProperties GetGestureProperties(); | ||||
| 
 | ||||
|     GestureState next_state{}; | ||||
|     GestureSharedMemory* shared_memory = nullptr; | ||||
|     GestureSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedConsole* console = nullptr; | ||||
| 
 | ||||
|     std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; | ||||
|  | ||||
| @ -8,16 +8,13 @@ | ||||
| #include "core/hid/emulated_devices.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/keyboard.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; | ||||
| 
 | ||||
| Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase{hid_core_} { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size, | ||||
|                   "KeyboardSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, | ||||
|                    KeyboardSharedMemoryFormat& keyboard_shared_memory) | ||||
|     : ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} { | ||||
|     emulated_devices = hid_core.GetEmulatedDevices(); | ||||
| } | ||||
| 
 | ||||
| @ -29,12 +26,12 @@ void Keyboard::OnRelease() {} | ||||
| 
 | ||||
| void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->keyboard_lifo.buffer_count = 0; | ||||
|         shared_memory->keyboard_lifo.buffer_tail = 0; | ||||
|         shared_memory.keyboard_lifo.buffer_count = 0; | ||||
|         shared_memory.keyboard_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state; | ||||
|     const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
| 
 | ||||
|     if (Settings::values.keyboard_enabled) { | ||||
| @ -46,7 +43,7 @@ void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         next_state.attribute.is_connected.Assign(1); | ||||
|     } | ||||
| 
 | ||||
|     shared_memory->keyboard_lifo.WriteNextEntry(next_state); | ||||
|     shared_memory.keyboard_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -5,18 +5,16 @@ | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/controllers/types/keyboard_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Core::HID { | ||||
| class EmulatedDevices; | ||||
| struct KeyboardModifier; | ||||
| struct KeyboardKey; | ||||
| } // namespace Core::HID
 | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct KeyboardSharedMemoryFormat; | ||||
| 
 | ||||
| class Keyboard final : public ControllerBase { | ||||
| public: | ||||
|     explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit Keyboard(Core::HID::HIDCore& hid_core_, | ||||
|                       KeyboardSharedMemoryFormat& keyboard_shared_memory); | ||||
|     ~Keyboard() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -29,25 +27,8 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     // This is nn::hid::detail::KeyboardState
 | ||||
|     struct KeyboardState { | ||||
|         s64 sampling_number{}; | ||||
|         Core::HID::KeyboardModifier modifier{}; | ||||
|         Core::HID::KeyboardAttribute attribute{}; | ||||
|         Core::HID::KeyboardKey key{}; | ||||
|     }; | ||||
|     static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); | ||||
| 
 | ||||
|     struct KeyboardSharedMemory { | ||||
|         // This is nn::hid::detail::KeyboardLifo
 | ||||
|         Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; | ||||
|         static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0xA); | ||||
|     }; | ||||
|     static_assert(sizeof(KeyboardSharedMemory) == 0x400, "KeyboardSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     KeyboardState next_state{}; | ||||
|     KeyboardSharedMemory* shared_memory = nullptr; | ||||
|     KeyboardSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedDevices* emulated_devices = nullptr; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -8,15 +8,12 @@ | ||||
| #include "core/hid/emulated_devices.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/mouse.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; | ||||
| 
 | ||||
| Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, | ||||
|                   "MouseSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory) | ||||
|     : ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} { | ||||
|     emulated_devices = hid_core.GetEmulatedDevices(); | ||||
| } | ||||
| 
 | ||||
| @ -27,14 +24,14 @@ void Mouse::OnRelease() {} | ||||
| 
 | ||||
| void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->mouse_lifo.buffer_count = 0; | ||||
|         shared_memory->mouse_lifo.buffer_tail = 0; | ||||
|         shared_memory.mouse_lifo.buffer_count = 0; | ||||
|         shared_memory.mouse_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     next_state = {}; | ||||
| 
 | ||||
|     const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state; | ||||
|     const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
| 
 | ||||
|     if (Settings::values.mouse_enabled) { | ||||
| @ -53,7 +50,7 @@ void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         next_state.button = mouse_button_state; | ||||
|     } | ||||
| 
 | ||||
|     shared_memory->mouse_lifo.WriteNextEntry(next_state); | ||||
|     shared_memory.mouse_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -14,9 +14,11 @@ struct AnalogStickState; | ||||
| } // namespace Core::HID
 | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct MouseSharedMemoryFormat; | ||||
| 
 | ||||
| class Mouse final : public ControllerBase { | ||||
| public: | ||||
|     explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory); | ||||
|     ~Mouse() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -29,17 +31,9 @@ public: | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     struct MouseSharedMemory { | ||||
|         // This is nn::hid::detail::MouseLifo
 | ||||
|         Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; | ||||
|         static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0x2C); | ||||
|     }; | ||||
|     static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     Core::HID::MouseState next_state{}; | ||||
|     Core::HID::AnalogStickState last_mouse_wheel_state{}; | ||||
|     MouseSharedMemory* shared_memory = nullptr; | ||||
|     MouseSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedDevices* emulated_devices = nullptr; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -17,12 +17,12 @@ | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/service/hid/controllers/npad.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| #include "core/hle/service/hid/hid_util.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t NPAD_OFFSET = 0x9A00; | ||||
| constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ | ||||
|     Core::HID::NpadIdType::Player1,  Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3, | ||||
|     Core::HID::NpadIdType::Player4,  Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6, | ||||
| @ -30,14 +30,12 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ | ||||
|     Core::HID::NpadIdType::Handheld, | ||||
| }; | ||||
| 
 | ||||
| NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | ||||
| NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, | ||||
|            KernelHelpers::ServiceContext& service_context_) | ||||
|     : ControllerBase{hid_core_}, service_context{service_context_} { | ||||
|     static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size); | ||||
|     for (std::size_t i = 0; i < controller_data.size(); ++i) { | ||||
|         auto& controller = controller_data[i]; | ||||
|         controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>( | ||||
|             raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState)))); | ||||
|         controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state; | ||||
|         controller.device = hid_core.GetEmulatedControllerByIndex(i); | ||||
|         controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = | ||||
|             Core::HID::DEFAULT_VIBRATION_VALUE; | ||||
| @ -617,7 +615,7 @@ void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) { | ||||
|     hold_type = joy_hold_type; | ||||
| } | ||||
| 
 | ||||
| NPad::NpadJoyHoldType NPad::GetHoldType() const { | ||||
| NpadJoyHoldType NPad::GetHoldType() const { | ||||
|     return hold_type; | ||||
| } | ||||
| 
 | ||||
| @ -630,7 +628,7 @@ void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_m | ||||
|     handheld_activation_mode = activation_mode; | ||||
| } | ||||
| 
 | ||||
| NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { | ||||
| NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { | ||||
|     return handheld_activation_mode; | ||||
| } | ||||
| 
 | ||||
| @ -638,7 +636,7 @@ void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) { | ||||
|     communication_mode = communication_mode_; | ||||
| } | ||||
| 
 | ||||
| NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const { | ||||
| NpadCommunicationMode NPad::GetNpadCommunicationMode() const { | ||||
|     return communication_mode; | ||||
| } | ||||
| 
 | ||||
| @ -978,27 +976,27 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; | ||||
| } | ||||
| 
 | ||||
| NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { | ||||
| NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { | ||||
|     return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; | ||||
| } | ||||
| 
 | ||||
| @ -1343,7 +1341,7 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { | ||||
| AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { | ||||
|     const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; | ||||
| 
 | ||||
|     return { | ||||
|  | ||||
| @ -13,6 +13,7 @@ | ||||
| 
 | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/controllers/types/npad_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Core::HID { | ||||
| @ -32,10 +33,13 @@ class ServiceContext; | ||||
| union Result; | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct NpadInternalState; | ||||
| struct NpadSixAxisSensorLifo; | ||||
| struct NpadSharedMemoryFormat; | ||||
| 
 | ||||
| class NPad final : public ControllerBase { | ||||
| public: | ||||
|     explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | ||||
|     explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format, | ||||
|                   KernelHelpers::ServiceContext& service_context_); | ||||
|     ~NPad() override; | ||||
| 
 | ||||
| @ -48,89 +52,6 @@ public: | ||||
|     // When the controller is requesting an update for the shared memory
 | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
|     // This is nn::hid::NpadJoyHoldType
 | ||||
|     enum class NpadJoyHoldType : u64 { | ||||
|         Vertical = 0, | ||||
|         Horizontal = 1, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadJoyAssignmentMode
 | ||||
|     enum class NpadJoyAssignmentMode : u32 { | ||||
|         Dual = 0, | ||||
|         Single = 1, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadJoyDeviceType
 | ||||
|     enum class NpadJoyDeviceType : s64 { | ||||
|         Left = 0, | ||||
|         Right = 1, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadHandheldActivationMode
 | ||||
|     enum class NpadHandheldActivationMode : u64 { | ||||
|         Dual = 0, | ||||
|         Single = 1, | ||||
|         None = 2, | ||||
|         MaxActivationMode = 3, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::system::AppletFooterUiAttributesSet
 | ||||
|     struct AppletFooterUiAttributes { | ||||
|         INSERT_PADDING_BYTES(0x4); | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::system::AppletFooterUiType
 | ||||
|     enum class AppletFooterUiType : u8 { | ||||
|         None = 0, | ||||
|         HandheldNone = 1, | ||||
|         HandheldJoyConLeftOnly = 2, | ||||
|         HandheldJoyConRightOnly = 3, | ||||
|         HandheldJoyConLeftJoyConRight = 4, | ||||
|         JoyDual = 5, | ||||
|         JoyDualLeftOnly = 6, | ||||
|         JoyDualRightOnly = 7, | ||||
|         JoyLeftHorizontal = 8, | ||||
|         JoyLeftVertical = 9, | ||||
|         JoyRightHorizontal = 10, | ||||
|         JoyRightVertical = 11, | ||||
|         SwitchProController = 12, | ||||
|         CompatibleProController = 13, | ||||
|         CompatibleJoyCon = 14, | ||||
|         LarkHvc1 = 15, | ||||
|         LarkHvc2 = 16, | ||||
|         LarkNesLeft = 17, | ||||
|         LarkNesRight = 18, | ||||
|         Lucia = 19, | ||||
|         Verification = 20, | ||||
|         Lagon = 21, | ||||
|     }; | ||||
| 
 | ||||
|     using AppletFooterUiVariant = u8; | ||||
| 
 | ||||
|     // This is "nn::hid::system::AppletDetailedUiType".
 | ||||
|     struct AppletDetailedUiType { | ||||
|         AppletFooterUiVariant ui_variant; | ||||
|         INSERT_PADDING_BYTES(0x2); | ||||
|         AppletFooterUiType footer; | ||||
|     }; | ||||
|     static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||||
|     // This is nn::hid::NpadCommunicationMode
 | ||||
|     enum class NpadCommunicationMode : u64 { | ||||
|         Mode_5ms = 0, | ||||
|         Mode_10ms = 1, | ||||
|         Mode_15ms = 2, | ||||
|         Default = 3, | ||||
|     }; | ||||
| 
 | ||||
|     enum class NpadRevision : u32 { | ||||
|         Revision0 = 0, | ||||
|         Revision1 = 1, | ||||
|         Revision2 = 2, | ||||
|         Revision3 = 3, | ||||
|     }; | ||||
| 
 | ||||
|     using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>; | ||||
| 
 | ||||
|     void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | ||||
|     Core::HID::NpadStyleTag GetSupportedStyleSet() const; | ||||
| 
 | ||||
| @ -188,12 +109,12 @@ public: | ||||
|     Result ResetIsSixAxisSensorDeviceNewlyAssigned( | ||||
|         const Core::HID::SixAxisSensorHandle& sixaxis_handle); | ||||
| 
 | ||||
|     SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); | ||||
|     SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); | ||||
|     SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); | ||||
|     SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); | ||||
|     SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); | ||||
|     SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); | ||||
|     NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); | ||||
| 
 | ||||
|     Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; | ||||
|     Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, | ||||
| @ -221,214 +142,6 @@ public: | ||||
|     AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); | ||||
| 
 | ||||
| private: | ||||
|     static constexpr std::size_t NPAD_COUNT = 10; | ||||
| 
 | ||||
|     // This is nn::hid::detail::ColorAttribute
 | ||||
|     enum class ColorAttribute : u32 { | ||||
|         Ok = 0, | ||||
|         ReadError = 1, | ||||
|         NoController = 2, | ||||
|     }; | ||||
|     static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::detail::NpadFullKeyColorState
 | ||||
|     struct NpadFullKeyColorState { | ||||
|         ColorAttribute attribute{ColorAttribute::NoController}; | ||||
|         Core::HID::NpadControllerColor fullkey{}; | ||||
|     }; | ||||
|     static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::detail::NpadJoyColorState
 | ||||
|     struct NpadJoyColorState { | ||||
|         ColorAttribute attribute{ColorAttribute::NoController}; | ||||
|         Core::HID::NpadControllerColor left{}; | ||||
|         Core::HID::NpadControllerColor right{}; | ||||
|     }; | ||||
|     static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::NpadAttribute
 | ||||
|     struct NpadAttribute { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
|             BitField<0, 1, u32> is_connected; | ||||
|             BitField<1, 1, u32> is_wired; | ||||
|             BitField<2, 1, u32> is_left_connected; | ||||
|             BitField<3, 1, u32> is_left_wired; | ||||
|             BitField<4, 1, u32> is_right_connected; | ||||
|             BitField<5, 1, u32> is_right_wired; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::NpadFullKeyState
 | ||||
|     // This is nn::hid::NpadHandheldState
 | ||||
|     // This is nn::hid::NpadJoyDualState
 | ||||
|     // This is nn::hid::NpadJoyLeftState
 | ||||
|     // This is nn::hid::NpadJoyRightState
 | ||||
|     // This is nn::hid::NpadPalmaState
 | ||||
|     // This is nn::hid::NpadSystemExtState
 | ||||
|     struct NPadGenericState { | ||||
|         s64_le sampling_number{}; | ||||
|         Core::HID::NpadButtonState npad_buttons{}; | ||||
|         Core::HID::AnalogStickState l_stick{}; | ||||
|         Core::HID::AnalogStickState r_stick{}; | ||||
|         NpadAttribute connection_status{}; | ||||
|         INSERT_PADDING_BYTES(4); // Reserved
 | ||||
|     }; | ||||
|     static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::server::NpadGcTriggerState
 | ||||
|     struct NpadGcTriggerState { | ||||
|         s64 sampling_number{}; | ||||
|         s32 l_analog{}; | ||||
|         s32 r_analog{}; | ||||
|     }; | ||||
|     static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::NpadSystemProperties
 | ||||
|     struct NPadSystemProperties { | ||||
|         union { | ||||
|             s64 raw{}; | ||||
|             BitField<0, 1, s64> is_charging_joy_dual; | ||||
|             BitField<1, 1, s64> is_charging_joy_left; | ||||
|             BitField<2, 1, s64> is_charging_joy_right; | ||||
|             BitField<3, 1, s64> is_powered_joy_dual; | ||||
|             BitField<4, 1, s64> is_powered_joy_left; | ||||
|             BitField<5, 1, s64> is_powered_joy_right; | ||||
|             BitField<9, 1, s64> is_system_unsupported_button; | ||||
|             BitField<10, 1, s64> is_system_ext_unsupported_button; | ||||
|             BitField<11, 1, s64> is_vertical; | ||||
|             BitField<12, 1, s64> is_horizontal; | ||||
|             BitField<13, 1, s64> use_plus; | ||||
|             BitField<14, 1, s64> use_minus; | ||||
|             BitField<15, 1, s64> use_directional_buttons; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::NpadSystemButtonProperties
 | ||||
|     struct NpadSystemButtonProperties { | ||||
|         union { | ||||
|             s32 raw{}; | ||||
|             BitField<0, 1, s32> is_home_button_protection_enabled; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(NpadSystemButtonProperties) == 0x4, | ||||
|                   "NPadButtonProperties is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::system::DeviceType
 | ||||
|     struct DeviceType { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
|             BitField<0, 1, s32> fullkey; | ||||
|             BitField<1, 1, s32> debug_pad; | ||||
|             BitField<2, 1, s32> handheld_left; | ||||
|             BitField<3, 1, s32> handheld_right; | ||||
|             BitField<4, 1, s32> joycon_left; | ||||
|             BitField<5, 1, s32> joycon_right; | ||||
|             BitField<6, 1, s32> palma; | ||||
|             BitField<7, 1, s32> lark_hvc_left; | ||||
|             BitField<8, 1, s32> lark_hvc_right; | ||||
|             BitField<9, 1, s32> lark_nes_left; | ||||
|             BitField<10, 1, s32> lark_nes_right; | ||||
|             BitField<11, 1, s32> handheld_lark_hvc_left; | ||||
|             BitField<12, 1, s32> handheld_lark_hvc_right; | ||||
|             BitField<13, 1, s32> handheld_lark_nes_left; | ||||
|             BitField<14, 1, s32> handheld_lark_nes_right; | ||||
|             BitField<15, 1, s32> lucia; | ||||
|             BitField<16, 1, s32> lagon; | ||||
|             BitField<17, 1, s32> lager; | ||||
|             BitField<31, 1, s32> system; | ||||
|         }; | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
 | ||||
|     struct NfcXcdDeviceHandleStateImpl { | ||||
|         u64 handle{}; | ||||
|         bool is_available{}; | ||||
|         bool is_activated{}; | ||||
|         INSERT_PADDING_BYTES(0x6); // Reserved
 | ||||
|         u64 sampling_number{}; | ||||
|     }; | ||||
|     static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | ||||
|                   "NfcXcdDeviceHandleStateImpl is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::NpadLarkType
 | ||||
|     enum class NpadLarkType : u32 { | ||||
|         Invalid, | ||||
|         H1, | ||||
|         H2, | ||||
|         NL, | ||||
|         NR, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadLuciaType
 | ||||
|     enum class NpadLuciaType : u32 { | ||||
|         Invalid, | ||||
|         J, | ||||
|         E, | ||||
|         U, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadLagonType
 | ||||
|     enum class NpadLagonType : u32 { | ||||
|         Invalid, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::NpadLagerType
 | ||||
|     enum class NpadLagerType : u32 { | ||||
|         Invalid, | ||||
|         J, | ||||
|         E, | ||||
|         U, | ||||
|     }; | ||||
| 
 | ||||
|     // This is nn::hid::detail::NpadInternalState
 | ||||
|     struct NpadInternalState { | ||||
|         Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; | ||||
|         NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; | ||||
|         NpadFullKeyColorState fullkey_color{}; | ||||
|         NpadJoyColorState joycon_color{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> fullkey_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> handheld_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> joy_left_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> palma_lifo{}; | ||||
|         Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{}; | ||||
|         Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{}; | ||||
|         DeviceType device_type{}; | ||||
|         INSERT_PADDING_BYTES(0x4); // Reserved
 | ||||
|         NPadSystemProperties system_properties{}; | ||||
|         NpadSystemButtonProperties button_properties{}; | ||||
|         Core::HID::NpadBatteryLevel battery_level_dual{}; | ||||
|         Core::HID::NpadBatteryLevel battery_level_left{}; | ||||
|         Core::HID::NpadBatteryLevel battery_level_right{}; | ||||
|         AppletFooterUiAttributes applet_footer_attributes{}; | ||||
|         AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; | ||||
|         INSERT_PADDING_BYTES(0x5B); // Reserved
 | ||||
|         INSERT_PADDING_BYTES(0x20); // Unknown
 | ||||
|         Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; | ||||
|         NpadLarkType lark_type_l_and_main{}; | ||||
|         NpadLarkType lark_type_r{}; | ||||
|         NpadLuciaType lucia_type{}; | ||||
|         NpadLagonType lagon_type{}; | ||||
|         NpadLagerType lager_type{}; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_left_properties; | ||||
|         Core::HID::SixAxisSensorProperties sixaxis_right_properties; | ||||
|         INSERT_PADDING_BYTES(0xc06); // Unknown
 | ||||
|     }; | ||||
|     static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size"); | ||||
| 
 | ||||
|     struct VibrationData { | ||||
|         bool device_mounted{}; | ||||
|         Core::HID::VibrationValue latest_vibration_value{}; | ||||
|  | ||||
| @ -12,8 +12,7 @@ | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | ||||
|              KernelHelpers::ServiceContext& service_context_) | ||||
| Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) | ||||
|     : ControllerBase{hid_core_}, service_context{service_context_} { | ||||
|     controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); | ||||
|     operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); | ||||
|  | ||||
| @ -97,8 +97,7 @@ public: | ||||
|     static_assert(sizeof(PalmaConnectionHandle) == 0x8, | ||||
|                   "PalmaConnectionHandle has incorrect size."); | ||||
| 
 | ||||
|     explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, | ||||
|                    KernelHelpers::ServiceContext& service_context_); | ||||
|     explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_); | ||||
|     ~Palma() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
|  | ||||
							
								
								
									
										239
									
								
								src/core/hle/service/hid/controllers/shared_memory_format.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								src/core/hle/service/hid/controllers/shared_memory_format.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,239 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid//controllers/types/debug_pad_types.h" | ||||
| #include "core/hle/service/hid//controllers/types/keyboard_types.h" | ||||
| #include "core/hle/service/hid//controllers/types/mouse_types.h" | ||||
| #include "core/hle/service/hid//controllers/types/npad_types.h" | ||||
| #include "core/hle/service/hid//controllers/types/touch_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| static const std::size_t HidEntryCount = 17; | ||||
| 
 | ||||
| struct CommonHeader { | ||||
|     s64 timestamp{}; | ||||
|     s64 total_entry_count{}; | ||||
|     s64 last_entry_index{}; | ||||
|     s64 entry_count{}; | ||||
| }; | ||||
| static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::DebugPadSharedMemoryFormat
 | ||||
| struct DebugPadSharedMemoryFormat { | ||||
|     // This is nn::hid::detail::DebugPadLifo
 | ||||
|     Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{}; | ||||
|     static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); | ||||
|     INSERT_PADDING_WORDS(0x4E); | ||||
| }; | ||||
| static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400, | ||||
|               "DebugPadSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::TouchScreenSharedMemoryFormat
 | ||||
| struct TouchScreenSharedMemoryFormat { | ||||
|     // This is nn::hid::detail::TouchScreenLifo
 | ||||
|     Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{}; | ||||
|     static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | ||||
|     INSERT_PADDING_WORDS(0xF2); | ||||
| }; | ||||
| static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000, | ||||
|               "TouchScreenSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::MouseSharedMemoryFormat
 | ||||
| struct MouseSharedMemoryFormat { | ||||
|     // This is nn::hid::detail::MouseLifo
 | ||||
|     Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{}; | ||||
|     static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); | ||||
|     INSERT_PADDING_WORDS(0x2C); | ||||
| }; | ||||
| static_assert(sizeof(MouseSharedMemoryFormat) == 0x400, | ||||
|               "MouseSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::KeyboardSharedMemoryFormat
 | ||||
| struct KeyboardSharedMemoryFormat { | ||||
|     // This is nn::hid::detail::KeyboardLifo
 | ||||
|     Lifo<KeyboardState, HidEntryCount> keyboard_lifo{}; | ||||
|     static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); | ||||
|     INSERT_PADDING_WORDS(0xA); | ||||
| }; | ||||
| static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400, | ||||
|               "KeyboardSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::DigitizerSharedMemoryFormat
 | ||||
| struct DigitizerSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0xFE0); | ||||
| }; | ||||
| static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, | ||||
|               "DigitizerSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::HomeButtonSharedMemoryFormat
 | ||||
| struct HomeButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
| }; | ||||
| static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, | ||||
|               "HomeButtonSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::SleepButtonSharedMemoryFormat
 | ||||
| struct SleepButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
| }; | ||||
| static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, | ||||
|               "SleepButtonSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::CaptureButtonSharedMemoryFormat
 | ||||
| struct CaptureButtonSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x1E0); | ||||
| }; | ||||
| static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, | ||||
|               "CaptureButtonSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::InputDetectorSharedMemoryFormat
 | ||||
| struct InputDetectorSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x7E0); | ||||
| }; | ||||
| static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800, | ||||
|               "InputDetectorSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::UniquePadSharedMemoryFormat
 | ||||
| struct UniquePadSharedMemoryFormat { | ||||
|     CommonHeader header; | ||||
|     INSERT_PADDING_BYTES(0x3FE0); | ||||
| }; | ||||
| static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000, | ||||
|               "UniquePadSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadSixAxisSensorLifo
 | ||||
| struct NpadSixAxisSensorLifo { | ||||
|     Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo; | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadInternalState
 | ||||
| struct NpadInternalState { | ||||
|     Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; | ||||
|     NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; | ||||
|     NpadFullKeyColorState fullkey_color{}; | ||||
|     NpadJoyColorState joycon_color{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> handheld_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> palma_lifo{}; | ||||
|     Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_fullkey_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_handheld_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_dual_left_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_dual_right_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_left_lifo{}; | ||||
|     NpadSixAxisSensorLifo sixaxis_right_lifo{}; | ||||
|     DeviceType device_type{}; | ||||
|     INSERT_PADDING_BYTES(0x4); // Reserved
 | ||||
|     NPadSystemProperties system_properties{}; | ||||
|     NpadSystemButtonProperties button_properties{}; | ||||
|     Core::HID::NpadBatteryLevel battery_level_dual{}; | ||||
|     Core::HID::NpadBatteryLevel battery_level_left{}; | ||||
|     Core::HID::NpadBatteryLevel battery_level_right{}; | ||||
|     AppletFooterUiAttributes applet_footer_attributes{}; | ||||
|     AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; | ||||
|     INSERT_PADDING_BYTES(0x5B); // Reserved
 | ||||
|     INSERT_PADDING_BYTES(0x20); // Unknown
 | ||||
|     Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{}; | ||||
|     NpadLarkType lark_type_l_and_main{}; | ||||
|     NpadLarkType lark_type_r{}; | ||||
|     NpadLuciaType lucia_type{}; | ||||
|     NpadLagerType lager_type{}; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_left_properties; | ||||
|     Core::HID::SixAxisSensorProperties sixaxis_right_properties; | ||||
| }; | ||||
| static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadSharedMemoryEntry
 | ||||
| struct NpadSharedMemoryEntry { | ||||
|     NpadInternalState internal_state; | ||||
|     INSERT_PADDING_BYTES(0xC08); | ||||
| }; | ||||
| static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadSharedMemoryFormat
 | ||||
| struct NpadSharedMemoryFormat { | ||||
|     std::array<NpadSharedMemoryEntry, NPAD_COUNT> npad_entry; | ||||
| }; | ||||
| static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, | ||||
|               "NpadSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::GestureSharedMemoryFormat
 | ||||
| struct GestureSharedMemoryFormat { | ||||
|     // This is nn::hid::detail::GestureLifo
 | ||||
|     Lifo<GestureState, HidEntryCount> gesture_lifo{}; | ||||
|     static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); | ||||
|     INSERT_PADDING_WORDS(0x3E); | ||||
| }; | ||||
| static_assert(sizeof(GestureSharedMemoryFormat) == 0x800, | ||||
|               "GestureSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
 | ||||
| struct ConsoleSixAxisSensorSharedMemoryFormat { | ||||
|     u64 sampling_number{}; | ||||
|     bool is_seven_six_axis_sensor_at_rest{}; | ||||
|     INSERT_PADDING_BYTES(3); // padding
 | ||||
|     f32 verticalization_error{}; | ||||
|     Common::Vec3f gyro_bias{}; | ||||
|     INSERT_PADDING_BYTES(4); // padding
 | ||||
| }; | ||||
| static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20, | ||||
|               "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| struct SharedMemoryFormat { | ||||
|     void Initialize() {} | ||||
| 
 | ||||
|     DebugPadSharedMemoryFormat debug_pad; | ||||
|     TouchScreenSharedMemoryFormat touch_screen; | ||||
|     MouseSharedMemoryFormat mouse; | ||||
|     KeyboardSharedMemoryFormat keyboard; | ||||
|     DigitizerSharedMemoryFormat digitizer; | ||||
|     HomeButtonSharedMemoryFormat home_button; | ||||
|     SleepButtonSharedMemoryFormat sleep_button; | ||||
|     CaptureButtonSharedMemoryFormat capture_button; | ||||
|     InputDetectorSharedMemoryFormat input_detector; | ||||
|     UniquePadSharedMemoryFormat unique_pad; | ||||
|     NpadSharedMemoryFormat npad; | ||||
|     GestureSharedMemoryFormat gesture; | ||||
|     ConsoleSixAxisSensorSharedMemoryFormat console; | ||||
|     INSERT_PADDING_BYTES(0x19E0); | ||||
|     MouseSharedMemoryFormat debug_mouse; | ||||
|     INSERT_PADDING_BYTES(0x2000); | ||||
| }; | ||||
| static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00, | ||||
|               "sleep_button has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000, | ||||
|               "capture_button has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200, | ||||
|               "input_detector has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset"); | ||||
| static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset"); | ||||
| static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size"); | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
| @ -0,0 +1,49 @@ | ||||
| // 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/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_holder.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| SharedMemoryHolder::SharedMemoryHolder() {} | ||||
| 
 | ||||
| Result SharedMemoryHolder::Initialize(Core::System& system) { | ||||
|     shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); | ||||
|     const Result result = shared_memory->Initialize( | ||||
|         system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, | ||||
|         Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); | ||||
|     if (result.IsError()) { | ||||
|         return result; | ||||
|     } | ||||
|     Kernel::KSharedMemory::Register(system.Kernel(), shared_memory); | ||||
| 
 | ||||
|     is_created = true; | ||||
|     is_mapped = true; | ||||
|     address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer())); | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| void SharedMemoryHolder::Finalize() { | ||||
|     if (address != nullptr) { | ||||
|         shared_memory->Close(); | ||||
|     } | ||||
|     is_created = false; | ||||
|     is_mapped = false; | ||||
|     address = nullptr; | ||||
| } | ||||
| 
 | ||||
| bool SharedMemoryHolder::IsMapped() { | ||||
|     return is_mapped; | ||||
| } | ||||
| 
 | ||||
| SharedMemoryFormat* SharedMemoryHolder::GetAddress() { | ||||
|     return address; | ||||
| } | ||||
| 
 | ||||
| Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() { | ||||
|     return shared_memory; | ||||
| } | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										44
									
								
								src/core/hle/service/hid/controllers/shared_memory_holder.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/core/hle/service/hid/controllers/shared_memory_holder.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/result.h" | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } | ||||
| 
 | ||||
| namespace Kernel { | ||||
| class KSharedMemory; | ||||
| } | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct SharedMemoryFormat; | ||||
| 
 | ||||
| // This is nn::hid::detail::SharedMemoryHolder
 | ||||
| class SharedMemoryHolder { | ||||
| public: | ||||
|     SharedMemoryHolder(); | ||||
| 
 | ||||
|     Result Initialize(Core::System& system); | ||||
|     void Finalize(); | ||||
| 
 | ||||
|     bool IsMapped(); | ||||
|     SharedMemoryFormat* GetAddress(); | ||||
|     Kernel::KSharedMemory* GetHandle(); | ||||
| 
 | ||||
| private: | ||||
|     bool is_owner{}; | ||||
|     bool is_created{}; | ||||
|     bool is_mapped{}; | ||||
|     INSERT_PADDING_BYTES(0x5); | ||||
|     Kernel::KSharedMemory* shared_memory; | ||||
|     INSERT_PADDING_BYTES(0x38); | ||||
|     SharedMemoryFormat* address = nullptr; | ||||
| }; | ||||
| // Correct size is 0x50 bytes
 | ||||
| static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
| @ -6,6 +6,7 @@ | ||||
| #include "core/hid/emulated_controller.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/npad.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/controllers/six_axis.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| #include "core/hle/service/hid/hid_util.h" | ||||
| @ -132,30 +133,30 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         } | ||||
| 
 | ||||
|         sixaxis_fullkey_state.sampling_number = | ||||
|             sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|         sixaxis_handheld_state.sampling_number = | ||||
|             sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|         sixaxis_dual_left_state.sampling_number = | ||||
|             sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|         sixaxis_dual_right_state.sampling_number = | ||||
|             sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|         sixaxis_left_lifo_state.sampling_number = | ||||
|             sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|         sixaxis_right_lifo_state.sampling_number = | ||||
|             sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
|             sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; | ||||
| 
 | ||||
|         if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { | ||||
|             // This buffer only is updated on handheld on HW
 | ||||
|             sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); | ||||
|             sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state); | ||||
|         } else { | ||||
|             // Handheld doesn't update this buffer on HW
 | ||||
|             sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); | ||||
|             sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state); | ||||
|         } | ||||
| 
 | ||||
|         sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); | ||||
|         sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); | ||||
|         sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); | ||||
|         sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); | ||||
|         sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state); | ||||
|         sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state); | ||||
|         sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state); | ||||
|         sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -4,15 +4,14 @@ | ||||
| #include <cstring> | ||||
| #include "common/common_types.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/controllers/stubbed.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase{hid_core_} { | ||||
|     raw_shared_memory = raw_shared_memory_; | ||||
| } | ||||
| Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, | ||||
|                                        CommonHeader& ring_lifo_header) | ||||
|     : ControllerBase{hid_core_}, header{ring_lifo_header} {} | ||||
| 
 | ||||
| Controller_Stubbed::~Controller_Stubbed() = default; | ||||
| 
 | ||||
| @ -25,18 +24,10 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     CommonHeader header{}; | ||||
|     header.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     header.total_entry_count = 17; | ||||
|     header.entry_count = 0; | ||||
|     header.last_entry_index = 0; | ||||
| 
 | ||||
|     std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader)); | ||||
| } | ||||
| 
 | ||||
| void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { | ||||
|     common_offset = off; | ||||
|     smart_update = true; | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -7,9 +7,11 @@ | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct CommonHeader; | ||||
| 
 | ||||
| class Controller_Stubbed final : public ControllerBase { | ||||
| public: | ||||
|     explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, CommonHeader& ring_lifo_header); | ||||
|     ~Controller_Stubbed() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -21,19 +23,8 @@ public: | ||||
|     // When the controller is requesting an update for the shared memory
 | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
|     void SetCommonHeaderOffset(std::size_t off); | ||||
| 
 | ||||
| private: | ||||
|     struct CommonHeader { | ||||
|         s64 timestamp{}; | ||||
|         s64 total_entry_count{}; | ||||
|         s64 last_entry_index{}; | ||||
|         s64 entry_count{}; | ||||
|     }; | ||||
|     static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | ||||
| 
 | ||||
|     u8* raw_shared_memory = nullptr; | ||||
|     CommonHeader& header; | ||||
|     bool smart_update{}; | ||||
|     std::size_t common_offset{}; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
|  | ||||
| @ -10,18 +10,16 @@ | ||||
| #include "core/frontend/emu_window.h" | ||||
| #include "core/hid/emulated_console.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/controllers/touchscreen.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; | ||||
| 
 | ||||
| TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) | ||||
|     : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width), | ||||
| TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, | ||||
|                          TouchScreenSharedMemoryFormat& touch_shared_memory) | ||||
|     : ControllerBase{hid_core_}, shared_memory{touch_shared_memory}, | ||||
|       touchscreen_width(Layout::ScreenUndocked::Width), | ||||
|       touchscreen_height(Layout::ScreenUndocked::Height) { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size, | ||||
|                   "TouchSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
|     console = hid_core.GetEmulatedConsole(); | ||||
| } | ||||
| 
 | ||||
| @ -32,11 +30,11 @@ void TouchScreen::OnInit() {} | ||||
| void TouchScreen::OnRelease() {} | ||||
| 
 | ||||
| void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
|     shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); | ||||
| 
 | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->touch_screen_lifo.buffer_count = 0; | ||||
|         shared_memory->touch_screen_lifo.buffer_tail = 0; | ||||
|         shared_memory.touch_screen_lifo.buffer_count = 0; | ||||
|         shared_memory.touch_screen_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| @ -86,7 +84,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); | ||||
| 
 | ||||
|     const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); | ||||
|     const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; | ||||
|     const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state; | ||||
| 
 | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
|     next_state.entry_count = static_cast<s32>(active_fingers_count); | ||||
| @ -118,7 +116,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     shared_memory->touch_screen_lifo.WriteNextEntry(next_state); | ||||
|     shared_memory.touch_screen_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { | ||||
|  | ||||
| @ -3,10 +3,12 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_funcs.h" | ||||
| #include <array> | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/controllers/types/touch_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Core::HID { | ||||
| @ -14,9 +16,12 @@ class EmulatedConsole; | ||||
| } // namespace Core::HID
 | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| struct TouchScreenSharedMemoryFormat; | ||||
| 
 | ||||
| class TouchScreen final : public ControllerBase { | ||||
| public: | ||||
|     explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     explicit TouchScreen(Core::HID::HIDCore& hid_core_, | ||||
|                          TouchScreenSharedMemoryFormat& touch_shared_memory); | ||||
|     ~TouchScreen() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
| @ -31,27 +36,8 @@ public: | ||||
|     void SetTouchscreenDimensions(u32 width, u32 height); | ||||
| 
 | ||||
| private: | ||||
|     static constexpr std::size_t MAX_FINGERS = 16; | ||||
| 
 | ||||
|     // This is nn::hid::TouchScreenState
 | ||||
|     struct TouchScreenState { | ||||
|         s64 sampling_number{}; | ||||
|         s32 entry_count{}; | ||||
|         INSERT_PADDING_BYTES(4); // Reserved
 | ||||
|         std::array<Core::HID::TouchState, MAX_FINGERS> states{}; | ||||
|     }; | ||||
|     static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); | ||||
| 
 | ||||
|     struct TouchSharedMemory { | ||||
|         // This is nn::hid::detail::TouchScreenLifo
 | ||||
|         Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; | ||||
|         static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0xF2); | ||||
|     }; | ||||
|     static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     TouchScreenState next_state{}; | ||||
|     TouchSharedMemory* shared_memory = nullptr; | ||||
|     TouchScreenSharedMemoryFormat& shared_memory; | ||||
|     Core::HID::EmulatedConsole* console = nullptr; | ||||
| 
 | ||||
|     std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; | ||||
|  | ||||
							
								
								
									
										31
									
								
								src/core/hle/service/hid/controllers/types/debug_pad_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/core/hle/service/hid/controllers/types/debug_pad_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| // This is nn::hid::DebugPadAttribute
 | ||||
| struct DebugPadAttribute { | ||||
|     union { | ||||
|         u32 raw{}; | ||||
|         BitField<0, 1, u32> connected; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::DebugPadState
 | ||||
| struct DebugPadState { | ||||
|     s64 sampling_number{}; | ||||
|     DebugPadAttribute attribute{}; | ||||
|     Core::HID::DebugPadButton pad_state{}; | ||||
|     Core::HID::AnalogStickState r_stick{}; | ||||
|     Core::HID::AnalogStickState l_stick{}; | ||||
| }; | ||||
| static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										77
									
								
								src/core/hle/service/hid/controllers/types/gesture_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/core/hle/service/hid/controllers/types/gesture_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| // 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 "common/point.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| static constexpr size_t MAX_FINGERS = 16; | ||||
| static constexpr size_t MAX_POINTS = 4; | ||||
| 
 | ||||
| // This is nn::hid::GestureType
 | ||||
| enum class GestureType : u32 { | ||||
|     Idle,     // Nothing touching the screen
 | ||||
|     Complete, // Set at the end of a touch event
 | ||||
|     Cancel,   // Set when the number of fingers change
 | ||||
|     Touch,    // A finger just touched the screen
 | ||||
|     Press,    // Set if last type is touch and the finger hasn't moved
 | ||||
|     Tap,      // Fast press then release
 | ||||
|     Pan,      // All points moving together across the screen
 | ||||
|     Swipe,    // Fast press movement and release of a single point
 | ||||
|     Pinch,    // All points moving away/closer to the midpoint
 | ||||
|     Rotate,   // All points rotating from the midpoint
 | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::GestureDirection
 | ||||
| enum class GestureDirection : u32 { | ||||
|     None, | ||||
|     Left, | ||||
|     Up, | ||||
|     Right, | ||||
|     Down, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::GestureAttribute
 | ||||
| struct GestureAttribute { | ||||
|     union { | ||||
|         u32 raw{}; | ||||
| 
 | ||||
|         BitField<4, 1, u32> is_new_touch; | ||||
|         BitField<8, 1, u32> is_double_tap; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::GestureState
 | ||||
| struct GestureState { | ||||
|     s64 sampling_number{}; | ||||
|     s64 detection_count{}; | ||||
|     GestureType type{GestureType::Idle}; | ||||
|     GestureDirection direction{GestureDirection::None}; | ||||
|     Common::Point<s32> pos{}; | ||||
|     Common::Point<s32> delta{}; | ||||
|     f32 vel_x{}; | ||||
|     f32 vel_y{}; | ||||
|     GestureAttribute attributes{}; | ||||
|     f32 scale{}; | ||||
|     f32 rotation_angle{}; | ||||
|     s32 point_count{}; | ||||
|     std::array<Common::Point<s32>, 4> points{}; | ||||
| }; | ||||
| static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||||
| 
 | ||||
| struct GestureProperties { | ||||
|     std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||||
|     std::size_t active_points{}; | ||||
|     Common::Point<s32> mid_point{}; | ||||
|     s64 detection_count{}; | ||||
|     u64 delta_time{}; | ||||
|     f32 average_distance{}; | ||||
|     f32 angle{}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										20
									
								
								src/core/hle/service/hid/controllers/types/keyboard_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/core/hle/service/hid/controllers/types/keyboard_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| // This is nn::hid::detail::KeyboardState
 | ||||
| struct KeyboardState { | ||||
|     s64 sampling_number{}; | ||||
|     Core::HID::KeyboardModifier modifier{}; | ||||
|     Core::HID::KeyboardAttribute attribute{}; | ||||
|     Core::HID::KeyboardKey key{}; | ||||
| }; | ||||
| static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										12
									
								
								src/core/hle/service/hid/controllers/types/mouse_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/core/hle/service/hid/controllers/types/mouse_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Service::HID {} // namespace Service::HID
 | ||||
							
								
								
									
										255
									
								
								src/core/hle/service/hid/controllers/types/npad_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										255
									
								
								src/core/hle/service/hid/controllers/types/npad_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,255 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/vector_math.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| static constexpr std::size_t NPAD_COUNT = 10; | ||||
| 
 | ||||
| // This is nn::hid::NpadJoyHoldType
 | ||||
| enum class NpadJoyHoldType : u64 { | ||||
|     Vertical = 0, | ||||
|     Horizontal = 1, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadJoyAssignmentMode
 | ||||
| enum class NpadJoyAssignmentMode : u32 { | ||||
|     Dual = 0, | ||||
|     Single = 1, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadJoyDeviceType
 | ||||
| enum class NpadJoyDeviceType : s64 { | ||||
|     Left = 0, | ||||
|     Right = 1, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadHandheldActivationMode
 | ||||
| enum class NpadHandheldActivationMode : u64 { | ||||
|     Dual = 0, | ||||
|     Single = 1, | ||||
|     None = 2, | ||||
|     MaxActivationMode = 3, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::system::AppletFooterUiAttributesSet
 | ||||
| struct AppletFooterUiAttributes { | ||||
|     INSERT_PADDING_BYTES(0x4); | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::system::AppletFooterUiType
 | ||||
| enum class AppletFooterUiType : u8 { | ||||
|     None = 0, | ||||
|     HandheldNone = 1, | ||||
|     HandheldJoyConLeftOnly = 2, | ||||
|     HandheldJoyConRightOnly = 3, | ||||
|     HandheldJoyConLeftJoyConRight = 4, | ||||
|     JoyDual = 5, | ||||
|     JoyDualLeftOnly = 6, | ||||
|     JoyDualRightOnly = 7, | ||||
|     JoyLeftHorizontal = 8, | ||||
|     JoyLeftVertical = 9, | ||||
|     JoyRightHorizontal = 10, | ||||
|     JoyRightVertical = 11, | ||||
|     SwitchProController = 12, | ||||
|     CompatibleProController = 13, | ||||
|     CompatibleJoyCon = 14, | ||||
|     LarkHvc1 = 15, | ||||
|     LarkHvc2 = 16, | ||||
|     LarkNesLeft = 17, | ||||
|     LarkNesRight = 18, | ||||
|     Lucia = 19, | ||||
|     Verification = 20, | ||||
|     Lagon = 21, | ||||
| }; | ||||
| 
 | ||||
| using AppletFooterUiVariant = u8; | ||||
| 
 | ||||
| // This is "nn::hid::system::AppletDetailedUiType".
 | ||||
| struct AppletDetailedUiType { | ||||
|     AppletFooterUiVariant ui_variant; | ||||
|     INSERT_PADDING_BYTES(0x2); | ||||
|     AppletFooterUiType footer; | ||||
| }; | ||||
| static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); | ||||
| // This is nn::hid::NpadCommunicationMode
 | ||||
| enum class NpadCommunicationMode : u64 { | ||||
|     Mode_5ms = 0, | ||||
|     Mode_10ms = 1, | ||||
|     Mode_15ms = 2, | ||||
|     Default = 3, | ||||
| }; | ||||
| 
 | ||||
| enum class NpadRevision : u32 { | ||||
|     Revision0 = 0, | ||||
|     Revision1 = 1, | ||||
|     Revision2 = 2, | ||||
|     Revision3 = 3, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::detail::ColorAttribute
 | ||||
| enum class ColorAttribute : u32 { | ||||
|     Ok = 0, | ||||
|     ReadError = 1, | ||||
|     NoController = 2, | ||||
| }; | ||||
| static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadFullKeyColorState
 | ||||
| struct NpadFullKeyColorState { | ||||
|     ColorAttribute attribute{ColorAttribute::NoController}; | ||||
|     Core::HID::NpadControllerColor fullkey{}; | ||||
| }; | ||||
| static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::detail::NpadJoyColorState
 | ||||
| struct NpadJoyColorState { | ||||
|     ColorAttribute attribute{ColorAttribute::NoController}; | ||||
|     Core::HID::NpadControllerColor left{}; | ||||
|     Core::HID::NpadControllerColor right{}; | ||||
| }; | ||||
| static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::NpadAttribute
 | ||||
| struct NpadAttribute { | ||||
|     union { | ||||
|         u32 raw{}; | ||||
|         BitField<0, 1, u32> is_connected; | ||||
|         BitField<1, 1, u32> is_wired; | ||||
|         BitField<2, 1, u32> is_left_connected; | ||||
|         BitField<3, 1, u32> is_left_wired; | ||||
|         BitField<4, 1, u32> is_right_connected; | ||||
|         BitField<5, 1, u32> is_right_wired; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::NpadFullKeyState
 | ||||
| // This is nn::hid::NpadHandheldState
 | ||||
| // This is nn::hid::NpadJoyDualState
 | ||||
| // This is nn::hid::NpadJoyLeftState
 | ||||
| // This is nn::hid::NpadJoyRightState
 | ||||
| // This is nn::hid::NpadPalmaState
 | ||||
| // This is nn::hid::NpadSystemExtState
 | ||||
| struct NPadGenericState { | ||||
|     s64_le sampling_number{}; | ||||
|     Core::HID::NpadButtonState npad_buttons{}; | ||||
|     Core::HID::AnalogStickState l_stick{}; | ||||
|     Core::HID::AnalogStickState r_stick{}; | ||||
|     NpadAttribute connection_status{}; | ||||
|     INSERT_PADDING_BYTES(4); // Reserved
 | ||||
| }; | ||||
| static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::server::NpadGcTriggerState
 | ||||
| struct NpadGcTriggerState { | ||||
|     s64 sampling_number{}; | ||||
|     s32 l_analog{}; | ||||
|     s32 r_analog{}; | ||||
| }; | ||||
| static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::NpadSystemProperties
 | ||||
| struct NPadSystemProperties { | ||||
|     union { | ||||
|         s64 raw{}; | ||||
|         BitField<0, 1, s64> is_charging_joy_dual; | ||||
|         BitField<1, 1, s64> is_charging_joy_left; | ||||
|         BitField<2, 1, s64> is_charging_joy_right; | ||||
|         BitField<3, 1, s64> is_powered_joy_dual; | ||||
|         BitField<4, 1, s64> is_powered_joy_left; | ||||
|         BitField<5, 1, s64> is_powered_joy_right; | ||||
|         BitField<9, 1, s64> is_system_unsupported_button; | ||||
|         BitField<10, 1, s64> is_system_ext_unsupported_button; | ||||
|         BitField<11, 1, s64> is_vertical; | ||||
|         BitField<12, 1, s64> is_horizontal; | ||||
|         BitField<13, 1, s64> use_plus; | ||||
|         BitField<14, 1, s64> use_minus; | ||||
|         BitField<15, 1, s64> use_directional_buttons; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::NpadSystemButtonProperties
 | ||||
| struct NpadSystemButtonProperties { | ||||
|     union { | ||||
|         s32 raw{}; | ||||
|         BitField<0, 1, s32> is_home_button_protection_enabled; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::system::DeviceType
 | ||||
| struct DeviceType { | ||||
|     union { | ||||
|         u32 raw{}; | ||||
|         BitField<0, 1, s32> fullkey; | ||||
|         BitField<1, 1, s32> debug_pad; | ||||
|         BitField<2, 1, s32> handheld_left; | ||||
|         BitField<3, 1, s32> handheld_right; | ||||
|         BitField<4, 1, s32> joycon_left; | ||||
|         BitField<5, 1, s32> joycon_right; | ||||
|         BitField<6, 1, s32> palma; | ||||
|         BitField<7, 1, s32> lark_hvc_left; | ||||
|         BitField<8, 1, s32> lark_hvc_right; | ||||
|         BitField<9, 1, s32> lark_nes_left; | ||||
|         BitField<10, 1, s32> lark_nes_right; | ||||
|         BitField<11, 1, s32> handheld_lark_hvc_left; | ||||
|         BitField<12, 1, s32> handheld_lark_hvc_right; | ||||
|         BitField<13, 1, s32> handheld_lark_nes_left; | ||||
|         BitField<14, 1, s32> handheld_lark_nes_right; | ||||
|         BitField<15, 1, s32> lucia; | ||||
|         BitField<16, 1, s32> lagon; | ||||
|         BitField<17, 1, s32> lager; | ||||
|         BitField<31, 1, s32> system; | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
 | ||||
| struct NfcXcdDeviceHandleStateImpl { | ||||
|     u64 handle{}; | ||||
|     bool is_available{}; | ||||
|     bool is_activated{}; | ||||
|     INSERT_PADDING_BYTES(0x6); // Reserved
 | ||||
|     u64 sampling_number{}; | ||||
| }; | ||||
| static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, | ||||
|               "NfcXcdDeviceHandleStateImpl is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::NpadLarkType
 | ||||
| enum class NpadLarkType : u32 { | ||||
|     Invalid, | ||||
|     H1, | ||||
|     H2, | ||||
|     NL, | ||||
|     NR, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadLuciaType
 | ||||
| enum class NpadLuciaType : u32 { | ||||
|     Invalid, | ||||
|     J, | ||||
|     E, | ||||
|     U, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadLagonType
 | ||||
| enum class NpadLagonType : u32 { | ||||
|     Invalid, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::NpadLagerType
 | ||||
| enum class NpadLagerType : u32 { | ||||
|     Invalid, | ||||
|     J, | ||||
|     E, | ||||
|     U, | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
							
								
								
									
										90
									
								
								src/core/hle/service/hid/controllers/types/touch_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/core/hle/service/hid/controllers/types/touch_types.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-3.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| 
 | ||||
| #include <array> | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_funcs.h" | ||||
| #include "common/common_types.h" | ||||
| #include "common/point.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| static constexpr std::size_t MAX_FINGERS = 16; | ||||
| static constexpr size_t MAX_POINTS = 4; | ||||
| 
 | ||||
| // This is nn::hid::GestureType
 | ||||
| enum class GestureType : u32 { | ||||
|     Idle,     // Nothing touching the screen
 | ||||
|     Complete, // Set at the end of a touch event
 | ||||
|     Cancel,   // Set when the number of fingers change
 | ||||
|     Touch,    // A finger just touched the screen
 | ||||
|     Press,    // Set if last type is touch and the finger hasn't moved
 | ||||
|     Tap,      // Fast press then release
 | ||||
|     Pan,      // All points moving together across the screen
 | ||||
|     Swipe,    // Fast press movement and release of a single point
 | ||||
|     Pinch,    // All points moving away/closer to the midpoint
 | ||||
|     Rotate,   // All points rotating from the midpoint
 | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::GestureDirection
 | ||||
| enum class GestureDirection : u32 { | ||||
|     None, | ||||
|     Left, | ||||
|     Up, | ||||
|     Right, | ||||
|     Down, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::GestureAttribute
 | ||||
| struct GestureAttribute { | ||||
|     union { | ||||
|         u32 raw{}; | ||||
| 
 | ||||
|         BitField<4, 1, u32> is_new_touch; | ||||
|         BitField<8, 1, u32> is_double_tap; | ||||
|     }; | ||||
| }; | ||||
| static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); | ||||
| 
 | ||||
| // This is nn::hid::GestureState
 | ||||
| struct GestureState { | ||||
|     s64 sampling_number{}; | ||||
|     s64 detection_count{}; | ||||
|     GestureType type{GestureType::Idle}; | ||||
|     GestureDirection direction{GestureDirection::None}; | ||||
|     Common::Point<s32> pos{}; | ||||
|     Common::Point<s32> delta{}; | ||||
|     f32 vel_x{}; | ||||
|     f32 vel_y{}; | ||||
|     GestureAttribute attributes{}; | ||||
|     f32 scale{}; | ||||
|     f32 rotation_angle{}; | ||||
|     s32 point_count{}; | ||||
|     std::array<Common::Point<s32>, 4> points{}; | ||||
| }; | ||||
| static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); | ||||
| 
 | ||||
| struct GestureProperties { | ||||
|     std::array<Common::Point<s32>, MAX_POINTS> points{}; | ||||
|     std::size_t active_points{}; | ||||
|     Common::Point<s32> mid_point{}; | ||||
|     s64 detection_count{}; | ||||
|     u64 delta_time{}; | ||||
|     f32 average_distance{}; | ||||
|     f32 angle{}; | ||||
| }; | ||||
| 
 | ||||
| // This is nn::hid::TouchScreenState
 | ||||
| struct TouchScreenState { | ||||
|     s64 sampling_number{}; | ||||
|     s32 entry_count{}; | ||||
|     INSERT_PADDING_BYTES(4); // Reserved
 | ||||
|     std::array<Core::HID::TouchState, MAX_FINGERS> states{}; | ||||
| }; | ||||
| static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
| @ -1,39 +0,0 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include <cstring> | ||||
| #include "common/common_types.h" | ||||
| #include "core/core_timing.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/service/hid/controllers/xpad.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; | ||||
| 
 | ||||
| XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { | ||||
|     static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size, | ||||
|                   "XpadSharedMemory is bigger than the shared memory"); | ||||
|     shared_memory = std::construct_at( | ||||
|         reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET)); | ||||
| } | ||||
| XPad::~XPad() = default; | ||||
| 
 | ||||
| void XPad::OnInit() {} | ||||
| 
 | ||||
| void XPad::OnRelease() {} | ||||
| 
 | ||||
| void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | ||||
|     if (!IsControllerActivated()) { | ||||
|         shared_memory->basic_xpad_lifo.buffer_count = 0; | ||||
|         shared_memory->basic_xpad_lifo.buffer_tail = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state; | ||||
|     next_state.sampling_number = last_entry.sampling_number + 1; | ||||
|     // TODO(ogniK): Update xpad states
 | ||||
| 
 | ||||
|     shared_memory->basic_xpad_lifo.WriteNextEntry(next_state); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::HID
 | ||||
| @ -1,112 +0,0 @@ | ||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/bit_field.h" | ||||
| #include "common/common_types.h" | ||||
| #include "core/hid/hid_types.h" | ||||
| #include "core/hle/service/hid/controllers/controller_base.h" | ||||
| #include "core/hle/service/hid/ring_lifo.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| class XPad final : public ControllerBase { | ||||
| public: | ||||
|     explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); | ||||
|     ~XPad() override; | ||||
| 
 | ||||
|     // Called when the controller is initialized
 | ||||
|     void OnInit() override; | ||||
| 
 | ||||
|     // When the controller is released
 | ||||
|     void OnRelease() override; | ||||
| 
 | ||||
|     // When the controller is requesting an update for the shared memory
 | ||||
|     void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | ||||
| 
 | ||||
| private: | ||||
|     // This is nn::hid::BasicXpadAttributeSet
 | ||||
|     struct BasicXpadAttributeSet { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
|             BitField<0, 1, u32> is_connected; | ||||
|             BitField<1, 1, u32> is_wired; | ||||
|             BitField<2, 1, u32> is_left_connected; | ||||
|             BitField<3, 1, u32> is_left_wired; | ||||
|             BitField<4, 1, u32> is_right_connected; | ||||
|             BitField<5, 1, u32> is_right_wired; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::BasicXpadButtonSet
 | ||||
|     struct BasicXpadButtonSet { | ||||
|         union { | ||||
|             u32 raw{}; | ||||
|             // Button states
 | ||||
|             BitField<0, 1, u32> a; | ||||
|             BitField<1, 1, u32> b; | ||||
|             BitField<2, 1, u32> x; | ||||
|             BitField<3, 1, u32> y; | ||||
|             BitField<4, 1, u32> l_stick; | ||||
|             BitField<5, 1, u32> r_stick; | ||||
|             BitField<6, 1, u32> l; | ||||
|             BitField<7, 1, u32> r; | ||||
|             BitField<8, 1, u32> zl; | ||||
|             BitField<9, 1, u32> zr; | ||||
|             BitField<10, 1, u32> plus; | ||||
|             BitField<11, 1, u32> minus; | ||||
| 
 | ||||
|             // D-Pad
 | ||||
|             BitField<12, 1, u32> d_left; | ||||
|             BitField<13, 1, u32> d_up; | ||||
|             BitField<14, 1, u32> d_right; | ||||
|             BitField<15, 1, u32> d_down; | ||||
| 
 | ||||
|             // Left JoyStick
 | ||||
|             BitField<16, 1, u32> l_stick_left; | ||||
|             BitField<17, 1, u32> l_stick_up; | ||||
|             BitField<18, 1, u32> l_stick_right; | ||||
|             BitField<19, 1, u32> l_stick_down; | ||||
| 
 | ||||
|             // Right JoyStick
 | ||||
|             BitField<20, 1, u32> r_stick_left; | ||||
|             BitField<21, 1, u32> r_stick_up; | ||||
|             BitField<22, 1, u32> r_stick_right; | ||||
|             BitField<23, 1, u32> r_stick_down; | ||||
| 
 | ||||
|             // Not always active?
 | ||||
|             BitField<24, 1, u32> left_sl; | ||||
|             BitField<25, 1, u32> left_sr; | ||||
| 
 | ||||
|             BitField<26, 1, u32> right_sl; | ||||
|             BitField<27, 1, u32> right_sr; | ||||
| 
 | ||||
|             BitField<28, 1, u32> palma; | ||||
|             BitField<30, 1, u32> handheld_left_b; | ||||
|         }; | ||||
|     }; | ||||
|     static_assert(sizeof(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size"); | ||||
| 
 | ||||
|     // This is nn::hid::detail::BasicXpadState
 | ||||
|     struct BasicXpadState { | ||||
|         s64 sampling_number{}; | ||||
|         BasicXpadAttributeSet attributes{}; | ||||
|         BasicXpadButtonSet pad_states{}; | ||||
|         Core::HID::AnalogStickState l_stick{}; | ||||
|         Core::HID::AnalogStickState r_stick{}; | ||||
|     }; | ||||
|     static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); | ||||
| 
 | ||||
|     struct XpadSharedMemory { | ||||
|         // This is nn::hid::detail::BasicXpadLifo
 | ||||
|         Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; | ||||
|         static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); | ||||
|         INSERT_PADDING_WORDS(0x4E); | ||||
|     }; | ||||
|     static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size"); | ||||
| 
 | ||||
|     BasicXpadState next_state{}; | ||||
|     XpadSharedMemory* shared_memory = nullptr; | ||||
| }; | ||||
| } // namespace Service::HID
 | ||||
| @ -28,6 +28,7 @@ | ||||
| #include "core/hle/service/hid/controllers/seven_six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/touchscreen.h" | ||||
| #include "core/hle/service/hid/controllers/types/npad_types.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| @ -1099,7 +1100,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) { | ||||
| void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     struct Parameters { | ||||
|         NPad::NpadRevision revision; | ||||
|         NpadRevision revision; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|     }; | ||||
| @ -1122,7 +1123,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { | ||||
| void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto applet_resource_user_id{rp.Pop<u64>()}; | ||||
|     const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()}; | ||||
|     const auto hold_type{rp.PopEnum<NpadJoyHoldType>()}; | ||||
| 
 | ||||
|     GetResourceManager()->GetNpad()->SetHoldType(hold_type); | ||||
| 
 | ||||
| @ -1157,8 +1158,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) | ||||
| 
 | ||||
|     Core::HID::NpadIdType new_npad_id{}; | ||||
|     auto controller = GetResourceManager()->GetNpad(); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left, | ||||
|                             NPad::NpadJoyAssignmentMode::Single); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left, | ||||
|                             NpadJoyAssignmentMode::Single); | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||||
|              parameters.applet_resource_user_id); | ||||
| @ -1173,7 +1174,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | ||||
|         Core::HID::NpadIdType npad_id; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|         NPad::NpadJoyDeviceType npad_joy_device_type; | ||||
|         NpadJoyDeviceType npad_joy_device_type; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||||
| 
 | ||||
| @ -1182,7 +1183,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) { | ||||
|     Core::HID::NpadIdType new_npad_id{}; | ||||
|     auto controller = GetResourceManager()->GetNpad(); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||||
|                             NPad::NpadJoyAssignmentMode::Single); | ||||
|                             NpadJoyAssignmentMode::Single); | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||||
|              parameters.npad_id, parameters.applet_resource_user_id, | ||||
| @ -1205,7 +1206,7 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) { | ||||
| 
 | ||||
|     Core::HID::NpadIdType new_npad_id{}; | ||||
|     auto controller = GetResourceManager()->GetNpad(); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); | ||||
|     controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual); | ||||
| 
 | ||||
|     LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, | ||||
|               parameters.applet_resource_user_id); // Spams a lot when controller applet is open
 | ||||
| @ -1257,7 +1258,7 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) { | ||||
| void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto applet_resource_user_id{rp.Pop<u64>()}; | ||||
|     const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()}; | ||||
|     const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()}; | ||||
| 
 | ||||
|     GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); | ||||
| 
 | ||||
| @ -1349,7 +1350,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext | ||||
|         Core::HID::NpadIdType npad_id; | ||||
|         INSERT_PADDING_WORDS_NOINIT(1); | ||||
|         u64 applet_resource_user_id; | ||||
|         NPad::NpadJoyDeviceType npad_joy_device_type; | ||||
|         NpadJoyDeviceType npad_joy_device_type; | ||||
|     }; | ||||
|     static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); | ||||
| 
 | ||||
| @ -1359,7 +1360,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext | ||||
|     auto controller = GetResourceManager()->GetNpad(); | ||||
|     const auto is_reassigned = | ||||
|         controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, | ||||
|                                 NPad::NpadJoyAssignmentMode::Single); | ||||
|                                 NpadJoyAssignmentMode::Single); | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", | ||||
|              parameters.npad_id, parameters.applet_resource_user_id, | ||||
| @ -2315,7 +2316,7 @@ void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) { | ||||
| void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { | ||||
|     IPC::RequestParser rp{ctx}; | ||||
|     const auto applet_resource_user_id{rp.Pop<u64>()}; | ||||
|     const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()}; | ||||
|     const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()}; | ||||
| 
 | ||||
|     GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); | ||||
| 
 | ||||
|  | ||||
| @ -5,6 +5,7 @@ | ||||
| #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/controllers/types/npad_types.h" | ||||
| #include "core/hle/service/hid/errors.h" | ||||
| #include "core/hle/service/hid/hid_system_server.h" | ||||
| #include "core/hle/service/hid/resource_manager.h" | ||||
| @ -328,7 +329,7 @@ void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_HID, "called, npad_id_type={}", | ||||
|               npad_id_type); // Spams a lot when controller applet is running
 | ||||
| 
 | ||||
|     const NPad::AppletDetailedUiType detailed_ui_type = | ||||
|     const AppletDetailedUiType detailed_ui_type = | ||||
|         GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); | ||||
| 
 | ||||
|     IPC::ResponseBuilder rb{ctx, 3}; | ||||
|  | ||||
| @ -18,10 +18,10 @@ | ||||
| #include "core/hle/service/hid/controllers/npad.h" | ||||
| #include "core/hle/service/hid/controllers/palma.h" | ||||
| #include "core/hle/service/hid/controllers/seven_six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/shared_memory_format.h" | ||||
| #include "core/hle/service/hid/controllers/six_axis.h" | ||||
| #include "core/hle/service/hid/controllers/stubbed.h" | ||||
| #include "core/hle/service/hid/controllers/touchscreen.h" | ||||
| #include "core/hle/service/hid/controllers/xpad.h" | ||||
| 
 | ||||
| namespace Service::HID { | ||||
| 
 | ||||
| @ -45,40 +45,43 @@ void ResourceManager::Initialize() { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); | ||||
|     debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory); | ||||
|     mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory); | ||||
|     debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory); | ||||
|     keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory); | ||||
|     unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory); | ||||
|     npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context); | ||||
|     gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory); | ||||
|     touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory); | ||||
|     xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory); | ||||
|     system.HIDCore().ReloadInputDevices(); | ||||
|     is_initialized = true; | ||||
| } | ||||
| 
 | ||||
|     palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context); | ||||
| void ResourceManager::InitializeController(u64 aruid) { | ||||
|     SharedMemoryFormat* shared_memory = nullptr; | ||||
|     const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid); | ||||
|     if (result.IsError()) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory); | ||||
|     sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory); | ||||
|     capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory); | ||||
|     debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad); | ||||
|     mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse); | ||||
|     debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse); | ||||
|     keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard); | ||||
|     unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header); | ||||
|     npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context); | ||||
|     gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture); | ||||
|     touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen); | ||||
| 
 | ||||
|     palma = std::make_shared<Palma>(system.HIDCore(), service_context); | ||||
| 
 | ||||
|     home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header); | ||||
|     sleep_button = | ||||
|         std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header); | ||||
|     capture_button = | ||||
|         std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header); | ||||
|     digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header); | ||||
| 
 | ||||
|     six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); | ||||
|     console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory); | ||||
|     console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console); | ||||
|     seven_six_axis = std::make_shared<SevenSixAxis>(system); | ||||
| 
 | ||||
|     home_button->SetCommonHeaderOffset(0x4C00); | ||||
|     sleep_button->SetCommonHeaderOffset(0x4E00); | ||||
|     capture_button->SetCommonHeaderOffset(0x5000); | ||||
|     unique_pad->SetCommonHeaderOffset(0x5A00); | ||||
|     debug_mouse->SetCommonHeaderOffset(0x3DC00); | ||||
| 
 | ||||
|     // Homebrew doesn't try to activate some controllers, so we activate them by default
 | ||||
|     npad->Activate(); | ||||
|     six_axis->Activate(); | ||||
|     touch_screen->Activate(); | ||||
| 
 | ||||
|     system.HIDCore().ReloadInputDevices(); | ||||
|     is_initialized = true; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { | ||||
| @ -101,6 +104,10 @@ std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { | ||||
|     return debug_pad; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const { | ||||
|     return digitizer; | ||||
| } | ||||
| 
 | ||||
| std::shared_ptr<Gesture> ResourceManager::GetGesture() const { | ||||
|     return gesture; | ||||
| } | ||||
| @ -163,7 +170,11 @@ Result ResourceManager::CreateAppletResource(u64 aruid) { | ||||
| 
 | ||||
| Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { | ||||
|     std::scoped_lock lock{shared_mutex}; | ||||
|     return applet_resource->CreateAppletResource(aruid); | ||||
|     const auto result = applet_resource->CreateAppletResource(aruid); | ||||
|     if (result.IsSuccess()) { | ||||
|         InitializeController(aruid); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| Result ResourceManager::RegisterCoreAppletResource() { | ||||
| @ -227,7 +238,6 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data, | ||||
|     home_button->OnUpdate(core_timing); | ||||
|     sleep_button->OnUpdate(core_timing); | ||||
|     capture_button->OnUpdate(core_timing); | ||||
|     xpad->OnUpdate(core_timing); | ||||
| } | ||||
| 
 | ||||
| void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | ||||
|  | ||||
| @ -31,10 +31,10 @@ class Palma; | ||||
| class SevenSixAxis; | ||||
| class SixAxis; | ||||
| class TouchScreen; | ||||
| class XPad; | ||||
| 
 | ||||
| using CaptureButton = Controller_Stubbed; | ||||
| using DebugMouse = Controller_Stubbed; | ||||
| using DebugMouse = Mouse; | ||||
| using Digitizer = Controller_Stubbed; | ||||
| using HomeButton = Controller_Stubbed; | ||||
| using SleepButton = Controller_Stubbed; | ||||
| using UniquePad = Controller_Stubbed; | ||||
| @ -46,12 +46,14 @@ public: | ||||
|     ~ResourceManager(); | ||||
| 
 | ||||
|     void Initialize(); | ||||
|     void InitializeController(u64 aruid); | ||||
| 
 | ||||
|     std::shared_ptr<AppletResource> GetAppletResource() const; | ||||
|     std::shared_ptr<CaptureButton> GetCaptureButton() const; | ||||
|     std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; | ||||
|     std::shared_ptr<DebugMouse> GetDebugMouse() const; | ||||
|     std::shared_ptr<DebugPad> GetDebugPad() const; | ||||
|     std::shared_ptr<Digitizer> GetDigitizer() const; | ||||
|     std::shared_ptr<Gesture> GetGesture() const; | ||||
|     std::shared_ptr<HomeButton> GetHomeButton() const; | ||||
|     std::shared_ptr<Keyboard> GetKeyboard() const; | ||||
| @ -96,6 +98,7 @@ private: | ||||
|     std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; | ||||
|     std::shared_ptr<DebugMouse> debug_mouse = nullptr; | ||||
|     std::shared_ptr<DebugPad> debug_pad = nullptr; | ||||
|     std::shared_ptr<Digitizer> digitizer = nullptr; | ||||
|     std::shared_ptr<Gesture> gesture = nullptr; | ||||
|     std::shared_ptr<HomeButton> home_button = nullptr; | ||||
|     std::shared_ptr<Keyboard> keyboard = nullptr; | ||||
| @ -107,7 +110,6 @@ private: | ||||
|     std::shared_ptr<SleepButton> sleep_button = nullptr; | ||||
|     std::shared_ptr<TouchScreen> touch_screen = nullptr; | ||||
|     std::shared_ptr<UniquePad> unique_pad = nullptr; | ||||
|     std::shared_ptr<XPad> xpad = nullptr; | ||||
| 
 | ||||
|     // TODO: Create these resources
 | ||||
|     // std::shared_ptr<AudioControl> audio_control = nullptr;
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user