From 1146049de0c56d5be14001abc6c2afa4e7ebb132 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sun, 19 Jul 2020 07:14:46 -0400 Subject: [PATCH 1/2] main: Fix Open Save/Mod Locations for installed titles Previously NAND/SDMC installed titles would open device saves when they are supposed to be user saves. This is due to the control nca not being read and thus returns 0 for both GetDefaultNormalSaveSize() and GetDeviceSaveDataSize(). Fix this by utilizing the patch manager to read the control nca. --- src/yuzu/game_list.cpp | 4 ++-- src/yuzu/game_list.h | 3 ++- src/yuzu/main.cpp | 14 ++++++-------- src/yuzu/main.h | 3 ++- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 62acc37207..9be6a5a2f7 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -502,10 +502,10 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string pat navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); connect(open_save_location, &QAction::triggered, [this, program_id, path]() { - emit OpenFolderRequested(GameListOpenTarget::SaveData, path); + emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); }); connect(open_mod_location, &QAction::triggered, [this, program_id, path]() { - emit OpenFolderRequested(GameListOpenTarget::ModData, path); + emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path); }); connect(open_transferable_shader_cache, &QAction::triggered, [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); }); diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 483835cceb..78e2ba1699 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -84,7 +84,8 @@ public: signals: void GameChosen(QString game_path); void ShouldCancelWorker(); - void OpenFolderRequested(GameListOpenTarget target, const std::string& game_path); + void OpenFolderRequested(u64 program_id, GameListOpenTarget target, + const std::string& game_path); void OpenTransferableShaderCacheRequested(u64 program_id); void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type); void RemoveFileRequested(u64 program_id, GameListRemoveTarget target); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 592993c363..f711a337fc 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1239,20 +1239,18 @@ void GMainWindow::OnGameListLoadFile(QString game_path) { BootGame(game_path); } -void GMainWindow::OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path) { +void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target, + const std::string& game_path) { std::string path; QString open_target; + FileSys::PatchManager pm{program_id}; + const auto control = pm.GetControlMetadata(); const auto v_file = Core::GetGameFileFromPath(vfs, game_path); const auto loader = Loader::GetLoader(v_file); - FileSys::NACP control{}; - u64 program_id{}; - loader->ReadControlData(control); - loader->ReadProgramId(program_id); - - const bool has_user_save{control.GetDefaultNormalSaveSize() > 0}; - const bool has_device_save{control.GetDeviceSaveDataSize() > 0}; + const bool has_user_save{control.first->GetDefaultNormalSaveSize() > 0}; + const bool has_device_save{control.first->GetDeviceSaveDataSize() > 0}; ASSERT_MSG(has_user_save != has_device_save, "Game uses both user and device savedata?"); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 73a44a3bf5..42a8e583cf 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -198,7 +198,8 @@ private slots: void OnOpenFAQ(); /// Called whenever a user selects a game in the game list widget. void OnGameListLoadFile(QString game_path); - void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path); + void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target, + const std::string& game_path); void OnTransferableShaderCacheOpenFile(u64 program_id); void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type); void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target); From cf946312ca5aad399e39492bbb130bb1ff322cd1 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Sun, 19 Jul 2020 23:52:06 -0400 Subject: [PATCH 2/2] main: Fallback to loader if no control nca is found with patch manager In some rare instances, the patch manager is not able to find a control nca, fallback to the previous method of parsing a control nca through the loader if this occurs. --- src/yuzu/main.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index f711a337fc..e2b6462bba 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1244,13 +1244,24 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target std::string path; QString open_target; - FileSys::PatchManager pm{program_id}; - const auto control = pm.GetControlMetadata(); - const auto v_file = Core::GetGameFileFromPath(vfs, game_path); - const auto loader = Loader::GetLoader(v_file); + const auto [user_save_size, device_save_size] = [this, &program_id, &game_path] { + FileSys::PatchManager pm{program_id}; + const auto control = pm.GetControlMetadata().first; + if (control != nullptr) { + return std::make_pair(control->GetDefaultNormalSaveSize(), + control->GetDeviceSaveDataSize()); + } else { + const auto file = Core::GetGameFileFromPath(vfs, game_path); + const auto loader = Loader::GetLoader(file); - const bool has_user_save{control.first->GetDefaultNormalSaveSize() > 0}; - const bool has_device_save{control.first->GetDeviceSaveDataSize() > 0}; + FileSys::NACP nacp{}; + loader->ReadControlData(nacp); + return std::make_pair(nacp.GetDefaultNormalSaveSize(), nacp.GetDeviceSaveDataSize()); + } + }(); + + const bool has_user_save{user_save_size > 0}; + const bool has_device_save{device_save_size > 0}; ASSERT_MSG(has_user_save != has_device_save, "Game uses both user and device savedata?");