summaryrefslogtreecommitdiffstats
path: root/src/input_common
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2023-05-19 03:10:38 +0200
committerGitHub <noreply@github.com>2023-05-19 03:10:38 +0200
commit1e398e6c36bf8839ca530497fee3772f51d62126 (patch)
tree9bc394d7aaf886b65ee18ba18088e0f057ae8225 /src/input_common
parentexternals: update cubeb (#10362) (diff)
parentinput_common: Fix pro controller amiibo support (diff)
downloadyuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar.gz
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar.bz2
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar.lz
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar.xz
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.tar.zst
yuzu-1e398e6c36bf8839ca530497fee3772f51d62126.zip
Diffstat (limited to 'src/input_common')
-rw-r--r--src/input_common/drivers/joycon.cpp9
-rw-r--r--src/input_common/drivers/joycon.h3
-rw-r--r--src/input_common/helpers/joycon_protocol/common_protocol.cpp2
-rw-r--r--src/input_common/helpers/joycon_protocol/joycon_types.h2
-rw-r--r--src/input_common/helpers/joycon_protocol/nfc.cpp151
-rw-r--r--src/input_common/helpers/joycon_protocol/nfc.h6
6 files changed, 70 insertions, 103 deletions
diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp
index 8b57ebe07..653862a72 100644
--- a/src/input_common/drivers/joycon.cpp
+++ b/src/input_common/drivers/joycon.cpp
@@ -195,8 +195,8 @@ void Joycons::RegisterNewDevice(SDL_hid_device_info* device_info) {
OnMotionUpdate(port, type, id, value);
}},
.on_ring_data = {[this](f32 ring_data) { OnRingConUpdate(ring_data); }},
- .on_amiibo_data = {[this, port](const std::vector<u8>& amiibo_data) {
- OnAmiiboUpdate(port, amiibo_data);
+ .on_amiibo_data = {[this, port, type](const std::vector<u8>& amiibo_data) {
+ OnAmiiboUpdate(port, type, amiibo_data);
}},
.on_camera_data = {[this, port](const std::vector<u8>& camera_data,
Joycon::IrsResolution format) {
@@ -398,8 +398,9 @@ void Joycons::OnRingConUpdate(f32 ring_data) {
SetAxis(identifier, 100, ring_data);
}
-void Joycons::OnAmiiboUpdate(std::size_t port, const std::vector<u8>& amiibo_data) {
- const auto identifier = GetIdentifier(port, Joycon::ControllerType::Right);
+void Joycons::OnAmiiboUpdate(std::size_t port, Joycon::ControllerType type,
+ const std::vector<u8>& amiibo_data) {
+ const auto identifier = GetIdentifier(port, type);
const auto nfc_state = amiibo_data.empty() ? Common::Input::NfcState::AmiiboRemoved
: Common::Input::NfcState::NewAmiibo;
SetNfc(identifier, {nfc_state, amiibo_data});
diff --git a/src/input_common/drivers/joycon.h b/src/input_common/drivers/joycon.h
index 5b40817e2..e3f0ad78f 100644
--- a/src/input_common/drivers/joycon.h
+++ b/src/input_common/drivers/joycon.h
@@ -81,7 +81,8 @@ private:
void OnMotionUpdate(std::size_t port, Joycon::ControllerType type, int id,
const Joycon::MotionData& value);
void OnRingConUpdate(f32 ring_data);
- void OnAmiiboUpdate(std::size_t port, const std::vector<u8>& amiibo_data);
+ void OnAmiiboUpdate(std::size_t port, Joycon::ControllerType type,
+ const std::vector<u8>& amiibo_data);
void OnCameraUpdate(std::size_t port, const std::vector<u8>& camera_data,
Joycon::IrsResolution format);
diff --git a/src/input_common/helpers/joycon_protocol/common_protocol.cpp b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
index 077d72cd0..51669261a 100644
--- a/src/input_common/helpers/joycon_protocol/common_protocol.cpp
+++ b/src/input_common/helpers/joycon_protocol/common_protocol.cpp
@@ -265,7 +265,7 @@ DriverResult JoyconCommonProtocol::SendMCUData(ReportMode report_mode, MCUSubCom
DriverResult JoyconCommonProtocol::WaitSetMCUMode(ReportMode report_mode, MCUMode mode) {
MCUCommandResponse output{};
- constexpr std::size_t MaxTries{8};
+ constexpr std::size_t MaxTries{16};
std::size_t tries{};
do {
diff --git a/src/input_common/helpers/joycon_protocol/joycon_types.h b/src/input_common/helpers/joycon_protocol/joycon_types.h
index 1c8d294b0..353dc744d 100644
--- a/src/input_common/helpers/joycon_protocol/joycon_types.h
+++ b/src/input_common/helpers/joycon_protocol/joycon_types.h
@@ -577,8 +577,8 @@ static_assert(sizeof(NFCPollingCommandData) == 0x05, "NFCPollingCommandData is a
struct NFCRequestState {
NFCReadCommand command_argument;
- u8 packet_id;
INSERT_PADDING_BYTES(0x1);
+ u8 packet_id;
MCUPacketFlag packet_flag;
u8 data_length;
union {
diff --git a/src/input_common/helpers/joycon_protocol/nfc.cpp b/src/input_common/helpers/joycon_protocol/nfc.cpp
index 14818ae33..46c9e9489 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.cpp
+++ b/src/input_common/helpers/joycon_protocol/nfc.cpp
@@ -65,6 +65,20 @@ DriverResult NfcProtocol::StartNFCPollingMode() {
result = WaitUntilNfcIsReady();
}
if (result == DriverResult::Success) {
+ MCUCommandResponse output{};
+ result = SendStopPollingRequest(output);
+ }
+ if (result == DriverResult::Success) {
+ result = WaitUntilNfcIsReady();
+ }
+ if (result == DriverResult::Success) {
+ MCUCommandResponse output{};
+ result = SendStartPollingRequest(output);
+ }
+ if (result == DriverResult::Success) {
+ result = WaitUntilNfcIsPolling();
+ }
+ if (result == DriverResult::Success) {
is_enabled = true;
}
@@ -77,24 +91,21 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
}
update_counter = 0;
- LOG_DEBUG(Input, "Start NFC pooling Mode");
+ LOG_DEBUG(Input, "Scan for amiibos");
ScopedSetBlocking sb(this);
DriverResult result{DriverResult::Success};
TagFoundData tag_data{};
if (result == DriverResult::Success) {
- result = StartPolling(tag_data);
- }
- if (result == DriverResult::Success) {
- result = ReadTag(tag_data);
- }
- if (result == DriverResult::Success) {
- result = WaitUntilNfcIsReady();
- }
- if (result == DriverResult::Success) {
- result = StartPolling(tag_data, 7);
+ result = IsTagInRange(tag_data);
}
+
if (result == DriverResult::Success) {
+ std::string uuid_string;
+ for (auto& content : tag_data.uuid) {
+ uuid_string += fmt::format(" {:02x}", content);
+ }
+ LOG_INFO(Input, "Tag detected, type={}, uuid={}", tag_data.type, uuid_string);
result = GetAmiiboData(data);
}
@@ -102,12 +113,17 @@ DriverResult NfcProtocol::ScanAmiibo(std::vector<u8>& data) {
}
bool NfcProtocol::HasAmiibo() {
+ if (update_counter++ < AMIIBO_UPDATE_DELAY) {
+ return true;
+ }
+ update_counter = 0;
+
ScopedSetBlocking sb(this);
DriverResult result{DriverResult::Success};
TagFoundData tag_data{};
if (result == DriverResult::Success) {
- result = StartPolling(tag_data);
+ result = IsTagInRange(tag_data, 7);
}
return result == DriverResult::Success;
@@ -119,7 +135,7 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() {
std::size_t tries = 0;
do {
- auto result = SendStartWaitingRecieveRequest(output);
+ auto result = SendNextPackageRequest(output, {});
if (result != DriverResult::Success) {
return result;
@@ -134,13 +150,14 @@ DriverResult NfcProtocol::WaitUntilNfcIsReady() {
return DriverResult::Success;
}
-DriverResult NfcProtocol::StartPolling(TagFoundData& data, std::size_t timeout_limit) {
- LOG_DEBUG(Input, "Start Polling for tag");
+DriverResult NfcProtocol::WaitUntilNfcIsPolling() {
+ constexpr std::size_t timeout_limit = 10;
MCUCommandResponse output{};
std::size_t tries = 0;
do {
- const auto result = SendStartPollingRequest(output);
+ auto result = SendNextPackageRequest(output, {});
+
if (result != DriverResult::Success) {
return result;
}
@@ -149,94 +166,50 @@ DriverResult NfcProtocol::StartPolling(TagFoundData& data, std::size_t timeout_l
}
} while (output.mcu_report != MCUReport::NFCState ||
(output.mcu_data[1] << 8) + output.mcu_data[0] != 0x0500 ||
- output.mcu_data[6] != 0x09);
-
- data.type = output.mcu_data[12];
- data.uuid.resize(output.mcu_data[14]);
- memcpy(data.uuid.data(), output.mcu_data.data() + 15, data.uuid.size());
+ output.mcu_data[5] != 0x31 || output.mcu_data[6] != 0x01);
return DriverResult::Success;
}
-DriverResult NfcProtocol::ReadTag(const TagFoundData& data) {
- constexpr std::size_t timeout_limit = 10;
+DriverResult NfcProtocol::IsTagInRange(TagFoundData& data, std::size_t timeout_limit) {
MCUCommandResponse output{};
std::size_t tries = 0;
- std::string uuid_string;
- for (auto& content : data.uuid) {
- uuid_string += fmt::format(" {:02x}", content);
- }
-
- LOG_INFO(Input, "Tag detected, type={}, uuid={}", data.type, uuid_string);
-
- tries = 0;
- NFCPages ntag_pages = NFCPages::Block0;
- // Read Tag data
- while (true) {
- auto result = SendReadAmiiboRequest(output, ntag_pages);
- const auto nfc_status = static_cast<NFCStatus>(output.mcu_data[6]);
-
+ do {
+ const auto result = SendNextPackageRequest(output, {});
if (result != DriverResult::Success) {
return result;
}
-
- if ((output.mcu_report == MCUReport::NFCReadData ||
- output.mcu_report == MCUReport::NFCState) &&
- nfc_status == NFCStatus::TagLost) {
- return DriverResult::ErrorReadingData;
- }
-
- if (output.mcu_report == MCUReport::NFCReadData && output.mcu_data[1] == 0x07 &&
- output.mcu_data[2] == 0x01) {
- if (data.type != 2) {
- continue;
- }
- switch (output.mcu_data[24]) {
- case 0:
- ntag_pages = NFCPages::Block135;
- break;
- case 3:
- ntag_pages = NFCPages::Block45;
- break;
- case 4:
- ntag_pages = NFCPages::Block231;
- break;
- default:
- return DriverResult::ErrorReadingData;
- }
- continue;
- }
-
- if (output.mcu_report == MCUReport::NFCState && nfc_status == NFCStatus::LastPackage) {
- // finished
- SendStopPollingRequest(output);
- return DriverResult::Success;
- }
-
- // Ignore other state reports
- if (output.mcu_report == MCUReport::NFCState) {
- continue;
- }
-
if (tries++ > timeout_limit) {
return DriverResult::Timeout;
}
- }
+ } while (output.mcu_report != MCUReport::NFCState ||
+ (output.mcu_data[1] << 8) + output.mcu_data[0] != 0x0500 ||
+ (output.mcu_data[6] != 0x09 && output.mcu_data[6] != 0x04));
+
+ data.type = output.mcu_data[12];
+ data.uuid.resize(output.mcu_data[14]);
+ memcpy(data.uuid.data(), output.mcu_data.data() + 15, data.uuid.size());
return DriverResult::Success;
}
DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
- constexpr std::size_t timeout_limit = 10;
+ constexpr std::size_t timeout_limit = 60;
MCUCommandResponse output{};
std::size_t tries = 0;
- NFCPages ntag_pages = NFCPages::Block135;
+ u8 package_index = 0;
std::size_t ntag_buffer_pos = 0;
+ auto result = SendReadAmiiboRequest(output, NFCPages::Block135);
+
+ if (result != DriverResult::Success) {
+ return result;
+ }
+
// Read Tag data
- while (true) {
- auto result = SendReadAmiiboRequest(output, ntag_pages);
+ while (tries++ < timeout_limit) {
+ result = SendNextPackageRequest(output, package_index);
const auto nfc_status = static_cast<NFCStatus>(output.mcu_data[6]);
if (result != DriverResult::Success) {
@@ -259,6 +232,7 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
memcpy(ntag_data.data() + ntag_buffer_pos, output.mcu_data.data() + 6,
payload_size);
}
+ package_index++;
continue;
}
@@ -266,18 +240,9 @@ DriverResult NfcProtocol::GetAmiiboData(std::vector<u8>& ntag_data) {
LOG_INFO(Input, "Finished reading amiibo");
return DriverResult::Success;
}
-
- // Ignore other state reports
- if (output.mcu_report == MCUReport::NFCState) {
- continue;
- }
-
- if (tries++ > timeout_limit) {
- return DriverResult::Timeout;
- }
}
- return DriverResult::Success;
+ return DriverResult::Timeout;
}
DriverResult NfcProtocol::SendStartPollingRequest(MCUCommandResponse& output) {
@@ -321,10 +286,10 @@ DriverResult NfcProtocol::SendStopPollingRequest(MCUCommandResponse& output) {
output);
}
-DriverResult NfcProtocol::SendStartWaitingRecieveRequest(MCUCommandResponse& output) {
+DriverResult NfcProtocol::SendNextPackageRequest(MCUCommandResponse& output, u8 packet_id) {
NFCRequestState request{
.command_argument = NFCReadCommand::StartWaitingRecieve,
- .packet_id = 0x0,
+ .packet_id = packet_id,
.packet_flag = MCUPacketFlag::LastCommandPacket,
.data_length = 0,
.raw_data = {},
diff --git a/src/input_common/helpers/joycon_protocol/nfc.h b/src/input_common/helpers/joycon_protocol/nfc.h
index 4cb992d1d..c9e9af03f 100644
--- a/src/input_common/helpers/joycon_protocol/nfc.h
+++ b/src/input_common/helpers/joycon_protocol/nfc.h
@@ -42,9 +42,9 @@ private:
DriverResult WaitUntilNfcIsReady();
- DriverResult StartPolling(TagFoundData& data, std::size_t timeout_limit = 1);
+ DriverResult WaitUntilNfcIsPolling();
- DriverResult ReadTag(const TagFoundData& data);
+ DriverResult IsTagInRange(TagFoundData& data, std::size_t timeout_limit = 1);
DriverResult GetAmiiboData(std::vector<u8>& data);
@@ -52,7 +52,7 @@ private:
DriverResult SendStopPollingRequest(MCUCommandResponse& output);
- DriverResult SendStartWaitingRecieveRequest(MCUCommandResponse& output);
+ DriverResult SendNextPackageRequest(MCUCommandResponse& output, u8 packet_id);
DriverResult SendReadAmiiboRequest(MCUCommandResponse& output, NFCPages ntag_pages);