From 0cdc8b13b743e4d7256d9337c7f01296cb98b7bd Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 20:43:26 -0600 Subject: [PATCH 01/11] service: mii: Add mii util and result --- src/core/CMakeLists.txt | 2 + src/core/hle/service/mii/mii.cpp | 11 ++--- src/core/hle/service/mii/mii_manager.cpp | 9 ++-- src/core/hle/service/mii/mii_result.h | 20 ++++++++ src/core/hle/service/mii/mii_util.h | 58 ++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 src/core/hle/service/mii/mii_result.h create mode 100644 src/core/hle/service/mii/mii_util.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 012648d69..e9095ac52 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -588,6 +588,8 @@ add_library(core STATIC hle/service/mii/mii.h hle/service/mii/mii_manager.cpp hle/service/mii/mii_manager.h + hle/service/mii/mii_result.h + hle/service/mii/mii_util.h hle/service/mii/raw_data.cpp hle/service/mii/raw_data.h hle/service/mii/types.h diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 65c11a2f3..bf3ee5907 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -7,13 +7,12 @@ #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/mii/mii.h" #include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/mii/mii_result.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" namespace Service::Mii { -constexpr Result ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1}; - class IDatabaseService final : public ServiceFramework { public: explicit IDatabaseService(Core::System& system_) @@ -162,21 +161,21 @@ private: if (age > Age::All) { IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); + rb.Push(ResultInvalidArgument); LOG_ERROR(Service_Mii, "invalid age={}", age); return; } if (gender > Gender::All) { IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); + rb.Push(ResultInvalidArgument); LOG_ERROR(Service_Mii, "invalid gender={}", gender); return; } if (race > Race::All) { IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); + rb.Push(ResultInvalidArgument); LOG_ERROR(Service_Mii, "invalid race={}", race); return; } @@ -196,7 +195,7 @@ private: LOG_ERROR(Service_Mii, "invalid argument, index cannot be greater than 5 but is {:08X}", index); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_INVALID_ARGUMENT); + rb.Push(ResultInvalidArgument); return; } diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index dd632df50..392aa78da 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -10,14 +10,13 @@ #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/mii/mii_result.h" #include "core/hle/service/mii/raw_data.h" namespace Service::Mii { namespace { -constexpr Result ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4}; - constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; constexpr MiiStoreData::Name DefaultMiiName{u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; @@ -410,11 +409,11 @@ u32 MiiManager::GetCount(SourceFlag source_flag) const { Result MiiManager::UpdateLatest(CharInfo* out_info, const CharInfo& info, SourceFlag source_flag) { if ((source_flag & SourceFlag::Database) == SourceFlag::None) { - return ERROR_CANNOT_FIND_ENTRY; + return ResultNotFound; } // TODO(bunnei): We don't implement the Mii database, so we can't have an entry - return ERROR_CANNOT_FIND_ENTRY; + return ResultNotFound; } CharInfo MiiManager::BuildRandom(Age age, Gender gender, Race race) { @@ -695,7 +694,7 @@ Result MiiManager::GetIndex([[maybe_unused]] const CharInfo& info, u32& index) { index = INVALID_INDEX; // TODO(bunnei): We don't implement the Mii database, so we can't have an index - return ERROR_CANNOT_FIND_ENTRY; + return ResultNotFound; } } // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii_result.h b/src/core/hle/service/mii/mii_result.h new file mode 100644 index 000000000..021cb76da --- /dev/null +++ b/src/core/hle/service/mii/mii_result.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/result.h" + +namespace Service::Mii { + +constexpr Result ResultInvalidArgument{ErrorModule::Mii, 1}; +constexpr Result ResultInvalidArgumentSize{ErrorModule::Mii, 2}; +constexpr Result ResultNotUpdated{ErrorModule::Mii, 3}; +constexpr Result ResultNotFound{ErrorModule::Mii, 4}; +constexpr Result ResultDatabaseFull{ErrorModule::Mii, 5}; +constexpr Result ResultInvalidCharInfo{ErrorModule::Mii, 100}; +constexpr Result ResultInvalidStoreData{ErrorModule::Mii, 109}; +constexpr Result ResultInvalidOperation{ErrorModule::Mii, 202}; +constexpr Result ResultPermissionDenied{ErrorModule::Mii, 203}; + +}; // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii_util.h b/src/core/hle/service/mii/mii_util.h new file mode 100644 index 000000000..5eb6df317 --- /dev/null +++ b/src/core/hle/service/mii/mii_util.h @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/common_types.h" +#include "common/swap.h" +#include "common/uuid.h" +#include "core/hle/service/mii/mii_types.h" + +namespace Service::Mii { +class MiiUtil { +public: + static u16 CalculateCrc16(const void* data, std::size_t size) { + s32 crc{}; + for (std::size_t i = 0; i < size; i++) { + crc ^= static_cast(data)[i] << 8; + for (std::size_t j = 0; j < 8; j++) { + crc <<= 1; + if ((crc & 0x10000) != 0) { + crc = (crc ^ 0x1021) & 0xFFFF; + } + } + } + return Common::swap16(static_cast(crc)); + } + + static Common::UUID MakeCreateId() { + return Common::UUID::MakeRandomRFC4122V4(); + } + + static Common::UUID GetDeviceId() { + // This should be nn::settings::detail::GetMiiAuthorId() + return Common::UUID::MakeDefault(); + } + + template + static T GetRandomValue(T min, T max) { + std::random_device device; + std::mt19937 gen(device()); + std::uniform_int_distribution distribution(static_cast(min), + static_cast(max)); + return static_cast(distribution(gen)); + } + + template + static T GetRandomValue(T max) { + return GetRandomValue({}, max); + } + + static bool IsFontRegionValid(FontRegion font, std::span text) { + // Todo:: This function needs to check against the font tables + return true; + } +}; +} // namespace Service::Mii From 63b239f5c6610bb1d3a31affce413951dd805e58 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 21:19:31 -0600 Subject: [PATCH 02/11] service: mii: Move all raw data to it's file --- src/core/hle/service/mii/mii_manager.cpp | 179 +++----- src/core/hle/service/mii/mii_util.h | 2 +- src/core/hle/service/mii/raw_data.cpp | 545 ++++++++++++++--------- src/core/hle/service/mii/raw_data.h | 70 ++- src/core/hle/service/mii/types.h | 62 +-- 5 files changed, 478 insertions(+), 380 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 392aa78da..de70c3da6 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -11,6 +11,7 @@ #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/mii/mii_manager.h" #include "core/hle/service/mii/mii_result.h" +#include "core/hle/service/mii/mii_util.h" #include "core/hle/service/mii/raw_data.h" namespace Service::Mii { @@ -19,19 +20,7 @@ namespace { constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; -constexpr MiiStoreData::Name DefaultMiiName{u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; -constexpr std::array HairColorLookup{8, 1, 2, 3, 4, 5, 6, 7}; -constexpr std::array EyeColorLookup{8, 9, 10, 11, 12, 13}; -constexpr std::array MouthColorLookup{19, 20, 21, 22, 23}; -constexpr std::array GlassesColorLookup{8, 14, 15, 16, 17, 18, 0}; -constexpr std::array EyeRotateLookup{ - {0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, - 0x04, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04, - 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04}}; -constexpr std::array EyebrowRotateLookup{{0x06, 0x06, 0x05, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x04, 0x07, 0x06, 0x08, 0x05, 0x05, 0x06, 0x06, - 0x07, 0x07, 0x06, 0x06, 0x05, 0x06, 0x07, 0x05}}; +constexpr Nickname DefaultMiiName{u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; template std::array ResizeArray(const std::array& in) { @@ -100,42 +89,15 @@ CharInfo ConvertStoreDataToInfo(const MiiStoreData& data) { }; } -u16 GenerateCrc16(const void* data, std::size_t size) { - s32 crc{}; - for (std::size_t i = 0; i < size; i++) { - crc ^= static_cast(data)[i] << 8; - for (std::size_t j = 0; j < 8; j++) { - crc <<= 1; - if ((crc & 0x10000) != 0) { - crc = (crc ^ 0x1021) & 0xFFFF; - } - } - } - return Common::swap16(static_cast(crc)); -} - -template -T GetRandomValue(T min, T max) { - std::random_device device; - std::mt19937 gen(device()); - std::uniform_int_distribution distribution(static_cast(min), static_cast(max)); - return static_cast(distribution(gen)); -} - -template -T GetRandomValue(T max) { - return GetRandomValue({}, max); -} - MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { MiiStoreBitFields bf{}; if (gender == Gender::All) { - gender = GetRandomValue(Gender::Maximum); + gender = MiiUtil::GetRandomValue(Gender::Maximum); } bf.gender.Assign(gender); - bf.favorite_color.Assign(GetRandomValue(11)); + bf.favorite_color.Assign(MiiUtil::GetRandomValue(11)); bf.region_move.Assign(0); bf.font_region.Assign(FontRegion::Standard); bf.type.Assign(0); @@ -143,7 +105,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.build.Assign(64); if (age == Age::All) { - const auto temp{GetRandomValue(10)}; + const auto temp{MiiUtil::GetRandomValue(10)}; if (temp >= 8) { age = Age::Old; } else if (temp >= 4) { @@ -154,7 +116,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo } if (race == Race::All) { - const auto temp{GetRandomValue(10)}; + const auto temp{MiiUtil::GetRandomValue(10)}; if (temp >= 8) { race = Race::Black; } else if (temp >= 4) { @@ -166,56 +128,57 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo u32 axis_y{}; if (gender == Gender::Female && age == Age::Young) { - axis_y = GetRandomValue(3); + axis_y = MiiUtil::GetRandomValue(3); } const std::size_t index{3 * static_cast(age) + 9 * static_cast(gender) + static_cast(race)}; - const auto faceline_type_info{RawData::RandomMiiFaceline.at(index)}; - const auto faceline_color_info{RawData::RandomMiiFacelineColor.at( + const auto& faceline_type_info{RawData::RandomMiiFaceline.at(index)}; + const auto& faceline_color_info{RawData::RandomMiiFacelineColor.at( 3 * static_cast(gender) + static_cast(race))}; - const auto faceline_wrinkle_info{RawData::RandomMiiFacelineWrinkle.at(index)}; - const auto faceline_makeup_info{RawData::RandomMiiFacelineMakeup.at(index)}; - const auto hair_type_info{RawData::RandomMiiHairType.at(index)}; - const auto hair_color_info{RawData::RandomMiiHairColor.at(3 * static_cast(race) + - static_cast(age))}; - const auto eye_type_info{RawData::RandomMiiEyeType.at(index)}; - const auto eye_color_info{RawData::RandomMiiEyeColor.at(static_cast(race))}; - const auto eyebrow_type_info{RawData::RandomMiiEyebrowType.at(index)}; - const auto nose_type_info{RawData::RandomMiiNoseType.at(index)}; - const auto mouth_type_info{RawData::RandomMiiMouthType.at(index)}; - const auto glasses_type_info{RawData::RandomMiiGlassType.at(static_cast(age))}; + const auto& faceline_wrinkle_info{RawData::RandomMiiFacelineWrinkle.at(index)}; + const auto& faceline_makeup_info{RawData::RandomMiiFacelineMakeup.at(index)}; + const auto& hair_type_info{RawData::RandomMiiHairType.at(index)}; + const auto& hair_color_info{RawData::RandomMiiHairColor.at(3 * static_cast(race) + + static_cast(age))}; + const auto& eye_type_info{RawData::RandomMiiEyeType.at(index)}; + const auto& eye_color_info{RawData::RandomMiiEyeColor.at(static_cast(race))}; + const auto& eyebrow_type_info{RawData::RandomMiiEyebrowType.at(index)}; + const auto& nose_type_info{RawData::RandomMiiNoseType.at(index)}; + const auto& mouth_type_info{RawData::RandomMiiMouthType.at(index)}; + const auto& glasses_type_info{RawData::RandomMiiGlassType.at(static_cast(age))}; bf.faceline_type.Assign( - faceline_type_info.values[GetRandomValue(faceline_type_info.values_count)]); + faceline_type_info + .values[MiiUtil::GetRandomValue(faceline_type_info.values_count)]); bf.faceline_color.Assign( - faceline_color_info.values[GetRandomValue(faceline_color_info.values_count)]); + faceline_color_info + .values[MiiUtil::GetRandomValue(faceline_color_info.values_count)]); bf.faceline_wrinkle.Assign( faceline_wrinkle_info - .values[GetRandomValue(faceline_wrinkle_info.values_count)]); + .values[MiiUtil::GetRandomValue(faceline_wrinkle_info.values_count)]); bf.faceline_makeup.Assign( faceline_makeup_info - .values[GetRandomValue(faceline_makeup_info.values_count)]); + .values[MiiUtil::GetRandomValue(faceline_makeup_info.values_count)]); bf.hair_type.Assign( - hair_type_info.values[GetRandomValue(hair_type_info.values_count)]); - bf.hair_color.Assign( - HairColorLookup[hair_color_info - .values[GetRandomValue(hair_color_info.values_count)]]); - bf.hair_flip.Assign(GetRandomValue(HairFlip::Maximum)); + hair_type_info.values[MiiUtil::GetRandomValue(hair_type_info.values_count)]); + bf.hair_color.Assign(RawData::GetHairColorFromVer3( + hair_color_info + .values[MiiUtil::GetRandomValue(hair_color_info.values_count)])); + bf.hair_flip.Assign(MiiUtil::GetRandomValue(HairFlip::Maximum)); bf.eye_type.Assign( - eye_type_info.values[GetRandomValue(eye_type_info.values_count)]); + eye_type_info.values[MiiUtil::GetRandomValue(eye_type_info.values_count)]); const auto eye_rotate_1{gender != Gender::Male ? 4 : 2}; const auto eye_rotate_2{gender != Gender::Male ? 3 : 4}; - const auto eye_rotate_offset{32 - EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; - const auto eye_rotate{32 - EyeRotateLookup[bf.eye_type]}; + const auto eye_rotate_offset{32 - RawData::EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; + const auto eye_rotate{32 - RawData::EyeRotateLookup[bf.eye_type]}; - bf.eye_color.Assign( - EyeColorLookup[eye_color_info - .values[GetRandomValue(eye_color_info.values_count)]]); + bf.eye_color.Assign(RawData::GetEyeColorFromVer3( + eye_color_info.values[MiiUtil::GetRandomValue(eye_color_info.values_count)])); bf.eye_scale.Assign(4); bf.eye_aspect.Assign(3); bf.eye_rotate.Assign(eye_rotate_offset - eye_rotate); @@ -223,13 +186,14 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.eye_y.Assign(axis_y + 12); bf.eyebrow_type.Assign( - eyebrow_type_info.values[GetRandomValue(eyebrow_type_info.values_count)]); + eyebrow_type_info + .values[MiiUtil::GetRandomValue(eyebrow_type_info.values_count)]); const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; const auto eyebrow_y{race == Race::Asian ? 9 : 10}; - const auto eyebrow_rotate_offset{32 - EyebrowRotateLookup[eyebrow_rotate_1] + 6}; + const auto eyebrow_rotate_offset{32 - RawData::EyebrowRotateLookup[eyebrow_rotate_1] + 6}; const auto eyebrow_rotate{ - 32 - EyebrowRotateLookup[static_cast(bf.eyebrow_type.Value())]}; + 32 - RawData::EyebrowRotateLookup[static_cast(bf.eyebrow_type.Value())]}; bf.eyebrow_color.Assign(bf.hair_color); bf.eyebrow_scale.Assign(4); @@ -241,15 +205,15 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo const auto nose_scale{gender == Gender::Female ? 3 : 4}; bf.nose_type.Assign( - nose_type_info.values[GetRandomValue(nose_type_info.values_count)]); + nose_type_info.values[MiiUtil::GetRandomValue(nose_type_info.values_count)]); bf.nose_scale.Assign(nose_scale); bf.nose_y.Assign(axis_y + 9); - const auto mouth_color{gender == Gender::Female ? GetRandomValue(4) : 0}; + const auto mouth_color{gender == Gender::Female ? MiiUtil::GetRandomValue(4) : 0}; bf.mouth_type.Assign( - mouth_type_info.values[GetRandomValue(mouth_type_info.values_count)]); - bf.mouth_color.Assign(MouthColorLookup[mouth_color]); + mouth_type_info.values[MiiUtil::GetRandomValue(mouth_type_info.values_count)]); + bf.mouth_color.Assign(RawData::GetMouthColorFromVer3(mouth_color)); bf.mouth_scale.Assign(4); bf.mouth_aspect.Assign(3); bf.mouth_y.Assign(axis_y + 13); @@ -257,22 +221,22 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.beard_color.Assign(bf.hair_color); bf.mustache_scale.Assign(4); - if (gender == Gender::Male && age != Age::Young && GetRandomValue(10) < 2) { + if (gender == Gender::Male && age != Age::Young && MiiUtil::GetRandomValue(10) < 2) { const auto mustache_and_beard_flag{ - GetRandomValue(BeardAndMustacheFlag::All)}; + MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; auto beard_type{BeardType::None}; auto mustache_type{MustacheType::None}; if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) == BeardAndMustacheFlag::Beard) { - beard_type = GetRandomValue(BeardType::Beard1, BeardType::Beard5); + beard_type = MiiUtil::GetRandomValue(BeardType::Beard1, BeardType::Beard5); } if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) == BeardAndMustacheFlag::Mustache) { - mustache_type = - GetRandomValue(MustacheType::Mustache1, MustacheType::Mustache5); + mustache_type = MiiUtil::GetRandomValue(MustacheType::Mustache1, + MustacheType::Mustache5); } bf.mustache_type.Assign(mustache_type); @@ -284,7 +248,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo bf.mustache_y.Assign(axis_y + 10); } - const auto glasses_type_start{GetRandomValue(100)}; + const auto glasses_type_start{MiiUtil::GetRandomValue(100)}; u8 glasses_type{}; while (glasses_type_start < glasses_type_info.values[glasses_type]) { if (++glasses_type >= glasses_type_info.values_count) { @@ -294,7 +258,7 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo } bf.glasses_type.Assign(glasses_type); - bf.glasses_color.Assign(GlassesColorLookup[0]); + bf.glasses_color.Assign(RawData::GetGlassColorFromVer3(0)); bf.glasses_scale.Assign(4); bf.glasses_y.Assign(axis_y + 10); @@ -315,23 +279,23 @@ MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& u bf.height.Assign(info.height); bf.build.Assign(info.weight); bf.type.Assign(info.type); - bf.region_move.Assign(info.region); + bf.region_move.Assign(info.region_move); bf.faceline_type.Assign(info.face_type); bf.faceline_color.Assign(info.face_color); bf.faceline_wrinkle.Assign(info.face_wrinkle); bf.faceline_makeup.Assign(info.face_makeup); bf.hair_type.Assign(info.hair_type); - bf.hair_color.Assign(HairColorLookup[info.hair_color]); + bf.hair_color.Assign(RawData::GetHairColorFromVer3(info.hair_color)); bf.hair_flip.Assign(static_cast(info.hair_flip)); bf.eye_type.Assign(info.eye_type); - bf.eye_color.Assign(EyeColorLookup[info.eye_color]); + bf.eye_color.Assign(RawData::GetEyeColorFromVer3(info.eye_color)); bf.eye_scale.Assign(info.eye_scale); bf.eye_aspect.Assign(info.eye_aspect); bf.eye_rotate.Assign(info.eye_rotate); bf.eye_x.Assign(info.eye_x); bf.eye_y.Assign(info.eye_y); bf.eyebrow_type.Assign(info.eyebrow_type); - bf.eyebrow_color.Assign(HairColorLookup[info.eyebrow_color]); + bf.eyebrow_color.Assign(RawData::GetHairColorFromVer3(info.eyebrow_color)); bf.eyebrow_scale.Assign(info.eyebrow_scale); bf.eyebrow_aspect.Assign(info.eyebrow_aspect); bf.eyebrow_rotate.Assign(info.eyebrow_rotate); @@ -341,17 +305,17 @@ MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& u bf.nose_scale.Assign(info.nose_scale); bf.nose_y.Assign(info.nose_y); bf.mouth_type.Assign(info.mouth_type); - bf.mouth_color.Assign(MouthColorLookup[info.mouth_color]); + bf.mouth_color.Assign(RawData::GetMouthColorFromVer3(info.mouth_color)); bf.mouth_scale.Assign(info.mouth_scale); bf.mouth_aspect.Assign(info.mouth_aspect); bf.mouth_y.Assign(info.mouth_y); - bf.beard_color.Assign(HairColorLookup[info.beard_color]); + bf.beard_color.Assign(RawData::GetHairColorFromVer3(info.beard_color)); bf.beard_type.Assign(static_cast(info.beard_type)); bf.mustache_type.Assign(static_cast(info.mustache_type)); bf.mustache_scale.Assign(info.mustache_scale); bf.mustache_y.Assign(info.mustache_y); bf.glasses_type.Assign(info.glasses_type); - bf.glasses_color.Assign(GlassesColorLookup[info.glasses_color]); + bf.glasses_color.Assign(RawData::GetGlassColorFromVer3(static_cast(info.glasses_color))); bf.glasses_scale.Assign(info.glasses_scale); bf.glasses_y.Assign(info.glasses_y); bf.mole_type.Assign(info.mole_type); @@ -366,14 +330,14 @@ MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& u MiiStoreData::MiiStoreData() = default; -MiiStoreData::MiiStoreData(const MiiStoreData::Name& name, const MiiStoreBitFields& bit_fields, +MiiStoreData::MiiStoreData(const Nickname& name, const MiiStoreBitFields& bit_fields, const Common::UUID& user_id) { data.name = name; data.uuid = Common::UUID::MakeRandomRFC4122V4(); std::memcpy(data.data.data(), &bit_fields, sizeof(MiiStoreBitFields)); - data_crc = GenerateCrc16(data.data.data(), sizeof(data)); - device_crc = GenerateCrc16(&user_id, sizeof(Common::UUID)); + data_crc = MiiUtil::CalculateCrc16(data.data.data(), sizeof(data)); + device_crc = MiiUtil::CalculateCrc16(&user_id, sizeof(Common::UUID)); } MiiManager::MiiManager() : user_id{Service::Account::ProfileManager().GetLastOpenedUser()} {} @@ -580,16 +544,19 @@ Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const { 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.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 = GenerateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16)); + mii_v3.crc = MiiUtil::CalculateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16)); // TODO: Validate mii_v3 data diff --git a/src/core/hle/service/mii/mii_util.h b/src/core/hle/service/mii/mii_util.h index 5eb6df317..d98f83825 100644 --- a/src/core/hle/service/mii/mii_util.h +++ b/src/core/hle/service/mii/mii_util.h @@ -8,7 +8,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "common/uuid.h" -#include "core/hle/service/mii/mii_types.h" +#include "core/hle/service/mii/types.h" namespace Service::Mii { class MiiUtil { diff --git a/src/core/hle/service/mii/raw_data.cpp b/src/core/hle/service/mii/raw_data.cpp index e5245b791..070e2d199 100644 --- a/src/core/hle/service/mii/raw_data.cpp +++ b/src/core/hle/service/mii/raw_data.cpp @@ -5,6 +5,83 @@ namespace Service::Mii::RawData { +constexpr std::array FromVer3FacelineColorTable{ + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, +}; + +constexpr std::array FromVer3HairColorTable{ + 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 FromVer3EyeColorTable{ + 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 FromVer3MouthlineColorTable{ + 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 FromVer3GlassColorTable{ + 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 FromVer3GlassTypeTable{ + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, + 0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7, +}; + +constexpr std::array Ver3FacelineColorTable{ + 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, +}; + +constexpr std::array Ver3HairColorTable{ + 0x8, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, +}; + +constexpr std::array Ver3EyeColorTable{ + 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, +}; + +constexpr std::array Ver3MouthColorTable{ + 0x13, 0x14, 0x15, 0x16, 0x17, +}; + +constexpr std::array Ver3GlassColorTable{ + 0x8, 0xe, 0xf, 0x10, 0x11, 0x12, 0x0, +}; + +const std::array EyeRotateLookup{ + 0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04, + 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04, +}; + +const std::array EyebrowRotateLookup{ + 0x06, 0x06, 0x05, 0x07, 0x06, 0x07, 0x06, 0x07, 0x04, 0x07, 0x06, 0x08, + 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x05, 0x06, 0x07, 0x05, +}; + const std::array BaseMii{ Service::Mii::DefaultMii{ .face_type = 0, @@ -13,7 +90,7 @@ const std::array BaseMii{ .face_makeup = 0, .hair_type = 33, .hair_color = 1, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -36,8 +113,8 @@ const std::array BaseMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -53,9 +130,10 @@ const std::array BaseMii{ .weight = 64, .gender = Gender::Male, .favorite_color = 0, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -64,7 +142,7 @@ const std::array BaseMii{ .face_makeup = 0, .hair_type = 12, .hair_color = 1, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -87,8 +165,8 @@ const std::array BaseMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -104,9 +182,10 @@ const std::array BaseMii{ .weight = 64, .gender = Gender::Female, .favorite_color = 0, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, }; @@ -118,7 +197,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 68, .hair_color = 0, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -141,8 +220,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -158,9 +237,10 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Male, .favorite_color = 4, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -169,7 +249,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 55, .hair_color = 6, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 2, .eye_color = 4, .eye_scale = 4, @@ -192,8 +272,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -209,9 +289,10 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Male, .favorite_color = 5, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -220,7 +301,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 33, .hair_color = 1, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -243,8 +324,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -260,9 +341,10 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Male, .favorite_color = 0, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -271,7 +353,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 24, .hair_color = 0, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -294,8 +376,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -311,9 +393,10 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Female, .favorite_color = 2, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -322,7 +405,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 14, .hair_color = 7, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 4, .eye_color = 5, .eye_scale = 4, @@ -345,8 +428,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -362,9 +445,10 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Female, .favorite_color = 6, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, Service::Mii::DefaultMii{ .face_type = 0, @@ -373,7 +457,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 12, .hair_color = 1, - .hair_flip = 0, + .hair_flip = HairFlip::Left, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -396,8 +480,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = 0, - .beard_type = 0, + .mustache_type = MustacheType::None, + .beard_type = BeardType::None, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -413,134 +497,135 @@ const std::array DefaultMii{ .weight = 64, .gender = Gender::Female, .favorite_color = 7, - .region = 0, + .region_move = 0, .font_region = FontRegion::Standard, .type = 0, + .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, }; -const std::array RandomMiiFaceline{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiFaceline{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, .values_count = 13, .values = {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 13, .values = {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -549,38 +634,38 @@ const std::array RandomMiiFaceline{ }, }; -const std::array RandomMiiFacelineColor{ - Service::Mii::RandomMiiData3{ +const std::array RandomMiiFacelineColor{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 0, .values_count = 10, .values = {2, 2, 4, 4, 4, 4, 5, 5, 5, 5}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 1, .values_count = 10, .values = {0, 0, 0, 0, 1, 1, 2, 3, 3, 3}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 2, .values_count = 10, .values = {0, 0, 1, 1, 1, 1, 1, 1, 1, 2}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 0, .values_count = 10, .values = {2, 2, 4, 4, 4, 4, 5, 5, 5, 5}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 1, .values_count = 10, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 3}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 2, .values_count = 10, @@ -588,127 +673,127 @@ const std::array RandomMiiFacelineColor{ }, }; -const std::array RandomMiiFacelineWrinkle{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiFacelineWrinkle{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4, 8, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4, 8, 8}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, .values_count = 20, .values = {9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, .values_count = 20, .values = {9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -717,127 +802,127 @@ const std::array RandomMiiFacelineWrinkle{ }, }; -const std::array RandomMiiFacelineMakeup{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiFacelineMakeup{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, .values_count = 20, .values = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -846,8 +931,8 @@ const std::array RandomMiiFacelineMakeup{ }, }; -const std::array RandomMiiHairType{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiHairType{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, @@ -855,7 +940,7 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 75, 76, 86, 89}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, @@ -863,7 +948,7 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 73, 75, 81, 86, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, @@ -871,7 +956,7 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 73, 75, 81, 86, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, @@ -879,7 +964,7 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 40, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 75, 76, 86, 89}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, @@ -887,7 +972,7 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 73, 75, 81, 86, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, @@ -895,28 +980,28 @@ const std::array RandomMiiHairType{ .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 73, 75, 81, 86, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 18, .values = {13, 23, 30, 36, 37, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 19, .values = {13, 23, 30, 36, 37, 39, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 19, .values = {13, 23, 30, 36, 37, 39, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, @@ -924,7 +1009,7 @@ const std::array RandomMiiHairType{ .values = {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 76, 77, 79, 80, 83, 85}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, @@ -933,7 +1018,7 @@ const std::array RandomMiiHairType{ 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 72, 74, 77, 78, 82, 83, 84, 85, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, @@ -942,7 +1027,7 @@ const std::array RandomMiiHairType{ 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 72, 74, 77, 78, 82, 83, 84, 85, 87}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, @@ -951,7 +1036,7 @@ const std::array RandomMiiHairType{ 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 42, 50, 58, 60, 62, 63, 64, 69, 71, 76, 79, 80, 81, 82, 83, 86}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, @@ -960,7 +1045,7 @@ const std::array RandomMiiHairType{ 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 50, 58, 60, 62, 63, 64, 69, 71, 72, 74, 79, 81, 82, 83, 84, 85}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, @@ -969,7 +1054,7 @@ const std::array RandomMiiHairType{ 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 50, 58, 60, 62, 63, 64, 69, 71, 72, 74, 79, 81, 82, 83, 84, 85}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, @@ -977,7 +1062,7 @@ const std::array RandomMiiHairType{ .values = {0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21, 24, 25, 58, 62, 69, 76, 83}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, @@ -985,7 +1070,7 @@ const std::array RandomMiiHairType{ .values = {0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21, 24, 25, 58, 62, 69, 74, 76, 81, 83, 85}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -996,55 +1081,55 @@ const std::array RandomMiiHairType{ }; const std::array RandomMiiHairColor{ - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 0, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 1, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 0, .arg_2 = 2, .values_count = 20, .values = {0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 0, .values_count = 20, .values = {2, 3, 3, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 1, .values_count = 20, .values = {2, 3, 3, 3, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 1, .arg_2 = 2, .values_count = 20, .values = {2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 2, .arg_2 = 0, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 2, .arg_2 = 1, .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 3}, }, - Service::Mii::RandomMiiData3{ + RandomMiiData3{ .arg_1 = 2, .arg_2 = 2, .values_count = 20, @@ -1052,8 +1137,8 @@ const std::array RandomMiiHairColor{ }, }; -const std::array RandomMiiEyeType{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiEyeType{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, @@ -1061,7 +1146,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 49, 51, 53, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, @@ -1069,7 +1154,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 49, 51, 53, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, @@ -1077,7 +1162,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 26, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 48, 49, 53, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, @@ -1085,7 +1170,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21, 22, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 49, 51, 53, 55, 56, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, @@ -1093,7 +1178,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21, 22, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 49, 51, 53, 55, 56, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, @@ -1101,7 +1186,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 21, 22, 26, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 48, 49, 50, 53, 56, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, @@ -1109,7 +1194,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 31, 32, 34, 36, 37, 39, 41, 44, 49, 51, 53, 55, 56, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, @@ -1117,7 +1202,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 31, 32, 34, 36, 37, 39, 41, 44, 49, 51, 53, 55, 56, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, @@ -1125,7 +1210,7 @@ const std::array RandomMiiEyeType{ .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 18, 21, 22, 26, 31, 32, 34, 36, 37, 39, 41, 44, 48, 49, 50, 51, 53, 57}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, @@ -1133,7 +1218,7 @@ const std::array RandomMiiEyeType{ .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, @@ -1141,7 +1226,7 @@ const std::array RandomMiiEyeType{ .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, @@ -1149,7 +1234,7 @@ const std::array RandomMiiEyeType{ .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, @@ -1158,7 +1243,7 @@ const std::array RandomMiiEyeType{ 18, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, @@ -1167,7 +1252,7 @@ const std::array RandomMiiEyeType{ 18, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, @@ -1176,7 +1261,7 @@ const std::array RandomMiiEyeType{ 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, @@ -1184,7 +1269,7 @@ const std::array RandomMiiEyeType{ .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, @@ -1192,7 +1277,7 @@ const std::array RandomMiiEyeType{ .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -1202,47 +1287,47 @@ const std::array RandomMiiEyeType{ }, }; -const std::array RandomMiiEyeColor{ - Service::Mii::RandomMiiData2{ +const std::array RandomMiiEyeColor{ + RandomMiiData2{ .arg_1 = 0, .values_count = 10, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, }, - Service::Mii::RandomMiiData2{ + RandomMiiData2{ .arg_1 = 1, .values_count = 10, .values = {0, 1, 1, 2, 3, 3, 4, 4, 4, 5}, }, - Service::Mii::RandomMiiData2{ + RandomMiiData2{ .arg_1 = 2, .values_count = 10, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, }, }; -const std::array RandomMiiEyebrowType{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiEyebrowType{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, @@ -1250,7 +1335,7 @@ const std::array RandomMiiEyebrowType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, @@ -1258,7 +1343,7 @@ const std::array RandomMiiEyebrowType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, @@ -1266,84 +1351,84 @@ const std::array RandomMiiEyebrowType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, .values_count = 9, .values = {0, 3, 7, 8, 9, 10, 11, 13, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, .values_count = 9, .values = {0, 3, 7, 8, 9, 10, 11, 13, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -1352,127 +1437,127 @@ const std::array RandomMiiEyebrowType{ }, }; -const std::array RandomMiiNoseType{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiNoseType{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, .values_count = 15, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, .values_count = 15, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, .values_count = 12, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 14, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, .values_count = 11, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, .values_count = 10, .values = {0, 1, 3, 4, 6, 8, 10, 11, 13, 14}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, .values_count = 12, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 14, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, .values_count = 11, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 15}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -1481,8 +1566,8 @@ const std::array RandomMiiNoseType{ }, }; -const std::array RandomMiiMouthType{ - Service::Mii::RandomMiiData4{ +const std::array RandomMiiMouthType{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Black, @@ -1490,7 +1575,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 32, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Black, @@ -1498,7 +1583,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 32, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Black, @@ -1506,7 +1591,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 31, 32, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::White, @@ -1514,7 +1599,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::White, @@ -1522,7 +1607,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::White, @@ -1530,7 +1615,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Young, .race = Race::Asian, @@ -1538,7 +1623,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Normal, .race = Race::Asian, @@ -1546,7 +1631,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Male, .age = Age::Old, .race = Race::Asian, @@ -1554,7 +1639,7 @@ const std::array RandomMiiMouthType{ .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Black, @@ -1562,7 +1647,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Black, @@ -1570,7 +1655,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Black, @@ -1578,7 +1663,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::White, @@ -1586,7 +1671,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 26, 27, 29, 33, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::White, @@ -1594,7 +1679,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 24, 26, 27, 29, 33, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::White, @@ -1602,7 +1687,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 29, 33, 35}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Young, .race = Race::Asian, @@ -1610,7 +1695,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 29, 33}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Normal, .race = Race::Asian, @@ -1618,7 +1703,7 @@ const std::array RandomMiiMouthType{ .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 29, 33}, }, - Service::Mii::RandomMiiData4{ + RandomMiiData4{ .gender = Gender::Female, .age = Age::Old, .race = Race::Asian, @@ -1628,22 +1713,66 @@ const std::array RandomMiiMouthType{ }, }; -const std::array RandomMiiGlassType{ - Service::Mii::RandomMiiData2{ +const std::array RandomMiiGlassType{ + RandomMiiData2{ .arg_1 = 0, .values_count = 9, .values = {90, 94, 96, 100, 0, 0, 0, 0, 0}, }, - Service::Mii::RandomMiiData2{ + RandomMiiData2{ .arg_1 = 1, .values_count = 9, .values = {83, 86, 90, 93, 94, 96, 98, 100, 0}, }, - Service::Mii::RandomMiiData2{ + RandomMiiData2{ .arg_1 = 2, .values_count = 9, .values = {78, 83, 0, 93, 0, 0, 98, 100, 0}, }, }; +u8 FromVer3GetFacelineColor(u8 color) { + return FromVer3FacelineColorTable[color]; +} + +u8 FromVer3GetHairColor(u8 color) { + return FromVer3HairColorTable[color]; +} + +u8 FromVer3GetEyeColor(u8 color) { + return FromVer3EyeColorTable[color]; +} + +u8 FromVer3GetMouthlineColor(u8 color) { + return FromVer3MouthlineColorTable[color]; +} + +u8 FromVer3GetGlassColor(u8 color) { + return FromVer3GlassColorTable[color]; +} + +u8 FromVer3GetGlassType(u8 type) { + return FromVer3GlassTypeTable[type]; +} + +u8 GetFacelineColorFromVer3(u8 color) { + return Ver3FacelineColorTable[color]; +} + +u8 GetHairColorFromVer3(u32 color) { + return Ver3HairColorTable[color]; +} + +u8 GetEyeColorFromVer3(u32 color) { + return Ver3EyeColorTable[color]; +} + +u8 GetMouthColorFromVer3(u32 color) { + return Ver3MouthColorTable[color]; +} + +u8 GetGlassColorFromVer3(u8 color) { + return Ver3GlassColorTable[color]; +} + } // namespace Service::Mii::RawData diff --git a/src/core/hle/service/mii/raw_data.h b/src/core/hle/service/mii/raw_data.h index cdd2337d6..ab84d09a1 100644 --- a/src/core/hle/service/mii/raw_data.h +++ b/src/core/hle/service/mii/raw_data.h @@ -9,19 +9,65 @@ namespace Service::Mii::RawData { +struct RandomMiiValues { + std::array values{}; +}; +static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); + +struct RandomMiiData4 { + Gender gender{}; + Age age{}; + Race race{}; + u32 values_count{}; + std::array values{}; +}; +static_assert(sizeof(RandomMiiData4) == 0xcc, "RandomMiiData4 has incorrect size."); + +struct RandomMiiData3 { + u32 arg_1; + u32 arg_2; + u32 values_count; + std::array values{}; +}; +static_assert(sizeof(RandomMiiData3) == 0xc8, "RandomMiiData3 has incorrect size."); + +struct RandomMiiData2 { + u32 arg_1; + u32 values_count; + std::array values{}; +}; +static_assert(sizeof(RandomMiiData2) == 0xc4, "RandomMiiData2 has incorrect size."); + extern const std::array BaseMii; extern const std::array DefaultMii; -extern const std::array RandomMiiFaceline; -extern const std::array RandomMiiFacelineColor; -extern const std::array RandomMiiFacelineWrinkle; -extern const std::array RandomMiiFacelineMakeup; -extern const std::array RandomMiiHairType; -extern const std::array RandomMiiHairColor; -extern const std::array RandomMiiEyeType; -extern const std::array RandomMiiEyeColor; -extern const std::array RandomMiiEyebrowType; -extern const std::array RandomMiiNoseType; -extern const std::array RandomMiiMouthType; -extern const std::array RandomMiiGlassType; + +extern const std::array EyeRotateLookup; +extern const std::array EyebrowRotateLookup; + +extern const std::array RandomMiiFaceline; +extern const std::array RandomMiiFacelineColor; +extern const std::array RandomMiiFacelineWrinkle; +extern const std::array RandomMiiFacelineMakeup; +extern const std::array RandomMiiHairType; +extern const std::array RandomMiiHairColor; +extern const std::array RandomMiiEyeType; +extern const std::array RandomMiiEyeColor; +extern const std::array RandomMiiEyebrowType; +extern const std::array RandomMiiNoseType; +extern const std::array RandomMiiMouthType; +extern const std::array RandomMiiGlassType; + +u8 FromVer3GetFacelineColor(u8 color); +u8 FromVer3GetHairColor(u8 color); +u8 FromVer3GetEyeColor(u8 color); +u8 FromVer3GetMouthlineColor(u8 color); +u8 FromVer3GetGlassColor(u8 color); +u8 FromVer3GetGlassType(u8 type); + +u8 GetFacelineColorFromVer3(u8 color); +u8 GetHairColorFromVer3(u32 color); +u8 GetEyeColorFromVer3(u32 color); +u8 GetMouthColorFromVer3(u32 color); +u8 GetGlassColorFromVer3(u8 color); } // namespace Service::Mii::RawData diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h index c48d08d79..cc8286189 100644 --- a/src/core/hle/service/mii/types.h +++ b/src/core/hle/service/mii/types.h @@ -86,6 +86,8 @@ enum class SourceFlag : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); +using Nickname = std::array; + // nn::mii::CharInfo struct CharInfo { Common::UUID uuid; @@ -382,56 +384,10 @@ struct NfpStoreDataExtension { }; static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); -constexpr std::array Ver3FacelineColorTable{ - 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, -}; - -constexpr std::array 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 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 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 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 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; MiiStoreData(); - MiiStoreData(const Name& name, const MiiStoreBitFields& bit_fields, + MiiStoreData(const Nickname& name, const MiiStoreBitFields& bit_fields, const Common::UUID& user_id); // This corresponds to the above structure MiiStoreBitFields. I did it like this because the @@ -441,7 +397,7 @@ struct MiiStoreData { std::array data{}; static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size."); - Name name{}; + Nickname name{}; Common::UUID uuid{}; } data; @@ -501,7 +457,7 @@ struct DefaultMii { u32 face_makeup{}; u32 hair_type{}; u32 hair_color{}; - u32 hair_flip{}; + HairFlip hair_flip{}; u32 eye_type{}; u32 eye_color{}; u32 eye_scale{}; @@ -524,8 +480,8 @@ struct DefaultMii { u32 mouth_scale{}; u32 mouth_aspect{}; u32 mouth_y{}; - u32 mustache_type{}; - u32 beard_type{}; + MustacheType mustache_type{}; + BeardType beard_type{}; u32 beard_color{}; u32 mustache_scale{}; u32 mustache_y{}; @@ -541,10 +497,10 @@ struct DefaultMii { u32 weight{}; Gender gender{}; u32 favorite_color{}; - u32 region{}; + u32 region_move{}; FontRegion font_region{}; u32 type{}; - INSERT_PADDING_WORDS(5); + Nickname nickname; }; static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); From 27929d7ca2b5fffc8866941d08cda921d586c45d Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 21:58:18 -0600 Subject: [PATCH 03/11] service: mii: separate mii types into their own file --- src/core/CMakeLists.txt | 14 +- .../am/applets/applet_mii_edit_types.h | 3 +- src/core/hle/service/mii/mii.cpp | 2 +- src/core/hle/service/mii/mii_manager.cpp | 38 +- src/core/hle/service/mii/mii_manager.h | 16 +- src/core/hle/service/mii/mii_types.h | 157 ++++++ src/core/hle/service/mii/mii_util.h | 4 +- src/core/hle/service/mii/types.h | 509 ------------------ src/core/hle/service/mii/types/char_info.cpp | 6 + src/core/hle/service/mii/types/char_info.h | 76 +++ src/core/hle/service/mii/types/core_data.cpp | 6 + src/core/hle/service/mii/types/core_data.h | 105 ++++ .../hle/service/mii/{ => types}/raw_data.cpp | 2 +- .../hle/service/mii/{ => types}/raw_data.h | 2 +- src/core/hle/service/mii/types/store_data.cpp | 6 + src/core/hle/service/mii/types/store_data.h | 29 + .../hle/service/mii/types/ver3_store_data.cpp | 6 + .../hle/service/mii/types/ver3_store_data.h | 141 +++++ src/core/hle/service/nfc/common/device.cpp | 1 - src/core/hle/service/nfp/nfp_types.h | 5 +- 20 files changed, 586 insertions(+), 542 deletions(-) create mode 100644 src/core/hle/service/mii/mii_types.h delete mode 100644 src/core/hle/service/mii/types.h create mode 100644 src/core/hle/service/mii/types/char_info.cpp create mode 100644 src/core/hle/service/mii/types/char_info.h create mode 100644 src/core/hle/service/mii/types/core_data.cpp create mode 100644 src/core/hle/service/mii/types/core_data.h rename src/core/hle/service/mii/{ => types}/raw_data.cpp (99%) rename src/core/hle/service/mii/{ => types}/raw_data.h (98%) create mode 100644 src/core/hle/service/mii/types/store_data.cpp create mode 100644 src/core/hle/service/mii/types/store_data.h create mode 100644 src/core/hle/service/mii/types/ver3_store_data.cpp create mode 100644 src/core/hle/service/mii/types/ver3_store_data.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index e9095ac52..c33910ade 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -584,15 +584,23 @@ add_library(core STATIC hle/service/lm/lm.h hle/service/mig/mig.cpp hle/service/mig/mig.h + hle/service/mii/types/char_info.cpp + hle/service/mii/types/char_info.h + hle/service/mii/types/core_data.cpp + hle/service/mii/types/core_data.h + hle/service/mii/types/raw_data.cpp + hle/service/mii/types/raw_data.h + hle/service/mii/types/store_data.cpp + hle/service/mii/types/store_data.h + hle/service/mii/types/ver3_store_data.cpp + hle/service/mii/types/ver3_store_data.h hle/service/mii/mii.cpp hle/service/mii/mii.h hle/service/mii/mii_manager.cpp hle/service/mii/mii_manager.h hle/service/mii/mii_result.h + hle/service/mii/mii_types.h hle/service/mii/mii_util.h - hle/service/mii/raw_data.cpp - hle/service/mii/raw_data.h - hle/service/mii/types.h hle/service/mm/mm_u.cpp hle/service/mm/mm_u.h hle/service/mnpp/mnpp_app.cpp diff --git a/src/core/hle/service/am/applets/applet_mii_edit_types.h b/src/core/hle/service/am/applets/applet_mii_edit_types.h index 4705d019f..f3d764073 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit_types.h +++ b/src/core/hle/service/am/applets/applet_mii_edit_types.h @@ -7,7 +7,8 @@ #include "common/common_funcs.h" #include "common/common_types.h" -#include "core/hle/service/mii/types.h" +#include "common/uuid.h" +#include "core/hle/service/mii/types/char_info.h" namespace Service::AM::Applets { diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index bf3ee5907..680f06beb 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -120,7 +120,7 @@ private: std::vector values; for (const auto& element : default_miis) { - values.emplace_back(element.info); + values.emplace_back(element.char_info); } ctx.WriteBuffer(SerializeArray(values)); diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index de70c3da6..035eed505 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -12,7 +12,8 @@ #include "core/hle/service/mii/mii_manager.h" #include "core/hle/service/mii/mii_result.h" #include "core/hle/service/mii/mii_util.h" -#include "core/hle/service/mii/raw_data.h" +#include "core/hle/service/mii/types/core_data.h" +#include "core/hle/service/mii/types/raw_data.h" namespace Service::Mii { @@ -29,13 +30,12 @@ std::array ResizeArray(const std::array& i return out; } -CharInfo ConvertStoreDataToInfo(const MiiStoreData& data) { - MiiStoreBitFields bf; - std::memcpy(&bf, data.data.data.data(), sizeof(MiiStoreBitFields)); +CharInfo ConvertStoreDataToInfo(const StoreData& data) { + const StoreDataBitFields& bf = data.core_data.data; return { - .uuid = data.data.uuid, - .name = ResizeArray(data.data.name), + .create_id = data.create_id, + .name = data.core_data.name, .font_region = static_cast(bf.font_region.Value()), .favorite_color = static_cast(bf.favorite_color.Value()), .gender = static_cast(bf.gender.Value()), @@ -89,8 +89,8 @@ CharInfo ConvertStoreDataToInfo(const MiiStoreData& data) { }; } -MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { - MiiStoreBitFields bf{}; +StoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { + StoreDataBitFields bf{}; if (gender == Gender::All) { gender = MiiUtil::GetRandomValue(Gender::Maximum); @@ -270,8 +270,8 @@ MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Commo return {DefaultMiiName, bf, user_id}; } -MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) { - MiiStoreBitFields bf{}; +StoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) { + StoreDataBitFields bf{}; bf.font_region.Assign(info.font_region); bf.favorite_color.Assign(info.favorite_color); @@ -328,15 +328,15 @@ MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& u } // namespace -MiiStoreData::MiiStoreData() = default; +StoreData::StoreData() = default; -MiiStoreData::MiiStoreData(const Nickname& name, const MiiStoreBitFields& bit_fields, - const Common::UUID& user_id) { - data.name = name; - data.uuid = Common::UUID::MakeRandomRFC4122V4(); +StoreData::StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, + const Common::UUID& user_id) { + core_data.name = name; + create_id = Common::UUID::MakeRandomRFC4122V4(); - std::memcpy(data.data.data(), &bit_fields, sizeof(MiiStoreBitFields)); - data_crc = MiiUtil::CalculateCrc16(data.data.data(), sizeof(data)); + core_data.data = bit_fields; + data_crc = MiiUtil::CalculateCrc16(&core_data.data, sizeof(core_data.data)); device_crc = MiiUtil::CalculateCrc16(&user_id, sizeof(Common::UUID)); } @@ -641,8 +641,8 @@ bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const { return is_valid; } -std::vector MiiManager::GetDefault(SourceFlag source_flag) { - std::vector result; +std::vector MiiManager::GetDefault(SourceFlag source_flag) { + std::vector result; if ((source_flag & SourceFlag::Default) == SourceFlag::None) { return result; diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h index 0c8295ebe..1f5c9e16f 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h @@ -6,7 +6,10 @@ #include #include "core/hle/result.h" -#include "core/hle/service/mii/types.h" +#include "core/hle/service/mii/mii_types.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" namespace Service::Mii { @@ -25,7 +28,7 @@ public: 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); + std::vector GetDefault(SourceFlag source_flag); Result GetIndex(const CharInfo& info, u32& index); // This is nn::mii::detail::Ver::StoreDataRaw::BuildFromStoreData @@ -34,6 +37,15 @@ public: // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const; + struct MiiDatabase { + u32 magic{}; // 'NFDB' + std::array miis{}; + INSERT_PADDING_BYTES(1); + u8 count{}; + u16 crc{}; + }; + static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size."); + private: const Common::UUID user_id{}; u64 update_counter{}; diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h new file mode 100644 index 000000000..ff836dcf2 --- /dev/null +++ b/src/core/hle/service/mii/mii_types.h @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include "common/bit_field.h" +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/uuid.h" + +namespace Service::Mii { + +enum class Age : u32 { + Young, + Normal, + Old, + All, +}; + +enum class BeardType : u32 { + None, + Beard1, + Beard2, + Beard3, + Beard4, + Beard5, +}; + +enum class BeardAndMustacheFlag : u32 { + Beard = 1, + Mustache, + All = Beard | Mustache, +}; +DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag); + +enum class FontRegion : u32 { + Standard, + China, + Korea, + Taiwan, +}; + +enum class Gender : u32 { + Male, + Female, + All, + Maximum = Female, +}; + +enum class HairFlip : u32 { + Left, + Right, + Maximum = Right, +}; + +enum class MustacheType : u32 { + None, + Mustache1, + Mustache2, + Mustache3, + Mustache4, + Mustache5, +}; + +enum class Race : u32 { + Black, + White, + Asian, + All, +}; + +enum class Source : u32 { + Database = 0, + Default = 1, + Account = 2, + Friend = 3, +}; + +enum class SourceFlag : u32 { + None = 0, + Database = 1 << 0, + Default = 1 << 1, +}; +DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); + +using Nickname = std::array; + +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"); + +struct DefaultMii { + u32 face_type{}; + u32 face_color{}; + u32 face_wrinkle{}; + u32 face_makeup{}; + u32 hair_type{}; + u32 hair_color{}; + HairFlip hair_flip{}; + u32 eye_type{}; + u32 eye_color{}; + u32 eye_scale{}; + u32 eye_aspect{}; + u32 eye_rotate{}; + u32 eye_x{}; + u32 eye_y{}; + u32 eyebrow_type{}; + u32 eyebrow_color{}; + u32 eyebrow_scale{}; + u32 eyebrow_aspect{}; + u32 eyebrow_rotate{}; + u32 eyebrow_x{}; + u32 eyebrow_y{}; + u32 nose_type{}; + u32 nose_scale{}; + u32 nose_y{}; + u32 mouth_type{}; + u32 mouth_color{}; + u32 mouth_scale{}; + u32 mouth_aspect{}; + u32 mouth_y{}; + MustacheType mustache_type{}; + BeardType beard_type{}; + u32 beard_color{}; + u32 mustache_scale{}; + u32 mustache_y{}; + u32 glasses_type{}; + u32 glasses_color{}; + u32 glasses_scale{}; + u32 glasses_y{}; + u32 mole_type{}; + u32 mole_scale{}; + u32 mole_x{}; + u32 mole_y{}; + u32 height{}; + u32 weight{}; + Gender gender{}; + u32 favorite_color{}; + u32 region_move{}; + FontRegion font_region{}; + u32 type{}; + Nickname nickname; +}; +static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii_util.h b/src/core/hle/service/mii/mii_util.h index d98f83825..782ffe22f 100644 --- a/src/core/hle/service/mii/mii_util.h +++ b/src/core/hle/service/mii/mii_util.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -8,7 +8,7 @@ #include "common/common_types.h" #include "common/swap.h" #include "common/uuid.h" -#include "core/hle/service/mii/types.h" +#include "core/hle/service/mii/mii_types.h" namespace Service::Mii { class MiiUtil { diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h deleted file mode 100644 index cc8286189..000000000 --- a/src/core/hle/service/mii/types.h +++ /dev/null @@ -1,509 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "common/bit_field.h" -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/uuid.h" - -namespace Service::Mii { - -enum class Age : u32 { - Young, - Normal, - Old, - All, -}; - -enum class BeardType : u32 { - None, - Beard1, - Beard2, - Beard3, - Beard4, - Beard5, -}; - -enum class BeardAndMustacheFlag : u32 { - Beard = 1, - Mustache, - All = Beard | Mustache, -}; -DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag); - -enum class FontRegion : u32 { - Standard, - China, - Korea, - Taiwan, -}; - -enum class Gender : u32 { - Male, - Female, - All, - Maximum = Female, -}; - -enum class HairFlip : u32 { - Left, - Right, - Maximum = Right, -}; - -enum class MustacheType : u32 { - None, - Mustache1, - Mustache2, - Mustache3, - Mustache4, - Mustache5, -}; - -enum class Race : u32 { - Black, - White, - Asian, - All, -}; - -enum class Source : u32 { - Database = 0, - Default = 1, - Account = 2, - Friend = 3, -}; - -enum class SourceFlag : u32 { - None = 0, - Database = 1 << 0, - Default = 1 << 1, -}; -DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); - -using Nickname = std::array; - -// nn::mii::CharInfo -struct CharInfo { - Common::UUID uuid; - std::array name; - u8 font_region; - u8 favorite_color; - u8 gender; - u8 height; - u8 build; - u8 type; - u8 region_move; - u8 faceline_type; - u8 faceline_color; - u8 faceline_wrinkle; - u8 faceline_make; - u8 hair_type; - u8 hair_color; - u8 hair_flip; - u8 eye_type; - u8 eye_color; - u8 eye_scale; - u8 eye_aspect; - u8 eye_rotate; - u8 eye_x; - u8 eye_y; - u8 eyebrow_type; - u8 eyebrow_color; - u8 eyebrow_scale; - u8 eyebrow_aspect; - u8 eyebrow_rotate; - u8 eyebrow_x; - u8 eyebrow_y; - u8 nose_type; - u8 nose_scale; - u8 nose_y; - u8 mouth_type; - u8 mouth_color; - u8 mouth_scale; - u8 mouth_aspect; - u8 mouth_y; - u8 beard_color; - u8 beard_type; - u8 mustache_type; - u8 mustache_scale; - u8 mustache_y; - u8 glasses_type; - u8 glasses_color; - u8 glasses_scale; - u8 glasses_y; - u8 mole_type; - u8 mole_scale; - u8 mole_x; - u8 mole_y; - u8 padding; -}; -static_assert(sizeof(CharInfo) == 0x58, "CharInfo has incorrect size."); -static_assert(std::has_unique_object_representations_v, - "All bits of CharInfo must contribute to its value."); - -#pragma pack(push, 4) - -struct MiiInfoElement { - MiiInfoElement(const CharInfo& info_, Source source_) : info{info_}, source{source_} {} - - CharInfo info{}; - Source source{}; -}; -static_assert(sizeof(MiiInfoElement) == 0x5c, "MiiInfoElement has incorrect size."); - -struct MiiStoreBitFields { - union { - u32 word_0{}; - - BitField<0, 8, u32> hair_type; - BitField<8, 7, u32> height; - BitField<15, 1, u32> mole_type; - BitField<16, 7, u32> build; - BitField<23, 1, HairFlip> hair_flip; - BitField<24, 7, u32> hair_color; - BitField<31, 1, u32> type; - }; - - union { - u32 word_1{}; - - BitField<0, 7, u32> eye_color; - BitField<7, 1, Gender> gender; - BitField<8, 7, u32> eyebrow_color; - BitField<16, 7, u32> mouth_color; - BitField<24, 7, u32> beard_color; - }; - - union { - u32 word_2{}; - - BitField<0, 7, u32> glasses_color; - BitField<8, 6, u32> eye_type; - BitField<14, 2, u32> region_move; - BitField<16, 6, u32> mouth_type; - BitField<22, 2, FontRegion> font_region; - BitField<24, 5, u32> eye_y; - BitField<29, 3, u32> glasses_scale; - }; - - union { - u32 word_3{}; - - BitField<0, 5, u32> eyebrow_type; - BitField<5, 3, MustacheType> mustache_type; - BitField<8, 5, u32> nose_type; - BitField<13, 3, BeardType> beard_type; - BitField<16, 5, u32> nose_y; - BitField<21, 3, u32> mouth_aspect; - BitField<24, 5, u32> mouth_y; - BitField<29, 3, u32> eyebrow_aspect; - }; - - union { - u32 word_4{}; - - BitField<0, 5, u32> mustache_y; - BitField<5, 3, u32> eye_rotate; - BitField<8, 5, u32> glasses_y; - BitField<13, 3, u32> eye_aspect; - BitField<16, 5, u32> mole_x; - BitField<21, 3, u32> eye_scale; - BitField<24, 5, u32> mole_y; - }; - - union { - u32 word_5{}; - - BitField<0, 5, u32> glasses_type; - BitField<8, 4, u32> favorite_color; - BitField<12, 4, u32> faceline_type; - BitField<16, 4, u32> faceline_color; - BitField<20, 4, u32> faceline_wrinkle; - BitField<24, 4, u32> faceline_makeup; - BitField<28, 4, u32> eye_x; - }; - - union { - u32 word_6{}; - - BitField<0, 4, u32> eyebrow_scale; - BitField<4, 4, u32> eyebrow_rotate; - BitField<8, 4, u32> eyebrow_x; - BitField<12, 4, u32> eyebrow_y; - BitField<16, 4, u32> nose_scale; - BitField<20, 4, u32> mouth_scale; - BitField<24, 4, u32> mustache_scale; - BitField<28, 4, u32> mole_scale; - }; -}; -static_assert(sizeof(MiiStoreBitFields) == 0x1c, "MiiStoreBitFields has incorrect size."); -static_assert(std::is_trivially_copyable_v, - "MiiStoreBitFields is not trivially copyable."); - -// This is nn::mii::Ver3StoreData -// Based on citra HLE::Applets::MiiData and PretendoNetwork. -// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 -// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 -struct Ver3StoreData { - u8 version; - union { - u8 raw; - - BitField<0, 1, u8> allow_copying; - BitField<1, 1, u8> profanity_flag; - BitField<2, 2, u8> region_lock; - BitField<4, 2, u8> character_set; - } region_information; - u16_be mii_id; - u64_be system_id; - u32_be specialness_and_creation_date; - std::array creator_mac; - u16_be padding; - union { - u16 raw; - - BitField<0, 1, u16> gender; - BitField<1, 4, u16> birth_month; - BitField<5, 5, u16> birth_day; - BitField<10, 4, u16> favorite_color; - BitField<14, 1, u16> favorite; - } mii_information; - std::array mii_name; - u8 height; - u8 build; - union { - u8 raw; - - BitField<0, 1, u8> disable_sharing; - BitField<1, 4, u8> face_shape; - BitField<5, 3, u8> skin_color; - } appearance_bits1; - union { - u8 raw; - - BitField<0, 4, u8> wrinkles; - BitField<4, 4, u8> makeup; - } appearance_bits2; - u8 hair_style; - union { - u8 raw; - - BitField<0, 3, u8> hair_color; - BitField<3, 1, u8> flip_hair; - } appearance_bits3; - union { - u32 raw; - - BitField<0, 6, u32> eye_type; - BitField<6, 3, u32> eye_color; - BitField<9, 4, u32> eye_scale; - BitField<13, 3, u32> eye_vertical_stretch; - BitField<16, 5, u32> eye_rotation; - BitField<21, 4, u32> eye_spacing; - BitField<25, 5, u32> eye_y_position; - } appearance_bits4; - union { - u32 raw; - - BitField<0, 5, u32> eyebrow_style; - BitField<5, 3, u32> eyebrow_color; - BitField<8, 4, u32> eyebrow_scale; - BitField<12, 3, u32> eyebrow_yscale; - BitField<16, 4, u32> eyebrow_rotation; - BitField<21, 4, u32> eyebrow_spacing; - BitField<25, 5, u32> eyebrow_y_position; - } appearance_bits5; - union { - u16 raw; - - BitField<0, 5, u16> nose_type; - BitField<5, 4, u16> nose_scale; - BitField<9, 5, u16> nose_y_position; - } appearance_bits6; - union { - u16 raw; - - BitField<0, 6, u16> mouth_type; - BitField<6, 3, u16> mouth_color; - BitField<9, 4, u16> mouth_scale; - BitField<13, 3, u16> mouth_horizontal_stretch; - } appearance_bits7; - union { - u8 raw; - - BitField<0, 5, u8> mouth_y_position; - BitField<5, 3, u8> mustache_type; - } appearance_bits8; - u8 allow_copying; - union { - u16 raw; - - BitField<0, 3, u16> bear_type; - BitField<3, 3, u16> facial_hair_color; - BitField<6, 4, u16> mustache_scale; - BitField<10, 5, u16> mustache_y_position; - } appearance_bits9; - union { - u16 raw; - - BitField<0, 4, u16> glasses_type; - BitField<4, 3, u16> glasses_color; - BitField<7, 4, u16> glasses_scale; - BitField<11, 5, u16> glasses_y_position; - } appearance_bits10; - union { - u16 raw; - - BitField<0, 1, u16> mole_enabled; - BitField<1, 4, u16> mole_scale; - BitField<5, 5, u16> mole_x_position; - BitField<10, 5, u16> mole_y_position; - } appearance_bits11; - - std::array author_name; - 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"); - -struct MiiStoreData { - - MiiStoreData(); - MiiStoreData(const Nickname& name, const MiiStoreBitFields& bit_fields, - const Common::UUID& user_id); - - // This corresponds to the above structure MiiStoreBitFields. I did it like this because the - // BitField<> type makes this (and any thing that contains it) not trivially copyable, which is - // not suitable for our uses. - struct { - std::array data{}; - static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size."); - - Nickname name{}; - Common::UUID uuid{}; - } data; - - u16 data_crc{}; - u16 device_crc{}; -}; -static_assert(sizeof(MiiStoreData) == 0x44, "MiiStoreData has incorrect size."); - -struct MiiStoreDataElement { - MiiStoreData data{}; - Source source{}; -}; -static_assert(sizeof(MiiStoreDataElement) == 0x48, "MiiStoreDataElement has incorrect size."); - -struct MiiDatabase { - u32 magic{}; // 'NFDB' - std::array miis{}; - INSERT_PADDING_BYTES(1); - u8 count{}; - u16 crc{}; -}; -static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size."); - -struct RandomMiiValues { - std::array values{}; -}; -static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); - -struct RandomMiiData4 { - Gender gender{}; - Age age{}; - Race race{}; - u32 values_count{}; - std::array values{}; -}; -static_assert(sizeof(RandomMiiData4) == 0xcc, "RandomMiiData4 has incorrect size."); - -struct RandomMiiData3 { - u32 arg_1; - u32 arg_2; - u32 values_count; - std::array values{}; -}; -static_assert(sizeof(RandomMiiData3) == 0xc8, "RandomMiiData3 has incorrect size."); - -struct RandomMiiData2 { - u32 arg_1; - u32 values_count; - std::array values{}; -}; -static_assert(sizeof(RandomMiiData2) == 0xc4, "RandomMiiData2 has incorrect size."); - -struct DefaultMii { - u32 face_type{}; - u32 face_color{}; - u32 face_wrinkle{}; - u32 face_makeup{}; - u32 hair_type{}; - u32 hair_color{}; - HairFlip hair_flip{}; - u32 eye_type{}; - u32 eye_color{}; - u32 eye_scale{}; - u32 eye_aspect{}; - u32 eye_rotate{}; - u32 eye_x{}; - u32 eye_y{}; - u32 eyebrow_type{}; - u32 eyebrow_color{}; - u32 eyebrow_scale{}; - u32 eyebrow_aspect{}; - u32 eyebrow_rotate{}; - u32 eyebrow_x{}; - u32 eyebrow_y{}; - u32 nose_type{}; - u32 nose_scale{}; - u32 nose_y{}; - u32 mouth_type{}; - u32 mouth_color{}; - u32 mouth_scale{}; - u32 mouth_aspect{}; - u32 mouth_y{}; - MustacheType mustache_type{}; - BeardType beard_type{}; - u32 beard_color{}; - u32 mustache_scale{}; - u32 mustache_y{}; - u32 glasses_type{}; - u32 glasses_color{}; - u32 glasses_scale{}; - u32 glasses_y{}; - u32 mole_type{}; - u32 mole_scale{}; - u32 mole_x{}; - u32 mole_y{}; - u32 height{}; - u32 weight{}; - Gender gender{}; - u32 favorite_color{}; - u32 region_move{}; - FontRegion font_region{}; - u32 type{}; - Nickname nickname; -}; -static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); - -#pragma pack(pop) - -} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp new file mode 100644 index 000000000..250fad44b --- /dev/null +++ b/src/core/hle/service/mii/types/char_info.cpp @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/mii/types/char_info.h" + +namespace Service::Mii {} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/char_info.h b/src/core/hle/service/mii/types/char_info.h new file mode 100644 index 000000000..5741b5089 --- /dev/null +++ b/src/core/hle/service/mii/types/char_info.h @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/mii/mii_types.h" + +namespace Service::Mii { + +// This is nn::mii::detail::CharInfoRaw +struct CharInfo { + Common::UUID create_id; + Nickname name; + u16 null_terminator; + u8 font_region; + u8 favorite_color; + u8 gender; + u8 height; + u8 build; + u8 type; + u8 region_move; + u8 faceline_type; + u8 faceline_color; + u8 faceline_wrinkle; + u8 faceline_make; + u8 hair_type; + u8 hair_color; + u8 hair_flip; + u8 eye_type; + u8 eye_color; + u8 eye_scale; + u8 eye_aspect; + u8 eye_rotate; + u8 eye_x; + u8 eye_y; + u8 eyebrow_type; + u8 eyebrow_color; + u8 eyebrow_scale; + u8 eyebrow_aspect; + u8 eyebrow_rotate; + u8 eyebrow_x; + u8 eyebrow_y; + u8 nose_type; + u8 nose_scale; + u8 nose_y; + u8 mouth_type; + u8 mouth_color; + u8 mouth_scale; + u8 mouth_aspect; + u8 mouth_y; + u8 beard_color; + u8 beard_type; + u8 mustache_type; + u8 mustache_scale; + u8 mustache_y; + u8 glasses_type; + u8 glasses_color; + u8 glasses_scale; + u8 glasses_y; + u8 mole_type; + u8 mole_scale; + u8 mole_x; + u8 mole_y; + u8 padding; +}; +static_assert(sizeof(CharInfo) == 0x58, "CharInfo has incorrect size."); +static_assert(std::has_unique_object_representations_v, + "All bits of CharInfo must contribute to its value."); + +struct CharInfoElement { + CharInfo char_info{}; + Source source{}; +}; +static_assert(sizeof(CharInfoElement) == 0x5c, "CharInfoElement has incorrect size."); + +}; // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp new file mode 100644 index 000000000..a7b12ad8d --- /dev/null +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/mii/types/core_data.h" + +namespace Service::Mii {} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/core_data.h b/src/core/hle/service/mii/types/core_data.h new file mode 100644 index 000000000..9dd7a5380 --- /dev/null +++ b/src/core/hle/service/mii/types/core_data.h @@ -0,0 +1,105 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/mii/mii_types.h" + +namespace Service::Mii { + +struct StoreDataBitFields { + union { + u32 word_0{}; + + BitField<0, 8, u32> hair_type; + BitField<8, 7, u32> height; + BitField<15, 1, u32> mole_type; + BitField<16, 7, u32> build; + BitField<23, 1, HairFlip> hair_flip; + BitField<24, 7, u32> hair_color; + BitField<31, 1, u32> type; + }; + + union { + u32 word_1{}; + + BitField<0, 7, u32> eye_color; + BitField<7, 1, Gender> gender; + BitField<8, 7, u32> eyebrow_color; + BitField<16, 7, u32> mouth_color; + BitField<24, 7, u32> beard_color; + }; + + union { + u32 word_2{}; + + BitField<0, 7, u32> glasses_color; + BitField<8, 6, u32> eye_type; + BitField<14, 2, u32> region_move; + BitField<16, 6, u32> mouth_type; + BitField<22, 2, FontRegion> font_region; + BitField<24, 5, u32> eye_y; + BitField<29, 3, u32> glasses_scale; + }; + + union { + u32 word_3{}; + + BitField<0, 5, u32> eyebrow_type; + BitField<5, 3, MustacheType> mustache_type; + BitField<8, 5, u32> nose_type; + BitField<13, 3, BeardType> beard_type; + BitField<16, 5, u32> nose_y; + BitField<21, 3, u32> mouth_aspect; + BitField<24, 5, u32> mouth_y; + BitField<29, 3, u32> eyebrow_aspect; + }; + + union { + u32 word_4{}; + + BitField<0, 5, u32> mustache_y; + BitField<5, 3, u32> eye_rotate; + BitField<8, 5, u32> glasses_y; + BitField<13, 3, u32> eye_aspect; + BitField<16, 5, u32> mole_x; + BitField<21, 3, u32> eye_scale; + BitField<24, 5, u32> mole_y; + }; + + union { + u32 word_5{}; + + BitField<0, 5, u32> glasses_type; + BitField<8, 4, u32> favorite_color; + BitField<12, 4, u32> faceline_type; + BitField<16, 4, u32> faceline_color; + BitField<20, 4, u32> faceline_wrinkle; + BitField<24, 4, u32> faceline_makeup; + BitField<28, 4, u32> eye_x; + }; + + union { + u32 word_6{}; + + BitField<0, 4, u32> eyebrow_scale; + BitField<4, 4, u32> eyebrow_rotate; + BitField<8, 4, u32> eyebrow_x; + BitField<12, 4, u32> eyebrow_y; + BitField<16, 4, u32> nose_scale; + BitField<20, 4, u32> mouth_scale; + BitField<24, 4, u32> mustache_scale; + BitField<28, 4, u32> mole_scale; + }; +}; +static_assert(sizeof(StoreDataBitFields) == 0x1c, "StoreDataBitFields has incorrect size."); +static_assert(std::is_trivially_copyable_v, + "StoreDataBitFields is not trivially copyable."); + +struct CoreData { + StoreDataBitFields data{}; + Nickname name{}; +}; +static_assert(sizeof(CoreData) == 0x30, "CoreData has incorrect size."); + +}; // namespace Service::Mii diff --git a/src/core/hle/service/mii/raw_data.cpp b/src/core/hle/service/mii/types/raw_data.cpp similarity index 99% rename from src/core/hle/service/mii/raw_data.cpp rename to src/core/hle/service/mii/types/raw_data.cpp index 070e2d199..ef678c527 100644 --- a/src/core/hle/service/mii/raw_data.cpp +++ b/src/core/hle/service/mii/types/raw_data.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Ryujinx Team and Contributors // SPDX-License-Identifier: MIT -#include "core/hle/service/mii/raw_data.h" +#include "core/hle/service/mii/types/raw_data.h" namespace Service::Mii::RawData { diff --git a/src/core/hle/service/mii/raw_data.h b/src/core/hle/service/mii/types/raw_data.h similarity index 98% rename from src/core/hle/service/mii/raw_data.h rename to src/core/hle/service/mii/types/raw_data.h index ab84d09a1..180f49fd0 100644 --- a/src/core/hle/service/mii/raw_data.h +++ b/src/core/hle/service/mii/types/raw_data.h @@ -5,7 +5,7 @@ #include -#include "core/hle/service/mii/types.h" +#include "core/hle/service/mii/mii_types.h" namespace Service::Mii::RawData { diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp new file mode 100644 index 000000000..aadc0e1af --- /dev/null +++ b/src/core/hle/service/mii/types/store_data.cpp @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/mii/types/store_data.h" + +namespace Service::Mii {} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h new file mode 100644 index 000000000..54a263b05 --- /dev/null +++ b/src/core/hle/service/mii/types/store_data.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/mii/mii_types.h" +#include "core/hle/service/mii/types/core_data.h" + +namespace Service::Mii { + +struct StoreData { + StoreData(); + StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, + const Common::UUID& user_id); + + CoreData core_data{}; + Common::UUID create_id{}; + u16 data_crc{}; + u16 device_crc{}; +}; +static_assert(sizeof(StoreData) == 0x44, "StoreData has incorrect size."); + +struct StoreDataElement { + StoreData store_data{}; + Source source{}; +}; +static_assert(sizeof(StoreDataElement) == 0x48, "StoreDataElement has incorrect size."); + +}; // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/ver3_store_data.cpp b/src/core/hle/service/mii/types/ver3_store_data.cpp new file mode 100644 index 000000000..4c8904c12 --- /dev/null +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/mii/types/ver3_store_data.h" + +namespace Service::Mii {} // 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 new file mode 100644 index 000000000..c3963548c --- /dev/null +++ b/src/core/hle/service/mii/types/ver3_store_data.h @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#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 { + +// This is nn::mii::Ver3StoreData +// Based on citra HLE::Applets::MiiData and PretendoNetwork. +// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 +// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 + +#pragma pack(push, 4) +struct Ver3StoreData { + u8 version; + union { + u8 raw; + + BitField<0, 1, u8> allow_copying; + BitField<1, 1, u8> profanity_flag; + BitField<2, 2, u8> region_lock; + BitField<4, 2, u8> character_set; + } region_information; + u16_be mii_id; + u64_be system_id; + u32_be specialness_and_creation_date; + std::array creator_mac; + u16_be padding; + union { + u16 raw; + + BitField<0, 1, u16> gender; + BitField<1, 4, u16> birth_month; + BitField<5, 5, u16> birth_day; + BitField<10, 4, u16> favorite_color; + BitField<14, 1, u16> favorite; + } mii_information; + std::array mii_name; + u8 height; + u8 build; + union { + u8 raw; + + BitField<0, 1, u8> disable_sharing; + BitField<1, 4, u8> face_shape; + BitField<5, 3, u8> skin_color; + } appearance_bits1; + union { + u8 raw; + + BitField<0, 4, u8> wrinkles; + BitField<4, 4, u8> makeup; + } appearance_bits2; + u8 hair_style; + union { + u8 raw; + + BitField<0, 3, u8> hair_color; + BitField<3, 1, u8> flip_hair; + } appearance_bits3; + union { + u32 raw; + + BitField<0, 6, u32> eye_type; + BitField<6, 3, u32> eye_color; + BitField<9, 4, u32> eye_scale; + BitField<13, 3, u32> eye_vertical_stretch; + BitField<16, 5, u32> eye_rotation; + BitField<21, 4, u32> eye_spacing; + BitField<25, 5, u32> eye_y_position; + } appearance_bits4; + union { + u32 raw; + + BitField<0, 5, u32> eyebrow_style; + BitField<5, 3, u32> eyebrow_color; + BitField<8, 4, u32> eyebrow_scale; + BitField<12, 3, u32> eyebrow_yscale; + BitField<16, 4, u32> eyebrow_rotation; + BitField<21, 4, u32> eyebrow_spacing; + BitField<25, 5, u32> eyebrow_y_position; + } appearance_bits5; + union { + u16 raw; + + BitField<0, 5, u16> nose_type; + BitField<5, 4, u16> nose_scale; + BitField<9, 5, u16> nose_y_position; + } appearance_bits6; + union { + u16 raw; + + BitField<0, 6, u16> mouth_type; + BitField<6, 3, u16> mouth_color; + BitField<9, 4, u16> mouth_scale; + BitField<13, 3, u16> mouth_horizontal_stretch; + } appearance_bits7; + union { + u8 raw; + + BitField<0, 5, u8> mouth_y_position; + BitField<5, 3, u8> mustache_type; + } appearance_bits8; + u8 allow_copying; + union { + u16 raw; + + BitField<0, 3, u16> bear_type; + BitField<3, 3, u16> facial_hair_color; + BitField<6, 4, u16> mustache_scale; + BitField<10, 5, u16> mustache_y_position; + } appearance_bits9; + union { + u16 raw; + + BitField<0, 4, u16> glasses_type; + BitField<4, 3, u16> glasses_color; + BitField<7, 4, u16> glasses_scale; + BitField<11, 5, u16> glasses_y_position; + } appearance_bits10; + union { + u16 raw; + + BitField<0, 1, u16> mole_enabled; + BitField<1, 4, u16> mole_scale; + BitField<5, 5, u16> mole_x_position; + BitField<10, 5, u16> mole_y_position; + } appearance_bits11; + + std::array author_name; + INSERT_PADDING_BYTES(0x2); + u16_be crc; +}; +static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); +#pragma pack(pop) + +}; // namespace Service::Mii diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 5df40f9a0..44ac8cc71 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -28,7 +28,6 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/mii/mii_manager.h" -#include "core/hle/service/mii/types.h" #include "core/hle/service/nfc/common/amiibo_crypto.h" #include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/mifare_result.h" diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index aed12a7f8..adcaa8e84 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -6,7 +6,8 @@ #include #include "common/swap.h" -#include "core/hle/service/mii/types.h" +#include "core/hle/service/mii/types/char_info.h" +#include "core/hle/service/mii/types/ver3_store_data.h" #include "core/hle/service/nfc/nfc_types.h" namespace Service::NFP { @@ -322,7 +323,7 @@ static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size"); // This is nn::nfp::RegisterInfoPrivate struct RegisterInfoPrivate { - Service::Mii::MiiStoreData mii_store_data; + Service::Mii::StoreData mii_store_data; WriteDate creation_date; AmiiboName amiibo_name; u8 font_region; From 8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 22:42:38 -0600 Subject: [PATCH 04/11] 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 035eed505..9ae7fb960 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 1f5c9e16f..0a47e613f 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 5741b5089..cdebb1c9d 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 4c8904c12..c774f4b47 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 c3963548c..6b4e1eb9c 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 44ac8cc71..5e61d2595 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 adcaa8e84..f96d21220 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" From 81f50d51326fc1ce401bd21c28cf78371b4ddcea Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 22:52:33 -0600 Subject: [PATCH 05/11] service: mii: Move core data operations --- src/core/hle/service/mii/mii_manager.cpp | 247 +------- src/core/hle/service/mii/types/core_data.cpp | 597 +++++++++++++++++- src/core/hle/service/mii/types/core_data.h | 111 +++- src/core/hle/service/mii/types/store_data.cpp | 16 +- src/core/hle/service/mii/types/store_data.h | 3 +- 5 files changed, 729 insertions(+), 245 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 9ae7fb960..3483d95e5 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -90,256 +90,21 @@ CharInfo ConvertStoreDataToInfo(const StoreData& data) { } StoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { - StoreDataBitFields bf{}; + CoreData core_data{}; + core_data.BuildRandom(age, gender, race); - if (gender == Gender::All) { - gender = MiiUtil::GetRandomValue(Gender::Maximum); - } - - bf.gender.Assign(gender); - bf.favorite_color.Assign(MiiUtil::GetRandomValue(11)); - bf.region_move.Assign(0); - bf.font_region.Assign(FontRegion::Standard); - bf.type.Assign(0); - bf.height.Assign(64); - bf.build.Assign(64); - - if (age == Age::All) { - const auto temp{MiiUtil::GetRandomValue(10)}; - if (temp >= 8) { - age = Age::Old; - } else if (temp >= 4) { - age = Age::Normal; - } else { - age = Age::Young; - } - } - - if (race == Race::All) { - const auto temp{MiiUtil::GetRandomValue(10)}; - if (temp >= 8) { - race = Race::Black; - } else if (temp >= 4) { - race = Race::White; - } else { - race = Race::Asian; - } - } - - u32 axis_y{}; - if (gender == Gender::Female && age == Age::Young) { - axis_y = MiiUtil::GetRandomValue(3); - } - - const std::size_t index{3 * static_cast(age) + - 9 * static_cast(gender) + static_cast(race)}; - - const auto& faceline_type_info{RawData::RandomMiiFaceline.at(index)}; - const auto& faceline_color_info{RawData::RandomMiiFacelineColor.at( - 3 * static_cast(gender) + static_cast(race))}; - const auto& faceline_wrinkle_info{RawData::RandomMiiFacelineWrinkle.at(index)}; - const auto& faceline_makeup_info{RawData::RandomMiiFacelineMakeup.at(index)}; - const auto& hair_type_info{RawData::RandomMiiHairType.at(index)}; - const auto& hair_color_info{RawData::RandomMiiHairColor.at(3 * static_cast(race) + - static_cast(age))}; - const auto& eye_type_info{RawData::RandomMiiEyeType.at(index)}; - const auto& eye_color_info{RawData::RandomMiiEyeColor.at(static_cast(race))}; - const auto& eyebrow_type_info{RawData::RandomMiiEyebrowType.at(index)}; - const auto& nose_type_info{RawData::RandomMiiNoseType.at(index)}; - const auto& mouth_type_info{RawData::RandomMiiMouthType.at(index)}; - const auto& glasses_type_info{RawData::RandomMiiGlassType.at(static_cast(age))}; - - bf.faceline_type.Assign( - faceline_type_info - .values[MiiUtil::GetRandomValue(faceline_type_info.values_count)]); - bf.faceline_color.Assign( - faceline_color_info - .values[MiiUtil::GetRandomValue(faceline_color_info.values_count)]); - bf.faceline_wrinkle.Assign( - faceline_wrinkle_info - .values[MiiUtil::GetRandomValue(faceline_wrinkle_info.values_count)]); - bf.faceline_makeup.Assign( - faceline_makeup_info - .values[MiiUtil::GetRandomValue(faceline_makeup_info.values_count)]); - - bf.hair_type.Assign( - hair_type_info.values[MiiUtil::GetRandomValue(hair_type_info.values_count)]); - bf.hair_color.Assign(RawData::GetHairColorFromVer3( - hair_color_info - .values[MiiUtil::GetRandomValue(hair_color_info.values_count)])); - bf.hair_flip.Assign(MiiUtil::GetRandomValue(HairFlip::Maximum)); - - bf.eye_type.Assign( - eye_type_info.values[MiiUtil::GetRandomValue(eye_type_info.values_count)]); - - const auto eye_rotate_1{gender != Gender::Male ? 4 : 2}; - const auto eye_rotate_2{gender != Gender::Male ? 3 : 4}; - const auto eye_rotate_offset{32 - RawData::EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; - const auto eye_rotate{32 - RawData::EyeRotateLookup[bf.eye_type]}; - - bf.eye_color.Assign(RawData::GetEyeColorFromVer3( - eye_color_info.values[MiiUtil::GetRandomValue(eye_color_info.values_count)])); - bf.eye_scale.Assign(4); - bf.eye_aspect.Assign(3); - bf.eye_rotate.Assign(eye_rotate_offset - eye_rotate); - bf.eye_x.Assign(2); - bf.eye_y.Assign(axis_y + 12); - - bf.eyebrow_type.Assign( - eyebrow_type_info - .values[MiiUtil::GetRandomValue(eyebrow_type_info.values_count)]); - - const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; - const auto eyebrow_y{race == Race::Asian ? 9 : 10}; - const auto eyebrow_rotate_offset{32 - RawData::EyebrowRotateLookup[eyebrow_rotate_1] + 6}; - const auto eyebrow_rotate{ - 32 - RawData::EyebrowRotateLookup[static_cast(bf.eyebrow_type.Value())]}; - - bf.eyebrow_color.Assign(bf.hair_color); - bf.eyebrow_scale.Assign(4); - bf.eyebrow_aspect.Assign(3); - bf.eyebrow_rotate.Assign(eyebrow_rotate_offset - eyebrow_rotate); - bf.eyebrow_x.Assign(2); - bf.eyebrow_y.Assign(axis_y + eyebrow_y); - - const auto nose_scale{gender == Gender::Female ? 3 : 4}; - - bf.nose_type.Assign( - nose_type_info.values[MiiUtil::GetRandomValue(nose_type_info.values_count)]); - bf.nose_scale.Assign(nose_scale); - bf.nose_y.Assign(axis_y + 9); - - const auto mouth_color{gender == Gender::Female ? MiiUtil::GetRandomValue(4) : 0}; - - bf.mouth_type.Assign( - mouth_type_info.values[MiiUtil::GetRandomValue(mouth_type_info.values_count)]); - bf.mouth_color.Assign(RawData::GetMouthColorFromVer3(mouth_color)); - bf.mouth_scale.Assign(4); - bf.mouth_aspect.Assign(3); - bf.mouth_y.Assign(axis_y + 13); - - bf.beard_color.Assign(bf.hair_color); - bf.mustache_scale.Assign(4); - - if (gender == Gender::Male && age != Age::Young && MiiUtil::GetRandomValue(10) < 2) { - const auto mustache_and_beard_flag{ - MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; - - auto beard_type{BeardType::None}; - auto mustache_type{MustacheType::None}; - - if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) == - BeardAndMustacheFlag::Beard) { - beard_type = MiiUtil::GetRandomValue(BeardType::Beard1, BeardType::Beard5); - } - - if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) == - BeardAndMustacheFlag::Mustache) { - mustache_type = MiiUtil::GetRandomValue(MustacheType::Mustache1, - MustacheType::Mustache5); - } - - bf.mustache_type.Assign(mustache_type); - bf.beard_type.Assign(beard_type); - bf.mustache_y.Assign(10); - } else { - bf.mustache_type.Assign(MustacheType::None); - bf.beard_type.Assign(BeardType::None); - bf.mustache_y.Assign(axis_y + 10); - } - - const auto glasses_type_start{MiiUtil::GetRandomValue(100)}; - u8 glasses_type{}; - while (glasses_type_start < glasses_type_info.values[glasses_type]) { - if (++glasses_type >= glasses_type_info.values_count) { - ASSERT(false); - break; - } - } - - bf.glasses_type.Assign(glasses_type); - bf.glasses_color.Assign(RawData::GetGlassColorFromVer3(0)); - bf.glasses_scale.Assign(4); - bf.glasses_y.Assign(axis_y + 10); - - bf.mole_type.Assign(0); - bf.mole_scale.Assign(4); - bf.mole_x.Assign(2); - bf.mole_y.Assign(20); - - return {DefaultMiiName, bf, user_id}; + return {DefaultMiiName, core_data.data, user_id}; } StoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) { - StoreDataBitFields bf{}; + CoreData core_data{}; + core_data.SetDefault(); - bf.font_region.Assign(info.font_region); - bf.favorite_color.Assign(info.favorite_color); - bf.gender.Assign(info.gender); - bf.height.Assign(info.height); - bf.build.Assign(info.weight); - bf.type.Assign(info.type); - bf.region_move.Assign(info.region_move); - bf.faceline_type.Assign(info.face_type); - bf.faceline_color.Assign(info.face_color); - bf.faceline_wrinkle.Assign(info.face_wrinkle); - bf.faceline_makeup.Assign(info.face_makeup); - bf.hair_type.Assign(info.hair_type); - bf.hair_color.Assign(RawData::GetHairColorFromVer3(info.hair_color)); - bf.hair_flip.Assign(static_cast(info.hair_flip)); - bf.eye_type.Assign(info.eye_type); - bf.eye_color.Assign(RawData::GetEyeColorFromVer3(info.eye_color)); - bf.eye_scale.Assign(info.eye_scale); - bf.eye_aspect.Assign(info.eye_aspect); - bf.eye_rotate.Assign(info.eye_rotate); - bf.eye_x.Assign(info.eye_x); - bf.eye_y.Assign(info.eye_y); - bf.eyebrow_type.Assign(info.eyebrow_type); - bf.eyebrow_color.Assign(RawData::GetHairColorFromVer3(info.eyebrow_color)); - bf.eyebrow_scale.Assign(info.eyebrow_scale); - bf.eyebrow_aspect.Assign(info.eyebrow_aspect); - bf.eyebrow_rotate.Assign(info.eyebrow_rotate); - bf.eyebrow_x.Assign(info.eyebrow_x); - bf.eyebrow_y.Assign(info.eyebrow_y - 3); - bf.nose_type.Assign(info.nose_type); - bf.nose_scale.Assign(info.nose_scale); - bf.nose_y.Assign(info.nose_y); - bf.mouth_type.Assign(info.mouth_type); - bf.mouth_color.Assign(RawData::GetMouthColorFromVer3(info.mouth_color)); - bf.mouth_scale.Assign(info.mouth_scale); - bf.mouth_aspect.Assign(info.mouth_aspect); - bf.mouth_y.Assign(info.mouth_y); - bf.beard_color.Assign(RawData::GetHairColorFromVer3(info.beard_color)); - bf.beard_type.Assign(static_cast(info.beard_type)); - bf.mustache_type.Assign(static_cast(info.mustache_type)); - bf.mustache_scale.Assign(info.mustache_scale); - bf.mustache_y.Assign(info.mustache_y); - bf.glasses_type.Assign(info.glasses_type); - bf.glasses_color.Assign(RawData::GetGlassColorFromVer3(static_cast(info.glasses_color))); - bf.glasses_scale.Assign(info.glasses_scale); - bf.glasses_y.Assign(info.glasses_y); - bf.mole_type.Assign(info.mole_type); - bf.mole_scale.Assign(info.mole_scale); - bf.mole_x.Assign(info.mole_x); - bf.mole_y.Assign(info.mole_y); - - return {DefaultMiiName, bf, user_id}; + return {DefaultMiiName, core_data.data, user_id}; } } // namespace -StoreData::StoreData() = default; - -StoreData::StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, - const Common::UUID& user_id) { - core_data.name = name; - create_id = Common::UUID::MakeRandomRFC4122V4(); - - core_data.data = bit_fields; - data_crc = MiiUtil::CalculateCrc16(&core_data.data, sizeof(core_data.data)); - device_crc = MiiUtil::CalculateCrc16(&user_id, sizeof(Common::UUID)); -} - MiiManager::MiiManager() : user_id{Service::Account::ProfileManager().GetLastOpenedUser()} {} bool MiiManager::CheckAndResetUpdateCounter(SourceFlag source_flag, u64& current_update_counter) { diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index a7b12ad8d..76c57fff2 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -1,6 +1,601 @@ // 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/core_data.h" +#include "core/hle/service/mii/types/raw_data.h" -namespace Service::Mii {} // namespace Service::Mii +namespace Service::Mii { + +void CoreData::SetDefault() { + data = {}; + name = GetDefaultNickname(); +} + +void CoreData::BuildRandom(Age age, Gender gender, Race race) { + if (gender == Gender::All) { + gender = MiiUtil::GetRandomValue(Gender::Maximum); + } + + data.gender.Assign(gender); + data.favorite_color.Assign(MiiUtil::GetRandomValue(11)); + data.region_move.Assign(0); + data.font_region.Assign(FontRegion::Standard); + data.type.Assign(0); + data.height.Assign(64); + data.build.Assign(64); + + if (age == Age::All) { + const auto temp{MiiUtil::GetRandomValue(10)}; + if (temp >= 8) { + age = Age::Old; + } else if (temp >= 4) { + age = Age::Normal; + } else { + age = Age::Young; + } + } + + if (race == Race::All) { + const auto temp{MiiUtil::GetRandomValue(10)}; + if (temp >= 8) { + race = Race::Black; + } else if (temp >= 4) { + race = Race::White; + } else { + race = Race::Asian; + } + } + + u32 axis_y{}; + if (gender == Gender::Female && age == Age::Young) { + axis_y = MiiUtil::GetRandomValue(3); + } + + const std::size_t index{3 * static_cast(age) + + 9 * static_cast(gender) + static_cast(race)}; + + const auto& faceline_type_info{RawData::RandomMiiFaceline.at(index)}; + const auto& faceline_color_info{RawData::RandomMiiFacelineColor.at( + 3 * static_cast(gender) + static_cast(race))}; + const auto& faceline_wrinkle_info{RawData::RandomMiiFacelineWrinkle.at(index)}; + const auto& faceline_makeup_info{RawData::RandomMiiFacelineMakeup.at(index)}; + const auto& hair_type_info{RawData::RandomMiiHairType.at(index)}; + const auto& hair_color_info{RawData::RandomMiiHairColor.at(3 * static_cast(race) + + static_cast(age))}; + const auto& eye_type_info{RawData::RandomMiiEyeType.at(index)}; + const auto& eye_color_info{RawData::RandomMiiEyeColor.at(static_cast(race))}; + const auto& eyebrow_type_info{RawData::RandomMiiEyebrowType.at(index)}; + const auto& nose_type_info{RawData::RandomMiiNoseType.at(index)}; + const auto& mouth_type_info{RawData::RandomMiiMouthType.at(index)}; + const auto& glasses_type_info{RawData::RandomMiiGlassType.at(static_cast(age))}; + + data.faceline_type.Assign( + faceline_type_info + .values[MiiUtil::GetRandomValue(faceline_type_info.values_count)]); + data.faceline_color.Assign( + faceline_color_info + .values[MiiUtil::GetRandomValue(faceline_color_info.values_count)]); + data.faceline_wrinkle.Assign( + faceline_wrinkle_info + .values[MiiUtil::GetRandomValue(faceline_wrinkle_info.values_count)]); + data.faceline_makeup.Assign( + faceline_makeup_info + .values[MiiUtil::GetRandomValue(faceline_makeup_info.values_count)]); + + data.hair_type.Assign( + hair_type_info.values[MiiUtil::GetRandomValue(hair_type_info.values_count)]); + data.hair_color.Assign(RawData::GetHairColorFromVer3( + hair_color_info + .values[MiiUtil::GetRandomValue(hair_color_info.values_count)])); + data.hair_flip.Assign(MiiUtil::GetRandomValue(HairFlip::Maximum)); + + data.eye_type.Assign( + eye_type_info.values[MiiUtil::GetRandomValue(eye_type_info.values_count)]); + + const auto eye_rotate_1{gender != Gender::Male ? 4 : 2}; + const auto eye_rotate_2{gender != Gender::Male ? 3 : 4}; + const auto eye_rotate_offset{32 - RawData::EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; + const auto eye_rotate{32 - RawData::EyeRotateLookup[data.eye_type]}; + + data.eye_color.Assign(RawData::GetEyeColorFromVer3( + eye_color_info.values[MiiUtil::GetRandomValue(eye_color_info.values_count)])); + data.eye_scale.Assign(4); + data.eye_aspect.Assign(3); + data.eye_rotate.Assign(eye_rotate_offset - eye_rotate); + data.eye_x.Assign(2); + data.eye_y.Assign(axis_y + 12); + + data.eyebrow_type.Assign( + eyebrow_type_info + .values[MiiUtil::GetRandomValue(eyebrow_type_info.values_count)]); + + const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; + const auto eyebrow_y{race == Race::Asian ? 9 : 10}; + const auto eyebrow_rotate_offset{32 - RawData::EyebrowRotateLookup[eyebrow_rotate_1] + 6}; + const auto eyebrow_rotate{ + 32 - RawData::EyebrowRotateLookup[static_cast(data.eyebrow_type.Value())]}; + + data.eyebrow_color.Assign(data.hair_color); + data.eyebrow_scale.Assign(4); + data.eyebrow_aspect.Assign(3); + data.eyebrow_rotate.Assign(eyebrow_rotate_offset - eyebrow_rotate); + data.eyebrow_x.Assign(2); + data.eyebrow_y.Assign(axis_y + eyebrow_y); + + const auto nose_scale{gender == Gender::Female ? 3 : 4}; + + data.nose_type.Assign( + nose_type_info.values[MiiUtil::GetRandomValue(nose_type_info.values_count)]); + data.nose_scale.Assign(nose_scale); + data.nose_y.Assign(axis_y + 9); + + const auto mouth_color{gender == Gender::Female ? MiiUtil::GetRandomValue(4) : 0}; + + data.mouth_type.Assign( + mouth_type_info.values[MiiUtil::GetRandomValue(mouth_type_info.values_count)]); + data.mouth_color.Assign(RawData::GetMouthColorFromVer3(mouth_color)); + data.mouth_scale.Assign(4); + data.mouth_aspect.Assign(3); + data.mouth_y.Assign(axis_y + 13); + + data.beard_color.Assign(data.hair_color); + data.mustache_scale.Assign(4); + + if (gender == Gender::Male && age != Age::Young && MiiUtil::GetRandomValue(10) < 2) { + const auto mustache_and_beard_flag{ + MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; + + auto beard_type{BeardType::None}; + auto mustache_type{MustacheType::None}; + + if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) == + BeardAndMustacheFlag::Beard) { + beard_type = MiiUtil::GetRandomValue(BeardType::Beard1, BeardType::Beard5); + } + + if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) == + BeardAndMustacheFlag::Mustache) { + mustache_type = MiiUtil::GetRandomValue(MustacheType::Mustache1, + MustacheType::Mustache5); + } + + data.mustache_type.Assign(mustache_type); + data.beard_type.Assign(beard_type); + data.mustache_y.Assign(10); + } else { + data.mustache_type.Assign(MustacheType::None); + data.beard_type.Assign(BeardType::None); + data.mustache_y.Assign(axis_y + 10); + } + + const auto glasses_type_start{MiiUtil::GetRandomValue(100)}; + u8 glasses_type{}; + while (glasses_type_start < glasses_type_info.values[glasses_type]) { + if (++glasses_type >= glasses_type_info.values_count) { + ASSERT(false); + break; + } + } + + data.glasses_type.Assign(glasses_type); + data.glasses_color.Assign(RawData::GetGlassColorFromVer3(0)); + data.glasses_scale.Assign(4); + data.glasses_y.Assign(axis_y + 10); + + data.mole_type.Assign(0); + data.mole_scale.Assign(4); + data.mole_x.Assign(2); + data.mole_y.Assign(20); +} + +u32 CoreData::IsValid() const { + // TODO: Complete this + return 0; +} + +void CoreData::SetFontRegion(FontRegion value) { + data.font_region.Assign(value); +} + +void CoreData::SetFavoriteColor(u8 value) { + data.favorite_color.Assign(value); +} + +void CoreData::SetGender(Gender value) { + data.gender.Assign(value); +} + +void CoreData::SetHeight(u8 value) { + data.height.Assign(value); +} + +void CoreData::SetBuild(u8 value) { + data.build.Assign(value); +} + +void CoreData::SetType(u8 value) { + data.type.Assign(value); +} + +void CoreData::SetRegionMove(u8 value) { + data.region_move.Assign(value); +} + +void CoreData::SetFacelineType(u8 value) { + data.faceline_type.Assign(value); +} + +void CoreData::SetFacelineColor(u8 value) { + data.faceline_color.Assign(value); +} + +void CoreData::SetFacelineWrinkle(u8 value) { + data.faceline_wrinkle.Assign(value); +} + +void CoreData::SetFacelineMake(u8 value) { + data.faceline_makeup.Assign(value); +} + +void CoreData::SetHairType(u8 value) { + data.hair_type.Assign(value); +} + +void CoreData::SetHairColor(u8 value) { + data.hair_color.Assign(value); +} + +void CoreData::SetHairFlip(HairFlip value) { + data.hair_flip.Assign(value); +} + +void CoreData::SetEyeType(u8 value) { + data.eye_type.Assign(value); +} + +void CoreData::SetEyeColor(u8 value) { + data.eye_color.Assign(value); +} + +void CoreData::SetEyeScale(u8 value) { + data.eye_scale.Assign(value); +} + +void CoreData::SetEyeAspect(u8 value) { + data.eye_aspect.Assign(value); +} + +void CoreData::SetEyeRotate(u8 value) { + data.eye_rotate.Assign(value); +} + +void CoreData::SetEyeX(u8 value) { + data.eye_x.Assign(value); +} + +void CoreData::SetEyeY(u8 value) { + data.eye_y.Assign(value); +} + +void CoreData::SetEyebrowType(u8 value) { + data.eyebrow_type.Assign(value); +} + +void CoreData::SetEyebrowColor(u8 value) { + data.eyebrow_color.Assign(value); +} + +void CoreData::SetEyebrowScale(u8 value) { + data.eyebrow_scale.Assign(value); +} + +void CoreData::SetEyebrowAspect(u8 value) { + data.eyebrow_aspect.Assign(value); +} + +void CoreData::SetEyebrowRotate(u8 value) { + data.eyebrow_rotate.Assign(value); +} + +void CoreData::SetEyebrowX(u8 value) { + data.eyebrow_x.Assign(value); +} + +void CoreData::SetEyebrowY(u8 value) { + data.eyebrow_y.Assign(value); +} + +void CoreData::SetNoseType(u8 value) { + data.nose_type.Assign(value); +} + +void CoreData::SetNoseScale(u8 value) { + data.nose_scale.Assign(value); +} + +void CoreData::SetNoseY(u8 value) { + data.nose_y.Assign(value); +} + +void CoreData::SetMouthType(u8 value) { + data.mouth_type.Assign(value); +} + +void CoreData::SetMouthColor(u8 value) { + data.mouth_color.Assign(value); +} + +void CoreData::SetMouthScale(u8 value) { + data.mouth_scale.Assign(value); +} + +void CoreData::SetMouthAspect(u8 value) { + data.mouth_aspect.Assign(value); +} + +void CoreData::SetMouthY(u8 value) { + data.mouth_y.Assign(value); +} + +void CoreData::SetBeardColor(u8 value) { + data.beard_color.Assign(value); +} + +void CoreData::SetBeardType(BeardType value) { + data.beard_type.Assign(value); +} + +void CoreData::SetMustacheType(MustacheType value) { + data.mustache_type.Assign(value); +} + +void CoreData::SetMustacheScale(u8 value) { + data.mustache_scale.Assign(value); +} + +void CoreData::SetMustacheY(u8 value) { + data.mustache_y.Assign(value); +} + +void CoreData::SetGlassType(u8 value) { + data.glasses_type.Assign(value); +} + +void CoreData::SetGlassColor(u8 value) { + data.glasses_color.Assign(value); +} + +void CoreData::SetGlassScale(u8 value) { + data.glasses_scale.Assign(value); +} + +void CoreData::SetGlassY(u8 value) { + data.glasses_y.Assign(value); +} + +void CoreData::SetMoleType(u8 value) { + data.mole_type.Assign(value); +} + +void CoreData::SetMoleScale(u8 value) { + data.mole_scale.Assign(value); +} + +void CoreData::SetMoleX(u8 value) { + data.mole_x.Assign(value); +} + +void CoreData::SetMoleY(u8 value) { + data.mole_y.Assign(value); +} + +void CoreData::SetNickname(Nickname nickname) { + name = nickname; +} + +u8 CoreData::GetFavoriteColor() const { + return static_cast(data.favorite_color.Value()); +} + +u8 CoreData::GetGender() const { + return static_cast(data.gender.Value()); +} + +u8 CoreData::GetHeight() const { + return static_cast(data.height.Value()); +} + +u8 CoreData::GetBuild() const { + return static_cast(data.build.Value()); +} + +u8 CoreData::GetType() const { + return static_cast(data.type.Value()); +} + +u8 CoreData::GetRegionMove() const { + return static_cast(data.region_move.Value()); +} + +u8 CoreData::GetFacelineType() const { + return static_cast(data.faceline_type.Value()); +} + +u8 CoreData::GetFacelineColor() const { + return static_cast(data.faceline_color.Value()); +} + +u8 CoreData::GetFacelineWrinkle() const { + return static_cast(data.faceline_wrinkle.Value()); +} + +u8 CoreData::GetFacelineMake() const { + return static_cast(data.faceline_makeup.Value()); +} + +u8 CoreData::GetHairType() const { + return static_cast(data.hair_type.Value()); +} + +u8 CoreData::GetHairColor() const { + return static_cast(data.hair_color.Value()); +} + +u8 CoreData::GetHairFlip() const { + return static_cast(data.hair_flip.Value()); +} + +u8 CoreData::GetEyeType() const { + return static_cast(data.eye_type.Value()); +} + +u8 CoreData::GetEyeColor() const { + return static_cast(data.eye_color.Value()); +} + +u8 CoreData::GetEyeScale() const { + return static_cast(data.eye_scale.Value()); +} + +u8 CoreData::GetEyeAspect() const { + return static_cast(data.eye_aspect.Value()); +} + +u8 CoreData::GetEyeRotate() const { + return static_cast(data.eye_rotate.Value()); +} + +u8 CoreData::GetEyeX() const { + return static_cast(data.eye_x.Value()); +} + +u8 CoreData::GetEyeY() const { + return static_cast(data.eye_y.Value()); +} + +u8 CoreData::GetEyebrowType() const { + return static_cast(data.eyebrow_type.Value()); +} + +u8 CoreData::GetEyebrowColor() const { + return static_cast(data.eyebrow_color.Value()); +} + +u8 CoreData::GetEyebrowScale() const { + return static_cast(data.eyebrow_scale.Value()); +} + +u8 CoreData::GetEyebrowAspect() const { + return static_cast(data.eyebrow_aspect.Value()); +} + +u8 CoreData::GetEyebrowRotate() const { + return static_cast(data.eyebrow_rotate.Value()); +} + +u8 CoreData::GetEyebrowX() const { + return static_cast(data.eyebrow_x.Value()); +} + +u8 CoreData::GetEyebrowY() const { + return static_cast(data.eyebrow_y.Value()); +} + +u8 CoreData::GetNoseType() const { + return static_cast(data.nose_type.Value()); +} + +u8 CoreData::GetNoseScale() const { + return static_cast(data.nose_scale.Value()); +} + +u8 CoreData::GetNoseY() const { + return static_cast(data.nose_y.Value()); +} + +u8 CoreData::GetMouthType() const { + return static_cast(data.mouth_type.Value()); +} + +u8 CoreData::GetMouthColor() const { + return static_cast(data.mouth_color.Value()); +} + +u8 CoreData::GetMouthScale() const { + return static_cast(data.mouth_scale.Value()); +} + +u8 CoreData::GetMouthAspect() const { + return static_cast(data.mouth_aspect.Value()); +} + +u8 CoreData::GetMouthY() const { + return static_cast(data.mouth_y.Value()); +} + +u8 CoreData::GetBeardColor() const { + return static_cast(data.beard_color.Value()); +} + +u8 CoreData::GetBeardType() const { + return static_cast(data.beard_type.Value()); +} + +u8 CoreData::GetMustacheType() const { + return static_cast(data.mustache_type.Value()); +} + +u8 CoreData::GetMustacheScale() const { + return static_cast(data.mustache_scale.Value()); +} + +u8 CoreData::GetMustacheY() const { + return static_cast(data.mustache_y.Value()); +} + +u8 CoreData::GetGlassType() const { + return static_cast(data.glasses_type.Value()); +} + +u8 CoreData::GetGlassColor() const { + return static_cast(data.glasses_color.Value()); +} + +u8 CoreData::GetGlassScale() const { + return static_cast(data.glasses_scale.Value()); +} + +u8 CoreData::GetGlassY() const { + return static_cast(data.glasses_y.Value()); +} + +u8 CoreData::GetMoleType() const { + return static_cast(data.mole_type.Value()); +} + +u8 CoreData::GetMoleScale() const { + return static_cast(data.mole_scale.Value()); +} + +u8 CoreData::GetMoleX() const { + return static_cast(data.mole_x.Value()); +} + +u8 CoreData::GetMoleY() const { + return static_cast(data.mole_y.Value()); +} + +Nickname CoreData::GetNickname() const { + return name; +} + +Nickname CoreData::GetDefaultNickname() const { + return {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; +} + +Nickname CoreData::GetInvalidNickname() const { + return {u'?', u'?', u' ', u'?'}; +} + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/core_data.h b/src/core/hle/service/mii/types/core_data.h index 9dd7a5380..76daf4e6e 100644 --- a/src/core/hle/service/mii/types/core_data.h +++ b/src/core/hle/service/mii/types/core_data.h @@ -96,7 +96,116 @@ static_assert(sizeof(StoreDataBitFields) == 0x1c, "StoreDataBitFields has incorr static_assert(std::is_trivially_copyable_v, "StoreDataBitFields is not trivially copyable."); -struct CoreData { +class CoreData { +public: + void SetDefault(); + void BuildRandom(Age age, Gender gender, Race race); + + u32 IsValid() const; + + void SetFontRegion(FontRegion value); + void SetFavoriteColor(u8 value); + void SetGender(Gender value); + void SetHeight(u8 value); + void SetBuild(u8 value); + void SetType(u8 value); + void SetRegionMove(u8 value); + void SetFacelineType(u8 value); + void SetFacelineColor(u8 value); + void SetFacelineWrinkle(u8 value); + void SetFacelineMake(u8 value); + void SetHairType(u8 value); + void SetHairColor(u8 value); + void SetHairFlip(HairFlip value); + void SetEyeType(u8 value); + void SetEyeColor(u8 value); + void SetEyeScale(u8 value); + void SetEyeAspect(u8 value); + void SetEyeRotate(u8 value); + void SetEyeX(u8 value); + void SetEyeY(u8 value); + void SetEyebrowType(u8 value); + void SetEyebrowColor(u8 value); + void SetEyebrowScale(u8 value); + void SetEyebrowAspect(u8 value); + void SetEyebrowRotate(u8 value); + void SetEyebrowX(u8 value); + void SetEyebrowY(u8 value); + void SetNoseType(u8 value); + void SetNoseScale(u8 value); + void SetNoseY(u8 value); + void SetMouthType(u8 value); + void SetMouthColor(u8 value); + void SetMouthScale(u8 value); + void SetMouthAspect(u8 value); + void SetMouthY(u8 value); + void SetBeardColor(u8 value); + void SetBeardType(BeardType value); + void SetMustacheType(MustacheType value); + void SetMustacheScale(u8 value); + void SetMustacheY(u8 value); + void SetGlassType(u8 value); + void SetGlassColor(u8 value); + void SetGlassScale(u8 value); + void SetGlassY(u8 value); + void SetMoleType(u8 value); + void SetMoleScale(u8 value); + void SetMoleX(u8 value); + void SetMoleY(u8 value); + void SetNickname(Nickname nickname); + + u8 GetFavoriteColor() const; + u8 GetGender() const; + u8 GetHeight() const; + u8 GetBuild() const; + u8 GetType() const; + u8 GetRegionMove() const; + u8 GetFacelineType() const; + u8 GetFacelineColor() const; + u8 GetFacelineWrinkle() const; + u8 GetFacelineMake() const; + u8 GetHairType() const; + u8 GetHairColor() const; + u8 GetHairFlip() const; + u8 GetEyeType() const; + u8 GetEyeColor() const; + u8 GetEyeScale() const; + u8 GetEyeAspect() const; + u8 GetEyeRotate() const; + u8 GetEyeX() const; + u8 GetEyeY() const; + u8 GetEyebrowType() const; + u8 GetEyebrowColor() const; + u8 GetEyebrowScale() const; + u8 GetEyebrowAspect() const; + u8 GetEyebrowRotate() const; + u8 GetEyebrowX() const; + u8 GetEyebrowY() const; + u8 GetNoseType() const; + u8 GetNoseScale() const; + u8 GetNoseY() const; + u8 GetMouthType() const; + u8 GetMouthColor() const; + u8 GetMouthScale() const; + u8 GetMouthAspect() const; + u8 GetMouthY() const; + u8 GetBeardColor() const; + u8 GetBeardType() const; + u8 GetMustacheType() const; + u8 GetMustacheScale() const; + u8 GetMustacheY() const; + u8 GetGlassType() const; + u8 GetGlassColor() const; + u8 GetGlassScale() const; + u8 GetGlassY() const; + u8 GetMoleType() const; + u8 GetMoleScale() const; + u8 GetMoleX() const; + u8 GetMoleY() const; + Nickname GetNickname() const; + Nickname GetDefaultNickname() const; + Nickname GetInvalidNickname() const; + StoreDataBitFields data{}; Nickname name{}; }; diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp index aadc0e1af..459e8699f 100644 --- a/src/core/hle/service/mii/types/store_data.cpp +++ b/src/core/hle/service/mii/types/store_data.cpp @@ -1,6 +1,20 @@ // 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/store_data.h" -namespace Service::Mii {} // namespace Service::Mii +namespace Service::Mii { +StoreData::StoreData() = default; + +StoreData::StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, + const Common::UUID& user_id) { + core_data.name = name; + create_id = Common::UUID::MakeRandomRFC4122V4(); + + core_data.data = bit_fields; + data_crc = MiiUtil::CalculateCrc16(&core_data.data, sizeof(core_data.data)); + device_crc = MiiUtil::CalculateCrc16(&user_id, sizeof(Common::UUID)); +} + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h index 54a263b05..be6950967 100644 --- a/src/core/hle/service/mii/types/store_data.h +++ b/src/core/hle/service/mii/types/store_data.h @@ -8,7 +8,8 @@ namespace Service::Mii { -struct StoreData { +class StoreData { +public: StoreData(); StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, const Common::UUID& user_id); From d6037efe5e63d193ae8c586ff9d1e1326cae05cb Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 23:07:00 -0600 Subject: [PATCH 06/11] service: mii: Move store data operations --- src/core/hle/service/mii/mii_manager.cpp | 70 +-- src/core/hle/service/mii/types/core_data.cpp | 4 + src/core/hle/service/mii/types/core_data.h | 1 + src/core/hle/service/mii/types/store_data.cpp | 439 +++++++++++++++++- src/core/hle/service/mii/types/store_data.h | 71 ++- 5 files changed, 512 insertions(+), 73 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 3483d95e5..dd7af531e 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -31,76 +31,22 @@ std::array ResizeArray(const std::array& i } CharInfo ConvertStoreDataToInfo(const StoreData& data) { - const StoreDataBitFields& bf = data.core_data.data; - - return { - .create_id = data.create_id, - .name = data.core_data.name, - .font_region = static_cast(bf.font_region.Value()), - .favorite_color = static_cast(bf.favorite_color.Value()), - .gender = static_cast(bf.gender.Value()), - .height = static_cast(bf.height.Value()), - .build = static_cast(bf.build.Value()), - .type = static_cast(bf.type.Value()), - .region_move = static_cast(bf.region_move.Value()), - .faceline_type = static_cast(bf.faceline_type.Value()), - .faceline_color = static_cast(bf.faceline_color.Value()), - .faceline_wrinkle = static_cast(bf.faceline_wrinkle.Value()), - .faceline_make = static_cast(bf.faceline_makeup.Value()), - .hair_type = static_cast(bf.hair_type.Value()), - .hair_color = static_cast(bf.hair_color.Value()), - .hair_flip = static_cast(bf.hair_flip.Value()), - .eye_type = static_cast(bf.eye_type.Value()), - .eye_color = static_cast(bf.eye_color.Value()), - .eye_scale = static_cast(bf.eye_scale.Value()), - .eye_aspect = static_cast(bf.eye_aspect.Value()), - .eye_rotate = static_cast(bf.eye_rotate.Value()), - .eye_x = static_cast(bf.eye_x.Value()), - .eye_y = static_cast(bf.eye_y.Value()), - .eyebrow_type = static_cast(bf.eyebrow_type.Value()), - .eyebrow_color = static_cast(bf.eyebrow_color.Value()), - .eyebrow_scale = static_cast(bf.eyebrow_scale.Value()), - .eyebrow_aspect = static_cast(bf.eyebrow_aspect.Value()), - .eyebrow_rotate = static_cast(bf.eyebrow_rotate.Value()), - .eyebrow_x = static_cast(bf.eyebrow_x.Value()), - .eyebrow_y = static_cast(bf.eyebrow_y.Value() + 3), - .nose_type = static_cast(bf.nose_type.Value()), - .nose_scale = static_cast(bf.nose_scale.Value()), - .nose_y = static_cast(bf.nose_y.Value()), - .mouth_type = static_cast(bf.mouth_type.Value()), - .mouth_color = static_cast(bf.mouth_color.Value()), - .mouth_scale = static_cast(bf.mouth_scale.Value()), - .mouth_aspect = static_cast(bf.mouth_aspect.Value()), - .mouth_y = static_cast(bf.mouth_y.Value()), - .beard_color = static_cast(bf.beard_color.Value()), - .beard_type = static_cast(bf.beard_type.Value()), - .mustache_type = static_cast(bf.mustache_type.Value()), - .mustache_scale = static_cast(bf.mustache_scale.Value()), - .mustache_y = static_cast(bf.mustache_y.Value()), - .glasses_type = static_cast(bf.glasses_type.Value()), - .glasses_color = static_cast(bf.glasses_color.Value()), - .glasses_scale = static_cast(bf.glasses_scale.Value()), - .glasses_y = static_cast(bf.glasses_y.Value()), - .mole_type = static_cast(bf.mole_type.Value()), - .mole_scale = static_cast(bf.mole_scale.Value()), - .mole_x = static_cast(bf.mole_x.Value()), - .mole_y = static_cast(bf.mole_y.Value()), - .padding = 0, - }; + // Next Commit Will fix this one + return {}; } StoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { - CoreData core_data{}; - core_data.BuildRandom(age, gender, race); + StoreData store_data{}; + store_data.BuildRandom(age, gender, race); - return {DefaultMiiName, core_data.data, user_id}; + return store_data; } StoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) { - CoreData core_data{}; - core_data.SetDefault(); + StoreData store_data{}; + store_data.BuildDefault(0); - return {DefaultMiiName, core_data.data, user_id}; + return store_data; } } // namespace diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index 76c57fff2..9d7e604a9 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -394,6 +394,10 @@ void CoreData::SetNickname(Nickname nickname) { name = nickname; } +u8 CoreData::GetFontRegion() const { + return static_cast(data.font_region.Value()); +} + u8 CoreData::GetFavoriteColor() const { return static_cast(data.favorite_color.Value()); } diff --git a/src/core/hle/service/mii/types/core_data.h b/src/core/hle/service/mii/types/core_data.h index 76daf4e6e..411c123b3 100644 --- a/src/core/hle/service/mii/types/core_data.h +++ b/src/core/hle/service/mii/types/core_data.h @@ -154,6 +154,7 @@ public: void SetMoleY(u8 value); void SetNickname(Nickname nickname); + u8 GetFontRegion() const; u8 GetFavoriteColor() const; u8 GetGender() const; u8 GetHeight() const; diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp index 459e8699f..72c8fa2e9 100644 --- a/src/core/hle/service/mii/types/store_data.cpp +++ b/src/core/hle/service/mii/types/store_data.cpp @@ -2,19 +2,442 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/mii/mii_util.h" +#include "core/hle/service/mii/types/raw_data.h" #include "core/hle/service/mii/types/store_data.h" namespace Service::Mii { -StoreData::StoreData() = default; -StoreData::StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, - const Common::UUID& user_id) { - core_data.name = name; - create_id = Common::UUID::MakeRandomRFC4122V4(); +void StoreData::BuildDefault(u32 mii_index) { + const auto& default_mii = RawData::DefaultMii[mii_index]; + core_data.SetDefault(); - core_data.data = bit_fields; - data_crc = MiiUtil::CalculateCrc16(&core_data.data, sizeof(core_data.data)); - device_crc = MiiUtil::CalculateCrc16(&user_id, sizeof(Common::UUID)); + core_data.SetFacelineType(static_cast(default_mii.face_type)); + core_data.SetFacelineColor( + RawData::GetFacelineColorFromVer3(static_cast(default_mii.face_color))); + core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); + core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); + + core_data.SetHairType(static_cast(default_mii.hair_type)); + core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast(default_mii.hair_color))); + core_data.SetHairFlip(default_mii.hair_flip); + core_data.SetEyeType(static_cast(default_mii.eye_type)); + core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast(default_mii.eye_color))); + core_data.SetEyeScale(static_cast(default_mii.eye_scale)); + core_data.SetEyeAspect(static_cast(default_mii.eye_aspect)); + core_data.SetEyeRotate(static_cast(default_mii.eye_rotate)); + core_data.SetEyeX(static_cast(default_mii.eye_x)); + core_data.SetEyeY(static_cast(default_mii.eye_y)); + + core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); + core_data.SetEyebrowColor( + RawData::GetHairColorFromVer3(static_cast(default_mii.eyebrow_color))); + core_data.SetEyebrowScale(static_cast(default_mii.eyebrow_scale)); + core_data.SetEyebrowAspect(static_cast(default_mii.eyebrow_aspect)); + core_data.SetEyebrowRotate(static_cast(default_mii.eyebrow_rotate)); + core_data.SetEyebrowX(static_cast(default_mii.eyebrow_x)); + core_data.SetEyebrowY(static_cast(default_mii.eyebrow_y)); + + core_data.SetNoseType(static_cast(default_mii.nose_type)); + core_data.SetNoseScale(static_cast(default_mii.nose_scale)); + core_data.SetNoseY(static_cast(default_mii.nose_y)); + + core_data.SetMouthType(static_cast(default_mii.mouth_type)); + core_data.SetMouthColor( + RawData::GetMouthColorFromVer3(static_cast(default_mii.mouth_color))); + core_data.SetMouthScale(static_cast(default_mii.mouth_scale)); + core_data.SetMouthAspect(static_cast(default_mii.mouth_aspect)); + core_data.SetMouthY(static_cast(default_mii.mouth_y)); + + core_data.SetMustacheType(default_mii.mustache_type); + core_data.SetBeardType(default_mii.beard_type); + core_data.SetBeardColor( + RawData::GetHairColorFromVer3(static_cast(default_mii.beard_color))); + core_data.SetMustacheScale(static_cast(default_mii.mustache_scale)); + core_data.SetMustacheY(static_cast(default_mii.mustache_y)); + + core_data.SetGlassType(static_cast(default_mii.glasses_type)); + core_data.SetGlassColor( + RawData::GetGlassColorFromVer3(static_cast(default_mii.glasses_color))); + core_data.SetGlassScale(static_cast(default_mii.glasses_scale)); + core_data.SetGlassY(static_cast(default_mii.glasses_y)); + + core_data.SetMoleType(static_cast(default_mii.mole_type)); + core_data.SetMoleScale(static_cast(default_mii.mole_scale)); + core_data.SetMoleX(static_cast(default_mii.mole_x)); + core_data.SetMoleY(static_cast(default_mii.mole_y)); + + core_data.SetHeight(static_cast(default_mii.height)); + core_data.SetBuild(static_cast(default_mii.weight)); + core_data.SetGender(default_mii.gender); + core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); + core_data.SetRegionMove(static_cast(default_mii.region_move)); + core_data.SetFontRegion(default_mii.font_region); + core_data.SetType(static_cast(default_mii.type)); + core_data.SetNickname(default_mii.nickname); + + const auto device_id = MiiUtil::GetDeviceId(); + create_id = MiiUtil::MakeCreateId(); + device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); + data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); +} + +void StoreData::BuildBase(Gender gender) { + const auto& default_mii = RawData::BaseMii[gender == Gender::Female ? 1 : 0]; + core_data.SetDefault(); + + core_data.SetFacelineType(static_cast(default_mii.face_type)); + core_data.SetFacelineColor( + RawData::GetFacelineColorFromVer3(static_cast(default_mii.face_color))); + core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); + core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); + + core_data.SetHairType(static_cast(default_mii.hair_type)); + core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast(default_mii.hair_color))); + core_data.SetHairFlip(default_mii.hair_flip); + core_data.SetEyeType(static_cast(default_mii.eye_type)); + core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast(default_mii.eye_color))); + core_data.SetEyeScale(static_cast(default_mii.eye_scale)); + core_data.SetEyeAspect(static_cast(default_mii.eye_aspect)); + core_data.SetEyeRotate(static_cast(default_mii.eye_rotate)); + core_data.SetEyeX(static_cast(default_mii.eye_x)); + core_data.SetEyeY(static_cast(default_mii.eye_y)); + + core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); + core_data.SetEyebrowColor( + RawData::GetHairColorFromVer3(static_cast(default_mii.eyebrow_color))); + core_data.SetEyebrowScale(static_cast(default_mii.eyebrow_scale)); + core_data.SetEyebrowAspect(static_cast(default_mii.eyebrow_aspect)); + core_data.SetEyebrowRotate(static_cast(default_mii.eyebrow_rotate)); + core_data.SetEyebrowX(static_cast(default_mii.eyebrow_x)); + core_data.SetEyebrowY(static_cast(default_mii.eyebrow_y)); + + core_data.SetNoseType(static_cast(default_mii.nose_type)); + core_data.SetNoseScale(static_cast(default_mii.nose_scale)); + core_data.SetNoseY(static_cast(default_mii.nose_y)); + + core_data.SetMouthType(static_cast(default_mii.mouth_type)); + core_data.SetMouthColor( + RawData::GetMouthColorFromVer3(static_cast(default_mii.mouth_color))); + core_data.SetMouthScale(static_cast(default_mii.mouth_scale)); + core_data.SetMouthAspect(static_cast(default_mii.mouth_aspect)); + core_data.SetMouthY(static_cast(default_mii.mouth_y)); + + core_data.SetMustacheType(default_mii.mustache_type); + core_data.SetBeardType(default_mii.beard_type); + core_data.SetBeardColor( + RawData::GetHairColorFromVer3(static_cast(default_mii.beard_color))); + core_data.SetMustacheScale(static_cast(default_mii.mustache_scale)); + core_data.SetMustacheY(static_cast(default_mii.mustache_y)); + + core_data.SetGlassType(static_cast(default_mii.glasses_type)); + core_data.SetGlassColor( + RawData::GetGlassColorFromVer3(static_cast(default_mii.glasses_color))); + core_data.SetGlassScale(static_cast(default_mii.glasses_scale)); + core_data.SetGlassY(static_cast(default_mii.glasses_y)); + + core_data.SetMoleType(static_cast(default_mii.mole_type)); + core_data.SetMoleScale(static_cast(default_mii.mole_scale)); + core_data.SetMoleX(static_cast(default_mii.mole_x)); + core_data.SetMoleY(static_cast(default_mii.mole_y)); + + core_data.SetHeight(static_cast(default_mii.height)); + core_data.SetBuild(static_cast(default_mii.weight)); + core_data.SetGender(default_mii.gender); + core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); + core_data.SetRegionMove(static_cast(default_mii.region_move)); + core_data.SetFontRegion(default_mii.font_region); + core_data.SetType(static_cast(default_mii.type)); + core_data.SetNickname(default_mii.nickname); + + const auto device_id = MiiUtil::GetDeviceId(); + create_id = MiiUtil::MakeCreateId(); + device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); + data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); +} + +void StoreData::BuildRandom(Age age, Gender gender, Race race) { + core_data.BuildRandom(age, gender, race); + const auto device_id = MiiUtil::GetDeviceId(); + create_id = MiiUtil::MakeCreateId(); + device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); + data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); +} + +void StoreData::SetInvalidName() { + const auto& invalid_name = core_data.GetInvalidNickname(); + const auto device_id = MiiUtil::GetDeviceId(); + core_data.SetNickname(invalid_name); + device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); + data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); +} + +bool StoreData::IsSpecial() const { + return GetType() == 1; +} + +u32 StoreData::IsValid() const { + // TODO: complete this + return 0; +} + +Common::UUID StoreData::GetCreateId() const { + return create_id; +} + +FontRegion StoreData::GetFontRegion() const { + return static_cast(core_data.GetFontRegion()); +} + +u8 StoreData::GetFavoriteColor() const { + return core_data.GetFavoriteColor(); +} + +u8 StoreData::GetGender() const { + return core_data.GetGender(); +} + +u8 StoreData::GetHeight() const { + return core_data.GetHeight(); +} + +u8 StoreData::GetBuild() const { + return core_data.GetBuild(); +} + +u8 StoreData::GetType() const { + return core_data.GetType(); +} + +u8 StoreData::GetRegionMove() const { + return core_data.GetRegionMove(); +} + +u8 StoreData::GetFacelineType() const { + return core_data.GetFacelineType(); +} + +u8 StoreData::GetFacelineColor() const { + return core_data.GetFacelineColor(); +} + +u8 StoreData::GetFacelineWrinkle() const { + return core_data.GetFacelineWrinkle(); +} + +u8 StoreData::GetFacelineMake() const { + return core_data.GetFacelineMake(); +} + +u8 StoreData::GetHairType() const { + return core_data.GetHairType(); +} + +u8 StoreData::GetHairColor() const { + return core_data.GetHairColor(); +} + +u8 StoreData::GetHairFlip() const { + return core_data.GetHairFlip(); +} + +u8 StoreData::GetEyeType() const { + return core_data.GetEyeType(); +} + +u8 StoreData::GetEyeColor() const { + return core_data.GetEyeColor(); +} + +u8 StoreData::GetEyeScale() const { + return core_data.GetEyeScale(); +} + +u8 StoreData::GetEyeAspect() const { + return core_data.GetEyeAspect(); +} + +u8 StoreData::GetEyeRotate() const { + return core_data.GetEyeRotate(); +} + +u8 StoreData::GetEyeX() const { + return core_data.GetEyeX(); +} + +u8 StoreData::GetEyeY() const { + return core_data.GetEyeY(); +} + +u8 StoreData::GetEyebrowType() const { + return core_data.GetEyebrowType(); +} + +u8 StoreData::GetEyebrowColor() const { + return core_data.GetEyebrowColor(); +} + +u8 StoreData::GetEyebrowScale() const { + return core_data.GetEyebrowScale(); +} + +u8 StoreData::GetEyebrowAspect() const { + return core_data.GetEyebrowAspect(); +} + +u8 StoreData::GetEyebrowRotate() const { + return core_data.GetEyebrowRotate(); +} + +u8 StoreData::GetEyebrowX() const { + return core_data.GetEyebrowX(); +} + +u8 StoreData::GetEyebrowY() const { + return core_data.GetEyebrowY(); +} + +u8 StoreData::GetNoseType() const { + return core_data.GetNoseType(); +} + +u8 StoreData::GetNoseScale() const { + return core_data.GetNoseScale(); +} + +u8 StoreData::GetNoseY() const { + return core_data.GetNoseY(); +} + +u8 StoreData::GetMouthType() const { + return core_data.GetMouthType(); +} + +u8 StoreData::GetMouthColor() const { + return core_data.GetMouthColor(); +} + +u8 StoreData::GetMouthScale() const { + return core_data.GetMouthScale(); +} + +u8 StoreData::GetMouthAspect() const { + return core_data.GetMouthAspect(); +} + +u8 StoreData::GetMouthY() const { + return core_data.GetMouthY(); +} + +u8 StoreData::GetBeardColor() const { + return core_data.GetBeardColor(); +} + +u8 StoreData::GetBeardType() const { + return core_data.GetBeardType(); +} + +u8 StoreData::GetMustacheType() const { + return core_data.GetMustacheType(); +} + +u8 StoreData::GetMustacheScale() const { + return core_data.GetMustacheScale(); +} + +u8 StoreData::GetMustacheY() const { + return core_data.GetMustacheY(); +} + +u8 StoreData::GetGlassType() const { + return core_data.GetGlassType(); +} + +u8 StoreData::GetGlassColor() const { + return core_data.GetGlassColor(); +} + +u8 StoreData::GetGlassScale() const { + return core_data.GetGlassScale(); +} + +u8 StoreData::GetGlassY() const { + return core_data.GetGlassY(); +} + +u8 StoreData::GetMoleType() const { + return core_data.GetMoleType(); +} + +u8 StoreData::GetMoleScale() const { + return core_data.GetMoleScale(); +} + +u8 StoreData::GetMoleX() const { + return core_data.GetMoleX(); +} + +u8 StoreData::GetMoleY() const { + return core_data.GetMoleY(); +} + +Nickname StoreData::GetNickname() const { + return core_data.GetNickname(); +} + +bool StoreData::operator==(const StoreData& data) { + bool is_identical = data.core_data.IsValid() == 0; + is_identical &= core_data.GetNickname() == data.core_data.GetNickname(); + is_identical &= GetCreateId() == data.GetCreateId(); + is_identical &= GetFontRegion() == data.GetFontRegion(); + is_identical &= GetFavoriteColor() == data.GetFavoriteColor(); + is_identical &= GetGender() == data.GetGender(); + is_identical &= GetHeight() == data.GetHeight(); + is_identical &= GetBuild() == data.GetBuild(); + is_identical &= GetType() == data.GetType(); + is_identical &= GetRegionMove() == data.GetRegionMove(); + is_identical &= GetFacelineType() == data.GetFacelineType(); + is_identical &= GetFacelineColor() == data.GetFacelineColor(); + is_identical &= GetFacelineWrinkle() == data.GetFacelineWrinkle(); + is_identical &= GetFacelineMake() == data.GetFacelineMake(); + is_identical &= GetHairType() == data.GetHairType(); + is_identical &= GetHairColor() == data.GetHairColor(); + is_identical &= GetHairFlip() == data.GetHairFlip(); + is_identical &= GetEyeType() == data.GetEyeType(); + is_identical &= GetEyeColor() == data.GetEyeColor(); + is_identical &= GetEyeScale() == data.GetEyeScale(); + is_identical &= GetEyeAspect() == data.GetEyeAspect(); + is_identical &= GetEyeRotate() == data.GetEyeRotate(); + is_identical &= GetEyeX() == data.GetEyeX(); + is_identical &= GetEyeY() == data.GetEyeY(); + is_identical &= GetEyebrowType() == data.GetEyebrowType(); + is_identical &= GetEyebrowColor() == data.GetEyebrowColor(); + is_identical &= GetEyebrowScale() == data.GetEyebrowScale(); + is_identical &= GetEyebrowAspect() == data.GetEyebrowAspect(); + is_identical &= GetEyebrowRotate() == data.GetEyebrowRotate(); + is_identical &= GetEyebrowX() == data.GetEyebrowX(); + is_identical &= GetEyebrowY() == data.GetEyebrowY(); + is_identical &= GetNoseType() == data.GetNoseType(); + is_identical &= GetNoseScale() == data.GetNoseScale(); + is_identical &= GetNoseY() == data.GetNoseY(); + is_identical &= GetMouthType() == data.GetMouthType(); + is_identical &= GetMouthColor() == data.GetMouthColor(); + is_identical &= GetMouthScale() == data.GetMouthScale(); + is_identical &= GetMouthAspect() == data.GetMouthAspect(); + is_identical &= GetMouthY() == data.GetMouthY(); + is_identical &= GetBeardColor() == data.GetBeardColor(); + is_identical &= GetBeardType() == data.GetBeardType(); + is_identical &= GetMustacheType() == data.GetMustacheType(); + is_identical &= GetMustacheScale() == data.GetMustacheScale(); + is_identical &= GetMustacheY() == data.GetMustacheY(); + is_identical &= GetGlassType() == data.GetGlassType(); + is_identical &= GetGlassColor() == data.GetGlassColor(); + is_identical &= GetGlassScale() == data.GetGlassScale(); + is_identical &= GetGlassY() == data.GetGlassY(); + is_identical &= GetMoleType() == data.GetMoleType(); + is_identical &= GetMoleScale() == data.GetMoleScale(); + is_identical &= GetMoleX() == data.GetMoleX(); + is_identical &= data.GetMoleY() == data.GetMoleY(); + return is_identical; } } // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h index be6950967..cc8551a66 100644 --- a/src/core/hle/service/mii/types/store_data.h +++ b/src/core/hle/service/mii/types/store_data.h @@ -10,10 +10,75 @@ namespace Service::Mii { class StoreData { public: - StoreData(); - StoreData(const Nickname& name, const StoreDataBitFields& bit_fields, - const Common::UUID& user_id); + // nn::mii::detail::StoreDataRaw::BuildDefault + void BuildDefault(u32 mii_index); + // nn::mii::detail::StoreDataRaw::BuildDefault + void BuildBase(Gender gender); + // nn::mii::detail::StoreDataRaw::BuildRandom + void BuildRandom(Age age, Gender gender, Race race); + + void SetInvalidName(); + + bool IsSpecial() const; + + u32 IsValid() const; + + Common::UUID GetCreateId() const; + FontRegion GetFontRegion() const; + u8 GetFavoriteColor() const; + u8 GetGender() const; + u8 GetHeight() const; + u8 GetBuild() const; + u8 GetType() const; + u8 GetRegionMove() const; + u8 GetFacelineType() const; + u8 GetFacelineColor() const; + u8 GetFacelineWrinkle() const; + u8 GetFacelineMake() const; + u8 GetHairType() const; + u8 GetHairColor() const; + u8 GetHairFlip() const; + u8 GetEyeType() const; + u8 GetEyeColor() const; + u8 GetEyeScale() const; + u8 GetEyeAspect() const; + u8 GetEyeRotate() const; + u8 GetEyeX() const; + u8 GetEyeY() const; + u8 GetEyebrowType() const; + u8 GetEyebrowColor() const; + u8 GetEyebrowScale() const; + u8 GetEyebrowAspect() const; + u8 GetEyebrowRotate() const; + u8 GetEyebrowX() const; + u8 GetEyebrowY() const; + u8 GetNoseType() const; + u8 GetNoseScale() const; + u8 GetNoseY() const; + u8 GetMouthType() const; + u8 GetMouthColor() const; + u8 GetMouthScale() const; + u8 GetMouthAspect() const; + u8 GetMouthY() const; + u8 GetBeardColor() const; + u8 GetBeardType() const; + u8 GetMustacheType() const; + u8 GetMustacheScale() const; + u8 GetMustacheY() const; + u8 GetGlassType() const; + u8 GetGlassColor() const; + u8 GetGlassScale() const; + u8 GetGlassY() const; + u8 GetMoleType() const; + u8 GetMoleScale() const; + u8 GetMoleX() const; + u8 GetMoleY() const; + Nickname GetNickname() const; + + bool operator==(const StoreData& data); + +private: CoreData core_data{}; Common::UUID create_id{}; u16 data_crc{}; From 36290f9a0ac953ce57a663b5ba817d7e3bb5a33c Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 10 Sep 2023 23:17:50 -0600 Subject: [PATCH 07/11] service: mii: move char info operations --- src/core/hle/service/mii/mii_manager.cpp | 30 +- src/core/hle/service/mii/mii_types.h | 29 +- src/core/hle/service/mii/types/char_info.cpp | 478 ++++++++++++++++++- src/core/hle/service/mii/types/char_info.h | 60 +++ 4 files changed, 576 insertions(+), 21 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index dd7af531e..2137a9af1 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -21,18 +21,10 @@ namespace { constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; -constexpr Nickname DefaultMiiName{u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; - -template -std::array ResizeArray(const std::array& in) { - std::array out{}; - std::memcpy(out.data(), in.data(), sizeof(T) * std::min(SourceArraySize, DestArraySize)); - return out; -} - CharInfo ConvertStoreDataToInfo(const StoreData& data) { - // Next Commit Will fix this one - return {}; + CharInfo char_info{}; + char_info.SetFromStoreData(data); + return char_info; } StoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { @@ -112,14 +104,14 @@ CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { return { - .faceline_color = static_cast(mii.faceline_color & 0xf), - .hair_color = static_cast(mii.hair_color & 0x7f), - .eye_color = static_cast(mii.eyebrow_color & 0x7f), - .eyebrow_color = static_cast(mii.eyebrow_color & 0x7f), - .mouth_color = static_cast(mii.mouth_color & 0x7f), - .beard_color = static_cast(mii.beard_color & 0x7f), - .glass_color = static_cast(mii.glasses_color & 0x7f), - .glass_type = static_cast(mii.glasses_type & 0x1f), + .faceline_color = static_cast(mii.GetFacelineColor() & 0xf), + .hair_color = static_cast(mii.GetHairColor() & 0x7f), + .eye_color = static_cast(mii.GetEyeColor() & 0x7f), + .eyebrow_color = static_cast(mii.GetEyebrowColor() & 0x7f), + .mouth_color = static_cast(mii.GetMouthColor() & 0x7f), + .beard_color = static_cast(mii.GetBeardColor() & 0x7f), + .glass_color = static_cast(mii.GetGlassColor() & 0x7f), + .glass_type = static_cast(mii.GetGlassType() & 0x1f), }; } diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index ff836dcf2..20d4e40ab 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -86,7 +86,34 @@ enum class SourceFlag : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); -using Nickname = std::array; +struct Nickname { + static constexpr std::size_t MaxNameSize = 10; + std::array data; + + // Checks for null, non-zero terminated or dirty strings + bool IsValid() const { + if (data[0] == 0) { + return false; + } + + if (data[MaxNameSize] != 0) { + return false; + } + std::size_t index = 1; + while (data[index] != 0) { + index++; + } + while (index < MaxNameSize && data[index] == 0) { + index++; + } + return index == MaxNameSize; + } + + bool operator==(const Nickname& name) { + return data == name.data; + }; +}; +static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size"); struct NfpStoreDataExtension { u8 faceline_color; diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp index 250fad44b..e1d874860 100644 --- a/src/core/hle/service/mii/types/char_info.cpp +++ b/src/core/hle/service/mii/types/char_info.cpp @@ -2,5 +2,481 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/service/mii/types/char_info.h" +#include "core/hle/service/mii/types/store_data.h" -namespace Service::Mii {} // namespace Service::Mii +namespace Service::Mii { + +void CharInfo::SetFromStoreData(const StoreData& store_data) { + name = store_data.GetNickname(); + null_terminator = '\0'; + create_id = store_data.GetCreateId(); + font_region = static_cast(store_data.GetFontRegion()); + favorite_color = store_data.GetFavoriteColor(); + gender = store_data.GetGender(); + height = store_data.GetHeight(); + build = store_data.GetBuild(); + type = store_data.GetType(); + region_move = store_data.GetRegionMove(); + faceline_type = store_data.GetFacelineType(); + faceline_color = store_data.GetFacelineColor(); + faceline_wrinkle = store_data.GetFacelineWrinkle(); + faceline_make = store_data.GetFacelineMake(); + hair_type = store_data.GetHairType(); + hair_color = store_data.GetHairColor(); + hair_flip = store_data.GetHairFlip(); + eye_type = store_data.GetEyeType(); + eye_color = store_data.GetEyeColor(); + eye_scale = store_data.GetEyeScale(); + eye_aspect = store_data.GetEyeAspect(); + eye_rotate = store_data.GetEyeRotate(); + eye_x = store_data.GetEyeX(); + eye_y = store_data.GetEyeY(); + eyebrow_type = store_data.GetEyebrowType(); + eyebrow_color = store_data.GetEyebrowColor(); + eyebrow_scale = store_data.GetEyebrowScale(); + eyebrow_aspect = store_data.GetEyebrowAspect(); + eyebrow_rotate = store_data.GetEyebrowRotate(); + eyebrow_x = store_data.GetEyebrowX(); + eyebrow_y = store_data.GetEyebrowY(); + nose_type = store_data.GetNoseType(); + nose_scale = store_data.GetNoseScale(); + nose_y = store_data.GetNoseY(); + mouth_type = store_data.GetMouthType(); + mouth_color = store_data.GetMouthColor(); + mouth_scale = store_data.GetMouthScale(); + mouth_aspect = store_data.GetMouthAspect(); + mouth_y = store_data.GetMouthY(); + beard_color = store_data.GetBeardColor(); + beard_type = store_data.GetBeardType(); + mustache_type = store_data.GetMustacheType(); + mustache_scale = store_data.GetMustacheScale(); + mustache_y = store_data.GetMustacheY(); + glasses_type = store_data.GetGlassType(); + glasses_color = store_data.GetGlassColor(); + glasses_scale = store_data.GetGlassScale(); + glasses_y = store_data.GetGlassY(); + mole_type = store_data.GetMoleType(); + mole_scale = store_data.GetMoleScale(); + mole_x = store_data.GetMoleX(); + mole_y = store_data.GetMoleY(); + padding = '\0'; +} + +u32 CharInfo::Verify() const { + if (!create_id.IsValid()) { + return 0x32; + } + if (!name.IsValid()) { + return 0x33; + } + if (3 < font_region) { + return 0x17; + } + if (0xb < favorite_color) { + return 0x16; + } + if (1 < gender) { + return 0x18; + } + if (height < 0) { + return 0x20; + } + if (build < 0) { + return 3; + } + if (1 < type) { + return 0x35; + } + if (3 < region_move) { + return 0x31; + } + if (0xb < faceline_type) { + return 0x15; + } + if (9 < faceline_color) { + return 0x12; + } + if (0xb < faceline_wrinkle) { + return 0x14; + } + if (0xb < faceline_make) { + return 0x13; + } + if (0x83 < hair_type) { + return 0x1f; + } + if (99 < hair_color) { + return 0x1d; + } + if (1 < hair_flip) { + return 0x1e; + } + if (0x3b < eye_type) { + return 8; + } + if (99 < eye_color) { + return 5; + } + if (7 < eye_scale) { + return 7; + } + if (6 < eye_aspect) { + return 4; + } + if (7 < eye_rotate) { + return 6; + } + if (0xc < eye_x) { + return 9; + } + if (0x12 < eye_y) { + return 10; + } + if (0x17 < eyebrow_type) { + return 0xf; + } + if (99 < eyebrow_color) { + return 0xc; + } + if (8 < eyebrow_scale) { + return 0xe; + } + if (6 < eyebrow_aspect) { + return 0xb; + } + if (0xb < eyebrow_rotate) { + return 0xd; + } + if (0xc < eyebrow_x) { + return 0x10; + } + if (0xf < eyebrow_y - 3) { + return 0x11; + } + if (0x11 < nose_type) { + return 0x2f; + } + if (nose_scale >= 9) { + return 0x2e; + } + if (0x12 < nose_y) { + return 0x30; + } + if (0x23 < mouth_type) { + return 0x28; + } + if (99 < mouth_color) { + return 0x26; + } + if (8 < mouth_scale) { + return 0x27; + } + if (6 < mouth_aspect) { + return 0x25; + } + if (0x12 < mouth_y) { + return 0x29; + } + if (99 < beard_color) { + return 1; + } + if (5 < beard_type) { + return 2; + } + if (5 < mustache_type) { + return 0x2b; + } + if (8 < mustache_scale) { + return 0x2a; + } + if (0x10 < mustache_y) { + return 0x2c; + } + if (0x13 < glasses_type) { + return 0x1b; + } + if (99 < glasses_color) { + return 0x19; + } + if (7 < glasses_scale) { + return 0x1a; + } + if (0x14 < glasses_y) { + return 0x1c; + } + if (mole_type >= 2) { + return 0x22; + } + if (8 < mole_scale) { + return 0x21; + } + if (mole_x >= 0x11) { + return 0x23; + } + if (0x1e < mole_y) { + return 0x24; + } + return 0; +} + +Common::UUID CharInfo::GetCreateId() const { + return create_id; +} + +Nickname CharInfo::GetNickname() const { + return name; +} + +u8 CharInfo::GetFontRegion() const { + return font_region; +} + +u8 CharInfo::GetFavoriteColor() const { + return favorite_color; +} + +u8 CharInfo::GetGender() const { + return gender; +} + +u8 CharInfo::GetHeight() const { + return height; +} + +u8 CharInfo::GetBuild() const { + return build; +} + +u8 CharInfo::GetType() const { + return type; +} + +u8 CharInfo::GetRegionMove() const { + return region_move; +} + +u8 CharInfo::GetFacelineType() const { + return faceline_type; +} + +u8 CharInfo::GetFacelineColor() const { + return faceline_color; +} + +u8 CharInfo::GetFacelineWrinkle() const { + return faceline_wrinkle; +} + +u8 CharInfo::GetFacelineMake() const { + return faceline_make; +} + +u8 CharInfo::GetHairType() const { + return hair_type; +} + +u8 CharInfo::GetHairColor() const { + return hair_color; +} + +u8 CharInfo::GetHairFlip() const { + return hair_flip; +} + +u8 CharInfo::GetEyeType() const { + return eye_type; +} + +u8 CharInfo::GetEyeColor() const { + return eye_color; +} + +u8 CharInfo::GetEyeScale() const { + return eye_scale; +} + +u8 CharInfo::GetEyeAspect() const { + return eye_aspect; +} + +u8 CharInfo::GetEyeRotate() const { + return eye_rotate; +} + +u8 CharInfo::GetEyeX() const { + return eye_x; +} + +u8 CharInfo::GetEyeY() const { + return eye_y; +} + +u8 CharInfo::GetEyebrowType() const { + return eyebrow_type; +} + +u8 CharInfo::GetEyebrowColor() const { + return eyebrow_color; +} + +u8 CharInfo::GetEyebrowScale() const { + return eyebrow_scale; +} + +u8 CharInfo::GetEyebrowAspect() const { + return eyebrow_aspect; +} + +u8 CharInfo::GetEyebrowRotate() const { + return eyebrow_rotate; +} + +u8 CharInfo::GetEyebrowX() const { + return eyebrow_x; +} + +u8 CharInfo::GetEyebrowY() const { + return eyebrow_y; +} + +u8 CharInfo::GetNoseType() const { + return nose_type; +} + +u8 CharInfo::GetNoseScale() const { + return nose_scale; +} + +u8 CharInfo::GetNoseY() const { + return nose_y; +} + +u8 CharInfo::GetMouthType() const { + return mouth_type; +} + +u8 CharInfo::GetMouthColor() const { + return mouth_color; +} + +u8 CharInfo::GetMouthScale() const { + return mouth_scale; +} + +u8 CharInfo::GetMouthAspect() const { + return mouth_aspect; +} + +u8 CharInfo::GetMouthY() const { + return mouth_y; +} + +u8 CharInfo::GetBeardColor() const { + return beard_color; +} + +u8 CharInfo::GetBeardType() const { + return beard_type; +} + +u8 CharInfo::GetMustacheType() const { + return mustache_type; +} + +u8 CharInfo::GetMustacheScale() const { + return mustache_scale; +} + +u8 CharInfo::GetMustacheY() const { + return mustache_y; +} + +u8 CharInfo::GetGlassType() const { + return glasses_type; +} + +u8 CharInfo::GetGlassColor() const { + return glasses_color; +} + +u8 CharInfo::GetGlassScale() const { + return glasses_scale; +} + +u8 CharInfo::GetGlassY() const { + return glasses_y; +} + +u8 CharInfo::GetMoleType() const { + return mole_type; +} + +u8 CharInfo::GetMoleScale() const { + return mole_scale; +} + +u8 CharInfo::GetMoleX() const { + return mole_x; +} + +u8 CharInfo::GetMoleY() const { + return mole_y; +} + +bool CharInfo::operator==(const CharInfo& info) { + bool is_identical = info.Verify() == 0; + is_identical &= name == info.GetNickname(); + is_identical &= create_id == info.GetCreateId(); + is_identical &= font_region == info.GetFontRegion(); + is_identical &= favorite_color == info.GetFavoriteColor(); + is_identical &= gender == info.GetGender(); + is_identical &= height == info.GetHeight(); + is_identical &= build == info.GetBuild(); + is_identical &= type == info.GetType(); + is_identical &= region_move == info.GetRegionMove(); + is_identical &= faceline_type == info.GetFacelineType(); + is_identical &= faceline_color == info.GetFacelineColor(); + is_identical &= faceline_wrinkle == info.GetFacelineWrinkle(); + is_identical &= faceline_make == info.GetFacelineMake(); + is_identical &= hair_type == info.GetHairType(); + is_identical &= hair_color == info.GetHairColor(); + is_identical &= hair_flip == info.GetHairFlip(); + is_identical &= eye_type == info.GetEyeType(); + is_identical &= eye_color == info.GetEyeColor(); + is_identical &= eye_scale == info.GetEyeScale(); + is_identical &= eye_aspect == info.GetEyeAspect(); + is_identical &= eye_rotate == info.GetEyeRotate(); + is_identical &= eye_x == info.GetEyeX(); + is_identical &= eye_y == info.GetEyeY(); + is_identical &= eyebrow_type == info.GetEyebrowType(); + is_identical &= eyebrow_color == info.GetEyebrowColor(); + is_identical &= eyebrow_scale == info.GetEyebrowScale(); + is_identical &= eyebrow_aspect == info.GetEyebrowAspect(); + is_identical &= eyebrow_rotate == info.GetEyebrowRotate(); + is_identical &= eyebrow_x == info.GetEyebrowX(); + is_identical &= eyebrow_y == info.GetEyebrowY(); + is_identical &= nose_type == info.GetNoseType(); + is_identical &= nose_scale == info.GetNoseScale(); + is_identical &= nose_y == info.GetNoseY(); + is_identical &= mouth_type == info.GetMouthType(); + is_identical &= mouth_color == info.GetMouthColor(); + is_identical &= mouth_scale == info.GetMouthScale(); + is_identical &= mouth_aspect == info.GetMouthAspect(); + is_identical &= mouth_y == info.GetMouthY(); + is_identical &= beard_color == info.GetBeardColor(); + is_identical &= beard_type == info.GetBeardType(); + is_identical &= mustache_type == info.GetMustacheType(); + is_identical &= mustache_scale == info.GetMustacheScale(); + is_identical &= mustache_y == info.GetMustacheY(); + is_identical &= glasses_type == info.GetGlassType(); + is_identical &= glasses_color == info.GetGlassColor(); + is_identical &= glasses_scale == info.GetGlassScale(); + is_identical &= glasses_y == info.GetGlassY(); + is_identical &= mole_type == info.GetMoleType(); + is_identical &= mole_scale == info.GetMoleScale(); + is_identical &= mole_x == info.GetMoleX(); + is_identical &= mole_y == info.GetMoleY(); + return is_identical; +} + +} // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/char_info.h b/src/core/hle/service/mii/types/char_info.h index cdebb1c9d..4f70edc24 100644 --- a/src/core/hle/service/mii/types/char_info.h +++ b/src/core/hle/service/mii/types/char_info.h @@ -6,10 +6,70 @@ #include "core/hle/service/mii/mii_types.h" namespace Service::Mii { +class StoreData; // This is nn::mii::detail::CharInfoRaw class CharInfo { public: + void SetFromStoreData(const StoreData& store_data_raw); + + u32 Verify() const; + + Common::UUID GetCreateId() const; + Nickname GetNickname() const; + u8 GetFontRegion() const; + u8 GetFavoriteColor() const; + u8 GetGender() const; + u8 GetHeight() const; + u8 GetBuild() const; + u8 GetType() const; + u8 GetRegionMove() const; + u8 GetFacelineType() const; + u8 GetFacelineColor() const; + u8 GetFacelineWrinkle() const; + u8 GetFacelineMake() const; + u8 GetHairType() const; + u8 GetHairColor() const; + u8 GetHairFlip() const; + u8 GetEyeType() const; + u8 GetEyeColor() const; + u8 GetEyeScale() const; + u8 GetEyeAspect() const; + u8 GetEyeRotate() const; + u8 GetEyeX() const; + u8 GetEyeY() const; + u8 GetEyebrowType() const; + u8 GetEyebrowColor() const; + u8 GetEyebrowScale() const; + u8 GetEyebrowAspect() const; + u8 GetEyebrowRotate() const; + u8 GetEyebrowX() const; + u8 GetEyebrowY() const; + u8 GetNoseType() const; + u8 GetNoseScale() const; + u8 GetNoseY() const; + u8 GetMouthType() const; + u8 GetMouthColor() const; + u8 GetMouthScale() const; + u8 GetMouthAspect() const; + u8 GetMouthY() const; + u8 GetBeardColor() const; + u8 GetBeardType() const; + u8 GetMustacheType() const; + u8 GetMustacheScale() const; + u8 GetMustacheY() const; + u8 GetGlassType() const; + u8 GetGlassColor() const; + u8 GetGlassScale() const; + u8 GetGlassY() const; + u8 GetMoleType() const; + u8 GetMoleScale() const; + u8 GetMoleX() const; + u8 GetMoleY() const; + + bool operator==(const CharInfo& info); + +private: Common::UUID create_id; Nickname name; u16 null_terminator; From 571399930cc3578acff064a7087fe85e7b2dd9b7 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 11 Sep 2023 00:23:46 -0600 Subject: [PATCH 08/11] service: mii: Fix ver3 inconsistencies --- src/core/hle/service/mii/mii_manager.cpp | 17 +- src/core/hle/service/mii/mii_manager.h | 3 - src/core/hle/service/mii/mii_types.h | 16 - src/core/hle/service/mii/types/char_info.cpp | 2 +- src/core/hle/service/mii/types/store_data.cpp | 202 ++++++++++++- src/core/hle/service/mii/types/store_data.h | 54 +++- .../hle/service/mii/types/ver3_store_data.cpp | 280 ++++++++++-------- .../hle/service/mii/types/ver3_store_data.h | 80 ++--- src/core/hle/service/nfc/common/device.cpp | 16 +- 9 files changed, 463 insertions(+), 207 deletions(-) diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 2137a9af1..3951e0b9c 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -98,23 +98,12 @@ CharInfo MiiManager::BuildDefault(std::size_t index) { CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { CharInfo char_info{}; - mii_v3.BuildToStoreData(char_info); + StoreData store_data{}; + mii_v3.BuildToStoreData(store_data); + char_info.SetFromStoreData(store_data); return char_info; } -NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { - return { - .faceline_color = static_cast(mii.GetFacelineColor() & 0xf), - .hair_color = static_cast(mii.GetHairColor() & 0x7f), - .eye_color = static_cast(mii.GetEyeColor() & 0x7f), - .eyebrow_color = static_cast(mii.GetEyebrowColor() & 0x7f), - .mouth_color = static_cast(mii.GetMouthColor() & 0x7f), - .beard_color = static_cast(mii.GetBeardColor() & 0x7f), - .glass_color = static_cast(mii.GetGlassColor() & 0x7f), - .glass_type = static_cast(mii.GetGlassType() & 0x1f), - }; -} - 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 0a47e613f..6098474e9 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h @@ -30,9 +30,6 @@ public: std::vector GetDefault(SourceFlag source_flag); Result GetIndex(const CharInfo& info, u32& index); - // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData - NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const; - struct MiiDatabase { u32 magic{}; // 'NFDB' std::array miis{}; diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index 20d4e40ab..d62005f61 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -108,25 +108,9 @@ struct Nickname { } return index == MaxNameSize; } - - bool operator==(const Nickname& name) { - return data == name.data; - }; }; static_assert(sizeof(Nickname) == 0x14, "Nickname 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"); - struct DefaultMii { u32 face_type{}; u32 face_color{}; diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp index e1d874860..0f9c37b84 100644 --- a/src/core/hle/service/mii/types/char_info.cpp +++ b/src/core/hle/service/mii/types/char_info.cpp @@ -425,7 +425,7 @@ u8 CharInfo::GetMoleY() const { bool CharInfo::operator==(const CharInfo& info) { bool is_identical = info.Verify() == 0; - is_identical &= name == info.GetNickname(); + is_identical &= name.data == info.GetNickname().data; is_identical &= create_id == info.GetCreateId(); is_identical &= font_region == info.GetFontRegion(); is_identical &= favorite_color == info.GetFavoriteColor(); diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp index 72c8fa2e9..91dfd3271 100644 --- a/src/core/hle/service/mii/types/store_data.cpp +++ b/src/core/hle/service/mii/types/store_data.cpp @@ -180,6 +180,206 @@ u32 StoreData::IsValid() const { return 0; } +void StoreData::SetFontRegion(FontRegion value) { + core_data.SetFontRegion(value); +} + +void StoreData::SetFavoriteColor(u8 value) { + core_data.SetFavoriteColor(value); +} + +void StoreData::SetGender(Gender value) { + core_data.SetGender(value); +} + +void StoreData::SetHeight(u8 value) { + core_data.SetHeight(value); +} + +void StoreData::SetBuild(u8 value) { + core_data.SetBuild(value); +} + +void StoreData::SetType(u8 value) { + core_data.SetType(value); +} + +void StoreData::SetRegionMove(u8 value) { + core_data.SetRegionMove(value); +} + +void StoreData::SetFacelineType(u8 value) { + core_data.SetFacelineType(value); +} + +void StoreData::SetFacelineColor(u8 value) { + core_data.SetFacelineColor(value); +} + +void StoreData::SetFacelineWrinkle(u8 value) { + core_data.SetFacelineWrinkle(value); +} + +void StoreData::SetFacelineMake(u8 value) { + core_data.SetFacelineMake(value); +} + +void StoreData::SetHairType(u8 value) { + core_data.SetHairType(value); +} + +void StoreData::SetHairColor(u8 value) { + core_data.SetHairColor(value); +} + +void StoreData::SetHairFlip(HairFlip value) { + core_data.SetHairFlip(value); +} + +void StoreData::SetEyeType(u8 value) { + core_data.SetEyeType(value); +} + +void StoreData::SetEyeColor(u8 value) { + core_data.SetEyeColor(value); +} + +void StoreData::SetEyeScale(u8 value) { + core_data.SetEyeScale(value); +} + +void StoreData::SetEyeAspect(u8 value) { + core_data.SetEyeAspect(value); +} + +void StoreData::SetEyeRotate(u8 value) { + core_data.SetEyeRotate(value); +} + +void StoreData::SetEyeX(u8 value) { + core_data.SetEyeX(value); +} + +void StoreData::SetEyeY(u8 value) { + core_data.SetEyeY(value); +} + +void StoreData::SetEyebrowType(u8 value) { + core_data.SetEyebrowType(value); +} + +void StoreData::SetEyebrowColor(u8 value) { + core_data.SetEyebrowColor(value); +} + +void StoreData::SetEyebrowScale(u8 value) { + core_data.SetEyebrowScale(value); +} + +void StoreData::SetEyebrowAspect(u8 value) { + core_data.SetEyebrowAspect(value); +} + +void StoreData::SetEyebrowRotate(u8 value) { + core_data.SetEyebrowRotate(value); +} + +void StoreData::SetEyebrowX(u8 value) { + core_data.SetEyebrowX(value); +} + +void StoreData::SetEyebrowY(u8 value) { + core_data.SetEyebrowY(value); +} + +void StoreData::SetNoseType(u8 value) { + core_data.SetNoseType(value); +} + +void StoreData::SetNoseScale(u8 value) { + core_data.SetNoseScale(value); +} + +void StoreData::SetNoseY(u8 value) { + core_data.SetNoseY(value); +} + +void StoreData::SetMouthType(u8 value) { + core_data.SetMouthType(value); +} + +void StoreData::SetMouthColor(u8 value) { + core_data.SetMouthColor(value); +} + +void StoreData::SetMouthScale(u8 value) { + core_data.SetMouthScale(value); +} + +void StoreData::SetMouthAspect(u8 value) { + core_data.SetMouthAspect(value); +} + +void StoreData::SetMouthY(u8 value) { + core_data.SetMouthY(value); +} + +void StoreData::SetBeardColor(u8 value) { + core_data.SetBeardColor(value); +} + +void StoreData::SetBeardType(BeardType value) { + core_data.SetBeardType(value); +} + +void StoreData::SetMustacheType(MustacheType value) { + core_data.SetMustacheType(value); +} + +void StoreData::SetMustacheScale(u8 value) { + core_data.SetMustacheScale(value); +} + +void StoreData::SetMustacheY(u8 value) { + core_data.SetMustacheY(value); +} + +void StoreData::SetGlassType(u8 value) { + core_data.SetGlassType(value); +} + +void StoreData::SetGlassColor(u8 value) { + core_data.SetGlassColor(value); +} + +void StoreData::SetGlassScale(u8 value) { + core_data.SetGlassScale(value); +} + +void StoreData::SetGlassY(u8 value) { + core_data.SetGlassY(value); +} + +void StoreData::SetMoleType(u8 value) { + core_data.SetMoleType(value); +} + +void StoreData::SetMoleScale(u8 value) { + core_data.SetMoleScale(value); +} + +void StoreData::SetMoleX(u8 value) { + core_data.SetMoleX(value); +} + +void StoreData::SetMoleY(u8 value) { + core_data.SetMoleY(value); +} + +void StoreData::SetNickname(Nickname value) { + core_data.SetNickname(value); +} + Common::UUID StoreData::GetCreateId() const { return create_id; } @@ -386,7 +586,7 @@ Nickname StoreData::GetNickname() const { bool StoreData::operator==(const StoreData& data) { bool is_identical = data.core_data.IsValid() == 0; - is_identical &= core_data.GetNickname() == data.core_data.GetNickname(); + is_identical &= core_data.GetNickname().data == data.core_data.GetNickname().data; is_identical &= GetCreateId() == data.GetCreateId(); is_identical &= GetFontRegion() == data.GetFontRegion(); is_identical &= GetFavoriteColor() == data.GetFavoriteColor(); diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h index cc8551a66..1e010000b 100644 --- a/src/core/hle/service/mii/types/store_data.h +++ b/src/core/hle/service/mii/types/store_data.h @@ -18,12 +18,62 @@ public: // nn::mii::detail::StoreDataRaw::BuildRandom void BuildRandom(Age age, Gender gender, Race race); - void SetInvalidName(); - bool IsSpecial() const; u32 IsValid() const; + void SetFontRegion(FontRegion value); + void SetFavoriteColor(u8 value); + void SetGender(Gender value); + void SetHeight(u8 value); + void SetBuild(u8 value); + void SetType(u8 value); + void SetRegionMove(u8 value); + void SetFacelineType(u8 value); + void SetFacelineColor(u8 value); + void SetFacelineWrinkle(u8 value); + void SetFacelineMake(u8 value); + void SetHairType(u8 value); + void SetHairColor(u8 value); + void SetHairFlip(HairFlip value); + void SetEyeType(u8 value); + void SetEyeColor(u8 value); + void SetEyeScale(u8 value); + void SetEyeAspect(u8 value); + void SetEyeRotate(u8 value); + void SetEyeX(u8 value); + void SetEyeY(u8 value); + void SetEyebrowType(u8 value); + void SetEyebrowColor(u8 value); + void SetEyebrowScale(u8 value); + void SetEyebrowAspect(u8 value); + void SetEyebrowRotate(u8 value); + void SetEyebrowX(u8 value); + void SetEyebrowY(u8 value); + void SetNoseType(u8 value); + void SetNoseScale(u8 value); + void SetNoseY(u8 value); + void SetMouthType(u8 value); + void SetMouthColor(u8 value); + void SetMouthScale(u8 value); + void SetMouthAspect(u8 value); + void SetMouthY(u8 value); + void SetBeardColor(u8 value); + void SetBeardType(BeardType value); + void SetMustacheType(MustacheType value); + void SetMustacheScale(u8 value); + void SetMustacheY(u8 value); + void SetGlassType(u8 value); + void SetGlassColor(u8 value); + void SetGlassScale(u8 value); + void SetGlassY(u8 value); + void SetMoleType(u8 value); + void SetMoleScale(u8 value); + void SetMoleX(u8 value); + void SetMoleY(u8 value); + void SetNickname(Nickname nickname); + void SetInvalidName(); + Common::UUID GetCreateId() const; FontRegion GetFontRegion() const; u8 GetFavoriteColor() const; 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 c774f4b47..53a3fe44b 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.cpp +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp @@ -2,160 +2,180 @@ // 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 { -void Ver3StoreData::BuildToStoreData(CharInfo& out_char_info) const { +void NfpStoreDataExtension::SetFromStoreData(const StoreData& store_data) { + faceline_color = static_cast(store_data.GetFacelineColor() & 0xf); + hair_color = static_cast(store_data.GetHairColor() & 0x7f); + eye_color = static_cast(store_data.GetEyeColor() & 0x7f); + eyebrow_color = static_cast(store_data.GetEyebrowColor() & 0x7f); + mouth_color = static_cast(store_data.GetMouthColor() & 0x7f); + beard_color = static_cast(store_data.GetBeardColor() & 0x7f); + glass_color = static_cast(store_data.GetGlassColor() & 0x7f); + glass_type = static_cast(store_data.GetGlassType() & 0x1f); +} + +void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { + out_store_data.BuildBase(Gender::Male); + 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; + out_store_data.SetGender(static_cast(static_cast(mii_information.gender))); + out_store_data.SetFavoriteColor(static_cast(mii_information.favorite_color)); + out_store_data.SetHeight(height); + out_store_data.SetBuild(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) { + Nickname name = {}; + for (std::size_t index = 0; index < name.data.size() - 1; index++) { + name.data[index] = mii_name[index]; + if (name.data[index] == 0) { break; } } - out_char_info.font_region = region_information.character_set; + out_store_data.SetNickname(name); + out_store_data.SetFontRegion( + static_cast(static_cast(region_information.font_region))); - 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_store_data.SetFacelineType(appearance_bits1.faceline_type); + out_store_data.SetFacelineColor(appearance_bits1.faceline_color); + out_store_data.SetFacelineWrinkle(appearance_bits2.faceline_wrinkle); + out_store_data.SetFacelineMake(appearance_bits2.faceline_make); - 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_store_data.SetHairType(hair_type); + out_store_data.SetHairColor(appearance_bits3.hair_color); + out_store_data.SetHairFlip(static_cast(static_cast(appearance_bits3.hair_flip))); - 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_store_data.SetEyeType(static_cast(appearance_bits4.eye_type)); + out_store_data.SetEyeColor(static_cast(appearance_bits4.eye_color)); + out_store_data.SetEyeScale(static_cast(appearance_bits4.eye_scale)); + out_store_data.SetEyeAspect(static_cast(appearance_bits4.eye_aspect)); + out_store_data.SetEyeRotate(static_cast(appearance_bits4.eye_rotate)); + out_store_data.SetEyeX(static_cast(appearance_bits4.eye_x)); + out_store_data.SetEyeY(static_cast(appearance_bits4.eye_y)); - 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_store_data.SetEyebrowType(static_cast(appearance_bits5.eyebrow_type)); + out_store_data.SetEyebrowColor(static_cast(appearance_bits5.eyebrow_color)); + out_store_data.SetEyebrowScale(static_cast(appearance_bits5.eyebrow_scale)); + out_store_data.SetEyebrowAspect(static_cast(appearance_bits5.eyebrow_aspect)); + out_store_data.SetEyebrowRotate(static_cast(appearance_bits5.eyebrow_rotate)); + out_store_data.SetEyebrowX(static_cast(appearance_bits5.eyebrow_x)); + out_store_data.SetEyebrowY(static_cast(appearance_bits5.eyebrow_y)); - 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_store_data.SetNoseType(static_cast(appearance_bits6.nose_type)); + out_store_data.SetNoseScale(static_cast(appearance_bits6.nose_scale)); + out_store_data.SetNoseY(static_cast(appearance_bits6.nose_y)); - 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_store_data.SetMouthType(static_cast(appearance_bits7.mouth_type)); + out_store_data.SetMouthColor(static_cast(appearance_bits7.mouth_color)); + out_store_data.SetMouthScale(static_cast(appearance_bits7.mouth_scale)); + out_store_data.SetMouthAspect(static_cast(appearance_bits7.mouth_aspect)); + out_store_data.SetMouthY(static_cast(appearance_bits8.mouth_y)); - 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_store_data.SetMustacheType( + static_cast(static_cast(appearance_bits8.mustache_type))); + out_store_data.SetMustacheScale(static_cast(appearance_bits9.mustache_scale)); + out_store_data.SetMustacheY(static_cast(appearance_bits9.mustache_y)); - out_char_info.beard_type = static_cast(appearance_bits9.bear_type); - out_char_info.beard_color = static_cast(appearance_bits9.facial_hair_color); + out_store_data.SetBeardType( + static_cast(static_cast(appearance_bits9.beard_type))); + out_store_data.SetBeardColor(static_cast(appearance_bits9.beard_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_store_data.SetGlassType(static_cast(appearance_bits10.glass_type)); + out_store_data.SetGlassColor(static_cast(appearance_bits10.glass_color)); + out_store_data.SetGlassScale(static_cast(appearance_bits10.glass_scale)); + out_store_data.SetGlassY(static_cast(appearance_bits10.glass_y)); - 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); + out_store_data.SetMoleType(static_cast(appearance_bits11.mole_type)); + out_store_data.SetMoleScale(static_cast(appearance_bits11.mole_scale)); + out_store_data.SetMoleX(static_cast(appearance_bits11.mole_x)); + out_store_data.SetMoleY(static_cast(appearance_bits11.mole_y)); } -void Ver3StoreData::BuildFromStoreData(const CharInfo& char_info) { +void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { 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; + mii_information.gender.Assign(store_data.GetGender()); + mii_information.favorite_color.Assign(store_data.GetFavoriteColor()); + height = store_data.GetHeight(); + build = store_data.GetBuild(); // 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]; + for (std::size_t index = 0; index < store_data.GetNickname().data.size() - 1; index++) { + mii_name[index] = store_data.GetNickname().data[index]; if (mii_name[index] == 0) { break; } } - region_information.character_set.Assign(char_info.font_region); + region_information.font_region.Assign(static_cast(store_data.GetFontRegion())); - 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); + appearance_bits1.faceline_type.Assign(store_data.GetFacelineType()); + appearance_bits2.faceline_wrinkle.Assign(store_data.GetFacelineWrinkle()); + appearance_bits2.faceline_make.Assign(store_data.GetFacelineMake()); - hair_style = char_info.hair_type; - appearance_bits3.flip_hair.Assign(char_info.hair_flip); + hair_type = store_data.GetHairType(); + appearance_bits3.hair_flip.Assign(store_data.GetHairFlip()); - 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_bits4.eye_type.Assign(store_data.GetEyeType()); + appearance_bits4.eye_scale.Assign(store_data.GetEyeScale()); + appearance_bits4.eye_aspect.Assign(store_data.GetEyebrowAspect()); + appearance_bits4.eye_rotate.Assign(store_data.GetEyeRotate()); + appearance_bits4.eye_x.Assign(store_data.GetEyeX()); + appearance_bits4.eye_y.Assign(store_data.GetEyeY()); - 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_bits5.eyebrow_type.Assign(store_data.GetEyebrowType()); + appearance_bits5.eyebrow_scale.Assign(store_data.GetEyebrowScale()); + appearance_bits5.eyebrow_aspect.Assign(store_data.GetEyebrowAspect()); + appearance_bits5.eyebrow_rotate.Assign(store_data.GetEyebrowRotate()); + appearance_bits5.eyebrow_x.Assign(store_data.GetEyebrowX()); + appearance_bits5.eyebrow_y.Assign(store_data.GetEyebrowY()); - 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_bits6.nose_type.Assign(store_data.GetNoseType()); + appearance_bits6.nose_scale.Assign(store_data.GetNoseScale()); + appearance_bits6.nose_y.Assign(store_data.GetNoseY()); - 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_bits7.mouth_type.Assign(store_data.GetMouthType()); + appearance_bits7.mouth_scale.Assign(store_data.GetMouthScale()); + appearance_bits7.mouth_aspect.Assign(store_data.GetMouthAspect()); + appearance_bits8.mouth_y.Assign(store_data.GetMouthY()); - 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_bits8.mustache_type.Assign(store_data.GetMustacheType()); + appearance_bits9.mustache_scale.Assign(store_data.GetMustacheScale()); + appearance_bits9.mustache_y.Assign(store_data.GetMustacheY()); - appearance_bits9.bear_type.Assign(char_info.beard_type); + appearance_bits9.beard_type.Assign(store_data.GetBeardType()); - appearance_bits10.glasses_scale.Assign(char_info.glasses_scale); - appearance_bits10.glasses_y_position.Assign(char_info.glasses_y); + appearance_bits10.glass_scale.Assign(store_data.GetGlassScale()); + appearance_bits10.glass_y.Assign(store_data.GetGlassY()); - 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); + appearance_bits11.mole_type.Assign(store_data.GetMoleType()); + appearance_bits11.mole_scale.Assign(store_data.GetMoleScale()); + appearance_bits11.mole_x.Assign(store_data.GetMoleX()); + appearance_bits11.mole_y.Assign(store_data.GetMoleY()); // 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)); + appearance_bits1.faceline_color.Assign( + RawData::FromVer3GetFacelineColor(store_data.GetFacelineColor())); + appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(store_data.GetHairColor())); + appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(store_data.GetEyeColor())); + appearance_bits5.eyebrow_color.Assign( + RawData::FromVer3GetHairColor(store_data.GetEyebrowColor())); + appearance_bits7.mouth_color.Assign( + RawData::FromVer3GetMouthlineColor(store_data.GetMouthColor())); + appearance_bits9.beard_color.Assign(RawData::FromVer3GetHairColor(store_data.GetBeardColor())); + appearance_bits10.glass_color.Assign( + RawData::FromVer3GetGlassColor(store_data.GetGlassColor())); + appearance_bits10.glass_type.Assign(RawData::FromVer3GetGlassType(store_data.GetGlassType())); crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); } @@ -171,56 +191,56 @@ u32 Ver3StoreData::IsValid() const { 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 && (appearance_bits1.faceline_type < 12); + is_valid = is_valid && (appearance_bits1.faceline_color < 7); + is_valid = is_valid && (appearance_bits2.faceline_wrinkle < 12); + is_valid = is_valid && (appearance_bits2.faceline_make < 12); - is_valid = is_valid && (hair_style < 132); + is_valid = is_valid && (hair_type < 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_bits4.eye_aspect < 7); + is_valid = is_valid && (appearance_bits4.eye_rotate < 8); + is_valid = is_valid && (appearance_bits4.eye_x < 13); + is_valid = is_valid && (appearance_bits4.eye_y < 19); - is_valid = is_valid && (appearance_bits5.eyebrow_style < 25); + is_valid = is_valid && (appearance_bits5.eyebrow_type < 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_bits5.eyebrow_aspect < 7); + is_valid = is_valid && (appearance_bits5.eyebrow_rotate < 12); + is_valid = is_valid && (appearance_bits5.eyebrow_x < 12); + is_valid = is_valid && (appearance_bits5.eyebrow_y < 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_bits6.nose_y < 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_bits7.mouth_aspect < 7); + is_valid = is_valid && (appearance_bits8.mouth_y < 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.mustache_y < 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_bits9.beard_type < 6); + is_valid = is_valid && (appearance_bits9.beard_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_bits10.glass_type < 9); + is_valid = is_valid && (appearance_bits10.glass_color < 6); + is_valid = is_valid && (appearance_bits10.glass_scale < 8); + is_valid = is_valid && (appearance_bits10.glass_y < 21); - is_valid = is_valid && (appearance_bits11.mole_enabled < 2); + is_valid = is_valid && (appearance_bits11.mole_type < 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); + is_valid = is_valid && (appearance_bits11.mole_x < 17); + is_valid = is_valid && (appearance_bits11.mole_y < 31); return is_valid; } 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 6b4e1eb9c..11caeb5c3 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.h +++ b/src/core/hle/service/mii/types/ver3_store_data.h @@ -6,20 +6,32 @@ #include "core/hle/service/mii/mii_types.h" namespace Service::Mii { -class CharInfo; +class StoreData; // This is nn::mii::Ver3StoreData // Based on citra HLE::Applets::MiiData and PretendoNetwork. // https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 // https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 +struct NfpStoreDataExtension { + void SetFromStoreData(const StoreData& store_data); + + 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"); + #pragma pack(push, 4) 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); + void BuildToStoreData(StoreData& out_store_data) const; + void BuildFromStoreData(const StoreData& store_data); u32 IsValid() const; @@ -30,7 +42,7 @@ public: BitField<0, 1, u8> allow_copying; BitField<1, 1, u8> profanity_flag; BitField<2, 2, u8> region_lock; - BitField<4, 2, u8> character_set; + BitField<4, 2, u8> font_region; } region_information; u16_be mii_id; u64_be system_id; @@ -53,21 +65,21 @@ public: u8 raw; BitField<0, 1, u8> disable_sharing; - BitField<1, 4, u8> face_shape; - BitField<5, 3, u8> skin_color; + BitField<1, 4, u8> faceline_type; + BitField<5, 3, u8> faceline_color; } appearance_bits1; union { u8 raw; - BitField<0, 4, u8> wrinkles; - BitField<4, 4, u8> makeup; + BitField<0, 4, u8> faceline_wrinkle; + BitField<4, 4, u8> faceline_make; } appearance_bits2; - u8 hair_style; + u8 hair_type; union { u8 raw; BitField<0, 3, u8> hair_color; - BitField<3, 1, u8> flip_hair; + BitField<3, 1, u8> hair_flip; } appearance_bits3; union { u32 raw; @@ -75,28 +87,28 @@ public: BitField<0, 6, u32> eye_type; BitField<6, 3, u32> eye_color; BitField<9, 4, u32> eye_scale; - BitField<13, 3, u32> eye_vertical_stretch; - BitField<16, 5, u32> eye_rotation; - BitField<21, 4, u32> eye_spacing; - BitField<25, 5, u32> eye_y_position; + BitField<13, 3, u32> eye_aspect; + BitField<16, 5, u32> eye_rotate; + BitField<21, 4, u32> eye_x; + BitField<25, 5, u32> eye_y; } appearance_bits4; union { u32 raw; - BitField<0, 5, u32> eyebrow_style; + BitField<0, 5, u32> eyebrow_type; BitField<5, 3, u32> eyebrow_color; BitField<8, 4, u32> eyebrow_scale; - BitField<12, 3, u32> eyebrow_yscale; - BitField<16, 4, u32> eyebrow_rotation; - BitField<21, 4, u32> eyebrow_spacing; - BitField<25, 5, u32> eyebrow_y_position; + BitField<12, 3, u32> eyebrow_aspect; + BitField<16, 4, u32> eyebrow_rotate; + BitField<21, 4, u32> eyebrow_x; + BitField<25, 5, u32> eyebrow_y; } appearance_bits5; union { u16 raw; BitField<0, 5, u16> nose_type; BitField<5, 4, u16> nose_scale; - BitField<9, 5, u16> nose_y_position; + BitField<9, 5, u16> nose_y; } appearance_bits6; union { u16 raw; @@ -104,38 +116,38 @@ public: BitField<0, 6, u16> mouth_type; BitField<6, 3, u16> mouth_color; BitField<9, 4, u16> mouth_scale; - BitField<13, 3, u16> mouth_horizontal_stretch; + BitField<13, 3, u16> mouth_aspect; } appearance_bits7; union { u8 raw; - BitField<0, 5, u8> mouth_y_position; + BitField<0, 5, u8> mouth_y; BitField<5, 3, u8> mustache_type; } appearance_bits8; u8 allow_copying; union { u16 raw; - BitField<0, 3, u16> bear_type; - BitField<3, 3, u16> facial_hair_color; + BitField<0, 3, u16> beard_type; + BitField<3, 3, u16> beard_color; BitField<6, 4, u16> mustache_scale; - BitField<10, 5, u16> mustache_y_position; + BitField<10, 5, u16> mustache_y; } appearance_bits9; union { u16 raw; - BitField<0, 4, u16> glasses_type; - BitField<4, 3, u16> glasses_color; - BitField<7, 4, u16> glasses_scale; - BitField<11, 5, u16> glasses_y_position; + BitField<0, 4, u16> glass_type; + BitField<4, 3, u16> glass_color; + BitField<7, 4, u16> glass_scale; + BitField<11, 5, u16> glass_y; } appearance_bits10; union { u16 raw; - BitField<0, 1, u16> mole_enabled; + BitField<0, 1, u16> mole_type; BitField<1, 4, u16> mole_scale; - BitField<5, 5, u16> mole_x_position; - BitField<10, 5, u16> mole_y_position; + BitField<5, 5, u16> mole_x; + BitField<10, 5, u16> mole_y; } appearance_bits11; std::array author_name; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 5e61d2595..eb7706015 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -824,8 +824,11 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe return ResultWrongDeviceState; } - Service::Mii::MiiManager manager; - const auto mii = manager.BuildBase(Mii::Gender::Male); + Service::Mii::StoreData store_data{}; + Service::Mii::NfpStoreDataExtension extension{}; + store_data.BuildBase(Mii::Gender::Male); + extension.SetFromStoreData(store_data); + auto& settings = tag_data.settings; if (tag_data.settings.settings.amiibo_initialized == 0) { @@ -834,8 +837,8 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe } SetAmiiboName(settings, register_info.amiibo_name); - tag_data.owner_mii.BuildFromStoreData(mii); - tag_data.mii_extension = manager.SetFromStoreData(mii); + tag_data.owner_mii.BuildFromStoreData(store_data); + tag_data.mii_extension = extension; tag_data.unknown = 0; tag_data.unknown2 = {}; settings.country_code_id = 0; @@ -1452,7 +1455,7 @@ void NfcDevice::UpdateRegisterInfoCrc() { void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, const NFP::EncryptedNTAG215File& encrypted_file) const { - Service::Mii::MiiManager manager; + Service::Mii::StoreData store_data{}; auto& settings = stubbed_tag_data.settings; stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file); @@ -1466,7 +1469,8 @@ 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.BuildFromStoreData(manager.BuildBase(Mii::Gender::Male)); + store_data.BuildBase(Mii::Gender::Male); + stubbed_tag_data.owner_mii.BuildFromStoreData(store_data); // Admin info settings.settings.amiibo_initialized.Assign(1); From bd169f417f471f574784fa3b499f57ad42cf1013 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 11 Sep 2023 00:58:46 -0600 Subject: [PATCH 09/11] mii: Prepare Interface for new implementation --- .../service/am/applets/applet_mii_edit.cpp | 11 +- src/core/hle/service/mii/mii.cpp | 128 +++++++------- src/core/hle/service/mii/mii_manager.cpp | 162 +++++++++++------- src/core/hle/service/mii/mii_manager.h | 29 +++- src/core/hle/service/mii/mii_types.h | 10 ++ src/core/hle/service/nfc/common/device.cpp | 8 +- 6 files changed, 210 insertions(+), 138 deletions(-) diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp index f8e2bac32..350a90818 100644 --- a/src/core/hle/service/am/applets/applet_mii_edit.cpp +++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp @@ -85,15 +85,18 @@ void MiiEdit::Execute() { break; case MiiEditAppletMode::CreateMii: case MiiEditAppletMode::EditMii: { - Service::Mii::MiiManager mii_manager; + Mii::CharInfo char_info{}; + Mii::StoreData store_data{}; + store_data.BuildBase(Mii::Gender::Male); + char_info.SetFromStoreData(store_data); - const MiiEditCharInfo char_info{ + const MiiEditCharInfo edit_char_info{ .mii_info{applet_input_common.applet_mode == MiiEditAppletMode::EditMii ? applet_input_v4.char_info.mii_info - : mii_manager.BuildBase(Mii::Gender::Male)}, + : char_info}, }; - MiiEditOutputForCharInfoEditing(MiiEditResult::Success, char_info); + MiiEditOutputForCharInfoEditing(MiiEditResult::Success, edit_char_info); break; } default: diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 680f06beb..653c36740 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -15,8 +15,8 @@ namespace Service::Mii { class IDatabaseService final : public ServiceFramework { public: - explicit IDatabaseService(Core::System& system_) - : ServiceFramework{system_, "IDatabaseService"} { + explicit IDatabaseService(Core::System& system_, bool is_system_) + : ServiceFramework{system_, "IDatabaseService"}, is_system{is_system_} { // clang-format off static const FunctionInfo functions[] = { {0, &IDatabaseService::IsUpdated, "IsUpdated"}, @@ -53,34 +53,27 @@ public: } private: - template - std::vector SerializeArray(const std::vector& values) { - std::vector out(values.size() * sizeof(T)); - std::size_t offset{}; - for (const auto& value : values) { - std::memcpy(out.data() + offset, &value, sizeof(T)); - offset += sizeof(T); - } - return out; - } - void IsUpdated(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto source_flag{rp.PopRaw()}; LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); + const bool is_updated = manager.IsUpdated(metadata, source_flag); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(manager.CheckAndResetUpdateCounter(source_flag, current_update_counter)); + rb.Push(is_updated); } void IsFullDatabase(HLERequestContext& ctx) { LOG_DEBUG(Service_Mii, "called"); + const bool is_full_database = manager.IsFullDatabase(); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(manager.IsFullDatabase()); + rb.Push(is_full_database); } void GetCount(HLERequestContext& ctx) { @@ -89,57 +82,63 @@ private: LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); + const u32 mii_count = manager.GetCount(metadata, source_flag); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(manager.GetCount(source_flag)); + rb.Push(mii_count); } void Get(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto source_flag{rp.PopRaw()}; + const auto output_size{ctx.GetWriteBufferNumElements()}; - LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); + LOG_DEBUG(Service_Mii, "called with source_flag={}, out_size={}", source_flag, output_size); - const auto default_miis{manager.GetDefault(source_flag)}; - if (default_miis.size() > 0) { - ctx.WriteBuffer(SerializeArray(default_miis)); + u32 mii_count{}; + std::vector char_info_elements(output_size); + Result result = manager.Get(metadata, char_info_elements, mii_count, source_flag); + + if (mii_count != 0) { + ctx.WriteBuffer(char_info_elements); } IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(default_miis.size())); + rb.Push(result); + rb.Push(mii_count); } void Get1(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto source_flag{rp.PopRaw()}; + const auto output_size{ctx.GetWriteBufferNumElements()}; - LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); + LOG_DEBUG(Service_Mii, "called with source_flag={}, out_size={}", source_flag, output_size); - const auto default_miis{manager.GetDefault(source_flag)}; + u32 mii_count{}; + std::vector char_info(output_size); + Result result = manager.Get(metadata, char_info, mii_count, source_flag); - std::vector values; - for (const auto& element : default_miis) { - values.emplace_back(element.char_info); + if (mii_count != 0) { + ctx.WriteBuffer(char_info); } - ctx.WriteBuffer(SerializeArray(values)); - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(static_cast(default_miis.size())); + rb.Push(result); + rb.Push(mii_count); } void UpdateLatest(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto info{rp.PopRaw()}; + const auto char_info{rp.PopRaw()}; const auto source_flag{rp.PopRaw()}; LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag); CharInfo new_char_info{}; - const auto result{manager.UpdateLatest(&new_char_info, info, source_flag)}; - if (result != ResultSuccess) { + const auto result = manager.UpdateLatest(metadata, new_char_info, char_info, source_flag); + if (result.IsFailure()) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); return; @@ -152,7 +151,6 @@ private: void BuildRandom(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto age{rp.PopRaw()}; const auto gender{rp.PopRaw()}; const auto race{rp.PopRaw()}; @@ -162,46 +160,47 @@ private: if (age > Age::All) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultInvalidArgument); - LOG_ERROR(Service_Mii, "invalid age={}", age); return; } if (gender > Gender::All) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultInvalidArgument); - LOG_ERROR(Service_Mii, "invalid gender={}", gender); return; } if (race > Race::All) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultInvalidArgument); - LOG_ERROR(Service_Mii, "invalid race={}", race); return; } + CharInfo char_info{}; + manager.BuildRandom(char_info, age, gender, race); + IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(ResultSuccess); - rb.PushRaw(manager.BuildRandom(age, gender, race)); + rb.PushRaw(char_info); } void BuildDefault(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto index{rp.Pop()}; - LOG_DEBUG(Service_Mii, "called with index={}", index); + LOG_INFO(Service_Mii, "called with index={}", index); if (index > 5) { - LOG_ERROR(Service_Mii, "invalid argument, index cannot be greater than 5 but is {:08X}", - index); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultInvalidArgument); return; } + CharInfo char_info{}; + manager.BuildDefault(char_info, index); + IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(ResultSuccess); - rb.PushRaw(manager.BuildDefault(index)); + rb.PushRaw(char_info); } void GetIndex(HLERequestContext& ctx) { @@ -210,19 +209,21 @@ private: LOG_DEBUG(Service_Mii, "called"); - u32 index{}; + s32 index{}; + const Result result = manager.GetIndex(metadata, info, index); + IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(manager.GetIndex(info, index)); + rb.Push(result); rb.Push(index); } void SetInterfaceVersion(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - current_interface_version = rp.PopRaw(); + const auto interface_version{rp.PopRaw()}; - LOG_DEBUG(Service_Mii, "called, interface_version={:08X}", current_interface_version); + LOG_INFO(Service_Mii, "called, interface_version={:08X}", interface_version); - UNIMPLEMENTED_IF(current_interface_version != 1); + manager.SetInterfaceVersion(metadata, interface_version); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -230,30 +231,27 @@ private: void Convert(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - const auto mii_v3{rp.PopRaw()}; LOG_INFO(Service_Mii, "called"); + CharInfo char_info{}; + manager.ConvertV3ToCharInfo(char_info, mii_v3); + IPC::ResponseBuilder rb{ctx, 2 + sizeof(CharInfo) / sizeof(u32)}; rb.Push(ResultSuccess); - rb.PushRaw(manager.ConvertV3ToCharInfo(mii_v3)); + rb.PushRaw(char_info); } - constexpr bool IsInterfaceVersionSupported(u32 interface_version) const { - return current_interface_version >= interface_version; - } - - MiiManager manager; - - u32 current_interface_version{}; - u64 current_update_counter{}; + MiiManager manager{}; + DatabaseSessionMetadata metadata{}; + bool is_system{}; }; class MiiDBModule final : public ServiceFramework { public: - explicit MiiDBModule(Core::System& system_, const char* name_) - : ServiceFramework{system_, name_} { + explicit MiiDBModule(Core::System& system_, const char* name_, bool is_system_) + : ServiceFramework{system_, name_}, is_system{is_system_} { // clang-format off static const FunctionInfo functions[] = { {0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"}, @@ -267,10 +265,12 @@ private: void GetDatabaseService(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); - rb.PushIpcInterface(system); + rb.PushIpcInterface(system, is_system); LOG_DEBUG(Service_Mii, "called"); } + + bool is_system{}; }; class MiiImg final : public ServiceFramework { @@ -302,8 +302,10 @@ public: void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService("mii:e", std::make_shared(system, "mii:e")); - server_manager->RegisterNamedService("mii:u", std::make_shared(system, "mii:u")); + server_manager->RegisterNamedService("mii:e", + std::make_shared(system, "mii:e", true)); + server_manager->RegisterNamedService("mii:u", + std::make_shared(system, "mii:u", false)); server_manager->RegisterNamedService("miiimg", std::make_shared(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 3951e0b9c..153a484c0 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -16,45 +16,18 @@ #include "core/hle/service/mii/types/raw_data.h" namespace Service::Mii { - -namespace { - constexpr std::size_t DefaultMiiCount{RawData::DefaultMii.size()}; -CharInfo ConvertStoreDataToInfo(const StoreData& data) { - CharInfo char_info{}; - char_info.SetFromStoreData(data); - return char_info; -} +MiiManager::MiiManager() {} -StoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) { - StoreData store_data{}; - store_data.BuildRandom(age, gender, race); - - return store_data; -} - -StoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) { - StoreData store_data{}; - store_data.BuildDefault(0); - - return store_data; -} - -} // namespace - -MiiManager::MiiManager() : user_id{Service::Account::ProfileManager().GetLastOpenedUser()} {} - -bool MiiManager::CheckAndResetUpdateCounter(SourceFlag source_flag, u64& current_update_counter) { +bool MiiManager::IsUpdated(DatabaseSessionMetadata& metadata, SourceFlag source_flag) const { if ((source_flag & SourceFlag::Database) == SourceFlag::None) { return false; } - const bool result{current_update_counter != update_counter}; - - current_update_counter = update_counter; - - return result; + const auto metadata_update_counter = metadata.update_counter; + metadata.update_counter = update_counter; + return metadata_update_counter != update_counter; } bool MiiManager::IsFullDatabase() const { @@ -62,19 +35,19 @@ bool MiiManager::IsFullDatabase() const { return false; } -u32 MiiManager::GetCount(SourceFlag source_flag) const { - std::size_t count{}; - if ((source_flag & SourceFlag::Database) != SourceFlag::None) { +u32 MiiManager::GetCount(const DatabaseSessionMetadata& metadata, SourceFlag source_flag) const { + u32 mii_count{}; + if ((source_flag & SourceFlag::Default) == SourceFlag::None) { + mii_count += DefaultMiiCount; + } + if ((source_flag & SourceFlag::Database) == SourceFlag::None) { // TODO(bunnei): We don't implement the Mii database, but when we do, update this - count += 0; } - if ((source_flag & SourceFlag::Default) != SourceFlag::None) { - count += DefaultMiiCount; - } - return static_cast(count); + return mii_count; } -Result MiiManager::UpdateLatest(CharInfo* out_info, const CharInfo& info, SourceFlag source_flag) { +Result MiiManager::UpdateLatest(DatabaseSessionMetadata& metadata, CharInfo& out_char_info, + const CharInfo& char_info, SourceFlag source_flag) { if ((source_flag & SourceFlag::Database) == SourceFlag::None) { return ResultNotFound; } @@ -83,48 +56,117 @@ Result MiiManager::UpdateLatest(CharInfo* out_info, const CharInfo& info, Source return ResultNotFound; } -CharInfo MiiManager::BuildRandom(Age age, Gender gender, Race race) { - return ConvertStoreDataToInfo(BuildRandomStoreData(age, gender, race, user_id)); +void MiiManager::BuildDefault(CharInfo& out_char_info, u32 index) const { + StoreData store_data{}; + store_data.BuildDefault(index); + out_char_info.SetFromStoreData(store_data); } -CharInfo MiiManager::BuildBase(Gender gender) { - const std::size_t index = gender == Gender::Female ? 1 : 0; - return ConvertStoreDataToInfo(BuildDefaultStoreData(RawData::BaseMii.at(index), user_id)); +void MiiManager::BuildBase(CharInfo& out_char_info, Gender gender) const { + StoreData store_data{}; + store_data.BuildBase(gender); + out_char_info.SetFromStoreData(store_data); } -CharInfo MiiManager::BuildDefault(std::size_t index) { - return ConvertStoreDataToInfo(BuildDefaultStoreData(RawData::DefaultMii.at(index), user_id)); +void MiiManager::BuildRandom(CharInfo& out_char_info, Age age, Gender gender, Race race) const { + StoreData store_data{}; + store_data.BuildRandom(age, gender, race); + out_char_info.SetFromStoreData(store_data); } -CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { - CharInfo char_info{}; +void MiiManager::ConvertV3ToCharInfo(CharInfo& out_char_info, const Ver3StoreData& mii_v3) const { StoreData store_data{}; mii_v3.BuildToStoreData(store_data); - char_info.SetFromStoreData(store_data); - return char_info; + out_char_info.SetFromStoreData(store_data); } -std::vector MiiManager::GetDefault(SourceFlag source_flag) { - std::vector result; +Result MiiManager::Get(const DatabaseSessionMetadata& metadata, + std::span out_elements, u32& out_count, + SourceFlag source_flag) { + if ((source_flag & SourceFlag::Database) == SourceFlag::None) { + return BuildDefault(out_elements, out_count, source_flag); + } + // TODO(bunnei): We don't implement the Mii database, so we can't have an entry + + // Include default Mii at the end of the list + return BuildDefault(out_elements, out_count, source_flag); +} + +Result MiiManager::Get(const DatabaseSessionMetadata& metadata, std::span out_char_info, + u32& out_count, SourceFlag source_flag) { + if ((source_flag & SourceFlag::Database) == SourceFlag::None) { + return BuildDefault(out_char_info, out_count, source_flag); + } + + // TODO(bunnei): We don't implement the Mii database, so we can't have an entry + + // Include default Mii at the end of the list + return BuildDefault(out_char_info, out_count, source_flag); +} + +Result MiiManager::BuildDefault(std::span out_elements, u32& out_count, + SourceFlag source_flag) { if ((source_flag & SourceFlag::Default) == SourceFlag::None) { - return result; + return ResultSuccess; } - for (std::size_t index = 0; index < DefaultMiiCount; index++) { - result.emplace_back(BuildDefault(index), Source::Default); + StoreData store_data{}; + + for (std::size_t index = 0; index < DefaultMiiCount; ++index) { + if (out_elements.size() <= static_cast(out_count)) { + return ResultInvalidArgumentSize; + } + + store_data.BuildDefault(static_cast(index)); + + out_elements[out_count].source = Source::Default; + out_elements[out_count].char_info.SetFromStoreData(store_data); + out_count++; } - return result; + return ResultSuccess; } -Result MiiManager::GetIndex([[maybe_unused]] const CharInfo& info, u32& index) { +Result MiiManager::BuildDefault(std::span out_char_info, u32& out_count, + SourceFlag source_flag) { + if ((source_flag & SourceFlag::Default) == SourceFlag::None) { + return ResultSuccess; + } + + StoreData store_data{}; + + for (std::size_t index = 0; index < DefaultMiiCount; ++index) { + if (out_char_info.size() <= static_cast(out_count)) { + return ResultInvalidArgumentSize; + } + + store_data.BuildDefault(static_cast(index)); + + out_char_info[out_count].SetFromStoreData(store_data); + out_count++; + } + + return ResultSuccess; +} + +Result MiiManager::GetIndex(const DatabaseSessionMetadata& metadata, const CharInfo& char_info, + s32& out_index) { + + if (char_info.Verify() != 0) { + return ResultInvalidCharInfo; + } + constexpr u32 INVALID_INDEX{0xFFFFFFFF}; - index = INVALID_INDEX; + out_index = INVALID_INDEX; // TODO(bunnei): We don't implement the Mii database, so we can't have an index return ResultNotFound; } +void MiiManager::SetInterfaceVersion(DatabaseSessionMetadata& metadata, u32 version) { + metadata.interface_version = version; +} + } // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h index 6098474e9..4f8be06c3 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h @@ -19,16 +19,24 @@ class MiiManager { public: MiiManager(); - bool CheckAndResetUpdateCounter(SourceFlag source_flag, u64& current_update_counter); + bool IsUpdated(DatabaseSessionMetadata& metadata, SourceFlag source_flag) const; + bool IsFullDatabase() const; - u32 GetCount(SourceFlag source_flag) const; - Result UpdateLatest(CharInfo* out_info, const CharInfo& info, SourceFlag source_flag); - CharInfo BuildRandom(Age age, Gender gender, Race race); - CharInfo BuildBase(Gender gender); - CharInfo BuildDefault(std::size_t index); - CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const; + u32 GetCount(const DatabaseSessionMetadata& metadata, SourceFlag source_flag) const; + Result UpdateLatest(DatabaseSessionMetadata& metadata, CharInfo& out_char_info, + const CharInfo& char_info, SourceFlag source_flag); + Result Get(const DatabaseSessionMetadata& metadata, std::span out_elements, + u32& out_count, SourceFlag source_flag); + Result Get(const DatabaseSessionMetadata& metadata, std::span out_char_info, + u32& out_count, SourceFlag source_flag); + void BuildDefault(CharInfo& out_char_info, u32 index) const; + void BuildBase(CharInfo& out_char_info, Gender gender) const; + void BuildRandom(CharInfo& out_char_info, Age age, Gender gender, Race race) const; + void ConvertV3ToCharInfo(CharInfo& out_char_info, const Ver3StoreData& mii_v3) const; std::vector GetDefault(SourceFlag source_flag); - Result GetIndex(const CharInfo& info, u32& index); + Result GetIndex(const DatabaseSessionMetadata& metadata, const CharInfo& char_info, + s32& out_index); + void SetInterfaceVersion(DatabaseSessionMetadata& metadata, u32 version); struct MiiDatabase { u32 magic{}; // 'NFDB' @@ -40,7 +48,10 @@ public: static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size."); private: - const Common::UUID user_id{}; + Result BuildDefault(std::span out_elements, u32& out_count, + SourceFlag source_flag); + Result BuildDefault(std::span out_char_info, u32& out_count, SourceFlag source_flag); + u64 update_counter{}; }; diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index d62005f61..b23ce477d 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -165,4 +165,14 @@ struct DefaultMii { }; static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); +struct DatabaseSessionMetadata { + u32 interface_version; + u32 magic; + u64 update_counter; + + bool IsInterfaceVersionSupported(u32 version) const { + return version <= interface_version; + } +}; + } // namespace Service::Mii diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index eb7706015..5dda12343 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -680,12 +680,16 @@ Result NfcDevice::GetRegisterInfo(NFP::RegisterInfo& register_info) const { return ResultRegistrationIsNotInitialized; } - Service::Mii::MiiManager manager; + Mii::CharInfo char_info{}; + Mii::StoreData store_data{}; + tag_data.owner_mii.BuildToStoreData(store_data); + char_info.SetFromStoreData(store_data); + const auto& settings = tag_data.settings; // TODO: Validate this data register_info = { - .mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii), + .mii_char_info = char_info, .creation_date = settings.init_date.GetWriteDate(), .amiibo_name = GetAmiiboName(settings), .font_region = settings.settings.font_region, From ec25f847d8c066241d3aa9bb00bd11cb0c47b161 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 11 Sep 2023 08:53:23 -0600 Subject: [PATCH 10/11] mii: service: Address review --- src/core/hle/service/mii/mii.cpp | 2 +- src/core/hle/service/mii/mii_manager.cpp | 6 +- src/core/hle/service/mii/mii_manager.h | 9 -- src/core/hle/service/mii/mii_types.h | 57 ++++++++- src/core/hle/service/mii/mii_util.h | 3 +- src/core/hle/service/mii/types/char_info.cpp | 112 +++++++++--------- src/core/hle/service/mii/types/char_info.h | 2 +- src/core/hle/service/mii/types/core_data.cpp | 12 +- src/core/hle/service/mii/types/raw_data.cpp | 2 +- src/core/hle/service/mii/types/raw_data.h | 2 +- .../hle/service/mii/types/ver3_store_data.cpp | 23 +--- .../hle/service/mii/types/ver3_store_data.h | 6 +- src/yuzu/applets/qt_amiibo_settings.cpp | 3 +- 13 files changed, 135 insertions(+), 104 deletions(-) diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 653c36740..3b83c5ed7 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -210,7 +210,7 @@ private: LOG_DEBUG(Service_Mii, "called"); s32 index{}; - const Result result = manager.GetIndex(metadata, info, index); + const auto result = manager.GetIndex(metadata, info, index); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(result); diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp index 153a484c0..292d63777 100644 --- a/src/core/hle/service/mii/mii_manager.cpp +++ b/src/core/hle/service/mii/mii_manager.cpp @@ -37,10 +37,10 @@ bool MiiManager::IsFullDatabase() const { u32 MiiManager::GetCount(const DatabaseSessionMetadata& metadata, SourceFlag source_flag) const { u32 mii_count{}; - if ((source_flag & SourceFlag::Default) == SourceFlag::None) { + if ((source_flag & SourceFlag::Default) != SourceFlag::None) { mii_count += DefaultMiiCount; } - if ((source_flag & SourceFlag::Database) == SourceFlag::None) { + if ((source_flag & SourceFlag::Database) != SourceFlag::None) { // TODO(bunnei): We don't implement the Mii database, but when we do, update this } return mii_count; @@ -153,7 +153,7 @@ Result MiiManager::BuildDefault(std::span out_char_info, u32& out_coun Result MiiManager::GetIndex(const DatabaseSessionMetadata& metadata, const CharInfo& char_info, s32& out_index) { - if (char_info.Verify() != 0) { + if (char_info.Verify() != ValidationResult::NoErrors) { return ResultInvalidCharInfo; } diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h index 4f8be06c3..a2e7a6d73 100644 --- a/src/core/hle/service/mii/mii_manager.h +++ b/src/core/hle/service/mii/mii_manager.h @@ -38,15 +38,6 @@ public: s32& out_index); void SetInterfaceVersion(DatabaseSessionMetadata& metadata, u32 version); - struct MiiDatabase { - u32 magic{}; // 'NFDB' - std::array miis{}; - INSERT_PADDING_BYTES(1); - u8 count{}; - u16 crc{}; - }; - static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size."); - private: Result BuildDefault(std::span out_elements, u32& out_count, SourceFlag source_flag); diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index b23ce477d..8fc827b5a 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -86,6 +86,61 @@ enum class SourceFlag : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); +enum class ValidationResult : u32 { + NoErrors = 0x0, + InvalidBeardColor = 0x1, + InvalidBeardType = 0x2, + InvalidBuild = 0x3, + InvalidEyeAspect = 0x4, + InvalidEyeColor = 0x5, + InvalidEyeRotate = 0x6, + InvalidEyeScale = 0x7, + InvalidEyeType = 0x8, + InvalidEyeX = 0x9, + InvalidEyeY = 0xa, + InvalidEyebrowAspect = 0xb, + InvalidEyebrowColor = 0xc, + InvalidEyebrowRotate = 0xd, + InvalidEyebrowScale = 0xe, + InvalidEyebrowType = 0xf, + InvalidEyebrowX = 0x10, + InvalidEyebrowY = 0x11, + InvalidFacelineColor = 0x12, + InvalidFacelineMake = 0x13, + InvalidFacelineWrinkle = 0x14, + InvalidFacelineType = 0x15, + InvalidColor = 0x16, + InvalidFont = 0x17, + InvalidGender = 0x18, + InvalidGlassColor = 0x19, + InvalidGlassScale = 0x1a, + InvalidGlassType = 0x1b, + InvalidGlassY = 0x1c, + InvalidHairColor = 0x1d, + InvalidHairFlip = 0x1e, + InvalidHairType = 0x1f, + InvalidHeight = 0x20, + InvalidMoleScale = 0x21, + InvalidMoleType = 0x22, + InvalidMoleX = 0x23, + InvalidMoleY = 0x24, + InvalidMouthAspect = 0x25, + InvalidMouthColor = 0x26, + InvalidMouthScale = 0x27, + InvalidMouthType = 0x28, + InvalidMouthY = 0x29, + InvalidMustacheScale = 0x2a, + InvalidMustacheType = 0x2b, + InvalidMustacheY = 0x2c, + InvalidNoseScale = 0x2e, + InvalidNoseType = 0x2f, + InvalidNoseY = 0x30, + InvalidRegionMove = 0x31, + InvalidCreateId = 0x32, + InvalidName = 0x33, + InvalidType = 0x35, +}; + struct Nickname { static constexpr std::size_t MaxNameSize = 10; std::array data; @@ -163,7 +218,7 @@ struct DefaultMii { u32 type{}; Nickname nickname; }; -static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); +static_assert(sizeof(DefaultMii) == 0xd8, "DefaultMii has incorrect size."); struct DatabaseSessionMetadata { u32 interface_version; diff --git a/src/core/hle/service/mii/mii_util.h b/src/core/hle/service/mii/mii_util.h index 782ffe22f..ddb544c23 100644 --- a/src/core/hle/service/mii/mii_util.h +++ b/src/core/hle/service/mii/mii_util.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include "common/common_types.h" #include "common/swap.h" @@ -51,7 +52,7 @@ public: } static bool IsFontRegionValid(FontRegion font, std::span text) { - // Todo:: This function needs to check against the font tables + // TODO: This function needs to check against the font tables return true; } }; diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp index 0f9c37b84..cd7154c91 100644 --- a/src/core/hle/service/mii/types/char_info.cpp +++ b/src/core/hle/service/mii/types/char_info.cpp @@ -62,161 +62,161 @@ void CharInfo::SetFromStoreData(const StoreData& store_data) { padding = '\0'; } -u32 CharInfo::Verify() const { +ValidationResult CharInfo::Verify() const { if (!create_id.IsValid()) { - return 0x32; + return ValidationResult::InvalidCreateId; } if (!name.IsValid()) { - return 0x33; + return ValidationResult::InvalidName; } if (3 < font_region) { - return 0x17; + return ValidationResult::InvalidFont; } if (0xb < favorite_color) { - return 0x16; + return ValidationResult::InvalidColor; } if (1 < gender) { - return 0x18; + return ValidationResult::InvalidGender; } - if (height < 0) { - return 0x20; + if (height > 0x7f) { + return ValidationResult::InvalidHeight; } - if (build < 0) { - return 3; + if (build > 0x7f) { + return ValidationResult::InvalidBuild; } if (1 < type) { - return 0x35; + return ValidationResult::InvalidType; } if (3 < region_move) { - return 0x31; + return ValidationResult::InvalidRegionMove; } if (0xb < faceline_type) { - return 0x15; + return ValidationResult::InvalidFacelineType; } if (9 < faceline_color) { - return 0x12; + return ValidationResult::InvalidFacelineColor; } if (0xb < faceline_wrinkle) { - return 0x14; + return ValidationResult::InvalidFacelineWrinkle; } if (0xb < faceline_make) { - return 0x13; + return ValidationResult::InvalidFacelineMake; } if (0x83 < hair_type) { - return 0x1f; + return ValidationResult::InvalidHairType; } if (99 < hair_color) { - return 0x1d; + return ValidationResult::InvalidHairColor; } if (1 < hair_flip) { - return 0x1e; + return ValidationResult::InvalidHairFlip; } if (0x3b < eye_type) { - return 8; + return ValidationResult::InvalidEyeType; } if (99 < eye_color) { - return 5; + return ValidationResult::InvalidEyeColor; } if (7 < eye_scale) { - return 7; + return ValidationResult::InvalidEyeScale; } if (6 < eye_aspect) { - return 4; + return ValidationResult::InvalidEyeAspect; } if (7 < eye_rotate) { - return 6; + return ValidationResult::InvalidEyeRotate; } if (0xc < eye_x) { - return 9; + return ValidationResult::InvalidEyeX; } if (0x12 < eye_y) { - return 10; + return ValidationResult::InvalidEyeY; } if (0x17 < eyebrow_type) { - return 0xf; + return ValidationResult::InvalidEyebrowType; } if (99 < eyebrow_color) { - return 0xc; + return ValidationResult::InvalidEyebrowColor; } if (8 < eyebrow_scale) { - return 0xe; + return ValidationResult::InvalidEyebrowScale; } if (6 < eyebrow_aspect) { - return 0xb; + return ValidationResult::InvalidEyebrowAspect; } if (0xb < eyebrow_rotate) { - return 0xd; + return ValidationResult::InvalidEyebrowRotate; } if (0xc < eyebrow_x) { - return 0x10; + return ValidationResult::InvalidEyebrowX; } if (0xf < eyebrow_y - 3) { - return 0x11; + return ValidationResult::InvalidEyebrowY; } if (0x11 < nose_type) { - return 0x2f; + return ValidationResult::InvalidNoseType; } if (nose_scale >= 9) { - return 0x2e; + return ValidationResult::InvalidNoseScale; } if (0x12 < nose_y) { - return 0x30; + return ValidationResult::InvalidNoseY; } if (0x23 < mouth_type) { - return 0x28; + return ValidationResult::InvalidMouthType; } if (99 < mouth_color) { - return 0x26; + return ValidationResult::InvalidMouthColor; } if (8 < mouth_scale) { - return 0x27; + return ValidationResult::InvalidMouthScale; } if (6 < mouth_aspect) { - return 0x25; + return ValidationResult::InvalidMouthAspect; } if (0x12 < mouth_y) { - return 0x29; + return ValidationResult::InvalidMoleY; } if (99 < beard_color) { - return 1; + return ValidationResult::InvalidBeardColor; } if (5 < beard_type) { - return 2; + return ValidationResult::InvalidBeardType; } if (5 < mustache_type) { - return 0x2b; + return ValidationResult::InvalidMustacheType; } if (8 < mustache_scale) { - return 0x2a; + return ValidationResult::InvalidMustacheScale; } if (0x10 < mustache_y) { - return 0x2c; + return ValidationResult::InvalidMustacheY; } if (0x13 < glasses_type) { - return 0x1b; + return ValidationResult::InvalidGlassType; } if (99 < glasses_color) { - return 0x19; + return ValidationResult::InvalidGlassColor; } if (7 < glasses_scale) { - return 0x1a; + return ValidationResult::InvalidGlassScale; } if (0x14 < glasses_y) { - return 0x1c; + return ValidationResult::InvalidGlassY; } if (mole_type >= 2) { - return 0x22; + return ValidationResult::InvalidMoleType; } if (8 < mole_scale) { - return 0x21; + return ValidationResult::InvalidMoleScale; } if (mole_x >= 0x11) { - return 0x23; + return ValidationResult::InvalidMoleX; } if (0x1e < mole_y) { - return 0x24; + return ValidationResult::InvalidMoleY; } - return 0; + return ValidationResult::NoErrors; } Common::UUID CharInfo::GetCreateId() const { @@ -424,7 +424,7 @@ u8 CharInfo::GetMoleY() const { } bool CharInfo::operator==(const CharInfo& info) { - bool is_identical = info.Verify() == 0; + bool is_identical = info.Verify() == ValidationResult::NoErrors; is_identical &= name.data == info.GetNickname().data; is_identical &= create_id == info.GetCreateId(); is_identical &= font_region == info.GetFontRegion(); diff --git a/src/core/hle/service/mii/types/char_info.h b/src/core/hle/service/mii/types/char_info.h index 4f70edc24..65a7707d3 100644 --- a/src/core/hle/service/mii/types/char_info.h +++ b/src/core/hle/service/mii/types/char_info.h @@ -13,7 +13,7 @@ class CharInfo { public: void SetFromStoreData(const StoreData& store_data_raw); - u32 Verify() const; + ValidationResult Verify() const; Common::UUID GetCreateId() const; Nickname GetNickname() const; diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index 9d7e604a9..de82481b0 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -26,10 +26,10 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { data.build.Assign(64); if (age == Age::All) { - const auto temp{MiiUtil::GetRandomValue(10)}; - if (temp >= 8) { + const auto random{MiiUtil::GetRandomValue(10)}; + if (random >= 8) { age = Age::Old; - } else if (temp >= 4) { + } else if (random >= 4) { age = Age::Normal; } else { age = Age::Young; @@ -37,10 +37,10 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { } if (race == Race::All) { - const auto temp{MiiUtil::GetRandomValue(10)}; - if (temp >= 8) { + const auto random{MiiUtil::GetRandomValue(10)}; + if (random >= 8) { race = Race::Black; - } else if (temp >= 4) { + } else if (random >= 4) { race = Race::White; } else { race = Race::Asian; diff --git a/src/core/hle/service/mii/types/raw_data.cpp b/src/core/hle/service/mii/types/raw_data.cpp index ef678c527..ed299521f 100644 --- a/src/core/hle/service/mii/types/raw_data.cpp +++ b/src/core/hle/service/mii/types/raw_data.cpp @@ -5,7 +5,7 @@ namespace Service::Mii::RawData { -constexpr std::array FromVer3FacelineColorTable{ +constexpr std::array FromVer3FacelineColorTable{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, }; diff --git a/src/core/hle/service/mii/types/raw_data.h b/src/core/hle/service/mii/types/raw_data.h index 180f49fd0..8c910096f 100644 --- a/src/core/hle/service/mii/types/raw_data.h +++ b/src/core/hle/service/mii/types/raw_data.h @@ -10,7 +10,7 @@ namespace Service::Mii::RawData { struct RandomMiiValues { - std::array values{}; + std::array values{}; }; static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); 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 53a3fe44b..c7624520c 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.cpp +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp @@ -33,16 +33,7 @@ void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { out_store_data.SetHeight(height); out_store_data.SetBuild(build); - // Copy name until string terminator - Nickname name = {}; - for (std::size_t index = 0; index < name.data.size() - 1; index++) { - name.data[index] = mii_name[index]; - if (name.data[index] == 0) { - break; - } - } - - out_store_data.SetNickname(name); + out_store_data.SetNickname(mii_name); out_store_data.SetFontRegion( static_cast(static_cast(region_information.font_region))); @@ -108,15 +99,7 @@ void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { height = store_data.GetHeight(); build = store_data.GetBuild(); - // Copy name until string terminator - mii_name = {}; - for (std::size_t index = 0; index < store_data.GetNickname().data.size() - 1; index++) { - mii_name[index] = store_data.GetNickname().data[index]; - if (mii_name[index] == 0) { - break; - } - } - + mii_name = store_data.GetNickname(); region_information.font_region.Assign(static_cast(store_data.GetFontRegion())); appearance_bits1.faceline_type.Assign(store_data.GetFacelineType()); @@ -183,7 +166,7 @@ void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { u32 Ver3StoreData::IsValid() const { bool is_valid = version == 0 || version == 3; - is_valid = is_valid && (mii_name[0] != 0); + is_valid = is_valid && (mii_name.data[0] != 0); is_valid = is_valid && (mii_information.birth_month < 13); is_valid = is_valid && (mii_information.birth_day < 32); 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 11caeb5c3..47907bf7d 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.h +++ b/src/core/hle/service/mii/types/ver3_store_data.h @@ -47,7 +47,7 @@ public: u16_be mii_id; u64_be system_id; u32_be specialness_and_creation_date; - std::array creator_mac; + std::array creator_mac; u16_be padding; union { u16 raw; @@ -58,7 +58,7 @@ public: BitField<10, 4, u16> favorite_color; BitField<14, 1, u16> favorite; } mii_information; - std::array mii_name; + Nickname mii_name; u8 height; u8 build; union { @@ -150,7 +150,7 @@ public: BitField<10, 5, u16> mole_y; } appearance_bits11; - std::array author_name; + Nickname author_name; INSERT_PADDING_BYTES(0x2); u16_be crc; }; diff --git a/src/yuzu/applets/qt_amiibo_settings.cpp b/src/yuzu/applets/qt_amiibo_settings.cpp index 4988fcc83..b457a736a 100644 --- a/src/yuzu/applets/qt_amiibo_settings.cpp +++ b/src/yuzu/applets/qt_amiibo_settings.cpp @@ -160,7 +160,8 @@ void QtAmiiboSettingsDialog::LoadAmiiboData() { } const auto amiibo_name = std::string(register_info.amiibo_name.data()); - const auto owner_name = Common::UTF16ToUTF8(register_info.mii_char_info.name.data()); + const auto owner_name = + Common::UTF16ToUTF8(register_info.mii_char_info.GetNickname().data.data()); const auto creation_date = QDate(register_info.creation_date.year, register_info.creation_date.month, register_info.creation_date.day); From 4d138b760b1eb09ee59dca40dba86112e3c8a39d Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Mon, 11 Sep 2023 17:12:51 -0600 Subject: [PATCH 11/11] service: mii: Remove most magic values --- src/core/hle/service/mii/mii_types.h | 559 +++++++++- src/core/hle/service/mii/types/char_info.cpp | 170 +-- src/core/hle/service/mii/types/char_info.h | 96 +- src/core/hle/service/mii/types/core_data.cpp | 272 +++-- src/core/hle/service/mii/types/core_data.h | 91 +- src/core/hle/service/mii/types/raw_data.cpp | 976 +++++++++--------- src/core/hle/service/mii/types/raw_data.h | 16 +- src/core/hle/service/mii/types/store_data.cpp | 138 +-- src/core/hle/service/mii/types/store_data.h | 78 +- .../hle/service/mii/types/ver3_store_data.cpp | 204 ++-- 10 files changed, 1534 insertions(+), 1066 deletions(-) diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h index 8fc827b5a..95476f745 100644 --- a/src/core/hle/service/mii/mii_types.h +++ b/src/core/hle/service/mii/mii_types.h @@ -13,20 +13,517 @@ namespace Service::Mii { -enum class Age : u32 { +constexpr u8 MaxHeight = 127; +constexpr u8 MaxBuild = 127; +constexpr u8 MaxType = 1; +constexpr u8 MaxRegionMove = 3; +constexpr u8 MaxEyeScale = 7; +constexpr u8 MaxEyeAspect = 6; +constexpr u8 MaxEyeRotate = 7; +constexpr u8 MaxEyeX = 12; +constexpr u8 MaxEyeY = 18; +constexpr u8 MaxEyebrowScale = 8; +constexpr u8 MaxEyebrowAspect = 6; +constexpr u8 MaxEyebrowRotate = 11; +constexpr u8 MaxEyebrowX = 12; +constexpr u8 MaxEyebrowY = 18; +constexpr u8 MaxNoseScale = 8; +constexpr u8 MaxNoseY = 18; +constexpr u8 MaxMouthScale = 8; +constexpr u8 MaxMoutAspect = 6; +constexpr u8 MaxMouthY = 18; +constexpr u8 MaxMustacheScale = 8; +constexpr u8 MasMustacheY = 16; +constexpr u8 MaxGlassScale = 7; +constexpr u8 MaxGlassY = 20; +constexpr u8 MaxMoleScale = 8; +constexpr u8 MaxMoleX = 16; +constexpr u8 MaxMoleY = 30; +constexpr u8 MaxVer3CommonColor = 7; +constexpr u8 MaxVer3GlassType = 8; + +enum class Age : u8 { Young, Normal, Old, - All, + All, // Default + + Max = All, }; -enum class BeardType : u32 { +enum class Gender : u8 { + Male, + Female, + All, // Default + + Max = Female, +}; + +enum class Race : u8 { + Black, + White, + Asian, + All, // Default + + Max = All, +}; + +enum class HairType : u8 { + NormalLong, // Default + NormalShort, + NormalMedium, + NormalExtraLong, + NormalLongBottom, + NormalTwoPeaks, + PartingLong, + FrontLock, + PartingShort, + PartingExtraLongCurved, + PartingExtraLong, + PartingMiddleLong, + PartingSquared, + PartingLongBottom, + PeaksTop, + PeaksSquared, + PartingPeaks, + PeaksLongBottom, + Peaks, + PeaksRounded, + PeaksSide, + PeaksMedium, + PeaksLong, + PeaksRoundedLong, + PartingFrontPeaks, + PartingLongFront, + PartingLongRounded, + PartingFrontPeaksLong, + PartingExtraLongRounded, + LongRounded, + NormalUnknown1, + NormalUnknown2, + NormalUnknown3, + NormalUnknown4, + NormalUnknown5, + NormalUnknown6, + DreadLocks, + PlatedMats, + Caps, + Afro, + PlatedMatsLong, + Beanie, + Short, + ShortTopLongSide, + ShortUnknown1, + ShortUnknown2, + MilitaryParting, + Military, + ShortUnknown3, + ShortUnknown4, + ShortUnknown5, + ShortUnknown6, + NoneTop, None, - Beard1, - Beard2, - Beard3, - Beard4, - Beard5, + LongUnknown1, + LongUnknown2, + LongUnknown3, + LongUnknown4, + LongUnknown5, + LongUnknown6, + LongUnknown7, + LongUnknown8, + LongUnknown9, + LongUnknown10, + LongUnknown11, + LongUnknown12, + LongUnknown13, + LongUnknown14, + LongUnknown15, + LongUnknown16, + LongUnknown17, + LongUnknown18, + LongUnknown19, + LongUnknown20, + LongUnknown21, + LongUnknown22, + LongUnknown23, + LongUnknown24, + LongUnknown25, + LongUnknown26, + LongUnknown27, + LongUnknown28, + LongUnknown29, + LongUnknown30, + LongUnknown31, + LongUnknown32, + LongUnknown33, + LongUnknown34, + LongUnknown35, + LongUnknown36, + LongUnknown37, + LongUnknown38, + LongUnknown39, + LongUnknown40, + LongUnknown41, + LongUnknown42, + LongUnknown43, + LongUnknown44, + LongUnknown45, + LongUnknown46, + LongUnknown47, + LongUnknown48, + LongUnknown49, + LongUnknown50, + LongUnknown51, + LongUnknown52, + LongUnknown53, + LongUnknown54, + LongUnknown55, + LongUnknown56, + LongUnknown57, + LongUnknown58, + LongUnknown59, + LongUnknown60, + LongUnknown61, + LongUnknown62, + LongUnknown63, + LongUnknown64, + LongUnknown65, + LongUnknown66, + TwoMediumFrontStrandsOneLongBackPonyTail, + TwoFrontStrandsLongBackPonyTail, + PartingFrontTwoLongBackPonyTails, + TwoFrontStrandsOneLongBackPonyTail, + LongBackPonyTail, + LongFrontTwoLongBackPonyTails, + StrandsTwoShortSidedPonyTails, + TwoMediumSidedPonyTails, + ShortFrontTwoBackPonyTails, + TwoShortSidedPonyTails, + TwoLongSidedPonyTails, + LongFrontTwoBackPonyTails, + + Max = LongFrontTwoBackPonyTails, +}; + +enum class MoleType : u8 { + None, // Default + OneDot, + + Max = OneDot, +}; + +enum class HairFlip : u8 { + Left, // Default + Right, + + Max = Right, +}; + +enum class CommonColor : u8 { + // For simplicity common colors aren't listed + Max = 99, + Count = 100, +}; + +enum class FavoriteColor : u8 { + Red, // Default + Orange, + Yellow, + LimeGreen, + Green, + Blue, + LightBlue, + Pink, + Purple, + Brown, + White, + Black, + + Max = Black, +}; + +enum class EyeType : u8 { + Normal, // Default + NormalLash, + WhiteLash, + WhiteNoBottom, + OvalAngledWhite, + AngryWhite, + DotLashType1, + Line, + DotLine, + OvalWhite, + RoundedWhite, + NormalShadow, + CircleWhite, + Circle, + CircleWhiteStroke, + NormalOvalNoBottom, + NormalOvalLarge, + NormalRoundedNoBottom, + SmallLash, + Small, + TwoSmall, + NormalLongLash, + WhiteTwoLashes, + WhiteThreeLashes, + DotAngry, + DotAngled, + Oval, + SmallWhite, + WhiteAngledNoBottom, + WhiteAngledNoLeft, + SmallWhiteTwoLashes, + LeafWhiteLash, + WhiteLargeNoBottom, + Dot, + DotLashType2, + DotThreeLashes, + WhiteOvalTop, + WhiteOvalBottom, + WhiteOvalBottomFlat, + WhiteOvalTwoLashes, + WhiteOvalThreeLashes, + WhiteOvalNoBottomTwoLashes, + DotWhite, + WhiteOvalTopFlat, + WhiteThinLeaf, + StarThreeLashes, + LineTwoLashes, + CrowsFeet, + WhiteNoBottomFlat, + WhiteNoBottomRounded, + WhiteSmallBottomLine, + WhiteNoBottomLash, + WhiteNoPartialBottomLash, + WhiteOvalBottomLine, + WhiteNoBottomLashTopLine, + WhiteNoPartialBottomTwoLashes, + NormalTopLine, + WhiteOvalLash, + RoundTired, + WhiteLarge, + + Max = WhiteLarge, +}; + +enum class MouthType : u8 { + Neutral, // Default + NeutralLips, + Smile, + SmileStroke, + SmileTeeth, + LipsSmall, + LipsLarge, + Wave, + WaveAngrySmall, + NeutralStrokeLarge, + TeethSurprised, + LipsExtraLarge, + LipsUp, + NeutralDown, + Surprised, + TeethMiddle, + NeutralStroke, + LipsExtraSmall, + Malicious, + LipsDual, + NeutralComma, + NeutralUp, + TeethLarge, + WaveAngry, + LipsSexy, + SmileInverted, + LipsSexyOutline, + SmileRounded, + LipsTeeth, + NeutralOpen, + TeethRounded, + WaveAngrySmallInverted, + NeutralCommaInverted, + TeethFull, + SmileDownLine, + Kiss, + + Max = Kiss, +}; + +enum class FontRegion : u8 { + Standard, // Default + China, + Korea, + Taiwan, + + Max = Taiwan, +}; + +enum class FacelineType : u8 { + Sharp, // Default + Rounded, + SharpRounded, + SharpRoundedSmall, + Large, + LargeRounded, + SharpSmall, + Flat, + Bump, + Angular, + FlatRounded, + AngularSmall, + + Max = AngularSmall, +}; + +enum class FacelineColor : u8 { + Beige, // Default + WarmBeige, + Natural, + Honey, + Chestnut, + Porcelain, + Ivory, + WarmIvory, + Almond, + Espresso, + + Max = Espresso, + Count = Max + 1, +}; + +enum class FacelineWrinkle : u8 { + None, // Default + TearTroughs, + FacialPain, + Cheeks, + Folds, + UnderTheEyes, + SplitChin, + Chin, + BrowDroop, + MouthFrown, + CrowsFeet, + FoldsCrowsFrown, + + Max = FoldsCrowsFrown, +}; + +enum class FacelineMake : u8 { + None, // Default + CheekPorcelain, + CheekNatural, + EyeShadowBlue, + CheekBlushPorcelain, + CheekBlushNatural, + CheekPorcelainEyeShadowBlue, + CheekPorcelainEyeShadowNatural, + CheekBlushPorcelainEyeShadowEspresso, + Freckles, + LionsManeBeard, + StubbleBeard, + + Max = StubbleBeard, +}; + +enum class EyebrowType : u8 { + FlatAngledLarge, // Default + LowArchRoundedThin, + SoftAngledLarge, + MediumArchRoundedThin, + RoundedMedium, + LowArchMedium, + RoundedThin, + UpThin, + MediumArchRoundedMedium, + RoundedLarge, + UpLarge, + FlatAngledLargeInverted, + MediumArchFlat, + AngledThin, + HorizontalLarge, + HighArchFlat, + Flat, + MediumArchLarge, + LowArchThin, + RoundedThinInverted, + HighArchLarge, + Hairy, + Dotted, + None, + + Max = None, +}; + +enum class NoseType : u8 { + Normal, // Default + Rounded, + Dot, + Arrow, + Roman, + Triangle, + Button, + RoundedInverted, + Potato, + Grecian, + Snub, + Aquiline, + ArrowLeft, + RoundedLarge, + Hooked, + Fat, + Droopy, + ArrowLarge, + + Max = ArrowLarge, +}; + +enum class BeardType : u8 { + None, + Goatee, + GoateeLong, + LionsManeLong, + LionsMane, + Full, + + Min = Goatee, + Max = Full, +}; + +enum class MustacheType : u8 { + None, + Walrus, + Pencil, + Horseshoe, + Normal, + Toothbrush, + + Min = Walrus, + Max = Toothbrush, +}; + +enum class GlassType : u8 { + None, + Oval, + Wayfarer, + Rectangle, + TopRimless, + Rounded, + Oversized, + CatEye, + Square, + BottomRimless, + SemiOpaqueRounded, + SemiOpaqueCatEye, + SemiOpaqueOval, + SemiOpaqueRectangle, + SemiOpaqueAviator, + OpaqueRounded, + OpaqueCatEye, + OpaqueOval, + OpaqueRectangle, + OpaqueAviator, + + Max = OpaqueAviator, + Count = Max + 1, }; enum class BeardAndMustacheFlag : u32 { @@ -36,42 +533,6 @@ enum class BeardAndMustacheFlag : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag); -enum class FontRegion : u32 { - Standard, - China, - Korea, - Taiwan, -}; - -enum class Gender : u32 { - Male, - Female, - All, - Maximum = Female, -}; - -enum class HairFlip : u32 { - Left, - Right, - Maximum = Right, -}; - -enum class MustacheType : u32 { - None, - Mustache1, - Mustache2, - Mustache3, - Mustache4, - Mustache5, -}; - -enum class Race : u32 { - Black, - White, - Asian, - All, -}; - enum class Source : u32 { Database = 0, Default = 1, @@ -173,7 +634,7 @@ struct DefaultMii { u32 face_makeup{}; u32 hair_type{}; u32 hair_color{}; - HairFlip hair_flip{}; + u32 hair_flip{}; u32 eye_type{}; u32 eye_color{}; u32 eye_scale{}; @@ -196,8 +657,8 @@ struct DefaultMii { u32 mouth_scale{}; u32 mouth_aspect{}; u32 mouth_y{}; - MustacheType mustache_type{}; - BeardType beard_type{}; + u32 mustache_type{}; + u32 beard_type{}; u32 beard_color{}; u32 mustache_scale{}; u32 mustache_y{}; @@ -211,10 +672,10 @@ struct DefaultMii { u32 mole_y{}; u32 height{}; u32 weight{}; - Gender gender{}; + u32 gender{}; u32 favorite_color{}; u32 region_move{}; - FontRegion font_region{}; + u32 font_region{}; u32 type{}; Nickname nickname; }; diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp index cd7154c91..bb948c628 100644 --- a/src/core/hle/service/mii/types/char_info.cpp +++ b/src/core/hle/service/mii/types/char_info.cpp @@ -10,7 +10,7 @@ void CharInfo::SetFromStoreData(const StoreData& store_data) { name = store_data.GetNickname(); null_terminator = '\0'; create_id = store_data.GetCreateId(); - font_region = static_cast(store_data.GetFontRegion()); + font_region = store_data.GetFontRegion(); favorite_color = store_data.GetFavoriteColor(); gender = store_data.GetGender(); height = store_data.GetHeight(); @@ -51,10 +51,10 @@ void CharInfo::SetFromStoreData(const StoreData& store_data) { mustache_type = store_data.GetMustacheType(); mustache_scale = store_data.GetMustacheScale(); mustache_y = store_data.GetMustacheY(); - glasses_type = store_data.GetGlassType(); - glasses_color = store_data.GetGlassColor(); - glasses_scale = store_data.GetGlassScale(); - glasses_y = store_data.GetGlassY(); + glass_type = store_data.GetGlassType(); + glass_color = store_data.GetGlassColor(); + glass_scale = store_data.GetGlassScale(); + glass_y = store_data.GetGlassY(); mole_type = store_data.GetMoleType(); mole_scale = store_data.GetMoleScale(); mole_x = store_data.GetMoleX(); @@ -69,151 +69,151 @@ ValidationResult CharInfo::Verify() const { if (!name.IsValid()) { return ValidationResult::InvalidName; } - if (3 < font_region) { + if (font_region > FontRegion::Max) { return ValidationResult::InvalidFont; } - if (0xb < favorite_color) { + if (favorite_color > FavoriteColor::Max) { return ValidationResult::InvalidColor; } - if (1 < gender) { + if (gender > Gender::Max) { return ValidationResult::InvalidGender; } - if (height > 0x7f) { + if (height > MaxHeight) { return ValidationResult::InvalidHeight; } - if (build > 0x7f) { + if (build > MaxBuild) { return ValidationResult::InvalidBuild; } - if (1 < type) { + if (type > MaxType) { return ValidationResult::InvalidType; } - if (3 < region_move) { + if (region_move > MaxRegionMove) { return ValidationResult::InvalidRegionMove; } - if (0xb < faceline_type) { + if (faceline_type > FacelineType::Max) { return ValidationResult::InvalidFacelineType; } - if (9 < faceline_color) { + if (faceline_color > FacelineColor::Max) { return ValidationResult::InvalidFacelineColor; } - if (0xb < faceline_wrinkle) { + if (faceline_wrinkle > FacelineWrinkle::Max) { return ValidationResult::InvalidFacelineWrinkle; } - if (0xb < faceline_make) { + if (faceline_make > FacelineMake::Max) { return ValidationResult::InvalidFacelineMake; } - if (0x83 < hair_type) { + if (hair_type > HairType::Max) { return ValidationResult::InvalidHairType; } - if (99 < hair_color) { + if (hair_color > CommonColor::Max) { return ValidationResult::InvalidHairColor; } - if (1 < hair_flip) { + if (hair_flip > HairFlip::Max) { return ValidationResult::InvalidHairFlip; } - if (0x3b < eye_type) { + if (eye_type > EyeType::Max) { return ValidationResult::InvalidEyeType; } - if (99 < eye_color) { + if (eye_color > CommonColor::Max) { return ValidationResult::InvalidEyeColor; } - if (7 < eye_scale) { + if (eye_scale > MaxEyeScale) { return ValidationResult::InvalidEyeScale; } - if (6 < eye_aspect) { + if (eye_aspect > MaxEyeAspect) { return ValidationResult::InvalidEyeAspect; } - if (7 < eye_rotate) { + if (eye_rotate > MaxEyeX) { return ValidationResult::InvalidEyeRotate; } - if (0xc < eye_x) { + if (eye_x > MaxEyeX) { return ValidationResult::InvalidEyeX; } - if (0x12 < eye_y) { + if (eye_y > MaxEyeY) { return ValidationResult::InvalidEyeY; } - if (0x17 < eyebrow_type) { + if (eyebrow_type > EyebrowType::Max) { return ValidationResult::InvalidEyebrowType; } - if (99 < eyebrow_color) { + if (eyebrow_color > CommonColor::Max) { return ValidationResult::InvalidEyebrowColor; } - if (8 < eyebrow_scale) { + if (eyebrow_scale > MaxEyebrowScale) { return ValidationResult::InvalidEyebrowScale; } - if (6 < eyebrow_aspect) { + if (eyebrow_aspect > MaxEyebrowAspect) { return ValidationResult::InvalidEyebrowAspect; } - if (0xb < eyebrow_rotate) { + if (eyebrow_rotate > MaxEyebrowRotate) { return ValidationResult::InvalidEyebrowRotate; } - if (0xc < eyebrow_x) { + if (eyebrow_x > MaxEyebrowX) { return ValidationResult::InvalidEyebrowX; } - if (0xf < eyebrow_y - 3) { + if (eyebrow_y > MaxEyebrowY) { return ValidationResult::InvalidEyebrowY; } - if (0x11 < nose_type) { + if (nose_type > NoseType::Max) { return ValidationResult::InvalidNoseType; } - if (nose_scale >= 9) { + if (nose_scale > MaxNoseScale) { return ValidationResult::InvalidNoseScale; } - if (0x12 < nose_y) { + if (nose_y > MaxNoseY) { return ValidationResult::InvalidNoseY; } - if (0x23 < mouth_type) { + if (mouth_type > MouthType::Max) { return ValidationResult::InvalidMouthType; } - if (99 < mouth_color) { + if (mouth_color > CommonColor::Max) { return ValidationResult::InvalidMouthColor; } - if (8 < mouth_scale) { + if (mouth_scale > MaxMouthScale) { return ValidationResult::InvalidMouthScale; } - if (6 < mouth_aspect) { + if (mouth_aspect > MaxMoutAspect) { return ValidationResult::InvalidMouthAspect; } - if (0x12 < mouth_y) { + if (mouth_y > MaxMouthY) { return ValidationResult::InvalidMoleY; } - if (99 < beard_color) { + if (beard_color > CommonColor::Max) { return ValidationResult::InvalidBeardColor; } - if (5 < beard_type) { + if (beard_type > BeardType::Max) { return ValidationResult::InvalidBeardType; } - if (5 < mustache_type) { + if (mustache_type > MustacheType::Max) { return ValidationResult::InvalidMustacheType; } - if (8 < mustache_scale) { + if (mustache_scale > MaxMustacheScale) { return ValidationResult::InvalidMustacheScale; } - if (0x10 < mustache_y) { + if (mustache_y > MasMustacheY) { return ValidationResult::InvalidMustacheY; } - if (0x13 < glasses_type) { + if (glass_type > GlassType::Max) { return ValidationResult::InvalidGlassType; } - if (99 < glasses_color) { + if (glass_color > CommonColor::Max) { return ValidationResult::InvalidGlassColor; } - if (7 < glasses_scale) { + if (glass_scale > MaxGlassScale) { return ValidationResult::InvalidGlassScale; } - if (0x14 < glasses_y) { + if (glass_y > MaxGlassY) { return ValidationResult::InvalidGlassY; } - if (mole_type >= 2) { + if (mole_type > MoleType::Max) { return ValidationResult::InvalidMoleType; } - if (8 < mole_scale) { + if (mole_scale > MaxMoleScale) { return ValidationResult::InvalidMoleScale; } - if (mole_x >= 0x11) { + if (mole_x > MaxMoleX) { return ValidationResult::InvalidMoleX; } - if (0x1e < mole_y) { + if (mole_y > MaxMoleY) { return ValidationResult::InvalidMoleY; } return ValidationResult::NoErrors; @@ -227,15 +227,15 @@ Nickname CharInfo::GetNickname() const { return name; } -u8 CharInfo::GetFontRegion() const { +FontRegion CharInfo::GetFontRegion() const { return font_region; } -u8 CharInfo::GetFavoriteColor() const { +FavoriteColor CharInfo::GetFavoriteColor() const { return favorite_color; } -u8 CharInfo::GetGender() const { +Gender CharInfo::GetGender() const { return gender; } @@ -255,39 +255,39 @@ u8 CharInfo::GetRegionMove() const { return region_move; } -u8 CharInfo::GetFacelineType() const { +FacelineType CharInfo::GetFacelineType() const { return faceline_type; } -u8 CharInfo::GetFacelineColor() const { +FacelineColor CharInfo::GetFacelineColor() const { return faceline_color; } -u8 CharInfo::GetFacelineWrinkle() const { +FacelineWrinkle CharInfo::GetFacelineWrinkle() const { return faceline_wrinkle; } -u8 CharInfo::GetFacelineMake() const { +FacelineMake CharInfo::GetFacelineMake() const { return faceline_make; } -u8 CharInfo::GetHairType() const { +HairType CharInfo::GetHairType() const { return hair_type; } -u8 CharInfo::GetHairColor() const { +CommonColor CharInfo::GetHairColor() const { return hair_color; } -u8 CharInfo::GetHairFlip() const { +HairFlip CharInfo::GetHairFlip() const { return hair_flip; } -u8 CharInfo::GetEyeType() const { +EyeType CharInfo::GetEyeType() const { return eye_type; } -u8 CharInfo::GetEyeColor() const { +CommonColor CharInfo::GetEyeColor() const { return eye_color; } @@ -311,11 +311,11 @@ u8 CharInfo::GetEyeY() const { return eye_y; } -u8 CharInfo::GetEyebrowType() const { +EyebrowType CharInfo::GetEyebrowType() const { return eyebrow_type; } -u8 CharInfo::GetEyebrowColor() const { +CommonColor CharInfo::GetEyebrowColor() const { return eyebrow_color; } @@ -339,7 +339,7 @@ u8 CharInfo::GetEyebrowY() const { return eyebrow_y; } -u8 CharInfo::GetNoseType() const { +NoseType CharInfo::GetNoseType() const { return nose_type; } @@ -351,11 +351,11 @@ u8 CharInfo::GetNoseY() const { return nose_y; } -u8 CharInfo::GetMouthType() const { +MouthType CharInfo::GetMouthType() const { return mouth_type; } -u8 CharInfo::GetMouthColor() const { +CommonColor CharInfo::GetMouthColor() const { return mouth_color; } @@ -371,15 +371,15 @@ u8 CharInfo::GetMouthY() const { return mouth_y; } -u8 CharInfo::GetBeardColor() const { +CommonColor CharInfo::GetBeardColor() const { return beard_color; } -u8 CharInfo::GetBeardType() const { +BeardType CharInfo::GetBeardType() const { return beard_type; } -u8 CharInfo::GetMustacheType() const { +MustacheType CharInfo::GetMustacheType() const { return mustache_type; } @@ -391,23 +391,23 @@ u8 CharInfo::GetMustacheY() const { return mustache_y; } -u8 CharInfo::GetGlassType() const { - return glasses_type; +GlassType CharInfo::GetGlassType() const { + return glass_type; } -u8 CharInfo::GetGlassColor() const { - return glasses_color; +CommonColor CharInfo::GetGlassColor() const { + return glass_color; } u8 CharInfo::GetGlassScale() const { - return glasses_scale; + return glass_scale; } u8 CharInfo::GetGlassY() const { - return glasses_y; + return glass_y; } -u8 CharInfo::GetMoleType() const { +MoleType CharInfo::GetMoleType() const { return mole_type; } @@ -468,10 +468,10 @@ bool CharInfo::operator==(const CharInfo& info) { is_identical &= mustache_type == info.GetMustacheType(); is_identical &= mustache_scale == info.GetMustacheScale(); is_identical &= mustache_y == info.GetMustacheY(); - is_identical &= glasses_type == info.GetGlassType(); - is_identical &= glasses_color == info.GetGlassColor(); - is_identical &= glasses_scale == info.GetGlassScale(); - is_identical &= glasses_y == info.GetGlassY(); + is_identical &= glass_type == info.GetGlassType(); + is_identical &= glass_color == info.GetGlassColor(); + is_identical &= glass_scale == info.GetGlassScale(); + is_identical &= glass_y == info.GetGlassY(); is_identical &= mole_type == info.GetMoleType(); is_identical &= mole_scale == info.GetMoleScale(); is_identical &= mole_x == info.GetMoleX(); diff --git a/src/core/hle/service/mii/types/char_info.h b/src/core/hle/service/mii/types/char_info.h index 65a7707d3..d069b221f 100644 --- a/src/core/hle/service/mii/types/char_info.h +++ b/src/core/hle/service/mii/types/char_info.h @@ -17,52 +17,52 @@ public: Common::UUID GetCreateId() const; Nickname GetNickname() const; - u8 GetFontRegion() const; - u8 GetFavoriteColor() const; - u8 GetGender() const; + FontRegion GetFontRegion() const; + FavoriteColor GetFavoriteColor() const; + Gender GetGender() const; u8 GetHeight() const; u8 GetBuild() const; u8 GetType() const; u8 GetRegionMove() const; - u8 GetFacelineType() const; - u8 GetFacelineColor() const; - u8 GetFacelineWrinkle() const; - u8 GetFacelineMake() const; - u8 GetHairType() const; - u8 GetHairColor() const; - u8 GetHairFlip() const; - u8 GetEyeType() const; - u8 GetEyeColor() const; + FacelineType GetFacelineType() const; + FacelineColor GetFacelineColor() const; + FacelineWrinkle GetFacelineWrinkle() const; + FacelineMake GetFacelineMake() const; + HairType GetHairType() const; + CommonColor GetHairColor() const; + HairFlip GetHairFlip() const; + EyeType GetEyeType() const; + CommonColor GetEyeColor() const; u8 GetEyeScale() const; u8 GetEyeAspect() const; u8 GetEyeRotate() const; u8 GetEyeX() const; u8 GetEyeY() const; - u8 GetEyebrowType() const; - u8 GetEyebrowColor() const; + EyebrowType GetEyebrowType() const; + CommonColor GetEyebrowColor() const; u8 GetEyebrowScale() const; u8 GetEyebrowAspect() const; u8 GetEyebrowRotate() const; u8 GetEyebrowX() const; u8 GetEyebrowY() const; - u8 GetNoseType() const; + NoseType GetNoseType() const; u8 GetNoseScale() const; u8 GetNoseY() const; - u8 GetMouthType() const; - u8 GetMouthColor() const; + MouthType GetMouthType() const; + CommonColor GetMouthColor() const; u8 GetMouthScale() const; u8 GetMouthAspect() const; u8 GetMouthY() const; - u8 GetBeardColor() const; - u8 GetBeardType() const; - u8 GetMustacheType() const; + CommonColor GetBeardColor() const; + BeardType GetBeardType() const; + MustacheType GetMustacheType() const; u8 GetMustacheScale() const; u8 GetMustacheY() const; - u8 GetGlassType() const; - u8 GetGlassColor() const; + GlassType GetGlassType() const; + CommonColor GetGlassColor() const; u8 GetGlassScale() const; u8 GetGlassY() const; - u8 GetMoleType() const; + MoleType GetMoleType() const; u8 GetMoleScale() const; u8 GetMoleX() const; u8 GetMoleY() const; @@ -73,52 +73,52 @@ private: Common::UUID create_id; Nickname name; u16 null_terminator; - u8 font_region; - u8 favorite_color; - u8 gender; + FontRegion font_region; + FavoriteColor favorite_color; + Gender gender; u8 height; u8 build; u8 type; u8 region_move; - u8 faceline_type; - u8 faceline_color; - u8 faceline_wrinkle; - u8 faceline_make; - u8 hair_type; - u8 hair_color; - u8 hair_flip; - u8 eye_type; - u8 eye_color; + FacelineType faceline_type; + FacelineColor faceline_color; + FacelineWrinkle faceline_wrinkle; + FacelineMake faceline_make; + HairType hair_type; + CommonColor hair_color; + HairFlip hair_flip; + EyeType eye_type; + CommonColor eye_color; u8 eye_scale; u8 eye_aspect; u8 eye_rotate; u8 eye_x; u8 eye_y; - u8 eyebrow_type; - u8 eyebrow_color; + EyebrowType eyebrow_type; + CommonColor eyebrow_color; u8 eyebrow_scale; u8 eyebrow_aspect; u8 eyebrow_rotate; u8 eyebrow_x; u8 eyebrow_y; - u8 nose_type; + NoseType nose_type; u8 nose_scale; u8 nose_y; - u8 mouth_type; - u8 mouth_color; + MouthType mouth_type; + CommonColor mouth_color; u8 mouth_scale; u8 mouth_aspect; u8 mouth_y; - u8 beard_color; - u8 beard_type; - u8 mustache_type; + CommonColor beard_color; + BeardType beard_type; + MustacheType mustache_type; u8 mustache_scale; u8 mustache_y; - u8 glasses_type; - u8 glasses_color; - u8 glasses_scale; - u8 glasses_y; - u8 mole_type; + GlassType glass_type; + CommonColor glass_color; + u8 glass_scale; + u8 glass_y; + MoleType mole_type; u8 mole_scale; u8 mole_x; u8 mole_y; diff --git a/src/core/hle/service/mii/types/core_data.cpp b/src/core/hle/service/mii/types/core_data.cpp index de82481b0..659288b51 100644 --- a/src/core/hle/service/mii/types/core_data.cpp +++ b/src/core/hle/service/mii/types/core_data.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/assert.h" #include "core/hle/service/mii/mii_util.h" #include "core/hle/service/mii/types/core_data.h" #include "core/hle/service/mii/types/raw_data.h" @@ -14,17 +15,9 @@ void CoreData::SetDefault() { void CoreData::BuildRandom(Age age, Gender gender, Race race) { if (gender == Gender::All) { - gender = MiiUtil::GetRandomValue(Gender::Maximum); + gender = MiiUtil::GetRandomValue(Gender::Max); } - data.gender.Assign(gender); - data.favorite_color.Assign(MiiUtil::GetRandomValue(11)); - data.region_move.Assign(0); - data.font_region.Assign(FontRegion::Standard); - data.type.Assign(0); - data.height.Assign(64); - data.build.Assign(64); - if (age == Age::All) { const auto random{MiiUtil::GetRandomValue(10)}; if (random >= 8) { @@ -47,6 +40,14 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { } } + SetGender(gender); + SetFavoriteColor(MiiUtil::GetRandomValue(FavoriteColor::Max)); + SetRegionMove(0); + SetFontRegion(FontRegion::Standard); + SetType(0); + SetHeight(64); + SetBuild(64); + u32 axis_y{}; if (gender == Gender::Female && age == Age::Young) { axis_y = MiiUtil::GetRandomValue(3); @@ -85,10 +86,10 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { data.hair_type.Assign( hair_type_info.values[MiiUtil::GetRandomValue(hair_type_info.values_count)]); - data.hair_color.Assign(RawData::GetHairColorFromVer3( + SetHairColor(RawData::GetHairColorFromVer3( hair_color_info .values[MiiUtil::GetRandomValue(hair_color_info.values_count)])); - data.hair_flip.Assign(MiiUtil::GetRandomValue(HairFlip::Maximum)); + SetHairFlip(MiiUtil::GetRandomValue(HairFlip::Max)); data.eye_type.Assign( eye_type_info.values[MiiUtil::GetRandomValue(eye_type_info.values_count)]); @@ -98,13 +99,13 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { const auto eye_rotate_offset{32 - RawData::EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; const auto eye_rotate{32 - RawData::EyeRotateLookup[data.eye_type]}; - data.eye_color.Assign(RawData::GetEyeColorFromVer3( + SetEyeColor(RawData::GetEyeColorFromVer3( eye_color_info.values[MiiUtil::GetRandomValue(eye_color_info.values_count)])); - data.eye_scale.Assign(4); - data.eye_aspect.Assign(3); - data.eye_rotate.Assign(eye_rotate_offset - eye_rotate); - data.eye_x.Assign(2); - data.eye_y.Assign(axis_y + 12); + SetEyeScale(4); + SetEyeAspect(3); + SetEyeRotate(static_cast(eye_rotate_offset - eye_rotate)); + SetEyeX(2); + SetEyeY(static_cast(axis_y + 12)); data.eyebrow_type.Assign( eyebrow_type_info @@ -116,57 +117,53 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { const auto eyebrow_rotate{ 32 - RawData::EyebrowRotateLookup[static_cast(data.eyebrow_type.Value())]}; - data.eyebrow_color.Assign(data.hair_color); - data.eyebrow_scale.Assign(4); - data.eyebrow_aspect.Assign(3); - data.eyebrow_rotate.Assign(eyebrow_rotate_offset - eyebrow_rotate); - data.eyebrow_x.Assign(2); - data.eyebrow_y.Assign(axis_y + eyebrow_y); - - const auto nose_scale{gender == Gender::Female ? 3 : 4}; + SetEyebrowColor(GetHairColor()); + SetEyebrowScale(4); + SetEyebrowAspect(3); + SetEyebrowRotate(static_cast(eyebrow_rotate_offset - eyebrow_rotate)); + SetEyebrowX(2); + SetEyebrowY(static_cast(axis_y + eyebrow_y)); data.nose_type.Assign( nose_type_info.values[MiiUtil::GetRandomValue(nose_type_info.values_count)]); - data.nose_scale.Assign(nose_scale); - data.nose_y.Assign(axis_y + 9); + SetNoseScale(gender == Gender::Female ? 3 : 4); + SetNoseY(static_cast(axis_y + 9)); const auto mouth_color{gender == Gender::Female ? MiiUtil::GetRandomValue(4) : 0}; data.mouth_type.Assign( mouth_type_info.values[MiiUtil::GetRandomValue(mouth_type_info.values_count)]); - data.mouth_color.Assign(RawData::GetMouthColorFromVer3(mouth_color)); - data.mouth_scale.Assign(4); - data.mouth_aspect.Assign(3); - data.mouth_y.Assign(axis_y + 13); + SetMouthColor(RawData::GetMouthColorFromVer3(mouth_color)); + SetMouthScale(4); + SetMouthAspect(3); + SetMouthY(static_cast(axis_y + 13)); - data.beard_color.Assign(data.hair_color); - data.mustache_scale.Assign(4); + SetBeardColor(GetHairColor()); + SetMustacheScale(4); if (gender == Gender::Male && age != Age::Young && MiiUtil::GetRandomValue(10) < 2) { - const auto mustache_and_beard_flag{ - MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; + const auto mustache_and_beard_flag{MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; auto beard_type{BeardType::None}; auto mustache_type{MustacheType::None}; if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) == BeardAndMustacheFlag::Beard) { - beard_type = MiiUtil::GetRandomValue(BeardType::Beard1, BeardType::Beard5); + beard_type = MiiUtil::GetRandomValue(BeardType::Min, BeardType::Max); } if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) == BeardAndMustacheFlag::Mustache) { - mustache_type = MiiUtil::GetRandomValue(MustacheType::Mustache1, - MustacheType::Mustache5); + mustache_type = MiiUtil::GetRandomValue(MustacheType::Min, MustacheType::Max); } - data.mustache_type.Assign(mustache_type); - data.beard_type.Assign(beard_type); - data.mustache_y.Assign(10); + SetMustacheType(mustache_type); + SetBeardType(beard_type); + SetMustacheY(10); } else { - data.mustache_type.Assign(MustacheType::None); - data.beard_type.Assign(BeardType::None); - data.mustache_y.Assign(axis_y + 10); + SetMustacheType(MustacheType::None); + SetBeardType(BeardType::None); + SetMustacheY(static_cast(axis_y + 10)); } const auto glasses_type_start{MiiUtil::GetRandomValue(100)}; @@ -178,15 +175,14 @@ void CoreData::BuildRandom(Age age, Gender gender, Race race) { } } - data.glasses_type.Assign(glasses_type); - data.glasses_color.Assign(RawData::GetGlassColorFromVer3(0)); - data.glasses_scale.Assign(4); - data.glasses_y.Assign(axis_y + 10); + SetGlassType(static_cast(glasses_type)); + SetGlassColor(RawData::GetGlassColorFromVer3(0)); + SetGlassScale(4); - data.mole_type.Assign(0); - data.mole_scale.Assign(4); - data.mole_x.Assign(2); - data.mole_y.Assign(20); + SetMoleType(MoleType::None); + SetMoleScale(4); + SetMoleX(2); + SetMoleY(20); } u32 CoreData::IsValid() const { @@ -195,15 +191,15 @@ u32 CoreData::IsValid() const { } void CoreData::SetFontRegion(FontRegion value) { - data.font_region.Assign(value); + data.font_region.Assign(static_cast(value)); } -void CoreData::SetFavoriteColor(u8 value) { - data.favorite_color.Assign(value); +void CoreData::SetFavoriteColor(FavoriteColor value) { + data.favorite_color.Assign(static_cast(value)); } void CoreData::SetGender(Gender value) { - data.gender.Assign(value); + data.gender.Assign(static_cast(value)); } void CoreData::SetHeight(u8 value) { @@ -222,40 +218,40 @@ void CoreData::SetRegionMove(u8 value) { data.region_move.Assign(value); } -void CoreData::SetFacelineType(u8 value) { - data.faceline_type.Assign(value); +void CoreData::SetFacelineType(FacelineType value) { + data.faceline_type.Assign(static_cast(value)); } -void CoreData::SetFacelineColor(u8 value) { - data.faceline_color.Assign(value); +void CoreData::SetFacelineColor(FacelineColor value) { + data.faceline_color.Assign(static_cast(value)); } -void CoreData::SetFacelineWrinkle(u8 value) { - data.faceline_wrinkle.Assign(value); +void CoreData::SetFacelineWrinkle(FacelineWrinkle value) { + data.faceline_wrinkle.Assign(static_cast(value)); } -void CoreData::SetFacelineMake(u8 value) { - data.faceline_makeup.Assign(value); +void CoreData::SetFacelineMake(FacelineMake value) { + data.faceline_makeup.Assign(static_cast(value)); } -void CoreData::SetHairType(u8 value) { - data.hair_type.Assign(value); +void CoreData::SetHairType(HairType value) { + data.hair_type.Assign(static_cast(value)); } -void CoreData::SetHairColor(u8 value) { - data.hair_color.Assign(value); +void CoreData::SetHairColor(CommonColor value) { + data.hair_color.Assign(static_cast(value)); } void CoreData::SetHairFlip(HairFlip value) { - data.hair_flip.Assign(value); + data.hair_flip.Assign(static_cast(value)); } -void CoreData::SetEyeType(u8 value) { - data.eye_type.Assign(value); +void CoreData::SetEyeType(EyeType value) { + data.eye_type.Assign(static_cast(value)); } -void CoreData::SetEyeColor(u8 value) { - data.eye_color.Assign(value); +void CoreData::SetEyeColor(CommonColor value) { + data.eye_color.Assign(static_cast(value)); } void CoreData::SetEyeScale(u8 value) { @@ -278,12 +274,12 @@ void CoreData::SetEyeY(u8 value) { data.eye_y.Assign(value); } -void CoreData::SetEyebrowType(u8 value) { - data.eyebrow_type.Assign(value); +void CoreData::SetEyebrowType(EyebrowType value) { + data.eyebrow_type.Assign(static_cast(value)); } -void CoreData::SetEyebrowColor(u8 value) { - data.eyebrow_color.Assign(value); +void CoreData::SetEyebrowColor(CommonColor value) { + data.eyebrow_color.Assign(static_cast(value)); } void CoreData::SetEyebrowScale(u8 value) { @@ -306,8 +302,8 @@ void CoreData::SetEyebrowY(u8 value) { data.eyebrow_y.Assign(value); } -void CoreData::SetNoseType(u8 value) { - data.nose_type.Assign(value); +void CoreData::SetNoseType(NoseType value) { + data.nose_type.Assign(static_cast(value)); } void CoreData::SetNoseScale(u8 value) { @@ -322,8 +318,8 @@ void CoreData::SetMouthType(u8 value) { data.mouth_type.Assign(value); } -void CoreData::SetMouthColor(u8 value) { - data.mouth_color.Assign(value); +void CoreData::SetMouthColor(CommonColor value) { + data.mouth_color.Assign(static_cast(value)); } void CoreData::SetMouthScale(u8 value) { @@ -338,16 +334,16 @@ void CoreData::SetMouthY(u8 value) { data.mouth_y.Assign(value); } -void CoreData::SetBeardColor(u8 value) { - data.beard_color.Assign(value); +void CoreData::SetBeardColor(CommonColor value) { + data.beard_color.Assign(static_cast(value)); } void CoreData::SetBeardType(BeardType value) { - data.beard_type.Assign(value); + data.beard_type.Assign(static_cast(value)); } void CoreData::SetMustacheType(MustacheType value) { - data.mustache_type.Assign(value); + data.mustache_type.Assign(static_cast(value)); } void CoreData::SetMustacheScale(u8 value) { @@ -358,12 +354,12 @@ void CoreData::SetMustacheY(u8 value) { data.mustache_y.Assign(value); } -void CoreData::SetGlassType(u8 value) { - data.glasses_type.Assign(value); +void CoreData::SetGlassType(GlassType value) { + data.glasses_type.Assign(static_cast(value)); } -void CoreData::SetGlassColor(u8 value) { - data.glasses_color.Assign(value); +void CoreData::SetGlassColor(CommonColor value) { + data.glasses_color.Assign(static_cast(value)); } void CoreData::SetGlassScale(u8 value) { @@ -374,8 +370,8 @@ void CoreData::SetGlassY(u8 value) { data.glasses_y.Assign(value); } -void CoreData::SetMoleType(u8 value) { - data.mole_type.Assign(value); +void CoreData::SetMoleType(MoleType value) { + data.mole_type.Assign(static_cast(value)); } void CoreData::SetMoleScale(u8 value) { @@ -394,16 +390,16 @@ void CoreData::SetNickname(Nickname nickname) { name = nickname; } -u8 CoreData::GetFontRegion() const { - return static_cast(data.font_region.Value()); +FontRegion CoreData::GetFontRegion() const { + return static_cast(data.font_region.Value()); } -u8 CoreData::GetFavoriteColor() const { - return static_cast(data.favorite_color.Value()); +FavoriteColor CoreData::GetFavoriteColor() const { + return static_cast(data.favorite_color.Value()); } -u8 CoreData::GetGender() const { - return static_cast(data.gender.Value()); +Gender CoreData::GetGender() const { + return static_cast(data.gender.Value()); } u8 CoreData::GetHeight() const { @@ -422,40 +418,40 @@ u8 CoreData::GetRegionMove() const { return static_cast(data.region_move.Value()); } -u8 CoreData::GetFacelineType() const { - return static_cast(data.faceline_type.Value()); +FacelineType CoreData::GetFacelineType() const { + return static_cast(data.faceline_type.Value()); } -u8 CoreData::GetFacelineColor() const { - return static_cast(data.faceline_color.Value()); +FacelineColor CoreData::GetFacelineColor() const { + return static_cast(data.faceline_color.Value()); } -u8 CoreData::GetFacelineWrinkle() const { - return static_cast(data.faceline_wrinkle.Value()); +FacelineWrinkle CoreData::GetFacelineWrinkle() const { + return static_cast(data.faceline_wrinkle.Value()); } -u8 CoreData::GetFacelineMake() const { - return static_cast(data.faceline_makeup.Value()); +FacelineMake CoreData::GetFacelineMake() const { + return static_cast(data.faceline_makeup.Value()); } -u8 CoreData::GetHairType() const { - return static_cast(data.hair_type.Value()); +HairType CoreData::GetHairType() const { + return static_cast(data.hair_type.Value()); } -u8 CoreData::GetHairColor() const { - return static_cast(data.hair_color.Value()); +CommonColor CoreData::GetHairColor() const { + return static_cast(data.hair_color.Value()); } -u8 CoreData::GetHairFlip() const { - return static_cast(data.hair_flip.Value()); +HairFlip CoreData::GetHairFlip() const { + return static_cast(data.hair_flip.Value()); } -u8 CoreData::GetEyeType() const { - return static_cast(data.eye_type.Value()); +EyeType CoreData::GetEyeType() const { + return static_cast(data.eye_type.Value()); } -u8 CoreData::GetEyeColor() const { - return static_cast(data.eye_color.Value()); +CommonColor CoreData::GetEyeColor() const { + return static_cast(data.eye_color.Value()); } u8 CoreData::GetEyeScale() const { @@ -478,12 +474,12 @@ u8 CoreData::GetEyeY() const { return static_cast(data.eye_y.Value()); } -u8 CoreData::GetEyebrowType() const { - return static_cast(data.eyebrow_type.Value()); +EyebrowType CoreData::GetEyebrowType() const { + return static_cast(data.eyebrow_type.Value()); } -u8 CoreData::GetEyebrowColor() const { - return static_cast(data.eyebrow_color.Value()); +CommonColor CoreData::GetEyebrowColor() const { + return static_cast(data.eyebrow_color.Value()); } u8 CoreData::GetEyebrowScale() const { @@ -506,8 +502,8 @@ u8 CoreData::GetEyebrowY() const { return static_cast(data.eyebrow_y.Value()); } -u8 CoreData::GetNoseType() const { - return static_cast(data.nose_type.Value()); +NoseType CoreData::GetNoseType() const { + return static_cast(data.nose_type.Value()); } u8 CoreData::GetNoseScale() const { @@ -518,12 +514,12 @@ u8 CoreData::GetNoseY() const { return static_cast(data.nose_y.Value()); } -u8 CoreData::GetMouthType() const { - return static_cast(data.mouth_type.Value()); +MouthType CoreData::GetMouthType() const { + return static_cast(data.mouth_type.Value()); } -u8 CoreData::GetMouthColor() const { - return static_cast(data.mouth_color.Value()); +CommonColor CoreData::GetMouthColor() const { + return static_cast(data.mouth_color.Value()); } u8 CoreData::GetMouthScale() const { @@ -538,16 +534,16 @@ u8 CoreData::GetMouthY() const { return static_cast(data.mouth_y.Value()); } -u8 CoreData::GetBeardColor() const { - return static_cast(data.beard_color.Value()); +CommonColor CoreData::GetBeardColor() const { + return static_cast(data.beard_color.Value()); } -u8 CoreData::GetBeardType() const { - return static_cast(data.beard_type.Value()); +BeardType CoreData::GetBeardType() const { + return static_cast(data.beard_type.Value()); } -u8 CoreData::GetMustacheType() const { - return static_cast(data.mustache_type.Value()); +MustacheType CoreData::GetMustacheType() const { + return static_cast(data.mustache_type.Value()); } u8 CoreData::GetMustacheScale() const { @@ -558,12 +554,12 @@ u8 CoreData::GetMustacheY() const { return static_cast(data.mustache_y.Value()); } -u8 CoreData::GetGlassType() const { - return static_cast(data.glasses_type.Value()); +GlassType CoreData::GetGlassType() const { + return static_cast(data.glasses_type.Value()); } -u8 CoreData::GetGlassColor() const { - return static_cast(data.glasses_color.Value()); +CommonColor CoreData::GetGlassColor() const { + return static_cast(data.glasses_color.Value()); } u8 CoreData::GetGlassScale() const { @@ -574,8 +570,8 @@ u8 CoreData::GetGlassY() const { return static_cast(data.glasses_y.Value()); } -u8 CoreData::GetMoleType() const { - return static_cast(data.mole_type.Value()); +MoleType CoreData::GetMoleType() const { + return static_cast(data.mole_type.Value()); } u8 CoreData::GetMoleScale() const { @@ -599,7 +595,7 @@ Nickname CoreData::GetDefaultNickname() const { } Nickname CoreData::GetInvalidNickname() const { - return {u'?', u'?', u' ', u'?'}; + return {u'?', u'?', u'?'}; } } // namespace Service::Mii diff --git a/src/core/hle/service/mii/types/core_data.h b/src/core/hle/service/mii/types/core_data.h index 411c123b3..cebcd2ee4 100644 --- a/src/core/hle/service/mii/types/core_data.h +++ b/src/core/hle/service/mii/types/core_data.h @@ -15,7 +15,7 @@ struct StoreDataBitFields { BitField<8, 7, u32> height; BitField<15, 1, u32> mole_type; BitField<16, 7, u32> build; - BitField<23, 1, HairFlip> hair_flip; + BitField<23, 1, u32> hair_flip; BitField<24, 7, u32> hair_color; BitField<31, 1, u32> type; }; @@ -24,7 +24,7 @@ struct StoreDataBitFields { u32 word_1{}; BitField<0, 7, u32> eye_color; - BitField<7, 1, Gender> gender; + BitField<7, 1, u32> gender; BitField<8, 7, u32> eyebrow_color; BitField<16, 7, u32> mouth_color; BitField<24, 7, u32> beard_color; @@ -37,7 +37,7 @@ struct StoreDataBitFields { BitField<8, 6, u32> eye_type; BitField<14, 2, u32> region_move; BitField<16, 6, u32> mouth_type; - BitField<22, 2, FontRegion> font_region; + BitField<22, 2, u32> font_region; BitField<24, 5, u32> eye_y; BitField<29, 3, u32> glasses_scale; }; @@ -46,9 +46,9 @@ struct StoreDataBitFields { u32 word_3{}; BitField<0, 5, u32> eyebrow_type; - BitField<5, 3, MustacheType> mustache_type; + BitField<5, 3, u32> mustache_type; BitField<8, 5, u32> nose_type; - BitField<13, 3, BeardType> beard_type; + BitField<13, 3, u32> beard_type; BitField<16, 5, u32> nose_y; BitField<21, 3, u32> mouth_aspect; BitField<24, 5, u32> mouth_y; @@ -104,102 +104,102 @@ public: u32 IsValid() const; void SetFontRegion(FontRegion value); - void SetFavoriteColor(u8 value); + void SetFavoriteColor(FavoriteColor value); void SetGender(Gender value); void SetHeight(u8 value); void SetBuild(u8 value); void SetType(u8 value); void SetRegionMove(u8 value); - void SetFacelineType(u8 value); - void SetFacelineColor(u8 value); - void SetFacelineWrinkle(u8 value); - void SetFacelineMake(u8 value); - void SetHairType(u8 value); - void SetHairColor(u8 value); + void SetFacelineType(FacelineType value); + void SetFacelineColor(FacelineColor value); + void SetFacelineWrinkle(FacelineWrinkle value); + void SetFacelineMake(FacelineMake value); + void SetHairType(HairType value); + void SetHairColor(CommonColor value); void SetHairFlip(HairFlip value); - void SetEyeType(u8 value); - void SetEyeColor(u8 value); + void SetEyeType(EyeType value); + void SetEyeColor(CommonColor value); void SetEyeScale(u8 value); void SetEyeAspect(u8 value); void SetEyeRotate(u8 value); void SetEyeX(u8 value); void SetEyeY(u8 value); - void SetEyebrowType(u8 value); - void SetEyebrowColor(u8 value); + void SetEyebrowType(EyebrowType value); + void SetEyebrowColor(CommonColor value); void SetEyebrowScale(u8 value); void SetEyebrowAspect(u8 value); void SetEyebrowRotate(u8 value); void SetEyebrowX(u8 value); void SetEyebrowY(u8 value); - void SetNoseType(u8 value); + void SetNoseType(NoseType value); void SetNoseScale(u8 value); void SetNoseY(u8 value); void SetMouthType(u8 value); - void SetMouthColor(u8 value); + void SetMouthColor(CommonColor value); void SetMouthScale(u8 value); void SetMouthAspect(u8 value); void SetMouthY(u8 value); - void SetBeardColor(u8 value); + void SetBeardColor(CommonColor value); void SetBeardType(BeardType value); void SetMustacheType(MustacheType value); void SetMustacheScale(u8 value); void SetMustacheY(u8 value); - void SetGlassType(u8 value); - void SetGlassColor(u8 value); + void SetGlassType(GlassType value); + void SetGlassColor(CommonColor value); void SetGlassScale(u8 value); void SetGlassY(u8 value); - void SetMoleType(u8 value); + void SetMoleType(MoleType value); void SetMoleScale(u8 value); void SetMoleX(u8 value); void SetMoleY(u8 value); void SetNickname(Nickname nickname); - u8 GetFontRegion() const; - u8 GetFavoriteColor() const; - u8 GetGender() const; + FontRegion GetFontRegion() const; + FavoriteColor GetFavoriteColor() const; + Gender GetGender() const; u8 GetHeight() const; u8 GetBuild() const; u8 GetType() const; u8 GetRegionMove() const; - u8 GetFacelineType() const; - u8 GetFacelineColor() const; - u8 GetFacelineWrinkle() const; - u8 GetFacelineMake() const; - u8 GetHairType() const; - u8 GetHairColor() const; - u8 GetHairFlip() const; - u8 GetEyeType() const; - u8 GetEyeColor() const; + FacelineType GetFacelineType() const; + FacelineColor GetFacelineColor() const; + FacelineWrinkle GetFacelineWrinkle() const; + FacelineMake GetFacelineMake() const; + HairType GetHairType() const; + CommonColor GetHairColor() const; + HairFlip GetHairFlip() const; + EyeType GetEyeType() const; + CommonColor GetEyeColor() const; u8 GetEyeScale() const; u8 GetEyeAspect() const; u8 GetEyeRotate() const; u8 GetEyeX() const; u8 GetEyeY() const; - u8 GetEyebrowType() const; - u8 GetEyebrowColor() const; + EyebrowType GetEyebrowType() const; + CommonColor GetEyebrowColor() const; u8 GetEyebrowScale() const; u8 GetEyebrowAspect() const; u8 GetEyebrowRotate() const; u8 GetEyebrowX() const; u8 GetEyebrowY() const; - u8 GetNoseType() const; + NoseType GetNoseType() const; u8 GetNoseScale() const; u8 GetNoseY() const; - u8 GetMouthType() const; - u8 GetMouthColor() const; + MouthType GetMouthType() const; + CommonColor GetMouthColor() const; u8 GetMouthScale() const; u8 GetMouthAspect() const; u8 GetMouthY() const; - u8 GetBeardColor() const; - u8 GetBeardType() const; - u8 GetMustacheType() const; + CommonColor GetBeardColor() const; + BeardType GetBeardType() const; + MustacheType GetMustacheType() const; u8 GetMustacheScale() const; u8 GetMustacheY() const; - u8 GetGlassType() const; - u8 GetGlassColor() const; + GlassType GetGlassType() const; + CommonColor GetGlassColor() const; u8 GetGlassScale() const; u8 GetGlassY() const; - u8 GetMoleType() const; + MoleType GetMoleType() const; u8 GetMoleScale() const; u8 GetMoleX() const; u8 GetMoleY() const; @@ -207,6 +207,7 @@ public: Nickname GetDefaultNickname() const; Nickname GetInvalidNickname() const; +private: StoreDataBitFields data{}; Nickname name{}; }; diff --git a/src/core/hle/service/mii/types/raw_data.cpp b/src/core/hle/service/mii/types/raw_data.cpp index ed299521f..5143abcc8 100644 --- a/src/core/hle/service/mii/types/raw_data.cpp +++ b/src/core/hle/service/mii/types/raw_data.cpp @@ -5,11 +5,11 @@ namespace Service::Mii::RawData { -constexpr std::array FromVer3FacelineColorTable{ +constexpr std::array(FacelineColor::Count)> FromVer3FacelineColorTable{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, }; -constexpr std::array FromVer3HairColorTable{ +constexpr std::array(CommonColor::Count)> FromVer3HairColorTable{ 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, @@ -18,7 +18,7 @@ constexpr std::array FromVer3HairColorTable{ 0x7, 0x7, 0x7, 0x7, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x4, 0x4, 0x4, }; -constexpr std::array FromVer3EyeColorTable{ +constexpr std::array(CommonColor::Count)> FromVer3EyeColorTable{ 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, @@ -27,7 +27,7 @@ constexpr std::array FromVer3EyeColorTable{ 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, }; -constexpr std::array FromVer3MouthlineColorTable{ +constexpr std::array(CommonColor::Count)> FromVer3MouthlineColorTable{ 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, @@ -36,7 +36,7 @@ constexpr std::array FromVer3MouthlineColorTable{ 0x3, 0x3, 0x3, 0x3, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x3, 0x3, }; -constexpr std::array FromVer3GlassColorTable{ +constexpr std::array(CommonColor::Count)> FromVer3GlassColorTable{ 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, @@ -45,7 +45,7 @@ constexpr std::array FromVer3GlassColorTable{ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, }; -constexpr std::array FromVer3GlassTypeTable{ +constexpr std::array(GlassType::Count)> FromVer3GlassTypeTable{ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7, }; @@ -90,7 +90,7 @@ const std::array BaseMii{ .face_makeup = 0, .hair_type = 33, .hair_color = 1, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -113,8 +113,8 @@ const std::array BaseMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -128,10 +128,10 @@ const std::array BaseMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Male, + .gender = 0, .favorite_color = 0, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -142,7 +142,7 @@ const std::array BaseMii{ .face_makeup = 0, .hair_type = 12, .hair_color = 1, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -165,8 +165,8 @@ const std::array BaseMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -180,10 +180,10 @@ const std::array BaseMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Female, + .gender = 1, .favorite_color = 0, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -197,7 +197,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 68, .hair_color = 0, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -220,8 +220,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -235,10 +235,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Male, + .gender = 0, .favorite_color = 4, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -249,7 +249,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 55, .hair_color = 6, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 2, .eye_color = 4, .eye_scale = 4, @@ -272,8 +272,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -287,10 +287,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Male, + .gender = 0, .favorite_color = 5, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -301,7 +301,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 33, .hair_color = 1, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 2, .eye_color = 0, .eye_scale = 4, @@ -324,8 +324,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -339,10 +339,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Male, + .gender = 0, .favorite_color = 0, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -353,7 +353,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 24, .hair_color = 0, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -376,8 +376,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -391,10 +391,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Female, + .gender = 1, .favorite_color = 2, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -405,7 +405,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 14, .hair_color = 7, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 4, .eye_color = 5, .eye_scale = 4, @@ -428,8 +428,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -443,10 +443,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Female, + .gender = 1, .favorite_color = 6, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -457,7 +457,7 @@ const std::array DefaultMii{ .face_makeup = 0, .hair_type = 12, .hair_color = 1, - .hair_flip = HairFlip::Left, + .hair_flip = 0, .eye_type = 4, .eye_color = 0, .eye_scale = 4, @@ -480,8 +480,8 @@ const std::array DefaultMii{ .mouth_scale = 4, .mouth_aspect = 3, .mouth_y = 13, - .mustache_type = MustacheType::None, - .beard_type = BeardType::None, + .mustache_type = 0, + .beard_type = 0, .beard_color = 0, .mustache_scale = 4, .mustache_y = 10, @@ -495,10 +495,10 @@ const std::array DefaultMii{ .mole_y = 20, .height = 64, .weight = 64, - .gender = Gender::Female, + .gender = 1, .favorite_color = 7, .region_move = 0, - .font_region = FontRegion::Standard, + .font_region = 0, .type = 0, .nickname = {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}, }, @@ -507,128 +507,128 @@ const std::array DefaultMii{ const std::array RandomMiiFaceline{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 13, .values = {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 13, .values = {0, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 0, 1, 2, 2, 3, 4, 5, 6, 7, 10, 11}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 10, .values = {0, 0, 1, 1, 2, 3, 4, 5, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 0, 0, 1, 1, 1, 2, 3, 4, 5, 8, 10}, }, @@ -675,128 +675,128 @@ const std::array RandomMiiFacelineColor{ const std::array RandomMiiFacelineWrinkle{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4, 8, 8}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4, 8, 8}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 4, 4}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 20, .values = {9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11}, }, @@ -804,128 +804,128 @@ const std::array RandomMiiFacelineWrinkle{ const std::array RandomMiiFacelineMakeup{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 20, .values = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, }, @@ -933,147 +933,147 @@ const std::array RandomMiiFacelineMakeup{ const std::array RandomMiiHairType{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 30, .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 75, 76, 86, 89}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 31, .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 73, 75, 81, 86, 87}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 31, .values = {13, 23, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 54, 56, 57, 64, 66, 73, 75, 81, 86, 87}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 38, .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 40, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 75, 76, 86, 89}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 39, .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 73, 75, 81, 86, 87}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 39, .values = {13, 23, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 60, 64, 65, 66, 67, 68, 70, 73, 75, 81, 86, 87}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 18, .values = {13, 23, 30, 36, 37, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 19, .values = {13, 23, 30, 36, 37, 39, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 19, .values = {13, 23, 30, 36, 37, 39, 41, 45, 47, 51, 53, 54, 55, 58, 59, 65, 67, 86, 88}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 39, .values = {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 76, 77, 79, 80, 83, 85}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 42, .values = {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 72, 74, 77, 78, 82, 83, 84, 85, 87}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 42, .values = {0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 46, 50, 61, 62, 63, 64, 69, 72, 74, 77, 78, 82, 83, 84, 85, 87}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 44, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 42, 50, 58, 60, 62, 63, 64, 69, 71, 76, 79, 80, 81, 82, 83, 86}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 44, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 50, 58, 60, 62, 63, 64, 69, 71, 72, 74, 79, 81, 82, 83, 84, 85}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 44, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 29, 50, 58, 60, 62, 63, 64, 69, 71, 72, 74, 79, 81, 82, 83, 84, 85}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 24, .values = {0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21, 24, 25, 58, 62, 69, 76, 83}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 27, .values = {0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21, 24, 25, 58, 62, 69, 74, 76, 81, 83, 85}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 27, .values = {0, 1, 2, 3, 4, 5, 6, 10, 11, 12, 13, 14, 16, 17, 18, 20, 21, 24, 25, 58, 62, 69, 74, 76, 81, 83, 85}, @@ -1139,148 +1139,148 @@ const std::array RandomMiiHairColor{ const std::array RandomMiiEyeType{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 26, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 49, 51, 53, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 26, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 49, 51, 53, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 27, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 15, 16, 18, 26, 27, 29, 32, 34, 36, 38, 39, 41, 43, 47, 48, 49, 53, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 35, .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21, 22, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 49, 51, 53, 55, 56, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 35, .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 21, 22, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 49, 51, 53, 55, 56, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 35, .values = {2, 3, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 18, 21, 22, 26, 27, 29, 31, 32, 34, 36, 37, 38, 39, 41, 43, 44, 47, 48, 49, 50, 53, 56, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 30, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 31, 32, 34, 36, 37, 39, 41, 44, 49, 51, 53, 55, 56, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 30, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 21, 22, 31, 32, 34, 36, 37, 39, 41, 44, 49, 51, 53, 55, 56, 57}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 30, .values = {2, 3, 5, 7, 8, 9, 11, 12, 13, 14, 15, 16, 18, 21, 22, 26, 31, 32, 34, 36, 37, 39, 41, 44, 48, 49, 50, 51, 53, 57}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 39, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 39, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 40, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 46, .values = {0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 46, .values = {0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 46, .values = {0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 37, 38, 39, 40, 41, 42, 45, 46, 47, 48, 53, 54, 57, 58, 59}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 34, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 34, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 35, .values = {0, 1, 2, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 19, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 38, 39, 40, 41, 42, 45, 46, 47}, @@ -1307,131 +1307,131 @@ const std::array RandomMiiEyeColor{ const std::array RandomMiiEyebrowType{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 20}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 23, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 23, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 23, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 21, .values = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 9, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 11, .values = {0, 1, 3, 7, 8, 9, 10, 11, 13, 15, 19}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 9, .values = {0, 3, 7, 8, 9, 10, 11, 13, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 9, .values = {0, 3, 7, 8, 9, 10, 11, 13, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 9, .values = {0, 3, 7, 8, 9, 10, 11, 13, 15}, }, @@ -1439,128 +1439,128 @@ const std::array RandomMiiEyebrowType{ const std::array RandomMiiNoseType{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 11, .values = {0, 1, 2, 3, 4, 5, 7, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 15, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 18, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 15, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 8, .values = {0, 1, 3, 4, 8, 10, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 12, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 14, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 11, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 10, .values = {0, 1, 3, 4, 6, 8, 10, 11, 13, 14}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 12, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 14, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 11, .values = {0, 1, 3, 4, 6, 8, 9, 10, 11, 13, 15}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 10, .values = {0, 1, 3, 4, 6, 8, 10, 11, 13, 14}, }, @@ -1568,145 +1568,145 @@ const std::array RandomMiiNoseType{ const std::array RandomMiiMouthType{ RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 25, .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 32, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 27, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 32, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 28, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 28, 30, 31, 32, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 24, .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 26, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 26, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 24, .values = {0, 2, 3, 6, 7, 8, 9, 10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 26, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Male, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Male), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 26, .values = {0, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 30, 31, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Black), .values_count = 25, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Black), .values_count = 26, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Black, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Black), .values_count = 26, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 30, 33, 34, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::White), .values_count = 25, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 26, 27, 29, 33, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::White), .values_count = 26, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 24, 26, 27, 29, 33, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::White, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::White), .values_count = 25, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 29, 33, 35}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Young, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Young), + .race = static_cast(Race::Asian), .values_count = 24, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 29, 33}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Normal, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Normal), + .race = static_cast(Race::Asian), .values_count = 25, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 29, 33}, }, RandomMiiData4{ - .gender = Gender::Female, - .age = Age::Old, - .race = Race::Asian, + .gender = static_cast(Gender::Female), + .age = static_cast(Age::Old), + .race = static_cast(Race::Asian), .values_count = 25, .values = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 25, 26, 29, 33}, @@ -1755,24 +1755,24 @@ u8 FromVer3GetGlassType(u8 type) { return FromVer3GlassTypeTable[type]; } -u8 GetFacelineColorFromVer3(u8 color) { - return Ver3FacelineColorTable[color]; +FacelineColor GetFacelineColorFromVer3(u32 color) { + return static_cast(Ver3FacelineColorTable[color]); } -u8 GetHairColorFromVer3(u32 color) { - return Ver3HairColorTable[color]; +CommonColor GetHairColorFromVer3(u32 color) { + return static_cast(Ver3HairColorTable[color]); } -u8 GetEyeColorFromVer3(u32 color) { - return Ver3EyeColorTable[color]; +CommonColor GetEyeColorFromVer3(u32 color) { + return static_cast(Ver3EyeColorTable[color]); } -u8 GetMouthColorFromVer3(u32 color) { - return Ver3MouthColorTable[color]; +CommonColor GetMouthColorFromVer3(u32 color) { + return static_cast(Ver3MouthColorTable[color]); } -u8 GetGlassColorFromVer3(u8 color) { - return Ver3GlassColorTable[color]; +CommonColor GetGlassColorFromVer3(u32 color) { + return static_cast(Ver3GlassColorTable[color]); } } // namespace Service::Mii::RawData diff --git a/src/core/hle/service/mii/types/raw_data.h b/src/core/hle/service/mii/types/raw_data.h index 8c910096f..9a4cfa738 100644 --- a/src/core/hle/service/mii/types/raw_data.h +++ b/src/core/hle/service/mii/types/raw_data.h @@ -15,9 +15,9 @@ struct RandomMiiValues { static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); struct RandomMiiData4 { - Gender gender{}; - Age age{}; - Race race{}; + u32 gender{}; + u32 age{}; + u32 race{}; u32 values_count{}; std::array values{}; }; @@ -64,10 +64,10 @@ u8 FromVer3GetMouthlineColor(u8 color); u8 FromVer3GetGlassColor(u8 color); u8 FromVer3GetGlassType(u8 type); -u8 GetFacelineColorFromVer3(u8 color); -u8 GetHairColorFromVer3(u32 color); -u8 GetEyeColorFromVer3(u32 color); -u8 GetMouthColorFromVer3(u32 color); -u8 GetGlassColorFromVer3(u8 color); +FacelineColor GetFacelineColorFromVer3(u32 color); +CommonColor GetHairColorFromVer3(u32 color); +CommonColor GetEyeColorFromVer3(u32 color); +CommonColor GetMouthColorFromVer3(u32 color); +CommonColor GetGlassColorFromVer3(u32 color); } // namespace Service::Mii::RawData diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp index 91dfd3271..8fce636c7 100644 --- a/src/core/hle/service/mii/types/store_data.cpp +++ b/src/core/hle/service/mii/types/store_data.cpp @@ -11,16 +11,16 @@ void StoreData::BuildDefault(u32 mii_index) { const auto& default_mii = RawData::DefaultMii[mii_index]; core_data.SetDefault(); - core_data.SetFacelineType(static_cast(default_mii.face_type)); + core_data.SetFacelineType(static_cast(default_mii.face_type)); core_data.SetFacelineColor( RawData::GetFacelineColorFromVer3(static_cast(default_mii.face_color))); - core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); - core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); + core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); + core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); - core_data.SetHairType(static_cast(default_mii.hair_type)); + core_data.SetHairType(static_cast(default_mii.hair_type)); core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast(default_mii.hair_color))); - core_data.SetHairFlip(default_mii.hair_flip); - core_data.SetEyeType(static_cast(default_mii.eye_type)); + core_data.SetHairFlip(static_cast(default_mii.hair_flip)); + core_data.SetEyeType(static_cast(default_mii.eye_type)); core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast(default_mii.eye_color))); core_data.SetEyeScale(static_cast(default_mii.eye_scale)); core_data.SetEyeAspect(static_cast(default_mii.eye_aspect)); @@ -28,7 +28,7 @@ void StoreData::BuildDefault(u32 mii_index) { core_data.SetEyeX(static_cast(default_mii.eye_x)); core_data.SetEyeY(static_cast(default_mii.eye_y)); - core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); + core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); core_data.SetEyebrowColor( RawData::GetHairColorFromVer3(static_cast(default_mii.eyebrow_color))); core_data.SetEyebrowScale(static_cast(default_mii.eyebrow_scale)); @@ -37,7 +37,7 @@ void StoreData::BuildDefault(u32 mii_index) { core_data.SetEyebrowX(static_cast(default_mii.eyebrow_x)); core_data.SetEyebrowY(static_cast(default_mii.eyebrow_y)); - core_data.SetNoseType(static_cast(default_mii.nose_type)); + core_data.SetNoseType(static_cast(default_mii.nose_type)); core_data.SetNoseScale(static_cast(default_mii.nose_scale)); core_data.SetNoseY(static_cast(default_mii.nose_y)); @@ -48,30 +48,30 @@ void StoreData::BuildDefault(u32 mii_index) { core_data.SetMouthAspect(static_cast(default_mii.mouth_aspect)); core_data.SetMouthY(static_cast(default_mii.mouth_y)); - core_data.SetMustacheType(default_mii.mustache_type); - core_data.SetBeardType(default_mii.beard_type); + core_data.SetMustacheType(static_cast(default_mii.mustache_type)); + core_data.SetBeardType(static_cast(default_mii.beard_type)); core_data.SetBeardColor( RawData::GetHairColorFromVer3(static_cast(default_mii.beard_color))); core_data.SetMustacheScale(static_cast(default_mii.mustache_scale)); core_data.SetMustacheY(static_cast(default_mii.mustache_y)); - core_data.SetGlassType(static_cast(default_mii.glasses_type)); + core_data.SetGlassType(static_cast(default_mii.glasses_type)); core_data.SetGlassColor( RawData::GetGlassColorFromVer3(static_cast(default_mii.glasses_color))); core_data.SetGlassScale(static_cast(default_mii.glasses_scale)); core_data.SetGlassY(static_cast(default_mii.glasses_y)); - core_data.SetMoleType(static_cast(default_mii.mole_type)); + core_data.SetMoleType(static_cast(default_mii.mole_type)); core_data.SetMoleScale(static_cast(default_mii.mole_scale)); core_data.SetMoleX(static_cast(default_mii.mole_x)); core_data.SetMoleY(static_cast(default_mii.mole_y)); core_data.SetHeight(static_cast(default_mii.height)); core_data.SetBuild(static_cast(default_mii.weight)); - core_data.SetGender(default_mii.gender); - core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); + core_data.SetGender(static_cast(default_mii.gender)); + core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); core_data.SetRegionMove(static_cast(default_mii.region_move)); - core_data.SetFontRegion(default_mii.font_region); + core_data.SetFontRegion(static_cast(default_mii.font_region)); core_data.SetType(static_cast(default_mii.type)); core_data.SetNickname(default_mii.nickname); @@ -85,16 +85,16 @@ void StoreData::BuildBase(Gender gender) { const auto& default_mii = RawData::BaseMii[gender == Gender::Female ? 1 : 0]; core_data.SetDefault(); - core_data.SetFacelineType(static_cast(default_mii.face_type)); + core_data.SetFacelineType(static_cast(default_mii.face_type)); core_data.SetFacelineColor( RawData::GetFacelineColorFromVer3(static_cast(default_mii.face_color))); - core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); - core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); + core_data.SetFacelineWrinkle(static_cast(default_mii.face_wrinkle)); + core_data.SetFacelineMake(static_cast(default_mii.face_makeup)); - core_data.SetHairType(static_cast(default_mii.hair_type)); + core_data.SetHairType(static_cast(default_mii.hair_type)); core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast(default_mii.hair_color))); - core_data.SetHairFlip(default_mii.hair_flip); - core_data.SetEyeType(static_cast(default_mii.eye_type)); + core_data.SetHairFlip(static_cast(default_mii.hair_flip)); + core_data.SetEyeType(static_cast(default_mii.eye_type)); core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast(default_mii.eye_color))); core_data.SetEyeScale(static_cast(default_mii.eye_scale)); core_data.SetEyeAspect(static_cast(default_mii.eye_aspect)); @@ -102,7 +102,7 @@ void StoreData::BuildBase(Gender gender) { core_data.SetEyeX(static_cast(default_mii.eye_x)); core_data.SetEyeY(static_cast(default_mii.eye_y)); - core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); + core_data.SetEyebrowType(static_cast(default_mii.eyebrow_type)); core_data.SetEyebrowColor( RawData::GetHairColorFromVer3(static_cast(default_mii.eyebrow_color))); core_data.SetEyebrowScale(static_cast(default_mii.eyebrow_scale)); @@ -111,7 +111,7 @@ void StoreData::BuildBase(Gender gender) { core_data.SetEyebrowX(static_cast(default_mii.eyebrow_x)); core_data.SetEyebrowY(static_cast(default_mii.eyebrow_y)); - core_data.SetNoseType(static_cast(default_mii.nose_type)); + core_data.SetNoseType(static_cast(default_mii.nose_type)); core_data.SetNoseScale(static_cast(default_mii.nose_scale)); core_data.SetNoseY(static_cast(default_mii.nose_y)); @@ -122,30 +122,30 @@ void StoreData::BuildBase(Gender gender) { core_data.SetMouthAspect(static_cast(default_mii.mouth_aspect)); core_data.SetMouthY(static_cast(default_mii.mouth_y)); - core_data.SetMustacheType(default_mii.mustache_type); - core_data.SetBeardType(default_mii.beard_type); + core_data.SetMustacheType(static_cast(default_mii.mustache_type)); + core_data.SetBeardType(static_cast(default_mii.beard_type)); core_data.SetBeardColor( RawData::GetHairColorFromVer3(static_cast(default_mii.beard_color))); core_data.SetMustacheScale(static_cast(default_mii.mustache_scale)); core_data.SetMustacheY(static_cast(default_mii.mustache_y)); - core_data.SetGlassType(static_cast(default_mii.glasses_type)); + core_data.SetGlassType(static_cast(default_mii.glasses_type)); core_data.SetGlassColor( RawData::GetGlassColorFromVer3(static_cast(default_mii.glasses_color))); core_data.SetGlassScale(static_cast(default_mii.glasses_scale)); core_data.SetGlassY(static_cast(default_mii.glasses_y)); - core_data.SetMoleType(static_cast(default_mii.mole_type)); + core_data.SetMoleType(static_cast(default_mii.mole_type)); core_data.SetMoleScale(static_cast(default_mii.mole_scale)); core_data.SetMoleX(static_cast(default_mii.mole_x)); core_data.SetMoleY(static_cast(default_mii.mole_y)); core_data.SetHeight(static_cast(default_mii.height)); core_data.SetBuild(static_cast(default_mii.weight)); - core_data.SetGender(default_mii.gender); - core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); + core_data.SetGender(static_cast(default_mii.gender)); + core_data.SetFavoriteColor(static_cast(default_mii.favorite_color)); core_data.SetRegionMove(static_cast(default_mii.region_move)); - core_data.SetFontRegion(default_mii.font_region); + core_data.SetFontRegion(static_cast(default_mii.font_region)); core_data.SetType(static_cast(default_mii.type)); core_data.SetNickname(default_mii.nickname); @@ -184,7 +184,7 @@ void StoreData::SetFontRegion(FontRegion value) { core_data.SetFontRegion(value); } -void StoreData::SetFavoriteColor(u8 value) { +void StoreData::SetFavoriteColor(FavoriteColor value) { core_data.SetFavoriteColor(value); } @@ -208,27 +208,27 @@ void StoreData::SetRegionMove(u8 value) { core_data.SetRegionMove(value); } -void StoreData::SetFacelineType(u8 value) { +void StoreData::SetFacelineType(FacelineType value) { core_data.SetFacelineType(value); } -void StoreData::SetFacelineColor(u8 value) { +void StoreData::SetFacelineColor(FacelineColor value) { core_data.SetFacelineColor(value); } -void StoreData::SetFacelineWrinkle(u8 value) { +void StoreData::SetFacelineWrinkle(FacelineWrinkle value) { core_data.SetFacelineWrinkle(value); } -void StoreData::SetFacelineMake(u8 value) { +void StoreData::SetFacelineMake(FacelineMake value) { core_data.SetFacelineMake(value); } -void StoreData::SetHairType(u8 value) { +void StoreData::SetHairType(HairType value) { core_data.SetHairType(value); } -void StoreData::SetHairColor(u8 value) { +void StoreData::SetHairColor(CommonColor value) { core_data.SetHairColor(value); } @@ -236,11 +236,11 @@ void StoreData::SetHairFlip(HairFlip value) { core_data.SetHairFlip(value); } -void StoreData::SetEyeType(u8 value) { +void StoreData::SetEyeType(EyeType value) { core_data.SetEyeType(value); } -void StoreData::SetEyeColor(u8 value) { +void StoreData::SetEyeColor(CommonColor value) { core_data.SetEyeColor(value); } @@ -264,11 +264,11 @@ void StoreData::SetEyeY(u8 value) { core_data.SetEyeY(value); } -void StoreData::SetEyebrowType(u8 value) { +void StoreData::SetEyebrowType(EyebrowType value) { core_data.SetEyebrowType(value); } -void StoreData::SetEyebrowColor(u8 value) { +void StoreData::SetEyebrowColor(CommonColor value) { core_data.SetEyebrowColor(value); } @@ -292,7 +292,7 @@ void StoreData::SetEyebrowY(u8 value) { core_data.SetEyebrowY(value); } -void StoreData::SetNoseType(u8 value) { +void StoreData::SetNoseType(NoseType value) { core_data.SetNoseType(value); } @@ -308,7 +308,7 @@ void StoreData::SetMouthType(u8 value) { core_data.SetMouthType(value); } -void StoreData::SetMouthColor(u8 value) { +void StoreData::SetMouthColor(CommonColor value) { core_data.SetMouthColor(value); } @@ -324,7 +324,7 @@ void StoreData::SetMouthY(u8 value) { core_data.SetMouthY(value); } -void StoreData::SetBeardColor(u8 value) { +void StoreData::SetBeardColor(CommonColor value) { core_data.SetBeardColor(value); } @@ -344,11 +344,11 @@ void StoreData::SetMustacheY(u8 value) { core_data.SetMustacheY(value); } -void StoreData::SetGlassType(u8 value) { +void StoreData::SetGlassType(GlassType value) { core_data.SetGlassType(value); } -void StoreData::SetGlassColor(u8 value) { +void StoreData::SetGlassColor(CommonColor value) { core_data.SetGlassColor(value); } @@ -360,7 +360,7 @@ void StoreData::SetGlassY(u8 value) { core_data.SetGlassY(value); } -void StoreData::SetMoleType(u8 value) { +void StoreData::SetMoleType(MoleType value) { core_data.SetMoleType(value); } @@ -388,11 +388,11 @@ FontRegion StoreData::GetFontRegion() const { return static_cast(core_data.GetFontRegion()); } -u8 StoreData::GetFavoriteColor() const { +FavoriteColor StoreData::GetFavoriteColor() const { return core_data.GetFavoriteColor(); } -u8 StoreData::GetGender() const { +Gender StoreData::GetGender() const { return core_data.GetGender(); } @@ -412,39 +412,39 @@ u8 StoreData::GetRegionMove() const { return core_data.GetRegionMove(); } -u8 StoreData::GetFacelineType() const { +FacelineType StoreData::GetFacelineType() const { return core_data.GetFacelineType(); } -u8 StoreData::GetFacelineColor() const { +FacelineColor StoreData::GetFacelineColor() const { return core_data.GetFacelineColor(); } -u8 StoreData::GetFacelineWrinkle() const { +FacelineWrinkle StoreData::GetFacelineWrinkle() const { return core_data.GetFacelineWrinkle(); } -u8 StoreData::GetFacelineMake() const { +FacelineMake StoreData::GetFacelineMake() const { return core_data.GetFacelineMake(); } -u8 StoreData::GetHairType() const { +HairType StoreData::GetHairType() const { return core_data.GetHairType(); } -u8 StoreData::GetHairColor() const { +CommonColor StoreData::GetHairColor() const { return core_data.GetHairColor(); } -u8 StoreData::GetHairFlip() const { +HairFlip StoreData::GetHairFlip() const { return core_data.GetHairFlip(); } -u8 StoreData::GetEyeType() const { +EyeType StoreData::GetEyeType() const { return core_data.GetEyeType(); } -u8 StoreData::GetEyeColor() const { +CommonColor StoreData::GetEyeColor() const { return core_data.GetEyeColor(); } @@ -468,11 +468,11 @@ u8 StoreData::GetEyeY() const { return core_data.GetEyeY(); } -u8 StoreData::GetEyebrowType() const { +EyebrowType StoreData::GetEyebrowType() const { return core_data.GetEyebrowType(); } -u8 StoreData::GetEyebrowColor() const { +CommonColor StoreData::GetEyebrowColor() const { return core_data.GetEyebrowColor(); } @@ -496,7 +496,7 @@ u8 StoreData::GetEyebrowY() const { return core_data.GetEyebrowY(); } -u8 StoreData::GetNoseType() const { +NoseType StoreData::GetNoseType() const { return core_data.GetNoseType(); } @@ -508,11 +508,11 @@ u8 StoreData::GetNoseY() const { return core_data.GetNoseY(); } -u8 StoreData::GetMouthType() const { +MouthType StoreData::GetMouthType() const { return core_data.GetMouthType(); } -u8 StoreData::GetMouthColor() const { +CommonColor StoreData::GetMouthColor() const { return core_data.GetMouthColor(); } @@ -528,15 +528,15 @@ u8 StoreData::GetMouthY() const { return core_data.GetMouthY(); } -u8 StoreData::GetBeardColor() const { +CommonColor StoreData::GetBeardColor() const { return core_data.GetBeardColor(); } -u8 StoreData::GetBeardType() const { +BeardType StoreData::GetBeardType() const { return core_data.GetBeardType(); } -u8 StoreData::GetMustacheType() const { +MustacheType StoreData::GetMustacheType() const { return core_data.GetMustacheType(); } @@ -548,11 +548,11 @@ u8 StoreData::GetMustacheY() const { return core_data.GetMustacheY(); } -u8 StoreData::GetGlassType() const { +GlassType StoreData::GetGlassType() const { return core_data.GetGlassType(); } -u8 StoreData::GetGlassColor() const { +CommonColor StoreData::GetGlassColor() const { return core_data.GetGlassColor(); } @@ -564,7 +564,7 @@ u8 StoreData::GetGlassY() const { return core_data.GetGlassY(); } -u8 StoreData::GetMoleType() const { +MoleType StoreData::GetMoleType() const { return core_data.GetMoleType(); } diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h index 1e010000b..224c32cf8 100644 --- a/src/core/hle/service/mii/types/store_data.h +++ b/src/core/hle/service/mii/types/store_data.h @@ -23,51 +23,51 @@ public: u32 IsValid() const; void SetFontRegion(FontRegion value); - void SetFavoriteColor(u8 value); + void SetFavoriteColor(FavoriteColor value); void SetGender(Gender value); void SetHeight(u8 value); void SetBuild(u8 value); void SetType(u8 value); void SetRegionMove(u8 value); - void SetFacelineType(u8 value); - void SetFacelineColor(u8 value); - void SetFacelineWrinkle(u8 value); - void SetFacelineMake(u8 value); - void SetHairType(u8 value); - void SetHairColor(u8 value); + void SetFacelineType(FacelineType value); + void SetFacelineColor(FacelineColor value); + void SetFacelineWrinkle(FacelineWrinkle value); + void SetFacelineMake(FacelineMake value); + void SetHairType(HairType value); + void SetHairColor(CommonColor value); void SetHairFlip(HairFlip value); - void SetEyeType(u8 value); - void SetEyeColor(u8 value); + void SetEyeType(EyeType value); + void SetEyeColor(CommonColor value); void SetEyeScale(u8 value); void SetEyeAspect(u8 value); void SetEyeRotate(u8 value); void SetEyeX(u8 value); void SetEyeY(u8 value); - void SetEyebrowType(u8 value); - void SetEyebrowColor(u8 value); + void SetEyebrowType(EyebrowType value); + void SetEyebrowColor(CommonColor value); void SetEyebrowScale(u8 value); void SetEyebrowAspect(u8 value); void SetEyebrowRotate(u8 value); void SetEyebrowX(u8 value); void SetEyebrowY(u8 value); - void SetNoseType(u8 value); + void SetNoseType(NoseType value); void SetNoseScale(u8 value); void SetNoseY(u8 value); void SetMouthType(u8 value); - void SetMouthColor(u8 value); + void SetMouthColor(CommonColor value); void SetMouthScale(u8 value); void SetMouthAspect(u8 value); void SetMouthY(u8 value); - void SetBeardColor(u8 value); + void SetBeardColor(CommonColor value); void SetBeardType(BeardType value); void SetMustacheType(MustacheType value); void SetMustacheScale(u8 value); void SetMustacheY(u8 value); - void SetGlassType(u8 value); - void SetGlassColor(u8 value); + void SetGlassType(GlassType value); + void SetGlassColor(CommonColor value); void SetGlassScale(u8 value); void SetGlassY(u8 value); - void SetMoleType(u8 value); + void SetMoleType(MoleType value); void SetMoleScale(u8 value); void SetMoleX(u8 value); void SetMoleY(u8 value); @@ -76,51 +76,51 @@ public: Common::UUID GetCreateId() const; FontRegion GetFontRegion() const; - u8 GetFavoriteColor() const; - u8 GetGender() const; + FavoriteColor GetFavoriteColor() const; + Gender GetGender() const; u8 GetHeight() const; u8 GetBuild() const; u8 GetType() const; u8 GetRegionMove() const; - u8 GetFacelineType() const; - u8 GetFacelineColor() const; - u8 GetFacelineWrinkle() const; - u8 GetFacelineMake() const; - u8 GetHairType() const; - u8 GetHairColor() const; - u8 GetHairFlip() const; - u8 GetEyeType() const; - u8 GetEyeColor() const; + FacelineType GetFacelineType() const; + FacelineColor GetFacelineColor() const; + FacelineWrinkle GetFacelineWrinkle() const; + FacelineMake GetFacelineMake() const; + HairType GetHairType() const; + CommonColor GetHairColor() const; + HairFlip GetHairFlip() const; + EyeType GetEyeType() const; + CommonColor GetEyeColor() const; u8 GetEyeScale() const; u8 GetEyeAspect() const; u8 GetEyeRotate() const; u8 GetEyeX() const; u8 GetEyeY() const; - u8 GetEyebrowType() const; - u8 GetEyebrowColor() const; + EyebrowType GetEyebrowType() const; + CommonColor GetEyebrowColor() const; u8 GetEyebrowScale() const; u8 GetEyebrowAspect() const; u8 GetEyebrowRotate() const; u8 GetEyebrowX() const; u8 GetEyebrowY() const; - u8 GetNoseType() const; + NoseType GetNoseType() const; u8 GetNoseScale() const; u8 GetNoseY() const; - u8 GetMouthType() const; - u8 GetMouthColor() const; + MouthType GetMouthType() const; + CommonColor GetMouthColor() const; u8 GetMouthScale() const; u8 GetMouthAspect() const; u8 GetMouthY() const; - u8 GetBeardColor() const; - u8 GetBeardType() const; - u8 GetMustacheType() const; + CommonColor GetBeardColor() const; + BeardType GetBeardType() const; + MustacheType GetMustacheType() const; u8 GetMustacheScale() const; u8 GetMustacheY() const; - u8 GetGlassType() const; - u8 GetGlassColor() const; + GlassType GetGlassType() const; + CommonColor GetGlassColor() const; u8 GetGlassScale() const; u8 GetGlassY() const; - u8 GetMoleType() const; + MoleType GetMoleType() const; u8 GetMoleScale() const; u8 GetMoleX() const; u8 GetMoleY() const; 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 c7624520c..1c28e0b1b 100644 --- a/src/core/hle/service/mii/types/ver3_store_data.cpp +++ b/src/core/hle/service/mii/types/ver3_store_data.cpp @@ -9,14 +9,14 @@ namespace Service::Mii { void NfpStoreDataExtension::SetFromStoreData(const StoreData& store_data) { - faceline_color = static_cast(store_data.GetFacelineColor() & 0xf); - hair_color = static_cast(store_data.GetHairColor() & 0x7f); - eye_color = static_cast(store_data.GetEyeColor() & 0x7f); - eyebrow_color = static_cast(store_data.GetEyebrowColor() & 0x7f); - mouth_color = static_cast(store_data.GetMouthColor() & 0x7f); - beard_color = static_cast(store_data.GetBeardColor() & 0x7f); - glass_color = static_cast(store_data.GetGlassColor() & 0x7f); - glass_type = static_cast(store_data.GetGlassType() & 0x1f); + faceline_color = static_cast(store_data.GetFacelineColor()) & 0xf; + hair_color = static_cast(store_data.GetHairColor()) & 0x7f; + eye_color = static_cast(store_data.GetEyeColor()) & 0x7f; + eyebrow_color = static_cast(store_data.GetEyebrowColor()) & 0x7f; + mouth_color = static_cast(store_data.GetMouthColor()) & 0x7f; + beard_color = static_cast(store_data.GetBeardColor()) & 0x7f; + glass_color = static_cast(store_data.GetGlassColor()) & 0x7f; + glass_type = static_cast(store_data.GetGlassType()) & 0x1f; } void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { @@ -28,8 +28,9 @@ void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { // TODO: We are ignoring a bunch of data from the mii_v3 - out_store_data.SetGender(static_cast(static_cast(mii_information.gender))); - out_store_data.SetFavoriteColor(static_cast(mii_information.favorite_color)); + out_store_data.SetGender(static_cast(mii_information.gender.Value())); + out_store_data.SetFavoriteColor( + static_cast(mii_information.favorite_color.Value())); out_store_data.SetHeight(height); out_store_data.SetBuild(build); @@ -37,56 +38,60 @@ void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { out_store_data.SetFontRegion( static_cast(static_cast(region_information.font_region))); - out_store_data.SetFacelineType(appearance_bits1.faceline_type); - out_store_data.SetFacelineColor(appearance_bits1.faceline_color); - out_store_data.SetFacelineWrinkle(appearance_bits2.faceline_wrinkle); - out_store_data.SetFacelineMake(appearance_bits2.faceline_make); + out_store_data.SetFacelineType( + static_cast(appearance_bits1.faceline_type.Value())); + out_store_data.SetFacelineColor( + static_cast(appearance_bits1.faceline_color.Value())); + out_store_data.SetFacelineWrinkle( + static_cast(appearance_bits2.faceline_wrinkle.Value())); + out_store_data.SetFacelineMake( + static_cast(appearance_bits2.faceline_make.Value())); - out_store_data.SetHairType(hair_type); - out_store_data.SetHairColor(appearance_bits3.hair_color); - out_store_data.SetHairFlip(static_cast(static_cast(appearance_bits3.hair_flip))); + out_store_data.SetHairType(static_cast(hair_type)); + out_store_data.SetHairColor(static_cast(appearance_bits3.hair_color.Value())); + out_store_data.SetHairFlip(static_cast(appearance_bits3.hair_flip.Value())); - out_store_data.SetEyeType(static_cast(appearance_bits4.eye_type)); - out_store_data.SetEyeColor(static_cast(appearance_bits4.eye_color)); + out_store_data.SetEyeType(static_cast(appearance_bits4.eye_type.Value())); + out_store_data.SetEyeColor(static_cast(appearance_bits4.eye_color.Value())); out_store_data.SetEyeScale(static_cast(appearance_bits4.eye_scale)); out_store_data.SetEyeAspect(static_cast(appearance_bits4.eye_aspect)); out_store_data.SetEyeRotate(static_cast(appearance_bits4.eye_rotate)); out_store_data.SetEyeX(static_cast(appearance_bits4.eye_x)); out_store_data.SetEyeY(static_cast(appearance_bits4.eye_y)); - out_store_data.SetEyebrowType(static_cast(appearance_bits5.eyebrow_type)); - out_store_data.SetEyebrowColor(static_cast(appearance_bits5.eyebrow_color)); + out_store_data.SetEyebrowType(static_cast(appearance_bits5.eyebrow_type.Value())); + out_store_data.SetEyebrowColor( + static_cast(appearance_bits5.eyebrow_color.Value())); out_store_data.SetEyebrowScale(static_cast(appearance_bits5.eyebrow_scale)); out_store_data.SetEyebrowAspect(static_cast(appearance_bits5.eyebrow_aspect)); out_store_data.SetEyebrowRotate(static_cast(appearance_bits5.eyebrow_rotate)); out_store_data.SetEyebrowX(static_cast(appearance_bits5.eyebrow_x)); out_store_data.SetEyebrowY(static_cast(appearance_bits5.eyebrow_y)); - out_store_data.SetNoseType(static_cast(appearance_bits6.nose_type)); + out_store_data.SetNoseType(static_cast(appearance_bits6.nose_type.Value())); out_store_data.SetNoseScale(static_cast(appearance_bits6.nose_scale)); out_store_data.SetNoseY(static_cast(appearance_bits6.nose_y)); out_store_data.SetMouthType(static_cast(appearance_bits7.mouth_type)); - out_store_data.SetMouthColor(static_cast(appearance_bits7.mouth_color)); + out_store_data.SetMouthColor(static_cast(appearance_bits7.mouth_color.Value())); out_store_data.SetMouthScale(static_cast(appearance_bits7.mouth_scale)); out_store_data.SetMouthAspect(static_cast(appearance_bits7.mouth_aspect)); out_store_data.SetMouthY(static_cast(appearance_bits8.mouth_y)); out_store_data.SetMustacheType( - static_cast(static_cast(appearance_bits8.mustache_type))); + static_cast(appearance_bits8.mustache_type.Value())); out_store_data.SetMustacheScale(static_cast(appearance_bits9.mustache_scale)); out_store_data.SetMustacheY(static_cast(appearance_bits9.mustache_y)); - out_store_data.SetBeardType( - static_cast(static_cast(appearance_bits9.beard_type))); - out_store_data.SetBeardColor(static_cast(appearance_bits9.beard_color)); + out_store_data.SetBeardType(static_cast(appearance_bits9.beard_type.Value())); + out_store_data.SetBeardColor(static_cast(appearance_bits9.beard_color.Value())); - out_store_data.SetGlassType(static_cast(appearance_bits10.glass_type)); - out_store_data.SetGlassColor(static_cast(appearance_bits10.glass_color)); + out_store_data.SetGlassType(static_cast(appearance_bits10.glass_type.Value())); + out_store_data.SetGlassColor(static_cast(appearance_bits10.glass_color.Value())); out_store_data.SetGlassScale(static_cast(appearance_bits10.glass_scale)); out_store_data.SetGlassY(static_cast(appearance_bits10.glass_y)); - out_store_data.SetMoleType(static_cast(appearance_bits11.mole_type)); + out_store_data.SetMoleType(static_cast(appearance_bits11.mole_type.Value())); out_store_data.SetMoleScale(static_cast(appearance_bits11.mole_scale)); out_store_data.SetMoleX(static_cast(appearance_bits11.mole_x)); out_store_data.SetMoleY(static_cast(appearance_bits11.mole_y)); @@ -94,71 +99,75 @@ void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { version = 1; - mii_information.gender.Assign(store_data.GetGender()); - mii_information.favorite_color.Assign(store_data.GetFavoriteColor()); + mii_information.gender.Assign(static_cast(store_data.GetGender())); + mii_information.favorite_color.Assign(static_cast(store_data.GetFavoriteColor())); height = store_data.GetHeight(); build = store_data.GetBuild(); mii_name = store_data.GetNickname(); region_information.font_region.Assign(static_cast(store_data.GetFontRegion())); - appearance_bits1.faceline_type.Assign(store_data.GetFacelineType()); - appearance_bits2.faceline_wrinkle.Assign(store_data.GetFacelineWrinkle()); - appearance_bits2.faceline_make.Assign(store_data.GetFacelineMake()); + appearance_bits1.faceline_type.Assign(static_cast(store_data.GetFacelineType())); + appearance_bits2.faceline_wrinkle.Assign(static_cast(store_data.GetFacelineWrinkle())); + appearance_bits2.faceline_make.Assign(static_cast(store_data.GetFacelineMake())); - hair_type = store_data.GetHairType(); - appearance_bits3.hair_flip.Assign(store_data.GetHairFlip()); + hair_type = static_cast(store_data.GetHairType()); + appearance_bits3.hair_flip.Assign(static_cast(store_data.GetHairFlip())); - appearance_bits4.eye_type.Assign(store_data.GetEyeType()); + appearance_bits4.eye_type.Assign(static_cast(store_data.GetEyeType())); appearance_bits4.eye_scale.Assign(store_data.GetEyeScale()); appearance_bits4.eye_aspect.Assign(store_data.GetEyebrowAspect()); appearance_bits4.eye_rotate.Assign(store_data.GetEyeRotate()); appearance_bits4.eye_x.Assign(store_data.GetEyeX()); appearance_bits4.eye_y.Assign(store_data.GetEyeY()); - appearance_bits5.eyebrow_type.Assign(store_data.GetEyebrowType()); + appearance_bits5.eyebrow_type.Assign(static_cast(store_data.GetEyebrowType())); appearance_bits5.eyebrow_scale.Assign(store_data.GetEyebrowScale()); appearance_bits5.eyebrow_aspect.Assign(store_data.GetEyebrowAspect()); appearance_bits5.eyebrow_rotate.Assign(store_data.GetEyebrowRotate()); appearance_bits5.eyebrow_x.Assign(store_data.GetEyebrowX()); appearance_bits5.eyebrow_y.Assign(store_data.GetEyebrowY()); - appearance_bits6.nose_type.Assign(store_data.GetNoseType()); + appearance_bits6.nose_type.Assign(static_cast(store_data.GetNoseType())); appearance_bits6.nose_scale.Assign(store_data.GetNoseScale()); appearance_bits6.nose_y.Assign(store_data.GetNoseY()); - appearance_bits7.mouth_type.Assign(store_data.GetMouthType()); + appearance_bits7.mouth_type.Assign(static_cast(store_data.GetMouthType())); appearance_bits7.mouth_scale.Assign(store_data.GetMouthScale()); appearance_bits7.mouth_aspect.Assign(store_data.GetMouthAspect()); appearance_bits8.mouth_y.Assign(store_data.GetMouthY()); - appearance_bits8.mustache_type.Assign(store_data.GetMustacheType()); + appearance_bits8.mustache_type.Assign(static_cast(store_data.GetMustacheType())); appearance_bits9.mustache_scale.Assign(store_data.GetMustacheScale()); appearance_bits9.mustache_y.Assign(store_data.GetMustacheY()); - appearance_bits9.beard_type.Assign(store_data.GetBeardType()); + appearance_bits9.beard_type.Assign(static_cast(store_data.GetBeardType())); appearance_bits10.glass_scale.Assign(store_data.GetGlassScale()); appearance_bits10.glass_y.Assign(store_data.GetGlassY()); - appearance_bits11.mole_type.Assign(store_data.GetMoleType()); + appearance_bits11.mole_type.Assign(static_cast(store_data.GetMoleType())); appearance_bits11.mole_scale.Assign(store_data.GetMoleScale()); appearance_bits11.mole_x.Assign(store_data.GetMoleX()); appearance_bits11.mole_y.Assign(store_data.GetMoleY()); // These types are converted to V3 from a table appearance_bits1.faceline_color.Assign( - RawData::FromVer3GetFacelineColor(store_data.GetFacelineColor())); - appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(store_data.GetHairColor())); - appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(store_data.GetEyeColor())); + RawData::FromVer3GetFacelineColor(static_cast(store_data.GetFacelineColor()))); + appearance_bits3.hair_color.Assign( + RawData::FromVer3GetHairColor(static_cast(store_data.GetHairColor()))); + appearance_bits4.eye_color.Assign( + RawData::FromVer3GetEyeColor(static_cast(store_data.GetEyeColor()))); appearance_bits5.eyebrow_color.Assign( - RawData::FromVer3GetHairColor(store_data.GetEyebrowColor())); + RawData::FromVer3GetHairColor(static_cast(store_data.GetEyebrowColor()))); appearance_bits7.mouth_color.Assign( - RawData::FromVer3GetMouthlineColor(store_data.GetMouthColor())); - appearance_bits9.beard_color.Assign(RawData::FromVer3GetHairColor(store_data.GetBeardColor())); + RawData::FromVer3GetMouthlineColor(static_cast(store_data.GetMouthColor()))); + appearance_bits9.beard_color.Assign( + RawData::FromVer3GetHairColor(static_cast(store_data.GetBeardColor()))); appearance_bits10.glass_color.Assign( - RawData::FromVer3GetGlassColor(store_data.GetGlassColor())); - appearance_bits10.glass_type.Assign(RawData::FromVer3GetGlassType(store_data.GetGlassType())); + RawData::FromVer3GetGlassColor(static_cast(store_data.GetGlassColor()))); + appearance_bits10.glass_type.Assign( + RawData::FromVer3GetGlassType(static_cast(store_data.GetGlassType()))); crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); } @@ -166,64 +175,65 @@ void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { u32 Ver3StoreData::IsValid() const { bool is_valid = version == 0 || version == 3; - is_valid = is_valid && (mii_name.data[0] != 0); + is_valid = is_valid && (mii_name.data[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 && (mii_information.favorite_color <= static_cast(FavoriteColor::Max)); + is_valid = is_valid && (height <= MaxHeight); + is_valid = is_valid && (build <= MaxBuild); - is_valid = is_valid && (appearance_bits1.faceline_type < 12); - is_valid = is_valid && (appearance_bits1.faceline_color < 7); - is_valid = is_valid && (appearance_bits2.faceline_wrinkle < 12); - is_valid = is_valid && (appearance_bits2.faceline_make < 12); + is_valid = is_valid && (appearance_bits1.faceline_type <= static_cast(FacelineType::Max)); + is_valid = is_valid && (appearance_bits1.faceline_color <= MaxVer3CommonColor - 2); + is_valid = + is_valid && (appearance_bits2.faceline_wrinkle <= static_cast(FacelineWrinkle::Max)); + is_valid = is_valid && (appearance_bits2.faceline_make <= static_cast(FacelineMake::Max)); - is_valid = is_valid && (hair_type < 132); - is_valid = is_valid && (appearance_bits3.hair_color < 8); + is_valid = is_valid && (hair_type <= static_cast(HairType::Max)); + is_valid = is_valid && (appearance_bits3.hair_color <= MaxVer3CommonColor); - 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_aspect < 7); - is_valid = is_valid && (appearance_bits4.eye_rotate < 8); - is_valid = is_valid && (appearance_bits4.eye_x < 13); - is_valid = is_valid && (appearance_bits4.eye_y < 19); + is_valid = is_valid && (appearance_bits4.eye_type <= static_cast(EyeType::Max)); + is_valid = is_valid && (appearance_bits4.eye_color <= MaxVer3CommonColor - 2); + is_valid = is_valid && (appearance_bits4.eye_scale <= MaxEyeScale); + is_valid = is_valid && (appearance_bits4.eye_aspect <= MaxEyeAspect); + is_valid = is_valid && (appearance_bits4.eye_rotate <= MaxEyeRotate); + is_valid = is_valid && (appearance_bits4.eye_x <= MaxEyeX); + is_valid = is_valid && (appearance_bits4.eye_y <= MaxEyeY); - is_valid = is_valid && (appearance_bits5.eyebrow_type < 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_aspect < 7); - is_valid = is_valid && (appearance_bits5.eyebrow_rotate < 12); - is_valid = is_valid && (appearance_bits5.eyebrow_x < 12); - is_valid = is_valid && (appearance_bits5.eyebrow_y < 19); + is_valid = is_valid && (appearance_bits5.eyebrow_type <= static_cast(EyebrowType::Max)); + is_valid = is_valid && (appearance_bits5.eyebrow_color <= MaxVer3CommonColor); + is_valid = is_valid && (appearance_bits5.eyebrow_scale <= MaxEyebrowScale); + is_valid = is_valid && (appearance_bits5.eyebrow_aspect <= MaxEyebrowAspect); + is_valid = is_valid && (appearance_bits5.eyebrow_rotate <= MaxEyebrowRotate); + is_valid = is_valid && (appearance_bits5.eyebrow_x <= MaxEyebrowX); + is_valid = is_valid && (appearance_bits5.eyebrow_y <= MaxEyebrowY); - 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 < 19); + is_valid = is_valid && (appearance_bits6.nose_type <= static_cast(NoseType::Max)); + is_valid = is_valid && (appearance_bits6.nose_scale <= MaxNoseScale); + is_valid = is_valid && (appearance_bits6.nose_y <= MaxNoseY); - 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_aspect < 7); - is_valid = is_valid && (appearance_bits8.mouth_y < 19); + is_valid = is_valid && (appearance_bits7.mouth_type <= static_cast(MouthType::Max)); + is_valid = is_valid && (appearance_bits7.mouth_color <= MaxVer3CommonColor - 3); + is_valid = is_valid && (appearance_bits7.mouth_scale <= MaxMouthScale); + is_valid = is_valid && (appearance_bits7.mouth_aspect <= MaxMoutAspect); + is_valid = is_valid && (appearance_bits8.mouth_y <= MaxMouthY); - 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 < 17); + is_valid = is_valid && (appearance_bits8.mustache_type <= static_cast(MustacheType::Max)); + is_valid = is_valid && (appearance_bits9.mustache_scale < MaxMustacheScale); + is_valid = is_valid && (appearance_bits9.mustache_y <= MasMustacheY); - is_valid = is_valid && (appearance_bits9.beard_type < 6); - is_valid = is_valid && (appearance_bits9.beard_color < 8); + is_valid = is_valid && (appearance_bits9.beard_type <= static_cast(BeardType::Max)); + is_valid = is_valid && (appearance_bits9.beard_color <= MaxVer3CommonColor); - is_valid = is_valid && (appearance_bits10.glass_type < 9); - is_valid = is_valid && (appearance_bits10.glass_color < 6); - is_valid = is_valid && (appearance_bits10.glass_scale < 8); - is_valid = is_valid && (appearance_bits10.glass_y < 21); + is_valid = is_valid && (appearance_bits10.glass_type <= MaxVer3GlassType); + is_valid = is_valid && (appearance_bits10.glass_color <= MaxVer3CommonColor - 2); + is_valid = is_valid && (appearance_bits10.glass_scale <= MaxGlassScale); + is_valid = is_valid && (appearance_bits10.glass_y <= MaxGlassScale); - is_valid = is_valid && (appearance_bits11.mole_type < 2); - is_valid = is_valid && (appearance_bits11.mole_scale < 9); - is_valid = is_valid && (appearance_bits11.mole_x < 17); - is_valid = is_valid && (appearance_bits11.mole_y < 31); + is_valid = is_valid && (appearance_bits11.mole_type <= static_cast(MoleType::Max)); + is_valid = is_valid && (appearance_bits11.mole_scale <= MaxMoleScale); + is_valid = is_valid && (appearance_bits11.mole_x <= MaxMoleX); + is_valid = is_valid && (appearance_bits11.mole_y <= MaxMoleY); return is_valid; }