Просмотр исходного кода

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
David Marcec 8 лет назад
Родитель
Сommit
eccc77a8c8
1 измененных файлов с 50 добавлено и 5 удалено
  1. 50 5
      src/core/hle/service/ns/pl_u.cpp

+ 50 - 5
src/core/hle/service/ns/pl_u.cpp

@@ -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_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
 // Virtual address and offsets/sizes likely will vary by dump
 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);
 }
 
+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) {
     u32 value;
     std::memcpy(&value, data, sizeof(value));
@@ -109,10 +127,10 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
     RegisterHandlers(functions);
     // Attempt to load shared font data from disk
     const auto nand = FileSystem::GetSystemNANDContents();
+    size_t offset = 0;
     // Rebuild shared fonts from data ncas
     if (nand->HasEntry(static_cast<u64>(FontArchives::Standard),
                        FileSys::ContentRecordType::Data)) {
-        size_t offset = 0;
         shared_font = std::make_shared<std::vector<u8>>(SHARED_FONT_MEM_SIZE);
         for (auto font : SHARED_FONTS) {
             const auto nca =
@@ -152,18 +170,45 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
             DecryptSharedFont(font_data_u32, *shared_font, offset);
             SHARED_FONT_REGIONS.push_back(region);
         }
+
     } else {
-        const std::string filepath{FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir) +
-                                   SHARED_FONT};
+        shared_font = std::make_shared<std::vector<u8>>(
+            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
         if (!FileUtil::CreateFullPath(filepath)) {
             LOG_ERROR(Service_NS, "Failed to create sharedfonts path \"{}\"!", filepath);
             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");
 
-        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()) {
             // Read shared font data
             ASSERT(file.GetSize() == SHARED_FONT_MEM_SIZE);