Added the ability to "disconnect" individual npads

Fixes arms
This commit is contained in:
David Marcec 2018-10-07 20:17:04 +11:00
parent b79c294c02
commit f43815af5d
3 changed files with 40 additions and 16 deletions

View file

@ -33,7 +33,7 @@ enum class JoystickId : std::size_t { Joystick_Left, Joystick_Right };
Controller_NPad::Controller_NPad() = default; Controller_NPad::Controller_NPad() = default;
void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) { 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]; auto& controller = shared_memory_entries[controller_idx];
if (controller_type == NPadControllerType::None) { if (controller_type == NPadControllerType::None) {
return; return;
@ -92,7 +92,7 @@ void Controller_NPad::OnInit() {
if (!IsControllerActivated()) if (!IsControllerActivated())
return; return;
std::size_t controller{}; 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) { if (style.raw == 0) {
// We want to support all controllers // We want to support all controllers
style.handheld.Assign(1); style.handheld.Assign(1);
@ -102,9 +102,9 @@ void Controller_NPad::OnInit() {
style.pro_controller.Assign(1); style.pro_controller.Assign(1);
style.pokeball.Assign(1); style.pokeball.Assign(1);
} }
std::memcpy(supported_npad_id_types.data(), NPAD_ID_LIST.data(), std::memcpy(supported_npad_id_types.data(), npad_id_list.data(),
NPAD_ID_LIST.size() * sizeof(u32)); npad_id_list.size() * sizeof(u32));
if (CONTROLLER_COUNT == 0) { if (controller_count == 0) {
AddNewController(NPadControllerType::Handheld); AddNewController(NPadControllerType::Handheld);
} }
} }
@ -150,12 +150,12 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
cur_entry.timestamp2 = cur_entry.timestamp; 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; continue;
} }
const auto& controller_type = CONNECTED_CONTROLLERS[i];
// Pad states // Pad states
ControllerPadState pad_state{}; ControllerPadState pad_state{};
using namespace Settings::NativeButton; 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<u32>& controller_ids, void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
const std::vector<Vibration>& vibrations) { const std::vector<Vibration>& vibrations) {
for (std::size_t i = 0; i < controller_ids.size(); i++) { for (std::size_t i = 0; i < controller_ids.size(); i++) {
if (i >= CONTROLLER_COUNT) { if (i >= controller_count) {
continue; continue;
} }
// TODO(ogniK): Vibrate the physical controller // TODO(ogniK): Vibrate the physical controller
@ -329,11 +329,23 @@ Controller_NPad::Vibration Controller_NPad::GetLastVibration() const {
return last_processed_vibration; return last_processed_vibration;
} }
void Controller_NPad::AddNewController(NPadControllerType controller) { 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!"); LOG_ERROR(Service_HID, "Cannot connect any more controllers!");
return; return;
} }
CONNECTED_CONTROLLERS[CONTROLLER_COUNT] = controller; connected_controllers[controller_count] = {controller, true};
InitNewlyAddedControler(CONTROLLER_COUNT++); 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 } // namespace Service::HID

View file

@ -91,6 +91,9 @@ public:
void AddNewController(NPadControllerType controller); void AddNewController(NPadControllerType controller);
void ConnectNPad(u32 npad_id);
void DisconnectNPad(u32 npad_id);
private: private:
struct CommonHeader { struct CommonHeader {
s64_le timestamp; s64_le timestamp;
@ -235,6 +238,12 @@ private:
INSERT_PADDING_BYTES(0xdf8); INSERT_PADDING_BYTES(0xdf8);
}; };
static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size");
struct ControllerHolder {
Controller_NPad::NPadControllerType type;
bool is_connected;
};
NPadType style{}; NPadType style{};
std::array<NPadEntry, 10> shared_memory_entries{}; std::array<NPadEntry, 10> shared_memory_entries{};
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
@ -245,9 +254,9 @@ private:
Kernel::SharedPtr<Kernel::Event> styleset_changed_event; Kernel::SharedPtr<Kernel::Event> styleset_changed_event;
std::size_t dump_idx{}; std::size_t dump_idx{};
Vibration last_processed_vibration{}; Vibration last_processed_vibration{};
std::size_t CONTROLLER_COUNT{}; std::size_t controller_count{};
const std::array<u32, 9> NPAD_ID_LIST{0, 1, 2, 3, 4, 5, 6, 7, 32}; static constexpr std::array<u32, 9> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32};
std::array<Controller_NPad::NPadControllerType, 9> CONNECTED_CONTROLLERS{}; std::array<ControllerHolder, 9> connected_controllers{};
void InitNewlyAddedControler(std::size_t controller_idx); void InitNewlyAddedControler(std::size_t controller_idx);
}; };

View file

@ -411,7 +411,10 @@ private:
} }
void DisconnectNpad(Kernel::HLERequestContext& ctx) { void DisconnectNpad(Kernel::HLERequestContext& ctx) {
applet_resource->DeactivateController(HidController::NPad); IPC::RequestParser rp{ctx};
auto npad_id = rp.PopRaw<u32>();
applet_resource->GetController<Controller_NPad>(HidController::NPad)
.DisconnectNPad(npad_id);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");