summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/am/applets/controller.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp17
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h21
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp11
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h26
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp208
-rw-r--r--src/core/hle/service/hid/controllers/npad.h189
-rw-r--r--src/core/hle/service/hid/controllers/xpad.h70
-rw-r--r--src/core/hle/service/hid/hid.cpp20
-rw-r--r--src/core/hle/service/hid/hid.h10
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp2
11 files changed, 407 insertions, 169 deletions
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index 7edfca64e..d7d3ee99a 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -37,7 +37,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
37 .border_colors = std::move(identification_colors), 37 .border_colors = std::move(identification_colors),
38 .enable_explain_text = enable_text, 38 .enable_explain_text = enable_text,
39 .explain_text = std::move(text), 39 .explain_text = std::move(text),
40 .allow_pro_controller = npad_style_set.pro_controller == 1, 40 .allow_pro_controller = npad_style_set.fullkey == 1,
41 .allow_handheld = npad_style_set.handheld == 1, 41 .allow_handheld = npad_style_set.handheld == 1,
42 .allow_dual_joycons = npad_style_set.joycon_dual == 1, 42 .allow_dual_joycons = npad_style_set.joycon_dual == 1,
43 .allow_left_joycon = npad_style_set.joycon_left == 1, 43 .allow_left_joycon = npad_style_set.joycon_left == 1,
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 59b694cd4..c4a59147d 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -39,16 +39,25 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
39 cur_entry.sampling_number2 = cur_entry.sampling_number; 39 cur_entry.sampling_number2 = cur_entry.sampling_number;
40 40
41 cur_entry.key.fill(0); 41 cur_entry.key.fill(0);
42 cur_entry.modifier = 0;
43 if (Settings::values.keyboard_enabled) { 42 if (Settings::values.keyboard_enabled) {
44 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { 43 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
45 auto& entry = cur_entry.key[i / KEYS_PER_BYTE]; 44 auto& entry = cur_entry.key[i / KEYS_PER_BYTE];
46 entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE))); 45 entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE)));
47 } 46 }
48 47
49 for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { 48 using namespace Settings::NativeKeyboard;
50 cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); 49
51 } 50 // TODO: Assign the correct key to all modifiers
51 cur_entry.modifier.control.Assign(keyboard_mods[LeftControl]->GetStatus());
52 cur_entry.modifier.shift.Assign(keyboard_mods[LeftShift]->GetStatus());
53 cur_entry.modifier.left_alt.Assign(keyboard_mods[LeftAlt]->GetStatus());
54 cur_entry.modifier.right_alt.Assign(keyboard_mods[RightAlt]->GetStatus());
55 cur_entry.modifier.gui.Assign(0);
56 cur_entry.modifier.caps_lock.Assign(keyboard_mods[CapsLock]->GetStatus());
57 cur_entry.modifier.scroll_lock.Assign(keyboard_mods[ScrollLock]->GetStatus());
58 cur_entry.modifier.num_lock.Assign(keyboard_mods[NumLock]->GetStatus());
59 cur_entry.modifier.katakana.Assign(0);
60 cur_entry.modifier.hiragana.Assign(0);
52 } 61 }
53 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); 62 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
54} 63}
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index f3eef5936..b5b281752 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include "common/bit_field.h"
8#include "common/common_funcs.h" 9#include "common/common_funcs.h"
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "common/swap.h" 11#include "common/swap.h"
@@ -31,12 +32,28 @@ public:
31 void OnLoadInputDevices() override; 32 void OnLoadInputDevices() override;
32 33
33private: 34private:
35 struct Modifiers {
36 union {
37 u32_le raw{};
38 BitField<0, 1, u32> control;
39 BitField<1, 1, u32> shift;
40 BitField<2, 1, u32> left_alt;
41 BitField<3, 1, u32> right_alt;
42 BitField<4, 1, u32> gui;
43 BitField<8, 1, u32> caps_lock;
44 BitField<9, 1, u32> scroll_lock;
45 BitField<10, 1, u32> num_lock;
46 BitField<11, 1, u32> katakana;
47 BitField<12, 1, u32> hiragana;
48 };
49 };
50 static_assert(sizeof(Modifiers) == 0x4, "Modifiers is an invalid size");
51
34 struct KeyboardState { 52 struct KeyboardState {
35 s64_le sampling_number; 53 s64_le sampling_number;
36 s64_le sampling_number2; 54 s64_le sampling_number2;
37 55
38 s32_le modifier; 56 Modifiers modifier;
39 s32_le attribute;
40 std::array<u8, 32> key; 57 std::array<u8, 32> key;
41 }; 58 };
42 static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size"); 59 static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size");
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index ac40989c5..2e7457604 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -36,6 +36,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
36 cur_entry.sampling_number = last_entry.sampling_number + 1; 36 cur_entry.sampling_number = last_entry.sampling_number + 1;
37 cur_entry.sampling_number2 = cur_entry.sampling_number; 37 cur_entry.sampling_number2 = cur_entry.sampling_number;
38 38
39 cur_entry.attribute.raw = 0;
39 if (Settings::values.mouse_enabled) { 40 if (Settings::values.mouse_enabled) {
40 const auto [px, py, sx, sy] = mouse_device->GetStatus(); 41 const auto [px, py, sx, sy] = mouse_device->GetStatus();
41 const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width); 42 const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width);
@@ -46,10 +47,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
46 cur_entry.delta_y = y - last_entry.y; 47 cur_entry.delta_y = y - last_entry.y;
47 cur_entry.mouse_wheel_x = sx; 48 cur_entry.mouse_wheel_x = sx;
48 cur_entry.mouse_wheel_y = sy; 49 cur_entry.mouse_wheel_y = sy;
50 cur_entry.attribute.is_connected.Assign(1);
49 51
50 for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) { 52 using namespace Settings::NativeMouseButton;
51 cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); 53 cur_entry.button.left.Assign(mouse_button_devices[Left]->GetStatus());
52 } 54 cur_entry.button.right.Assign(mouse_button_devices[Right]->GetStatus());
55 cur_entry.button.middle.Assign(mouse_button_devices[Middle]->GetStatus());
56 cur_entry.button.forward.Assign(mouse_button_devices[Forward]->GetStatus());
57 cur_entry.button.back.Assign(mouse_button_devices[Back]->GetStatus());
53 } 58 }
54 59
55 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); 60 std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 357ab7107..3b432a36e 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include "common/bit_field.h"
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "common/swap.h" 10#include "common/swap.h"
10#include "core/frontend/input.h" 11#include "core/frontend/input.h"
@@ -30,6 +31,27 @@ public:
30 void OnLoadInputDevices() override; 31 void OnLoadInputDevices() override;
31 32
32private: 33private:
34 struct Buttons {
35 union {
36 u32_le raw{};
37 BitField<0, 1, u32> left;
38 BitField<1, 1, u32> right;
39 BitField<2, 1, u32> middle;
40 BitField<3, 1, u32> forward;
41 BitField<4, 1, u32> back;
42 };
43 };
44 static_assert(sizeof(Buttons) == 0x4, "Buttons is an invalid size");
45
46 struct Attributes {
47 union {
48 u32_le raw{};
49 BitField<0, 1, u32> transferable;
50 BitField<1, 1, u32> is_connected;
51 };
52 };
53 static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size");
54
33 struct MouseState { 55 struct MouseState {
34 s64_le sampling_number; 56 s64_le sampling_number;
35 s64_le sampling_number2; 57 s64_le sampling_number2;
@@ -39,8 +61,8 @@ private:
39 s32_le delta_y; 61 s32_le delta_y;
40 s32_le mouse_wheel_x; 62 s32_le mouse_wheel_x;
41 s32_le mouse_wheel_y; 63 s32_le mouse_wheel_y;
42 s32_le button; 64 Buttons button;
43 s32_le attribute; 65 Attributes attribute;
44 }; 66 };
45 static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size"); 67 static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size");
46 68
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 5794f417c..dbf198345 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -157,76 +157,83 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
157 styleset_changed_events[controller_idx]->GetWritableEvent()->Signal(); 157 styleset_changed_events[controller_idx]->GetWritableEvent()->Signal();
158 return; 158 return;
159 } 159 }
160 controller.joy_styles.raw = 0; // Zero out 160 controller.style_set.raw = 0; // Zero out
161 controller.device_type.raw = 0; 161 controller.device_type.raw = 0;
162 controller.properties.raw = 0; 162 controller.system_properties.raw = 0;
163 switch (controller_type) { 163 switch (controller_type) {
164 case NPadControllerType::None: 164 case NPadControllerType::None:
165 UNREACHABLE(); 165 UNREACHABLE();
166 break; 166 break;
167 case NPadControllerType::ProController: 167 case NPadControllerType::ProController:
168 controller.joy_styles.pro_controller.Assign(1); 168 controller.style_set.fullkey.Assign(1);
169 controller.device_type.pro_controller.Assign(1); 169 controller.device_type.fullkey.Assign(1);
170 controller.properties.is_vertical.Assign(1); 170 controller.system_properties.is_vertical.Assign(1);
171 controller.properties.use_plus.Assign(1); 171 controller.system_properties.use_plus.Assign(1);
172 controller.properties.use_minus.Assign(1); 172 controller.system_properties.use_minus.Assign(1);
173 controller.pad_assignment = NpadAssignments::Single; 173 controller.assignment_mode = NpadAssignments::Single;
174 controller.footer_type = AppletFooterUiType::SwitchProController;
174 break; 175 break;
175 case NPadControllerType::Handheld: 176 case NPadControllerType::Handheld:
176 controller.joy_styles.handheld.Assign(1); 177 controller.style_set.handheld.Assign(1);
177 controller.device_type.handheld.Assign(1); 178 controller.device_type.handheld_left.Assign(1);
178 controller.properties.is_vertical.Assign(1); 179 controller.device_type.handheld_right.Assign(1);
179 controller.properties.use_plus.Assign(1); 180 controller.system_properties.is_vertical.Assign(1);
180 controller.properties.use_minus.Assign(1); 181 controller.system_properties.use_plus.Assign(1);
181 controller.pad_assignment = NpadAssignments::Dual; 182 controller.system_properties.use_minus.Assign(1);
183 controller.assignment_mode = NpadAssignments::Dual;
184 controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;
182 break; 185 break;
183 case NPadControllerType::JoyDual: 186 case NPadControllerType::JoyDual:
184 controller.joy_styles.joycon_dual.Assign(1); 187 controller.style_set.joycon_dual.Assign(1);
185 controller.device_type.joycon_left.Assign(1); 188 controller.device_type.joycon_left.Assign(1);
186 controller.device_type.joycon_right.Assign(1); 189 controller.device_type.joycon_right.Assign(1);
187 controller.properties.is_vertical.Assign(1); 190 controller.system_properties.is_vertical.Assign(1);
188 controller.properties.use_plus.Assign(1); 191 controller.system_properties.use_plus.Assign(1);
189 controller.properties.use_minus.Assign(1); 192 controller.system_properties.use_minus.Assign(1);
190 controller.pad_assignment = NpadAssignments::Dual; 193 controller.assignment_mode = NpadAssignments::Dual;
194 controller.footer_type = AppletFooterUiType::JoyDual;
191 break; 195 break;
192 case NPadControllerType::JoyLeft: 196 case NPadControllerType::JoyLeft:
193 controller.joy_styles.joycon_left.Assign(1); 197 controller.style_set.joycon_left.Assign(1);
194 controller.device_type.joycon_left.Assign(1); 198 controller.device_type.joycon_left.Assign(1);
195 controller.properties.is_horizontal.Assign(1); 199 controller.system_properties.is_horizontal.Assign(1);
196 controller.properties.use_minus.Assign(1); 200 controller.system_properties.use_minus.Assign(1);
197 controller.pad_assignment = NpadAssignments::Single; 201 controller.assignment_mode = NpadAssignments::Single;
202 controller.footer_type = AppletFooterUiType::JoyLeftHorizontal;
198 break; 203 break;
199 case NPadControllerType::JoyRight: 204 case NPadControllerType::JoyRight:
200 controller.joy_styles.joycon_right.Assign(1); 205 controller.style_set.joycon_right.Assign(1);
201 controller.device_type.joycon_right.Assign(1); 206 controller.device_type.joycon_right.Assign(1);
202 controller.properties.is_horizontal.Assign(1); 207 controller.system_properties.is_horizontal.Assign(1);
203 controller.properties.use_plus.Assign(1); 208 controller.system_properties.use_plus.Assign(1);
204 controller.pad_assignment = NpadAssignments::Single; 209 controller.assignment_mode = NpadAssignments::Single;
210 controller.footer_type = AppletFooterUiType::JoyRightHorizontal;
205 break; 211 break;
206 case NPadControllerType::Pokeball: 212 case NPadControllerType::Pokeball:
207 controller.joy_styles.pokeball.Assign(1); 213 controller.style_set.palma.Assign(1);
208 controller.device_type.pokeball.Assign(1); 214 controller.device_type.palma.Assign(1);
209 controller.pad_assignment = NpadAssignments::Single; 215 controller.assignment_mode = NpadAssignments::Single;
210 break; 216 break;
211 } 217 }
212 218
213 controller.single_color_error = ColorReadError::ReadOk; 219 controller.fullkey_color.attribute = ColorAttributes::Ok;
214 controller.single_color.body_color = 0; 220 controller.fullkey_color.fullkey.body = 0;
215 controller.single_color.button_color = 0; 221 controller.fullkey_color.fullkey.button = 0;
216 222
217 controller.dual_color_error = ColorReadError::ReadOk; 223 controller.joycon_color.attribute = ColorAttributes::Ok;
218 controller.left_color.body_color = 224 controller.joycon_color.left.body =
219 Settings::values.players.GetValue()[controller_idx].body_color_left; 225 Settings::values.players.GetValue()[controller_idx].body_color_left;
220 controller.left_color.button_color = 226 controller.joycon_color.left.button =
221 Settings::values.players.GetValue()[controller_idx].button_color_left; 227 Settings::values.players.GetValue()[controller_idx].button_color_left;
222 controller.right_color.body_color = 228 controller.joycon_color.right.body =
223 Settings::values.players.GetValue()[controller_idx].body_color_right; 229 Settings::values.players.GetValue()[controller_idx].body_color_right;
224 controller.right_color.button_color = 230 controller.joycon_color.right.button =
225 Settings::values.players.GetValue()[controller_idx].button_color_right; 231 Settings::values.players.GetValue()[controller_idx].button_color_right;
226 232
227 controller.battery_level[0] = BATTERY_FULL; 233 // TODO: Investigate when we should report all batery types
228 controller.battery_level[1] = BATTERY_FULL; 234 controller.battery_level_dual = BATTERY_FULL;
229 controller.battery_level[2] = BATTERY_FULL; 235 controller.battery_level_left = BATTERY_FULL;
236 controller.battery_level_right = BATTERY_FULL;
230 237
231 SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); 238 SignalStyleSetChangedEvent(IndexToNPad(controller_idx));
232} 239}
@@ -251,8 +258,8 @@ void Controller_NPad::OnInit() {
251 style.joycon_left.Assign(1); 258 style.joycon_left.Assign(1);
252 style.joycon_right.Assign(1); 259 style.joycon_right.Assign(1);
253 style.joycon_dual.Assign(1); 260 style.joycon_dual.Assign(1);
254 style.pro_controller.Assign(1); 261 style.fullkey.Assign(1);
255 style.pokeball.Assign(1); 262 style.palma.Assign(1);
256 } 263 }
257 264
258 std::transform(Settings::values.players.GetValue().begin(), 265 std::transform(Settings::values.players.GetValue().begin(),
@@ -406,13 +413,10 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
406 } 413 }
407 for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) { 414 for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) {
408 auto& npad = shared_memory_entries[i]; 415 auto& npad = shared_memory_entries[i];
409 const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states, 416 const std::array<NPadGeneric*, 7> controller_npads{
410 &npad.handheld_states, 417 &npad.fullkey_states, &npad.handheld_states, &npad.joy_dual_states,
411 &npad.dual_states, 418 &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states,
412 &npad.left_joy_states, 419 &npad.system_ext_states};
413 &npad.right_joy_states,
414 &npad.pokeball_states,
415 &npad.libnx};
416 420
417 for (auto* main_controller : controller_npads) { 421 for (auto* main_controller : controller_npads) {
418 main_controller->common.entry_count = 16; 422 main_controller->common.entry_count = 16;
@@ -442,19 +446,19 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
442 auto& pad_state = npad_pad_states[npad_index]; 446 auto& pad_state = npad_pad_states[npad_index];
443 447
444 auto& main_controller = 448 auto& main_controller =
445 npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; 449 npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index];
446 auto& handheld_entry = 450 auto& handheld_entry =
447 npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; 451 npad.handheld_states.npad[npad.handheld_states.common.last_entry_index];
448 auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; 452 auto& dual_entry = npad.joy_dual_states.npad[npad.joy_dual_states.common.last_entry_index];
449 auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; 453 auto& left_entry = npad.joy_left_states.npad[npad.joy_left_states.common.last_entry_index];
450 auto& right_entry = 454 auto& right_entry =
451 npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; 455 npad.joy_right_states.npad[npad.joy_right_states.common.last_entry_index];
452 auto& pokeball_entry = 456 auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index];
453 npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; 457 auto& libnx_entry =
454 auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; 458 npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index];
455 459
456 libnx_entry.connection_status.raw = 0; 460 libnx_entry.connection_status.raw = 0;
457 libnx_entry.connection_status.IsConnected.Assign(1); 461 libnx_entry.connection_status.is_connected.Assign(1);
458 462
459 switch (controller_type) { 463 switch (controller_type) {
460 case NPadControllerType::None: 464 case NPadControllerType::None:
@@ -462,67 +466,67 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8*
462 break; 466 break;
463 case NPadControllerType::ProController: 467 case NPadControllerType::ProController:
464 main_controller.connection_status.raw = 0; 468 main_controller.connection_status.raw = 0;
465 main_controller.connection_status.IsConnected.Assign(1); 469 main_controller.connection_status.is_connected.Assign(1);
466 main_controller.connection_status.IsWired.Assign(1); 470 main_controller.connection_status.is_wired.Assign(1);
467 main_controller.pad.pad_states.raw = pad_state.pad_states.raw; 471 main_controller.pad.pad_states.raw = pad_state.pad_states.raw;
468 main_controller.pad.l_stick = pad_state.l_stick; 472 main_controller.pad.l_stick = pad_state.l_stick;
469 main_controller.pad.r_stick = pad_state.r_stick; 473 main_controller.pad.r_stick = pad_state.r_stick;
470 474
471 libnx_entry.connection_status.IsWired.Assign(1); 475 libnx_entry.connection_status.is_wired.Assign(1);
472 break; 476 break;
473 case NPadControllerType::Handheld: 477 case NPadControllerType::Handheld:
474 handheld_entry.connection_status.raw = 0; 478 handheld_entry.connection_status.raw = 0;
475 handheld_entry.connection_status.IsConnected.Assign(1); 479 handheld_entry.connection_status.is_connected.Assign(1);
476 handheld_entry.connection_status.IsWired.Assign(1); 480 handheld_entry.connection_status.is_wired.Assign(1);
477 handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); 481 handheld_entry.connection_status.is_left_connected.Assign(1);
478 handheld_entry.connection_status.IsRightJoyConnected.Assign(1); 482 handheld_entry.connection_status.is_right_connected.Assign(1);
479 handheld_entry.connection_status.IsLeftJoyWired.Assign(1); 483 handheld_entry.connection_status.is_left_wired.Assign(1);
480 handheld_entry.connection_status.IsRightJoyWired.Assign(1); 484 handheld_entry.connection_status.is_right_wired.Assign(1);
481 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; 485 handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw;
482 handheld_entry.pad.l_stick = pad_state.l_stick; 486 handheld_entry.pad.l_stick = pad_state.l_stick;
483 handheld_entry.pad.r_stick = pad_state.r_stick; 487 handheld_entry.pad.r_stick = pad_state.r_stick;
484 488
485 libnx_entry.connection_status.IsWired.Assign(1); 489 libnx_entry.connection_status.is_wired.Assign(1);
486 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); 490 libnx_entry.connection_status.is_left_connected.Assign(1);
487 libnx_entry.connection_status.IsRightJoyConnected.Assign(1); 491 libnx_entry.connection_status.is_right_connected.Assign(1);
488 libnx_entry.connection_status.IsLeftJoyWired.Assign(1); 492 libnx_entry.connection_status.is_left_wired.Assign(1);
489 libnx_entry.connection_status.IsRightJoyWired.Assign(1); 493 libnx_entry.connection_status.is_right_wired.Assign(1);
490 break; 494 break;
491 case NPadControllerType::JoyDual: 495 case NPadControllerType::JoyDual:
492 dual_entry.connection_status.raw = 0; 496 dual_entry.connection_status.raw = 0;
493 dual_entry.connection_status.IsConnected.Assign(1); 497 dual_entry.connection_status.is_connected.Assign(1);
494 dual_entry.connection_status.IsLeftJoyConnected.Assign(1); 498 dual_entry.connection_status.is_left_connected.Assign(1);
495 dual_entry.connection_status.IsRightJoyConnected.Assign(1); 499 dual_entry.connection_status.is_right_connected.Assign(1);
496 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; 500 dual_entry.pad.pad_states.raw = pad_state.pad_states.raw;
497 dual_entry.pad.l_stick = pad_state.l_stick; 501 dual_entry.pad.l_stick = pad_state.l_stick;
498 dual_entry.pad.r_stick = pad_state.r_stick; 502 dual_entry.pad.r_stick = pad_state.r_stick;
499 503
500 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); 504 libnx_entry.connection_status.is_left_connected.Assign(1);
501 libnx_entry.connection_status.IsRightJoyConnected.Assign(1); 505 libnx_entry.connection_status.is_right_connected.Assign(1);
502 break; 506 break;
503 case NPadControllerType::JoyLeft: 507 case NPadControllerType::JoyLeft:
504 left_entry.connection_status.raw = 0; 508 left_entry.connection_status.raw = 0;
505 left_entry.connection_status.IsConnected.Assign(1); 509 left_entry.connection_status.is_connected.Assign(1);
506 left_entry.connection_status.IsLeftJoyConnected.Assign(1); 510 left_entry.connection_status.is_left_connected.Assign(1);
507 left_entry.pad.pad_states.raw = pad_state.pad_states.raw; 511 left_entry.pad.pad_states.raw = pad_state.pad_states.raw;
508 left_entry.pad.l_stick = pad_state.l_stick; 512 left_entry.pad.l_stick = pad_state.l_stick;
509 left_entry.pad.r_stick = pad_state.r_stick; 513 left_entry.pad.r_stick = pad_state.r_stick;
510 514
511 libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); 515 libnx_entry.connection_status.is_left_connected.Assign(1);
512 break; 516 break;
513 case NPadControllerType::JoyRight: 517 case NPadControllerType::JoyRight:
514 right_entry.connection_status.raw = 0; 518 right_entry.connection_status.raw = 0;
515 right_entry.connection_status.IsConnected.Assign(1); 519 right_entry.connection_status.is_connected.Assign(1);
516 right_entry.connection_status.IsRightJoyConnected.Assign(1); 520 right_entry.connection_status.is_right_connected.Assign(1);
517 right_entry.pad.pad_states.raw = pad_state.pad_states.raw; 521 right_entry.pad.pad_states.raw = pad_state.pad_states.raw;
518 right_entry.pad.l_stick = pad_state.l_stick; 522 right_entry.pad.l_stick = pad_state.l_stick;
519 right_entry.pad.r_stick = pad_state.r_stick; 523 right_entry.pad.r_stick = pad_state.r_stick;
520 524
521 libnx_entry.connection_status.IsRightJoyConnected.Assign(1); 525 libnx_entry.connection_status.is_right_connected.Assign(1);
522 break; 526 break;
523 case NPadControllerType::Pokeball: 527 case NPadControllerType::Pokeball:
524 pokeball_entry.connection_status.raw = 0; 528 pokeball_entry.connection_status.raw = 0;
525 pokeball_entry.connection_status.IsConnected.Assign(1); 529 pokeball_entry.connection_status.is_connected.Assign(1);
526 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; 530 pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw;
527 pokeball_entry.pad.l_stick = pad_state.l_stick; 531 pokeball_entry.pad.l_stick = pad_state.l_stick;
528 pokeball_entry.pad.r_stick = pad_state.r_stick; 532 pokeball_entry.pad.r_stick = pad_state.r_stick;
@@ -556,7 +560,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
556 } 560 }
557 561
558 const std::array<SixAxisGeneric*, 6> controller_sixaxes{ 562 const std::array<SixAxisGeneric*, 6> controller_sixaxes{
559 &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, 563 &npad.sixaxis_fullkey, &npad.sixaxis_handheld, &npad.sixaxis_dual_left,
560 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, 564 &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right,
561 }; 565 };
562 566
@@ -594,7 +598,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
594 } 598 }
595 599
596 auto& full_sixaxis_entry = 600 auto& full_sixaxis_entry =
597 npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; 601 npad.sixaxis_fullkey.sixaxis[npad.sixaxis_fullkey.common.last_entry_index];
598 auto& handheld_sixaxis_entry = 602 auto& handheld_sixaxis_entry =
599 npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; 603 npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index];
600 auto& dual_left_sixaxis_entry = 604 auto& dual_left_sixaxis_entry =
@@ -611,7 +615,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
611 UNREACHABLE(); 615 UNREACHABLE();
612 break; 616 break;
613 case NPadControllerType::ProController: 617 case NPadControllerType::ProController:
618 full_sixaxis_entry.attribute.raw = 0;
614 if (sixaxis_sensors_enabled && motions[i][0]) { 619 if (sixaxis_sensors_enabled && motions[i][0]) {
620 full_sixaxis_entry.attribute.is_connected.Assign(1);
615 full_sixaxis_entry.accel = motion_devices[0].accel; 621 full_sixaxis_entry.accel = motion_devices[0].accel;
616 full_sixaxis_entry.gyro = motion_devices[0].gyro; 622 full_sixaxis_entry.gyro = motion_devices[0].gyro;
617 full_sixaxis_entry.rotation = motion_devices[0].rotation; 623 full_sixaxis_entry.rotation = motion_devices[0].rotation;
@@ -619,7 +625,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
619 } 625 }
620 break; 626 break;
621 case NPadControllerType::Handheld: 627 case NPadControllerType::Handheld:
628 handheld_sixaxis_entry.attribute.raw = 0;
622 if (sixaxis_sensors_enabled && motions[i][0]) { 629 if (sixaxis_sensors_enabled && motions[i][0]) {
630 handheld_sixaxis_entry.attribute.is_connected.Assign(1);
623 handheld_sixaxis_entry.accel = motion_devices[0].accel; 631 handheld_sixaxis_entry.accel = motion_devices[0].accel;
624 handheld_sixaxis_entry.gyro = motion_devices[0].gyro; 632 handheld_sixaxis_entry.gyro = motion_devices[0].gyro;
625 handheld_sixaxis_entry.rotation = motion_devices[0].rotation; 633 handheld_sixaxis_entry.rotation = motion_devices[0].rotation;
@@ -627,8 +635,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
627 } 635 }
628 break; 636 break;
629 case NPadControllerType::JoyDual: 637 case NPadControllerType::JoyDual:
638 dual_left_sixaxis_entry.attribute.raw = 0;
639 dual_right_sixaxis_entry.attribute.raw = 0;
630 if (sixaxis_sensors_enabled && motions[i][0]) { 640 if (sixaxis_sensors_enabled && motions[i][0]) {
631 // Set motion for the left joycon 641 // Set motion for the left joycon
642 dual_left_sixaxis_entry.attribute.is_connected.Assign(1);
632 dual_left_sixaxis_entry.accel = motion_devices[0].accel; 643 dual_left_sixaxis_entry.accel = motion_devices[0].accel;
633 dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; 644 dual_left_sixaxis_entry.gyro = motion_devices[0].gyro;
634 dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; 645 dual_left_sixaxis_entry.rotation = motion_devices[0].rotation;
@@ -636,6 +647,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
636 } 647 }
637 if (sixaxis_sensors_enabled && motions[i][1]) { 648 if (sixaxis_sensors_enabled && motions[i][1]) {
638 // Set motion for the right joycon 649 // Set motion for the right joycon
650 dual_right_sixaxis_entry.attribute.is_connected.Assign(1);
639 dual_right_sixaxis_entry.accel = motion_devices[1].accel; 651 dual_right_sixaxis_entry.accel = motion_devices[1].accel;
640 dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; 652 dual_right_sixaxis_entry.gyro = motion_devices[1].gyro;
641 dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; 653 dual_right_sixaxis_entry.rotation = motion_devices[1].rotation;
@@ -643,7 +655,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
643 } 655 }
644 break; 656 break;
645 case NPadControllerType::JoyLeft: 657 case NPadControllerType::JoyLeft:
658 left_sixaxis_entry.attribute.raw = 0;
646 if (sixaxis_sensors_enabled && motions[i][0]) { 659 if (sixaxis_sensors_enabled && motions[i][0]) {
660 left_sixaxis_entry.attribute.is_connected.Assign(1);
647 left_sixaxis_entry.accel = motion_devices[0].accel; 661 left_sixaxis_entry.accel = motion_devices[0].accel;
648 left_sixaxis_entry.gyro = motion_devices[0].gyro; 662 left_sixaxis_entry.gyro = motion_devices[0].gyro;
649 left_sixaxis_entry.rotation = motion_devices[0].rotation; 663 left_sixaxis_entry.rotation = motion_devices[0].rotation;
@@ -651,7 +665,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
651 } 665 }
652 break; 666 break;
653 case NPadControllerType::JoyRight: 667 case NPadControllerType::JoyRight:
668 right_sixaxis_entry.attribute.raw = 0;
654 if (sixaxis_sensors_enabled && motions[i][1]) { 669 if (sixaxis_sensors_enabled && motions[i][1]) {
670 right_sixaxis_entry.attribute.is_connected.Assign(1);
655 right_sixaxis_entry.accel = motion_devices[1].accel; 671 right_sixaxis_entry.accel = motion_devices[1].accel;
656 right_sixaxis_entry.gyro = motion_devices[1].gyro; 672 right_sixaxis_entry.gyro = motion_devices[1].gyro;
657 right_sixaxis_entry.rotation = motion_devices[1].rotation; 673 right_sixaxis_entry.rotation = motion_devices[1].rotation;
@@ -717,8 +733,8 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
717void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { 733void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) {
718 const std::size_t npad_index = NPadIdToIndex(npad_id); 734 const std::size_t npad_index = NPadIdToIndex(npad_id);
719 ASSERT(npad_index < shared_memory_entries.size()); 735 ASSERT(npad_index < shared_memory_entries.size());
720 if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) { 736 if (shared_memory_entries[npad_index].assignment_mode != assignment_mode) {
721 shared_memory_entries[npad_index].pad_assignment = assignment_mode; 737 shared_memory_entries[npad_index].assignment_mode = assignment_mode;
722 } 738 }
723} 739}
724 740
@@ -926,9 +942,17 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
926 connected_controllers[npad_index].is_connected = false; 942 connected_controllers[npad_index].is_connected = false;
927 943
928 auto& controller = shared_memory_entries[npad_index]; 944 auto& controller = shared_memory_entries[npad_index];
929 controller.joy_styles.raw = 0; // Zero out 945 controller.style_set.raw = 0; // Zero out
930 controller.device_type.raw = 0; 946 controller.device_type.raw = 0;
931 controller.properties.raw = 0; 947 controller.system_properties.raw = 0;
948 controller.button_properties.raw = 0;
949 controller.battery_level_dual = 0;
950 controller.battery_level_left = 0;
951 controller.battery_level_right = 0;
952 controller.fullkey_color = {};
953 controller.joycon_color = {};
954 controller.assignment_mode = NpadAssignments::Dual;
955 controller.footer_type = AppletFooterUiType::None;
932 956
933 SignalStyleSetChangedEvent(IndexToNPad(npad_index)); 957 SignalStyleSetChangedEvent(IndexToNPad(npad_index));
934} 958}
@@ -1104,7 +1128,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
1104 [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { 1128 [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) {
1105 switch (controller) { 1129 switch (controller) {
1106 case NPadControllerType::ProController: 1130 case NPadControllerType::ProController:
1107 return style.pro_controller; 1131 return style.fullkey;
1108 case NPadControllerType::JoyDual: 1132 case NPadControllerType::JoyDual:
1109 return style.joycon_dual; 1133 return style.joycon_dual;
1110 case NPadControllerType::JoyLeft: 1134 case NPadControllerType::JoyLeft:
@@ -1112,7 +1136,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
1112 case NPadControllerType::JoyRight: 1136 case NPadControllerType::JoyRight:
1113 return style.joycon_right; 1137 return style.joycon_right;
1114 case NPadControllerType::Pokeball: 1138 case NPadControllerType::Pokeball:
1115 return style.pokeball; 1139 return style.palma;
1116 default: 1140 default:
1117 return false; 1141 return false;
1118 } 1142 }
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 1a65b19f5..48bab988c 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -94,10 +94,10 @@ public:
94 }; 94 };
95 95
96 enum class NpadCommunicationMode : u64 { 96 enum class NpadCommunicationMode : u64 {
97 Unknown0 = 0, 97 Mode_5ms = 0,
98 Unknown1 = 1, 98 Mode_10ms = 1,
99 Unknown2 = 2, 99 Mode_15ms = 2,
100 Unknown3 = 3, 100 Default = 3,
101 }; 101 };
102 102
103 struct DeviceHandle { 103 struct DeviceHandle {
@@ -112,13 +112,18 @@ public:
112 union { 112 union {
113 u32_le raw{}; 113 u32_le raw{};
114 114
115 BitField<0, 1, u32> pro_controller; 115 BitField<0, 1, u32> fullkey;
116 BitField<1, 1, u32> handheld; 116 BitField<1, 1, u32> handheld;
117 BitField<2, 1, u32> joycon_dual; 117 BitField<2, 1, u32> joycon_dual;
118 BitField<3, 1, u32> joycon_left; 118 BitField<3, 1, u32> joycon_left;
119 BitField<4, 1, u32> joycon_right; 119 BitField<4, 1, u32> joycon_right;
120 120 BitField<5, 1, u32> gamecube;
121 BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible 121 BitField<6, 1, u32> palma;
122 BitField<7, 1, u32> lark;
123 BitField<8, 1, u32> handheld_lark;
124 BitField<9, 1, u32> lucia;
125 BitField<29, 1, u32> system_ext;
126 BitField<30, 1, u32> system;
122 }; 127 };
123 }; 128 };
124 static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); 129 static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
@@ -242,12 +247,32 @@ private:
242 }; 247 };
243 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); 248 static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size");
244 249
250 enum class ColorAttributes : u32_le {
251 Ok = 0,
252 ReadError = 1,
253 NoController = 2,
254 };
255 static_assert(sizeof(ColorAttributes) == 4, "ColorAttributes is an invalid size");
256
245 struct ControllerColor { 257 struct ControllerColor {
246 u32_le body_color; 258 u32_le body;
247 u32_le button_color; 259 u32_le button;
248 }; 260 };
249 static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size"); 261 static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size");
250 262
263 struct FullKeyColor {
264 ColorAttributes attribute;
265 ControllerColor fullkey;
266 };
267 static_assert(sizeof(FullKeyColor) == 0xC, "FullKeyColor is an invalid size");
268
269 struct JoyconColor {
270 ColorAttributes attribute;
271 ControllerColor left;
272 ControllerColor right;
273 };
274 static_assert(sizeof(JoyconColor) == 0x14, "JoyconColor is an invalid size");
275
251 struct ControllerPadState { 276 struct ControllerPadState {
252 union { 277 union {
253 u64_le raw{}; 278 u64_le raw{};
@@ -289,6 +314,9 @@ private:
289 314
290 BitField<26, 1, u64> right_sl; 315 BitField<26, 1, u64> right_sl;
291 BitField<27, 1, u64> right_sr; 316 BitField<27, 1, u64> right_sr;
317
318 BitField<28, 1, u64> palma;
319 BitField<30, 1, u64> handheld_left_b;
292 }; 320 };
293 }; 321 };
294 static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); 322 static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size");
@@ -302,12 +330,12 @@ private:
302 struct ConnectionState { 330 struct ConnectionState {
303 union { 331 union {
304 u32_le raw{}; 332 u32_le raw{};
305 BitField<0, 1, u32> IsConnected; 333 BitField<0, 1, u32> is_connected;
306 BitField<1, 1, u32> IsWired; 334 BitField<1, 1, u32> is_wired;
307 BitField<2, 1, u32> IsLeftJoyConnected; 335 BitField<2, 1, u32> is_left_connected;
308 BitField<3, 1, u32> IsLeftJoyWired; 336 BitField<3, 1, u32> is_left_wired;
309 BitField<4, 1, u32> IsRightJoyConnected; 337 BitField<4, 1, u32> is_right_connected;
310 BitField<5, 1, u32> IsRightJoyWired; 338 BitField<5, 1, u32> is_right_wired;
311 }; 339 };
312 }; 340 };
313 static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); 341 static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size");
@@ -333,6 +361,15 @@ private:
333 }; 361 };
334 static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); 362 static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size");
335 363
364 struct SixAxisAttributes {
365 union {
366 u32_le raw{};
367 BitField<0, 1, u32> is_connected;
368 BitField<1, 1, u32> is_interpolated;
369 };
370 };
371 static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size");
372
336 struct SixAxisStates { 373 struct SixAxisStates {
337 s64_le timestamp{}; 374 s64_le timestamp{};
338 INSERT_PADDING_WORDS(2); 375 INSERT_PADDING_WORDS(2);
@@ -341,7 +378,8 @@ private:
341 Common::Vec3f gyro{}; 378 Common::Vec3f gyro{};
342 Common::Vec3f rotation{}; 379 Common::Vec3f rotation{};
343 std::array<Common::Vec3f, 3> orientation{}; 380 std::array<Common::Vec3f, 3> orientation{};
344 s64_le always_one{1}; 381 SixAxisAttributes attribute;
382 INSERT_PADDING_BYTES(4); // Reserved
345 }; 383 };
346 static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); 384 static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size");
347 385
@@ -351,32 +389,54 @@ private:
351 }; 389 };
352 static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); 390 static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size");
353 391
354 enum class ColorReadError : u32_le { 392 struct NPadSystemProperties {
355 ReadOk = 0,
356 ColorDoesntExist = 1,
357 NoController = 2,
358 };
359
360 struct NPadProperties {
361 union { 393 union {
362 s64_le raw{}; 394 s64_le raw{};
395 BitField<0, 1, s64> is_charging_joy_dual;
396 BitField<1, 1, s64> is_charging_joy_left;
397 BitField<2, 1, s64> is_charging_joy_right;
398 BitField<3, 1, s64> is_powered_joy_dual;
399 BitField<4, 1, s64> is_powered_joy_left;
400 BitField<5, 1, s64> is_powered_joy_right;
401 BitField<9, 1, s64> is_system_unsupported_button;
402 BitField<10, 1, s64> is_system_ext_unsupported_button;
363 BitField<11, 1, s64> is_vertical; 403 BitField<11, 1, s64> is_vertical;
364 BitField<12, 1, s64> is_horizontal; 404 BitField<12, 1, s64> is_horizontal;
365 BitField<13, 1, s64> use_plus; 405 BitField<13, 1, s64> use_plus;
366 BitField<14, 1, s64> use_minus; 406 BitField<14, 1, s64> use_minus;
407 BitField<15, 1, s64> use_directional_buttons;
408 };
409 };
410 static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size");
411
412 struct NPadButtonProperties {
413 union {
414 s32_le raw{};
415 BitField<0, 1, s32> is_home_button_protection_enabled;
367 }; 416 };
368 }; 417 };
418 static_assert(sizeof(NPadButtonProperties) == 0x4, "NPadButtonProperties is an invalid size");
369 419
370 struct NPadDevice { 420 struct NPadDevice {
371 union { 421 union {
372 u32_le raw{}; 422 u32_le raw{};
373 BitField<0, 1, s32> pro_controller; 423 BitField<0, 1, s32> fullkey;
374 BitField<1, 1, s32> handheld; 424 BitField<1, 1, s32> debug_pad;
375 BitField<2, 1, s32> handheld_left; 425 BitField<2, 1, s32> handheld_left;
376 BitField<3, 1, s32> handheld_right; 426 BitField<3, 1, s32> handheld_right;
377 BitField<4, 1, s32> joycon_left; 427 BitField<4, 1, s32> joycon_left;
378 BitField<5, 1, s32> joycon_right; 428 BitField<5, 1, s32> joycon_right;
379 BitField<6, 1, s32> pokeball; 429 BitField<6, 1, s32> palma;
430 BitField<7, 1, s32> lark_hvc_left;
431 BitField<8, 1, s32> lark_hvc_right;
432 BitField<9, 1, s32> lark_nes_left;
433 BitField<10, 1, s32> lark_nes_right;
434 BitField<11, 1, s32> handheld_lark_hvc_left;
435 BitField<12, 1, s32> handheld_lark_hvc_right;
436 BitField<13, 1, s32> handheld_lark_nes_left;
437 BitField<14, 1, s32> handheld_lark_nes_right;
438 BitField<15, 1, s32> lucia;
439 BitField<31, 1, s32> system;
380 }; 440 };
381 }; 441 };
382 442
@@ -387,37 +447,69 @@ private:
387 std::array<Common::Vec3f, 3> orientation; 447 std::array<Common::Vec3f, 3> orientation;
388 }; 448 };
389 449
390 struct NPadEntry { 450 struct NfcXcdHandle {
391 NpadStyleSet joy_styles; 451 INSERT_PADDING_BYTES(0x60);
392 NpadAssignments pad_assignment; 452 };
453
454 struct AppletFooterUiAttributes {
455 INSERT_PADDING_BYTES(0x4);
456 };
393 457
394 ColorReadError single_color_error; 458 enum class AppletFooterUiType : u8 {
395 ControllerColor single_color; 459 None = 0,
460 HandheldNone = 1,
461 HandheldJoyConLeftOnly = 1,
462 HandheldJoyConRightOnly = 3,
463 HandheldJoyConLeftJoyConRight = 4,
464 JoyDual = 5,
465 JoyDualLeftOnly = 6,
466 JoyDualRightOnly = 7,
467 JoyLeftHorizontal = 8,
468 JoyLeftVertical = 9,
469 JoyRightHorizontal = 10,
470 JoyRightVertical = 11,
471 SwitchProController = 12,
472 CompatibleProController = 13,
473 CompatibleJoyCon = 14,
474 LarkHvc1 = 15,
475 LarkHvc2 = 16,
476 LarkNesLeft = 17,
477 LarkNesRight = 18,
478 Lucia = 19,
479 Verification = 20,
480 };
396 481
397 ColorReadError dual_color_error; 482 struct NPadEntry {
398 ControllerColor left_color; 483 NpadStyleSet style_set;
399 ControllerColor right_color; 484 NpadAssignments assignment_mode;
485 FullKeyColor fullkey_color;
486 JoyconColor joycon_color;
400 487
401 NPadGeneric main_controller_states; 488 NPadGeneric fullkey_states;
402 NPadGeneric handheld_states; 489 NPadGeneric handheld_states;
403 NPadGeneric dual_states; 490 NPadGeneric joy_dual_states;
404 NPadGeneric left_joy_states; 491 NPadGeneric joy_left_states;
405 NPadGeneric right_joy_states; 492 NPadGeneric joy_right_states;
406 NPadGeneric pokeball_states; 493 NPadGeneric palma_states;
407 NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be 494 NPadGeneric system_ext_states;
408 // relying on this for the time being 495 SixAxisGeneric sixaxis_fullkey;
409 SixAxisGeneric sixaxis_full;
410 SixAxisGeneric sixaxis_handheld; 496 SixAxisGeneric sixaxis_handheld;
411 SixAxisGeneric sixaxis_dual_left; 497 SixAxisGeneric sixaxis_dual_left;
412 SixAxisGeneric sixaxis_dual_right; 498 SixAxisGeneric sixaxis_dual_right;
413 SixAxisGeneric sixaxis_left; 499 SixAxisGeneric sixaxis_left;
414 SixAxisGeneric sixaxis_right; 500 SixAxisGeneric sixaxis_right;
415 NPadDevice device_type; 501 NPadDevice device_type;
416 NPadProperties properties; 502 INSERT_PADDING_BYTES(0x4); // reserved
417 INSERT_PADDING_WORDS(1); 503 NPadSystemProperties system_properties;
418 std::array<u32, 3> battery_level; 504 NPadButtonProperties button_properties;
419 INSERT_PADDING_BYTES(0x5c); 505 u32 battery_level_dual;
420 INSERT_PADDING_BYTES(0xdf8); 506 u32 battery_level_left;
507 u32 battery_level_right;
508 AppletFooterUiAttributes footer_attributes;
509 AppletFooterUiType footer_type;
510 // nfc_states needs to be checked switchbrew does not match with HW
511 NfcXcdHandle nfc_states;
512 INSERT_PADDING_BYTES(0xdef);
421 }; 513 };
422 static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); 514 static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
423 515
@@ -453,8 +545,7 @@ private:
453 std::vector<u32> supported_npad_id_types{}; 545 std::vector<u32> supported_npad_id_types{};
454 NpadHoldType hold_type{NpadHoldType::Vertical}; 546 NpadHoldType hold_type{NpadHoldType::Vertical};
455 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; 547 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
456 // NpadCommunicationMode is unknown, default value is 1 548 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
457 NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1};
458 // Each controller should have their own styleset changed event 549 // Each controller should have their own styleset changed event
459 std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events; 550 std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
460 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; 551 std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h
index ad229787c..5b59961bd 100644
--- a/src/core/hle/service/hid/controllers/xpad.h
+++ b/src/core/hle/service/hid/controllers/xpad.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/bit_field.h"
7#include "common/common_funcs.h" 8#include "common/common_funcs.h"
8#include "common/common_types.h" 9#include "common/common_types.h"
9#include "common/swap.h" 10#include "common/swap.h"
@@ -28,6 +29,67 @@ public:
28 void OnLoadInputDevices() override; 29 void OnLoadInputDevices() override;
29 30
30private: 31private:
32 struct Attributes {
33 union {
34 u32_le raw{};
35 BitField<0, 1, u32> is_connected;
36 BitField<1, 1, u32> is_wired;
37 BitField<2, 1, u32> is_left_connected;
38 BitField<3, 1, u32> is_left_wired;
39 BitField<4, 1, u32> is_right_connected;
40 BitField<5, 1, u32> is_right_wired;
41 };
42 };
43 static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size");
44
45 struct Buttons {
46 union {
47 u32_le raw{};
48 // Button states
49 BitField<0, 1, u32> a;
50 BitField<1, 1, u32> b;
51 BitField<2, 1, u32> x;
52 BitField<3, 1, u32> y;
53 BitField<4, 1, u32> l_stick;
54 BitField<5, 1, u32> r_stick;
55 BitField<6, 1, u32> l;
56 BitField<7, 1, u32> r;
57 BitField<8, 1, u32> zl;
58 BitField<9, 1, u32> zr;
59 BitField<10, 1, u32> plus;
60 BitField<11, 1, u32> minus;
61
62 // D-Pad
63 BitField<12, 1, u32> d_left;
64 BitField<13, 1, u32> d_up;
65 BitField<14, 1, u32> d_right;
66 BitField<15, 1, u32> d_down;
67
68 // Left JoyStick
69 BitField<16, 1, u32> l_stick_left;
70 BitField<17, 1, u32> l_stick_up;
71 BitField<18, 1, u32> l_stick_right;
72 BitField<19, 1, u32> l_stick_down;
73
74 // Right JoyStick
75 BitField<20, 1, u32> r_stick_left;
76 BitField<21, 1, u32> r_stick_up;
77 BitField<22, 1, u32> r_stick_right;
78 BitField<23, 1, u32> r_stick_down;
79
80 // Not always active?
81 BitField<24, 1, u32> left_sl;
82 BitField<25, 1, u32> left_sr;
83
84 BitField<26, 1, u32> right_sl;
85 BitField<27, 1, u32> right_sr;
86
87 BitField<28, 1, u32> palma;
88 BitField<30, 1, u32> handheld_left_b;
89 };
90 };
91 static_assert(sizeof(Buttons) == 4, "Buttons is an invalid size");
92
31 struct AnalogStick { 93 struct AnalogStick {
32 s32_le x; 94 s32_le x;
33 s32_le y; 95 s32_le y;
@@ -37,10 +99,10 @@ private:
37 struct XPadState { 99 struct XPadState {
38 s64_le sampling_number; 100 s64_le sampling_number;
39 s64_le sampling_number2; 101 s64_le sampling_number2;
40 s32_le attributes; 102 Attributes attributes;
41 u32_le pad_states; 103 Buttons pad_states;
42 AnalogStick x_stick; 104 AnalogStick l_stick;
43 AnalogStick y_stick; 105 AnalogStick r_stick;
44 }; 106 };
45 static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); 107 static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size");
46 108
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index dda33f2b4..51a010a55 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -59,20 +59,26 @@ IAppletResource::IAppletResource(Core::System& system_)
59 MakeController<Controller_Mouse>(HidController::Mouse); 59 MakeController<Controller_Mouse>(HidController::Mouse);
60 MakeController<Controller_Keyboard>(HidController::Keyboard); 60 MakeController<Controller_Keyboard>(HidController::Keyboard);
61 MakeController<Controller_XPad>(HidController::XPad); 61 MakeController<Controller_XPad>(HidController::XPad);
62 MakeController<Controller_Stubbed>(HidController::Unknown1); 62 MakeController<Controller_Stubbed>(HidController::HomeButton);
63 MakeController<Controller_Stubbed>(HidController::Unknown2); 63 MakeController<Controller_Stubbed>(HidController::SleepButton);
64 MakeController<Controller_Stubbed>(HidController::Unknown3); 64 MakeController<Controller_Stubbed>(HidController::CaptureButton);
65 MakeController<Controller_Stubbed>(HidController::SixAxisSensor); 65 MakeController<Controller_Stubbed>(HidController::InputDetector);
66 MakeController<Controller_Stubbed>(HidController::UniquePad);
66 MakeController<Controller_NPad>(HidController::NPad); 67 MakeController<Controller_NPad>(HidController::NPad);
67 MakeController<Controller_Gesture>(HidController::Gesture); 68 MakeController<Controller_Gesture>(HidController::Gesture);
69 MakeController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor);
68 70
69 // Homebrew doesn't try to activate some controllers, so we activate them by default 71 // Homebrew doesn't try to activate some controllers, so we activate them by default
70 GetController<Controller_NPad>(HidController::NPad).ActivateController(); 72 GetController<Controller_NPad>(HidController::NPad).ActivateController();
71 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); 73 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
72 74
73 GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); 75 GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
74 GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); 76 GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
75 GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); 77 GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000);
78 GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200);
79 GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00);
80 GetController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor)
81 .SetCommonHeaderOffset(0x3C200);
76 82
77 // Register update callbacks 83 // Register update callbacks
78 pad_update_event = Core::Timing::CreateEvent( 84 pad_update_event = Core::Timing::CreateEvent(
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index d991bd721..7cc0433e2 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -29,12 +29,14 @@ enum class HidController : std::size_t {
29 Mouse, 29 Mouse,
30 Keyboard, 30 Keyboard,
31 XPad, 31 XPad,
32 Unknown1, 32 HomeButton,
33 Unknown2, 33 SleepButton,
34 Unknown3, 34 CaptureButton,
35 SixAxisSensor, 35 InputDetector,
36 UniquePad,
36 NPad, 37 NPad,
37 Gesture, 38 Gesture,
39 ConsoleSixAxisSensor,
38 40
39 MaxControllers, 41 MaxControllers,
40}; 42};
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 1ab5bcbb9..b40d7c5e2 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -884,7 +884,7 @@ void ConfigureInputPlayer::SetConnectableControllers() {
884 index_controller_type_pairs.clear(); 884 index_controller_type_pairs.clear();
885 ui->comboControllerType->clear(); 885 ui->comboControllerType->clear();
886 886
887 if (enable_all || npad_style_set.pro_controller == 1) { 887 if (enable_all || npad_style_set.fullkey == 1) {
888 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 888 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
889 Settings::ControllerType::ProController); 889 Settings::ControllerType::ProController);
890 ui->comboControllerType->addItem(tr("Pro Controller")); 890 ui->comboControllerType->addItem(tr("Pro Controller"));