From f30ef987615729f5a3b8eab524ce5680369057e9 Mon Sep 17 00:00:00 2001 From: german Date: Sun, 10 Jan 2021 11:37:19 -0600 Subject: [PATCH 1/3] Adds missing controller types and properties --- .../hle/service/hid/controllers/keyboard.cpp | 17 +++-- .../hle/service/hid/controllers/keyboard.h | 21 +++++- .../hle/service/hid/controllers/mouse.cpp | 12 ++-- src/core/hle/service/hid/controllers/mouse.h | 26 ++++++- src/core/hle/service/hid/controllers/npad.cpp | 12 ++++ src/core/hle/service/hid/controllers/npad.h | 33 ++++++++- src/core/hle/service/hid/controllers/xpad.h | 70 +++++++++++++++++-- src/core/hle/service/hid/hid.cpp | 20 ++++-- src/core/hle/service/hid/hid.h | 10 +-- 9 files changed, 191 insertions(+), 30 deletions(-) diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 59b694cd4..fd5d5e057 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, cur_entry.sampling_number2 = cur_entry.sampling_number; cur_entry.key.fill(0); - cur_entry.modifier = 0; if (Settings::values.keyboard_enabled) { for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { auto& entry = cur_entry.key[i / KEYS_PER_BYTE]; entry = static_cast(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE))); } - for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { - cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); - } + using namespace Settings::NativeKeyboard; + + // TODO: Assign the correct key to all modifiers + cur_entry.modifier.control.Assign(keyboard_mods[LeftControl]->GetStatus()); + cur_entry.modifier.shift.Assign(keyboard_mods[LeftShift]->GetStatus()); + cur_entry.modifier.left_alt.Assign(keyboard_mods[LeftAlt]->GetStatus()); + cur_entry.modifier.right_alt.Assign(keyboard_mods[RightAlt]->GetStatus()); + cur_entry.modifier.gui.Assign(0); + cur_entry.modifier.caps_lock.Assign(keyboard_mods[CapsLock]->GetStatus()); + cur_entry.modifier.scroll_lock.Assign(keyboard_mods[ScrollLock]->GetStatus()); + cur_entry.modifier.num_lock.Assign(keyboard_mods[NumLock]->GetStatus()); + cur_entry.modifier.katana.Assign(0); + cur_entry.modifier.hiragana.Assign(0); } std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); } diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index f3eef5936..8a89eb4bb 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -5,6 +5,7 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -31,12 +32,28 @@ public: void OnLoadInputDevices() override; private: + struct Modifiers { + union { + s32_le raw{}; + BitField<0, 1, u32> control; + BitField<1, 1, u32> shift; + BitField<2, 1, u32> left_alt; + BitField<3, 1, u32> right_alt; + BitField<4, 1, u32> gui; + BitField<8, 1, u32> caps_lock; + BitField<9, 1, u32> scroll_lock; + BitField<10, 1, u32> num_lock; + BitField<11, 1, u32> katana; + BitField<12, 1, u32> hiragana; + }; + }; + static_assert(sizeof(Modifiers) == 0x4, "Modifiers is an invalid size"); + struct KeyboardState { s64_le sampling_number; s64_le sampling_number2; - s32_le modifier; - s32_le attribute; + Modifiers modifier; std::array key; }; 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..30924d9e2 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -35,7 +35,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; - + cur_entry.attribute.raw = 0; if (Settings::values.mouse_enabled) { const auto [px, py, sx, sy] = mouse_device->GetStatus(); const auto x = static_cast(px * Layout::ScreenUndocked::Width); @@ -46,10 +46,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.delta_y = y - last_entry.y; cur_entry.mouse_wheel_x = sx; cur_entry.mouse_wheel_y = sy; + cur_entry.attribute.is_connected.Assign(1); - for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) { - cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); - } + using namespace Settings::NativeMouseButton; + cur_entry.button.left.Assign(mouse_button_devices[Left]->GetStatus()); + cur_entry.button.right.Assign(mouse_button_devices[Right]->GetStatus()); + cur_entry.button.middle.Assign(mouse_button_devices[Middle]->GetStatus()); + cur_entry.button.forward.Assign(mouse_button_devices[Forward]->GetStatus()); + cur_entry.button.back.Assign(mouse_button_devices[Back]->GetStatus()); } 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..2c8ebe1d5 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -5,6 +5,7 @@ #pragma once #include +#include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" #include "core/frontend/input.h" @@ -30,6 +31,27 @@ public: void OnLoadInputDevices() override; private: + struct Buttons { + union { + s32_le raw{}; + BitField<0, 1, u32> left; + BitField<1, 1, u32> right; + BitField<2, 1, u32> middle; + BitField<3, 1, u32> forward; + BitField<4, 1, u32> back; + }; + }; + static_assert(sizeof(Buttons) == 0x4, "Buttons is an invalid size"); + + struct Attributes { + union { + s32_le raw{}; + BitField<0, 1, u32> transferable; + BitField<1, 1, u32> is_connected; + }; + }; + static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); + struct MouseState { s64_le sampling_number; s64_le sampling_number2; @@ -39,8 +61,8 @@ private: s32_le delta_y; s32_le mouse_wheel_x; s32_le mouse_wheel_y; - s32_le button; - s32_le attribute; + Buttons button; + Attributes attribute; }; static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size"); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 0c227b135..251db1f84 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -609,7 +609,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing UNREACHABLE(); break; case NPadControllerType::ProController: + full_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + full_sixaxis_entry.attribute.IsConnected.Assign(1); full_sixaxis_entry.accel = motion_devices[0].accel; full_sixaxis_entry.gyro = motion_devices[0].gyro; full_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -617,7 +619,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::Handheld: + handheld_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + handheld_sixaxis_entry.attribute.IsConnected.Assign(1); handheld_sixaxis_entry.accel = motion_devices[0].accel; handheld_sixaxis_entry.gyro = motion_devices[0].gyro; handheld_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -625,8 +629,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyDual: + dual_left_sixaxis_entry.attribute.raw = 0; + dual_right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { // Set motion for the left joycon + dual_left_sixaxis_entry.attribute.IsConnected.Assign(1); dual_left_sixaxis_entry.accel = motion_devices[0].accel; dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -634,6 +641,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } if (sixaxis_sensors_enabled && motions[i][1]) { // Set motion for the right joycon + dual_right_sixaxis_entry.attribute.IsConnected.Assign(1); dual_right_sixaxis_entry.accel = motion_devices[1].accel; dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; @@ -641,7 +649,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyLeft: + left_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { + left_sixaxis_entry.attribute.IsConnected.Assign(1); left_sixaxis_entry.accel = motion_devices[0].accel; left_sixaxis_entry.gyro = motion_devices[0].gyro; left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -649,7 +659,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } break; case NPadControllerType::JoyRight: + right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][1]) { + right_sixaxis_entry.attribute.IsConnected.Assign(1); right_sixaxis_entry.accel = motion_devices[1].accel; right_sixaxis_entry.gyro = motion_devices[1].gyro; right_sixaxis_entry.rotation = motion_devices[1].rotation; diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 2e13922b9..e5778921f 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -113,8 +113,13 @@ public: BitField<2, 1, u32> joycon_dual; BitField<3, 1, u32> joycon_left; BitField<4, 1, u32> joycon_right; - - BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible + BitField<5, 1, u32> gamecube; + BitField<6, 1, u32> pokeball; + BitField<7, 1, u32> lark; + BitField<8, 1, u32> handheld_lark; + BitField<9, 1, u32> lucia; + BitField<29, 1, u32> system_ext; + BitField<30, 1, u32> system; }; }; static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); @@ -285,6 +290,9 @@ private: BitField<26, 1, u64> right_sl; BitField<27, 1, u64> right_sr; + + BitField<28, 1, u64> palma; + BitField<30, 1, u64> handheld_left_b; }; }; static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); @@ -329,6 +337,15 @@ private: }; static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); + struct SixAxisAttributes { + union { + u32_le raw{}; + BitField<0, 1, u32> IsConnected; + BitField<1, 1, u32> IsInterpolated; + }; + }; + static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); + struct SixAxisStates { s64_le timestamp{}; INSERT_PADDING_WORDS(2); @@ -337,7 +354,8 @@ private: Common::Vec3f gyro{}; Common::Vec3f rotation{}; std::array orientation{}; - s64_le always_one{1}; + SixAxisAttributes attribute; + INSERT_PADDING_BYTES(4); // Reserved }; static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); @@ -356,10 +374,19 @@ private: struct NPadProperties { union { s64_le raw{}; + BitField<0, 1, s64> is_charging_joy_dual; + BitField<1, 1, s64> is_charging_joy_left; + BitField<2, 1, s64> is_charging_joy_right; + BitField<3, 1, s64> is_powered_joy_dual; + BitField<4, 1, s64> is_powered_joy_left; + BitField<5, 1, s64> is_powered_joy_right; + BitField<9, 1, s64> is_system_unsuported_button; + BitField<10, 1, s64> is_system_ext_unsuported_button; BitField<11, 1, s64> is_vertical; BitField<12, 1, s64> is_horizontal; BitField<13, 1, s64> use_plus; BitField<14, 1, s64> use_minus; + BitField<15, 1, s64> use_directional_buttons; }; }; diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index ad229787c..d91cf62a2 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h @@ -4,6 +4,7 @@ #pragma once +#include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -28,6 +29,67 @@ public: void OnLoadInputDevices() override; private: + struct Attributes { + union { + s32_le raw{}; + BitField<0, 1, u32> IsConnected; + BitField<1, 1, u32> IsWired; + BitField<2, 1, u32> IsLeftConnected; + BitField<3, 1, u32> IsLeftWired; + BitField<4, 1, u32> IsRightConnected; + BitField<5, 1, u32> IsRightWired; + }; + }; + static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size"); + + struct Buttons { + union { + u32_le raw{}; + // Button states + BitField<0, 1, u32> a; + BitField<1, 1, u32> b; + BitField<2, 1, u32> x; + BitField<3, 1, u32> y; + BitField<4, 1, u32> l_stick; + BitField<5, 1, u32> r_stick; + BitField<6, 1, u32> l; + BitField<7, 1, u32> r; + BitField<8, 1, u32> zl; + BitField<9, 1, u32> zr; + BitField<10, 1, u32> plus; + BitField<11, 1, u32> minus; + + // D-Pad + BitField<12, 1, u32> d_left; + BitField<13, 1, u32> d_up; + BitField<14, 1, u32> d_right; + BitField<15, 1, u32> d_down; + + // Left JoyStick + BitField<16, 1, u32> l_stick_left; + BitField<17, 1, u32> l_stick_up; + BitField<18, 1, u32> l_stick_right; + BitField<19, 1, u32> l_stick_down; + + // Right JoyStick + BitField<20, 1, u32> r_stick_left; + BitField<21, 1, u32> r_stick_up; + BitField<22, 1, u32> r_stick_right; + BitField<23, 1, u32> r_stick_down; + + // Not always active? + BitField<24, 1, u32> left_sl; + BitField<25, 1, u32> left_sr; + + BitField<26, 1, u32> right_sl; + BitField<27, 1, u32> right_sr; + + BitField<28, 1, u32> palma; + BitField<30, 1, u32> handheld_left_b; + }; + }; + static_assert(sizeof(Buttons) == 4, "Buttons is an invalid size"); + struct AnalogStick { s32_le x; s32_le y; @@ -37,10 +99,10 @@ private: struct XPadState { s64_le sampling_number; s64_le sampling_number2; - s32_le attributes; - u32_le pad_states; - AnalogStick x_stick; - AnalogStick y_stick; + Attributes attributes; + Buttons pad_states; + AnalogStick l_stick; + AnalogStick r_stick; }; static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 4cee4838c..370e266a8 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_) MakeController(HidController::Mouse); MakeController(HidController::Keyboard); MakeController(HidController::XPad); - MakeController(HidController::Unknown1); - MakeController(HidController::Unknown2); - MakeController(HidController::Unknown3); - MakeController(HidController::SixAxisSensor); + MakeController(HidController::HomeButton); + MakeController(HidController::SleepButton); + MakeController(HidController::CaptureButton); + MakeController(HidController::InputDetector); + MakeController(HidController::UniquePad); MakeController(HidController::NPad); MakeController(HidController::Gesture); + MakeController(HidController::ConsoleSixAxisSensor); // Homebrew doesn't try to activate some controllers, so we activate them by default GetController(HidController::NPad).ActivateController(); GetController(HidController::Touchscreen).ActivateController(); - GetController(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); - GetController(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); - GetController(HidController::Unknown3).SetCommonHeaderOffset(0x5000); + GetController(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); + GetController(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); + GetController(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); + GetController(HidController::InputDetector).SetCommonHeaderOffset(0x5200); + GetController(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); + GetController(HidController::ConsoleSixAxisSensor) + .SetCommonHeaderOffset(0x3C200); // Register update callbacks 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 { Mouse, Keyboard, XPad, - Unknown1, - Unknown2, - Unknown3, - SixAxisSensor, + HomeButton, + SleepButton, + CaptureButton, + InputDetector, + UniquePad, NPad, Gesture, + ConsoleSixAxisSensor, MaxControllers, }; From 9a9e81f2e9b93d0028654c7ee50e9ebacee0e5d6 Mon Sep 17 00:00:00 2001 From: german Date: Sun, 10 Jan 2021 13:47:56 -0600 Subject: [PATCH 2/3] Fix npad struct to match switchbrew --- .../hle/service/am/applets/controller.cpp | 2 +- src/core/hle/service/hid/controllers/npad.cpp | 129 +++++++++--------- src/core/hle/service/hid/controllers/npad.h | 108 +++++++++------ .../configuration/configure_input_player.cpp | 2 +- 4 files changed, 135 insertions(+), 106 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( .border_colors = std::move(identification_colors), .enable_explain_text = enable_text, .explain_text = std::move(text), - .allow_pro_controller = npad_style_set.pro_controller == 1, + .allow_pro_controller = npad_style_set.fullkey == 1, .allow_handheld = npad_style_set.handheld == 1, .allow_dual_joycons = npad_style_set.joycon_dual == 1, .allow_left_joycon = npad_style_set.joycon_left == 1, diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 251db1f84..5d91e6fc1 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -156,76 +156,77 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { styleset_changed_events[controller_idx].writable->Signal(); return; } - controller.joy_styles.raw = 0; // Zero out + controller.style_set.raw = 0; // Zero out controller.device_type.raw = 0; - controller.properties.raw = 0; + controller.system_properties.raw = 0; switch (controller_type) { case NPadControllerType::None: UNREACHABLE(); break; case NPadControllerType::ProController: - controller.joy_styles.pro_controller.Assign(1); - controller.device_type.pro_controller.Assign(1); - controller.properties.is_vertical.Assign(1); - controller.properties.use_plus.Assign(1); - controller.properties.use_minus.Assign(1); - controller.pad_assignment = NpadAssignments::Single; + controller.style_set.fullkey.Assign(1); + controller.device_type.fullkey.Assign(1); + controller.system_properties.is_vertical.Assign(1); + controller.system_properties.use_plus.Assign(1); + controller.system_properties.use_minus.Assign(1); + controller.assignment_mode = NpadAssignments::Single; break; case NPadControllerType::Handheld: - controller.joy_styles.handheld.Assign(1); - controller.device_type.handheld.Assign(1); - controller.properties.is_vertical.Assign(1); - controller.properties.use_plus.Assign(1); - controller.properties.use_minus.Assign(1); - controller.pad_assignment = NpadAssignments::Dual; + controller.style_set.handheld.Assign(1); + controller.device_type.handheld_left.Assign(1); + controller.device_type.handheld_right.Assign(1); + controller.system_properties.is_vertical.Assign(1); + controller.system_properties.use_plus.Assign(1); + controller.system_properties.use_minus.Assign(1); + controller.assignment_mode = NpadAssignments::Dual; break; case NPadControllerType::JoyDual: - controller.joy_styles.joycon_dual.Assign(1); + controller.style_set.joycon_dual.Assign(1); controller.device_type.joycon_left.Assign(1); controller.device_type.joycon_right.Assign(1); - controller.properties.is_vertical.Assign(1); - controller.properties.use_plus.Assign(1); - controller.properties.use_minus.Assign(1); - controller.pad_assignment = NpadAssignments::Dual; + controller.system_properties.is_vertical.Assign(1); + controller.system_properties.use_plus.Assign(1); + controller.system_properties.use_minus.Assign(1); + controller.assignment_mode = NpadAssignments::Dual; break; case NPadControllerType::JoyLeft: - controller.joy_styles.joycon_left.Assign(1); + controller.style_set.joycon_left.Assign(1); controller.device_type.joycon_left.Assign(1); - controller.properties.is_horizontal.Assign(1); - controller.properties.use_minus.Assign(1); - controller.pad_assignment = NpadAssignments::Single; + controller.system_properties.is_horizontal.Assign(1); + controller.system_properties.use_minus.Assign(1); + controller.assignment_mode = NpadAssignments::Single; break; case NPadControllerType::JoyRight: - controller.joy_styles.joycon_right.Assign(1); + controller.style_set.joycon_right.Assign(1); controller.device_type.joycon_right.Assign(1); - controller.properties.is_horizontal.Assign(1); - controller.properties.use_plus.Assign(1); - controller.pad_assignment = NpadAssignments::Single; + controller.system_properties.is_horizontal.Assign(1); + controller.system_properties.use_plus.Assign(1); + controller.assignment_mode = NpadAssignments::Single; break; case NPadControllerType::Pokeball: - controller.joy_styles.pokeball.Assign(1); - controller.device_type.pokeball.Assign(1); - controller.pad_assignment = NpadAssignments::Single; + controller.style_set.palma.Assign(1); + controller.device_type.palma.Assign(1); + controller.assignment_mode = NpadAssignments::Single; break; } - controller.single_color_error = ColorReadError::ReadOk; - controller.single_color.body_color = 0; - controller.single_color.button_color = 0; + controller.fullkey_color.attribute = ColorAttributes::Ok; + controller.fullkey_color.fullkey.body = 0; + controller.fullkey_color.fullkey.button = 0; - controller.dual_color_error = ColorReadError::ReadOk; - controller.left_color.body_color = + controller.joycon_color.attribute = ColorAttributes::Ok; + controller.joycon_color.left.body = Settings::values.players.GetValue()[controller_idx].body_color_left; - controller.left_color.button_color = + controller.joycon_color.left.button = Settings::values.players.GetValue()[controller_idx].button_color_left; - controller.right_color.body_color = + controller.joycon_color.right.body = Settings::values.players.GetValue()[controller_idx].body_color_right; - controller.right_color.button_color = + controller.joycon_color.right.button = Settings::values.players.GetValue()[controller_idx].button_color_right; - controller.battery_level[0] = BATTERY_FULL; - controller.battery_level[1] = BATTERY_FULL; - controller.battery_level[2] = BATTERY_FULL; + controller.battery_level_dual = BATTERY_FULL; + controller.battery_level_left = BATTERY_FULL; + controller.battery_level_right = BATTERY_FULL; SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); } @@ -249,8 +250,8 @@ void Controller_NPad::OnInit() { style.joycon_left.Assign(1); style.joycon_right.Assign(1); style.joycon_dual.Assign(1); - style.pro_controller.Assign(1); - style.pokeball.Assign(1); + style.fullkey.Assign(1); + style.palma.Assign(1); } std::transform(Settings::values.players.GetValue().begin(), @@ -404,13 +405,10 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* } for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) { auto& npad = shared_memory_entries[i]; - const std::array controller_npads{&npad.main_controller_states, - &npad.handheld_states, - &npad.dual_states, - &npad.left_joy_states, - &npad.right_joy_states, - &npad.pokeball_states, - &npad.libnx}; + const std::array controller_npads{ + &npad.fullkey_states, &npad.handheld_states, &npad.joy_dual_states, + &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, + &npad.system_ext_states}; for (auto* main_controller : controller_npads) { main_controller->common.entry_count = 16; @@ -440,16 +438,16 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* auto& pad_state = npad_pad_states[npad_index]; auto& main_controller = - npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; + npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; auto& handheld_entry = npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; - auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; - auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; + auto& dual_entry = npad.joy_dual_states.npad[npad.joy_dual_states.common.last_entry_index]; + auto& left_entry = npad.joy_left_states.npad[npad.joy_left_states.common.last_entry_index]; auto& right_entry = - npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; - auto& pokeball_entry = - npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; - auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; + npad.joy_right_states.npad[npad.joy_right_states.common.last_entry_index]; + auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; + auto& libnx_entry = + npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; libnx_entry.connection_status.raw = 0; libnx_entry.connection_status.IsConnected.Assign(1); @@ -554,7 +552,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } const std::array controller_sixaxes{ - &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, + &npad.sixaxis_fullkey, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, }; @@ -592,7 +590,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } auto& full_sixaxis_entry = - npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; + npad.sixaxis_fullkey.sixaxis[npad.sixaxis_fullkey.common.last_entry_index]; auto& handheld_sixaxis_entry = npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; auto& dual_left_sixaxis_entry = @@ -727,8 +725,8 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { const std::size_t npad_index = NPadIdToIndex(npad_id); ASSERT(npad_index < shared_memory_entries.size()); - if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) { - shared_memory_entries[npad_index].pad_assignment = assignment_mode; + if (shared_memory_entries[npad_index].assignment_mode != assignment_mode) { + shared_memory_entries[npad_index].assignment_mode = assignment_mode; } } @@ -935,9 +933,10 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { connected_controllers[npad_index].is_connected = false; auto& controller = shared_memory_entries[npad_index]; - controller.joy_styles.raw = 0; // Zero out + controller.style_set.raw = 0; // Zero out controller.device_type.raw = 0; - controller.properties.raw = 0; + controller.system_properties.raw = 0; + controller.button_properties.raw = 0; SignalStyleSetChangedEvent(IndexToNPad(npad_index)); } @@ -1113,7 +1112,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { switch (controller) { case NPadControllerType::ProController: - return style.pro_controller; + return style.fullkey; case NPadControllerType::JoyDual: return style.joycon_dual; case NPadControllerType::JoyLeft: @@ -1121,7 +1120,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const case NPadControllerType::JoyRight: return style.joycon_right; case NPadControllerType::Pokeball: - return style.pokeball; + return style.palma; default: return false; } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index e5778921f..d791e327c 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -90,10 +90,10 @@ public: }; enum class NpadCommunicationMode : u64 { - Unknown0 = 0, - Unknown1 = 1, - Unknown2 = 2, - Unknown3 = 3, + Mode_5ms = 0, + Mode_10ms = 1, + Mode_15ms = 2, + Default = 3, }; struct DeviceHandle { @@ -108,13 +108,13 @@ public: union { u32_le raw{}; - BitField<0, 1, u32> pro_controller; + BitField<0, 1, u32> fullkey; BitField<1, 1, u32> handheld; BitField<2, 1, u32> joycon_dual; BitField<3, 1, u32> joycon_left; BitField<4, 1, u32> joycon_right; BitField<5, 1, u32> gamecube; - BitField<6, 1, u32> pokeball; + BitField<6, 1, u32> palma; BitField<7, 1, u32> lark; BitField<8, 1, u32> handheld_lark; BitField<9, 1, u32> lucia; @@ -243,12 +243,32 @@ private: }; static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); + enum class ColorAttributes : u32_le { + Ok = 0, + ReadError = 1, + NoController = 2, + }; + static_assert(sizeof(ColorAttributes) == 4, "ColorAttributes is an invalid size"); + struct ControllerColor { - u32_le body_color; - u32_le button_color; + u32_le body; + u32_le button; }; static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size"); + struct FullKeyColor { + ColorAttributes attribute; + ControllerColor fullkey; + }; + static_assert(sizeof(FullKeyColor) == 0xC, "FullKeyColor is an invalid size"); + + struct JoyconColor { + ColorAttributes attribute; + ControllerColor left; + ControllerColor right; + }; + static_assert(sizeof(JoyconColor) == 0x14, "JoyconColor is an invalid size"); + struct ControllerPadState { union { u64_le raw{}; @@ -365,13 +385,7 @@ private: }; static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); - enum class ColorReadError : u32_le { - ReadOk = 0, - ColorDoesntExist = 1, - NoController = 2, - }; - - struct NPadProperties { + struct NPadSystemProperties { union { s64_le raw{}; BitField<0, 1, s64> is_charging_joy_dual; @@ -389,17 +403,36 @@ private: BitField<15, 1, s64> use_directional_buttons; }; }; + static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); + + struct NPadButtonProperties { + union { + s32_le raw{}; + BitField<0, 1, s32> is_home_button_protection_enabled; + }; + }; + static_assert(sizeof(NPadButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); struct NPadDevice { union { u32_le raw{}; - BitField<0, 1, s32> pro_controller; - BitField<1, 1, s32> handheld; + BitField<0, 1, s32> fullkey; + BitField<1, 1, s32> debug_pad; BitField<2, 1, s32> handheld_left; BitField<3, 1, s32> handheld_right; BitField<4, 1, s32> joycon_left; BitField<5, 1, s32> joycon_right; - BitField<6, 1, s32> pokeball; + BitField<6, 1, s32> palma; + BitField<7, 1, s32> lark_hvc_left; + BitField<8, 1, s32> lark_hvc_right; + BitField<9, 1, s32> lark_nes_left; + BitField<10, 1, s32> lark_nes_right; + BitField<11, 1, s32> handheld_lark_hvc_left; + BitField<12, 1, s32> handheld_lark_hvc_right; + BitField<13, 1, s32> handheld_lark_nes_left; + BitField<14, 1, s32> handheld_lark_nes_right; + BitField<15, 1, s32> lucia; + BitField<31, 1, s32> system; }; }; @@ -411,34 +444,31 @@ private: }; struct NPadEntry { - NpadStyleSet joy_styles; - NpadAssignments pad_assignment; + NpadStyleSet style_set; + NpadAssignments assignment_mode; + FullKeyColor fullkey_color; + JoyconColor joycon_color; - ColorReadError single_color_error; - ControllerColor single_color; - - ColorReadError dual_color_error; - ControllerColor left_color; - ControllerColor right_color; - - NPadGeneric main_controller_states; + NPadGeneric fullkey_states; NPadGeneric handheld_states; - NPadGeneric dual_states; - NPadGeneric left_joy_states; - NPadGeneric right_joy_states; - NPadGeneric pokeball_states; - NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be - // relying on this for the time being - SixAxisGeneric sixaxis_full; + NPadGeneric joy_dual_states; + NPadGeneric joy_left_states; + NPadGeneric joy_right_states; + NPadGeneric palma_states; + NPadGeneric system_ext_states; + SixAxisGeneric sixaxis_fullkey; SixAxisGeneric sixaxis_handheld; SixAxisGeneric sixaxis_dual_left; SixAxisGeneric sixaxis_dual_right; SixAxisGeneric sixaxis_left; SixAxisGeneric sixaxis_right; NPadDevice device_type; - NPadProperties properties; - INSERT_PADDING_WORDS(1); - std::array battery_level; + INSERT_PADDING_BYTES(0x4); // reserved + NPadSystemProperties system_properties; + NPadButtonProperties button_properties; + u32 battery_level_dual; + u32 battery_level_left; + u32 battery_level_right; INSERT_PADDING_BYTES(0x5c); INSERT_PADDING_BYTES(0xdf8); }; @@ -477,7 +507,7 @@ private: NpadHoldType hold_type{NpadHoldType::Vertical}; NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; // NpadCommunicationMode is unknown, default value is 1 - NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1}; + NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; // Each controller should have their own styleset changed event std::array styleset_changed_events; std::array, 10> last_vibration_timepoints; diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index fbe36046b..a129dc46b 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -886,7 +886,7 @@ void ConfigureInputPlayer::SetConnectableControllers() { index_controller_type_pairs.clear(); ui->comboControllerType->clear(); - if (enable_all || npad_style_set.pro_controller == 1) { + if (enable_all || npad_style_set.fullkey == 1) { index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), Settings::ControllerType::ProController); ui->comboControllerType->addItem(tr("Pro Controller")); From 8019b2b9b5265647dbadc45f60a12e4bbfefbd77 Mon Sep 17 00:00:00 2001 From: german Date: Mon, 11 Jan 2021 00:03:17 -0600 Subject: [PATCH 3/3] Add footer types and address comments --- .../hle/service/hid/controllers/keyboard.cpp | 2 +- .../hle/service/hid/controllers/keyboard.h | 4 +- .../hle/service/hid/controllers/mouse.cpp | 1 + src/core/hle/service/hid/controllers/mouse.h | 4 +- src/core/hle/service/hid/controllers/npad.cpp | 79 +++++++++++-------- src/core/hle/service/hid/controllers/npad.h | 60 +++++++++++--- src/core/hle/service/hid/controllers/xpad.h | 14 ++-- 7 files changed, 106 insertions(+), 58 deletions(-) diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index fd5d5e057..c4a59147d 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -56,7 +56,7 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, cur_entry.modifier.caps_lock.Assign(keyboard_mods[CapsLock]->GetStatus()); cur_entry.modifier.scroll_lock.Assign(keyboard_mods[ScrollLock]->GetStatus()); cur_entry.modifier.num_lock.Assign(keyboard_mods[NumLock]->GetStatus()); - cur_entry.modifier.katana.Assign(0); + cur_entry.modifier.katakana.Assign(0); cur_entry.modifier.hiragana.Assign(0); } std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index 8a89eb4bb..b5b281752 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h @@ -34,7 +34,7 @@ public: private: struct Modifiers { union { - s32_le raw{}; + u32_le raw{}; BitField<0, 1, u32> control; BitField<1, 1, u32> shift; BitField<2, 1, u32> left_alt; @@ -43,7 +43,7 @@ private: BitField<8, 1, u32> caps_lock; BitField<9, 1, u32> scroll_lock; BitField<10, 1, u32> num_lock; - BitField<11, 1, u32> katana; + BitField<11, 1, u32> katakana; BitField<12, 1, u32> hiragana; }; }; diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index 30924d9e2..2e7457604 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp @@ -35,6 +35,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* cur_entry.sampling_number = last_entry.sampling_number + 1; cur_entry.sampling_number2 = cur_entry.sampling_number; + cur_entry.attribute.raw = 0; if (Settings::values.mouse_enabled) { const auto [px, py, sx, sy] = mouse_device->GetStatus(); diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 2c8ebe1d5..3b432a36e 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h @@ -33,7 +33,7 @@ public: private: struct Buttons { union { - s32_le raw{}; + u32_le raw{}; BitField<0, 1, u32> left; BitField<1, 1, u32> right; BitField<2, 1, u32> middle; @@ -45,7 +45,7 @@ private: struct Attributes { union { - s32_le raw{}; + u32_le raw{}; BitField<0, 1, u32> transferable; BitField<1, 1, u32> is_connected; }; diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 5d91e6fc1..5eeb6081f 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -170,6 +170,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.system_properties.use_plus.Assign(1); controller.system_properties.use_minus.Assign(1); controller.assignment_mode = NpadAssignments::Single; + controller.footer_type = AppletFooterUiType::SwitchProController; break; case NPadControllerType::Handheld: controller.style_set.handheld.Assign(1); @@ -179,6 +180,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.system_properties.use_plus.Assign(1); controller.system_properties.use_minus.Assign(1); controller.assignment_mode = NpadAssignments::Dual; + controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; break; case NPadControllerType::JoyDual: controller.style_set.joycon_dual.Assign(1); @@ -188,6 +190,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.system_properties.use_plus.Assign(1); controller.system_properties.use_minus.Assign(1); controller.assignment_mode = NpadAssignments::Dual; + controller.footer_type = AppletFooterUiType::JoyDual; break; case NPadControllerType::JoyLeft: controller.style_set.joycon_left.Assign(1); @@ -195,6 +198,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.system_properties.is_horizontal.Assign(1); controller.system_properties.use_minus.Assign(1); controller.assignment_mode = NpadAssignments::Single; + controller.footer_type = AppletFooterUiType::JoyLeftHorizontal; break; case NPadControllerType::JoyRight: controller.style_set.joycon_right.Assign(1); @@ -202,6 +206,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.system_properties.is_horizontal.Assign(1); controller.system_properties.use_plus.Assign(1); controller.assignment_mode = NpadAssignments::Single; + controller.footer_type = AppletFooterUiType::JoyRightHorizontal; break; case NPadControllerType::Pokeball: controller.style_set.palma.Assign(1); @@ -224,6 +229,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { controller.joycon_color.right.button = Settings::values.players.GetValue()[controller_idx].button_color_right; + // TODO: Investigate when we should report all batery types controller.battery_level_dual = BATTERY_FULL; controller.battery_level_left = BATTERY_FULL; controller.battery_level_right = BATTERY_FULL; @@ -450,7 +456,7 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; libnx_entry.connection_status.raw = 0; - libnx_entry.connection_status.IsConnected.Assign(1); + libnx_entry.connection_status.is_connected.Assign(1); switch (controller_type) { case NPadControllerType::None: @@ -458,67 +464,67 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* break; case NPadControllerType::ProController: main_controller.connection_status.raw = 0; - main_controller.connection_status.IsConnected.Assign(1); - main_controller.connection_status.IsWired.Assign(1); + main_controller.connection_status.is_connected.Assign(1); + main_controller.connection_status.is_wired.Assign(1); main_controller.pad.pad_states.raw = pad_state.pad_states.raw; main_controller.pad.l_stick = pad_state.l_stick; main_controller.pad.r_stick = pad_state.r_stick; - libnx_entry.connection_status.IsWired.Assign(1); + libnx_entry.connection_status.is_wired.Assign(1); break; case NPadControllerType::Handheld: handheld_entry.connection_status.raw = 0; - handheld_entry.connection_status.IsConnected.Assign(1); - handheld_entry.connection_status.IsWired.Assign(1); - handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); - handheld_entry.connection_status.IsRightJoyConnected.Assign(1); - handheld_entry.connection_status.IsLeftJoyWired.Assign(1); - handheld_entry.connection_status.IsRightJoyWired.Assign(1); + handheld_entry.connection_status.is_connected.Assign(1); + handheld_entry.connection_status.is_wired.Assign(1); + handheld_entry.connection_status.is_left_connected.Assign(1); + handheld_entry.connection_status.is_right_connected.Assign(1); + handheld_entry.connection_status.is_left_wired.Assign(1); + handheld_entry.connection_status.is_right_wired.Assign(1); handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; handheld_entry.pad.l_stick = pad_state.l_stick; handheld_entry.pad.r_stick = pad_state.r_stick; - libnx_entry.connection_status.IsWired.Assign(1); - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); - libnx_entry.connection_status.IsLeftJoyWired.Assign(1); - libnx_entry.connection_status.IsRightJoyWired.Assign(1); + libnx_entry.connection_status.is_wired.Assign(1); + libnx_entry.connection_status.is_left_connected.Assign(1); + libnx_entry.connection_status.is_right_connected.Assign(1); + libnx_entry.connection_status.is_left_wired.Assign(1); + libnx_entry.connection_status.is_right_wired.Assign(1); break; case NPadControllerType::JoyDual: dual_entry.connection_status.raw = 0; - dual_entry.connection_status.IsConnected.Assign(1); - dual_entry.connection_status.IsLeftJoyConnected.Assign(1); - dual_entry.connection_status.IsRightJoyConnected.Assign(1); + dual_entry.connection_status.is_connected.Assign(1); + dual_entry.connection_status.is_left_connected.Assign(1); + dual_entry.connection_status.is_right_connected.Assign(1); dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; dual_entry.pad.l_stick = pad_state.l_stick; dual_entry.pad.r_stick = pad_state.r_stick; - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); + libnx_entry.connection_status.is_left_connected.Assign(1); + libnx_entry.connection_status.is_right_connected.Assign(1); break; case NPadControllerType::JoyLeft: left_entry.connection_status.raw = 0; - left_entry.connection_status.IsConnected.Assign(1); - left_entry.connection_status.IsLeftJoyConnected.Assign(1); + left_entry.connection_status.is_connected.Assign(1); + left_entry.connection_status.is_left_connected.Assign(1); left_entry.pad.pad_states.raw = pad_state.pad_states.raw; left_entry.pad.l_stick = pad_state.l_stick; left_entry.pad.r_stick = pad_state.r_stick; - libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); + libnx_entry.connection_status.is_left_connected.Assign(1); break; case NPadControllerType::JoyRight: right_entry.connection_status.raw = 0; - right_entry.connection_status.IsConnected.Assign(1); - right_entry.connection_status.IsRightJoyConnected.Assign(1); + right_entry.connection_status.is_connected.Assign(1); + right_entry.connection_status.is_right_connected.Assign(1); right_entry.pad.pad_states.raw = pad_state.pad_states.raw; right_entry.pad.l_stick = pad_state.l_stick; right_entry.pad.r_stick = pad_state.r_stick; - libnx_entry.connection_status.IsRightJoyConnected.Assign(1); + libnx_entry.connection_status.is_right_connected.Assign(1); break; case NPadControllerType::Pokeball: pokeball_entry.connection_status.raw = 0; - pokeball_entry.connection_status.IsConnected.Assign(1); + pokeball_entry.connection_status.is_connected.Assign(1); pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; pokeball_entry.pad.l_stick = pad_state.l_stick; pokeball_entry.pad.r_stick = pad_state.r_stick; @@ -609,7 +615,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing case NPadControllerType::ProController: full_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { - full_sixaxis_entry.attribute.IsConnected.Assign(1); + full_sixaxis_entry.attribute.is_connected.Assign(1); full_sixaxis_entry.accel = motion_devices[0].accel; full_sixaxis_entry.gyro = motion_devices[0].gyro; full_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -619,7 +625,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing case NPadControllerType::Handheld: handheld_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { - handheld_sixaxis_entry.attribute.IsConnected.Assign(1); + handheld_sixaxis_entry.attribute.is_connected.Assign(1); handheld_sixaxis_entry.accel = motion_devices[0].accel; handheld_sixaxis_entry.gyro = motion_devices[0].gyro; handheld_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -631,7 +637,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing dual_right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { // Set motion for the left joycon - dual_left_sixaxis_entry.attribute.IsConnected.Assign(1); + dual_left_sixaxis_entry.attribute.is_connected.Assign(1); dual_left_sixaxis_entry.accel = motion_devices[0].accel; dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -639,7 +645,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing } if (sixaxis_sensors_enabled && motions[i][1]) { // Set motion for the right joycon - dual_right_sixaxis_entry.attribute.IsConnected.Assign(1); + dual_right_sixaxis_entry.attribute.is_connected.Assign(1); dual_right_sixaxis_entry.accel = motion_devices[1].accel; dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; @@ -649,7 +655,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing case NPadControllerType::JoyLeft: left_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][0]) { - left_sixaxis_entry.attribute.IsConnected.Assign(1); + left_sixaxis_entry.attribute.is_connected.Assign(1); left_sixaxis_entry.accel = motion_devices[0].accel; left_sixaxis_entry.gyro = motion_devices[0].gyro; left_sixaxis_entry.rotation = motion_devices[0].rotation; @@ -659,7 +665,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing case NPadControllerType::JoyRight: right_sixaxis_entry.attribute.raw = 0; if (sixaxis_sensors_enabled && motions[i][1]) { - right_sixaxis_entry.attribute.IsConnected.Assign(1); + right_sixaxis_entry.attribute.is_connected.Assign(1); right_sixaxis_entry.accel = motion_devices[1].accel; right_sixaxis_entry.gyro = motion_devices[1].gyro; right_sixaxis_entry.rotation = motion_devices[1].rotation; @@ -937,6 +943,13 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { controller.device_type.raw = 0; controller.system_properties.raw = 0; controller.button_properties.raw = 0; + controller.battery_level_dual = 0; + controller.battery_level_left = 0; + controller.battery_level_right = 0; + controller.fullkey_color = {}; + controller.joycon_color = {}; + controller.assignment_mode = NpadAssignments::Dual; + controller.footer_type = AppletFooterUiType::None; SignalStyleSetChangedEvent(IndexToNPad(npad_index)); } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index d791e327c..9eecb1830 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -326,12 +326,12 @@ private: struct ConnectionState { union { u32_le raw{}; - BitField<0, 1, u32> IsConnected; - BitField<1, 1, u32> IsWired; - BitField<2, 1, u32> IsLeftJoyConnected; - BitField<3, 1, u32> IsLeftJoyWired; - BitField<4, 1, u32> IsRightJoyConnected; - BitField<5, 1, u32> IsRightJoyWired; + BitField<0, 1, u32> is_connected; + BitField<1, 1, u32> is_wired; + BitField<2, 1, u32> is_left_connected; + BitField<3, 1, u32> is_left_wired; + BitField<4, 1, u32> is_right_connected; + BitField<5, 1, u32> is_right_wired; }; }; static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); @@ -360,8 +360,8 @@ private: struct SixAxisAttributes { union { u32_le raw{}; - BitField<0, 1, u32> IsConnected; - BitField<1, 1, u32> IsInterpolated; + BitField<0, 1, u32> is_connected; + BitField<1, 1, u32> is_interpolated; }; }; static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); @@ -394,8 +394,8 @@ private: BitField<3, 1, s64> is_powered_joy_dual; BitField<4, 1, s64> is_powered_joy_left; BitField<5, 1, s64> is_powered_joy_right; - BitField<9, 1, s64> is_system_unsuported_button; - BitField<10, 1, s64> is_system_ext_unsuported_button; + BitField<9, 1, s64> is_system_unsupported_button; + BitField<10, 1, s64> is_system_ext_unsupported_button; BitField<11, 1, s64> is_vertical; BitField<12, 1, s64> is_horizontal; BitField<13, 1, s64> use_plus; @@ -443,6 +443,38 @@ private: std::array orientation; }; + struct NfcXcdHandle { + INSERT_PADDING_BYTES(0x60); + }; + + struct AppletFooterUiAttributes { + INSERT_PADDING_BYTES(0x4); + }; + + enum class AppletFooterUiType : u8 { + None = 0, + HandheldNone = 1, + HandheldJoyConLeftOnly = 1, + HandheldJoyConRightOnly = 3, + HandheldJoyConLeftJoyConRight = 4, + JoyDual = 5, + JoyDualLeftOnly = 6, + JoyDualRightOnly = 7, + JoyLeftHorizontal = 8, + JoyLeftVertical = 9, + JoyRightHorizontal = 10, + JoyRightVertical = 11, + SwitchProController = 12, + CompatibleProController = 13, + CompatibleJoyCon = 14, + LarkHvc1 = 15, + LarkHvc2 = 16, + LarkNesLeft = 17, + LarkNesRight = 18, + Lucia = 19, + Verification = 20, + }; + struct NPadEntry { NpadStyleSet style_set; NpadAssignments assignment_mode; @@ -469,8 +501,11 @@ private: u32 battery_level_dual; u32 battery_level_left; u32 battery_level_right; - INSERT_PADDING_BYTES(0x5c); - INSERT_PADDING_BYTES(0xdf8); + AppletFooterUiAttributes footer_attributes; + AppletFooterUiType footer_type; + // nfc_states needs to be checked switchbrew does not match with HW + NfcXcdHandle nfc_states; + INSERT_PADDING_BYTES(0xdef); }; static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); @@ -506,7 +541,6 @@ private: std::vector supported_npad_id_types{}; NpadHoldType hold_type{NpadHoldType::Vertical}; NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; - // NpadCommunicationMode is unknown, default value is 1 NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; // Each controller should have their own styleset changed event std::array styleset_changed_events; diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index d91cf62a2..5b59961bd 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h @@ -31,13 +31,13 @@ public: private: struct Attributes { union { - s32_le raw{}; - BitField<0, 1, u32> IsConnected; - BitField<1, 1, u32> IsWired; - BitField<2, 1, u32> IsLeftConnected; - BitField<3, 1, u32> IsLeftWired; - BitField<4, 1, u32> IsRightConnected; - BitField<5, 1, u32> IsRightWired; + u32_le raw{}; + BitField<0, 1, u32> is_connected; + BitField<1, 1, u32> is_wired; + BitField<2, 1, u32> is_left_connected; + BitField<3, 1, u32> is_left_wired; + BitField<4, 1, u32> is_right_connected; + BitField<5, 1, u32> is_right_wired; }; }; static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size");