Browse Source
Merge pull request #11480 from german77/mii_service
Merge pull request #11480 from german77/mii_service
service: mii: Update implementation Part1pull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 4466 additions and 1943 deletions
-
16src/core/CMakeLists.txt
-
11src/core/hle/service/am/applets/applet_mii_edit.cpp
-
3src/core/hle/service/am/applets/applet_mii_edit_types.h
-
139src/core/hle/service/mii/mii.cpp
-
717src/core/hle/service/mii/mii_manager.cpp
-
43src/core/hle/service/mii/mii_manager.h
-
20src/core/hle/service/mii/mii_result.h
-
694src/core/hle/service/mii/mii_types.h
-
59src/core/hle/service/mii/mii_util.h
-
27src/core/hle/service/mii/raw_data.h
-
553src/core/hle/service/mii/types.h
-
482src/core/hle/service/mii/types/char_info.cpp
-
137src/core/hle/service/mii/types/char_info.h
-
601src/core/hle/service/mii/types/core_data.cpp
-
216src/core/hle/service/mii/types/core_data.h
-
1395src/core/hle/service/mii/types/raw_data.cpp
-
73src/core/hle/service/mii/types/raw_data.h
-
643src/core/hle/service/mii/types/store_data.cpp
-
145src/core/hle/service/mii/types/store_data.h
-
241src/core/hle/service/mii/types/ver3_store_data.cpp
-
160src/core/hle/service/mii/types/ver3_store_data.h
-
25src/core/hle/service/nfc/common/device.cpp
-
6src/core/hle/service/nfp/nfp_types.h
-
3src/yuzu/applets/qt_amiibo_settings.cpp
@ -0,0 +1,20 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/result.h" |
|||
|
|||
namespace Service::Mii { |
|||
|
|||
constexpr Result ResultInvalidArgument{ErrorModule::Mii, 1}; |
|||
constexpr Result ResultInvalidArgumentSize{ErrorModule::Mii, 2}; |
|||
constexpr Result ResultNotUpdated{ErrorModule::Mii, 3}; |
|||
constexpr Result ResultNotFound{ErrorModule::Mii, 4}; |
|||
constexpr Result ResultDatabaseFull{ErrorModule::Mii, 5}; |
|||
constexpr Result ResultInvalidCharInfo{ErrorModule::Mii, 100}; |
|||
constexpr Result ResultInvalidStoreData{ErrorModule::Mii, 109}; |
|||
constexpr Result ResultInvalidOperation{ErrorModule::Mii, 202}; |
|||
constexpr Result ResultPermissionDenied{ErrorModule::Mii, 203}; |
|||
|
|||
}; // namespace Service::Mii |
|||
@ -0,0 +1,694 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <type_traits> |
|||
|
|||
#include "common/bit_field.h" |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/uuid.h" |
|||
|
|||
namespace Service::Mii { |
|||
|
|||
constexpr u8 MaxHeight = 127; |
|||
constexpr u8 MaxBuild = 127; |
|||
constexpr u8 MaxType = 1; |
|||
constexpr u8 MaxRegionMove = 3; |
|||
constexpr u8 MaxEyeScale = 7; |
|||
constexpr u8 MaxEyeAspect = 6; |
|||
constexpr u8 MaxEyeRotate = 7; |
|||
constexpr u8 MaxEyeX = 12; |
|||
constexpr u8 MaxEyeY = 18; |
|||
constexpr u8 MaxEyebrowScale = 8; |
|||
constexpr u8 MaxEyebrowAspect = 6; |
|||
constexpr u8 MaxEyebrowRotate = 11; |
|||
constexpr u8 MaxEyebrowX = 12; |
|||
constexpr u8 MaxEyebrowY = 18; |
|||
constexpr u8 MaxNoseScale = 8; |
|||
constexpr u8 MaxNoseY = 18; |
|||
constexpr u8 MaxMouthScale = 8; |
|||
constexpr u8 MaxMoutAspect = 6; |
|||
constexpr u8 MaxMouthY = 18; |
|||
constexpr u8 MaxMustacheScale = 8; |
|||
constexpr u8 MasMustacheY = 16; |
|||
constexpr u8 MaxGlassScale = 7; |
|||
constexpr u8 MaxGlassY = 20; |
|||
constexpr u8 MaxMoleScale = 8; |
|||
constexpr u8 MaxMoleX = 16; |
|||
constexpr u8 MaxMoleY = 30; |
|||
constexpr u8 MaxVer3CommonColor = 7; |
|||
constexpr u8 MaxVer3GlassType = 8; |
|||
|
|||
enum class Age : u8 { |
|||
Young, |
|||
Normal, |
|||
Old, |
|||
All, // Default |
|||
|
|||
Max = All, |
|||
}; |
|||
|
|||
enum class Gender : u8 { |
|||
Male, |
|||
Female, |
|||
All, // Default |
|||
|
|||
Max = Female, |
|||
}; |
|||
|
|||
enum class Race : u8 { |
|||
Black, |
|||
White, |
|||
Asian, |
|||
All, // Default |
|||
|
|||
Max = All, |
|||
}; |
|||
|
|||
enum class HairType : u8 { |
|||
NormalLong, // Default |
|||
NormalShort, |
|||
NormalMedium, |
|||
NormalExtraLong, |
|||
NormalLongBottom, |
|||
NormalTwoPeaks, |
|||
PartingLong, |
|||
FrontLock, |
|||
PartingShort, |
|||
PartingExtraLongCurved, |
|||
PartingExtraLong, |
|||
PartingMiddleLong, |
|||
PartingSquared, |
|||
PartingLongBottom, |
|||
PeaksTop, |
|||
PeaksSquared, |
|||
PartingPeaks, |
|||
PeaksLongBottom, |
|||
Peaks, |
|||
PeaksRounded, |
|||
PeaksSide, |
|||
PeaksMedium, |
|||
PeaksLong, |
|||
PeaksRoundedLong, |
|||
PartingFrontPeaks, |
|||
PartingLongFront, |
|||
PartingLongRounded, |
|||
PartingFrontPeaksLong, |
|||
PartingExtraLongRounded, |
|||
LongRounded, |
|||
NormalUnknown1, |
|||
NormalUnknown2, |
|||
NormalUnknown3, |
|||
NormalUnknown4, |
|||
NormalUnknown5, |
|||
NormalUnknown6, |
|||
DreadLocks, |
|||
PlatedMats, |
|||
Caps, |
|||
Afro, |
|||
PlatedMatsLong, |
|||
Beanie, |
|||
Short, |
|||
ShortTopLongSide, |
|||
ShortUnknown1, |
|||
ShortUnknown2, |
|||
MilitaryParting, |
|||
Military, |
|||
ShortUnknown3, |
|||
ShortUnknown4, |
|||
ShortUnknown5, |
|||
ShortUnknown6, |
|||
NoneTop, |
|||
None, |
|||
LongUnknown1, |
|||
LongUnknown2, |
|||
LongUnknown3, |
|||
LongUnknown4, |
|||
LongUnknown5, |
|||
LongUnknown6, |
|||
LongUnknown7, |
|||
LongUnknown8, |
|||
LongUnknown9, |
|||
LongUnknown10, |
|||
LongUnknown11, |
|||
LongUnknown12, |
|||
LongUnknown13, |
|||
LongUnknown14, |
|||
LongUnknown15, |
|||
LongUnknown16, |
|||
LongUnknown17, |
|||
LongUnknown18, |
|||
LongUnknown19, |
|||
LongUnknown20, |
|||
LongUnknown21, |
|||
LongUnknown22, |
|||
LongUnknown23, |
|||
LongUnknown24, |
|||
LongUnknown25, |
|||
LongUnknown26, |
|||
LongUnknown27, |
|||
LongUnknown28, |
|||
LongUnknown29, |
|||
LongUnknown30, |
|||
LongUnknown31, |
|||
LongUnknown32, |
|||
LongUnknown33, |
|||
LongUnknown34, |
|||
LongUnknown35, |
|||
LongUnknown36, |
|||
LongUnknown37, |
|||
LongUnknown38, |
|||
LongUnknown39, |
|||
LongUnknown40, |
|||
LongUnknown41, |
|||
LongUnknown42, |
|||
LongUnknown43, |
|||
LongUnknown44, |
|||
LongUnknown45, |
|||
LongUnknown46, |
|||
LongUnknown47, |
|||
LongUnknown48, |
|||
LongUnknown49, |
|||
LongUnknown50, |
|||
LongUnknown51, |
|||
LongUnknown52, |
|||
LongUnknown53, |
|||
LongUnknown54, |
|||
LongUnknown55, |
|||
LongUnknown56, |
|||
LongUnknown57, |
|||
LongUnknown58, |
|||
LongUnknown59, |
|||
LongUnknown60, |
|||
LongUnknown61, |
|||
LongUnknown62, |
|||
LongUnknown63, |
|||
LongUnknown64, |
|||
LongUnknown65, |
|||
LongUnknown66, |
|||
TwoMediumFrontStrandsOneLongBackPonyTail, |
|||
TwoFrontStrandsLongBackPonyTail, |
|||
PartingFrontTwoLongBackPonyTails, |
|||
TwoFrontStrandsOneLongBackPonyTail, |
|||
LongBackPonyTail, |
|||
LongFrontTwoLongBackPonyTails, |
|||
StrandsTwoShortSidedPonyTails, |
|||
TwoMediumSidedPonyTails, |
|||
ShortFrontTwoBackPonyTails, |
|||
TwoShortSidedPonyTails, |
|||
TwoLongSidedPonyTails, |
|||
LongFrontTwoBackPonyTails, |
|||
|
|||
Max = LongFrontTwoBackPonyTails, |
|||
}; |
|||
|
|||
enum class MoleType : u8 { |
|||
None, // Default |
|||
OneDot, |
|||
|
|||
Max = OneDot, |
|||
}; |
|||
|
|||
enum class HairFlip : u8 { |
|||
Left, // Default |
|||
Right, |
|||
|
|||
Max = Right, |
|||
}; |
|||
|
|||
enum class CommonColor : u8 { |
|||
// For simplicity common colors aren't listed |
|||
Max = 99, |
|||
Count = 100, |
|||
}; |
|||
|
|||
enum class FavoriteColor : u8 { |
|||
Red, // Default |
|||
Orange, |
|||
Yellow, |
|||
LimeGreen, |
|||
Green, |
|||
Blue, |
|||
LightBlue, |
|||
Pink, |
|||
Purple, |
|||
Brown, |
|||
White, |
|||
Black, |
|||
|
|||
Max = Black, |
|||
}; |
|||
|
|||
enum class EyeType : u8 { |
|||
Normal, // Default |
|||
NormalLash, |
|||
WhiteLash, |
|||
WhiteNoBottom, |
|||
OvalAngledWhite, |
|||
AngryWhite, |
|||
DotLashType1, |
|||
Line, |
|||
DotLine, |
|||
OvalWhite, |
|||
RoundedWhite, |
|||
NormalShadow, |
|||
CircleWhite, |
|||
Circle, |
|||
CircleWhiteStroke, |
|||
NormalOvalNoBottom, |
|||
NormalOvalLarge, |
|||
NormalRoundedNoBottom, |
|||
SmallLash, |
|||
Small, |
|||
TwoSmall, |
|||
NormalLongLash, |
|||
WhiteTwoLashes, |
|||
WhiteThreeLashes, |
|||
DotAngry, |
|||
DotAngled, |
|||
Oval, |
|||
SmallWhite, |
|||
WhiteAngledNoBottom, |
|||
WhiteAngledNoLeft, |
|||
SmallWhiteTwoLashes, |
|||
LeafWhiteLash, |
|||
WhiteLargeNoBottom, |
|||
Dot, |
|||
DotLashType2, |
|||
DotThreeLashes, |
|||
WhiteOvalTop, |
|||
WhiteOvalBottom, |
|||
WhiteOvalBottomFlat, |
|||
WhiteOvalTwoLashes, |
|||
WhiteOvalThreeLashes, |
|||
WhiteOvalNoBottomTwoLashes, |
|||
DotWhite, |
|||
WhiteOvalTopFlat, |
|||
WhiteThinLeaf, |
|||
StarThreeLashes, |
|||
LineTwoLashes, |
|||
CrowsFeet, |
|||
WhiteNoBottomFlat, |
|||
WhiteNoBottomRounded, |
|||
WhiteSmallBottomLine, |
|||
WhiteNoBottomLash, |
|||
WhiteNoPartialBottomLash, |
|||
WhiteOvalBottomLine, |
|||
WhiteNoBottomLashTopLine, |
|||
WhiteNoPartialBottomTwoLashes, |
|||
NormalTopLine, |
|||
WhiteOvalLash, |
|||
RoundTired, |
|||
WhiteLarge, |
|||
|
|||
Max = WhiteLarge, |
|||
}; |
|||
|
|||
enum class MouthType : u8 { |
|||
Neutral, // Default |
|||
NeutralLips, |
|||
Smile, |
|||
SmileStroke, |
|||
SmileTeeth, |
|||
LipsSmall, |
|||
LipsLarge, |
|||
Wave, |
|||
WaveAngrySmall, |
|||
NeutralStrokeLarge, |
|||
TeethSurprised, |
|||
LipsExtraLarge, |
|||
LipsUp, |
|||
NeutralDown, |
|||
Surprised, |
|||
TeethMiddle, |
|||
NeutralStroke, |
|||
LipsExtraSmall, |
|||
Malicious, |
|||
LipsDual, |
|||
NeutralComma, |
|||
NeutralUp, |
|||
TeethLarge, |
|||
WaveAngry, |
|||
LipsSexy, |
|||
SmileInverted, |
|||
LipsSexyOutline, |
|||
SmileRounded, |
|||
LipsTeeth, |
|||
NeutralOpen, |
|||
TeethRounded, |
|||
WaveAngrySmallInverted, |
|||
NeutralCommaInverted, |
|||
TeethFull, |
|||
SmileDownLine, |
|||
Kiss, |
|||
|
|||
Max = Kiss, |
|||
}; |
|||
|
|||
enum class FontRegion : u8 { |
|||
Standard, // Default |
|||
China, |
|||
Korea, |
|||
Taiwan, |
|||
|
|||
Max = Taiwan, |
|||
}; |
|||
|
|||
enum class FacelineType : u8 { |
|||
Sharp, // Default |
|||
Rounded, |
|||
SharpRounded, |
|||
SharpRoundedSmall, |
|||
Large, |
|||
LargeRounded, |
|||
SharpSmall, |
|||
Flat, |
|||
Bump, |
|||
Angular, |
|||
FlatRounded, |
|||
AngularSmall, |
|||
|
|||
Max = AngularSmall, |
|||
}; |
|||
|
|||
enum class FacelineColor : u8 { |
|||
Beige, // Default |
|||
WarmBeige, |
|||
Natural, |
|||
Honey, |
|||
Chestnut, |
|||
Porcelain, |
|||
Ivory, |
|||
WarmIvory, |
|||
Almond, |
|||
Espresso, |
|||
|
|||
Max = Espresso, |
|||
Count = Max + 1, |
|||
}; |
|||
|
|||
enum class FacelineWrinkle : u8 { |
|||
None, // Default |
|||
TearTroughs, |
|||
FacialPain, |
|||
Cheeks, |
|||
Folds, |
|||
UnderTheEyes, |
|||
SplitChin, |
|||
Chin, |
|||
BrowDroop, |
|||
MouthFrown, |
|||
CrowsFeet, |
|||
FoldsCrowsFrown, |
|||
|
|||
Max = FoldsCrowsFrown, |
|||
}; |
|||
|
|||
enum class FacelineMake : u8 { |
|||
None, // Default |
|||
CheekPorcelain, |
|||
CheekNatural, |
|||
EyeShadowBlue, |
|||
CheekBlushPorcelain, |
|||
CheekBlushNatural, |
|||
CheekPorcelainEyeShadowBlue, |
|||
CheekPorcelainEyeShadowNatural, |
|||
CheekBlushPorcelainEyeShadowEspresso, |
|||
Freckles, |
|||
LionsManeBeard, |
|||
StubbleBeard, |
|||
|
|||
Max = StubbleBeard, |
|||
}; |
|||
|
|||
enum class EyebrowType : u8 { |
|||
FlatAngledLarge, // Default |
|||
LowArchRoundedThin, |
|||
SoftAngledLarge, |
|||
MediumArchRoundedThin, |
|||
RoundedMedium, |
|||
LowArchMedium, |
|||
RoundedThin, |
|||
UpThin, |
|||
MediumArchRoundedMedium, |
|||
RoundedLarge, |
|||
UpLarge, |
|||
FlatAngledLargeInverted, |
|||
MediumArchFlat, |
|||
AngledThin, |
|||
HorizontalLarge, |
|||
HighArchFlat, |
|||
Flat, |
|||
MediumArchLarge, |
|||
LowArchThin, |
|||
RoundedThinInverted, |
|||
HighArchLarge, |
|||
Hairy, |
|||
Dotted, |
|||
None, |
|||
|
|||
Max = None, |
|||
}; |
|||
|
|||
enum class NoseType : u8 { |
|||
Normal, // Default |
|||
Rounded, |
|||
Dot, |
|||
Arrow, |
|||
Roman, |
|||
Triangle, |
|||
Button, |
|||
RoundedInverted, |
|||
Potato, |
|||
Grecian, |
|||
Snub, |
|||
Aquiline, |
|||
ArrowLeft, |
|||
RoundedLarge, |
|||
Hooked, |
|||
Fat, |
|||
Droopy, |
|||
ArrowLarge, |
|||
|
|||
Max = ArrowLarge, |
|||
}; |
|||
|
|||
enum class BeardType : u8 { |
|||
None, |
|||
Goatee, |
|||
GoateeLong, |
|||
LionsManeLong, |
|||
LionsMane, |
|||
Full, |
|||
|
|||
Min = Goatee, |
|||
Max = Full, |
|||
}; |
|||
|
|||
enum class MustacheType : u8 { |
|||
None, |
|||
Walrus, |
|||
Pencil, |
|||
Horseshoe, |
|||
Normal, |
|||
Toothbrush, |
|||
|
|||
Min = Walrus, |
|||
Max = Toothbrush, |
|||
}; |
|||
|
|||
enum class GlassType : u8 { |
|||
None, |
|||
Oval, |
|||
Wayfarer, |
|||
Rectangle, |
|||
TopRimless, |
|||
Rounded, |
|||
Oversized, |
|||
CatEye, |
|||
Square, |
|||
BottomRimless, |
|||
SemiOpaqueRounded, |
|||
SemiOpaqueCatEye, |
|||
SemiOpaqueOval, |
|||
SemiOpaqueRectangle, |
|||
SemiOpaqueAviator, |
|||
OpaqueRounded, |
|||
OpaqueCatEye, |
|||
OpaqueOval, |
|||
OpaqueRectangle, |
|||
OpaqueAviator, |
|||
|
|||
Max = OpaqueAviator, |
|||
Count = Max + 1, |
|||
}; |
|||
|
|||
enum class BeardAndMustacheFlag : u32 { |
|||
Beard = 1, |
|||
Mustache, |
|||
All = Beard | Mustache, |
|||
}; |
|||
DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag); |
|||
|
|||
enum class Source : u32 { |
|||
Database = 0, |
|||
Default = 1, |
|||
Account = 2, |
|||
Friend = 3, |
|||
}; |
|||
|
|||
enum class SourceFlag : u32 { |
|||
None = 0, |
|||
Database = 1 << 0, |
|||
Default = 1 << 1, |
|||
}; |
|||
DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); |
|||
|
|||
enum class ValidationResult : u32 { |
|||
NoErrors = 0x0, |
|||
InvalidBeardColor = 0x1, |
|||
InvalidBeardType = 0x2, |
|||
InvalidBuild = 0x3, |
|||
InvalidEyeAspect = 0x4, |
|||
InvalidEyeColor = 0x5, |
|||
InvalidEyeRotate = 0x6, |
|||
InvalidEyeScale = 0x7, |
|||
InvalidEyeType = 0x8, |
|||
InvalidEyeX = 0x9, |
|||
InvalidEyeY = 0xa, |
|||
InvalidEyebrowAspect = 0xb, |
|||
InvalidEyebrowColor = 0xc, |
|||
InvalidEyebrowRotate = 0xd, |
|||
InvalidEyebrowScale = 0xe, |
|||
InvalidEyebrowType = 0xf, |
|||
InvalidEyebrowX = 0x10, |
|||
InvalidEyebrowY = 0x11, |
|||
InvalidFacelineColor = 0x12, |
|||
InvalidFacelineMake = 0x13, |
|||
InvalidFacelineWrinkle = 0x14, |
|||
InvalidFacelineType = 0x15, |
|||
InvalidColor = 0x16, |
|||
InvalidFont = 0x17, |
|||
InvalidGender = 0x18, |
|||
InvalidGlassColor = 0x19, |
|||
InvalidGlassScale = 0x1a, |
|||
InvalidGlassType = 0x1b, |
|||
InvalidGlassY = 0x1c, |
|||
InvalidHairColor = 0x1d, |
|||
InvalidHairFlip = 0x1e, |
|||
InvalidHairType = 0x1f, |
|||
InvalidHeight = 0x20, |
|||
InvalidMoleScale = 0x21, |
|||
InvalidMoleType = 0x22, |
|||
InvalidMoleX = 0x23, |
|||
InvalidMoleY = 0x24, |
|||
InvalidMouthAspect = 0x25, |
|||
InvalidMouthColor = 0x26, |
|||
InvalidMouthScale = 0x27, |
|||
InvalidMouthType = 0x28, |
|||
InvalidMouthY = 0x29, |
|||
InvalidMustacheScale = 0x2a, |
|||
InvalidMustacheType = 0x2b, |
|||
InvalidMustacheY = 0x2c, |
|||
InvalidNoseScale = 0x2e, |
|||
InvalidNoseType = 0x2f, |
|||
InvalidNoseY = 0x30, |
|||
InvalidRegionMove = 0x31, |
|||
InvalidCreateId = 0x32, |
|||
InvalidName = 0x33, |
|||
InvalidType = 0x35, |
|||
}; |
|||
|
|||
struct Nickname { |
|||
static constexpr std::size_t MaxNameSize = 10; |
|||
std::array<char16_t, MaxNameSize> data; |
|||
|
|||
// Checks for null, non-zero terminated or dirty strings |
|||
bool IsValid() const { |
|||
if (data[0] == 0) { |
|||
return false; |
|||
} |
|||
|
|||
if (data[MaxNameSize] != 0) { |
|||
return false; |
|||
} |
|||
std::size_t index = 1; |
|||
while (data[index] != 0) { |
|||
index++; |
|||
} |
|||
while (index < MaxNameSize && data[index] == 0) { |
|||
index++; |
|||
} |
|||
return index == MaxNameSize; |
|||
} |
|||
}; |
|||
static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size"); |
|||
|
|||
struct DefaultMii { |
|||
u32 face_type{}; |
|||
u32 face_color{}; |
|||
u32 face_wrinkle{}; |
|||
u32 face_makeup{}; |
|||
u32 hair_type{}; |
|||
u32 hair_color{}; |
|||
u32 hair_flip{}; |
|||
u32 eye_type{}; |
|||
u32 eye_color{}; |
|||
u32 eye_scale{}; |
|||
u32 eye_aspect{}; |
|||
u32 eye_rotate{}; |
|||
u32 eye_x{}; |
|||
u32 eye_y{}; |
|||
u32 eyebrow_type{}; |
|||
u32 eyebrow_color{}; |
|||
u32 eyebrow_scale{}; |
|||
u32 eyebrow_aspect{}; |
|||
u32 eyebrow_rotate{}; |
|||
u32 eyebrow_x{}; |
|||
u32 eyebrow_y{}; |
|||
u32 nose_type{}; |
|||
u32 nose_scale{}; |
|||
u32 nose_y{}; |
|||
u32 mouth_type{}; |
|||
u32 mouth_color{}; |
|||
u32 mouth_scale{}; |
|||
u32 mouth_aspect{}; |
|||
u32 mouth_y{}; |
|||
u32 mustache_type{}; |
|||
u32 beard_type{}; |
|||
u32 beard_color{}; |
|||
u32 mustache_scale{}; |
|||
u32 mustache_y{}; |
|||
u32 glasses_type{}; |
|||
u32 glasses_color{}; |
|||
u32 glasses_scale{}; |
|||
u32 glasses_y{}; |
|||
u32 mole_type{}; |
|||
u32 mole_scale{}; |
|||
u32 mole_x{}; |
|||
u32 mole_y{}; |
|||
u32 height{}; |
|||
u32 weight{}; |
|||
u32 gender{}; |
|||
u32 favorite_color{}; |
|||
u32 region_move{}; |
|||
u32 font_region{}; |
|||
u32 type{}; |
|||
Nickname nickname; |
|||
}; |
|||
static_assert(sizeof(DefaultMii) == 0xd8, "DefaultMii has incorrect size."); |
|||
|
|||
struct DatabaseSessionMetadata { |
|||
u32 interface_version; |
|||
u32 magic; |
|||
u64 update_counter; |
|||
|
|||
bool IsInterfaceVersionSupported(u32 version) const { |
|||
return version <= interface_version; |
|||
} |
|||
}; |
|||
|
|||
} // namespace Service::Mii |
|||
@ -0,0 +1,59 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <random> |
|||
#include <span> |
|||
|
|||
#include "common/common_types.h" |
|||
#include "common/swap.h" |
|||
#include "common/uuid.h" |
|||
#include "core/hle/service/mii/mii_types.h" |
|||
|
|||
namespace Service::Mii { |
|||
class MiiUtil { |
|||
public: |
|||
static u16 CalculateCrc16(const void* data, std::size_t size) { |
|||
s32 crc{}; |
|||
for (std::size_t i = 0; i < size; i++) { |
|||
crc ^= static_cast<const u8*>(data)[i] << 8; |
|||
for (std::size_t j = 0; j < 8; j++) { |
|||
crc <<= 1; |
|||
if ((crc & 0x10000) != 0) { |
|||
crc = (crc ^ 0x1021) & 0xFFFF; |
|||
} |
|||
} |
|||
} |
|||
return Common::swap16(static_cast<u16>(crc)); |
|||
} |
|||
|
|||
static Common::UUID MakeCreateId() { |
|||
return Common::UUID::MakeRandomRFC4122V4(); |
|||
} |
|||
|
|||
static Common::UUID GetDeviceId() { |
|||
// This should be nn::settings::detail::GetMiiAuthorId() |
|||
return Common::UUID::MakeDefault(); |
|||
} |
|||
|
|||
template <typename T> |
|||
static T GetRandomValue(T min, T max) { |
|||
std::random_device device; |
|||
std::mt19937 gen(device()); |
|||
std::uniform_int_distribution<u64> distribution(static_cast<u64>(min), |
|||
static_cast<u64>(max)); |
|||
return static_cast<T>(distribution(gen)); |
|||
} |
|||
|
|||
template <typename T> |
|||
static T GetRandomValue(T max) { |
|||
return GetRandomValue<T>({}, max); |
|||
} |
|||
|
|||
static bool IsFontRegionValid(FontRegion font, std::span<const char16_t> text) { |
|||
// TODO: This function needs to check against the font tables |
|||
return true; |
|||
} |
|||
}; |
|||
} // namespace Service::Mii |
|||
@ -1,27 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include "core/hle/service/mii/types.h" |
|||
|
|||
namespace Service::Mii::RawData { |
|||
|
|||
extern const std::array<Service::Mii::DefaultMii, 2> BaseMii; |
|||
extern const std::array<Service::Mii::DefaultMii, 6> DefaultMii; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiFaceline; |
|||
extern const std::array<Service::Mii::RandomMiiData3, 6> RandomMiiFacelineColor; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiFacelineWrinkle; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiFacelineMakeup; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiHairType; |
|||
extern const std::array<Service::Mii::RandomMiiData3, 9> RandomMiiHairColor; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiEyeType; |
|||
extern const std::array<Service::Mii::RandomMiiData2, 3> RandomMiiEyeColor; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiEyebrowType; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiNoseType; |
|||
extern const std::array<Service::Mii::RandomMiiData4, 18> RandomMiiMouthType; |
|||
extern const std::array<Service::Mii::RandomMiiData2, 3> RandomMiiGlassType; |
|||
|
|||
} // namespace Service::Mii::RawData |
|||
@ -1,553 +0,0 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <type_traits> |
|||
|
|||
#include "common/bit_field.h" |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/uuid.h" |
|||
|
|||
namespace Service::Mii { |
|||
|
|||
enum class Age : u32 { |
|||
Young, |
|||
Normal, |
|||
Old, |
|||
All, |
|||
}; |
|||
|
|||
enum class BeardType : u32 { |
|||
None, |
|||
Beard1, |
|||
Beard2, |
|||
Beard3, |
|||
Beard4, |
|||
Beard5, |
|||
}; |
|||
|
|||
enum class BeardAndMustacheFlag : u32 { |
|||
Beard = 1, |
|||
Mustache, |
|||
All = Beard | Mustache, |
|||
}; |
|||
DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag); |
|||
|
|||
enum class FontRegion : u32 { |
|||
Standard, |
|||
China, |
|||
Korea, |
|||
Taiwan, |
|||
}; |
|||
|
|||
enum class Gender : u32 { |
|||
Male, |
|||
Female, |
|||
All, |
|||
Maximum = Female, |
|||
}; |
|||
|
|||
enum class HairFlip : u32 { |
|||
Left, |
|||
Right, |
|||
Maximum = Right, |
|||
}; |
|||
|
|||
enum class MustacheType : u32 { |
|||
None, |
|||
Mustache1, |
|||
Mustache2, |
|||
Mustache3, |
|||
Mustache4, |
|||
Mustache5, |
|||
}; |
|||
|
|||
enum class Race : u32 { |
|||
Black, |
|||
White, |
|||
Asian, |
|||
All, |
|||
}; |
|||
|
|||
enum class Source : u32 { |
|||
Database = 0, |
|||
Default = 1, |
|||
Account = 2, |
|||
Friend = 3, |
|||
}; |
|||
|
|||
enum class SourceFlag : u32 { |
|||
None = 0, |
|||
Database = 1 << 0, |
|||
Default = 1 << 1, |
|||
}; |
|||
DECLARE_ENUM_FLAG_OPERATORS(SourceFlag); |
|||
|
|||
// nn::mii::CharInfo |
|||
struct CharInfo { |
|||
Common::UUID uuid; |
|||
std::array<char16_t, 11> name; |
|||
u8 font_region; |
|||
u8 favorite_color; |
|||
u8 gender; |
|||
u8 height; |
|||
u8 build; |
|||
u8 type; |
|||
u8 region_move; |
|||
u8 faceline_type; |
|||
u8 faceline_color; |
|||
u8 faceline_wrinkle; |
|||
u8 faceline_make; |
|||
u8 hair_type; |
|||
u8 hair_color; |
|||
u8 hair_flip; |
|||
u8 eye_type; |
|||
u8 eye_color; |
|||
u8 eye_scale; |
|||
u8 eye_aspect; |
|||
u8 eye_rotate; |
|||
u8 eye_x; |
|||
u8 eye_y; |
|||
u8 eyebrow_type; |
|||
u8 eyebrow_color; |
|||
u8 eyebrow_scale; |
|||
u8 eyebrow_aspect; |
|||
u8 eyebrow_rotate; |
|||
u8 eyebrow_x; |
|||
u8 eyebrow_y; |
|||
u8 nose_type; |
|||
u8 nose_scale; |
|||
u8 nose_y; |
|||
u8 mouth_type; |
|||
u8 mouth_color; |
|||
u8 mouth_scale; |
|||
u8 mouth_aspect; |
|||
u8 mouth_y; |
|||
u8 beard_color; |
|||
u8 beard_type; |
|||
u8 mustache_type; |
|||
u8 mustache_scale; |
|||
u8 mustache_y; |
|||
u8 glasses_type; |
|||
u8 glasses_color; |
|||
u8 glasses_scale; |
|||
u8 glasses_y; |
|||
u8 mole_type; |
|||
u8 mole_scale; |
|||
u8 mole_x; |
|||
u8 mole_y; |
|||
u8 padding; |
|||
}; |
|||
static_assert(sizeof(CharInfo) == 0x58, "CharInfo has incorrect size."); |
|||
static_assert(std::has_unique_object_representations_v<CharInfo>, |
|||
"All bits of CharInfo must contribute to its value."); |
|||
|
|||
#pragma pack(push, 4) |
|||
|
|||
struct MiiInfoElement { |
|||
MiiInfoElement(const CharInfo& info_, Source source_) : info{info_}, source{source_} {} |
|||
|
|||
CharInfo info{}; |
|||
Source source{}; |
|||
}; |
|||
static_assert(sizeof(MiiInfoElement) == 0x5c, "MiiInfoElement has incorrect size."); |
|||
|
|||
struct MiiStoreBitFields { |
|||
union { |
|||
u32 word_0{}; |
|||
|
|||
BitField<0, 8, u32> hair_type; |
|||
BitField<8, 7, u32> height; |
|||
BitField<15, 1, u32> mole_type; |
|||
BitField<16, 7, u32> build; |
|||
BitField<23, 1, HairFlip> hair_flip; |
|||
BitField<24, 7, u32> hair_color; |
|||
BitField<31, 1, u32> type; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_1{}; |
|||
|
|||
BitField<0, 7, u32> eye_color; |
|||
BitField<7, 1, Gender> gender; |
|||
BitField<8, 7, u32> eyebrow_color; |
|||
BitField<16, 7, u32> mouth_color; |
|||
BitField<24, 7, u32> beard_color; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_2{}; |
|||
|
|||
BitField<0, 7, u32> glasses_color; |
|||
BitField<8, 6, u32> eye_type; |
|||
BitField<14, 2, u32> region_move; |
|||
BitField<16, 6, u32> mouth_type; |
|||
BitField<22, 2, FontRegion> font_region; |
|||
BitField<24, 5, u32> eye_y; |
|||
BitField<29, 3, u32> glasses_scale; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_3{}; |
|||
|
|||
BitField<0, 5, u32> eyebrow_type; |
|||
BitField<5, 3, MustacheType> mustache_type; |
|||
BitField<8, 5, u32> nose_type; |
|||
BitField<13, 3, BeardType> beard_type; |
|||
BitField<16, 5, u32> nose_y; |
|||
BitField<21, 3, u32> mouth_aspect; |
|||
BitField<24, 5, u32> mouth_y; |
|||
BitField<29, 3, u32> eyebrow_aspect; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_4{}; |
|||
|
|||
BitField<0, 5, u32> mustache_y; |
|||
BitField<5, 3, u32> eye_rotate; |
|||
BitField<8, 5, u32> glasses_y; |
|||
BitField<13, 3, u32> eye_aspect; |
|||
BitField<16, 5, u32> mole_x; |
|||
BitField<21, 3, u32> eye_scale; |
|||
BitField<24, 5, u32> mole_y; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_5{}; |
|||
|
|||
BitField<0, 5, u32> glasses_type; |
|||
BitField<8, 4, u32> favorite_color; |
|||
BitField<12, 4, u32> faceline_type; |
|||
BitField<16, 4, u32> faceline_color; |
|||
BitField<20, 4, u32> faceline_wrinkle; |
|||
BitField<24, 4, u32> faceline_makeup; |
|||
BitField<28, 4, u32> eye_x; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_6{}; |
|||
|
|||
BitField<0, 4, u32> eyebrow_scale; |
|||
BitField<4, 4, u32> eyebrow_rotate; |
|||
BitField<8, 4, u32> eyebrow_x; |
|||
BitField<12, 4, u32> eyebrow_y; |
|||
BitField<16, 4, u32> nose_scale; |
|||
BitField<20, 4, u32> mouth_scale; |
|||
BitField<24, 4, u32> mustache_scale; |
|||
BitField<28, 4, u32> mole_scale; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(MiiStoreBitFields) == 0x1c, "MiiStoreBitFields has incorrect size."); |
|||
static_assert(std::is_trivially_copyable_v<MiiStoreBitFields>, |
|||
"MiiStoreBitFields is not trivially copyable."); |
|||
|
|||
// This is nn::mii::Ver3StoreData |
|||
// Based on citra HLE::Applets::MiiData and PretendoNetwork. |
|||
// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 |
|||
// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 |
|||
struct Ver3StoreData { |
|||
u8 version; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 1, u8> allow_copying; |
|||
BitField<1, 1, u8> profanity_flag; |
|||
BitField<2, 2, u8> region_lock; |
|||
BitField<4, 2, u8> character_set; |
|||
} region_information; |
|||
u16_be mii_id; |
|||
u64_be system_id; |
|||
u32_be specialness_and_creation_date; |
|||
std::array<u8, 0x6> creator_mac; |
|||
u16_be padding; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 1, u16> gender; |
|||
BitField<1, 4, u16> birth_month; |
|||
BitField<5, 5, u16> birth_day; |
|||
BitField<10, 4, u16> favorite_color; |
|||
BitField<14, 1, u16> favorite; |
|||
} mii_information; |
|||
std::array<char16_t, 0xA> mii_name; |
|||
u8 height; |
|||
u8 build; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 1, u8> disable_sharing; |
|||
BitField<1, 4, u8> face_shape; |
|||
BitField<5, 3, u8> skin_color; |
|||
} appearance_bits1; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 4, u8> wrinkles; |
|||
BitField<4, 4, u8> makeup; |
|||
} appearance_bits2; |
|||
u8 hair_style; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 3, u8> hair_color; |
|||
BitField<3, 1, u8> flip_hair; |
|||
} appearance_bits3; |
|||
union { |
|||
u32 raw; |
|||
|
|||
BitField<0, 6, u32> eye_type; |
|||
BitField<6, 3, u32> eye_color; |
|||
BitField<9, 4, u32> eye_scale; |
|||
BitField<13, 3, u32> eye_vertical_stretch; |
|||
BitField<16, 5, u32> eye_rotation; |
|||
BitField<21, 4, u32> eye_spacing; |
|||
BitField<25, 5, u32> eye_y_position; |
|||
} appearance_bits4; |
|||
union { |
|||
u32 raw; |
|||
|
|||
BitField<0, 5, u32> eyebrow_style; |
|||
BitField<5, 3, u32> eyebrow_color; |
|||
BitField<8, 4, u32> eyebrow_scale; |
|||
BitField<12, 3, u32> eyebrow_yscale; |
|||
BitField<16, 4, u32> eyebrow_rotation; |
|||
BitField<21, 4, u32> eyebrow_spacing; |
|||
BitField<25, 5, u32> eyebrow_y_position; |
|||
} appearance_bits5; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 5, u16> nose_type; |
|||
BitField<5, 4, u16> nose_scale; |
|||
BitField<9, 5, u16> nose_y_position; |
|||
} appearance_bits6; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 6, u16> mouth_type; |
|||
BitField<6, 3, u16> mouth_color; |
|||
BitField<9, 4, u16> mouth_scale; |
|||
BitField<13, 3, u16> mouth_horizontal_stretch; |
|||
} appearance_bits7; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 5, u8> mouth_y_position; |
|||
BitField<5, 3, u8> mustache_type; |
|||
} appearance_bits8; |
|||
u8 allow_copying; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 3, u16> bear_type; |
|||
BitField<3, 3, u16> facial_hair_color; |
|||
BitField<6, 4, u16> mustache_scale; |
|||
BitField<10, 5, u16> mustache_y_position; |
|||
} appearance_bits9; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 4, u16> glasses_type; |
|||
BitField<4, 3, u16> glasses_color; |
|||
BitField<7, 4, u16> glasses_scale; |
|||
BitField<11, 5, u16> glasses_y_position; |
|||
} appearance_bits10; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 1, u16> mole_enabled; |
|||
BitField<1, 4, u16> mole_scale; |
|||
BitField<5, 5, u16> mole_x_position; |
|||
BitField<10, 5, u16> mole_y_position; |
|||
} appearance_bits11; |
|||
|
|||
std::array<u16_le, 0xA> author_name; |
|||
INSERT_PADDING_BYTES(0x2); |
|||
u16_be crc; |
|||
}; |
|||
static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); |
|||
|
|||
struct NfpStoreDataExtension { |
|||
u8 faceline_color; |
|||
u8 hair_color; |
|||
u8 eye_color; |
|||
u8 eyebrow_color; |
|||
u8 mouth_color; |
|||
u8 beard_color; |
|||
u8 glass_color; |
|||
u8 glass_type; |
|||
}; |
|||
static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); |
|||
|
|||
constexpr std::array<u8, 0x10> Ver3FacelineColorTable{ |
|||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5, |
|||
}; |
|||
|
|||
constexpr std::array<u8, 100> Ver3HairColorTable{ |
|||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x4, 0x3, 0x5, 0x4, 0x4, 0x6, 0x2, 0x0, |
|||
0x6, 0x4, 0x3, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, |
|||
0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, |
|||
0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, |
|||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x7, 0x5, 0x7, 0x7, 0x7, 0x7, 0x7, 0x6, 0x7, |
|||
0x7, 0x7, 0x7, 0x7, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x4, 0x4, 0x4, |
|||
}; |
|||
|
|||
constexpr std::array<u8, 100> Ver3EyeColorTable{ |
|||
0x0, 0x2, 0x2, 0x2, 0x1, 0x3, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x2, 0x2, 0x4, |
|||
0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, |
|||
0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x0, 0x4, 0x4, |
|||
0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, |
|||
0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, |
|||
0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, |
|||
}; |
|||
|
|||
constexpr std::array<u8, 100> Ver3MouthlineColorTable{ |
|||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4, |
|||
0x4, 0x4, 0x0, 0x1, 0x2, 0x3, 0x4, 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4, |
|||
0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, |
|||
0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, |
|||
0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, |
|||
0x3, 0x3, 0x3, 0x3, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x3, 0x3, |
|||
}; |
|||
|
|||
constexpr std::array<u8, 100> Ver3GlassColorTable{ |
|||
0x0, 0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x4, 0x0, 0x5, 0x1, 0x1, 0x3, 0x5, 0x1, 0x2, 0x3, |
|||
0x4, 0x5, 0x4, 0x2, 0x2, 0x4, 0x4, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, |
|||
0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, |
|||
0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x0, 0x5, 0x5, |
|||
0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x1, 0x4, |
|||
0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, |
|||
}; |
|||
|
|||
constexpr std::array<u8, 20> Ver3GlassTypeTable{ |
|||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, |
|||
0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7, |
|||
}; |
|||
|
|||
struct MiiStoreData { |
|||
using Name = std::array<char16_t, 10>; |
|||
|
|||
MiiStoreData(); |
|||
MiiStoreData(const Name& name, const MiiStoreBitFields& bit_fields, |
|||
const Common::UUID& user_id); |
|||
|
|||
// This corresponds to the above structure MiiStoreBitFields. I did it like this because the |
|||
// BitField<> type makes this (and any thing that contains it) not trivially copyable, which is |
|||
// not suitable for our uses. |
|||
struct { |
|||
std::array<u8, 0x1C> data{}; |
|||
static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size."); |
|||
|
|||
Name name{}; |
|||
Common::UUID uuid{}; |
|||
} data; |
|||
|
|||
u16 data_crc{}; |
|||
u16 device_crc{}; |
|||
}; |
|||
static_assert(sizeof(MiiStoreData) == 0x44, "MiiStoreData has incorrect size."); |
|||
|
|||
struct MiiStoreDataElement { |
|||
MiiStoreData data{}; |
|||
Source source{}; |
|||
}; |
|||
static_assert(sizeof(MiiStoreDataElement) == 0x48, "MiiStoreDataElement has incorrect size."); |
|||
|
|||
struct MiiDatabase { |
|||
u32 magic{}; // 'NFDB' |
|||
std::array<MiiStoreData, 0x64> miis{}; |
|||
INSERT_PADDING_BYTES(1); |
|||
u8 count{}; |
|||
u16 crc{}; |
|||
}; |
|||
static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size."); |
|||
|
|||
struct RandomMiiValues { |
|||
std::array<u8, 0xbc> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); |
|||
|
|||
struct RandomMiiData4 { |
|||
Gender gender{}; |
|||
Age age{}; |
|||
Race race{}; |
|||
u32 values_count{}; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData4) == 0xcc, "RandomMiiData4 has incorrect size."); |
|||
|
|||
struct RandomMiiData3 { |
|||
u32 arg_1; |
|||
u32 arg_2; |
|||
u32 values_count; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData3) == 0xc8, "RandomMiiData3 has incorrect size."); |
|||
|
|||
struct RandomMiiData2 { |
|||
u32 arg_1; |
|||
u32 values_count; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData2) == 0xc4, "RandomMiiData2 has incorrect size."); |
|||
|
|||
struct DefaultMii { |
|||
u32 face_type{}; |
|||
u32 face_color{}; |
|||
u32 face_wrinkle{}; |
|||
u32 face_makeup{}; |
|||
u32 hair_type{}; |
|||
u32 hair_color{}; |
|||
u32 hair_flip{}; |
|||
u32 eye_type{}; |
|||
u32 eye_color{}; |
|||
u32 eye_scale{}; |
|||
u32 eye_aspect{}; |
|||
u32 eye_rotate{}; |
|||
u32 eye_x{}; |
|||
u32 eye_y{}; |
|||
u32 eyebrow_type{}; |
|||
u32 eyebrow_color{}; |
|||
u32 eyebrow_scale{}; |
|||
u32 eyebrow_aspect{}; |
|||
u32 eyebrow_rotate{}; |
|||
u32 eyebrow_x{}; |
|||
u32 eyebrow_y{}; |
|||
u32 nose_type{}; |
|||
u32 nose_scale{}; |
|||
u32 nose_y{}; |
|||
u32 mouth_type{}; |
|||
u32 mouth_color{}; |
|||
u32 mouth_scale{}; |
|||
u32 mouth_aspect{}; |
|||
u32 mouth_y{}; |
|||
u32 mustache_type{}; |
|||
u32 beard_type{}; |
|||
u32 beard_color{}; |
|||
u32 mustache_scale{}; |
|||
u32 mustache_y{}; |
|||
u32 glasses_type{}; |
|||
u32 glasses_color{}; |
|||
u32 glasses_scale{}; |
|||
u32 glasses_y{}; |
|||
u32 mole_type{}; |
|||
u32 mole_scale{}; |
|||
u32 mole_x{}; |
|||
u32 mole_y{}; |
|||
u32 height{}; |
|||
u32 weight{}; |
|||
Gender gender{}; |
|||
u32 favorite_color{}; |
|||
u32 region{}; |
|||
FontRegion font_region{}; |
|||
u32 type{}; |
|||
INSERT_PADDING_WORDS(5); |
|||
}; |
|||
static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size."); |
|||
|
|||
#pragma pack(pop) |
|||
|
|||
} // namespace Service::Mii |
|||
@ -0,0 +1,482 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "core/hle/service/mii/types/char_info.h"
|
|||
#include "core/hle/service/mii/types/store_data.h"
|
|||
|
|||
namespace Service::Mii { |
|||
|
|||
void CharInfo::SetFromStoreData(const StoreData& store_data) { |
|||
name = store_data.GetNickname(); |
|||
null_terminator = '\0'; |
|||
create_id = store_data.GetCreateId(); |
|||
font_region = store_data.GetFontRegion(); |
|||
favorite_color = store_data.GetFavoriteColor(); |
|||
gender = store_data.GetGender(); |
|||
height = store_data.GetHeight(); |
|||
build = store_data.GetBuild(); |
|||
type = store_data.GetType(); |
|||
region_move = store_data.GetRegionMove(); |
|||
faceline_type = store_data.GetFacelineType(); |
|||
faceline_color = store_data.GetFacelineColor(); |
|||
faceline_wrinkle = store_data.GetFacelineWrinkle(); |
|||
faceline_make = store_data.GetFacelineMake(); |
|||
hair_type = store_data.GetHairType(); |
|||
hair_color = store_data.GetHairColor(); |
|||
hair_flip = store_data.GetHairFlip(); |
|||
eye_type = store_data.GetEyeType(); |
|||
eye_color = store_data.GetEyeColor(); |
|||
eye_scale = store_data.GetEyeScale(); |
|||
eye_aspect = store_data.GetEyeAspect(); |
|||
eye_rotate = store_data.GetEyeRotate(); |
|||
eye_x = store_data.GetEyeX(); |
|||
eye_y = store_data.GetEyeY(); |
|||
eyebrow_type = store_data.GetEyebrowType(); |
|||
eyebrow_color = store_data.GetEyebrowColor(); |
|||
eyebrow_scale = store_data.GetEyebrowScale(); |
|||
eyebrow_aspect = store_data.GetEyebrowAspect(); |
|||
eyebrow_rotate = store_data.GetEyebrowRotate(); |
|||
eyebrow_x = store_data.GetEyebrowX(); |
|||
eyebrow_y = store_data.GetEyebrowY(); |
|||
nose_type = store_data.GetNoseType(); |
|||
nose_scale = store_data.GetNoseScale(); |
|||
nose_y = store_data.GetNoseY(); |
|||
mouth_type = store_data.GetMouthType(); |
|||
mouth_color = store_data.GetMouthColor(); |
|||
mouth_scale = store_data.GetMouthScale(); |
|||
mouth_aspect = store_data.GetMouthAspect(); |
|||
mouth_y = store_data.GetMouthY(); |
|||
beard_color = store_data.GetBeardColor(); |
|||
beard_type = store_data.GetBeardType(); |
|||
mustache_type = store_data.GetMustacheType(); |
|||
mustache_scale = store_data.GetMustacheScale(); |
|||
mustache_y = store_data.GetMustacheY(); |
|||
glass_type = store_data.GetGlassType(); |
|||
glass_color = store_data.GetGlassColor(); |
|||
glass_scale = store_data.GetGlassScale(); |
|||
glass_y = store_data.GetGlassY(); |
|||
mole_type = store_data.GetMoleType(); |
|||
mole_scale = store_data.GetMoleScale(); |
|||
mole_x = store_data.GetMoleX(); |
|||
mole_y = store_data.GetMoleY(); |
|||
padding = '\0'; |
|||
} |
|||
|
|||
ValidationResult CharInfo::Verify() const { |
|||
if (!create_id.IsValid()) { |
|||
return ValidationResult::InvalidCreateId; |
|||
} |
|||
if (!name.IsValid()) { |
|||
return ValidationResult::InvalidName; |
|||
} |
|||
if (font_region > FontRegion::Max) { |
|||
return ValidationResult::InvalidFont; |
|||
} |
|||
if (favorite_color > FavoriteColor::Max) { |
|||
return ValidationResult::InvalidColor; |
|||
} |
|||
if (gender > Gender::Max) { |
|||
return ValidationResult::InvalidGender; |
|||
} |
|||
if (height > MaxHeight) { |
|||
return ValidationResult::InvalidHeight; |
|||
} |
|||
if (build > MaxBuild) { |
|||
return ValidationResult::InvalidBuild; |
|||
} |
|||
if (type > MaxType) { |
|||
return ValidationResult::InvalidType; |
|||
} |
|||
if (region_move > MaxRegionMove) { |
|||
return ValidationResult::InvalidRegionMove; |
|||
} |
|||
if (faceline_type > FacelineType::Max) { |
|||
return ValidationResult::InvalidFacelineType; |
|||
} |
|||
if (faceline_color > FacelineColor::Max) { |
|||
return ValidationResult::InvalidFacelineColor; |
|||
} |
|||
if (faceline_wrinkle > FacelineWrinkle::Max) { |
|||
return ValidationResult::InvalidFacelineWrinkle; |
|||
} |
|||
if (faceline_make > FacelineMake::Max) { |
|||
return ValidationResult::InvalidFacelineMake; |
|||
} |
|||
if (hair_type > HairType::Max) { |
|||
return ValidationResult::InvalidHairType; |
|||
} |
|||
if (hair_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidHairColor; |
|||
} |
|||
if (hair_flip > HairFlip::Max) { |
|||
return ValidationResult::InvalidHairFlip; |
|||
} |
|||
if (eye_type > EyeType::Max) { |
|||
return ValidationResult::InvalidEyeType; |
|||
} |
|||
if (eye_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidEyeColor; |
|||
} |
|||
if (eye_scale > MaxEyeScale) { |
|||
return ValidationResult::InvalidEyeScale; |
|||
} |
|||
if (eye_aspect > MaxEyeAspect) { |
|||
return ValidationResult::InvalidEyeAspect; |
|||
} |
|||
if (eye_rotate > MaxEyeX) { |
|||
return ValidationResult::InvalidEyeRotate; |
|||
} |
|||
if (eye_x > MaxEyeX) { |
|||
return ValidationResult::InvalidEyeX; |
|||
} |
|||
if (eye_y > MaxEyeY) { |
|||
return ValidationResult::InvalidEyeY; |
|||
} |
|||
if (eyebrow_type > EyebrowType::Max) { |
|||
return ValidationResult::InvalidEyebrowType; |
|||
} |
|||
if (eyebrow_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidEyebrowColor; |
|||
} |
|||
if (eyebrow_scale > MaxEyebrowScale) { |
|||
return ValidationResult::InvalidEyebrowScale; |
|||
} |
|||
if (eyebrow_aspect > MaxEyebrowAspect) { |
|||
return ValidationResult::InvalidEyebrowAspect; |
|||
} |
|||
if (eyebrow_rotate > MaxEyebrowRotate) { |
|||
return ValidationResult::InvalidEyebrowRotate; |
|||
} |
|||
if (eyebrow_x > MaxEyebrowX) { |
|||
return ValidationResult::InvalidEyebrowX; |
|||
} |
|||
if (eyebrow_y > MaxEyebrowY) { |
|||
return ValidationResult::InvalidEyebrowY; |
|||
} |
|||
if (nose_type > NoseType::Max) { |
|||
return ValidationResult::InvalidNoseType; |
|||
} |
|||
if (nose_scale > MaxNoseScale) { |
|||
return ValidationResult::InvalidNoseScale; |
|||
} |
|||
if (nose_y > MaxNoseY) { |
|||
return ValidationResult::InvalidNoseY; |
|||
} |
|||
if (mouth_type > MouthType::Max) { |
|||
return ValidationResult::InvalidMouthType; |
|||
} |
|||
if (mouth_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidMouthColor; |
|||
} |
|||
if (mouth_scale > MaxMouthScale) { |
|||
return ValidationResult::InvalidMouthScale; |
|||
} |
|||
if (mouth_aspect > MaxMoutAspect) { |
|||
return ValidationResult::InvalidMouthAspect; |
|||
} |
|||
if (mouth_y > MaxMouthY) { |
|||
return ValidationResult::InvalidMoleY; |
|||
} |
|||
if (beard_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidBeardColor; |
|||
} |
|||
if (beard_type > BeardType::Max) { |
|||
return ValidationResult::InvalidBeardType; |
|||
} |
|||
if (mustache_type > MustacheType::Max) { |
|||
return ValidationResult::InvalidMustacheType; |
|||
} |
|||
if (mustache_scale > MaxMustacheScale) { |
|||
return ValidationResult::InvalidMustacheScale; |
|||
} |
|||
if (mustache_y > MasMustacheY) { |
|||
return ValidationResult::InvalidMustacheY; |
|||
} |
|||
if (glass_type > GlassType::Max) { |
|||
return ValidationResult::InvalidGlassType; |
|||
} |
|||
if (glass_color > CommonColor::Max) { |
|||
return ValidationResult::InvalidGlassColor; |
|||
} |
|||
if (glass_scale > MaxGlassScale) { |
|||
return ValidationResult::InvalidGlassScale; |
|||
} |
|||
if (glass_y > MaxGlassY) { |
|||
return ValidationResult::InvalidGlassY; |
|||
} |
|||
if (mole_type > MoleType::Max) { |
|||
return ValidationResult::InvalidMoleType; |
|||
} |
|||
if (mole_scale > MaxMoleScale) { |
|||
return ValidationResult::InvalidMoleScale; |
|||
} |
|||
if (mole_x > MaxMoleX) { |
|||
return ValidationResult::InvalidMoleX; |
|||
} |
|||
if (mole_y > MaxMoleY) { |
|||
return ValidationResult::InvalidMoleY; |
|||
} |
|||
return ValidationResult::NoErrors; |
|||
} |
|||
|
|||
Common::UUID CharInfo::GetCreateId() const { |
|||
return create_id; |
|||
} |
|||
|
|||
Nickname CharInfo::GetNickname() const { |
|||
return name; |
|||
} |
|||
|
|||
FontRegion CharInfo::GetFontRegion() const { |
|||
return font_region; |
|||
} |
|||
|
|||
FavoriteColor CharInfo::GetFavoriteColor() const { |
|||
return favorite_color; |
|||
} |
|||
|
|||
Gender CharInfo::GetGender() const { |
|||
return gender; |
|||
} |
|||
|
|||
u8 CharInfo::GetHeight() const { |
|||
return height; |
|||
} |
|||
|
|||
u8 CharInfo::GetBuild() const { |
|||
return build; |
|||
} |
|||
|
|||
u8 CharInfo::GetType() const { |
|||
return type; |
|||
} |
|||
|
|||
u8 CharInfo::GetRegionMove() const { |
|||
return region_move; |
|||
} |
|||
|
|||
FacelineType CharInfo::GetFacelineType() const { |
|||
return faceline_type; |
|||
} |
|||
|
|||
FacelineColor CharInfo::GetFacelineColor() const { |
|||
return faceline_color; |
|||
} |
|||
|
|||
FacelineWrinkle CharInfo::GetFacelineWrinkle() const { |
|||
return faceline_wrinkle; |
|||
} |
|||
|
|||
FacelineMake CharInfo::GetFacelineMake() const { |
|||
return faceline_make; |
|||
} |
|||
|
|||
HairType CharInfo::GetHairType() const { |
|||
return hair_type; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetHairColor() const { |
|||
return hair_color; |
|||
} |
|||
|
|||
HairFlip CharInfo::GetHairFlip() const { |
|||
return hair_flip; |
|||
} |
|||
|
|||
EyeType CharInfo::GetEyeType() const { |
|||
return eye_type; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetEyeColor() const { |
|||
return eye_color; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyeScale() const { |
|||
return eye_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyeAspect() const { |
|||
return eye_aspect; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyeRotate() const { |
|||
return eye_rotate; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyeX() const { |
|||
return eye_x; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyeY() const { |
|||
return eye_y; |
|||
} |
|||
|
|||
EyebrowType CharInfo::GetEyebrowType() const { |
|||
return eyebrow_type; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetEyebrowColor() const { |
|||
return eyebrow_color; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyebrowScale() const { |
|||
return eyebrow_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyebrowAspect() const { |
|||
return eyebrow_aspect; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyebrowRotate() const { |
|||
return eyebrow_rotate; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyebrowX() const { |
|||
return eyebrow_x; |
|||
} |
|||
|
|||
u8 CharInfo::GetEyebrowY() const { |
|||
return eyebrow_y; |
|||
} |
|||
|
|||
NoseType CharInfo::GetNoseType() const { |
|||
return nose_type; |
|||
} |
|||
|
|||
u8 CharInfo::GetNoseScale() const { |
|||
return nose_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetNoseY() const { |
|||
return nose_y; |
|||
} |
|||
|
|||
MouthType CharInfo::GetMouthType() const { |
|||
return mouth_type; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetMouthColor() const { |
|||
return mouth_color; |
|||
} |
|||
|
|||
u8 CharInfo::GetMouthScale() const { |
|||
return mouth_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetMouthAspect() const { |
|||
return mouth_aspect; |
|||
} |
|||
|
|||
u8 CharInfo::GetMouthY() const { |
|||
return mouth_y; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetBeardColor() const { |
|||
return beard_color; |
|||
} |
|||
|
|||
BeardType CharInfo::GetBeardType() const { |
|||
return beard_type; |
|||
} |
|||
|
|||
MustacheType CharInfo::GetMustacheType() const { |
|||
return mustache_type; |
|||
} |
|||
|
|||
u8 CharInfo::GetMustacheScale() const { |
|||
return mustache_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetMustacheY() const { |
|||
return mustache_y; |
|||
} |
|||
|
|||
GlassType CharInfo::GetGlassType() const { |
|||
return glass_type; |
|||
} |
|||
|
|||
CommonColor CharInfo::GetGlassColor() const { |
|||
return glass_color; |
|||
} |
|||
|
|||
u8 CharInfo::GetGlassScale() const { |
|||
return glass_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetGlassY() const { |
|||
return glass_y; |
|||
} |
|||
|
|||
MoleType CharInfo::GetMoleType() const { |
|||
return mole_type; |
|||
} |
|||
|
|||
u8 CharInfo::GetMoleScale() const { |
|||
return mole_scale; |
|||
} |
|||
|
|||
u8 CharInfo::GetMoleX() const { |
|||
return mole_x; |
|||
} |
|||
|
|||
u8 CharInfo::GetMoleY() const { |
|||
return mole_y; |
|||
} |
|||
|
|||
bool CharInfo::operator==(const CharInfo& info) { |
|||
bool is_identical = info.Verify() == ValidationResult::NoErrors; |
|||
is_identical &= name.data == info.GetNickname().data; |
|||
is_identical &= create_id == info.GetCreateId(); |
|||
is_identical &= font_region == info.GetFontRegion(); |
|||
is_identical &= favorite_color == info.GetFavoriteColor(); |
|||
is_identical &= gender == info.GetGender(); |
|||
is_identical &= height == info.GetHeight(); |
|||
is_identical &= build == info.GetBuild(); |
|||
is_identical &= type == info.GetType(); |
|||
is_identical &= region_move == info.GetRegionMove(); |
|||
is_identical &= faceline_type == info.GetFacelineType(); |
|||
is_identical &= faceline_color == info.GetFacelineColor(); |
|||
is_identical &= faceline_wrinkle == info.GetFacelineWrinkle(); |
|||
is_identical &= faceline_make == info.GetFacelineMake(); |
|||
is_identical &= hair_type == info.GetHairType(); |
|||
is_identical &= hair_color == info.GetHairColor(); |
|||
is_identical &= hair_flip == info.GetHairFlip(); |
|||
is_identical &= eye_type == info.GetEyeType(); |
|||
is_identical &= eye_color == info.GetEyeColor(); |
|||
is_identical &= eye_scale == info.GetEyeScale(); |
|||
is_identical &= eye_aspect == info.GetEyeAspect(); |
|||
is_identical &= eye_rotate == info.GetEyeRotate(); |
|||
is_identical &= eye_x == info.GetEyeX(); |
|||
is_identical &= eye_y == info.GetEyeY(); |
|||
is_identical &= eyebrow_type == info.GetEyebrowType(); |
|||
is_identical &= eyebrow_color == info.GetEyebrowColor(); |
|||
is_identical &= eyebrow_scale == info.GetEyebrowScale(); |
|||
is_identical &= eyebrow_aspect == info.GetEyebrowAspect(); |
|||
is_identical &= eyebrow_rotate == info.GetEyebrowRotate(); |
|||
is_identical &= eyebrow_x == info.GetEyebrowX(); |
|||
is_identical &= eyebrow_y == info.GetEyebrowY(); |
|||
is_identical &= nose_type == info.GetNoseType(); |
|||
is_identical &= nose_scale == info.GetNoseScale(); |
|||
is_identical &= nose_y == info.GetNoseY(); |
|||
is_identical &= mouth_type == info.GetMouthType(); |
|||
is_identical &= mouth_color == info.GetMouthColor(); |
|||
is_identical &= mouth_scale == info.GetMouthScale(); |
|||
is_identical &= mouth_aspect == info.GetMouthAspect(); |
|||
is_identical &= mouth_y == info.GetMouthY(); |
|||
is_identical &= beard_color == info.GetBeardColor(); |
|||
is_identical &= beard_type == info.GetBeardType(); |
|||
is_identical &= mustache_type == info.GetMustacheType(); |
|||
is_identical &= mustache_scale == info.GetMustacheScale(); |
|||
is_identical &= mustache_y == info.GetMustacheY(); |
|||
is_identical &= glass_type == info.GetGlassType(); |
|||
is_identical &= glass_color == info.GetGlassColor(); |
|||
is_identical &= glass_scale == info.GetGlassScale(); |
|||
is_identical &= glass_y == info.GetGlassY(); |
|||
is_identical &= mole_type == info.GetMoleType(); |
|||
is_identical &= mole_scale == info.GetMoleScale(); |
|||
is_identical &= mole_x == info.GetMoleX(); |
|||
is_identical &= mole_y == info.GetMoleY(); |
|||
return is_identical; |
|||
} |
|||
|
|||
} // namespace Service::Mii
|
|||
@ -0,0 +1,137 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/service/mii/mii_types.h" |
|||
|
|||
namespace Service::Mii { |
|||
class StoreData; |
|||
|
|||
// This is nn::mii::detail::CharInfoRaw |
|||
class CharInfo { |
|||
public: |
|||
void SetFromStoreData(const StoreData& store_data_raw); |
|||
|
|||
ValidationResult Verify() const; |
|||
|
|||
Common::UUID GetCreateId() const; |
|||
Nickname GetNickname() const; |
|||
FontRegion GetFontRegion() const; |
|||
FavoriteColor GetFavoriteColor() const; |
|||
Gender GetGender() const; |
|||
u8 GetHeight() const; |
|||
u8 GetBuild() const; |
|||
u8 GetType() const; |
|||
u8 GetRegionMove() const; |
|||
FacelineType GetFacelineType() const; |
|||
FacelineColor GetFacelineColor() const; |
|||
FacelineWrinkle GetFacelineWrinkle() const; |
|||
FacelineMake GetFacelineMake() const; |
|||
HairType GetHairType() const; |
|||
CommonColor GetHairColor() const; |
|||
HairFlip GetHairFlip() const; |
|||
EyeType GetEyeType() const; |
|||
CommonColor GetEyeColor() const; |
|||
u8 GetEyeScale() const; |
|||
u8 GetEyeAspect() const; |
|||
u8 GetEyeRotate() const; |
|||
u8 GetEyeX() const; |
|||
u8 GetEyeY() const; |
|||
EyebrowType GetEyebrowType() const; |
|||
CommonColor GetEyebrowColor() const; |
|||
u8 GetEyebrowScale() const; |
|||
u8 GetEyebrowAspect() const; |
|||
u8 GetEyebrowRotate() const; |
|||
u8 GetEyebrowX() const; |
|||
u8 GetEyebrowY() const; |
|||
NoseType GetNoseType() const; |
|||
u8 GetNoseScale() const; |
|||
u8 GetNoseY() const; |
|||
MouthType GetMouthType() const; |
|||
CommonColor GetMouthColor() const; |
|||
u8 GetMouthScale() const; |
|||
u8 GetMouthAspect() const; |
|||
u8 GetMouthY() const; |
|||
CommonColor GetBeardColor() const; |
|||
BeardType GetBeardType() const; |
|||
MustacheType GetMustacheType() const; |
|||
u8 GetMustacheScale() const; |
|||
u8 GetMustacheY() const; |
|||
GlassType GetGlassType() const; |
|||
CommonColor GetGlassColor() const; |
|||
u8 GetGlassScale() const; |
|||
u8 GetGlassY() const; |
|||
MoleType GetMoleType() const; |
|||
u8 GetMoleScale() const; |
|||
u8 GetMoleX() const; |
|||
u8 GetMoleY() const; |
|||
|
|||
bool operator==(const CharInfo& info); |
|||
|
|||
private: |
|||
Common::UUID create_id; |
|||
Nickname name; |
|||
u16 null_terminator; |
|||
FontRegion font_region; |
|||
FavoriteColor favorite_color; |
|||
Gender gender; |
|||
u8 height; |
|||
u8 build; |
|||
u8 type; |
|||
u8 region_move; |
|||
FacelineType faceline_type; |
|||
FacelineColor faceline_color; |
|||
FacelineWrinkle faceline_wrinkle; |
|||
FacelineMake faceline_make; |
|||
HairType hair_type; |
|||
CommonColor hair_color; |
|||
HairFlip hair_flip; |
|||
EyeType eye_type; |
|||
CommonColor eye_color; |
|||
u8 eye_scale; |
|||
u8 eye_aspect; |
|||
u8 eye_rotate; |
|||
u8 eye_x; |
|||
u8 eye_y; |
|||
EyebrowType eyebrow_type; |
|||
CommonColor eyebrow_color; |
|||
u8 eyebrow_scale; |
|||
u8 eyebrow_aspect; |
|||
u8 eyebrow_rotate; |
|||
u8 eyebrow_x; |
|||
u8 eyebrow_y; |
|||
NoseType nose_type; |
|||
u8 nose_scale; |
|||
u8 nose_y; |
|||
MouthType mouth_type; |
|||
CommonColor mouth_color; |
|||
u8 mouth_scale; |
|||
u8 mouth_aspect; |
|||
u8 mouth_y; |
|||
CommonColor beard_color; |
|||
BeardType beard_type; |
|||
MustacheType mustache_type; |
|||
u8 mustache_scale; |
|||
u8 mustache_y; |
|||
GlassType glass_type; |
|||
CommonColor glass_color; |
|||
u8 glass_scale; |
|||
u8 glass_y; |
|||
MoleType mole_type; |
|||
u8 mole_scale; |
|||
u8 mole_x; |
|||
u8 mole_y; |
|||
u8 padding; |
|||
}; |
|||
static_assert(sizeof(CharInfo) == 0x58, "CharInfo has incorrect size."); |
|||
static_assert(std::has_unique_object_representations_v<CharInfo>, |
|||
"All bits of CharInfo must contribute to its value."); |
|||
|
|||
struct CharInfoElement { |
|||
CharInfo char_info{}; |
|||
Source source{}; |
|||
}; |
|||
static_assert(sizeof(CharInfoElement) == 0x5c, "CharInfoElement has incorrect size."); |
|||
|
|||
}; // namespace Service::Mii |
|||
@ -0,0 +1,601 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "common/assert.h"
|
|||
#include "core/hle/service/mii/mii_util.h"
|
|||
#include "core/hle/service/mii/types/core_data.h"
|
|||
#include "core/hle/service/mii/types/raw_data.h"
|
|||
|
|||
namespace Service::Mii { |
|||
|
|||
void CoreData::SetDefault() { |
|||
data = {}; |
|||
name = GetDefaultNickname(); |
|||
} |
|||
|
|||
void CoreData::BuildRandom(Age age, Gender gender, Race race) { |
|||
if (gender == Gender::All) { |
|||
gender = MiiUtil::GetRandomValue(Gender::Max); |
|||
} |
|||
|
|||
if (age == Age::All) { |
|||
const auto random{MiiUtil::GetRandomValue<int>(10)}; |
|||
if (random >= 8) { |
|||
age = Age::Old; |
|||
} else if (random >= 4) { |
|||
age = Age::Normal; |
|||
} else { |
|||
age = Age::Young; |
|||
} |
|||
} |
|||
|
|||
if (race == Race::All) { |
|||
const auto random{MiiUtil::GetRandomValue<int>(10)}; |
|||
if (random >= 8) { |
|||
race = Race::Black; |
|||
} else if (random >= 4) { |
|||
race = Race::White; |
|||
} else { |
|||
race = Race::Asian; |
|||
} |
|||
} |
|||
|
|||
SetGender(gender); |
|||
SetFavoriteColor(MiiUtil::GetRandomValue(FavoriteColor::Max)); |
|||
SetRegionMove(0); |
|||
SetFontRegion(FontRegion::Standard); |
|||
SetType(0); |
|||
SetHeight(64); |
|||
SetBuild(64); |
|||
|
|||
u32 axis_y{}; |
|||
if (gender == Gender::Female && age == Age::Young) { |
|||
axis_y = MiiUtil::GetRandomValue<u32>(3); |
|||
} |
|||
|
|||
const std::size_t index{3 * static_cast<std::size_t>(age) + |
|||
9 * static_cast<std::size_t>(gender) + static_cast<std::size_t>(race)}; |
|||
|
|||
const auto& faceline_type_info{RawData::RandomMiiFaceline.at(index)}; |
|||
const auto& faceline_color_info{RawData::RandomMiiFacelineColor.at( |
|||
3 * static_cast<std::size_t>(gender) + static_cast<std::size_t>(race))}; |
|||
const auto& faceline_wrinkle_info{RawData::RandomMiiFacelineWrinkle.at(index)}; |
|||
const auto& faceline_makeup_info{RawData::RandomMiiFacelineMakeup.at(index)}; |
|||
const auto& hair_type_info{RawData::RandomMiiHairType.at(index)}; |
|||
const auto& hair_color_info{RawData::RandomMiiHairColor.at(3 * static_cast<std::size_t>(race) + |
|||
static_cast<std::size_t>(age))}; |
|||
const auto& eye_type_info{RawData::RandomMiiEyeType.at(index)}; |
|||
const auto& eye_color_info{RawData::RandomMiiEyeColor.at(static_cast<std::size_t>(race))}; |
|||
const auto& eyebrow_type_info{RawData::RandomMiiEyebrowType.at(index)}; |
|||
const auto& nose_type_info{RawData::RandomMiiNoseType.at(index)}; |
|||
const auto& mouth_type_info{RawData::RandomMiiMouthType.at(index)}; |
|||
const auto& glasses_type_info{RawData::RandomMiiGlassType.at(static_cast<std::size_t>(age))}; |
|||
|
|||
data.faceline_type.Assign( |
|||
faceline_type_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(faceline_type_info.values_count)]); |
|||
data.faceline_color.Assign( |
|||
faceline_color_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(faceline_color_info.values_count)]); |
|||
data.faceline_wrinkle.Assign( |
|||
faceline_wrinkle_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(faceline_wrinkle_info.values_count)]); |
|||
data.faceline_makeup.Assign( |
|||
faceline_makeup_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(faceline_makeup_info.values_count)]); |
|||
|
|||
data.hair_type.Assign( |
|||
hair_type_info.values[MiiUtil::GetRandomValue<std::size_t>(hair_type_info.values_count)]); |
|||
SetHairColor(RawData::GetHairColorFromVer3( |
|||
hair_color_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(hair_color_info.values_count)])); |
|||
SetHairFlip(MiiUtil::GetRandomValue(HairFlip::Max)); |
|||
|
|||
data.eye_type.Assign( |
|||
eye_type_info.values[MiiUtil::GetRandomValue<std::size_t>(eye_type_info.values_count)]); |
|||
|
|||
const auto eye_rotate_1{gender != Gender::Male ? 4 : 2}; |
|||
const auto eye_rotate_2{gender != Gender::Male ? 3 : 4}; |
|||
const auto eye_rotate_offset{32 - RawData::EyeRotateLookup[eye_rotate_1] + eye_rotate_2}; |
|||
const auto eye_rotate{32 - RawData::EyeRotateLookup[data.eye_type]}; |
|||
|
|||
SetEyeColor(RawData::GetEyeColorFromVer3( |
|||
eye_color_info.values[MiiUtil::GetRandomValue<std::size_t>(eye_color_info.values_count)])); |
|||
SetEyeScale(4); |
|||
SetEyeAspect(3); |
|||
SetEyeRotate(static_cast<u8>(eye_rotate_offset - eye_rotate)); |
|||
SetEyeX(2); |
|||
SetEyeY(static_cast<u8>(axis_y + 12)); |
|||
|
|||
data.eyebrow_type.Assign( |
|||
eyebrow_type_info |
|||
.values[MiiUtil::GetRandomValue<std::size_t>(eyebrow_type_info.values_count)]); |
|||
|
|||
const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0}; |
|||
const auto eyebrow_y{race == Race::Asian ? 9 : 10}; |
|||
const auto eyebrow_rotate_offset{32 - RawData::EyebrowRotateLookup[eyebrow_rotate_1] + 6}; |
|||
const auto eyebrow_rotate{ |
|||
32 - RawData::EyebrowRotateLookup[static_cast<std::size_t>(data.eyebrow_type.Value())]}; |
|||
|
|||
SetEyebrowColor(GetHairColor()); |
|||
SetEyebrowScale(4); |
|||
SetEyebrowAspect(3); |
|||
SetEyebrowRotate(static_cast<u8>(eyebrow_rotate_offset - eyebrow_rotate)); |
|||
SetEyebrowX(2); |
|||
SetEyebrowY(static_cast<u8>(axis_y + eyebrow_y)); |
|||
|
|||
data.nose_type.Assign( |
|||
nose_type_info.values[MiiUtil::GetRandomValue<std::size_t>(nose_type_info.values_count)]); |
|||
SetNoseScale(gender == Gender::Female ? 3 : 4); |
|||
SetNoseY(static_cast<u8>(axis_y + 9)); |
|||
|
|||
const auto mouth_color{gender == Gender::Female ? MiiUtil::GetRandomValue<int>(4) : 0}; |
|||
|
|||
data.mouth_type.Assign( |
|||
mouth_type_info.values[MiiUtil::GetRandomValue<std::size_t>(mouth_type_info.values_count)]); |
|||
SetMouthColor(RawData::GetMouthColorFromVer3(mouth_color)); |
|||
SetMouthScale(4); |
|||
SetMouthAspect(3); |
|||
SetMouthY(static_cast<u8>(axis_y + 13)); |
|||
|
|||
SetBeardColor(GetHairColor()); |
|||
SetMustacheScale(4); |
|||
|
|||
if (gender == Gender::Male && age != Age::Young && MiiUtil::GetRandomValue<int>(10) < 2) { |
|||
const auto mustache_and_beard_flag{MiiUtil::GetRandomValue(BeardAndMustacheFlag::All)}; |
|||
|
|||
auto beard_type{BeardType::None}; |
|||
auto mustache_type{MustacheType::None}; |
|||
|
|||
if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) == |
|||
BeardAndMustacheFlag::Beard) { |
|||
beard_type = MiiUtil::GetRandomValue(BeardType::Min, BeardType::Max); |
|||
} |
|||
|
|||
if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) == |
|||
BeardAndMustacheFlag::Mustache) { |
|||
mustache_type = MiiUtil::GetRandomValue(MustacheType::Min, MustacheType::Max); |
|||
} |
|||
|
|||
SetMustacheType(mustache_type); |
|||
SetBeardType(beard_type); |
|||
SetMustacheY(10); |
|||
} else { |
|||
SetMustacheType(MustacheType::None); |
|||
SetBeardType(BeardType::None); |
|||
SetMustacheY(static_cast<u8>(axis_y + 10)); |
|||
} |
|||
|
|||
const auto glasses_type_start{MiiUtil::GetRandomValue<std::size_t>(100)}; |
|||
u8 glasses_type{}; |
|||
while (glasses_type_start < glasses_type_info.values[glasses_type]) { |
|||
if (++glasses_type >= glasses_type_info.values_count) { |
|||
ASSERT(false); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
SetGlassType(static_cast<GlassType>(glasses_type)); |
|||
SetGlassColor(RawData::GetGlassColorFromVer3(0)); |
|||
SetGlassScale(4); |
|||
|
|||
SetMoleType(MoleType::None); |
|||
SetMoleScale(4); |
|||
SetMoleX(2); |
|||
SetMoleY(20); |
|||
} |
|||
|
|||
u32 CoreData::IsValid() const { |
|||
// TODO: Complete this
|
|||
return 0; |
|||
} |
|||
|
|||
void CoreData::SetFontRegion(FontRegion value) { |
|||
data.font_region.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetFavoriteColor(FavoriteColor value) { |
|||
data.favorite_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetGender(Gender value) { |
|||
data.gender.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetHeight(u8 value) { |
|||
data.height.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetBuild(u8 value) { |
|||
data.build.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetType(u8 value) { |
|||
data.type.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetRegionMove(u8 value) { |
|||
data.region_move.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetFacelineType(FacelineType value) { |
|||
data.faceline_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetFacelineColor(FacelineColor value) { |
|||
data.faceline_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetFacelineWrinkle(FacelineWrinkle value) { |
|||
data.faceline_wrinkle.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetFacelineMake(FacelineMake value) { |
|||
data.faceline_makeup.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetHairType(HairType value) { |
|||
data.hair_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetHairColor(CommonColor value) { |
|||
data.hair_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetHairFlip(HairFlip value) { |
|||
data.hair_flip.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetEyeType(EyeType value) { |
|||
data.eye_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetEyeColor(CommonColor value) { |
|||
data.eye_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetEyeScale(u8 value) { |
|||
data.eye_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyeAspect(u8 value) { |
|||
data.eye_aspect.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyeRotate(u8 value) { |
|||
data.eye_rotate.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyeX(u8 value) { |
|||
data.eye_x.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyeY(u8 value) { |
|||
data.eye_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowType(EyebrowType value) { |
|||
data.eyebrow_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowColor(CommonColor value) { |
|||
data.eyebrow_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowScale(u8 value) { |
|||
data.eyebrow_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowAspect(u8 value) { |
|||
data.eyebrow_aspect.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowRotate(u8 value) { |
|||
data.eyebrow_rotate.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowX(u8 value) { |
|||
data.eyebrow_x.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetEyebrowY(u8 value) { |
|||
data.eyebrow_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetNoseType(NoseType value) { |
|||
data.nose_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetNoseScale(u8 value) { |
|||
data.nose_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetNoseY(u8 value) { |
|||
data.nose_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMouthType(u8 value) { |
|||
data.mouth_type.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMouthColor(CommonColor value) { |
|||
data.mouth_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetMouthScale(u8 value) { |
|||
data.mouth_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMouthAspect(u8 value) { |
|||
data.mouth_aspect.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMouthY(u8 value) { |
|||
data.mouth_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetBeardColor(CommonColor value) { |
|||
data.beard_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetBeardType(BeardType value) { |
|||
data.beard_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetMustacheType(MustacheType value) { |
|||
data.mustache_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetMustacheScale(u8 value) { |
|||
data.mustache_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMustacheY(u8 value) { |
|||
data.mustache_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetGlassType(GlassType value) { |
|||
data.glasses_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetGlassColor(CommonColor value) { |
|||
data.glasses_color.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetGlassScale(u8 value) { |
|||
data.glasses_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetGlassY(u8 value) { |
|||
data.glasses_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMoleType(MoleType value) { |
|||
data.mole_type.Assign(static_cast<u32>(value)); |
|||
} |
|||
|
|||
void CoreData::SetMoleScale(u8 value) { |
|||
data.mole_scale.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMoleX(u8 value) { |
|||
data.mole_x.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetMoleY(u8 value) { |
|||
data.mole_y.Assign(value); |
|||
} |
|||
|
|||
void CoreData::SetNickname(Nickname nickname) { |
|||
name = nickname; |
|||
} |
|||
|
|||
FontRegion CoreData::GetFontRegion() const { |
|||
return static_cast<FontRegion>(data.font_region.Value()); |
|||
} |
|||
|
|||
FavoriteColor CoreData::GetFavoriteColor() const { |
|||
return static_cast<FavoriteColor>(data.favorite_color.Value()); |
|||
} |
|||
|
|||
Gender CoreData::GetGender() const { |
|||
return static_cast<Gender>(data.gender.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetHeight() const { |
|||
return static_cast<u8>(data.height.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetBuild() const { |
|||
return static_cast<u8>(data.build.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetType() const { |
|||
return static_cast<u8>(data.type.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetRegionMove() const { |
|||
return static_cast<u8>(data.region_move.Value()); |
|||
} |
|||
|
|||
FacelineType CoreData::GetFacelineType() const { |
|||
return static_cast<FacelineType>(data.faceline_type.Value()); |
|||
} |
|||
|
|||
FacelineColor CoreData::GetFacelineColor() const { |
|||
return static_cast<FacelineColor>(data.faceline_color.Value()); |
|||
} |
|||
|
|||
FacelineWrinkle CoreData::GetFacelineWrinkle() const { |
|||
return static_cast<FacelineWrinkle>(data.faceline_wrinkle.Value()); |
|||
} |
|||
|
|||
FacelineMake CoreData::GetFacelineMake() const { |
|||
return static_cast<FacelineMake>(data.faceline_makeup.Value()); |
|||
} |
|||
|
|||
HairType CoreData::GetHairType() const { |
|||
return static_cast<HairType>(data.hair_type.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetHairColor() const { |
|||
return static_cast<CommonColor>(data.hair_color.Value()); |
|||
} |
|||
|
|||
HairFlip CoreData::GetHairFlip() const { |
|||
return static_cast<HairFlip>(data.hair_flip.Value()); |
|||
} |
|||
|
|||
EyeType CoreData::GetEyeType() const { |
|||
return static_cast<EyeType>(data.eye_type.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetEyeColor() const { |
|||
return static_cast<CommonColor>(data.eye_color.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyeScale() const { |
|||
return static_cast<u8>(data.eye_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyeAspect() const { |
|||
return static_cast<u8>(data.eye_aspect.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyeRotate() const { |
|||
return static_cast<u8>(data.eye_rotate.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyeX() const { |
|||
return static_cast<u8>(data.eye_x.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyeY() const { |
|||
return static_cast<u8>(data.eye_y.Value()); |
|||
} |
|||
|
|||
EyebrowType CoreData::GetEyebrowType() const { |
|||
return static_cast<EyebrowType>(data.eyebrow_type.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetEyebrowColor() const { |
|||
return static_cast<CommonColor>(data.eyebrow_color.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyebrowScale() const { |
|||
return static_cast<u8>(data.eyebrow_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyebrowAspect() const { |
|||
return static_cast<u8>(data.eyebrow_aspect.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyebrowRotate() const { |
|||
return static_cast<u8>(data.eyebrow_rotate.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyebrowX() const { |
|||
return static_cast<u8>(data.eyebrow_x.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetEyebrowY() const { |
|||
return static_cast<u8>(data.eyebrow_y.Value()); |
|||
} |
|||
|
|||
NoseType CoreData::GetNoseType() const { |
|||
return static_cast<NoseType>(data.nose_type.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetNoseScale() const { |
|||
return static_cast<u8>(data.nose_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetNoseY() const { |
|||
return static_cast<u8>(data.nose_y.Value()); |
|||
} |
|||
|
|||
MouthType CoreData::GetMouthType() const { |
|||
return static_cast<MouthType>(data.mouth_type.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetMouthColor() const { |
|||
return static_cast<CommonColor>(data.mouth_color.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMouthScale() const { |
|||
return static_cast<u8>(data.mouth_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMouthAspect() const { |
|||
return static_cast<u8>(data.mouth_aspect.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMouthY() const { |
|||
return static_cast<u8>(data.mouth_y.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetBeardColor() const { |
|||
return static_cast<CommonColor>(data.beard_color.Value()); |
|||
} |
|||
|
|||
BeardType CoreData::GetBeardType() const { |
|||
return static_cast<BeardType>(data.beard_type.Value()); |
|||
} |
|||
|
|||
MustacheType CoreData::GetMustacheType() const { |
|||
return static_cast<MustacheType>(data.mustache_type.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMustacheScale() const { |
|||
return static_cast<u8>(data.mustache_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMustacheY() const { |
|||
return static_cast<u8>(data.mustache_y.Value()); |
|||
} |
|||
|
|||
GlassType CoreData::GetGlassType() const { |
|||
return static_cast<GlassType>(data.glasses_type.Value()); |
|||
} |
|||
|
|||
CommonColor CoreData::GetGlassColor() const { |
|||
return static_cast<CommonColor>(data.glasses_color.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetGlassScale() const { |
|||
return static_cast<u8>(data.glasses_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetGlassY() const { |
|||
return static_cast<u8>(data.glasses_y.Value()); |
|||
} |
|||
|
|||
MoleType CoreData::GetMoleType() const { |
|||
return static_cast<MoleType>(data.mole_type.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMoleScale() const { |
|||
return static_cast<u8>(data.mole_scale.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMoleX() const { |
|||
return static_cast<u8>(data.mole_x.Value()); |
|||
} |
|||
|
|||
u8 CoreData::GetMoleY() const { |
|||
return static_cast<u8>(data.mole_y.Value()); |
|||
} |
|||
|
|||
Nickname CoreData::GetNickname() const { |
|||
return name; |
|||
} |
|||
|
|||
Nickname CoreData::GetDefaultNickname() const { |
|||
return {u'n', u'o', u' ', u'n', u'a', u'm', u'e'}; |
|||
} |
|||
|
|||
Nickname CoreData::GetInvalidNickname() const { |
|||
return {u'?', u'?', u'?'}; |
|||
} |
|||
|
|||
} // namespace Service::Mii
|
|||
@ -0,0 +1,216 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/service/mii/mii_types.h" |
|||
|
|||
namespace Service::Mii { |
|||
|
|||
struct StoreDataBitFields { |
|||
union { |
|||
u32 word_0{}; |
|||
|
|||
BitField<0, 8, u32> hair_type; |
|||
BitField<8, 7, u32> height; |
|||
BitField<15, 1, u32> mole_type; |
|||
BitField<16, 7, u32> build; |
|||
BitField<23, 1, u32> hair_flip; |
|||
BitField<24, 7, u32> hair_color; |
|||
BitField<31, 1, u32> type; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_1{}; |
|||
|
|||
BitField<0, 7, u32> eye_color; |
|||
BitField<7, 1, u32> gender; |
|||
BitField<8, 7, u32> eyebrow_color; |
|||
BitField<16, 7, u32> mouth_color; |
|||
BitField<24, 7, u32> beard_color; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_2{}; |
|||
|
|||
BitField<0, 7, u32> glasses_color; |
|||
BitField<8, 6, u32> eye_type; |
|||
BitField<14, 2, u32> region_move; |
|||
BitField<16, 6, u32> mouth_type; |
|||
BitField<22, 2, u32> font_region; |
|||
BitField<24, 5, u32> eye_y; |
|||
BitField<29, 3, u32> glasses_scale; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_3{}; |
|||
|
|||
BitField<0, 5, u32> eyebrow_type; |
|||
BitField<5, 3, u32> mustache_type; |
|||
BitField<8, 5, u32> nose_type; |
|||
BitField<13, 3, u32> beard_type; |
|||
BitField<16, 5, u32> nose_y; |
|||
BitField<21, 3, u32> mouth_aspect; |
|||
BitField<24, 5, u32> mouth_y; |
|||
BitField<29, 3, u32> eyebrow_aspect; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_4{}; |
|||
|
|||
BitField<0, 5, u32> mustache_y; |
|||
BitField<5, 3, u32> eye_rotate; |
|||
BitField<8, 5, u32> glasses_y; |
|||
BitField<13, 3, u32> eye_aspect; |
|||
BitField<16, 5, u32> mole_x; |
|||
BitField<21, 3, u32> eye_scale; |
|||
BitField<24, 5, u32> mole_y; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_5{}; |
|||
|
|||
BitField<0, 5, u32> glasses_type; |
|||
BitField<8, 4, u32> favorite_color; |
|||
BitField<12, 4, u32> faceline_type; |
|||
BitField<16, 4, u32> faceline_color; |
|||
BitField<20, 4, u32> faceline_wrinkle; |
|||
BitField<24, 4, u32> faceline_makeup; |
|||
BitField<28, 4, u32> eye_x; |
|||
}; |
|||
|
|||
union { |
|||
u32 word_6{}; |
|||
|
|||
BitField<0, 4, u32> eyebrow_scale; |
|||
BitField<4, 4, u32> eyebrow_rotate; |
|||
BitField<8, 4, u32> eyebrow_x; |
|||
BitField<12, 4, u32> eyebrow_y; |
|||
BitField<16, 4, u32> nose_scale; |
|||
BitField<20, 4, u32> mouth_scale; |
|||
BitField<24, 4, u32> mustache_scale; |
|||
BitField<28, 4, u32> mole_scale; |
|||
}; |
|||
}; |
|||
static_assert(sizeof(StoreDataBitFields) == 0x1c, "StoreDataBitFields has incorrect size."); |
|||
static_assert(std::is_trivially_copyable_v<StoreDataBitFields>, |
|||
"StoreDataBitFields is not trivially copyable."); |
|||
|
|||
class CoreData { |
|||
public: |
|||
void SetDefault(); |
|||
void BuildRandom(Age age, Gender gender, Race race); |
|||
|
|||
u32 IsValid() const; |
|||
|
|||
void SetFontRegion(FontRegion value); |
|||
void SetFavoriteColor(FavoriteColor value); |
|||
void SetGender(Gender value); |
|||
void SetHeight(u8 value); |
|||
void SetBuild(u8 value); |
|||
void SetType(u8 value); |
|||
void SetRegionMove(u8 value); |
|||
void SetFacelineType(FacelineType value); |
|||
void SetFacelineColor(FacelineColor value); |
|||
void SetFacelineWrinkle(FacelineWrinkle value); |
|||
void SetFacelineMake(FacelineMake value); |
|||
void SetHairType(HairType value); |
|||
void SetHairColor(CommonColor value); |
|||
void SetHairFlip(HairFlip value); |
|||
void SetEyeType(EyeType value); |
|||
void SetEyeColor(CommonColor value); |
|||
void SetEyeScale(u8 value); |
|||
void SetEyeAspect(u8 value); |
|||
void SetEyeRotate(u8 value); |
|||
void SetEyeX(u8 value); |
|||
void SetEyeY(u8 value); |
|||
void SetEyebrowType(EyebrowType value); |
|||
void SetEyebrowColor(CommonColor value); |
|||
void SetEyebrowScale(u8 value); |
|||
void SetEyebrowAspect(u8 value); |
|||
void SetEyebrowRotate(u8 value); |
|||
void SetEyebrowX(u8 value); |
|||
void SetEyebrowY(u8 value); |
|||
void SetNoseType(NoseType value); |
|||
void SetNoseScale(u8 value); |
|||
void SetNoseY(u8 value); |
|||
void SetMouthType(u8 value); |
|||
void SetMouthColor(CommonColor value); |
|||
void SetMouthScale(u8 value); |
|||
void SetMouthAspect(u8 value); |
|||
void SetMouthY(u8 value); |
|||
void SetBeardColor(CommonColor value); |
|||
void SetBeardType(BeardType value); |
|||
void SetMustacheType(MustacheType value); |
|||
void SetMustacheScale(u8 value); |
|||
void SetMustacheY(u8 value); |
|||
void SetGlassType(GlassType value); |
|||
void SetGlassColor(CommonColor value); |
|||
void SetGlassScale(u8 value); |
|||
void SetGlassY(u8 value); |
|||
void SetMoleType(MoleType value); |
|||
void SetMoleScale(u8 value); |
|||
void SetMoleX(u8 value); |
|||
void SetMoleY(u8 value); |
|||
void SetNickname(Nickname nickname); |
|||
|
|||
FontRegion GetFontRegion() const; |
|||
FavoriteColor GetFavoriteColor() const; |
|||
Gender GetGender() const; |
|||
u8 GetHeight() const; |
|||
u8 GetBuild() const; |
|||
u8 GetType() const; |
|||
u8 GetRegionMove() const; |
|||
FacelineType GetFacelineType() const; |
|||
FacelineColor GetFacelineColor() const; |
|||
FacelineWrinkle GetFacelineWrinkle() const; |
|||
FacelineMake GetFacelineMake() const; |
|||
HairType GetHairType() const; |
|||
CommonColor GetHairColor() const; |
|||
HairFlip GetHairFlip() const; |
|||
EyeType GetEyeType() const; |
|||
CommonColor GetEyeColor() const; |
|||
u8 GetEyeScale() const; |
|||
u8 GetEyeAspect() const; |
|||
u8 GetEyeRotate() const; |
|||
u8 GetEyeX() const; |
|||
u8 GetEyeY() const; |
|||
EyebrowType GetEyebrowType() const; |
|||
CommonColor GetEyebrowColor() const; |
|||
u8 GetEyebrowScale() const; |
|||
u8 GetEyebrowAspect() const; |
|||
u8 GetEyebrowRotate() const; |
|||
u8 GetEyebrowX() const; |
|||
u8 GetEyebrowY() const; |
|||
NoseType GetNoseType() const; |
|||
u8 GetNoseScale() const; |
|||
u8 GetNoseY() const; |
|||
MouthType GetMouthType() const; |
|||
CommonColor GetMouthColor() const; |
|||
u8 GetMouthScale() const; |
|||
u8 GetMouthAspect() const; |
|||
u8 GetMouthY() const; |
|||
CommonColor GetBeardColor() const; |
|||
BeardType GetBeardType() const; |
|||
MustacheType GetMustacheType() const; |
|||
u8 GetMustacheScale() const; |
|||
u8 GetMustacheY() const; |
|||
GlassType GetGlassType() const; |
|||
CommonColor GetGlassColor() const; |
|||
u8 GetGlassScale() const; |
|||
u8 GetGlassY() const; |
|||
MoleType GetMoleType() const; |
|||
u8 GetMoleScale() const; |
|||
u8 GetMoleX() const; |
|||
u8 GetMoleY() const; |
|||
Nickname GetNickname() const; |
|||
Nickname GetDefaultNickname() const; |
|||
Nickname GetInvalidNickname() const; |
|||
|
|||
private: |
|||
StoreDataBitFields data{}; |
|||
Nickname name{}; |
|||
}; |
|||
static_assert(sizeof(CoreData) == 0x30, "CoreData has incorrect size."); |
|||
|
|||
}; // namespace Service::Mii |
|||
1395
src/core/hle/service/mii/types/raw_data.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,73 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include "core/hle/service/mii/mii_types.h" |
|||
|
|||
namespace Service::Mii::RawData { |
|||
|
|||
struct RandomMiiValues { |
|||
std::array<u8, 188> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size."); |
|||
|
|||
struct RandomMiiData4 { |
|||
u32 gender{}; |
|||
u32 age{}; |
|||
u32 race{}; |
|||
u32 values_count{}; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData4) == 0xcc, "RandomMiiData4 has incorrect size."); |
|||
|
|||
struct RandomMiiData3 { |
|||
u32 arg_1; |
|||
u32 arg_2; |
|||
u32 values_count; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData3) == 0xc8, "RandomMiiData3 has incorrect size."); |
|||
|
|||
struct RandomMiiData2 { |
|||
u32 arg_1; |
|||
u32 values_count; |
|||
std::array<u32, 47> values{}; |
|||
}; |
|||
static_assert(sizeof(RandomMiiData2) == 0xc4, "RandomMiiData2 has incorrect size."); |
|||
|
|||
extern const std::array<Service::Mii::DefaultMii, 2> BaseMii; |
|||
extern const std::array<Service::Mii::DefaultMii, 6> DefaultMii; |
|||
|
|||
extern const std::array<u8, 62> EyeRotateLookup; |
|||
extern const std::array<u8, 24> EyebrowRotateLookup; |
|||
|
|||
extern const std::array<RandomMiiData4, 18> RandomMiiFaceline; |
|||
extern const std::array<RandomMiiData3, 6> RandomMiiFacelineColor; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiFacelineWrinkle; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiFacelineMakeup; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiHairType; |
|||
extern const std::array<RandomMiiData3, 9> RandomMiiHairColor; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiEyeType; |
|||
extern const std::array<RandomMiiData2, 3> RandomMiiEyeColor; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiEyebrowType; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiNoseType; |
|||
extern const std::array<RandomMiiData4, 18> RandomMiiMouthType; |
|||
extern const std::array<RandomMiiData2, 3> RandomMiiGlassType; |
|||
|
|||
u8 FromVer3GetFacelineColor(u8 color); |
|||
u8 FromVer3GetHairColor(u8 color); |
|||
u8 FromVer3GetEyeColor(u8 color); |
|||
u8 FromVer3GetMouthlineColor(u8 color); |
|||
u8 FromVer3GetGlassColor(u8 color); |
|||
u8 FromVer3GetGlassType(u8 type); |
|||
|
|||
FacelineColor GetFacelineColorFromVer3(u32 color); |
|||
CommonColor GetHairColorFromVer3(u32 color); |
|||
CommonColor GetEyeColorFromVer3(u32 color); |
|||
CommonColor GetMouthColorFromVer3(u32 color); |
|||
CommonColor GetGlassColorFromVer3(u32 color); |
|||
|
|||
} // namespace Service::Mii::RawData |
|||
@ -0,0 +1,643 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "core/hle/service/mii/mii_util.h"
|
|||
#include "core/hle/service/mii/types/raw_data.h"
|
|||
#include "core/hle/service/mii/types/store_data.h"
|
|||
|
|||
namespace Service::Mii { |
|||
|
|||
void StoreData::BuildDefault(u32 mii_index) { |
|||
const auto& default_mii = RawData::DefaultMii[mii_index]; |
|||
core_data.SetDefault(); |
|||
|
|||
core_data.SetFacelineType(static_cast<FacelineType>(default_mii.face_type)); |
|||
core_data.SetFacelineColor( |
|||
RawData::GetFacelineColorFromVer3(static_cast<u8>(default_mii.face_color))); |
|||
core_data.SetFacelineWrinkle(static_cast<FacelineWrinkle>(default_mii.face_wrinkle)); |
|||
core_data.SetFacelineMake(static_cast<FacelineMake>(default_mii.face_makeup)); |
|||
|
|||
core_data.SetHairType(static_cast<HairType>(default_mii.hair_type)); |
|||
core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.hair_color))); |
|||
core_data.SetHairFlip(static_cast<HairFlip>(default_mii.hair_flip)); |
|||
core_data.SetEyeType(static_cast<EyeType>(default_mii.eye_type)); |
|||
core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast<u8>(default_mii.eye_color))); |
|||
core_data.SetEyeScale(static_cast<u8>(default_mii.eye_scale)); |
|||
core_data.SetEyeAspect(static_cast<u8>(default_mii.eye_aspect)); |
|||
core_data.SetEyeRotate(static_cast<u8>(default_mii.eye_rotate)); |
|||
core_data.SetEyeX(static_cast<u8>(default_mii.eye_x)); |
|||
core_data.SetEyeY(static_cast<u8>(default_mii.eye_y)); |
|||
|
|||
core_data.SetEyebrowType(static_cast<EyebrowType>(default_mii.eyebrow_type)); |
|||
core_data.SetEyebrowColor( |
|||
RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.eyebrow_color))); |
|||
core_data.SetEyebrowScale(static_cast<u8>(default_mii.eyebrow_scale)); |
|||
core_data.SetEyebrowAspect(static_cast<u8>(default_mii.eyebrow_aspect)); |
|||
core_data.SetEyebrowRotate(static_cast<u8>(default_mii.eyebrow_rotate)); |
|||
core_data.SetEyebrowX(static_cast<u8>(default_mii.eyebrow_x)); |
|||
core_data.SetEyebrowY(static_cast<u8>(default_mii.eyebrow_y)); |
|||
|
|||
core_data.SetNoseType(static_cast<NoseType>(default_mii.nose_type)); |
|||
core_data.SetNoseScale(static_cast<u8>(default_mii.nose_scale)); |
|||
core_data.SetNoseY(static_cast<u8>(default_mii.nose_y)); |
|||
|
|||
core_data.SetMouthType(static_cast<u8>(default_mii.mouth_type)); |
|||
core_data.SetMouthColor( |
|||
RawData::GetMouthColorFromVer3(static_cast<u8>(default_mii.mouth_color))); |
|||
core_data.SetMouthScale(static_cast<u8>(default_mii.mouth_scale)); |
|||
core_data.SetMouthAspect(static_cast<u8>(default_mii.mouth_aspect)); |
|||
core_data.SetMouthY(static_cast<u8>(default_mii.mouth_y)); |
|||
|
|||
core_data.SetMustacheType(static_cast<MustacheType>(default_mii.mustache_type)); |
|||
core_data.SetBeardType(static_cast<BeardType>(default_mii.beard_type)); |
|||
core_data.SetBeardColor( |
|||
RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.beard_color))); |
|||
core_data.SetMustacheScale(static_cast<u8>(default_mii.mustache_scale)); |
|||
core_data.SetMustacheY(static_cast<u8>(default_mii.mustache_y)); |
|||
|
|||
core_data.SetGlassType(static_cast<GlassType>(default_mii.glasses_type)); |
|||
core_data.SetGlassColor( |
|||
RawData::GetGlassColorFromVer3(static_cast<u8>(default_mii.glasses_color))); |
|||
core_data.SetGlassScale(static_cast<u8>(default_mii.glasses_scale)); |
|||
core_data.SetGlassY(static_cast<u8>(default_mii.glasses_y)); |
|||
|
|||
core_data.SetMoleType(static_cast<MoleType>(default_mii.mole_type)); |
|||
core_data.SetMoleScale(static_cast<u8>(default_mii.mole_scale)); |
|||
core_data.SetMoleX(static_cast<u8>(default_mii.mole_x)); |
|||
core_data.SetMoleY(static_cast<u8>(default_mii.mole_y)); |
|||
|
|||
core_data.SetHeight(static_cast<u8>(default_mii.height)); |
|||
core_data.SetBuild(static_cast<u8>(default_mii.weight)); |
|||
core_data.SetGender(static_cast<Gender>(default_mii.gender)); |
|||
core_data.SetFavoriteColor(static_cast<FavoriteColor>(default_mii.favorite_color)); |
|||
core_data.SetRegionMove(static_cast<u8>(default_mii.region_move)); |
|||
core_data.SetFontRegion(static_cast<FontRegion>(default_mii.font_region)); |
|||
core_data.SetType(static_cast<u8>(default_mii.type)); |
|||
core_data.SetNickname(default_mii.nickname); |
|||
|
|||
const auto device_id = MiiUtil::GetDeviceId(); |
|||
create_id = MiiUtil::MakeCreateId(); |
|||
device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); |
|||
data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); |
|||
} |
|||
|
|||
void StoreData::BuildBase(Gender gender) { |
|||
const auto& default_mii = RawData::BaseMii[gender == Gender::Female ? 1 : 0]; |
|||
core_data.SetDefault(); |
|||
|
|||
core_data.SetFacelineType(static_cast<FacelineType>(default_mii.face_type)); |
|||
core_data.SetFacelineColor( |
|||
RawData::GetFacelineColorFromVer3(static_cast<u8>(default_mii.face_color))); |
|||
core_data.SetFacelineWrinkle(static_cast<FacelineWrinkle>(default_mii.face_wrinkle)); |
|||
core_data.SetFacelineMake(static_cast<FacelineMake>(default_mii.face_makeup)); |
|||
|
|||
core_data.SetHairType(static_cast<HairType>(default_mii.hair_type)); |
|||
core_data.SetHairColor(RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.hair_color))); |
|||
core_data.SetHairFlip(static_cast<HairFlip>(default_mii.hair_flip)); |
|||
core_data.SetEyeType(static_cast<EyeType>(default_mii.eye_type)); |
|||
core_data.SetEyeColor(RawData::GetEyeColorFromVer3(static_cast<u8>(default_mii.eye_color))); |
|||
core_data.SetEyeScale(static_cast<u8>(default_mii.eye_scale)); |
|||
core_data.SetEyeAspect(static_cast<u8>(default_mii.eye_aspect)); |
|||
core_data.SetEyeRotate(static_cast<u8>(default_mii.eye_rotate)); |
|||
core_data.SetEyeX(static_cast<u8>(default_mii.eye_x)); |
|||
core_data.SetEyeY(static_cast<u8>(default_mii.eye_y)); |
|||
|
|||
core_data.SetEyebrowType(static_cast<EyebrowType>(default_mii.eyebrow_type)); |
|||
core_data.SetEyebrowColor( |
|||
RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.eyebrow_color))); |
|||
core_data.SetEyebrowScale(static_cast<u8>(default_mii.eyebrow_scale)); |
|||
core_data.SetEyebrowAspect(static_cast<u8>(default_mii.eyebrow_aspect)); |
|||
core_data.SetEyebrowRotate(static_cast<u8>(default_mii.eyebrow_rotate)); |
|||
core_data.SetEyebrowX(static_cast<u8>(default_mii.eyebrow_x)); |
|||
core_data.SetEyebrowY(static_cast<u8>(default_mii.eyebrow_y)); |
|||
|
|||
core_data.SetNoseType(static_cast<NoseType>(default_mii.nose_type)); |
|||
core_data.SetNoseScale(static_cast<u8>(default_mii.nose_scale)); |
|||
core_data.SetNoseY(static_cast<u8>(default_mii.nose_y)); |
|||
|
|||
core_data.SetMouthType(static_cast<u8>(default_mii.mouth_type)); |
|||
core_data.SetMouthColor( |
|||
RawData::GetMouthColorFromVer3(static_cast<u8>(default_mii.mouth_color))); |
|||
core_data.SetMouthScale(static_cast<u8>(default_mii.mouth_scale)); |
|||
core_data.SetMouthAspect(static_cast<u8>(default_mii.mouth_aspect)); |
|||
core_data.SetMouthY(static_cast<u8>(default_mii.mouth_y)); |
|||
|
|||
core_data.SetMustacheType(static_cast<MustacheType>(default_mii.mustache_type)); |
|||
core_data.SetBeardType(static_cast<BeardType>(default_mii.beard_type)); |
|||
core_data.SetBeardColor( |
|||
RawData::GetHairColorFromVer3(static_cast<u8>(default_mii.beard_color))); |
|||
core_data.SetMustacheScale(static_cast<u8>(default_mii.mustache_scale)); |
|||
core_data.SetMustacheY(static_cast<u8>(default_mii.mustache_y)); |
|||
|
|||
core_data.SetGlassType(static_cast<GlassType>(default_mii.glasses_type)); |
|||
core_data.SetGlassColor( |
|||
RawData::GetGlassColorFromVer3(static_cast<u8>(default_mii.glasses_color))); |
|||
core_data.SetGlassScale(static_cast<u8>(default_mii.glasses_scale)); |
|||
core_data.SetGlassY(static_cast<u8>(default_mii.glasses_y)); |
|||
|
|||
core_data.SetMoleType(static_cast<MoleType>(default_mii.mole_type)); |
|||
core_data.SetMoleScale(static_cast<u8>(default_mii.mole_scale)); |
|||
core_data.SetMoleX(static_cast<u8>(default_mii.mole_x)); |
|||
core_data.SetMoleY(static_cast<u8>(default_mii.mole_y)); |
|||
|
|||
core_data.SetHeight(static_cast<u8>(default_mii.height)); |
|||
core_data.SetBuild(static_cast<u8>(default_mii.weight)); |
|||
core_data.SetGender(static_cast<Gender>(default_mii.gender)); |
|||
core_data.SetFavoriteColor(static_cast<FavoriteColor>(default_mii.favorite_color)); |
|||
core_data.SetRegionMove(static_cast<u8>(default_mii.region_move)); |
|||
core_data.SetFontRegion(static_cast<FontRegion>(default_mii.font_region)); |
|||
core_data.SetType(static_cast<u8>(default_mii.type)); |
|||
core_data.SetNickname(default_mii.nickname); |
|||
|
|||
const auto device_id = MiiUtil::GetDeviceId(); |
|||
create_id = MiiUtil::MakeCreateId(); |
|||
device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); |
|||
data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); |
|||
} |
|||
|
|||
void StoreData::BuildRandom(Age age, Gender gender, Race race) { |
|||
core_data.BuildRandom(age, gender, race); |
|||
const auto device_id = MiiUtil::GetDeviceId(); |
|||
create_id = MiiUtil::MakeCreateId(); |
|||
device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); |
|||
data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); |
|||
} |
|||
|
|||
void StoreData::SetInvalidName() { |
|||
const auto& invalid_name = core_data.GetInvalidNickname(); |
|||
const auto device_id = MiiUtil::GetDeviceId(); |
|||
core_data.SetNickname(invalid_name); |
|||
device_crc = MiiUtil::CalculateCrc16(&device_id, sizeof(Common::UUID)); |
|||
data_crc = MiiUtil::CalculateCrc16(&core_data, sizeof(CoreData)); |
|||
} |
|||
|
|||
bool StoreData::IsSpecial() const { |
|||
return GetType() == 1; |
|||
} |
|||
|
|||
u32 StoreData::IsValid() const { |
|||
// TODO: complete this
|
|||
return 0; |
|||
} |
|||
|
|||
void StoreData::SetFontRegion(FontRegion value) { |
|||
core_data.SetFontRegion(value); |
|||
} |
|||
|
|||
void StoreData::SetFavoriteColor(FavoriteColor value) { |
|||
core_data.SetFavoriteColor(value); |
|||
} |
|||
|
|||
void StoreData::SetGender(Gender value) { |
|||
core_data.SetGender(value); |
|||
} |
|||
|
|||
void StoreData::SetHeight(u8 value) { |
|||
core_data.SetHeight(value); |
|||
} |
|||
|
|||
void StoreData::SetBuild(u8 value) { |
|||
core_data.SetBuild(value); |
|||
} |
|||
|
|||
void StoreData::SetType(u8 value) { |
|||
core_data.SetType(value); |
|||
} |
|||
|
|||
void StoreData::SetRegionMove(u8 value) { |
|||
core_data.SetRegionMove(value); |
|||
} |
|||
|
|||
void StoreData::SetFacelineType(FacelineType value) { |
|||
core_data.SetFacelineType(value); |
|||
} |
|||
|
|||
void StoreData::SetFacelineColor(FacelineColor value) { |
|||
core_data.SetFacelineColor(value); |
|||
} |
|||
|
|||
void StoreData::SetFacelineWrinkle(FacelineWrinkle value) { |
|||
core_data.SetFacelineWrinkle(value); |
|||
} |
|||
|
|||
void StoreData::SetFacelineMake(FacelineMake value) { |
|||
core_data.SetFacelineMake(value); |
|||
} |
|||
|
|||
void StoreData::SetHairType(HairType value) { |
|||
core_data.SetHairType(value); |
|||
} |
|||
|
|||
void StoreData::SetHairColor(CommonColor value) { |
|||
core_data.SetHairColor(value); |
|||
} |
|||
|
|||
void StoreData::SetHairFlip(HairFlip value) { |
|||
core_data.SetHairFlip(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeType(EyeType value) { |
|||
core_data.SetEyeType(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeColor(CommonColor value) { |
|||
core_data.SetEyeColor(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeScale(u8 value) { |
|||
core_data.SetEyeScale(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeAspect(u8 value) { |
|||
core_data.SetEyeAspect(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeRotate(u8 value) { |
|||
core_data.SetEyeRotate(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeX(u8 value) { |
|||
core_data.SetEyeX(value); |
|||
} |
|||
|
|||
void StoreData::SetEyeY(u8 value) { |
|||
core_data.SetEyeY(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowType(EyebrowType value) { |
|||
core_data.SetEyebrowType(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowColor(CommonColor value) { |
|||
core_data.SetEyebrowColor(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowScale(u8 value) { |
|||
core_data.SetEyebrowScale(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowAspect(u8 value) { |
|||
core_data.SetEyebrowAspect(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowRotate(u8 value) { |
|||
core_data.SetEyebrowRotate(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowX(u8 value) { |
|||
core_data.SetEyebrowX(value); |
|||
} |
|||
|
|||
void StoreData::SetEyebrowY(u8 value) { |
|||
core_data.SetEyebrowY(value); |
|||
} |
|||
|
|||
void StoreData::SetNoseType(NoseType value) { |
|||
core_data.SetNoseType(value); |
|||
} |
|||
|
|||
void StoreData::SetNoseScale(u8 value) { |
|||
core_data.SetNoseScale(value); |
|||
} |
|||
|
|||
void StoreData::SetNoseY(u8 value) { |
|||
core_data.SetNoseY(value); |
|||
} |
|||
|
|||
void StoreData::SetMouthType(u8 value) { |
|||
core_data.SetMouthType(value); |
|||
} |
|||
|
|||
void StoreData::SetMouthColor(CommonColor value) { |
|||
core_data.SetMouthColor(value); |
|||
} |
|||
|
|||
void StoreData::SetMouthScale(u8 value) { |
|||
core_data.SetMouthScale(value); |
|||
} |
|||
|
|||
void StoreData::SetMouthAspect(u8 value) { |
|||
core_data.SetMouthAspect(value); |
|||
} |
|||
|
|||
void StoreData::SetMouthY(u8 value) { |
|||
core_data.SetMouthY(value); |
|||
} |
|||
|
|||
void StoreData::SetBeardColor(CommonColor value) { |
|||
core_data.SetBeardColor(value); |
|||
} |
|||
|
|||
void StoreData::SetBeardType(BeardType value) { |
|||
core_data.SetBeardType(value); |
|||
} |
|||
|
|||
void StoreData::SetMustacheType(MustacheType value) { |
|||
core_data.SetMustacheType(value); |
|||
} |
|||
|
|||
void StoreData::SetMustacheScale(u8 value) { |
|||
core_data.SetMustacheScale(value); |
|||
} |
|||
|
|||
void StoreData::SetMustacheY(u8 value) { |
|||
core_data.SetMustacheY(value); |
|||
} |
|||
|
|||
void StoreData::SetGlassType(GlassType value) { |
|||
core_data.SetGlassType(value); |
|||
} |
|||
|
|||
void StoreData::SetGlassColor(CommonColor value) { |
|||
core_data.SetGlassColor(value); |
|||
} |
|||
|
|||
void StoreData::SetGlassScale(u8 value) { |
|||
core_data.SetGlassScale(value); |
|||
} |
|||
|
|||
void StoreData::SetGlassY(u8 value) { |
|||
core_data.SetGlassY(value); |
|||
} |
|||
|
|||
void StoreData::SetMoleType(MoleType value) { |
|||
core_data.SetMoleType(value); |
|||
} |
|||
|
|||
void StoreData::SetMoleScale(u8 value) { |
|||
core_data.SetMoleScale(value); |
|||
} |
|||
|
|||
void StoreData::SetMoleX(u8 value) { |
|||
core_data.SetMoleX(value); |
|||
} |
|||
|
|||
void StoreData::SetMoleY(u8 value) { |
|||
core_data.SetMoleY(value); |
|||
} |
|||
|
|||
void StoreData::SetNickname(Nickname value) { |
|||
core_data.SetNickname(value); |
|||
} |
|||
|
|||
Common::UUID StoreData::GetCreateId() const { |
|||
return create_id; |
|||
} |
|||
|
|||
FontRegion StoreData::GetFontRegion() const { |
|||
return static_cast<FontRegion>(core_data.GetFontRegion()); |
|||
} |
|||
|
|||
FavoriteColor StoreData::GetFavoriteColor() const { |
|||
return core_data.GetFavoriteColor(); |
|||
} |
|||
|
|||
Gender StoreData::GetGender() const { |
|||
return core_data.GetGender(); |
|||
} |
|||
|
|||
u8 StoreData::GetHeight() const { |
|||
return core_data.GetHeight(); |
|||
} |
|||
|
|||
u8 StoreData::GetBuild() const { |
|||
return core_data.GetBuild(); |
|||
} |
|||
|
|||
u8 StoreData::GetType() const { |
|||
return core_data.GetType(); |
|||
} |
|||
|
|||
u8 StoreData::GetRegionMove() const { |
|||
return core_data.GetRegionMove(); |
|||
} |
|||
|
|||
FacelineType StoreData::GetFacelineType() const { |
|||
return core_data.GetFacelineType(); |
|||
} |
|||
|
|||
FacelineColor StoreData::GetFacelineColor() const { |
|||
return core_data.GetFacelineColor(); |
|||
} |
|||
|
|||
FacelineWrinkle StoreData::GetFacelineWrinkle() const { |
|||
return core_data.GetFacelineWrinkle(); |
|||
} |
|||
|
|||
FacelineMake StoreData::GetFacelineMake() const { |
|||
return core_data.GetFacelineMake(); |
|||
} |
|||
|
|||
HairType StoreData::GetHairType() const { |
|||
return core_data.GetHairType(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetHairColor() const { |
|||
return core_data.GetHairColor(); |
|||
} |
|||
|
|||
HairFlip StoreData::GetHairFlip() const { |
|||
return core_data.GetHairFlip(); |
|||
} |
|||
|
|||
EyeType StoreData::GetEyeType() const { |
|||
return core_data.GetEyeType(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetEyeColor() const { |
|||
return core_data.GetEyeColor(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyeScale() const { |
|||
return core_data.GetEyeScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyeAspect() const { |
|||
return core_data.GetEyeAspect(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyeRotate() const { |
|||
return core_data.GetEyeRotate(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyeX() const { |
|||
return core_data.GetEyeX(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyeY() const { |
|||
return core_data.GetEyeY(); |
|||
} |
|||
|
|||
EyebrowType StoreData::GetEyebrowType() const { |
|||
return core_data.GetEyebrowType(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetEyebrowColor() const { |
|||
return core_data.GetEyebrowColor(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyebrowScale() const { |
|||
return core_data.GetEyebrowScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyebrowAspect() const { |
|||
return core_data.GetEyebrowAspect(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyebrowRotate() const { |
|||
return core_data.GetEyebrowRotate(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyebrowX() const { |
|||
return core_data.GetEyebrowX(); |
|||
} |
|||
|
|||
u8 StoreData::GetEyebrowY() const { |
|||
return core_data.GetEyebrowY(); |
|||
} |
|||
|
|||
NoseType StoreData::GetNoseType() const { |
|||
return core_data.GetNoseType(); |
|||
} |
|||
|
|||
u8 StoreData::GetNoseScale() const { |
|||
return core_data.GetNoseScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetNoseY() const { |
|||
return core_data.GetNoseY(); |
|||
} |
|||
|
|||
MouthType StoreData::GetMouthType() const { |
|||
return core_data.GetMouthType(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetMouthColor() const { |
|||
return core_data.GetMouthColor(); |
|||
} |
|||
|
|||
u8 StoreData::GetMouthScale() const { |
|||
return core_data.GetMouthScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetMouthAspect() const { |
|||
return core_data.GetMouthAspect(); |
|||
} |
|||
|
|||
u8 StoreData::GetMouthY() const { |
|||
return core_data.GetMouthY(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetBeardColor() const { |
|||
return core_data.GetBeardColor(); |
|||
} |
|||
|
|||
BeardType StoreData::GetBeardType() const { |
|||
return core_data.GetBeardType(); |
|||
} |
|||
|
|||
MustacheType StoreData::GetMustacheType() const { |
|||
return core_data.GetMustacheType(); |
|||
} |
|||
|
|||
u8 StoreData::GetMustacheScale() const { |
|||
return core_data.GetMustacheScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetMustacheY() const { |
|||
return core_data.GetMustacheY(); |
|||
} |
|||
|
|||
GlassType StoreData::GetGlassType() const { |
|||
return core_data.GetGlassType(); |
|||
} |
|||
|
|||
CommonColor StoreData::GetGlassColor() const { |
|||
return core_data.GetGlassColor(); |
|||
} |
|||
|
|||
u8 StoreData::GetGlassScale() const { |
|||
return core_data.GetGlassScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetGlassY() const { |
|||
return core_data.GetGlassY(); |
|||
} |
|||
|
|||
MoleType StoreData::GetMoleType() const { |
|||
return core_data.GetMoleType(); |
|||
} |
|||
|
|||
u8 StoreData::GetMoleScale() const { |
|||
return core_data.GetMoleScale(); |
|||
} |
|||
|
|||
u8 StoreData::GetMoleX() const { |
|||
return core_data.GetMoleX(); |
|||
} |
|||
|
|||
u8 StoreData::GetMoleY() const { |
|||
return core_data.GetMoleY(); |
|||
} |
|||
|
|||
Nickname StoreData::GetNickname() const { |
|||
return core_data.GetNickname(); |
|||
} |
|||
|
|||
bool StoreData::operator==(const StoreData& data) { |
|||
bool is_identical = data.core_data.IsValid() == 0; |
|||
is_identical &= core_data.GetNickname().data == data.core_data.GetNickname().data; |
|||
is_identical &= GetCreateId() == data.GetCreateId(); |
|||
is_identical &= GetFontRegion() == data.GetFontRegion(); |
|||
is_identical &= GetFavoriteColor() == data.GetFavoriteColor(); |
|||
is_identical &= GetGender() == data.GetGender(); |
|||
is_identical &= GetHeight() == data.GetHeight(); |
|||
is_identical &= GetBuild() == data.GetBuild(); |
|||
is_identical &= GetType() == data.GetType(); |
|||
is_identical &= GetRegionMove() == data.GetRegionMove(); |
|||
is_identical &= GetFacelineType() == data.GetFacelineType(); |
|||
is_identical &= GetFacelineColor() == data.GetFacelineColor(); |
|||
is_identical &= GetFacelineWrinkle() == data.GetFacelineWrinkle(); |
|||
is_identical &= GetFacelineMake() == data.GetFacelineMake(); |
|||
is_identical &= GetHairType() == data.GetHairType(); |
|||
is_identical &= GetHairColor() == data.GetHairColor(); |
|||
is_identical &= GetHairFlip() == data.GetHairFlip(); |
|||
is_identical &= GetEyeType() == data.GetEyeType(); |
|||
is_identical &= GetEyeColor() == data.GetEyeColor(); |
|||
is_identical &= GetEyeScale() == data.GetEyeScale(); |
|||
is_identical &= GetEyeAspect() == data.GetEyeAspect(); |
|||
is_identical &= GetEyeRotate() == data.GetEyeRotate(); |
|||
is_identical &= GetEyeX() == data.GetEyeX(); |
|||
is_identical &= GetEyeY() == data.GetEyeY(); |
|||
is_identical &= GetEyebrowType() == data.GetEyebrowType(); |
|||
is_identical &= GetEyebrowColor() == data.GetEyebrowColor(); |
|||
is_identical &= GetEyebrowScale() == data.GetEyebrowScale(); |
|||
is_identical &= GetEyebrowAspect() == data.GetEyebrowAspect(); |
|||
is_identical &= GetEyebrowRotate() == data.GetEyebrowRotate(); |
|||
is_identical &= GetEyebrowX() == data.GetEyebrowX(); |
|||
is_identical &= GetEyebrowY() == data.GetEyebrowY(); |
|||
is_identical &= GetNoseType() == data.GetNoseType(); |
|||
is_identical &= GetNoseScale() == data.GetNoseScale(); |
|||
is_identical &= GetNoseY() == data.GetNoseY(); |
|||
is_identical &= GetMouthType() == data.GetMouthType(); |
|||
is_identical &= GetMouthColor() == data.GetMouthColor(); |
|||
is_identical &= GetMouthScale() == data.GetMouthScale(); |
|||
is_identical &= GetMouthAspect() == data.GetMouthAspect(); |
|||
is_identical &= GetMouthY() == data.GetMouthY(); |
|||
is_identical &= GetBeardColor() == data.GetBeardColor(); |
|||
is_identical &= GetBeardType() == data.GetBeardType(); |
|||
is_identical &= GetMustacheType() == data.GetMustacheType(); |
|||
is_identical &= GetMustacheScale() == data.GetMustacheScale(); |
|||
is_identical &= GetMustacheY() == data.GetMustacheY(); |
|||
is_identical &= GetGlassType() == data.GetGlassType(); |
|||
is_identical &= GetGlassColor() == data.GetGlassColor(); |
|||
is_identical &= GetGlassScale() == data.GetGlassScale(); |
|||
is_identical &= GetGlassY() == data.GetGlassY(); |
|||
is_identical &= GetMoleType() == data.GetMoleType(); |
|||
is_identical &= GetMoleScale() == data.GetMoleScale(); |
|||
is_identical &= GetMoleX() == data.GetMoleX(); |
|||
is_identical &= data.GetMoleY() == data.GetMoleY(); |
|||
return is_identical; |
|||
} |
|||
|
|||
} // namespace Service::Mii
|
|||
@ -0,0 +1,145 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/service/mii/mii_types.h" |
|||
#include "core/hle/service/mii/types/core_data.h" |
|||
|
|||
namespace Service::Mii { |
|||
|
|||
class StoreData { |
|||
public: |
|||
// nn::mii::detail::StoreDataRaw::BuildDefault |
|||
void BuildDefault(u32 mii_index); |
|||
// nn::mii::detail::StoreDataRaw::BuildDefault |
|||
|
|||
void BuildBase(Gender gender); |
|||
// nn::mii::detail::StoreDataRaw::BuildRandom |
|||
void BuildRandom(Age age, Gender gender, Race race); |
|||
|
|||
bool IsSpecial() const; |
|||
|
|||
u32 IsValid() const; |
|||
|
|||
void SetFontRegion(FontRegion value); |
|||
void SetFavoriteColor(FavoriteColor value); |
|||
void SetGender(Gender value); |
|||
void SetHeight(u8 value); |
|||
void SetBuild(u8 value); |
|||
void SetType(u8 value); |
|||
void SetRegionMove(u8 value); |
|||
void SetFacelineType(FacelineType value); |
|||
void SetFacelineColor(FacelineColor value); |
|||
void SetFacelineWrinkle(FacelineWrinkle value); |
|||
void SetFacelineMake(FacelineMake value); |
|||
void SetHairType(HairType value); |
|||
void SetHairColor(CommonColor value); |
|||
void SetHairFlip(HairFlip value); |
|||
void SetEyeType(EyeType value); |
|||
void SetEyeColor(CommonColor value); |
|||
void SetEyeScale(u8 value); |
|||
void SetEyeAspect(u8 value); |
|||
void SetEyeRotate(u8 value); |
|||
void SetEyeX(u8 value); |
|||
void SetEyeY(u8 value); |
|||
void SetEyebrowType(EyebrowType value); |
|||
void SetEyebrowColor(CommonColor value); |
|||
void SetEyebrowScale(u8 value); |
|||
void SetEyebrowAspect(u8 value); |
|||
void SetEyebrowRotate(u8 value); |
|||
void SetEyebrowX(u8 value); |
|||
void SetEyebrowY(u8 value); |
|||
void SetNoseType(NoseType value); |
|||
void SetNoseScale(u8 value); |
|||
void SetNoseY(u8 value); |
|||
void SetMouthType(u8 value); |
|||
void SetMouthColor(CommonColor value); |
|||
void SetMouthScale(u8 value); |
|||
void SetMouthAspect(u8 value); |
|||
void SetMouthY(u8 value); |
|||
void SetBeardColor(CommonColor value); |
|||
void SetBeardType(BeardType value); |
|||
void SetMustacheType(MustacheType value); |
|||
void SetMustacheScale(u8 value); |
|||
void SetMustacheY(u8 value); |
|||
void SetGlassType(GlassType value); |
|||
void SetGlassColor(CommonColor value); |
|||
void SetGlassScale(u8 value); |
|||
void SetGlassY(u8 value); |
|||
void SetMoleType(MoleType value); |
|||
void SetMoleScale(u8 value); |
|||
void SetMoleX(u8 value); |
|||
void SetMoleY(u8 value); |
|||
void SetNickname(Nickname nickname); |
|||
void SetInvalidName(); |
|||
|
|||
Common::UUID GetCreateId() const; |
|||
FontRegion GetFontRegion() const; |
|||
FavoriteColor GetFavoriteColor() const; |
|||
Gender GetGender() const; |
|||
u8 GetHeight() const; |
|||
u8 GetBuild() const; |
|||
u8 GetType() const; |
|||
u8 GetRegionMove() const; |
|||
FacelineType GetFacelineType() const; |
|||
FacelineColor GetFacelineColor() const; |
|||
FacelineWrinkle GetFacelineWrinkle() const; |
|||
FacelineMake GetFacelineMake() const; |
|||
HairType GetHairType() const; |
|||
CommonColor GetHairColor() const; |
|||
HairFlip GetHairFlip() const; |
|||
EyeType GetEyeType() const; |
|||
CommonColor GetEyeColor() const; |
|||
u8 GetEyeScale() const; |
|||
u8 GetEyeAspect() const; |
|||
u8 GetEyeRotate() const; |
|||
u8 GetEyeX() const; |
|||
u8 GetEyeY() const; |
|||
EyebrowType GetEyebrowType() const; |
|||
CommonColor GetEyebrowColor() const; |
|||
u8 GetEyebrowScale() const; |
|||
u8 GetEyebrowAspect() const; |
|||
u8 GetEyebrowRotate() const; |
|||
u8 GetEyebrowX() const; |
|||
u8 GetEyebrowY() const; |
|||
NoseType GetNoseType() const; |
|||
u8 GetNoseScale() const; |
|||
u8 GetNoseY() const; |
|||
MouthType GetMouthType() const; |
|||
CommonColor GetMouthColor() const; |
|||
u8 GetMouthScale() const; |
|||
u8 GetMouthAspect() const; |
|||
u8 GetMouthY() const; |
|||
CommonColor GetBeardColor() const; |
|||
BeardType GetBeardType() const; |
|||
MustacheType GetMustacheType() const; |
|||
u8 GetMustacheScale() const; |
|||
u8 GetMustacheY() const; |
|||
GlassType GetGlassType() const; |
|||
CommonColor GetGlassColor() const; |
|||
u8 GetGlassScale() const; |
|||
u8 GetGlassY() const; |
|||
MoleType GetMoleType() const; |
|||
u8 GetMoleScale() const; |
|||
u8 GetMoleX() const; |
|||
u8 GetMoleY() const; |
|||
Nickname GetNickname() const; |
|||
|
|||
bool operator==(const StoreData& data); |
|||
|
|||
private: |
|||
CoreData core_data{}; |
|||
Common::UUID create_id{}; |
|||
u16 data_crc{}; |
|||
u16 device_crc{}; |
|||
}; |
|||
static_assert(sizeof(StoreData) == 0x44, "StoreData has incorrect size."); |
|||
|
|||
struct StoreDataElement { |
|||
StoreData store_data{}; |
|||
Source source{}; |
|||
}; |
|||
static_assert(sizeof(StoreDataElement) == 0x48, "StoreDataElement has incorrect size."); |
|||
|
|||
}; // namespace Service::Mii |
|||
@ -0,0 +1,241 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "core/hle/service/mii/mii_util.h"
|
|||
#include "core/hle/service/mii/types/raw_data.h"
|
|||
#include "core/hle/service/mii/types/store_data.h"
|
|||
#include "core/hle/service/mii/types/ver3_store_data.h"
|
|||
|
|||
namespace Service::Mii { |
|||
|
|||
void NfpStoreDataExtension::SetFromStoreData(const StoreData& store_data) { |
|||
faceline_color = static_cast<u8>(store_data.GetFacelineColor()) & 0xf; |
|||
hair_color = static_cast<u8>(store_data.GetHairColor()) & 0x7f; |
|||
eye_color = static_cast<u8>(store_data.GetEyeColor()) & 0x7f; |
|||
eyebrow_color = static_cast<u8>(store_data.GetEyebrowColor()) & 0x7f; |
|||
mouth_color = static_cast<u8>(store_data.GetMouthColor()) & 0x7f; |
|||
beard_color = static_cast<u8>(store_data.GetBeardColor()) & 0x7f; |
|||
glass_color = static_cast<u8>(store_data.GetGlassColor()) & 0x7f; |
|||
glass_type = static_cast<u8>(store_data.GetGlassType()) & 0x1f; |
|||
} |
|||
|
|||
void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const { |
|||
out_store_data.BuildBase(Gender::Male); |
|||
|
|||
if (!IsValid()) { |
|||
return; |
|||
} |
|||
|
|||
// TODO: We are ignoring a bunch of data from the mii_v3
|
|||
|
|||
out_store_data.SetGender(static_cast<Gender>(mii_information.gender.Value())); |
|||
out_store_data.SetFavoriteColor( |
|||
static_cast<FavoriteColor>(mii_information.favorite_color.Value())); |
|||
out_store_data.SetHeight(height); |
|||
out_store_data.SetBuild(build); |
|||
|
|||
out_store_data.SetNickname(mii_name); |
|||
out_store_data.SetFontRegion( |
|||
static_cast<FontRegion>(static_cast<u8>(region_information.font_region))); |
|||
|
|||
out_store_data.SetFacelineType( |
|||
static_cast<FacelineType>(appearance_bits1.faceline_type.Value())); |
|||
out_store_data.SetFacelineColor( |
|||
static_cast<FacelineColor>(appearance_bits1.faceline_color.Value())); |
|||
out_store_data.SetFacelineWrinkle( |
|||
static_cast<FacelineWrinkle>(appearance_bits2.faceline_wrinkle.Value())); |
|||
out_store_data.SetFacelineMake( |
|||
static_cast<FacelineMake>(appearance_bits2.faceline_make.Value())); |
|||
|
|||
out_store_data.SetHairType(static_cast<HairType>(hair_type)); |
|||
out_store_data.SetHairColor(static_cast<CommonColor>(appearance_bits3.hair_color.Value())); |
|||
out_store_data.SetHairFlip(static_cast<HairFlip>(appearance_bits3.hair_flip.Value())); |
|||
|
|||
out_store_data.SetEyeType(static_cast<EyeType>(appearance_bits4.eye_type.Value())); |
|||
out_store_data.SetEyeColor(static_cast<CommonColor>(appearance_bits4.eye_color.Value())); |
|||
out_store_data.SetEyeScale(static_cast<u8>(appearance_bits4.eye_scale)); |
|||
out_store_data.SetEyeAspect(static_cast<u8>(appearance_bits4.eye_aspect)); |
|||
out_store_data.SetEyeRotate(static_cast<u8>(appearance_bits4.eye_rotate)); |
|||
out_store_data.SetEyeX(static_cast<u8>(appearance_bits4.eye_x)); |
|||
out_store_data.SetEyeY(static_cast<u8>(appearance_bits4.eye_y)); |
|||
|
|||
out_store_data.SetEyebrowType(static_cast<EyebrowType>(appearance_bits5.eyebrow_type.Value())); |
|||
out_store_data.SetEyebrowColor( |
|||
static_cast<CommonColor>(appearance_bits5.eyebrow_color.Value())); |
|||
out_store_data.SetEyebrowScale(static_cast<u8>(appearance_bits5.eyebrow_scale)); |
|||
out_store_data.SetEyebrowAspect(static_cast<u8>(appearance_bits5.eyebrow_aspect)); |
|||
out_store_data.SetEyebrowRotate(static_cast<u8>(appearance_bits5.eyebrow_rotate)); |
|||
out_store_data.SetEyebrowX(static_cast<u8>(appearance_bits5.eyebrow_x)); |
|||
out_store_data.SetEyebrowY(static_cast<u8>(appearance_bits5.eyebrow_y)); |
|||
|
|||
out_store_data.SetNoseType(static_cast<NoseType>(appearance_bits6.nose_type.Value())); |
|||
out_store_data.SetNoseScale(static_cast<u8>(appearance_bits6.nose_scale)); |
|||
out_store_data.SetNoseY(static_cast<u8>(appearance_bits6.nose_y)); |
|||
|
|||
out_store_data.SetMouthType(static_cast<u8>(appearance_bits7.mouth_type)); |
|||
out_store_data.SetMouthColor(static_cast<CommonColor>(appearance_bits7.mouth_color.Value())); |
|||
out_store_data.SetMouthScale(static_cast<u8>(appearance_bits7.mouth_scale)); |
|||
out_store_data.SetMouthAspect(static_cast<u8>(appearance_bits7.mouth_aspect)); |
|||
out_store_data.SetMouthY(static_cast<u8>(appearance_bits8.mouth_y)); |
|||
|
|||
out_store_data.SetMustacheType( |
|||
static_cast<MustacheType>(appearance_bits8.mustache_type.Value())); |
|||
out_store_data.SetMustacheScale(static_cast<u8>(appearance_bits9.mustache_scale)); |
|||
out_store_data.SetMustacheY(static_cast<u8>(appearance_bits9.mustache_y)); |
|||
|
|||
out_store_data.SetBeardType(static_cast<BeardType>(appearance_bits9.beard_type.Value())); |
|||
out_store_data.SetBeardColor(static_cast<CommonColor>(appearance_bits9.beard_color.Value())); |
|||
|
|||
out_store_data.SetGlassType(static_cast<GlassType>(appearance_bits10.glass_type.Value())); |
|||
out_store_data.SetGlassColor(static_cast<CommonColor>(appearance_bits10.glass_color.Value())); |
|||
out_store_data.SetGlassScale(static_cast<u8>(appearance_bits10.glass_scale)); |
|||
out_store_data.SetGlassY(static_cast<u8>(appearance_bits10.glass_y)); |
|||
|
|||
out_store_data.SetMoleType(static_cast<MoleType>(appearance_bits11.mole_type.Value())); |
|||
out_store_data.SetMoleScale(static_cast<u8>(appearance_bits11.mole_scale)); |
|||
out_store_data.SetMoleX(static_cast<u8>(appearance_bits11.mole_x)); |
|||
out_store_data.SetMoleY(static_cast<u8>(appearance_bits11.mole_y)); |
|||
} |
|||
|
|||
void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) { |
|||
version = 1; |
|||
mii_information.gender.Assign(static_cast<u8>(store_data.GetGender())); |
|||
mii_information.favorite_color.Assign(static_cast<u8>(store_data.GetFavoriteColor())); |
|||
height = store_data.GetHeight(); |
|||
build = store_data.GetBuild(); |
|||
|
|||
mii_name = store_data.GetNickname(); |
|||
region_information.font_region.Assign(static_cast<u8>(store_data.GetFontRegion())); |
|||
|
|||
appearance_bits1.faceline_type.Assign(static_cast<u8>(store_data.GetFacelineType())); |
|||
appearance_bits2.faceline_wrinkle.Assign(static_cast<u8>(store_data.GetFacelineWrinkle())); |
|||
appearance_bits2.faceline_make.Assign(static_cast<u8>(store_data.GetFacelineMake())); |
|||
|
|||
hair_type = static_cast<u8>(store_data.GetHairType()); |
|||
appearance_bits3.hair_flip.Assign(static_cast<u8>(store_data.GetHairFlip())); |
|||
|
|||
appearance_bits4.eye_type.Assign(static_cast<u8>(store_data.GetEyeType())); |
|||
appearance_bits4.eye_scale.Assign(store_data.GetEyeScale()); |
|||
appearance_bits4.eye_aspect.Assign(store_data.GetEyebrowAspect()); |
|||
appearance_bits4.eye_rotate.Assign(store_data.GetEyeRotate()); |
|||
appearance_bits4.eye_x.Assign(store_data.GetEyeX()); |
|||
appearance_bits4.eye_y.Assign(store_data.GetEyeY()); |
|||
|
|||
appearance_bits5.eyebrow_type.Assign(static_cast<u8>(store_data.GetEyebrowType())); |
|||
appearance_bits5.eyebrow_scale.Assign(store_data.GetEyebrowScale()); |
|||
appearance_bits5.eyebrow_aspect.Assign(store_data.GetEyebrowAspect()); |
|||
appearance_bits5.eyebrow_rotate.Assign(store_data.GetEyebrowRotate()); |
|||
appearance_bits5.eyebrow_x.Assign(store_data.GetEyebrowX()); |
|||
appearance_bits5.eyebrow_y.Assign(store_data.GetEyebrowY()); |
|||
|
|||
appearance_bits6.nose_type.Assign(static_cast<u8>(store_data.GetNoseType())); |
|||
appearance_bits6.nose_scale.Assign(store_data.GetNoseScale()); |
|||
appearance_bits6.nose_y.Assign(store_data.GetNoseY()); |
|||
|
|||
appearance_bits7.mouth_type.Assign(static_cast<u8>(store_data.GetMouthType())); |
|||
appearance_bits7.mouth_scale.Assign(store_data.GetMouthScale()); |
|||
appearance_bits7.mouth_aspect.Assign(store_data.GetMouthAspect()); |
|||
appearance_bits8.mouth_y.Assign(store_data.GetMouthY()); |
|||
|
|||
appearance_bits8.mustache_type.Assign(static_cast<u8>(store_data.GetMustacheType())); |
|||
appearance_bits9.mustache_scale.Assign(store_data.GetMustacheScale()); |
|||
appearance_bits9.mustache_y.Assign(store_data.GetMustacheY()); |
|||
|
|||
appearance_bits9.beard_type.Assign(static_cast<u8>(store_data.GetBeardType())); |
|||
|
|||
appearance_bits10.glass_scale.Assign(store_data.GetGlassScale()); |
|||
appearance_bits10.glass_y.Assign(store_data.GetGlassY()); |
|||
|
|||
appearance_bits11.mole_type.Assign(static_cast<u8>(store_data.GetMoleType())); |
|||
appearance_bits11.mole_scale.Assign(store_data.GetMoleScale()); |
|||
appearance_bits11.mole_x.Assign(store_data.GetMoleX()); |
|||
appearance_bits11.mole_y.Assign(store_data.GetMoleY()); |
|||
|
|||
// These types are converted to V3 from a table
|
|||
appearance_bits1.faceline_color.Assign( |
|||
RawData::FromVer3GetFacelineColor(static_cast<u8>(store_data.GetFacelineColor()))); |
|||
appearance_bits3.hair_color.Assign( |
|||
RawData::FromVer3GetHairColor(static_cast<u8>(store_data.GetHairColor()))); |
|||
appearance_bits4.eye_color.Assign( |
|||
RawData::FromVer3GetEyeColor(static_cast<u8>(store_data.GetEyeColor()))); |
|||
appearance_bits5.eyebrow_color.Assign( |
|||
RawData::FromVer3GetHairColor(static_cast<u8>(store_data.GetEyebrowColor()))); |
|||
appearance_bits7.mouth_color.Assign( |
|||
RawData::FromVer3GetMouthlineColor(static_cast<u8>(store_data.GetMouthColor()))); |
|||
appearance_bits9.beard_color.Assign( |
|||
RawData::FromVer3GetHairColor(static_cast<u8>(store_data.GetBeardColor()))); |
|||
appearance_bits10.glass_color.Assign( |
|||
RawData::FromVer3GetGlassColor(static_cast<u8>(store_data.GetGlassColor()))); |
|||
appearance_bits10.glass_type.Assign( |
|||
RawData::FromVer3GetGlassType(static_cast<u8>(store_data.GetGlassType()))); |
|||
|
|||
crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); |
|||
} |
|||
|
|||
u32 Ver3StoreData::IsValid() const { |
|||
bool is_valid = version == 0 || version == 3; |
|||
|
|||
is_valid = is_valid && (mii_name.data[0] != '\0'); |
|||
|
|||
is_valid = is_valid && (mii_information.birth_month < 13); |
|||
is_valid = is_valid && (mii_information.birth_day < 32); |
|||
is_valid = is_valid && (mii_information.favorite_color <= static_cast<u8>(FavoriteColor::Max)); |
|||
is_valid = is_valid && (height <= MaxHeight); |
|||
is_valid = is_valid && (build <= MaxBuild); |
|||
|
|||
is_valid = is_valid && (appearance_bits1.faceline_type <= static_cast<u8>(FacelineType::Max)); |
|||
is_valid = is_valid && (appearance_bits1.faceline_color <= MaxVer3CommonColor - 2); |
|||
is_valid = |
|||
is_valid && (appearance_bits2.faceline_wrinkle <= static_cast<u8>(FacelineWrinkle::Max)); |
|||
is_valid = is_valid && (appearance_bits2.faceline_make <= static_cast<u8>(FacelineMake::Max)); |
|||
|
|||
is_valid = is_valid && (hair_type <= static_cast<u8>(HairType::Max)); |
|||
is_valid = is_valid && (appearance_bits3.hair_color <= MaxVer3CommonColor); |
|||
|
|||
is_valid = is_valid && (appearance_bits4.eye_type <= static_cast<u8>(EyeType::Max)); |
|||
is_valid = is_valid && (appearance_bits4.eye_color <= MaxVer3CommonColor - 2); |
|||
is_valid = is_valid && (appearance_bits4.eye_scale <= MaxEyeScale); |
|||
is_valid = is_valid && (appearance_bits4.eye_aspect <= MaxEyeAspect); |
|||
is_valid = is_valid && (appearance_bits4.eye_rotate <= MaxEyeRotate); |
|||
is_valid = is_valid && (appearance_bits4.eye_x <= MaxEyeX); |
|||
is_valid = is_valid && (appearance_bits4.eye_y <= MaxEyeY); |
|||
|
|||
is_valid = is_valid && (appearance_bits5.eyebrow_type <= static_cast<u8>(EyebrowType::Max)); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_color <= MaxVer3CommonColor); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_scale <= MaxEyebrowScale); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_aspect <= MaxEyebrowAspect); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_rotate <= MaxEyebrowRotate); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_x <= MaxEyebrowX); |
|||
is_valid = is_valid && (appearance_bits5.eyebrow_y <= MaxEyebrowY); |
|||
|
|||
is_valid = is_valid && (appearance_bits6.nose_type <= static_cast<u8>(NoseType::Max)); |
|||
is_valid = is_valid && (appearance_bits6.nose_scale <= MaxNoseScale); |
|||
is_valid = is_valid && (appearance_bits6.nose_y <= MaxNoseY); |
|||
|
|||
is_valid = is_valid && (appearance_bits7.mouth_type <= static_cast<u8>(MouthType::Max)); |
|||
is_valid = is_valid && (appearance_bits7.mouth_color <= MaxVer3CommonColor - 3); |
|||
is_valid = is_valid && (appearance_bits7.mouth_scale <= MaxMouthScale); |
|||
is_valid = is_valid && (appearance_bits7.mouth_aspect <= MaxMoutAspect); |
|||
is_valid = is_valid && (appearance_bits8.mouth_y <= MaxMouthY); |
|||
|
|||
is_valid = is_valid && (appearance_bits8.mustache_type <= static_cast<u8>(MustacheType::Max)); |
|||
is_valid = is_valid && (appearance_bits9.mustache_scale < MaxMustacheScale); |
|||
is_valid = is_valid && (appearance_bits9.mustache_y <= MasMustacheY); |
|||
|
|||
is_valid = is_valid && (appearance_bits9.beard_type <= static_cast<u8>(BeardType::Max)); |
|||
is_valid = is_valid && (appearance_bits9.beard_color <= MaxVer3CommonColor); |
|||
|
|||
is_valid = is_valid && (appearance_bits10.glass_type <= MaxVer3GlassType); |
|||
is_valid = is_valid && (appearance_bits10.glass_color <= MaxVer3CommonColor - 2); |
|||
is_valid = is_valid && (appearance_bits10.glass_scale <= MaxGlassScale); |
|||
is_valid = is_valid && (appearance_bits10.glass_y <= MaxGlassScale); |
|||
|
|||
is_valid = is_valid && (appearance_bits11.mole_type <= static_cast<u8>(MoleType::Max)); |
|||
is_valid = is_valid && (appearance_bits11.mole_scale <= MaxMoleScale); |
|||
is_valid = is_valid && (appearance_bits11.mole_x <= MaxMoleX); |
|||
is_valid = is_valid && (appearance_bits11.mole_y <= MaxMoleY); |
|||
|
|||
return is_valid; |
|||
} |
|||
|
|||
} // namespace Service::Mii
|
|||
@ -0,0 +1,160 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "core/hle/service/mii/mii_types.h" |
|||
|
|||
namespace Service::Mii { |
|||
class StoreData; |
|||
|
|||
// This is nn::mii::Ver3StoreData |
|||
// Based on citra HLE::Applets::MiiData and PretendoNetwork. |
|||
// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 |
|||
// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 |
|||
|
|||
struct NfpStoreDataExtension { |
|||
void SetFromStoreData(const StoreData& store_data); |
|||
|
|||
u8 faceline_color; |
|||
u8 hair_color; |
|||
u8 eye_color; |
|||
u8 eyebrow_color; |
|||
u8 mouth_color; |
|||
u8 beard_color; |
|||
u8 glass_color; |
|||
u8 glass_type; |
|||
}; |
|||
static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size"); |
|||
|
|||
#pragma pack(push, 4) |
|||
class Ver3StoreData { |
|||
public: |
|||
void BuildToStoreData(StoreData& out_store_data) const; |
|||
void BuildFromStoreData(const StoreData& store_data); |
|||
|
|||
u32 IsValid() const; |
|||
|
|||
u8 version; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 1, u8> allow_copying; |
|||
BitField<1, 1, u8> profanity_flag; |
|||
BitField<2, 2, u8> region_lock; |
|||
BitField<4, 2, u8> font_region; |
|||
} region_information; |
|||
u16_be mii_id; |
|||
u64_be system_id; |
|||
u32_be specialness_and_creation_date; |
|||
std::array<u8, 6> creator_mac; |
|||
u16_be padding; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 1, u16> gender; |
|||
BitField<1, 4, u16> birth_month; |
|||
BitField<5, 5, u16> birth_day; |
|||
BitField<10, 4, u16> favorite_color; |
|||
BitField<14, 1, u16> favorite; |
|||
} mii_information; |
|||
Nickname mii_name; |
|||
u8 height; |
|||
u8 build; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 1, u8> disable_sharing; |
|||
BitField<1, 4, u8> faceline_type; |
|||
BitField<5, 3, u8> faceline_color; |
|||
} appearance_bits1; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 4, u8> faceline_wrinkle; |
|||
BitField<4, 4, u8> faceline_make; |
|||
} appearance_bits2; |
|||
u8 hair_type; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 3, u8> hair_color; |
|||
BitField<3, 1, u8> hair_flip; |
|||
} appearance_bits3; |
|||
union { |
|||
u32 raw; |
|||
|
|||
BitField<0, 6, u32> eye_type; |
|||
BitField<6, 3, u32> eye_color; |
|||
BitField<9, 4, u32> eye_scale; |
|||
BitField<13, 3, u32> eye_aspect; |
|||
BitField<16, 5, u32> eye_rotate; |
|||
BitField<21, 4, u32> eye_x; |
|||
BitField<25, 5, u32> eye_y; |
|||
} appearance_bits4; |
|||
union { |
|||
u32 raw; |
|||
|
|||
BitField<0, 5, u32> eyebrow_type; |
|||
BitField<5, 3, u32> eyebrow_color; |
|||
BitField<8, 4, u32> eyebrow_scale; |
|||
BitField<12, 3, u32> eyebrow_aspect; |
|||
BitField<16, 4, u32> eyebrow_rotate; |
|||
BitField<21, 4, u32> eyebrow_x; |
|||
BitField<25, 5, u32> eyebrow_y; |
|||
} appearance_bits5; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 5, u16> nose_type; |
|||
BitField<5, 4, u16> nose_scale; |
|||
BitField<9, 5, u16> nose_y; |
|||
} appearance_bits6; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 6, u16> mouth_type; |
|||
BitField<6, 3, u16> mouth_color; |
|||
BitField<9, 4, u16> mouth_scale; |
|||
BitField<13, 3, u16> mouth_aspect; |
|||
} appearance_bits7; |
|||
union { |
|||
u8 raw; |
|||
|
|||
BitField<0, 5, u8> mouth_y; |
|||
BitField<5, 3, u8> mustache_type; |
|||
} appearance_bits8; |
|||
u8 allow_copying; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 3, u16> beard_type; |
|||
BitField<3, 3, u16> beard_color; |
|||
BitField<6, 4, u16> mustache_scale; |
|||
BitField<10, 5, u16> mustache_y; |
|||
} appearance_bits9; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 4, u16> glass_type; |
|||
BitField<4, 3, u16> glass_color; |
|||
BitField<7, 4, u16> glass_scale; |
|||
BitField<11, 5, u16> glass_y; |
|||
} appearance_bits10; |
|||
union { |
|||
u16 raw; |
|||
|
|||
BitField<0, 1, u16> mole_type; |
|||
BitField<1, 4, u16> mole_scale; |
|||
BitField<5, 5, u16> mole_x; |
|||
BitField<10, 5, u16> mole_y; |
|||
} appearance_bits11; |
|||
|
|||
Nickname author_name; |
|||
INSERT_PADDING_BYTES(0x2); |
|||
u16_be crc; |
|||
}; |
|||
static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size"); |
|||
#pragma pack(pop) |
|||
|
|||
}; // namespace Service::Mii |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue