summaryrefslogtreecommitdiff
path: root/src/yuzu/game_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/game_list.cpp')
-rw-r--r--src/yuzu/game_list.cpp72
1 files changed, 47 insertions, 25 deletions
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 3e2a5976b..a3b841684 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -21,6 +21,7 @@
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/nca_metadata.h"
+#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs.h"
#include "core/file_sys/vfs_real.h"
@@ -232,6 +233,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent)
item_model->insertColumns(0, COLUMN_COUNT);
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, "Name");
item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, "Compatibility");
+ item_model->setHeaderData(COLUMN_ADD_ONS, Qt::Horizontal, "Add-ons");
item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type");
item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size");
@@ -454,6 +456,25 @@ static QString FormatGameName(const std::string& physical_name) {
return physical_name_as_qstring;
}
+static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager,
+ bool updatable = true) {
+ QString out;
+ for (const auto& kv : patch_manager.GetPatchVersionNames()) {
+ if (!updatable && kv.first == FileSys::PatchType::Update)
+ continue;
+
+ if (kv.second.empty()) {
+ out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str());
+ } else {
+ out.append(fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), kv.second)
+ .c_str());
+ }
+ }
+
+ out.chop(1);
+ return out;
+}
+
void GameList::RefreshGameDirectory() {
if (!UISettings::values.gamedir.isEmpty() && current_worker != nullptr) {
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
@@ -462,26 +483,14 @@ void GameList::RefreshGameDirectory() {
}
}
-static void GetMetadataFromControlNCA(const std::shared_ptr<FileSys::NCA>& nca,
+static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager,
+ const std::shared_ptr<FileSys::NCA>& nca,
std::vector<u8>& icon, std::string& name) {
- const auto control_dir = FileSys::ExtractRomFS(nca->GetRomFS());
- if (control_dir == nullptr)
- return;
-
- const auto nacp_file = control_dir->GetFile("control.nacp");
- if (nacp_file == nullptr)
- return;
- 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_" + std::string(language) + ".dat");
- if (icon_file != nullptr) {
- icon = icon_file->ReadAllBytes();
- break;
- }
- }
+ auto [nacp, icon_file] = patch_manager.ParseControlNCA(nca);
+ if (icon_file != nullptr)
+ icon = icon_file->ReadAllBytes();
+ if (nacp != nullptr)
+ name = nacp->GetApplicationName();
}
GameListWorker::GameListWorker(
@@ -492,7 +501,8 @@ GameListWorker::GameListWorker(
GameListWorker::~GameListWorker() = default;
-void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr<FileSys::RegisteredCache> cache) {
+void GameListWorker::AddInstalledTitlesToGameList() {
+ const auto cache = Service::FileSystem::GetUnionContents();
const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application,
FileSys::ContentRecordType::Program);
@@ -507,14 +517,25 @@ void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr<FileSys::Regis
u64 program_id = 0;
loader->ReadProgramId(program_id);
+ const FileSys::PatchManager patch{program_id};
const auto& control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control);
if (control != nullptr)
- GetMetadataFromControlNCA(control, icon, name);
+ GetMetadataFromControlNCA(patch, control, icon, name);
+
+ auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
+
+ // The game list uses this as compatibility number for untested games
+ QString compatibility("99");
+ if (it != compatibility_list.end())
+ compatibility = it->second.first;
+
emit EntryReady({
new GameListItemPath(
FormatGameName(file->GetFullPath()), icon, QString::fromStdString(name),
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())),
program_id),
+ new GameListItemCompat(compatibility),
+ new GameListItem(FormatPatchNameVersions(patch)),
new GameListItem(
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
new GameListItemSize(file->GetSize()),
@@ -580,12 +601,14 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
std::string name = " ";
const auto res3 = loader->ReadTitle(name);
+ const FileSys::PatchManager patch{program_id};
+
if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success &&
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];
- GetMetadataFromControlNCA(nca, icon, name);
+ GetMetadataFromControlNCA(patch, nca, icon, name);
}
}
@@ -602,6 +625,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())),
program_id),
new GameListItemCompat(compatibility),
+ new GameListItem(FormatPatchNameVersions(patch, loader->IsRomFSUpdatable())),
new GameListItem(
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
new GameListItemSize(FileUtil::GetSize(physical_name)),
@@ -621,9 +645,7 @@ void GameListWorker::run() {
stop_processing = false;
watch_list.append(dir_path);
FillControlMap(dir_path.toStdString());
- AddInstalledTitlesToGameList(Service::FileSystem::GetUserNANDContents());
- AddInstalledTitlesToGameList(Service::FileSystem::GetSystemNANDContents());
- AddInstalledTitlesToGameList(Service::FileSystem::GetSDMCContents());
+ AddInstalledTitlesToGameList();
AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0);
nca_control_map.clear();
emit Finished(watch_list);