summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar David Marcec2018-10-18 14:11:15 +1100
committerGravatar Zach Hilman2018-11-18 23:21:33 -0500
commitbeab38601badd54930881858b4a021fe76a92b39 (patch)
tree1e385dee587c3b7b09d191a11c425983ec659b84 /src
parentMerge pull request #1717 from FreddyFunk/swizzle-gob (diff)
downloadyuzu-beab38601badd54930881858b4a021fe76a92b39.tar.gz
yuzu-beab38601badd54930881858b4a021fe76a92b39.tar.xz
yuzu-beab38601badd54930881858b4a021fe76a92b39.zip
Added multi-input support and controller assignment at any port
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp287
-rw-r--r--src/core/hle/service/hid/controllers/npad.h16
2 files changed, 181 insertions, 122 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 205e4fd14..5b0ca57f8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -164,6 +164,57 @@ void Controller_NPad::OnLoadInputDevices() {
164 164
165void Controller_NPad::OnRelease() {} 165void Controller_NPad::OnRelease() {}
166 166
167void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
168 const auto controller_idx = NPadIdToIndex(npad_id);
169 const auto controller_type = connected_controllers[controller_idx].type;
170 if (!connected_controllers[controller_idx].is_connected) {
171 return;
172 }
173 auto& pad_state = npad_pad_states[controller_idx].pad_states;
174 auto& lstick_entry = npad_pad_states[controller_idx].l_stick;
175 auto& rstick_entry = npad_pad_states[controller_idx].r_stick;
176 using namespace Settings::NativeButton;
177 pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
178 pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
179 pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
180 pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
181 pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
182 pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
183 pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
184 pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
185 pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
186 pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
187 pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
188 pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
189
190 pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
191 pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
192 pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
193 pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
194
195 pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
196 pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
197 pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
198 pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
199
200 pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
201 pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
202 pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
203 pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
204
205 pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
206 pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
207
208 const auto [stick_l_x_f, stick_l_y_f] =
209 sticks[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
210 const auto [stick_r_x_f, stick_r_y_f] =
211 sticks[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
212 lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
213 lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
214 rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
215 rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
216}
217
167void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { 218void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
168 if (!IsControllerActivated()) 219 if (!IsControllerActivated())
169 return; 220 return;
@@ -199,97 +250,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
199 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { 250 if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) {
200 continue; 251 continue;
201 } 252 }
202 253 const u32 npad_index = static_cast<u32>(i);
203 // Pad states 254 RequestPadStateUpdate(npad_index);
204 ControllerPadState pad_state{}; 255 auto& pad_state = npad_pad_states[npad_index];
205 using namespace Settings::NativeButton;
206 pad_state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
207 pad_state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
208 pad_state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
209 pad_state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
210 pad_state.l_stick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
211 pad_state.r_stick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
212 pad_state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
213 pad_state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
214 pad_state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
215 pad_state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
216 pad_state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
217 pad_state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
218
219 pad_state.d_left.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
220 pad_state.d_up.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
221 pad_state.d_right.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
222 pad_state.d_down.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
223
224 pad_state.l_stick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
225 pad_state.l_stick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
226 pad_state.l_stick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
227 pad_state.l_stick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
228
229 pad_state.r_stick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
230 pad_state.r_stick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
231 pad_state.r_stick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
232 pad_state.r_stick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
233
234 pad_state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
235 pad_state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
236
237 AnalogPosition lstick_entry{};
238 AnalogPosition rstick_entry{};
239
240 const auto [stick_l_x_f, stick_l_y_f] =
241 sticks[static_cast<std::size_t>(JoystickId::Joystick_Left)]->GetStatus();
242 const auto [stick_r_x_f, stick_r_y_f] =
243 sticks[static_cast<std::size_t>(JoystickId::Joystick_Right)]->GetStatus();
244 lstick_entry.x = static_cast<s32>(stick_l_x_f * HID_JOYSTICK_MAX);
245 lstick_entry.y = static_cast<s32>(stick_l_y_f * HID_JOYSTICK_MAX);
246 rstick_entry.x = static_cast<s32>(stick_r_x_f * HID_JOYSTICK_MAX);
247 rstick_entry.y = static_cast<s32>(stick_r_y_f * HID_JOYSTICK_MAX);
248
249 if (controller_type == NPadControllerType::JoyLeft ||
250 controller_type == NPadControllerType::JoyRight) {
251 if (npad.properties.is_horizontal) {
252 ControllerPadState state{};
253 AnalogPosition temp_lstick_entry{};
254 AnalogPosition temp_rstick_entry{};
255 if (controller_type == NPadControllerType::JoyLeft) {
256 state.d_down.Assign(pad_state.d_left.Value());
257 state.d_left.Assign(pad_state.d_up.Value());
258 state.d_right.Assign(pad_state.d_down.Value());
259 state.d_up.Assign(pad_state.d_right.Value());
260 state.l.Assign(pad_state.l.Value() | pad_state.sl.Value());
261 state.r.Assign(pad_state.r.Value() | pad_state.sr.Value());
262
263 state.zl.Assign(pad_state.zl.Value());
264 state.plus.Assign(pad_state.minus.Value());
265
266 temp_lstick_entry = lstick_entry;
267 temp_rstick_entry = rstick_entry;
268 std::swap(temp_lstick_entry.x, temp_lstick_entry.y);
269 std::swap(temp_rstick_entry.x, temp_rstick_entry.y);
270 temp_lstick_entry.y *= -1;
271 } else if (controller_type == NPadControllerType::JoyRight) {
272 state.x.Assign(pad_state.a.Value());
273 state.a.Assign(pad_state.b.Value());
274 state.b.Assign(pad_state.y.Value());
275 state.y.Assign(pad_state.b.Value());
276
277 state.l.Assign(pad_state.l.Value() | pad_state.sl.Value());
278 state.r.Assign(pad_state.r.Value() | pad_state.sr.Value());
279 state.zr.Assign(pad_state.zr.Value());
280 state.plus.Assign(pad_state.plus.Value());
281
282 temp_lstick_entry = lstick_entry;
283 temp_rstick_entry = rstick_entry;
284 std::swap(temp_lstick_entry.x, temp_lstick_entry.y);
285 std::swap(temp_rstick_entry.x, temp_rstick_entry.y);
286 temp_rstick_entry.x *= -1;
287 }
288 pad_state.raw = state.raw;
289 lstick_entry = temp_lstick_entry;
290 rstick_entry = temp_rstick_entry;
291 }
292 }
293 256
294 auto& main_controller = 257 auto& main_controller =
295 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; 258 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index];
@@ -304,7 +267,45 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
304 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; 267 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index];
305 268
306 if (hold_type == NpadHoldType::Horizontal) { 269 if (hold_type == NpadHoldType::Horizontal) {
307 // TODO(ogniK): Remap buttons for different orientations 270 ControllerPadState state{};
271 AnalogPosition temp_lstick_entry{};
272 AnalogPosition temp_rstick_entry{};
273 if (controller_type == NPadControllerType::JoyLeft) {
274 state.d_down.Assign(pad_state.pad_states.d_left.Value());
275 state.d_left.Assign(pad_state.pad_states.d_up.Value());
276 state.d_right.Assign(pad_state.pad_states.d_down.Value());
277 state.d_up.Assign(pad_state.pad_states.d_right.Value());
278 state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value());
279 state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value());
280
281 state.zl.Assign(pad_state.pad_states.zl.Value());
282 state.plus.Assign(pad_state.pad_states.minus.Value());
283
284 temp_lstick_entry = pad_state.l_stick;
285 temp_rstick_entry = pad_state.r_stick;
286 std::swap(temp_lstick_entry.x, temp_lstick_entry.y);
287 std::swap(temp_rstick_entry.x, temp_rstick_entry.y);
288 temp_lstick_entry.y *= -1;
289 } else if (controller_type == NPadControllerType::JoyRight) {
290 state.x.Assign(pad_state.pad_states.a.Value());
291 state.a.Assign(pad_state.pad_states.b.Value());
292 state.b.Assign(pad_state.pad_states.y.Value());
293 state.y.Assign(pad_state.pad_states.b.Value());
294
295 state.l.Assign(pad_state.pad_states.l.Value() | pad_state.pad_states.sl.Value());
296 state.r.Assign(pad_state.pad_states.r.Value() | pad_state.pad_states.sr.Value());
297 state.zr.Assign(pad_state.pad_states.zr.Value());
298 state.plus.Assign(pad_state.pad_states.plus.Value());
299
300 temp_lstick_entry = pad_state.l_stick;
301 temp_rstick_entry = pad_state.r_stick;
302 std::swap(temp_lstick_entry.x, temp_lstick_entry.y);
303 std::swap(temp_rstick_entry.x, temp_rstick_entry.y);
304 temp_rstick_entry.x *= -1;
305 }
306 pad_state.pad_states.raw = state.raw;
307 pad_state.l_stick = temp_lstick_entry;
308 pad_state.r_stick = temp_rstick_entry;
308 } 309 }
309 libnx_entry.connection_status.raw = 0; 310 libnx_entry.connection_status.raw = 0;
310 311
@@ -316,9 +317,9 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
316 handheld_entry.connection_status.IsRightJoyConnected.Assign(1); 317 handheld_entry.connection_status.IsRightJoyConnected.Assign(1);
317 handheld_entry.connection_status.IsLeftJoyWired.Assign(1); 318 handheld_entry.connection_status.IsLeftJoyWired.Assign(1);
318 handheld_entry.connection_status.IsRightJoyWired.Assign(1); 319 handheld_entry.connection_status.IsRightJoyWired.Assign(1);
319 handheld_entry.pad_states.raw = pad_state.raw; 320 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
320 handheld_entry.l_stick = lstick_entry; 321 handheld_entry.pad.l_stick = pad_state.l_stick;
321 handheld_entry.r_stick = rstick_entry; 322 handheld_entry.pad.r_stick = pad_state.r_stick;
322 break; 323 break;
323 case NPadControllerType::JoyDual: 324 case NPadControllerType::JoyDual:
324 dual_entry.connection_status.raw = 0; 325 dual_entry.connection_status.raw = 0;
@@ -339,17 +340,17 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
339 left_entry.connection_status.raw = 0; 340 left_entry.connection_status.raw = 0;
340 341
341 left_entry.connection_status.IsConnected.Assign(1); 342 left_entry.connection_status.IsConnected.Assign(1);
342 left_entry.pad_states.raw = pad_state.raw; 343 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
343 left_entry.l_stick = lstick_entry; 344 left_entry.pad.l_stick = pad_state.l_stick;
344 left_entry.r_stick = rstick_entry; 345 left_entry.pad.r_stick = pad_state.r_stick;
345 break; 346 break;
346 case NPadControllerType::JoyRight: 347 case NPadControllerType::JoyRight:
347 right_entry.connection_status.raw = 0; 348 right_entry.connection_status.raw = 0;
348 349
349 right_entry.connection_status.IsConnected.Assign(1); 350 right_entry.connection_status.IsConnected.Assign(1);
350 right_entry.pad_states.raw = pad_state.raw; 351 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
351 right_entry.l_stick = lstick_entry; 352 right_entry.pad.l_stick = pad_state.l_stick;
352 right_entry.r_stick = rstick_entry; 353 right_entry.pad.r_stick = pad_state.r_stick;
353 break; 354 break;
354 case NPadControllerType::Pokeball: 355 case NPadControllerType::Pokeball:
355 pokeball_entry.connection_status.raw = 0; 356 pokeball_entry.connection_status.raw = 0;
@@ -357,26 +358,26 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
357 pokeball_entry.connection_status.IsConnected.Assign(1); 358 pokeball_entry.connection_status.IsConnected.Assign(1);
358 pokeball_entry.connection_status.IsWired.Assign(1); 359 pokeball_entry.connection_status.IsWired.Assign(1);
359 360
360 pokeball_entry.pad_states.raw = pad_state.raw; 361 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
361 pokeball_entry.l_stick = lstick_entry; 362 pokeball_entry.pad.l_stick = pad_state.l_stick;
362 pokeball_entry.r_stick = rstick_entry; 363 pokeball_entry.pad.r_stick = pad_state.r_stick;
363 break; 364 break;
364 case NPadControllerType::ProController: 365 case NPadControllerType::ProController:
365 main_controller.connection_status.raw = 0; 366 main_controller.connection_status.raw = 0;
366 367
367 main_controller.connection_status.IsConnected.Assign(1); 368 main_controller.connection_status.IsConnected.Assign(1);
368 main_controller.connection_status.IsWired.Assign(1); 369 main_controller.connection_status.IsWired.Assign(1);
369 main_controller.pad_states.raw = pad_state.raw; 370 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
370 main_controller.l_stick = lstick_entry; 371 main_controller.pad.l_stick = pad_state.l_stick;
371 main_controller.r_stick = rstick_entry; 372 main_controller.pad.r_stick = pad_state.r_stick;
372 break; 373 break;
373 } 374 }
374 375
375 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate 376 // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate
376 // any controllers. 377 // any controllers.
377 libnx_entry.pad_states.raw = pad_state.raw; 378 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
378 libnx_entry.l_stick = lstick_entry; 379 libnx_entry.pad.l_stick = pad_state.l_stick;
379 libnx_entry.r_stick = rstick_entry; 380 libnx_entry.pad.r_stick = pad_state.r_stick;
380 } 381 }
381 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), 382 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
382 shared_memory_entries.size() * sizeof(NPadEntry)); 383 shared_memory_entries.size() * sizeof(NPadEntry));
@@ -450,15 +451,7 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
450 return; 451 return;
451 } 452 }
452 for (std::size_t i = 0; i < controller_ids.size(); i++) { 453 for (std::size_t i = 0; i < controller_ids.size(); i++) {
453 std::size_t controller_pos = i; 454 std::size_t controller_pos = NPadIdToIndex(static_cast<u32>(i));
454 // Handheld controller conversion
455 if (controller_pos == NPAD_HANDHELD) {
456 controller_pos = 8;
457 }
458 // Unknown controller conversion
459 if (controller_pos == NPAD_UNKNOWN) {
460 controller_pos = 9;
461 }
462 if (connected_controllers[controller_pos].is_connected) { 455 if (connected_controllers[controller_pos].is_connected) {
463 // TODO(ogniK): Vibrate the physical controller 456 // TODO(ogniK): Vibrate the physical controller
464 } 457 }
@@ -477,6 +470,51 @@ Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() cons
477Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { 470Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
478 return last_processed_vibration; 471 return last_processed_vibration;
479} 472}
473
474std::size_t Controller_NPad::NPadIdToIndex(u32 npad_id) {
475 switch (npad_id) {
476 case 0:
477 case 1:
478 case 2:
479 case 3:
480 case 4:
481 case 5:
482 case 6:
483 case 7:
484 return static_cast<std::size_t>(npad_id);
485 case 8:
486 case 32:
487 return 8;
488 case 9:
489 case 16:
490 return 9;
491 default:
492 UNIMPLEMENTED_MSG("Unknown npad id {}", npad_id);
493 return 0;
494 }
495}
496
497u32 Controller_NPad::IndexToNPad(std::size_t index) {
498 switch (index) {
499 case 0:
500 case 1:
501 case 2:
502 case 3:
503 case 4:
504 case 5:
505 case 6:
506 case 7:
507 return static_cast<u32>(index);
508 case 8:
509 return 32;
510 case 9:
511 return 16;
512 default:
513 UNIMPLEMENTED_MSG("Unknown npad index {}", index);
514 return 0;
515 };
516}
517
480void Controller_NPad::AddNewController(NPadControllerType controller) { 518void Controller_NPad::AddNewController(NPadControllerType controller) {
481 if (controller == NPadControllerType::Handheld) { 519 if (controller == NPadControllerType::Handheld) {
482 connected_controllers[8] = {controller, true}; 520 connected_controllers[8] = {controller, true};
@@ -495,6 +533,17 @@ void Controller_NPad::AddNewController(NPadControllerType controller) {
495 InitNewlyAddedControler(controller_id); 533 InitNewlyAddedControler(controller_id);
496} 534}
497 535
536void Controller_NPad::AddNewControllerAt(NPadControllerType controller, u32 npad_id) {
537 if (controller == NPadControllerType::Handheld) {
538 connected_controllers[8] = {controller, true};
539 InitNewlyAddedControler(8);
540 return;
541 }
542 const size_t controller_id = static_cast<std::size_t>(npad_id);
543 connected_controllers[controller_id] = {controller, true};
544 InitNewlyAddedControler(controller_id);
545}
546
498void Controller_NPad::ConnectNPad(u32 npad_id) { 547void Controller_NPad::ConnectNPad(u32 npad_id) {
499 connected_controllers[NPadIdToIndex(npad_id)].is_connected = true; 548 connected_controllers[NPadIdToIndex(npad_id)].is_connected = true;
500} 549}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index ac86985ff..1192cfcd9 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -107,6 +107,7 @@ public:
107 Vibration GetLastVibration() const; 107 Vibration GetLastVibration() const;
108 108
109 void AddNewController(NPadControllerType controller); 109 void AddNewController(NPadControllerType controller);
110 void AddNewControllerAt(NPadControllerType controller, u32 npad_id);
110 111
111 void ConnectNPad(u32 npad_id); 112 void ConnectNPad(u32 npad_id);
112 void DisconnectNPad(u32 npad_id); 113 void DisconnectNPad(u32 npad_id);
@@ -189,12 +190,17 @@ private:
189 }; 190 };
190 static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); 191 static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
191 192
192 struct GenericStates { 193 struct ControllerPad {
193 s64_le timestamp;
194 s64_le timestamp2;
195 ControllerPadState pad_states; 194 ControllerPadState pad_states;
196 AnalogPosition l_stick; 195 AnalogPosition l_stick;
197 AnalogPosition r_stick; 196 AnalogPosition r_stick;
197 };
198 static_assert(sizeof(ControllerPad) == 0x18, "ControllerPad is an invalid size");
199
200 struct GenericStates {
201 s64_le timestamp;
202 s64_le timestamp2;
203 ControllerPad pad;
198 ConnectionState connection_status; 204 ConnectionState connection_status;
199 }; 205 };
200 static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size"); 206 static_assert(sizeof(GenericStates) == 0x30, "NPadGenericStates is an invalid size");
@@ -285,5 +291,9 @@ private:
285 void InitNewlyAddedControler(std::size_t controller_idx); 291 void InitNewlyAddedControler(std::size_t controller_idx);
286 bool IsControllerSupported(NPadControllerType controller) const; 292 bool IsControllerSupported(NPadControllerType controller) const;
287 NPadControllerType DecideBestController(NPadControllerType priority) const; 293 NPadControllerType DecideBestController(NPadControllerType priority) const;
294 void RequestPadStateUpdate(u32 npad_id);
295 std::size_t NPadIdToIndex(u32 npad_id);
296 u32 IndexToNPad(std::size_t index);
297 std::array<ControllerPad, 10> npad_pad_states{};
288}; 298};
289} // namespace Service::HID 299} // namespace Service::HID