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 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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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{};