Added ability to change save data path (#2199)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / linux-sdl-gcc (push) Blocked by required conditions
Build and Release / linux-qt-gcc (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions

* added ability to change save data path

* get default save data path from fs

* add copyright

* formatting
This commit is contained in:
f3d209 2025-01-22 10:10:35 +00:00 committed by GitHub
parent 78ae9613c5
commit adbff4056f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 132 additions and 53 deletions

View file

@ -78,6 +78,7 @@ static std::string trophyKey;
static bool load_game_size = true;
std::vector<std::filesystem::path> settings_install_dirs = {};
std::filesystem::path settings_addon_install_dir = {};
std::filesystem::path save_data_path = {};
u32 main_window_geometry_x = 400;
u32 main_window_geometry_y = 400;
u32 main_window_geometry_w = 1280;
@ -110,6 +111,13 @@ bool GetLoadGameSizeEnabled() {
return load_game_size;
}
std::filesystem::path GetSaveDataPath() {
if (save_data_path.empty()) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir);
}
return save_data_path;
}
void setLoadGameSizeEnabled(bool enable) {
load_game_size = enable;
}
@ -502,6 +510,10 @@ void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_insta
settings_install_dirs = settings_install_dirs_config;
}
void setSaveDataPath(const std::filesystem::path& path) {
save_data_path = path;
}
u32 getMainWindowGeometryX() {
return main_window_geometry_x;
}
@ -690,6 +702,8 @@ void load(const std::filesystem::path& path) {
addGameInstallDir(std::filesystem::path{dir});
}
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
@ -784,6 +798,7 @@ void save(const std::filesystem::path& path) {
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
}
data["GUI"]["installDirs"] = install_dirs;
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
data["GUI"]["addonInstallDir"] =

View file

@ -18,6 +18,7 @@ void saveMainWindow(const std::filesystem::path& path);
std::string getTrophyKey();
void setTrophyKey(std::string key);
bool GetLoadGameSizeEnabled();
std::filesystem::path GetSaveDataPath();
void setLoadGameSizeEnabled(bool enable);
bool getIsFullscreen();
std::string getFullscreenMode();
@ -82,6 +83,7 @@ void setUserName(const std::string& type);
void setUpdateChannel(const std::string& type);
void setSeparateUpdateEnabled(bool use);
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
void setSaveDataPath(const std::filesystem::path& path);
void setCompatibilityEnabled(bool use);
void setCheckCompatibilityOnStartup(bool use);

View file

