From 8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 22:42:38 -0600 Subject: [PATCH] service: mii: Move ver3 operations --- src/core/hle/service/mii/mii_manager.cpp | 235 +----------------- src/core/hle/service/mii/mii_manager.h | 4 - src/core/hle/service/mii/types/char_info.h | 3 +- .../hle/service/mii/types/ver3_store_data.cpp | 224 ++++++++++++++++- .../hle/service/mii/types/ver3_store_data.h | 13 +- src/core/hle/service/nfc/common/device.cpp | 4 +- src/core/hle/service/nfp/nfp_types.h | 1 + 7 files changed, 241 insertions(+), 243 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 035eed5056..9ae7fb960d 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -394,173 +394,9 @@ CharInfo MiiManager::BuildDefault(std::size_t index) { } CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { - Service::Mii::MiiManager manager; - auto mii = manager.BuildBase(Mii::Gender::Male); - - if (!ValidateV3Info(mii_v3)) { - return mii; - } - - // TODO: We are ignoring a bunch of data from the mii_v3 - - mii.gender = static_cast(mii_v3.mii_information.gender); - mii.favorite_color = static_cast(mii_v3.mii_information.favorite_color); - mii.height = mii_v3.height; - mii.build = mii_v3.build; - - // Copy name until string terminator - mii.name = {}; - for (std::size_t index = 0; index < mii.name.size() - 1; index++) { - mii.name[index] = mii_v3.mii_name[index]; - if (mii.name[index] == 0) { - break; - } - } - - mii.font_region = mii_v3.region_information.character_set; - - mii.faceline_type = mii_v3.appearance_bits1.face_shape; - mii.faceline_color = mii_v3.appearance_bits1.skin_color; - mii.faceline_wrinkle = mii_v3.appearance_bits2.wrinkles; - mii.faceline_make = mii_v3.appearance_bits2.makeup; - - mii.hair_type = mii_v3.hair_style; - mii.hair_color = mii_v3.appearance_bits3.hair_color; - mii.hair_flip = mii_v3.appearance_bits3.flip_hair; - - mii.eye_type = static_cast(mii_v3.appearance_bits4.eye_type); - mii.eye_color = static_cast(mii_v3.appearance_bits4.eye_color); - mii.eye_scale = static_cast(mii_v3.appearance_bits4.eye_scale); - mii.eye_aspect = static_cast(mii_v3.appearance_bits4.eye_vertical_stretch); - mii.eye_rotate = static_cast(mii_v3.appearance_bits4.eye_rotation); - mii.eye_x = static_cast(mii_v3.appearance_bits4.eye_spacing); - mii.eye_y = static_cast(mii_v3.appearance_bits4.eye_y_position); - - mii.eyebrow_type = static_cast(mii_v3.appearance_bits5.eyebrow_style); - mii.eyebrow_color = static_cast(mii_v3.appearance_bits5.eyebrow_color); - mii.eyebrow_scale = static_cast(mii_v3.appearance_bits5.eyebrow_scale); - mii.eyebrow_aspect = static_cast(mii_v3.appearance_bits5.eyebrow_yscale); - mii.eyebrow_rotate = static_cast(mii_v3.appearance_bits5.eyebrow_rotation); - mii.eyebrow_x = static_cast(mii_v3.appearance_bits5.eyebrow_spacing); - mii.eyebrow_y = static_cast(mii_v3.appearance_bits5.eyebrow_y_position); - - mii.nose_type = static_cast(mii_v3.appearance_bits6.nose_type); - mii.nose_scale = static_cast(mii_v3.appearance_bits6.nose_scale); - mii.nose_y = static_cast(mii_v3.appearance_bits6.nose_y_position); - - mii.mouth_type = static_cast(mii_v3.appearance_bits7.mouth_type); - mii.mouth_color = static_cast(mii_v3.appearance_bits7.mouth_color); - mii.mouth_scale = static_cast(mii_v3.appearance_bits7.mouth_scale); - mii.mouth_aspect = static_cast(mii_v3.appearance_bits7.mouth_horizontal_stretch); - mii.mouth_y = static_cast(mii_v3.appearance_bits8.mouth_y_position); - - mii.mustache_type = static_cast(mii_v3.appearance_bits8.mustache_type); - mii.mustache_scale = static_cast(mii_v3.appearance_bits9.mustache_scale); - mii.mustache_y = static_cast(mii_v3.appearance_bits9.mustache_y_position); - - mii.beard_type = static_cast(mii_v3.appearance_bits9.bear_type); - mii.beard_color = static_cast(mii_v3.appearance_bits9.facial_hair_color); - - mii.glasses_type = static_cast(mii_v3.appearance_bits10.glasses_type); - mii.glasses_color = static_cast(mii_v3.appearance_bits10.glasses_color); - mii.glasses_scale = static_cast(mii_v3.appearance_bits10.glasses_scale); - mii.glasses_y = static_cast(mii_v3.appearance_bits10.glasses_y_position); - - mii.mole_type = static_cast(mii_v3.appearance_bits11.mole_enabled); - mii.mole_scale = static_cast(mii_v3.appearance_bits11.mole_scale); - mii.mole_x = static_cast(mii_v3.appearance_bits11.mole_x_position); - mii.mole_y = static_cast(mii_v3.appearance_bits11.mole_y_position); - - // TODO: Validate mii data - - return mii; -} - -Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const { - Service::Mii::MiiManager manager; - Ver3StoreData mii_v3{}; - - // TODO: We are ignoring a bunch of data from the mii_v3 - - mii_v3.version = 1; - mii_v3.mii_information.gender.Assign(mii.gender); - mii_v3.mii_information.favorite_color.Assign(mii.favorite_color); - mii_v3.height = mii.height; - mii_v3.build = mii.build; - - // Copy name until string terminator - mii_v3.mii_name = {}; - for (std::size_t index = 0; index < mii.name.size() - 1; index++) { - mii_v3.mii_name[index] = mii.name[index]; - if (mii_v3.mii_name[index] == 0) { - break; - } - } - - mii_v3.region_information.character_set.Assign(mii.font_region); - - mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type); - 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.flip_hair.Assign(mii.hair_flip); - - mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type); - 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); - mii_v3.appearance_bits4.eye_spacing.Assign(mii.eye_x); - 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_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); - mii_v3.appearance_bits5.eyebrow_spacing.Assign(mii.eyebrow_x); - mii_v3.appearance_bits5.eyebrow_y_position.Assign(mii.eyebrow_y); - - mii_v3.appearance_bits6.nose_type.Assign(mii.nose_type); - mii_v3.appearance_bits6.nose_scale.Assign(mii.nose_scale); - 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_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); - - mii_v3.appearance_bits8.mustache_type.Assign(mii.mustache_type); - mii_v3.appearance_bits9.mustache_scale.Assign(mii.mustache_scale); - mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y); - - mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type); - - mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale); - mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y); - - mii_v3.appearance_bits11.mole_enabled.Assign(mii.mole_type); - mii_v3.appearance_bits11.mole_scale.Assign(mii.mole_scale); - 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( - RawData::FromVer3GetFacelineColor(mii.faceline_color)); - mii_v3.appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(mii.hair_color)); - mii_v3.appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(mii.eye_color)); - mii_v3.appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(mii.eyebrow_color)); - mii_v3.appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(mii.mouth_color)); - mii_v3.appearance_bits9.facial_hair_color.Assign( - RawData::FromVer3GetHairColor(mii.beard_color)); - mii_v3.appearance_bits10.glasses_color.Assign( - RawData::FromVer3GetGlassColor(mii.glasses_color)); - mii_v3.appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(mii.glasses_type)); - - mii_v3.crc = MiiUtil::CalculateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16)); - - // TODO: Validate mii_v3 data - - return mii_v3; + CharInfo char_info{}; + mii_v3.BuildToStoreData(char_info); + return char_info; } NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { @@ -576,71 +412,6 @@ NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { }; } -bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const { - bool is_valid = mii_v3.version == 0 || mii_v3.version == 3; - - is_valid = is_valid && (mii_v3.mii_name[0] != 0); - - is_valid = is_valid && (mii_v3.mii_information.birth_month < 13); - is_valid = is_valid && (mii_v3.mii_information.birth_day < 32); - is_valid = is_valid && (mii_v3.mii_information.favorite_color < 12); - is_valid = is_valid && (mii_v3.height < 128); - is_valid = is_valid && (mii_v3.build < 128); - - is_valid = is_valid && (mii_v3.appearance_bits1.face_shape < 12); - is_valid = is_valid && (mii_v3.appearance_bits1.skin_color < 7); - is_valid = is_valid && (mii_v3.appearance_bits2.wrinkles < 12); - is_valid = is_valid && (mii_v3.appearance_bits2.makeup < 12); - - is_valid = is_valid && (mii_v3.hair_style < 132); - is_valid = is_valid && (mii_v3.appearance_bits3.hair_color < 8); - - is_valid = is_valid && (mii_v3.appearance_bits4.eye_type < 60); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_color < 6); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_scale < 8); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_vertical_stretch < 7); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_rotation < 8); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_spacing < 13); - is_valid = is_valid && (mii_v3.appearance_bits4.eye_y_position < 19); - - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_style < 25); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_color < 8); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_scale < 9); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_yscale < 7); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_rotation < 12); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_spacing < 12); - is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_y_position < 19); - - is_valid = is_valid && (mii_v3.appearance_bits6.nose_type < 18); - is_valid = is_valid && (mii_v3.appearance_bits6.nose_scale < 9); - is_valid = is_valid && (mii_v3.appearance_bits6.nose_y_position < 19); - - is_valid = is_valid && (mii_v3.appearance_bits7.mouth_type < 36); - is_valid = is_valid && (mii_v3.appearance_bits7.mouth_color < 5); - is_valid = is_valid && (mii_v3.appearance_bits7.mouth_scale < 9); - is_valid = is_valid && (mii_v3.appearance_bits7.mouth_horizontal_stretch < 7); - is_valid = is_valid && (mii_v3.appearance_bits8.mouth_y_position < 19); - - is_valid = is_valid && (mii_v3.appearance_bits8.mustache_type < 6); - is_valid = is_valid && (mii_v3.appearance_bits9.mustache_scale < 7); - is_valid = is_valid && (mii_v3.appearance_bits9.mustache_y_position < 17); - - is_valid = is_valid && (mii_v3.appearance_bits9.bear_type < 6); - is_valid = is_valid && (mii_v3.appearance_bits9.facial_hair_color < 8); - - is_valid = is_valid && (mii_v3.appearance_bits10.glasses_type < 9); - is_valid = is_valid && (mii_v3.appearance_bits10.glasses_color < 6); - is_valid = is_valid && (mii_v3.appearance_bits10.glasses_scale < 8); - is_valid = is_valid && (mii_v3.appearance_bits10.glasses_y_position < 21); - - is_valid = is_valid && (mii_v3.appearance_bits11.mole_enabled < 2); - is_valid = is_valid && (mii_v3.appearance_bits11.mole_scale < 9); - is_valid = is_valid && (mii_v3.appearance_bits11.mole_x_position < 17); - is_valid = is_valid && (mii_v3.appearance_bits11.mole_y_position < 31); - - return is_valid; -} - std::vector MiiManager::GetDefault(SourceFlag source_flag) { std::vector result; diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h index 1f5c9e16fe..0a47e613fb 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h @@ -27,13 +27,9 @@ public: CharInfo BuildBase(Gender gender); CharInfo BuildDefault(std::size_t index); CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const; - bool ValidateV3Info(const Ver3StoreData& mii_v3) const; std::vector 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; diff --git a/src/core/hle/service/mii/types/char_info.h b/src/core/hle/service/mii/types/char_info.h index 5741b50892..cdebb1c9de 100644 --- a/src/core/hle/service/mii/types/char_info.h +++ b/src/core/hle/service/mii/types/char_info.h @@ -8,7 +8,8 @@ namespace Service::Mii { // This is nn::mii::detail::CharInfoRaw -struct CharInfo { +class CharInfo { +public: Common::UUID create_id; Nickname name; u16 null_terminator; diff --git a/src/core/hle/service/mii/types/ver3_store_data.cpp b/src/core/hle/service/mii/types/ver3_store_data.cpp index 4c8904c12c..c774f4b47a 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.cpp +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp @@ -1,6 +1,228 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/mii/mii_util.h" +#include "core/hle/service/mii/types/char_info.h" +#include "core/hle/service/mii/types/raw_data.h" +#include "core/hle/service/mii/types/store_data.h" #include "core/hle/service/mii/types/ver3_store_data.h" -namespace Service::Mii {} // namespace Service::Mii +namespace Service::Mii { + +void Ver3StoreData::BuildToStoreData(CharInfo& out_char_info) const { + if (!IsValid()) { + return; + } + + // TODO: We are ignoring a bunch of data from the mii_v3 + + out_char_info.gender = static_cast(mii_information.gender); + out_char_info.favorite_color = static_cast(mii_information.favorite_color); + out_char_info.height = height; + out_char_info.build = build; + + // Copy name until string terminator + out_char_info.name = {}; + for (std::size_t index = 0; index < out_char_info.name.size() - 1; index++) { + out_char_info.name[index] = mii_name[index]; + if (out_char_info.name[index] == 0) { + break; + } + } + + out_char_info.font_region = region_information.character_set; + + out_char_info.faceline_type = appearance_bits1.face_shape; + out_char_info.faceline_color = appearance_bits1.skin_color; + out_char_info.faceline_wrinkle = appearance_bits2.wrinkles; + out_char_info.faceline_make = appearance_bits2.makeup; + + out_char_info.hair_type = hair_style; + out_char_info.hair_color = appearance_bits3.hair_color; + out_char_info.hair_flip = appearance_bits3.flip_hair; + + out_char_info.eye_type = static_cast(appearance_bits4.eye_type); + out_char_info.eye_color = static_cast(appearance_bits4.eye_color); + out_char_info.eye_scale = static_cast(appearance_bits4.eye_scale); + out_char_info.eye_aspect = static_cast(appearance_bits4.eye_vertical_stretch); + out_char_info.eye_rotate = static_cast(appearance_bits4.eye_rotation); + out_char_info.eye_x = static_cast(appearance_bits4.eye_spacing); + out_char_info.eye_y = static_cast(appearance_bits4.eye_y_position); + + out_char_info.eyebrow_type = static_cast(appearance_bits5.eyebrow_style); + out_char_info.eyebrow_color = static_cast(appearance_bits5.eyebrow_color); + out_char_info.eyebrow_scale = static_cast(appearance_bits5.eyebrow_scale); + out_char_info.eyebrow_aspect = static_cast(appearance_bits5.eyebrow_yscale); + out_char_info.eyebrow_rotate = static_cast(appearance_bits5.eyebrow_rotation); + out_char_info.eyebrow_x = static_cast(appearance_bits5.eyebrow_spacing); + out_char_info.eyebrow_y = static_cast(appearance_bits5.eyebrow_y_position); + + out_char_info.nose_type = static_cast(appearance_bits6.nose_type); + out_char_info.nose_scale = static_cast(appearance_bits6.nose_scale); + out_char_info.nose_y = static_cast(appearance_bits6.nose_y_position); + + out_char_info.mouth_type = static_cast(appearance_bits7.mouth_type); + out_char_info.mouth_color = static_cast(appearance_bits7.mouth_color); + out_char_info.mouth_scale = static_cast(appearance_bits7.mouth_scale); + out_char_info.mouth_aspect = static_cast(appearance_bits7.mouth_horizontal_stretch); + out_char_info.mouth_y = static_cast(appearance_bits8.mouth_y_position); + + out_char_info.mustache_type = static_cast(appearance_bits8.mustache_type); + out_char_info.mustache_scale = static_cast(appearance_bits9.mustache_scale); + out_char_info.mustache_y = static_cast(appearance_bits9.mustache_y_position); + + out_char_info.beard_type = static_cast(appearance_bits9.bear_type); + out_char_info.beard_color = static_cast(appearance_bits9.facial_hair_color); + + out_char_info.glasses_type = static_cast(appearance_bits10.glasses_type); + out_char_info.glasses_color = static_cast(appearance_bits10.glasses_color); + out_char_info.glasses_scale = static_cast(appearance_bits10.glasses_scale); + out_char_info.glasses_y = static_cast(appearance_bits10.glasses_y_position); + + out_char_info.mole_type = static_cast(appearance_bits11.mole_enabled); + out_char_info.mole_scale = static_cast(appearance_bits11.mole_scale); + out_char_info.mole_x = static_cast(appearance_bits11.mole_x_position); + out_char_info.mole_y = static_cast(appearance_bits11.mole_y_position); +} + +void Ver3StoreData::BuildFromStoreData(const CharInfo& char_info) { + version = 1; + mii_information.gender.Assign(char_info.gender); + mii_information.favorite_color.Assign(char_info.favorite_color); + height = char_info.height; + build = char_info.build; + + // Copy name until string terminator + mii_name = {}; + for (std::size_t index = 0; index < char_info.name.size() - 1; index++) { + mii_name[index] = char_info.name[index]; + if (mii_name[index] == 0) { + break; + } + } + + region_information.character_set.Assign(char_info.font_region); + + appearance_bits1.face_shape.Assign(char_info.faceline_type); + appearance_bits2.wrinkles.Assign(char_info.faceline_wrinkle); + appearance_bits2.makeup.Assign(char_info.faceline_make); + + hair_style = char_info.hair_type; + appearance_bits3.flip_hair.Assign(char_info.hair_flip); + + appearance_bits4.eye_type.Assign(char_info.eye_type); + appearance_bits4.eye_scale.Assign(char_info.eye_scale); + appearance_bits4.eye_vertical_stretch.Assign(char_info.eye_aspect); + appearance_bits4.eye_rotation.Assign(char_info.eye_rotate); + appearance_bits4.eye_spacing.Assign(char_info.eye_x); + appearance_bits4.eye_y_position.Assign(char_info.eye_y); + + appearance_bits5.eyebrow_style.Assign(char_info.eyebrow_type); + appearance_bits5.eyebrow_scale.Assign(char_info.eyebrow_scale); + appearance_bits5.eyebrow_yscale.Assign(char_info.eyebrow_aspect); + appearance_bits5.eyebrow_rotation.Assign(char_info.eyebrow_rotate); + appearance_bits5.eyebrow_spacing.Assign(char_info.eyebrow_x); + appearance_bits5.eyebrow_y_position.Assign(char_info.eyebrow_y); + + appearance_bits6.nose_type.Assign(char_info.nose_type); + appearance_bits6.nose_scale.Assign(char_info.nose_scale); + appearance_bits6.nose_y_position.Assign(char_info.nose_y); + + appearance_bits7.mouth_type.Assign(char_info.mouth_type); + appearance_bits7.mouth_scale.Assign(char_info.mouth_scale); + appearance_bits7.mouth_horizontal_stretch.Assign(char_info.mouth_aspect); + appearance_bits8.mouth_y_position.Assign(char_info.mouth_y); + + appearance_bits8.mustache_type.Assign(char_info.mustache_type); + appearance_bits9.mustache_scale.Assign(char_info.mustache_scale); + appearance_bits9.mustache_y_position.Assign(char_info.mustache_y); + + appearance_bits9.bear_type.Assign(char_info.beard_type); + + appearance_bits10.glasses_scale.Assign(char_info.glasses_scale); + appearance_bits10.glasses_y_position.Assign(char_info.glasses_y); + + appearance_bits11.mole_enabled.Assign(char_info.mole_type); + appearance_bits11.mole_scale.Assign(char_info.mole_scale); + appearance_bits11.mole_x_position.Assign(char_info.mole_x); + appearance_bits11.mole_y_position.Assign(char_info.mole_y); + + // These types are converted to V3 from a table + appearance_bits1.skin_color.Assign(RawData::FromVer3GetFacelineColor(char_info.faceline_color)); + appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(char_info.hair_color)); + appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(char_info.eye_color)); + appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(char_info.eyebrow_color)); + appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(char_info.mouth_color)); + appearance_bits9.facial_hair_color.Assign(RawData::FromVer3GetHairColor(char_info.beard_color)); + appearance_bits10.glasses_color.Assign(RawData::FromVer3GetGlassColor(char_info.glasses_color)); + appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(char_info.glasses_type)); + + crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); +} + +u32 Ver3StoreData::IsValid() const { + bool is_valid = version == 0 || version == 3; + + is_valid = is_valid && (mii_name[0] != 0); + + is_valid = is_valid && (mii_information.birth_month < 13); + is_valid = is_valid && (mii_information.birth_day < 32); + is_valid = is_valid && (mii_information.favorite_color < 12); + is_valid = is_valid && (height < 128); + is_valid = is_valid && (build < 128); + + is_valid = is_valid && (appearance_bits1.face_shape < 12); + is_valid = is_valid && (appearance_bits1.skin_color < 7); + is_valid = is_valid && (appearance_bits2.wrinkles < 12); + is_valid = is_valid && (appearance_bits2.makeup < 12); + + is_valid = is_valid && (hair_style < 132); + is_valid = is_valid && (appearance_bits3.hair_color < 8); + + is_valid = is_valid && (appearance_bits4.eye_type < 60); + is_valid = is_valid && (appearance_bits4.eye_color < 6); + is_valid = is_valid && (appearance_bits4.eye_scale < 8); + is_valid = is_valid && (appearance_bits4.eye_vertical_stretch < 7); + is_valid = is_valid && (appearance_bits4.eye_rotation < 8); + is_valid = is_valid && (appearance_bits4.eye_spacing < 13); + is_valid = is_valid && (appearance_bits4.eye_y_position < 19); + + is_valid = is_valid && (appearance_bits5.eyebrow_style < 25); + is_valid = is_valid && (appearance_bits5.eyebrow_color < 8); + is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9); + is_valid = is_valid && (appearance_bits5.eyebrow_yscale < 7); + is_valid = is_valid && (appearance_bits5.eyebrow_rotation < 12); + is_valid = is_valid && (appearance_bits5.eyebrow_spacing < 12); + is_valid = is_valid && (appearance_bits5.eyebrow_y_position < 19); + + is_valid = is_valid && (appearance_bits6.nose_type < 18); + is_valid = is_valid && (appearance_bits6.nose_scale < 9); + is_valid = is_valid && (appearance_bits6.nose_y_position < 19); + + is_valid = is_valid && (appearance_bits7.mouth_type < 36); + is_valid = is_valid && (appearance_bits7.mouth_color < 5); + is_valid = is_valid && (appearance_bits7.mouth_scale < 9); + is_valid = is_valid && (appearance_bits7.mouth_horizontal_stretch < 7); + is_valid = is_valid && (appearance_bits8.mouth_y_position < 19); + + is_valid = is_valid && (appearance_bits8.mustache_type < 6); + is_valid = is_valid && (appearance_bits9.mustache_scale < 7); + is_valid = is_valid && (appearance_bits9.mustache_y_position < 17); + + is_valid = is_valid && (appearance_bits9.bear_type < 6); + is_valid = is_valid && (appearance_bits9.facial_hair_color < 8); + + is_valid = is_valid && (appearance_bits10.glasses_type < 9); + is_valid = is_valid && (appearance_bits10.glasses_color < 6); + is_valid = is_valid && (appearance_bits10.glasses_scale < 8); + is_valid = is_valid && (appearance_bits10.glasses_y_position < 21); + + is_valid = is_valid && (appearance_bits11.mole_enabled < 2); + is_valid = is_valid && (appearance_bits11.mole_scale < 9); + is_valid = is_valid && (appearance_bits11.mole_x_position < 17); + is_valid = is_valid && (appearance_bits11.mole_y_position < 31); + + return is_valid; +} + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/ver3_store_data.h b/src/core/hle/service/mii/types/ver3_store_data.h index c3963548c7..6b4e1eb9cd 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.h +++ b/src/core/hle/service/mii/types/ver3_store_data.h @@ -4,10 +4,9 @@ #pragma once #include "core/hle/service/mii/mii_types.h" -#include "core/hle/service/mii/types/core_data.h" -#include "core/hle/service/mii/types/store_data.h" namespace Service::Mii { +class CharInfo; // This is nn::mii::Ver3StoreData // Based on citra HLE::Applets::MiiData and PretendoNetwork. @@ -15,7 +14,15 @@ namespace Service::Mii { // https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 #pragma pack(push, 4) -struct Ver3StoreData { +class Ver3StoreData { +public: + // TODO: This function is wrong. It should use StoreData. + void BuildToStoreData(CharInfo& out_char_info) const; + // TODO: This function is wrong. It should use StoreData. + void BuildFromStoreData(const CharInfo& char_info); + + u32 IsValid() const; + u8 version; union { u8 raw; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 44ac8cc716..5e61d2595e 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -834,7 +834,7 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe } SetAmiiboName(settings, register_info.amiibo_name); - tag_data.owner_mii = manager.BuildFromStoreData(mii); + tag_data.owner_mii.BuildFromStoreData(mii); tag_data.mii_extension = manager.SetFromStoreData(mii); tag_data.unknown = 0; tag_data.unknown2 = {}; @@ -1466,7 +1466,7 @@ void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); settings.settings.font_region.Assign(0); settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); - stubbed_tag_data.owner_mii = manager.BuildFromStoreData(manager.BuildBase(Mii::Gender::Male)); + stubbed_tag_data.owner_mii.BuildFromStoreData(manager.BuildBase(Mii::Gender::Male)); // Admin info settings.settings.amiibo_initialized.Assign(1); diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index adcaa8e84b..f96d212205 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -7,6 +7,7 @@ #include "common/swap.h" #include "core/hle/service/mii/types/char_info.h" +#include "core/hle/service/mii/types/store_data.h" #include "core/hle/service/mii/types/ver3_store_data.h" #include "core/hle/service/nfc/nfc_types.h"