diff options
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 115 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/npad.h | 17 | ||||
| -rw-r--r-- | src/core/hle/service/hid/hid.cpp | 4 | 
3 files changed, 59 insertions, 77 deletions
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 9aa8d6f92..d17e64b2a 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -27,7 +27,7 @@ constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E;  constexpr s32 HID_JOYSTICK_MAX = 0x7fff;  constexpr s32 HID_JOYSTICK_MIN = -0x7fff;  constexpr std::size_t NPAD_OFFSET = 0x9A00; - +constexpr u32 BATTERY_FULL = 2;  enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right };  Controller_NPad::Controller_NPad() = default; @@ -46,6 +46,12 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {          controller.device_type.handheld.Assign(1);          controller.pad_assignment = NPadAssignments::Dual;          break; +    case NPadControllerType::JoyDual: +        controller.joy_styles.joycon_dual.Assign(1); +        controller.device_type.joycon_left.Assign(1); +        controller.device_type.joycon_right.Assign(1); +        controller.pad_assignment = NPadAssignments::Dual; +        break;      case NPadControllerType::JoyLeft:          controller.joy_styles.joycon_left.Assign(1);          controller.device_type.joycon_left.Assign(1); @@ -56,9 +62,6 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {          controller.device_type.joycon_right.Assign(1);          controller.pad_assignment = NPadAssignments::Dual;          break; -    case NPadControllerType::Tabletop: -        UNIMPLEMENTED_MSG("Tabletop is not implemented"); -        break;      case NPadControllerType::Pokeball:          controller.joy_styles.pokeball.Assign(1);          controller.device_type.pokeball.Assign(1); @@ -82,6 +85,11 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {      controller.right_color.button_color = JOYCON_BUTTONS_NEON_RED;      controller.properties.is_vertical.Assign(1); // TODO(ogniK): Swap joycons orientations +    controller.properties.use_plus.Assign(1); +    controller.properties.use_minus.Assign(1); +    controller.battery_level[0] = BATTERY_FULL; +    controller.battery_level[1] = BATTERY_FULL; +    controller.battery_level[2] = BATTERY_FULL;  }  void Controller_NPad::OnInit() { @@ -106,7 +114,7 @@ void Controller_NPad::OnInit() {          supported_npad_id_types.resize(npad_id_list.size());          std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),                      npad_id_list.size() * sizeof(u32)); -        AddNewController(NPadControllerType::Handheld); +        AddNewController(NPadControllerType::JoyDual);      }  } @@ -218,9 +226,11 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {          if (hold_type == NpadHoldType::Horizontal) {              // TODO(ogniK): Remap buttons for different orientations          } +        libnx_entry.connection_status.raw = 0;          switch (controller_type) {          case NPadControllerType::Handheld: +            handheld_entry.connection_status.raw = 0;              handheld_entry.connection_status.IsConnected.Assign(1);              if (!Settings::values.use_docked_mode) {                  handheld_entry.connection_status.IsWired.Assign(1); @@ -229,26 +239,39 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {              handheld_entry.l_stick = lstick_entry;              handheld_entry.r_stick = rstick_entry;              break; +        case NPadControllerType::JoyDual: +            dual_entry.connection_status.raw = 0; + +            dual_entry.connection_status.IsLeftJoyConnected.Assign(1); +            dual_entry.connection_status.IsRightJoyConnected.Assign(1); +            dual_entry.connection_status.IsConnected.Assign(1); + +            libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); +            libnx_entry.connection_status.IsRightJoyConnected.Assign(1); +            libnx_entry.connection_status.IsConnected.Assign(1); + +            dual_entry.pad_states.raw = pad_state.raw; +            dual_entry.l_stick = lstick_entry; +            dual_entry.r_stick = rstick_entry;          case NPadControllerType::JoyLeft: +            left_entry.connection_status.raw = 0; +              left_entry.connection_status.IsConnected.Assign(1);              left_entry.pad_states.raw = pad_state.raw;              left_entry.l_stick = lstick_entry;              left_entry.r_stick = rstick_entry;              break;          case NPadControllerType::JoyRight: +            right_entry.connection_status.raw = 0; +              right_entry.connection_status.IsConnected.Assign(1);              right_entry.pad_states.raw = pad_state.raw;              right_entry.l_stick = lstick_entry;              right_entry.r_stick = rstick_entry;              break; -        case NPadControllerType::Tabletop: -            // TODO(ogniK): Figure out how to add proper tabletop support -            dual_entry.pad_states.raw = pad_state.raw; -            dual_entry.l_stick = lstick_entry; -            dual_entry.r_stick = rstick_entry; -            dual_entry.connection_status.IsConnected.Assign(1); -            break;          case NPadControllerType::Pokeball: +            pokeball_entry.connection_status.raw = 0; +              pokeball_entry.connection_status.IsConnected.Assign(1);              pokeball_entry.connection_status.IsWired.Assign(1); @@ -257,18 +280,18 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {              pokeball_entry.r_stick = rstick_entry;              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.pad_states.raw = pad_state.raw;              main_controller.l_stick = lstick_entry;              main_controller.r_stick = rstick_entry; -            main_controller.connection_status.IsConnected.Assign(1); -            main_controller.connection_status.IsWired.Assign(1);              break;          }          // LibNX exclusively uses this section, so we always update it since LibNX doesn't activate          // any controllers. -        libnx_entry.connection_status.IsConnected.Assign(1); -        libnx_entry.connection_status.IsWired.Assign(1);          libnx_entry.pad_states.raw = pad_state.raw;          libnx_entry.l_stick = lstick_entry;          libnx_entry.r_stick = rstick_entry; @@ -290,44 +313,6 @@ void Controller_NPad::SetSupportedNPadIdTypes(u8* data, std::size_t length) {      supported_npad_id_types.clear();      supported_npad_id_types.resize(length / sizeof(u32));      std::memcpy(supported_npad_id_types.data(), data, length); -    CheckForHandheldVariant(); -} -#pragma optimize("", off) -void Controller_NPad::CheckForHandheldVariant() { -    // As some games expect us to use the variant of handheld mode and some games don't. It's -    // consistent that games set the npad ids in order of priority. We can just swap the controller -    // ids on the fly then if we're in handheld mode -    if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), 32) != -        supported_npad_id_types.end()) { -        const auto& first_controller = connected_controllers.front(); -        if (first_controller.is_connected && -            first_controller.type == NPadControllerType::Handheld) { -            DisconnectNPad(0); -            AddNewController(NPadControllerType::Handheld, true); -        } -    } else { -        if (connected_controllers[8].is_connected) { -            DisconnectNPad(8); -            AddNewController(NPadControllerType::Handheld); -        } -    } -    /* -    if (supported_npad_id_types.size() > 0) { -        const auto& first_controller = supported_npad_id_types.front(); -        if (first_controller == 32 && !connected_controllers[8].is_connected) { -            const auto& first_controller = connected_controllers.front(); -            if (first_controller.is_connected && -                first_controller.type == NPadControllerType::Handheld) { -                DisconnectNPad(0); -                AddNewController(NPadControllerType::Handheld, true); -            } -        } else if (first_controller != 32 && connected_controllers[8].is_connected) { -            if (!connected_controllers[0].is_connected) { -                DisconnectNPad(8); -                AddNewController(NPadControllerType::Handheld); -            } -        } -    }*/  }  const void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) { @@ -358,11 +343,14 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,      }      for (std::size_t i = 0; i < controller_ids.size(); i++) {          std::size_t controller_pos = i; -        if (controller_pos == 32) +        // Handheld controller conversion +        if (controller_pos == 32) {              controller_pos = 8; -        if (controller_pos == 16) +        } +        // Unknown controller conversion +        if (controller_pos == 16) {              controller_pos = 9; - +        }          if (connected_controllers[controller_pos].is_connected) {              // TODO(ogniK): Vibrate the physical controller          } @@ -378,8 +366,8 @@ Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() cons  Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {      return last_processed_vibration;  } -void Controller_NPad::AddNewController(NPadControllerType controller, bool is_handheld_variant) { -    if (is_handheld_variant) { +void Controller_NPad::AddNewController(NPadControllerType controller) { +    if (controller == NPadControllerType::Handheld) {          connected_controllers[8] = {controller, true};          InitNewlyAddedControler(8);          return; @@ -438,13 +426,4 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {  void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {      can_controllers_vibrate = can_vibrate;  } - -void Controller_NPad::SetHandheldActiviationMode(u32 mode) { -    const auto& first_controller = connected_controllers.front(); -    if (!first_controller.is_connected || connected_controllers[8].is_connected) { -        return; -    } -    DisconnectNPad(0); -    AddNewController(NPadControllerType::Handheld, true); -}  } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index bc3d15ce6..9d07d258d 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -65,9 +65,9 @@ public:          None,          ProController,          Handheld, +        JoyDual,          JoyLeft,          JoyRight, -        Tabletop,          Pokeball,      }; @@ -105,13 +105,12 @@ public:      Kernel::SharedPtr<Kernel::Event> GetStyleSetChangedEvent() const;      Vibration GetLastVibration() const; -    void AddNewController(NPadControllerType controller, bool is_handheld_variant = false); +    void AddNewController(NPadControllerType controller);      void ConnectNPad(u32 npad_id);      void DisconnectNPad(u32 npad_id);      LedPattern GetLedPattern(u32 npad_id);      void SetVibrationEnabled(bool can_vibrate); -    void SetHandheldActiviationMode(u32 mode);  private:      struct CommonHeader { @@ -181,6 +180,10 @@ private:              u32_le raw{};              BitField<0, 1, u32_le> IsConnected;              BitField<1, 1, u32_le> IsWired; +            BitField<2, 1, u32_le> IsLeftJoyConnected; +            BitField<3, 1, u32_le> IsLeftJoyWired; +            BitField<4, 1, u32_le> IsRightJoyConnected; +            BitField<5, 1, u32_le> IsRightJoyWired;          };      };      static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); @@ -212,6 +215,8 @@ private:              s64_le raw{};              BitField<11, 1, s64_le> is_vertical;              BitField<12, 1, s64_le> is_horizontal; +            BitField<13, 1, s64_le> use_plus; +            BitField<14, 1, s64_le> use_minus;          };      }; @@ -252,8 +257,9 @@ private:              6); // TODO(ogniK): SixAxis states, require more information before implementation          NPadDevice device_type;          NPadProperties properties; -        INSERT_PADDING_WORDS(4); -        INSERT_PADDING_BYTES(0x60); +        INSERT_PADDING_WORDS(1); +        std::array<u32, 3> battery_level; +        INSERT_PADDING_BYTES(0x5c);          INSERT_PADDING_BYTES(0xdf8);      };      static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); @@ -276,7 +282,6 @@ private:      static constexpr std::array<u32, 10> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16};      std::array<ControllerHolder, 10> connected_controllers{};      bool can_controllers_vibrate{true}; -    void CheckForHandheldVariant();      void InitNewlyAddedControler(std::size_t controller_idx);  }; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index db1537b40..8aca0f197 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -284,7 +284,7 @@ public:  private:      std::shared_ptr<IAppletResource> applet_resource; -#pragma optimize("", off) +      void CreateAppletResource(Kernel::HLERequestContext& ctx) {          if (applet_resource == nullptr) {              applet_resource = std::make_shared<IAppletResource>(); @@ -545,8 +545,6 @@ private:          IPC::ResponseBuilder rb{ctx, 2};          rb.Push(RESULT_SUCCESS);          LOG_WARNING(Service_HID, "(STUBBED) called"); -        applet_resource->GetController<Controller_NPad>(HidController::NPad) -            .SetHandheldActiviationMode(mode);      }      void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {  | 