@ -47,15 +47,13 @@ namespace Libraries::SaveData {
std::filesystem::path SaveInstance::MakeTitleSavePath(OrbisUserServiceUserId user_id,
std::string_view game_serial) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
game_serial;
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial;
}
std::filesystem::path SaveInstance::MakeDirSavePath(OrbisUserServiceUserId user_id,
std::string_view game_serial,
std::string_view dir_name) {
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) / std::to_string(user_id) /
game_serial / dir_name;
return Config::GetSaveDataPath() / std::to_string(user_id) / game_serial / dir_name;
}
uint64_t SaveInstance::GetMaxBlockFromSFO(const PSF& psf) {

View file

@ -202,6 +202,21 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
delete selected_item;
}
});
connect(ui->browseButton, &QPushButton::clicked, this, [this]() {
const auto save_data_path = Config::GetSaveDataPath();
QString initial_path;
Common::FS::PathToQString(initial_path, save_data_path);
QString save_data_path_string =
QFileDialog::getExistingDirectory(this, tr("Directory to save data"), initial_path);
auto file_path = Common::FS::PathFromQString(save_data_path_string);
if (!file_path.empty()) {
Config::setSaveDataPath(file_path);
ui->currentSaveDataPath->setText(save_data_path_string);
}
});
}
// DEBUG TAB
@ -256,6 +271,10 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices,
ui->addFolderButton->installEventFilter(this);
ui->removeFolderButton->installEventFilter(this);
ui->saveDataGroupBox->installEventFilter(this);
ui->currentSaveDataPath->installEventFilter(this);
ui->browseButton->installEventFilter(this);
// Debug
ui->debugDump->installEventFilter(this);
ui->vkValidationCheckBox->installEventFilter(this);
@ -286,6 +305,11 @@ void SettingsDialog::LoadValuesFromConfig() {
const QVector<int> languageIndexes = {21, 23, 14, 6, 18, 1, 12, 22, 2, 4, 25, 24, 29, 5, 0, 9,
15, 16, 17, 7, 26, 8, 11, 20, 3, 13, 27, 10, 19, 30, 28};
const auto save_data_path = Config::GetSaveDataPath();
QString save_data_path_string;
Common::FS::PathToQString(save_data_path_string, save_data_path);
ui->currentSaveDataPath->setText(save_data_path_string);
ui->consoleLanguageComboBox->setCurrentIndex(
std::distance(languageIndexes.begin(),
std::find(languageIndexes.begin(), languageIndexes.end(),
@ -497,6 +521,13 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) {
text = tr("removeFolderButton");
}
// Save Data
if (elementName == "saveDataGroupBox" || elementName == "currentSaveDataPath") {
text = tr("saveDataBox");
} else if (elementName == "browseButton") {
text = tr("browseButton");
}
// Debug
if (elementName == "debugDump") {
text = tr("debugDump");
@ -603,4 +634,4 @@ void SettingsDialog::ResetInstallFolders() {
}
Config::setGameInstallDirs(settings_install_dirs_config);
}
}
}

View file

@ -53,7 +53,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>0</number>
<number>3</number>
</property>
<widget class="QScrollArea" name="generalTab">
<property name="widgetResizable">
@ -67,8 +67,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>611</height>
<width>771</width>
<height>606</height>
</rect>
</property>
<layout class="QVBoxLayout" name="generalTabVLayout" stretch="0">
@ -644,8 +644,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>605</height>
<width>455</width>
<height>252</height>
</rect>
</property>
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0,0">
@ -928,8 +928,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>605</height>
<width>579</width>
<height>194</height>
</rect>
</property>
<layout class="QVBoxLayout" name="graphicsTabVLayout" stretch="0,0">
@ -1178,51 +1178,76 @@
<string>Paths</string>
</attribute>
<widget class="QWidget" name="pathsTabContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>605</height>
</rect>
</property>
<layout class="QVBoxLayout" name="pathsTabLayout" stretch="0">
<layout class="QVBoxLayout" name="pathsTabLayout">
<item>
<layout class="QHBoxLayout" name="pathsTabVLayout">
<item>
<widget class="QGroupBox" name="gameFoldersGroupBox">
<property name="title">
<string>Game Folders</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="gameFoldersGroupBox">
<property name="title">
<string>Game Folders</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="addFolderButton">
<property name="text">
<string>Add...</string>
</property>
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item>
</item>
<item>
<widget class="QPushButton" name="removeFolderButton">
<property name="text">
<string>Remove</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="gameFoldersListWidget"/>
</item>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="gameFoldersListWidget"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="saveDataGroupBox">
<property name="title">
<string>Save Data Path</string>
</property>
<layout class="QVBoxLayout" name="saveDataLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="currentSaveDataPath">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="browseButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
@ -1239,8 +1264,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>586</height>
<width>510</width>
<height>269</height>
</rect>
</property>
<layout class="QVBoxLayout" name="debugTabVLayout" stretch="0,1">

View file

@ -912,6 +912,14 @@
<source>rdocCheckBox</source>
<translation>Enable RenderDoc Debugging:\nIf enabled, the emulator will provide compatibility with Renderdoc to allow capture and analysis of the currently rendered frame.</translation>
</message>
<message>
<source>saveDataBox</source>
<translation>Save Data Path:\nThe folder where game save data will be saved.</translation>
</message>
<message>
<source>browseButton</source>
<translation>Browse:\nBrowse for a folder to set as the save data path.</translation>
</message>
</context>
<context>
<name>CheatsPatches</name>