diff options
| author | 2023-09-10 22:42:38 -0600 | |
|---|---|---|
| committer | 2023-09-10 22:42:38 -0600 | |
| commit | 8d7d62dc24b0788b6158fd6b3bd5bce6a6969a8c (patch) | |
| tree | 6ea7d5f1e5d3cf29bf8abcd16bbb30bf71ec3419 /src/core/hle/service/mii | |
| parent | service: mii: separate mii types into their own file (diff) | |
| download | yuzu-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.cpp | 235 | ||||
| -rw-r--r-- | src/core/hle/service/mii/mii_manager.h | 4 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/char_info.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/ver3_store_data.cpp | 224 | ||||
| -rw-r--r-- | src/core/hle/service/mii/types/ver3_store_data.h | 13 |
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 | ||
| 396 | CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { | 396 | CharInfo 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 | |||
| 479 | Ver3StoreData 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 | ||
| 566 | NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { | 402 | NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { |
| @@ -576,71 +412,6 @@ NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const { | |||
| 576 | }; | 412 | }; |
| 577 | } | 413 | } |
| 578 | 414 | ||
| 579 | bool 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 | |||
| 644 | std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) { | 415 | std::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 @@ | |||
| 8 | namespace Service::Mii { | 8 | namespace Service::Mii { |
| 9 | 9 | ||
| 10 | // This is nn::mii::detail::CharInfoRaw | 10 | // This is nn::mii::detail::CharInfoRaw |
| 11 | struct CharInfo { | 11 | class CharInfo { |
| 12 | public: | ||
| 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 | ||
| 6 | namespace Service::Mii {} // namespace Service::Mii | 10 | namespace Service::Mii { |
| 11 | |||
| 12 | void 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 | |||
| 88 | void 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 | |||
| 163 | u32 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 | ||
| 10 | namespace Service::Mii { | 8 | namespace Service::Mii { |
| 9 | class 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) |
| 18 | struct Ver3StoreData { | 17 | class Ver3StoreData { |
| 18 | public: | ||
| 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; |