summaryrefslogtreecommitdiff
path: root/src/core/hle/service/mii
diff options
context:
space:
mode:
authorGravatar german772023-09-10 22:42:38 -0600
committerGravatar german772023-09-10 22:42:38 -0600
commit8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c (patch)
tree6ea7d5f1e5d3cf29bf8abcd16bbb30bf71ec3419 /src/core/hle/service/mii
parentservice: mii: separate mii types into their own file (diff)
downloadyuzu-8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c.tar.gz
yuzu-8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c.tar.xz
yuzu-8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c.zip
service: mii: Move ver3 operations
Diffstat (limited to 'src/core/hle/service/mii')
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp235
-rw-r--r--src/core/hle/service/mii/mii_manager.h4
-rw-r--r--src/core/hle/service/mii/types/char_info.h3
-rw-r--r--src/core/hle/service/mii/types/ver3_store_data.cpp224
-rw-r--r--src/core/hle/service/mii/types/ver3_store_data.h13
5 files changed, 238 insertions, 241 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) {
394} 394}
395 395
396CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { 396CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const {
397 Service::Mii::MiiManager manager; 397 CharInfo char_info{};
398 auto mii = manager.BuildBase(Mii::Gender::Male); 398 mii_v3.BuildToStoreData(char_info);
399 399 return char_info;
400 if (!ValidateV3Info(mii_v3)) {
401 return mii;
402 }
403
404 // TODO: We are ignoring a bunch of data from the mii_v3
405
406 mii.gender = static_cast<u8>(mii_v3.mii_information.gender);
407 mii.favorite_color = static_cast<u8>(mii_v3.mii_information.favorite_color);
408 mii.height = mii_v3.height;
409 mii.build = mii_v3.build;
410
411 // Copy name until string terminator
412 mii.name = {};
413 for (std::size_t index = 0; index < mii.name.size() - 1; index++) {
414 mii.name[index] = mii_v3.mii_name[index];
415 if (mii.name[index] == 0) {
416 break;
417 }
418 }
419
420 mii.font_region = mii_v3.region_information.character_set;
421
422 mii.faceline_type = mii_v3.appearance_bits1.face_shape;
423 mii.faceline_color = mii_v3.appearance_bits1.skin_color;
424 mii.faceline_wrinkle = mii_v3.appearance_bits2.wrinkles;
425 mii.faceline_make = mii_v3.appearance_bits2.makeup;
426
427 mii.hair_type = mii_v3.hair_style;
428 mii.hair_color = mii_v3.appearance_bits3.hair_color;
429 mii.hair_flip = mii_v3.appearance_bits3.flip_hair;
430
431 mii.eye_type = static_cast<u8>(mii_v3.appearance_bits4.eye_type);
432 mii.eye_color = static_cast<u8>(mii_v3.appearance_bits4.eye_color);
433 mii.eye_scale = static_cast<u8>(mii_v3.appearance_bits4.eye_scale);
434 mii.eye_aspect = static_cast<u8>(mii_v3.appearance_bits4.eye_vertical_stretch);
435 mii.eye_rotate = static_cast<u8>(mii_v3.appearance_bits4.eye_rotation);
436 mii.eye_x = static_cast<u8>(mii_v3.appearance_bits4.eye_spacing);
437 mii.eye_y = static_cast<u8>(mii_v3.appearance_bits4.eye_y_position);
438
439 mii.eyebrow_type = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_style);
440 mii.eyebrow_color = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_color);
441 mii.eyebrow_scale = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_scale);
442 mii.eyebrow_aspect = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_yscale);
443 mii.eyebrow_rotate = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_rotation);
444 mii.eyebrow_x = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_spacing);
445 mii.eyebrow_y = static_cast<u8>(mii_v3.appearance_bits5.eyebrow_y_position);
446
447 mii.nose_type = static_cast<u8>(mii_v3.appearance_bits6.nose_type);
448 mii.nose_scale = static_cast<u8>(mii_v3.appearance_bits6.nose_scale);
449 mii.nose_y = static_cast<u8>(mii_v3.appearance_bits6.nose_y_position);
450
451 mii.mouth_type = static_cast<u8>(mii_v3.appearance_bits7.mouth_type);
452 mii.mouth_color = static_cast<u8>(mii_v3.appearance_bits7.mouth_color);
453 mii.mouth_scale = static_cast<u8>(mii_v3.appearance_bits7.mouth_scale);
454 mii.mouth_aspect = static_cast<u8>(mii_v3.appearance_bits7.mouth_horizontal_stretch);
455 mii.mouth_y = static_cast<u8>(mii_v3.appearance_bits8.mouth_y_position);
456
457 mii.mustache_type = static_cast<u8>(mii_v3.appearance_bits8.mustache_type);
458 mii.mustache_scale = static_cast<u8>(mii_v3.appearance_bits9.mustache_scale);
459 mii.mustache_y = static_cast<u8>(mii_v3.appearance_bits9.mustache_y_position);
460
461 mii.beard_type = static_cast<u8>(mii_v3.appearance_bits9.bear_type);
462 mii.beard_color = static_cast<u8>(mii_v3.appearance_bits9.facial_hair_color);
463
464 mii.glasses_type = static_cast<u8>(mii_v3.appearance_bits10.glasses_type);
465 mii.glasses_color = static_cast<u8>(mii_v3.appearance_bits10.glasses_color);
466 mii.glasses_scale = static_cast<u8>(mii_v3.appearance_bits10.glasses_scale);
467 mii.glasses_y = static_cast<u8>(mii_v3.appearance_bits10.glasses_y_position);
468
469 mii.mole_type = static_cast<u8>(mii_v3.appearance_bits11.mole_enabled);
470 mii.mole_scale = static_cast<u8>(mii_v3.appearance_bits11.mole_scale);
471 mii.mole_x = static_cast<u8>(mii_v3.appearance_bits11.mole_x_position);
472 mii.mole_y = static_cast<u8>(mii_v3.appearance_bits11.mole_y_position);
473
474 // TODO: Validate mii data
475
476 return mii;
477}
478
479Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const {
480 Service::Mii::MiiManager manager;
481 Ver3StoreData mii_v3{};
482
483 // TODO: We are ignoring a bunch of data from the mii_v3
484
485 mii_v3.version = 1;
486 mii_v3.mii_information.gender.Assign(mii.gender);
487 mii_v3.mii_information.favorite_color.Assign(mii.favorite_color);
488 mii_v3.height = mii.height;
489 mii_v3.build = mii.build;
490
491 // Copy name until string terminator
492 mii_v3.mii_name = {};
493 for (std::size_t index = 0; index < mii.name.size() - 1; index++) {
494 mii_v3.mii_name[index] = mii.name[index];
495 if (mii_v3.mii_name[index] == 0) {
496 break;
497 }
498 }
499
500 mii_v3.region_information.character_set.Assign(mii.font_region);
501
502 mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type);
503 mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle);
504 mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make);
505
506 mii_v3.hair_style = mii.hair_type;
507 mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip);
508
509 mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type);
510 mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale);
511 mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect);
512 mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate);
513 mii_v3.appearance_bits4.eye_spacing.Assign(mii.eye_x);
514 mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y);
515
516 mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type);
517 mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale);
518 mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect);
519 mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate);
520 mii_v3.appearance_bits5.eyebrow_spacing.Assign(mii.eyebrow_x);
521 mii_v3.appearance_bits5.eyebrow_y_position.Assign(mii.eyebrow_y);
522
523 mii_v3.appearance_bits6.nose_type.Assign(mii.nose_type);
524 mii_v3.appearance_bits6.nose_scale.Assign(mii.nose_scale);
525 mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y);
526
527 mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type);
528 mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale);
529 mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect);
530 mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y);
531
532 mii_v3.appearance_bits8.mustache_type.Assign(mii.mustache_type);
533 mii_v3.appearance_bits9.mustache_scale.Assign(mii.mustache_scale);
534 mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y);
535
536 mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type);
537
538 mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale);
539 mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y);
540
541 mii_v3.appearance_bits11.mole_enabled.Assign(mii.mole_type);
542 mii_v3.appearance_bits11.mole_scale.Assign(mii.mole_scale);
543 mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x);
544 mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y);
545
546 // These types are converted to V3 from a table
547 mii_v3.appearance_bits1.skin_color.Assign(
548 RawData::FromVer3GetFacelineColor(mii.faceline_color));
549 mii_v3.appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(mii.hair_color));
550 mii_v3.appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(mii.eye_color));
551 mii_v3.appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(mii.eyebrow_color));
552 mii_v3.appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(mii.mouth_color));
553 mii_v3.appearance_bits9.facial_hair_color.Assign(
554 RawData::FromVer3GetHairColor(mii.beard_color));
555 mii_v3.appearance_bits10.glasses_color.Assign(
556 RawData::FromVer3GetGlassColor(mii.glasses_color));
557 mii_v3.appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(mii.glasses_type));
558
559 mii_v3.crc = MiiUtil::CalculateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16));
560
561 // TODO: Validate mii_v3 data
562
563 return mii_v3;
564} 400}
565 401
566NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { 402NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const {
@@ -576,71 +412,6 @@ NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const {
576 }; 412 };
577} 413}
578 414
579bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const {
580 bool is_valid = mii_v3.version == 0 || mii_v3.version == 3;
581
582 is_valid = is_valid && (mii_v3.mii_name[0] != 0);
583
584 is_valid = is_valid && (mii_v3.mii_information.birth_month < 13);
585 is_valid = is_valid && (mii_v3.mii_information.birth_day < 32);
586 is_valid = is_valid && (mii_v3.mii_information.favorite_color < 12);
587 is_valid = is_valid && (mii_v3.height < 128);
588 is_valid = is_valid && (mii_v3.build < 128);
589
590 is_valid = is_valid && (mii_v3.appearance_bits1.face_shape < 12);
591 is_valid = is_valid && (mii_v3.appearance_bits1.skin_color < 7);
592 is_valid = is_valid && (mii_v3.appearance_bits2.wrinkles < 12);
593 is_valid = is_valid && (mii_v3.appearance_bits2.makeup < 12);
594
595 is_valid = is_valid && (mii_v3.hair_style < 132);
596 is_valid = is_valid && (mii_v3.appearance_bits3.hair_color < 8);
597
598 is_valid = is_valid && (mii_v3.appearance_bits4.eye_type < 60);
599 is_valid = is_valid && (mii_v3.appearance_bits4.eye_color < 6);
600 is_valid = is_valid && (mii_v3.appearance_bits4.eye_scale < 8);
601 is_valid = is_valid && (mii_v3.appearance_bits4.eye_vertical_stretch < 7);
602 is_valid = is_valid && (mii_v3.appearance_bits4.eye_rotation < 8);
603 is_valid = is_valid && (mii_v3.appearance_bits4.eye_spacing < 13);
604 is_valid = is_valid && (mii_v3.appearance_bits4.eye_y_position < 19);
605
606 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_style < 25);
607 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_color < 8);
608 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_scale < 9);
609 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_yscale < 7);
610 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_rotation < 12);
611 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_spacing < 12);
612 is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_y_position < 19);
613
614 is_valid = is_valid && (mii_v3.appearance_bits6.nose_type < 18);
615 is_valid = is_valid && (mii_v3.appearance_bits6.nose_scale < 9);
616 is_valid = is_valid && (mii_v3.appearance_bits6.nose_y_position < 19);
617
618 is_valid = is_valid && (mii_v3.appearance_bits7.mouth_type < 36);
619 is_valid = is_valid && (mii_v3.appearance_bits7.mouth_color < 5);
620 is_valid = is_valid && (mii_v3.appearance_bits7.mouth_scale < 9);
621 is_valid = is_valid && (mii_v3.appearance_bits7.mouth_horizontal_stretch < 7);
622 is_valid = is_valid && (mii_v3.appearance_bits8.mouth_y_position < 19);
623
624 is_valid = is_valid && (mii_v3.appearance_bits8.mustache_type < 6);
625 is_valid = is_valid && (mii_v3.appearance_bits9.mustache_scale < 7);
626 is_valid = is_valid && (mii_v3.appearance_bits9.mustache_y_position < 17);
627
628 is_valid = is_valid && (mii_v3.appearance_bits9.bear_type < 6);
629 is_valid = is_valid && (mii_v3.appearance_bits9.facial_hair_color < 8);
630
631 is_valid = is_valid && (mii_v3.appearance_bits10.glasses_type < 9);
632 is_valid = is_valid && (mii_v3.appearance_bits10.glasses_color < 6);
633 is_valid = is_valid && (mii_v3.appearance_bits10.glasses_scale < 8);
634 is_valid = is_valid && (mii_v3.appearance_bits10.glasses_y_position < 21);
635
636 is_valid = is_valid && (mii_v3.appearance_bits11.mole_enabled < 2);
637 is_valid = is_valid && (mii_v3.appearance_bits11.mole_scale < 9);
638 is_valid = is_valid && (mii_v3.appearance_bits11.mole_x_position < 17);
639 is_valid = is_valid && (mii_v3.appearance_bits11.mole_y_position < 31);
640
641 return is_valid;
642}
643
644std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) { 415std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) {
645 std::vector<CharInfoElement> result; 416 std::vector<CharInfoElement> result;
646 417
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:
27 CharInfo BuildBase(Gender gender); 27 CharInfo BuildBase(Gender gender);
28 CharInfo BuildDefault(std::size_t index); 28 CharInfo BuildDefault(std::size_t index);
29 CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const; 29 CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const;
30 bool ValidateV3Info(const Ver3StoreData& mii_v3) const;
31 std::vector<CharInfoElement> GetDefault(SourceFlag source_flag); 30 std::vector<CharInfoElement> GetDefault(SourceFlag source_flag);
32 Result GetIndex(const CharInfo& info, u32& index); 31 Result GetIndex(const CharInfo& info, u32& index);
33 32
34 // This is nn::mii::detail::Ver::StoreDataRaw::BuildFromStoreData
35 Ver3StoreData BuildFromStoreData(const CharInfo& mii) const;
36
37 // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData 33 // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData
38 NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const; 34 NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const;
39 35
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 @@
8namespace Service::Mii { 8namespace Service::Mii {
9 9
10// This is nn::mii::detail::CharInfoRaw 10// This is nn::mii::detail::CharInfoRaw
11struct CharInfo { 11class CharInfo {
12public:
12 Common::UUID create_id; 13 Common::UUID create_id;
13 Nickname name; 14 Nickname name;
14 u16 null_terminator; 15 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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
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"
5#include "core/hle/service/mii/types/char_info.h"
6#include "core/hle/service/mii/types/raw_data.h"
7#include "core/hle/service/mii/types/store_data.h"
4#include "core/hle/service/mii/types/ver3_store_data.h" 8#include "core/hle/service/mii/types/ver3_store_data.h"
5 9
6namespace Service::Mii {} // namespace Service::Mii 10namespace Service::Mii {
11
12void Ver3StoreData::BuildToStoreData(CharInfo& out_char_info) const {
13 if (!IsValid()) {
14 return;
15 }
16
17 // TODO: We are ignoring a bunch of data from the mii_v3
18
19 out_char_info.gender = static_cast<u8>(mii_information.gender);
20 out_char_info.favorite_color = static_cast<u8>(mii_information.favorite_color);
21 out_char_info.height = height;
22 out_char_info.build = build;
23
24 // Copy name until string terminator
25 out_char_info.name = {};
26 for (std::size_t index = 0; index < out_char_info.name.size() - 1; index++) {
27 out_char_info.name[index] = mii_name[index];
28 if (out_char_info.name[index] == 0) {
29 break;
30 }
31 }
32
33 out_char_info.font_region = region_information.character_set;
34
35 out_char_info.faceline_type = appearance_bits1.face_shape;
36 out_char_info.faceline_color = appearance_bits1.skin_color;
37 out_char_info.faceline_wrinkle = appearance_bits2.wrinkles;
38 out_char_info.faceline_make = appearance_bits2.makeup;
39
40 out_char_info.hair_type = hair_style;
41 out_char_info.hair_color = appearance_bits3.hair_color;
42 out_char_info.hair_flip = appearance_bits3.flip_hair;
43
44 out_char_info.eye_type = static_cast<u8>(appearance_bits4.eye_type);
45 out_char_info.eye_color = static_cast<u8>(appearance_bits4.eye_color);
46 out_char_info.eye_scale = static_cast<u8>(appearance_bits4.eye_scale);
47 out_char_info.eye_aspect = static_cast<u8>(appearance_bits4.eye_vertical_stretch);
48 out_char_info.eye_rotate = static_cast<u8>(appearance_bits4.eye_rotation);
49 out_char_info.eye_x = static_cast<u8>(appearance_bits4.eye_spacing);
50 out_char_info.eye_y = static_cast<u8>(appearance_bits4.eye_y_position);
51
52 out_char_info.eyebrow_type = static_cast<u8>(appearance_bits5.eyebrow_style);
53 out_char_info.eyebrow_color = static_cast<u8>(appearance_bits5.eyebrow_color);
54 out_char_info.eyebrow_scale = static_cast<u8>(appearance_bits5.eyebrow_scale);
55 out_char_info.eyebrow_aspect = static_cast<u8>(appearance_bits5.eyebrow_yscale);
56 out_char_info.eyebrow_rotate = static_cast<u8>(appearance_bits5.eyebrow_rotation);
57 out_char_info.eyebrow_x = static_cast<u8>(appearance_bits5.eyebrow_spacing);
58 out_char_info.eyebrow_y = static_cast<u8>(appearance_bits5.eyebrow_y_position);
59
60 out_char_info.nose_type = static_cast<u8>(appearance_bits6.nose_type);
61 out_char_info.nose_scale = static_cast<u8>(appearance_bits6.nose_scale);
62 out_char_info.nose_y = static_cast<u8>(appearance_bits6.nose_y_position);
63
64 out_char_info.mouth_type = static_cast<u8>(appearance_bits7.mouth_type);
65 out_char_info.mouth_color = static_cast<u8>(appearance_bits7.mouth_color);
66 out_char_info.mouth_scale = static_cast<u8>(appearance_bits7.mouth_scale);
67 out_char_info.mouth_aspect = static_cast<u8>(appearance_bits7.mouth_horizontal_stretch);
68 out_char_info.mouth_y = static_cast<u8>(appearance_bits8.mouth_y_position);
69
70 out_char_info.mustache_type = static_cast<u8>(appearance_bits8.mustache_type);
71 out_char_info.mustache_scale = static_cast<u8>(appearance_bits9.mustache_scale);
72 out_char_info.mustache_y = static_cast<u8>(appearance_bits9.mustache_y_position);
73
74 out_char_info.beard_type = static_cast<u8>(appearance_bits9.bear_type);
75 out_char_info.beard_color = static_cast<u8>(appearance_bits9.facial_hair_color);
76
77 out_char_info.glasses_type = static_cast<u8>(appearance_bits10.glasses_type);
78 out_char_info.glasses_color = static_cast<u8>(appearance_bits10.glasses_color);
79 out_char_info.glasses_scale = static_cast<u8>(appearance_bits10.glasses_scale);
80 out_char_info.glasses_y = static_cast<u8>(appearance_bits10.glasses_y_position);
81
82 out_char_info.mole_type = static_cast<u8>(appearance_bits11.mole_enabled);
83 out_char_info.mole_scale = static_cast<u8>(appearance_bits11.mole_scale);
84 out_char_info.mole_x = static_cast<u8>(appearance_bits11.mole_x_position);
85 out_char_info.mole_y = static_cast<u8>(appearance_bits11.mole_y_position);
86}
87
88void Ver3StoreData::BuildFromStoreData(const CharInfo& char_info) {
89 version = 1;
90 mii_information.gender.Assign(char_info.gender);
91 mii_information.favorite_color.Assign(char_info.favorite_color);
92 height = char_info.height;
93 build = char_info.build;
94
95 // Copy name until string terminator
96 mii_name = {};
97 for (std::size_t index = 0; index < char_info.name.size() - 1; index++) {
98 mii_name[index] = char_info.name[index];
99 if (mii_name[index] == 0) {
100 break;
101 }
102 }
103
104 region_information.character_set.Assign(char_info.font_region);
105
106 appearance_bits1.face_shape.Assign(char_info.faceline_type);
107 appearance_bits2.wrinkles.Assign(char_info.faceline_wrinkle);
108 appearance_bits2.makeup.Assign(char_info.faceline_make);
109
110 hair_style = char_info.hair_type;
111 appearance_bits3.flip_hair.Assign(char_info.hair_flip);
112
113 appearance_bits4.eye_type.Assign(char_info.eye_type);
114 appearance_bits4.eye_scale.Assign(char_info.eye_scale);
115 appearance_bits4.eye_vertical_stretch.Assign(char_info.eye_aspect);
116 appearance_bits4.eye_rotation.Assign(char_info.eye_rotate);
117 appearance_bits4.eye_spacing.Assign(char_info.eye_x);
118 appearance_bits4.eye_y_position.Assign(char_info.eye_y);
119
120 appearance_bits5.eyebrow_style.Assign(char_info.eyebrow_type);
121 appearance_bits5.eyebrow_scale.Assign(char_info.eyebrow_scale);
122 appearance_bits5.eyebrow_yscale.Assign(char_info.eyebrow_aspect);
123 appearance_bits5.eyebrow_rotation.Assign(char_info.eyebrow_rotate);
124 appearance_bits5.eyebrow_spacing.Assign(char_info.eyebrow_x);
125 appearance_bits5.eyebrow_y_position.Assign(char_info.eyebrow_y);
126
127 appearance_bits6.nose_type.Assign(char_info.nose_type);
128 appearance_bits6.nose_scale.Assign(char_info.nose_scale);
129 appearance_bits6.nose_y_position.Assign(char_info.nose_y);
130
131 appearance_bits7.mouth_type.Assign(char_info.mouth_type);
132 appearance_bits7.mouth_scale.Assign(char_info.mouth_scale);
133 appearance_bits7.mouth_horizontal_stretch.Assign(char_info.mouth_aspect);
134 appearance_bits8.mouth_y_position.Assign(char_info.mouth_y);
135
136 appearance_bits8.mustache_type.Assign(char_info.mustache_type);
137 appearance_bits9.mustache_scale.Assign(char_info.mustache_scale);
138 appearance_bits9.mustache_y_position.Assign(char_info.mustache_y);
139
140 appearance_bits9.bear_type.Assign(char_info.beard_type);
141
142 appearance_bits10.glasses_scale.Assign(char_info.glasses_scale);
143 appearance_bits10.glasses_y_position.Assign(char_info.glasses_y);
144
145 appearance_bits11.mole_enabled.Assign(char_info.mole_type);
146 appearance_bits11.mole_scale.Assign(char_info.mole_scale);
147 appearance_bits11.mole_x_position.Assign(char_info.mole_x);
148 appearance_bits11.mole_y_position.Assign(char_info.mole_y);
149
150 // These types are converted to V3 from a table
151 appearance_bits1.skin_color.Assign(RawData::FromVer3GetFacelineColor(char_info.faceline_color));
152 appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(char_info.hair_color));
153 appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(char_info.eye_color));
154 appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(char_info.eyebrow_color));
155 appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(char_info.mouth_color));
156 appearance_bits9.facial_hair_color.Assign(RawData::FromVer3GetHairColor(char_info.beard_color));
157 appearance_bits10.glasses_color.Assign(RawData::FromVer3GetGlassColor(char_info.glasses_color));
158 appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(char_info.glasses_type));
159
160 crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16));
161}
162
163u32 Ver3StoreData::IsValid() const {
164 bool is_valid = version == 0 || version == 3;
165
166 is_valid = is_valid && (mii_name[0] != 0);
167
168 is_valid = is_valid && (mii_information.birth_month < 13);
169 is_valid = is_valid && (mii_information.birth_day < 32);
170 is_valid = is_valid && (mii_information.favorite_color < 12);
171 is_valid = is_valid && (height < 128);
172 is_valid = is_valid && (build < 128);
173
174 is_valid = is_valid && (appearance_bits1.face_shape < 12);
175 is_valid = is_valid && (appearance_bits1.skin_color < 7);
176 is_valid = is_valid && (appearance_bits2.wrinkles < 12);
177 is_valid = is_valid && (appearance_bits2.makeup < 12);
178
179 is_valid = is_valid && (hair_style < 132);
180 is_valid = is_valid && (appearance_bits3.hair_color < 8);
181
182 is_valid = is_valid && (appearance_bits4.eye_type < 60);
183 is_valid = is_valid && (appearance_bits4.eye_color < 6);
184 is_valid = is_valid && (appearance_bits4.eye_scale < 8);
185 is_valid = is_valid && (appearance_bits4.eye_vertical_stretch < 7);
186 is_valid = is_valid && (appearance_bits4.eye_rotation < 8);
187 is_valid = is_valid && (appearance_bits4.eye_spacing < 13);
188 is_valid = is_valid && (appearance_bits4.eye_y_position < 19);
189
190 is_valid = is_valid && (appearance_bits5.eyebrow_style < 25);
191 is_valid = is_valid && (appearance_bits5.eyebrow_color < 8);
192 is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9);
193 is_valid = is_valid && (appearance_bits5.eyebrow_yscale < 7);
194 is_valid = is_valid && (appearance_bits5.eyebrow_rotation < 12);
195 is_valid = is_valid && (appearance_bits5.eyebrow_spacing < 12);
196 is_valid = is_valid && (appearance_bits5.eyebrow_y_position < 19);
197
198 is_valid = is_valid && (appearance_bits6.nose_type < 18);
199 is_valid = is_valid && (appearance_bits6.nose_scale < 9);
200 is_valid = is_valid && (appearance_bits6.nose_y_position < 19);
201
202 is_valid = is_valid && (appearance_bits7.mouth_type < 36);
203 is_valid = is_valid && (appearance_bits7.mouth_color < 5);
204 is_valid = is_valid && (appearance_bits7.mouth_scale < 9);
205 is_valid = is_valid && (appearance_bits7.mouth_horizontal_stretch < 7);
206 is_valid = is_valid && (appearance_bits8.mouth_y_position < 19);
207
208 is_valid = is_valid && (appearance_bits8.mustache_type < 6);
209 is_valid = is_valid && (appearance_bits9.mustache_scale < 7);
210 is_valid = is_valid && (appearance_bits9.mustache_y_position < 17);
211
212 is_valid = is_valid && (appearance_bits9.bear_type < 6);
213 is_valid = is_valid && (appearance_bits9.facial_hair_color < 8);
214
215 is_valid = is_valid && (appearance_bits10.glasses_type < 9);
216 is_valid = is_valid && (appearance_bits10.glasses_color < 6);
217 is_valid = is_valid && (appearance_bits10.glasses_scale < 8);
218 is_valid = is_valid && (appearance_bits10.glasses_y_position < 21);
219
220 is_valid = is_valid && (appearance_bits11.mole_enabled < 2);
221 is_valid = is_valid && (appearance_bits11.mole_scale < 9);
222 is_valid = is_valid && (appearance_bits11.mole_x_position < 17);
223 is_valid = is_valid && (appearance_bits11.mole_y_position < 31);
224
225 return is_valid;
226}
227
228} // 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 @@
4#pragma once 4#pragma once
5 5
6#include "core/hle/service/mii/mii_types.h" 6#include "core/hle/service/mii/mii_types.h"
7#include "core/hle/service/mii/types/core_data.h"
8#include "core/hle/service/mii/types/store_data.h"
9 7
10namespace Service::Mii { 8namespace Service::Mii {
9class CharInfo;
11 10
12// This is nn::mii::Ver3StoreData 11// This is nn::mii::Ver3StoreData
13// Based on citra HLE::Applets::MiiData and PretendoNetwork. 12// Based on citra HLE::Applets::MiiData and PretendoNetwork.
@@ -15,7 +14,15 @@ namespace Service::Mii {
15// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 14// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299
16 15
17#pragma pack(push, 4) 16#pragma pack(push, 4)
18struct Ver3StoreData { 17class Ver3StoreData {
18public:
19 // TODO: This function is wrong. It should use StoreData.
20 void BuildToStoreData(CharInfo& out_char_info) const;
21 // TODO: This function is wrong. It should use StoreData.
22 void BuildFromStoreData(const CharInfo& char_info);
23
24 u32 IsValid() const;
25
19 u8 version; 26 u8 version;
20 union { 27 union {
21 u8 raw; 28 u8 raw;