summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar german772021-09-20 20:37:50 -0500
committerGravatar Narr the Reg2021-11-24 20:30:24 -0600
commitc87ad2d0d635d8786c48fed856e1bcf1ecc154bf (patch)
tree81f6ae938d90c23e2bfffed541ba094d5aecd822
parentservice/hid: Update console sixaxis to the emulated console (diff)
downloadyuzu-c87ad2d0d635d8786c48fed856e1bcf1ecc154bf.tar.gz
yuzu-c87ad2d0d635d8786c48fed856e1bcf1ecc154bf.tar.xz
yuzu-c87ad2d0d635d8786c48fed856e1bcf1ecc154bf.zip
service/hid: Rewrite npad to use ring lifo and the emulated controller
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp1100
-rw-r--r--src/core/hle/service/hid/controllers/npad.h395
2 files changed, 605 insertions, 890 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 196876810..03cbd42f4 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -12,7 +12,6 @@
12#include "common/settings.h" 12#include "common/settings.h"
13#include "core/core.h" 13#include "core/core.h"
14#include "core/core_timing.h" 14#include "core/core_timing.h"
15#include "core/frontend/input.h"
16#include "core/hle/kernel/k_event.h" 15#include "core/hle/kernel/k_event.h"
17#include "core/hle/kernel/k_readable_event.h" 16#include "core/hle/kernel/k_readable_event.h"
18#include "core/hle/kernel/k_writable_event.h" 17#include "core/hle/kernel/k_writable_event.h"
@@ -20,64 +19,13 @@
20#include "core/hle/service/kernel_helpers.h" 19#include "core/hle/service/kernel_helpers.h"
21 20
22namespace Service::HID { 21namespace Service::HID {
23constexpr s32 HID_JOYSTICK_MAX = 0x7fff;
24constexpr s32 HID_TRIGGER_MAX = 0x7fff;
25[[maybe_unused]] constexpr s32 HID_JOYSTICK_MIN = -0x7fff;
26constexpr std::size_t NPAD_OFFSET = 0x9A00; 22constexpr std::size_t NPAD_OFFSET = 0x9A00;
27constexpr u32 BATTERY_FULL = 2;
28constexpr u32 MAX_NPAD_ID = 7; 23constexpr u32 MAX_NPAD_ID = 7;
29constexpr std::size_t HANDHELD_INDEX = 8; 24constexpr std::size_t HANDHELD_INDEX = 8;
30constexpr std::array<u32, 10> npad_id_list{ 25constexpr std::array<u32, 10> npad_id_list{
31 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN, 26 0, 1, 2, 3, 4, 5, 6, 7, NPAD_HANDHELD, NPAD_UNKNOWN,
32}; 27};
33 28
34enum class JoystickId : std::size_t {
35 Joystick_Left,
36 Joystick_Right,
37};
38
39Controller_NPad::NPadControllerType Controller_NPad::MapSettingsTypeToNPad(
40 Settings::ControllerType type) {
41 switch (type) {
42 case Settings::ControllerType::ProController:
43 return NPadControllerType::ProController;
44 case Settings::ControllerType::DualJoyconDetached:
45 return NPadControllerType::JoyDual;
46 case Settings::ControllerType::LeftJoycon:
47 return NPadControllerType::JoyLeft;
48 case Settings::ControllerType::RightJoycon:
49 return NPadControllerType::JoyRight;
50 case Settings::ControllerType::Handheld:
51 return NPadControllerType::Handheld;
52 case Settings::ControllerType::GameCube:
53 return NPadControllerType::GameCube;
54 default:
55 UNREACHABLE();
56 return NPadControllerType::ProController;
57 }
58}
59
60Settings::ControllerType Controller_NPad::MapNPadToSettingsType(
61 Controller_NPad::NPadControllerType type) {
62 switch (type) {
63 case NPadControllerType::ProController:
64 return Settings::ControllerType::ProController;
65 case NPadControllerType::JoyDual:
66 return Settings::ControllerType::DualJoyconDetached;
67 case NPadControllerType::JoyLeft:
68 return Settings::ControllerType::LeftJoycon;
69 case NPadControllerType::JoyRight:
70 return Settings::ControllerType::RightJoycon;
71 case NPadControllerType::Handheld:
72 return Settings::ControllerType::Handheld;
73 case NPadControllerType::GameCube:
74 return Settings::ControllerType::GameCube;
75 default:
76 UNREACHABLE();
77 return Settings::ControllerType::ProController;
78 }
79}
80
81std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) { 29std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) {
82 switch (npad_id) { 30 switch (npad_id) {
83 case 0: 31 case 0:
@@ -143,118 +91,157 @@ bool Controller_NPad::IsNpadIdValid(u32 npad_id) {
143 91
144bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) { 92bool Controller_NPad::IsDeviceHandleValid(const DeviceHandle& device_handle) {
145 return IsNpadIdValid(device_handle.npad_id) && 93 return IsNpadIdValid(device_handle.npad_id) &&
146 device_handle.npad_type < NpadType::MaxNpadType && 94 device_handle.npad_type < Core::HID::NpadType::MaxNpadType &&
147 device_handle.device_index < DeviceIndex::MaxDeviceIndex; 95 device_handle.device_index < DeviceIndex::MaxDeviceIndex;
148} 96}
149 97
150Controller_NPad::Controller_NPad(Core::System& system_, 98Controller_NPad::Controller_NPad(Core::System& system_,
151 KernelHelpers::ServiceContext& service_context_) 99 KernelHelpers::ServiceContext& service_context_)
152 : ControllerBase{system_}, service_context{service_context_} { 100 : ControllerBase{system_}, service_context{service_context_} {
153 latest_vibration_values.fill({DEFAULT_VIBRATION_VALUE, DEFAULT_VIBRATION_VALUE}); 101 for (std::size_t i = 0; i < controller_data.size(); ++i) {
102 auto& controller = controller_data[i];
103 controller.device = system.HIDCore().GetEmulatedControllerByIndex(i);
104 controller.vibration[0].latest_vibration_value = DEFAULT_VIBRATION_VALUE;
105 controller.vibration[1].latest_vibration_value = DEFAULT_VIBRATION_VALUE;
106 Core::HID::ControllerUpdateCallback engine_callback{
107 [this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }};
108 controller.callback_key = controller.device->SetCallback(engine_callback);
109 }
154} 110}
155 111
156Controller_NPad::~Controller_NPad() { 112Controller_NPad::~Controller_NPad() {
113 for (std::size_t i = 0; i < controller_data.size(); ++i) {
114 auto& controller = controller_data[i];
115 controller.device->DeleteCallback(controller.callback_key);
116 }
157 OnRelease(); 117 OnRelease();
158} 118}
159 119
120void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
121 std::size_t controller_idx) {
122 if (type == Core::HID::ControllerTriggerType::All) {
123 ControllerUpdate(Core::HID::ControllerTriggerType::Type, controller_idx);
124 ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx);
125 return;
126 }
127
128 switch (type) {
129 case Core::HID::ControllerTriggerType::Connected:
130 InitNewlyAddedController(controller_idx);
131 break;
132 case Core::HID::ControllerTriggerType::Disconnected:
133 DisconnectNpadAtIndex(controller_idx);
134 break;
135 case Core::HID::ControllerTriggerType::Type: {
136 auto& controller = controller_data[controller_idx];
137 if (controller.device->IsConnected()) {
138 LOG_ERROR(Service_HID, "Controller type changed without turning off the controller");
139 }
140 break;
141 }
142 default:
143 break;
144 }
145}
146
160void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { 147void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
161 const auto controller_type = connected_controllers[controller_idx].type; 148 auto& controller = controller_data[controller_idx];
162 auto& controller = shared_memory_entries[controller_idx]; 149 const auto controller_type = controller.device->GetNpadType();
163 if (controller_type == NPadControllerType::None) { 150 auto& shared_memory = controller.shared_memory_entry;
164 styleset_changed_events[controller_idx]->GetWritableEvent().Signal(); 151 if (controller_type == Core::HID::NpadType::None) {
152 controller.styleset_changed_event->GetWritableEvent().Signal();
165 return; 153 return;
166 } 154 }
167 controller.style_set.raw = 0; // Zero out 155 shared_memory.style_set.raw = 0; // Zero out
168 controller.device_type.raw = 0; 156 shared_memory.device_type.raw = 0;
169 controller.system_properties.raw = 0; 157 shared_memory.system_properties.raw = 0;
170 switch (controller_type) { 158 switch (controller_type) {
171 case NPadControllerType::None: 159 case Core::HID::NpadType::None:
172 UNREACHABLE(); 160 UNREACHABLE();
173 break; 161 break;
174 case NPadControllerType::ProController: 162 case Core::HID::NpadType::ProController:
175 controller.style_set.fullkey.Assign(1); 163 shared_memory.style_set.fullkey.Assign(1);
176 controller.device_type.fullkey.Assign(1); 164 shared_memory.device_type.fullkey.Assign(1);
177 controller.system_properties.is_vertical.Assign(1); 165 shared_memory.system_properties.is_vertical.Assign(1);
178 controller.system_properties.use_plus.Assign(1); 166 shared_memory.system_properties.use_plus.Assign(1);
179 controller.system_properties.use_minus.Assign(1); 167 shared_memory.system_properties.use_minus.Assign(1);
180 controller.assignment_mode = NpadAssignments::Single; 168 shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
181 controller.footer_type = AppletFooterUiType::SwitchProController; 169 shared_memory.footer_type = AppletFooterUiType::SwitchProController;
182 break; 170 break;
183 case NPadControllerType::Handheld: 171 case Core::HID::NpadType::Handheld:
184 controller.style_set.handheld.Assign(1); 172 shared_memory.style_set.handheld.Assign(1);
185 controller.device_type.handheld_left.Assign(1); 173 shared_memory.device_type.handheld_left.Assign(1);
186 controller.device_type.handheld_right.Assign(1); 174 shared_memory.device_type.handheld_right.Assign(1);
187 controller.system_properties.is_vertical.Assign(1); 175 shared_memory.system_properties.is_vertical.Assign(1);
188 controller.system_properties.use_plus.Assign(1); 176 shared_memory.system_properties.use_plus.Assign(1);
189 controller.system_properties.use_minus.Assign(1); 177 shared_memory.system_properties.use_minus.Assign(1);
190 controller.assignment_mode = NpadAssignments::Dual; 178 shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
191 controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; 179 shared_memory.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
192 break; 180 break;
193 case NPadControllerType::JoyDual: 181 case Core::HID::NpadType::JoyconDual:
194 controller.style_set.joycon_dual.Assign(1); 182 shared_memory.style_set.joycon_dual.Assign(1);
195 controller.device_type.joycon_left.Assign(1); 183 shared_memory.device_type.joycon_left.Assign(1);
196 controller.device_type.joycon_right.Assign(1); 184 shared_memory.device_type.joycon_right.Assign(1);
197 controller.system_properties.is_vertical.Assign(1); 185 shared_memory.system_properties.is_vertical.Assign(1);
198 controller.system_properties.use_plus.Assign(1); 186 shared_memory.system_properties.use_plus.Assign(1);
199 controller.system_properties.use_minus.Assign(1); 187 shared_memory.system_properties.use_minus.Assign(1);
200 controller.assignment_mode = NpadAssignments::Dual; 188 shared_memory.assignment_mode = NpadJoyAssignmentMode::Dual;
201 controller.footer_type = AppletFooterUiType::JoyDual; 189 shared_memory.footer_type = AppletFooterUiType::JoyDual;
202 break; 190 break;
203 case NPadControllerType::JoyLeft: 191 case Core::HID::NpadType::JoyconLeft:
204 controller.style_set.joycon_left.Assign(1); 192 shared_memory.style_set.joycon_left.Assign(1);
205 controller.device_type.joycon_left.Assign(1); 193 shared_memory.device_type.joycon_left.Assign(1);
206 controller.system_properties.is_horizontal.Assign(1); 194 shared_memory.system_properties.is_horizontal.Assign(1);
207 controller.system_properties.use_minus.Assign(1); 195 shared_memory.system_properties.use_minus.Assign(1);
208 controller.assignment_mode = NpadAssignments::Single; 196 shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
209 controller.footer_type = AppletFooterUiType::JoyLeftHorizontal; 197 shared_memory.footer_type = AppletFooterUiType::JoyLeftHorizontal;
210 break; 198 break;
211 case NPadControllerType::JoyRight: 199 case Core::HID::NpadType::JoyconRight:
212 controller.style_set.joycon_right.Assign(1); 200 shared_memory.style_set.joycon_right.Assign(1);
213 controller.device_type.joycon_right.Assign(1); 201 shared_memory.device_type.joycon_right.Assign(1);
214 controller.system_properties.is_horizontal.Assign(1); 202 shared_memory.system_properties.is_horizontal.Assign(1);
215 controller.system_properties.use_plus.Assign(1); 203 shared_memory.system_properties.use_plus.Assign(1);
216 controller.assignment_mode = NpadAssignments::Single; 204 shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
217 controller.footer_type = AppletFooterUiType::JoyRightHorizontal; 205 shared_memory.footer_type = AppletFooterUiType::JoyRightHorizontal;
218 break; 206 break;
219 case NPadControllerType::GameCube: 207 case Core::HID::NpadType::GameCube:
220 controller.style_set.gamecube.Assign(1); 208 shared_memory.style_set.gamecube.Assign(1);
221 // The GC Controller behaves like a wired Pro Controller 209 // The GC Controller behaves like a wired Pro Controller
222 controller.device_type.fullkey.Assign(1); 210 shared_memory.device_type.fullkey.Assign(1);
223 controller.system_properties.is_vertical.Assign(1); 211 shared_memory.system_properties.is_vertical.Assign(1);
224 controller.system_properties.use_plus.Assign(1); 212 shared_memory.system_properties.use_plus.Assign(1);
225 break; 213 break;
226 case NPadControllerType::Pokeball: 214 case Core::HID::NpadType::Pokeball:
227 controller.style_set.palma.Assign(1); 215 shared_memory.style_set.palma.Assign(1);
228 controller.device_type.palma.Assign(1); 216 shared_memory.device_type.palma.Assign(1);
229 controller.assignment_mode = NpadAssignments::Single; 217 shared_memory.assignment_mode = NpadJoyAssignmentMode::Single;
218 break;
219 default:
230 break; 220 break;
231 } 221 }
232 222
233 controller.fullkey_color.attribute = ColorAttributes::Ok; 223 const auto& body_colors = controller.device->GetColors();
234 controller.fullkey_color.fullkey.body = 0;
235 controller.fullkey_color.fullkey.button = 0;
236 224
237 controller.joycon_color.attribute = ColorAttributes::Ok; 225 shared_memory.fullkey_color.attribute = ColorAttribute::Ok;
238 controller.joycon_color.left.body = 226 shared_memory.fullkey_color.fullkey = body_colors.fullkey;
239 Settings::values.players.GetValue()[controller_idx].body_color_left; 227
240 controller.joycon_color.left.button = 228 shared_memory.joycon_color.attribute = ColorAttribute::Ok;
241 Settings::values.players.GetValue()[controller_idx].button_color_left; 229 shared_memory.joycon_color.left = body_colors.left;
242 controller.joycon_color.right.body = 230 shared_memory.joycon_color.right = body_colors.right;
243 Settings::values.players.GetValue()[controller_idx].body_color_right;
244 controller.joycon_color.right.button =
245 Settings::values.players.GetValue()[controller_idx].button_color_right;
246 231
247 // TODO: Investigate when we should report all batery types 232 // TODO: Investigate when we should report all batery types
248 controller.battery_level_dual = BATTERY_FULL; 233 const auto& battery_level = controller.device->GetBattery();
249 controller.battery_level_left = BATTERY_FULL; 234 shared_memory.battery_level_dual = battery_level.dual.battery_level;
250 controller.battery_level_right = BATTERY_FULL; 235 shared_memory.battery_level_left = battery_level.left.battery_level;
236 shared_memory.battery_level_right = battery_level.right.battery_level;
251 237
252 SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); 238 SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
253} 239}
254 240
255void Controller_NPad::OnInit() { 241void Controller_NPad::OnInit() {
256 for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { 242 for (std::size_t i = 0; i < controller_data.size(); ++i) {
257 styleset_changed_events[i] = 243 auto& controller = controller_data[i];
244 controller.styleset_changed_event =
258 service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i)); 245 service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
259 } 246 }
260 247
@@ -262,10 +249,9 @@ void Controller_NPad::OnInit() {
262 return; 249 return;
263 } 250 }
264 251
265 OnLoadInputDevices(); 252 if (system.HIDCore().GetSupportedStyleTag().raw == 0) {
266
267 if (style.raw == 0) {
268 // We want to support all controllers 253 // We want to support all controllers
254 Core::HID::NpadStyleTag style{};
269 style.handheld.Assign(1); 255 style.handheld.Assign(1);
270 style.joycon_left.Assign(1); 256 style.joycon_left.Assign(1);
271 style.joycon_right.Assign(1); 257 style.joycon_right.Assign(1);
@@ -273,173 +259,98 @@ void Controller_NPad::OnInit() {
273 style.fullkey.Assign(1); 259 style.fullkey.Assign(1);
274 style.gamecube.Assign(1); 260 style.gamecube.Assign(1);
275 style.palma.Assign(1); 261 style.palma.Assign(1);
276 } 262 system.HIDCore().SetSupportedStyleTag(style);
277
278 std::transform(Settings::values.players.GetValue().begin(),
279 Settings::values.players.GetValue().end(), connected_controllers.begin(),
280 [](const Settings::PlayerInput& player) {
281 return ControllerHolder{MapSettingsTypeToNPad(player.controller_type),
282 player.connected};
283 });
284
285 // Connect the Player 1 or Handheld controller if none are connected.
286 if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
287 [](const ControllerHolder& controller) { return controller.is_connected; })) {
288 const auto controller =
289 MapSettingsTypeToNPad(Settings::values.players.GetValue()[0].controller_type);
290 if (controller == NPadControllerType::Handheld) {
291 Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
292 connected_controllers[HANDHELD_INDEX] = {controller, true};
293 } else {
294 Settings::values.players.GetValue()[0].connected = true;
295 connected_controllers[0] = {controller, true};
296 }
297 }
298
299 // Account for handheld
300 if (connected_controllers[HANDHELD_INDEX].is_connected) {
301 connected_controllers[HANDHELD_INDEX].type = NPadControllerType::Handheld;
302 } 263 }
303 264
304 supported_npad_id_types.resize(npad_id_list.size()); 265 supported_npad_id_types.resize(npad_id_list.size());
305 std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), 266 std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
306 npad_id_list.size() * sizeof(u32)); 267 npad_id_list.size() * sizeof(u32));
307 268
308 for (std::size_t i = 0; i < connected_controllers.size(); ++i) { 269 for (std::size_t i = 0; i < controller_data.size(); ++i) {
309 const auto& controller = connected_controllers[i]; 270 auto& controller = controller_data[i].device;
310 if (controller.is_connected) { 271 if (controller->IsConnected()) {
311 AddNewControllerAt(controller.type, i); 272 AddNewControllerAt(controller->GetNpadType(), i);
312 } 273 }
313 } 274 }
314}
315 275
316void Controller_NPad::OnLoadInputDevices() { 276 // Prefill controller buffers
317 const auto& players = Settings::values.players.GetValue(); 277 for (auto& controller : controller_data) {
318 278 NPadGenericState dummy_pad_state{};
319 std::lock_guard lock{mutex}; 279 auto& npad = controller.shared_memory_entry;
320 for (std::size_t i = 0; i < players.size(); ++i) { 280 for (std::size_t i = 0; i < 17; ++i) {
321 std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, 281 dummy_pad_state.sampling_number =
322 players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END, 282 npad.fullkey_lifo.ReadCurrentEntry().sampling_number + 1;
323 buttons[i].begin(), Input::CreateDevice<Input::ButtonDevice>); 283 npad.fullkey_lifo.WriteNextEntry(dummy_pad_state);
324 std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, 284 npad.handheld_lifo.WriteNextEntry(dummy_pad_state);
325 players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, 285 npad.joy_dual_lifo.WriteNextEntry(dummy_pad_state);
326 sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>); 286 npad.joy_left_lifo.WriteNextEntry(dummy_pad_state);
327 std::transform(players[i].vibrations.begin() + 287 npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
328 Settings::NativeVibration::VIBRATION_HID_BEGIN, 288 npad.joy_right_lifo.WriteNextEntry(dummy_pad_state);
329 players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END, 289 npad.palma_lifo.WriteNextEntry(dummy_pad_state);
330 vibrations[i].begin(), Input::CreateDevice<Input::VibrationDevice>);
331 std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
332 players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
333 motions[i].begin(), Input::CreateDevice<Input::MotionDevice>);
334 for (std::size_t device_idx = 0; device_idx < vibrations[i].size(); ++device_idx) {
335 InitializeVibrationDeviceAtIndex(i, device_idx);
336 } 290 }
337 } 291 }
338} 292}
339 293
340void Controller_NPad::OnRelease() { 294void Controller_NPad::OnRelease() {
341 for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) { 295 for (std::size_t i = 0; i < controller_data.size(); ++i) {
342 for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) { 296 auto& controller = controller_data[i];
343 VibrateControllerAtIndex(npad_idx, device_idx, {}); 297 service_context.CloseEvent(controller.styleset_changed_event);
298 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
299 VibrateControllerAtIndex(i, device_idx, {});
344 } 300 }
345 } 301 }
346
347 for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
348 service_context.CloseEvent(styleset_changed_events[i]);
349 }
350} 302}
351 303
352void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { 304void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
353 std::lock_guard lock{mutex}; 305 std::lock_guard lock{mutex};
354
355 const auto controller_idx = NPadIdToIndex(npad_id); 306 const auto controller_idx = NPadIdToIndex(npad_id);
356 const auto controller_type = connected_controllers[controller_idx].type; 307 auto& controller = controller_data[controller_idx];
357 if (!connected_controllers[controller_idx].is_connected) { 308 const auto controller_type = controller.device->GetNpadType();
309 if (!controller.device->IsConnected()) {
358 return; 310 return;
359 } 311 }
360 auto& pad_state = npad_pad_states[controller_idx].pad_states; 312
361 auto& lstick_entry = npad_pad_states[controller_idx].l_stick; 313 auto& pad_entry = controller.npad_pad_state;
362 auto& rstick_entry = npad_pad_states[controller_idx].r_stick; 314 auto& trigger_entry = controller.npad_trigger_state;
363 auto& trigger_entry = npad_trigger_states[controller_idx]; 315 const auto button_state = controller.device->GetNpadButtons();
364 const auto& button_state = buttons[controller_idx]; 316 const auto stick_state = controller.device->GetSticks();
365 const auto& analog_state = sticks[controller_idx]; 317
366 const auto [stick_l_x_f, stick_l_y_f] = 318 using btn = Core::HID::NpadButton;
367 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus(); 319 pad_entry.npad_buttons.raw = btn::None;
368 const auto [stick_r_x_f, stick_r_y_f] = 320 if (controller_type != Core::HID::NpadType::JoyconLeft) {
369 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus(); 321 constexpr btn right_button_mask = btn::A | btn::B | btn::X | btn::Y | btn::StickR | btn::R |
370 322 btn::ZR | btn::Plus | btn::StickRLeft | btn::StickRUp |
371 using namespace Settings::NativeButton; 323 btn::StickRRight | btn::StickRDown;
372 if (controller_type != NPadControllerType::JoyLeft) { 324 pad_entry.npad_buttons.raw |= button_state.raw & right_button_mask;
373 pad_state.a.Assign(button_state[A - BUTTON_HID_BEGIN]->GetStatus()); 325 pad_entry.r_stick = stick_state.right;
374 pad_state.b.Assign(button_state[B - BUTTON_HID_BEGIN]->GetStatus());
375 pad_state.x.Assign(button_state[X - BUTTON_HID_BEGIN]->GetStatus());
376 pad_state.y.Assign(button_state[Y - BUTTON_HID_BEGIN]->GetStatus());
377 pad_state.r_stick.Assign(button_state[RStick - BUTTON_HID_BEGIN]->GetStatus());
378 pad_state.r.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus());
379 pad_state.zr.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus());
380 pad_state.plus.Assign(button_state[Plus - BUTTON_HID_BEGIN]->GetStatus());
381
382 pad_state.r_stick_right.Assign(
383 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
384 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
385 pad_state.r_stick_left.Assign(
386 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
387 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
388 pad_state.r_stick_up.Assign(
389 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
390 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
391 pad_state.r_stick_down.Assign(
392 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Right)]
393 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
394 rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
395 rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
396 } 326 }
397 327
398 if (controller_type != NPadControllerType::JoyRight) { 328 if (controller_type != Core::HID::NpadType::JoyconRight) {
399 pad_state.d_left.Assign(button_state[DLeft - BUTTON_HID_BEGIN]->GetStatus()); 329 constexpr btn left_button_mask =
400 pad_state.d_up.Assign(button_state[DUp - BUTTON_HID_BEGIN]->GetStatus()); 330 btn::Left | btn::Up | btn::Right | btn::Down | btn::StickL | btn::L | btn::ZL |
401 pad_state.d_right.Assign(button_state[DRight - BUTTON_HID_BEGIN]->GetStatus()); 331 btn::Minus | btn::StickLLeft | btn::StickLUp | btn::StickLRight | btn::StickLDown;
402 pad_state.d_down.Assign(button_state[DDown - BUTTON_HID_BEGIN]->GetStatus()); 332 pad_entry.npad_buttons.raw |= button_state.raw & left_button_mask;
403 pad_state.l_stick.Assign(button_state[LStick - BUTTON_HID_BEGIN]->GetStatus()); 333 pad_entry.l_stick = stick_state.left;
404 pad_state.l.Assign(button_state[L - BUTTON_HID_BEGIN]->GetStatus());
405 pad_state.zl.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus());
406 pad_state.minus.Assign(button_state[Minus - BUTTON_HID_BEGIN]->GetStatus());
407
408 pad_state.l_stick_right.Assign(
409 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
410 ->GetAnalogDirectionStatus(Input::AnalogDirection::RIGHT));
411 pad_state.l_stick_left.Assign(
412 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
413 ->GetAnalogDirectionStatus(Input::AnalogDirection::LEFT));
414 pad_state.l_stick_up.Assign(
415 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
416 ->GetAnalogDirectionStatus(Input::AnalogDirection::UP));
417 pad_state.l_stick_down.Assign(
418 analog_state[static_cast<std::size_t>(JoystickId::Joystick_Left)]
419 ->GetAnalogDirectionStatus(Input::AnalogDirection::DOWN));
420 lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
421 lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
422 } 334 }
423 335
424 if (controller_type == NPadControllerType::JoyLeft) { 336 if (controller_type == Core::HID::NpadType::JoyconLeft) {
425 pad_state.left_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); 337 pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl);
426 pad_state.left_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); 338 pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr);
427 } 339 }
428 340
429 if (controller_type == NPadControllerType::JoyRight) { 341 if (controller_type == Core::HID::NpadType::JoyconRight) {
430 pad_state.right_sl.Assign(button_state[SL - BUTTON_HID_BEGIN]->GetStatus()); 342 pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl);
431 pad_state.right_sr.Assign(button_state[SR - BUTTON_HID_BEGIN]->GetStatus()); 343 pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr);
432 } 344 }
433 345
434 if (controller_type == NPadControllerType::GameCube) { 346 if (controller_type == Core::HID::NpadType::GameCube) {
435 trigger_entry.l_analog = static_cast<s32>( 347 const auto& trigger_state = controller.device->GetTriggers();
436 button_state[ZL - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); 348 trigger_entry.l_analog = trigger_state.left;
437 trigger_entry.r_analog = static_cast<s32>( 349 trigger_entry.r_analog = trigger_state.right;
438 button_state[ZR - BUTTON_HID_BEGIN]->GetStatus() ? HID_TRIGGER_MAX : 0); 350 pad_entry.npad_buttons.zl.Assign(false);
439 pad_state.zl.Assign(false); 351 pad_entry.npad_buttons.zr.Assign(button_state.r);
440 pad_state.zr.Assign(button_state[R - BUTTON_HID_BEGIN]->GetStatus()); 352 pad_entry.npad_buttons.l.Assign(button_state.zl);
441 pad_state.l.Assign(button_state[ZL - BUTTON_HID_BEGIN]->GetStatus()); 353 pad_entry.npad_buttons.r.Assign(button_state.zr);
442 pad_state.r.Assign(button_state[ZR - BUTTON_HID_BEGIN]->GetStatus());
443 } 354 }
444} 355}
445 356
@@ -448,173 +359,124 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
448 if (!IsControllerActivated()) { 359 if (!IsControllerActivated()) {
449 return; 360 return;
450 } 361 }
451 for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) { 362 for (std::size_t i = 0; i < controller_data.size(); ++i) {
452 auto& npad = shared_memory_entries[i]; 363 auto& controller = controller_data[i];
453 const std::array<NPadGeneric*, 7> controller_npads{ 364 auto& npad = controller.shared_memory_entry;
454 &npad.fullkey_states, &npad.handheld_states, &npad.joy_dual_states,
455 &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states,
456 &npad.system_ext_states};
457
458 // There is the posibility to have more controllers with analog triggers
459 const std::array<TriggerGeneric*, 1> controller_triggers{
460 &npad.gc_trigger_states,
461 };
462
463 for (auto* main_controller : controller_npads) {
464 main_controller->common.entry_count = 16;
465 main_controller->common.total_entry_count = 17;
466
467 const auto& last_entry =
468 main_controller->npad[main_controller->common.last_entry_index];
469
470 main_controller->common.timestamp = core_timing.GetCPUTicks();
471 main_controller->common.last_entry_index =
472 (main_controller->common.last_entry_index + 1) % 17;
473
474 auto& cur_entry = main_controller->npad[main_controller->common.last_entry_index];
475
476 cur_entry.timestamp = last_entry.timestamp + 1;
477 cur_entry.timestamp2 = cur_entry.timestamp;
478 }
479 365
480 for (auto* analog_trigger : controller_triggers) { 366 const auto& controller_type = controller.device->GetNpadType();
481 analog_trigger->entry_count = 16;
482 analog_trigger->total_entry_count = 17;
483 367
484 const auto& last_entry = analog_trigger->trigger[analog_trigger->last_entry_index]; 368 if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) {
485
486 analog_trigger->timestamp = core_timing.GetCPUTicks();
487 analog_trigger->last_entry_index = (analog_trigger->last_entry_index + 1) % 17;
488
489 auto& cur_entry = analog_trigger->trigger[analog_trigger->last_entry_index];
490
491 cur_entry.timestamp = last_entry.timestamp + 1;
492 cur_entry.timestamp2 = cur_entry.timestamp;
493 }
494
495 const auto& controller_type = connected_controllers[i].type;
496
497 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
498 continue; 369 continue;
499 } 370 }
500 const u32 npad_index = static_cast<u32>(i); 371 const u32 npad_index = static_cast<u32>(i);
501 372
502 RequestPadStateUpdate(npad_index); 373 RequestPadStateUpdate(npad_index);
503 auto& pad_state = npad_pad_states[npad_index]; 374 auto& pad_state = controller.npad_pad_state;
504 auto& trigger_state = npad_trigger_states[npad_index]; 375 auto& libnx_state = controller.npad_libnx_state;
505 376 auto& trigger_state = controller.npad_trigger_state;
506 auto& main_controller =
507 npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index];
508 auto& handheld_entry =
509 npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
510 auto& dual_entry = npad.joy_dual_states.npad[npad.joy_dual_states.common.last_entry_index];
511 auto& left_entry = npad.joy_left_states.npad[npad.joy_left_states.common.last_entry_index];
512 auto& right_entry =
513 npad.joy_right_states.npad[npad.joy_right_states.common.last_entry_index];
514 auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index];
515 auto& libnx_entry =
516 npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index];
517 auto& trigger_entry =
518 npad.gc_trigger_states.trigger[npad.gc_trigger_states.last_entry_index];
519
520 libnx_entry.connection_status.raw = 0;
521 libnx_entry.connection_status.is_connected.Assign(1);
522 377
378 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
379 // any controllers.
380 libnx_state.connection_status.raw = 0;
381 libnx_state.connection_status.is_connected.Assign(1);
523 switch (controller_type) { 382 switch (controller_type) {
524 case NPadControllerType::None: 383 case Core::HID::NpadType::None:
525 UNREACHABLE(); 384 UNREACHABLE();
526 break; 385 break;
527 case NPadControllerType::ProController: 386 case Core::HID::NpadType::ProController:
528 main_controller.connection_status.raw = 0; 387 pad_state.connection_status.raw = 0;
529 main_controller.connection_status.is_connected.Assign(1); 388 pad_state.connection_status.is_connected.Assign(1);
530 main_controller.connection_status.is_wired.Assign(1); 389 pad_state.connection_status.is_wired.Assign(1);
531 main_controller.pad.pad_states.raw = pad_state.pad_states.raw; 390
532 main_controller.pad.l_stick = pad_state.l_stick; 391 libnx_state.connection_status.is_wired.Assign(1);
533 main_controller.pad.r_stick = pad_state.r_stick; 392 pad_state.sampling_number =
534 393 npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
535 libnx_entry.connection_status.is_wired.Assign(1); 394 npad.fullkey_lifo.WriteNextEntry(pad_state);
536 break; 395 break;
537 case NPadControllerType::Handheld: 396 case Core::HID::NpadType::Handheld:
538 handheld_entry.connection_status.raw = 0; 397 pad_state.connection_status.raw = 0;
539 handheld_entry.connection_status.is_connected.Assign(1); 398 pad_state.connection_status.is_connected.Assign(1);
540 handheld_entry.connection_status.is_wired.Assign(1); 399 pad_state.connection_status.is_wired.Assign(1);
541 handheld_entry.connection_status.is_left_connected.Assign(1); 400 pad_state.connection_status.is_left_connected.Assign(1);
542 handheld_entry.connection_status.is_right_connected.Assign(1); 401 pad_state.connection_status.is_right_connected.Assign(1);
543 handheld_entry.connection_status.is_left_wired.Assign(1); 402 pad_state.connection_status.is_left_wired.Assign(1);
544 handheld_entry.connection_status.is_right_wired.Assign(1); 403 pad_state.connection_status.is_right_wired.Assign(1);
545 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; 404
546 handheld_entry.pad.l_stick = pad_state.l_stick; 405 libnx_state.connection_status.is_wired.Assign(1);
547 handheld_entry.pad.r_stick = pad_state.r_stick; 406 libnx_state.connection_status.is_left_connected.Assign(1);
548 407 libnx_state.connection_status.is_right_connected.Assign(1);
549 libnx_entry.connection_status.is_wired.Assign(1); 408 libnx_state.connection_status.is_left_wired.Assign(1);
550 libnx_entry.connection_status.is_left_connected.Assign(1); 409 libnx_state.connection_status.is_right_wired.Assign(1);
551 libnx_entry.connection_status.is_right_connected.Assign(1); 410 pad_state.sampling_number =
552 libnx_entry.connection_status.is_left_wired.Assign(1); 411 npad.handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
553 libnx_entry.connection_status.is_right_wired.Assign(1); 412 npad.handheld_lifo.WriteNextEntry(pad_state);
554 break; 413 break;
555 case NPadControllerType::JoyDual: 414 case Core::HID::NpadType::JoyconDual:
556 dual_entry.connection_status.raw = 0; 415 pad_state.connection_status.raw = 0;
557 dual_entry.connection_status.is_connected.Assign(1); 416 pad_state.connection_status.is_connected.Assign(1);
558 dual_entry.connection_status.is_left_connected.Assign(1); 417 pad_state.connection_status.is_left_connected.Assign(1);
559 dual_entry.connection_status.is_right_connected.Assign(1); 418 pad_state.connection_status.is_right_connected.Assign(1);
560 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; 419
561 dual_entry.pad.l_stick = pad_state.l_stick; 420 libnx_state.connection_status.is_left_connected.Assign(1);
562 dual_entry.pad.r_stick = pad_state.r_stick; 421 libnx_state.connection_status.is_right_connected.Assign(1);
563 422 pad_state.sampling_number =
564 libnx_entry.connection_status.is_left_connected.Assign(1); 423 npad.joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1;
565 libnx_entry.connection_status.is_right_connected.Assign(1); 424 npad.joy_dual_lifo.WriteNextEntry(pad_state);
566 break; 425 break;
567 case NPadControllerType::JoyLeft: 426 case Core::HID::NpadType::JoyconLeft:
568 left_entry.connection_status.raw = 0; 427 pad_state.connection_status.raw = 0;
569 left_entry.connection_status.is_connected.Assign(1); 428 pad_state.connection_status.is_connected.Assign(1);
570 left_entry.connection_status.is_left_connected.Assign(1); 429 pad_state.connection_status.is_left_connected.Assign(1);
571 left_entry.pad.pad_states.raw = pad_state.pad_states.raw; 430
572 left_entry.pad.l_stick = pad_state.l_stick; 431 libnx_state.connection_status.is_left_connected.Assign(1);
573 left_entry.pad.r_stick = pad_state.r_stick; 432 pad_state.sampling_number =
574 433 npad.joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
575 libnx_entry.connection_status.is_left_connected.Assign(1); 434 npad.joy_left_lifo.WriteNextEntry(pad_state);
576 break; 435 break;
577 case NPadControllerType::JoyRight: 436 case Core::HID::NpadType::JoyconRight:
578 right_entry.connection_status.raw = 0; 437 pad_state.connection_status.raw = 0;
579 right_entry.connection_status.is_connected.Assign(1); 438 pad_state.connection_status.is_connected.Assign(1);
580 right_entry.connection_status.is_right_connected.Assign(1); 439 pad_state.connection_status.is_right_connected.Assign(1);
581 right_entry.pad.pad_states.raw = pad_state.pad_states.raw; 440
582 right_entry.pad.l_stick = pad_state.l_stick; 441 libnx_state.connection_status.is_right_connected.Assign(1);
583 right_entry.pad.r_stick = pad_state.r_stick; 442 pad_state.sampling_number =
584 443 npad.joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
585 libnx_entry.connection_status.is_right_connected.Assign(1); 444 npad.joy_right_lifo.WriteNextEntry(pad_state);
586 break; 445 break;
587 case NPadControllerType::GameCube: 446 case Core::HID::NpadType::GameCube:
588 main_controller.connection_status.raw = 0; 447 pad_state.connection_status.raw = 0;
589 main_controller.connection_status.is_connected.Assign(1); 448 pad_state.connection_status.is_connected.Assign(1);
590 main_controller.connection_status.is_wired.Assign(1); 449 pad_state.connection_status.is_wired.Assign(1);
591 main_controller.pad.pad_states.raw = pad_state.pad_states.raw; 450
592 main_controller.pad.l_stick = pad_state.l_stick; 451 libnx_state.connection_status.is_wired.Assign(1);
593 main_controller.pad.r_stick = pad_state.r_stick; 452 pad_state.sampling_number =
594 trigger_entry.l_analog = trigger_state.l_analog; 453 npad.fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
595 trigger_entry.r_analog = trigger_state.r_analog; 454 trigger_state.sampling_number =
596 455 npad.gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1;
597 libnx_entry.connection_status.is_wired.Assign(1); 456 npad.fullkey_lifo.WriteNextEntry(pad_state);
457 npad.gc_trigger_lifo.WriteNextEntry(trigger_state);
598 break; 458 break;
599 case NPadControllerType::Pokeball: 459 case Core::HID::NpadType::Pokeball:
600 pokeball_entry.connection_status.raw = 0; 460 pad_state.connection_status.raw = 0;
601 pokeball_entry.connection_status.is_connected.Assign(1); 461 pad_state.connection_status.is_connected.Assign(1);
602 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; 462 pad_state.sampling_number =
603 pokeball_entry.pad.l_stick = pad_state.l_stick; 463 npad.palma_lifo.ReadCurrentEntry().state.sampling_number + 1;
604 pokeball_entry.pad.r_stick = pad_state.r_stick; 464 npad.palma_lifo.WriteNextEntry(pad_state);
465 break;
466 default:
605 break; 467 break;
606 } 468 }
607 469
608 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate 470 libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw;
609 // any controllers. 471 libnx_state.l_stick = pad_state.l_stick;
610 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; 472 libnx_state.r_stick = pad_state.r_stick;
611 libnx_entry.pad.l_stick = pad_state.l_stick; 473 npad.system_ext_lifo.WriteNextEntry(pad_state);
612 libnx_entry.pad.r_stick = pad_state.r_stick; 474
475 press_state |= static_cast<u32>(pad_state.npad_buttons.raw);
613 476
614 press_state |= static_cast<u32>(pad_state.pad_states.raw); 477 std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
478 &controller.shared_memory_entry, sizeof(NpadInternalState));
615 } 479 }
616 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
617 shared_memory_entries.size() * sizeof(NPadEntry));
618} 480}
619 481
620void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 482void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
@@ -622,145 +484,130 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
622 if (!IsControllerActivated()) { 484 if (!IsControllerActivated()) {
623 return; 485 return;
624 } 486 }
625 for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
626 auto& npad = shared_memory_entries[i];
627 487
628 const auto& controller_type = connected_controllers[i].type; 488 for (std::size_t i = 0; i < controller_data.size(); ++i) {
629 489 auto& controller = controller_data[i];
630 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
631 continue;
632 }
633 490
634 const std::array<SixAxisGeneric*, 6> controller_sixaxes{ 491 const auto& controller_type = controller.device->GetNpadType();
635 &npad.sixaxis_fullkey, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
636 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
637 };
638 492
639 for (auto* sixaxis_sensor : controller_sixaxes) { 493 if (controller_type == Core::HID::NpadType::None || !controller.device->IsConnected()) {
640 sixaxis_sensor->common.entry_count = 16; 494 continue;
641 sixaxis_sensor->common.total_entry_count = 17;
642
643 const auto& last_entry =
644 sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
645
646 sixaxis_sensor->common.timestamp = core_timing.GetCPUTicks();
647 sixaxis_sensor->common.last_entry_index =
648 (sixaxis_sensor->common.last_entry_index + 1) % 17;
649
650 auto& cur_entry = sixaxis_sensor->sixaxis[sixaxis_sensor->common.last_entry_index];
651
652 cur_entry.timestamp = last_entry.timestamp + 1;
653 cur_entry.timestamp2 = cur_entry.timestamp;
654 } 495 }
655 496
656 // Try to read sixaxis sensor states 497 auto& npad = controller.shared_memory_entry;
657 std::array<MotionDevice, 2> motion_devices; 498 const auto& motion_state = controller.device->GetMotions();
499 auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state;
500 auto& sixaxis_handheld_state = controller.sixaxis_handheld_state;
501 auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state;
502 auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state;
503 auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
504 auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
658 505
659 if (sixaxis_sensors_enabled && Settings::values.motion_enabled.GetValue()) { 506 if (sixaxis_sensors_enabled && Settings::values.motion_enabled.GetValue()) {
660 sixaxis_at_rest = true; 507 sixaxis_at_rest = true;
661 for (std::size_t e = 0; e < motion_devices.size(); ++e) { 508 for (std::size_t e = 0; e < motion_state.size(); ++e) {
662 const auto& device = motions[i][e]; 509 sixaxis_at_rest = sixaxis_at_rest && motion_state[e].is_at_rest;
663 if (device) {
664 std::tie(motion_devices[e].accel, motion_devices[e].gyro,
665 motion_devices[e].rotation, motion_devices[e].orientation,
666 motion_devices[e].quaternion) = device->GetStatus();
667 sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f;
668 }
669 } 510 }
670 } 511 }
671 512
672 auto& full_sixaxis_entry =
673 npad.sixaxis_fullkey.sixaxis[npad.sixaxis_fullkey.common.last_entry_index];
674 auto& handheld_sixaxis_entry =
675 npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
676 auto& dual_left_sixaxis_entry =
677 npad.sixaxis_dual_left.sixaxis[npad.sixaxis_dual_left.common.last_entry_index];
678 auto& dual_right_sixaxis_entry =
679 npad.sixaxis_dual_right.sixaxis[npad.sixaxis_dual_right.common.last_entry_index];
680 auto& left_sixaxis_entry =
681 npad.sixaxis_left.sixaxis[npad.sixaxis_left.common.last_entry_index];
682 auto& right_sixaxis_entry =
683 npad.sixaxis_right.sixaxis[npad.sixaxis_right.common.last_entry_index];
684
685 switch (controller_type) { 513 switch (controller_type) {
686 case NPadControllerType::None: 514 case Core::HID::NpadType::None:
687 UNREACHABLE(); 515 UNREACHABLE();
688 break; 516 break;
689 case NPadControllerType::ProController: 517 case Core::HID::NpadType::ProController:
690 full_sixaxis_entry.attribute.raw = 0; 518 sixaxis_fullkey_state.attribute.raw = 0;
691 if (sixaxis_sensors_enabled && motions[i][0]) { 519 if (sixaxis_sensors_enabled) {
692 full_sixaxis_entry.attribute.is_connected.Assign(1); 520 sixaxis_fullkey_state.attribute.is_connected.Assign(1);
693 full_sixaxis_entry.accel = motion_devices[0].accel; 521 sixaxis_fullkey_state.accel = motion_state[0].accel;
694 full_sixaxis_entry.gyro = motion_devices[0].gyro; 522 sixaxis_fullkey_state.gyro = motion_state[0].gyro;
695 full_sixaxis_entry.rotation = motion_devices[0].rotation; 523 sixaxis_fullkey_state.rotation = motion_state[0].rotation;
696 full_sixaxis_entry.orientation = motion_devices[0].orientation; 524 sixaxis_fullkey_state.orientation = motion_state[0].orientation;
697 } 525 }
698 break; 526 break;
699 case NPadControllerType::Handheld: 527 case Core::HID::NpadType::Handheld:
700 handheld_sixaxis_entry.attribute.raw = 0; 528 sixaxis_handheld_state.attribute.raw = 0;
701 if (sixaxis_sensors_enabled && motions[i][0]) { 529 if (sixaxis_sensors_enabled) {
702 handheld_sixaxis_entry.attribute.is_connected.Assign(1); 530 sixaxis_handheld_state.attribute.is_connected.Assign(1);
703 handheld_sixaxis_entry.accel = motion_devices[0].accel; 531 sixaxis_handheld_state.accel = motion_state[0].accel;
704 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; 532 sixaxis_handheld_state.gyro = motion_state[0].gyro;
705 handheld_sixaxis_entry.rotation = motion_devices[0].rotation; 533 sixaxis_handheld_state.rotation = motion_state[0].rotation;
706 handheld_sixaxis_entry.orientation = motion_devices[0].orientation; 534 sixaxis_handheld_state.orientation = motion_state[0].orientation;
707 } 535 }
708 break; 536 break;
709 case NPadControllerType::JoyDual: 537 case Core::HID::NpadType::JoyconDual:
710 dual_left_sixaxis_entry.attribute.raw = 0; 538 sixaxis_dual_left_state.attribute.raw = 0;
711 dual_right_sixaxis_entry.attribute.raw = 0; 539 sixaxis_dual_right_state.attribute.raw = 0;
712 if (sixaxis_sensors_enabled && motions[i][0]) { 540 if (sixaxis_sensors_enabled) {
713 // Set motion for the left joycon 541 // Set motion for the left joycon
714 dual_left_sixaxis_entry.attribute.is_connected.Assign(1); 542 sixaxis_dual_left_state.attribute.is_connected.Assign(1);
715 dual_left_sixaxis_entry.accel = motion_devices[0].accel; 543 sixaxis_dual_left_state.accel = motion_state[0].accel;
716 dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; 544 sixaxis_dual_left_state.gyro = motion_state[0].gyro;
717 dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; 545 sixaxis_dual_left_state.rotation = motion_state[0].rotation;
718 dual_left_sixaxis_entry.orientation = motion_devices[0].orientation; 546 sixaxis_dual_left_state.orientation = motion_state[0].orientation;
719 } 547 }
720 if (sixaxis_sensors_enabled && motions[i][1]) { 548 if (sixaxis_sensors_enabled) {
721 // Set motion for the right joycon 549 // Set motion for the right joycon
722 dual_right_sixaxis_entry.attribute.is_connected.Assign(1); 550 sixaxis_dual_right_state.attribute.is_connected.Assign(1);
723 dual_right_sixaxis_entry.accel = motion_devices[1].accel; 551 sixaxis_dual_right_state.accel = motion_state[1].accel;
724 dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; 552 sixaxis_dual_right_state.gyro = motion_state[1].gyro;
725 dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; 553 sixaxis_dual_right_state.rotation = motion_state[1].rotation;
726 dual_right_sixaxis_entry.orientation = motion_devices[1].orientation; 554 sixaxis_dual_right_state.orientation = motion_state[1].orientation;
727 } 555 }
728 break; 556 break;
729 case NPadControllerType::JoyLeft: 557 case Core::HID::NpadType::JoyconLeft:
730 left_sixaxis_entry.attribute.raw = 0; 558 sixaxis_left_lifo_state.attribute.raw = 0;
731 if (sixaxis_sensors_enabled && motions[i][0]) { 559 if (sixaxis_sensors_enabled) {
732 left_sixaxis_entry.attribute.is_connected.Assign(1); 560 sixaxis_left_lifo_state.attribute.is_connected.Assign(1);
733 left_sixaxis_entry.accel = motion_devices[0].accel; 561 sixaxis_left_lifo_state.accel = motion_state[0].accel;
734 left_sixaxis_entry.gyro = motion_devices[0].gyro; 562 sixaxis_left_lifo_state.gyro = motion_state[0].gyro;
735 left_sixaxis_entry.rotation = motion_devices[0].rotation; 563 sixaxis_left_lifo_state.rotation = motion_state[0].rotation;
736 left_sixaxis_entry.orientation = motion_devices[0].orientation; 564 sixaxis_left_lifo_state.orientation = motion_state[0].orientation;
737 } 565 }
738 break; 566 break;
739 case NPadControllerType::JoyRight: 567 case Core::HID::NpadType::JoyconRight:
740 right_sixaxis_entry.attribute.raw = 0; 568 sixaxis_right_lifo_state.attribute.raw = 0;
741 if (sixaxis_sensors_enabled && motions[i][1]) { 569 if (sixaxis_sensors_enabled) {
742 right_sixaxis_entry.attribute.is_connected.Assign(1); 570 sixaxis_right_lifo_state.attribute.is_connected.Assign(1);
743 right_sixaxis_entry.accel = motion_devices[1].accel; 571 sixaxis_right_lifo_state.accel = motion_state[1].accel;
744 right_sixaxis_entry.gyro = motion_devices[1].gyro; 572 sixaxis_right_lifo_state.gyro = motion_state[1].gyro;
745 right_sixaxis_entry.rotation = motion_devices[1].rotation; 573 sixaxis_right_lifo_state.rotation = motion_state[1].rotation;
746 right_sixaxis_entry.orientation = motion_devices[1].orientation; 574 sixaxis_right_lifo_state.orientation = motion_state[1].orientation;
747 } 575 }
748 break; 576 break;
749 case NPadControllerType::GameCube: 577 default:
750 case NPadControllerType::Pokeball:
751 break; 578 break;
752 } 579 }
580
581 sixaxis_fullkey_state.sampling_number =
582 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
583 sixaxis_handheld_state.sampling_number =
584 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
585 sixaxis_dual_left_state.sampling_number =
586 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
587 sixaxis_dual_right_state.sampling_number =
588 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
589 sixaxis_left_lifo_state.sampling_number =
590 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
591 sixaxis_right_lifo_state.sampling_number =
592 npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
593
594 npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
595 npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
596 npad.sixaxis_dual_left_lifo.WriteNextEntry(sixaxis_dual_left_state);
597 npad.sixaxis_dual_right_lifo.WriteNextEntry(sixaxis_dual_right_state);
598 npad.sixaxis_left_lifo.WriteNextEntry(sixaxis_left_lifo_state);
599 npad.sixaxis_right_lifo.WriteNextEntry(sixaxis_right_lifo_state);
600 std::memcpy(data + NPAD_OFFSET + (i * sizeof(NpadInternalState)),
601 &controller.shared_memory_entry, sizeof(NpadInternalState));
753 } 602 }
754 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
755 shared_memory_entries.size() * sizeof(NPadEntry));
756} 603}
757 604
758void Controller_NPad::SetSupportedStyleSet(NpadStyleSet style_set) { 605void Controller_NPad::SetSupportedStyleSet(Core::HID::NpadStyleTag style_set) {
759 style.raw = style_set.raw; 606 system.HIDCore().SetSupportedStyleTag(style_set);
760} 607}
761 608
762Controller_NPad::NpadStyleSet Controller_NPad::GetSupportedStyleSet() const { 609Core::HID::NpadStyleTag Controller_NPad::GetSupportedStyleSet() const {
763 return style; 610 return system.HIDCore().GetSupportedStyleTag();
764} 611}
765 612
766void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) { 613void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) {
@@ -779,11 +626,11 @@ std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
779 return supported_npad_id_types.size(); 626 return supported_npad_id_types.size();
780} 627}
781 628
782void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) { 629void Controller_NPad::SetHoldType(NpadJoyHoldType joy_hold_type) {
783 hold_type = joy_hold_type; 630 hold_type = joy_hold_type;
784} 631}
785 632
786Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const { 633Controller_NPad::NpadJoyHoldType Controller_NPad::GetHoldType() const {
787 return hold_type; 634 return hold_type;
788} 635}
789 636
@@ -803,29 +650,31 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
803 return communication_mode; 650 return communication_mode;
804} 651}
805 652
806void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { 653void Controller_NPad::SetNpadMode(u32 npad_id, NpadJoyAssignmentMode assignment_mode) {
807 const std::size_t npad_index = NPadIdToIndex(npad_id); 654 const std::size_t npad_index = NPadIdToIndex(npad_id);
808 ASSERT(npad_index < shared_memory_entries.size()); 655 ASSERT(npad_index < controller_data.size());
809 if (shared_memory_entries[npad_index].assignment_mode != assignment_mode) { 656 auto& controller = controller_data[npad_index];
810 shared_memory_entries[npad_index].assignment_mode = assignment_mode; 657 if (controller.shared_memory_entry.assignment_mode != assignment_mode) {
658 controller.shared_memory_entry.assignment_mode = assignment_mode;
811 } 659 }
812} 660}
813 661
814bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, 662bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
815 const VibrationValue& vibration_value) { 663 const VibrationValue& vibration_value) {
816 if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) { 664 auto& controller = controller_data[npad_index];
665
666 if (!controller.device->IsConnected()) {
817 return false; 667 return false;
818 } 668 }
819 669
820 const auto& player = Settings::values.players.GetValue()[npad_index]; 670 if (!controller.device->IsVibrationEnabled()) {
821 671 if (controller.vibration[device_index].latest_vibration_value.amp_low != 0.0f ||
822 if (!player.vibration_enabled) { 672 controller.vibration[device_index].latest_vibration_value.amp_high != 0.0f) {
823 if (latest_vibration_values[npad_index][device_index].amp_low != 0.0f ||
824 latest_vibration_values[npad_index][device_index].amp_high != 0.0f) {
825 // Send an empty vibration to stop any vibrations. 673 // Send an empty vibration to stop any vibrations.
826 vibrations[npad_index][device_index]->SetRumblePlay(0.0f, 160.0f, 0.0f, 320.0f); 674 Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f};
675 controller.device->SetVibration(device_index, vibration);
827 // Then reset the vibration value to its default value. 676 // Then reset the vibration value to its default value.
828 latest_vibration_values[npad_index][device_index] = DEFAULT_VIBRATION_VALUE; 677 controller.vibration[device_index].latest_vibration_value = DEFAULT_VIBRATION_VALUE;
829 } 678 }
830 679
831 return false; 680 return false;
@@ -840,22 +689,18 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
840 689
841 // Filter out non-zero vibrations that are within 10ms of each other. 690 // Filter out non-zero vibrations that are within 10ms of each other.
842 if ((vibration_value.amp_low != 0.0f || vibration_value.amp_high != 0.0f) && 691 if ((vibration_value.amp_low != 0.0f || vibration_value.amp_high != 0.0f) &&
843 duration_cast<milliseconds>(now - last_vibration_timepoints[npad_index][device_index]) < 692 duration_cast<milliseconds>(
693 now - controller.vibration[device_index].last_vibration_timepoint) <
844 milliseconds(10)) { 694 milliseconds(10)) {
845 return false; 695 return false;
846 } 696 }
847 697
848 last_vibration_timepoints[npad_index][device_index] = now; 698 controller.vibration[device_index].last_vibration_timepoint = now;
849 } 699 }
850 700
851 auto& vibration = vibrations[npad_index][device_index]; 701 Core::HID::VibrationValue vibration{vibration_value.amp_low, vibration_value.freq_low,
852 const auto player_vibration_strength = static_cast<f32>(player.vibration_strength); 702 vibration_value.amp_high, vibration_value.freq_high};
853 const auto amp_low = 703 return controller.device->SetVibration(device_index, vibration);
854 std::min(vibration_value.amp_low * player_vibration_strength / 100.0f, 1.0f);
855 const auto amp_high =
856 std::min(vibration_value.amp_high * player_vibration_strength / 100.0f, 1.0f);
857 return vibration->SetRumblePlay(amp_low, vibration_value.freq_low, amp_high,
858 vibration_value.freq_high);
859} 704}
860 705
861void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle, 706void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
@@ -869,10 +714,10 @@ void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_han
869 } 714 }
870 715
871 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 716 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
717 auto& controller = controller_data[npad_index];
872 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 718 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
873 719
874 if (!vibration_devices_mounted[npad_index][device_index] || 720 if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) {
875 !connected_controllers[npad_index].is_connected) {
876 return; 721 return;
877 } 722 }
878 723
@@ -882,23 +727,25 @@ void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_han
882 } 727 }
883 728
884 // Some games try to send mismatched parameters in the device handle, block these. 729 // Some games try to send mismatched parameters in the device handle, block these.
885 if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && 730 if ((controller.device->GetNpadType() == Core::HID::NpadType::JoyconLeft &&
886 (vibration_device_handle.npad_type == NpadType::JoyconRight || 731 (vibration_device_handle.npad_type == Core::HID::NpadType::JoyconRight ||
887 vibration_device_handle.device_index == DeviceIndex::Right)) || 732 vibration_device_handle.device_index == DeviceIndex::Right)) ||
888 (connected_controllers[npad_index].type == NPadControllerType::JoyRight && 733 (controller.device->GetNpadType() == Core::HID::NpadType::JoyconRight &&
889 (vibration_device_handle.npad_type == NpadType::JoyconLeft || 734 (vibration_device_handle.npad_type == Core::HID::NpadType::JoyconLeft ||
890 vibration_device_handle.device_index == DeviceIndex::Left))) { 735 vibration_device_handle.device_index == DeviceIndex::Left))) {
891 return; 736 return;
892 } 737 }
893 738
894 // Filter out vibrations with equivalent values to reduce unnecessary state changes. 739 // Filter out vibrations with equivalent values to reduce unnecessary state changes.
895 if (vibration_value.amp_low == latest_vibration_values[npad_index][device_index].amp_low && 740 if (vibration_value.amp_low ==
896 vibration_value.amp_high == latest_vibration_values[npad_index][device_index].amp_high) { 741 controller.vibration[device_index].latest_vibration_value.amp_low &&
742 vibration_value.amp_high ==
743 controller.vibration[device_index].latest_vibration_value.amp_high) {
897 return; 744 return;
898 } 745 }
899 746
900 if (VibrateControllerAtIndex(npad_index, device_index, vibration_value)) { 747 if (VibrateControllerAtIndex(npad_index, device_index, vibration_value)) {
901 latest_vibration_values[npad_index][device_index] = vibration_value; 748 controller.vibration[device_index].latest_vibration_value = vibration_value;
902 } 749 }
903} 750}
904 751
@@ -925,8 +772,9 @@ Controller_NPad::VibrationValue Controller_NPad::GetLastVibration(
925 } 772 }
926 773
927 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 774 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
775 const auto& controller = controller_data[npad_index];
928 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 776 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
929 return latest_vibration_values[npad_index][device_index]; 777 return controller.vibration[device_index].latest_vibration_value;
930} 778}
931 779
932void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) { 780void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_device_handle) {
@@ -941,17 +789,14 @@ void Controller_NPad::InitializeVibrationDevice(const DeviceHandle& vibration_de
941 789
942void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index, 790void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index,
943 std::size_t device_index) { 791 std::size_t device_index) {
792 auto& controller = controller_data[npad_index];
944 if (!Settings::values.vibration_enabled.GetValue()) { 793 if (!Settings::values.vibration_enabled.GetValue()) {
945 vibration_devices_mounted[npad_index][device_index] = false; 794 controller.vibration[device_index].device_mounted = false;
946 return; 795 return;
947 } 796 }
948 797
949 if (vibrations[npad_index][device_index]) { 798 controller.vibration[device_index].device_mounted =
950 vibration_devices_mounted[npad_index][device_index] = 799 controller.device->TestVibration(device_index) == 1;
951 vibrations[npad_index][device_index]->GetStatus() == 1;
952 } else {
953 vibration_devices_mounted[npad_index][device_index] = false;
954 }
955} 800}
956 801
957void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { 802void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
@@ -964,42 +809,35 @@ bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_dev
964 } 809 }
965 810
966 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); 811 const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id);
812 const auto& controller = controller_data[npad_index];
967 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); 813 const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index);
968 return vibration_devices_mounted[npad_index][device_index]; 814 return controller.vibration[device_index].device_mounted;
969} 815}
970 816
971Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) { 817Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) {
972 return styleset_changed_events[NPadIdToIndex(npad_id)]->GetReadableEvent(); 818 const auto& controller = controller_data[NPadIdToIndex(npad_id)];
819 return controller.styleset_changed_event->GetReadableEvent();
973} 820}
974 821
975void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const { 822void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const {
976 styleset_changed_events[NPadIdToIndex(npad_id)]->GetWritableEvent().Signal(); 823 const auto& controller = controller_data[NPadIdToIndex(npad_id)];
824 controller.styleset_changed_event->GetWritableEvent().Signal();
977} 825}
978 826
979void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) { 827void Controller_NPad::AddNewControllerAt(Core::HID::NpadType controller, std::size_t npad_index) {
980 UpdateControllerAt(controller, npad_index, true); 828 UpdateControllerAt(controller, npad_index, true);
981} 829}
982 830
983void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, 831void Controller_NPad::UpdateControllerAt(Core::HID::NpadType type, std::size_t npad_index,
984 bool connected) { 832 bool connected) {
833 auto& controller = controller_data[npad_index].device;
985 if (!connected) { 834 if (!connected) {
986 DisconnectNpadAtIndex(npad_index); 835 DisconnectNpadAtIndex(npad_index);
987 return; 836 return;
988 } 837 }
989 838
990 if (controller == NPadControllerType::Handheld && npad_index == HANDHELD_INDEX) { 839 controller->SetNpadType(type);
991 Settings::values.players.GetValue()[HANDHELD_INDEX].controller_type = 840 controller->Connect();
992 MapNPadToSettingsType(controller);
993 Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
994 connected_controllers[HANDHELD_INDEX] = {controller, true};
995 InitNewlyAddedController(HANDHELD_INDEX);
996 return;
997 }
998
999 Settings::values.players.GetValue()[npad_index].controller_type =
1000 MapNPadToSettingsType(controller);
1001 Settings::values.players.GetValue()[npad_index].connected = true;
1002 connected_controllers[npad_index] = {controller, true};
1003 InitNewlyAddedController(npad_index); 841 InitNewlyAddedController(npad_index);
1004} 842}
1005 843
@@ -1008,27 +846,27 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) {
1008} 846}
1009 847
1010void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { 848void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
1011 for (std::size_t device_idx = 0; device_idx < vibrations[npad_index].size(); ++device_idx) { 849 auto& controller = controller_data[npad_index];
850 for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
1012 // Send an empty vibration to stop any vibrations. 851 // Send an empty vibration to stop any vibrations.
1013 VibrateControllerAtIndex(npad_index, device_idx, {}); 852 VibrateControllerAtIndex(npad_index, device_idx, {});
1014 vibration_devices_mounted[npad_index][device_idx] = false; 853 controller.vibration[device_idx].device_mounted = false;
1015 } 854 }
1016 855
1017 Settings::values.players.GetValue()[npad_index].connected = false; 856 controller.device->Disconnect();
1018 connected_controllers[npad_index].is_connected = false; 857
1019 858 auto& shared_memory_entry = controller.shared_memory_entry;
1020 auto& controller = shared_memory_entries[npad_index]; 859 shared_memory_entry.style_set.raw = 0; // Zero out
1021 controller.style_set.raw = 0; // Zero out 860 shared_memory_entry.device_type.raw = 0;
1022 controller.device_type.raw = 0; 861 shared_memory_entry.system_properties.raw = 0;
1023 controller.system_properties.raw = 0; 862 shared_memory_entry.button_properties.raw = 0;
1024 controller.button_properties.raw = 0; 863 shared_memory_entry.battery_level_dual = 0;
1025 controller.battery_level_dual = 0; 864 shared_memory_entry.battery_level_left = 0;
1026 controller.battery_level_left = 0; 865 shared_memory_entry.battery_level_right = 0;
1027 controller.battery_level_right = 0; 866 shared_memory_entry.fullkey_color = {};
1028 controller.fullkey_color = {}; 867 shared_memory_entry.joycon_color = {};
1029 controller.joycon_color = {}; 868 shared_memory_entry.assignment_mode = NpadJoyAssignmentMode::Dual;
1030 controller.assignment_mode = NpadAssignments::Dual; 869 shared_memory_entry.footer_type = AppletFooterUiType::None;
1031 controller.footer_type = AppletFooterUiType::None;
1032 870
1033 SignalStyleSetChangedEvent(IndexToNPad(npad_index)); 871 SignalStyleSetChangedEvent(IndexToNPad(npad_index));
1034} 872}
@@ -1069,16 +907,18 @@ void Controller_NPad::ResetSixAxisFusionParameters() {
1069void Controller_NPad::MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2) { 907void Controller_NPad::MergeSingleJoyAsDualJoy(u32 npad_id_1, u32 npad_id_2) {
1070 const auto npad_index_1 = NPadIdToIndex(npad_id_1); 908 const auto npad_index_1 = NPadIdToIndex(npad_id_1);
1071 const auto npad_index_2 = NPadIdToIndex(npad_id_2); 909 const auto npad_index_2 = NPadIdToIndex(npad_id_2);
910 const auto& controller_1 = controller_data[npad_index_1].device;
911 const auto& controller_2 = controller_data[npad_index_2].device;
1072 912
1073 // If the controllers at both npad indices form a pair of left and right joycons, merge them. 913 // If the controllers at both npad indices form a pair of left and right joycons, merge them.
1074 // Otherwise, do nothing. 914 // Otherwise, do nothing.
1075 if ((connected_controllers[npad_index_1].type == NPadControllerType::JoyLeft && 915 if ((controller_1->GetNpadType() == Core::HID::NpadType::JoyconLeft &&
1076 connected_controllers[npad_index_2].type == NPadControllerType::JoyRight) || 916 controller_2->GetNpadType() == Core::HID::NpadType::JoyconRight) ||
1077 (connected_controllers[npad_index_2].type == NPadControllerType::JoyLeft && 917 (controller_2->GetNpadType() == Core::HID::NpadType::JoyconLeft &&
1078 connected_controllers[npad_index_1].type == NPadControllerType::JoyRight)) { 918 controller_1->GetNpadType() == Core::HID::NpadType::JoyconRight)) {
1079 // Disconnect the joycon at the second id and connect the dual joycon at the first index. 919 // Disconnect the joycon at the second id and connect the dual joycon at the first index.
1080 DisconnectNpad(npad_id_2); 920 DisconnectNpad(npad_id_2);
1081 AddNewControllerAt(NPadControllerType::JoyDual, npad_index_1); 921 AddNewControllerAt(Core::HID::NpadType::JoyconDual, npad_index_1);
1082 } 922 }
1083} 923}
1084 924
@@ -1099,16 +939,17 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
1099 } 939 }
1100 const auto npad_index_1 = NPadIdToIndex(npad_id_1); 940 const auto npad_index_1 = NPadIdToIndex(npad_id_1);
1101 const auto npad_index_2 = NPadIdToIndex(npad_id_2); 941 const auto npad_index_2 = NPadIdToIndex(npad_id_2);
942 const auto& controller_1 = controller_data[npad_index_1].device;
943 const auto& controller_2 = controller_data[npad_index_2].device;
944 const auto type_index_1 = controller_1->GetNpadType();
945 const auto type_index_2 = controller_2->GetNpadType();
1102 946
1103 if (!IsControllerSupported(connected_controllers[npad_index_1].type) || 947 if (!IsControllerSupported(type_index_1) || !IsControllerSupported(type_index_2)) {
1104 !IsControllerSupported(connected_controllers[npad_index_2].type)) {
1105 return false; 948 return false;
1106 } 949 }
1107 950
1108 std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type); 951 AddNewControllerAt(type_index_2, npad_index_1);
1109 952 AddNewControllerAt(type_index_1, npad_index_2);
1110 AddNewControllerAt(connected_controllers[npad_index_1].type, npad_index_1);
1111 AddNewControllerAt(connected_controllers[npad_index_2].type, npad_index_2);
1112 953
1113 return true; 954 return true;
1114} 955}
@@ -1141,12 +982,14 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
1141} 982}
1142 983
1143bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { 984bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const {
1144 return unintended_home_button_input_protection[NPadIdToIndex(npad_id)]; 985 auto& controller = controller_data[NPadIdToIndex(npad_id)];
986 return controller.unintended_home_button_input_protection;
1145} 987}
1146 988
1147void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, 989void Controller_NPad::SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled,
1148 u32 npad_id) { 990 u32 npad_id) {
1149 unintended_home_button_input_protection[NPadIdToIndex(npad_id)] = is_protection_enabled; 991 auto& controller = controller_data[NPadIdToIndex(npad_id)];
992 controller.unintended_home_button_input_protection = is_protection_enabled;
1150} 993}
1151 994
1152void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) { 995void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
@@ -1154,32 +997,34 @@ void Controller_NPad::SetAnalogStickUseCenterClamp(bool use_center_clamp) {
1154} 997}
1155 998
1156void Controller_NPad::ClearAllConnectedControllers() { 999void Controller_NPad::ClearAllConnectedControllers() {
1157 for (auto& controller : connected_controllers) { 1000 for (auto& controller : controller_data) {
1158 if (controller.is_connected && controller.type != NPadControllerType::None) { 1001 if (controller.device->IsConnected() &&
1159 controller.type = NPadControllerType::None; 1002 controller.device->GetNpadType() != Core::HID::NpadType::None) {
1160 controller.is_connected = false; 1003 controller.device->SetNpadType(Core::HID::NpadType::None);
1004 controller.device->Disconnect();
1161 } 1005 }
1162 } 1006 }
1163} 1007}
1164 1008
1165void Controller_NPad::DisconnectAllConnectedControllers() { 1009void Controller_NPad::DisconnectAllConnectedControllers() {
1166 for (auto& controller : connected_controllers) { 1010 for (auto& controller : controller_data) {
1167 controller.is_connected = false; 1011 controller.device->Disconnect();
1168 } 1012 }
1169} 1013}
1170 1014
1171void Controller_NPad::ConnectAllDisconnectedControllers() { 1015void Controller_NPad::ConnectAllDisconnectedControllers() {
1172 for (auto& controller : connected_controllers) { 1016 for (auto& controller : controller_data) {
1173 if (controller.type != NPadControllerType::None && !controller.is_connected) { 1017 if (controller.device->GetNpadType() != Core::HID::NpadType::None &&
1174 controller.is_connected = true; 1018 !controller.device->IsConnected()) {
1019 controller.device->Connect();
1175 } 1020 }
1176 } 1021 }
1177} 1022}
1178 1023
1179void Controller_NPad::ClearAllControllers() { 1024void Controller_NPad::ClearAllControllers() {
1180 for (auto& controller : connected_controllers) { 1025 for (auto& controller : controller_data) {
1181 controller.type = NPadControllerType::None; 1026 controller.device->SetNpadType(Core::HID::NpadType::None);
1182 controller.is_connected = false; 1027 controller.device->Disconnect();
1183 } 1028 }
1184} 1029}
1185 1030
@@ -1187,8 +1032,8 @@ u32 Controller_NPad::GetAndResetPressState() {
1187 return press_state.exchange(0); 1032 return press_state.exchange(0);
1188} 1033}
1189 1034
1190bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { 1035bool Controller_NPad::IsControllerSupported(Core::HID::NpadType controller) const {
1191 if (controller == NPadControllerType::Handheld) { 1036 if (controller == Core::HID::NpadType::Handheld) {
1192 const bool support_handheld = 1037 const bool support_handheld =
1193 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 1038 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
1194 NPAD_HANDHELD) != supported_npad_id_types.end(); 1039 NPAD_HANDHELD) != supported_npad_id_types.end();
@@ -1196,7 +1041,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
1196 if (!support_handheld) { 1041 if (!support_handheld) {
1197 return false; 1042 return false;
1198 } 1043 }
1199 // Handheld should not be supported in docked mode 1044 // Handheld shouldn't be supported in docked mode
1200 if (Settings::values.use_docked_mode.GetValue()) { 1045 if (Settings::values.use_docked_mode.GetValue()) {
1201 return false; 1046 return false;
1202 } 1047 }
@@ -1206,18 +1051,19 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
1206 1051
1207 if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(), 1052 if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(),
1208 [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { 1053 [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) {
1054 Core::HID::NpadStyleTag style = GetSupportedStyleSet();
1209 switch (controller) { 1055 switch (controller) {
1210 case NPadControllerType::ProController: 1056 case Core::HID::NpadType::ProController:
1211 return style.fullkey; 1057 return style.fullkey;
1212 case NPadControllerType::JoyDual: 1058 case Core::HID::NpadType::JoyconDual:
1213 return style.joycon_dual; 1059 return style.joycon_dual;
1214 case NPadControllerType::JoyLeft: 1060 case Core::HID::NpadType::JoyconLeft:
1215 return style.joycon_left; 1061 return style.joycon_left;
1216 case NPadControllerType::JoyRight: 1062 case Core::HID::NpadType::JoyconRight:
1217 return style.joycon_right; 1063 return style.joycon_right;
1218 case NPadControllerType::GameCube: 1064 case Core::HID::NpadType::GameCube:
1219 return style.gamecube; 1065 return style.gamecube;
1220 case NPadControllerType::Pokeball: 1066 case Core::HID::NpadType::Pokeball:
1221 return style.palma; 1067 return style.palma;
1222 default: 1068 default:
1223 return false; 1069 return false;
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index f3e868bdb..483cae5b6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -12,8 +12,10 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/quaternion.h" 13#include "common/quaternion.h"
14#include "common/settings.h" 14#include "common/settings.h"
15#include "core/frontend/input.h" 15#include "core/hid/hid_core.h"
16#include "core/hid/hid_types.h"
16#include "core/hle/service/hid/controllers/controller_base.h" 17#include "core/hle/service/hid/controllers/controller_base.h"
18#include "core/hle/service/hid/ring_lifo.h"
17 19
18namespace Kernel { 20namespace Kernel {
19class KEvent; 21class KEvent;
@@ -48,31 +50,6 @@ public:
48 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, 50 void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing, u8* data,
49 std::size_t size) override; 51 std::size_t size) override;
50 52
51 // Called when input devices should be loaded
52 void OnLoadInputDevices() override;
53
54 enum class NPadControllerType {
55 None,
56 ProController,
57 Handheld,
58 JoyDual,
59 JoyLeft,
60 JoyRight,
61 GameCube,
62 Pokeball,
63 };
64
65 enum class NpadType : u8 {
66 ProController = 3,
67 Handheld = 4,
68 JoyconDual = 5,
69 JoyconLeft = 6,
70 JoyconRight = 7,
71 GameCube = 8,
72 Pokeball = 9,
73 MaxNpadType = 10,
74 };
75
76 enum class DeviceIndex : u8 { 53 enum class DeviceIndex : u8 {
77 Left = 0, 54 Left = 0,
78 Right = 1, 55 Right = 1,
@@ -80,28 +57,33 @@ public:
80 MaxDeviceIndex = 3, 57 MaxDeviceIndex = 3,
81 }; 58 };
82 59
60 // This is nn::hid::GyroscopeZeroDriftMode
83 enum class GyroscopeZeroDriftMode : u32 { 61 enum class GyroscopeZeroDriftMode : u32 {
84 Loose = 0, 62 Loose = 0,
85 Standard = 1, 63 Standard = 1,
86 Tight = 2, 64 Tight = 2,
87 }; 65 };
88 66
89 enum class NpadHoldType : u64 { 67 // This is nn::hid::NpadJoyHoldType
68 enum class NpadJoyHoldType : u64 {
90 Vertical = 0, 69 Vertical = 0,
91 Horizontal = 1, 70 Horizontal = 1,
92 }; 71 };
93 72
94 enum class NpadAssignments : u32 { 73 // This is nn::hid::NpadJoyAssignmentMode
74 enum class NpadJoyAssignmentMode : u32 {
95 Dual = 0, 75 Dual = 0,
96 Single = 1, 76 Single = 1,
97 }; 77 };
98 78
79 // This is nn::hid::NpadHandheldActivationMode
99 enum class NpadHandheldActivationMode : u64 { 80 enum class NpadHandheldActivationMode : u64 {
100 Dual = 0, 81 Dual = 0,
101 Single = 1, 82 Single = 1,
102 None = 2, 83 None = 2,
103 }; 84 };
104 85
86 // This is nn::hid::NpadCommunicationMode
105 enum class NpadCommunicationMode : u64 { 87 enum class NpadCommunicationMode : u64 {
106 Mode_5ms = 0, 88 Mode_5ms = 0,
107 Mode_10ms = 1, 89 Mode_10ms = 1,
@@ -110,33 +92,14 @@ public:
110 }; 92 };
111 93
112 struct DeviceHandle { 94 struct DeviceHandle {
113 NpadType npad_type; 95 Core::HID::NpadType npad_type;
114 u8 npad_id; 96 u8 npad_id;
115 DeviceIndex device_index; 97 DeviceIndex device_index;
116 INSERT_PADDING_BYTES_NOINIT(1); 98 INSERT_PADDING_BYTES_NOINIT(1);
117 }; 99 };
118 static_assert(sizeof(DeviceHandle) == 4, "DeviceHandle is an invalid size"); 100 static_assert(sizeof(DeviceHandle) == 4, "DeviceHandle is an invalid size");
119 101
120 struct NpadStyleSet { 102 // This is nn::hid::VibrationValue
121 union {
122 u32_le raw{};
123
124 BitField<0, 1, u32> fullkey;
125 BitField<1, 1, u32> handheld;
126 BitField<2, 1, u32> joycon_dual;
127 BitField<3, 1, u32> joycon_left;
128 BitField<4, 1, u32> joycon_right;
129 BitField<5, 1, u32> gamecube;
130 BitField<6, 1, u32> palma;
131 BitField<7, 1, u32> lark;
132 BitField<8, 1, u32> handheld_lark;
133 BitField<9, 1, u32> lucia;
134 BitField<29, 1, u32> system_ext;
135 BitField<30, 1, u32> system;
136 };
137 };
138 static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
139
140 struct VibrationValue { 103 struct VibrationValue {
141 f32 amp_low; 104 f32 amp_low;
142 f32 freq_low; 105 f32 freq_low;
@@ -168,15 +131,15 @@ public:
168 }; 131 };
169 }; 132 };
170 133
171 void SetSupportedStyleSet(NpadStyleSet style_set); 134 void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
172 NpadStyleSet GetSupportedStyleSet() const; 135 Core::HID::NpadStyleTag GetSupportedStyleSet() const;
173 136
174 void SetSupportedNpadIdTypes(u8* data, std::size_t length); 137 void SetSupportedNpadIdTypes(u8* data, std::size_t length);
175 void GetSupportedNpadIdTypes(u32* data, std::size_t max_length); 138 void GetSupportedNpadIdTypes(u32* data, std::size_t max_length);
176 std::size_t GetSupportedNpadIdTypesSize() const; 139 std::size_t GetSupportedNpadIdTypesSize() const;
177 140
178 void SetHoldType(NpadHoldType joy_hold_type); 141 void SetHoldType(NpadJoyHoldType joy_hold_type);
179 NpadHoldType GetHoldType() const; 142 NpadJoyHoldType GetHoldType() const;
180 143
181 void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode); 144 void SetNpadHandheldActivationMode(NpadHandheldActivationMode activation_mode);
182 NpadHandheldActivationMode GetNpadHandheldActivationMode() const; 145 NpadHandheldActivationMode GetNpadHandheldActivationMode() const;
@@ -184,7 +147,7 @@ public:
184 void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_); 147 void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
185 NpadCommunicationMode GetNpadCommunicationMode() const; 148 NpadCommunicationMode GetNpadCommunicationMode() const;
186 149
187 void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode); 150 void SetNpadMode(u32 npad_id, NpadJoyAssignmentMode assignment_mode);
188 151
189 bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index, 152 bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
190 const VibrationValue& vibration_value); 153 const VibrationValue& vibration_value);
@@ -209,9 +172,9 @@ public:
209 void SignalStyleSetChangedEvent(u32 npad_id) const; 172 void SignalStyleSetChangedEvent(u32 npad_id) const;
210 173
211 // Adds a new controller at an index. 174 // Adds a new controller at an index.
212 void AddNewControllerAt(NPadControllerType controller, std::size_t npad_index); 175 void AddNewControllerAt(Core::HID::NpadType controller, std::size_t npad_index);
213 // Adds a new controller at an index with connection status. 176 // Adds a new controller at an index with connection status.
214 void UpdateControllerAt(NPadControllerType controller, std::size_t npad_index, bool connected); 177 void UpdateControllerAt(Core::HID::NpadType controller, std::size_t npad_index, bool connected);
215 178
216 void DisconnectNpad(u32 npad_id); 179 void DisconnectNpad(u32 npad_id);
217 void DisconnectNpadAtIndex(std::size_t index); 180 void DisconnectNpadAtIndex(std::size_t index);
@@ -241,103 +204,37 @@ public:
241 // Specifically for cheat engine and other features. 204 // Specifically for cheat engine and other features.
242 u32 GetAndResetPressState(); 205 u32 GetAndResetPressState();
243 206
244 static Controller_NPad::NPadControllerType MapSettingsTypeToNPad(Settings::ControllerType type);
245 static Settings::ControllerType MapNPadToSettingsType(Controller_NPad::NPadControllerType type);
246 static std::size_t NPadIdToIndex(u32 npad_id); 207 static std::size_t NPadIdToIndex(u32 npad_id);
247 static u32 IndexToNPad(std::size_t index); 208 static u32 IndexToNPad(std::size_t index);
248 static bool IsNpadIdValid(u32 npad_id); 209 static bool IsNpadIdValid(u32 npad_id);
249 static bool IsDeviceHandleValid(const DeviceHandle& device_handle); 210 static bool IsDeviceHandleValid(const DeviceHandle& device_handle);
250 211
251private: 212private:
252 struct CommonHeader { 213 // This is nn::hid::detail::ColorAttribute
253 s64_le timestamp; 214 enum class ColorAttribute : u32_le {
254 s64_le total_entry_count;
255 s64_le last_entry_index;
256 s64_le entry_count;
257 };
258 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
259
260 enum class ColorAttributes : u32_le {
261 Ok = 0, 215 Ok = 0,
262 ReadError = 1, 216 ReadError = 1,
263 NoController = 2, 217 NoController = 2,
264 }; 218 };
265 static_assert(sizeof(ColorAttributes) == 4, "ColorAttributes is an invalid size"); 219 static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size");
266
267 struct ControllerColor {
268 u32_le body;
269 u32_le button;
270 };
271 static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
272
273 struct FullKeyColor {
274 ColorAttributes attribute;
275 ControllerColor fullkey;
276 };
277 static_assert(sizeof(FullKeyColor) == 0xC, "FullKeyColor is an invalid size");
278
279 struct JoyconColor {
280 ColorAttributes attribute;
281 ControllerColor left;
282 ControllerColor right;
283 };
284 static_assert(sizeof(JoyconColor) == 0x14, "JoyconColor is an invalid size");
285 220
286 struct ControllerPadState { 221 // This is nn::hid::detail::NpadFullKeyColorState
287 union { 222 struct NpadFullKeyColorState {
288 u64_le raw{}; 223 ColorAttribute attribute;
289 // Button states 224 Core::HID::NpadControllerColor fullkey;
290 BitField<0, 1, u64> a;
291 BitField<1, 1, u64> b;
292 BitField<2, 1, u64> x;
293 BitField<3, 1, u64> y;
294 BitField<4, 1, u64> l_stick;
295 BitField<5, 1, u64> r_stick;
296 BitField<6, 1, u64> l;
297 BitField<7, 1, u64> r;
298 BitField<8, 1, u64> zl;
299 BitField<9, 1, u64> zr;
300 BitField<10, 1, u64> plus;
301 BitField<11, 1, u64> minus;
302
303 // D-Pad
304 BitField<12, 1, u64> d_left;
305 BitField<13, 1, u64> d_up;
306 BitField<14, 1, u64> d_right;
307 BitField<15, 1, u64> d_down;
308
309 // Left JoyStick
310 BitField<16, 1, u64> l_stick_left;
311 BitField<17, 1, u64> l_stick_up;
312 BitField<18, 1, u64> l_stick_right;
313 BitField<19, 1, u64> l_stick_down;
314
315 // Right JoyStick
316 BitField<20, 1, u64> r_stick_left;
317 BitField<21, 1, u64> r_stick_up;
318 BitField<22, 1, u64> r_stick_right;
319 BitField<23, 1, u64> r_stick_down;
320
321 // Not always active?
322 BitField<24, 1, u64> left_sl;
323 BitField<25, 1, u64> left_sr;
324
325 BitField<26, 1, u64> right_sl;
326 BitField<27, 1, u64> right_sr;
327
328 BitField<28, 1, u64> palma;
329 BitField<30, 1, u64> handheld_left_b;
330 };
331 }; 225 };
332 static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); 226 static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size");
333 227
334 struct AnalogPosition { 228 // This is nn::hid::detail::NpadJoyColorState
335 s32_le x; 229 struct NpadJoyColorState {
336 s32_le y; 230 ColorAttribute attribute;
231 Core::HID::NpadControllerColor left;
232 Core::HID::NpadControllerColor right;
337 }; 233 };
338 static_assert(sizeof(AnalogPosition) == 8, "AnalogPosition is an invalid size"); 234 static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size");
339 235
340 struct ConnectionState { 236 // This is nn::hid::NpadAttribute
237 struct NpadAttribute {
341 union { 238 union {
342 u32_le raw{}; 239 u32_le raw{};
343 BitField<0, 1, u32> is_connected; 240 BitField<0, 1, u32> is_connected;
@@ -348,76 +245,57 @@ private:
348 BitField<5, 1, u32> is_right_wired; 245 BitField<5, 1, u32> is_right_wired;
349 }; 246 };
350 }; 247 };
351 static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); 248 static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size");
352 249
353 struct ControllerPad { 250 // This is nn::hid::NpadFullKeyState
354 ControllerPadState pad_states; 251 // This is nn::hid::NpadHandheldState
355 AnalogPosition l_stick; 252 // This is nn::hid::NpadJoyDualState
356 AnalogPosition r_stick; 253 // This is nn::hid::NpadJoyLeftState
357 }; 254 // This is nn::hid::NpadJoyRightState
358 static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size"); 255 // This is nn::hid::NpadPalmaState
359 256 // This is nn::hid::NpadSystemExtState
360 struct GenericStates { 257 struct NPadGenericState {
361 s64_le timestamp; 258 s64_le sampling_number;
362 s64_le timestamp2; 259 Core::HID::NpadButtonState npad_buttons;
363 ControllerPad pad; 260 Core::HID::AnalogStickState l_stick;
364 ConnectionState connection_status; 261 Core::HID::AnalogStickState r_stick;
365 }; 262 NpadAttribute connection_status;
366 static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); 263 INSERT_PADDING_BYTES(4); // Reserved
367
368 struct NPadGeneric {
369 CommonHeader common;
370 std::array<GenericStates, 17> npad;
371 }; 264 };
372 static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); 265 static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size");
373 266
374 struct SixAxisAttributes { 267 // This is nn::hid::SixAxisSensorAttribute
268 struct SixAxisSensorAttribute {
375 union { 269 union {
376 u32_le raw{}; 270 u32_le raw{};
377 BitField<0, 1, u32> is_connected; 271 BitField<0, 1, u32> is_connected;
378 BitField<1, 1, u32> is_interpolated; 272 BitField<1, 1, u32> is_interpolated;
379 }; 273 };
380 }; 274 };
381 static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); 275 static_assert(sizeof(SixAxisSensorAttribute) == 4, "SixAxisSensorAttribute is an invalid size");
382 276
383 struct SixAxisStates { 277 // This is nn::hid::SixAxisSensorState
384 s64_le timestamp{}; 278 struct SixAxisSensorState {
385 INSERT_PADDING_WORDS(2); 279 s64_le delta_time{};
386 s64_le timestamp2{}; 280 s64_le sampling_number{};
387 Common::Vec3f accel{}; 281 Common::Vec3f accel{};
388 Common::Vec3f gyro{}; 282 Common::Vec3f gyro{};
389 Common::Vec3f rotation{}; 283 Common::Vec3f rotation{};
390 std::array<Common::Vec3f, 3> orientation{}; 284 std::array<Common::Vec3f, 3> orientation{};
391 SixAxisAttributes attribute; 285 SixAxisSensorAttribute attribute;
392 INSERT_PADDING_BYTES(4); // Reserved 286 INSERT_PADDING_BYTES(4); // Reserved
393 }; 287 };
394 static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); 288 static_assert(sizeof(SixAxisSensorState) == 0x60, "SixAxisSensorState is an invalid size");
395
396 struct SixAxisGeneric {
397 CommonHeader common{};
398 std::array<SixAxisStates, 17> sixaxis{};
399 };
400 static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
401 289
402 struct TriggerState { 290 // This is nn::hid::server::NpadGcTriggerState
403 s64_le timestamp{}; 291 struct NpadGcTriggerState {
404 s64_le timestamp2{}; 292 s64_le sampling_number{};
405 s32_le l_analog{}; 293 s32_le l_analog{};
406 s32_le r_analog{}; 294 s32_le r_analog{};
407 }; 295 };
408 static_assert(sizeof(TriggerState) == 0x18, "TriggerState is an invalid size"); 296 static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size");
409
410 struct TriggerGeneric {
411 INSERT_PADDING_BYTES(0x4);
412 s64_le timestamp;
413 INSERT_PADDING_BYTES(0x4);
414 s64_le total_entry_count;
415 s64_le last_entry_index;
416 s64_le entry_count;
417 std::array<TriggerState, 17> trigger{};
418 };
419 static_assert(sizeof(TriggerGeneric) == 0x1C8, "TriggerGeneric is an invalid size");
420 297
298 // This is nn::hid::NpadSystemProperties
421 struct NPadSystemProperties { 299 struct NPadSystemProperties {
422 union { 300 union {
423 s64_le raw{}; 301 s64_le raw{};
@@ -438,15 +316,18 @@ private:
438 }; 316 };
439 static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); 317 static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
440 318
441 struct NPadButtonProperties { 319 // This is nn::hid::NpadSystemButtonProperties
320 struct NpadSystemButtonProperties {
442 union { 321 union {
443 s32_le raw{}; 322 s32_le raw{};
444 BitField<0, 1, s32> is_home_button_protection_enabled; 323 BitField<0, 1, s32> is_home_button_protection_enabled;
445 }; 324 };
446 }; 325 };
447 static_assert(sizeof(NPadButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); 326 static_assert(sizeof(NpadSystemButtonProperties) == 0x4,
327 "NPadButtonProperties is an invalid size");
448 328
449 struct NPadDevice { 329 // This is nn::hid::system::DeviceType
330 struct DeviceType {
450 union { 331 union {
451 u32_le raw{}; 332 u32_le raw{};
452 BitField<0, 1, s32> fullkey; 333 BitField<0, 1, s32> fullkey;
@@ -469,14 +350,6 @@ private:
469 }; 350 };
470 }; 351 };
471 352
472 struct MotionDevice {
473 Common::Vec3f accel;
474 Common::Vec3f gyro;
475 Common::Vec3f rotation;
476 std::array<Common::Vec3f, 3> orientation;
477 Common::Quaternion<f32> quaternion;
478 };
479
480 struct NfcXcdHandle { 353 struct NfcXcdHandle {
481 INSERT_PADDING_BYTES(0x60); 354 INSERT_PADDING_BYTES(0x60);
482 }; 355 };
@@ -485,6 +358,7 @@ private:
485 INSERT_PADDING_BYTES(0x4); 358 INSERT_PADDING_BYTES(0x4);
486 }; 359 };
487 360
361 // This is nn::hid::server::NpadGcTriggerState
488 enum class AppletFooterUiType : u8 { 362 enum class AppletFooterUiType : u8 {
489 None = 0, 363 None = 0,
490 HandheldNone = 1, 364 HandheldNone = 1,
@@ -510,95 +384,90 @@ private:
510 Lagon = 21, 384 Lagon = 21,
511 }; 385 };
512 386
513 struct NPadEntry { 387 // This is nn::hid::detail::NpadInternalState
514 NpadStyleSet style_set; 388 struct NpadInternalState {
515 NpadAssignments assignment_mode; 389 Core::HID::NpadStyleTag style_set;
516 FullKeyColor fullkey_color; 390 NpadJoyAssignmentMode assignment_mode;
517 JoyconColor joycon_color; 391 NpadFullKeyColorState fullkey_color;
518 392 NpadJoyColorState joycon_color;
519 NPadGeneric fullkey_states; 393 Lifo<NPadGenericState> fullkey_lifo;
520 NPadGeneric handheld_states; 394 Lifo<NPadGenericState> handheld_lifo;
521 NPadGeneric joy_dual_states; 395 Lifo<NPadGenericState> joy_dual_lifo;
522 NPadGeneric joy_left_states; 396 Lifo<NPadGenericState> joy_left_lifo;
523 NPadGeneric joy_right_states; 397 Lifo<NPadGenericState> joy_right_lifo;
524 NPadGeneric palma_states; 398 Lifo<NPadGenericState> palma_lifo;
525 NPadGeneric system_ext_states; 399 Lifo<NPadGenericState> system_ext_lifo;
526 SixAxisGeneric sixaxis_fullkey; 400 Lifo<SixAxisSensorState> sixaxis_fullkey_lifo;
527 SixAxisGeneric sixaxis_handheld; 401 Lifo<SixAxisSensorState> sixaxis_handheld_lifo;
528 SixAxisGeneric sixaxis_dual_left; 402 Lifo<SixAxisSensorState> sixaxis_dual_left_lifo;
529 SixAxisGeneric sixaxis_dual_right; 403 Lifo<SixAxisSensorState> sixaxis_dual_right_lifo;
530 SixAxisGeneric sixaxis_left; 404 Lifo<SixAxisSensorState> sixaxis_left_lifo;
531 SixAxisGeneric sixaxis_right; 405 Lifo<SixAxisSensorState> sixaxis_right_lifo;
532 NPadDevice device_type; 406 DeviceType device_type;
533 INSERT_PADDING_BYTES(0x4); // reserved 407 INSERT_PADDING_BYTES(0x4); // Reserved
534 NPadSystemProperties system_properties; 408 NPadSystemProperties system_properties;
535 NPadButtonProperties button_properties; 409 NpadSystemButtonProperties button_properties;
536 u32 battery_level_dual; 410 Core::HID::BatteryLevel battery_level_dual;
537 u32 battery_level_left; 411 Core::HID::BatteryLevel battery_level_left;
538 u32 battery_level_right; 412 Core::HID::BatteryLevel battery_level_right;
539 AppletFooterUiAttributes footer_attributes; 413 AppletFooterUiAttributes footer_attributes;
540 AppletFooterUiType footer_type; 414 AppletFooterUiType footer_type;
541 // nfc_states needs to be checked switchbrew does not match with HW 415 // nfc_states needs to be checked switchbrew doesn't match with HW
542 NfcXcdHandle nfc_states; 416 NfcXcdHandle nfc_states;
543 INSERT_PADDING_BYTES(0x8); // Mutex 417 INSERT_PADDING_BYTES(0x18); // Unknown
544 TriggerGeneric gc_trigger_states; 418 Lifo<NpadGcTriggerState> gc_trigger_lifo;
545 INSERT_PADDING_BYTES(0xc1f); 419 INSERT_PADDING_BYTES(0xc1f); // Unknown
546 }; 420 };
547 static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); 421 static_assert(sizeof(NpadInternalState) == 0x5000, "NpadInternalState is an invalid size");
548 422
549 struct ControllerHolder { 423 struct VibrationData {
550 NPadControllerType type; 424 bool device_mounted{};
551 bool is_connected; 425 VibrationValue latest_vibration_value{};
426 std::chrono::steady_clock::time_point last_vibration_timepoint{};
552 }; 427 };
553 428
429 struct ControllerData {
430 Core::HID::EmulatedController* device;
431 Kernel::KEvent* styleset_changed_event{};
432 NpadInternalState shared_memory_entry{};
433
434 std::array<VibrationData, 2> vibration{};
435 bool unintended_home_button_input_protection{};
436
437 // Current pad state
438 NPadGenericState npad_pad_state{};
439 NPadGenericState npad_libnx_state{};
440 NpadGcTriggerState npad_trigger_state{};
441 SixAxisSensorState sixaxis_fullkey_state{};
442 SixAxisSensorState sixaxis_handheld_state{};
443 SixAxisSensorState sixaxis_dual_left_state{};
444 SixAxisSensorState sixaxis_dual_right_state{};
445 SixAxisSensorState sixaxis_left_lifo_state{};
446 SixAxisSensorState sixaxis_right_lifo_state{};
447 int callback_key;
448 };
449
450 void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx);
554 void InitNewlyAddedController(std::size_t controller_idx); 451 void InitNewlyAddedController(std::size_t controller_idx);
555 bool IsControllerSupported(NPadControllerType controller) const; 452 bool IsControllerSupported(Core::HID::NpadType controller) const;
556 void RequestPadStateUpdate(u32 npad_id); 453 void RequestPadStateUpdate(u32 npad_id);
557 454
558 std::atomic<u32> press_state{}; 455 std::atomic<u32> press_state{};
559 456
560 NpadStyleSet style{}; 457 std::array<ControllerData, 10> controller_data{};
561 std::array<NPadEntry, 10> shared_memory_entries{};
562 using ButtonArray = std::array<
563 std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>,
564 10>;
565 using StickArray = std::array<
566 std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NumAnalogs>,
567 10>;
568 using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>,
569 Settings::NativeVibration::NUM_VIBRATIONS_HID>,
570 10>;
571 using MotionArray = std::array<
572 std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
573 10>;
574
575 KernelHelpers::ServiceContext& service_context; 458 KernelHelpers::ServiceContext& service_context;
576 std::mutex mutex; 459 std::mutex mutex;
577 ButtonArray buttons;
578 StickArray sticks;
579 VibrationArray vibrations;
580 MotionArray motions;
581 std::vector<u32> supported_npad_id_types{}; 460 std::vector<u32> supported_npad_id_types{};
582 NpadHoldType hold_type{NpadHoldType::Vertical}; 461 NpadJoyHoldType hold_type{NpadJoyHoldType::Vertical};
583 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; 462 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
584 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; 463 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
585 // Each controller should have their own styleset changed event
586 std::array<Kernel::KEvent*, 10> styleset_changed_events{};
587 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10>
588 last_vibration_timepoints{};
589 std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
590 bool permit_vibration_session_enabled{false}; 464 bool permit_vibration_session_enabled{false};
591 std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};
592 std::array<ControllerHolder, 10> connected_controllers{};
593 std::array<bool, 10> unintended_home_button_input_protection{};
594 bool analog_stick_use_center_clamp{}; 465 bool analog_stick_use_center_clamp{};
595 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; 466 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
596 bool sixaxis_sensors_enabled{true}; 467 bool sixaxis_sensors_enabled{true};
597 f32 sixaxis_fusion_parameter1{}; 468 f32 sixaxis_fusion_parameter1{};
598 f32 sixaxis_fusion_parameter2{}; 469 f32 sixaxis_fusion_parameter2{};
599 bool sixaxis_at_rest{true}; 470 bool sixaxis_at_rest{true};
600 std::array<ControllerPad, 10> npad_pad_states{};
601 std::array<TriggerState, 10> npad_trigger_states{};
602 bool is_in_lr_assignment_mode{false}; 471 bool is_in_lr_assignment_mode{false};
603}; 472};
604} // namespace Service::HID 473} // namespace Service::HID