using System; using System.Runtime.InteropServices; namespace Ryujinx.HLE.HOS.Services.Mii.Types { [StructLayout(LayoutKind.Sequential, Size = 0x58)] struct CharInfo : IStoredData { public CreateId CreateId; public Nickname Nickname; public FontRegion FontRegion; public byte FavoriteColor; public Gender Gender; public byte Height; public byte Build; public byte Type; public byte RegionMove; public FacelineType FacelineType; public FacelineColor FacelineColor; public FacelineWrinkle FacelineWrinkle; public FacelineMake FacelineMake; public HairType HairType; public CommonColor HairColor; public HairFlip HairFlip; public EyeType EyeType; public CommonColor EyeColor; public byte EyeScale; public byte EyeAspect; public byte EyeRotate; public byte EyeX; public byte EyeY; public EyebrowType EyebrowType; public CommonColor EyebrowColor; public byte EyebrowScale; public byte EyebrowAspect; public byte EyebrowRotate; public byte EyebrowX; public byte EyebrowY; public NoseType NoseType; public byte NoseScale; public byte NoseY; public MouthType MouthType; public CommonColor MouthColor; public byte MouthScale; public byte MouthAspect; public byte MouthY; public CommonColor BeardColor; public BeardType BeardType; public MustacheType MustacheType; public byte MustacheScale; public byte MustacheY; public GlassType GlassType; public CommonColor GlassColor; public byte GlassScale; public byte GlassY; public MoleType MoleType; public byte MoleScale; public byte MoleX; public byte MoleY; public byte Reserved; byte IStoredData.Type => Type; CreateId IStoredData.CreateId => CreateId; public ResultCode InvalidData => ResultCode.InvalidCharInfo; public bool IsValid() { return Verify() == 0; } public uint Verify() { if (!CreateId.IsValid) return 50; if (!Nickname.IsValid()) return 51; if ((byte)FontRegion > 3) return 23; if (FavoriteColor > 11) return 22; if (Gender > Gender.Max) return 24; if ((sbyte)Height < 0) return 32; if ((sbyte)Build < 0) return 3; if (Type > 1) return 53; if (RegionMove > 3) return 49; if (FacelineType > FacelineType.Max) return 21; if (FacelineColor > FacelineColor.Max) return 18; if (FacelineWrinkle > FacelineWrinkle.Max) return 20; if (FacelineMake > FacelineMake.Max) return 19; if (HairType > HairType.Max) return 31; if (HairColor > CommonColor.Max) return 29; if (HairFlip > HairFlip.Max) return 30; if (EyeType > EyeType.Max) return 8; if (EyeColor > CommonColor.Max) return 5; if (EyeScale > 7) return 7; if (EyeAspect > 6) return 4; if (EyeRotate > 7) return 6; if (EyeX > 12) return 9; if (EyeY > 18) return 10; if (EyebrowType > EyebrowType.Max) return 15; if (EyebrowColor > CommonColor.Max) return 12; if (EyebrowScale > 8) return 14; if (EyebrowAspect > 6) return 11; if (EyebrowRotate > 11) return 13; if (EyebrowX > 12) return 16; if (EyebrowY - 3 > 15) return 17; if (NoseType > NoseType.Max) return 47; if (NoseScale > 8) return 46; if (NoseY> 18) return 48; if (MouthType > MouthType.Max) return 40; if (MouthColor > CommonColor.Max) return 38; if (MouthScale > 8) return 39; if (MouthAspect > 6) return 37; if (MouthY > 18) return 41; if (BeardColor > CommonColor.Max) return 1; if (BeardType > BeardType.Max) return 2; if (MustacheType > MustacheType.Max) return 43; if (MustacheScale > 8) return 42; if (MustacheY > 16) return 44; if (GlassType > GlassType.Max) return 27; if (GlassColor > CommonColor.Max) return 25; if (GlassScale > 7) return 26; if (GlassY > 20) return 28; if (MoleType > MoleType.Max) return 34; if (MoleScale > 8) return 33; if (MoleX > 16) return 35; if (MoleY >= 31) return 36; return 0; } public void SetFromStoreData(StoreData storeData) { Nickname = storeData.CoreData.Nickname; CreateId = storeData.CreateId; FontRegion = storeData.CoreData.FontRegion; FavoriteColor = storeData.CoreData.FavoriteColor; Gender = storeData.CoreData.Gender; Height = storeData.CoreData.Height; Build = storeData.CoreData.Build; Type = storeData.CoreData.Type; RegionMove = storeData.CoreData.RegionMove; FacelineType = storeData.CoreData.FacelineType; FacelineColor = storeData.CoreData.FacelineColor; FacelineWrinkle = storeData.CoreData.FacelineWrinkle; FacelineMake = storeData.CoreData.FacelineMake; HairType = storeData.CoreData.HairType; HairColor = storeData.CoreData.HairColor; HairFlip = storeData.CoreData.HairFlip; EyeType = storeData.CoreData.EyeType; EyeColor = storeData.CoreData.EyeColor; EyeScale = storeData.CoreData.EyeScale; EyeAspect = storeData.CoreData.EyeAspect; EyeRotate = storeData.CoreData.EyeRotate; EyeX = storeData.CoreData.EyeX; EyeY = storeData.CoreData.EyeY; EyebrowType = storeData.CoreData.EyebrowType; EyebrowColor = storeData.CoreData.EyebrowColor; EyebrowScale = storeData.CoreData.EyebrowScale; EyebrowAspect = storeData.CoreData.EyebrowAspect; EyebrowRotate = storeData.CoreData.EyebrowRotate; EyebrowX = storeData.CoreData.EyebrowX; EyebrowY = storeData.CoreData.EyebrowY; NoseType = storeData.CoreData.NoseType; NoseScale = storeData.CoreData.NoseScale; NoseY = storeData.CoreData.NoseY; MouthType = storeData.CoreData.MouthType; MouthColor = storeData.CoreData.MouthColor; MouthScale = storeData.CoreData.MouthScale; MouthAspect = storeData.CoreData.MouthAspect; MouthY = storeData.CoreData.MouthY; BeardColor = storeData.CoreData.BeardColor; BeardType = storeData.CoreData.BeardType; MustacheType = storeData.CoreData.MustacheType; MustacheScale = storeData.CoreData.MustacheScale; MustacheY = storeData.CoreData.MustacheY; GlassType = storeData.CoreData.GlassType; GlassColor = storeData.CoreData.GlassColor; GlassScale = storeData.CoreData.GlassScale; GlassY = storeData.CoreData.GlassY; MoleType = storeData.CoreData.MoleType; MoleScale = storeData.CoreData.MoleScale; MoleX = storeData.CoreData.MoleX; MoleY = storeData.CoreData.MoleY; Reserved = 0; } public void SetSource(Source source) { // Only implemented for Element variants. } public static bool operator ==(CharInfo x, CharInfo y) { return x.Equals(y); } public static bool operator !=(CharInfo x, CharInfo y) { return !x.Equals(y); } public override bool Equals(object obj) { return obj is CharInfo charInfo && Equals(charInfo); } public bool Equals(CharInfo cmpObj) { if (!cmpObj.IsValid()) { return false; } bool result = true; result &= Nickname == cmpObj.Nickname; result &= CreateId == cmpObj.CreateId; result &= FontRegion == cmpObj.FontRegion; result &= FavoriteColor == cmpObj.FavoriteColor; result &= Gender == cmpObj.Gender; result &= Height == cmpObj.Height; result &= Build == cmpObj.Build; result &= Type == cmpObj.Type; result &= RegionMove == cmpObj.RegionMove; result &= FacelineType == cmpObj.FacelineType; result &= FacelineColor == cmpObj.FacelineColor; result &= FacelineWrinkle == cmpObj.FacelineWrinkle; result &= FacelineMake == cmpObj.FacelineMake; result &= HairType == cmpObj.HairType; result &= HairColor == cmpObj.HairColor; result &= HairFlip == cmpObj.HairFlip; result &= EyeType == cmpObj.EyeType; result &= EyeColor == cmpObj.EyeColor; result &= EyeScale == cmpObj.EyeScale; result &= EyeAspect == cmpObj.EyeAspect; result &= EyeRotate == cmpObj.EyeRotate; result &= EyeX == cmpObj.EyeX; result &= EyeY == cmpObj.EyeY; result &= EyebrowType == cmpObj.EyebrowType; result &= EyebrowColor == cmpObj.EyebrowColor; result &= EyebrowScale == cmpObj.EyebrowScale; result &= EyebrowAspect == cmpObj.EyebrowAspect; result &= EyebrowRotate == cmpObj.EyebrowRotate; result &= EyebrowX == cmpObj.EyebrowX; result &= EyebrowY == cmpObj.EyebrowY; result &= NoseType == cmpObj.NoseType; result &= NoseScale == cmpObj.NoseScale; result &= NoseY == cmpObj.NoseY; result &= MouthType == cmpObj.MouthType; result &= MouthColor == cmpObj.MouthColor; result &= MouthScale == cmpObj.MouthScale; result &= MouthAspect == cmpObj.MouthAspect; result &= MouthY == cmpObj.MouthY; result &= BeardColor == cmpObj.BeardColor; result &= BeardType == cmpObj.BeardType; result &= MustacheType == cmpObj.MustacheType; result &= MustacheScale == cmpObj.MustacheScale; result &= MustacheY == cmpObj.MustacheY; result &= GlassType == cmpObj.GlassType; result &= GlassColor == cmpObj.GlassColor; result &= GlassScale == cmpObj.GlassScale; result &= GlassY == cmpObj.GlassY; result &= MoleType == cmpObj.MoleType; result &= MoleScale == cmpObj.MoleScale; result &= MoleX == cmpObj.MoleX; result &= MoleY == cmpObj.MoleY; return result; } public override int GetHashCode() { HashCode hashCode = new HashCode(); hashCode.Add(Nickname); hashCode.Add(CreateId); hashCode.Add(FontRegion); hashCode.Add(FavoriteColor); hashCode.Add(Gender); hashCode.Add(Height); hashCode.Add(Build); hashCode.Add(Type); hashCode.Add(RegionMove); hashCode.Add(FacelineType); hashCode.Add(FacelineColor); hashCode.Add(FacelineWrinkle); hashCode.Add(FacelineMake); hashCode.Add(HairType); hashCode.Add(HairColor); hashCode.Add(HairFlip); hashCode.Add(EyeType); hashCode.Add(EyeColor); hashCode.Add(EyeScale); hashCode.Add(EyeAspect); hashCode.Add(EyeRotate); hashCode.Add(EyeX); hashCode.Add(EyeY); hashCode.Add(EyebrowType); hashCode.Add(EyebrowColor); hashCode.Add(EyebrowScale); hashCode.Add(EyebrowAspect); hashCode.Add(EyebrowRotate); hashCode.Add(EyebrowX); hashCode.Add(EyebrowY); hashCode.Add(NoseType); hashCode.Add(NoseScale); hashCode.Add(NoseY); hashCode.Add(MouthType); hashCode.Add(MouthColor); hashCode.Add(MouthScale); hashCode.Add(MouthAspect); hashCode.Add(MouthY); hashCode.Add(BeardColor); hashCode.Add(BeardType); hashCode.Add(MustacheType); hashCode.Add(MustacheScale); hashCode.Add(MustacheY); hashCode.Add(GlassType); hashCode.Add(GlassColor); hashCode.Add(GlassScale); hashCode.Add(GlassY); hashCode.Add(MoleType); hashCode.Add(MoleScale); hashCode.Add(MoleX); hashCode.Add(MoleY); return hashCode.ToHashCode(); } } }