Merge pull request #10903 from german77/nfc_state

input_common: Improve nfc state handling and 3rd party support
This commit is contained in:
liamwhite 2023-06-26 14:31:23 -04:00 committed by GitHub
commit b82c649b0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 18 deletions

View file

@ -1250,6 +1250,11 @@ Common::Input::DriverResult EmulatedController::SetPollingMode(
const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode); const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
const auto mapped_nfc_result = right_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) { if (virtual_nfc_result == Common::Input::DriverResult::Success) {
return virtual_nfc_result; 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_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3]; auto& nfc_virtual_output_device = output_devices[3];
return nfc_output_device->StartNfcPolling() == Common::Input::NfcState::Success || const auto device_result = nfc_output_device->StartNfcPolling();
nfc_virtual_output_device->StartNfcPolling() == Common::Input::NfcState::Success; 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() { bool EmulatedController::StopNfcPolling() {
auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; auto& nfc_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
auto& nfc_virtual_output_device = output_devices[3]; auto& nfc_virtual_output_device = output_devices[3];
return nfc_output_device->StopNfcPolling() == Common::Input::NfcState::Success || const auto device_result = nfc_output_device->StopNfcPolling();
nfc_virtual_output_device->StopNfcPolling() == Common::Input::NfcState::Success; 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) { bool EmulatedController::ReadAmiiboData(std::vector<u8>& data) {

View file

@ -72,6 +72,7 @@ DriverResult JoyconDriver::InitializeDevice() {
nfc_enabled = false; nfc_enabled = false;
passive_enabled = false; passive_enabled = false;
irs_enabled = false; irs_enabled = false;
input_only_device = false;
gyro_sensitivity = Joycon::GyroSensitivity::DPS2000; gyro_sensitivity = Joycon::GyroSensitivity::DPS2000;
gyro_performance = Joycon::GyroPerformance::HZ833; gyro_performance = Joycon::GyroPerformance::HZ833;
accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8; accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8;
@ -86,16 +87,23 @@ DriverResult JoyconDriver::InitializeDevice() {
rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle); rumble_protocol = std::make_unique<RumbleProtocol>(hidapi_handle);
// Get fixed joycon info // Get fixed joycon info
generic_protocol->GetVersionNumber(version); if (generic_protocol->GetVersionNumber(version) != DriverResult::Success) {
generic_protocol->SetLowPowerMode(false); // If this command fails the device doesn't accept configuration commands
generic_protocol->GetColor(color); input_only_device = true;
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);
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(); supported_features = GetSupportedFeatures();
// Get Calibration data // Get Calibration data
@ -261,6 +269,10 @@ DriverResult JoyconDriver::SetPollingMode() {
generic_protocol->EnableImu(false); generic_protocol->EnableImu(false);
} }
if (input_only_device) {
return DriverResult::NotSupported;
}
if (irs_protocol->IsEnabled()) { if (irs_protocol->IsEnabled()) {
irs_protocol->DisableIrs(); irs_protocol->DisableIrs();
} }
@ -282,6 +294,7 @@ DriverResult JoyconDriver::SetPollingMode() {
} }
irs_protocol->DisableIrs(); irs_protocol->DisableIrs();
LOG_ERROR(Input, "Error enabling IRS"); LOG_ERROR(Input, "Error enabling IRS");
return result;
} }
if (nfc_enabled && supported_features.nfc) { if (nfc_enabled && supported_features.nfc) {
@ -291,6 +304,7 @@ DriverResult JoyconDriver::SetPollingMode() {
} }
nfc_protocol->DisableNfc(); nfc_protocol->DisableNfc();
LOG_ERROR(Input, "Error enabling NFC"); LOG_ERROR(Input, "Error enabling NFC");
return result;
} }
if (hidbus_enabled && supported_features.hidbus) { if (hidbus_enabled && supported_features.hidbus) {
@ -305,6 +319,7 @@ DriverResult JoyconDriver::SetPollingMode() {
ring_connected = false; ring_connected = false;
ring_protocol->DisableRingCon(); ring_protocol->DisableRingCon();
LOG_ERROR(Input, "Error enabling Ringcon"); LOG_ERROR(Input, "Error enabling Ringcon");
return result;
} }
if (passive_enabled && supported_features.passive) { if (passive_enabled && supported_features.passive) {
@ -333,6 +348,10 @@ JoyconDriver::SupportedFeatures JoyconDriver::GetSupportedFeatures() {
.vibration = true, .vibration = true,
}; };
if (input_only_device) {
return features;
}
if (device_type == ControllerType::Right) { if (device_type == ControllerType::Right) {
features.nfc = true; features.nfc = true;
features.irs = true; features.irs = true;
@ -517,6 +536,11 @@ DriverResult JoyconDriver::StopNfcPolling() {
const auto result = nfc_protocol->StopNFCPollingMode(); const auto result = nfc_protocol->StopNFCPollingMode();
disable_input_thread = false; disable_input_thread = false;
if (amiibo_detected) {
amiibo_detected = false;
joycon_poller->UpdateAmiibo({});
}
return result; return result;
} }

View file

@ -120,6 +120,7 @@ private:
// Hardware configuration // Hardware configuration
u8 leds{}; u8 leds{};
ReportMode mode{}; ReportMode mode{};
bool input_only_device{};
bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time bool passive_enabled{}; // Low power mode, Ideal for multiple controllers at the same time
bool hidbus_enabled{}; // External device support bool hidbus_enabled{}; // External device support
bool irs_enabled{}; // Infrared camera input bool irs_enabled{}; // Infrared camera input

View file

@ -73,7 +73,7 @@ DriverResult JoyconCommonProtocol::SendRawData(std::span<const u8> buffer) {
DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc, DriverResult JoyconCommonProtocol::GetSubCommandResponse(SubCommand sc,
SubCommandResponse& output) { SubCommandResponse& output) {
constexpr int timeout_mili = 66; constexpr int timeout_mili = 66;
constexpr int MaxTries = 15; constexpr int MaxTries = 3;
int tries = 0; int tries = 0;
do { do {
@ -113,9 +113,7 @@ DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const
return result; return result;
} }
result = GetSubCommandResponse(sc, output); return GetSubCommandResponse(sc, output);
return DriverResult::Success;
} }
DriverResult JoyconCommonProtocol::SendSubCommand(SubCommand sc, std::span<const u8> buffer) { 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) { DriverResult JoyconCommonProtocol::ReadRawSPI(SpiAddress addr, std::span<u8> output) {
constexpr std::size_t HeaderSize = 5; constexpr std::size_t HeaderSize = 5;
constexpr std::size_t MaxTries = 10; constexpr std::size_t MaxTries = 5;
std::size_t tries = 0; std::size_t tries = 0;
SubCommandResponse response{}; SubCommandResponse response{};
std::array<u8, sizeof(ReadSpiPacket)> buffer{}; std::array<u8, sizeof(ReadSpiPacket)> buffer{};