summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nfp/nfp.cpp12
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp172
-rw-r--r--src/core/hle/service/nfp/nfp_device.h10
-rw-r--r--src/core/hle/service/nfp/nfp_interface.cpp204
-rw-r--r--src/core/hle/service/nfp/nfp_interface.h9
-rw-r--r--src/core/hle/service/nfp/nfp_types.h45
6 files changed, 444 insertions, 8 deletions
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 8a7365f17..2714f4bea 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -90,8 +90,8 @@ public:
90 explicit IDebug(Core::System& system_) : Interface(system_, "NFP:IDebug") { 90 explicit IDebug(Core::System& system_) : Interface(system_, "NFP:IDebug") {
91 // clang-format off 91 // clang-format off
92 static const FunctionInfo functions[] = { 92 static const FunctionInfo functions[] = {
93 {0, nullptr, "InitializeDebug"}, 93 {0, &IDebug::InitializeDebug, "InitializeDebug"},
94 {1, nullptr, "FinalizeDebug"}, 94 {1, &IDebug::FinalizeDebug, "FinalizeDebug"},
95 {2, &IDebug::ListDevices, "ListDevices"}, 95 {2, &IDebug::ListDevices, "ListDevices"},
96 {3, &IDebug::StartDetection, "StartDetection"}, 96 {3, &IDebug::StartDetection, "StartDetection"},
97 {4, &IDebug::StopDetection, "StopDetection"}, 97 {4, &IDebug::StopDetection, "StopDetection"},
@@ -122,10 +122,10 @@ public:
122 {104, &IDebug::DeleteRegisterInfo, "DeleteRegisterInfo"}, 122 {104, &IDebug::DeleteRegisterInfo, "DeleteRegisterInfo"},
123 {105, &IDebug::DeleteApplicationArea, "DeleteApplicationArea"}, 123 {105, &IDebug::DeleteApplicationArea, "DeleteApplicationArea"},
124 {106, &IDebug::ExistsApplicationArea, "ExistsApplicationArea"}, 124 {106, &IDebug::ExistsApplicationArea, "ExistsApplicationArea"},
125 {200, nullptr, "GetAll"}, 125 {200, &IDebug::GetAll, "GetAll"},
126 {201, nullptr, "SetAll"}, 126 {201, &IDebug::SetAll, "SetAll"},
127 {202, nullptr, "FlushDebug"}, 127 {202, &IDebug::FlushDebug, "FlushDebug"},
128 {203, nullptr, "BreakTag"}, 128 {203, &IDebug::BreakTag, "BreakTag"},
129 {204, nullptr, "ReadBackupData"}, 129 {204, nullptr, "ReadBackupData"},
130 {205, nullptr, "WriteBackupData"}, 130 {205, nullptr, "WriteBackupData"},
131 {206, nullptr, "WriteNtf"}, 131 {206, nullptr, "WriteNtf"},
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index 5ed6d4181..3f9af53c8 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -240,6 +240,42 @@ Result NfpDevice::Flush() {
240 240
241 tag_data.write_counter++; 241 tag_data.write_counter++;
242 242
243 FlushWithBreak(BreakType::Normal);
244
245 is_data_moddified = false;
246
247 return ResultSuccess;
248}
249
250Result NfpDevice::FlushDebug() {
251 if (device_state != DeviceState::TagMounted) {
252 LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
253 if (device_state == DeviceState::TagRemoved) {
254 return TagRemoved;
255 }
256 return WrongDeviceState;
257 }
258
259 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
260 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
261 return WrongDeviceState;
262 }
263
264 tag_data.write_counter++;
265
266 FlushWithBreak(BreakType::Normal);
267
268 is_data_moddified = false;
269
270 return ResultSuccess;
271}
272
273Result NfpDevice::FlushWithBreak(BreakType break_type) {
274 if (break_type != BreakType::Normal) {
275 LOG_ERROR(Service_NFC, "Break type not implemented {}", break_type);
276 return WrongDeviceState;
277 }
278
243 std::vector<u8> data(sizeof(EncryptedNTAG215File)); 279 std::vector<u8> data(sizeof(EncryptedNTAG215File));
244 if (is_plain_amiibo) { 280 if (is_plain_amiibo) {
245 memcpy(data.data(), &tag_data, sizeof(tag_data)); 281 memcpy(data.data(), &tag_data, sizeof(tag_data));
@@ -257,8 +293,6 @@ Result NfpDevice::Flush() {
257 return WriteAmiiboFailed; 293 return WriteAmiiboFailed;
258 } 294 }
259 295
260 is_data_moddified = false;
261
262 return ResultSuccess; 296 return ResultSuccess;
263} 297}
264 298
@@ -857,6 +891,140 @@ Result NfpDevice::ExistApplicationArea(bool& has_application_area) {
857 return ResultSuccess; 891 return ResultSuccess;
858} 892}
859 893
894Result NfpDevice::GetAll(NfpData& data) const {
895 if (device_state != DeviceState::TagMounted) {
896 LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
897 if (device_state == DeviceState::TagRemoved) {
898 return TagRemoved;
899 }
900 return WrongDeviceState;
901 }
902
903 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
904 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
905 return WrongDeviceState;
906 }
907
908 CommonInfo common_info{};
909 Service::Mii::MiiManager manager;
910 const u64 application_id = tag_data.application_id;
911
912 GetCommonInfo(common_info);
913
914 data = {
915 .magic = tag_data.constant_value,
916 .write_counter = tag_data.write_counter,
917 .settings_crc = tag_data.settings.crc,
918 .common_info = common_info,
919 .mii_char_info = tag_data.owner_mii,
920 .mii_store_data_extension = tag_data.mii_extension,
921 .creation_date = tag_data.settings.init_date.GetWriteDate(),
922 .amiibo_name = tag_data.settings.amiibo_name,
923 .amiibo_name_null_terminated = 0,
924 .settings = tag_data.settings.settings,
925 .unknown1 = tag_data.unknown,
926 .register_info_crc = tag_data.register_info_crc,
927 .unknown2 = tag_data.unknown2,
928 .application_id = application_id,
929 .access_id = tag_data.application_area_id,
930 .settings_crc_counter = tag_data.settings.crc_counter,
931 .font_region = tag_data.settings.settings.font_region,
932 .tag_type = PackedTagType::Type2,
933 .console_type =
934 static_cast<AppAreaVersion>(application_id >> application_id_version_offset & 0xf),
935 .application_id_byte = tag_data.application_id_byte,
936 .application_area = tag_data.application_area,
937 };
938
939 return ResultSuccess;
940}
941
942Result NfpDevice::SetAll(const NfpData& data) {
943 if (device_state != DeviceState::TagMounted) {
944 LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
945 if (device_state == DeviceState::TagRemoved) {
946 return TagRemoved;
947 }
948 return WrongDeviceState;
949 }
950
951 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
952 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
953 return WrongDeviceState;
954 }
955
956 tag_data.constant_value = data.magic;
957 tag_data.write_counter = data.write_counter;
958 tag_data.settings.crc = data.settings_crc;
959 tag_data.settings.write_date.SetWriteDate(data.common_info.last_write_date);
960 tag_data.write_counter = data.common_info.write_counter;
961 tag_data.amiibo_version = data.common_info.version;
962 tag_data.owner_mii = data.mii_char_info;
963 tag_data.mii_extension = data.mii_store_data_extension;
964 tag_data.settings.init_date.SetWriteDate(data.creation_date);
965 tag_data.settings.amiibo_name = data.amiibo_name;
966 tag_data.settings.settings = data.settings;
967 tag_data.unknown = data.unknown1;
968 tag_data.register_info_crc = data.register_info_crc;
969 tag_data.unknown2 = data.unknown2;
970 tag_data.application_id = data.application_id;
971 tag_data.application_area_id = data.access_id;
972 tag_data.settings.crc_counter = data.settings_crc_counter;
973 tag_data.settings.settings.font_region.Assign(data.font_region);
974 tag_data.application_id_byte = data.application_id_byte;
975 tag_data.application_area = data.application_area;
976
977 return ResultSuccess;
978}
979
980Result NfpDevice::BreakTag(BreakType break_type) {
981 if (device_state != DeviceState::TagMounted) {
982 LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
983 if (device_state == DeviceState::TagRemoved) {
984 return TagRemoved;
985 }
986 return WrongDeviceState;
987 }
988
989 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
990 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
991 return WrongDeviceState;
992 }
993
994 // TODO: Complete this implementation
995
996 return FlushWithBreak(break_type);
997}
998
999Result NfpDevice::ReadBackupData() {
1000 // Not implemented
1001 return ResultSuccess;
1002}
1003
1004Result NfpDevice::WriteBackupData() {
1005 // Not implemented
1006 return ResultSuccess;
1007}
1008
1009Result NfpDevice::WriteNtf() {
1010 if (device_state != DeviceState::TagMounted) {
1011 LOG_ERROR(Service_NFC, "Wrong device state {}", device_state);
1012 if (device_state == DeviceState::TagRemoved) {
1013 return TagRemoved;
1014 }
1015 return WrongDeviceState;
1016 }
1017
1018 if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
1019 LOG_ERROR(Service_NFC, "Amiibo is read only", device_state);
1020 return WrongDeviceState;
1021 }
1022
1023 // Not implemented
1024
1025 return ResultSuccess;
1026}
1027
860u64 NfpDevice::GetHandle() const { 1028u64 NfpDevice::GetHandle() const {
861 // Generate a handle based of the npad id 1029 // Generate a handle based of the npad id
862 return static_cast<u64>(npad_id); 1030 return static_cast<u64>(npad_id);
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h
index 0d778c1d7..bab05538a 100644
--- a/src/core/hle/service/nfp/nfp_device.h
+++ b/src/core/hle/service/nfp/nfp_device.h
@@ -41,7 +41,10 @@ public:
41 Result StopDetection(); 41 Result StopDetection();
42 Result Mount(MountTarget mount_target); 42 Result Mount(MountTarget mount_target);
43 Result Unmount(); 43 Result Unmount();
44
44 Result Flush(); 45 Result Flush();
46 Result FlushDebug();
47 Result FlushWithBreak(BreakType break_type);
45 48
46 Result GetTagInfo(TagInfo& tag_info) const; 49 Result GetTagInfo(TagInfo& tag_info) const;
47 Result GetCommonInfo(CommonInfo& common_info) const; 50 Result GetCommonInfo(CommonInfo& common_info) const;
@@ -64,6 +67,13 @@ public:
64 Result DeleteApplicationArea(); 67 Result DeleteApplicationArea();
65 Result ExistApplicationArea(bool& has_application_area); 68 Result ExistApplicationArea(bool& has_application_area);
66 69
70 Result GetAll(NfpData& data) const;
71 Result SetAll(const NfpData& data);
72 Result BreakTag(BreakType break_type);
73 Result ReadBackupData();
74 Result WriteBackupData();
75 Result WriteNtf();
76
67 u64 GetHandle() const; 77 u64 GetHandle() const;
68 u32 GetApplicationAreaSize() const; 78 u32 GetApplicationAreaSize() const;
69 DeviceState GetCurrentState() const; 79 DeviceState GetCurrentState() const;
diff --git a/src/core/hle/service/nfp/nfp_interface.cpp b/src/core/hle/service/nfp/nfp_interface.cpp
index d60f3cb97..2ed8bb1ba 100644
--- a/src/core/hle/service/nfp/nfp_interface.cpp
+++ b/src/core/hle/service/nfp/nfp_interface.cpp
@@ -53,6 +53,19 @@ void Interface::InitializeSystem(HLERequestContext& ctx) {
53 rb.Push(ResultSuccess); 53 rb.Push(ResultSuccess);
54} 54}
55 55
56void Interface::InitializeDebug(HLERequestContext& ctx) {
57 LOG_INFO(Service_NFP, "called");
58
59 state = State::Initialized;
60
61 for (auto& device : devices) {
62 device->Initialize();
63 }
64
65 IPC::ResponseBuilder rb{ctx, 2};
66 rb.Push(ResultSuccess);
67}
68
56void Interface::Finalize(HLERequestContext& ctx) { 69void Interface::Finalize(HLERequestContext& ctx) {
57 LOG_INFO(Service_NFP, "called"); 70 LOG_INFO(Service_NFP, "called");
58 71
@@ -79,6 +92,19 @@ void Interface::FinalizeSystem(HLERequestContext& ctx) {
79 rb.Push(ResultSuccess); 92 rb.Push(ResultSuccess);
80} 93}
81 94
95void Interface::FinalizeDebug(HLERequestContext& ctx) {
96 LOG_INFO(Service_NFP, "called");
97
98 state = State::NonInitialized;
99
100 for (auto& device : devices) {
101 device->Finalize();
102 }
103
104 IPC::ResponseBuilder rb{ctx, 2};
105 rb.Push(ResultSuccess);
106}
107
82void Interface::ListDevices(HLERequestContext& ctx) { 108void Interface::ListDevices(HLERequestContext& ctx) {
83 LOG_DEBUG(Service_NFP, "called"); 109 LOG_DEBUG(Service_NFP, "called");
84 110
@@ -833,6 +859,184 @@ void Interface::ExistsApplicationArea(HLERequestContext& ctx) {
833 rb.Push(has_application_area); 859 rb.Push(has_application_area);
834} 860}
835 861
862void Interface::GetAll(HLERequestContext& ctx) {
863 IPC::RequestParser rp{ctx};
864 const auto device_handle{rp.Pop<u64>()};
865 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
866
867 if (state == State::NonInitialized) {
868 IPC::ResponseBuilder rb{ctx, 2};
869 rb.Push(NfcDisabled);
870 return;
871 }
872
873 auto device = GetNfpDevice(device_handle);
874
875 if (!device.has_value()) {
876 IPC::ResponseBuilder rb{ctx, 2};
877 rb.Push(DeviceNotFound);
878 return;
879 }
880
881 NfpData data{};
882 const auto result = device.value()->GetAll(data);
883
884 ctx.WriteBuffer(data);
885
886 IPC::ResponseBuilder rb{ctx, 2};
887 rb.Push(result);
888}
889
890void Interface::SetAll(HLERequestContext& ctx) {
891 IPC::RequestParser rp{ctx};
892 const auto device_handle{rp.Pop<u64>()};
893 const auto nfp_data{ctx.ReadBuffer()};
894
895 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
896
897 if (state == State::NonInitialized) {
898 IPC::ResponseBuilder rb{ctx, 2};
899 rb.Push(NfcDisabled);
900 return;
901 }
902
903 auto device = GetNfpDevice(device_handle);
904
905 if (!device.has_value()) {
906 IPC::ResponseBuilder rb{ctx, 2};
907 rb.Push(DeviceNotFound);
908 return;
909 }
910
911 NfpData data{};
912 memcpy(&data, nfp_data.data(), sizeof(NfpData));
913
914 const auto result = device.value()->SetAll(data);
915 IPC::ResponseBuilder rb{ctx, 2};
916 rb.Push(result);
917}
918
919void Interface::FlushDebug(HLERequestContext& ctx) {
920 IPC::RequestParser rp{ctx};
921 const auto device_handle{rp.Pop<u64>()};
922 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
923
924 if (state == State::NonInitialized) {
925 IPC::ResponseBuilder rb{ctx, 2};
926 rb.Push(NfcDisabled);
927 return;
928 }
929
930 auto device = GetNfpDevice(device_handle);
931
932 if (!device.has_value()) {
933 IPC::ResponseBuilder rb{ctx, 2};
934 rb.Push(DeviceNotFound);
935 return;
936 }
937
938 const auto result = device.value()->FlushDebug();
939 IPC::ResponseBuilder rb{ctx, 2};
940 rb.Push(result);
941}
942
943void Interface::BreakTag(HLERequestContext& ctx) {
944 IPC::RequestParser rp{ctx};
945 const auto device_handle{rp.Pop<u64>()};
946 const auto break_type{rp.PopEnum<BreakType>()};
947 LOG_DEBUG(Service_NFP, "called, device_handle={}, break_type={}", device_handle, break_type);
948
949 if (state == State::NonInitialized) {
950 IPC::ResponseBuilder rb{ctx, 2};
951 rb.Push(NfcDisabled);
952 return;
953 }
954
955 auto device = GetNfpDevice(device_handle);
956
957 if (!device.has_value()) {
958 IPC::ResponseBuilder rb{ctx, 2};
959 rb.Push(DeviceNotFound);
960 return;
961 }
962
963 const auto result = device.value()->BreakTag(break_type);
964 IPC::ResponseBuilder rb{ctx, 2};
965 rb.Push(result);
966}
967
968void Interface::ReadBackupData(HLERequestContext& ctx) {
969 IPC::RequestParser rp{ctx};
970 const auto device_handle{rp.Pop<u64>()};
971 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
972
973 if (state == State::NonInitialized) {
974 IPC::ResponseBuilder rb{ctx, 2};
975 rb.Push(NfcDisabled);
976 return;
977 }
978
979 auto device = GetNfpDevice(device_handle);
980
981 if (!device.has_value()) {
982 IPC::ResponseBuilder rb{ctx, 2};
983 rb.Push(DeviceNotFound);
984 return;
985 }
986
987 const auto result = device.value()->ReadBackupData();
988 IPC::ResponseBuilder rb{ctx, 2};
989 rb.Push(result);
990}
991
992void Interface::WriteBackupData(HLERequestContext& ctx) {
993 IPC::RequestParser rp{ctx};
994 const auto device_handle{rp.Pop<u64>()};
995 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
996
997 if (state == State::NonInitialized) {
998 IPC::ResponseBuilder rb{ctx, 2};
999 rb.Push(NfcDisabled);
1000 return;
1001 }
1002
1003 auto device = GetNfpDevice(device_handle);
1004
1005 if (!device.has_value()) {
1006 IPC::ResponseBuilder rb{ctx, 2};
1007 rb.Push(DeviceNotFound);
1008 return;
1009 }
1010
1011 const auto result = device.value()->WriteBackupData();
1012 IPC::ResponseBuilder rb{ctx, 2};
1013 rb.Push(result);
1014}
1015
1016void Interface::WriteNtf(HLERequestContext& ctx) {
1017 IPC::RequestParser rp{ctx};
1018 const auto device_handle{rp.Pop<u64>()};
1019 LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
1020
1021 if (state == State::NonInitialized) {
1022 IPC::ResponseBuilder rb{ctx, 2};
1023 rb.Push(NfcDisabled);
1024 return;
1025 }
1026
1027 auto device = GetNfpDevice(device_handle);
1028
1029 if (!device.has_value()) {
1030 IPC::ResponseBuilder rb{ctx, 2};
1031 rb.Push(DeviceNotFound);
1032 return;
1033 }
1034
1035 const auto result = device.value()->WriteNtf();
1036 IPC::ResponseBuilder rb{ctx, 2};
1037 rb.Push(result);
1038}
1039
836std::optional<std::shared_ptr<NfpDevice>> Interface::GetNfpDevice(u64 handle) { 1040std::optional<std::shared_ptr<NfpDevice>> Interface::GetNfpDevice(u64 handle) {
837 for (auto& device : devices) { 1041 for (auto& device : devices) {
838 if (device->GetHandle() == handle) { 1042 if (device->GetHandle() == handle) {
diff --git a/src/core/hle/service/nfp/nfp_interface.h b/src/core/hle/service/nfp/nfp_interface.h
index 4affdbc0c..616c94b06 100644
--- a/src/core/hle/service/nfp/nfp_interface.h
+++ b/src/core/hle/service/nfp/nfp_interface.h
@@ -20,8 +20,10 @@ public:
20 20
21 void Initialize(HLERequestContext& ctx); 21 void Initialize(HLERequestContext& ctx);
22 void InitializeSystem(HLERequestContext& ctx); 22 void InitializeSystem(HLERequestContext& ctx);
23 void InitializeDebug(HLERequestContext& ctx);
23 void Finalize(HLERequestContext& ctx); 24 void Finalize(HLERequestContext& ctx);
24 void FinalizeSystem(HLERequestContext& ctx); 25 void FinalizeSystem(HLERequestContext& ctx);
26 void FinalizeDebug(HLERequestContext& ctx);
25 void ListDevices(HLERequestContext& ctx); 27 void ListDevices(HLERequestContext& ctx);
26 void StartDetection(HLERequestContext& ctx); 28 void StartDetection(HLERequestContext& ctx);
27 void StopDetection(HLERequestContext& ctx); 29 void StopDetection(HLERequestContext& ctx);
@@ -52,6 +54,13 @@ public:
52 void DeleteRegisterInfo(HLERequestContext& ctx); 54 void DeleteRegisterInfo(HLERequestContext& ctx);
53 void DeleteApplicationArea(HLERequestContext& ctx); 55 void DeleteApplicationArea(HLERequestContext& ctx);
54 void ExistsApplicationArea(HLERequestContext& ctx); 56 void ExistsApplicationArea(HLERequestContext& ctx);
57 void GetAll(HLERequestContext& ctx);
58 void SetAll(HLERequestContext& ctx);
59 void FlushDebug(HLERequestContext& ctx);
60 void BreakTag(HLERequestContext& ctx);
61 void ReadBackupData(HLERequestContext& ctx);
62 void WriteBackupData(HLERequestContext& ctx);
63 void WriteNtf(HLERequestContext& ctx);
55 64
56private: 65private:
57 enum class State : u32 { 66 enum class State : u32 {
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 90429baa2..1ef047cee 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -109,6 +109,12 @@ enum class AppAreaVersion : u8 {
109 NotSet = 0xFF, 109 NotSet = 0xFF,
110}; 110};
111 111
112enum class BreakType : u32 {
113 Normal,
114 Unknown1,
115 Unknown2,
116};
117
112enum class CabinetMode : u8 { 118enum class CabinetMode : u8 {
113 StartNicknameAndOwnerSettings, 119 StartNicknameAndOwnerSettings,
114 StartGameDataEraser, 120 StartGameDataEraser,
@@ -181,6 +187,12 @@ struct AmiiboDate {
181 }; 187 };
182 } 188 }
183 189
190 void SetWriteDate(const WriteDate& write_date) {
191 SetYear(write_date.year);
192 SetMonth(write_date.month);
193 SetDay(write_date.day);
194 }
195
184 void SetYear(u16 year) { 196 void SetYear(u16 year) {
185 const u16 year_converted = static_cast<u16>((year - 2000) << 9); 197 const u16 year_converted = static_cast<u16>((year - 2000) << 9);
186 raw_date = Common::swap16((GetValue() & ~0xFE00) | year_converted); 198 raw_date = Common::swap16((GetValue() & ~0xFE00) | year_converted);
@@ -375,6 +387,39 @@ struct AdminInfo {
375}; 387};
376static_assert(sizeof(AdminInfo) == 0x40, "AdminInfo is an invalid size"); 388static_assert(sizeof(AdminInfo) == 0x40, "AdminInfo is an invalid size");
377 389
390#pragma pack(1)
391// This is nn::nfp::NfpData
392struct NfpData {
393 u8 magic;
394 INSERT_PADDING_BYTES(0x1);
395 u8 write_counter;
396 INSERT_PADDING_BYTES(0x1);
397 u32 settings_crc;
398 INSERT_PADDING_BYTES(0x38);
399 CommonInfo common_info;
400 Service::Mii::Ver3StoreData mii_char_info;
401 Service::Mii::NfpStoreDataExtension mii_store_data_extension;
402 WriteDate creation_date;
403 std::array<u16_be, amiibo_name_length> amiibo_name;
404 u16 amiibo_name_null_terminated;
405 Settings settings;
406 u8 unknown1;
407 u32 register_info_crc;
408 std::array<u32, 5> unknown2;
409 INSERT_PADDING_BYTES(0x64);
410 u64 application_id;
411 u32 access_id;
412 u16 settings_crc_counter;
413 u8 font_region;
414 PackedTagType tag_type;
415 AppAreaVersion console_type;
416 u8 application_id_byte;
417 INSERT_PADDING_BYTES(0x2E);
418 ApplicationArea application_area;
419};
420static_assert(sizeof(NfpData) == 0x298, "NfpData is an invalid size");
421#pragma pack()
422
378struct SectorKey { 423struct SectorKey {
379 MifareCmd command; 424 MifareCmd command;
380 u8 unknown; // Usually 1 425 u8 unknown; // Usually 1