Merge pull request #850 from DarkLordZach/icon-meta

Add Icons and Metadata Support
This commit is contained in:
bunnei 2018-08-08 12:27:19 -04:00 committed by GitHub
commit fd9da4232b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 490 additions and 20 deletions

View file

@ -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

View file

@ -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

View file

@ -68,7 +68,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";

View file

@ -61,7 +61,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 {

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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

View file

@ -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