From 9e88f03e7591bd3b91d7af9b9995a727c0b92ac9 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 28 Jul 2018 12:32:16 -0400 Subject: Avoid parsing RomFS to directory in NCA --- src/yuzu/game_list.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 9 deletions(-) (limited to 'src/yuzu/game_list.cpp') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 24f38a3c7..893c5f693 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -12,6 +12,8 @@ #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" #include "core/file_sys/vfs_real.h" #include "core/loader/loader.h" #include "game_list.h" @@ -398,8 +400,32 @@ void GameList::RefreshGameDirectory() { } void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) { - const auto callback = [this, recursion](u64* num_entries_out, const std::string& directory, - const std::string& virtual_name) -> bool { + boost::container::flat_map> nca_control_map; + + const auto nca_control_callback = + [this, &nca_control_map](u64* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { + std::string physical_name = directory + DIR_SEP + virtual_name; + + if (stop_processing) + return false; // Breaks the callback loop. + + bool is_dir = FileUtil::IsDirectory(physical_name); + QFileInfo file_info(physical_name.c_str()); + if (!is_dir && file_info.suffix().toStdString() == "nca") { + auto nca = std::make_shared( + std::make_shared(physical_name)); + if (nca->GetType() == FileSys::NCAContentType::Control) + nca_control_map.insert_or_assign(nca->GetTitleId(), nca); + } + return true; + }; + + FileUtil::ForeachDirectoryEntry(nullptr, dir_path, nca_control_callback); + + const auto callback = [this, recursion, + &nca_control_map](u64* num_entries_out, const std::string& directory, + const std::string& virtual_name) -> bool { std::string physical_name = directory + DIR_SEP + virtual_name; if (stop_processing) @@ -410,17 +436,50 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { std::unique_ptr loader = Loader::GetLoader(std::make_shared(physical_name)); - if (!loader) + if (!loader || ((loader->GetFileType() == Loader::FileType::Unknown || + loader->GetFileType() == Loader::FileType::Error) && + !UISettings::values.show_unknown)) return true; - std::vector smdh; - loader->ReadIcon(smdh); - - u64 program_id = 0; - loader->ReadProgramId(program_id); + std::vector icon; + const auto res1 = loader->ReadIcon(icon); + + u64 program_id; + const auto res2 = loader->ReadProgramId(program_id); + + std::string name = " "; + const auto res3 = loader->ReadTitle(name); + + if ((res1 == Loader::ResultStatus::ErrorNotUsed || + res1 == Loader::ResultStatus::ErrorNotImplemented) && + (res3 == Loader::ResultStatus::ErrorNotUsed || + res3 == Loader::ResultStatus::ErrorNotImplemented) && + res2 == Loader::ResultStatus::Success) { + // 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); + + auto nacp_file = control_dir->GetFile("control.nacp"); + FileSys::NACP nacp(nacp_file); + name = nacp.GetApplicationName(); + + FileSys::VirtualFile icon_file = nullptr; + for (const auto& language : FileSys::LANGUAGE_NAMES) { + icon_file = control_dir->GetFile("icon_" + language + ".dat"); + if (icon_file != nullptr) { + icon = icon_file->ReadAllBytes(); + break; + } + } + } + } emit EntryReady({ - new GameListItemPath(FormatGameName(physical_name), smdh, program_id), + new GameListItemPath( + FormatGameName(physical_name), icon, QString::fromStdString(name), + QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), + program_id), new GameListItem( QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(FileUtil::GetSize(physical_name)), -- cgit v1.2.3 From 5927cf0e177d1804bcc0d9f95aa3fe1c4d0f6201 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 28 Jul 2018 12:35:02 -0400 Subject: Use const where applicable --- src/yuzu/game_list.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/yuzu/game_list.cpp') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 893c5f693..481d91be5 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -466,7 +466,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign FileSys::VirtualFile icon_file = nullptr; for (const auto& language : FileSys::LANGUAGE_NAMES) { - icon_file = control_dir->GetFile("icon_" + language + ".dat"); + icon_file = control_dir->GetFile("icon_" + std::string(language) + ".dat"); if (icon_file != nullptr) { icon = icon_file->ReadAllBytes(); break; -- cgit v1.2.3 From 91cfe70301bec23099ae27ad70e3da525a573cfe Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 6 Aug 2018 23:13:37 -0400 Subject: loader: Add icon and title support to XCI --- src/yuzu/game_list.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/yuzu/game_list.cpp') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 481d91be5..5f47f5a2b 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #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(); -- cgit v1.2.3 From 4b471f0554146463f3b82eed14ff3922a5584e9f Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 3 Aug 2018 11:51:48 -0400 Subject: core: Port core to VfsFilesystem for file access --- src/yuzu/game_list.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/yuzu/game_list.cpp') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 5f47f5a2b..e150a0684 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -197,7 +197,8 @@ void GameList::onFilterCloseClicked() { main_window->filterBarSetChecked(false); } -GameList::GameList(GMainWindow* parent) : QWidget{parent} { +GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) + : QWidget{parent}, vfs(std::move(vfs)) { watcher = new QFileSystemWatcher(this); connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); @@ -341,7 +342,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { emit ShouldCancelWorker(); - GameListWorker* worker = new GameListWorker(dir_path, deep_scan); + GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan); connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating, @@ -436,7 +437,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign if (!is_dir && (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { std::unique_ptr loader = - Loader::GetLoader(std::make_shared(physical_name)); + Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read)); if (!loader || ((loader->GetFileType() == Loader::FileType::Unknown || loader->GetFileType() == Loader::FileType::Error) && !UISettings::values.show_unknown)) -- cgit v1.2.3 From 94cf327e776eff934052847346d8415d584b369b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Wed, 8 Aug 2018 14:34:06 -0400 Subject: vfs: Fix typo in VfsFilesystem docs --- src/yuzu/game_list.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/yuzu/game_list.cpp') diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index e150a0684..1c738d2a4 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -15,6 +15,7 @@ #include "common/string_util.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" +#include "core/file_sys/romfs.h" #include "core/file_sys/vfs_real.h" #include "core/loader/loader.h" #include "game_list.h" @@ -415,8 +416,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign bool is_dir = FileUtil::IsDirectory(physical_name); QFileInfo file_info(physical_name.c_str()); if (!is_dir && file_info.suffix().toStdString() == "nca") { - auto nca = std::make_shared( - std::make_shared(physical_name)); + auto nca = + std::make_shared(vfs->OpenFile(physical_name, FileSys::Mode::Read)); if (nca->GetType() == FileSys::NCAContentType::Control) nca_control_map.insert_or_assign(nca->GetTitleId(), nca); } @@ -460,7 +461,7 @@ 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]; - const auto control_dir = nca->GetSubdirectories()[0]; + const auto control_dir = FileSys::ExtractRomFS(nca->GetRomFS()); const auto nacp_file = control_dir->GetFile("control.nacp"); FileSys::NACP nacp(nacp_file); -- cgit v1.2.3