Permalink
Browse files

Made the game follow standards for the settings and the save games.

I also created two functions copying the files from their old locations
so people won't worry about it.
I tested this both on windows and linux, OSX wasn't actually
impacted by the change.

I also made the game setup the stting and user data path only once,
not on each requests.

On unices, now the save games will be at ~/.local/share/valyriatear
and the settings in ~/.config/valyriatear

And on windows, both will in:
Documents and Settings\User\Application Data\ValyriaTear

Closes #9
  • Loading branch information...
1 parent 7b2676a commit c661263bd6554f40177fba76b669fa6e9912cfc1 Yohann Ferreira committed Mar 27, 2013
Showing with 231 additions and 34 deletions.
  1. +1 −1 src/engine/input.cpp
  2. +1 −1 src/engine/video/texture_controller.cpp
  3. +1 −1 src/main.cpp
  4. +3 −3 src/modes/boot/boot.cpp
  5. +3 −3 src/modes/save/save_mode.cpp
  6. +216 −18 src/utils.cpp
  7. +6 −7 src/utils.h
View
@@ -298,7 +298,7 @@ void InputEngine::_KeyEventHandler(SDL_KeyboardEvent &key_event)
static uint32 i = 1;
std::string path = "";
while(true) {
- path = hoa_utils::GetUserDataPath(true) + "screenshot_" + NumberToString<uint32>(i) + ".jpg";
+ path = hoa_utils::GetUserDataPath() + "screenshot_" + NumberToString<uint32>(i) + ".jpg";
if(!DoesFileExist(path))
break;
i++;
@@ -338,7 +338,7 @@ bool TextureController::_SaveTempTextures()
IF_PRINT_DEBUG(VIDEO_DEBUG) << " saving temporary texture " << image->filename << std::endl;
ImageMemory buffer;
buffer.CopyFromImage(image);
- std::string path = GetUserDataPath(true);
+ std::string path = GetUserDataPath();
if(buffer.SaveImage(path + image->filename + ".png", true) == false) {
success = false;
IF_PRINT_WARNING(VIDEO_DEBUG) << "call to ImageMemory::SaveImage() failed" << std::endl;
View
@@ -502,7 +502,7 @@ int main(int argc, char *argv[])
// Now the program should be in app/Contents
path.append("/Resources/");
chdir(path.c_str());
-#elif (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && !defined(RELEASE_BUILD)
+#elif (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(SOLARIS)) && !defined(RELEASE_BUILD)
// Look for data files in DATADIR only if they are not available in the current directory.
if(std::ifstream("dat/config/settings.lua") == NULL) {
if(chdir(PKG_DATADIR) != 0) {
View
@@ -415,7 +415,7 @@ bool BootMode::_SavesAvailable(int32 maxId)
{
assert(maxId > 0);
int32 savesAvailable = 0;
- std::string data_path = GetUserDataPath(true);
+ std::string data_path = GetUserDataPath();
for(int id = 0; id < maxId; ++id) {
std::ostringstream f;
f << data_path + "saved_game_" << id << ".lua";
@@ -1075,12 +1075,12 @@ bool BootMode::_SaveSettingsFile(const std::string &filename)
std::string fileTemp;
// Load the settings file for reading in the original data
- fileTemp = GetUserDataPath(false) + "/settings.lua";
+ fileTemp = GetUserConfigPath() + "/settings.lua";
if(filename.empty())
file = fileTemp;
else
- file = GetUserDataPath(false) + "/" + filename;
+ file = GetUserConfigPath() + "/" + filename;
//copy the default file so we have an already set up lua file and then we can modify its settings
if(!DoesFileExist(file))
@@ -258,7 +258,7 @@ void SaveMode::Update()
// do not change unless you understand this and can test it properly!
uint32 id = (uint32)_file_list.GetSelection();
std::ostringstream f;
- f << GetUserDataPath(true) + "saved_game_" << id << ".lua";
+ f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str();
// now, attempt to save the game. If failure, we need to tell the user that!
if(GlobalManager->SaveGame(filename, id, _x_position, _y_position)) {
@@ -411,7 +411,7 @@ void SaveMode::DrawPostEffects()
bool SaveMode::_LoadGame(uint32 id)
{
std::ostringstream f;
- f << GetUserDataPath(true) + "saved_game_" << id << ".lua";
+ f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str();
if(DoesFileExist(filename)) {
@@ -460,7 +460,7 @@ void SaveMode::_ClearSaveData(bool selected_file_exists)
bool SaveMode::_PreviewGame(uint32 id)
{
std::ostringstream f;
- f << GetUserDataPath(true) + "saved_game_" << id << ".lua";
+ f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str();
// Check for the file existence, prevents a useless warning
View
@@ -856,45 +856,152 @@ bool DeleteFile(const std::string &filename)
return false;
}
+// Copy old save files from ~/.valyriatear to new path on unices
+// And from the personal folder to the destination on Windows.
+//! \DEPRECATED: Remove this in one or two releases.
+static void _CopyOldSaveFiles(const std::string &destination_path)
+{
+ if(!DoesFileExist(destination_path)) {
+ PRINT_WARNING << "No valid destination path given: " << destination_path
+ << std::endl << "Can't copy old save files." << std::endl;
+ return;
+ }
+
+#if (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(SOLARIS))
+ // We assume the old save files are in ~/.valyriatear
+ passwd *pw = getpwuid(getuid());
+ if(!pw)
+ return;
+ std::string old_path = std::string(pw->pw_dir) + "/."APPSHORTNAME"/";
+ if(!DoesFileExist(old_path))
+ return; // Nothing to do.
+#elif defined _WIN32
+ TCHAR path[MAX_PATH];
+ // %USERPROFILE%\My Documents
+ if(!(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path))))
+ return; // No folder, nothing to do.
+ std::string old_path = std::string(path) + "/"APPUPCASEDIRNAME"/";
+ if(!DoesFileExist(old_path))
+ return; // nothing to do
+#endif
-#if defined __MACH__
-const std::string GetUserDataPath(bool user_files)
-{
-#else
-const std::string GetUserDataPath(bool /*user_files*/)
+#ifndef __MACH__
+ for (uint32 i = 0; i < 6; ++i) {
+ std::stringstream save_filename;
+ save_filename << "saved_game_" << i << ".lua";
+ std::string old_file = old_path + save_filename.str();
+
+ if(!DoesFileExist(old_file))
+ return; // Nothing to do.
+
+ std::string new_filename = destination_path + save_filename.str();
+
+ if (!MoveFile(old_file, new_filename))
+ PRINT_WARNING << "Couldn't move the save file ('" << save_filename.str() << "') to new location!" << std::endl;
+
+ PRINT_WARNING << "Moved " << save_filename.str() << " file from: " << old_file << std::endl
+ << "to: " << new_filename << std::endl;
+ }
+#endif
+}
+
+// Copy old save files from ~/.valyriatear to new path on unices
+// And from the personal folder to the destination on Windows.
+//! \DEPRECATED: Remove this in one or two releases.
+static void _CopyOldSettingsFile(const std::string &destination_path)
{
+ if(!DoesFileExist(destination_path)) {
+ PRINT_WARNING << "No valid destination path given: " << destination_path
+ << std::endl << "Can't copy old settings file." << std::endl;
+ return;
+ }
+
+#if (defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(SOLARIS))
+ // We assume the old settings.lua file is in ~/.valyriatear
+ passwd *pw = getpwuid(getuid());
+ if(!pw)
+ return; // Nothing to do
+
+ std::string old_file = std::string(pw->pw_dir) + "/."APPSHORTNAME"/settings.lua";
+ if(!DoesFileExist(old_file))
+ return; // Nothing to do.
+
+#elif defined _WIN32
+ TCHAR path[MAX_PATH];
+ // %USERPROFILE%\My Documents
+ if(!(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path))))
+ return; // No folder, nothing to do.
+
+ std::string old_file = std::string(path) + "/"APPUPCASEDIRNAME"/settings.lua";
+ if(!DoesFileExist(old_file))
+ return; // nothing to do
+#endif
+#ifndef __MACH__
+ std::string new_filename = destination_path + "settings.lua";
+
+ if (!MoveFile(old_file, new_filename))
+ PRINT_WARNING << "Couldn't move the settings file to new location!" << std::endl;
+
+ PRINT_WARNING << "Moved settings.lua file from: " << old_file << std::endl
+ << "to: " << new_filename << std::endl;
#endif
+}
+
+//! \brief Finds the OS specific directory path to save and retrieve user data
+static const std::string _SetupUserDataPath()
+{
#if defined _WIN32
TCHAR path[MAX_PATH];
-
- if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path))) {
+ // %APPDATA% (%USERPROFILE%\Application Data)
+ if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path))) {
std::string user_path = std::string(path) + "/"APPUPCASEDIRNAME"/";
- if(DoesFileExist(user_path) == false)
+ if(!DoesFileExist(user_path))
MakeDirectory(user_path);
+
+ _CopyOldSaveFiles(user_path);
+
return user_path;
}
#elif defined __MACH__
passwd *pw = getpwuid(getuid());
if(pw) {
- std::string path = "";
- if(user_files)
- path = std::string(pw->pw_dir) + "/Library/Application Support/"APPUPCASEDIRNAME"/";
- else
- path = std::string(pw->pw_dir) + "/Library/Preferences/"APPUPCASEDIRNAME"/";
- if(DoesFileExist(path) == false)
+ std::string path = std::string(pw->pw_dir) + "/Library/Application Support/"APPUPCASEDIRNAME"/";
+ if(!DoesFileExist(path))
MakeDirectory(path);
return path;
}
#else // Linux, BSD, other POSIX systems
+ // Implementation of the freedesktop specs (at least partially)
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+ // $XDG_DATA_HOME/valyriatear/
+ // equals to: ~/.local/share/valyriatear/ most of the time
+ if (getenv("XDG_DATA_HOME")) {
+ std::string path = std::string(getenv("XDG_DATA_HOME")) + "/"APPSHORTNAME"/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ _CopyOldSaveFiles(path);
+
+ return path;
+ }
+ // We create a sane default: ~/.local/share/valyriatear
passwd *pw = getpwuid(getuid());
if(pw) {
- std::string path = std::string(pw->pw_dir) + "/."APPSHORTNAME"/";
- if(DoesFileExist(path) == false)
+ std::string path = std::string(pw->pw_dir) + "/.local/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ path += "/share/";
+ if(!DoesFileExist(path))
MakeDirectory(path);
+ path += "/"APPSHORTNAME"/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ _CopyOldSaveFiles(path);
+
return path;
}
#endif
@@ -905,9 +1012,71 @@ const std::string GetUserDataPath(bool /*user_files*/)
return "dat/";
}
-const std::string GetSettingsFilename()
+//! \brief Finds the OS specific directory path to save and retrieve user config data
+static const std::string _SetupUserConfigPath()
+{
+#if defined _WIN32
+ TCHAR path[MAX_PATH];
+ // %APPDATA% (%USERPROFILE%\Application Data)
+ if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path))) {
+ std::string user_path = std::string(path) + "/"APPUPCASEDIRNAME"/";
+ if(!DoesFileExist(user_path))
+ MakeDirectory(user_path);
+ _CopyOldSettingsFile(user_path);
+ return user_path;
+ }
+
+#elif defined __MACH__
+ passwd *pw = getpwuid(getuid());
+ if(pw) {
+ std::string path = std::string(pw->pw_dir) + "/Library/Preferences/"APPUPCASEDIRNAME"/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ return path;
+ }
+
+#else // Linux, BSD, other POSIX systems
+ // Implementation of the freedesktop specs (at least partially)
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+ // $XDG_CONFIG_HOME/valyriatear/
+ // equals to: ~/.config/valyriatear/ most of the time
+ if (getenv("XDG_CONFIG_HOME")) {
+ std::string path = std::string(getenv("XDG_CONFIG_HOME")) + "/"APPSHORTNAME"/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ _CopyOldSettingsFile(path);
+
+ return path;
+ }
+
+ // We create a sane default: ~/.config/valyriatear
+ passwd *pw = getpwuid(getuid());
+ if(pw) {
+ std::string path = std::string(pw->pw_dir) + "/.config/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ path += "/"APPSHORTNAME"/";
+ if(!DoesFileExist(path))
+ MakeDirectory(path);
+ _CopyOldSettingsFile(path);
+
+ return path;
+ }
+#endif
+
+ // Default path if a specific solution could not be found. Note that this path may
+ // not be writable by the user since it could be installed in administrator/root space
+ PRINT_WARNING << "could not idenfity user config path, defaulting to system path" << std::endl;
+ return "dat/";
+}
+
+/** \brief Retrieves the path and filename of the settings file to use
+*** \return A string with the settings filename, or an empty string if the settings file could not be found
+**/
+static const std::string _SetupSettingsFilename()
{
- std::string settings_file = GetUserDataPath(false) + "/settings.lua";
+ std::string settings_file = GetUserConfigPath() + "settings.lua";
if(!DoesFileExist(settings_file)) {
settings_file = "dat/config/settings.lua";
if(!DoesFileExist(settings_file))
@@ -917,4 +1086,33 @@ const std::string GetSettingsFilename()
return settings_file;
}
+// Static variables storing the user data and config paths
+static std::string _data_path;
+static std::string _config_path;
+static std::string _config_filename;
+
+const std::string GetUserDataPath()
+{
+ if (_data_path.empty())
+ _data_path = _SetupUserDataPath();
+
+ return _data_path;
+}
+
+const std::string GetUserConfigPath()
+{
+ if (_config_path.empty())
+ _config_path = _SetupUserConfigPath();
+
+ return _config_path;
+}
+
+const std::string GetSettingsFilename()
+{
+ if (_config_filename.empty())
+ _config_filename = _SetupSettingsFilename();
+
+ return _config_filename;
+}
+
} // namespace utils
View
@@ -697,14 +697,13 @@ bool DeleteFile(const std::string &filename);
//! \name User directory and settings paths
//@{
-/** \brief Finds the OS specific directory path to save and retrieve user data
-*** \param user_files If true, retrieves the path for user created content files. If false,
-*** retrieves the path for application settings. Default value is true.
-*** \note Only OS X systems make any use of the user_files parameter.
-**/
-const std::string GetUserDataPath(bool user_files = true);
+//! \brief Gives the OS specific directory path to save and retrieve user data
+const std::string GetUserDataPath();
+
+//! \brief Gives the OS specific directory path to save and retrieve user config data
+const std::string GetUserConfigPath();
-/** \brief Retrieves the path and filename of the settings file to use
+/** \brief Gives the path and filename of the settings file to use
*** \return A string with the settings filename, or an empty string if the settings file could not be found
**/
const std::string GetSettingsFilename();

0 comments on commit c661263

Please sign in to comment.