summaryrefslogtreecommitdiffstats
path: root/src/core/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/loader')
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp68
-rw-r--r--src/core/loader/deconstructed_rom_directory.h7
-rw-r--r--src/core/loader/loader.cpp6
-rw-r--r--src/core/loader/loader.h10
-rw-r--r--src/core/loader/nca.cpp4
-rw-r--r--src/core/loader/nca.h2
-rw-r--r--src/core/loader/xci.cpp33
-rw-r--r--src/core/loader/xci.h5
8 files changed, 115 insertions, 20 deletions
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 9a8cdd0ff..915d525b0 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -7,6 +7,7 @@
#include "common/file_util.h"
#include "common/logging/log.h"
#include "core/file_sys/content_archive.h"
+#include "core/file_sys/control_metadata.h"
#include "core/gdbstub/gdbstub.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
@@ -17,8 +18,50 @@
namespace Loader {
-AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file)
- : AppLoader(std::move(file)) {}
+AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_)
+ : AppLoader(std::move(file_)) {
+ const auto dir = file->GetContainingDirectory();
+
+ // Icon
+ FileSys::VirtualFile icon_file = nullptr;
+ for (const auto& language : FileSys::LANGUAGE_NAMES) {
+ icon_file = dir->GetFile("icon_" + std::string(language) + ".dat");
+ if (icon_file != nullptr) {
+ icon_data = icon_file->ReadAllBytes();
+ break;
+ }
+ }
+
+ if (icon_data.empty()) {
+ // Any png, jpeg, or bmp file
+ const auto& files = dir->GetFiles();
+ const auto icon_iter =
+ std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
+ return file->GetExtension() == "png" || file->GetExtension() == "jpg" ||
+ file->GetExtension() == "bmp" || file->GetExtension() == "jpeg";
+ });
+ if (icon_iter != files.end())
+ icon_data = (*icon_iter)->ReadAllBytes();
+ }
+
+ // Metadata
+ FileSys::VirtualFile nacp_file = dir->GetFile("control.nacp");
+ if (nacp_file == nullptr) {
+ const auto& files = dir->GetFiles();
+ const auto nacp_iter =
+ std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
+ return file->GetExtension() == "nacp";
+ });
+ if (nacp_iter != files.end())
+ nacp_file = *nacp_iter;
+ }
+
+ if (nacp_file != nullptr) {
+ FileSys::NACP nacp(nacp_file);
+ title_id = nacp.GetTitleId();
+ name = nacp.GetApplicationName();
+ }
+}
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(
FileSys::VirtualDir directory)
@@ -105,4 +148,25 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile
return ResultStatus::Success;
}
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) {
+ if (icon_data.empty())
+ return ResultStatus::ErrorNotUsed;
+ buffer = icon_data;
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program_id) {
+ if (name.empty())
+ return ResultStatus::ErrorNotUsed;
+ out_program_id = title_id;
+ return ResultStatus::Success;
+}
+
+ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) {
+ if (name.empty())
+ return ResultStatus::ErrorNotUsed;
+ title = name;
+ return ResultStatus::Success;
+}
+
} // namespace Loader
diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h
index 7d5433563..b20804f75 100644
--- a/src/core/loader/deconstructed_rom_directory.h
+++ b/src/core/loader/deconstructed_rom_directory.h
@@ -39,11 +39,18 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
+ ResultStatus ReadIcon(std::vector<u8>& buffer) override;
+ ResultStatus ReadProgramId(u64& out_program_id) override;
+ ResultStatus ReadTitle(std::string& title) override;
private:
FileSys::ProgramMetadata metadata;
FileSys::VirtualFile romfs;
FileSys::VirtualDir dir;
+
+ std::vector<u8> icon_data;
+ std::string name;
+ u64 title_id{};
};
} // namespace Loader
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 57e6c0365..a288654df 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -43,10 +43,6 @@ FileType IdentifyFile(FileSys::VirtualFile file) {
return FileType::Unknown;
}
-FileType IdentifyFile(const std::string& file_name) {
- return IdentifyFile(std::make_shared<FileSys::RealVfsFile>(file_name));
-}
-
FileType GuessFromFilename(const std::string& name) {
if (name == "main")
return FileType::DeconstructedRomDirectory;
@@ -68,7 +64,7 @@ FileType GuessFromFilename(const std::string& name) {
return FileType::Unknown;
}
-const char* GetFileTypeString(FileType type) {
+std::string GetFileTypeString(FileType type) {
switch (type) {
case FileType::ELF:
return "ELF";
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index e69ab85ef..6a9e5a68b 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -43,14 +43,6 @@ enum class FileType {
FileType IdentifyFile(FileSys::VirtualFile file);
/**
- * Identifies the type of a bootable file based on the magic value in its header.
- * @param file_name path to file
- * @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
- * a filetype, and will never return FileType::Error.
- */
-FileType IdentifyFile(const std::string& file_name);
-
-/**
* Guess the type of a bootable file from its name
* @param name String name of bootable file
* @return FileType of file. Note: this will return FileType::Unknown if it is unable to determine
@@ -61,7 +53,7 @@ FileType GuessFromFilename(const std::string& name);
/**
* Convert a FileType into a string which can be displayed to the user.
*/
-const char* GetFileTypeString(FileType type);
+std::string GetFileTypeString(FileType type);
/// Return type for functions in Loader namespace
enum class ResultStatus {
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index dbc67c0b5..46f5cd393 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -77,8 +77,8 @@ ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
}
ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
- if (nca == nullptr)
- return ResultStatus::ErrorNotLoaded;
+ if (nca == nullptr || nca->GetStatus() != ResultStatus::Success)
+ return ResultStatus::ErrorInvalidFormat;
out_program_id = nca->GetTitleId();
return ResultStatus::Success;
}
diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h
index 0fd2d0417..7f7d8ea0b 100644
--- a/src/core/loader/nca.h
+++ b/src/core/loader/nca.h
@@ -33,7 +33,6 @@ public:
ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override;
-
ResultStatus ReadProgramId(u64& out_program_id) override;
~AppLoader_NCA();
@@ -41,6 +40,7 @@ public:
private:
FileSys::ProgramMetadata metadata;
+ FileSys::NCAHeader header;
std::unique_ptr<FileSys::NCA> nca;
std::unique_ptr<AppLoader_DeconstructedRomDirectory> directory_loader;
};
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index eb4dee2c2..d3fe24419 100644
--- a/src/core/loader/xci.cpp
+++ b/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
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
index 0dbcfbdf8..973833050 100644
--- a/src/core/loader/xci.h
+++ b/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