summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/bounded_threadsafe_queue.h5
-rw-r--r--src/common/string_util.cpp14
-rw-r--r--src/common/string_util.h8
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp2
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp35
-rw-r--r--src/core/hle/service/mii/mii_manager.h7
-rw-r--r--src/core/hle/service/mii/types.h60
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.cpp6
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp89
-rw-r--r--src/core/hle/service/nfp/nfp_device.h2
-rw-r--r--src/core/hle/service/nfp/nfp_types.h10
-rw-r--r--src/video_core/gpu_thread.cpp3
-rw-r--r--src/video_core/gpu_thread.h4
13 files changed, 176 insertions, 69 deletions
diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h
index 21217801e..14e887c70 100644
--- a/src/common/bounded_threadsafe_queue.h
+++ b/src/common/bounded_threadsafe_queue.h
@@ -9,10 +9,11 @@
#include <memory>
#include <mutex>
#include <new>
-#include <stop_token>
#include <type_traits>
#include <utility>
+#include "common/polyfill_thread.h"
+
namespace Common {
#if defined(__cpp_lib_hardware_interference_size)
@@ -78,7 +79,7 @@ public:
auto& slot = slots[idx(tail)];
if (!slot.turn.test()) {
std::unique_lock lock{cv_mutex};
- cv.wait(lock, stop, [&slot] { return slot.turn.test(); });
+ Common::CondvarWait(cv, lock, stop, [&slot] { return slot.turn.test(); });
}
v = slot.move();
slot.destroy();
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp
index e0b6180c5..feab1653d 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -125,18 +125,18 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
return result;
}
-std::string UTF16ToUTF8(const std::u16string& input) {
+std::string UTF16ToUTF8(std::u16string_view input) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
- return convert.to_bytes(input);
+ return convert.to_bytes(input.data(), input.data() + input.size());
}
-std::u16string UTF8ToUTF16(const std::string& input) {
+std::u16string UTF8ToUTF16(std::string_view input) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
- return convert.from_bytes(input);
+ return convert.from_bytes(input.data(), input.data() + input.size());
}
#ifdef _WIN32
-static std::wstring CPToUTF16(u32 code_page, const std::string& input) {
+static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
const auto size =
MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0);
@@ -154,7 +154,7 @@ static std::wstring CPToUTF16(u32 code_page, const std::string& input) {
return output;
}
-std::string UTF16ToUTF8(const std::wstring& input) {
+std::string UTF16ToUTF8(std::wstring_view input) {
const auto size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()),
nullptr, 0, nullptr, nullptr);
if (size == 0) {
@@ -172,7 +172,7 @@ std::string UTF16ToUTF8(const std::wstring& input) {
return output;
}
-std::wstring UTF8ToUTF16W(const std::string& input) {
+std::wstring UTF8ToUTF16W(std::string_view input) {
return CPToUTF16(CP_UTF8, input);
}
diff --git a/src/common/string_util.h b/src/common/string_util.h
index f8aecc875..c351f1a0c 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -36,12 +36,12 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
[[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src,
const std::string& dest);
-[[nodiscard]] std::string UTF16ToUTF8(const std::u16string& input);
-[[nodiscard]] std::u16string UTF8ToUTF16(const std::string& input);
+[[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input);
+[[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input);
#ifdef _WIN32
-[[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input);
-[[nodiscard]] std::wstring UTF8ToUTF16W(const std::string& str);
+[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input);
+[[nodiscard]] std::wstring UTF8ToUTF16W(std::string_view str);
#endif
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp
index 46fd0f2ea..2a8c09a79 100644
--- a/src/core/hle/kernel/svc/svc_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_ipc.cpp
@@ -17,7 +17,7 @@ Result SendSyncRequest(Core::System& system, Handle handle) {
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KClientSession>(handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
- LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
+ LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle);
R_RETURN(session->SendSyncRequest());
}
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 3a2fe938f..c920650f5 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -510,7 +510,7 @@ CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const {
return mii;
}
-Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
+Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const {
Service::Mii::MiiManager manager;
Ver3StoreData mii_v3{};
@@ -534,16 +534,13 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.region_information.character_set.Assign(mii.font_region);
mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type);
- mii_v3.appearance_bits1.skin_color.Assign(mii.faceline_color);
mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle);
mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make);
mii_v3.hair_style = mii.hair_type;
- mii_v3.appearance_bits3.hair_color.Assign(mii.hair_color);
mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip);
mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type);
- mii_v3.appearance_bits4.eye_color.Assign(mii.eye_color);
mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale);
mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect);
mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate);
@@ -551,7 +548,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y);
mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type);
- mii_v3.appearance_bits5.eyebrow_color.Assign(mii.eyebrow_color);
mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale);
mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect);
mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate);
@@ -563,7 +559,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y);
mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type);
- mii_v3.appearance_bits7.mouth_color.Assign(mii.mouth_color);
mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale);
mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect);
mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y);
@@ -573,10 +568,7 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y);
mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type);
- mii_v3.appearance_bits9.facial_hair_color.Assign(mii.beard_color);
- mii_v3.appearance_bits10.glasses_type.Assign(mii.glasses_type);
- mii_v3.appearance_bits10.glasses_color.Assign(mii.glasses_color);
mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale);
mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y);
@@ -585,11 +577,36 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x);
mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y);
+ // These types are converted to V3 from a table
+ mii_v3.appearance_bits1.skin_color.Assign(Ver3FacelineColorTable[mii.faceline_color]);
+ mii_v3.appearance_bits3.hair_color.Assign(Ver3HairColorTable[mii.hair_color]);
+ mii_v3.appearance_bits4.eye_color.Assign(Ver3EyeColorTable[mii.eye_color]);
+ mii_v3.appearance_bits5.eyebrow_color.Assign(Ver3HairColorTable[mii.eyebrow_color]);
+ mii_v3.appearance_bits7.mouth_color.Assign(Ver3MouthlineColorTable[mii.mouth_color]);
+ mii_v3.appearance_bits9.facial_hair_color.Assign(Ver3HairColorTable[mii.beard_color]);
+ mii_v3.appearance_bits10.glasses_color.Assign(Ver3GlassColorTable[mii.glasses_color]);
+ mii_v3.appearance_bits10.glasses_type.Assign(Ver3GlassTypeTable[mii.glasses_type]);
+
+ mii_v3.crc = GenerateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16));
+
// TODO: Validate mii_v3 data
return mii_v3;
}
+NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const {
+ return {
+ .faceline_color = static_cast<u8>(mii.faceline_color & 0xf),
+ .hair_color = static_cast<u8>(mii.hair_color & 0x7f),
+ .eye_color = static_cast<u8>(mii.eyebrow_color & 0x7f),
+ .eyebrow_color = static_cast<u8>(mii.eyebrow_color & 0x7f),
+ .mouth_color = static_cast<u8>(mii.mouth_color & 0x7f),
+ .beard_color = static_cast<u8>(mii.beard_color & 0x7f),
+ .glass_color = static_cast<u8>(mii.glasses_color & 0x7f),
+ .glass_type = static_cast<u8>(mii.glasses_type & 0x1f),
+ };
+}
+
bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const {
bool is_valid = mii_v3.version == 0 || mii_v3.version == 3;
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
index 83ad3d343..5525fcd1c 100644
--- a/src/core/hle/service/mii/mii_manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
@@ -23,11 +23,16 @@ public:
CharInfo BuildRandom(Age age, Gender gender, Race race);
CharInfo BuildDefault(std::size_t index);
CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const;
- Ver3StoreData ConvertCharInfoToV3(const CharInfo& mii) const;
bool ValidateV3Info(const Ver3StoreData& mii_v3) const;
ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag);
Result GetIndex(const CharInfo& info, u32& index);
+ // This is nn::mii::detail::Ver::StoreDataRaw::BuildFromStoreData
+ Ver3StoreData BuildFromStoreData(const CharInfo& mii) const;
+
+ // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData
+ NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const;
+
private:
const Common::UUID user_id{};
u64 update_counter{};
diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h
index 9e3247397..c48d08d79 100644
--- a/src/core/hle/service/mii/types.h
+++ b/src/core/hle/service/mii/types.h
@@ -365,10 +365,68 @@ struct Ver3StoreData {
} appearance_bits11;
std::array<u16_le, 0xA> author_name;
- INSERT_PADDING_BYTES(0x4);
+ INSERT_PADDING_BYTES(0x2);
+ u16_be crc;
};
static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size");
+struct NfpStoreDataExtension {
+ u8 faceline_color;
+ u8 hair_color;
+ u8 eye_color;
+ u8 eyebrow_color;
+ u8 mouth_color;
+ u8 beard_color;
+ u8 glass_color;
+ u8 glass_type;
+};
+static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size");
+
+constexpr std::array<u8, 0x10> Ver3FacelineColorTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5,
+};
+
+constexpr std::array<u8, 100> Ver3HairColorTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x4, 0x3, 0x5, 0x4, 0x4, 0x6, 0x2, 0x0,
+ 0x6, 0x4, 0x3, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x7, 0x5, 0x7, 0x7, 0x7, 0x7, 0x7, 0x6, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x4, 0x4, 0x4,
+};
+
+constexpr std::array<u8, 100> Ver3EyeColorTable{
+ 0x0, 0x2, 0x2, 0x2, 0x1, 0x3, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x2, 0x2, 0x4,
+ 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x0, 0x4, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2,
+ 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+};
+
+constexpr std::array<u8, 100> Ver3MouthlineColorTable{
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4,
+ 0x4, 0x4, 0x0, 0x1, 0x2, 0x3, 0x4, 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4,
+ 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4,
+ 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4,
+ 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3,
+ 0x3, 0x3, 0x3, 0x3, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x3, 0x3,
+};
+
+constexpr std::array<u8, 100> Ver3GlassColorTable{
+ 0x0, 0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x4, 0x0, 0x5, 0x1, 0x1, 0x3, 0x5, 0x1, 0x2, 0x3,
+ 0x4, 0x5, 0x4, 0x2, 0x2, 0x4, 0x4, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x0, 0x5, 0x5,
+ 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x1, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+};
+
+constexpr std::array<u8, 20> Ver3GlassTypeTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1,
+ 0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7,
+};
+
struct MiiStoreData {
using Name = std::array<char16_t, 10>;
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp
index ad73edbda..bba862fb2 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfp/amiibo_crypto.cpp
@@ -88,8 +88,9 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
encoded_data.application_area_id = nfc_data.user_memory.application_area_id;
encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte;
encoded_data.unknown = nfc_data.user_memory.unknown;
+ encoded_data.mii_extension = nfc_data.user_memory.mii_extension;
encoded_data.unknown2 = nfc_data.user_memory.unknown2;
- encoded_data.application_area_crc = nfc_data.user_memory.application_area_crc;
+ encoded_data.register_info_crc = nfc_data.user_memory.register_info_crc;
encoded_data.application_area = nfc_data.user_memory.application_area;
encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag;
encoded_data.lock_bytes = nfc_data.uuid.lock_bytes;
@@ -122,8 +123,9 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
nfc_data.user_memory.application_area_id = encoded_data.application_area_id;
nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte;
nfc_data.user_memory.unknown = encoded_data.unknown;
+ nfc_data.user_memory.mii_extension = encoded_data.mii_extension;
nfc_data.user_memory.unknown2 = encoded_data.unknown2;
- nfc_data.user_memory.application_area_crc = encoded_data.application_area_crc;
+ nfc_data.user_memory.register_info_crc = encoded_data.register_info_crc;
nfc_data.user_memory.application_area = encoded_data.application_area;
nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag;
nfc_data.user_memory.model_info = encoded_data.model_info;
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index ddff90d6a..268337d2e 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -3,6 +3,17 @@
#include <array>
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4701) // Potentially uninitialized local variable 'result' used
+#endif
+
+#include <boost/crc.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
#include "common/input.h"
#include "common/logging/log.h"
#include "common/string_util.h"
@@ -448,7 +459,7 @@ Result NfpDevice::DeleteRegisterInfo() {
rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8));
rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32));
rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32));
- rng.GenerateRandomBytes(&tag_data.application_area_crc, sizeof(u32));
+ rng.GenerateRandomBytes(&tag_data.register_info_crc, sizeof(u32));
rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32));
tag_data.settings.settings.font_region.Assign(0);
tag_data.settings.settings.amiibo_initialized.Assign(0);
@@ -471,6 +482,7 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) {
}
Service::Mii::MiiManager manager;
+ const auto mii = manager.BuildDefault(0);
auto& settings = tag_data.settings;
if (tag_data.settings.settings.amiibo_initialized == 0) {
@@ -479,16 +491,15 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) {
}
SetAmiiboName(settings, amiibo_name);
- tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0));
+ tag_data.owner_mii = manager.BuildFromStoreData(mii);
+ tag_data.mii_extension = manager.SetFromStoreData(mii);
tag_data.unknown = 0;
- tag_data.unknown2[6] = 0;
+ tag_data.unknown2 = {};
settings.country_code_id = 0;
settings.settings.font_region.Assign(0);
settings.settings.amiibo_initialized.Assign(1);
- // TODO: this is a mix of tag.file input
- std::array<u8, 0x7e> unknown_input{};
- tag_data.application_area_crc = CalculateCrc(unknown_input);
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -685,6 +696,11 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
return WrongDeviceState;
}
+ if (is_app_area_open) {
+ LOG_ERROR(Service_NFP, "Application area is open");
+ return WrongDeviceState;
+ }
+
if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
return WrongDeviceState;
@@ -715,10 +731,9 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
tag_data.settings.settings.appdata_initialized.Assign(1);
tag_data.application_area_id = access_id;
tag_data.unknown = {};
+ tag_data.unknown2 = {};
- // TODO: this is a mix of tag_data input
- std::array<u8, 0x7e> unknown_input{};
- tag_data.application_area_crc = CalculateCrc(unknown_input);
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -752,6 +767,10 @@ Result NfpDevice::DeleteApplicationArea() {
rng.GenerateRandomBytes(&tag_data.application_id_byte, sizeof(u8));
tag_data.settings.settings.appdata_initialized.Assign(0);
tag_data.unknown = {};
+ tag_data.unknown2 = {};
+ is_app_area_open = false;
+
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -835,32 +854,34 @@ void NfpDevice::UpdateSettingsCrc() {
// TODO: this reads data from a global, find what it is
std::array<u8, 8> unknown_input{};
- settings.crc = CalculateCrc(unknown_input);
-}
-
-u32 NfpDevice::CalculateCrc(std::span<const u8> data) {
- constexpr u32 magic = 0xedb88320;
- u32 crc = 0xffffffff;
-
- if (data.size() == 0) {
- return 0;
- }
-
- for (u8 input : data) {
- u32 temp = (crc ^ input) >> 1;
- if (((crc ^ input) & 1) != 0) {
- temp = temp ^ magic;
- }
-
- for (std::size_t step = 0; step < 7; ++step) {
- crc = temp >> 1;
- if ((temp & 1) != 0) {
- crc = temp >> 1 ^ magic;
- }
- }
- }
+ boost::crc_32_type crc;
+ crc.process_bytes(&unknown_input, sizeof(unknown_input));
+ settings.crc = crc.checksum();
+}
+
+void NfpDevice::UpdateRegisterInfoCrc() {
+#pragma pack(push, 1)
+ struct CrcData {
+ Mii::Ver3StoreData mii;
+ u8 application_id_byte;
+ u8 unknown;
+ Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ };
+ static_assert(sizeof(CrcData) == 0x7e, "CrcData is an invalid size");
+#pragma pack(pop)
+
+ const CrcData crc_data{
+ .mii = tag_data.owner_mii,
+ .application_id_byte = tag_data.application_id_byte,
+ .unknown = tag_data.unknown,
+ .mii_extension = tag_data.mii_extension,
+ .unknown2 = tag_data.unknown2,
+ };
- return ~crc;
+ boost::crc_32_type crc;
+ crc.process_bytes(&crc_data, sizeof(CrcData));
+ tag_data.register_info_crc = crc.checksum();
}
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h
index 06386401d..8813df998 100644
--- a/src/core/hle/service/nfp/nfp_device.h
+++ b/src/core/hle/service/nfp/nfp_device.h
@@ -80,7 +80,7 @@ private:
AmiiboDate GetAmiiboDate(s64 posix_time) const;
u64 RemoveVersionByte(u64 application_id) const;
void UpdateSettingsCrc();
- u32 CalculateCrc(std::span<const u8>);
+ void UpdateRegisterInfoCrc();
bool is_controller_set{};
int callback_key;
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 142343d6e..b3599a513 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -259,8 +259,9 @@ struct EncryptedAmiiboFile {
u32_be application_area_id; // Encrypted Game id
u8 application_id_byte;
u8 unknown;
- std::array<u32, 0x7> unknown2;
- u32_be application_area_crc;
+ Service::Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ u32_be register_info_crc;
ApplicationArea application_area; // Encrypted Game data
};
static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size");
@@ -280,8 +281,9 @@ struct NTAG215File {
u32_be application_area_id;
u8 application_id_byte;
u8 unknown;
- std::array<u32, 0x7> unknown2;
- u32_be application_area_crc;
+ Service::Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ u32_be register_info_crc;
ApplicationArea application_area; // Encrypted Game data
HashData hmac_tag; // Hash
UniqueSerialNumber uid; // Unique serial number
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 050b11874..f52f9e28f 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -32,7 +32,8 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer();
while (!stop_token.stop_requested()) {
- CommandDataContainer next = state.queue.PopWait(stop_token);
+ CommandDataContainer next;
+ state.queue.Pop(next, stop_token);
if (stop_token.stop_requested()) {
break;
}
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index 90bcb5958..43940bd6d 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -10,8 +10,8 @@
#include <thread>
#include <variant>
+#include "common/bounded_threadsafe_queue.h"
#include "common/polyfill_thread.h"
-#include "common/threadsafe_queue.h"
#include "video_core/framebuffer_config.h"
namespace Tegra {
@@ -97,7 +97,7 @@ struct CommandDataContainer {
/// Struct used to synchronize the GPU thread
struct SynchState final {
- using CommandQueue = Common::MPSCQueue<CommandDataContainer, true>;
+ using CommandQueue = Common::MPSCQueue<CommandDataContainer>;
std::mutex write_lock;
CommandQueue queue;
u64 last_fence{};