From f43815af5d59bb1b31696f317c2e2ce243445cb5 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sun, 7 Oct 2018 20:17:04 +1100 Subject: [PATCH] Added the ability to "disconnect" individual npads Fixes arms --- src/core/hle/service/hid/controllers/npad.cpp | 36 ++++++++++++------- src/core/hle/service/hid/controllers/npad.h | 15 ++++++-- src/core/hle/service/hid/hid.cpp | 5 ++- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 8a713a407..211b8bb60 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -33,7 +33,7 @@ enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right }; Controller_NPad::Controller_NPad() = default; void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { - const auto controller_type = CONNECTED_CONTROLLERS[controller_idx]; + const auto controller_type = connected_controllers[controller_idx].type; auto& controller = shared_memory_entries[controller_idx]; if (controller_type == NPadControllerType::None) { return; @@ -92,7 +92,7 @@ void Controller_NPad::OnInit() { if (!IsControllerActivated()) return; std::size_t controller{}; - supported_npad_id_types.resize(NPAD_ID_LIST.size()); + supported_npad_id_types.resize(npad_id_list.size()); if (style.raw == 0) { // We want to support all controllers style.handheld.Assign(1); @@ -102,9 +102,9 @@ void Controller_NPad::OnInit() { style.pro_controller.Assign(1); style.pokeball.Assign(1); } - std::memcpy(supported_npad_id_types.data(), NPAD_ID_LIST.data(), - NPAD_ID_LIST.size() * sizeof(u32)); - if (CONTROLLER_COUNT == 0) { + std::memcpy(supported_npad_id_types.data(), npad_id_list.data(), + npad_id_list.size() * sizeof(u32)); + if (controller_count == 0) { AddNewController(NPadControllerType::Handheld); } } @@ -150,12 +150,12 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { cur_entry.timestamp2 = cur_entry.timestamp; } - if (CONNECTED_CONTROLLERS[i] == NPadControllerType::None) { + const auto& controller_type = connected_controllers[i].type; + + if (controller_type == NPadControllerType::None || !connected_controllers[i].is_connected) { continue; } - const auto& controller_type = CONNECTED_CONTROLLERS[i]; - // Pad states ControllerPadState pad_state{}; using namespace Settings::NativeButton; @@ -312,7 +312,7 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) void Controller_NPad::VibrateController(const std::vector& controller_ids, const std::vector& vibrations) { for (std::size_t i = 0; i < controller_ids.size(); i++) { - if (i >= CONTROLLER_COUNT) { + if (i >= controller_count) { continue; } // TODO(ogniK): Vibrate the physical controller @@ -329,11 +329,23 @@ Controller_NPad::Vibration Controller_NPad::GetLastVibration() const { return last_processed_vibration; } void Controller_NPad::AddNewController(NPadControllerType controller) { - if (CONTROLLER_COUNT >= CONNECTED_CONTROLLERS.size()) { + if (controller_count >= connected_controllers.size()) { LOG_ERROR(Service_HID, "Cannot connect any more controllers!"); return; } - CONNECTED_CONTROLLERS[CONTROLLER_COUNT] = controller; - InitNewlyAddedControler(CONTROLLER_COUNT++); + connected_controllers[controller_count] = {controller, true}; + InitNewlyAddedControler(controller_count++); +} + +void Controller_NPad::ConnectNPad(u32 npad_id) { + if (npad_id >= connected_controllers.size()) + return; + connected_controllers[npad_id].is_connected = true; +} + +void Controller_NPad::DisconnectNPad(u32 npad_id) { + if (npad_id >= connected_controllers.size()) + return; + connected_controllers[npad_id].is_connected = false; } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 2d1614747..86ab0e429 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -91,6 +91,9 @@ public: void AddNewController(NPadControllerType controller); + void ConnectNPad(u32 npad_id); + void DisconnectNPad(u32 npad_id); + private: struct CommonHeader { s64_le timestamp; @@ -235,6 +238,12 @@ private: INSERT_PADDING_BYTES(0xdf8); }; static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); + + struct ControllerHolder { + Controller_NPad::NPadControllerType type; + bool is_connected; + }; + NPadType style{}; std::array shared_memory_entries{}; std::array, Settings::NativeButton::NUM_BUTTONS_HID> @@ -245,9 +254,9 @@ private: Kernel::SharedPtr styleset_changed_event; std::size_t dump_idx{}; Vibration last_processed_vibration{}; - std::size_t CONTROLLER_COUNT{}; - const std::array NPAD_ID_LIST{0, 1, 2, 3, 4, 5, 6, 7, 32}; - std::array CONNECTED_CONTROLLERS{}; + std::size_t controller_count{}; + static constexpr std::array npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32}; + std::array connected_controllers{}; 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 ba4aefa6c..dfee289d2 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -411,7 +411,10 @@ private: } void DisconnectNpad(Kernel::HLERequestContext& ctx) { - applet_resource->DeactivateController(HidController::NPad); + IPC::RequestParser rp{ctx}; + auto npad_id = rp.PopRaw(); + applet_resource->GetController(HidController::NPad) + .DisconnectNPad(npad_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_HID, "called");