diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/hle/service/am/applets/web_browser.cpp | 5 | ||||
| -rw-r--r-- | src/yuzu/game_list.cpp | 9 | ||||
| -rw-r--r-- | src/yuzu/game_list.h | 7 | ||||
| -rw-r--r-- | src/yuzu/game_list_worker.cpp | 125 | ||||
| -rw-r--r-- | src/yuzu/game_list_worker.h | 16 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 23 | ||||
| -rw-r--r-- | src/yuzu/main.h | 6 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 2 |
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 | ||
| 160 | void WebBrowser::UnpackRomFS() { | 161 | void 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 | ||
| 196 | GameList::GameList(FileSys::VirtualFilesystem vfs, GMainWindow* parent) | 197 | GameList::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; | |||
| 26 | class GMainWindow; | 26 | class GMainWindow; |
| 27 | 27 | ||
| 28 | namespace FileSys { | 28 | namespace FileSys { |
| 29 | class ManualContentProvider; | ||
| 29 | class VfsFilesystem; | 30 | class VfsFilesystem; |
| 30 | } | 31 | } // namespace FileSys |
| 31 | 32 | ||
| 32 | enum class GameListOpenTarget { | 33 | enum 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 | ||
| 122 | GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, QString dir_path, bool deep_scan, | 125 | GameListWorker::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 | ||
| 127 | GameListWorker::~GameListWorker() = default; | 131 | GameListWorker::~GameListWorker() = default; |
| 128 | 132 | ||
| 129 | void GameListWorker::AddInstalledTitlesToGameList() { | 133 | void 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 | ||
| 165 | void GameListWorker::FillControlMap(const std::string& dir_path) { | 163 | void 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 | |||
| 189 | void 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 | |||
| 245 | void GameListWorker::run() { | 233 | void 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 | ||
| 35 | public: | 35 | public: |
| 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 | ||
| 60 | private: | 61 | private: |
| 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 | ||
| 169 | GMainWindow::GMainWindow() | 169 | GMainWindow::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 | ||
| 1889 | std::optional<u64> GMainWindow::SelectRomFSDumpTarget( | 1894 | std::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 | ||
| 39 | namespace FileSys { | 39 | namespace FileSys { |
| 40 | class RegisteredCacheUnion; | 40 | class ContentProvider; |
| 41 | class ManualContentProvider; | ||
| 41 | class VfsFilesystem; | 42 | class 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 | ||
| 206 | private: | 207 | private: |
| 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 | ||