[Scummvm-git-logs] scummvm master -> 18f2ab00cdbb90a02983f3d9850fb7a19784e0c4
dreammaster
noreply at scummvm.org
Fri Apr 1 05:16:20 UTC 2022
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e37ab7b725 AGS: Implemented "localuserconf" option in cmdline and global config
8d8b786079 AGS: Don't mkdirs in the platform driver, return FSLocation instead
ccba1ca389 AGS: Code rewrite: split MakeGameDataDir() to make things bit clear
1d92ed73d9 AGS: Code rewrite: split SetSaveGameDirectory to make things easier
18f2ab00cd AGS: Fixed and simplified MakeSaveGameDir() to match recent changes
Commit: e37ab7b7253b7f6b87c6a3bb56bac7d619b6f97d
https://github.com/scummvm/scummvm/commit/e37ab7b7253b7f6b87c6a3bb56bac7d619b6f97d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-31T19:36:12-07:00
Commit Message:
AGS: Implemented "localuserconf" option in cmdline and global config
>From upstream 109a9d985f498ed31308e2e97e1b97fa306c87c0
Changed paths:
engines/ags/engine/ac/file.cpp
engines/ags/engine/ac/game_setup.cpp
engines/ags/engine/ac/game_setup.h
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/main.cpp
diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp
index da20e76f51e..dfdecafb1dc 100644
--- a/engines/ags/engine/ac/file.cpp
+++ b/engines/ags/engine/ac/file.cpp
@@ -269,6 +269,8 @@ FSLocation GetGameUserConfigDir() {
return FSLocation(_GP(usetup).user_conf_dir);
else if (Path::IsRelativePath(dir)) // relative dir is resolved relative to the game data dir
return FSLocation(_GP(ResPaths).DataDir, dir);
+ else if (_GP(usetup).local_user_conf) // directive to use game dir location
+ return FSLocation(_GP(ResPaths).DataDir);
// For absolute dir, we assume it's a special directory prepared for AGS engine
// and therefore amend it with a game own subdir
return FSLocation(dir, _GP(game).saveGameFolderName);
diff --git a/engines/ags/engine/ac/game_setup.cpp b/engines/ags/engine/ac/game_setup.cpp
index ff6c7a52439..948cce1936c 100644
--- a/engines/ags/engine/ac/game_setup.cpp
+++ b/engines/ags/engine/ac/game_setup.cpp
@@ -24,6 +24,7 @@
namespace AGS3 {
GameSetup::GameSetup() {
+ local_user_conf = false;
audio_backend = 1;
no_speech_pack = false;
textheight = 0;
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index d165bd62f71..1b7bc4a2dfc 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -68,6 +68,7 @@ struct GameSetup {
String opt_voice_dir; // optional custom install voice-over dir path
//
String conf_path; // a read-only config path (if set the regular config is ignored)
+ bool local_user_conf; // search for user config in the game directory
String user_conf_dir; // directory to read and write user config in
String user_data_dir; // directory to write savedgames and user files to
String shared_data_dir; // directory to write shared game files to
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 39ac3eb7b41..384daf60476 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -964,6 +964,15 @@ void engine_read_config(ConfigTree &cfg) {
}
}
+ // Handle directive to search for the user config inside the game directory;
+ // this option may come either from command line or default/global config.
+ _GP(usetup).local_user_conf |= INIreadint(cfg, "misc", "localuserconf", 0) != 0;
+ if (_GP(usetup).local_user_conf) { // Test if the file is writeable, if it is then both engine and setup
+ // applications may actually use it fully as a user config, otherwise
+ // fallback to default behavior.
+ _GP(usetup).local_user_conf = File::TestWriteFile(def_cfg_file);
+ }
+
// Read user configuration file
String user_cfg_file = find_user_cfg_file();
if (Path::ComparePaths(user_cfg_file, def_cfg_file) != 0 &&
diff --git a/engines/ags/engine/main/main.cpp b/engines/ags/engine/main/main.cpp
index c4e19aade28..1b3894c9778 100644
--- a/engines/ags/engine/main/main.cpp
+++ b/engines/ags/engine/main/main.cpp
@@ -211,6 +211,8 @@ int main_process_cmdline(ConfigTree &cfg, int argc, const char *argv[]) {
ee++;
} else if (ags_stricmp(arg, "--conf") == 0 && (argc > ee + 1)) {
_GP(usetup).conf_path = argv[++ee];
+ } else if (ags_stricmp(arg, "--localuserconf") == 0) {
+ _GP(usetup).local_user_conf = true;
} else if (ags_stricmp(arg, "--localuserconf") == 0) {
_GP(usetup).user_conf_dir = ".";
} else if ((ags_stricmp(arg, "--user-conf-dir") == 0) && (argc > ee + 1)) {
Commit: 8d8b7860796f9beca1375dbdf27a2dd1437aab28
https://github.com/scummvm/scummvm/commit/8d8b7860796f9beca1375dbdf27a2dd1437aab28
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-31T20:04:43-07:00
Commit Message:
AGS: Don't mkdirs in the platform driver, return FSLocation instead
>From upstream 13312e9a1d3a427f49ccfe4e78f7d0736123a809
Changed paths:
engines/ags/engine/ac/file.cpp
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/path_helper.h
engines/ags/engine/debugging/debug.cpp
engines/ags/engine/platform/base/ags_platform_driver.h
engines/ags/engine/platform/scummvm/scummvm_platform_driver.cpp
diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp
index dfdecafb1dc..9bee383f4ee 100644
--- a/engines/ags/engine/ac/file.cpp
+++ b/engines/ags/engine/ac/file.cpp
@@ -250,6 +250,12 @@ String PathFromInstallDir(const String &path) {
return path;
}
+FSLocation PathFromInstallDir(const FSLocation &fsloc) {
+ if (is_relative_filename(fsloc.FullDir.GetCStr()))
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(fsloc.FullDir);
+ return fsloc;
+}
+
String PreparePathForWriting(const FSLocation &fsloc, const String &filename) {
if (Directory::CreateAllDirectories(fsloc.BaseDir, fsloc.SubDir))
return Path::ConcatPaths(fsloc.FullDir, filename);
@@ -257,45 +263,41 @@ String PreparePathForWriting(const FSLocation &fsloc, const String &filename) {
}
FSLocation GetGlobalUserConfigDir() {
- String dir = _G(platform)->GetUserGlobalConfigDirectory();
- if (Path::IsRelativePath(dir)) // relative dir is resolved relative to the game data dir
- return FSLocation(_GP(ResPaths).DataDir, dir);
- return FSLocation(dir);
+ FSLocation dir = _G(platform)->GetUserGlobalConfigDirectory();
+ if (is_relative_filename(dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(dir.FullDir);
+ return dir;
}
FSLocation GetGameUserConfigDir() {
- String dir = _G(platform)->GetUserConfigDirectory();
- if (!_GP(usetup).user_conf_dir.IsEmpty()) // directive to use custom userconf location
- return FSLocation(_GP(usetup).user_conf_dir);
- else if (Path::IsRelativePath(dir)) // relative dir is resolved relative to the game data dir
- return FSLocation(_GP(ResPaths).DataDir, dir);
+ FSLocation dir = _G(platform)->GetUserConfigDirectory();
+ if (is_relative_filename(dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(dir.FullDir);
else if (_GP(usetup).local_user_conf) // directive to use game dir location
return FSLocation(_GP(ResPaths).DataDir);
// For absolute dir, we assume it's a special directory prepared for AGS engine
- // and therefore amend it with a game own subdir
- return FSLocation(dir, _GP(game).saveGameFolderName);
+ // and therefore append a game's own subdir
+ return dir.Concat(_GP(game).saveGameFolderName);
}
// A helper function that deduces a data directory either using default system location,
// or user option from config. In case of a default location a path is appended with
// game's "save folder" name, which is meant to separate files from different games.
-static FSLocation MakeGameDataDir(const String &default_dir, const String &user_option) {
- if (user_option.IsEmpty()) {
- String dir = default_dir;
- if (Path::IsRelativePath(dir)) // relative dir is resolved relative to the game data dir
- return FSLocation(_GP(ResPaths).DataDir, dir);
+static FSLocation MakeGameDataDir(const FSLocation &def_dir, const String &user_dir) {
+ if (user_dir.IsEmpty()) {
+ if (is_relative_filename(def_dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(def_dir.FullDir);
// For absolute dir, we assume it's a special directory prepared for AGS engine
- // and therefore amend it with a game own subdir
- return FSLocation(dir, _GP(game).saveGameFolderName);
+ // and therefore amend it with a game's own subdir
+ return def_dir.Concat(_GP(game).saveGameFolderName);
}
// If this location is set up by user config, then use it as is (resolving relative path if necessary)
- String dir = user_option;
- if (Path::IsSameOrSubDir(_GP(ResPaths).DataDir, dir)) // check if it's inside game dir
- return FSLocation(_GP(ResPaths).DataDir, Path::MakeRelativePath(_GP(ResPaths).DataDir, dir));
- dir = Path::MakeAbsolutePath(dir);
- return FSLocation(dir);
+ if (Path::IsSameOrSubDir(_GP(ResPaths).DataDir, user_dir)) // check if it's inside game dir
+ return FSLocation(_GP(ResPaths).DataDir, Path::MakeRelativePath(_GP(ResPaths).DataDir, user_dir));
+ return FSLocation(Path::MakeAbsolutePath(user_dir));
}
+
FSLocation GetGameAppDataDir() {
return MakeGameDataDir(_G(platform)->GetAllUsersDataDirectory(), _GP(usetup).shared_data_dir);
}
@@ -422,6 +424,10 @@ bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp) {
return true;
}
+bool CreateFSDirs(const FSLocation &fs) {
+ return Directory::CreateAllDirectories(fs.BaseDir, fs.FullDir);
+}
+
//
// AGS custom PACKFILE callbacks, that use our own Stream object
//
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index c603df1dc7f..abd2164bae0 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -237,46 +237,46 @@ String get_save_game_path(int slotNum) {
#if !AGS_PLATFORM_SCUMMVM
// Convert a path possibly containing path tags into acceptable save path
+// NOTE that the game script may issue an order to change the save directory to
+// a dir of a new name. While we let this work, we also try to keep these
+// inside same parent location, would that be a common system directory,
+// or a custom one set by a player in config.
bool MakeSaveGameDir(const String &newFolder, FSLocation &fsloc) {
- fsloc = FSLocation();
+ rp = ResolvedPath();
// don't allow absolute paths
- if (!Path::IsRelativePath(newFolder))
+ if (!is_relative_filename(newFolder))
return false;
- String base_dir;
- String sub_dir;
+ FSLocation fsdir;
+ String newSaveGameDir = FixSlashAfterToken(newFolder);
- if (newFolder.CompareLeft(UserSavedgamesRootToken) == 0) {
- // IMPORTANT: for compatibility reasons we support both cases:
- // when token is followed by the path separator and when it is not, in which case it's assumed.
- if (saveGameParent.IsEmpty()) {
- base_dir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
- sub_dir = newFolder.Mid(UserSavedgamesRootToken.GetLength());
+ if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) {
+ if (saveGameParent.IsEmpty()) { // Set this up inside a standard AGS save dir
+ fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
+ fsdir = fsdir.Concat(newSaveGameDir.Mid(UserSavedgamesRootToken.GetLength()));
} else {
// If there is a custom save parent directory, then replace
- // not only root token, but also first subdirectory after the token
- base_dir = saveGameParent;
- sub_dir = Path::ConcatPaths(".", newFolder.Mid(UserSavedgamesRootToken.GetLength()));
- sub_dir.ClipSection('/', 0, 1); // TODO: Path helper function for this?
+ // not only root token, but also first subdirectory
+ newSaveGameDir.ClipSection('/', 0, 1); // TODO: Path helper function for this?
+ fsdir = FSLocation(saveGameParent).Concat(newSaveGameDir);
}
- fsloc = FSLocation(base_dir, sub_dir);
} else {
// Convert the path relative to installation folder into path relative to the
// safe save path with default name
- if (saveGameParent.IsEmpty()) {
- base_dir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
- sub_dir = Path::ConcatPaths(game.saveGameFolderName, newFolder);
+ if (saveGameParent.IsEmpty()) { // Set this up inside a standard AGS save dir
+ fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
+ fsdir = fsdir.Concat(Path::ConcatPaths(game.saveGameFolderName, newFolder));
} else {
- base_dir = saveGameParent;
- sub_dir = newFolder;
+ fsdir = FSLocation(saveGameParent).Concat(newFolder);
}
- fsloc = FSLocation(base_dir, sub_dir);
// For games made in the safe-path-aware versions of AGS, report a warning
if (game.options[OPT_SAFEFILEPATHS]) {
debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'",
- newFolder.GetCStr(), fsloc.FullDir.GetCStr());
+ newFolder.GetCStr(), fsdir.FullDir.GetCStr());
}
}
+ rp.BaseDir = fsdir.BaseDir;
+ rp.FullPath = fsdir.FullDir;
return true;
}
#endif
diff --git a/engines/ags/engine/ac/path_helper.h b/engines/ags/engine/ac/path_helper.h
index 399372b81f1..265651a0f4e 100644
--- a/engines/ags/engine/ac/path_helper.h
+++ b/engines/ags/engine/ac/path_helper.h
@@ -47,9 +47,6 @@ extern const char *DefaultConfigFileName;
// Subsitutes illegal characters with '_'. This function uses illegal chars array
// specific to current platform.
void FixupFilename(char *filename);
-// Tests the input path, if it's an absolute path then returns it unchanged;
-// if it's a relative path then resolves it into absolute, using install dir as a base.
-String PathFromInstallDir(const String &path);
// FSLocation describes a file system location defined by two parts:
// a secure path that engine does not own, and sub-path that it owns.
@@ -66,7 +63,22 @@ struct FSLocation {
: BaseDir(base), SubDir(subdir),
FullDir(AGS::Shared::Path::ConcatPaths(base, subdir)) {
}
+ inline bool IsValid() const {
+ return !FullDir.IsEmpty();
+ }
+ // Concats the given path to the existing full dir
+ inline FSLocation Concat(const String &path) const {
+ return FSLocation(BaseDir, AGS::Shared::Path::ConcatPaths(FullDir, path));
+ }
+ // Sets full path as a relative to the existing base dir
+ inline FSLocation Rebase(const String &path) const {
+ return FSLocation(BaseDir, AGS::Shared::Path::ConcatPaths(BaseDir, path));
+ }
};
+// Tests the input path, if it's an absolute path then returns it unchanged;
+// if it's a relative path then resolves it into absolute, using install dir as a base.
+String PathFromInstallDir(const String &path);
+FSLocation PathFromInstallDir(const FSLocation &fsloc);
// Makes sure that given system location is available, makes directories if have to (and if it's allowed to)
// Returns full file path on success, empty string on failure.
String PreparePathForWriting(const FSLocation &fsloc, const String &filename);
@@ -106,6 +118,8 @@ bool ResolveScriptPath(const String &sc_path, bool read_only, ResolvedPath &rp);
// Returns 'true' on success, and 'false' if either path is impossible to resolve,
// forbidden for writing, or if failed to create any subdirectories.
bool ResolveWritePathAndCreateDirs(const String &sc_path, ResolvedPath &rp);
+// Creates all necessary subdirectories inside the safe parent location.
+bool CreateFSDirs(const FSLocation &fs);
} // namespace AGS3
diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp
index 16fe3c1569c..8080be0e4cc 100644
--- a/engines/ags/engine/debugging/debug.cpp
+++ b/engines/ags/engine/debugging/debug.cpp
@@ -90,7 +90,12 @@ PDebugOutput create_log_output(const String &name, const String &path = "", LogF
return _GP(DbgMgr).RegisterOutput(OutputSystemID, AGSPlatformDriver::GetDriver(), kDbgMsg_None);
} else if (name.CompareNoCase(OutputFileID) == 0) {
_GP(DebugLogFile).reset(new LogFile());
- String logfile_path = !path.IsEmpty() ? path : Path::ConcatPaths(_G(platform)->GetAppOutputDirectory(), "ags.log");
+ String logfile_path = path;
+ if (logfile_path.IsEmpty()) {
+ FSLocation fs = _G(platform)->GetAppOutputDirectory();
+ CreateFSDirs(fs);
+ logfile_path = Path::ConcatPaths(fs.FullDir, "ags.log");
+ }
if (!_GP(DebugLogFile)->OpenFile(logfile_path, open_mode))
return nullptr;
Debug::Printf(kDbgMsg_Info, "Logging to %s", logfile_path.GetCStr());
diff --git a/engines/ags/engine/platform/base/ags_platform_driver.h b/engines/ags/engine/platform/base/ags_platform_driver.h
index 3347bf52e59..415486b48fb 100644
--- a/engines/ags/engine/platform/base/ags_platform_driver.h
+++ b/engines/ags/engine/platform/base/ags_platform_driver.h
@@ -30,6 +30,7 @@
#include "ags/lib/std/vector.h"
#include "ags/engine/ac/date_time.h"
+#include "ags/engine/ac/path_helper.h"
#include "ags/shared/debugging/output_handler.h"
#include "ags/shared/util/ini_util.h"
#include "ags/lib/allegro/error.h"
@@ -86,24 +87,24 @@ struct AGSPlatformDriver
virtual void AttachToParentConsole();
virtual int GetLastSystemError();
// Get root directory for storing per-game shared data
- virtual const char *GetAllUsersDataDirectory() {
- return ".";
+ virtual FSLocation GetAllUsersDataDirectory() {
+ return FSLocation(".");
}
// Get root directory for storing per-game saved games
- virtual const char *GetUserSavedgamesDirectory() {
- return ".";
+ virtual FSLocation GetUserSavedgamesDirectory() {
+ return FSLocation(".");
}
// Get root directory for storing per-game user configuration files
- virtual const char *GetUserConfigDirectory() {
- return ".";
+ virtual FSLocation GetUserConfigDirectory() {
+ return FSLocation(".");
}
// Get directory for storing all-games user configuration files
- virtual const char *GetUserGlobalConfigDirectory() {
- return ".";
+ virtual FSLocation GetUserGlobalConfigDirectory() {
+ return FSLocation(".");
}
// Get default directory for program output (logs)
- virtual const char *GetAppOutputDirectory() {
- return ".";
+ virtual FSLocation GetAppOutputDirectory() {
+ return FSLocation(".");
}
// Returns array of characters illegal to use in file names
virtual const char *GetIllegalFileChars() {
diff --git a/engines/ags/engine/platform/scummvm/scummvm_platform_driver.cpp b/engines/ags/engine/platform/scummvm/scummvm_platform_driver.cpp
index e083bfd2963..c7dfa5afc16 100644
--- a/engines/ags/engine/platform/scummvm/scummvm_platform_driver.cpp
+++ b/engines/ags/engine/platform/scummvm/scummvm_platform_driver.cpp
@@ -40,11 +40,11 @@ struct ScummVMPlatformDriver : AGSPlatformDriver {
int CDPlayerCommand(int cmdd, int datt) override;
void DisplayAlert(const char *, ...) override;
- const char *GetAllUsersDataDirectory() override;
- const char *GetUserSavedgamesDirectory() override;
- const char *GetUserConfigDirectory() override;
- const char *GetUserGlobalConfigDirectory() override;
- const char *GetAppOutputDirectory() override;
+ FSLocation GetAllUsersDataDirectory() override;
+ FSLocation GetUserSavedgamesDirectory() override;
+ FSLocation GetUserConfigDirectory() override;
+ FSLocation GetUserGlobalConfigDirectory() override;
+ FSLocation GetAppOutputDirectory() override;
unsigned long GetDiskFreeSpaceMB() override;
const char *GetNoMouseErrorString() override;
const char *GetAllegroFailUserHint() override;
@@ -77,24 +77,24 @@ void ScummVMPlatformDriver::DisplayAlert(const char *text, ...) {
::AGS::g_vm->GUIError(msg);
}
-const char *ScummVMPlatformDriver::GetAllUsersDataDirectory() {
- return "";
+FSLocation ScummVMPlatformDriver::GetAllUsersDataDirectory() {
+ return FSLocation(".");
}
-const char *ScummVMPlatformDriver::GetUserSavedgamesDirectory() {
- return "";
+FSLocation ScummVMPlatformDriver::GetUserSavedgamesDirectory() {
+ return FSLocation(".");
}
-const char *ScummVMPlatformDriver::GetUserConfigDirectory() {
+FSLocation ScummVMPlatformDriver::GetUserConfigDirectory() {
return GetUserSavedgamesDirectory();
}
-const char *ScummVMPlatformDriver::GetUserGlobalConfigDirectory() {
+FSLocation ScummVMPlatformDriver::GetUserGlobalConfigDirectory() {
return GetUserSavedgamesDirectory();
}
-const char *ScummVMPlatformDriver::GetAppOutputDirectory() {
- return "";
+FSLocation ScummVMPlatformDriver::GetAppOutputDirectory() {
+ return FSLocation(".");
}
unsigned long ScummVMPlatformDriver::GetDiskFreeSpaceMB() {
Commit: ccba1ca38934fb4575bd94159328569ee05b1a35
https://github.com/scummvm/scummvm/commit/ccba1ca38934fb4575bd94159328569ee05b1a35
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-31T20:29:04-07:00
Commit Message:
AGS: Code rewrite: split MakeGameDataDir() to make things bit clear
>From upstream 403e680373732d984c97845d20f32dd53f5c23f1
Changed paths:
engines/ags/engine/ac/file.cpp
engines/ags/shared/util/string.h
diff --git a/engines/ags/engine/ac/file.cpp b/engines/ags/engine/ac/file.cpp
index 9bee383f4ee..62e6ab5f815 100644
--- a/engines/ags/engine/ac/file.cpp
+++ b/engines/ags/engine/ac/file.cpp
@@ -251,7 +251,7 @@ String PathFromInstallDir(const String &path) {
}
FSLocation PathFromInstallDir(const FSLocation &fsloc) {
- if (is_relative_filename(fsloc.FullDir.GetCStr()))
+ if (is_relative_filename(fsloc.FullDir))
return FSLocation(_GP(ResPaths).DataDir).Rebase(fsloc.FullDir);
return fsloc;
}
@@ -264,14 +264,14 @@ String PreparePathForWriting(const FSLocation &fsloc, const String &filename) {
FSLocation GetGlobalUserConfigDir() {
FSLocation dir = _G(platform)->GetUserGlobalConfigDirectory();
- if (is_relative_filename(dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
+ if (is_relative_filename(dir.FullDir)) // relative dir is resolved relative to the game data dir
return FSLocation(_GP(ResPaths).DataDir).Rebase(dir.FullDir);
return dir;
}
FSLocation GetGameUserConfigDir() {
FSLocation dir = _G(platform)->GetUserConfigDirectory();
- if (is_relative_filename(dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
+ if (is_relative_filename(dir.FullDir)) // relative dir is resolved relative to the game data dir
return FSLocation(_GP(ResPaths).DataDir).Rebase(dir.FullDir);
else if (_GP(usetup).local_user_conf) // directive to use game dir location
return FSLocation(_GP(ResPaths).DataDir);
@@ -280,30 +280,35 @@ FSLocation GetGameUserConfigDir() {
return dir.Concat(_GP(game).saveGameFolderName);
}
-// A helper function that deduces a data directory either using default system location,
-// or user option from config. In case of a default location a path is appended with
-// game's "save folder" name, which is meant to separate files from different games.
-static FSLocation MakeGameDataDir(const FSLocation &def_dir, const String &user_dir) {
- if (user_dir.IsEmpty()) {
- if (is_relative_filename(def_dir.FullDir.GetCStr())) // relative dir is resolved relative to the game data dir
- return FSLocation(_GP(ResPaths).DataDir).Rebase(def_dir.FullDir);
- // For absolute dir, we assume it's a special directory prepared for AGS engine
- // and therefore amend it with a game's own subdir
- return def_dir.Concat(_GP(game).saveGameFolderName);
- }
- // If this location is set up by user config, then use it as is (resolving relative path if necessary)
- if (Path::IsSameOrSubDir(_GP(ResPaths).DataDir, user_dir)) // check if it's inside game dir
- return FSLocation(_GP(ResPaths).DataDir, Path::MakeRelativePath(_GP(ResPaths).DataDir, user_dir));
- return FSLocation(Path::MakeAbsolutePath(user_dir));
+// Constructs data dir using rules for default system location
+inline FSLocation MakeDefaultDataDir(const FSLocation &def_dir) {
+ // Relative dir is resolved relative to the game data dir
+ if (is_relative_filename(def_dir.FullDir))
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(def_dir.FullDir);
+ // For absolute dir, we assume it's a special directory prepared for AGS engine
+ // and therefore amend it with a game's own subdir (to separate files from different games)
+ return def_dir.Concat(_GP(game).saveGameFolderName);
}
+// Constructs data dir using rules for the user-specified location
+inline FSLocation MakeUserDataDir(const String &user_dir) {
+ // If user-set location is inside game dir, then form a relative path
+ if (is_relative_filename(user_dir))
+ return FSLocation(_GP(ResPaths).DataDir).Rebase(user_dir);
+ // Otherwise treat it as an absolute path
+ return FSLocation(Path::MakeAbsolutePath(user_dir));
+}
FSLocation GetGameAppDataDir() {
- return MakeGameDataDir(_G(platform)->GetAllUsersDataDirectory(), _GP(usetup).shared_data_dir);
+ if (_GP(usetup).shared_data_dir.IsEmpty())
+ return MakeDefaultDataDir(_G(platform)->GetAllUsersDataDirectory());
+ return MakeUserDataDir(_GP(usetup).shared_data_dir);
}
FSLocation GetGameUserDataDir() {
- return MakeGameDataDir(_G(platform)->GetUserSavedgamesDirectory(), _GP(usetup).user_data_dir);
+ if (_GP(usetup).user_data_dir.IsEmpty())
+ return MakeDefaultDataDir(_G(platform)->GetUserSavedgamesDirectory());
+ return MakeUserDataDir(_GP(usetup).user_data_dir);
}
bool ResolveScriptPath(const String &orig_sc_path, bool read_only, ResolvedPath &rp) {
diff --git a/engines/ags/shared/util/string.h b/engines/ags/shared/util/string.h
index a969aae7097..c216506f08c 100644
--- a/engines/ags/shared/util/string.h
+++ b/engines/ags/shared/util/string.h
@@ -423,6 +423,9 @@ public:
operator bool() const {
return !IsEmpty();
}
+ operator const char *() const {
+ return GetCStr();
+ }
private:
// Creates new empty string with buffer enough to fit given length
Commit: 1d92ed73d94fc76c3dea26dadba83489cf7d43f6
https://github.com/scummvm/scummvm/commit/1d92ed73d94fc76c3dea26dadba83489cf7d43f6
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-31T21:34:33-07:00
Commit Message:
AGS: Code rewrite: split SetSaveGameDirectory to make things easier
>From upstream a53c06090a268b8c6dd6aa30369a30db2d3513a7
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/game.h
engines/ags/engine/main/engine.cpp
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index abd2164bae0..a311d7cff46 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -220,11 +220,9 @@ void set_save_game_suffix(const String &suffix) {
_G(saveGameSuffix) = suffix;
}
-#if !AGS_PLATFORM_SCUMMVM
String get_save_game_filename(int slotNum) {
- return String::FromFormat("agssave.%03d%s", slotNum, _G(saveGameSuffix).GetCStr());
+ return String(g_engine->getSaveStateName(slotNum).c_str());
}
-#endif
String get_save_game_path(int slotNum) {
#if AGS_PLATFORM_SCUMMVM
@@ -241,33 +239,32 @@ String get_save_game_path(int slotNum) {
// a dir of a new name. While we let this work, we also try to keep these
// inside same parent location, would that be a common system directory,
// or a custom one set by a player in config.
-bool MakeSaveGameDir(const String &newFolder, FSLocation &fsloc) {
- rp = ResolvedPath();
+static bool MakeSaveGameDir(const String &newFolder, FSLocation &fsdir) {
+ fsdir = FSLocation();
// don't allow absolute paths
if (!is_relative_filename(newFolder))
return false;
- FSLocation fsdir;
String newSaveGameDir = FixSlashAfterToken(newFolder);
if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) {
- if (saveGameParent.IsEmpty()) { // Set this up inside a standard AGS save dir
+ if (_G(saveGameParent).IsEmpty()) { // Set this up inside a standard AGS save dir
fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
fsdir = fsdir.Concat(newSaveGameDir.Mid(UserSavedgamesRootToken.GetLength()));
} else {
// If there is a custom save parent directory, then replace
// not only root token, but also first subdirectory
newSaveGameDir.ClipSection('/', 0, 1); // TODO: Path helper function for this?
- fsdir = FSLocation(saveGameParent).Concat(newSaveGameDir);
+ fsdir = FSLocation(_G(saveGameParent)).Concat(newSaveGameDir);
}
} else {
// Convert the path relative to installation folder into path relative to the
// safe save path with default name
- if (saveGameParent.IsEmpty()) { // Set this up inside a standard AGS save dir
+ if (_G(saveGameParent).IsEmpty()) { // Set this up inside a standard AGS save dir
fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
fsdir = fsdir.Concat(Path::ConcatPaths(game.saveGameFolderName, newFolder));
} else {
- fsdir = FSLocation(saveGameParent).Concat(newFolder);
+ fsdir = FSLocation(_G(saveGameParent)).Concat(newFolder);
}
// For games made in the safe-path-aware versions of AGS, report a warning
if (game.options[OPT_SAFEFILEPATHS]) {
@@ -275,47 +272,24 @@ bool MakeSaveGameDir(const String &newFolder, FSLocation &fsloc) {
newFolder.GetCStr(), fsdir.FullDir.GetCStr());
}
}
- rp.BaseDir = fsdir.BaseDir;
- rp.FullPath = fsdir.FullDir;
+
return true;
}
#endif
-bool SetCustomSaveParent(const String &path) {
- if (SetSaveGameDirectoryPath(path, true)) {
- _G(saveGameParent) = path;
- return true;
- }
- return false;
-}
-
-bool SetSaveGameDirectoryPath(const String &newFolder, bool explicit_path) {
-#if AGS_PLATFORM_SCUMMVM
- return false;
-#else
- String newFolder = new_dir.IsEmpty() ? "." : new_dir;
- String newSaveGameDir;
- if (explicit_path) {
- newSaveGameDir = PathFromInstallDir(newFolder);
- if (!Directory::CreateDirectory(newSaveGameDir))
- return false;
- } else {
- FSLocation fsloc;
- if (!MakeSaveGameDir(newFolder, fsloc))
- return false;
- if (!Directory::CreateAllDirectories(fsloc.BaseDir, fsloc.SubDir)) {
- debug_script_warn("SetSaveGameDirectory: failed to create all subdirectories: %s", fsloc.FullDir.GetCStr());
- return false;
- }
- newSaveGameDir = fsloc.FullDir;
+// Tries to assign a new save directory, and copies the restart point if available
+static bool SetSaveGameDirectory(const FSLocation &fsdir) {
+ if (!Directory::CreateAllDirectories(fsdir.BaseDir, fsdir.FullDir)) {
+ debug_script_warn("SetSaveGameDirectory: failed to create all subdirectories: %s", fsdir.FullDir.GetCStr());
+ return false;
}
+ String newSaveGameDir = fsdir.FullDir;
- String newFolderTempFile = Path::ConcatPaths(newSaveGameDir, "agstmp.tmp");
- if (!File::TestCreateFile(newFolderTempFile))
+ if (!File::TestCreateFile(Path::ConcatPaths(newSaveGameDir, "agstmp.tmp")))
return false;
// copy the Restart Game file, if applicable
- String restartGamePath = Path::ConcatPaths(saveGameDirectory, get_save_game_filename(RESTART_POINT_SAVE_GAME_NUMBER));
+ String restartGamePath = Path::ConcatPaths(_G(saveGameDirectory), get_save_game_filename(RESTART_POINT_SAVE_GAME_NUMBER));
Stream *restartGameFile = File::OpenFileRead(restartGamePath);
if (restartGameFile != nullptr) {
long fileSize = restartGameFile->GetLength();
@@ -330,15 +304,34 @@ bool SetSaveGameDirectoryPath(const String &newFolder, bool explicit_path) {
free(mbuffer);
}
- saveGameDirectory = newSaveGameDir;
+ _G(saveGameDirectory) = newSaveGameDir;
return true;
-#endif
}
-int Game_SetSaveGameDirectory(const String &newFolder) {
- return SetSaveGameDirectoryPath(newFolder, false) ? 1 : 0;
+void SetDefaultSaveDirectory() {
+ // If user set a custom save dir, also keep it as a "save root", in case
+ // the game script uses Game.SetSaveGameDirectory().
+ if (!_GP(usetup).user_data_dir.IsEmpty())
+ _G(saveGameParent) = _GP(usetup).user_data_dir;
+ // Request a default save location, and assign it as a save dir
+ FSLocation fsdir = GetGameUserDataDir();
+ SetSaveGameDirectory(fsdir);
+}
+
+int Game_SetSaveGameDirectory(const char *newFolder) {
+#if AGS_PLATFORM_SCUMMVM
+ return 1;
+#else
+ // First resolve the script path (it may contain tokens)
+ FSLocation fsdir;
+ if (!MakeSaveGameDir(newFolder, fsdir))
+ return 0;
+ // If resolved successfully, try to assign the new dir
+ return SetSaveGameDirectory(fsdir) ? 1 : 0;
+#endif
}
+
const char *Game_GetSaveSlotDescription(int slnum) {
String description;
if (read_savedgame_description(get_save_game_path(slnum), description)) {
diff --git a/engines/ags/engine/ac/game.h b/engines/ags/engine/ac/game.h
index 3fa76848152..6f50abc49b0 100644
--- a/engines/ags/engine/ac/game.h
+++ b/engines/ags/engine/ac/game.h
@@ -90,13 +90,10 @@ int Game_GetMODPattern();
//=============================================================================
int Game_GetDialogCount();
-// Defines a custom save parent directory, which will replace $MYDOCS$/GameName
-// when a new save directory is set from the script
-bool SetCustomSaveParent(const Shared::String &path);
-// If explicit_path flag is false, the actual path will be constructed
-// as a relative to system's user saves directory
-bool SetSaveGameDirectoryPath(const Shared::String &newFolder, bool explicit_path = false);
-int Game_SetSaveGameDirectory(const Shared::String &newFolder);
+// Sets a default save directory, based on platform driver settings and user config
+void SetDefaultSaveDirectory();
+// Sets a new save directory within the save parent; copies "restart" slot if available
+int Game_SetSaveGameDirectory(const char *newFolder);
const char *Game_GetSaveSlotDescription(int slnum);
const char *Game_GetGlobalStrings(int index);
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 384daf60476..3266515a786 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -411,19 +411,8 @@ void engine_init_user_directories() {
if (!_GP(usetup).shared_data_dir.IsEmpty())
Debug::Printf(kDbgMsg_Info, "Shared data directory: %s", _GP(usetup).shared_data_dir.GetCStr());
- // if end-user specified custom save path, use it
- bool res = false;
- if (!_GP(usetup).user_data_dir.IsEmpty()) {
- res = SetCustomSaveParent(_GP(usetup).user_data_dir);
- if (!res) {
- Debug::Printf(kDbgMsg_Warn, "WARNING: custom user save path failed, using default system paths");
- res = false;
- }
- }
- // if there is no custom path, or if custom path failed, use default system path
- if (!res) {
- SetSaveGameDirectoryPath(Path::ConcatPaths(UserSavedgamesRootToken, _GP(game).saveGameFolderName));
- }
+ // Initialize default save directory early, for we'll need it to set restart point
+ SetDefaultSaveDirectory();
}
#if AGS_PLATFORM_OS_ANDROID
Commit: 18f2ab00cdbb90a02983f3d9850fb7a19784e0c4
https://github.com/scummvm/scummvm/commit/18f2ab00cdbb90a02983f3d9850fb7a19784e0c4
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-31T21:43:00-07:00
Commit Message:
AGS: Fixed and simplified MakeSaveGameDir() to match recent changes
>From upstream 133843b5c1eef7b8614532be9b62d6a8809069db
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index a311d7cff46..144a2756ab7 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -239,40 +239,22 @@ String get_save_game_path(int slotNum) {
// a dir of a new name. While we let this work, we also try to keep these
// inside same parent location, would that be a common system directory,
// or a custom one set by a player in config.
-static bool MakeSaveGameDir(const String &newFolder, FSLocation &fsdir) {
+static bool MakeSaveGameDir(const String &new_dir, FSLocation &fsdir) {
fsdir = FSLocation();
// don't allow absolute paths
- if (!is_relative_filename(newFolder))
+ if (!is_relative_filename(new_dir))
return false;
- String newSaveGameDir = FixSlashAfterToken(newFolder);
-
- if (newSaveGameDir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) {
- if (_G(saveGameParent).IsEmpty()) { // Set this up inside a standard AGS save dir
- fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
- fsdir = fsdir.Concat(newSaveGameDir.Mid(UserSavedgamesRootToken.GetLength()));
- } else {
- // If there is a custom save parent directory, then replace
- // not only root token, but also first subdirectory
- newSaveGameDir.ClipSection('/', 0, 1); // TODO: Path helper function for this?
- fsdir = FSLocation(_G(saveGameParent)).Concat(newSaveGameDir);
- }
- } else {
- // Convert the path relative to installation folder into path relative to the
- // safe save path with default name
- if (_G(saveGameParent).IsEmpty()) { // Set this up inside a standard AGS save dir
- fsdir = PathFromInstallDir(platform->GetUserSavedgamesDirectory());
- fsdir = fsdir.Concat(Path::ConcatPaths(game.saveGameFolderName, newFolder));
- } else {
- fsdir = FSLocation(_G(saveGameParent)).Concat(newFolder);
- }
- // For games made in the safe-path-aware versions of AGS, report a warning
- if (game.options[OPT_SAFEFILEPATHS]) {
- debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'",
- newFolder.GetCStr(), fsdir.FullDir.GetCStr());
- }
+ String fixed_newdir = FixSlashAfterToken(new_dir);
+ if (fixed_newdir.CompareLeft(UserSavedgamesRootToken, UserSavedgamesRootToken.GetLength()) == 0) {
+ fixed_newdir.ClipLeft(UserSavedgamesRootToken.GetLength());
+ } else if (game.options[OPT_SAFEFILEPATHS] > 0) { // For games made in the safe-path-aware versions of AGS, report a warning
+ debug_script_warn("Attempt to explicitly set savegame location relative to the game installation directory ('%s') denied;\nPath will be remapped to the user documents directory: '%s'",
+ fixed_newdir.GetCStr(), fsdir.FullDir.GetCStr());
}
+ // Resolve the new dir relative to the user data parent dir
+ fsdir = GetGameUserDataDir().Concat(fixed_newdir);
return true;
}
#endif
@@ -309,10 +291,6 @@ static bool SetSaveGameDirectory(const FSLocation &fsdir) {
}
void SetDefaultSaveDirectory() {
- // If user set a custom save dir, also keep it as a "save root", in case
- // the game script uses Game.SetSaveGameDirectory().
- if (!_GP(usetup).user_data_dir.IsEmpty())
- _G(saveGameParent) = _GP(usetup).user_data_dir;
// Request a default save location, and assign it as a save dir
FSLocation fsdir = GetGameUserDataDir();
SetSaveGameDirectory(fsdir);
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index e8ccca6985f..5830cc6b5f7 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -754,7 +754,6 @@ public:
MoveList *_mls = nullptr;
GameSetup *_usetup;
AGS::Shared::String _saveGameDirectory;
- AGS::Shared::String _saveGameParent;
AGS::Shared::String _saveGameSuffix;
bool _want_exit = false;
bool _abort_engine = false;
More information about the Scummvm-git-logs
mailing list