mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-03 16:39:01 -06:00 
			
		
		
		
	core/hid: Ensure only valid npad are connected
This commit is contained in:
		@@ -866,7 +866,50 @@ void EmulatedController::SetLedPattern() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles) {
 | 
			
		||||
    supported_style_tag = supported_styles;
 | 
			
		||||
    if (!is_connected) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!IsControllerSupported()) {
 | 
			
		||||
        LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller",
 | 
			
		||||
                  npad_type);
 | 
			
		||||
        Disconnect();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool EmulatedController::IsControllerSupported() const {
 | 
			
		||||
    switch (npad_type) {
 | 
			
		||||
    case NpadStyleIndex::ProController:
 | 
			
		||||
        return supported_style_tag.fullkey;
 | 
			
		||||
    case NpadStyleIndex::JoyconDual:
 | 
			
		||||
        return supported_style_tag.joycon_dual;
 | 
			
		||||
    case NpadStyleIndex::JoyconLeft:
 | 
			
		||||
        return supported_style_tag.joycon_left;
 | 
			
		||||
    case NpadStyleIndex::JoyconRight:
 | 
			
		||||
        return supported_style_tag.joycon_right;
 | 
			
		||||
    case NpadStyleIndex::GameCube:
 | 
			
		||||
        return supported_style_tag.gamecube;
 | 
			
		||||
    case NpadStyleIndex::Pokeball:
 | 
			
		||||
        return supported_style_tag.palma;
 | 
			
		||||
    case NpadStyleIndex::NES:
 | 
			
		||||
        return supported_style_tag.lark;
 | 
			
		||||
    case NpadStyleIndex::SNES:
 | 
			
		||||
        return supported_style_tag.lucia;
 | 
			
		||||
    case NpadStyleIndex::N64:
 | 
			
		||||
        return supported_style_tag.lagoon;
 | 
			
		||||
    case NpadStyleIndex::SegaGenesis:
 | 
			
		||||
        return supported_style_tag.lager;
 | 
			
		||||
    default:
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EmulatedController::Connect() {
 | 
			
		||||
    if (!IsControllerSupported()) {
 | 
			
		||||
        LOG_ERROR(Service_HID, "Controller type {} is not supported", npad_type);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard lock{mutex};
 | 
			
		||||
        if (is_configuring) {
 | 
			
		||||
 
 | 
			
		||||
@@ -160,6 +160,13 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    NpadStyleIndex GetNpadStyleIndex(bool get_temporary_value = false) const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the supported controller types. Disconnects the controller if current type is not
 | 
			
		||||
     * supported
 | 
			
		||||
     * @param supported_styles bitflag with supported types
 | 
			
		||||
     */
 | 
			
		||||
    void SetSupportedNpadStyleTag(NpadStyleTag supported_styles);
 | 
			
		||||
 | 
			
		||||
    /// Sets the connected status to true
 | 
			
		||||
    void Connect();
 | 
			
		||||
 | 
			
		||||
@@ -310,6 +317,12 @@ private:
 | 
			
		||||
    /// Set the params for TAS devices
 | 
			
		||||
    void LoadTASParams();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks the current controller type against the supported_style_tag
 | 
			
		||||
     * @return true if the controller is supported
 | 
			
		||||
     */
 | 
			
		||||
    bool IsControllerSupported() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the button status of the controller
 | 
			
		||||
     * @param callback A CallbackStatus containing the button status
 | 
			
		||||
@@ -354,6 +367,7 @@ private:
 | 
			
		||||
 | 
			
		||||
    NpadIdType npad_id_type;
 | 
			
		||||
    NpadStyleIndex npad_type{NpadStyleIndex::None};
 | 
			
		||||
    NpadStyleTag supported_style_tag{NpadStyleSet::All};
 | 
			
		||||
    bool is_connected{false};
 | 
			
		||||
    bool is_configuring{false};
 | 
			
		||||
    f32 motion_sensitivity{0.01f};
 | 
			
		||||
 
 | 
			
		||||
@@ -108,6 +108,16 @@ const EmulatedController* HIDCore::GetEmulatedControllerByIndex(std::size_t inde
 | 
			
		||||
 | 
			
		||||
void HIDCore::SetSupportedStyleTag(NpadStyleTag style_tag) {
 | 
			
		||||
    supported_style_tag.raw = style_tag.raw;
 | 
			
		||||
    player_1->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_2->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_3->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_4->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_5->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_6->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_7->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    player_8->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    other->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
    handheld->SetSupportedNpadStyleTag(supported_style_tag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NpadStyleTag HIDCore::GetSupportedStyleTag() const {
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ private:
 | 
			
		||||
    std::unique_ptr<EmulatedController> handheld;
 | 
			
		||||
    std::unique_ptr<EmulatedConsole> console;
 | 
			
		||||
    std::unique_ptr<EmulatedDevices> devices;
 | 
			
		||||
    NpadStyleTag supported_style_tag;
 | 
			
		||||
    NpadStyleTag supported_style_tag{NpadStyleSet::All};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace Core::HID
 | 
			
		||||
 
 | 
			
		||||
@@ -256,6 +256,8 @@ enum class NpadStyleSet : u32 {
 | 
			
		||||
    Lager = 1U << 11,
 | 
			
		||||
    SystemExt = 1U << 29,
 | 
			
		||||
    System = 1U << 30,
 | 
			
		||||
 | 
			
		||||
    All = 0xFFFFFFFFU,
 | 
			
		||||
};
 | 
			
		||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -126,8 +126,11 @@ void Controller_NPad::ControllerUpdate(Core::HID::ControllerTriggerType type,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
 | 
			
		||||
    LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
 | 
			
		||||
    auto& controller = GetControllerFromNpadIdType(npad_id);
 | 
			
		||||
    if (!IsControllerSupported(controller.device->GetNpadStyleIndex())) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_DEBUG(Service_HID, "Npad connected {}", npad_id);
 | 
			
		||||
    const auto controller_type = controller.device->GetNpadStyleIndex();
 | 
			
		||||
    auto& shared_memory = controller.shared_memory_entry;
 | 
			
		||||
    if (controller_type == Core::HID::NpadStyleIndex::None) {
 | 
			
		||||
@@ -255,19 +258,7 @@ void Controller_NPad::OnInit() {
 | 
			
		||||
 | 
			
		||||
    if (hid_core.GetSupportedStyleTag().raw == Core::HID::NpadStyleSet::None) {
 | 
			
		||||
        // We want to support all controllers
 | 
			
		||||
        Core::HID::NpadStyleTag style{};
 | 
			
		||||
        style.handheld.Assign(1);
 | 
			
		||||
        style.joycon_left.Assign(1);
 | 
			
		||||
        style.joycon_right.Assign(1);
 | 
			
		||||
        style.joycon_dual.Assign(1);
 | 
			
		||||
        style.fullkey.Assign(1);
 | 
			
		||||
        style.gamecube.Assign(1);
 | 
			
		||||
        style.palma.Assign(1);
 | 
			
		||||
        style.lark.Assign(1);
 | 
			
		||||
        style.lucia.Assign(1);
 | 
			
		||||
        style.lagoon.Assign(1);
 | 
			
		||||
        style.lager.Assign(1);
 | 
			
		||||
        hid_core.SetSupportedStyleTag(style);
 | 
			
		||||
        hid_core.SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    supported_npad_id_types.resize(npad_id_list.size());
 | 
			
		||||
@@ -1072,13 +1063,18 @@ bool Controller_NPad::SwapNpadAssignment(Core::HID::NpadIdType npad_id_1,
 | 
			
		||||
    const auto& controller_2 = GetControllerFromNpadIdType(npad_id_2).device;
 | 
			
		||||
    const auto type_index_1 = controller_1->GetNpadStyleIndex();
 | 
			
		||||
    const auto type_index_2 = controller_2->GetNpadStyleIndex();
 | 
			
		||||
    const auto is_connected_1 = controller_1->IsConnected();
 | 
			
		||||
    const auto is_connected_2 = controller_2->IsConnected();
 | 
			
		||||
 | 
			
		||||
    if (!IsControllerSupported(type_index_1) || !IsControllerSupported(type_index_2)) {
 | 
			
		||||
    if (!IsControllerSupported(type_index_1) && is_connected_1) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (!IsControllerSupported(type_index_2) && is_connected_2) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AddNewControllerAt(type_index_2, npad_id_1);
 | 
			
		||||
    AddNewControllerAt(type_index_1, npad_id_2);
 | 
			
		||||
    UpdateControllerAt(type_index_2, npad_id_1, is_connected_2);
 | 
			
		||||
    UpdateControllerAt(type_index_1, npad_id_2, is_connected_1);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -907,88 +907,79 @@ void ConfigureInputPlayer::UpdateUI() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConfigureInputPlayer::SetConnectableControllers() {
 | 
			
		||||
    const auto add_controllers = [this](bool enable_all,
 | 
			
		||||
                                        Core::HID::NpadStyleTag npad_style_set = {}) {
 | 
			
		||||
        index_controller_type_pairs.clear();
 | 
			
		||||
        ui->comboControllerType->clear();
 | 
			
		||||
    Core::HID::NpadStyleTag npad_style_set = hid_core.GetSupportedStyleTag();
 | 
			
		||||
    index_controller_type_pairs.clear();
 | 
			
		||||
    ui->comboControllerType->clear();
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.fullkey == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::ProController);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Pro Controller"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.joycon_dual == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::JoyconDual);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Dual Joycons"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.joycon_left == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::JoyconLeft);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Left Joycon"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.joycon_right == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::JoyconRight);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Right Joycon"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (player_index == 0 && (enable_all || npad_style_set.handheld == 1)) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::Handheld);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Handheld"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.gamecube == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::GameCube);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("GameCube Controller"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Disable all unsupported controllers
 | 
			
		||||
        if (!Settings::values.enable_all_controllers) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (enable_all || npad_style_set.palma == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::Pokeball);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Poke Ball Plus"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.lark == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::NES);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("NES Controller"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.lucia == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::SNES);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("SNES Controller"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.lagoon == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::N64);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("N64 Controller"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_all || npad_style_set.lager == 1) {
 | 
			
		||||
            index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                     Core::HID::NpadStyleIndex::SegaGenesis);
 | 
			
		||||
            ui->comboControllerType->addItem(tr("Sega Genesis"));
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (!is_powered_on) {
 | 
			
		||||
        add_controllers(true);
 | 
			
		||||
        return;
 | 
			
		||||
    if (npad_style_set.fullkey == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::ProController);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Pro Controller"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    add_controllers(false, hid_core.GetSupportedStyleTag());
 | 
			
		||||
    if (npad_style_set.joycon_dual == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::JoyconDual);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Dual Joycons"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.joycon_left == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::JoyconLeft);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Left Joycon"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.joycon_right == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::JoyconRight);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Right Joycon"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (player_index == 0 && npad_style_set.handheld == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::Handheld);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Handheld"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.gamecube == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::GameCube);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("GameCube Controller"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Disable all unsupported controllers
 | 
			
		||||
    if (!Settings::values.enable_all_controllers) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (npad_style_set.palma == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::Pokeball);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Poke Ball Plus"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.lark == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::NES);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("NES Controller"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.lucia == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::SNES);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("SNES Controller"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.lagoon == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::N64);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("N64 Controller"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (npad_style_set.lager == 1) {
 | 
			
		||||
        index_controller_type_pairs.emplace_back(ui->comboControllerType->count(),
 | 
			
		||||
                                                 Core::HID::NpadStyleIndex::SegaGenesis);
 | 
			
		||||
        ui->comboControllerType->addItem(tr("Sega Genesis"));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Core::HID::NpadStyleIndex ConfigureInputPlayer::GetControllerTypeFromIndex(int index) const {
 | 
			
		||||
 
 | 
			
		||||
@@ -1516,6 +1516,9 @@ void GMainWindow::ShutdownGame() {
 | 
			
		||||
    input_subsystem->GetTas()->Stop();
 | 
			
		||||
    OnTasStateChanged();
 | 
			
		||||
 | 
			
		||||
    // Enable all controllers
 | 
			
		||||
    system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
 | 
			
		||||
 | 
			
		||||
    render_window->removeEventFilter(render_window);
 | 
			
		||||
    render_window->setAttribute(Qt::WA_Hover, false);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user