diff options
| author | bunnei <bunneidev@gmail.com> | 2021-02-06 02:40:11 -0800 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-06 02:40:11 -0800 | 
| commit | 61bf850f3dfd0b44aa5d56f6f3147d7a1fa47353 (patch) | |
| tree | 08709ce3ce8890b37353ff747f4ce4401fcb1fd1 /src/core/hle | |
| parent | 1498a7c9a84037d7c78ff21b3bc996622269db43 (diff) | |
| parent | 8019b2b9b5265647dbadc45f60a12e4bbfefbd77 (diff) | |
Merge pull request #5326 from german77/hidUpdate1
HID: Update the HID service to match more closely to switchbrew part 1
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/am/applets/controller.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/keyboard.cpp | 17 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/keyboard.h | 21 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/mouse.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/mouse.h | 26 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 208 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 189 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/xpad.h | 70 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 20 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.h | 10 | 
10 files changed, 406 insertions, 168 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/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,      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<u8>(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.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 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 @@  #pragma once  #include <array> +#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 { +            u32_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> katakana; +            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<u8, 32> 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..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*      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<s32>(px * Layout::ScreenUndocked::Width); @@ -46,10 +47,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..3b432a36e 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 <array> +#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 { +            u32_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 { +            u32_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 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) {          styleset_changed_events[controller_idx]->GetWritableEvent()->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; +        controller.footer_type = AppletFooterUiType::SwitchProController;          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; +        controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight;          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; +        controller.footer_type = AppletFooterUiType::JoyDual;          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; +        controller.footer_type = AppletFooterUiType::JoyLeftHorizontal;          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; +        controller.footer_type = AppletFooterUiType::JoyRightHorizontal;          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; +    // 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;      SignalStyleSetChangedEvent(IndexToNPad(controller_idx));  } @@ -251,8 +258,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(), @@ -406,13 +413,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<NPadGeneric*, 7> 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<NPadGeneric*, 7> 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; @@ -442,19 +446,19 @@ 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); +        libnx_entry.connection_status.is_connected.Assign(1);          switch (controller_type) {          case NPadControllerType::None: @@ -462,67 +466,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; @@ -556,7 +560,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing          }          const std::array<SixAxisGeneric*, 6> 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,          }; @@ -594,7 +598,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 = @@ -611,7 +615,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.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,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.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; @@ -627,8 +635,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.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; @@ -636,6 +647,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.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; @@ -643,7 +655,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.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; @@ -651,7 +665,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.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; @@ -717,8 +733,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;      }  } @@ -926,9 +942,17 @@ 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; +    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));  } @@ -1104,7 +1128,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: @@ -1112,7 +1136,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 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:      };      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 { @@ -112,13 +112,18 @@ 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<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible +            BitField<5, 1, u32> gamecube; +            BitField<6, 1, u32> palma; +            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"); @@ -242,12 +247,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{}; @@ -289,6 +314,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"); @@ -302,12 +330,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"); @@ -333,6 +361,15 @@ private:      };      static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); +    struct SixAxisAttributes { +        union { +            u32_le raw{}; +            BitField<0, 1, u32> is_connected; +            BitField<1, 1, u32> is_interpolated; +        }; +    }; +    static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); +      struct SixAxisStates {          s64_le timestamp{};          INSERT_PADDING_WORDS(2); @@ -341,7 +378,8 @@ private:          Common::Vec3f gyro{};          Common::Vec3f rotation{};          std::array<Common::Vec3f, 3> orientation{}; -        s64_le always_one{1}; +        SixAxisAttributes attribute; +        INSERT_PADDING_BYTES(4); // Reserved      };      static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); @@ -351,32 +389,54 @@ 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; +            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_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;              BitField<14, 1, s64> use_minus; +            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;          };      }; @@ -387,37 +447,69 @@ private:          std::array<Common::Vec3f, 3> orientation;      }; -    struct NPadEntry { -        NpadStyleSet joy_styles; -        NpadAssignments pad_assignment; +    struct NfcXcdHandle { +        INSERT_PADDING_BYTES(0x60); +    }; + +    struct AppletFooterUiAttributes { +        INSERT_PADDING_BYTES(0x4); +    }; -        ColorReadError single_color_error; -        ControllerColor single_color; +    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, +    }; -        ColorReadError dual_color_error; -        ControllerColor left_color; -        ControllerColor right_color; +    struct NPadEntry { +        NpadStyleSet style_set; +        NpadAssignments assignment_mode; +        FullKeyColor fullkey_color; +        JoyconColor joycon_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<u32, 3> battery_level; -        INSERT_PADDING_BYTES(0x5c); -        INSERT_PADDING_BYTES(0xdf8); +        INSERT_PADDING_BYTES(0x4); // reserved +        NPadSystemProperties system_properties; +        NPadButtonProperties button_properties; +        u32 battery_level_dual; +        u32 battery_level_left; +        u32 battery_level_right; +        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"); @@ -453,8 +545,7 @@ private:      std::vector<u32> 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::Unknown1}; +    NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};      // Each controller should have their own styleset changed event      std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;      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 @@  #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 { +            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"); + +    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 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_)      MakeController<Controller_Mouse>(HidController::Mouse);      MakeController<Controller_Keyboard>(HidController::Keyboard);      MakeController<Controller_XPad>(HidController::XPad); -    MakeController<Controller_Stubbed>(HidController::Unknown1); -    MakeController<Controller_Stubbed>(HidController::Unknown2); -    MakeController<Controller_Stubbed>(HidController::Unknown3); -    MakeController<Controller_Stubbed>(HidController::SixAxisSensor); +    MakeController<Controller_Stubbed>(HidController::HomeButton); +    MakeController<Controller_Stubbed>(HidController::SleepButton); +    MakeController<Controller_Stubbed>(HidController::CaptureButton); +    MakeController<Controller_Stubbed>(HidController::InputDetector); +    MakeController<Controller_Stubbed>(HidController::UniquePad);      MakeController<Controller_NPad>(HidController::NPad);      MakeController<Controller_Gesture>(HidController::Gesture); +    MakeController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor);      // Homebrew doesn't try to activate some controllers, so we activate them by default      GetController<Controller_NPad>(HidController::NPad).ActivateController();      GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); -    GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); -    GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); -    GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); +    GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); +    GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); +    GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); +    GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200); +    GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); +    GetController<Controller_Stubbed>(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,  }; | 
