mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-18 13:20:04 +00:00
Merge pull request #4893 from wwylele/nfc-state
NFC: extract frontend-facing tag state
This commit is contained in:
commit
7bfd829c77
@ -53,7 +53,7 @@ void Module::Interface::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
if (nfc->nfc_tag_state != TagState::NotInitialized) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
@ -99,13 +99,14 @@ void Module::Interface::StartTagScanning(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
if (nfc->nfc_tag_state != TagState::NotScanning &&
|
||||
nfc->nfc_tag_state != TagState::TagOutOfRange) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
}
|
||||
|
||||
nfc->nfc_tag_state = TagState::Scanning;
|
||||
nfc->SyncTagState();
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
LOG_WARNING(Service_NFC, "(STUBBED) called, in_val={:04x}", in_val);
|
||||
@ -116,7 +117,7 @@ void Module::Interface::GetTagInfo(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
if (nfc->nfc_tag_state != TagState::TagInRange &&
|
||||
nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
@ -163,7 +164,7 @@ void Module::Interface::StopTagScanning(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
if (nfc->nfc_tag_state == TagState::NotInitialized ||
|
||||
nfc->nfc_tag_state == TagState::NotScanning) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
@ -192,13 +193,14 @@ void Module::Interface::ResetTagScanState(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
if (nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
}
|
||||
|
||||
nfc->nfc_tag_state = TagState::TagInRange;
|
||||
nfc->SyncTagState();
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
LOG_DEBUG(Service_NFC, "called");
|
||||
@ -208,7 +210,7 @@ void Module::Interface::GetTagInRangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x0B, 0, 0);
|
||||
|
||||
if (nfc->nfc_tag_state != TagState::NotScanning) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
@ -225,7 +227,7 @@ void Module::Interface::GetTagOutOfRangeEvent(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x0C, 0, 0);
|
||||
|
||||
if (nfc->nfc_tag_state != TagState::NotScanning) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
@ -243,7 +245,7 @@ void Module::Interface::GetTagState(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushEnum(nfc->nfc_tag_state.load());
|
||||
rb.PushEnum(nfc->nfc_tag_state);
|
||||
LOG_DEBUG(Service_NFC, "called");
|
||||
}
|
||||
|
||||
@ -261,7 +263,7 @@ void Module::Interface::Unknown0x1A(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
if (nfc->nfc_tag_state != TagState::TagInRange) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
return;
|
||||
@ -277,7 +279,7 @@ void Module::Interface::GetIdentificationBlock(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp(ctx, 0x1B, 0, 0);
|
||||
|
||||
if (nfc->nfc_tag_state != TagState::TagDataLoaded && nfc->nfc_tag_state != TagState::Unknown6) {
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state.load()));
|
||||
LOG_ERROR(Service_NFC, "Invalid TagState {}", static_cast<int>(nfc->nfc_tag_state));
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(ResultCode(ErrCodes::CommandInvalidForState, ErrorModule::NFC,
|
||||
ErrorSummary::InvalidState, ErrorLevel::Status));
|
||||
@ -304,15 +306,29 @@ std::shared_ptr<Module> Module::Interface::GetModule() const {
|
||||
void Module::Interface::LoadAmiibo(const AmiiboData& amiibo_data) {
|
||||
std::lock_guard lock(HLE::g_hle_lock);
|
||||
nfc->amiibo_data = amiibo_data;
|
||||
nfc->nfc_tag_state = Service::NFC::TagState::TagInRange;
|
||||
nfc->tag_in_range_event->Signal();
|
||||
nfc->amiibo_in_range = true;
|
||||
nfc->SyncTagState();
|
||||
}
|
||||
|
||||
void Module::Interface::RemoveAmiibo() {
|
||||
std::lock_guard lock(HLE::g_hle_lock);
|
||||
nfc->nfc_tag_state = Service::NFC::TagState::TagOutOfRange;
|
||||
nfc->tag_out_of_range_event->Signal();
|
||||
nfc->amiibo_data = {};
|
||||
nfc->amiibo_in_range = false;
|
||||
nfc->SyncTagState();
|
||||
}
|
||||
|
||||
void Module::SyncTagState() {
|
||||
if (amiibo_in_range &&
|
||||
(nfc_tag_state == TagState::TagOutOfRange || nfc_tag_state == TagState::Scanning)) {
|
||||
// TODO (wwylele): Should TagOutOfRange->TagInRange transition only happen on the same tag
|
||||
// detected on Scanning->TagInRange?
|
||||
nfc_tag_state = TagState::TagInRange;
|
||||
tag_in_range_event->Signal();
|
||||
} else if (!amiibo_in_range && nfc_tag_state == TagState::TagInRange) {
|
||||
nfc_tag_state = TagState::TagOutOfRange;
|
||||
// TODO (wwylele): If a tag is removed during TagDataLoaded/Unknown6, should this event
|
||||
// signals early?
|
||||
tag_out_of_range_event->Signal();
|
||||
}
|
||||
}
|
||||
|
||||
Module::Interface::Interface(std::shared_ptr<Module> nfc, const char* name, u32 max_session)
|
||||
|
@ -231,12 +231,16 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
// Sync nfc_tag_state with amiibo_in_range and signal events on state change.
|
||||
void SyncTagState();
|
||||
|
||||
std::shared_ptr<Kernel::Event> tag_in_range_event;
|
||||
std::shared_ptr<Kernel::Event> tag_out_of_range_event;
|
||||
std::atomic<TagState> nfc_tag_state = TagState::NotInitialized;
|
||||
TagState nfc_tag_state = TagState::NotInitialized;
|
||||
CommunicationStatus nfc_status = CommunicationStatus::NfcInitialized;
|
||||
|
||||
AmiiboData amiibo_data{};
|
||||
bool amiibo_in_range = false;
|
||||
};
|
||||
|
||||
void InstallInterfaces(Core::System& system);
|
||||
|
Loading…
Reference in New Issue
Block a user