game_list: Register content with ContentProvider
This commit is contained in:
parent
60f39060c6
commit
41d2565f29
|
@ -86,7 +86,7 @@ static FileSys::VirtualFile GetManualRomFS() {
|
||||||
if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success)
|
if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success)
|
||||||
return out;
|
return out;
|
||||||
|
|
||||||
const auto& installed{FileSystem::GetUnionContents()};
|
const auto& installed{Core::System::GetInstance().GetContentProvider()};
|
||||||
const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(),
|
const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(),
|
||||||
FileSys::ContentRecordType::Manual);
|
FileSys::ContentRecordType::Manual);
|
||||||
|
|
||||||
|
@ -154,7 +154,8 @@ void WebBrowser::Execute() {
|
||||||
|
|
||||||
auto& frontend{Core::System::GetInstance().GetWebBrowser()};
|
auto& frontend{Core::System::GetInstance().GetWebBrowser()};
|
||||||
|
|
||||||
frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
|
frontend.OpenPage(
|
||||||
|
filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebBrowser::UnpackRomFS() {
|
void WebBrowser::UnpackRomFS() {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
|
#include "core/file_sys/registered_cache.h"
|
||||||
#include "yuzu/compatibility_list.h"
|
#include "yuzu/compatibility_list.h"
|
||||||
#include "yuzu/game_list.h"
|
#include "yuzu/game_list.h"
|
||||||
#include "yuzu/game_list_p.h"
|
#include "yuzu/game_list_p.h"
|
||||||
|
@ -193,8 +194,9 @@ void GameList::onFilterCloseClicked() {
|
||||||
main_window->filterBarSetChecked(false);
|
main_window->filterBarSetChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent)
|
GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvider* provider,
|
||||||
: QWidget{parent}, vfs(std::move(vfs)) {
|
GMainWindow* parent)
|
||||||
|
: QWidget{parent}, vfs(std::move(vfs)), provider(provider) {
|
||||||
watcher = new QFileSystemWatcher(this);
|
watcher = new QFileSystemWatcher(this);
|
||||||
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
|
connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
|
||||||
|
|
||||||
|
@ -428,7 +430,8 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
||||||
|
|
||||||
emit ShouldCancelWorker();
|
emit ShouldCancelWorker();
|
||||||
|
|
||||||
GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan, compatibility_list);
|
GameListWorker* worker =
|
||||||
|
new GameListWorker(vfs, provider, dir_path, deep_scan, compatibility_list);
|
||||||
|
|
||||||
connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
|
connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
|
||||||
connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
|
connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
|
||||||
|
|
|
@ -26,8 +26,9 @@ class GameListSearchField;
|
||||||
class GMainWindow;
|
class GMainWindow;
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
|
class ManualContentProvider;
|
||||||
class VfsFilesystem;
|
class VfsFilesystem;
|
||||||
}
|
} // namespace FileSys
|
||||||
|
|
||||||
enum class GameListOpenTarget {
|
enum class GameListOpenTarget {
|
||||||
SaveData,
|
SaveData,
|
||||||
|
@ -47,7 +48,8 @@ public:
|
||||||
COLUMN_COUNT, // Number of columns
|
COLUMN_COUNT, // Number of columns
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs, GMainWindow* parent = nullptr);
|
explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs,
|
||||||
|
FileSys::ManualContentProvider* provider, GMainWindow* parent = nullptr);
|
||||||
~GameList() override;
|
~GameList() override;
|
||||||
|
|
||||||
void clearFilter();
|
void clearFilter();
|
||||||
|
@ -85,6 +87,7 @@ private:
|
||||||
void RefreshGameDirectory();
|
void RefreshGameDirectory();
|
||||||
|
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
||||||
|
FileSys::ManualContentProvider* provider;
|
||||||
GameListSearchField* search_field;
|
GameListSearchField* search_field;
|
||||||
GMainWindow* main_window = nullptr;
|
GMainWindow* main_window = nullptr;
|
||||||
QVBoxLayout* layout = nullptr;
|
QVBoxLayout* layout = nullptr;
|
||||||
|
|
|
@ -12,12 +12,15 @@
|
||||||
|
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
#include "core/core.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/mode.h"
|
#include "core/file_sys/mode.h"
|
||||||
#include "core/file_sys/nca_metadata.h"
|
#include "core/file_sys/nca_metadata.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
#include "core/file_sys/submission_package.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "yuzu/compatibility_list.h"
|
#include "yuzu/compatibility_list.h"
|
||||||
|
@ -119,20 +122,25 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan,
|
GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs,
|
||||||
const CompatibilityList& compatibility_list)
|
FileSys::ManualContentProvider* provider, QString dir_path,
|
||||||
: vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan),
|
bool deep_scan, const CompatibilityList& compatibility_list)
|
||||||
|
: vfs(std::move(vfs)), provider(provider), dir_path(std::move(dir_path)), deep_scan(deep_scan),
|
||||||
compatibility_list(compatibility_list) {}
|
compatibility_list(compatibility_list) {}
|
||||||
|
|
||||||
GameListWorker::~GameListWorker() = default;
|
GameListWorker::~GameListWorker() = default;
|
||||||
|
|
||||||
void GameListWorker::AddInstalledTitlesToGameList() {
|
void GameListWorker::AddTitlesToGameList() {
|
||||||
const auto cache = Service::FileSystem::GetUnionContents();
|
const auto& cache = dynamic_cast<FileSys::ContentProviderUnion&>(
|
||||||
const auto installed_games = cache.ListEntriesFilter(FileSys::TitleType::Application,
|
Core::System::GetInstance().GetContentProvider());
|
||||||
FileSys::ContentRecordType::Program);
|
const auto installed_games = cache.ListEntriesFilterOrigin(
|
||||||
|
std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
|
||||||
|
|
||||||
for (const auto& game : installed_games) {
|
for (const auto& [slot, game] : installed_games) {
|
||||||
const auto file = cache.GetEntryUnparsed(game);
|
if (slot == FileSys::ContentProviderUnionSlot::FrontendManual)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto file = cache.GetEntryUnparsed(game.title_id, game.type);
|
||||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file);
|
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file);
|
||||||
if (!loader)
|
if (!loader)
|
||||||
continue;
|
continue;
|
||||||
|
@ -150,45 +158,13 @@ void GameListWorker::AddInstalledTitlesToGameList() {
|
||||||
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
|
emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
|
||||||
compatibility_list, patch));
|
compatibility_list, patch));
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto control_data = cache.ListEntriesFilter(FileSys::TitleType::Application,
|
|
||||||
FileSys::ContentRecordType::Control);
|
|
||||||
|
|
||||||
for (const auto& entry : control_data) {
|
|
||||||
auto nca = cache.GetEntry(entry);
|
|
||||||
if (nca != nullptr) {
|
|
||||||
nca_control_map.insert_or_assign(entry.title_id, std::move(nca));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameListWorker::FillControlMap(const std::string& dir_path) {
|
void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path,
|
||||||
const auto nca_control_callback = [this](u64* num_entries_out, const std::string& directory,
|
unsigned int recursion) {
|
||||||
const std::string& virtual_name) -> bool {
|
const auto callback = [this, target, recursion](u64* num_entries_out,
|
||||||
if (stop_processing) {
|
const std::string& directory,
|
||||||
// Breaks the callback loop
|
const std::string& virtual_name) -> bool {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string physical_name = directory + DIR_SEP + virtual_name;
|
|
||||||
const QFileInfo file_info(QString::fromStdString(physical_name));
|
|
||||||
if (!file_info.isDir() && file_info.suffix() == QStringLiteral("nca")) {
|
|
||||||
auto nca =
|
|
||||||
std::make_unique<FileSys::NCA>(vfs->OpenFile(physical_name, FileSys::Mode::Read));
|
|
||||||
if (nca->GetType() == FileSys::NCAContentType::Control) {
|
|
||||||
const u64 title_id = nca->GetTitleId();
|
|
||||||
nca_control_map.insert_or_assign(title_id, std::move(nca));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
FileUtil::ForeachDirectoryEntry(nullptr, dir_path, nca_control_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if (stop_processing) {
|
if (stop_processing) {
|
||||||
// Breaks the callback loop.
|
// Breaks the callback loop.
|
||||||
return false;
|
return false;
|
||||||
|
@ -198,7 +174,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
const bool is_dir = FileUtil::IsDirectory(physical_name);
|
const bool is_dir = FileUtil::IsDirectory(physical_name);
|
||||||
if (!is_dir &&
|
if (!is_dir &&
|
||||||
(HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
|
(HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
|
||||||
auto loader = Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read));
|
const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read);
|
||||||
|
auto loader = Loader::GetLoader(file);
|
||||||
if (!loader) {
|
if (!loader) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -209,31 +186,42 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> icon;
|
|
||||||
const auto res1 = loader->ReadIcon(icon);
|
|
||||||
|
|
||||||
u64 program_id = 0;
|
u64 program_id = 0;
|
||||||
const auto res2 = loader->ReadProgramId(program_id);
|
const auto res2 = loader->ReadProgramId(program_id);
|
||||||
|
|
||||||
std::string name = " ";
|
if (target == ScanTarget::FillManualContentProvider) {
|
||||||
const auto res3 = loader->ReadTitle(name);
|
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
|
||||||
|
provider->AddEntry(FileSys::TitleType::Application,
|
||||||
const FileSys::PatchManager patch{program_id};
|
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
|
||||||
|
program_id, file);
|
||||||
if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success &&
|
} else if (res2 == Loader::ResultStatus::Success &&
|
||||||
res2 == Loader::ResultStatus::Success) {
|
(file_type == Loader::FileType::XCI ||
|
||||||
// Use from metadata pool.
|
file_type == Loader::FileType::NSP)) {
|
||||||
if (nca_control_map.find(program_id) != nca_control_map.end()) {
|
const auto nsp = file_type == Loader::FileType::NSP
|
||||||
const auto& nca = nca_control_map[program_id];
|
? std::make_shared<FileSys::NSP>(file)
|
||||||
GetMetadataFromControlNCA(patch, *nca, icon, name);
|
: FileSys::XCI{file}.GetSecurePartitionNSP();
|
||||||
|
for (const auto& title : nsp->GetNCAs()) {
|
||||||
|
for (const auto& entry : title.second) {
|
||||||
|
provider->AddEntry(entry.first.first, entry.first.second, title.first,
|
||||||
|
entry.second->GetBaseFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
std::vector<u8> icon;
|
||||||
|
const auto res1 = loader->ReadIcon(icon);
|
||||||
|
|
||||||
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
|
std::string name = " ";
|
||||||
compatibility_list, patch));
|
const auto res3 = loader->ReadTitle(name);
|
||||||
|
|
||||||
|
const FileSys::PatchManager patch{program_id};
|
||||||
|
|
||||||
|
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
|
||||||
|
compatibility_list, patch));
|
||||||
|
}
|
||||||
} else if (is_dir && recursion > 0) {
|
} else if (is_dir && recursion > 0) {
|
||||||
watch_list.append(QString::fromStdString(physical_name));
|
watch_list.append(QString::fromStdString(physical_name));
|
||||||
AddFstEntriesToGameList(physical_name, recursion - 1);
|
ScanFileSystem(target, physical_name, recursion - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -245,10 +233,11 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
void GameListWorker::run() {
|
void GameListWorker::run() {
|
||||||
stop_processing = false;
|
stop_processing = false;
|
||||||
watch_list.append(dir_path);
|
watch_list.append(dir_path);
|
||||||
FillControlMap(dir_path.toStdString());
|
provider->ClearAllEntries();
|
||||||
AddInstalledTitlesToGameList();
|
ScanFileSystem(ScanTarget::FillManualContentProvider, dir_path.toStdString(),
|
||||||
AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0);
|
deep_scan ? 256 : 0);
|
||||||
nca_control_map.clear();
|
AddTitlesToGameList();
|
||||||
|
ScanFileSystem(ScanTarget::PopulateGameList, dir_path.toStdString(), deep_scan ? 256 : 0);
|
||||||
emit Finished(watch_list);
|
emit Finished(watch_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ class GameListWorker : public QObject, public QRunnable {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, QString dir_path, bool deep_scan,
|
GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs,
|
||||||
|
FileSys::ManualContentProvider* provider, QString dir_path, bool deep_scan,
|
||||||
const CompatibilityList& compatibility_list);
|
const CompatibilityList& compatibility_list);
|
||||||
~GameListWorker() override;
|
~GameListWorker() override;
|
||||||
|
|
||||||
|
@ -58,12 +59,17 @@ signals:
|
||||||
void Finished(QStringList watch_list);
|
void Finished(QStringList watch_list);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddInstalledTitlesToGameList();
|
void AddTitlesToGameList();
|
||||||
void FillControlMap(const std::string& dir_path);
|
|
||||||
void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0);
|
enum class ScanTarget {
|
||||||
|
FillManualContentProvider,
|
||||||
|
PopulateGameList,
|
||||||
|
};
|
||||||
|
|
||||||
|
void ScanFileSystem(ScanTarget target, const std::string& dir_path, unsigned int recursion = 0);
|
||||||
|
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
||||||
std::map<u64, std::unique_ptr<FileSys::NCA>> nca_control_map;
|
FileSys::ManualContentProvider* provider;
|
||||||
QStringList watch_list;
|
QStringList watch_list;
|
||||||
QString dir_path;
|
QString dir_path;
|
||||||
bool deep_scan;
|
bool deep_scan;
|
||||||
|
|
|
@ -168,7 +168,8 @@ static void InitializeLogging() {
|
||||||
|
|
||||||
GMainWindow::GMainWindow()
|
GMainWindow::GMainWindow()
|
||||||
: config(new Config()), emu_thread(nullptr),
|
: config(new Config()), emu_thread(nullptr),
|
||||||
vfs(std::make_shared<FileSys::RealVfsFilesystem>()) {
|
vfs(std::make_shared<FileSys::RealVfsFilesystem>()),
|
||||||
|
provider(std::make_unique<FileSys::ManualContentProvider>()) {
|
||||||
InitializeLogging();
|
InitializeLogging();
|
||||||
|
|
||||||
debug_context = Tegra::DebugContext::Construct();
|
debug_context = Tegra::DebugContext::Construct();
|
||||||
|
@ -200,11 +201,15 @@ GMainWindow::GMainWindow()
|
||||||
.arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
|
.arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
Core::System::GetInstance().SetContentProvider(
|
||||||
|
std::make_unique<FileSys::ContentProviderUnion>());
|
||||||
|
Core::System::GetInstance().RegisterContentProvider(
|
||||||
|
FileSys::ContentProviderUnionSlot::FrontendManual, provider.get());
|
||||||
|
Service::FileSystem::CreateFactories(*vfs);
|
||||||
|
|
||||||
// Gen keys if necessary
|
// Gen keys if necessary
|
||||||
OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
|
OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
|
||||||
|
|
||||||
// Necessary to load titles from nand in gamelist.
|
|
||||||
Service::FileSystem::CreateFactories(*vfs);
|
|
||||||
game_list->LoadCompatibilityList();
|
game_list->LoadCompatibilityList();
|
||||||
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
||||||
|
|
||||||
|
@ -416,7 +421,7 @@ void GMainWindow::InitializeWidgets() {
|
||||||
render_window = new GRenderWindow(this, emu_thread.get());
|
render_window = new GRenderWindow(this, emu_thread.get());
|
||||||
render_window->hide();
|
render_window->hide();
|
||||||
|
|
||||||
game_list = new GameList(vfs, this);
|
game_list = new GameList(vfs, provider.get(), this);
|
||||||
ui.horizontalLayout->addWidget(game_list);
|
ui.horizontalLayout->addWidget(game_list);
|
||||||
|
|
||||||
loading_screen = new LoadingScreen(this);
|
loading_screen = new LoadingScreen(this);
|
||||||
|
@ -1141,7 +1146,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto installed = Service::FileSystem::GetUnionContents();
|
const auto& installed = Core::System::GetInstance().GetContentProvider();
|
||||||
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
|
const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
|
||||||
|
|
||||||
if (!romfs_title_id) {
|
if (!romfs_title_id) {
|
||||||
|
@ -1886,14 +1891,14 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<u64> GMainWindow::SelectRomFSDumpTarget(
|
std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed,
|
||||||
const FileSys::RegisteredCacheUnion& installed, u64 program_id) {
|
u64 program_id) {
|
||||||
const auto dlc_entries =
|
const auto dlc_entries =
|
||||||
installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
|
installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
|
||||||
std::vector<FileSys::RegisteredCacheEntry> dlc_match;
|
std::vector<FileSys::ContentProviderEntry> dlc_match;
|
||||||
dlc_match.reserve(dlc_entries.size());
|
dlc_match.reserve(dlc_entries.size());
|
||||||
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
|
||||||
[&program_id, &installed](const FileSys::RegisteredCacheEntry& entry) {
|
[&program_id, &installed](const FileSys::ContentProviderEntry& entry) {
|
||||||
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id &&
|
return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id &&
|
||||||
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
|
installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
|
||||||
});
|
});
|
||||||
|
|
|
@ -37,7 +37,8 @@ struct SoftwareKeyboardParameters;
|
||||||
} // namespace Core::Frontend
|
} // namespace Core::Frontend
|
||||||
|
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
class RegisteredCacheUnion;
|
class ContentProvider;
|
||||||
|
class ManualContentProvider;
|
||||||
class VfsFilesystem;
|
class VfsFilesystem;
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
||||||
|
@ -204,7 +205,7 @@ private slots:
|
||||||
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<u64> SelectRomFSDumpTarget(const FileSys::RegisteredCacheUnion&, u64 program_id);
|
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
|
||||||
void UpdateStatusBar();
|
void UpdateStatusBar();
|
||||||
|
|
||||||
Ui::MainWindow ui;
|
Ui::MainWindow ui;
|
||||||
|
@ -232,6 +233,7 @@ private:
|
||||||
|
|
||||||
// FS
|
// FS
|
||||||
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
std::shared_ptr<FileSys::VfsFilesystem> vfs;
|
||||||
|
std::unique_ptr<FileSys::ManualContentProvider> provider;
|
||||||
|
|
||||||
// Debugger panes
|
// Debugger panes
|
||||||
ProfilerWidget* profilerWidget;
|
ProfilerWidget* profilerWidget;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
|
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include "core/file_sys/registered_cache.h"
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -178,6 +179,7 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::System& system{Core::System::GetInstance()};
|
Core::System& system{Core::System::GetInstance()};
|
||||||
|
system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
||||||
system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
|
system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
|
||||||
Service::FileSystem::CreateFactories(*system.GetFilesystem());
|
Service::FileSystem::CreateFactories(*system.GetFilesystem());
|
||||||
|
|
||||||
|
|
Reference in New Issue