game_list: Fix version display on non-NAND titles

This commit is contained in:
Zach Hilman 2018-09-01 13:11:30 -04:00
parent cbd517d8cc
commit c91b60a421
4 changed files with 52 additions and 30 deletions

View file

@ -82,15 +82,31 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset,
return romfs; return romfs;
} }
std::map<PatchType, u32> PatchManager::GetPatchVersionNames() const { std::map<PatchType, std::string> PatchManager::GetPatchVersionNames() const {
std::map<PatchType, u32> out; std::map<PatchType, std::string> out;
const auto installed = Service::FileSystem::GetUnionContents(); const auto installed = Service::FileSystem::GetUnionContents();
const auto update_tid = GetUpdateTitleID(title_id); const auto update_tid = GetUpdateTitleID(title_id);
const auto update_version = installed->GetEntryVersion(update_tid); const auto update_control = installed->GetEntry(title_id, ContentRecordType::Control);
if (update_version != boost::none && if (update_control != nullptr) {
installed->HasEntry(update_tid, ContentRecordType::Program)) { do {
out[PatchType::Update] = update_version.get(); 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; return out;

View file

@ -45,7 +45,7 @@ public:
// Returns a vector of pairs between patch names and patch versions. // Returns a vector of pairs between patch names and patch versions.
// i.e. Update v80 will return {Update, 80} // i.e. Update v80 will return {Update, 80}
std::map<PatchType, u32> GetPatchVersionNames() const; std::map<PatchType, std::string> GetPatchVersionNames() const;
private: private:
u64 title_id; u64 title_id;

View file

@ -8,6 +8,7 @@
#include "core/file_sys/card_image.h" #include "core/file_sys/card_image.h"
#include "core/file_sys/content_archive.h" #include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/romfs.h" #include "core/file_sys/romfs.h"
#include "core/hle/kernel/process.h" #include "core/hle/kernel/process.h"
#include "core/loader/nca.h" #include "core/loader/nca.h"
@ -20,10 +21,18 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file)
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
if (xci->GetStatus() != ResultStatus::Success) if (xci->GetStatus() != ResultStatus::Success)
return; return;
const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control); const auto control_nca = xci->GetNCAByType(FileSys::NCAContentType::Control);
if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success) if (control_nca == nullptr || control_nca->GetStatus() != ResultStatus::Success)
return; 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) if (romfs == nullptr)
return; return;
for (const auto& language : FileSys::LANGUAGE_NAMES) { for (const auto& language : FileSys::LANGUAGE_NAMES) {

View file

@ -457,23 +457,17 @@ static QString FormatGameName(const std::string& physical_name) {
} }
static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager, static QString FormatPatchNameVersions(const FileSys::PatchManager& patch_manager,
std::string update_version_override = "",
bool updatable = true) { bool updatable = true) {
QString out; QString out;
for (const auto& kv : patch_manager.GetPatchVersionNames()) { for (const auto& kv : patch_manager.GetPatchVersionNames()) {
if (!updatable && kv.first == FileSys::PatchType::Update) if (!updatable && kv.first == FileSys::PatchType::Update)
continue; continue;
if (kv.second == 0) { if (kv.second.empty()) {
out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str()); out.append(fmt::format("{}\n", FileSys::FormatPatchTypeName(kv.first)).c_str());
} else { } else {
auto version_data = FileSys::FormatTitleVersion(kv.second); out.append(fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), kv.second)
if (kv.first == FileSys::PatchType::Update && !update_version_override.empty()) .c_str());
version_data = update_version_override;
out.append(
fmt::format("{} ({})\n", FileSys::FormatPatchTypeName(kv.first), version_data)
.c_str());
} }
} }
@ -491,8 +485,7 @@ void GameList::RefreshGameDirectory() {
static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager,
const std::shared_ptr<FileSys::NCA>& nca, const std::shared_ptr<FileSys::NCA>& nca,
std::vector<u8>& icon, std::string& name, std::vector<u8>& icon, std::string& name) {
std::string& version) {
const auto romfs = patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(), const auto romfs = patch_manager.PatchRomFS(nca->GetRomFS(), nca->GetBaseIVFCOffset(),
FileSys::ContentRecordType::Control); FileSys::ContentRecordType::Control);
if (romfs == nullptr) if (romfs == nullptr)
@ -507,7 +500,6 @@ static void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager
return; return;
FileSys::NACP nacp(nacp_file); FileSys::NACP nacp(nacp_file);
name = nacp.GetApplicationName(); name = nacp.GetApplicationName();
version = nacp.GetVersionString();
FileSys::VirtualFile icon_file = nullptr; FileSys::VirtualFile icon_file = nullptr;
for (const auto& language : FileSys::LANGUAGE_NAMES) { for (const auto& language : FileSys::LANGUAGE_NAMES) {
@ -527,7 +519,8 @@ GameListWorker::GameListWorker(
GameListWorker::~GameListWorker() = default; 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, const auto installed_games = cache->ListEntriesFilter(FileSys::TitleType::Application,
FileSys::ContentRecordType::Program); FileSys::ContentRecordType::Program);
@ -539,20 +532,28 @@ void GameListWorker::AddInstalledTitlesToGameList(std::shared_ptr<FileSys::Regis
std::vector<u8> icon; std::vector<u8> icon;
std::string name; std::string name;
std::string version = "";
u64 program_id = 0; u64 program_id = 0;
loader->ReadProgramId(program_id); loader->ReadProgramId(program_id);
const FileSys::PatchManager patch{program_id}; const FileSys::PatchManager patch{program_id};
const auto& control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control); const auto& control = cache->GetEntry(game.title_id, FileSys::ContentRecordType::Control);
if (control != nullptr) 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({ emit EntryReady({
new GameListItemPath( new GameListItemPath(
FormatGameName(file->GetFullPath()), icon, QString::fromStdString(name), FormatGameName(file->GetFullPath()), icon, QString::fromStdString(name),
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())), QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())),
program_id), program_id),
new GameListItem(FormatPatchNameVersions(patch, version)), new GameListItemCompat(compatibility),
new GameListItem(FormatPatchNameVersions(patch)),
new GameListItem( new GameListItem(
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
new GameListItemSize(file->GetSize()), new GameListItemSize(file->GetSize()),
@ -620,14 +621,12 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
const FileSys::PatchManager patch{program_id}; const FileSys::PatchManager patch{program_id};
std::string version = "";
if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success && if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success &&
res2 == Loader::ResultStatus::Success) { res2 == Loader::ResultStatus::Success) {
// Use from metadata pool. // Use from metadata pool.
if (nca_control_map.find(program_id) != nca_control_map.end()) { if (nca_control_map.find(program_id) != nca_control_map.end()) {
const auto nca = nca_control_map[program_id]; 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())), QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())),
program_id), program_id),
new GameListItemCompat(compatibility), new GameListItemCompat(compatibility),
new GameListItem(FormatPatchNameVersions(program_id, loader->IsRomFSUpdatable())), new GameListItem(FormatPatchNameVersions(patch, loader->IsRomFSUpdatable())),
new GameListItem(
FormatPatchNameVersions(patch, version, loader->IsRomFSUpdatable())),
new GameListItem( new GameListItem(
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
new GameListItemSize(FileUtil::GetSize(physical_name)), new GameListItemSize(FileUtil::GetSize(physical_name)),