From 5f6598f9e91521c7932215debdbf0eac8607ad07 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 16 Mar 2020 21:03:21 +0100 Subject: [PATCH 1/2] StringUtil: Add PathToFileName function --- Source/Core/Common/StringUtil.cpp | 7 +++++++ Source/Core/Common/StringUtil.h | 2 ++ .../Core/DolphinQt/Settings/InterfacePane.cpp | 17 +++++++---------- Source/Core/UICommon/GameFile.cpp | 6 ++---- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp index 3afb09873f..c44f3fa7b1 100644 --- a/Source/Core/Common/StringUtil.cpp +++ b/Source/Core/Common/StringUtil.cpp @@ -322,6 +322,13 @@ bool SplitPath(std::string_view full_path, std::string* path, std::string* filen return true; } +std::string PathToFileName(std::string_view path) +{ + std::string file_name, extension; + SplitPath(path, nullptr, &file_name, &extension); + return file_name + extension; +} + void BuildCompleteFilename(std::string& complete_filename, std::string_view path, std::string_view filename) { diff --git a/Source/Core/Common/StringUtil.h b/Source/Core/Common/StringUtil.h index 211c381abf..969c6e9ea1 100644 --- a/Source/Core/Common/StringUtil.h +++ b/Source/Core/Common/StringUtil.h @@ -159,6 +159,8 @@ std::string JoinStrings(const std::vector& strings, const std::stri bool SplitPath(std::string_view full_path, std::string* path, std::string* filename, std::string* extension); +std::string PathToFileName(std::string_view path); + void BuildCompleteFilename(std::string& complete_filename, std::string_view path, std::string_view filename); diff --git a/Source/Core/DolphinQt/Settings/InterfacePane.cpp b/Source/Core/DolphinQt/Settings/InterfacePane.cpp index 0de6099cea..8281ae0132 100644 --- a/Source/Core/DolphinQt/Settings/InterfacePane.cpp +++ b/Source/Core/DolphinQt/Settings/InterfacePane.cpp @@ -119,12 +119,9 @@ void InterfacePane::CreateUI() // List avalable themes auto theme_search_results = Common::DoFileSearch({File::GetUserPath(D_THEMES_IDX), File::GetSysDirectory() + THEMES_DIR}); - for (const std::string& filename : theme_search_results) + for (const std::string& path : theme_search_results) { - std::string name, ext; - SplitPath(filename, nullptr, &name, &ext); - name += ext; - QString qt_name = QString::fromStdString(name); + const QString qt_name = QString::fromStdString(PathToFileName(path)); m_combobox_theme->addItem(qt_name); } @@ -137,12 +134,12 @@ void InterfacePane::CreateUI() m_combobox_userstyle->addItem(tr("(None)"), QString{}); - for (const std::string& filename : userstyle_search_results) + for (const std::string& path : userstyle_search_results) { - std::string name, ext; - SplitPath(filename, nullptr, &name, &ext); - QString qt_name = QString::fromStdString(name); - m_combobox_userstyle->addItem(qt_name, QString::fromStdString(filename)); + std::string name; + SplitPath(path, nullptr, &name, nullptr); + const QString qt_name = QString::fromStdString(name); + m_combobox_userstyle->addItem(qt_name, QString::fromStdString(path)); } // Checkboxes diff --git a/Source/Core/UICommon/GameFile.cpp b/Source/Core/UICommon/GameFile.cpp index 8499d270f4..cc64d9d3e9 100644 --- a/Source/Core/UICommon/GameFile.cpp +++ b/Source/Core/UICommon/GameFile.cpp @@ -97,11 +97,9 @@ GameFile::GameFile() = default; GameFile::GameFile(std::string path) : m_file_path(std::move(path)) { - { - std::string name, extension; - SplitPath(m_file_path, nullptr, &name, &extension); - m_file_name = name + extension; + m_file_name = PathToFileName(m_file_path); + { std::unique_ptr volume(DiscIO::CreateVolume(m_file_path)); if (volume != nullptr) { From 1b844067aa96f01ea630164f2328b0e16ca6b291 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 16 Mar 2020 13:02:35 +0100 Subject: [PATCH 2/2] Back up Wii setting.txt and SYSCONF while emulating When booting a Wii game, Dolphin can overwrite certain settings in the SYSCONF file, such as turning off PAL60 for NTSC games. Normally, these settings get reverted at the end of emulation, but this does not happen if Dolphin crashes or force quits in some other way. (Personally, I have a tendency to use Visual Studio's Stop Debugging button, which kills the process...) Dolphin also overwrites certain values in setting.txt when booting a Wii game. Unlike with SYSCONF, we currently make no effort to preserve the original values in this file. This change fixes both of these problems by copying SYSCONF and setting.txt to the Backup folder when booting a Wii game, and then copying them back either when launching Dolphin (in case the previous run of Dolphin crashed) or when ending emulation. --- Source/Core/Core/BootManager.cpp | 5 +++ Source/Core/Core/WiiRoot.cpp | 57 +++++++++++++++++++++++++++++++ Source/Core/Core/WiiRoot.h | 9 +++++ Source/Core/UICommon/UICommon.cpp | 3 ++ 4 files changed, 74 insertions(+) diff --git a/Source/Core/Core/BootManager.cpp b/Source/Core/Core/BootManager.cpp index 9b58f580e1..4dbe7a2f9d 100644 --- a/Source/Core/Core/BootManager.cpp +++ b/Source/Core/Core/BootManager.cpp @@ -45,6 +45,7 @@ #include "Core/Movie.h" #include "Core/NetPlayProto.h" #include "Core/PowerPC/PowerPC.h" +#include "Core/WiiRoot.h" #include "DiscIO/Enums.h" @@ -439,7 +440,10 @@ bool BootCore(std::unique_ptr boot, const WindowSystemInfo& wsi) // Ensure any new settings are written to the SYSCONF if (StartUp.bWii) + { + Core::BackupWiiSettings(); ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta); + } const bool load_ipl = !StartUp.bWii && !StartUp.bHLE_BS2 && std::holds_alternative(boot->parameters); @@ -487,6 +491,7 @@ static void RestoreSYSCONF() void RestoreConfig() { + Core::RestoreWiiSettings(Core::RestoreReason::EmulationEnd); RestoreSYSCONF(); Config::ClearCurrentRunLayer(); Config::RemoveLayer(Config::LayerType::Movie); diff --git a/Source/Core/Core/WiiRoot.cpp b/Source/Core/Core/WiiRoot.cpp index c5caf3b7b7..3b7a17ab97 100644 --- a/Source/Core/Core/WiiRoot.cpp +++ b/Source/Core/Core/WiiRoot.cpp @@ -16,6 +16,8 @@ #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/NandPaths.h" +#include "Common/StringUtil.h" +#include "Core/CommonTitles.h" #include "Core/ConfigManager.h" #include "Core/HW/WiiSave.h" #include "Core/IOS/ES/ES.h" @@ -32,6 +34,38 @@ namespace FS = IOS::HLE::FS; static std::string s_temp_wii_root; +static bool CopyBackupFile(const std::string& path_from, const std::string& path_to) +{ + if (!File::Exists(path_from)) + return false; + + return File::Copy(path_from, path_to); +} + +static void DeleteBackupFile(const std::string& file_name) +{ + File::Delete(File::GetUserPath(D_BACKUP_IDX) + DIR_SEP + file_name); +} + +static void BackupFile(const std::string& path_in_nand) +{ + const std::string file_name = PathToFileName(path_in_nand); + const std::string original_path = File::GetUserPath(D_WIIROOT_IDX) + DIR_SEP + path_in_nand; + const std::string backup_path = File::GetUserPath(D_BACKUP_IDX) + DIR_SEP + file_name; + + CopyBackupFile(original_path, backup_path); +} + +static void RestoreFile(const std::string& path_in_nand) +{ + const std::string file_name = PathToFileName(path_in_nand); + const std::string original_path = File::GetUserPath(D_WIIROOT_IDX) + DIR_SEP + path_in_nand; + const std::string backup_path = File::GetUserPath(D_BACKUP_IDX) + DIR_SEP + file_name; + + if (CopyBackupFile(backup_path, original_path)) + DeleteBackupFile(file_name); +} + static void CopySave(FS::FileSystem* source, FS::FileSystem* dest, const u64 title_id) { dest->CreateFullPath(IOS::PID_KERNEL, IOS::PID_KERNEL, Common::GetTitleDataPath(title_id) + '/', @@ -173,6 +207,29 @@ void ShutdownWiiRoot() } } +void BackupWiiSettings() +{ + // Back up files which Dolphin can modify at boot, so that we can preserve the original contents. + // For SYSCONF, the backup is only needed in case Dolphin crashes or otherwise exists unexpectedly + // during emulation, since the config system will restore the SYSCONF settings at emulation end. + // For setting.txt, there is no other code that restores the original values for us. + + BackupFile(Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING); + BackupFile("/shared2/sys/SYSCONF"); +} + +void RestoreWiiSettings(RestoreReason reason) +{ + RestoreFile(Common::GetTitleDataPath(Titles::SYSTEM_MENU) + "/" WII_SETTING); + + // We must not restore the SYSCONF backup when ending emulation cleanly, since the user may have + // edited the SYSCONF file in the NAND using the emulated software (e.g. the Wii Menu settings). + if (reason == RestoreReason::CrashRecovery) + RestoreFile("/shared2/sys/SYSCONF"); + else + DeleteBackupFile("SYSCONF"); +} + /// Copy a directory from host_source_path (on the host FS) to nand_target_path on the NAND. /// /// Both paths should not have trailing slashes. To specify the NAND root, use "". diff --git a/Source/Core/Core/WiiRoot.h b/Source/Core/Core/WiiRoot.h index c62aaa103f..7b069d0c07 100644 --- a/Source/Core/Core/WiiRoot.h +++ b/Source/Core/Core/WiiRoot.h @@ -6,9 +6,18 @@ namespace Core { +enum class RestoreReason +{ + EmulationEnd, + CrashRecovery, +}; + void InitializeWiiRoot(bool use_temporary); void ShutdownWiiRoot(); +void BackupWiiSettings(); +void RestoreWiiSettings(RestoreReason reason); + // Initialize or clean up the filesystem contents. void InitializeWiiFileSystemContents(); void CleanUpWiiFileSystemContents(); diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp index 76ff64ac25..5af9192711 100644 --- a/Source/Core/UICommon/UICommon.cpp +++ b/Source/Core/UICommon/UICommon.cpp @@ -31,6 +31,7 @@ #include "Core/HW/Wiimote.h" #include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" +#include "Core/WiiRoot.h" #include "InputCommon/GCAdapter.h" @@ -88,6 +89,8 @@ static void InitCustomPaths() void Init() { + Core::RestoreWiiSettings(Core::RestoreReason::CrashRecovery); + Config::Init(); Config::AddConfigChangedCallback(InitCustomPaths); Config::AddLayer(ConfigLoaders::GenerateBaseConfigLoader());