summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp20
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.h7
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h7
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h18
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp32
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h17
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h17
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp19
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h19
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp290
-rw-r--r--src/core/hle/service/hid/controllers/npad.h27
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.h5
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp21
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h18
-rw-r--r--src/core/hle/service/hid/controllers/xpad.cpp20
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h16
-rw-r--r--src/core/hle/service/hid/hid.cpp41
-rw-r--r--src/core/hle/service/hid/hid.h9
21 files changed, 347 insertions, 305 deletions
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index f5a0b94dd..c93bcd678 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -9,9 +9,14 @@
9namespace Service::HID { 9namespace Service::HID {
10constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; 10constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200;
11 11
12Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_) 12Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
13 u8* raw_shared_memory_)
13 : ControllerBase{hid_core_} { 14 : ControllerBase{hid_core_} {
14 console = hid_core.GetEmulatedConsole(); 15 console = hid_core.GetEmulatedConsole();
16 static_assert(SHARED_MEMORY_OFFSET + sizeof(ConsoleSharedMemory) < shared_memory_size,
17 "ConsoleSharedMemory is bigger than the shared memory");
18 shared_memory =
19 std::construct_at(reinterpret_cast<ConsoleSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
15} 20}
16 21
17Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; 22Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default;
@@ -20,8 +25,7 @@ void Controller_ConsoleSixAxis::OnInit() {}
20 25
21void Controller_ConsoleSixAxis::OnRelease() {} 26void Controller_ConsoleSixAxis::OnRelease() {}
22 27
23void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 28void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
24 std::size_t size) {
25 if (!IsControllerActivated() || !is_transfer_memory_set) { 29 if (!IsControllerActivated() || !is_transfer_memory_set) {
26 seven_sixaxis_lifo.buffer_count = 0; 30 seven_sixaxis_lifo.buffer_count = 0;
27 seven_sixaxis_lifo.buffer_tail = 0; 31 seven_sixaxis_lifo.buffer_tail = 0;
@@ -48,13 +52,11 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
48 -motion_status.quaternion.xyz.z, 52 -motion_status.quaternion.xyz.z,
49 }; 53 };
50 54
51 console_six_axis.sampling_number++; 55 shared_memory->sampling_number++;
52 console_six_axis.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; 56 shared_memory->is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest;
53 console_six_axis.verticalization_error = motion_status.verticalization_error; 57 shared_memory->verticalization_error = motion_status.verticalization_error;
54 console_six_axis.gyro_bias = motion_status.gyro_bias; 58 shared_memory->gyro_bias = motion_status.gyro_bias;
55 59
56 // Update console six axis shared memory
57 std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis));
58 // Update seven six axis transfer memory 60 // Update seven six axis transfer memory
59 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); 61 seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
60 std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo)); 62 std::memcpy(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 6da5e9454..85b281957 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -17,7 +17,7 @@ class EmulatedConsole;
17namespace Service::HID { 17namespace Service::HID {
18class Controller_ConsoleSixAxis final : public ControllerBase { 18class Controller_ConsoleSixAxis final : public ControllerBase {
19public: 19public:
20 explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_); 20 explicit Controller_ConsoleSixAxis(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
21 ~Controller_ConsoleSixAxis() override; 21 ~Controller_ConsoleSixAxis() override;
22 22
23 // Called when the controller is initialized 23 // Called when the controller is initialized
@@ -27,7 +27,7 @@ public:
27 void OnRelease() override; 27 void OnRelease() override;
28 28
29 // When the controller is requesting an update for the shared memory 29 // When the controller is requesting an update for the shared memory
30 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override; 30 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
31 31
32 // Called on InitializeSevenSixAxisSensor 32 // Called on InitializeSevenSixAxisSensor
33 void SetTransferMemoryPointer(u8* t_mem); 33 void SetTransferMemoryPointer(u8* t_mem);
@@ -61,12 +61,13 @@ private:
61 Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; 61 Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{};
62 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); 62 static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
63 63
64 ConsoleSharedMemory* shared_memory;
65
64 Core::HID::EmulatedConsole* console; 66 Core::HID::EmulatedConsole* console;
65 u8* transfer_memory = nullptr; 67 u8* transfer_memory = nullptr;
66 bool is_transfer_memory_set = false; 68 bool is_transfer_memory_set = false;
67 u64 last_saved_timestamp{}; 69 u64 last_saved_timestamp{};
68 u64 last_global_timestamp{}; 70 u64 last_global_timestamp{};
69 ConsoleSharedMemory console_six_axis{};
70 SevenSixAxisState next_seven_sixaxis_state{}; 71 SevenSixAxisState next_seven_sixaxis_state{};
71}; 72};
72} // namespace Service::HID 73} // 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 bb01ea643..d6f7a5073 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -26,12 +26,10 @@ public:
26 virtual void OnRelease() = 0; 26 virtual void OnRelease() = 0;
27 27
28 // When the controller is requesting an update for the shared memory 28 // When the controller is requesting an update for the shared memory
29 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 29 virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0;
30 std::size_t size) = 0;
31 30
32 // When the controller is requesting a motion update for the shared memory 31 // When the controller is requesting a motion update for the shared memory
33 virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 32 virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
34 std::size_t size) {}
35 33
36 void ActivateController(); 34 void ActivateController();
37 35
@@ -40,6 +38,7 @@ public:
40 bool IsControllerActivated() const; 38 bool IsControllerActivated() const;
41 39
42 static const std::size_t hid_entry_count = 17; 40 static const std::size_t hid_entry_count = 17;
41 static const std::size_t shared_memory_size = 0x40000;
43 42
44protected: 43protected:
45 bool is_activated{false}; 44 bool is_activated{false};
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index 73309d64e..8ec9f4a95 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -13,8 +13,12 @@
13namespace Service::HID { 13namespace Service::HID {
14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000; 14constexpr std::size_t SHARED_MEMORY_OFFSET = 0x00000;
15 15
16Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_) 16Controller_DebugPad::Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
17 : ControllerBase{hid_core_} { 17 : ControllerBase{hid_core_} {
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));
18 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); 22 controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
19} 23}
20 24
@@ -24,16 +28,14 @@ void Controller_DebugPad::OnInit() {}
24 28
25void Controller_DebugPad::OnRelease() {} 29void Controller_DebugPad::OnRelease() {}
26 30
27void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 31void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
28 std::size_t size) {
29 if (!IsControllerActivated()) { 32 if (!IsControllerActivated()) {
30 debug_pad_lifo.buffer_count = 0; 33 shared_memory->debug_pad_lifo.buffer_count = 0;
31 debug_pad_lifo.buffer_tail = 0; 34 shared_memory->debug_pad_lifo.buffer_tail = 0;
32 std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
33 return; 35 return;
34 } 36 }
35 37
36 const auto& last_entry = debug_pad_lifo.ReadCurrentEntry().state; 38 const auto& last_entry = shared_memory->debug_pad_lifo.ReadCurrentEntry().state;
37 next_state.sampling_number = last_entry.sampling_number + 1; 39 next_state.sampling_number = last_entry.sampling_number + 1;
38 40
39 if (Settings::values.debug_pad_enabled) { 41 if (Settings::values.debug_pad_enabled) {
@@ -47,8 +49,7 @@ void Controller_DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing,
47 next_state.r_stick = stick_state.right; 49 next_state.r_stick = stick_state.right;
48 } 50 }
49 51
50 debug_pad_lifo.WriteNextEntry(next_state); 52 shared_memory->debug_pad_lifo.WriteNextEntry(next_state);
51 std::memcpy(data + SHARED_MEMORY_OFFSET, &debug_pad_lifo, sizeof(debug_pad_lifo));
52} 53}
53 54
54} // namespace Service::HID 55} // 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 388d25b3c..543e9f3a6 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -17,7 +17,7 @@ struct AnalogStickState;
17namespace Service::HID { 17namespace Service::HID {
18class Controller_DebugPad final : public ControllerBase { 18class Controller_DebugPad final : public ControllerBase {
19public: 19public:
20 explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_); 20 explicit Controller_DebugPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
21 ~Controller_DebugPad() override; 21 ~Controller_DebugPad() override;
22 22
23 // Called when the controller is initialized 23 // Called when the controller is initialized
@@ -27,7 +27,7 @@ public:
27 void OnRelease() override; 27 void OnRelease() override;
28 28
29 // When the controller is requesting an update for the shared memory 29 // When the controller is requesting an update for the shared memory
30 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 30 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
31 31
32private: 32private:
33 // This is nn::hid::DebugPadAttribute 33 // This is nn::hid::DebugPadAttribute
@@ -49,11 +49,17 @@ private:
49 }; 49 };
50 static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); 50 static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state");
51 51
52 // This is nn::hid::detail::DebugPadLifo 52 struct DebugPadSharedMemory {
53 Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{}; 53 // This is nn::hid::detail::DebugPadLifo
54 static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); 54 Lifo<DebugPadState, hid_entry_count> debug_pad_lifo{};
55 DebugPadState next_state{}; 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");
56 59
60 DebugPadSharedMemory* shared_memory;
61
62 DebugPadState next_state{};
57 Core::HID::EmulatedController* controller; 63 Core::HID::EmulatedController* controller;
58}; 64};
59} // namespace Service::HID 65} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index c8dd131dd..e03d47ef3 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -23,25 +23,28 @@ constexpr f32 Square(s32 num) {
23 return static_cast<f32>(num * num); 23 return static_cast<f32>(num * num);
24} 24}
25 25
26Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) { 26Controller_Gesture::Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
27 : ControllerBase(hid_core_) {
28 static_assert(SHARED_MEMORY_OFFSET + sizeof(GestureSharedMemory) < shared_memory_size,
29 "GestureSharedMemory is bigger than the shared memory");
30 shared_memory =
31 std::construct_at(reinterpret_cast<GestureSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
27 console = hid_core.GetEmulatedConsole(); 32 console = hid_core.GetEmulatedConsole();
28} 33}
29Controller_Gesture::~Controller_Gesture() = default; 34Controller_Gesture::~Controller_Gesture() = default;
30 35
31void Controller_Gesture::OnInit() { 36void Controller_Gesture::OnInit() {
32 gesture_lifo.buffer_count = 0; 37 shared_memory->gesture_lifo.buffer_count = 0;
33 gesture_lifo.buffer_tail = 0; 38 shared_memory->gesture_lifo.buffer_tail = 0;
34 force_update = true; 39 force_update = true;
35} 40}
36 41
37void Controller_Gesture::OnRelease() {} 42void Controller_Gesture::OnRelease() {}
38 43
39void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 44void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
40 std::size_t size) {
41 if (!IsControllerActivated()) { 45 if (!IsControllerActivated()) {
42 gesture_lifo.buffer_count = 0; 46 shared_memory->gesture_lifo.buffer_count = 0;
43 gesture_lifo.buffer_tail = 0; 47 shared_memory->gesture_lifo.buffer_tail = 0;
44 std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
45 return; 48 return;
46 } 49 }
47 50
@@ -49,15 +52,15 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
49 52
50 GestureProperties gesture = GetGestureProperties(); 53 GestureProperties gesture = GetGestureProperties();
51 f32 time_difference = 54 f32 time_difference =
52 static_cast<f32>(gesture_lifo.timestamp - last_update_timestamp) / (1000 * 1000 * 1000); 55 static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) /
56 (1000 * 1000 * 1000);
53 57
54 // Only update if necesary 58 // Only update if necesary
55 if (!ShouldUpdateGesture(gesture, time_difference)) { 59 if (!ShouldUpdateGesture(gesture, time_difference)) {
56 return; 60 return;
57 } 61 }
58 62
59 last_update_timestamp = gesture_lifo.timestamp; 63 last_update_timestamp = shared_memory->gesture_lifo.timestamp;
60 UpdateGestureSharedMemory(data, size, gesture, time_difference);
61} 64}
62 65
63void Controller_Gesture::ReadTouchInput() { 66void Controller_Gesture::ReadTouchInput() {
@@ -97,7 +100,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
97 GestureType type = GestureType::Idle; 100 GestureType type = GestureType::Idle;
98 GestureAttribute attributes{}; 101 GestureAttribute attributes{};
99 102
100 const auto& last_entry = gesture_lifo.ReadCurrentEntry().state; 103 const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state;
101 104
102 // Reset next state to default 105 // Reset next state to default
103 next_state.sampling_number = last_entry.sampling_number + 1; 106 next_state.sampling_number = last_entry.sampling_number + 1;
@@ -127,8 +130,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
127 next_state.points = gesture.points; 130 next_state.points = gesture.points;
128 last_gesture = gesture; 131 last_gesture = gesture;
129 132
130 gesture_lifo.WriteNextEntry(next_state); 133 shared_memory->gesture_lifo.WriteNextEntry(next_state);
131 std::memcpy(data + SHARED_MEMORY_OFFSET, &gesture_lifo, sizeof(gesture_lifo));
132} 134}
133 135
134void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type, 136void Controller_Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
@@ -305,7 +307,7 @@ void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
305} 307}
306 308
307const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { 309const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const {
308 return gesture_lifo.ReadCurrentEntry().state; 310 return shared_memory->gesture_lifo.ReadCurrentEntry().state;
309} 311}
310 312
311Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() { 313Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() {
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 7a9d28dc6..c8edb35e1 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -14,7 +14,7 @@
14namespace Service::HID { 14namespace Service::HID {
15class Controller_Gesture final : public ControllerBase { 15class Controller_Gesture final : public ControllerBase {
16public: 16public:
17 explicit Controller_Gesture(Core::HID::HIDCore& hid_core_); 17 explicit Controller_Gesture(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
18 ~Controller_Gesture() override; 18 ~Controller_Gesture() override;
19 19
20 // Called when the controller is initialized 20 // Called when the controller is initialized
@@ -24,7 +24,7 @@ public:
24 void OnRelease() override; 24 void OnRelease() override;
25 25
26 // When the controller is requesting an update for the shared memory 26 // When the controller is requesting an update for the shared memory
27 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, size_t size) override; 27 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
28 28
29private: 29private:
30 static constexpr size_t MAX_FINGERS = 16; 30 static constexpr size_t MAX_FINGERS = 16;
@@ -92,6 +92,14 @@ private:
92 f32 angle{}; 92 f32 angle{};
93 }; 93 };
94 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
95 // Reads input from all available input engines 103 // Reads input from all available input engines
96 void ReadTouchInput(); 104 void ReadTouchInput();
97 105
@@ -134,11 +142,8 @@ private:
134 // Returns the average distance, angle and middle point of the active fingers 142 // Returns the average distance, angle and middle point of the active fingers
135 GestureProperties GetGestureProperties(); 143 GestureProperties GetGestureProperties();
136 144
137 // This is nn::hid::detail::GestureLifo 145 GestureSharedMemory* shared_memory;
138 Lifo<GestureState, hid_entry_count> gesture_lifo{};
139 static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size");
140 GestureState next_state{}; 146 GestureState next_state{};
141
142 Core::HID::EmulatedConsole* console; 147 Core::HID::EmulatedConsole* console;
143 148
144 std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; 149 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 8dc67757b..534a3ff18 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -12,8 +12,12 @@
12namespace Service::HID { 12namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800; 13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3800;
14 14
15Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_) 15Controller_Keyboard::Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
16 : ControllerBase{hid_core_} { 16 : ControllerBase{hid_core_} {
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(KeyboardSharedMemory) < shared_memory_size,
18 "KeyboardSharedMemory is bigger than the shared memory");
19 shared_memory =
20 std::construct_at(reinterpret_cast<KeyboardSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
17 emulated_devices = hid_core.GetEmulatedDevices(); 21 emulated_devices = hid_core.GetEmulatedDevices();
18} 22}
19 23
@@ -23,16 +27,14 @@ void Controller_Keyboard::OnInit() {}
23 27
24void Controller_Keyboard::OnRelease() {} 28void Controller_Keyboard::OnRelease() {}
25 29
26void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 30void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
27 std::size_t size) {
28 if (!IsControllerActivated()) { 31 if (!IsControllerActivated()) {
29 keyboard_lifo.buffer_count = 0; 32 shared_memory->keyboard_lifo.buffer_count = 0;
30 keyboard_lifo.buffer_tail = 0; 33 shared_memory->keyboard_lifo.buffer_tail = 0;
31 std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
32 return; 34 return;
33 } 35 }
34 36
35 const auto& last_entry = keyboard_lifo.ReadCurrentEntry().state; 37 const auto& last_entry = shared_memory->keyboard_lifo.ReadCurrentEntry().state;
36 next_state.sampling_number = last_entry.sampling_number + 1; 38 next_state.sampling_number = last_entry.sampling_number + 1;
37 39
38 if (Settings::values.keyboard_enabled) { 40 if (Settings::values.keyboard_enabled) {
@@ -44,8 +46,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
44 next_state.attribute.is_connected.Assign(1); 46 next_state.attribute.is_connected.Assign(1);
45 } 47 }
46 48
47 keyboard_lifo.WriteNextEntry(next_state); 49 shared_memory->keyboard_lifo.WriteNextEntry(next_state);
48 std::memcpy(data + SHARED_MEMORY_OFFSET, &keyboard_lifo, sizeof(keyboard_lifo));
49} 50}
50 51
51} // namespace Service::HID 52} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 39c6085f1..4c9c06a39 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -16,7 +16,7 @@ struct KeyboardKey;
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Keyboard final : public ControllerBase { 17class Controller_Keyboard final : public ControllerBase {
18public: 18public:
19 explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_); 19 explicit Controller_Keyboard(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
20 ~Controller_Keyboard() override; 20 ~Controller_Keyboard() override;
21 21
22 // Called when the controller is initialized 22 // Called when the controller is initialized
@@ -26,7 +26,7 @@ public:
26 void OnRelease() override; 26 void OnRelease() override;
27 27
28 // When the controller is requesting an update for the shared memory 28 // When the controller is requesting an update for the shared memory
29 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 29 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
30 30
31private: 31private:
32 // This is nn::hid::detail::KeyboardState 32 // This is nn::hid::detail::KeyboardState
@@ -38,11 +38,16 @@ private:
38 }; 38 };
39 static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); 39 static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size");
40 40
41 // This is nn::hid::detail::KeyboardLifo 41 struct KeyboardSharedMemory {
42 Lifo<KeyboardState, hid_entry_count> keyboard_lifo{}; 42 // This is nn::hid::detail::KeyboardLifo
43 static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); 43 Lifo<KeyboardState, hid_entry_count> keyboard_lifo{};
44 KeyboardState next_state{}; 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");
45 48
49 KeyboardSharedMemory* shared_memory;
50 KeyboardState next_state{};
46 Core::HID::EmulatedDevices* emulated_devices; 51 Core::HID::EmulatedDevices* emulated_devices;
47}; 52};
48} // namespace Service::HID 53} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index a0292f586..730be33cd 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -12,7 +12,11 @@
12namespace Service::HID { 12namespace Service::HID {
13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400; 13constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3400;
14 14
15Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { 15Controller_Mouse::Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
16 : ControllerBase{hid_core_} {
17 static_assert(SHARED_MEMORY_OFFSET + sizeof(MouseSharedMemory) < shared_memory_size,
18 "MouseSharedMemory is bigger than the shared memory");
19 shared_memory = std::construct_at(reinterpret_cast<MouseSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
16 emulated_devices = hid_core.GetEmulatedDevices(); 20 emulated_devices = hid_core.GetEmulatedDevices();
17} 21}
18 22
@@ -21,16 +25,14 @@ Controller_Mouse::~Controller_Mouse() = default;
21void Controller_Mouse::OnInit() {} 25void Controller_Mouse::OnInit() {}
22void Controller_Mouse::OnRelease() {} 26void Controller_Mouse::OnRelease() {}
23 27
24void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 28void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
25 std::size_t size) {
26 if (!IsControllerActivated()) { 29 if (!IsControllerActivated()) {
27 mouse_lifo.buffer_count = 0; 30 shared_memory->mouse_lifo.buffer_count = 0;
28 mouse_lifo.buffer_tail = 0; 31 shared_memory->mouse_lifo.buffer_tail = 0;
29 std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
30 return; 32 return;
31 } 33 }
32 34
33 const auto& last_entry = mouse_lifo.ReadCurrentEntry().state; 35 const auto& last_entry = shared_memory->mouse_lifo.ReadCurrentEntry().state;
34 next_state.sampling_number = last_entry.sampling_number + 1; 36 next_state.sampling_number = last_entry.sampling_number + 1;
35 37
36 next_state.attribute.raw = 0; 38 next_state.attribute.raw = 0;
@@ -50,8 +52,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
50 next_state.button = mouse_button_state; 52 next_state.button = mouse_button_state;
51 } 53 }
52 54
53 mouse_lifo.WriteNextEntry(next_state); 55 shared_memory->mouse_lifo.WriteNextEntry(next_state);
54 std::memcpy(data + SHARED_MEMORY_OFFSET, &mouse_lifo, sizeof(mouse_lifo));
55} 56}
56 57
57} // namespace Service::HID 58} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 62acdfb77..a9395c44b 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -16,7 +16,7 @@ struct AnalogStickState;
16namespace Service::HID { 16namespace Service::HID {
17class Controller_Mouse final : public ControllerBase { 17class Controller_Mouse final : public ControllerBase {
18public: 18public:
19 explicit Controller_Mouse(Core::HID::HIDCore& hid_core_); 19 explicit Controller_Mouse(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
20 ~Controller_Mouse() override; 20 ~Controller_Mouse() override;
21 21
22 // Called when the controller is initialized 22 // Called when the controller is initialized
@@ -26,15 +26,20 @@ public:
26 void OnRelease() override; 26 void OnRelease() override;
27 27
28 // When the controller is requesting an update for the shared memory 28 // When the controller is requesting an update for the shared memory
29 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 29 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
30 30
31private: 31private:
32 // This is nn::hid::detail::MouseLifo 32 struct MouseSharedMemory {
33 Lifo<Core::HID::MouseState, hid_entry_count> mouse_lifo{}; 33 // This is nn::hid::detail::MouseLifo
34 static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); 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 MouseSharedMemory* shared_memory;
35 Core::HID::MouseState next_state{}; 41 Core::HID::MouseState next_state{};
36 42 Core::HID::AnalogStickState last_mouse_wheel_state{};
37 Core::HID::AnalogStickState last_mouse_wheel_state;
38 Core::HID::EmulatedDevices* emulated_devices; 43 Core::HID::EmulatedDevices* emulated_devices;
39}; 44};
40} // namespace Service::HID 45} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 16e973b25..17f71beaf 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -61,11 +61,14 @@ bool Controller_NPad::IsDeviceHandleValid(const Core::HID::SixAxisSensorHandle&
61 return npad_id && npad_type && device_index; 61 return npad_id && npad_type && device_index;
62} 62}
63 63
64Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, 64Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
65 KernelHelpers::ServiceContext& service_context_) 65 KernelHelpers::ServiceContext& service_context_)
66 : ControllerBase{hid_core_}, service_context{service_context_} { 66 : ControllerBase{hid_core_}, service_context{service_context_} {
67 static_assert(NPAD_OFFSET + (NPAD_COUNT * sizeof(NpadInternalState)) < shared_memory_size);
67 for (std::size_t i = 0; i < controller_data.size(); ++i) { 68 for (std::size_t i = 0; i < controller_data.size(); ++i) {
68 auto& controller = controller_data[i]; 69 auto& controller = controller_data[i];
70 controller.shared_memory = std::construct_at(reinterpret_cast<NpadInternalState*>(
71 raw_shared_memory_ + NPAD_OFFSET + (i * sizeof(NpadInternalState))));
69 controller.device = hid_core.GetEmulatedControllerByIndex(i); 72 controller.device = hid_core.GetEmulatedControllerByIndex(i);
70 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = 73 controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
71 Core::HID::DEFAULT_VIBRATION_VALUE; 74 Core::HID::DEFAULT_VIBRATION_VALUE;
@@ -115,11 +118,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
115 if (!controller.device->IsConnected()) { 118 if (!controller.device->IsConnected()) {
116 return; 119 return;
117 } 120 }
118 auto& shared_memory = controller.shared_memory_entry; 121 auto* shared_memory = controller.shared_memory;
119 const auto& battery_level = controller.device->GetBattery(); 122 const auto& battery_level = controller.device->GetBattery();
120 shared_memory.battery_level_dual = battery_level.dual.battery_level; 123 shared_memory->battery_level_dual = battery_level.dual.battery_level;
121 shared_memory.battery_level_left = battery_level.left.battery_level; 124 shared_memory->battery_level_left = battery_level.left.battery_level;
122 shared_memory.battery_level_right = battery_level.right.battery_level; 125 shared_memory->battery_level_right = battery_level.right.battery_level;
123 break; 126 break;
124 } 127 }
125 default: 128 default:
@@ -134,99 +137,100 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
134 } 137 }
135 LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); 138 LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
136 const auto controller_type = controller.device->GetNpadStyleIndex(); 139 const auto controller_type = controller.device->GetNpadStyleIndex();
137 auto& shared_memory = controller.shared_memory_entry; 140 auto* shared_memory = controller.shared_memory;
138 if (controller_type == Core::HID::NpadStyleIndex::None) { 141 if (controller_type == Core::HID::NpadStyleIndex::None) {
139 controller.styleset_changed_event->GetWritableEvent().Signal(); 142 controller.styleset_changed_event->GetWritableEvent().Signal();
140 return; 143 return;
141 } 144 }
142 shared_memory.style_tag.raw = Core::HID::NpadStyleSet::None; 145 shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None;
143 shared_memory.device_type.raw = 0; 146 shared_memory->device_type.raw = 0;
144 shared_memory.system_properties.raw = 0; 147 shared_memory->system_properties.raw = 0;
145 switch (controller_type) { 148 switch (controller_type) {
146 case Core::HID::NpadStyleIndex::None: 149 case Core::HID::NpadStyleIndex::None:
147 UNREACHABLE(); 150 UNREACHABLE();
148 break; 151 break;
149 case Core::HID::NpadStyleIndex::ProController: 152 case Core::HID::NpadStyleIndex::ProController:
150 shared_memory.style_tag.fullkey.Assign(1); 153 shared_memory->style_tag.fullkey.Assign(1);
151 shared_memory.device_type.fullkey.Assign(1); 154 shared_memory->device_type.fullkey.Assign(1);
152 shared_memory.system_properties.is_vertical.Assign(1); 155 shared_memory->system_properties.is_vertical.Assign(1);
153 shared_memory.system_properties.use_plus.Assign(1); 156 shared_memory->system_properties.use_plus.Assign(1);
154 shared_memory.system_properties.use_minus.Assign(1); 157 shared_memory->system_properties.use_minus.Assign(1);
155 shared_memory.applet_footer.type = AppletFooterUiType::SwitchProController; 158 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::SwitchProController;
156 break; 159 break;
157 case Core::HID::NpadStyleIndex::Handheld: 160 case Core::HID::NpadStyleIndex::Handheld:
158 shared_memory.style_tag.handheld.Assign(1); 161 shared_memory->style_tag.handheld.Assign(1);
159 shared_memory.device_type.handheld_left.Assign(1); 162 shared_memory->device_type.handheld_left.Assign(1);
160 shared_memory.device_type.handheld_right.Assign(1); 163 shared_memory->device_type.handheld_right.Assign(1);
161 shared_memory.system_properties.is_vertical.Assign(1); 164 shared_memory->system_properties.is_vertical.Assign(1);
162 shared_memory.system_properties.use_plus.Assign(1); 165 shared_memory->system_properties.use_plus.Assign(1);
163 shared_memory.system_properties.use_minus.Assign(1); 166 shared_memory->system_properties.use_minus.Assign(1);
164 shared_memory.system_properties.use_directional_buttons.Assign(1); 167 shared_memory->system_properties.use_directional_buttons.Assign(1);
165 shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; 168 shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
166 shared_memory.applet_footer.type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; 169 shared_memory->applet_nfc_xcd.applet_footer.type =
170 AppletFooterUiType::HandheldJoyConLeftJoyConRight;
167 break; 171 break;
168 case Core::HID::NpadStyleIndex::JoyconDual: 172 case Core::HID::NpadStyleIndex::JoyconDual:
169 shared_memory.style_tag.joycon_dual.Assign(1); 173 shared_memory->style_tag.joycon_dual.Assign(1);
170 if (controller.is_dual_left_connected) { 174 if (controller.is_dual_left_connected) {
171 shared_memory.device_type.joycon_left.Assign(1); 175 shared_memory->device_type.joycon_left.Assign(1);
172 shared_memory.system_properties.use_minus.Assign(1); 176 shared_memory->system_properties.use_minus.Assign(1);
173 } 177 }
174 if (controller.is_dual_right_connected) { 178 if (controller.is_dual_right_connected) {
175 shared_memory.device_type.joycon_right.Assign(1); 179 shared_memory->device_type.joycon_right.Assign(1);
176 shared_memory.system_properties.use_plus.Assign(1); 180 shared_memory->system_properties.use_plus.Assign(1);
177 } 181 }
178 shared_memory.system_properties.use_directional_buttons.Assign(1); 182 shared_memory->system_properties.use_directional_buttons.Assign(1);
179 shared_memory.system_properties.is_vertical.Assign(1); 183 shared_memory->system_properties.is_vertical.Assign(1);
180 shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual; 184 shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual;
181 if (controller.is_dual_left_connected && controller.is_dual_right_connected) { 185 if (controller.is_dual_left_connected && controller.is_dual_right_connected) {
182 shared_memory.applet_footer.type = AppletFooterUiType::JoyDual; 186 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDual;
183 } else if (controller.is_dual_left_connected) { 187 } else if (controller.is_dual_left_connected) {
184 shared_memory.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly; 188 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualLeftOnly;
185 } else { 189 } else {
186 shared_memory.applet_footer.type = AppletFooterUiType::JoyDualRightOnly; 190 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyDualRightOnly;
187 } 191 }
188 break; 192 break;
189 case Core::HID::NpadStyleIndex::JoyconLeft: 193 case Core::HID::NpadStyleIndex::JoyconLeft:
190 shared_memory.style_tag.joycon_left.Assign(1); 194 shared_memory->style_tag.joycon_left.Assign(1);
191 shared_memory.device_type.joycon_left.Assign(1); 195 shared_memory->device_type.joycon_left.Assign(1);
192 shared_memory.system_properties.is_horizontal.Assign(1); 196 shared_memory->system_properties.is_horizontal.Assign(1);
193 shared_memory.system_properties.use_minus.Assign(1); 197 shared_memory->system_properties.use_minus.Assign(1);
194 shared_memory.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal; 198 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyLeftHorizontal;
195 break; 199 break;
196 case Core::HID::NpadStyleIndex::JoyconRight: 200 case Core::HID::NpadStyleIndex::JoyconRight:
197 shared_memory.style_tag.joycon_right.Assign(1); 201 shared_memory->style_tag.joycon_right.Assign(1);
198 shared_memory.device_type.joycon_right.Assign(1); 202 shared_memory->device_type.joycon_right.Assign(1);
199 shared_memory.system_properties.is_horizontal.Assign(1); 203 shared_memory->system_properties.is_horizontal.Assign(1);
200 shared_memory.system_properties.use_plus.Assign(1); 204 shared_memory->system_properties.use_plus.Assign(1);
201 shared_memory.applet_footer.type = AppletFooterUiType::JoyRightHorizontal; 205 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::JoyRightHorizontal;
202 break; 206 break;
203 case Core::HID::NpadStyleIndex::GameCube: 207 case Core::HID::NpadStyleIndex::GameCube:
204 shared_memory.style_tag.gamecube.Assign(1); 208 shared_memory->style_tag.gamecube.Assign(1);
205 shared_memory.device_type.fullkey.Assign(1); 209 shared_memory->device_type.fullkey.Assign(1);
206 shared_memory.system_properties.is_vertical.Assign(1); 210 shared_memory->system_properties.is_vertical.Assign(1);
207 shared_memory.system_properties.use_plus.Assign(1); 211 shared_memory->system_properties.use_plus.Assign(1);
208 break; 212 break;
209 case Core::HID::NpadStyleIndex::Pokeball: 213 case Core::HID::NpadStyleIndex::Pokeball:
210 shared_memory.style_tag.palma.Assign(1); 214 shared_memory->style_tag.palma.Assign(1);
211 shared_memory.device_type.palma.Assign(1); 215 shared_memory->device_type.palma.Assign(1);
212 break; 216 break;
213 case Core::HID::NpadStyleIndex::NES: 217 case Core::HID::NpadStyleIndex::NES:
214 shared_memory.style_tag.lark.Assign(1); 218 shared_memory->style_tag.lark.Assign(1);
215 shared_memory.device_type.fullkey.Assign(1); 219 shared_memory->device_type.fullkey.Assign(1);
216 break; 220 break;
217 case Core::HID::NpadStyleIndex::SNES: 221 case Core::HID::NpadStyleIndex::SNES:
218 shared_memory.style_tag.lucia.Assign(1); 222 shared_memory->style_tag.lucia.Assign(1);
219 shared_memory.device_type.fullkey.Assign(1); 223 shared_memory->device_type.fullkey.Assign(1);
220 shared_memory.applet_footer.type = AppletFooterUiType::Lucia; 224 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lucia;
221 break; 225 break;
222 case Core::HID::NpadStyleIndex::N64: 226 case Core::HID::NpadStyleIndex::N64:
223 shared_memory.style_tag.lagoon.Assign(1); 227 shared_memory->style_tag.lagoon.Assign(1);
224 shared_memory.device_type.fullkey.Assign(1); 228 shared_memory->device_type.fullkey.Assign(1);
225 shared_memory.applet_footer.type = AppletFooterUiType::Lagon; 229 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::Lagon;
226 break; 230 break;
227 case Core::HID::NpadStyleIndex::SegaGenesis: 231 case Core::HID::NpadStyleIndex::SegaGenesis:
228 shared_memory.style_tag.lager.Assign(1); 232 shared_memory->style_tag.lager.Assign(1);
229 shared_memory.device_type.fullkey.Assign(1); 233 shared_memory->device_type.fullkey.Assign(1);
230 break; 234 break;
231 default: 235 default:
232 break; 236 break;
@@ -234,23 +238,23 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
234 238
235 const auto& body_colors = controller.device->GetColors(); 239 const auto& body_colors = controller.device->GetColors();
236 240
237 shared_memory.fullkey_color.attribute = ColorAttribute::Ok; 241 shared_memory->fullkey_color.attribute = ColorAttribute::Ok;
238 shared_memory.fullkey_color.fullkey = body_colors.fullkey; 242 shared_memory->fullkey_color.fullkey = body_colors.fullkey;
239 243
240 shared_memory.joycon_color.attribute = ColorAttribute::Ok; 244 shared_memory->joycon_color.attribute = ColorAttribute::Ok;
241 shared_memory.joycon_color.left = body_colors.left; 245 shared_memory->joycon_color.left = body_colors.left;
242 shared_memory.joycon_color.right = body_colors.right; 246 shared_memory->joycon_color.right = body_colors.right;
243 247
244 // TODO: Investigate when we should report all batery types 248 // TODO: Investigate when we should report all batery types
245 const auto& battery_level = controller.device->GetBattery(); 249 const auto& battery_level = controller.device->GetBattery();
246 shared_memory.battery_level_dual = battery_level.dual.battery_level; 250 shared_memory->battery_level_dual = battery_level.dual.battery_level;
247 shared_memory.battery_level_left = battery_level.left.battery_level; 251 shared_memory->battery_level_left = battery_level.left.battery_level;
248 shared_memory.battery_level_right = battery_level.right.battery_level; 252 shared_memory->battery_level_right = battery_level.right.battery_level;
249 253
250 controller.is_connected = true; 254 controller.is_connected = true;
251 controller.device->Connect(); 255 controller.device->Connect();
252 SignalStyleSetChangedEvent(npad_id); 256 SignalStyleSetChangedEvent(npad_id);
253 WriteEmptyEntry(controller.shared_memory_entry); 257 WriteEmptyEntry(controller.shared_memory);
254} 258}
255 259
256void Controller_NPad::OnInit() { 260void Controller_NPad::OnInit() {
@@ -270,12 +274,12 @@ void Controller_NPad::OnInit() {
270 274
271 // Prefill controller buffers 275 // Prefill controller buffers
272 for (auto& controller : controller_data) { 276 for (auto& controller : controller_data) {
273 auto& npad = controller.shared_memory_entry; 277 auto* npad = controller.shared_memory;
274 npad.fullkey_color = { 278 npad->fullkey_color = {
275 .attribute = ColorAttribute::NoController, 279 .attribute = ColorAttribute::NoController,
276 .fullkey = {}, 280 .fullkey = {},
277 }; 281 };
278 npad.joycon_color = { 282 npad->joycon_color = {
279 .attribute = ColorAttribute::NoController, 283 .attribute = ColorAttribute::NoController,
280 .left = {}, 284 .left = {},
281 .right = {}, 285 .right = {},
@@ -287,25 +291,25 @@ void Controller_NPad::OnInit() {
287 } 291 }
288} 292}
289 293
290void Controller_NPad::WriteEmptyEntry(NpadInternalState& npad) { 294void Controller_NPad::WriteEmptyEntry(NpadInternalState* npad) {
291 NPadGenericState dummy_pad_state{}; 295 NPadGenericState dummy_pad_state{};
292 NpadGcTriggerState dummy_gc_state{}; 296 NpadGcTriggerState dummy_gc_state{};
293 dummy_pad_state.sampling_number = npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1; 297 dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
294 npad.fullkey_lifo.WriteNextEntry(dummy_pad_state); 298 npad->fullkey_lifo.WriteNextEntry(dummy_pad_state);
295 dummy_pad_state.sampling_number = npad.handheld_lifo.ReadCurrentEntry().sampling_number + 1; 299 dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1;
296 npad.handheld_lifo.WriteNextEntry(dummy_pad_state); 300 npad->handheld_lifo.WriteNextEntry(dummy_pad_state);
297 dummy_pad_state.sampling_number = npad.joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; 301 dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1;
298 npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state); 302 npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state);
299 dummy_pad_state.sampling_number = npad.joy_left_lifo.ReadCurrentEntry().sampling_number + 1; 303 dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1;
300 npad.joy_left_lifo.WriteNextEntry(dummy_pad_state); 304 npad->joy_left_lifo.WriteNextEntry(dummy_pad_state);
301 dummy_pad_state.sampling_number = npad.joy_right_lifo.ReadCurrentEntry().sampling_number + 1; 305 dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1;
302 npad.joy_right_lifo.WriteNextEntry(dummy_pad_state); 306 npad->joy_right_lifo.WriteNextEntry(dummy_pad_state);
303 dummy_pad_state.sampling_number = npad.palma_lifo.ReadCurrentEntry().sampling_number + 1; 307 dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1;
304 npad.palma_lifo.WriteNextEntry(dummy_pad_state); 308 npad->palma_lifo.WriteNextEntry(dummy_pad_state);
305 dummy_pad_state.sampling_number = npad.system_ext_lifo.ReadCurrentEntry().sampling_number + 1; 309 dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1;
306 npad.system_ext_lifo.WriteNextEntry(dummy_pad_state); 310 npad->system_ext_lifo.WriteNextEntry(dummy_pad_state);
307 dummy_gc_state.sampling_number = npad.gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; 311 dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1;
308 npad.gc_trigger_lifo.WriteNextEntry(dummy_gc_state); 312 npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state);
309} 313}
310 314
311void Controller_NPad::OnRelease() { 315void Controller_NPad::OnRelease() {
@@ -371,23 +375,19 @@ void Controller_NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
371 } 375 }
372} 376}
373 377
374void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 378void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
375 std::size_t data_len) {
376 if (!IsControllerActivated()) { 379 if (!IsControllerActivated()) {
377 return; 380 return;
378 } 381 }
379 382
380 for (std::size_t i = 0; i < controller_data.size(); ++i) { 383 for (std::size_t i = 0; i < controller_data.size(); ++i) {
381 auto& controller = controller_data[i]; 384 auto& controller = controller_data[i];
382 auto& npad = controller.shared_memory_entry; 385 auto* npad = controller.shared_memory;
383 386
384 const auto& controller_type = controller.device->GetNpadStyleIndex(); 387 const auto& controller_type = controller.device->GetNpadStyleIndex();
385 388
386 if (controller_type == Core::HID::NpadStyleIndex::None || 389 if (controller_type == Core::HID::NpadStyleIndex::None ||
387 !controller.device->IsConnected()) { 390 !controller.device->IsConnected()) {
388 // Refresh shared memory
389 std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
390 &controller.shared_memory_entry, sizeof(NpadInternalState));
391 continue; 391 continue;
392 } 392 }
393 393
@@ -415,8 +415,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
415 415
416 libnx_state.connection_status.is_wired.Assign(1); 416 libnx_state.connection_status.is_wired.Assign(1);
417 pad_state.sampling_number = 417 pad_state.sampling_number =
418 npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; 418 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
419 npad.fullkey_lifo.WriteNextEntry(pad_state); 419 npad->fullkey_lifo.WriteNextEntry(pad_state);
420 break; 420 break;
421 case Core::HID::NpadStyleIndex::Handheld: 421 case Core::HID::NpadStyleIndex::Handheld:
422 pad_state.connection_status.raw = 0; 422 pad_state.connection_status.raw = 0;
@@ -433,8 +433,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
433 libnx_state.connection_status.is_left_wired.Assign(1); 433 libnx_state.connection_status.is_left_wired.Assign(1);
434 libnx_state.connection_status.is_right_wired.Assign(1); 434 libnx_state.connection_status.is_right_wired.Assign(1);
435 pad_state.sampling_number = 435 pad_state.sampling_number =
436 npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; 436 npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
437 npad.handheld_lifo.WriteNextEntry(pad_state); 437 npad->handheld_lifo.WriteNextEntry(pad_state);
438 break; 438 break;
439 case Core::HID::NpadStyleIndex::JoyconDual: 439 case Core::HID::NpadStyleIndex::JoyconDual:
440 pad_state.connection_status.raw = 0; 440 pad_state.connection_status.raw = 0;
@@ -449,8 +449,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
449 } 449 }
450 450
451 pad_state.sampling_number = 451 pad_state.sampling_number =
452 npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; 452 npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
453 npad.joy_dual_lifo.WriteNextEntry(pad_state); 453 npad->joy_dual_lifo.WriteNextEntry(pad_state);
454 break; 454 break;
455 case Core::HID::NpadStyleIndex::JoyconLeft: 455 case Core::HID::NpadStyleIndex::JoyconLeft:
456 pad_state.connection_status.raw = 0; 456 pad_state.connection_status.raw = 0;
@@ -459,8 +459,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
459 459
460 libnx_state.connection_status.is_left_connected.Assign(1); 460 libnx_state.connection_status.is_left_connected.Assign(1);
461 pad_state.sampling_number = 461 pad_state.sampling_number =
462 npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1; 462 npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
463 npad.joy_left_lifo.WriteNextEntry(pad_state); 463 npad->joy_left_lifo.WriteNextEntry(pad_state);
464 break; 464 break;
465 case Core::HID::NpadStyleIndex::JoyconRight: 465 case Core::HID::NpadStyleIndex::JoyconRight:
466 pad_state.connection_status.raw = 0; 466 pad_state.connection_status.raw = 0;
@@ -469,8 +469,8 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
469 469
470 libnx_state.connection_status.is_right_connected.Assign(1); 470 libnx_state.connection_status.is_right_connected.Assign(1);
471 pad_state.sampling_number = 471 pad_state.sampling_number =
472 npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1; 472 npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
473 npad.joy_right_lifo.WriteNextEntry(pad_state); 473 npad->joy_right_lifo.WriteNextEntry(pad_state);
474 break; 474 break;
475 case Core::HID::NpadStyleIndex::GameCube: 475 case Core::HID::NpadStyleIndex::GameCube:
476 pad_state.connection_status.raw = 0; 476 pad_state.connection_status.raw = 0;
@@ -479,18 +479,18 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
479 479
480 libnx_state.connection_status.is_wired.Assign(1); 480 libnx_state.connection_status.is_wired.Assign(1);
481 pad_state.sampling_number = 481 pad_state.sampling_number =
482 npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; 482 npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
483 trigger_state.sampling_number = 483 trigger_state.sampling_number =
484 npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1; 484 npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
485 npad.fullkey_lifo.WriteNextEntry(pad_state); 485 npad->fullkey_lifo.WriteNextEntry(pad_state);
486 npad.gc_trigger_lifo.WriteNextEntry(trigger_state); 486 npad->gc_trigger_lifo.WriteNextEntry(trigger_state);
487 break; 487 break;
488 case Core::HID::NpadStyleIndex::Pokeball: 488 case Core::HID::NpadStyleIndex::Pokeball:
489 pad_state.connection_status.raw = 0; 489 pad_state.connection_status.raw = 0;
490 pad_state.connection_status.is_connected.Assign(1); 490 pad_state.connection_status.is_connected.Assign(1);
491 pad_state.sampling_number = 491 pad_state.sampling_number =
492 npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1; 492 npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
493 npad.palma_lifo.WriteNextEntry(pad_state); 493 npad->palma_lifo.WriteNextEntry(pad_state);
494 break; 494 break;
495 default: 495 default:
496 break; 496 break;
@@ -499,17 +499,13 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
499 libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; 499 libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
500 libnx_state.l_stick = pad_state.l_stick; 500 libnx_state.l_stick = pad_state.l_stick;
501 libnx_state.r_stick = pad_state.r_stick; 501 libnx_state.r_stick = pad_state.r_stick;
502 npad.system_ext_lifo.WriteNextEntry(pad_state); 502 npad->system_ext_lifo.WriteNextEntry(pad_state);
503 503
504 press_state |= static_cast<u64>(pad_state.npad_buttons.raw); 504 press_state |= static_cast<u64>(pad_state.npad_buttons.raw);
505
506 std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
507 &controller.shared_memory_entry, sizeof(NpadInternalState));
508 } 505 }
509} 506}
510 507
511void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 508void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {
512 std::size_t data_len) {
513 if (!IsControllerActivated()) { 509 if (!IsControllerActivated()) {
514 return; 510 return;
515 } 511 }
@@ -524,7 +520,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
524 continue; 520 continue;
525 } 521 }
526 522
527 auto& npad = controller.shared_memory_entry; 523 auto* npad = controller.shared_memory;
528 const auto& motion_state = controller.device->GetMotions(); 524 const auto& motion_state = controller.device->GetMotions();
529 auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; 525 auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
530 auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; 526 auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
@@ -610,32 +606,30 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
610 } 606 }
611 607
612 sixaxis_fullkey_state.sampling_number = 608 sixaxis_fullkey_state.sampling_number =
613 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; 609 npad->sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
614 sixaxis_handheld_state.sampling_number = 610 sixaxis_handheld_state.sampling_number =
615 npad.sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; 611 npad->sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
616 sixaxis_dual_left_state.sampling_number = 612 sixaxis_dual_left_state.sampling_number =
617 npad.sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1; 613 npad->sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
618 sixaxis_dual_right_state.sampling_number = 614 sixaxis_dual_right_state.sampling_number =
619 npad.sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1; 615 npad->sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
620 sixaxis_left_lifo_state.sampling_number = 616 sixaxis_left_lifo_state.sampling_number =
621 npad.sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1; 617 npad->sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
622 sixaxis_right_lifo_state.sampling_number = 618 sixaxis_right_lifo_state.sampling_number =
623 npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1; 619 npad->sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
624 620
625 if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { 621 if (Core::HID::IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) {
626 // This buffer only is updated on handheld on HW 622 // This buffer only is updated on handheld on HW
627 npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state); 623 npad->sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
628 } else { 624 } else {
629 // Handheld doesn't update this buffer on HW 625 // Handheld doesn't update this buffer on HW
630 npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state); 626 npad->sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
631 } 627 }
632 628
633 npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state); 629 npad->sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
634 npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state); 630 npad->sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
635 npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state); 631 npad->sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
636 npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state); 632 npad->sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
637 std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
638 &controller.shared_memory_entry, sizeof(NpadInternalState));
639 } 633 }
640} 634}
641 635
@@ -713,8 +707,8 @@ void Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceTy
713 } 707 }
714 708
715 auto& controller = GetControllerFromNpadIdType(npad_id); 709 auto& controller = GetControllerFromNpadIdType(npad_id);
716 if (controller.shared_memory_entry.assignment_mode != assignment_mode) { 710 if (controller.shared_memory->assignment_mode != assignment_mode) {
717 controller.shared_memory_entry.assignment_mode = assignment_mode; 711 controller.shared_memory->assignment_mode = assignment_mode;
718 } 712 }
719 713
720 if (!controller.device->IsConnected()) { 714 if (!controller.device->IsConnected()) {
@@ -981,32 +975,32 @@ void Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
981 controller.vibration[device_idx].device_mounted = false; 975 controller.vibration[device_idx].device_mounted = false;
982 } 976 }
983 977
984 auto& shared_memory_entry = controller.shared_memory_entry; 978 auto* shared_memory = controller.shared_memory;
985 // Don't reset shared_memory_entry.assignment_mode this value is persistent 979 // Don't reset shared_memory->assignment_mode this value is persistent
986 shared_memory_entry.style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out 980 shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out
987 shared_memory_entry.device_type.raw = 0; 981 shared_memory->device_type.raw = 0;
988 shared_memory_entry.system_properties.raw = 0; 982 shared_memory->system_properties.raw = 0;
989 shared_memory_entry.button_properties.raw = 0; 983 shared_memory->button_properties.raw = 0;
990 shared_memory_entry.battery_level_dual = 0; 984 shared_memory->battery_level_dual = 0;
991 shared_memory_entry.battery_level_left = 0; 985 shared_memory->battery_level_left = 0;
992 shared_memory_entry.battery_level_right = 0; 986 shared_memory->battery_level_right = 0;
993 shared_memory_entry.fullkey_color = { 987 shared_memory->fullkey_color = {
994 .attribute = ColorAttribute::NoController, 988 .attribute = ColorAttribute::NoController,
995 .fullkey = {}, 989 .fullkey = {},
996 }; 990 };
997 shared_memory_entry.joycon_color = { 991 shared_memory->joycon_color = {
998 .attribute = ColorAttribute::NoController, 992 .attribute = ColorAttribute::NoController,
999 .left = {}, 993 .left = {},
1000 .right = {}, 994 .right = {},
1001 }; 995 };
1002 shared_memory_entry.applet_footer.type = AppletFooterUiType::None; 996 shared_memory->applet_nfc_xcd.applet_footer.type = AppletFooterUiType::None;
1003 997
1004 controller.is_dual_left_connected = true; 998 controller.is_dual_left_connected = true;
1005 controller.is_dual_right_connected = true; 999 controller.is_dual_right_connected = true;
1006 controller.is_connected = false; 1000 controller.is_connected = false;
1007 controller.device->Disconnect(); 1001 controller.device->Disconnect();
1008 SignalStyleSetChangedEvent(npad_id); 1002 SignalStyleSetChangedEvent(npad_id);
1009 WriteEmptyEntry(controller.shared_memory_entry); 1003 WriteEmptyEntry(shared_memory);
1010} 1004}
1011 1005
1012ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle, 1006ResultCode Controller_NPad::SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index b42532b68..425b84abd 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -35,7 +35,7 @@ namespace Service::HID {
35 35
36class Controller_NPad final : public ControllerBase { 36class Controller_NPad final : public ControllerBase {
37public: 37public:
38 explicit Controller_NPad(Core::HID::HIDCore& hid_core_, 38 explicit Controller_NPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
39 KernelHelpers::ServiceContext& service_context_); 39 KernelHelpers::ServiceContext& service_context_);
40 ~Controller_NPad() override; 40 ~Controller_NPad() override;
41 41
@@ -46,11 +46,10 @@ public:
46 void OnRelease() override; 46 void OnRelease() override;
47 47
48 // When the controller is requesting an update for the shared memory 48 // When the controller is requesting an update for the shared memory
49 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 49 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
50 50
51 // When the controller is requesting a motion update for the shared memory 51 // When the controller is requesting a motion update for the shared memory
52 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 52 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) override;
53 std::size_t size) override;
54 53
55 // This is nn::hid::GyroscopeZeroDriftMode 54 // This is nn::hid::GyroscopeZeroDriftMode
56 enum class GyroscopeZeroDriftMode : u32 { 55 enum class GyroscopeZeroDriftMode : u32 {
@@ -188,6 +187,8 @@ public:
188 static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle); 187 static bool IsDeviceHandleValid(const Core::HID::VibrationDeviceHandle& device_handle);
189 188
190private: 189private:
190 static const std::size_t NPAD_COUNT = 10;
191
191 // This is nn::hid::detail::ColorAttribute 192 // This is nn::hid::detail::ColorAttribute
192 enum class ColorAttribute : u32 { 193 enum class ColorAttribute : u32 {
193 Ok = 0, 194 Ok = 0,
@@ -409,6 +410,13 @@ private:
409 U, 410 U,
410 }; 411 };
411 412
413 struct AppletNfcXcd {
414 union {
415 AppletFooterUi applet_footer{};
416 Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
417 };
418 };
419
412 // This is nn::hid::detail::NpadInternalState 420 // This is nn::hid::detail::NpadInternalState
413 struct NpadInternalState { 421 struct NpadInternalState {
414 Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; 422 Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None};
@@ -435,10 +443,7 @@ private:
435 Core::HID::NpadBatteryLevel battery_level_dual{}; 443 Core::HID::NpadBatteryLevel battery_level_dual{};
436 Core::HID::NpadBatteryLevel battery_level_left{}; 444 Core::HID::NpadBatteryLevel battery_level_left{};
437 Core::HID::NpadBatteryLevel battery_level_right{}; 445 Core::HID::NpadBatteryLevel battery_level_right{};
438 union { 446 AppletNfcXcd applet_nfc_xcd{};
439 AppletFooterUi applet_footer{};
440 Lifo<NfcXcdDeviceHandleStateImpl, 0x2> nfc_xcd_device_lifo;
441 };
442 INSERT_PADDING_BYTES(0x20); // Unknown 447 INSERT_PADDING_BYTES(0x20); // Unknown
443 Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{}; 448 Lifo<NpadGcTriggerState, hid_entry_count> gc_trigger_lifo{};
444 NpadLarkType lark_type_l_and_main{}; 449 NpadLarkType lark_type_l_and_main{};
@@ -467,7 +472,7 @@ private:
467 struct NpadControllerData { 472 struct NpadControllerData {
468 Core::HID::EmulatedController* device; 473 Core::HID::EmulatedController* device;
469 Kernel::KEvent* styleset_changed_event{}; 474 Kernel::KEvent* styleset_changed_event{};
470 NpadInternalState shared_memory_entry{}; 475 NpadInternalState* shared_memory;
471 476
472 std::array<VibrationData, 2> vibration{}; 477 std::array<VibrationData, 2> vibration{};
473 bool unintended_home_button_input_protection{}; 478 bool unintended_home_button_input_protection{};
@@ -505,7 +510,7 @@ private:
505 void InitNewlyAddedController(Core::HID::NpadIdType npad_id); 510 void InitNewlyAddedController(Core::HID::NpadIdType npad_id);
506 bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const; 511 bool IsControllerSupported(Core::HID::NpadStyleIndex controller) const;
507 void RequestPadStateUpdate(Core::HID::NpadIdType npad_id); 512 void RequestPadStateUpdate(Core::HID::NpadIdType npad_id);
508 void WriteEmptyEntry(NpadInternalState& npad); 513 void WriteEmptyEntry(NpadInternalState* npad);
509 514
510 NpadControllerData& GetControllerFromHandle( 515 NpadControllerData& GetControllerFromHandle(
511 const Core::HID::SixAxisSensorHandle& device_handle); 516 const Core::HID::SixAxisSensorHandle& device_handle);
@@ -520,7 +525,7 @@ private:
520 525
521 std::atomic<u64> press_state{}; 526 std::atomic<u64> press_state{};
522 527
523 std::array<NpadControllerData, 10> controller_data{}; 528 std::array<NpadControllerData, NPAD_COUNT> controller_data{};
524 KernelHelpers::ServiceContext& service_context; 529 KernelHelpers::ServiceContext& service_context;
525 std::mutex mutex; 530 std::mutex mutex;
526 std::vector<Core::HID::NpadIdType> supported_npad_id_types{}; 531 std::vector<Core::HID::NpadIdType> supported_npad_id_types{};
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index 4d3b9d2be..df9ee0c3f 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -9,15 +9,18 @@
9 9
10namespace Service::HID { 10namespace Service::HID {
11 11
12Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} 12Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
13 : ControllerBase{hid_core_} {
14 raw_shared_memory = raw_shared_memory_;
15}
16
13Controller_Stubbed::~Controller_Stubbed() = default; 17Controller_Stubbed::~Controller_Stubbed() = default;
14 18
15void Controller_Stubbed::OnInit() {} 19void Controller_Stubbed::OnInit() {}
16 20
17void Controller_Stubbed::OnRelease() {} 21void Controller_Stubbed::OnRelease() {}
18 22
19void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 23void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
20 std::size_t size) {
21 if (!smart_update) { 24 if (!smart_update) {
22 return; 25 return;
23 } 26 }
@@ -28,7 +31,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
28 header.entry_count = 0; 31 header.entry_count = 0;
29 header.last_entry_index = 0; 32 header.last_entry_index = 0;
30 33
31 std::memcpy(data + common_offset, &header, sizeof(CommonHeader)); 34 std::memcpy(raw_shared_memory + common_offset, &header, sizeof(CommonHeader));
32} 35}
33 36
34void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) { 37void Controller_Stubbed::SetCommonHeaderOffset(std::size_t off) {
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/stubbed.h
index 512066eb3..5973358bc 100644
--- a/src/core/hle/service/hid/controllers/stubbed.h
+++ b/src/core/hle/service/hid/controllers/stubbed.h
@@ -9,7 +9,7 @@
9namespace Service::HID { 9namespace Service::HID {
10class Controller_Stubbed final : public ControllerBase { 10class Controller_Stubbed final : public ControllerBase {
11public: 11public:
12 explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_); 12 explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
13 ~Controller_Stubbed() override; 13 ~Controller_Stubbed() override;
14 14
15 // Called when the controller is initialized 15 // Called when the controller is initialized
@@ -19,7 +19,7 @@ public:
19 void OnRelease() override; 19 void OnRelease() override;
20 20
21 // When the controller is requesting an update for the shared memory 21 // When the controller is requesting an update for the shared memory
22 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 22 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
23 23
24 void SetCommonHeaderOffset(std::size_t off); 24 void SetCommonHeaderOffset(std::size_t off);
25 25
@@ -32,6 +32,7 @@ private:
32 }; 32 };
33 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); 33 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
34 34
35 u8* raw_shared_memory;
35 bool smart_update{}; 36 bool smart_update{};
36 std::size_t common_offset{}; 37 std::size_t common_offset{};
37}; 38};
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 5b4b51a69..5f584586b 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -15,8 +15,12 @@
15namespace Service::HID { 15namespace Service::HID {
16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400; 16constexpr std::size_t SHARED_MEMORY_OFFSET = 0x400;
17 17
18Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_) 18Controller_Touchscreen::Controller_Touchscreen(Core::HID::HIDCore& hid_core_,
19 u8* raw_shared_memory_)
19 : ControllerBase{hid_core_} { 20 : ControllerBase{hid_core_} {
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(reinterpret_cast<TouchSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
20 console = hid_core.GetEmulatedConsole(); 24 console = hid_core.GetEmulatedConsole();
21} 25}
22 26
@@ -26,14 +30,12 @@ void Controller_Touchscreen::OnInit() {}
26 30
27void Controller_Touchscreen::OnRelease() {} 31void Controller_Touchscreen::OnRelease() {}
28 32
29void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 33void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
30 std::size_t size) { 34 shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
31 touch_screen_lifo.timestamp = core_timing.GetCPUTicks();
32 35
33 if (!IsControllerActivated()) { 36 if (!IsControllerActivated()) {
34 touch_screen_lifo.buffer_count = 0; 37 shared_memory->touch_screen_lifo.buffer_count = 0;
35 touch_screen_lifo.buffer_tail = 0; 38 shared_memory->touch_screen_lifo.buffer_tail = 0;
36 std::memcpy(data, &touch_screen_lifo, sizeof(touch_screen_lifo));
37 return; 39 return;
38 } 40 }
39 41
@@ -74,7 +76,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
74 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); 76 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
75 77
76 const u64 tick = core_timing.GetCPUTicks(); 78 const u64 tick = core_timing.GetCPUTicks();
77 const auto& last_entry = touch_screen_lifo.ReadCurrentEntry().state; 79 const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state;
78 80
79 next_state.sampling_number = last_entry.sampling_number + 1; 81 next_state.sampling_number = last_entry.sampling_number + 1;
80 next_state.entry_count = static_cast<s32>(active_fingers_count); 82 next_state.entry_count = static_cast<s32>(active_fingers_count);
@@ -106,8 +108,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
106 } 108 }
107 } 109 }
108 110
109 touch_screen_lifo.WriteNextEntry(next_state); 111 shared_memory->touch_screen_lifo.WriteNextEntry(next_state);
110 std::memcpy(data + SHARED_MEMORY_OFFSET, &touch_screen_lifo, sizeof(touch_screen_lifo));
111} 112}
112 113
113} // namespace Service::HID 114} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 424973b38..2e1dde2f1 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -32,7 +32,7 @@ public:
32 static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17, 32 static_assert(sizeof(TouchScreenConfigurationForNx) == 0x17,
33 "TouchScreenConfigurationForNx is an invalid size"); 33 "TouchScreenConfigurationForNx is an invalid size");
34 34
35 explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_); 35 explicit Controller_Touchscreen(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
36 ~Controller_Touchscreen() override; 36 ~Controller_Touchscreen() override;
37 37
38 // Called when the controller is initialized 38 // Called when the controller is initialized
@@ -42,7 +42,7 @@ public:
42 void OnRelease() override; 42 void OnRelease() override;
43 43
44 // When the controller is requesting an update for the shared memory 44 // When the controller is requesting an update for the shared memory
45 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 45 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
46 46
47private: 47private:
48 static constexpr std::size_t MAX_FINGERS = 16; 48 static constexpr std::size_t MAX_FINGERS = 16;
@@ -56,11 +56,17 @@ private:
56 }; 56 };
57 static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); 57 static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size");
58 58
59 // This is nn::hid::detail::TouchScreenLifo 59 struct TouchSharedMemory {
60 Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{}; 60 // This is nn::hid::detail::TouchScreenLifo
61 static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); 61 Lifo<TouchScreenState, hid_entry_count> touch_screen_lifo{};
62 TouchScreenState next_state{}; 62 static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size");
63 INSERT_PADDING_WORDS(0xF2);
64 };
65 static_assert(sizeof(TouchSharedMemory) == 0x3000, "TouchSharedMemory is an invalid size");
63 66
67 TouchSharedMemory* shared_memory;
68
69 TouchScreenState next_state{};
64 std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers; 70 std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers;
65 Core::HID::EmulatedConsole* console; 71 Core::HID::EmulatedConsole* console;
66}; 72};
diff --git a/src/core/hle/service/hid/controllers/xpad.cpp b/src/core/hle/service/hid/controllers/xpad.cpp
index fc6ac6457..a35632560 100644
--- a/src/core/hle/service/hid/controllers/xpad.cpp
+++ b/src/core/hle/service/hid/controllers/xpad.cpp
@@ -10,28 +10,30 @@
10namespace Service::HID { 10namespace Service::HID {
11constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00; 11constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C00;
12 12
13Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} 13Controller_XPad::Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_)
14 : ControllerBase{hid_core_} {
15 static_assert(SHARED_MEMORY_OFFSET + sizeof(XpadSharedMemory) < shared_memory_size,
16 "XpadSharedMemory is bigger than the shared memory");
17 shared_memory = std::construct_at(reinterpret_cast<XpadSharedMemory*>(raw_shared_memory_ + SHARED_MEMORY_OFFSET));
18}
14Controller_XPad::~Controller_XPad() = default; 19Controller_XPad::~Controller_XPad() = default;
15 20
16void Controller_XPad::OnInit() {} 21void Controller_XPad::OnInit() {}
17 22
18void Controller_XPad::OnRelease() {} 23void Controller_XPad::OnRelease() {}
19 24
20void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 25void Controller_XPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
21 std::size_t size) {
22 if (!IsControllerActivated()) { 26 if (!IsControllerActivated()) {
23 basic_xpad_lifo.buffer_count = 0; 27 shared_memory->basic_xpad_lifo.buffer_count = 0;
24 basic_xpad_lifo.buffer_tail = 0; 28 shared_memory->basic_xpad_lifo.buffer_tail = 0;
25 std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
26 return; 29 return;
27 } 30 }
28 31
29 const auto& last_entry = basic_xpad_lifo.ReadCurrentEntry().state; 32 const auto& last_entry = shared_memory->basic_xpad_lifo.ReadCurrentEntry().state;
30 next_state.sampling_number = last_entry.sampling_number + 1; 33 next_state.sampling_number = last_entry.sampling_number + 1;
31 // TODO(ogniK): Update xpad states 34 // TODO(ogniK): Update xpad states
32 35
33 basic_xpad_lifo.WriteNextEntry(next_state); 36 shared_memory->basic_xpad_lifo.WriteNextEntry(next_state);
34 std::memcpy(data + SHARED_MEMORY_OFFSET, &basic_xpad_lifo, sizeof(basic_xpad_lifo));
35} 37}
36 38
37} // namespace Service::HID 39} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
index 8211b6ee3..7ed8d5d97 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -12,7 +12,7 @@
12namespace Service::HID { 12namespace Service::HID {
13class Controller_XPad final : public ControllerBase { 13class Controller_XPad final : public ControllerBase {
14public: 14public:
15 explicit Controller_XPad(Core::HID::HIDCore& hid_core_); 15 explicit Controller_XPad(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_);
16 ~Controller_XPad() override; 16 ~Controller_XPad() override;
17 17
18 // Called when the controller is initialized 18 // Called when the controller is initialized
@@ -22,7 +22,7 @@ public:
22 void OnRelease() override; 22 void OnRelease() override;
23 23
24 // When the controller is requesting an update for the shared memory 24 // When the controller is requesting an update for the shared memory
25 void OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, std::size_t size) override; 25 void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
26 26
27private: 27private:
28 // This is nn::hid::BasicXpadAttributeSet 28 // This is nn::hid::BasicXpadAttributeSet
@@ -98,9 +98,15 @@ private:
98 }; 98 };
99 static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size"); 99 static_assert(sizeof(BasicXpadState) == 0x20, "BasicXpadState is an invalid size");
100 100
101 // This is nn::hid::detail::BasicXpadLifo 101 struct XpadSharedMemory {
102 Lifo<BasicXpadState, hid_entry_count> basic_xpad_lifo{}; 102 // This is nn::hid::detail::BasicXpadLifo
103 static_assert(sizeof(basic_xpad_lifo) == 0x2C8, "basic_xpad_lifo is an invalid size"); 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 XpadSharedMemory* shared_memory;
104 BasicXpadState next_state{}; 110 BasicXpadState next_state{};
105}; 111};
106} // namespace Service::HID 112} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index fb1ec52b2..36162ac97 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -39,7 +39,6 @@ constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000};
39constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) 39constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
40// TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed 40// TODO: Correct update rate for motion is 5ms. Check why some games don't behave at that speed
41constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz) 41constexpr auto motion_update_ns = std::chrono::nanoseconds{10 * 1000 * 1000}; // (10ms, 100Hz)
42constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
43 42
44IAppletResource::IAppletResource(Core::System& system_, 43IAppletResource::IAppletResource(Core::System& system_,
45 KernelHelpers::ServiceContext& service_context_) 44 KernelHelpers::ServiceContext& service_context_)
@@ -48,20 +47,20 @@ IAppletResource::IAppletResource(Core::System& system_,
48 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, 47 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
49 }; 48 };
50 RegisterHandlers(functions); 49 RegisterHandlers(functions);
51 50 u8* shared_memory = system.Kernel().GetHidSharedMem().GetPointer();
52 MakeController<Controller_DebugPad>(HidController::DebugPad); 51 MakeController<Controller_DebugPad>(HidController::DebugPad, shared_memory);
53 MakeController<Controller_Touchscreen>(HidController::Touchscreen); 52 MakeController<Controller_Touchscreen>(HidController::Touchscreen, shared_memory);
54 MakeController<Controller_Mouse>(HidController::Mouse); 53 MakeController<Controller_Mouse>(HidController::Mouse, shared_memory);
55 MakeController<Controller_Keyboard>(HidController::Keyboard); 54 MakeController<Controller_Keyboard>(HidController::Keyboard, shared_memory);
56 MakeController<Controller_XPad>(HidController::XPad); 55 MakeController<Controller_XPad>(HidController::XPad, shared_memory);
57 MakeController<Controller_Stubbed>(HidController::HomeButton); 56 MakeController<Controller_Stubbed>(HidController::HomeButton, shared_memory);
58 MakeController<Controller_Stubbed>(HidController::SleepButton); 57 MakeController<Controller_Stubbed>(HidController::SleepButton, shared_memory);
59 MakeController<Controller_Stubbed>(HidController::CaptureButton); 58 MakeController<Controller_Stubbed>(HidController::CaptureButton, shared_memory);
60 MakeController<Controller_Stubbed>(HidController::InputDetector); 59 MakeController<Controller_Stubbed>(HidController::InputDetector, shared_memory);
61 MakeController<Controller_Stubbed>(HidController::UniquePad); 60 MakeController<Controller_Stubbed>(HidController::UniquePad, shared_memory);
62 MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad); 61 MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
63 MakeController<Controller_Gesture>(HidController::Gesture); 62 MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
64 MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor); 63 MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
65 64
66 // Homebrew doesn't try to activate some controllers, so we activate them by default 65 // Homebrew doesn't try to activate some controllers, so we activate them by default
67 GetController<Controller_NPad>(HidController::NPad).ActivateController(); 66 GetController<Controller_NPad>(HidController::NPad).ActivateController();
@@ -135,8 +134,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
135 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) { 134 if (controller == controllers[static_cast<size_t>(HidController::Mouse)]) {
136 continue; 135 continue;
137 } 136 }
138 controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), 137 controller->OnUpdate(core_timing);
139 SHARED_MEMORY_SIZE);
140 } 138 }
141 139
142 // If ns_late is higher than the update rate ignore the delay 140 // If ns_late is higher than the update rate ignore the delay
@@ -151,10 +149,8 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
151 std::chrono::nanoseconds ns_late) { 149 std::chrono::nanoseconds ns_late) {
152 auto& core_timing = system.CoreTiming(); 150 auto& core_timing = system.CoreTiming();
153 151
154 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate( 152 controllers[static_cast<size_t>(HidController::Mouse)]->OnUpdate(core_timing);
155 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); 153 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(core_timing);
156 controllers[static_cast<size_t>(HidController::Keyboard)]->OnUpdate(
157 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
158 154
159 // If ns_late is higher than the update rate ignore the delay 155 // If ns_late is higher than the update rate ignore the delay
160 if (ns_late > mouse_keyboard_update_ns) { 156 if (ns_late > mouse_keyboard_update_ns) {
@@ -167,8 +163,7 @@ void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data,
167void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { 163void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
168 auto& core_timing = system.CoreTiming(); 164 auto& core_timing = system.CoreTiming();
169 165
170 controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate( 166 controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate(core_timing);
171 core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE);
172 167
173 // If ns_late is higher than the update rate ignore the delay 168 // If ns_late is higher than the update rate ignore the delay
174 if (ns_late > motion_update_ns) { 169 if (ns_late > motion_update_ns) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 95778e673..e61f8ed08 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -58,13 +58,14 @@ public:
58 58
59private: 59private:
60 template <typename T> 60 template <typename T>
61 void MakeController(HidController controller) { 61 void MakeController(HidController controller, u8* shared_memory) {
62 controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(system.HIDCore()); 62 controllers[static_cast<std::size_t>(controller)] =
63 std::make_unique<T>(system.HIDCore(), shared_memory);
63 } 64 }
64 template <typename T> 65 template <typename T>
65 void MakeControllerWithServiceContext(HidController controller) { 66 void MakeControllerWithServiceContext(HidController controller, u8* shared_memory) {
66 controllers[static_cast<std::size_t>(controller)] = 67 controllers[static_cast<std::size_t>(controller)] =
67 std::make_unique<T>(system.HIDCore(), service_context); 68 std::make_unique<T>(system.HIDCore(), shared_memory, service_context);
68 } 69 }
69 70
70 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); 71 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);