Added SharedFonts loading via TTF

By having the following TTF files in your yuzu sysdata directory. You can load sharedfonts via TTF files.
FontStandard.ttf
FontChineseSimplified.ttf
FontExtendedChineseSimplified.ttf
FontChineseTraditional.ttf
FontKorean.ttf
FontNintendoExtended.ttf
FontNintendoExtended2.ttf
This commit is contained in:
David Marcec 2018-08-23 14:42:06 +10:00
parent 74e08b4800
commit eccc77a8c8

View file

@ -35,6 +35,14 @@ static constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONT
std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"), std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"),
std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf")}; std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf")};
static constexpr std::array<const char*, 7> SHARED_FONTS_TTF{"FontStandard.ttf",
"FontChineseSimplified.ttf",
"FontExtendedChineseSimplified.ttf",
"FontChineseTraditional.ttf",
"FontKorean.ttf",
"FontNintendoExtended.ttf",
"FontNintendoExtended2.ttf"};
// The below data is specific to shared font data dumped from Switch on f/w 2.2 // The below data is specific to shared font data dumped from Switch on f/w 2.2
// Virtual address and offsets/sizes likely will vary by dump // Virtual address and offsets/sizes likely will vary by dump
static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; static constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL};
@ -76,6 +84,16 @@ void DecryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s
offset += transformed_font.size() * sizeof(u32); offset += transformed_font.size() * sizeof(u32);
} }
void EncryptSharedFont(const std::vector<u8>& input, std::vector<u8>& output, size_t& offset) {
ASSERT_MSG(offset + input.size() + 8 < SHARED_FONT_MEM_SIZE, "Shared fonts exceeds 17mb!");
const u32 KEY = EXPECTED_MAGIC ^ EXPECTED_RESULT;
std::memcpy(output.data() + offset, &EXPECTED_RESULT, sizeof(u32)); // Magic header
const u32 ENC_SIZE = static_cast<u32>(input.size()) ^ KEY;
std::memcpy(output.data() + offset + sizeof(u32), &ENC_SIZE, sizeof(u32));
std::memcpy(output.data() + offset + (sizeof(u32) * 2), input.data(), input.size());
offset += input.size() + (sizeof(u32) * 2);
}
static u32 GetU32Swapped(const u8* data) { static u32 GetU32Swapped(const u8* data) {
u32 value; u32 value;
std::memcpy(&value, data, sizeof(value)); std::memcpy(&value, data, sizeof(value));
@ -109,10 +127,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
RegisterHandlers(functions); RegisterHandlers(functions);
// Attempt to load shared font data from disk // Attempt to load shared font data from disk
const auto nand = FileSystem::GetSystemNANDContents(); const auto nand = FileSystem::GetSystemNANDContents();
size_t offset = 0;
// Rebuild shared fonts from data ncas // Rebuild shared fonts from data ncas
if (nand->HasEntry(static_cast<u64>(FontArchives::Standard), if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
FileSys::ContentRecordType::Data)) { FileSys::ContentRecordType::Data)) {
size_t offset = 0;
shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE); shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE);
for (auto font : SHARED_FONTS) { for (auto font : SHARED_FONTS) {
const auto nca = const auto nca =
@ -152,18 +170,45 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
DecryptSharedFont(font_data_u32, *shared_font, offset); DecryptSharedFont(font_data_u32, *shared_font, offset);
SHARED_FONT_REGIONS.push_back(region); SHARED_FONT_REGIONS.push_back(region);
} }
} else { } else {
const std::string filepath{FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) + shared_font = std::make_shared<std::vector<u8>>(
SHARED_FONT}; SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
const std::string user_path = FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir);
const std::string filepath{user_path + SHARED_FONT};
// Create path if not already created // Create path if not already created
if (!FileUtil::CreateFullPath(filepath)) { if (!FileUtil::CreateFullPath(filepath)) {
LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath); LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath);
return; return;
} }
bool using_ttf = false;
for (auto FontTTF : SHARED_FONTS_TTF) {
if (FileUtil::Exists(user_path + FontTTF)) {
using_ttf = true;
FileUtil::IOFile file(user_path + FontTTF, "rb");
if (file.IsOpen()) {
std::vector<u8> ttf_bytes(file.GetSize());
file.ReadBytes<u8>(ttf_bytes.data(), ttf_bytes.size());
FontRegion region{
static_cast<u32>(offset + 8),
static_cast<u32>(ttf_bytes.size())}; // Font offset and size do not account
// for the header
EncryptSharedFont(ttf_bytes, *shared_font, offset);
SHARED_FONT_REGIONS.push_back(region);
} else {
LOG_WARNING(Service_NS, "Unable to load font: {}", FontTTF);
}
} else if (using_ttf) {
LOG_WARNING(Service_NS, "Unable to find font: {}", FontTTF);
}
}
if (using_ttf)
return;
FileUtil::IOFile file(filepath, "rb"); FileUtil::IOFile file(filepath, "rb");
shared_font = std::make_shared<std::vector<u8>>(
SHARED_FONT_MEM_SIZE); // Shared memory needs to always be allocated and a fixed size
if (file.IsOpen()) { if (file.IsOpen()) {
// Read shared font data // Read shared font data
ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE); ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE);