summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp5
-rw-r--r--src/yuzu/game_list.cpp9
-rw-r--r--src/yuzu/game_list.h7
-rw-r--r--src/yuzu/game_list_worker.cpp125
-rw-r--r--src/yuzu/game_list_worker.h16
-rw-r--r--src/yuzu/main.cpp23
-rw-r--r--src/yuzu/main.h6
-rw-r--r--src/yuzu_cmd/yuzu.cpp2
8 files changed, 102 insertions, 91 deletions
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
index 9b0aa7f5f..70d840a67 100644
--- a/src/core/hle/service/am/applets/web_browser.cpp
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -86,7 +86,7 @@ static FileSys::VirtualFile GetManualRomFS() {
86 if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success) 86 if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success)
87 return out; 87 return out;
88 88
89 const auto& installed{FileSystem::GetUnionContents()}; 89 const auto& installed{Core::System::GetInstance().GetContentProvider()};
90 const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(), 90 const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(),
91 FileSys::ContentRecordType::Manual); 91 FileSys::ContentRecordType::Manual);
92 92
@@ -154,7 +154,8 @@ void WebBrowser::Execute() {
154 154
155 auto& frontend{Core::System::GetInstance().GetWebBrowser()}; 155 auto& frontend{Core::System::GetInstance().GetWebBrowser()};
156 156
157 frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); }); 157 frontend.OpenPage(
158 filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
158} 159}
159 160
160void WebBrowser::UnpackRomFS() { 161void WebBrowser::UnpackRomFS() {
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index c0e3c5fa9..5e5737030 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -18,6 +18,7 @@
18#include "common/common_types.h" 18#include "common/common_types.h"
19#include "common/logging/log.h" 19#include "common/logging/log.h"
20#include "core/file_sys/patch_manager.h" 20#include "core/file_sys/patch_manager.h"
21#include "core/file_sys/registered_cache.h"
21#include "yuzu/compatibility_list.h" 22#include "yuzu/compatibility_list.h"
22#include "yuzu/game_list.h" 23#include "yuzu/game_list.h"
23#include "yuzu/game_list_p.h" 24#include "yuzu/game_list_p.h"
@@ -193,8 +194,9 @@ void GameList::onFilterCloseClicked() {
193 main_window->filterBarSetChecked(false); 194 main_window->filterBarSetChecked(false);
194} 195}
195 196
196GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) 197GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvider* provider,
197 : QWidget{parent}, vfs(std::move(vfs)) { 198 GMainWindow* parent)
199 : QWidget{parent}, vfs(std::move(vfs)), provider(provider) {
198 watcher = new QFileSystemWatcher(this); 200 watcher = new QFileSystemWatcher(this);
199 connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); 201 connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory);
200 202
@@ -428,7 +430,8 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
428 430
429 emit ShouldCancelWorker(); 431 emit ShouldCancelWorker();
430 432
431 GameListWorker* worker = new GameListWorker(vfs, dir_path, deep_scan, compatibility_list); 433 GameListWorker* worker =
434 new GameListWorker(vfs, provider, dir_path, deep_scan, compatibility_list);
432 435
433 connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection); 436 connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
434 connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating, 437 connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index b317eb2fc..e645904cd 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -26,8 +26,9 @@ class GameListSearchField;
26class GMainWindow; 26class GMainWindow;
27 27
28namespace FileSys { 28namespace FileSys {
29class ManualContentProvider;
29class VfsFilesystem; 30class VfsFilesystem;
30} 31} // namespace FileSys
31 32
32enum class GameListOpenTarget { 33enum class GameListOpenTarget {
33 SaveData, 34 SaveData,
@@ -47,7 +48,8 @@ public:
47 COLUMN_COUNT, // Number of columns 48 COLUMN_COUNT, // Number of columns
48 }; 49 };
49 50
50 explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs, GMainWindow* parent = nullptr); 51 explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs,
52 FileSys::ManualContentProvider* provider, GMainWindow* parent = nullptr);
51 ~GameList() override; 53 ~GameList() override;
52 54
53 void clearFilter(); 55 void clearFilter();
@@ -85,6 +87,7 @@ private:
85 void RefreshGameDirectory(); 87 void RefreshGameDirectory();
86 88
87 std::shared_ptr<FileSys::VfsFilesystem> vfs; 89 std::shared_ptr<FileSys::VfsFilesystem> vfs;
90 FileSys::ManualContentProvider* provider;
88 GameListSearchField* search_field; 91 GameListSearchField* search_field;
89 GMainWindow* main_window = nullptr; 92 GMainWindow* main_window = nullptr;
90 QVBoxLayout* layout = nullptr; 93 QVBoxLayout* layout = nullptr;
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index b37710f59..8687e7c5a 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -12,12 +12,15 @@
12 12
13#include "common/common_paths.h" 13#include "common/common_paths.h"
14#include "common/file_util.h" 14#include "common/file_util.h"
15#include "core/core.h"
16#include "core/file_sys/card_image.h"
15#include "core/file_sys/content_archive.h" 17#include "core/file_sys/content_archive.h"
16#include "core/file_sys/control_metadata.h" 18#include "core/file_sys/control_metadata.h"
17#include "core/file_sys/mode.h" 19#include "core/file_sys/mode.h"
18#include "core/file_sys/nca_metadata.h" 20#include "core/file_sys/nca_metadata.h"
19#include "core/file_sys/patch_manager.h" 21#include "core/file_sys/patch_manager.h"
20#include "core/file_sys/registered_cache.h" 22#include "core/file_sys/registered_cache.h"
23#include "core/file_sys/submission_package.h"
21#include "core/hle/service/filesystem/filesystem.h" 24#include "core/hle/service/filesystem/filesystem.h"
22#include "core/loader/loader.h" 25#include "core/loader/loader.h"
23#include "yuzu/compatibility_list.h" 26#include "yuzu/compatibility_list.h"
@@ -119,20 +122,25 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
119} 122}
120} // Anonymous namespace 123} // Anonymous namespace
121 124
122GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan, 125GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs,
123 const CompatibilityList& compatibility_list) 126 FileSys::ManualContentProvider* provider, QString dir_path,
124 : vfs(std::move(vfs)), dir_path(std::move(dir_path)), deep_scan(deep_scan), 127 bool deep_scan, const CompatibilityList& compatibility_list)
128 : vfs(std::move(vfs)), provider(provider), dir_path(std::move(dir_path)), deep_scan(deep_scan),
125 compatibility_list(compatibility_list) {} 129 compatibility_list(compatibility_list) {}
126 130
127GameListWorker::~GameListWorker() = default; 131GameListWorker::~GameListWorker() = default;
128 132
129void GameListWorker::AddInstalledTitlesToGameList() { 133void GameListWorker::AddTitlesToGameList() {
130 const auto cache = Service::FileSystem::GetUnionContents(); 134 const auto& cache = dynamic_cast<FileSys::ContentProviderUnion&>(
131 const auto installed_games = cache.ListEntriesFilter(FileSys::TitleType::Application, 135 Core::System::GetInstance().GetContentProvider());
132 FileSys::ContentRecordType::Program); 136 const auto installed_games = cache.ListEntriesFilterOrigin(
137 std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
133 138
134 for (const auto& game : installed_games) { 139 for (const auto& [slot, game] : installed_games) {
135 const auto file = cache.GetEntryUnparsed(game); 140 if (slot == FileSys::ContentProviderUnionSlot::FrontendManual)
141 continue;
142
143 const auto file = cache.GetEntryUnparsed(game.title_id, game.type);
136 std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file); 144 std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(file);
137 if (!loader) 145 if (!loader)
138 continue; 146 continue;
@@ -150,45 +158,13 @@ void GameListWorker::AddInstalledTitlesToGameList() {
150 emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id, 158 emit EntryReady(MakeGameListEntry(file->GetFullPath(), name, icon, *loader, program_id,
151 compatibility_list, patch)); 159 compatibility_list, patch));
152 } 160 }
153
154 const auto control_data = cache.ListEntriesFilter(FileSys::TitleType::Application,
155 FileSys::ContentRecordType::Control);
156
157 for (const auto& entry : control_data) {
158 auto nca = cache.GetEntry(entry);
159 if (nca != nullptr) {
160 nca_control_map.insert_or_assign(entry.title_id, std::move(nca));
161 }
162 }
163} 161}
164 162
165void GameListWorker::FillControlMap(const std::string& dir_path) { 163void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_path,
166 const auto nca_control_callback = [this](u64* num_entries_out, const std::string& directory, 164 unsigned int recursion) {
167 const std::string& virtual_name) -> bool { 165 const auto callback = [this, target, recursion](u64* num_entries_out,
168 if (stop_processing) { 166 const std::string& directory,
169 // Breaks the callback loop 167 const std::string& virtual_name) -> bool {
170 return false;
171 }
172
173 const std::string physical_name = directory + DIR_SEP + virtual_name;
174 const QFileInfo file_info(QString::fromStdString(physical_name));
175 if (!file_info.isDir() && file_info.suffix() == QStringLiteral("nca")) {
176 auto nca =
177 std::make_unique<FileSys::NCA>(vfs->OpenFile(physical_name, FileSys::Mode::Read));
178 if (nca->GetType() == FileSys::NCAContentType::Control) {
179 const u64 title_id = nca->GetTitleId();
180 nca_control_map.insert_or_assign(title_id, std::move(nca));
181 }
182 }
183 return true;
184 };
185
186 FileUtil::ForeachDirectoryEntry(nullptr, dir_path, nca_control_callback);
187}
188
189void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) {
190 const auto callback = [this, recursion](u64* num_entries_out, const std::string& directory,
191 const std::string& virtual_name) -> bool {
192 if (stop_processing) { 168 if (stop_processing) {
193 // Breaks the callback loop. 169 // Breaks the callback loop.
194 return false; 170 return false;
@@ -198,7 +174,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
198 const bool is_dir = FileUtil::IsDirectory(physical_name); 174 const bool is_dir = FileUtil::IsDirectory(physical_name);
199 if (!is_dir && 175 if (!is_dir &&
200 (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) { 176 (HasSupportedFileExtension(physical_name) || IsExtractedNCAMain(physical_name))) {
201 auto loader = Loader::GetLoader(vfs->OpenFile(physical_name, FileSys::Mode::Read)); 177 const auto file = vfs->OpenFile(physical_name, FileSys::Mode::Read);
178 auto loader = Loader::GetLoader(file);
202 if (!loader) { 179 if (!loader) {
203 return true; 180 return true;
204 } 181 }
@@ -209,31 +186,42 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
209 return true; 186 return true;
210 } 187 }
211 188
212 std::vector<u8> icon;
213 const auto res1 = loader->ReadIcon(icon);
214
215 u64 program_id = 0; 189 u64 program_id = 0;
216 const auto res2 = loader->ReadProgramId(program_id); 190 const auto res2 = loader->ReadProgramId(program_id);
217 191
218 std::string name = " "; 192 if (target == ScanTarget::FillManualContentProvider) {
219 const auto res3 = loader->ReadTitle(name); 193 if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
194 provider->AddEntry(FileSys::TitleType::Application,
195 FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
196 program_id, file);
197 } else if (res2 == Loader::ResultStatus::Success &&
198 (file_type == Loader::FileType::XCI ||
199 file_type == Loader::FileType::NSP)) {
200 const auto nsp = file_type == Loader::FileType::NSP
201 ? std::make_shared<FileSys::NSP>(file)
202 : FileSys::XCI{file}.GetSecurePartitionNSP();
203 for (const auto& title : nsp->GetNCAs()) {
204 for (const auto& entry : title.second) {
205 provider->AddEntry(entry.first.first, entry.first.second, title.first,
206 entry.second->GetBaseFile());
207 }
208 }
209 }
210 } else {
211 std::vector<u8> icon;
212 const auto res1 = loader->ReadIcon(icon);
220 213
221 const FileSys::PatchManager patch{program_id}; 214 std::string name = " ";
215 const auto res3 = loader->ReadTitle(name);
222 216
223 if (res1 != Loader::ResultStatus::Success && res3 != Loader::ResultStatus::Success && 217 const FileSys::PatchManager patch{program_id};
224 res2 == Loader::ResultStatus::Success) {
225 // Use from metadata pool.
226 if (nca_control_map.find(program_id) != nca_control_map.end()) {
227 const auto& nca = nca_control_map[program_id];
228 GetMetadataFromControlNCA(patch, *nca, icon, name);
229 }
230 }
231 218
232 emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id, 219 emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
233 compatibility_list, patch)); 220 compatibility_list, patch));
221 }
234 } else if (is_dir && recursion > 0) { 222 } else if (is_dir && recursion > 0) {
235 watch_list.append(QString::fromStdString(physical_name)); 223 watch_list.append(QString::fromStdString(physical_name));
236 AddFstEntriesToGameList(physical_name, recursion - 1); 224 ScanFileSystem(target, physical_name, recursion - 1);
237 } 225 }
238 226
239 return true; 227 return true;
@@ -245,10 +233,11 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
245void GameListWorker::run() { 233void GameListWorker::run() {
246 stop_processing = false; 234 stop_processing = false;
247 watch_list.append(dir_path); 235 watch_list.append(dir_path);
248 FillControlMap(dir_path.toStdString()); 236 provider->ClearAllEntries();
249 AddInstalledTitlesToGameList(); 237 ScanFileSystem(ScanTarget::FillManualContentProvider, dir_path.toStdString(),
250 AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0); 238 deep_scan ? 256 : 0);
251 nca_control_map.clear(); 239 AddTitlesToGameList();
240 ScanFileSystem(ScanTarget::PopulateGameList, dir_path.toStdString(), deep_scan ? 256 : 0);
252 emit Finished(watch_list); 241 emit Finished(watch_list);
253} 242}
254 243
diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h
index 0e42d0bde..7c3074af9 100644
--- a/src/yuzu/game_list_worker.h
+++ b/src/yuzu/game_list_worker.h
@@ -33,7 +33,8 @@ class GameListWorker : public QObject, public QRunnable {
33 Q_OBJECT 33 Q_OBJECT
34 34
35public: 35public:
36 GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, QString dir_path, bool deep_scan, 36 GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs,
37 FileSys::ManualContentProvider* provider, QString dir_path, bool deep_scan,
37 const CompatibilityList& compatibility_list); 38 const CompatibilityList& compatibility_list);
38 ~GameListWorker() override; 39 ~GameListWorker() override;
39 40
@@ -58,12 +59,17 @@ signals:
58 void Finished(QStringList watch_list); 59 void Finished(QStringList watch_list);
59 60
60private: 61private:
61 void AddInstalledTitlesToGameList(); 62 void AddTitlesToGameList();
62 void FillControlMap(const std::string& dir_path); 63
63 void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0); 64 enum class ScanTarget {
65 FillManualContentProvider,
66 PopulateGameList,
67 };
68
69 void ScanFileSystem(ScanTarget target, const std::string& dir_path, unsigned int recursion = 0);
64 70
65 std::shared_ptr<FileSys::VfsFilesystem> vfs; 71 std::shared_ptr<FileSys::VfsFilesystem> vfs;
66 std::map<u64, std::unique_ptr<FileSys::NCA>> nca_control_map; 72 FileSys::ManualContentProvider* provider;
67 QStringList watch_list; 73 QStringList watch_list;
68 QString dir_path; 74 QString dir_path;
69 bool deep_scan; 75 bool deep_scan;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 41ba3c4c6..65bac76e7 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -168,7 +168,8 @@ static void InitializeLogging() {
168 168
169GMainWindow::GMainWindow() 169GMainWindow::GMainWindow()
170 : config(new Config()), emu_thread(nullptr), 170 : config(new Config()), emu_thread(nullptr),
171 vfs(std::make_shared<FileSys::RealVfsFilesystem>()) { 171 vfs(std::make_shared<FileSys::RealVfsFilesystem>()),
172 provider(std::make_unique<FileSys::ManualContentProvider>()) {
172 InitializeLogging(); 173 InitializeLogging();
173 174
174 debug_context = Tegra::DebugContext::Construct(); 175 debug_context = Tegra::DebugContext::Construct();
@@ -200,11 +201,15 @@ GMainWindow::GMainWindow()
200 .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc)); 201 .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
201 show(); 202 show();
202 203
204 Core::System::GetInstance().SetContentProvider(
205 std::make_unique<FileSys::ContentProviderUnion>());
206 Core::System::GetInstance().RegisterContentProvider(
207 FileSys::ContentProviderUnionSlot::FrontendManual, provider.get());
208 Service::FileSystem::CreateFactories(*vfs);
209
203 // Gen keys if necessary 210 // Gen keys if necessary
204 OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning); 211 OnReinitializeKeys(ReinitializeKeyBehavior::NoWarning);
205 212
206 // Necessary to load titles from nand in gamelist.
207 Service::FileSystem::CreateFactories(*vfs);
208 game_list->LoadCompatibilityList(); 213 game_list->LoadCompatibilityList();
209 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan); 214 game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
210 215
@@ -416,7 +421,7 @@ void GMainWindow::InitializeWidgets() {
416 render_window = new GRenderWindow(this, emu_thread.get()); 421 render_window = new GRenderWindow(this, emu_thread.get());
417 render_window->hide(); 422 render_window->hide();
418 423
419 game_list = new GameList(vfs, this); 424 game_list = new GameList(vfs, provider.get(), this);
420 ui.horizontalLayout->addWidget(game_list); 425 ui.horizontalLayout->addWidget(game_list);
421 426
422 loading_screen = new LoadingScreen(this); 427 loading_screen = new LoadingScreen(this);
@@ -1141,7 +1146,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
1141 return; 1146 return;
1142 } 1147 }
1143 1148
1144 const auto installed = Service::FileSystem::GetUnionContents(); 1149 const auto& installed = Core::System::GetInstance().GetContentProvider();
1145 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id); 1150 const auto romfs_title_id = SelectRomFSDumpTarget(installed, program_id);
1146 1151
1147 if (!romfs_title_id) { 1152 if (!romfs_title_id) {
@@ -1886,14 +1891,14 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
1886 } 1891 }
1887} 1892}
1888 1893
1889std::optional<u64> GMainWindow::SelectRomFSDumpTarget( 1894std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProvider& installed,
1890 const FileSys::RegisteredCacheUnion& installed, u64 program_id) { 1895 u64 program_id) {
1891 const auto dlc_entries = 1896 const auto dlc_entries =
1892 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); 1897 installed.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data);
1893 std::vector<FileSys::RegisteredCacheEntry> dlc_match; 1898 std::vector<FileSys::ContentProviderEntry> dlc_match;
1894 dlc_match.reserve(dlc_entries.size()); 1899 dlc_match.reserve(dlc_entries.size());
1895 std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match), 1900 std::copy_if(dlc_entries.begin(), dlc_entries.end(), std::back_inserter(dlc_match),
1896 [&program_id, &installed](const FileSys::RegisteredCacheEntry& entry) { 1901 [&program_id, &installed](const FileSys::ContentProviderEntry& entry) {
1897 return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id && 1902 return (entry.title_id & DLC_BASE_TITLE_ID_MASK) == program_id &&
1898 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success; 1903 installed.GetEntry(entry)->GetStatus() == Loader::ResultStatus::Success;
1899 }); 1904 });
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index e07c892cf..36105dd39 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -37,7 +37,8 @@ struct SoftwareKeyboardParameters;
37} // namespace Core::Frontend 37} // namespace Core::Frontend
38 38
39namespace FileSys { 39namespace FileSys {
40class RegisteredCacheUnion; 40class ContentProvider;
41class ManualContentProvider;
41class VfsFilesystem; 42class VfsFilesystem;
42} // namespace FileSys 43} // namespace FileSys
43 44
@@ -204,7 +205,7 @@ private slots:
204 void OnReinitializeKeys(ReinitializeKeyBehavior behavior); 205 void OnReinitializeKeys(ReinitializeKeyBehavior behavior);
205 206
206private: 207private:
207 std::optional<u64> SelectRomFSDumpTarget(const FileSys::RegisteredCacheUnion&, u64 program_id); 208 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
208 void UpdateStatusBar(); 209 void UpdateStatusBar();
209 210
210 Ui::MainWindow ui; 211 Ui::MainWindow ui;
@@ -232,6 +233,7 @@ private:
232 233
233 // FS 234 // FS
234 std::shared_ptr<FileSys::VfsFilesystem> vfs; 235 std::shared_ptr<FileSys::VfsFilesystem> vfs;
236 std::unique_ptr<FileSys::ManualContentProvider> provider;
235 237
236 // Debugger panes 238 // Debugger panes
237 ProfilerWidget* profilerWidget; 239 ProfilerWidget* profilerWidget;
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 245f25847..7ea4a1b18 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -33,6 +33,7 @@
33#include "yuzu_cmd/emu_window/emu_window_sdl2.h" 33#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
34 34
35#include <getopt.h> 35#include <getopt.h>
36#include "core/file_sys/registered_cache.h"
36#ifndef _MSC_VER 37#ifndef _MSC_VER
37#include <unistd.h> 38#include <unistd.h>
38#endif 39#endif
@@ -178,6 +179,7 @@ int main(int argc, char** argv) {
178 } 179 }
179 180
180 Core::System& system{Core::System::GetInstance()}; 181 Core::System& system{Core::System::GetInstance()};
182 system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
181 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>()); 183 system.SetFilesystem(std::make_shared<FileSys::RealVfsFilesystem>());
182 Service::FileSystem::CreateFactories(*system.GetFilesystem()); 184 Service::FileSystem::CreateFactories(*system.GetFilesystem());
183 185