diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/bounded_threadsafe_queue.h | 5 | ||||
| -rw-r--r-- | src/common/string_util.cpp | 14 | ||||
| -rw-r--r-- | src/common/string_util.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc/svc_ipc.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/mii/mii_manager.cpp | 35 | ||||
| -rw-r--r-- | src/core/hle/service/mii/mii_manager.h | 7 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types.h | 60 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/amiibo_crypto.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.cpp | 89 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_device.h | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nfp/nfp_types.h | 10 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.cpp | 3 | ||||
| -rw-r--r-- | src/video_core/gpu_thread.h | 4 |
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 @@ | |||
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | #include <mutex> | 10 | #include <mutex> |
| 11 | #include <new> | 11 | #include <new> |
| 12 | #include <stop_token> | ||
| 13 | #include <type_traits> | 12 | #include <type_traits> |
| 14 | #include <utility> | 13 | #include <utility> |
| 15 | 14 | ||
| 15 | #include "common/polyfill_thread.h" | ||
| 16 | |||
| 16 | namespace Common { | 17 | namespace Common { |
| 17 | 18 | ||
| 18 | #if defined(__cpp_lib_hardware_interference_size) | 19 | #if defined(__cpp_lib_hardware_interference_size) |
| @@ -78,7 +79,7 @@ public: | |||
| 78 | auto& slot = slots[idx(tail)]; | 79 | auto& slot = slots[idx(tail)]; |
| 79 | if (!slot.turn.test()) { | 80 | if (!slot.turn.test()) { |
| 80 | std::unique_lock lock{cv_mutex}; | 81 | std::unique_lock lock{cv_mutex}; |
| 81 | cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); | 82 | Common::CondvarWait(cv, lock, stop, [&slot] { return slot.turn.test(); }); |
| 82 | } | 83 | } |
| 83 | v = slot.move(); | 84 | v = slot.move(); |
| 84 | slot.destroy(); | 85 | 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 | |||
| 125 | return result; | 125 | return result; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | std::string UTF16ToUTF8(const std::u16string& input) { | 128 | std::string UTF16ToUTF8(std::u16string_view input) { |
| 129 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; | 129 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; |
| 130 | return convert.to_bytes(input); | 130 | return convert.to_bytes(input.data(), input.data() + input.size()); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | std::u16string UTF8ToUTF16(const std::string& input) { | 133 | std::u16string UTF8ToUTF16(std::string_view input) { |
| 134 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; | 134 | std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert; |
| 135 | return convert.from_bytes(input); | 135 | return convert.from_bytes(input.data(), input.data() + input.size()); |
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | #ifdef _WIN32 | 138 | #ifdef _WIN32 |
| 139 | static std::wstring CPToUTF16(u32 code_page, const std::string& input) { | 139 | static std::wstring CPToUTF16(u32 code_page, std::string_view input) { |
| 140 | const auto size = | 140 | const auto size = |
| 141 | MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0); | 141 | MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0); |
| 142 | 142 | ||
| @@ -154,7 +154,7 @@ static std::wstring CPToUTF16(u32 code_page, const std::string& input) { | |||
| 154 | return output; | 154 | return output; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | std::string UTF16ToUTF8(const std::wstring& input) { | 157 | std::string UTF16ToUTF8(std::wstring_view input) { |
| 158 | const auto size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), | 158 | const auto size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), |
| 159 | nullptr, 0, nullptr, nullptr); | 159 | nullptr, 0, nullptr, nullptr); |
| 160 | if (size == 0) { | 160 | if (size == 0) { |
| @@ -172,7 +172,7 @@ std::string UTF16ToUTF8(const std::wstring& input) { | |||
| 172 | return output; | 172 | return output; |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | std::wstring UTF8ToUTF16W(const std::string& input) { | 175 | std::wstring UTF8ToUTF16W(std::string_view input) { |
| 176 | return CPToUTF16(CP_UTF8, input); | 176 | return CPToUTF16(CP_UTF8, input); |
| 177 | } | 177 | } |
| 178 | 178 | ||
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* _ | |||
| 36 | [[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src, | 36 | [[nodiscard]] std::string ReplaceAll(std::string result, const std::string& src, |
| 37 | const std::string& dest); | 37 | const std::string& dest); |
| 38 | 38 | ||
| 39 | [[nodiscard]] std::string UTF16ToUTF8(const std::u16string& input); | 39 | [[nodiscard]] std::string UTF16ToUTF8(std::u16string_view input); |
| 40 | [[nodiscard]] std::u16string UTF8ToUTF16(const std::string& input); | 40 | [[nodiscard]] std::u16string UTF8ToUTF16(std::string_view input); |
| 41 | 41 | ||
| 42 | #ifdef _WIN32 | 42 | #ifdef _WIN32 |
| 43 | [[nodiscard]] std::string UTF16ToUTF8(const std::wstring& input); | 43 | [[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input); |
| 44 | [[nodiscard]] std::wstring UTF8ToUTF16W(const std::string& str); | 44 | [[nodiscard]] std::wstring UTF8ToUTF16W(std::string_view str); |
| 45 | 45 | ||
| 46 | #endif | 46 | #endif |
| 47 | 47 | ||
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) { | |||
| 17 | GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KClientSession>(handle); | 17 | GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KClientSession>(handle); |
| 18 | R_UNLESS(session.IsNotNull(), ResultInvalidHandle); | 18 | R_UNLESS(session.IsNotNull(), ResultInvalidHandle); |
| 19 | 19 | ||
| 20 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | 20 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle); |
| 21 | 21 | ||
| 22 | R_RETURN(session->SendSyncRequest()); | 22 | R_RETURN(session->SendSyncRequest()); |
| 23 | } | 23 | } |
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 { | |||
| 510 | return mii; | 510 | return mii; |
| 511 | } | 511 | } |
| 512 | 512 | ||
| 513 | Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | 513 | Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const { |
| 514 | Service::Mii::MiiManager manager; | 514 | Service::Mii::MiiManager manager; |
| 515 | Ver3StoreData mii_v3{}; | 515 | Ver3StoreData mii_v3{}; |
| 516 | 516 | ||
| @@ -534,16 +534,13 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | |||
| 534 | mii_v3.region_information.character_set.Assign(mii.font_region); | 534 | mii_v3.region_information.character_set.Assign(mii.font_region); |
| 535 | 535 | ||
| 536 | mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type); | 536 | mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type); |
| 537 | mii_v3.appearance_bits1.skin_color.Assign(mii.faceline_color); | ||
| 538 | mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle); | 537 | mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle); |
| 539 | mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make); | 538 | mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make); |
| 540 | 539 | ||
| 541 | mii_v3.hair_style = mii.hair_type; | 540 | mii_v3.hair_style = mii.hair_type; |
| 542 | mii_v3.appearance_bits3.hair_color.Assign(mii.hair_color); | ||
| 543 | mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip); | 541 | mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip); |
| 544 | 542 | ||
| 545 | mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type); | 543 | mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type); |
| 546 | mii_v3.appearance_bits4.eye_color.Assign(mii.eye_color); | ||
| 547 | mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale); | 544 | mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale); |
| 548 | mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect); | 545 | mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect); |
| 549 | mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate); | 546 | mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate); |
| @@ -551,7 +548,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | |||
| 551 | mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y); | 548 | mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y); |
| 552 | 549 | ||
| 553 | mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type); | 550 | mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type); |
| 554 | mii_v3.appearance_bits5.eyebrow_color.Assign(mii.eyebrow_color); | ||
| 555 | mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale); | 551 | mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale); |
| 556 | mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect); | 552 | mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect); |
| 557 | mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate); | 553 | mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate); |
| @@ -563,7 +559,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | |||
| 563 | mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y); | 559 | mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y); |
| 564 | 560 | ||
| 565 | mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type); | 561 | mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type); |
| 566 | mii_v3.appearance_bits7.mouth_color.Assign(mii.mouth_color); | ||
| 567 | mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale); | 562 | mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale); |
| 568 | mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect); | 563 | mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect); |
| 569 | mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y); | 564 | mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y); |
| @@ -573,10 +568,7 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | |||
| 573 | mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y); | 568 | mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y); |
| 574 | 569 | ||
| 575 | mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type); | 570 | mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type); |
| 576 | mii_v3.appearance_bits9.facial_hair_color.Assign(mii.beard_color); | ||
| 577 | 571 | ||
| 578 | mii_v3.appearance_bits10.glasses_type.Assign(mii.glasses_type); | ||
| 579 | mii_v3.appearance_bits10.glasses_color.Assign(mii.glasses_color); | ||
| 580 | mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale); | 572 | mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale); |
| 581 | mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y); | 573 | mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y); |
| 582 | 574 | ||
| @@ -585,11 +577,36 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const { | |||
| 585 | mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x); | 577 | mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x); |
| 586 | mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y); | 578 | mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y); |
| 587 | 579 | ||
| 580 | // These types are converted to V3 from a table | ||
| 581 | mii_v3.appearance_bits1.skin_color.Assign(Ver3FacelineColorTable[mii.faceline_color]); | ||
| 582 | mii_v3.appearance_bits3.hair_color.Assign(Ver3HairColorTable[mii.hair_color]); | ||
| 583 | mii_v3.appearance_bits4.eye_color.Assign(Ver3EyeColorTable[mii.eye_color]); | ||
| 584 | mii_v3.appearance_bits5.eyebrow_color.Assign(Ver3HairColorTable[mii.eyebrow_color]); | ||
| 585 | mii_v3.appearance_bits7.mouth_color.Assign(Ver3MouthlineColorTable[mii.mouth_color]); | ||
| 586 | mii_v3.appearance_bits9.facial_hair_color.Assign(Ver3HairColorTable[mii.beard_color]); | ||
| 587 | mii_v3.appearance_bits10.glasses_color.Assign(Ver3GlassColorTable[mii.glasses_color]); | ||
| 588 | mii_v3.appearance_bits10.glasses_type.Assign(Ver3GlassTypeTable[mii.glasses_type]); | ||
| 589 | |||
| 590 | mii_v3.crc = GenerateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16)); | ||
| 591 | |||
| 588 | // TODO: Validate mii_v3 data | 592 | // TODO: Validate mii_v3 data |
| 589 | 593 | ||
| 590 | return mii_v3; | 594 | return mii_v3; |
| 591 | } | 595 | } |
| 592 | 596 | ||
| 597 | NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { | ||
| 598 | return { | ||
| 599 | .faceline_color = static_cast<u8>(mii.faceline_color & 0xf), | ||
| 600 | .hair_color = static_cast<u8>(mii.hair_color & 0x7f), | ||
| 601 | .eye_color = static_cast<u8>(mii.eyebrow_color & 0x7f), | ||
| 602 | .eyebrow_color = static_cast<u8>(mii.eyebrow_color & 0x7f), | ||
| 603 | .mouth_color = static_cast<u8>(mii.mouth_color & 0x7f), | ||
| 604 | .beard_color = static_cast<u8>(mii.beard_color & 0x7f), | ||
| 605 | .glass_color = static_cast<u8>(mii.glasses_color & 0x7f), | ||
| 606 | .glass_type = static_cast<u8>(mii.glasses_type & 0x1f), | ||
| 607 | }; | ||
| 608 | } | ||
| 609 | |||
| 593 | bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const { | 610 | bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const { |
| 594 | bool is_valid = mii_v3.version == 0 || mii_v3.version == 3; | 611 | bool is_valid = mii_v3.version == 0 || mii_v3.version == 3; |
| 595 | 612 | ||
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: | |||
| 23 | CharInfo BuildRandom(Age age, Gender gender, Race race); | 23 | CharInfo BuildRandom(Age age, Gender gender, Race race); |
| 24 | CharInfo BuildDefault(std::size_t index); | 24 | CharInfo BuildDefault(std::size_t index); |
| 25 | CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const; | 25 | CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const; |
| 26 | Ver3StoreData ConvertCharInfoToV3(const CharInfo& mii) const; | ||
| 27 | bool ValidateV3Info(const Ver3StoreData& mii_v3) const; | 26 | bool ValidateV3Info(const Ver3StoreData& mii_v3) const; |
| 28 | ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag); | 27 | ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag); |
| 29 | Result GetIndex(const CharInfo& info, u32& index); | 28 | Result GetIndex(const CharInfo& info, u32& index); |
| 30 | 29 | ||
| 30 | // This is nn::mii::detail::Ver::StoreDataRaw::BuildFromStoreData | ||
| 31 | Ver3StoreData BuildFromStoreData(const CharInfo& mii) const; | ||
| 32 | |||
| 33 | // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData | ||
| 34 | NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const; | ||
| 35 | |||
| 31 | private: | 36 | private: |
| 32 | const Common::UUID user_id{}; | 37 | const Common::UUID user_id{}; |
| 33 | u64 update_counter{}; | 38 | 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 { | |||
| 365 | } appearance_bits11; | 365 | } appearance_bits11; |
| 366 | 366 | ||
| 367 | std::array<u16_le, 0xA> author_name; | 367 | std::array<u16_le, 0xA> author_name; |
| 368 | INSERT_PADDING_BYTES(0x4); | 368 | INSERT_PADDING_BYTES(0x2); |
| 369 | u16_be crc; | ||
| 369 | }; | 370 | }; |
| 370 | static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); | 371 | static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); |
| 371 | 372 | ||
| 373 | struct NfpStoreDataExtension { | ||
| 374 | u8 faceline_color; | ||
| 375 | u8 hair_color; | ||
| 376 | u8 eye_color; | ||
| 377 | u8 eyebrow_color; | ||
| 378 | u8 mouth_color; | ||
| 379 | u8 beard_color; | ||
| 380 | u8 glass_color; | ||
| 381 | u8 glass_type; | ||
| 382 | }; | ||
| 383 | static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); | ||
| 384 | |||
| 385 | constexpr std::array<u8, 0x10> Ver3FacelineColorTable{ | ||
| 386 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, | ||
| 387 | }; | ||
| 388 | |||
| 389 | constexpr std::array<u8, 100> Ver3HairColorTable{ | ||
| 390 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x4, 0x3, 0x5, 0x4, 0x4, 0x6, 0x2, 0x0, | ||
| 391 | 0x6, 0x4, 0x3, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, | ||
| 392 | 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, | ||
| 393 | 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, | ||
| 394 | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x7, 0x5, 0x7, 0x7, 0x7, 0x7, 0x7, 0x6, 0x7, | ||
| 395 | 0x7, 0x7, 0x7, 0x7, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x4, 0x4, 0x4, | ||
| 396 | }; | ||
| 397 | |||
| 398 | constexpr std::array<u8, 100> Ver3EyeColorTable{ | ||
| 399 | 0x0, 0x2, 0x2, 0x2, 0x1, 0x3, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x2, 0x2, 0x4, | ||
| 400 | 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, | ||
| 401 | 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x0, 0x4, 0x4, | ||
| 402 | 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, | ||
| 403 | 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, | ||
| 404 | 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, | ||
| 405 | }; | ||
| 406 | |||
| 407 | constexpr std::array<u8, 100> Ver3MouthlineColorTable{ | ||
| 408 | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4, | ||
| 409 | 0x4, 0x4, 0x0, 0x1, 0x2, 0x3, 0x4, 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4, | ||
| 410 | 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, | ||
| 411 | 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, | ||
| 412 | 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, | ||
| 413 | 0x3, 0x3, 0x3, 0x3, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x3, 0x3, | ||
| 414 | }; | ||
| 415 | |||
| 416 | constexpr std::array<u8, 100> Ver3GlassColorTable{ | ||
| 417 | 0x0, 0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x4, 0x0, 0x5, 0x1, 0x1, 0x3, 0x5, 0x1, 0x2, 0x3, | ||
| 418 | 0x4, 0x5, 0x4, 0x2, 0x2, 0x4, 0x4, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, | ||
| 419 | 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, | ||
| 420 | 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x0, 0x5, 0x5, | ||
| 421 | 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x1, 0x4, | ||
| 422 | 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, | ||
| 423 | }; | ||
| 424 | |||
| 425 | constexpr std::array<u8, 20> Ver3GlassTypeTable{ | ||
| 426 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, | ||
| 427 | 0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7, | ||
| 428 | }; | ||
| 429 | |||
| 372 | struct MiiStoreData { | 430 | struct MiiStoreData { |
| 373 | using Name = std::array<char16_t, 10>; | 431 | using Name = std::array<char16_t, 10>; |
| 374 | 432 | ||
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) { | |||
| 88 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; | 88 | encoded_data.application_area_id = nfc_data.user_memory.application_area_id; |
| 89 | encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte; | 89 | encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte; |
| 90 | encoded_data.unknown = nfc_data.user_memory.unknown; | 90 | encoded_data.unknown = nfc_data.user_memory.unknown; |
| 91 | encoded_data.mii_extension = nfc_data.user_memory.mii_extension; | ||
| 91 | encoded_data.unknown2 = nfc_data.user_memory.unknown2; | 92 | encoded_data.unknown2 = nfc_data.user_memory.unknown2; |
| 92 | encoded_data.application_area_crc = nfc_data.user_memory.application_area_crc; | 93 | encoded_data.register_info_crc = nfc_data.user_memory.register_info_crc; |
| 93 | encoded_data.application_area = nfc_data.user_memory.application_area; | 94 | encoded_data.application_area = nfc_data.user_memory.application_area; |
| 94 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; | 95 | encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag; |
| 95 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; | 96 | encoded_data.lock_bytes = nfc_data.uuid.lock_bytes; |
| @@ -122,8 +123,9 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) { | |||
| 122 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; | 123 | nfc_data.user_memory.application_area_id = encoded_data.application_area_id; |
| 123 | nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte; | 124 | nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte; |
| 124 | nfc_data.user_memory.unknown = encoded_data.unknown; | 125 | nfc_data.user_memory.unknown = encoded_data.unknown; |
| 126 | nfc_data.user_memory.mii_extension = encoded_data.mii_extension; | ||
| 125 | nfc_data.user_memory.unknown2 = encoded_data.unknown2; | 127 | nfc_data.user_memory.unknown2 = encoded_data.unknown2; |
| 126 | nfc_data.user_memory.application_area_crc = encoded_data.application_area_crc; | 128 | nfc_data.user_memory.register_info_crc = encoded_data.register_info_crc; |
| 127 | nfc_data.user_memory.application_area = encoded_data.application_area; | 129 | nfc_data.user_memory.application_area = encoded_data.application_area; |
| 128 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; | 130 | nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag; |
| 129 | nfc_data.user_memory.model_info = encoded_data.model_info; | 131 | 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 @@ | |||
| 3 | 3 | ||
| 4 | #include <array> | 4 | #include <array> |
| 5 | 5 | ||
| 6 | #ifdef _MSC_VER | ||
| 7 | #pragma warning(push) | ||
| 8 | #pragma warning(disable : 4701) // Potentially uninitialized local variable 'result' used | ||
| 9 | #endif | ||
| 10 | |||
| 11 | #include <boost/crc.hpp> | ||
| 12 | |||
| 13 | #ifdef _MSC_VER | ||
| 14 | #pragma warning(pop) | ||
| 15 | #endif | ||
| 16 | |||
| 6 | #include "common/input.h" | 17 | #include "common/input.h" |
| 7 | #include "common/logging/log.h" | 18 | #include "common/logging/log.h" |
| 8 | #include "common/string_util.h" | 19 | #include "common/string_util.h" |
| @@ -448,7 +459,7 @@ Result NfpDevice::DeleteRegisterInfo() { | |||
| 448 | rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); | 459 | rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); |
| 449 | rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32)); | 460 | rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32)); |
| 450 | rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32)); | 461 | rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32)); |
| 451 | rng.GenerateRandomBytes(&tag_data.application_area_crc, sizeof(u32)); | 462 | rng.GenerateRandomBytes(&tag_data.register_info_crc, sizeof(u32)); |
| 452 | rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32)); | 463 | rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32)); |
| 453 | tag_data.settings.settings.font_region.Assign(0); | 464 | tag_data.settings.settings.font_region.Assign(0); |
| 454 | tag_data.settings.settings.amiibo_initialized.Assign(0); | 465 | tag_data.settings.settings.amiibo_initialized.Assign(0); |
| @@ -471,6 +482,7 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) { | |||
| 471 | } | 482 | } |
| 472 | 483 | ||
| 473 | Service::Mii::MiiManager manager; | 484 | Service::Mii::MiiManager manager; |
| 485 | const auto mii = manager.BuildDefault(0); | ||
| 474 | auto& settings = tag_data.settings; | 486 | auto& settings = tag_data.settings; |
| 475 | 487 | ||
| 476 | if (tag_data.settings.settings.amiibo_initialized == 0) { | 488 | if (tag_data.settings.settings.amiibo_initialized == 0) { |
| @@ -479,16 +491,15 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) { | |||
| 479 | } | 491 | } |
| 480 | 492 | ||
| 481 | SetAmiiboName(settings, amiibo_name); | 493 | SetAmiiboName(settings, amiibo_name); |
| 482 | tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0)); | 494 | tag_data.owner_mii = manager.BuildFromStoreData(mii); |
| 495 | tag_data.mii_extension = manager.SetFromStoreData(mii); | ||
| 483 | tag_data.unknown = 0; | 496 | tag_data.unknown = 0; |
| 484 | tag_data.unknown2[6] = 0; | 497 | tag_data.unknown2 = {}; |
| 485 | settings.country_code_id = 0; | 498 | settings.country_code_id = 0; |
| 486 | settings.settings.font_region.Assign(0); | 499 | settings.settings.font_region.Assign(0); |
| 487 | settings.settings.amiibo_initialized.Assign(1); | 500 | settings.settings.amiibo_initialized.Assign(1); |
| 488 | 501 | ||
| 489 | // TODO: this is a mix of tag.file input | 502 | UpdateRegisterInfoCrc(); |
| 490 | std::array<u8, 0x7e> unknown_input{}; | ||
| 491 | tag_data.application_area_crc = CalculateCrc(unknown_input); | ||
| 492 | 503 | ||
| 493 | return Flush(); | 504 | return Flush(); |
| 494 | } | 505 | } |
| @@ -685,6 +696,11 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat | |||
| 685 | return WrongDeviceState; | 696 | return WrongDeviceState; |
| 686 | } | 697 | } |
| 687 | 698 | ||
| 699 | if (is_app_area_open) { | ||
| 700 | LOG_ERROR(Service_NFP, "Application area is open"); | ||
| 701 | return WrongDeviceState; | ||
| 702 | } | ||
| 703 | |||
| 688 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { | 704 | if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { |
| 689 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); | 705 | LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); |
| 690 | return WrongDeviceState; | 706 | return WrongDeviceState; |
| @@ -715,10 +731,9 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat | |||
| 715 | tag_data.settings.settings.appdata_initialized.Assign(1); | 731 | tag_data.settings.settings.appdata_initialized.Assign(1); |
| 716 | tag_data.application_area_id = access_id; | 732 | tag_data.application_area_id = access_id; |
| 717 | tag_data.unknown = {}; | 733 | tag_data.unknown = {}; |
| 734 | tag_data.unknown2 = {}; | ||
| 718 | 735 | ||
| 719 | // TODO: this is a mix of tag_data input | 736 | UpdateRegisterInfoCrc(); |
| 720 | std::array<u8, 0x7e> unknown_input{}; | ||
| 721 | tag_data.application_area_crc = CalculateCrc(unknown_input); | ||
| 722 | 737 | ||
| 723 | return Flush(); | 738 | return Flush(); |
| 724 | } | 739 | } |
| @@ -752,6 +767,10 @@ Result NfpDevice::DeleteApplicationArea() { | |||
| 752 | rng.GenerateRandomBytes(&tag_data.application_id_byte, sizeof(u8)); | 767 | rng.GenerateRandomBytes(&tag_data.application_id_byte, sizeof(u8)); |
| 753 | tag_data.settings.settings.appdata_initialized.Assign(0); | 768 | tag_data.settings.settings.appdata_initialized.Assign(0); |
| 754 | tag_data.unknown = {}; | 769 | tag_data.unknown = {}; |
| 770 | tag_data.unknown2 = {}; | ||
| 771 | is_app_area_open = false; | ||
| 772 | |||
| 773 | UpdateRegisterInfoCrc(); | ||
| 755 | 774 | ||
| 756 | return Flush(); | 775 | return Flush(); |
| 757 | } | 776 | } |
| @@ -835,32 +854,34 @@ void NfpDevice::UpdateSettingsCrc() { | |||
| 835 | 854 | ||
| 836 | // TODO: this reads data from a global, find what it is | 855 | // TODO: this reads data from a global, find what it is |
| 837 | std::array<u8, 8> unknown_input{}; | 856 | std::array<u8, 8> unknown_input{}; |
| 838 | settings.crc = CalculateCrc(unknown_input); | 857 | boost::crc_32_type crc; |
| 839 | } | 858 | crc.process_bytes(&unknown_input, sizeof(unknown_input)); |
| 840 | 859 | settings.crc = crc.checksum(); | |
| 841 | u32 NfpDevice::CalculateCrc(std::span<const u8> data) { | 860 | } |
| 842 | constexpr u32 magic = 0xedb88320; | 861 | |
| 843 | u32 crc = 0xffffffff; | 862 | void NfpDevice::UpdateRegisterInfoCrc() { |
| 844 | 863 | #pragma pack(push, 1) | |
| 845 | if (data.size() == 0) { | 864 | struct CrcData { |
| 846 | return 0; | 865 | Mii::Ver3StoreData mii; |
| 847 | } | 866 | u8 application_id_byte; |
| 848 | 867 | u8 unknown; | |
| 849 | for (u8 input : data) { | 868 | Mii::NfpStoreDataExtension mii_extension; |
| 850 | u32 temp = (crc ^ input) >> 1; | 869 | std::array<u32, 0x5> unknown2; |
| 851 | if (((crc ^ input) & 1) != 0) { | 870 | }; |
| 852 | temp = temp ^ magic; | 871 | static_assert(sizeof(CrcData) == 0x7e, "CrcData is an invalid size"); |
| 853 | } | 872 | #pragma pack(pop) |
| 854 | 873 | ||
| 855 | for (std::size_t step = 0; step < 7; ++step) { | 874 | const CrcData crc_data{ |
| 856 | crc = temp >> 1; | 875 | .mii = tag_data.owner_mii, |
| 857 | if ((temp & 1) != 0) { | 876 | .application_id_byte = tag_data.application_id_byte, |
| 858 | crc = temp >> 1 ^ magic; | 877 | .unknown = tag_data.unknown, |
| 859 | } | 878 | .mii_extension = tag_data.mii_extension, |
| 860 | } | 879 | .unknown2 = tag_data.unknown2, |
| 861 | } | 880 | }; |
| 862 | 881 | ||
| 863 | return ~crc; | 882 | boost::crc_32_type crc; |
| 883 | crc.process_bytes(&crc_data, sizeof(CrcData)); | ||
| 884 | tag_data.register_info_crc = crc.checksum(); | ||
| 864 | } | 885 | } |
| 865 | 886 | ||
| 866 | } // namespace Service::NFP | 887 | } // 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: | |||
| 80 | AmiiboDate GetAmiiboDate(s64 posix_time) const; | 80 | AmiiboDate GetAmiiboDate(s64 posix_time) const; |
| 81 | u64 RemoveVersionByte(u64 application_id) const; | 81 | u64 RemoveVersionByte(u64 application_id) const; |
| 82 | void UpdateSettingsCrc(); | 82 | void UpdateSettingsCrc(); |
| 83 | u32 CalculateCrc(std::span<const u8>); | 83 | void UpdateRegisterInfoCrc(); |
| 84 | 84 | ||
| 85 | bool is_controller_set{}; | 85 | bool is_controller_set{}; |
| 86 | int callback_key; | 86 | 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 { | |||
| 259 | u32_be application_area_id; // Encrypted Game id | 259 | u32_be application_area_id; // Encrypted Game id |
| 260 | u8 application_id_byte; | 260 | u8 application_id_byte; |
| 261 | u8 unknown; | 261 | u8 unknown; |
| 262 | std::array<u32, 0x7> unknown2; | 262 | Service::Mii::NfpStoreDataExtension mii_extension; |
| 263 | u32_be application_area_crc; | 263 | std::array<u32, 0x5> unknown2; |
| 264 | u32_be register_info_crc; | ||
| 264 | ApplicationArea application_area; // Encrypted Game data | 265 | ApplicationArea application_area; // Encrypted Game data |
| 265 | }; | 266 | }; |
| 266 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); | 267 | static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size"); |
| @@ -280,8 +281,9 @@ struct NTAG215File { | |||
| 280 | u32_be application_area_id; | 281 | u32_be application_area_id; |
| 281 | u8 application_id_byte; | 282 | u8 application_id_byte; |
| 282 | u8 unknown; | 283 | u8 unknown; |
| 283 | std::array<u32, 0x7> unknown2; | 284 | Service::Mii::NfpStoreDataExtension mii_extension; |
| 284 | u32_be application_area_crc; | 285 | std::array<u32, 0x5> unknown2; |
| 286 | u32_be register_info_crc; | ||
| 285 | ApplicationArea application_area; // Encrypted Game data | 287 | ApplicationArea application_area; // Encrypted Game data |
| 286 | HashData hmac_tag; // Hash | 288 | HashData hmac_tag; // Hash |
| 287 | UniqueSerialNumber uid; // Unique serial number | 289 | 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, | |||
| 32 | VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer(); | 32 | VideoCore::RasterizerInterface* const rasterizer = renderer.ReadRasterizer(); |
| 33 | 33 | ||
| 34 | while (!stop_token.stop_requested()) { | 34 | while (!stop_token.stop_requested()) { |
| 35 | CommandDataContainer next = state.queue.PopWait(stop_token); | 35 | CommandDataContainer next; |
| 36 | state.queue.Pop(next, stop_token); | ||
| 36 | if (stop_token.stop_requested()) { | 37 | if (stop_token.stop_requested()) { |
| 37 | break; | 38 | break; |
| 38 | } | 39 | } |
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 @@ | |||
| 10 | #include <thread> | 10 | #include <thread> |
| 11 | #include <variant> | 11 | #include <variant> |
| 12 | 12 | ||
| 13 | #include "common/bounded_threadsafe_queue.h" | ||
| 13 | #include "common/polyfill_thread.h" | 14 | #include "common/polyfill_thread.h" |
| 14 | #include "common/threadsafe_queue.h" | ||
| 15 | #include "video_core/framebuffer_config.h" | 15 | #include "video_core/framebuffer_config.h" |
| 16 | 16 | ||
| 17 | namespace Tegra { | 17 | namespace Tegra { |
| @@ -97,7 +97,7 @@ struct CommandDataContainer { | |||
| 97 | 97 | ||
| 98 | /// Struct used to synchronize the GPU thread | 98 | /// Struct used to synchronize the GPU thread |
| 99 | struct SynchState final { | 99 | struct SynchState final { |
| 100 | using CommandQueue = Common::MPSCQueue<CommandDataContainer, true>; | 100 | using CommandQueue = Common::MPSCQueue<CommandDataContainer>; |
| 101 | std::mutex write_lock; | 101 | std::mutex write_lock; |
| 102 | CommandQueue queue; | 102 | CommandQueue queue; |
| 103 | u64 last_fence{}; | 103 | u64 last_fence{}; |