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

loader: Add icon and title support to XCI

Zach Hilman 8 лет назад
Родитель
Сommit
91cfe70301

+ 1 - 0
src/core/file_sys/card_image.cpp

@@ -5,6 +5,7 @@
 #include <array>
 #include <string>
 #include <core/loader/loader.h>
+#include "common/logging/log.h"
 #include "core/file_sys/card_image.h"
 #include "core/file_sys/partition_filesystem.h"
 #include "core/file_sys/vfs_offset.h"

+ 4 - 0
src/core/file_sys/content_archive.cpp

@@ -140,6 +140,10 @@ VirtualFile NCA::Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_o
 }
 
 NCA::NCA(VirtualFile file_) : file(std::move(file_)) {
+    if (file == nullptr) {
+        status = Loader::ResultStatus::ErrorInvalidFormat;
+        return;
+    }
     if (sizeof(NCAHeader) != file->ReadObject(&header))
         LOG_ERROR(Loader, "File reader errored out during header read.");
 

+ 1 - 0
src/core/file_sys/content_archive.h

@@ -12,6 +12,7 @@
 #include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/swap.h"
+#include "control_metadata.h"
 #include "core/crypto/key_manager.h"
 #include "core/file_sys/partition_filesystem.h"
 #include "core/loader/loader.h"

+ 0 - 2
src/core/loader/nca.h

@@ -35,8 +35,6 @@ public:
     ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
     ResultStatus ReadProgramId(u64& out_program_id) override;
 
-    ResultStatus ReadProgramId(u64& out_program_id) override;
-
     ~AppLoader_NCA();
 
 private:

+ 32 - 1
src/core/loader/xci.cpp

@@ -26,7 +26,25 @@ namespace Loader {
 AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
     : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file)),
       nca_loader(std::make_unique<AppLoader_NCA>(
-          xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {}
+          xci->GetNCAFileByType(FileSys::NCAContentType::Program))) {
+    if (xci->GetStatus() != ResultStatus::Success)
+        return;
+    const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
+    if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
+        return;
+    const auto romfs = FileSys::ExtractRomFS(control_nca->GetRomFS());
+    if (romfs == nullptr)
+        return;
+    for (const auto& language : FileSys::LANGUAGE_NAMES) {
+        icon_file = romfs->GetFile("icon_" + std::string(language) + ".dat");
+        if (icon_file != nullptr)
+            break;
+    }
+    const auto nacp_raw = romfs->GetFile("control.nacp");
+    if (nacp_raw == nullptr)
+        return;
+    nacp_file = std::make_shared<FileSys::NACP>(nacp_raw);
+}
 
 AppLoader_XCI::~AppLoader_XCI() = default;
 
@@ -71,4 +89,17 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
     return nca_loader->ReadProgramId(out_program_id);
 }
 
+ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
+    if (icon_file == nullptr)
+        return ResultStatus::ErrorInvalidFormat;
+    buffer = icon_file->ReadAllBytes();
+    return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_XCI::ReadTitle(std::string& title) {
+    if (nacp_file == nullptr)
+        return ResultStatus::ErrorInvalidFormat;
+    title = nacp_file->GetApplicationName();
+    return ResultStatus::Success;
+}
 } // namespace Loader

+ 5 - 0
src/core/loader/xci.h

@@ -33,12 +33,17 @@ public:
 
     ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
     ResultStatus ReadProgramId(u64& out_program_id) override;
+    ResultStatus ReadIcon(std::vector<u8>& buffer) override;
+    ResultStatus ReadTitle(std::string& title) override;
 
 private:
     FileSys::ProgramMetadata metadata;
 
     std::unique_ptr<FileSys::XCI> xci;
     std::unique_ptr<AppLoader_NCA> nca_loader;
+
+    FileSys::VirtualFile icon_file;
+    std::shared_ptr<FileSys::NACP> nacp_file;
 };
 
 } // namespace Loader

+ 3 - 2
src/yuzu/game_list.cpp

@@ -9,6 +9,7 @@
 #include <QKeyEvent>
 #include <QMenu>
 #include <QThreadPool>
+#include <boost/container/flat_map.hpp>
 #include "common/common_paths.h"
 #include "common/logging/log.h"
 #include "common/string_util.h"
@@ -458,9 +459,9 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
                 // Use from metadata pool.
                 if (nca_control_map.find(program_id) != nca_control_map.end()) {
                     const auto nca = nca_control_map[program_id];
-                    auto control_dir = nca->GetSection(0);
+                    const auto control_dir = nca->GetSubdirectories()[0];
 
-                    auto nacp_file = control_dir->GetFile("control.nacp");
+                    const auto nacp_file = control_dir->GetFile("control.nacp");
                     FileSys::NACP nacp(nacp_file);
                     name = nacp.GetApplicationName();