core: nfp: Correct date and amiibo name
This commit is contained in:
parent
19a4e12e6e
commit
caa138b33f
4 changed files with 36 additions and 18 deletions
|
@ -443,8 +443,9 @@ CharInfo MiiManager::ConvertV3ToCharInfo(Ver3StoreData mii_v3) const {
|
||||||
mii.height = mii_v3.height;
|
mii.height = mii_v3.height;
|
||||||
mii.build = mii_v3.build;
|
mii.build = mii_v3.build;
|
||||||
|
|
||||||
|
memset(mii.name.data(), 0, sizeof(mii.name));
|
||||||
|
memcpy(mii.name.data(), mii_v3.mii_name.data(), sizeof(mii_v3.mii_name));
|
||||||
mii.font_region = mii_v3.region_information.character_set;
|
mii.font_region = mii_v3.region_information.character_set;
|
||||||
memcpy(mii.name.data(), mii_v3.mii_name.data(), 10);
|
|
||||||
|
|
||||||
mii.faceline_type = mii_v3.appearance_bits1.face_shape;
|
mii.faceline_type = mii_v3.appearance_bits1.face_shape;
|
||||||
mii.faceline_color = mii_v3.appearance_bits1.skin_color;
|
mii.faceline_color = mii_v3.appearance_bits1.skin_color;
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include "core/hle/service/mii/types.h"
|
#include "core/hle/service/mii/types.h"
|
||||||
|
|
||||||
namespace Service::NFP {
|
namespace Service::NFP {
|
||||||
|
static constexpr std::size_t amiibo_name_length = 0xA;
|
||||||
|
|
||||||
enum class ServiceType : u32 {
|
enum class ServiceType : u32 {
|
||||||
User,
|
User,
|
||||||
Debug,
|
Debug,
|
||||||
|
@ -76,16 +78,16 @@ using HashData = std::array<u8, 0x20>;
|
||||||
using ApplicationArea = std::array<u8, 0xD8>;
|
using ApplicationArea = std::array<u8, 0xD8>;
|
||||||
|
|
||||||
struct AmiiboDate {
|
struct AmiiboDate {
|
||||||
u16_be raw_date{};
|
u16 raw_date{};
|
||||||
|
|
||||||
u16 GetYear() const {
|
u16 GetYear() const {
|
||||||
return ((raw_date & 0xFE00) >> 9) + 2000;
|
return static_cast<u16>(((raw_date & 0xFE00) >> 9) + 2000);
|
||||||
}
|
}
|
||||||
u8 GetMonth() const {
|
u8 GetMonth() const {
|
||||||
return ((raw_date & 0x01E0) >> 5) - 1;
|
return static_cast<u8>(((raw_date & 0x01E0) >> 5) - 1);
|
||||||
}
|
}
|
||||||
u8 GetDay() const {
|
u8 GetDay() const {
|
||||||
return raw_date & 0x001F;
|
return static_cast<u8>(raw_date & 0x001F);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static_assert(sizeof(AmiiboDate) == 2, "AmiiboDate is an invalid size");
|
static_assert(sizeof(AmiiboDate) == 2, "AmiiboDate is an invalid size");
|
||||||
|
@ -107,7 +109,7 @@ struct AmiiboSettings {
|
||||||
AmiiboDate init_date;
|
AmiiboDate init_date;
|
||||||
AmiiboDate write_date;
|
AmiiboDate write_date;
|
||||||
u32_be crc;
|
u32_be crc;
|
||||||
std::array<u16_be, 0xA> amiibo_name; // UTF-16 text
|
std::array<u16_be, amiibo_name_length> amiibo_name; // UTF-16 text
|
||||||
};
|
};
|
||||||
static_assert(sizeof(AmiiboSettings) == 0x20, "AmiiboSettings is an invalid size");
|
static_assert(sizeof(AmiiboSettings) == 0x20, "AmiiboSettings is an invalid size");
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/fs/file.h"
|
#include "common/fs/file.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hid/emulated_controller.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
#include "core/hid/hid_core.h"
|
#include "core/hid/hid_core.h"
|
||||||
|
@ -917,20 +918,14 @@ Result Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const {
|
||||||
if (is_data_decoded && tag_data.settings.settings.amiibo_initialized != 0) {
|
if (is_data_decoded && tag_data.settings.settings.amiibo_initialized != 0) {
|
||||||
const auto& settings = tag_data.settings;
|
const auto& settings = tag_data.settings;
|
||||||
|
|
||||||
// Amiibo name is u16 while the register info is u8. Figure out how to handle this properly
|
|
||||||
std::array<u8, 11> amiibo_name{};
|
|
||||||
for (std::size_t i = 0; i < sizeof(amiibo_name) - 1; ++i) {
|
|
||||||
amiibo_name[i] = static_cast<u8>(settings.amiibo_name[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Validate this data
|
// TODO: Validate this data
|
||||||
register_info = {
|
register_info = {
|
||||||
.mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii),
|
.mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii),
|
||||||
.first_write_year = settings.init_date.GetYear(),
|
.first_write_year = settings.init_date.GetYear(),
|
||||||
.first_write_month = settings.init_date.GetMonth(),
|
.first_write_month = settings.init_date.GetMonth(),
|
||||||
.first_write_day = settings.init_date.GetDay(),
|
.first_write_day = settings.init_date.GetDay(),
|
||||||
.amiibo_name = amiibo_name,
|
.amiibo_name = GetAmiiboName(settings),
|
||||||
.unknown = {},
|
.font_region = {},
|
||||||
};
|
};
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
|
@ -943,7 +938,7 @@ Result Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const {
|
||||||
.first_write_month = 2,
|
.first_write_month = 2,
|
||||||
.first_write_day = 7,
|
.first_write_day = 7,
|
||||||
.amiibo_name = {'Y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o', 0},
|
.amiibo_name = {'Y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o', 0},
|
||||||
.unknown = {},
|
.font_region = {},
|
||||||
};
|
};
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
@ -1077,6 +1072,22 @@ Core::HID::NpadIdType Module::Interface::GetNpadId() const {
|
||||||
return npad_id;
|
return npad_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AmiiboName Module::Interface::GetAmiiboName(const AmiiboSettings& settings) const {
|
||||||
|
std::array<char16_t, amiibo_name_length> settings_amiibo_name{};
|
||||||
|
AmiiboName amiibo_name{};
|
||||||
|
|
||||||
|
// Convert from big endian to little endian
|
||||||
|
for (std::size_t i = 0; i < amiibo_name_length; i++) {
|
||||||
|
settings_amiibo_name[i] = static_cast<u16>(settings.amiibo_name[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert from utf16 to utf8
|
||||||
|
const auto amiibo_name_utf8 = Common::UTF16ToUTF8(settings_amiibo_name.data());
|
||||||
|
memcpy(amiibo_name.data(), amiibo_name_utf8.data(), amiibo_name_utf8.size());
|
||||||
|
|
||||||
|
return amiibo_name;
|
||||||
|
}
|
||||||
|
|
||||||
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
||||||
auto module = std::make_shared<Module>();
|
auto module = std::make_shared<Module>();
|
||||||
std::make_shared<NFP_User>(module, system)->InstallAsService(service_manager);
|
std::make_shared<NFP_User>(module, system)->InstallAsService(service_manager);
|
||||||
|
|
|
@ -22,6 +22,8 @@ enum class NpadIdType : u32;
|
||||||
} // namespace Core::HID
|
} // namespace Core::HID
|
||||||
|
|
||||||
namespace Service::NFP {
|
namespace Service::NFP {
|
||||||
|
using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
|
||||||
|
|
||||||
struct TagInfo {
|
struct TagInfo {
|
||||||
TagUuid uuid;
|
TagUuid uuid;
|
||||||
u8 uuid_length;
|
u8 uuid_length;
|
||||||
|
@ -59,9 +61,9 @@ struct RegisterInfo {
|
||||||
u16 first_write_year;
|
u16 first_write_year;
|
||||||
u8 first_write_month;
|
u8 first_write_month;
|
||||||
u8 first_write_day;
|
u8 first_write_day;
|
||||||
std::array<u8, 0xA + 1> amiibo_name;
|
AmiiboName amiibo_name;
|
||||||
u8 unknown;
|
u8 font_region;
|
||||||
INSERT_PADDING_BYTES(0x98);
|
INSERT_PADDING_BYTES(0x7A);
|
||||||
};
|
};
|
||||||
static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size");
|
static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size");
|
||||||
|
|
||||||
|
@ -109,6 +111,8 @@ public:
|
||||||
std::shared_ptr<Module> module;
|
std::shared_ptr<Module> module;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AmiiboName GetAmiiboName(const AmiiboSettings& settings) const;
|
||||||
|
|
||||||
const Core::HID::NpadIdType npad_id;
|
const Core::HID::NpadIdType npad_id;
|
||||||
|
|
||||||
bool is_data_decoded{};
|
bool is_data_decoded{};
|
||||||
|
|
Loading…
Reference in a new issue