summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Narr the Reg2023-12-13 21:39:38 -0600
committerGravatar Narr the Reg2023-12-13 23:24:28 -0600
commit64f68e96354df3afb9bb563c888793f98ecb5026 (patch)
tree82a1f3f51902e0a926bae4ae8a84ba1dcf2a145b /src
parentMerge pull request #12342 from FearlessTobi/fix-msvc (diff)
downloadyuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.gz
yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.tar.xz
yuzu-64f68e96354df3afb9bb563c888793f98ecb5026.zip
service: hid: Allow to create multiple instances of shared memory
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/core/hle/kernel/kernel.cpp15
-rw-r--r--src/core/hle/kernel/kernel.h6
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.cpp39
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.h7
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.h19
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h3
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp21
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h47
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp33
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h85
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp21
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h31
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp17
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h14
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp28
-rw-r--r--src/core/hle/service/hid/controllers/npad.h309
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/palma.h3
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_format.h239
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_holder.cpp49
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_holder.h44
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.cpp25
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp17
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.h17
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp22
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h30
-rw-r--r--src/core/hle/service/hid/controllers/types/debug_pad_types.h31
-rw-r--r--src/core/hle/service/hid/controllers/types/gesture_types.h77
-rw-r--r--src/core/hle/service/hid/controllers/types/keyboard_types.h20
-rw-r--r--src/core/hle/service/hid/controllers/types/mouse_types.h12
-rw-r--r--src/core/hle/service/hid/controllers/types/npad_types.h255
-rw-r--r--src/core/hle/service/hid/controllers/types/touch_types.h90
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp39
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h112
-rw-r--r--src/core/hle/service/hid/hid_server.cpp23
-rw-r--r--src/core/hle/service/hid/hid_system_server.cpp3
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp64
-rw-r--r--src/core/hle/service/hid/resource_manager.h8
40 files changed, 1065 insertions, 842 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 7b9ed856f..dced37079 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -549,6 +549,11 @@ add_library(core STATIC
549 hle/service/hid/xcd.cpp 549 hle/service/hid/xcd.cpp
550 hle/service/hid/xcd.h 550 hle/service/hid/xcd.h
551 hle/service/hid/errors.h 551 hle/service/hid/errors.h
552 hle/service/hid/controllers/types/debug_pad_types.h
553 hle/service/hid/controllers/types/keyboard_types.h
554 hle/service/hid/controllers/types/mouse_types.h
555 hle/service/hid/controllers/types/npad_types.h
556 hle/service/hid/controllers/types/touch_types.h
552 hle/service/hid/controllers/applet_resource.cpp 557 hle/service/hid/controllers/applet_resource.cpp
553 hle/service/hid/controllers/applet_resource.h 558 hle/service/hid/controllers/applet_resource.h
554 hle/service/hid/controllers/console_six_axis.cpp 559 hle/service/hid/controllers/console_six_axis.cpp
@@ -569,14 +574,15 @@ add_library(core STATIC
569 hle/service/hid/controllers/palma.h 574 hle/service/hid/controllers/palma.h
570 hle/service/hid/controllers/seven_six_axis.cpp 575 hle/service/hid/controllers/seven_six_axis.cpp
571 hle/service/hid/controllers/seven_six_axis.h 576 hle/service/hid/controllers/seven_six_axis.h
577 hle/service/hid/controllers/shared_memory_format.h
578 hle/service/hid/controllers/shared_memory_holder.cpp
579 hle/service/hid/controllers/shared_memory_holder.h
572 hle/service/hid/controllers/six_axis.cpp 580 hle/service/hid/controllers/six_axis.cpp
573 hle/service/hid/controllers/six_axis.h 581 hle/service/hid/controllers/six_axis.h
574 hle/service/hid/controllers/stubbed.cpp 582 hle/service/hid/controllers/stubbed.cpp
575 hle/service/hid/controllers/stubbed.h 583 hle/service/hid/controllers/stubbed.h
576 hle/service/hid/controllers/touchscreen.cpp 584 hle/service/hid/controllers/touchscreen.cpp
577 hle/service/hid/controllers/touchscreen.h 585 hle/service/hid/controllers/touchscreen.h
578 hle/service/hid/controllers/xpad.cpp
579 hle/service/hid/controllers/xpad.h
580 hle/service/hid/hidbus/hidbus_base.cpp 586 hle/service/hid/hidbus/hidbus_base.cpp
581 hle/service/hid/hidbus/hidbus_base.h 587 hle/service/hid/hidbus/hidbus_base.h
582 hle/service/hid/hidbus/ringcon.cpp 588 hle/service/hid/hidbus/ringcon.cpp
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8cb05ca0b..e479dacde 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -135,7 +135,6 @@ struct KernelCore::Impl {
135 obj = nullptr; 135 obj = nullptr;
136 } 136 }
137 }; 137 };
138 CleanupObject(hid_shared_mem);
139 CleanupObject(font_shared_mem); 138 CleanupObject(font_shared_mem);
140 CleanupObject(irs_shared_mem); 139 CleanupObject(irs_shared_mem);
141 CleanupObject(time_shared_mem); 140 CleanupObject(time_shared_mem);
@@ -744,22 +743,16 @@ struct KernelCore::Impl {
744 void InitializeHackSharedMemory(KernelCore& kernel) { 743 void InitializeHackSharedMemory(KernelCore& kernel) {
745 // Setup memory regions for emulated processes 744 // Setup memory regions for emulated processes
746 // TODO(bunnei): These should not be hardcoded regions initialized within the kernel 745 // TODO(bunnei): These should not be hardcoded regions initialized within the kernel
747 constexpr std::size_t hid_size{0x40000};
748 constexpr std::size_t font_size{0x1100000}; 746 constexpr std::size_t font_size{0x1100000};
749 constexpr std::size_t irs_size{0x8000}; 747 constexpr std::size_t irs_size{0x8000};
750 constexpr std::size_t time_size{0x1000}; 748 constexpr std::size_t time_size{0x1000};
751 constexpr std::size_t hidbus_size{0x1000}; 749 constexpr std::size_t hidbus_size{0x1000};
752 750
753 hid_shared_mem = KSharedMemory::Create(system.Kernel());
754 font_shared_mem = KSharedMemory::Create(system.Kernel()); 751 font_shared_mem = KSharedMemory::Create(system.Kernel());
755 irs_shared_mem = KSharedMemory::Create(system.Kernel()); 752 irs_shared_mem = KSharedMemory::Create(system.Kernel());
756 time_shared_mem = KSharedMemory::Create(system.Kernel()); 753 time_shared_mem = KSharedMemory::Create(system.Kernel());
757 hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); 754 hidbus_shared_mem = KSharedMemory::Create(system.Kernel());
758 755
759 hid_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
760 Svc::MemoryPermission::Read, hid_size);
761 KSharedMemory::Register(kernel, hid_shared_mem);
762
763 font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, 756 font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None,
764 Svc::MemoryPermission::Read, font_size); 757 Svc::MemoryPermission::Read, font_size);
765 KSharedMemory::Register(kernel, font_shared_mem); 758 KSharedMemory::Register(kernel, font_shared_mem);
@@ -1190,14 +1183,6 @@ const KSystemResource& KernelCore::GetSystemSystemResource() const {
1190 return *impl->sys_system_resource; 1183 return *impl->sys_system_resource;
1191} 1184}
1192 1185
1193Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
1194 return *impl->hid_shared_mem;
1195}
1196
1197const Kernel::KSharedMemory& KernelCore::GetHidSharedMem() const {
1198 return *impl->hid_shared_mem;
1199}
1200
1201Kernel::KSharedMemory& KernelCore::GetFontSharedMem() { 1186Kernel::KSharedMemory& KernelCore::GetFontSharedMem() {
1202 return *impl->font_shared_mem; 1187 return *impl->font_shared_mem;
1203} 1188}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 69b5bbd6c..78c88902c 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -239,12 +239,6 @@ public:
239 /// Gets the system resource manager. 239 /// Gets the system resource manager.
240 const KSystemResource& GetSystemSystemResource() const; 240 const KSystemResource& GetSystemSystemResource() const;
241 241
242 /// Gets the shared memory object for HID services.
243 Kernel::KSharedMemory& GetHidSharedMem();
244
245 /// Gets the shared memory object for HID services.
246 const Kernel::KSharedMemory& GetHidSharedMem() const;
247
248 /// Gets the shared memory object for font services. 242 /// Gets the shared memory object for font services.
249 Kernel::KSharedMemory& GetFontSharedMem(); 243 Kernel::KSharedMemory& GetFontSharedMem();
250 244
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp
index 435b86233..c8e74c764 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.cpp
+++ b/src/core/hle/service/hid/controllers/applet_resource.cpp
@@ -4,6 +4,7 @@
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/kernel/k_shared_memory.h" 5#include "core/hle/kernel/k_shared_memory.h"
6#include "core/hle/service/hid/controllers/applet_resource.h" 6#include "core/hle/service/hid/controllers/applet_resource.h"
7#include "core/hle/service/hid/controllers/shared_memory_format.h"
7#include "core/hle/service/hid/errors.h" 8#include "core/hle/service/hid/errors.h"
8 9
9namespace Service::HID { 10namespace Service::HID {
@@ -23,11 +24,24 @@ Result AppletResource::CreateAppletResource(u64 aruid) {
23 return ResultAruidAlreadyRegistered; 24 return ResultAruidAlreadyRegistered;
24 } 25 }
25 26
26 // TODO: Here shared memory is created for the process we don't quite emulate this part so 27 auto& shared_memory = shared_memory_holder[index];
27 // obtain this pointer from system 28 if (!shared_memory.IsMapped()) {
28 auto& shared_memory = system.Kernel().GetHidSharedMem(); 29 const Result result = shared_memory.Initialize(system);
30 if (result.IsError()) {
31 return result;
32 }
33 if (shared_memory.GetAddress() == nullptr) {
34 shared_memory.Finalize();
35 return ResultSharedMemoryNotInitialized;
36 }
37 }
38
39 auto* shared_memory_format = shared_memory.GetAddress();
40 if (shared_memory_format != nullptr) {
41 shared_memory_format->Initialize();
42 }
29 43
30 data[index].shared_memory_handle = &shared_memory; 44 data[index].shared_memory_format = shared_memory_format;
31 data[index].flag.is_assigned.Assign(true); 45 data[index].flag.is_assigned.Assign(true);
32 // TODO: InitializeSixAxisControllerConfig(false); 46 // TODO: InitializeSixAxisControllerConfig(false);
33 active_aruid = aruid; 47 active_aruid = aruid;
@@ -94,7 +108,7 @@ void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
94 108
95 if (index < AruidIndexMax) { 109 if (index < AruidIndexMax) {
96 if (data[index].flag.is_assigned) { 110 if (data[index].flag.is_assigned) {
97 data[index].shared_memory_handle = nullptr; 111 data[index].shared_memory_format = nullptr;
98 data[index].flag.is_assigned.Assign(false); 112 data[index].flag.is_assigned.Assign(false);
99 } 113 }
100 } 114 }
@@ -120,7 +134,7 @@ void AppletResource::FreeAppletResourceId(u64 aruid) {
120 134
121 auto& aruid_data = data[index]; 135 auto& aruid_data = data[index];
122 if (aruid_data.flag.is_assigned) { 136 if (aruid_data.flag.is_assigned) {
123 aruid_data.shared_memory_handle = nullptr; 137 aruid_data.shared_memory_format = nullptr;
124 aruid_data.flag.is_assigned.Assign(false); 138 aruid_data.flag.is_assigned.Assign(false);
125 } 139 }
126} 140}
@@ -135,7 +149,18 @@ Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle,
135 return ResultAruidNotRegistered; 149 return ResultAruidNotRegistered;
136 } 150 }
137 151
138 *out_handle = data[index].shared_memory_handle; 152 *out_handle = shared_memory_holder[index].GetHandle();
153 return ResultSuccess;
154}
155
156Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format,
157 u64 aruid) {
158 u64 index = GetIndexFromAruid(aruid);
159 if (index >= AruidIndexMax) {
160 return ResultAruidNotRegistered;
161 }
162
163 *out_shared_memory_format = data[index].shared_memory_format;
139 return ResultSuccess; 164 return ResultSuccess;
140} 165}
141 166
diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h
index 62137db13..e7991f93a 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.h
+++ b/src/core/hle/service/hid/controllers/applet_resource.h
@@ -8,6 +8,7 @@
8#include "common/bit_field.h" 8#include "common/bit_field.h"
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
11#include "core/hle/service/hid/controllers/shared_memory_holder.h"
11 12
12namespace Core { 13namespace Core {
13class System; 14class System;
@@ -18,6 +19,8 @@ class KSharedMemory;
18} 19}
19 20
20namespace Service::HID { 21namespace Service::HID {
22struct SharedMemoryFormat;
23
21class AppletResource { 24class AppletResource {
22public: 25public:
23 explicit AppletResource(Core::System& system_); 26 explicit AppletResource(Core::System& system_);
@@ -32,6 +35,7 @@ public:
32 35
33 u64 GetActiveAruid(); 36 u64 GetActiveAruid();
34 Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); 37 Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
38 Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
35 39
36 u64 GetIndexFromAruid(u64 aruid); 40 u64 GetIndexFromAruid(u64 aruid);
37 41
@@ -80,12 +84,13 @@ private:
80 struct AruidData { 84 struct AruidData {
81 DataStatusFlag flag{}; 85 DataStatusFlag flag{};
82 u64 aruid{}; 86 u64 aruid{};
83 Kernel::KSharedMemory* shared_memory_handle{nullptr}; 87 SharedMemoryFormat* shared_memory_format{nullptr};
84 }; 88 };
85 89
86 u64 active_aruid{}; 90 u64 active_aruid{};
87 AruidRegisterList registration_list{}; 91 AruidRegisterList registration_list{};
88 std::array<AruidData, AruidIndexMax> data{}; 92 std::array<AruidData, AruidIndexMax> data{};
93 std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
89 s32 ref_counter{}; 94 s32 ref_counter{};
90 95
91 Core::System& system; 96 Core::System& system;
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp
index b2bf1d78d..084e99556 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.cpp
+++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp
@@ -6,18 +6,15 @@
6#include "core/hid/emulated_console.h" 6#include "core/hid/emulated_console.h"
7#include "core/hid/hid_core.h" 7#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/console_six_axis.h" 8#include "core/hle/service/hid/controllers/console_six_axis.h"
9#include "core/hle/service/hid/controllers/shared_memory_format.h"
9#include "core/memory.h" 10#include "core/memory.h"
10 11
11namespace Service::HID { 12namespace Service::HID {
12constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
13 13
14ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 14ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
15 : ControllerBase{hid_core_} { 15 ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory)
16 : ControllerBase{hid_core_}, shared_memory{console_shared_memory} {
16 console = hid_core.GetEmulatedConsole(); 17 console = hid_core.GetEmulatedConsole();
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
18 "ConsoleSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at(
20 reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
21} 18}
22 19
23ConsoleSixAxis::~ConsoleSixAxis() = default; 20ConsoleSixAxis::~ConsoleSixAxis() = default;
@@ -33,10 +30,10 @@ void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
33 30
34 const auto motion_status = console->GetMotion(); 31 const auto motion_status = console->GetMotion();
35 32
36 shared_memory->sampling_number++; 33 shared_memory.sampling_number++;
37 shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; 34 shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
38 shared_memory->verticalization_error = motion_status.verticalization_error; 35 shared_memory.verticalization_error = motion_status.verticalization_error;
39 shared_memory->gyro_bias = motion_status.gyro_bias; 36 shared_memory.gyro_bias = motion_status.gyro_bias;
40} 37}
41 38
42} // namespace Service::HID 39} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h
index 5b7c6a29a..3d1c9ce23 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.h
+++ b/src/core/hle/service/hid/controllers/console_six_axis.h
@@ -3,7 +3,6 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/vector_math.h"
7#include "core/hle/service/hid/controllers/controller_base.h" 6#include "core/hle/service/hid/controllers/controller_base.h"
8 7
9namespace Core::HID { 8namespace Core::HID {
@@ -11,9 +10,12 @@ class EmulatedConsole;
11} // namespace Core::HID 10} // namespace Core::HID
12 11
13namespace Service::HID { 12namespace Service::HID {
13struct ConsoleSixAxisSensorSharedMemoryFormat;
14
14class ConsoleSixAxis final : public ControllerBase { 15class ConsoleSixAxis final : public ControllerBase {
15public: 16public:
16 explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 17 explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
18 ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory);
17 ~ConsoleSixAxis() override; 19 ~ConsoleSixAxis() override;
18 20
19 // Called when the controller is initialized 21 // Called when the controller is initialized
@@ -26,18 +28,7 @@ public:
26 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 28 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
27 29
28private: 30private:
29 // This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat 31 ConsoleSixAxisSensorSharedMemoryFormat& shared_memory;
30 struct ConsoleSharedMemory {
31 u64 sampling_number{};
32 bool is_seven_six_axis_sensor_at_rest{};
33 INSERT_PADDING_BYTES(3); // padding
34 f32 verticalization_error{};
35 Common::Vec3f gyro_bias{};
36 INSERT_PADDING_BYTES(4); // padding
37 };
38 static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size");
39
40 ConsoleSharedMemory* shared_memory = nullptr;
41 Core::HID::EmulatedConsole* console = nullptr; 32 Core::HID::EmulatedConsole* console = nullptr;
42}; 33};
43} // namespace Service::HID 34} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 9a44ee41e..4326c7821 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -39,9 +39,6 @@ public:
39 39
40 bool IsControllerActivated() const; 40 bool IsControllerActivated() const;
41 41
42 static const std::size_t hid_entry_count = 17;
43 static const std::size_t shared_memory_size = 0x40000;
44
45protected: 42protected:
46 bool is_activated{false}; 43 bool is_activated{false};
47 44
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index 9de19ebfc..38fafe88f 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -9,16 +9,13 @@
9#include "core/hid/hid_core.h" 9#include "core/hid/hid_core.h"
10#include "core/hid/hid_types.h" 10#include "core/hid/hid_types.h"
11#include "core/hle/service/hid/controllers/debug_pad.h" 11#include "core/hle/service/hid/controllers/debug_pad.h"
12#include "core/hle/service/hid/controllers/shared_memory_format.h"
12 13
13namespace Service::HID { 14namespace Service::HID {
14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; 15
15 16DebugPad::DebugPad(Core::HID::HIDCore& hid_core_,
16DebugPad::DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 17 DebugPadSharedMemoryFormat& debug_pad_shared_memory)
17 : ControllerBase{hid_core_} { 18 : ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} {
18 static_assert(SHARED_MEMORY_OFFSET + sizeof(DebugPadSharedMemory) < shared_memory_size,
19 "DebugPadSharedMemory is bigger than the shared memory");
20 shared_memory = std::construct_at(
21 reinterpret_cast<DebugPadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
22 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); 19 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
23} 20}
24 21
@@ -30,12 +27,12 @@ void DebugPad::OnRelease() {}
30 27
31void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 28void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
32 if (!IsControllerActivated()) { 29 if (!IsControllerActivated()) {
33 shared_memory->debug_pad_lifo.buffer_count = 0; 30 shared_memory.debug_pad_lifo.buffer_count = 0;
34 shared_memory->debug_pad_lifo.buffer_tail = 0; 31 shared_memory.debug_pad_lifo.buffer_tail = 0;
35 return; 32 return;
36 } 33 }
37 34
38 const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state; 35 const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state;
39 next_state.sampling_number = last_entry.sampling_number + 1; 36 next_state.sampling_number = last_entry.sampling_number + 1;
40 37
41 if (Settings::values.debug_pad_enabled) { 38 if (Settings::values.debug_pad_enabled) {
@@ -49,7 +46,7 @@ void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
49 next_state.r_stick = stick_state.right; 46 next_state.r_stick = stick_state.right;
50 } 47 }
51 48
52 shared_memory->debug_pad_lifo.WriteNextEntry(next_state); 49 shared_memory.debug_pad_lifo.WriteNextEntry(next_state);
53} 50}
54 51
55} // namespace Service::HID 52} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 5566dba77..704d1fc98 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -3,21 +3,25 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/bit_field.h"
7#include "common/common_types.h" 6#include "common/common_types.h"
8#include "core/hle/service/hid/controllers/controller_base.h" 7#include "core/hle/service/hid/controllers/controller_base.h"
9#include "core/hle/service/hid/ring_lifo.h" 8#include "core/hle/service/hid/controllers/types/debug_pad_types.h"
10 9
11namespace Core::HID { 10namespace Core::HID {
12class EmulatedController; 11class HIDCore;
13struct DebugPadButton; 12}
14struct AnalogStickState; 13
15} // namespace Core::HID 14namespace Core::Timing {
15class CoreTiming;
16}
16 17
17namespace Service::HID { 18namespace Service::HID {
19struct DebugPadSharedMemoryFormat;
20
18class DebugPad final : public ControllerBase { 21class DebugPad final : public ControllerBase {
19public: 22public:
20 explicit DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 23 explicit DebugPad(Core::HID::HIDCore& hid_core_,
24 DebugPadSharedMemoryFormat& debug_pad_shared_memory);
21 ~DebugPad() override; 25 ~DebugPad() override;
22 26
23 // Called when the controller is initialized 27 // Called when the controller is initialized
@@ -30,35 +34,8 @@ public:
30 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 34 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
31 35
32private: 36private:
33 // This is nn::hid::DebugPadAttribute
34 struct DebugPadAttribute {
35 union {
36 u32 raw{};
37 BitField<0, 1, u32> connected;
38 };
39 };
40 static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size");
41
42 // This is nn::hid::DebugPadState
43 struct DebugPadState {
44 s64 sampling_number{};
45 DebugPadAttribute attribute{};
46 Core::HID::DebugPadButton pad_state{};
47 Core::HID::AnalogStickState r_stick{};
48 Core::HID::AnalogStickState l_stick{};
49 };
50 static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
51
52 struct DebugPadSharedMemory {
53 // This is nn::hid::detail::DebugPadLifo
54 Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{};
55 static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
56 INSERT_PADDING_WORDS(0x4E);
57 };
58 static_assert(sizeof(DebugPadSharedMemory) == 0x400, "DebugPadSharedMemory is an invalid size");
59
60 DebugPadState next_state{}; 37 DebugPadState next_state{};
61 DebugPadSharedMemory* shared_memory = nullptr; 38 DebugPadSharedMemoryFormat& shared_memory;
62 Core::HID::EmulatedController* controller = nullptr; 39 Core::HID::EmulatedController* controller = nullptr;
63}; 40};
64} // namespace Service::HID 41} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index 59b2ec73c..0b6e9c4e5 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -8,10 +8,9 @@
8#include "core/frontend/emu_window.h" 8#include "core/frontend/emu_window.h"
9#include "core/hid/hid_core.h" 9#include "core/hid/hid_core.h"
10#include "core/hle/service/hid/controllers/gesture.h" 10#include "core/hle/service/hid/controllers/gesture.h"
11#include "core/hle/service/hid/controllers/shared_memory_format.h"
11 12
12namespace Service::HID { 13namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
14
15// HW is around 700, value is set to 400 to make it easier to trigger with mouse 14// HW is around 700, value is set to 400 to make it easier to trigger with mouse
16constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s 15constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s
17constexpr f32 angle_threshold = 0.015f; // Threshold in radians 16constexpr f32 angle_threshold = 0.015f; // Threshold in radians
@@ -23,19 +22,15 @@ constexpr f32 Square(s32 num) {
23 return static_cast<f32>(num * num); 22 return static_cast<f32>(num * num);
24} 23}
25 24
26Gesture::Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 25Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory)
27 : ControllerBase(hid_core_) { 26 : ControllerBase(hid_core_), shared_memory{gesture_shared_memory} {
28 static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size,
29 "GestureSharedMemory is bigger than the shared memory");
30 shared_memory = std::construct_at(
31 reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
32 console = hid_core.GetEmulatedConsole(); 27 console = hid_core.GetEmulatedConsole();
33} 28}
34Gesture::~Gesture() = default; 29Gesture::~Gesture() = default;
35 30
36void Gesture::OnInit() { 31void Gesture::OnInit() {
37 shared_memory->gesture_lifo.buffer_count = 0; 32 shared_memory.gesture_lifo.buffer_count = 0;
38 shared_memory->gesture_lifo.buffer_tail = 0; 33 shared_memory.gesture_lifo.buffer_tail = 0;
39 force_update = true; 34 force_update = true;
40} 35}
41 36
@@ -43,8 +38,8 @@ void Gesture::OnRelease() {}
43 38
44void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 39void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
45 if (!IsControllerActivated()) { 40 if (!IsControllerActivated()) {
46 shared_memory->gesture_lifo.buffer_count = 0; 41 shared_memory.gesture_lifo.buffer_count = 0;
47 shared_memory->gesture_lifo.buffer_tail = 0; 42 shared_memory.gesture_lifo.buffer_tail = 0;
48 return; 43 return;
49 } 44 }
50 45
@@ -52,7 +47,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
52 47
53 GestureProperties gesture = GetGestureProperties(); 48 GestureProperties gesture = GetGestureProperties();
54 f32 time_difference = 49 f32 time_difference =
55 static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / 50 static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) /
56 (1000 * 1000 * 1000); 51 (1000 * 1000 * 1000);
57 52
58 // Only update if necessary 53 // Only update if necessary
@@ -60,7 +55,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
60 return; 55 return;
61 } 56 }
62 57
63 last_update_timestamp = shared_memory->gesture_lifo.timestamp; 58 last_update_timestamp = shared_memory.gesture_lifo.timestamp;
64 UpdateGestureSharedMemory(gesture, time_difference); 59 UpdateGestureSharedMemory(gesture, time_difference);
65} 60}
66 61
@@ -103,7 +98,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
103 GestureType type = GestureType::Idle; 98 GestureType type = GestureType::Idle;
104 GestureAttribute attributes{}; 99 GestureAttribute attributes{};
105 100
106 const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; 101 const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state;
107 102
108 // Reset next state to default 103 // Reset next state to default
109 next_state.sampling_number = last_entry.sampling_number + 1; 104 next_state.sampling_number = last_entry.sampling_number + 1;
@@ -133,7 +128,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
133 next_state.points = gesture.points; 128 next_state.points = gesture.points;
134 last_gesture = gesture; 129 last_gesture = gesture;
135 130
136 shared_memory->gesture_lifo.WriteNextEntry(next_state); 131 shared_memory.gesture_lifo.WriteNextEntry(next_state);
137} 132}
138 133
139void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, 134void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
@@ -305,11 +300,11 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_
305 next_state.direction = GestureDirection::Up; 300 next_state.direction = GestureDirection::Up;
306} 301}
307 302
308const Gesture::GestureState& Gesture::GetLastGestureEntry() const { 303const GestureState& Gesture::GetLastGestureEntry() const {
309 return shared_memory->gesture_lifo.ReadCurrentEntry().state; 304 return shared_memory.gesture_lifo.ReadCurrentEntry().state;
310} 305}
311 306
312Gesture::GestureProperties Gesture::GetGestureProperties() { 307GestureProperties Gesture::GetGestureProperties() {
313 GestureProperties gesture; 308 GestureProperties gesture;
314 std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; 309 std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers;
315 const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), 310 const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(),
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 4c6f8ee07..cee6b6c07 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -4,17 +4,19 @@
4#pragma once 4#pragma once
5 5
6#include <array> 6#include <array>
7#include "common/bit_field.h" 7
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/point.h"
10#include "core/hid/emulated_console.h" 9#include "core/hid/emulated_console.h"
11#include "core/hle/service/hid/controllers/controller_base.h" 10#include "core/hle/service/hid/controllers/controller_base.h"
12#include "core/hle/service/hid/ring_lifo.h" 11#include "core/hle/service/hid/controllers/types/touch_types.h"
13 12
14namespace Service::HID { 13namespace Service::HID {
14struct GestureSharedMemoryFormat;
15
15class Gesture final : public ControllerBase { 16class Gesture final : public ControllerBase {
16public: 17public:
17 explicit Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 18 explicit Gesture(Core::HID::HIDCore& hid_core_,
19 GestureSharedMemoryFormat& gesture_shared_memory);
18 ~Gesture() override; 20 ~Gesture() override;
19 21
20 // Called when the controller is initialized 22 // Called when the controller is initialized
@@ -27,79 +29,6 @@ public:
27 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 29 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
28 30
29private: 31private:
30 static constexpr size_t MAX_FINGERS = 16;
31 static constexpr size_t MAX_POINTS = 4;
32
33 // This is nn::hid::GestureType
34 enum class GestureType : u32 {
35 Idle, // Nothing touching the screen
36 Complete, // Set at the end of a touch event
37 Cancel, // Set when the number of fingers change
38 Touch, // A finger just touched the screen
39 Press, // Set if last type is touch and the finger hasn't moved
40 Tap, // Fast press then release
41 Pan, // All points moving together across the screen
42 Swipe, // Fast press movement and release of a single point
43 Pinch, // All points moving away/closer to the midpoint
44 Rotate, // All points rotating from the midpoint
45 };
46
47 // This is nn::hid::GestureDirection
48 enum class GestureDirection : u32 {
49 None,
50 Left,
51 Up,
52 Right,
53 Down,
54 };
55
56 // This is nn::hid::GestureAttribute
57 struct GestureAttribute {
58 union {
59 u32 raw{};
60
61 BitField<4, 1, u32> is_new_touch;
62 BitField<8, 1, u32> is_double_tap;
63 };
64 };
65 static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
66
67 // This is nn::hid::GestureState
68 struct GestureState {
69 s64 sampling_number{};
70 s64 detection_count{};
71 GestureType type{GestureType::Idle};
72 GestureDirection direction{GestureDirection::None};
73 Common::Point<s32> pos{};
74 Common::Point<s32> delta{};
75 f32 vel_x{};
76 f32 vel_y{};
77 GestureAttribute attributes{};
78 f32 scale{};
79 f32 rotation_angle{};
80 s32 point_count{};
81 std::array<Common::Point<s32>, 4> points{};
82 };
83 static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
84
85 struct GestureProperties {
86 std::array<Common::Point<s32>, MAX_POINTS> points{};
87 std::size_t active_points{};
88 Common::Point<s32> mid_point{};
89 s64 detection_count{};
90 u64 delta_time{};
91 f32 average_distance{};
92 f32 angle{};
93 };
94
95 struct GestureSharedMemory {
96 // This is nn::hid::detail::GestureLifo
97 Lifo<GestureState, hid_entry_count> gesture_lifo{};
98 static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
99 INSERT_PADDING_WORDS(0x3E);
100 };
101 static_assert(sizeof(GestureSharedMemory) == 0x800, "GestureSharedMemory is an invalid size");
102
103 // Reads input from all available input engines 32 // Reads input from all available input engines
104 void ReadTouchInput(); 33 void ReadTouchInput();
105 34
@@ -142,7 +71,7 @@ private:
142 GestureProperties GetGestureProperties(); 71 GestureProperties GetGestureProperties();
143 72
144 GestureState next_state{}; 73 GestureState next_state{};
145 GestureSharedMemory* shared_memory = nullptr; 74 GestureSharedMemoryFormat& shared_memory;
146 Core::HID::EmulatedConsole* console = nullptr; 75 Core::HID::EmulatedConsole* console = nullptr;
147 76
148 std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; 77 std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index ddb1b0ba4..feab499bd 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -8,16 +8,13 @@
8#include "core/hid/emulated_devices.h" 8#include "core/hid/emulated_devices.h"
9#include "core/hid/hid_core.h" 9#include "core/hid/hid_core.h"
10#include "core/hle/service/hid/controllers/keyboard.h" 10#include "core/hle/service/hid/controllers/keyboard.h"
11#include "core/hle/service/hid/controllers/shared_memory_format.h"
11 12
12namespace Service::HID { 13namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; 14
14 15Keyboard::Keyboard(Core::HID::HIDCore& hid_core_,
15Keyboard::Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 16 KeyboardSharedMemoryFormat& keyboard_shared_memory)
16 : ControllerBase{hid_core_} { 17 : ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} {
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size,
18 "KeyboardSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at(
20 reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
21 emulated_devices = hid_core.GetEmulatedDevices(); 18 emulated_devices = hid_core.GetEmulatedDevices();
22} 19}
23 20
@@ -29,12 +26,12 @@ void Keyboard::OnRelease() {}
29 26
30void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 27void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
31 if (!IsControllerActivated()) { 28 if (!IsControllerActivated()) {
32 shared_memory->keyboard_lifo.buffer_count = 0; 29 shared_memory.keyboard_lifo.buffer_count = 0;
33 shared_memory->keyboard_lifo.buffer_tail = 0; 30 shared_memory.keyboard_lifo.buffer_tail = 0;
34 return; 31 return;
35 } 32 }
36 33
37 const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state; 34 const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state;
38 next_state.sampling_number = last_entry.sampling_number + 1; 35 next_state.sampling_number = last_entry.sampling_number + 1;
39 36
40 if (Settings::values.keyboard_enabled) { 37 if (Settings::values.keyboard_enabled) {
@@ -46,7 +43,7 @@ void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
46 next_state.attribute.is_connected.Assign(1); 43 next_state.attribute.is_connected.Assign(1);
47 } 44 }
48 45
49 shared_memory->keyboard_lifo.WriteNextEntry(next_state); 46 shared_memory.keyboard_lifo.WriteNextEntry(next_state);
50} 47}
51 48
52} // namespace Service::HID 49} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 172ec1309..8abc8c5e9 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -5,18 +5,16 @@
5 5
6#include "common/common_types.h" 6#include "common/common_types.h"
7#include "core/hle/service/hid/controllers/controller_base.h" 7#include "core/hle/service/hid/controllers/controller_base.h"
8#include "core/hle/service/hid/controllers/types/keyboard_types.h"
8#include "core/hle/service/hid/ring_lifo.h" 9#include "core/hle/service/hid/ring_lifo.h"
9 10
10namespace Core::HID {
11class EmulatedDevices;
12struct KeyboardModifier;
13struct KeyboardKey;
14} // namespace Core::HID
15
16namespace Service::HID { 11namespace Service::HID {
12struct KeyboardSharedMemoryFormat;
13
17class Keyboard final : public ControllerBase { 14class Keyboard final : public ControllerBase {
18public: 15public:
19 explicit Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 16 explicit Keyboard(Core::HID::HIDCore& hid_core_,
17 KeyboardSharedMemoryFormat& keyboard_shared_memory);
20 ~Keyboard() override; 18 ~Keyboard() override;
21 19
22 // Called when the controller is initialized 20 // Called when the controller is initialized
@@ -29,25 +27,8 @@ public:
29 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 27 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
30 28
31private: 29private:
32 // This is nn::hid::detail::KeyboardState
33 struct KeyboardState {
34 s64 sampling_number{};
35 Core::HID::KeyboardModifier modifier{};
36 Core::HID::KeyboardAttribute attribute{};
37 Core::HID::KeyboardKey key{};
38 };
39 static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
40
41 struct KeyboardSharedMemory {
42 // This is nn::hid::detail::KeyboardLifo
43 Lifo<KeyboardState, hid_entry_count> keyboard_lifo{};
44 static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
45 INSERT_PADDING_WORDS(0xA);
46 };
47 static_assert(sizeof(KeyboardSharedMemory) == 0x400, "KeyboardSharedMemory is an invalid size");
48
49 KeyboardState next_state{}; 30 KeyboardState next_state{};
50 KeyboardSharedMemory* shared_memory = nullptr; 31 KeyboardSharedMemoryFormat& shared_memory;
51 Core::HID::EmulatedDevices* emulated_devices = nullptr; 32 Core::HID::EmulatedDevices* emulated_devices = nullptr;
52}; 33};
53} // namespace Service::HID 34} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index 6e5a04e34..cce6deb52 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -8,15 +8,12 @@
8#include "core/hid/emulated_devices.h" 8#include "core/hid/emulated_devices.h"
9#include "core/hid/hid_core.h" 9#include "core/hid/hid_core.h"
10#include "core/hle/service/hid/controllers/mouse.h" 10#include "core/hle/service/hid/controllers/mouse.h"
11#include "core/hle/service/hid/controllers/shared_memory_format.h"
11 12
12namespace Service::HID { 13namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
14 14
15Mouse::Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} { 15Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory)
16 static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size, 16 : ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} {
17 "MouseSharedMemory is bigger than the shared memory");
18 shared_memory = std::construct_at(
19 reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
20 emulated_devices = hid_core.GetEmulatedDevices(); 17 emulated_devices = hid_core.GetEmulatedDevices();
21} 18}
22 19
@@ -27,14 +24,14 @@ void Mouse::OnRelease() {}
27 24
28void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 25void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
29 if (!IsControllerActivated()) { 26 if (!IsControllerActivated()) {
30 shared_memory->mouse_lifo.buffer_count = 0; 27 shared_memory.mouse_lifo.buffer_count = 0;
31 shared_memory->mouse_lifo.buffer_tail = 0; 28 shared_memory.mouse_lifo.buffer_tail = 0;
32 return; 29 return;
33 } 30 }
34 31
35 next_state = {}; 32 next_state = {};
36 33
37 const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state; 34 const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state;
38 next_state.sampling_number = last_entry.sampling_number + 1; 35 next_state.sampling_number = last_entry.sampling_number + 1;
39 36
40 if (Settings::values.mouse_enabled) { 37 if (Settings::values.mouse_enabled) {
@@ -53,7 +50,7 @@ void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
53 next_state.button = mouse_button_state; 50 next_state.button = mouse_button_state;
54 } 51 }
55 52
56 shared_memory->mouse_lifo.WriteNextEntry(next_state); 53 shared_memory.mouse_lifo.WriteNextEntry(next_state);
57} 54}
58 55
59} // namespace Service::HID 56} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index a80f3823f..3107915d7 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -14,9 +14,11 @@ struct AnalogStickState;
14} // namespace Core::HID 14} // namespace Core::HID
15 15
16namespace Service::HID { 16namespace Service::HID {
17struct MouseSharedMemoryFormat;
18
17class Mouse final : public ControllerBase { 19class Mouse final : public ControllerBase {
18public: 20public:
19 explicit Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 21 explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory);
20 ~Mouse() override; 22 ~Mouse() override;
21 23
22 // Called when the controller is initialized 24 // Called when the controller is initialized
@@ -29,17 +31,9 @@ public:
29 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 31 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
30 32
31private: 33private:
32 struct MouseSharedMemory {
33 // This is nn::hid::detail::MouseLifo
34 Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{};
35 static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
36 INSERT_PADDING_WORDS(0x2C);
37 };
38 static_assert(sizeof(MouseSharedMemory) == 0x400, "MouseSharedMemory is an invalid size");
39
40 Core::HID::MouseState next_state{}; 34 Core::HID::MouseState next_state{};
41 Core::HID::AnalogStickState last_mouse_wheel_state{}; 35 Core::HID::AnalogStickState last_mouse_wheel_state{};
42 MouseSharedMemory* shared_memory = nullptr; 36 MouseSharedMemoryFormat& shared_memory;
43 Core::HID::EmulatedDevices* emulated_devices = nullptr; 37 Core::HID::EmulatedDevices* emulated_devices = nullptr;
44}; 38};
45} // namespace Service::HID 39} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 08ee9de9c..53a737cf5 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -17,12 +17,12 @@
17#include "core/hle/kernel/k_event.h" 17#include "core/hle/kernel/k_event.h"
18#include "core/hle/kernel/k_readable_event.h" 18#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/service/hid/controllers/npad.h" 19#include "core/hle/service/hid/controllers/npad.h"
20#include "core/hle/service/hid/controllers/shared_memory_format.h"
20#include "core/hle/service/hid/errors.h" 21#include "core/hle/service/hid/errors.h"
21#include "core/hle/service/hid/hid_util.h" 22#include "core/hle/service/hid/hid_util.h"
22#include "core/hle/service/kernel_helpers.h" 23#include "core/hle/service/kernel_helpers.h"
23 24
24namespace Service::HID { 25namespace Service::HID {
25constexpr std::size_t NPAD_OFFSET = 0x9A00;
26constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{ 26constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
27 Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3, 27 Core::HID::NpadIdType::Player1, Core::HID::NpadIdType::Player2, Core::HID::NpadIdType::Player3,
28 Core::HID::NpadIdType::Player4, Core::HID::NpadIdType::Player5, Core::HID::NpadIdType::Player6, 28 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{
30 Core::HID::NpadIdType::Handheld, 30 Core::HID::NpadIdType::Handheld,
31}; 31};
32 32
33NPad::NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 33NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
34 KernelHelpers::ServiceContext& service_context_) 34 KernelHelpers::ServiceContext& service_context_)
35 : ControllerBase{hid_core_}, service_context{service_context_} { 35 : ControllerBase{hid_core_}, service_context{service_context_} {
36 static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size);
37 for (std::size_t i = 0; i < controller_data.size(); ++i) { 36 for (std::size_t i = 0; i < controller_data.size(); ++i) {
38 auto& controller = controller_data[i]; 37 auto& controller = controller_data[i];
39 controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>( 38 controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state;
40 raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState))));
41 controller.device = hid_core.GetEmulatedControllerByIndex(i); 39 controller.device = hid_core.GetEmulatedControllerByIndex(i);
42 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = 40 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
43 Core::HID::DEFAULT_VIBRATION_VALUE; 41 Core::HID::DEFAULT_VIBRATION_VALUE;
@@ -617,7 +615,7 @@ void NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
617 hold_type = joy_hold_type; 615 hold_type = joy_hold_type;
618} 616}
619 617
620NPad::NpadJoyHoldType NPad::GetHoldType() const { 618NpadJoyHoldType NPad::GetHoldType() const {
621 return hold_type; 619 return hold_type;
622} 620}
623 621
@@ -630,7 +628,7 @@ void NPad::SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_m
630 handheld_activation_mode = activation_mode; 628 handheld_activation_mode = activation_mode;
631} 629}
632 630
633NPad::NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const { 631NpadHandheldActivationMode NPad::GetNpadHandheldActivationMode() const {
634 return handheld_activation_mode; 632 return handheld_activation_mode;
635} 633}
636 634
@@ -638,7 +636,7 @@ void NPad::SetNpadCommunicationMode(NpadCommunicationMode communication_mode_) {
638 communication_mode = communication_mode_; 636 communication_mode = communication_mode_;
639} 637}
640 638
641NPad::NpadCommunicationMode NPad::GetNpadCommunicationMode() const { 639NpadCommunicationMode NPad::GetNpadCommunicationMode() const {
642 return communication_mode; 640 return communication_mode;
643} 641}
644 642
@@ -978,27 +976,27 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
978 return ResultSuccess; 976 return ResultSuccess;
979} 977}
980 978
981NPad::SixAxisLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) { 979NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
982 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo; 980 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
983} 981}
984 982
985NPad::SixAxisLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) { 983NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
986 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo; 984 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
987} 985}
988 986
989NPad::SixAxisLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) { 987NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
990 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo; 988 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
991} 989}
992 990
993NPad::SixAxisLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) { 991NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
994 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo; 992 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
995} 993}
996 994
997NPad::SixAxisLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) { 995NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
998 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo; 996 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
999} 997}
1000 998
1001NPad::SixAxisLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) { 999NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) {
1002 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo; 1000 return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo;
1003} 1001}
1004 1002
@@ -1343,7 +1341,7 @@ const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties(
1343 } 1341 }
1344} 1342}
1345 1343
1346NPad::AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { 1344AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) {
1347 const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory; 1345 const auto& shared_memory = GetControllerFromNpadIdType(npad_id).shared_memory;
1348 1346
1349 return { 1347 return {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 9167c93f0..19e8becb4 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -13,6 +13,7 @@
13 13
14#include "core/hid/hid_types.h" 14#include "core/hid/hid_types.h"
15#include "core/hle/service/hid/controllers/controller_base.h" 15#include "core/hle/service/hid/controllers/controller_base.h"
16#include "core/hle/service/hid/controllers/types/npad_types.h"
16#include "core/hle/service/hid/ring_lifo.h" 17#include "core/hle/service/hid/ring_lifo.h"
17 18
18namespace Core::HID { 19namespace Core::HID {
@@ -32,10 +33,13 @@ class ServiceContext;
32union Result; 33union Result;
33 34
34namespace Service::HID { 35namespace Service::HID {
36struct NpadInternalState;
37struct NpadSixAxisSensorLifo;
38struct NpadSharedMemoryFormat;
35 39
36class NPad final : public ControllerBase { 40class NPad final : public ControllerBase {
37public: 41public:
38 explicit NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 42 explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
39 KernelHelpers::ServiceContext& service_context_); 43 KernelHelpers::ServiceContext& service_context_);
40 ~NPad() override; 44 ~NPad() override;
41 45
@@ -48,89 +52,6 @@ public:
48 // When the controller is requesting an update for the shared memory 52 // When the controller is requesting an update for the shared memory
49 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 53 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
50 54
51 // This is nn::hid::NpadJoyHoldType
52 enum class NpadJoyHoldType : u64 {
53 Vertical = 0,
54 Horizontal = 1,
55 };
56
57 // This is nn::hid::NpadJoyAssignmentMode
58 enum class NpadJoyAssignmentMode : u32 {
59 Dual = 0,
60 Single = 1,
61 };
62
63 // This is nn::hid::NpadJoyDeviceType
64 enum class NpadJoyDeviceType : s64 {
65 Left = 0,
66 Right = 1,
67 };
68
69 // This is nn::hid::NpadHandheldActivationMode
70 enum class NpadHandheldActivationMode : u64 {
71 Dual = 0,
72 Single = 1,
73 None = 2,
74 MaxActivationMode = 3,
75 };
76
77 // This is nn::hid::system::AppletFooterUiAttributesSet
78 struct AppletFooterUiAttributes {
79 INSERT_PADDING_BYTES(0x4);
80 };
81
82 // This is nn::hid::system::AppletFooterUiType
83 enum class AppletFooterUiType : u8 {
84 None = 0,
85 HandheldNone = 1,
86 HandheldJoyConLeftOnly = 2,
87 HandheldJoyConRightOnly = 3,
88 HandheldJoyConLeftJoyConRight = 4,
89 JoyDual = 5,
90 JoyDualLeftOnly = 6,
91 JoyDualRightOnly = 7,
92 JoyLeftHorizontal = 8,
93 JoyLeftVertical = 9,
94 JoyRightHorizontal = 10,
95 JoyRightVertical = 11,
96 SwitchProController = 12,
97 CompatibleProController = 13,
98 CompatibleJoyCon = 14,
99 LarkHvc1 = 15,
100 LarkHvc2 = 16,
101 LarkNesLeft = 17,
102 LarkNesRight = 18,
103 Lucia = 19,
104 Verification = 20,
105 Lagon = 21,
106 };
107
108 using AppletFooterUiVariant = u8;
109
110 // This is "nn::hid::system::AppletDetailedUiType".
111 struct AppletDetailedUiType {
112 AppletFooterUiVariant ui_variant;
113 INSERT_PADDING_BYTES(0x2);
114 AppletFooterUiType footer;
115 };
116 static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
117 // This is nn::hid::NpadCommunicationMode
118 enum class NpadCommunicationMode : u64 {
119 Mode_5ms = 0,
120 Mode_10ms = 1,
121 Mode_15ms = 2,
122 Default = 3,
123 };
124
125 enum class NpadRevision : u32 {
126 Revision0 = 0,
127 Revision1 = 1,
128 Revision2 = 2,
129 Revision3 = 3,
130 };
131
132 using SixAxisLifo = Lifo<Core::HID::SixAxisSensorState, hid_entry_count>;
133
134 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); 55 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
135 Core::HID::NpadStyleTag GetSupportedStyleSet() const; 56 Core::HID::NpadStyleTag GetSupportedStyleSet() const;
136 57
@@ -188,12 +109,12 @@ public:
188 Result ResetIsSixAxisSensorDeviceNewlyAssigned( 109 Result ResetIsSixAxisSensorDeviceNewlyAssigned(
189 const Core::HID::SixAxisSensorHandle& sixaxis_handle); 110 const Core::HID::SixAxisSensorHandle& sixaxis_handle);
190 111
191 SixAxisLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id); 112 NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
192 SixAxisLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id); 113 NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
193 SixAxisLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id); 114 NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
194 SixAxisLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id); 115 NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
195 SixAxisLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id); 116 NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
196 SixAxisLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id); 117 NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
197 118
198 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; 119 Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
199 Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id, 120 Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
@@ -221,214 +142,6 @@ public:
221 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); 142 AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id);
222 143
223private: 144private:
224 static constexpr std::size_t NPAD_COUNT = 10;
225
226 // This is nn::hid::detail::ColorAttribute
227 enum class ColorAttribute : u32 {
228 Ok = 0,
229 ReadError = 1,
230 NoController = 2,
231 };
232 static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
233
234 // This is nn::hid::detail::NpadFullKeyColorState
235 struct NpadFullKeyColorState {
236 ColorAttribute attribute{ColorAttribute::NoController};
237 Core::HID::NpadControllerColor fullkey{};
238 };
239 static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
240
241 // This is nn::hid::detail::NpadJoyColorState
242 struct NpadJoyColorState {
243 ColorAttribute attribute{ColorAttribute::NoController};
244 Core::HID::NpadControllerColor left{};
245 Core::HID::NpadControllerColor right{};
246 };
247 static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
248
249 // This is nn::hid::NpadAttribute
250 struct NpadAttribute {
251 union {
252 u32 raw{};
253 BitField<0, 1, u32> is_connected;
254 BitField<1, 1, u32> is_wired;
255 BitField<2, 1, u32> is_left_connected;
256 BitField<3, 1, u32> is_left_wired;
257 BitField<4, 1, u32> is_right_connected;
258 BitField<5, 1, u32> is_right_wired;
259 };
260 };
261 static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
262
263 // This is nn::hid::NpadFullKeyState
264 // This is nn::hid::NpadHandheldState
265 // This is nn::hid::NpadJoyDualState
266 // This is nn::hid::NpadJoyLeftState
267 // This is nn::hid::NpadJoyRightState
268 // This is nn::hid::NpadPalmaState
269 // This is nn::hid::NpadSystemExtState
270 struct NPadGenericState {
271 s64_le sampling_number{};
272 Core::HID::NpadButtonState npad_buttons{};
273 Core::HID::AnalogStickState l_stick{};
274 Core::HID::AnalogStickState r_stick{};
275 NpadAttribute connection_status{};
276 INSERT_PADDING_BYTES(4); // Reserved
277 };
278 static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
279
280 // This is nn::hid::server::NpadGcTriggerState
281 struct NpadGcTriggerState {
282 s64 sampling_number{};
283 s32 l_analog{};
284 s32 r_analog{};
285 };
286 static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
287
288 // This is nn::hid::NpadSystemProperties
289 struct NPadSystemProperties {
290 union {
291 s64 raw{};
292 BitField<0, 1, s64> is_charging_joy_dual;
293 BitField<1, 1, s64> is_charging_joy_left;
294 BitField<2, 1, s64> is_charging_joy_right;
295 BitField<3, 1, s64> is_powered_joy_dual;
296 BitField<4, 1, s64> is_powered_joy_left;
297 BitField<5, 1, s64> is_powered_joy_right;
298 BitField<9, 1, s64> is_system_unsupported_button;
299 BitField<10, 1, s64> is_system_ext_unsupported_button;
300 BitField<11, 1, s64> is_vertical;
301 BitField<12, 1, s64> is_horizontal;
302 BitField<13, 1, s64> use_plus;
303 BitField<14, 1, s64> use_minus;
304 BitField<15, 1, s64> use_directional_buttons;
305 };
306 };
307 static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
308
309 // This is nn::hid::NpadSystemButtonProperties
310 struct NpadSystemButtonProperties {
311 union {
312 s32 raw{};
313 BitField<0, 1, s32> is_home_button_protection_enabled;
314 };
315 };
316 static_assert(sizeof(NpadSystemButtonProperties) == 0x4,
317 "NPadButtonProperties is an invalid size");
318
319 // This is nn::hid::system::DeviceType
320 struct DeviceType {
321 union {
322 u32 raw{};
323 BitField<0, 1, s32> fullkey;
324 BitField<1, 1, s32> debug_pad;
325 BitField<2, 1, s32> handheld_left;
326 BitField<3, 1, s32> handheld_right;
327 BitField<4, 1, s32> joycon_left;
328 BitField<5, 1, s32> joycon_right;
329 BitField<6, 1, s32> palma;
330 BitField<7, 1, s32> lark_hvc_left;
331 BitField<8, 1, s32> lark_hvc_right;
332 BitField<9, 1, s32> lark_nes_left;
333 BitField<10, 1, s32> lark_nes_right;
334 BitField<11, 1, s32> handheld_lark_hvc_left;
335 BitField<12, 1, s32> handheld_lark_hvc_right;
336 BitField<13, 1, s32> handheld_lark_nes_left;
337 BitField<14, 1, s32> handheld_lark_nes_right;
338 BitField<15, 1, s32> lucia;
339 BitField<16, 1, s32> lagon;
340 BitField<17, 1, s32> lager;
341 BitField<31, 1, s32> system;
342 };
343 };
344
345 // This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
346 struct NfcXcdDeviceHandleStateImpl {
347 u64 handle{};
348 bool is_available{};
349 bool is_activated{};
350 INSERT_PADDING_BYTES(0x6); // Reserved
351 u64 sampling_number{};
352 };
353 static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
354 "NfcXcdDeviceHandleStateImpl is an invalid size");
355
356 // This is nn::hid::NpadLarkType
357 enum class NpadLarkType : u32 {
358 Invalid,
359 H1,
360 H2,
361 NL,
362 NR,
363 };
364
365 // This is nn::hid::NpadLuciaType
366 enum class NpadLuciaType : u32 {
367 Invalid,
368 J,
369 E,
370 U,
371 };
372
373 // This is nn::hid::NpadLagonType
374 enum class NpadLagonType : u32 {
375 Invalid,
376 };
377
378 // This is nn::hid::NpadLagerType
379 enum class NpadLagerType : u32 {
380 Invalid,
381 J,
382 E,
383 U,
384 };
385
386 // This is nn::hid::detail::NpadInternalState
387 struct NpadInternalState {
388 Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
389 NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
390 NpadFullKeyColorState fullkey_color{};
391 NpadJoyColorState joycon_color{};
392 Lifo<NPadGenericState, hid_entry_count> fullkey_lifo{};
393 Lifo<NPadGenericState, hid_entry_count> handheld_lifo{};
394 Lifo<NPadGenericState, hid_entry_count> joy_dual_lifo{};
395 Lifo<NPadGenericState, hid_entry_count> joy_left_lifo{};
396 Lifo<NPadGenericState, hid_entry_count> joy_right_lifo{};
397 Lifo<NPadGenericState, hid_entry_count> palma_lifo{};
398 Lifo<NPadGenericState, hid_entry_count> system_ext_lifo{};
399 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_fullkey_lifo{};
400 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_handheld_lifo{};
401 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_left_lifo{};
402 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_dual_right_lifo{};
403 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_left_lifo{};
404 Lifo<Core::HID::SixAxisSensorState, hid_entry_count> sixaxis_right_lifo{};
405 DeviceType device_type{};
406 INSERT_PADDING_BYTES(0x4); // Reserved
407 NPadSystemProperties system_properties{};
408 NpadSystemButtonProperties button_properties{};
409 Core::HID::NpadBatteryLevel battery_level_dual{};
410 Core::HID::NpadBatteryLevel battery_level_left{};
411 Core::HID::NpadBatteryLevel battery_level_right{};
412 AppletFooterUiAttributes applet_footer_attributes{};
413 AppletFooterUiType applet_footer_type{AppletFooterUiType::None};
414 INSERT_PADDING_BYTES(0x5B); // Reserved
415 INSERT_PADDING_BYTES(0x20); // Unknown
416 Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
417 NpadLarkType lark_type_l_and_main{};
418 NpadLarkType lark_type_r{};
419 NpadLuciaType lucia_type{};
420 NpadLagonType lagon_type{};
421 NpadLagerType lager_type{};
422 Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties;
423 Core::HID::SixAxisSensorProperties sixaxis_handheld_properties;
424 Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties;
425 Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties;
426 Core::HID::SixAxisSensorProperties sixaxis_left_properties;
427 Core::HID::SixAxisSensorProperties sixaxis_right_properties;
428 INSERT_PADDING_BYTES(0xc06); // Unknown
429 };
430 static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
431
432 struct VibrationData { 145 struct VibrationData {
433 bool device_mounted{}; 146 bool device_mounted{};
434 Core::HID::VibrationValue latest_vibration_value{}; 147 Core::HID::VibrationValue latest_vibration_value{};
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 588ff9d62..aa0454b5e 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -12,8 +12,7 @@
12 12
13namespace Service::HID { 13namespace Service::HID {
14 14
15Palma::Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 15Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
16 KernelHelpers::ServiceContext& service_context_)
17 : ControllerBase{hid_core_}, service_context{service_context_} { 16 : ControllerBase{hid_core_}, service_context{service_context_} {
18 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); 17 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
19 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); 18 operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index a6047f36a..73884230d 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -97,8 +97,7 @@ public:
97 static_assert(sizeof(PalmaConnectionHandle) == 0x8, 97 static_assert(sizeof(PalmaConnectionHandle) == 0x8,
98 "PalmaConnectionHandle has incorrect size."); 98 "PalmaConnectionHandle has incorrect size.");
99 99
100 explicit Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, 100 explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
101 KernelHelpers::ServiceContext& service_context_);
102 ~Palma() override; 101 ~Palma() override;
103 102
104 // Called when the controller is initialized 103 // Called when the controller is initialized
diff --git a/src/core/hle/service/hid/controllers/shared_memory_format.h b/src/core/hle/service/hid/controllers/shared_memory_format.h
new file mode 100644
index 000000000..63fb46c11
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/shared_memory_format.h
@@ -0,0 +1,239 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_funcs.h"
7#include "common/common_types.h"
8#include "common/vector_math.h"
9#include "core/hid/hid_types.h"
10#include "core/hle/service/hid//controllers/types/debug_pad_types.h"
11#include "core/hle/service/hid//controllers/types/keyboard_types.h"
12#include "core/hle/service/hid//controllers/types/mouse_types.h"
13#include "core/hle/service/hid//controllers/types/npad_types.h"
14#include "core/hle/service/hid//controllers/types/touch_types.h"
15#include "core/hle/service/hid/ring_lifo.h"
16
17namespace Service::HID {
18static const std::size_t HidEntryCount = 17;
19
20struct CommonHeader {
21 s64 timestamp{};
22 s64 total_entry_count{};
23 s64 last_entry_index{};
24 s64 entry_count{};
25};
26static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
27
28// This is nn::hid::detail::DebugPadSharedMemoryFormat
29struct DebugPadSharedMemoryFormat {
30 // This is nn::hid::detail::DebugPadLifo
31 Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{};
32 static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size");
33 INSERT_PADDING_WORDS(0x4E);
34};
35static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400,
36 "DebugPadSharedMemoryFormat is an invalid size");
37
38// This is nn::hid::detail::TouchScreenSharedMemoryFormat
39struct TouchScreenSharedMemoryFormat {
40 // This is nn::hid::detail::TouchScreenLifo
41 Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{};
42 static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
43 INSERT_PADDING_WORDS(0xF2);
44};
45static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000,
46 "TouchScreenSharedMemoryFormat is an invalid size");
47
48// This is nn::hid::detail::MouseSharedMemoryFormat
49struct MouseSharedMemoryFormat {
50 // This is nn::hid::detail::MouseLifo
51 Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{};
52 static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size");
53 INSERT_PADDING_WORDS(0x2C);
54};
55static_assert(sizeof(MouseSharedMemoryFormat) == 0x400,
56 "MouseSharedMemoryFormat is an invalid size");
57
58// This is nn::hid::detail::KeyboardSharedMemoryFormat
59struct KeyboardSharedMemoryFormat {
60 // This is nn::hid::detail::KeyboardLifo
61 Lifo<KeyboardState, HidEntryCount> keyboard_lifo{};
62 static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size");
63 INSERT_PADDING_WORDS(0xA);
64};
65static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400,
66 "KeyboardSharedMemoryFormat is an invalid size");
67
68// This is nn::hid::detail::DigitizerSharedMemoryFormat
69struct DigitizerSharedMemoryFormat {
70 CommonHeader header;
71 INSERT_PADDING_BYTES(0xFE0);
72};
73static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000,
74 "DigitizerSharedMemoryFormat is an invalid size");
75
76// This is nn::hid::detail::HomeButtonSharedMemoryFormat
77struct HomeButtonSharedMemoryFormat {
78 CommonHeader header;
79 INSERT_PADDING_BYTES(0x1E0);
80};
81static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200,
82 "HomeButtonSharedMemoryFormat is an invalid size");
83
84// This is nn::hid::detail::SleepButtonSharedMemoryFormat
85struct SleepButtonSharedMemoryFormat {
86 CommonHeader header;
87 INSERT_PADDING_BYTES(0x1E0);
88};
89static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200,
90 "SleepButtonSharedMemoryFormat is an invalid size");
91
92// This is nn::hid::detail::CaptureButtonSharedMemoryFormat
93struct CaptureButtonSharedMemoryFormat {
94 CommonHeader header;
95 INSERT_PADDING_BYTES(0x1E0);
96};
97static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200,
98 "CaptureButtonSharedMemoryFormat is an invalid size");
99
100// This is nn::hid::detail::InputDetectorSharedMemoryFormat
101struct InputDetectorSharedMemoryFormat {
102 CommonHeader header;
103 INSERT_PADDING_BYTES(0x7E0);
104};
105static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800,
106 "InputDetectorSharedMemoryFormat is an invalid size");
107
108// This is nn::hid::detail::UniquePadSharedMemoryFormat
109struct UniquePadSharedMemoryFormat {
110 CommonHeader header;
111 INSERT_PADDING_BYTES(0x3FE0);
112};
113static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000,
114 "UniquePadSharedMemoryFormat is an invalid size");
115
116// This is nn::hid::detail::NpadSixAxisSensorLifo
117struct NpadSixAxisSensorLifo {
118 Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo;
119};
120
121// This is nn::hid::detail::NpadInternalState
122struct NpadInternalState {
123 Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
124 NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual};
125 NpadFullKeyColorState fullkey_color{};
126 NpadJoyColorState joycon_color{};
127 Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{};
128 Lifo<NPadGenericState, HidEntryCount> handheld_lifo{};
129 Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{};
130 Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{};
131 Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{};
132 Lifo<NPadGenericState, HidEntryCount> palma_lifo{};
133 Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{};
134 NpadSixAxisSensorLifo sixaxis_fullkey_lifo{};
135 NpadSixAxisSensorLifo sixaxis_handheld_lifo{};
136 NpadSixAxisSensorLifo sixaxis_dual_left_lifo{};
137 NpadSixAxisSensorLifo sixaxis_dual_right_lifo{};
138 NpadSixAxisSensorLifo sixaxis_left_lifo{};
139 NpadSixAxisSensorLifo sixaxis_right_lifo{};
140 DeviceType device_type{};
141 INSERT_PADDING_BYTES(0x4); // Reserved
142 NPadSystemProperties system_properties{};
143 NpadSystemButtonProperties button_properties{};
144 Core::HID::NpadBatteryLevel battery_level_dual{};
145 Core::HID::NpadBatteryLevel battery_level_left{};
146 Core::HID::NpadBatteryLevel battery_level_right{};
147 AppletFooterUiAttributes applet_footer_attributes{};
148 AppletFooterUiType applet_footer_type{AppletFooterUiType::None};
149 INSERT_PADDING_BYTES(0x5B); // Reserved
150 INSERT_PADDING_BYTES(0x20); // Unknown
151 Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{};
152 NpadLarkType lark_type_l_and_main{};
153 NpadLarkType lark_type_r{};
154 NpadLuciaType lucia_type{};
155 NpadLagerType lager_type{};
156 Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties;
157 Core::HID::SixAxisSensorProperties sixaxis_handheld_properties;
158 Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties;
159 Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties;
160 Core::HID::SixAxisSensorProperties sixaxis_left_properties;
161 Core::HID::SixAxisSensorProperties sixaxis_right_properties;
162};
163static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size");
164
165// This is nn::hid::detail::NpadSharedMemoryEntry
166struct NpadSharedMemoryEntry {
167 NpadInternalState internal_state;
168 INSERT_PADDING_BYTES(0xC08);
169};
170static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size");
171
172// This is nn::hid::detail::NpadSharedMemoryFormat
173struct NpadSharedMemoryFormat {
174 std::array<NpadSharedMemoryEntry, NPAD_COUNT> npad_entry;
175};
176static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000,
177 "NpadSharedMemoryFormat is an invalid size");
178
179// This is nn::hid::detail::GestureSharedMemoryFormat
180struct GestureSharedMemoryFormat {
181 // This is nn::hid::detail::GestureLifo
182 Lifo<GestureState, HidEntryCount> gesture_lifo{};
183 static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
184 INSERT_PADDING_WORDS(0x3E);
185};
186static_assert(sizeof(GestureSharedMemoryFormat) == 0x800,
187 "GestureSharedMemoryFormat is an invalid size");
188
189// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat
190struct ConsoleSixAxisSensorSharedMemoryFormat {
191 u64 sampling_number{};
192 bool is_seven_six_axis_sensor_at_rest{};
193 INSERT_PADDING_BYTES(3); // padding
194 f32 verticalization_error{};
195 Common::Vec3f gyro_bias{};
196 INSERT_PADDING_BYTES(4); // padding
197};
198static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20,
199 "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size");
200
201struct SharedMemoryFormat {
202 void Initialize() {}
203
204 DebugPadSharedMemoryFormat debug_pad;
205 TouchScreenSharedMemoryFormat touch_screen;
206 MouseSharedMemoryFormat mouse;
207 KeyboardSharedMemoryFormat keyboard;
208 DigitizerSharedMemoryFormat digitizer;
209 HomeButtonSharedMemoryFormat home_button;
210 SleepButtonSharedMemoryFormat sleep_button;
211 CaptureButtonSharedMemoryFormat capture_button;
212 InputDetectorSharedMemoryFormat input_detector;
213 UniquePadSharedMemoryFormat unique_pad;
214 NpadSharedMemoryFormat npad;
215 GestureSharedMemoryFormat gesture;
216 ConsoleSixAxisSensorSharedMemoryFormat console;
217 INSERT_PADDING_BYTES(0x19E0);
218 MouseSharedMemoryFormat debug_mouse;
219 INSERT_PADDING_BYTES(0x2000);
220};
221static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset");
222static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset");
223static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset");
224static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset");
225static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset");
226static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset");
227static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00,
228 "sleep_button has wrong offset");
229static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000,
230 "capture_button has wrong offset");
231static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200,
232 "input_detector has wrong offset");
233static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset");
234static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset");
235static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset");
236static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset");
237static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size");
238
239} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
new file mode 100644
index 000000000..223487421
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
@@ -0,0 +1,49 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#include "core/core.h"
5#include "core/hle/kernel/k_shared_memory.h"
6#include "core/hle/service/hid/controllers/shared_memory_format.h"
7#include "core/hle/service/hid/controllers/shared_memory_holder.h"
8#include "core/hle/service/hid/errors.h"
9
10namespace Service::HID {
11SharedMemoryHolder::SharedMemoryHolder() {}
12
13Result SharedMemoryHolder::Initialize(Core::System& system) {
14 shared_memory = Kernel::KSharedMemory::Create(system.Kernel());
15 const Result result = shared_memory->Initialize(
16 system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None,
17 Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat));
18 if (result.IsError()) {
19 return result;
20 }
21 Kernel::KSharedMemory::Register(system.Kernel(), shared_memory);
22
23 is_created = true;
24 is_mapped = true;
25 address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer()));
26 return ResultSuccess;
27}
28
29void SharedMemoryHolder::Finalize() {
30 if (address != nullptr) {
31 shared_memory->Close();
32 }
33 is_created = false;
34 is_mapped = false;
35 address = nullptr;
36}
37
38bool SharedMemoryHolder::IsMapped() {
39 return is_mapped;
40}
41
42SharedMemoryFormat* SharedMemoryHolder::GetAddress() {
43 return address;
44}
45
46Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() {
47 return shared_memory;
48}
49} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/core/hle/service/hid/controllers/shared_memory_holder.h
new file mode 100644
index 000000000..260402712
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/shared_memory_holder.h
@@ -0,0 +1,44 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7#include "core/hle/result.h"
8
9namespace Core {
10class System;
11}
12
13namespace Kernel {
14class KSharedMemory;
15}
16
17namespace Service::HID {
18struct SharedMemoryFormat;
19
20// This is nn::hid::detail::SharedMemoryHolder
21class SharedMemoryHolder {
22public:
23 SharedMemoryHolder();
24
25 Result Initialize(Core::System& system);
26 void Finalize();
27
28 bool IsMapped();
29 SharedMemoryFormat* GetAddress();
30 Kernel::KSharedMemory* GetHandle();
31
32private:
33 bool is_owner{};
34 bool is_created{};
35 bool is_mapped{};
36 INSERT_PADDING_BYTES(0x5);
37 Kernel::KSharedMemory* shared_memory;
38 INSERT_PADDING_BYTES(0x38);
39 SharedMemoryFormat* address = nullptr;
40};
41// Correct size is 0x50 bytes
42static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size");
43
44} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp
index 3d24a5c04..36b72f9ea 100644
--- a/src/core/hle/service/hid/controllers/six_axis.cpp
+++ b/src/core/hle/service/hid/controllers/six_axis.cpp
@@ -6,6 +6,7 @@
6#include "core/hid/emulated_controller.h" 6#include "core/hid/emulated_controller.h"
7#include "core/hid/hid_core.h" 7#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/npad.h" 8#include "core/hle/service/hid/controllers/npad.h"
9#include "core/hle/service/hid/controllers/shared_memory_format.h"
9#include "core/hle/service/hid/controllers/six_axis.h" 10#include "core/hle/service/hid/controllers/six_axis.h"
10#include "core/hle/service/hid/errors.h" 11#include "core/hle/service/hid/errors.h"
11#include "core/hle/service/hid/hid_util.h" 12#include "core/hle/service/hid/hid_util.h"
@@ -132,30 +133,30 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
132 } 133 }
133 134
134 sixaxis_fullkey_state.sampling_number = 135 sixaxis_fullkey_state.sampling_number =
135 sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; 136 sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
136 sixaxis_handheld_state.sampling_number = 137 sixaxis_handheld_state.sampling_number =
137 sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; 138 sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
138 sixaxis_dual_left_state.sampling_number = 139 sixaxis_dual_left_state.sampling_number =
139 sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; 140 sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
140 sixaxis_dual_right_state.sampling_number = 141 sixaxis_dual_right_state.sampling_number =
141 sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; 142 sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
142 sixaxis_left_lifo_state.sampling_number = 143 sixaxis_left_lifo_state.sampling_number =
143 sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; 144 sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
144 sixaxis_right_lifo_state.sampling_number = 145 sixaxis_right_lifo_state.sampling_number =
145 sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; 146 sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1;
146 147
147 if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { 148 if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
148 // This buffer only is updated on handheld on HW 149 // This buffer only is updated on handheld on HW
149 sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); 150 sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state);
150 } else { 151 } else {
151 // Handheld doesn't update this buffer on HW 152 // Handheld doesn't update this buffer on HW
152 sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); 153 sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state);
153 } 154 }
154 155
155 sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); 156 sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state);
156 sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); 157 sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state);
157 sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); 158 sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state);
158 sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); 159 sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state);
159 } 160 }
160} 161}
161 162
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index 9e2f3ab21..26001e914 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -4,15 +4,14 @@
4#include <cstring> 4#include <cstring>
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "core/core_timing.h" 6#include "core/core_timing.h"
7#include "core/hid/hid_core.h" 7#include "core/hle/service/hid/controllers/shared_memory_format.h"
8#include "core/hle/service/hid/controllers/stubbed.h" 8#include "core/hle/service/hid/controllers/stubbed.h"
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
12Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 12Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_,
13 : ControllerBase{hid_core_} { 13 CommonHeader& ring_lifo_header)
14 raw_shared_memory = raw_shared_memory_; 14 : ControllerBase{hid_core_}, header{ring_lifo_header} {}
15}
16 15
17Controller_Stubbed::~Controller_Stubbed() = default; 16Controller_Stubbed::~Controller_Stubbed() = default;
18 17
@@ -25,18 +24,10 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
25 return; 24 return;
26 } 25 }
27 26
28 CommonHeader header{};
29 header.timestamp = core_timing.GetGlobalTimeNs().count(); 27 header.timestamp = core_timing.GetGlobalTimeNs().count();
30 header.total_entry_count = 17; 28 header.total_entry_count = 17;
31 header.entry_count = 0; 29 header.entry_count = 0;
32 header.last_entry_index = 0; 30 header.last_entry_index = 0;
33
34 std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader));
35}
36
37void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
38 common_offset = off;
39 smart_update = true;
40} 31}
41 32
42} // namespace Service::HID 33} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h
index 1483a968e..bdf35d84b 100644
--- a/src/core/hle/service/hid/controllers/stubbed.h
+++ b/src/core/hle/service/hid/controllers/stubbed.h
@@ -7,9 +7,11 @@
7#include "core/hle/service/hid/controllers/controller_base.h" 7#include "core/hle/service/hid/controllers/controller_base.h"
8 8
9namespace Service::HID { 9namespace Service::HID {
10struct CommonHeader;
11
10class Controller_Stubbed final : public ControllerBase { 12class Controller_Stubbed final : public ControllerBase {
11public: 13public:
12 explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 14 explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, CommonHeader& ring_lifo_header);
13 ~Controller_Stubbed() override; 15 ~Controller_Stubbed() override;
14 16
15 // Called when the controller is initialized 17 // Called when the controller is initialized
@@ -21,19 +23,8 @@ public:
21 // When the controller is requesting an update for the shared memory 23 // When the controller is requesting an update for the shared memory
22 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; 24 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
23 25
24 void SetCommonHeaderOffset(std::size_t off);
25
26private: 26private:
27 struct CommonHeader { 27 CommonHeader& header;
28 s64 timestamp{};
29 s64 total_entry_count{};
30 s64 last_entry_index{};
31 s64 entry_count{};
32 };
33 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
34
35 u8* raw_shared_memory = nullptr;
36 bool smart_update{}; 28 bool smart_update{};
37 std::size_t common_offset{};
38}; 29};
39} // namespace Service::HID 30} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index fcd973414..a98f1f85e 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -10,18 +10,16 @@
10#include "core/frontend/emu_window.h" 10#include "core/frontend/emu_window.h"
11#include "core/hid/emulated_console.h" 11#include "core/hid/emulated_console.h"
12#include "core/hid/hid_core.h" 12#include "core/hid/hid_core.h"
13#include "core/hle/service/hid/controllers/shared_memory_format.h"
13#include "core/hle/service/hid/controllers/touchscreen.h" 14#include "core/hle/service/hid/controllers/touchscreen.h"
14 15
15namespace Service::HID { 16namespace Service::HID {
16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
17 17
18TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) 18TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_,
19 : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width), 19 TouchScreenSharedMemoryFormat& touch_shared_memory)
20 : ControllerBase{hid_core_}, shared_memory{touch_shared_memory},
21 touchscreen_width(Layout::ScreenUndocked::Width),
20 touchscreen_height(Layout::ScreenUndocked::Height) { 22 touchscreen_height(Layout::ScreenUndocked::Height) {
21 static_assert(SHARED_MEMORY_OFFSET + sizeof(TouchSharedMemory) < shared_memory_size,
22 "TouchSharedMemory is bigger than the shared memory");
23 shared_memory = std::construct_at(
24 reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
25 console = hid_core.GetEmulatedConsole(); 23 console = hid_core.GetEmulatedConsole();
26} 24}
27 25
@@ -32,11 +30,11 @@ void TouchScreen::OnInit() {}
32void TouchScreen::OnRelease() {} 30void TouchScreen::OnRelease() {}
33 31
34void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 32void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
35 shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); 33 shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
36 34
37 if (!IsControllerActivated()) { 35 if (!IsControllerActivated()) {
38 shared_memory->touch_screen_lifo.buffer_count = 0; 36 shared_memory.touch_screen_lifo.buffer_count = 0;
39 shared_memory->touch_screen_lifo.buffer_tail = 0; 37 shared_memory.touch_screen_lifo.buffer_tail = 0;
40 return; 38 return;
41 } 39 }
42 40
@@ -86,7 +84,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
86 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); 84 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
87 85
88 const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); 86 const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count());
89 const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; 87 const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state;
90 88
91 next_state.sampling_number = last_entry.sampling_number + 1; 89 next_state.sampling_number = last_entry.sampling_number + 1;
92 next_state.entry_count = static_cast<s32>(active_fingers_count); 90 next_state.entry_count = static_cast<s32>(active_fingers_count);
@@ -118,7 +116,7 @@ void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
118 } 116 }
119 } 117 }
120 118
121 shared_memory->touch_screen_lifo.WriteNextEntry(next_state); 119 shared_memory.touch_screen_lifo.WriteNextEntry(next_state);
122} 120}
123 121
124void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { 122void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) {
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 79f026a81..63513404b 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -3,10 +3,12 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/common_funcs.h" 6#include <array>
7
7#include "common/common_types.h" 8#include "common/common_types.h"
8#include "core/hid/hid_types.h" 9#include "core/hid/hid_types.h"
9#include "core/hle/service/hid/controllers/controller_base.h" 10#include "core/hle/service/hid/controllers/controller_base.h"
11#include "core/hle/service/hid/controllers/types/touch_types.h"
10#include "core/hle/service/hid/ring_lifo.h" 12#include "core/hle/service/hid/ring_lifo.h"
11 13
12namespace Core::HID { 14namespace Core::HID {
@@ -14,9 +16,12 @@ class EmulatedConsole;
14} // namespace Core::HID 16} // namespace Core::HID
15 17
16namespace Service::HID { 18namespace Service::HID {
19struct TouchScreenSharedMemoryFormat;
20
17class TouchScreen final : public ControllerBase { 21class TouchScreen final : public ControllerBase {
18public: 22public:
19 explicit TouchScreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_); 23 explicit TouchScreen(Core::HID::HIDCore& hid_core_,
24 TouchScreenSharedMemoryFormat& touch_shared_memory);
20 ~TouchScreen() override; 25 ~TouchScreen() override;
21 26
22 // Called when the controller is initialized 27 // Called when the controller is initialized
@@ -31,27 +36,8 @@ public:
31 void SetTouchscreenDimensions(u32 width, u32 height); 36 void SetTouchscreenDimensions(u32 width, u32 height);
32 37
33private: 38private:
34 static constexpr std::size_t MAX_FINGERS = 16;
35
36 // This is nn::hid::TouchScreenState
37 struct TouchScreenState {
38 s64 sampling_number{};
39 s32 entry_count{};
40 INSERT_PADDING_BYTES(4); // Reserved
41 std::array<Core::HID::TouchState, MAX_FINGERS> states{};
42 };
43 static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
44
45 struct TouchSharedMemory {
46 // This is nn::hid::detail::TouchScreenLifo
47 Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{};
48 static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
49 INSERT_PADDING_WORDS(0xF2);
50 };
51 static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size");
52
53 TouchScreenState next_state{}; 39 TouchScreenState next_state{};
54 TouchSharedMemory* shared_memory = nullptr; 40 TouchScreenSharedMemoryFormat& shared_memory;
55 Core::HID::EmulatedConsole* console = nullptr; 41 Core::HID::EmulatedConsole* console = nullptr;
56 42
57 std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; 43 std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/core/hle/service/hid/controllers/types/debug_pad_types.h
new file mode 100644
index 000000000..a96171b62
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/debug_pad_types.h
@@ -0,0 +1,31 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/bit_field.h"
7#include "common/common_types.h"
8#include "core/hid/hid_types.h"
9
10namespace Service::HID {
11
12// This is nn::hid::DebugPadAttribute
13struct DebugPadAttribute {
14 union {
15 u32 raw{};
16 BitField<0, 1, u32> connected;
17 };
18};
19static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size");
20
21// This is nn::hid::DebugPadState
22struct DebugPadState {
23 s64 sampling_number{};
24 DebugPadAttribute attribute{};
25 Core::HID::DebugPadButton pad_state{};
26 Core::HID::AnalogStickState r_stick{};
27 Core::HID::AnalogStickState l_stick{};
28};
29static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
30
31} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/core/hle/service/hid/controllers/types/gesture_types.h
new file mode 100644
index 000000000..b4f034cd3
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/gesture_types.h
@@ -0,0 +1,77 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7#include "common/bit_field.h"
8#include "common/common_types.h"
9#include "common/point.h"
10
11namespace Service::HID {
12static constexpr size_t MAX_FINGERS = 16;
13static constexpr size_t MAX_POINTS = 4;
14
15// This is nn::hid::GestureType
16enum class GestureType : u32 {
17 Idle, // Nothing touching the screen
18 Complete, // Set at the end of a touch event
19 Cancel, // Set when the number of fingers change
20 Touch, // A finger just touched the screen
21 Press, // Set if last type is touch and the finger hasn't moved
22 Tap, // Fast press then release
23 Pan, // All points moving together across the screen
24 Swipe, // Fast press movement and release of a single point
25 Pinch, // All points moving away/closer to the midpoint
26 Rotate, // All points rotating from the midpoint
27};
28
29// This is nn::hid::GestureDirection
30enum class GestureDirection : u32 {
31 None,
32 Left,
33 Up,
34 Right,
35 Down,
36};
37
38// This is nn::hid::GestureAttribute
39struct GestureAttribute {
40 union {
41 u32 raw{};
42
43 BitField<4, 1, u32> is_new_touch;
44 BitField<8, 1, u32> is_double_tap;
45 };
46};
47static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
48
49// This is nn::hid::GestureState
50struct GestureState {
51 s64 sampling_number{};
52 s64 detection_count{};
53 GestureType type{GestureType::Idle};
54 GestureDirection direction{GestureDirection::None};
55 Common::Point<s32> pos{};
56 Common::Point<s32> delta{};
57 f32 vel_x{};
58 f32 vel_y{};
59 GestureAttribute attributes{};
60 f32 scale{};
61 f32 rotation_angle{};
62 s32 point_count{};
63 std::array<Common::Point<s32>, 4> points{};
64};
65static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
66
67struct GestureProperties {
68 std::array<Common::Point<s32>, MAX_POINTS> points{};
69 std::size_t active_points{};
70 Common::Point<s32> mid_point{};
71 s64 detection_count{};
72 u64 delta_time{};
73 f32 average_distance{};
74 f32 angle{};
75};
76
77} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/core/hle/service/hid/controllers/types/keyboard_types.h
new file mode 100644
index 000000000..f44a536b9
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/keyboard_types.h
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7#include "core/hid/hid_types.h"
8
9namespace Service::HID {
10
11// This is nn::hid::detail::KeyboardState
12struct KeyboardState {
13 s64 sampling_number{};
14 Core::HID::KeyboardModifier modifier{};
15 Core::HID::KeyboardAttribute attribute{};
16 Core::HID::KeyboardKey key{};
17};
18static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
19
20} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/core/hle/service/hid/controllers/types/mouse_types.h
new file mode 100644
index 000000000..fb9c7703a
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/mouse_types.h
@@ -0,0 +1,12 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_funcs.h"
7#include "common/common_types.h"
8#include "common/vector_math.h"
9#include "core/hid/hid_types.h"
10#include "core/hle/service/hid/ring_lifo.h"
11
12namespace Service::HID {} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/core/hle/service/hid/controllers/types/npad_types.h
new file mode 100644
index 000000000..9eb98ccef
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/npad_types.h
@@ -0,0 +1,255 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include "common/common_funcs.h"
7#include "common/common_types.h"
8#include "common/vector_math.h"
9#include "core/hid/hid_types.h"
10#include "core/hle/service/hid/ring_lifo.h"
11
12namespace Service::HID {
13static constexpr std::size_t NPAD_COUNT = 10;
14
15// This is nn::hid::NpadJoyHoldType
16enum class NpadJoyHoldType : u64 {
17 Vertical = 0,
18 Horizontal = 1,
19};
20
21// This is nn::hid::NpadJoyAssignmentMode
22enum class NpadJoyAssignmentMode : u32 {
23 Dual = 0,
24 Single = 1,
25};
26
27// This is nn::hid::NpadJoyDeviceType
28enum class NpadJoyDeviceType : s64 {
29 Left = 0,
30 Right = 1,
31};
32
33// This is nn::hid::NpadHandheldActivationMode
34enum class NpadHandheldActivationMode : u64 {
35 Dual = 0,
36 Single = 1,
37 None = 2,
38 MaxActivationMode = 3,
39};
40
41// This is nn::hid::system::AppletFooterUiAttributesSet
42struct AppletFooterUiAttributes {
43 INSERT_PADDING_BYTES(0x4);
44};
45
46// This is nn::hid::system::AppletFooterUiType
47enum class AppletFooterUiType : u8 {
48 None = 0,
49 HandheldNone = 1,
50 HandheldJoyConLeftOnly = 2,
51 HandheldJoyConRightOnly = 3,
52 HandheldJoyConLeftJoyConRight = 4,
53 JoyDual = 5,
54 JoyDualLeftOnly = 6,
55 JoyDualRightOnly = 7,
56 JoyLeftHorizontal = 8,
57 JoyLeftVertical = 9,
58 JoyRightHorizontal = 10,
59 JoyRightVertical = 11,
60 SwitchProController = 12,
61 CompatibleProController = 13,
62 CompatibleJoyCon = 14,
63 LarkHvc1 = 15,
64 LarkHvc2 = 16,
65 LarkNesLeft = 17,
66 LarkNesRight = 18,
67 Lucia = 19,
68 Verification = 20,
69 Lagon = 21,
70};
71
72using AppletFooterUiVariant = u8;
73
74// This is "nn::hid::system::AppletDetailedUiType".
75struct AppletDetailedUiType {
76 AppletFooterUiVariant ui_variant;
77 INSERT_PADDING_BYTES(0x2);
78 AppletFooterUiType footer;
79};
80static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size");
81// This is nn::hid::NpadCommunicationMode
82enum class NpadCommunicationMode : u64 {
83 Mode_5ms = 0,
84 Mode_10ms = 1,
85 Mode_15ms = 2,
86 Default = 3,
87};
88
89enum class NpadRevision : u32 {
90 Revision0 = 0,
91 Revision1 = 1,
92 Revision2 = 2,
93 Revision3 = 3,
94};
95
96// This is nn::hid::detail::ColorAttribute
97enum class ColorAttribute : u32 {
98 Ok = 0,
99 ReadError = 1,
100 NoController = 2,
101};
102static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
103
104// This is nn::hid::detail::NpadFullKeyColorState
105struct NpadFullKeyColorState {
106 ColorAttribute attribute{ColorAttribute::NoController};
107 Core::HID::NpadControllerColor fullkey{};
108};
109static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
110
111// This is nn::hid::detail::NpadJoyColorState
112struct NpadJoyColorState {
113 ColorAttribute attribute{ColorAttribute::NoController};
114 Core::HID::NpadControllerColor left{};
115 Core::HID::NpadControllerColor right{};
116};
117static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
118
119// This is nn::hid::NpadAttribute
120struct NpadAttribute {
121 union {
122 u32 raw{};
123 BitField<0, 1, u32> is_connected;
124 BitField<1, 1, u32> is_wired;
125 BitField<2, 1, u32> is_left_connected;
126 BitField<3, 1, u32> is_left_wired;
127 BitField<4, 1, u32> is_right_connected;
128 BitField<5, 1, u32> is_right_wired;
129 };
130};
131static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
132
133// This is nn::hid::NpadFullKeyState
134// This is nn::hid::NpadHandheldState
135// This is nn::hid::NpadJoyDualState
136// This is nn::hid::NpadJoyLeftState
137// This is nn::hid::NpadJoyRightState
138// This is nn::hid::NpadPalmaState
139// This is nn::hid::NpadSystemExtState
140struct NPadGenericState {
141 s64_le sampling_number{};
142 Core::HID::NpadButtonState npad_buttons{};
143 Core::HID::AnalogStickState l_stick{};
144 Core::HID::AnalogStickState r_stick{};
145 NpadAttribute connection_status{};
146 INSERT_PADDING_BYTES(4); // Reserved
147};
148static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
149
150// This is nn::hid::server::NpadGcTriggerState
151struct NpadGcTriggerState {
152 s64 sampling_number{};
153 s32 l_analog{};
154 s32 r_analog{};
155};
156static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
157
158// This is nn::hid::NpadSystemProperties
159struct NPadSystemProperties {
160 union {
161 s64 raw{};
162 BitField<0, 1, s64> is_charging_joy_dual;
163 BitField<1, 1, s64> is_charging_joy_left;
164 BitField<2, 1, s64> is_charging_joy_right;
165 BitField<3, 1, s64> is_powered_joy_dual;
166 BitField<4, 1, s64> is_powered_joy_left;
167 BitField<5, 1, s64> is_powered_joy_right;
168 BitField<9, 1, s64> is_system_unsupported_button;
169 BitField<10, 1, s64> is_system_ext_unsupported_button;
170 BitField<11, 1, s64> is_vertical;
171 BitField<12, 1, s64> is_horizontal;
172 BitField<13, 1, s64> use_plus;
173 BitField<14, 1, s64> use_minus;
174 BitField<15, 1, s64> use_directional_buttons;
175 };
176};
177static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
178
179// This is nn::hid::NpadSystemButtonProperties
180struct NpadSystemButtonProperties {
181 union {
182 s32 raw{};
183 BitField<0, 1, s32> is_home_button_protection_enabled;
184 };
185};
186static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size");
187
188// This is nn::hid::system::DeviceType
189struct DeviceType {
190 union {
191 u32 raw{};
192 BitField<0, 1, s32> fullkey;
193 BitField<1, 1, s32> debug_pad;
194 BitField<2, 1, s32> handheld_left;
195 BitField<3, 1, s32> handheld_right;
196 BitField<4, 1, s32> joycon_left;
197 BitField<5, 1, s32> joycon_right;
198 BitField<6, 1, s32> palma;
199 BitField<7, 1, s32> lark_hvc_left;
200 BitField<8, 1, s32> lark_hvc_right;
201 BitField<9, 1, s32> lark_nes_left;
202 BitField<10, 1, s32> lark_nes_right;
203 BitField<11, 1, s32> handheld_lark_hvc_left;
204 BitField<12, 1, s32> handheld_lark_hvc_right;
205 BitField<13, 1, s32> handheld_lark_nes_left;
206 BitField<14, 1, s32> handheld_lark_nes_right;
207 BitField<15, 1, s32> lucia;
208 BitField<16, 1, s32> lagon;
209 BitField<17, 1, s32> lager;
210 BitField<31, 1, s32> system;
211 };
212};
213
214// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl
215struct NfcXcdDeviceHandleStateImpl {
216 u64 handle{};
217 bool is_available{};
218 bool is_activated{};
219 INSERT_PADDING_BYTES(0x6); // Reserved
220 u64 sampling_number{};
221};
222static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18,
223 "NfcXcdDeviceHandleStateImpl is an invalid size");
224
225// This is nn::hid::NpadLarkType
226enum class NpadLarkType : u32 {
227 Invalid,
228 H1,
229 H2,
230 NL,
231 NR,
232};
233
234// This is nn::hid::NpadLuciaType
235enum class NpadLuciaType : u32 {
236 Invalid,
237 J,
238 E,
239 U,
240};
241
242// This is nn::hid::NpadLagonType
243enum class NpadLagonType : u32 {
244 Invalid,
245};
246
247// This is nn::hid::NpadLagerType
248enum class NpadLagerType : u32 {
249 Invalid,
250 J,
251 E,
252 U,
253};
254
255} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/core/hle/service/hid/controllers/types/touch_types.h
new file mode 100644
index 000000000..efeaa796d
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/types/touch_types.h
@@ -0,0 +1,90 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4#pragma once
5
6#include <array>
7
8#include <array>
9#include "common/bit_field.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h"
12#include "common/point.h"
13#include "core/hid/hid_types.h"
14
15namespace Service::HID {
16static constexpr std::size_t MAX_FINGERS = 16;
17static constexpr size_t MAX_POINTS = 4;
18
19// This is nn::hid::GestureType
20enum class GestureType : u32 {
21 Idle, // Nothing touching the screen
22 Complete, // Set at the end of a touch event
23 Cancel, // Set when the number of fingers change
24 Touch, // A finger just touched the screen
25 Press, // Set if last type is touch and the finger hasn't moved
26 Tap, // Fast press then release
27 Pan, // All points moving together across the screen
28 Swipe, // Fast press movement and release of a single point
29 Pinch, // All points moving away/closer to the midpoint
30 Rotate, // All points rotating from the midpoint
31};
32
33// This is nn::hid::GestureDirection
34enum class GestureDirection : u32 {
35 None,
36 Left,
37 Up,
38 Right,
39 Down,
40};
41
42// This is nn::hid::GestureAttribute
43struct GestureAttribute {
44 union {
45 u32 raw{};
46
47 BitField<4, 1, u32> is_new_touch;
48 BitField<8, 1, u32> is_double_tap;
49 };
50};
51static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size");
52
53// This is nn::hid::GestureState
54struct GestureState {
55 s64 sampling_number{};
56 s64 detection_count{};
57 GestureType type{GestureType::Idle};
58 GestureDirection direction{GestureDirection::None};
59 Common::Point<s32> pos{};
60 Common::Point<s32> delta{};
61 f32 vel_x{};
62 f32 vel_y{};
63 GestureAttribute attributes{};
64 f32 scale{};
65 f32 rotation_angle{};
66 s32 point_count{};
67 std::array<Common::Point<s32>, 4> points{};
68};
69static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size");
70
71struct GestureProperties {
72 std::array<Common::Point<s32>, MAX_POINTS> points{};
73 std::size_t active_points{};
74 Common::Point<s32> mid_point{};
75 s64 detection_count{};
76 u64 delta_time{};
77 f32 average_distance{};
78 f32 angle{};
79};
80
81// This is nn::hid::TouchScreenState
82struct TouchScreenState {
83 s64 sampling_number{};
84 s32 entry_count{};
85 INSERT_PADDING_BYTES(4); // Reserved
86 std::array<Core::HID::TouchState, MAX_FINGERS> states{};
87};
88static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
89
90} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
deleted file mode 100644
index 0aaed1fa7..000000000
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <cstring>
5#include "common/common_types.h"
6#include "core/core_timing.h"
7#include "core/hid/hid_core.h"
8#include "core/hle/service/hid/controllers/xpad.h"
9
10namespace Service::HID {
11constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
12
13XPad::XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_) : ControllerBase{hid_core_} {
14 static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size,
15 "XpadSharedMemory is bigger than the shared memory");
16 shared_memory = std::construct_at(
17 reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
18}
19XPad::~XPad() = default;
20
21void XPad::OnInit() {}
22
23void XPad::OnRelease() {}
24
25void XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
26 if (!IsControllerActivated()) {
27 shared_memory->basic_xpad_lifo.buffer_count = 0;
28 shared_memory->basic_xpad_lifo.buffer_tail = 0;
29 return;
30 }
31
32 const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state;
33 next_state.sampling_number = last_entry.sampling_number + 1;
34 // TODO(ogniK): Update xpad states
35
36 shared_memory->basic_xpad_lifo.WriteNextEntry(next_state);
37}
38
39} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
deleted file mode 100644
index 9e63a317a..000000000
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ /dev/null
@@ -1,112 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/bit_field.h"
7#include "common/common_types.h"
8#include "core/hid/hid_types.h"
9#include "core/hle/service/hid/controllers/controller_base.h"
10#include "core/hle/service/hid/ring_lifo.h"
11
12namespace Service::HID {
13class XPad final : public ControllerBase {
14public:
15 explicit XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
16 ~XPad() override;
17
18 // Called when the controller is initialized
19 void OnInit() override;
20
21 // When the controller is released
22 void OnRelease() override;
23
24 // When the controller is requesting an update for the shared memory
25 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
26
27private:
28 // This is nn::hid::BasicXpadAttributeSet
29 struct BasicXpadAttributeSet {
30 union {
31 u32 raw{};
32 BitField<0, 1, u32> is_connected;
33 BitField<1, 1, u32> is_wired;
34 BitField<2, 1, u32> is_left_connected;
35 BitField<3, 1, u32> is_left_wired;
36 BitField<4, 1, u32> is_right_connected;
37 BitField<5, 1, u32> is_right_wired;
38 };
39 };
40 static_assert(sizeof(BasicXpadAttributeSet) == 4, "BasicXpadAttributeSet is an invalid size");
41
42 // This is nn::hid::BasicXpadButtonSet
43 struct BasicXpadButtonSet {
44 union {
45 u32 raw{};
46 // Button states
47 BitField<0, 1, u32> a;
48 BitField<1, 1, u32> b;
49 BitField<2, 1, u32> x;
50 BitField<3, 1, u32> y;
51 BitField<4, 1, u32> l_stick;
52 BitField<5, 1, u32> r_stick;
53 BitField<6, 1, u32> l;
54 BitField<7, 1, u32> r;
55 BitField<8, 1, u32> zl;
56 BitField<9, 1, u32> zr;
57 BitField<10, 1, u32> plus;
58 BitField<11, 1, u32> minus;
59
60 // D-Pad
61 BitField<12, 1, u32> d_left;
62 BitField<13, 1, u32> d_up;
63 BitField<14, 1, u32> d_right;
64 BitField<15, 1, u32> d_down;
65
66 // Left JoyStick
67 BitField<16, 1, u32> l_stick_left;
68 BitField<17, 1, u32> l_stick_up;
69 BitField<18, 1, u32> l_stick_right;
70 BitField<19, 1, u32> l_stick_down;
71
72 // Right JoyStick
73 BitField<20, 1, u32> r_stick_left;
74 BitField<21, 1, u32> r_stick_up;
75 BitField<22, 1, u32> r_stick_right;
76 BitField<23, 1, u32> r_stick_down;
77
78 // Not always active?
79 BitField<24, 1, u32> left_sl;
80 BitField<25, 1, u32> left_sr;
81
82 BitField<26, 1, u32> right_sl;
83 BitField<27, 1, u32> right_sr;
84
85 BitField<28, 1, u32> palma;
86 BitField<30, 1, u32> handheld_left_b;
87 };
88 };
89 static_assert(sizeof(BasicXpadButtonSet) == 4, "BasicXpadButtonSet is an invalid size");
90
91 // This is nn::hid::detail::BasicXpadState
92 struct BasicXpadState {
93 s64 sampling_number{};
94 BasicXpadAttributeSet attributes{};
95 BasicXpadButtonSet pad_states{};
96 Core::HID::AnalogStickState l_stick{};
97 Core::HID::AnalogStickState r_stick{};
98 };
99 static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size");
100
101 struct XpadSharedMemory {
102 // This is nn::hid::detail::BasicXpadLifo
103 Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{};
104 static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size");
105 INSERT_PADDING_WORDS(0x4E);
106 };
107 static_assert(sizeof(XpadSharedMemory) == 0x400, "XpadSharedMemory is an invalid size");
108
109 BasicXpadState next_state{};
110 XpadSharedMemory* shared_memory = nullptr;
111};
112} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp
index b06ea467e..de24b0401 100644
--- a/src/core/hle/service/hid/hid_server.cpp
+++ b/src/core/hle/service/hid/hid_server.cpp
@@ -28,6 +28,7 @@
28#include "core/hle/service/hid/controllers/seven_six_axis.h" 28#include "core/hle/service/hid/controllers/seven_six_axis.h"
29#include "core/hle/service/hid/controllers/six_axis.h" 29#include "core/hle/service/hid/controllers/six_axis.h"
30#include "core/hle/service/hid/controllers/touchscreen.h" 30#include "core/hle/service/hid/controllers/touchscreen.h"
31#include "core/hle/service/hid/controllers/types/npad_types.h"
31 32
32namespace Service::HID { 33namespace Service::HID {
33 34
@@ -1099,7 +1100,7 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
1099void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) { 1100void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1100 IPC::RequestParser rp{ctx}; 1101 IPC::RequestParser rp{ctx};
1101 struct Parameters { 1102 struct Parameters {
1102 NPad::NpadRevision revision; 1103 NpadRevision revision;
1103 INSERT_PADDING_WORDS_NOINIT(1); 1104 INSERT_PADDING_WORDS_NOINIT(1);
1104 u64 applet_resource_user_id; 1105 u64 applet_resource_user_id;
1105 }; 1106 };
@@ -1122,7 +1123,7 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
1122void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) { 1123void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
1123 IPC::RequestParser rp{ctx}; 1124 IPC::RequestParser rp{ctx};
1124 const auto applet_resource_user_id{rp.Pop<u64>()}; 1125 const auto applet_resource_user_id{rp.Pop<u64>()};
1125 const auto hold_type{rp.PopEnum<NPad::NpadJoyHoldType>()}; 1126 const auto hold_type{rp.PopEnum<NpadJoyHoldType>()};
1126 1127
1127 GetResourceManager()->GetNpad()->SetHoldType(hold_type); 1128 GetResourceManager()->GetNpad()->SetHoldType(hold_type);
1128 1129
@@ -1157,8 +1158,8 @@ void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx)
1157 1158
1158 Core::HID::NpadIdType new_npad_id{}; 1159 Core::HID::NpadIdType new_npad_id{};
1159 auto controller = GetResourceManager()->GetNpad(); 1160 auto controller = GetResourceManager()->GetNpad();
1160 controller->SetNpadMode(new_npad_id, parameters.npad_id, NPad::NpadJoyDeviceType::Left, 1161 controller->SetNpadMode(new_npad_id, parameters.npad_id, NpadJoyDeviceType::Left,
1161 NPad::NpadJoyAssignmentMode::Single); 1162 NpadJoyAssignmentMode::Single);
1162 1163
1163 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1164 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1164 parameters.applet_resource_user_id); 1165 parameters.applet_resource_user_id);
@@ -1173,7 +1174,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1173 Core::HID::NpadIdType npad_id; 1174 Core::HID::NpadIdType npad_id;
1174 INSERT_PADDING_WORDS_NOINIT(1); 1175 INSERT_PADDING_WORDS_NOINIT(1);
1175 u64 applet_resource_user_id; 1176 u64 applet_resource_user_id;
1176 NPad::NpadJoyDeviceType npad_joy_device_type; 1177 NpadJoyDeviceType npad_joy_device_type;
1177 }; 1178 };
1178 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); 1179 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1179 1180
@@ -1182,7 +1183,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
1182 Core::HID::NpadIdType new_npad_id{}; 1183 Core::HID::NpadIdType new_npad_id{};
1183 auto controller = GetResourceManager()->GetNpad(); 1184 auto controller = GetResourceManager()->GetNpad();
1184 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1185 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1185 NPad::NpadJoyAssignmentMode::Single); 1186 NpadJoyAssignmentMode::Single);
1186 1187
1187 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1188 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1188 parameters.npad_id, parameters.applet_resource_user_id, 1189 parameters.npad_id, parameters.applet_resource_user_id,
@@ -1205,7 +1206,7 @@ void IHidServer::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
1205 1206
1206 Core::HID::NpadIdType new_npad_id{}; 1207 Core::HID::NpadIdType new_npad_id{};
1207 auto controller = GetResourceManager()->GetNpad(); 1208 auto controller = GetResourceManager()->GetNpad();
1208 controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NPad::NpadJoyAssignmentMode::Dual); 1209 controller->SetNpadMode(new_npad_id, parameters.npad_id, {}, NpadJoyAssignmentMode::Dual);
1209 1210
1210 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, 1211 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
1211 parameters.applet_resource_user_id); // Spams a lot when controller applet is open 1212 parameters.applet_resource_user_id); // Spams a lot when controller applet is open
@@ -1257,7 +1258,7 @@ void IHidServer::StopLrAssignmentMode(HLERequestContext& ctx) {
1257void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) { 1258void IHidServer::SetNpadHandheldActivationMode(HLERequestContext& ctx) {
1258 IPC::RequestParser rp{ctx}; 1259 IPC::RequestParser rp{ctx};
1259 const auto applet_resource_user_id{rp.Pop<u64>()}; 1260 const auto applet_resource_user_id{rp.Pop<u64>()};
1260 const auto activation_mode{rp.PopEnum<NPad::NpadHandheldActivationMode>()}; 1261 const auto activation_mode{rp.PopEnum<NpadHandheldActivationMode>()};
1261 1262
1262 GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode); 1263 GetResourceManager()->GetNpad()->SetNpadHandheldActivationMode(activation_mode);
1263 1264
@@ -1349,7 +1350,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
1349 Core::HID::NpadIdType npad_id; 1350 Core::HID::NpadIdType npad_id;
1350 INSERT_PADDING_WORDS_NOINIT(1); 1351 INSERT_PADDING_WORDS_NOINIT(1);
1351 u64 applet_resource_user_id; 1352 u64 applet_resource_user_id;
1352 NPad::NpadJoyDeviceType npad_joy_device_type; 1353 NpadJoyDeviceType npad_joy_device_type;
1353 }; 1354 };
1354 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); 1355 static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
1355 1356
@@ -1359,7 +1360,7 @@ void IHidServer::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext
1359 auto controller = GetResourceManager()->GetNpad(); 1360 auto controller = GetResourceManager()->GetNpad();
1360 const auto is_reassigned = 1361 const auto is_reassigned =
1361 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type, 1362 controller->SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
1362 NPad::NpadJoyAssignmentMode::Single); 1363 NpadJoyAssignmentMode::Single);
1363 1364
1364 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", 1365 LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
1365 parameters.npad_id, parameters.applet_resource_user_id, 1366 parameters.npad_id, parameters.applet_resource_user_id,
@@ -2315,7 +2316,7 @@ void IHidServer::SetDisallowedPalmaConnection(HLERequestContext& ctx) {
2315void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) { 2316void IHidServer::SetNpadCommunicationMode(HLERequestContext& ctx) {
2316 IPC::RequestParser rp{ctx}; 2317 IPC::RequestParser rp{ctx};
2317 const auto applet_resource_user_id{rp.Pop<u64>()}; 2318 const auto applet_resource_user_id{rp.Pop<u64>()};
2318 const auto communication_mode{rp.PopEnum<NPad::NpadCommunicationMode>()}; 2319 const auto communication_mode{rp.PopEnum<NpadCommunicationMode>()};
2319 2320
2320 GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode); 2321 GetResourceManager()->GetNpad()->SetNpadCommunicationMode(communication_mode);
2321 2322
diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp
index 4d33456a3..5cc88c4a1 100644
--- a/src/core/hle/service/hid/hid_system_server.cpp
+++ b/src/core/hle/service/hid/hid_system_server.cpp
@@ -5,6 +5,7 @@
5#include "core/hle/service/hid/controllers/npad.h" 5#include "core/hle/service/hid/controllers/npad.h"
6#include "core/hle/service/hid/controllers/palma.h" 6#include "core/hle/service/hid/controllers/palma.h"
7#include "core/hle/service/hid/controllers/touchscreen.h" 7#include "core/hle/service/hid/controllers/touchscreen.h"
8#include "core/hle/service/hid/controllers/types/npad_types.h"
8#include "core/hle/service/hid/errors.h" 9#include "core/hle/service/hid/errors.h"
9#include "core/hle/service/hid/hid_system_server.h" 10#include "core/hle/service/hid/hid_system_server.h"
10#include "core/hle/service/hid/resource_manager.h" 11#include "core/hle/service/hid/resource_manager.h"
@@ -328,7 +329,7 @@ void IHidSystemServer::GetAppletDetailedUiType(HLERequestContext& ctx) {
328 LOG_DEBUG(Service_HID, "called, npad_id_type={}", 329 LOG_DEBUG(Service_HID, "called, npad_id_type={}",
329 npad_id_type); // Spams a lot when controller applet is running 330 npad_id_type); // Spams a lot when controller applet is running
330 331
331 const NPad::AppletDetailedUiType detailed_ui_type = 332 const AppletDetailedUiType detailed_ui_type =
332 GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type); 333 GetResourceManager()->GetNpad()->GetAppletDetailedUiType(npad_id_type);
333 334
334 IPC::ResponseBuilder rb{ctx, 3}; 335 IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
index 89cdc19cc..0cfe30fde 100644
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -18,10 +18,10 @@
18#include "core/hle/service/hid/controllers/npad.h" 18#include "core/hle/service/hid/controllers/npad.h"
19#include "core/hle/service/hid/controllers/palma.h" 19#include "core/hle/service/hid/controllers/palma.h"
20#include "core/hle/service/hid/controllers/seven_six_axis.h" 20#include "core/hle/service/hid/controllers/seven_six_axis.h"
21#include "core/hle/service/hid/controllers/shared_memory_format.h"
21#include "core/hle/service/hid/controllers/six_axis.h" 22#include "core/hle/service/hid/controllers/six_axis.h"
22#include "core/hle/service/hid/controllers/stubbed.h" 23#include "core/hle/service/hid/controllers/stubbed.h"
23#include "core/hle/service/hid/controllers/touchscreen.h" 24#include "core/hle/service/hid/controllers/touchscreen.h"
24#include "core/hle/service/hid/controllers/xpad.h"
25 25
26namespace Service::HID { 26namespace Service::HID {
27 27
@@ -45,40 +45,43 @@ void ResourceManager::Initialize() {
45 return; 45 return;
46 } 46 }
47 47
48 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer(); 48 system.HIDCore().ReloadInputDevices();
49 debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory); 49 is_initialized = true;
50 mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory); 50}
51 debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory); 51
52 keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory); 52void ResourceManager::InitializeController(u64 aruid) {
53 unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory); 53 SharedMemoryFormat* shared_memory = nullptr;
54 npad = std::make_shared<NPad>(system.HIDCore(), shared_memory, service_context); 54 const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid);
55 gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory); 55 if (result.IsError()) {
56 touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory); 56 return;
57 xpad = std::make_shared<XPad>(system.HIDCore(), shared_memory); 57 }
58
59 debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad);
60 mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse);
61 debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse);
62 keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard);
63 unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header);
64 npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context);
65 gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture);
66 touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen);
58 67
59 palma = std::make_shared<Palma>(system.HIDCore(), shared_memory, service_context); 68 palma = std::make_shared<Palma>(system.HIDCore(), service_context);
60 69
61 home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory); 70 home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header);
62 sleep_button = std::make_shared<SleepButton>(system.HIDCore(), shared_memory); 71 sleep_button =
63 capture_button = std::make_shared<CaptureButton>(system.HIDCore(), shared_memory); 72 std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header);
73 capture_button =
74 std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header);
75 digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header);
64 76
65 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); 77 six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
66 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory); 78 console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console);
67 seven_six_axis = std::make_shared<SevenSixAxis>(system); 79 seven_six_axis = std::make_shared<SevenSixAxis>(system);
68 80
69 home_button->SetCommonHeaderOffset(0x4C00);
70 sleep_button->SetCommonHeaderOffset(0x4E00);
71 capture_button->SetCommonHeaderOffset(0x5000);
72 unique_pad->SetCommonHeaderOffset(0x5A00);
73 debug_mouse->SetCommonHeaderOffset(0x3DC00);
74
75 // Homebrew doesn't try to activate some controllers, so we activate them by default 81 // Homebrew doesn't try to activate some controllers, so we activate them by default
76 npad->Activate(); 82 npad->Activate();
77 six_axis->Activate(); 83 six_axis->Activate();
78 touch_screen->Activate(); 84 touch_screen->Activate();
79
80 system.HIDCore().ReloadInputDevices();
81 is_initialized = true;
82} 85}
83 86
84std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { 87std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
@@ -101,6 +104,10 @@ std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const {
101 return debug_pad; 104 return debug_pad;
102} 105}
103 106
107std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const {
108 return digitizer;
109}
110
104std::shared_ptr<Gesture> ResourceManager::GetGesture() const { 111std::shared_ptr<Gesture> ResourceManager::GetGesture() const {
105 return gesture; 112 return gesture;
106} 113}
@@ -163,7 +170,11 @@ Result ResourceManager::CreateAppletResource(u64 aruid) {
163 170
164Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { 171Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
165 std::scoped_lock lock{shared_mutex}; 172 std::scoped_lock lock{shared_mutex};
166 return applet_resource->CreateAppletResource(aruid); 173 const auto result = applet_resource->CreateAppletResource(aruid);
174 if (result.IsSuccess()) {
175 InitializeController(aruid);
176 }
177 return result;
167} 178}
168 179
169Result ResourceManager::RegisterCoreAppletResource() { 180Result ResourceManager::RegisterCoreAppletResource() {
@@ -227,7 +238,6 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data,
227 home_button->OnUpdate(core_timing); 238 home_button->OnUpdate(core_timing);
228 sleep_button->OnUpdate(core_timing); 239 sleep_button->OnUpdate(core_timing);
229 capture_button->OnUpdate(core_timing); 240 capture_button->OnUpdate(core_timing);
230 xpad->OnUpdate(core_timing);
231} 241}
232 242
233void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 243void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
index 15c1beb1a..5ad7cb564 100644
--- a/src/core/hle/service/hid/resource_manager.h
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -31,10 +31,10 @@ class Palma;
31class SevenSixAxis; 31class SevenSixAxis;
32class SixAxis; 32class SixAxis;
33class TouchScreen; 33class TouchScreen;
34class XPad;
35 34
36using CaptureButton = Controller_Stubbed; 35using CaptureButton = Controller_Stubbed;
37using DebugMouse = Controller_Stubbed; 36using DebugMouse = Mouse;
37using Digitizer = Controller_Stubbed;
38using HomeButton = Controller_Stubbed; 38using HomeButton = Controller_Stubbed;
39using SleepButton = Controller_Stubbed; 39using SleepButton = Controller_Stubbed;
40using UniquePad = Controller_Stubbed; 40using UniquePad = Controller_Stubbed;
@@ -46,12 +46,14 @@ public:
46 ~ResourceManager(); 46 ~ResourceManager();
47 47
48 void Initialize(); 48 void Initialize();
49 void InitializeController(u64 aruid);
49 50
50 std::shared_ptr<AppletResource> GetAppletResource() const; 51 std::shared_ptr<AppletResource> GetAppletResource() const;
51 std::shared_ptr<CaptureButton> GetCaptureButton() const; 52 std::shared_ptr<CaptureButton> GetCaptureButton() const;
52 std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; 53 std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
53 std::shared_ptr<DebugMouse> GetDebugMouse() const; 54 std::shared_ptr<DebugMouse> GetDebugMouse() const;
54 std::shared_ptr<DebugPad> GetDebugPad() const; 55 std::shared_ptr<DebugPad> GetDebugPad() const;
56 std::shared_ptr<Digitizer> GetDigitizer() const;
55 std::shared_ptr<Gesture> GetGesture() const; 57 std::shared_ptr<Gesture> GetGesture() const;
56 std::shared_ptr<HomeButton> GetHomeButton() const; 58 std::shared_ptr<HomeButton> GetHomeButton() const;
57 std::shared_ptr<Keyboard> GetKeyboard() const; 59 std::shared_ptr<Keyboard> GetKeyboard() const;
@@ -96,6 +98,7 @@ private:
96 std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; 98 std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
97 std::shared_ptr<DebugMouse> debug_mouse = nullptr; 99 std::shared_ptr<DebugMouse> debug_mouse = nullptr;
98 std::shared_ptr<DebugPad> debug_pad = nullptr; 100 std::shared_ptr<DebugPad> debug_pad = nullptr;
101 std::shared_ptr<Digitizer> digitizer = nullptr;
99 std::shared_ptr<Gesture> gesture = nullptr; 102 std::shared_ptr<Gesture> gesture = nullptr;
100 std::shared_ptr<HomeButton> home_button = nullptr; 103 std::shared_ptr<HomeButton> home_button = nullptr;
101 std::shared_ptr<Keyboard> keyboard = nullptr; 104 std::shared_ptr<Keyboard> keyboard = nullptr;
@@ -107,7 +110,6 @@ private:
107 std::shared_ptr<SleepButton> sleep_button = nullptr; 110 std::shared_ptr<SleepButton> sleep_button = nullptr;
108 std::shared_ptr<TouchScreen> touch_screen = nullptr; 111 std::shared_ptr<TouchScreen> touch_screen = nullptr;
109 std::shared_ptr<UniquePad> unique_pad = nullptr; 112 std::shared_ptr<UniquePad> unique_pad = nullptr;
110 std::shared_ptr<XPad> xpad = nullptr;
111 113
112 // TODO: Create these resources 114 // TODO: Create these resources
113 // std::shared_ptr<AudioControl> audio_control = nullptr; 115 // std::shared_ptr<AudioControl> audio_control = nullptr;