Merge pull request #10903 from german77/nfc_state
input_common: Improve nfc state handling and 3rd party support
This commit is contained in:
		@@ -1250,6 +1250,11 @@ Common::Input::DriverResult EmulatedController::SetPollingMode(
 | 
			
		||||
        const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
 | 
			
		||||
        const auto mapped_nfc_result = right_output_device->SetPollingMode(polling_mode);
 | 
			
		||||
 | 
			
		||||
        // Restore previous state
 | 
			
		||||
        if (mapped_nfc_result != Common::Input::DriverResult::Success) {
 | 
			
		||||
            right_output_device->SetPollingMode(Common::Input::PollingMode::Active);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (virtual_nfc_result == Common::Input::DriverResult::Success) {
 | 
			
		||||
            return virtual_nfc_result;
 | 
			
		||||
        }
 | 
			
		||||
@@ -1329,16 +1334,22 @@ bool EmulatedController::StartNfcPolling() {
 | 
			
		||||
    auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
 | 
			
		||||
    auto& nfc_virtual_output_device = output_devices[3];
 | 
			
		||||
 | 
			
		||||
    return nfc_output_device->StartNfcPolling() == Common::Input::NfcState::Success ||
 | 
			
		||||
           nfc_virtual_output_device->StartNfcPolling() == Common::Input::NfcState::Success;
 | 
			
		||||
    const auto device_result = nfc_output_device->StartNfcPolling();
 | 
			
		||||
    const auto virtual_device_result = nfc_virtual_output_device->StartNfcPolling();
 | 
			
		||||
 | 
			
		||||
    return device_result == Common::Input::NfcState::Success ||
 | 
			
		||||
           virtual_device_result == Common::Input::NfcState::Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool EmulatedController::StopNfcPolling() {
 | 
			
		||||
    auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
 | 
			
		||||
    auto& nfc_virtual_output_device = output_devices[3];
 | 
			
		||||
 | 
			
		||||
    return nfc_output_device->StopNfcPolling() == Common::Input::NfcState::Success ||
 | 
			
		||||
           nfc_virtual_output_device->StopNfcPolling() == Common::Input::NfcState::Success;
 | 
			
		||||
    const auto device_result = nfc_output_device->StopNfcPolling();
 | 
			
		||||
    const auto virtual_device_result = nfc_virtual_output_device->StopNfcPolling();
 | 
			
		||||
 | 
			
		||||
    return device_result == Common::Input::NfcState::Success ||
 | 
			
		||||
           virtual_device_result == Common::Input::NfcState::Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {
 | 
			
		||||
 
 | 
			
		||||
@@ -72,6 +72,7 @@ DriverResult JoyconDriver::InitializeDevice() {
 | 
			
		||||
    nfc_enabled = false;
 | 
			
		||||
    passive_enabled = false;
 | 
			
		||||
    irs_enabled = false;
 | 
			
		||||
    input_only_device = false;
 | 
			
		||||
    gyro_sensitivity = Joycon::GyroSensitivity::DPS2000;
 | 
			
		||||
    gyro_performance = Joycon::GyroPerformance::HZ833;
 | 
			
		||||
    accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8;
 | 
			
		||||
@@ -86,16 +87,23 @@ DriverResult JoyconDriver::InitializeDevice() {
 | 
			
		||||
    rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle);
 | 
			
		||||
 | 
			
		||||
    // Get fixed joycon info
 | 
			
		||||
    generic_protocol->GetVersionNumber(version);
 | 
			
		||||
    generic_protocol->SetLowPowerMode(false);
 | 
			
		||||
    generic_protocol->GetColor(color);
 | 
			
		||||
    if (handle_device_type == ControllerType::Pro) {
 | 
			
		||||
        // Some 3rd party controllers aren't pro controllers
 | 
			
		||||
        generic_protocol->GetControllerType(device_type);
 | 
			
		||||
    } else {
 | 
			
		||||
        device_type = handle_device_type;
 | 
			
		||||
    if (generic_protocol->GetVersionNumber(version) != DriverResult::Success) {
 | 
			
		||||
        // If this command fails the device doesn't accept configuration commands
 | 
			
		||||
        input_only_device = true;
 | 
			
		||||
    }
 | 
			
		||||
    generic_protocol->GetSerialNumber(serial_number);
 | 
			
		||||
 | 
			
		||||
    if (!input_only_device) {
 | 
			
		||||
        generic_protocol->SetLowPowerMode(false);
 | 
			
		||||
        generic_protocol->GetColor(color);
 | 
			
		||||
        if (handle_device_type == ControllerType::Pro) {
 | 
			
		||||
            // Some 3rd party controllers aren't pro controllers
 | 
			
		||||
            generic_protocol->GetControllerType(device_type);
 | 
			
		||||
        } else {
 | 
			
		||||
            device_type = handle_device_type;
 | 
			
		||||
        }
 | 
			
		||||
        generic_protocol->GetSerialNumber(serial_number);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    supported_features = GetSupportedFeatures();
 | 
			
		||||
 | 
			
		||||
    // Get Calibration data
 | 
			
		||||
@@ -261,6 +269,10 @@ DriverResult JoyconDriver::SetPollingMode() {
 | 
			
		||||
        generic_protocol->EnableImu(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (input_only_device) {
 | 
			
		||||
        return DriverResult::NotSupported;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (irs_protocol->IsEnabled()) {
 | 
			
		||||
        irs_protocol->DisableIrs();
 | 
			
		||||
    }
 | 
			
		||||
@@ -282,6 +294,7 @@ DriverResult JoyconDriver::SetPollingMode() {
 | 
			
		||||
        }
 | 
			
		||||
        irs_protocol->DisableIrs();
 | 
			
		||||
        LOG_ERROR(Input, "Error enabling IRS");
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (nfc_enabled && supported_features.nfc) {
 | 
			
		||||
@@ -291,6 +304,7 @@ DriverResult JoyconDriver::SetPollingMode() {
 | 
			
		||||
        }
 | 
			
		||||
        nfc_protocol->DisableNfc();
 | 
			
		||||
        LOG_ERROR(Input, "Error enabling NFC");
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (hidbus_enabled && supported_features.hidbus) {
 | 
			
		||||
@@ -305,6 +319,7 @@ DriverResult JoyconDriver::SetPollingMode() {
 | 
			
		||||
        ring_connected = false;
 | 
			
		||||
        ring_protocol->DisableRingCon();
 | 
			
		||||
        LOG_ERROR(Input, "Error enabling Ringcon");
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (passive_enabled && supported_features.passive) {
 | 
			
		||||
@@ -333,6 +348,10 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() {
 | 
			
		||||
        .vibration = true,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if (input_only_device) {
 | 
			
		||||
        return features;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (device_type == ControllerType::Right) {
 | 
			
		||||
        features.nfc = true;
 | 
			
		||||
        features.irs = true;
 | 
			
		||||
@@ -517,6 +536,11 @@ DriverResult JoyconDriver::StopNfcPolling() {
 | 
			
		||||
    const auto result = nfc_protocol->StopNFCPollingMode();
 | 
			
		||||
    disable_input_thread = false;
 | 
			
		||||
 | 
			
		||||
    if (amiibo_detected) {
 | 
			
		||||
        amiibo_detected = false;
 | 
			
		||||
        joycon_poller->UpdateAmiibo({});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -120,6 +120,7 @@ private:
 | 
			
		||||
    // Hardware configuration
 | 
			
		||||
    u8 leds{};
 | 
			
		||||
    ReportMode mode{};
 | 
			
		||||
    bool input_only_device{};
 | 
			
		||||
    bool passive_enabled{};   // Low power mode, Ideal for multiple controllers at the same time
 | 
			
		||||
    bool hidbus_enabled{};    // External device support
 | 
			
		||||
    bool irs_enabled{};       // Infrared camera input
 | 
			
		||||
 
 | 
			
		||||
@@ -73,7 +73,7 @@ DriverResult JoyconCommonProtocol::SendRawData(std::span<const u8> buffer) {
 | 
			
		||||
DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc,
 | 
			
		||||
                                                         SubCommandResponse& output) {
 | 
			
		||||
    constexpr int timeout_mili = 66;
 | 
			
		||||
    constexpr int MaxTries = 15;
 | 
			
		||||
    constexpr int MaxTries = 3;
 | 
			
		||||
    int tries = 0;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
@@ -113,9 +113,7 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result = GetSubCommandResponse(sc, output);
 | 
			
		||||
 | 
			
		||||
    return DriverResult::Success;
 | 
			
		||||
    return GetSubCommandResponse(sc, output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) {
 | 
			
		||||
@@ -158,7 +156,7 @@ DriverResult JoyconCommonProtocol::SendVibrationReport(std::span<const u8> buffe
 | 
			
		||||
 | 
			
		||||
DriverResult JoyconCommonProtocol::ReadRawSPI(SpiAddress addr, std::span<u8> output) {
 | 
			
		||||
    constexpr std::size_t HeaderSize = 5;
 | 
			
		||||
    constexpr std::size_t MaxTries = 10;
 | 
			
		||||
    constexpr std::size_t MaxTries = 5;
 | 
			
		||||
    std::size_t tries = 0;
 | 
			
		||||
    SubCommandResponse response{};
 | 
			
		||||
    std::array<u8, sizeof(ReadSpiPacket)> buffer{};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user