diff options
| author | 2023-09-11 00:23:46 -0600 | |
|---|---|---|
| committer | 2023-09-11 00:23:46 -0600 | |
| commit | 571399930cc3578acff064a7087fe85e7b2dd9b7 (patch) | |
| tree | aa02d3b9932d758d1febb3e7bbd6cf50a9ee6f31 | |
| parent | service: mii: move char info operations (diff) | |
| download | yuzu-571399930cc3578acff064a7087fe85e7b2dd9b7.tar.gz yuzu-571399930cc3578acff064a7087fe85e7b2dd9b7.tar.xz yuzu-571399930cc3578acff064a7087fe85e7b2dd9b7.zip | |
service: mii: Fix ver3 inconsistencies
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/mii/mii_manager.cpp | 17 | ||||
| -rw-r--r-- | src/core/hle/service/mii/mii_manager.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/mii/mii_types.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/char_info.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/store_data.cpp | 202 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/store_data.h | 54 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/ver3_store_data.cpp | 300 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/ver3_store_data.h | 80 | ||||
| -rw-r--r-- | src/core/hle/service/nfc/common/device.cpp | 16 |
9 files changed, 473 insertions, 217 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) { | |||
| 98 | 98 | ||
| 99 | CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { | 99 | CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { |
| 100 | CharInfo char_info{}; | 100 | CharInfo char_info{}; |
| 101 | mii_v3.BuildToStoreData(char_info); | 101 | StoreData store_data{}; |
| 102 | mii_v3.BuildToStoreData(store_data); | ||
| 103 | char_info.SetFromStoreData(store_data); | ||
| 102 | return char_info; | 104 | return char_info; |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { | ||
| 106 | return { | ||
| 107 | .faceline_color = static_cast<u8>(mii.GetFacelineColor() & 0xf), | ||
| 108 | .hair_color = static_cast<u8>(mii.GetHairColor() & 0x7f), | ||
| 109 | .eye_color = static_cast<u8>(mii.GetEyeColor() & 0x7f), | ||
| 110 | .eyebrow_color = static_cast<u8>(mii.GetEyebrowColor() & 0x7f), | ||
| 111 | .mouth_color = static_cast<u8>(mii.GetMouthColor() & 0x7f), | ||
| 112 | .beard_color = static_cast<u8>(mii.GetBeardColor() & 0x7f), | ||
| 113 | .glass_color = static_cast<u8>(mii.GetGlassColor() & 0x7f), | ||
| 114 | .glass_type = static_cast<u8>(mii.GetGlassType() & 0x1f), | ||
| 115 | }; | ||
| 116 | } | ||
| 117 | |||
| 118 | std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) { | 107 | std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) { |
| 119 | std::vector<CharInfoElement> result; | 108 | std::vector<CharInfoElement> result; |
| 120 | 109 | ||
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: | |||
| 30 | std::vector<CharInfoElement> GetDefault(SourceFlag source_flag); | 30 | std::vector<CharInfoElement> GetDefault(SourceFlag source_flag); |
| 31 | Result GetIndex(const CharInfo& info, u32& index); | 31 | Result GetIndex(const CharInfo& info, u32& index); |
| 32 | 32 | ||
| 33 | // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData | ||
| 34 | NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const; | ||
| 35 | |||
| 36 | struct MiiDatabase { | 33 | struct MiiDatabase { |
| 37 | u32 magic{}; // 'NFDB' | 34 | u32 magic{}; // 'NFDB' |
| 38 | std::array<StoreData, 0x64> miis{}; | 35 | std::array<StoreData, 0x64> 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 { | |||
| 108 | } | 108 | } |
| 109 | return index == MaxNameSize; | 109 | return index == MaxNameSize; |
| 110 | } | 110 | } |
| 111 | |||
| 112 | bool operator==(const Nickname& name) { | ||
| 113 | return data == name.data; | ||
| 114 | }; | ||
| 115 | }; | 111 | }; |
| 116 | static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size"); | 112 | static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size"); |
| 117 | 113 | ||
| 118 | struct NfpStoreDataExtension { | ||
| 119 | u8 faceline_color; | ||
| 120 | u8 hair_color; | ||
| 121 | u8 eye_color; | ||
| 122 | u8 eyebrow_color; | ||
| 123 | u8 mouth_color; | ||
| 124 | u8 beard_color; | ||
| 125 | u8 glass_color; | ||
| 126 | u8 glass_type; | ||
| 127 | }; | ||
| 128 | static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); | ||
| 129 | |||
| 130 | struct DefaultMii { | 114 | struct DefaultMii { |
| 131 | u32 face_type{}; | 115 | u32 face_type{}; |
| 132 | u32 face_color{}; | 116 | 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 { | |||
| 425 | 425 | ||
| 426 | bool CharInfo::operator==(const CharInfo& info) { | 426 | bool CharInfo::operator==(const CharInfo& info) { |
| 427 | bool is_identical = info.Verify() == 0; | 427 | bool is_identical = info.Verify() == 0; |
| 428 | is_identical &= name == info.GetNickname(); | 428 | is_identical &= name.data == info.GetNickname().data; |
| 429 | is_identical &= create_id == info.GetCreateId(); | 429 | is_identical &= create_id == info.GetCreateId(); |
| 430 | is_identical &= font_region == info.GetFontRegion(); | 430 | is_identical &= font_region == info.GetFontRegion(); |
| 431 | is_identical &= favorite_color == info.GetFavoriteColor(); | 431 | 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 { | |||
| 180 | return 0; | 180 | return 0; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | void StoreData::SetFontRegion(FontRegion value) { | ||
| 184 | core_data.SetFontRegion(value); | ||
| 185 | } | ||
| 186 | |||
| 187 | void StoreData::SetFavoriteColor(u8 value) { | ||
| 188 | core_data.SetFavoriteColor(value); | ||
| 189 | } | ||
| 190 | |||
| 191 | void StoreData::SetGender(Gender value) { | ||
| 192 | core_data.SetGender(value); | ||
| 193 | } | ||
| 194 | |||
| 195 | void StoreData::SetHeight(u8 value) { | ||
| 196 | core_data.SetHeight(value); | ||
| 197 | } | ||
| 198 | |||
| 199 | void StoreData::SetBuild(u8 value) { | ||
| 200 | core_data.SetBuild(value); | ||
| 201 | } | ||
| 202 | |||
| 203 | void StoreData::SetType(u8 value) { | ||
| 204 | core_data.SetType(value); | ||
| 205 | } | ||
| 206 | |||
| 207 | void StoreData::SetRegionMove(u8 value) { | ||
| 208 | core_data.SetRegionMove(value); | ||
| 209 | } | ||
| 210 | |||
| 211 | void StoreData::SetFacelineType(u8 value) { | ||
| 212 | core_data.SetFacelineType(value); | ||
| 213 | } | ||
| 214 | |||
| 215 | void StoreData::SetFacelineColor(u8 value) { | ||
| 216 | core_data.SetFacelineColor(value); | ||
| 217 | } | ||
| 218 | |||
| 219 | void StoreData::SetFacelineWrinkle(u8 value) { | ||
| 220 | core_data.SetFacelineWrinkle(value); | ||
| 221 | } | ||
| 222 | |||
| 223 | void StoreData::SetFacelineMake(u8 value) { | ||
| 224 | core_data.SetFacelineMake(value); | ||
| 225 | } | ||
| 226 | |||
| 227 | void StoreData::SetHairType(u8 value) { | ||
| 228 | core_data.SetHairType(value); | ||
| 229 | } | ||
| 230 | |||
| 231 | void StoreData::SetHairColor(u8 value) { | ||
| 232 | core_data.SetHairColor(value); | ||
| 233 | } | ||
| 234 | |||
| 235 | void StoreData::SetHairFlip(HairFlip value) { | ||
| 236 | core_data.SetHairFlip(value); | ||
| 237 | } | ||
| 238 | |||
| 239 | void StoreData::SetEyeType(u8 value) { | ||
| 240 | core_data.SetEyeType(value); | ||
| 241 | } | ||
| 242 | |||
| 243 | void StoreData::SetEyeColor(u8 value) { | ||
| 244 | core_data.SetEyeColor(value); | ||
| 245 | } | ||
| 246 | |||
| 247 | void StoreData::SetEyeScale(u8 value) { | ||
| 248 | core_data.SetEyeScale(value); | ||
| 249 | } | ||
| 250 | |||
| 251 | void StoreData::SetEyeAspect(u8 value) { | ||
| 252 | core_data.SetEyeAspect(value); | ||
| 253 | } | ||
| 254 | |||
| 255 | void StoreData::SetEyeRotate(u8 value) { | ||
| 256 | core_data.SetEyeRotate(value); | ||
| 257 | } | ||
| 258 | |||
| 259 | void StoreData::SetEyeX(u8 value) { | ||
| 260 | core_data.SetEyeX(value); | ||
| 261 | } | ||
| 262 | |||
| 263 | void StoreData::SetEyeY(u8 value) { | ||
| 264 | core_data.SetEyeY(value); | ||
| 265 | } | ||
| 266 | |||
| 267 | void StoreData::SetEyebrowType(u8 value) { | ||
| 268 | core_data.SetEyebrowType(value); | ||
| 269 | } | ||
| 270 | |||
| 271 | void StoreData::SetEyebrowColor(u8 value) { | ||
| 272 | core_data.SetEyebrowColor(value); | ||
| 273 | } | ||
| 274 | |||
| 275 | void StoreData::SetEyebrowScale(u8 value) { | ||
| 276 | core_data.SetEyebrowScale(value); | ||
| 277 | } | ||
| 278 | |||
| 279 | void StoreData::SetEyebrowAspect(u8 value) { | ||
| 280 | core_data.SetEyebrowAspect(value); | ||
| 281 | } | ||
| 282 | |||
| 283 | void StoreData::SetEyebrowRotate(u8 value) { | ||
| 284 | core_data.SetEyebrowRotate(value); | ||
| 285 | } | ||
| 286 | |||
| 287 | void StoreData::SetEyebrowX(u8 value) { | ||
| 288 | core_data.SetEyebrowX(value); | ||
| 289 | } | ||
| 290 | |||
| 291 | void StoreData::SetEyebrowY(u8 value) { | ||
| 292 | core_data.SetEyebrowY(value); | ||
| 293 | } | ||
| 294 | |||
| 295 | void StoreData::SetNoseType(u8 value) { | ||
| 296 | core_data.SetNoseType(value); | ||
| 297 | } | ||
| 298 | |||
| 299 | void StoreData::SetNoseScale(u8 value) { | ||
| 300 | core_data.SetNoseScale(value); | ||
| 301 | } | ||
| 302 | |||
| 303 | void StoreData::SetNoseY(u8 value) { | ||
| 304 | core_data.SetNoseY(value); | ||
| 305 | } | ||
| 306 | |||
| 307 | void StoreData::SetMouthType(u8 value) { | ||
| 308 | core_data.SetMouthType(value); | ||
| 309 | } | ||
| 310 | |||
| 311 | void StoreData::SetMouthColor(u8 value) { | ||
| 312 | core_data.SetMouthColor(value); | ||
| 313 | } | ||
| 314 | |||
| 315 | void StoreData::SetMouthScale(u8 value) { | ||
| 316 | core_data.SetMouthScale(value); | ||
| 317 | } | ||
| 318 | |||
| 319 | void StoreData::SetMouthAspect(u8 value) { | ||
| 320 | core_data.SetMouthAspect(value); | ||
| 321 | } | ||
| 322 | |||
| 323 | void StoreData::SetMouthY(u8 value) { | ||
| 324 | core_data.SetMouthY(value); | ||
| 325 | } | ||
| 326 | |||
| 327 | void StoreData::SetBeardColor(u8 value) { | ||
| 328 | core_data.SetBeardColor(value); | ||
| 329 | } | ||
| 330 | |||
| 331 | void StoreData::SetBeardType(BeardType value) { | ||
| 332 | core_data.SetBeardType(value); | ||
| 333 | } | ||
| 334 | |||
| 335 | void StoreData::SetMustacheType(MustacheType value) { | ||
| 336 | core_data.SetMustacheType(value); | ||
| 337 | } | ||
| 338 | |||
| 339 | void StoreData::SetMustacheScale(u8 value) { | ||
| 340 | core_data.SetMustacheScale(value); | ||
| 341 | } | ||
| 342 | |||
| 343 | void StoreData::SetMustacheY(u8 value) { | ||
| 344 | core_data.SetMustacheY(value); | ||
| 345 | } | ||
| 346 | |||
| 347 | void StoreData::SetGlassType(u8 value) { | ||
| 348 | core_data.SetGlassType(value); | ||
| 349 | } | ||
| 350 | |||
| 351 | void StoreData::SetGlassColor(u8 value) { | ||
| 352 | core_data.SetGlassColor(value); | ||
| 353 | } | ||
| 354 | |||
| 355 | void StoreData::SetGlassScale(u8 value) { | ||
| 356 | core_data.SetGlassScale(value); | ||
| 357 | } | ||
| 358 | |||
| 359 | void StoreData::SetGlassY(u8 value) { | ||
| 360 | core_data.SetGlassY(value); | ||
| 361 | } | ||
| 362 | |||
| 363 | void StoreData::SetMoleType(u8 value) { | ||
| 364 | core_data.SetMoleType(value); | ||
| 365 | } | ||
| 366 | |||
| 367 | void StoreData::SetMoleScale(u8 value) { | ||
| 368 | core_data.SetMoleScale(value); | ||
| 369 | } | ||
| 370 | |||
| 371 | void StoreData::SetMoleX(u8 value) { | ||
| 372 | core_data.SetMoleX(value); | ||
| 373 | } | ||
| 374 | |||
| 375 | void StoreData::SetMoleY(u8 value) { | ||
| 376 | core_data.SetMoleY(value); | ||
| 377 | } | ||
| 378 | |||
| 379 | void StoreData::SetNickname(Nickname value) { | ||
| 380 | core_data.SetNickname(value); | ||
| 381 | } | ||
| 382 | |||
| 183 | Common::UUID StoreData::GetCreateId() const { | 383 | Common::UUID StoreData::GetCreateId() const { |
| 184 | return create_id; | 384 | return create_id; |
| 185 | } | 385 | } |
| @@ -386,7 +586,7 @@ Nickname StoreData::GetNickname() const { | |||
| 386 | 586 | ||
| 387 | bool StoreData::operator==(const StoreData& data) { | 587 | bool StoreData::operator==(const StoreData& data) { |
| 388 | bool is_identical = data.core_data.IsValid() == 0; | 588 | bool is_identical = data.core_data.IsValid() == 0; |
| 389 | is_identical &= core_data.GetNickname() == data.core_data.GetNickname(); | 589 | is_identical &= core_data.GetNickname().data == data.core_data.GetNickname().data; |
| 390 | is_identical &= GetCreateId() == data.GetCreateId(); | 590 | is_identical &= GetCreateId() == data.GetCreateId(); |
| 391 | is_identical &= GetFontRegion() == data.GetFontRegion(); | 591 | is_identical &= GetFontRegion() == data.GetFontRegion(); |
| 392 | is_identical &= GetFavoriteColor() == data.GetFavoriteColor(); | 592 | 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: | |||
| 18 | // nn::mii::detail::StoreDataRaw::BuildRandom | 18 | // nn::mii::detail::StoreDataRaw::BuildRandom |
| 19 | void BuildRandom(Age age, Gender gender, Race race); | 19 | void BuildRandom(Age age, Gender gender, Race race); |
| 20 | 20 | ||
| 21 | void SetInvalidName(); | ||
| 22 | |||
| 23 | bool IsSpecial() const; | 21 | bool IsSpecial() const; |
| 24 | 22 | ||
| 25 | u32 IsValid() const; | 23 | u32 IsValid() const; |
| 26 | 24 | ||
| 25 | void SetFontRegion(FontRegion value); | ||
| 26 | void SetFavoriteColor(u8 value); | ||
| 27 | void SetGender(Gender value); | ||
| 28 | void SetHeight(u8 value); | ||
| 29 | void SetBuild(u8 value); | ||
| 30 | void SetType(u8 value); | ||
| 31 | void SetRegionMove(u8 value); | ||
| 32 | void SetFacelineType(u8 value); | ||
| 33 | void SetFacelineColor(u8 value); | ||
| 34 | void SetFacelineWrinkle(u8 value); | ||
| 35 | void SetFacelineMake(u8 value); | ||
| 36 | void SetHairType(u8 value); | ||
| 37 | void SetHairColor(u8 value); | ||
| 38 | void SetHairFlip(HairFlip value); | ||
| 39 | void SetEyeType(u8 value); | ||
| 40 | void SetEyeColor(u8 value); | ||
| 41 | void SetEyeScale(u8 value); | ||
| 42 | void SetEyeAspect(u8 value); | ||
| 43 | void SetEyeRotate(u8 value); | ||
| 44 | void SetEyeX(u8 value); | ||
| 45 | void SetEyeY(u8 value); | ||
| 46 | void SetEyebrowType(u8 value); | ||
| 47 | void SetEyebrowColor(u8 value); | ||
| 48 | void SetEyebrowScale(u8 value); | ||
| 49 | void SetEyebrowAspect(u8 value); | ||
| 50 | void SetEyebrowRotate(u8 value); | ||
| 51 | void SetEyebrowX(u8 value); | ||
| 52 | void SetEyebrowY(u8 value); | ||
| 53 | void SetNoseType(u8 value); | ||
| 54 | void SetNoseScale(u8 value); | ||
| 55 | void SetNoseY(u8 value); | ||
| 56 | void SetMouthType(u8 value); | ||
| 57 | void SetMouthColor(u8 value); | ||
| 58 | void SetMouthScale(u8 value); | ||
| 59 | void SetMouthAspect(u8 value); | ||
| 60 | void SetMouthY(u8 value); | ||
| 61 | void SetBeardColor(u8 value); | ||
| 62 | void SetBeardType(BeardType value); | ||
| 63 | void SetMustacheType(MustacheType value); | ||
| 64 | void SetMustacheScale(u8 value); | ||
| 65 | void SetMustacheY(u8 value); | ||
| 66 | void SetGlassType(u8 value); | ||
| 67 | void SetGlassColor(u8 value); | ||
| 68 | void SetGlassScale(u8 value); | ||
| 69 | void SetGlassY(u8 value); | ||
| 70 | void SetMoleType(u8 value); | ||
| 71 | void SetMoleScale(u8 value); | ||
| 72 | void SetMoleX(u8 value); | ||
| 73 | void SetMoleY(u8 value); | ||
| 74 | void SetNickname(Nickname nickname); | ||
| 75 | void SetInvalidName(); | ||
| 76 | |||
| 27 | Common::UUID GetCreateId() const; | 77 | Common::UUID GetCreateId() const; |
| 28 | FontRegion GetFontRegion() const; | 78 | FontRegion GetFontRegion() const; |
| 29 | u8 GetFavoriteColor() const; | 79 | 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 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/hle/service/mii/mii_util.h" | 4 | #include "core/hle/service/mii/mii_util.h" |
| 5 | #include "core/hle/service/mii/types/char_info.h" | ||
| 6 | #include "core/hle/service/mii/types/raw_data.h" | 5 | #include "core/hle/service/mii/types/raw_data.h" |
| 7 | #include "core/hle/service/mii/types/store_data.h" | 6 | #include "core/hle/service/mii/types/store_data.h" |
| 8 | #include "core/hle/service/mii/types/ver3_store_data.h" | 7 | #include "core/hle/service/mii/types/ver3_store_data.h" |
| 9 | 8 | ||
| 10 | namespace Service::Mii { | 9 | namespace Service::Mii { |
| 11 | 10 | ||
| 12 | void Ver3StoreData::BuildToStoreData(CharInfo& out_char_info) const { | 11 | void NfpStoreDataExtension::SetFromStoreData(const StoreData& store_data) { |
| 12 | faceline_color = static_cast<u8>(store_data.GetFacelineColor() & 0xf); | ||
| 13 | hair_color = static_cast<u8>(store_data.GetHairColor() & 0x7f); | ||
| 14 | eye_color = static_cast<u8>(store_data.GetEyeColor() & 0x7f); | ||
| 15 | eyebrow_color = static_cast<u8>(store_data.GetEyebrowColor() & 0x7f); | ||
| 16 | mouth_color = static_cast<u8>(store_data.GetMouthColor() & 0x7f); | ||
| 17 | beard_color = static_cast<u8>(store_data.GetBeardColor() & 0x7f); | ||
| 18 | glass_color = static_cast<u8>(store_data.GetGlassColor() & 0x7f); | ||
| 19 | glass_type = static_cast<u8>(store_data.GetGlassType() & 0x1f); | ||
| 20 | } | ||
| 21 | |||
| 22 | void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { | ||
| 23 | out_store_data.BuildBase(Gender::Male); | ||
| 24 | |||
| 13 | if (!IsValid()) { | 25 | if (!IsValid()) { |
| 14 | return; | 26 | return; |
| 15 | } | 27 | } |
| 16 | 28 | ||
| 17 | // TODO: We are ignoring a bunch of data from the mii_v3 | 29 | // TODO: We are ignoring a bunch of data from the mii_v3 |
| 18 | 30 | ||
| 19 | out_char_info.gender = static_cast<u8>(mii_information.gender); | 31 | out_store_data.SetGender(static_cast<Gender>(static_cast<u8>(mii_information.gender))); |
| 20 | out_char_info.favorite_color = static_cast<u8>(mii_information.favorite_color); | 32 | out_store_data.SetFavoriteColor(static_cast<u8>(mii_information.favorite_color)); |
| 21 | out_char_info.height = height; | 33 | out_store_data.SetHeight(height); |
| 22 | out_char_info.build = build; | 34 | out_store_data.SetBuild(build); |
| 23 | 35 | ||
| 24 | // Copy name until string terminator | 36 | // Copy name until string terminator |
| 25 | out_char_info.name = {}; | 37 | Nickname name = {}; |
| 26 | for (std::size_t index = 0; index < out_char_info.name.size() - 1; index++) { | 38 | for (std::size_t index = 0; index < name.data.size() - 1; index++) { |
| 27 | out_char_info.name[index] = mii_name[index]; | 39 | name.data[index] = mii_name[index]; |
| 28 | if (out_char_info.name[index] == 0) { | 40 | if (name.data[index] == 0) { |
| 29 | break; | 41 | break; |
| 30 | } | 42 | } |
| 31 | } | 43 | } |
| 32 | 44 | ||
| 33 | out_char_info.font_region = region_information.character_set; | 45 | out_store_data.SetNickname(name); |
| 34 | 46 | out_store_data.SetFontRegion( | |
| 35 | out_char_info.faceline_type = appearance_bits1.face_shape; | 47 | static_cast<FontRegion>(static_cast<u8>(region_information.font_region))); |
| 36 | out_char_info.faceline_color = appearance_bits1.skin_color; | 48 | |
| 37 | out_char_info.faceline_wrinkle = appearance_bits2.wrinkles; | 49 | out_store_data.SetFacelineType(appearance_bits1.faceline_type); |
| 38 | out_char_info.faceline_make = appearance_bits2.makeup; | 50 | out_store_data.SetFacelineColor(appearance_bits1.faceline_color); |
| 39 | 51 | out_store_data.SetFacelineWrinkle(appearance_bits2.faceline_wrinkle); | |
| 40 | out_char_info.hair_type = hair_style; | 52 | out_store_data.SetFacelineMake(appearance_bits2.faceline_make); |
| 41 | out_char_info.hair_color = appearance_bits3.hair_color; | 53 | |
| 42 | out_char_info.hair_flip = appearance_bits3.flip_hair; | 54 | out_store_data.SetHairType(hair_type); |
| 43 | 55 | out_store_data.SetHairColor(appearance_bits3.hair_color); | |
| 44 | out_char_info.eye_type = static_cast<u8>(appearance_bits4.eye_type); | 56 | out_store_data.SetHairFlip(static_cast<HairFlip>(static_cast<u8>(appearance_bits3.hair_flip))); |
| 45 | out_char_info.eye_color = static_cast<u8>(appearance_bits4.eye_color); | 57 | |
| 46 | out_char_info.eye_scale = static_cast<u8>(appearance_bits4.eye_scale); | 58 | out_store_data.SetEyeType(static_cast<u8>(appearance_bits4.eye_type)); |
| 47 | out_char_info.eye_aspect = static_cast<u8>(appearance_bits4.eye_vertical_stretch); | 59 | out_store_data.SetEyeColor(static_cast<u8>(appearance_bits4.eye_color)); |
| 48 | out_char_info.eye_rotate = static_cast<u8>(appearance_bits4.eye_rotation); | 60 | out_store_data.SetEyeScale(static_cast<u8>(appearance_bits4.eye_scale)); |
| 49 | out_char_info.eye_x = static_cast<u8>(appearance_bits4.eye_spacing); | 61 | out_store_data.SetEyeAspect(static_cast<u8>(appearance_bits4.eye_aspect)); |
| 50 | out_char_info.eye_y = static_cast<u8>(appearance_bits4.eye_y_position); | 62 | out_store_data.SetEyeRotate(static_cast<u8>(appearance_bits4.eye_rotate)); |
| 51 | 63 | out_store_data.SetEyeX(static_cast<u8>(appearance_bits4.eye_x)); | |
| 52 | out_char_info.eyebrow_type = static_cast<u8>(appearance_bits5.eyebrow_style); | 64 | out_store_data.SetEyeY(static_cast<u8>(appearance_bits4.eye_y)); |
| 53 | out_char_info.eyebrow_color = static_cast<u8>(appearance_bits5.eyebrow_color); | 65 | |
| 54 | out_char_info.eyebrow_scale = static_cast<u8>(appearance_bits5.eyebrow_scale); | 66 | out_store_data.SetEyebrowType(static_cast<u8>(appearance_bits5.eyebrow_type)); |
| 55 | out_char_info.eyebrow_aspect = static_cast<u8>(appearance_bits5.eyebrow_yscale); | 67 | out_store_data.SetEyebrowColor(static_cast<u8>(appearance_bits5.eyebrow_color)); |
| 56 | out_char_info.eyebrow_rotate = static_cast<u8>(appearance_bits5.eyebrow_rotation); | 68 | out_store_data.SetEyebrowScale(static_cast<u8>(appearance_bits5.eyebrow_scale)); |
| 57 | out_char_info.eyebrow_x = static_cast<u8>(appearance_bits5.eyebrow_spacing); | 69 | out_store_data.SetEyebrowAspect(static_cast<u8>(appearance_bits5.eyebrow_aspect)); |
| 58 | out_char_info.eyebrow_y = static_cast<u8>(appearance_bits5.eyebrow_y_position); | 70 | out_store_data.SetEyebrowRotate(static_cast<u8>(appearance_bits5.eyebrow_rotate)); |
| 59 | 71 | out_store_data.SetEyebrowX(static_cast<u8>(appearance_bits5.eyebrow_x)); | |
| 60 | out_char_info.nose_type = static_cast<u8>(appearance_bits6.nose_type); | 72 | out_store_data.SetEyebrowY(static_cast<u8>(appearance_bits5.eyebrow_y)); |
| 61 | out_char_info.nose_scale = static_cast<u8>(appearance_bits6.nose_scale); | 73 | |
| 62 | out_char_info.nose_y = static_cast<u8>(appearance_bits6.nose_y_position); | 74 | out_store_data.SetNoseType(static_cast<u8>(appearance_bits6.nose_type)); |
| 63 | 75 | out_store_data.SetNoseScale(static_cast<u8>(appearance_bits6.nose_scale)); | |
| 64 | out_char_info.mouth_type = static_cast<u8>(appearance_bits7.mouth_type); | 76 | out_store_data.SetNoseY(static_cast<u8>(appearance_bits6.nose_y)); |
| 65 | out_char_info.mouth_color = static_cast<u8>(appearance_bits7.mouth_color); | 77 | |
| 66 | out_char_info.mouth_scale = static_cast<u8>(appearance_bits7.mouth_scale); | 78 | out_store_data.SetMouthType(static_cast<u8>(appearance_bits7.mouth_type)); |
| 67 | out_char_info.mouth_aspect = static_cast<u8>(appearance_bits7.mouth_horizontal_stretch); | 79 | out_store_data.SetMouthColor(static_cast<u8>(appearance_bits7.mouth_color)); |
| 68 | out_char_info.mouth_y = static_cast<u8>(appearance_bits8.mouth_y_position); | 80 | out_store_data.SetMouthScale(static_cast<u8>(appearance_bits7.mouth_scale)); |
| 69 | 81 | out_store_data.SetMouthAspect(static_cast<u8>(appearance_bits7.mouth_aspect)); | |
| 70 | out_char_info.mustache_type = static_cast<u8>(appearance_bits8.mustache_type); | 82 | out_store_data.SetMouthY(static_cast<u8>(appearance_bits8.mouth_y)); |
| 71 | out_char_info.mustache_scale = static_cast<u8>(appearance_bits9.mustache_scale); | 83 | |
| 72 | out_char_info.mustache_y = static_cast<u8>(appearance_bits9.mustache_y_position); | 84 | out_store_data.SetMustacheType( |
| 73 | 85 | static_cast<MustacheType>(static_cast<u8>(appearance_bits8.mustache_type))); | |
| 74 | out_char_info.beard_type = static_cast<u8>(appearance_bits9.bear_type); | 86 | out_store_data.SetMustacheScale(static_cast<u8>(appearance_bits9.mustache_scale)); |
| 75 | out_char_info.beard_color = static_cast<u8>(appearance_bits9.facial_hair_color); | 87 | out_store_data.SetMustacheY(static_cast<u8>(appearance_bits9.mustache_y)); |
| 76 | 88 | ||
| 77 | out_char_info.glasses_type = static_cast<u8>(appearance_bits10.glasses_type); | 89 | out_store_data.SetBeardType( |
| 78 | out_char_info.glasses_color = static_cast<u8>(appearance_bits10.glasses_color); | 90 | static_cast<BeardType>(static_cast<u8>(appearance_bits9.beard_type))); |
| 79 | out_char_info.glasses_scale = static_cast<u8>(appearance_bits10.glasses_scale); | 91 | out_store_data.SetBeardColor(static_cast<u8>(appearance_bits9.beard_color)); |
| 80 | out_char_info.glasses_y = static_cast<u8>(appearance_bits10.glasses_y_position); | 92 | |
| 81 | 93 | out_store_data.SetGlassType(static_cast<u8>(appearance_bits10.glass_type)); | |
| 82 | out_char_info.mole_type = static_cast<u8>(appearance_bits11.mole_enabled); | 94 | out_store_data.SetGlassColor(static_cast<u8>(appearance_bits10.glass_color)); |
| 83 | out_char_info.mole_scale = static_cast<u8>(appearance_bits11.mole_scale); | 95 | out_store_data.SetGlassScale(static_cast<u8>(appearance_bits10.glass_scale)); |
| 84 | out_char_info.mole_x = static_cast<u8>(appearance_bits11.mole_x_position); | 96 | out_store_data.SetGlassY(static_cast<u8>(appearance_bits10.glass_y)); |
| 85 | out_char_info.mole_y = static_cast<u8>(appearance_bits11.mole_y_position); | 97 | |
| 98 | out_store_data.SetMoleType(static_cast<u8>(appearance_bits11.mole_type)); | ||
| 99 | out_store_data.SetMoleScale(static_cast<u8>(appearance_bits11.mole_scale)); | ||
| 100 | out_store_data.SetMoleX(static_cast<u8>(appearance_bits11.mole_x)); | ||
| 101 | out_store_data.SetMoleY(static_cast<u8>(appearance_bits11.mole_y)); | ||
| 86 | } | 102 | } |
| 87 | 103 | ||
| 88 | void Ver3StoreData::BuildFromStoreData(const CharInfo& char_info) { | 104 | void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { |
| 89 | version = 1; | 105 | version = 1; |
| 90 | mii_information.gender.Assign(char_info.gender); | 106 | mii_information.gender.Assign(store_data.GetGender()); |
| 91 | mii_information.favorite_color.Assign(char_info.favorite_color); | 107 | mii_information.favorite_color.Assign(store_data.GetFavoriteColor()); |
| 92 | height = char_info.height; | 108 | height = store_data.GetHeight(); |
| 93 | build = char_info.build; | 109 | build = store_data.GetBuild(); |
| 94 | 110 | ||
| 95 | // Copy name until string terminator | 111 | // Copy name until string terminator |
| 96 | mii_name = {}; | 112 | mii_name = {}; |
| 97 | for (std::size_t index = 0; index < char_info.name.size() - 1; index++) { | 113 | for (std::size_t index = 0; index < store_data.GetNickname().data.size() - 1; index++) { |
| 98 | mii_name[index] = char_info.name[index]; | 114 | mii_name[index] = store_data.GetNickname().data[index]; |
| 99 | if (mii_name[index] == 0) { | 115 | if (mii_name[index] == 0) { |
| 100 | break; | 116 | break; |
| 101 | } | 117 | } |
| 102 | } | 118 | } |
| 103 | 119 | ||
| 104 | region_information.character_set.Assign(char_info.font_region); | 120 | region_information.font_region.Assign(static_cast<u8>(store_data.GetFontRegion())); |
| 105 | 121 | ||
| 106 | appearance_bits1.face_shape.Assign(char_info.faceline_type); | 122 | appearance_bits1.faceline_type.Assign(store_data.GetFacelineType()); |
| 107 | appearance_bits2.wrinkles.Assign(char_info.faceline_wrinkle); | 123 | appearance_bits2.faceline_wrinkle.Assign(store_data.GetFacelineWrinkle()); |
| 108 | appearance_bits2.makeup.Assign(char_info.faceline_make); | 124 | appearance_bits2.faceline_make.Assign(store_data.GetFacelineMake()); |
| 109 | 125 | ||
| 110 | hair_style = char_info.hair_type; | 126 | hair_type = store_data.GetHairType(); |
| 111 | appearance_bits3.flip_hair.Assign(char_info.hair_flip); | 127 | appearance_bits3.hair_flip.Assign(store_data.GetHairFlip()); |
| 112 | 128 | ||
| 113 | appearance_bits4.eye_type.Assign(char_info.eye_type); | 129 | appearance_bits4.eye_type.Assign(store_data.GetEyeType()); |
| 114 | appearance_bits4.eye_scale.Assign(char_info.eye_scale); | 130 | appearance_bits4.eye_scale.Assign(store_data.GetEyeScale()); |
| 115 | appearance_bits4.eye_vertical_stretch.Assign(char_info.eye_aspect); | 131 | appearance_bits4.eye_aspect.Assign(store_data.GetEyebrowAspect()); |
| 116 | appearance_bits4.eye_rotation.Assign(char_info.eye_rotate); | 132 | appearance_bits4.eye_rotate.Assign(store_data.GetEyeRotate()); |
| 117 | appearance_bits4.eye_spacing.Assign(char_info.eye_x); | 133 | appearance_bits4.eye_x.Assign(store_data.GetEyeX()); |
| 118 | appearance_bits4.eye_y_position.Assign(char_info.eye_y); | 134 | appearance_bits4.eye_y.Assign(store_data.GetEyeY()); |
| 119 | 135 | ||
| 120 | appearance_bits5.eyebrow_style.Assign(char_info.eyebrow_type); | 136 | appearance_bits5.eyebrow_type.Assign(store_data.GetEyebrowType()); |
| 121 | appearance_bits5.eyebrow_scale.Assign(char_info.eyebrow_scale); | 137 | appearance_bits5.eyebrow_scale.Assign(store_data.GetEyebrowScale()); |
| 122 | appearance_bits5.eyebrow_yscale.Assign(char_info.eyebrow_aspect); | 138 | appearance_bits5.eyebrow_aspect.Assign(store_data.GetEyebrowAspect()); |
| 123 | appearance_bits5.eyebrow_rotation.Assign(char_info.eyebrow_rotate); | 139 | appearance_bits5.eyebrow_rotate.Assign(store_data.GetEyebrowRotate()); |
| 124 | appearance_bits5.eyebrow_spacing.Assign(char_info.eyebrow_x); | 140 | appearance_bits5.eyebrow_x.Assign(store_data.GetEyebrowX()); |
| 125 | appearance_bits5.eyebrow_y_position.Assign(char_info.eyebrow_y); | 141 | appearance_bits5.eyebrow_y.Assign(store_data.GetEyebrowY()); |
| 126 | 142 | ||
| 127 | appearance_bits6.nose_type.Assign(char_info.nose_type); | 143 | appearance_bits6.nose_type.Assign(store_data.GetNoseType()); |
| 128 | appearance_bits6.nose_scale.Assign(char_info.nose_scale); | 144 | appearance_bits6.nose_scale.Assign(store_data.GetNoseScale()); |
| 129 | appearance_bits6.nose_y_position.Assign(char_info.nose_y); | 145 | appearance_bits6.nose_y.Assign(store_data.GetNoseY()); |
| 130 | 146 | ||
| 131 | appearance_bits7.mouth_type.Assign(char_info.mouth_type); | 147 | appearance_bits7.mouth_type.Assign(store_data.GetMouthType()); |
| 132 | appearance_bits7.mouth_scale.Assign(char_info.mouth_scale); | 148 | appearance_bits7.mouth_scale.Assign(store_data.GetMouthScale()); |
| 133 | appearance_bits7.mouth_horizontal_stretch.Assign(char_info.mouth_aspect); | 149 | appearance_bits7.mouth_aspect.Assign(store_data.GetMouthAspect()); |
| 134 | appearance_bits8.mouth_y_position.Assign(char_info.mouth_y); | 150 | appearance_bits8.mouth_y.Assign(store_data.GetMouthY()); |
| 135 | 151 | ||
| 136 | appearance_bits8.mustache_type.Assign(char_info.mustache_type); | 152 | appearance_bits8.mustache_type.Assign(store_data.GetMustacheType()); |
| 137 | appearance_bits9.mustache_scale.Assign(char_info.mustache_scale); | 153 | appearance_bits9.mustache_scale.Assign(store_data.GetMustacheScale()); |
| 138 | appearance_bits9.mustache_y_position.Assign(char_info.mustache_y); | 154 | appearance_bits9.mustache_y.Assign(store_data.GetMustacheY()); |
| 139 | 155 | ||
| 140 | appearance_bits9.bear_type.Assign(char_info.beard_type); | 156 | appearance_bits9.beard_type.Assign(store_data.GetBeardType()); |
| 141 | 157 | ||
| 142 | appearance_bits10.glasses_scale.Assign(char_info.glasses_scale); | 158 | appearance_bits10.glass_scale.Assign(store_data.GetGlassScale()); |
| 143 | appearance_bits10.glasses_y_position.Assign(char_info.glasses_y); | 159 | appearance_bits10.glass_y.Assign(store_data.GetGlassY()); |
| 144 | 160 | ||
| 145 | appearance_bits11.mole_enabled.Assign(char_info.mole_type); | 161 | appearance_bits11.mole_type.Assign(store_data.GetMoleType()); |
| 146 | appearance_bits11.mole_scale.Assign(char_info.mole_scale); | 162 | appearance_bits11.mole_scale.Assign(store_data.GetMoleScale()); |
| 147 | appearance_bits11.mole_x_position.Assign(char_info.mole_x); | 163 | appearance_bits11.mole_x.Assign(store_data.GetMoleX()); |
| 148 | appearance_bits11.mole_y_position.Assign(char_info.mole_y); | 164 | appearance_bits11.mole_y.Assign(store_data.GetMoleY()); |
| 149 | 165 | ||
| 150 | // These types are converted to V3 from a table | 166 | // These types are converted to V3 from a table |
| 151 | appearance_bits1.skin_color.Assign(RawData::FromVer3GetFacelineColor(char_info.faceline_color)); | 167 | appearance_bits1.faceline_color.Assign( |
| 152 | appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(char_info.hair_color)); | 168 | RawData::FromVer3GetFacelineColor(store_data.GetFacelineColor())); |
| 153 | appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(char_info.eye_color)); | 169 | appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(store_data.GetHairColor())); |
| 154 | appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(char_info.eyebrow_color)); | 170 | appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(store_data.GetEyeColor())); |
| 155 | appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(char_info.mouth_color)); | 171 | appearance_bits5.eyebrow_color.Assign( |
| 156 | appearance_bits9.facial_hair_color.Assign(RawData::FromVer3GetHairColor(char_info.beard_color)); | 172 | RawData::FromVer3GetHairColor(store_data.GetEyebrowColor())); |
| 157 | appearance_bits10.glasses_color.Assign(RawData::FromVer3GetGlassColor(char_info.glasses_color)); | 173 | appearance_bits7.mouth_color.Assign( |
| 158 | appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(char_info.glasses_type)); | 174 | RawData::FromVer3GetMouthlineColor(store_data.GetMouthColor())); |
| 175 | appearance_bits9.beard_color.Assign(RawData::FromVer3GetHairColor(store_data.GetBeardColor())); | ||
| 176 | appearance_bits10.glass_color.Assign( | ||
| 177 | RawData::FromVer3GetGlassColor(store_data.GetGlassColor())); | ||
| 178 | appearance_bits10.glass_type.Assign(RawData::FromVer3GetGlassType(store_data.GetGlassType())); | ||
| 159 | 179 | ||
| 160 | crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); | 180 | crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); |
| 161 | } | 181 | } |
| @@ -171,56 +191,56 @@ u32 Ver3StoreData::IsValid() const { | |||
| 171 | is_valid = is_valid && (height < 128); | 191 | is_valid = is_valid && (height < 128); |
| 172 | is_valid = is_valid && (build < 128); | 192 | is_valid = is_valid && (build < 128); |
| 173 | 193 | ||
| 174 | is_valid = is_valid && (appearance_bits1.face_shape < 12); | 194 | is_valid = is_valid && (appearance_bits1.faceline_type < 12); |
| 175 | is_valid = is_valid && (appearance_bits1.skin_color < 7); | 195 | is_valid = is_valid && (appearance_bits1.faceline_color < 7); |
| 176 | is_valid = is_valid && (appearance_bits2.wrinkles < 12); | 196 | is_valid = is_valid && (appearance_bits2.faceline_wrinkle < 12); |
| 177 | is_valid = is_valid && (appearance_bits2.makeup < 12); | 197 | is_valid = is_valid && (appearance_bits2.faceline_make < 12); |
| 178 | 198 | ||
| 179 | is_valid = is_valid && (hair_style < 132); | 199 | is_valid = is_valid && (hair_type < 132); |
| 180 | is_valid = is_valid && (appearance_bits3.hair_color < 8); | 200 | is_valid = is_valid && (appearance_bits3.hair_color < 8); |
| 181 | 201 | ||
| 182 | is_valid = is_valid && (appearance_bits4.eye_type < 60); | 202 | is_valid = is_valid && (appearance_bits4.eye_type < 60); |
| 183 | is_valid = is_valid && (appearance_bits4.eye_color < 6); | 203 | is_valid = is_valid && (appearance_bits4.eye_color < 6); |
| 184 | is_valid = is_valid && (appearance_bits4.eye_scale < 8); | 204 | is_valid = is_valid && (appearance_bits4.eye_scale < 8); |
| 185 | is_valid = is_valid && (appearance_bits4.eye_vertical_stretch < 7); | 205 | is_valid = is_valid && (appearance_bits4.eye_aspect < 7); |
| 186 | is_valid = is_valid && (appearance_bits4.eye_rotation < 8); | 206 | is_valid = is_valid && (appearance_bits4.eye_rotate < 8); |
| 187 | is_valid = is_valid && (appearance_bits4.eye_spacing < 13); | 207 | is_valid = is_valid && (appearance_bits4.eye_x < 13); |
| 188 | is_valid = is_valid && (appearance_bits4.eye_y_position < 19); | 208 | is_valid = is_valid && (appearance_bits4.eye_y < 19); |
| 189 | 209 | ||
| 190 | is_valid = is_valid && (appearance_bits5.eyebrow_style < 25); | 210 | is_valid = is_valid && (appearance_bits5.eyebrow_type < 25); |
| 191 | is_valid = is_valid && (appearance_bits5.eyebrow_color < 8); | 211 | is_valid = is_valid && (appearance_bits5.eyebrow_color < 8); |
| 192 | is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9); | 212 | is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9); |
| 193 | is_valid = is_valid && (appearance_bits5.eyebrow_yscale < 7); | 213 | is_valid = is_valid && (appearance_bits5.eyebrow_aspect < 7); |
| 194 | is_valid = is_valid && (appearance_bits5.eyebrow_rotation < 12); | 214 | is_valid = is_valid && (appearance_bits5.eyebrow_rotate < 12); |
| 195 | is_valid = is_valid && (appearance_bits5.eyebrow_spacing < 12); | 215 | is_valid = is_valid && (appearance_bits5.eyebrow_x < 12); |
| 196 | is_valid = is_valid && (appearance_bits5.eyebrow_y_position < 19); | 216 | is_valid = is_valid && (appearance_bits5.eyebrow_y < 19); |
| 197 | 217 | ||
| 198 | is_valid = is_valid && (appearance_bits6.nose_type < 18); | 218 | is_valid = is_valid && (appearance_bits6.nose_type < 18); |
| 199 | is_valid = is_valid && (appearance_bits6.nose_scale < 9); | 219 | is_valid = is_valid && (appearance_bits6.nose_scale < 9); |
| 200 | is_valid = is_valid && (appearance_bits6.nose_y_position < 19); | 220 | is_valid = is_valid && (appearance_bits6.nose_y < 19); |
| 201 | 221 | ||
| 202 | is_valid = is_valid && (appearance_bits7.mouth_type < 36); | 222 | is_valid = is_valid && (appearance_bits7.mouth_type < 36); |
| 203 | is_valid = is_valid && (appearance_bits7.mouth_color < 5); | 223 | is_valid = is_valid && (appearance_bits7.mouth_color < 5); |
| 204 | is_valid = is_valid && (appearance_bits7.mouth_scale < 9); | 224 | is_valid = is_valid && (appearance_bits7.mouth_scale < 9); |
| 205 | is_valid = is_valid && (appearance_bits7.mouth_horizontal_stretch < 7); | 225 | is_valid = is_valid && (appearance_bits7.mouth_aspect < 7); |
| 206 | is_valid = is_valid && (appearance_bits8.mouth_y_position < 19); | 226 | is_valid = is_valid && (appearance_bits8.mouth_y < 19); |
| 207 | 227 | ||
| 208 | is_valid = is_valid && (appearance_bits8.mustache_type < 6); | 228 | is_valid = is_valid && (appearance_bits8.mustache_type < 6); |
| 209 | is_valid = is_valid && (appearance_bits9.mustache_scale < 7); | 229 | is_valid = is_valid && (appearance_bits9.mustache_scale < 7); |
| 210 | is_valid = is_valid && (appearance_bits9.mustache_y_position < 17); | 230 | is_valid = is_valid && (appearance_bits9.mustache_y < 17); |
| 211 | 231 | ||
| 212 | is_valid = is_valid && (appearance_bits9.bear_type < 6); | 232 | is_valid = is_valid && (appearance_bits9.beard_type < 6); |
| 213 | is_valid = is_valid && (appearance_bits9.facial_hair_color < 8); | 233 | is_valid = is_valid && (appearance_bits9.beard_color < 8); |
| 214 | 234 | ||
| 215 | is_valid = is_valid && (appearance_bits10.glasses_type < 9); | 235 | is_valid = is_valid && (appearance_bits10.glass_type < 9); |
| 216 | is_valid = is_valid && (appearance_bits10.glasses_color < 6); | 236 | is_valid = is_valid && (appearance_bits10.glass_color < 6); |
| 217 | is_valid = is_valid && (appearance_bits10.glasses_scale < 8); | 237 | is_valid = is_valid && (appearance_bits10.glass_scale < 8); |
| 218 | is_valid = is_valid && (appearance_bits10.glasses_y_position < 21); | 238 | is_valid = is_valid && (appearance_bits10.glass_y < 21); |
| 219 | 239 | ||
| 220 | is_valid = is_valid && (appearance_bits11.mole_enabled < 2); | 240 | is_valid = is_valid && (appearance_bits11.mole_type < 2); |
| 221 | is_valid = is_valid && (appearance_bits11.mole_scale < 9); | 241 | is_valid = is_valid && (appearance_bits11.mole_scale < 9); |
| 222 | is_valid = is_valid && (appearance_bits11.mole_x_position < 17); | 242 | is_valid = is_valid && (appearance_bits11.mole_x < 17); |
| 223 | is_valid = is_valid && (appearance_bits11.mole_y_position < 31); | 243 | is_valid = is_valid && (appearance_bits11.mole_y < 31); |
| 224 | 244 | ||
| 225 | return is_valid; | 245 | return is_valid; |
| 226 | } | 246 | } |
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 @@ | |||
| 6 | #include "core/hle/service/mii/mii_types.h" | 6 | #include "core/hle/service/mii/mii_types.h" |
| 7 | 7 | ||
| 8 | namespace Service::Mii { | 8 | namespace Service::Mii { |
| 9 | class CharInfo; | 9 | class StoreData; |
| 10 | 10 | ||
| 11 | // This is nn::mii::Ver3StoreData | 11 | // This is nn::mii::Ver3StoreData |
| 12 | // Based on citra HLE::Applets::MiiData and PretendoNetwork. | 12 | // Based on citra HLE::Applets::MiiData and PretendoNetwork. |
| 13 | // https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 | 13 | // https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 |
| 14 | // https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 | 14 | // https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 |
| 15 | 15 | ||
| 16 | struct NfpStoreDataExtension { | ||
| 17 | void SetFromStoreData(const StoreData& store_data); | ||
| 18 | |||
| 19 | u8 faceline_color; | ||
| 20 | u8 hair_color; | ||
| 21 | u8 eye_color; | ||
| 22 | u8 eyebrow_color; | ||
| 23 | u8 mouth_color; | ||
| 24 | u8 beard_color; | ||
| 25 | u8 glass_color; | ||
| 26 | u8 glass_type; | ||
| 27 | }; | ||
| 28 | static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); | ||
| 29 | |||
| 16 | #pragma pack(push, 4) | 30 | #pragma pack(push, 4) |
| 17 | class Ver3StoreData { | 31 | class Ver3StoreData { |
| 18 | public: | 32 | public: |
| 19 | // TODO: This function is wrong. It should use StoreData. | 33 | void BuildToStoreData(StoreData& out_store_data) const; |
| 20 | void BuildToStoreData(CharInfo& out_char_info) const; | 34 | void BuildFromStoreData(const StoreData& store_data); |
| 21 | // TODO: This function is wrong. It should use StoreData. | ||
| 22 | void BuildFromStoreData(const CharInfo& char_info); | ||
| 23 | 35 | ||
| 24 | u32 IsValid() const; | 36 | u32 IsValid() const; |
| 25 | 37 | ||
| @@ -30,7 +42,7 @@ public: | |||
| 30 | BitField<0, 1, u8> allow_copying; | 42 | BitField<0, 1, u8> allow_copying; |
| 31 | BitField<1, 1, u8> profanity_flag; | 43 | BitField<1, 1, u8> profanity_flag; |
| 32 | BitField<2, 2, u8> region_lock; | 44 | BitField<2, 2, u8> region_lock; |
| 33 | BitField<4, 2, u8> character_set; | 45 | BitField<4, 2, u8> font_region; |
| 34 | } region_information; | 46 | } region_information; |
| 35 | u16_be mii_id; | 47 | u16_be mii_id; |
| 36 | u64_be system_id; | 48 | u64_be system_id; |
| @@ -53,21 +65,21 @@ public: | |||
| 53 | u8 raw; | 65 | u8 raw; |
| 54 | 66 | ||
| 55 | BitField<0, 1, u8> disable_sharing; | 67 | BitField<0, 1, u8> disable_sharing; |
| 56 | BitField<1, 4, u8> face_shape; | 68 | BitField<1, 4, u8> faceline_type; |
| 57 | BitField<5, 3, u8> skin_color; | 69 | BitField<5, 3, u8> faceline_color; |
| 58 | } appearance_bits1; | 70 | } appearance_bits1; |
| 59 | union { | 71 | union { |
| 60 | u8 raw; | 72 | u8 raw; |
| 61 | 73 | ||
| 62 | BitField<0, 4, u8> wrinkles; | 74 | BitField<0, 4, u8> faceline_wrinkle; |
| 63 | BitField<4, 4, u8> makeup; | 75 | BitField<4, 4, u8> faceline_make; |
| 64 | } appearance_bits2; | 76 | } appearance_bits2; |
| 65 | u8 hair_style; | 77 | u8 hair_type; |
| 66 | union { | 78 | union { |
| 67 | u8 raw; | 79 | u8 raw; |
| 68 | 80 | ||
| 69 | BitField<0, 3, u8> hair_color; | 81 | BitField<0, 3, u8> hair_color; |
| 70 | BitField<3, 1, u8> flip_hair; | 82 | BitField<3, 1, u8> hair_flip; |
| 71 | } appearance_bits3; | 83 | } appearance_bits3; |
| 72 | union { | 84 | union { |
| 73 | u32 raw; | 85 | u32 raw; |
| @@ -75,28 +87,28 @@ public: | |||
| 75 | BitField<0, 6, u32> eye_type; | 87 | BitField<0, 6, u32> eye_type; |
| 76 | BitField<6, 3, u32> eye_color; | 88 | BitField<6, 3, u32> eye_color; |
| 77 | BitField<9, 4, u32> eye_scale; | 89 | BitField<9, 4, u32> eye_scale; |
| 78 | BitField<13, 3, u32> eye_vertical_stretch; | 90 | BitField<13, 3, u32> eye_aspect; |
| 79 | BitField<16, 5, u32> eye_rotation; | 91 | BitField<16, 5, u32> eye_rotate; |
| 80 | BitField<21, 4, u32> eye_spacing; | 92 | BitField<21, 4, u32> eye_x; |
| 81 | BitField<25, 5, u32> eye_y_position; | 93 | BitField<25, 5, u32> eye_y; |
| 82 | } appearance_bits4; | 94 | } appearance_bits4; |
| 83 | union { | 95 | union { |
| 84 | u32 raw; | 96 | u32 raw; |
| 85 | 97 | ||
| 86 | BitField<0, 5, u32> eyebrow_style; | 98 | BitField<0, 5, u32> eyebrow_type; |
| 87 | BitField<5, 3, u32> eyebrow_color; | 99 | BitField<5, 3, u32> eyebrow_color; |
| 88 | BitField<8, 4, u32> eyebrow_scale; | 100 | BitField<8, 4, u32> eyebrow_scale; |
| 89 | BitField<12, 3, u32> eyebrow_yscale; | 101 | BitField<12, 3, u32> eyebrow_aspect; |
| 90 | BitField<16, 4, u32> eyebrow_rotation; | 102 | BitField<16, 4, u32> eyebrow_rotate; |
| 91 | BitField<21, 4, u32> eyebrow_spacing; | 103 | BitField<21, 4, u32> eyebrow_x; |
| 92 | BitField<25, 5, u32> eyebrow_y_position; | 104 | BitField<25, 5, u32> eyebrow_y; |
| 93 | } appearance_bits5; | 105 | } appearance_bits5; |
| 94 | union { | 106 | union { |
| 95 | u16 raw; | 107 | u16 raw; |
| 96 | 108 | ||
| 97 | BitField<0, 5, u16> nose_type; | 109 | BitField<0, 5, u16> nose_type; |
| 98 | BitField<5, 4, u16> nose_scale; | 110 | BitField<5, 4, u16> nose_scale; |
| 99 | BitField<9, 5, u16> nose_y_position; | 111 | BitField<9, 5, u16> nose_y; |
| 100 | } appearance_bits6; | 112 | } appearance_bits6; |
| 101 | union { | 113 | union { |
| 102 | u16 raw; | 114 | u16 raw; |
| @@ -104,38 +116,38 @@ public: | |||
| 104 | BitField<0, 6, u16> mouth_type; | 116 | BitField<0, 6, u16> mouth_type; |
| 105 | BitField<6, 3, u16> mouth_color; | 117 | BitField<6, 3, u16> mouth_color; |
| 106 | BitField<9, 4, u16> mouth_scale; | 118 | BitField<9, 4, u16> mouth_scale; |
| 107 | BitField<13, 3, u16> mouth_horizontal_stretch; | 119 | BitField<13, 3, u16> mouth_aspect; |
| 108 | } appearance_bits7; | 120 | } appearance_bits7; |
| 109 | union { | 121 | union { |
| 110 | u8 raw; | 122 | u8 raw; |
| 111 | 123 | ||
| 112 | BitField<0, 5, u8> mouth_y_position; | 124 | BitField<0, 5, u8> mouth_y; |
| 113 | BitField<5, 3, u8> mustache_type; | 125 | BitField<5, 3, u8> mustache_type; |
| 114 | } appearance_bits8; | 126 | } appearance_bits8; |
| 115 | u8 allow_copying; | 127 | u8 allow_copying; |
| 116 | union { | 128 | union { |
| 117 | u16 raw; | 129 | u16 raw; |
| 118 | 130 | ||
| 119 | BitField<0, 3, u16> bear_type; | 131 | BitField<0, 3, u16> beard_type; |
| 120 | BitField<3, 3, u16> facial_hair_color; | 132 | BitField<3, 3, u16> beard_color; |
| 121 | BitField<6, 4, u16> mustache_scale; | 133 | BitField<6, 4, u16> mustache_scale; |
| 122 | BitField<10, 5, u16> mustache_y_position; | 134 | BitField<10, 5, u16> mustache_y; |
| 123 | } appearance_bits9; | 135 | } appearance_bits9; |
| 124 | union { | 136 | union { |
| 125 | u16 raw; | 137 | u16 raw; |
| 126 | 138 | ||
| 127 | BitField<0, 4, u16> glasses_type; | 139 | BitField<0, 4, u16> glass_type; |
| 128 | BitField<4, 3, u16> glasses_color; | 140 | BitField<4, 3, u16> glass_color; |
| 129 | BitField<7, 4, u16> glasses_scale; | 141 | BitField<7, 4, u16> glass_scale; |
| 130 | BitField<11, 5, u16> glasses_y_position; | 142 | BitField<11, 5, u16> glass_y; |
| 131 | } appearance_bits10; | 143 | } appearance_bits10; |
| 132 | union { | 144 | union { |
| 133 | u16 raw; | 145 | u16 raw; |
| 134 | 146 | ||
| 135 | BitField<0, 1, u16> mole_enabled; | 147 | BitField<0, 1, u16> mole_type; |
| 136 | BitField<1, 4, u16> mole_scale; | 148 | BitField<1, 4, u16> mole_scale; |
| 137 | BitField<5, 5, u16> mole_x_position; | 149 | BitField<5, 5, u16> mole_x; |
| 138 | BitField<10, 5, u16> mole_y_position; | 150 | BitField<10, 5, u16> mole_y; |
| 139 | } appearance_bits11; | 151 | } appearance_bits11; |
| 140 | 152 | ||
| 141 | std::array<u16_le, 0xA> author_name; | 153 | std::array<u16_le, 0xA> 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 | |||
| 824 | return ResultWrongDeviceState; | 824 | return ResultWrongDeviceState; |
| 825 | } | 825 | } |
| 826 | 826 | ||
| 827 | Service::Mii::MiiManager manager; | 827 | Service::Mii::StoreData store_data{}; |
| 828 | const auto mii = manager.BuildBase(Mii::Gender::Male); | 828 | Service::Mii::NfpStoreDataExtension extension{}; |
| 829 | store_data.BuildBase(Mii::Gender::Male); | ||
| 830 | extension.SetFromStoreData(store_data); | ||
| 831 | |||
| 829 | auto& settings = tag_data.settings; | 832 | auto& settings = tag_data.settings; |
| 830 | 833 | ||
| 831 | if (tag_data.settings.settings.amiibo_initialized == 0) { | 834 | if (tag_data.settings.settings.amiibo_initialized == 0) { |
| @@ -834,8 +837,8 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe | |||
| 834 | } | 837 | } |
| 835 | 838 | ||
| 836 | SetAmiiboName(settings, register_info.amiibo_name); | 839 | SetAmiiboName(settings, register_info.amiibo_name); |
| 837 | tag_data.owner_mii.BuildFromStoreData(mii); | 840 | tag_data.owner_mii.BuildFromStoreData(store_data); |
| 838 | tag_data.mii_extension = manager.SetFromStoreData(mii); | 841 | tag_data.mii_extension = extension; |
| 839 | tag_data.unknown = 0; | 842 | tag_data.unknown = 0; |
| 840 | tag_data.unknown2 = {}; | 843 | tag_data.unknown2 = {}; |
| 841 | settings.country_code_id = 0; | 844 | settings.country_code_id = 0; |
| @@ -1452,7 +1455,7 @@ void NfcDevice::UpdateRegisterInfoCrc() { | |||
| 1452 | 1455 | ||
| 1453 | void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, | 1456 | void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, |
| 1454 | const NFP::EncryptedNTAG215File& encrypted_file) const { | 1457 | const NFP::EncryptedNTAG215File& encrypted_file) const { |
| 1455 | Service::Mii::MiiManager manager; | 1458 | Service::Mii::StoreData store_data{}; |
| 1456 | auto& settings = stubbed_tag_data.settings; | 1459 | auto& settings = stubbed_tag_data.settings; |
| 1457 | 1460 | ||
| 1458 | stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file); | 1461 | stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file); |
| @@ -1466,7 +1469,8 @@ void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, | |||
| 1466 | SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); | 1469 | SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); |
| 1467 | settings.settings.font_region.Assign(0); | 1470 | settings.settings.font_region.Assign(0); |
| 1468 | settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); | 1471 | settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); |
| 1469 | stubbed_tag_data.owner_mii.BuildFromStoreData(manager.BuildBase(Mii::Gender::Male)); | 1472 | store_data.BuildBase(Mii::Gender::Male); |
| 1473 | stubbed_tag_data.owner_mii.BuildFromStoreData(store_data); | ||
| 1470 | 1474 | ||
| 1471 | // Admin info | 1475 | // Admin info |
| 1472 | settings.settings.amiibo_initialized.Assign(1); | 1476 | settings.settings.amiibo_initialized.Assign(1); |