summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp17
-rw-r--r--src/core/hle/service/mii/mii_manager.h3
-rw-r--r--src/core/hle/service/mii/mii_types.h16
-rw-r--r--src/core/hle/service/mii/types/char_info.cpp2
-rw-r--r--src/core/hle/service/mii/types/store_data.cpp202
-rw-r--r--src/core/hle/service/mii/types/store_data.h54
-rw-r--r--src/core/hle/service/mii/types/ver3_store_data.cpp300
-rw-r--r--src/core/hle/service/mii/types/ver3_store_data.h80
-rw-r--r--src/core/hle/service/nfc/common/device.cpp16
9 files changed, 473 insertions, 217 deletions
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 2137a9af1..3951e0b9c 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -98,23 +98,12 @@ CharInfo MiiManager::BuildDefault(std::size_t index) {
98 98
99CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const { 99CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const {
100 CharInfo char_info{}; 100 CharInfo char_info{};
101 mii_v3.BuildToStoreData(char_info); 101 StoreData store_data{};
102 mii_v3.BuildToStoreData(store_data);
103 char_info.SetFromStoreData(store_data);
102 return char_info; 104 return char_info;
103} 105}
104 106
105NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const {
106 return {
107 .faceline_color = static_cast<u8>(mii.GetFacelineColor() & 0xf),
108 .hair_color = static_cast<u8>(mii.GetHairColor() & 0x7f),
109 .eye_color = static_cast<u8>(mii.GetEyeColor() & 0x7f),
110 .eyebrow_color = static_cast<u8>(mii.GetEyebrowColor() & 0x7f),
111 .mouth_color = static_cast<u8>(mii.GetMouthColor() & 0x7f),
112 .beard_color = static_cast<u8>(mii.GetBeardColor() & 0x7f),
113 .glass_color = static_cast<u8>(mii.GetGlassColor() & 0x7f),
114 .glass_type = static_cast<u8>(mii.GetGlassType() & 0x1f),
115 };
116}
117
118std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) { 107std::vector<CharInfoElement> MiiManager::GetDefault(SourceFlag source_flag) {
119 std::vector<CharInfoElement> result; 108 std::vector<CharInfoElement> result;
120 109
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
index 0a47e613f..6098474e9 100644
--- a/src/core/hle/service/mii/mii_manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
@@ -30,9 +30,6 @@ public:
30 std::vector<CharInfoElement> GetDefault(SourceFlag source_flag); 30 std::vector<CharInfoElement> GetDefault(SourceFlag source_flag);
31 Result GetIndex(const CharInfo& info, u32& index); 31 Result GetIndex(const CharInfo& info, u32& index);
32 32
33 // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData
34 NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const;
35
36 struct MiiDatabase { 33 struct MiiDatabase {
37 u32 magic{}; // 'NFDB' 34 u32 magic{}; // 'NFDB'
38 std::array<StoreData, 0x64> miis{}; 35 std::array<StoreData, 0x64> miis{};
diff --git a/src/core/hle/service/mii/mii_types.h b/src/core/hle/service/mii/mii_types.h
index 20d4e40ab..d62005f61 100644
--- a/src/core/hle/service/mii/mii_types.h
+++ b/src/core/hle/service/mii/mii_types.h
@@ -108,25 +108,9 @@ struct Nickname {
108 } 108 }
109 return index == MaxNameSize; 109 return index == MaxNameSize;
110 } 110 }
111
112 bool operator==(const Nickname& name) {
113 return data == name.data;
114 };
115}; 111};
116static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size"); 112static_assert(sizeof(Nickname) == 0x14, "Nickname is an invalid size");
117 113
118struct NfpStoreDataExtension {
119 u8 faceline_color;
120 u8 hair_color;
121 u8 eye_color;
122 u8 eyebrow_color;
123 u8 mouth_color;
124 u8 beard_color;
125 u8 glass_color;
126 u8 glass_type;
127};
128static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size");
129
130struct DefaultMii { 114struct DefaultMii {
131 u32 face_type{}; 115 u32 face_type{};
132 u32 face_color{}; 116 u32 face_color{};
diff --git a/src/core/hle/service/mii/types/char_info.cpp b/src/core/hle/service/mii/types/char_info.cpp
index e1d874860..0f9c37b84 100644
--- a/src/core/hle/service/mii/types/char_info.cpp
+++ b/src/core/hle/service/mii/types/char_info.cpp
@@ -425,7 +425,7 @@ u8 CharInfo::GetMoleY() const {
425 425
426bool CharInfo::operator==(const CharInfo& info) { 426bool CharInfo::operator==(const CharInfo& info) {
427 bool is_identical = info.Verify() == 0; 427 bool is_identical = info.Verify() == 0;
428 is_identical &= name == info.GetNickname(); 428 is_identical &= name.data == info.GetNickname().data;
429 is_identical &= create_id == info.GetCreateId(); 429 is_identical &= create_id == info.GetCreateId();
430 is_identical &= font_region == info.GetFontRegion(); 430 is_identical &= font_region == info.GetFontRegion();
431 is_identical &= favorite_color == info.GetFavoriteColor(); 431 is_identical &= favorite_color == info.GetFavoriteColor();
diff --git a/src/core/hle/service/mii/types/store_data.cpp b/src/core/hle/service/mii/types/store_data.cpp
index 72c8fa2e9..91dfd3271 100644
--- a/src/core/hle/service/mii/types/store_data.cpp
+++ b/src/core/hle/service/mii/types/store_data.cpp
@@ -180,6 +180,206 @@ u32 StoreData::IsValid() const {
180 return 0; 180 return 0;
181} 181}
182 182
183void StoreData::SetFontRegion(FontRegion value) {
184 core_data.SetFontRegion(value);
185}
186
187void StoreData::SetFavoriteColor(u8 value) {
188 core_data.SetFavoriteColor(value);
189}
190
191void StoreData::SetGender(Gender value) {
192 core_data.SetGender(value);
193}
194
195void StoreData::SetHeight(u8 value) {
196 core_data.SetHeight(value);
197}
198
199void StoreData::SetBuild(u8 value) {
200 core_data.SetBuild(value);
201}
202
203void StoreData::SetType(u8 value) {
204 core_data.SetType(value);
205}
206
207void StoreData::SetRegionMove(u8 value) {
208 core_data.SetRegionMove(value);
209}
210
211void StoreData::SetFacelineType(u8 value) {
212 core_data.SetFacelineType(value);
213}
214
215void StoreData::SetFacelineColor(u8 value) {
216 core_data.SetFacelineColor(value);
217}
218
219void StoreData::SetFacelineWrinkle(u8 value) {
220 core_data.SetFacelineWrinkle(value);
221}
222
223void StoreData::SetFacelineMake(u8 value) {
224 core_data.SetFacelineMake(value);
225}
226
227void StoreData::SetHairType(u8 value) {
228 core_data.SetHairType(value);
229}
230
231void StoreData::SetHairColor(u8 value) {
232 core_data.SetHairColor(value);
233}
234
235void StoreData::SetHairFlip(HairFlip value) {
236 core_data.SetHairFlip(value);
237}
238
239void StoreData::SetEyeType(u8 value) {
240 core_data.SetEyeType(value);
241}
242
243void StoreData::SetEyeColor(u8 value) {
244 core_data.SetEyeColor(value);
245}
246
247void StoreData::SetEyeScale(u8 value) {
248 core_data.SetEyeScale(value);
249}
250
251void StoreData::SetEyeAspect(u8 value) {
252 core_data.SetEyeAspect(value);
253}
254
255void StoreData::SetEyeRotate(u8 value) {
256 core_data.SetEyeRotate(value);
257}
258
259void StoreData::SetEyeX(u8 value) {
260 core_data.SetEyeX(value);
261}
262
263void StoreData::SetEyeY(u8 value) {
264 core_data.SetEyeY(value);
265}
266
267void StoreData::SetEyebrowType(u8 value) {
268 core_data.SetEyebrowType(value);
269}
270
271void StoreData::SetEyebrowColor(u8 value) {
272 core_data.SetEyebrowColor(value);
273}
274
275void StoreData::SetEyebrowScale(u8 value) {
276 core_data.SetEyebrowScale(value);
277}
278
279void StoreData::SetEyebrowAspect(u8 value) {
280 core_data.SetEyebrowAspect(value);
281}
282
283void StoreData::SetEyebrowRotate(u8 value) {
284 core_data.SetEyebrowRotate(value);
285}
286
287void StoreData::SetEyebrowX(u8 value) {
288 core_data.SetEyebrowX(value);
289}
290
291void StoreData::SetEyebrowY(u8 value) {
292 core_data.SetEyebrowY(value);
293}
294
295void StoreData::SetNoseType(u8 value) {
296 core_data.SetNoseType(value);
297}
298
299void StoreData::SetNoseScale(u8 value) {
300 core_data.SetNoseScale(value);
301}
302
303void StoreData::SetNoseY(u8 value) {
304 core_data.SetNoseY(value);
305}
306
307void StoreData::SetMouthType(u8 value) {
308 core_data.SetMouthType(value);
309}
310
311void StoreData::SetMouthColor(u8 value) {
312 core_data.SetMouthColor(value);
313}
314
315void StoreData::SetMouthScale(u8 value) {
316 core_data.SetMouthScale(value);
317}
318
319void StoreData::SetMouthAspect(u8 value) {
320 core_data.SetMouthAspect(value);
321}
322
323void StoreData::SetMouthY(u8 value) {
324 core_data.SetMouthY(value);
325}
326
327void StoreData::SetBeardColor(u8 value) {
328 core_data.SetBeardColor(value);
329}
330
331void StoreData::SetBeardType(BeardType value) {
332 core_data.SetBeardType(value);
333}
334
335void StoreData::SetMustacheType(MustacheType value) {
336 core_data.SetMustacheType(value);
337}
338
339void StoreData::SetMustacheScale(u8 value) {
340 core_data.SetMustacheScale(value);
341}
342
343void StoreData::SetMustacheY(u8 value) {
344 core_data.SetMustacheY(value);
345}
346
347void StoreData::SetGlassType(u8 value) {
348 core_data.SetGlassType(value);
349}
350
351void StoreData::SetGlassColor(u8 value) {
352 core_data.SetGlassColor(value);
353}
354
355void StoreData::SetGlassScale(u8 value) {
356 core_data.SetGlassScale(value);
357}
358
359void StoreData::SetGlassY(u8 value) {
360 core_data.SetGlassY(value);
361}
362
363void StoreData::SetMoleType(u8 value) {
364 core_data.SetMoleType(value);
365}
366
367void StoreData::SetMoleScale(u8 value) {
368 core_data.SetMoleScale(value);
369}
370
371void StoreData::SetMoleX(u8 value) {
372 core_data.SetMoleX(value);
373}
374
375void StoreData::SetMoleY(u8 value) {
376 core_data.SetMoleY(value);
377}
378
379void StoreData::SetNickname(Nickname value) {
380 core_data.SetNickname(value);
381}
382
183Common::UUID StoreData::GetCreateId() const { 383Common::UUID StoreData::GetCreateId() const {
184 return create_id; 384 return create_id;
185} 385}
@@ -386,7 +586,7 @@ Nickname StoreData::GetNickname() const {
386 586
387bool StoreData::operator==(const StoreData& data) { 587bool StoreData::operator==(const StoreData& data) {
388 bool is_identical = data.core_data.IsValid() == 0; 588 bool is_identical = data.core_data.IsValid() == 0;
389 is_identical &= core_data.GetNickname() == data.core_data.GetNickname(); 589 is_identical &= core_data.GetNickname().data == data.core_data.GetNickname().data;
390 is_identical &= GetCreateId() == data.GetCreateId(); 590 is_identical &= GetCreateId() == data.GetCreateId();
391 is_identical &= GetFontRegion() == data.GetFontRegion(); 591 is_identical &= GetFontRegion() == data.GetFontRegion();
392 is_identical &= GetFavoriteColor() == data.GetFavoriteColor(); 592 is_identical &= GetFavoriteColor() == data.GetFavoriteColor();
diff --git a/src/core/hle/service/mii/types/store_data.h b/src/core/hle/service/mii/types/store_data.h
index cc8551a66..1e010000b 100644
--- a/src/core/hle/service/mii/types/store_data.h
+++ b/src/core/hle/service/mii/types/store_data.h
@@ -18,12 +18,62 @@ public:
18 // nn::mii::detail::StoreDataRaw::BuildRandom 18 // nn::mii::detail::StoreDataRaw::BuildRandom
19 void BuildRandom(Age age, Gender gender, Race race); 19 void BuildRandom(Age age, Gender gender, Race race);
20 20
21 void SetInvalidName();
22
23 bool IsSpecial() const; 21 bool IsSpecial() const;
24 22
25 u32 IsValid() const; 23 u32 IsValid() const;
26 24
25 void SetFontRegion(FontRegion value);
26 void SetFavoriteColor(u8 value);
27 void SetGender(Gender value);
28 void SetHeight(u8 value);
29 void SetBuild(u8 value);
30 void SetType(u8 value);
31 void SetRegionMove(u8 value);
32 void SetFacelineType(u8 value);
33 void SetFacelineColor(u8 value);
34 void SetFacelineWrinkle(u8 value);
35 void SetFacelineMake(u8 value);
36 void SetHairType(u8 value);
37 void SetHairColor(u8 value);
38 void SetHairFlip(HairFlip value);
39 void SetEyeType(u8 value);
40 void SetEyeColor(u8 value);
41 void SetEyeScale(u8 value);
42 void SetEyeAspect(u8 value);
43 void SetEyeRotate(u8 value);
44 void SetEyeX(u8 value);
45 void SetEyeY(u8 value);
46 void SetEyebrowType(u8 value);
47 void SetEyebrowColor(u8 value);
48 void SetEyebrowScale(u8 value);
49 void SetEyebrowAspect(u8 value);
50 void SetEyebrowRotate(u8 value);
51 void SetEyebrowX(u8 value);
52 void SetEyebrowY(u8 value);
53 void SetNoseType(u8 value);
54 void SetNoseScale(u8 value);
55 void SetNoseY(u8 value);
56 void SetMouthType(u8 value);
57 void SetMouthColor(u8 value);
58 void SetMouthScale(u8 value);
59 void SetMouthAspect(u8 value);
60 void SetMouthY(u8 value);
61 void SetBeardColor(u8 value);
62 void SetBeardType(BeardType value);
63 void SetMustacheType(MustacheType value);
64 void SetMustacheScale(u8 value);
65 void SetMustacheY(u8 value);
66 void SetGlassType(u8 value);
67 void SetGlassColor(u8 value);
68 void SetGlassScale(u8 value);
69 void SetGlassY(u8 value);
70 void SetMoleType(u8 value);
71 void SetMoleScale(u8 value);
72 void SetMoleX(u8 value);
73 void SetMoleY(u8 value);
74 void SetNickname(Nickname nickname);
75 void SetInvalidName();
76
27 Common::UUID GetCreateId() const; 77 Common::UUID GetCreateId() const;
28 FontRegion GetFontRegion() const; 78 FontRegion GetFontRegion() const;
29 u8 GetFavoriteColor() const; 79 u8 GetFavoriteColor() const;
diff --git a/src/core/hle/service/mii/types/ver3_store_data.cpp b/src/core/hle/service/mii/types/ver3_store_data.cpp
index c774f4b47..53a3fe44b 100644
--- a/src/core/hle/service/mii/types/ver3_store_data.cpp
+++ b/src/core/hle/service/mii/types/ver3_store_data.cpp
@@ -2,160 +2,180 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/mii/mii_util.h" 4#include "core/hle/service/mii/mii_util.h"
5#include "core/hle/service/mii/types/char_info.h"
6#include "core/hle/service/mii/types/raw_data.h" 5#include "core/hle/service/mii/types/raw_data.h"
7#include "core/hle/service/mii/types/store_data.h" 6#include "core/hle/service/mii/types/store_data.h"
8#include "core/hle/service/mii/types/ver3_store_data.h" 7#include "core/hle/service/mii/types/ver3_store_data.h"
9 8
10namespace Service::Mii { 9namespace Service::Mii {
11 10
12void Ver3StoreData::BuildToStoreData(CharInfo& out_char_info) const { 11void NfpStoreDataExtension::SetFromStoreData(const StoreData& store_data) {
12 faceline_color = static_cast<u8>(store_data.GetFacelineColor() & 0xf);
13 hair_color = static_cast<u8>(store_data.GetHairColor() & 0x7f);
14 eye_color = static_cast<u8>(store_data.GetEyeColor() & 0x7f);
15 eyebrow_color = static_cast<u8>(store_data.GetEyebrowColor() & 0x7f);
16 mouth_color = static_cast<u8>(store_data.GetMouthColor() & 0x7f);
17 beard_color = static_cast<u8>(store_data.GetBeardColor() & 0x7f);
18 glass_color = static_cast<u8>(store_data.GetGlassColor() & 0x7f);
19 glass_type = static_cast<u8>(store_data.GetGlassType() & 0x1f);
20}
21
22void Ver3StoreData::BuildToStoreData(StoreData& out_store_data) const {
23 out_store_data.BuildBase(Gender::Male);
24
13 if (!IsValid()) { 25 if (!IsValid()) {
14 return; 26 return;
15 } 27 }
16 28
17 // TODO: We are ignoring a bunch of data from the mii_v3 29 // TODO: We are ignoring a bunch of data from the mii_v3
18 30
19 out_char_info.gender = static_cast<u8>(mii_information.gender); 31 out_store_data.SetGender(static_cast<Gender>(static_cast<u8>(mii_information.gender)));
20 out_char_info.favorite_color = static_cast<u8>(mii_information.favorite_color); 32 out_store_data.SetFavoriteColor(static_cast<u8>(mii_information.favorite_color));
21 out_char_info.height = height; 33 out_store_data.SetHeight(height);
22 out_char_info.build = build; 34 out_store_data.SetBuild(build);
23 35
24 // Copy name until string terminator 36 // Copy name until string terminator
25 out_char_info.name = {}; 37 Nickname name = {};
26 for (std::size_t index = 0; index < out_char_info.name.size() - 1; index++) { 38 for (std::size_t index = 0; index < name.data.size() - 1; index++) {
27 out_char_info.name[index] = mii_name[index]; 39 name.data[index] = mii_name[index];
28 if (out_char_info.name[index] == 0) { 40 if (name.data[index] == 0) {
29 break; 41 break;
30 } 42 }
31 } 43 }
32 44
33 out_char_info.font_region = region_information.character_set; 45 out_store_data.SetNickname(name);
34 46 out_store_data.SetFontRegion(
35 out_char_info.faceline_type = appearance_bits1.face_shape; 47 static_cast<FontRegion>(static_cast<u8>(region_information.font_region)));
36 out_char_info.faceline_color = appearance_bits1.skin_color; 48
37 out_char_info.faceline_wrinkle = appearance_bits2.wrinkles; 49 out_store_data.SetFacelineType(appearance_bits1.faceline_type);
38 out_char_info.faceline_make = appearance_bits2.makeup; 50 out_store_data.SetFacelineColor(appearance_bits1.faceline_color);
39 51 out_store_data.SetFacelineWrinkle(appearance_bits2.faceline_wrinkle);
40 out_char_info.hair_type = hair_style; 52 out_store_data.SetFacelineMake(appearance_bits2.faceline_make);
41 out_char_info.hair_color = appearance_bits3.hair_color; 53
42 out_char_info.hair_flip = appearance_bits3.flip_hair; 54 out_store_data.SetHairType(hair_type);
43 55 out_store_data.SetHairColor(appearance_bits3.hair_color);
44 out_char_info.eye_type = static_cast<u8>(appearance_bits4.eye_type); 56 out_store_data.SetHairFlip(static_cast<HairFlip>(static_cast<u8>(appearance_bits3.hair_flip)));
45 out_char_info.eye_color = static_cast<u8>(appearance_bits4.eye_color); 57
46 out_char_info.eye_scale = static_cast<u8>(appearance_bits4.eye_scale); 58 out_store_data.SetEyeType(static_cast<u8>(appearance_bits4.eye_type));
47 out_char_info.eye_aspect = static_cast<u8>(appearance_bits4.eye_vertical_stretch); 59 out_store_data.SetEyeColor(static_cast<u8>(appearance_bits4.eye_color));
48 out_char_info.eye_rotate = static_cast<u8>(appearance_bits4.eye_rotation); 60 out_store_data.SetEyeScale(static_cast<u8>(appearance_bits4.eye_scale));
49 out_char_info.eye_x = static_cast<u8>(appearance_bits4.eye_spacing); 61 out_store_data.SetEyeAspect(static_cast<u8>(appearance_bits4.eye_aspect));
50 out_char_info.eye_y = static_cast<u8>(appearance_bits4.eye_y_position); 62 out_store_data.SetEyeRotate(static_cast<u8>(appearance_bits4.eye_rotate));
51 63 out_store_data.SetEyeX(static_cast<u8>(appearance_bits4.eye_x));
52 out_char_info.eyebrow_type = static_cast<u8>(appearance_bits5.eyebrow_style); 64 out_store_data.SetEyeY(static_cast<u8>(appearance_bits4.eye_y));
53 out_char_info.eyebrow_color = static_cast<u8>(appearance_bits5.eyebrow_color); 65
54 out_char_info.eyebrow_scale = static_cast<u8>(appearance_bits5.eyebrow_scale); 66 out_store_data.SetEyebrowType(static_cast<u8>(appearance_bits5.eyebrow_type));
55 out_char_info.eyebrow_aspect = static_cast<u8>(appearance_bits5.eyebrow_yscale); 67 out_store_data.SetEyebrowColor(static_cast<u8>(appearance_bits5.eyebrow_color));
56 out_char_info.eyebrow_rotate = static_cast<u8>(appearance_bits5.eyebrow_rotation); 68 out_store_data.SetEyebrowScale(static_cast<u8>(appearance_bits5.eyebrow_scale));
57 out_char_info.eyebrow_x = static_cast<u8>(appearance_bits5.eyebrow_spacing); 69 out_store_data.SetEyebrowAspect(static_cast<u8>(appearance_bits5.eyebrow_aspect));
58 out_char_info.eyebrow_y = static_cast<u8>(appearance_bits5.eyebrow_y_position); 70 out_store_data.SetEyebrowRotate(static_cast<u8>(appearance_bits5.eyebrow_rotate));
59 71 out_store_data.SetEyebrowX(static_cast<u8>(appearance_bits5.eyebrow_x));
60 out_char_info.nose_type = static_cast<u8>(appearance_bits6.nose_type); 72 out_store_data.SetEyebrowY(static_cast<u8>(appearance_bits5.eyebrow_y));
61 out_char_info.nose_scale = static_cast<u8>(appearance_bits6.nose_scale); 73
62 out_char_info.nose_y = static_cast<u8>(appearance_bits6.nose_y_position); 74 out_store_data.SetNoseType(static_cast<u8>(appearance_bits6.nose_type));
63 75 out_store_data.SetNoseScale(static_cast<u8>(appearance_bits6.nose_scale));
64 out_char_info.mouth_type = static_cast<u8>(appearance_bits7.mouth_type); 76 out_store_data.SetNoseY(static_cast<u8>(appearance_bits6.nose_y));
65 out_char_info.mouth_color = static_cast<u8>(appearance_bits7.mouth_color); 77
66 out_char_info.mouth_scale = static_cast<u8>(appearance_bits7.mouth_scale); 78 out_store_data.SetMouthType(static_cast<u8>(appearance_bits7.mouth_type));
67 out_char_info.mouth_aspect = static_cast<u8>(appearance_bits7.mouth_horizontal_stretch); 79 out_store_data.SetMouthColor(static_cast<u8>(appearance_bits7.mouth_color));
68 out_char_info.mouth_y = static_cast<u8>(appearance_bits8.mouth_y_position); 80 out_store_data.SetMouthScale(static_cast<u8>(appearance_bits7.mouth_scale));
69 81 out_store_data.SetMouthAspect(static_cast<u8>(appearance_bits7.mouth_aspect));
70 out_char_info.mustache_type = static_cast<u8>(appearance_bits8.mustache_type); 82 out_store_data.SetMouthY(static_cast<u8>(appearance_bits8.mouth_y));
71 out_char_info.mustache_scale = static_cast<u8>(appearance_bits9.mustache_scale); 83
72 out_char_info.mustache_y = static_cast<u8>(appearance_bits9.mustache_y_position); 84 out_store_data.SetMustacheType(
73 85 static_cast<MustacheType>(static_cast<u8>(appearance_bits8.mustache_type)));
74 out_char_info.beard_type = static_cast<u8>(appearance_bits9.bear_type); 86 out_store_data.SetMustacheScale(static_cast<u8>(appearance_bits9.mustache_scale));
75 out_char_info.beard_color = static_cast<u8>(appearance_bits9.facial_hair_color); 87 out_store_data.SetMustacheY(static_cast<u8>(appearance_bits9.mustache_y));
76 88
77 out_char_info.glasses_type = static_cast<u8>(appearance_bits10.glasses_type); 89 out_store_data.SetBeardType(
78 out_char_info.glasses_color = static_cast<u8>(appearance_bits10.glasses_color); 90 static_cast<BeardType>(static_cast<u8>(appearance_bits9.beard_type)));
79 out_char_info.glasses_scale = static_cast<u8>(appearance_bits10.glasses_scale); 91 out_store_data.SetBeardColor(static_cast<u8>(appearance_bits9.beard_color));
80 out_char_info.glasses_y = static_cast<u8>(appearance_bits10.glasses_y_position); 92
81 93 out_store_data.SetGlassType(static_cast<u8>(appearance_bits10.glass_type));
82 out_char_info.mole_type = static_cast<u8>(appearance_bits11.mole_enabled); 94 out_store_data.SetGlassColor(static_cast<u8>(appearance_bits10.glass_color));
83 out_char_info.mole_scale = static_cast<u8>(appearance_bits11.mole_scale); 95 out_store_data.SetGlassScale(static_cast<u8>(appearance_bits10.glass_scale));
84 out_char_info.mole_x = static_cast<u8>(appearance_bits11.mole_x_position); 96 out_store_data.SetGlassY(static_cast<u8>(appearance_bits10.glass_y));
85 out_char_info.mole_y = static_cast<u8>(appearance_bits11.mole_y_position); 97
98 out_store_data.SetMoleType(static_cast<u8>(appearance_bits11.mole_type));
99 out_store_data.SetMoleScale(static_cast<u8>(appearance_bits11.mole_scale));
100 out_store_data.SetMoleX(static_cast<u8>(appearance_bits11.mole_x));
101 out_store_data.SetMoleY(static_cast<u8>(appearance_bits11.mole_y));
86} 102}
87 103
88void Ver3StoreData::BuildFromStoreData(const CharInfo& char_info) { 104void Ver3StoreData::BuildFromStoreData(const StoreData& store_data) {
89 version = 1; 105 version = 1;
90 mii_information.gender.Assign(char_info.gender); 106 mii_information.gender.Assign(store_data.GetGender());
91 mii_information.favorite_color.Assign(char_info.favorite_color); 107 mii_information.favorite_color.Assign(store_data.GetFavoriteColor());
92 height = char_info.height; 108 height = store_data.GetHeight();
93 build = char_info.build; 109 build = store_data.GetBuild();
94 110
95 // Copy name until string terminator 111 // Copy name until string terminator
96 mii_name = {}; 112 mii_name = {};
97 for (std::size_t index = 0; index < char_info.name.size() - 1; index++) { 113 for (std::size_t index = 0; index < store_data.GetNickname().data.size() - 1; index++) {
98 mii_name[index] = char_info.name[index]; 114 mii_name[index] = store_data.GetNickname().data[index];
99 if (mii_name[index] == 0) { 115 if (mii_name[index] == 0) {
100 break; 116 break;
101 } 117 }
102 } 118 }
103 119
104 region_information.character_set.Assign(char_info.font_region); 120 region_information.font_region.Assign(static_cast<u8>(store_data.GetFontRegion()));
105 121
106 appearance_bits1.face_shape.Assign(char_info.faceline_type); 122 appearance_bits1.faceline_type.Assign(store_data.GetFacelineType());
107 appearance_bits2.wrinkles.Assign(char_info.faceline_wrinkle); 123 appearance_bits2.faceline_wrinkle.Assign(store_data.GetFacelineWrinkle());
108 appearance_bits2.makeup.Assign(char_info.faceline_make); 124 appearance_bits2.faceline_make.Assign(store_data.GetFacelineMake());
109 125
110 hair_style = char_info.hair_type; 126 hair_type = store_data.GetHairType();
111 appearance_bits3.flip_hair.Assign(char_info.hair_flip); 127 appearance_bits3.hair_flip.Assign(store_data.GetHairFlip());
112 128
113 appearance_bits4.eye_type.Assign(char_info.eye_type); 129 appearance_bits4.eye_type.Assign(store_data.GetEyeType());
114 appearance_bits4.eye_scale.Assign(char_info.eye_scale); 130 appearance_bits4.eye_scale.Assign(store_data.GetEyeScale());
115 appearance_bits4.eye_vertical_stretch.Assign(char_info.eye_aspect); 131 appearance_bits4.eye_aspect.Assign(store_data.GetEyebrowAspect());
116 appearance_bits4.eye_rotation.Assign(char_info.eye_rotate); 132 appearance_bits4.eye_rotate.Assign(store_data.GetEyeRotate());
117 appearance_bits4.eye_spacing.Assign(char_info.eye_x); 133 appearance_bits4.eye_x.Assign(store_data.GetEyeX());
118 appearance_bits4.eye_y_position.Assign(char_info.eye_y); 134 appearance_bits4.eye_y.Assign(store_data.GetEyeY());
119 135
120 appearance_bits5.eyebrow_style.Assign(char_info.eyebrow_type); 136 appearance_bits5.eyebrow_type.Assign(store_data.GetEyebrowType());
121 appearance_bits5.eyebrow_scale.Assign(char_info.eyebrow_scale); 137 appearance_bits5.eyebrow_scale.Assign(store_data.GetEyebrowScale());
122 appearance_bits5.eyebrow_yscale.Assign(char_info.eyebrow_aspect); 138 appearance_bits5.eyebrow_aspect.Assign(store_data.GetEyebrowAspect());
123 appearance_bits5.eyebrow_rotation.Assign(char_info.eyebrow_rotate); 139 appearance_bits5.eyebrow_rotate.Assign(store_data.GetEyebrowRotate());
124 appearance_bits5.eyebrow_spacing.Assign(char_info.eyebrow_x); 140 appearance_bits5.eyebrow_x.Assign(store_data.GetEyebrowX());
125 appearance_bits5.eyebrow_y_position.Assign(char_info.eyebrow_y); 141 appearance_bits5.eyebrow_y.Assign(store_data.GetEyebrowY());
126 142
127 appearance_bits6.nose_type.Assign(char_info.nose_type); 143 appearance_bits6.nose_type.Assign(store_data.GetNoseType());
128 appearance_bits6.nose_scale.Assign(char_info.nose_scale); 144 appearance_bits6.nose_scale.Assign(store_data.GetNoseScale());
129 appearance_bits6.nose_y_position.Assign(char_info.nose_y); 145 appearance_bits6.nose_y.Assign(store_data.GetNoseY());
130 146
131 appearance_bits7.mouth_type.Assign(char_info.mouth_type); 147 appearance_bits7.mouth_type.Assign(store_data.GetMouthType());
132 appearance_bits7.mouth_scale.Assign(char_info.mouth_scale); 148 appearance_bits7.mouth_scale.Assign(store_data.GetMouthScale());
133 appearance_bits7.mouth_horizontal_stretch.Assign(char_info.mouth_aspect); 149 appearance_bits7.mouth_aspect.Assign(store_data.GetMouthAspect());
134 appearance_bits8.mouth_y_position.Assign(char_info.mouth_y); 150 appearance_bits8.mouth_y.Assign(store_data.GetMouthY());
135 151
136 appearance_bits8.mustache_type.Assign(char_info.mustache_type); 152 appearance_bits8.mustache_type.Assign(store_data.GetMustacheType());
137 appearance_bits9.mustache_scale.Assign(char_info.mustache_scale); 153 appearance_bits9.mustache_scale.Assign(store_data.GetMustacheScale());
138 appearance_bits9.mustache_y_position.Assign(char_info.mustache_y); 154 appearance_bits9.mustache_y.Assign(store_data.GetMustacheY());
139 155
140 appearance_bits9.bear_type.Assign(char_info.beard_type); 156 appearance_bits9.beard_type.Assign(store_data.GetBeardType());
141 157
142 appearance_bits10.glasses_scale.Assign(char_info.glasses_scale); 158 appearance_bits10.glass_scale.Assign(store_data.GetGlassScale());
143 appearance_bits10.glasses_y_position.Assign(char_info.glasses_y); 159 appearance_bits10.glass_y.Assign(store_data.GetGlassY());
144 160
145 appearance_bits11.mole_enabled.Assign(char_info.mole_type); 161 appearance_bits11.mole_type.Assign(store_data.GetMoleType());
146 appearance_bits11.mole_scale.Assign(char_info.mole_scale); 162 appearance_bits11.mole_scale.Assign(store_data.GetMoleScale());
147 appearance_bits11.mole_x_position.Assign(char_info.mole_x); 163 appearance_bits11.mole_x.Assign(store_data.GetMoleX());
148 appearance_bits11.mole_y_position.Assign(char_info.mole_y); 164 appearance_bits11.mole_y.Assign(store_data.GetMoleY());
149 165
150 // These types are converted to V3 from a table 166 // These types are converted to V3 from a table
151 appearance_bits1.skin_color.Assign(RawData::FromVer3GetFacelineColor(char_info.faceline_color)); 167 appearance_bits1.faceline_color.Assign(
152 appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(char_info.hair_color)); 168 RawData::FromVer3GetFacelineColor(store_data.GetFacelineColor()));
153 appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(char_info.eye_color)); 169 appearance_bits3.hair_color.Assign(RawData::FromVer3GetHairColor(store_data.GetHairColor()));
154 appearance_bits5.eyebrow_color.Assign(RawData::FromVer3GetHairColor(char_info.eyebrow_color)); 170 appearance_bits4.eye_color.Assign(RawData::FromVer3GetEyeColor(store_data.GetEyeColor()));
155 appearance_bits7.mouth_color.Assign(RawData::FromVer3GetMouthlineColor(char_info.mouth_color)); 171 appearance_bits5.eyebrow_color.Assign(
156 appearance_bits9.facial_hair_color.Assign(RawData::FromVer3GetHairColor(char_info.beard_color)); 172 RawData::FromVer3GetHairColor(store_data.GetEyebrowColor()));
157 appearance_bits10.glasses_color.Assign(RawData::FromVer3GetGlassColor(char_info.glasses_color)); 173 appearance_bits7.mouth_color.Assign(
158 appearance_bits10.glasses_type.Assign(RawData::FromVer3GetGlassType(char_info.glasses_type)); 174 RawData::FromVer3GetMouthlineColor(store_data.GetMouthColor()));
175 appearance_bits9.beard_color.Assign(RawData::FromVer3GetHairColor(store_data.GetBeardColor()));
176 appearance_bits10.glass_color.Assign(
177 RawData::FromVer3GetGlassColor(store_data.GetGlassColor()));
178 appearance_bits10.glass_type.Assign(RawData::FromVer3GetGlassType(store_data.GetGlassType()));
159 179
160 crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16)); 180 crc = MiiUtil::CalculateCrc16(&version, sizeof(Ver3StoreData) - sizeof(u16));
161} 181}
@@ -171,56 +191,56 @@ u32 Ver3StoreData::IsValid() const {
171 is_valid = is_valid && (height < 128); 191 is_valid = is_valid && (height < 128);
172 is_valid = is_valid && (build < 128); 192 is_valid = is_valid && (build < 128);
173 193
174 is_valid = is_valid && (appearance_bits1.face_shape < 12); 194 is_valid = is_valid && (appearance_bits1.faceline_type < 12);
175 is_valid = is_valid && (appearance_bits1.skin_color < 7); 195 is_valid = is_valid && (appearance_bits1.faceline_color < 7);
176 is_valid = is_valid && (appearance_bits2.wrinkles < 12); 196 is_valid = is_valid && (appearance_bits2.faceline_wrinkle < 12);
177 is_valid = is_valid && (appearance_bits2.makeup < 12); 197 is_valid = is_valid && (appearance_bits2.faceline_make < 12);
178 198
179 is_valid = is_valid && (hair_style < 132); 199 is_valid = is_valid && (hair_type < 132);
180 is_valid = is_valid && (appearance_bits3.hair_color < 8); 200 is_valid = is_valid && (appearance_bits3.hair_color < 8);
181 201
182 is_valid = is_valid && (appearance_bits4.eye_type < 60); 202 is_valid = is_valid && (appearance_bits4.eye_type < 60);
183 is_valid = is_valid && (appearance_bits4.eye_color < 6); 203 is_valid = is_valid && (appearance_bits4.eye_color < 6);
184 is_valid = is_valid && (appearance_bits4.eye_scale < 8); 204 is_valid = is_valid && (appearance_bits4.eye_scale < 8);
185 is_valid = is_valid && (appearance_bits4.eye_vertical_stretch < 7); 205 is_valid = is_valid && (appearance_bits4.eye_aspect < 7);
186 is_valid = is_valid && (appearance_bits4.eye_rotation < 8); 206 is_valid = is_valid && (appearance_bits4.eye_rotate < 8);
187 is_valid = is_valid && (appearance_bits4.eye_spacing < 13); 207 is_valid = is_valid && (appearance_bits4.eye_x < 13);
188 is_valid = is_valid && (appearance_bits4.eye_y_position < 19); 208 is_valid = is_valid && (appearance_bits4.eye_y < 19);
189 209
190 is_valid = is_valid && (appearance_bits5.eyebrow_style < 25); 210 is_valid = is_valid && (appearance_bits5.eyebrow_type < 25);
191 is_valid = is_valid && (appearance_bits5.eyebrow_color < 8); 211 is_valid = is_valid && (appearance_bits5.eyebrow_color < 8);
192 is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9); 212 is_valid = is_valid && (appearance_bits5.eyebrow_scale < 9);
193 is_valid = is_valid && (appearance_bits5.eyebrow_yscale < 7); 213 is_valid = is_valid && (appearance_bits5.eyebrow_aspect < 7);
194 is_valid = is_valid && (appearance_bits5.eyebrow_rotation < 12); 214 is_valid = is_valid && (appearance_bits5.eyebrow_rotate < 12);
195 is_valid = is_valid && (appearance_bits5.eyebrow_spacing < 12); 215 is_valid = is_valid && (appearance_bits5.eyebrow_x < 12);
196 is_valid = is_valid && (appearance_bits5.eyebrow_y_position < 19); 216 is_valid = is_valid && (appearance_bits5.eyebrow_y < 19);
197 217
198 is_valid = is_valid && (appearance_bits6.nose_type < 18); 218 is_valid = is_valid && (appearance_bits6.nose_type < 18);
199 is_valid = is_valid && (appearance_bits6.nose_scale < 9); 219 is_valid = is_valid && (appearance_bits6.nose_scale < 9);
200 is_valid = is_valid && (appearance_bits6.nose_y_position < 19); 220 is_valid = is_valid && (appearance_bits6.nose_y < 19);
201 221
202 is_valid = is_valid && (appearance_bits7.mouth_type < 36); 222 is_valid = is_valid && (appearance_bits7.mouth_type < 36);
203 is_valid = is_valid && (appearance_bits7.mouth_color < 5); 223 is_valid = is_valid && (appearance_bits7.mouth_color < 5);
204 is_valid = is_valid && (appearance_bits7.mouth_scale < 9); 224 is_valid = is_valid && (appearance_bits7.mouth_scale < 9);
205 is_valid = is_valid && (appearance_bits7.mouth_horizontal_stretch < 7); 225 is_valid = is_valid && (appearance_bits7.mouth_aspect < 7);
206 is_valid = is_valid && (appearance_bits8.mouth_y_position < 19); 226 is_valid = is_valid && (appearance_bits8.mouth_y < 19);
207 227
208 is_valid = is_valid && (appearance_bits8.mustache_type < 6); 228 is_valid = is_valid && (appearance_bits8.mustache_type < 6);
209 is_valid = is_valid && (appearance_bits9.mustache_scale < 7); 229 is_valid = is_valid && (appearance_bits9.mustache_scale < 7);
210 is_valid = is_valid && (appearance_bits9.mustache_y_position < 17); 230 is_valid = is_valid && (appearance_bits9.mustache_y < 17);
211 231
212 is_valid = is_valid && (appearance_bits9.bear_type < 6); 232 is_valid = is_valid && (appearance_bits9.beard_type < 6);
213 is_valid = is_valid && (appearance_bits9.facial_hair_color < 8); 233 is_valid = is_valid && (appearance_bits9.beard_color < 8);
214 234
215 is_valid = is_valid && (appearance_bits10.glasses_type < 9); 235 is_valid = is_valid && (appearance_bits10.glass_type < 9);
216 is_valid = is_valid && (appearance_bits10.glasses_color < 6); 236 is_valid = is_valid && (appearance_bits10.glass_color < 6);
217 is_valid = is_valid && (appearance_bits10.glasses_scale < 8); 237 is_valid = is_valid && (appearance_bits10.glass_scale < 8);
218 is_valid = is_valid && (appearance_bits10.glasses_y_position < 21); 238 is_valid = is_valid && (appearance_bits10.glass_y < 21);
219 239
220 is_valid = is_valid && (appearance_bits11.mole_enabled < 2); 240 is_valid = is_valid && (appearance_bits11.mole_type < 2);
221 is_valid = is_valid && (appearance_bits11.mole_scale < 9); 241 is_valid = is_valid && (appearance_bits11.mole_scale < 9);
222 is_valid = is_valid && (appearance_bits11.mole_x_position < 17); 242 is_valid = is_valid && (appearance_bits11.mole_x < 17);
223 is_valid = is_valid && (appearance_bits11.mole_y_position < 31); 243 is_valid = is_valid && (appearance_bits11.mole_y < 31);
224 244
225 return is_valid; 245 return is_valid;
226} 246}
diff --git a/src/core/hle/service/mii/types/ver3_store_data.h b/src/core/hle/service/mii/types/ver3_store_data.h
index 6b4e1eb9c..11caeb5c3 100644
--- a/src/core/hle/service/mii/types/ver3_store_data.h
+++ b/src/core/hle/service/mii/types/ver3_store_data.h
@@ -6,20 +6,32 @@
6#include "core/hle/service/mii/mii_types.h" 6#include "core/hle/service/mii/mii_types.h"
7 7
8namespace Service::Mii { 8namespace Service::Mii {
9class CharInfo; 9class StoreData;
10 10
11// This is nn::mii::Ver3StoreData 11// This is nn::mii::Ver3StoreData
12// Based on citra HLE::Applets::MiiData and PretendoNetwork. 12// Based on citra HLE::Applets::MiiData and PretendoNetwork.
13// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48 13// https://github.com/citra-emu/citra/blob/master/src/core/hle/applets/mii_selector.h#L48
14// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299 14// https://github.com/PretendoNetwork/mii-js/blob/master/mii.js#L299
15 15
16struct NfpStoreDataExtension {
17 void SetFromStoreData(const StoreData& store_data);
18
19 u8 faceline_color;
20 u8 hair_color;
21 u8 eye_color;
22 u8 eyebrow_color;
23 u8 mouth_color;
24 u8 beard_color;
25 u8 glass_color;
26 u8 glass_type;
27};
28static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size");
29
16#pragma pack(push, 4) 30#pragma pack(push, 4)
17class Ver3StoreData { 31class Ver3StoreData {
18public: 32public:
19 // TODO: This function is wrong. It should use StoreData. 33 void BuildToStoreData(StoreData& out_store_data) const;
20 void BuildToStoreData(CharInfo& out_char_info) const; 34 void BuildFromStoreData(const StoreData& store_data);
21 // TODO: This function is wrong. It should use StoreData.
22 void BuildFromStoreData(const CharInfo& char_info);
23 35
24 u32 IsValid() const; 36 u32 IsValid() const;
25 37
@@ -30,7 +42,7 @@ public:
30 BitField<0, 1, u8> allow_copying; 42 BitField<0, 1, u8> allow_copying;
31 BitField<1, 1, u8> profanity_flag; 43 BitField<1, 1, u8> profanity_flag;
32 BitField<2, 2, u8> region_lock; 44 BitField<2, 2, u8> region_lock;
33 BitField<4, 2, u8> character_set; 45 BitField<4, 2, u8> font_region;
34 } region_information; 46 } region_information;
35 u16_be mii_id; 47 u16_be mii_id;
36 u64_be system_id; 48 u64_be system_id;
@@ -53,21 +65,21 @@ public:
53 u8 raw; 65 u8 raw;
54 66
55 BitField<0, 1, u8> disable_sharing; 67 BitField<0, 1, u8> disable_sharing;
56 BitField<1, 4, u8> face_shape; 68 BitField<1, 4, u8> faceline_type;
57 BitField<5, 3, u8> skin_color; 69 BitField<5, 3, u8> faceline_color;
58 } appearance_bits1; 70 } appearance_bits1;
59 union { 71 union {
60 u8 raw; 72 u8 raw;
61 73
62 BitField<0, 4, u8> wrinkles; 74 BitField<0, 4, u8> faceline_wrinkle;
63 BitField<4, 4, u8> makeup; 75 BitField<4, 4, u8> faceline_make;
64 } appearance_bits2; 76 } appearance_bits2;
65 u8 hair_style; 77 u8 hair_type;
66 union { 78 union {
67 u8 raw; 79 u8 raw;
68 80
69 BitField<0, 3, u8> hair_color; 81 BitField<0, 3, u8> hair_color;
70 BitField<3, 1, u8> flip_hair; 82 BitField<3, 1, u8> hair_flip;
71 } appearance_bits3; 83 } appearance_bits3;
72 union { 84 union {
73 u32 raw; 85 u32 raw;
@@ -75,28 +87,28 @@ public:
75 BitField<0, 6, u32> eye_type; 87 BitField<0, 6, u32> eye_type;
76 BitField<6, 3, u32> eye_color; 88 BitField<6, 3, u32> eye_color;
77 BitField<9, 4, u32> eye_scale; 89 BitField<9, 4, u32> eye_scale;
78 BitField<13, 3, u32> eye_vertical_stretch; 90 BitField<13, 3, u32> eye_aspect;
79 BitField<16, 5, u32> eye_rotation; 91 BitField<16, 5, u32> eye_rotate;
80 BitField<21, 4, u32> eye_spacing; 92 BitField<21, 4, u32> eye_x;
81 BitField<25, 5, u32> eye_y_position; 93 BitField<25, 5, u32> eye_y;
82 } appearance_bits4; 94 } appearance_bits4;
83 union { 95 union {
84 u32 raw; 96 u32 raw;
85 97
86 BitField<0, 5, u32> eyebrow_style; 98 BitField<0, 5, u32> eyebrow_type;
87 BitField<5, 3, u32> eyebrow_color; 99 BitField<5, 3, u32> eyebrow_color;
88 BitField<8, 4, u32> eyebrow_scale; 100 BitField<8, 4, u32> eyebrow_scale;
89 BitField<12, 3, u32> eyebrow_yscale; 101 BitField<12, 3, u32> eyebrow_aspect;
90 BitField<16, 4, u32> eyebrow_rotation; 102 BitField<16, 4, u32> eyebrow_rotate;
91 BitField<21, 4, u32> eyebrow_spacing; 103 BitField<21, 4, u32> eyebrow_x;
92 BitField<25, 5, u32> eyebrow_y_position; 104 BitField<25, 5, u32> eyebrow_y;
93 } appearance_bits5; 105 } appearance_bits5;
94 union { 106 union {
95 u16 raw; 107 u16 raw;
96 108
97 BitField<0, 5, u16> nose_type; 109 BitField<0, 5, u16> nose_type;
98 BitField<5, 4, u16> nose_scale; 110 BitField<5, 4, u16> nose_scale;
99 BitField<9, 5, u16> nose_y_position; 111 BitField<9, 5, u16> nose_y;
100 } appearance_bits6; 112 } appearance_bits6;
101 union { 113 union {
102 u16 raw; 114 u16 raw;
@@ -104,38 +116,38 @@ public:
104 BitField<0, 6, u16> mouth_type; 116 BitField<0, 6, u16> mouth_type;
105 BitField<6, 3, u16> mouth_color; 117 BitField<6, 3, u16> mouth_color;
106 BitField<9, 4, u16> mouth_scale; 118 BitField<9, 4, u16> mouth_scale;
107 BitField<13, 3, u16> mouth_horizontal_stretch; 119 BitField<13, 3, u16> mouth_aspect;
108 } appearance_bits7; 120 } appearance_bits7;
109 union { 121 union {
110 u8 raw; 122 u8 raw;
111 123
112 BitField<0, 5, u8> mouth_y_position; 124 BitField<0, 5, u8> mouth_y;
113 BitField<5, 3, u8> mustache_type; 125 BitField<5, 3, u8> mustache_type;
114 } appearance_bits8; 126 } appearance_bits8;
115 u8 allow_copying; 127 u8 allow_copying;
116 union { 128 union {
117 u16 raw; 129 u16 raw;
118 130
119 BitField<0, 3, u16> bear_type; 131 BitField<0, 3, u16> beard_type;
120 BitField<3, 3, u16> facial_hair_color; 132 BitField<3, 3, u16> beard_color;
121 BitField<6, 4, u16> mustache_scale; 133 BitField<6, 4, u16> mustache_scale;
122 BitField<10, 5, u16> mustache_y_position; 134 BitField<10, 5, u16> mustache_y;
123 } appearance_bits9; 135 } appearance_bits9;
124 union { 136 union {
125 u16 raw; 137 u16 raw;
126 138
127 BitField<0, 4, u16> glasses_type; 139 BitField<0, 4, u16> glass_type;
128 BitField<4, 3, u16> glasses_color; 140 BitField<4, 3, u16> glass_color;
129 BitField<7, 4, u16> glasses_scale; 141 BitField<7, 4, u16> glass_scale;
130 BitField<11, 5, u16> glasses_y_position; 142 BitField<11, 5, u16> glass_y;
131 } appearance_bits10; 143 } appearance_bits10;
132 union { 144 union {
133 u16 raw; 145 u16 raw;
134 146
135 BitField<0, 1, u16> mole_enabled; 147 BitField<0, 1, u16> mole_type;
136 BitField<1, 4, u16> mole_scale; 148 BitField<1, 4, u16> mole_scale;
137 BitField<5, 5, u16> mole_x_position; 149 BitField<5, 5, u16> mole_x;
138 BitField<10, 5, u16> mole_y_position; 150 BitField<10, 5, u16> mole_y;
139 } appearance_bits11; 151 } appearance_bits11;
140 152
141 std::array<u16_le, 0xA> author_name; 153 std::array<u16_le, 0xA> author_name;
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 5e61d2595..eb7706015 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -824,8 +824,11 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe
824 return ResultWrongDeviceState; 824 return ResultWrongDeviceState;
825 } 825 }
826 826
827 Service::Mii::MiiManager manager; 827 Service::Mii::StoreData store_data{};
828 const auto mii = manager.BuildBase(Mii::Gender::Male); 828 Service::Mii::NfpStoreDataExtension extension{};
829 store_data.BuildBase(Mii::Gender::Male);
830 extension.SetFromStoreData(store_data);
831
829 auto& settings = tag_data.settings; 832 auto& settings = tag_data.settings;
830 833
831 if (tag_data.settings.settings.amiibo_initialized == 0) { 834 if (tag_data.settings.settings.amiibo_initialized == 0) {
@@ -834,8 +837,8 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe
834 } 837 }
835 838
836 SetAmiiboName(settings, register_info.amiibo_name); 839 SetAmiiboName(settings, register_info.amiibo_name);
837 tag_data.owner_mii.BuildFromStoreData(mii); 840 tag_data.owner_mii.BuildFromStoreData(store_data);
838 tag_data.mii_extension = manager.SetFromStoreData(mii); 841 tag_data.mii_extension = extension;
839 tag_data.unknown = 0; 842 tag_data.unknown = 0;
840 tag_data.unknown2 = {}; 843 tag_data.unknown2 = {};
841 settings.country_code_id = 0; 844 settings.country_code_id = 0;
@@ -1452,7 +1455,7 @@ void NfcDevice::UpdateRegisterInfoCrc() {
1452 1455
1453void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data, 1456void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
1454 const NFP::EncryptedNTAG215File& encrypted_file) const { 1457 const NFP::EncryptedNTAG215File& encrypted_file) const {
1455 Service::Mii::MiiManager manager; 1458 Service::Mii::StoreData store_data{};
1456 auto& settings = stubbed_tag_data.settings; 1459 auto& settings = stubbed_tag_data.settings;
1457 1460
1458 stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file); 1461 stubbed_tag_data = NFP::AmiiboCrypto::NfcDataToEncodedData(encrypted_file);
@@ -1466,7 +1469,8 @@ void NfcDevice::BuildAmiiboWithoutKeys(NFP::NTAG215File& stubbed_tag_data,
1466 SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'}); 1469 SetAmiiboName(settings, {'y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o'});
1467 settings.settings.font_region.Assign(0); 1470 settings.settings.font_region.Assign(0);
1468 settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); 1471 settings.init_date = GetAmiiboDate(GetCurrentPosixTime());
1469 stubbed_tag_data.owner_mii.BuildFromStoreData(manager.BuildBase(Mii::Gender::Male)); 1472 store_data.BuildBase(Mii::Gender::Male);
1473 stubbed_tag_data.owner_mii.BuildFromStoreData(store_data);
1470 1474
1471 // Admin info 1475 // Admin info
1472 settings.settings.amiibo_initialized.Assign(1); 1476 settings.settings.amiibo_initialized.Assign(1);