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