| | |
| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <boost/serialization/export.hpp> |
| | #include "common/bit_field.h" |
| | #include "common/common_types.h" |
| |
|
| | namespace Mii { |
| |
|
| | using Nickname = std::array<char16_t, 10>; |
| |
|
| | #pragma pack(push, 1) |
| | |
| | struct MiiData { |
| | u8 version; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 1, u8> allow_copying; |
| | BitField<1, 1, u8> is_private_name; |
| | BitField<2, 2, u8> region_lock; |
| | BitField<4, 2, u8> char_set; |
| | } mii_options; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 4, u8> page_index; |
| | BitField<4, 4, u8> slot_index; |
| | } mii_pos; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 4, u8> unknown0; |
| | BitField<4, 3, u8> |
| | origin_console; |
| | } console_identity; |
| |
|
| | u64_be system_id; |
| | u32_be mii_id; |
| | std::array<u8, 6> mac; |
| | u16 pad; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 1, u16> gender; |
| | BitField<1, 4, u16> bday_month; |
| | BitField<5, 5, u16> bday_day; |
| | BitField<10, 4, u16> favorite_color; |
| | BitField<14, 1, u16> favorite; |
| | } mii_details; |
| |
|
| | Nickname mii_name; |
| | u8 height; |
| | u8 width; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 1, u8> disable_sharing; |
| | BitField<1, 4, u8> type; |
| | BitField<5, 3, u8> skin_color; |
| | } face_style; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 4, u8> wrinkles; |
| | BitField<4, 4, u8> makeup; |
| | } face_details; |
| |
|
| | u8 hair_style; |
| |
|
| | |
| | union { |
| | u8 raw; |
| |
|
| | BitField<0, 3, u8> color; |
| | BitField<3, 1, u8> flip; |
| | } hair_details; |
| |
|
| | |
| | union { |
| | u32_be raw; |
| |
|
| | BitField<0, 6, u32> type; |
| | BitField<6, 3, u32> color; |
| | BitField<9, 4, u32> scale; |
| | BitField<13, 3, u32> aspect; |
| | BitField<16, 5, u32> rotate; |
| | BitField<21, 4, u32> x; |
| | BitField<25, 5, u32> y; |
| | } eye_details; |
| |
|
| | |
| | union { |
| | u32_be raw; |
| |
|
| | BitField<0, 5, u32> style; |
| | BitField<5, 3, u32> color; |
| | BitField<8, 4, u32> scale; |
| | BitField<12, 3, u32> aspect; |
| | BitField<16, 5, u32> rotate; |
| | BitField<21, 4, u32> x; |
| | BitField<25, 5, u32> y; |
| | } eyebrow_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 5, u16> type; |
| | BitField<5, 4, u16> scale; |
| | BitField<9, 5, u16> y; |
| | } nose_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 6, u16> type; |
| | BitField<6, 3, u16> color; |
| | BitField<9, 4, u16> scale; |
| | BitField<13, 3, u16> aspect; |
| | } mouth_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 5, u16> mouth_y; |
| | BitField<5, 3, u16> mustache_type; |
| | } mustache_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 3, u16> type; |
| | BitField<3, 3, u16> color; |
| | BitField<6, 4, u16> scale; |
| | BitField<10, 5, u16> y; |
| | } beard_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 4, u16> type; |
| | BitField<4, 3, u16> color; |
| | BitField<7, 4, u16> scale; |
| | BitField<11, 5, u16> y; |
| | } glasses_details; |
| |
|
| | |
| | union { |
| | u16_be raw; |
| |
|
| | BitField<0, 1, u16> type; |
| | BitField<1, 4, u16> scale; |
| | BitField<5, 5, u16> x; |
| | BitField<10, 5, u16> y; |
| | } mole_details; |
| |
|
| | Nickname author_name; |
| | private: |
| | template <class Archive> |
| | void serialize(Archive& ar, const unsigned int); |
| | friend class boost::serialization::access; |
| | }; |
| |
|
| | static_assert(sizeof(MiiData) == 0x5C, "MiiData structure has incorrect size"); |
| | static_assert(std::is_trivial_v<MiiData>, "MiiData must be trivial."); |
| | static_assert(std::is_trivially_copyable_v<MiiData>, "MiiData must be trivially copyable."); |
| |
|
| | struct ChecksummedMiiData { |
| | private: |
| | MiiData mii_data; |
| | u16 padding; |
| | u16_be crc16; |
| |
|
| | public: |
| | ChecksummedMiiData& operator=(const MiiData& data) { |
| | mii_data = data; |
| | padding = 0; |
| | FixChecksum(); |
| | return *this; |
| | } |
| |
|
| | ChecksummedMiiData& operator=(MiiData&& data) { |
| | mii_data = std::move(data); |
| | padding = 0; |
| | FixChecksum(); |
| | return *this; |
| | } |
| |
|
| | void SetMiiData(MiiData data) { |
| | mii_data = data; |
| | FixChecksum(); |
| | } |
| |
|
| | operator MiiData() const { |
| | return mii_data; |
| | } |
| |
|
| | bool IsChecksumValid() { |
| | return crc16 == CalculateChecksum(); |
| | } |
| |
|
| | u16 CalculateChecksum(); |
| |
|
| | void FixChecksum() { |
| | crc16 = CalculateChecksum(); |
| | } |
| |
|
| | private: |
| | template <class Archive> |
| | void serialize(Archive& ar, const unsigned int); |
| | friend class boost::serialization::access; |
| | }; |
| | #pragma pack(pop) |
| | static_assert(sizeof(ChecksummedMiiData) == 0x60, |
| | "ChecksummedMiiData structure has incorrect size"); |
| | static_assert(std::is_trivial_v<ChecksummedMiiData>, "ChecksummedMiiData must be trivial."); |
| | static_assert(std::is_trivially_copyable_v<ChecksummedMiiData>, |
| | "ChecksummedMiiData must be trivially copyable."); |
| | } |
| |
|
| | BOOST_CLASS_EXPORT_KEY(Mii::MiiData) |
| | BOOST_CLASS_EXPORT_KEY(Mii::ChecksummedMiiData) |
| |
|