mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2025-01-22 22:51:11 +01:00
1492d73ccb
* mii: Improve mii data variable naming * frd: Stub several functions Allows the friend applet to open successfully. * frd: Address review comments
245 lines
6.5 KiB
C++
245 lines
6.5 KiB
C++
// Copyright 2023 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <boost/serialization/base_object.hpp>
|
|
#include <boost/serialization/binary_object.hpp>
|
|
#include "common/bit_field.h"
|
|
#include "common/common_types.h"
|
|
|
|
namespace Mii {
|
|
|
|
using Nickname = std::array<char16_t, 10>;
|
|
|
|
#pragma pack(push, 1)
|
|
// Reference: https://github.com/devkitPro/libctru/blob/master/libctru/include/3ds/mii.h
|
|
struct MiiData {
|
|
u8 version; ///< Always 3?
|
|
|
|
/// Mii options
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 1, u8> allow_copying; ///< True if copying is allowed
|
|
BitField<1, 1, u8> is_private_name; ///< Private name?
|
|
BitField<2, 2, u8> region_lock; ///< Region lock (0=no lock, 1=JPN, 2=USA, 3=EUR)
|
|
BitField<4, 2, u8> char_set; ///< Character set (0=JPN+USA+EUR, 1=CHN, 2=KOR, 3=TWN)
|
|
} mii_options;
|
|
|
|
/// Mii position in Mii selector or Mii maker
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 4, u8> page_index; ///< Page index of Mii
|
|
BitField<4, 4, u8> slot_index; ///< Slot offset of Mii on its Page
|
|
} mii_pos;
|
|
|
|
/// Console Identity
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 4, u8> unknown0; ///< Mabye padding (always seems to be 0)?
|
|
BitField<4, 3, u8>
|
|
origin_console; ///< Console that the Mii was created on (1=WII, 2=DSI, 3=3DS)
|
|
} console_identity;
|
|
|
|
u64_be system_id; ///< Identifies the system that the Mii was created on (Determines pants)
|
|
u32_be mii_id; ///< ID of Mii
|
|
std::array<u8, 6> mac; ///< Creator's system's full MAC address
|
|
u16 pad; ///< Padding
|
|
|
|
/// Mii details
|
|
union {
|
|
u16_be raw;
|
|
|
|
BitField<0, 1, u16> gender; ///< Gender of Mii (0=Male, 1=Female)
|
|
BitField<1, 4, u16> bday_month; ///< Month of Mii's birthday
|
|
BitField<5, 5, u16> bday_day; ///< Day of Mii's birthday
|
|
BitField<10, 4, u16> favorite_color; ///< Color of Mii's shirt
|
|
BitField<14, 1, u16> favorite; ///< Whether the Mii is one of your 10 favorite Mii's
|
|
} mii_details;
|
|
|
|
Nickname mii_name; ///< Name of Mii (Encoded using UTF16)
|
|
u8 height; ///< How tall the Mii is
|
|
u8 width; ///< How wide the Mii is
|
|
|
|
/// Face style
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 1, u8> disable_sharing; ///< Whether or not Sharing of the Mii is allowed
|
|
BitField<1, 4, u8> type; ///< Face type
|
|
BitField<5, 3, u8> skin_color; ///< Color of skin
|
|
} face_style;
|
|
|
|
/// Face details
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 4, u8> wrinkles;
|
|
BitField<4, 4, u8> makeup;
|
|
} face_details;
|
|
|
|
u8 hair_style;
|
|
|
|
/// Hair details
|
|
union {
|
|
u8 raw;
|
|
|
|
BitField<0, 3, u8> color;
|
|
BitField<3, 1, u8> flip;
|
|
} hair_details;
|
|
|
|
/// Eye 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;
|
|
|
|
/// Eyebrow 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;
|
|
|
|
/// Nose details
|
|
union {
|
|
u16_be raw;
|
|
|
|
BitField<0, 5, u16> type;
|
|
BitField<5, 4, u16> scale;
|
|
BitField<9, 5, u16> y;
|
|
} nose_details;
|
|
|
|
/// Mouth 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;
|
|
|
|
/// Mustache details
|
|
union {
|
|
u16_be raw;
|
|
|
|
BitField<0, 5, u16> mouth_y;
|
|
BitField<5, 3, u16> mustache_type;
|
|
} mustache_details;
|
|
|
|
/// Beard 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;
|
|
|
|
/// Glasses 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;
|
|
|
|
/// Mole 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; ///< Name of Mii's author (Encoded using UTF16)
|
|
private:
|
|
template <class Archive>
|
|
void serialize(Archive& ar, const unsigned int) {
|
|
ar& boost::serialization::make_binary_object(this, sizeof(MiiData));
|
|
}
|
|
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) {
|
|
ar& boost::serialization::make_binary_object(this, sizeof(ChecksummedMiiData));
|
|
}
|
|
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.");
|
|
} // namespace Mii
|