mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-07-07 18:37:52 -05:00
file_sys: Support load game collection (#6582)
Adds support for loading games with multiple programs embedded within such as the Dragon Quest 1+2+3 Collection
This commit is contained in:
@ -404,9 +404,11 @@ void GameList::ValidateEntry(const QModelIndex& item) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto title_id = selected.data(GameListItemPath::ProgramIdRole).toULongLong();
|
||||
|
||||
// Users usually want to run a different game after closing one
|
||||
search_field->clear();
|
||||
emit GameChosen(file_path);
|
||||
emit GameChosen(file_path, title_id);
|
||||
break;
|
||||
}
|
||||
case GameListItemType::AddDir:
|
||||
@ -548,10 +550,10 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
||||
emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
|
||||
});
|
||||
connect(start_game, &QAction::triggered, [this, path]() {
|
||||
emit BootGame(QString::fromStdString(path), 0, StartGameType::Normal);
|
||||
emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal);
|
||||
});
|
||||
connect(start_game_global, &QAction::triggered, [this, path]() {
|
||||
emit BootGame(QString::fromStdString(path), 0, StartGameType::Global);
|
||||
emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global);
|
||||
});
|
||||
connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
|
||||
emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
|
||||
|
@ -88,8 +88,9 @@ public:
|
||||
static const QStringList supported_file_extensions;
|
||||
|
||||
signals:
|
||||
void BootGame(const QString& game_path, std::size_t program_index, StartGameType type);
|
||||
void GameChosen(const QString& game_path);
|
||||
void BootGame(const QString& game_path, u64 program_id, std::size_t program_index,
|
||||
StartGameType type);
|
||||
void GameChosen(const QString& game_path, const u64 title_id = 0);
|
||||
void ShouldCancelWorker();
|
||||
void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
|
||||
const std::string& game_path);
|
||||
|
@ -336,18 +336,44 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::vector<u8> icon;
|
||||
[[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
|
||||
std::vector<u64> program_ids;
|
||||
loader->ReadProgramIds(program_ids);
|
||||
|
||||
std::string name = " ";
|
||||
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
|
||||
if (res2 == Loader::ResultStatus::Success && program_ids.size() > 1 &&
|
||||
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
|
||||
for (const auto id : program_ids) {
|
||||
loader = Loader::GetLoader(system, file, id);
|
||||
if (!loader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
std::vector<u8> icon;
|
||||
[[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
|
||||
|
||||
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
|
||||
compatibility_list, patch),
|
||||
parent_dir);
|
||||
std::string name = " ";
|
||||
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
|
||||
|
||||
const FileSys::PatchManager patch{id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
|
||||
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, id,
|
||||
compatibility_list, patch),
|
||||
parent_dir);
|
||||
}
|
||||
} else {
|
||||
std::vector<u8> icon;
|
||||
[[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
|
||||
|
||||
std::string name = " ";
|
||||
[[maybe_unused]] const auto res3 = loader->ReadTitle(name);
|
||||
|
||||
const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
|
||||
emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader,
|
||||
program_id, compatibility_list, patch),
|
||||
parent_dir);
|
||||
}
|
||||
}
|
||||
} else if (is_dir) {
|
||||
watch_list.append(QString::fromStdString(physical_name));
|
||||
|
@ -1221,7 +1221,7 @@ void GMainWindow::AllowOSSleep() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) {
|
||||
bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) {
|
||||
// Shutdown previous session if the emu thread is still active...
|
||||
if (emu_thread != nullptr)
|
||||
ShutdownGame();
|
||||
@ -1244,7 +1244,7 @@ bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) {
|
||||
});
|
||||
|
||||
const Core::System::ResultStatus result{
|
||||
system.Load(*render_window, filename.toStdString(), program_index)};
|
||||
system.Load(*render_window, filename.toStdString(), program_id, program_index)};
|
||||
|
||||
const auto drd_callout = (UISettings::values.callout_flags.GetValue() &
|
||||
static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
|
||||
@ -1331,7 +1331,8 @@ void GMainWindow::SelectAndSetCurrentUser() {
|
||||
Settings::values.current_user = dialog.GetIndex();
|
||||
}
|
||||
|
||||
void GMainWindow::BootGame(const QString& filename, std::size_t program_index, StartGameType type) {
|
||||
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
|
||||
StartGameType type) {
|
||||
LOG_INFO(Frontend, "yuzu starting...");
|
||||
StoreRecentFile(filename); // Put the filename on top of the list
|
||||
|
||||
@ -1341,7 +1342,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
|
||||
|
||||
auto& system = Core::System::GetInstance();
|
||||
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
|
||||
const auto loader = Loader::GetLoader(system, v_file, program_index);
|
||||
const auto loader = Loader::GetLoader(system, v_file, program_id, program_index);
|
||||
|
||||
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
|
||||
type == StartGameType::Normal) {
|
||||
@ -1369,7 +1370,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
|
||||
SelectAndSetCurrentUser();
|
||||
}
|
||||
|
||||
if (!LoadROM(filename, program_index))
|
||||
if (!LoadROM(filename, program_id, program_index))
|
||||
return;
|
||||
|
||||
// Create and start the emulation thread
|
||||
@ -1548,8 +1549,8 @@ void GMainWindow::UpdateRecentFiles() {
|
||||
ui.menu_recent_files->setEnabled(num_recent_files != 0);
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListLoadFile(QString game_path) {
|
||||
BootGame(game_path);
|
||||
void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) {
|
||||
BootGame(game_path, program_id);
|
||||
}
|
||||
|
||||
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
|
||||
@ -2450,7 +2451,7 @@ void GMainWindow::OnLoadComplete() {
|
||||
|
||||
void GMainWindow::OnExecuteProgram(std::size_t program_index) {
|
||||
ShutdownGame();
|
||||
BootGame(last_filename_booted, program_index);
|
||||
BootGame(last_filename_booted, 0, program_index);
|
||||
}
|
||||
|
||||
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
|
||||
|
@ -186,8 +186,8 @@ private:
|
||||
void PreventOSSleep();
|
||||
void AllowOSSleep();
|
||||
|
||||
bool LoadROM(const QString& filename, std::size_t program_index);
|
||||
void BootGame(const QString& filename, std::size_t program_index = 0,
|
||||
bool LoadROM(const QString& filename, u64 program_id, std::size_t program_index);
|
||||
void BootGame(const QString& filename, u64 program_id = 0, std::size_t program_index = 0,
|
||||
StartGameType with_config = StartGameType::Normal);
|
||||
void ShutdownGame();
|
||||
|
||||
@ -238,7 +238,7 @@ private slots:
|
||||
void OnOpenQuickstartGuide();
|
||||
void OnOpenFAQ();
|
||||
/// Called whenever a user selects a game in the game list widget.
|
||||
void OnGameListLoadFile(QString game_path);
|
||||
void OnGameListLoadFile(QString game_path, u64 program_id);
|
||||
void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
|
||||
const std::string& game_path);
|
||||
void OnTransferableShaderCacheOpenFile(u64 program_id);
|
||||
|
Reference in New Issue
Block a user