From c91b60a421a3bd0dc85d80e0a5a2d261370df340 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 1 Sep 2018 13:11:30 -0400 Subject: [PATCH] game_list: Fix version display on non-NAND titles --- src/core/file_sys/patch_manager.cpp | 28 +++++++++++++++----- src/core/file_sys/patch_manager.h | 2 +- src/core/loader/xci.cpp | 11 +++++++- src/yuzu/game_list.cpp | 41 +++++++++++++---------------- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index 8b7d797734..b6e25f7eb1 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -82,15 +82,31 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, return romfs; } -std::map PatchManager::GetPatchVersionNames() const { - std::map out; +std::map PatchManager::GetPatchVersionNames() const { + std::map out; const auto installed = Service::FileSystem::GetUnionContents(); const auto update_tid = GetUpdateTitleID(title_id); - const auto update_version = installed->GetEntryVersion(update_tid); - if (update_version != boost::none && - installed->HasEntry(update_tid, ContentRecordType::Program)) { - out[PatchType::Update] = update_version.get(); + const auto update_control = installed->GetEntry(title_id, ContentRecordType::Control); + if (update_control != nullptr) { + do { + const auto romfs = + PatchRomFS(update_control->GetRomFS(), update_control->GetBaseIVFCOffset(), + FileSys::ContentRecordType::Control); + if (romfs == nullptr) + break; + + const auto control_dir = FileSys::ExtractRomFS(romfs); + if (control_dir == nullptr) + break; + + const auto nacp_file = control_dir->GetFile("control.nacp"); + if (nacp_file == nullptr) + break; + + FileSys::NACP nacp(nacp_file); + out[PatchType::Update] = nacp.GetVersionString(); + } while (false); } return out; diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h index 021bc33667..b6bf86222b 100644 --- a/src/core/file_sys/patch_manager.h +++ b/src/core/file_sys/patch_manager.h @@ -45,7 +45,7 @@ public: // Returns a vector of pairs between patch names and patch versions. // i.e. Update v80 will return {Update, 80} - std::map GetPatchVersionNames() const; + std::map GetPatchVersionNames() const; private: u64 title_id; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 75b998faaa..b01d51abb7 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -8,6 +8,7 @@ #include "core/file_sys/card_image.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/control_metadata.h" +#include "core/file_sys/patch_manager.h" #include "core/file_sys/romfs.h" #include "core/hle/kernel/process.h" #include "core/loader/nca.h" @@ -20,10 +21,18 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file) nca_loader(std::make_unique(xci->GetProgramNCAFile())) { 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()); + + auto romfs_raw = control_nca->GetRomFS(); + FileSys::PatchManager patch{xci->GetNCAByType(FileSys::NCAContentType::Program)->GetTitleId()}; + romfs_raw = patch.PatchRomFS(romfs_raw, control_nca->GetBaseIVFCOffset(), + FileSys::ContentRecordType::Control); + + const auto romfs = FileSys::ExtractRomFS(romfs_raw); if (romfs == nullptr) return; for (const auto& language : FileSys::LANGUAGE_NAMES) { diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 02d8a38828..38c5071e3a 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -457,23 +457,17 @@ static QString FormatGameName(const std::string& physical_name) { } static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, - std::string update_version_override = "", bool updatable = true) { QString out; for (const auto& kv : patch_manager.GetPatchVersionNames()) { if (!updatable && kv.first == FileSys::PatchType::Update) continue; - if (kv.second == 0) { + if (kv.second.empty()) { out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str()); } else { - auto version_data = FileSys::FormatTitleVersion(kv.second); - if (kv.first == FileSys::PatchType::Update && !update_version_override.empty()) - version_data = update_version_override; - - out.append( - fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), version_data) - .c_str()); + out.append(fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), kv.second) + .c_str()); } } @@ -491,8 +485,7 @@ void GameList::RefreshGameDirectory() { static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const std::shared_ptr& nca, - std::vector& icon, std::string& name, - std::string& version) { + std::vector& icon, std::string& name) { const auto romfs = patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), FileSys::ContentRecordType::Control); if (romfs == nullptr) @@ -507,7 +500,6 @@ static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager return; FileSys::NACP nacp(nacp_file); name = nacp.GetApplicationName(); - version = nacp.GetVersionString(); FileSys::VirtualFile icon_file = nullptr; for (const auto& language : FileSys::LANGUAGE_NAMES) { @@ -527,7 +519,8 @@ GameListWorker::GameListWorker( GameListWorker::~GameListWorker() = default; -void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr cache) { +void GameListWorker::AddInstalledTitlesToGameList() { + const auto cache = Service::FileSystem::GetUnionContents(); const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application, FileSys::ContentRecordType::Program); @@ -539,20 +532,28 @@ void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr icon; std::string name; - std::string version = ""; 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(patch, control, icon, name, version); + 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 GameListItem(FormatPatchNameVersions(patch, version)), + new GameListItemCompat(compatibility), + new GameListItem(FormatPatchNameVersions(patch)), new GameListItem( QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(file->GetSize()), @@ -620,14 +621,12 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign const FileSys::PatchManager patch{program_id}; - std::string version = ""; - 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(patch, nca, icon, name, version); + GetMetadataFromControlNCA(patch, nca, icon, name); } } @@ -644,9 +643,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), program_id), new GameListItemCompat(compatibility), - new GameListItem(FormatPatchNameVersions(program_id, loader->IsRomFSUpdatable())), - new GameListItem( - FormatPatchNameVersions(patch, version, loader->IsRomFSUpdatable())), + new GameListItem(FormatPatchNameVersions(patch, loader->IsRomFSUpdatable())), new GameListItem( QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(FileUtil::GetSize(physical_name)),