Skip to content

Commit

Permalink
Made the game follow standards for the settings and the save games.
Browse files Browse the repository at this point in the history
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
Yohann Ferreira committed Mar 27, 2013
1 parent 7b2676a commit c661263
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/engine/input.cpp
Expand Up @@ -298,7 +298,7 @@ void InputEngine::_KeyEventHandler(SDL_KeyboardEvent &key_event)
static uint32 i = 1; static uint32 i = 1;
std::string path = ""; std::string path = "";
while(true) { while(true) {
path = hoa_utils::GetUserDataPath(true) + "screenshot_" + NumberToString<uint32>(i) + ".jpg"; path = hoa_utils::GetUserDataPath() + "screenshot_" + NumberToString<uint32>(i) + ".jpg";
if(!DoesFileExist(path)) if(!DoesFileExist(path))
break; break;
i++; i++;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/video/texture_controller.cpp
Expand Up @@ -338,7 +338,7 @@ bool TextureController::_SaveTempTextures()
IF_PRINT_DEBUG(VIDEO_DEBUG) << " saving temporary texture " << image->filename << std::endl; IF_PRINT_DEBUG(VIDEO_DEBUG) << " saving temporary texture " << image->filename << std::endl;
ImageMemory buffer; ImageMemory buffer;
buffer.CopyFromImage(image); buffer.CopyFromImage(image);
std::string path = GetUserDataPath(true); std::string path = GetUserDataPath();
if(buffer.SaveImage(path + image->filename + ".png", true) == false) { if(buffer.SaveImage(path + image->filename + ".png", true) == false) {
success = false; success = false;
IF_PRINT_WARNING(VIDEO_DEBUG) << "call to ImageMemory::SaveImage() failed" << std::endl; IF_PRINT_WARNING(VIDEO_DEBUG) << "call to ImageMemory::SaveImage() failed" << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Expand Up @@ -502,7 +502,7 @@ int main(int argc, char *argv[])
// Now the program should be in app/Contents // Now the program should be in app/Contents
path.append("/Resources/"); path.append("/Resources/");
chdir(path.c_str()); 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. // 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(std::ifstream("dat/config/settings.lua") == NULL) {
if(chdir(PKG_DATADIR) != 0) { if(chdir(PKG_DATADIR) != 0) {
Expand Down
6 changes: 3 additions & 3 deletions src/modes/boot/boot.cpp
Expand Up @@ -415,7 +415,7 @@ bool BootMode::_SavesAvailable(int32 maxId)
{ {
assert(maxId > 0); assert(maxId > 0);
int32 savesAvailable = 0; int32 savesAvailable = 0;
std::string data_path = GetUserDataPath(true); std::string data_path = GetUserDataPath();
for(int id = 0; id < maxId; ++id) { for(int id = 0; id < maxId; ++id) {
std::ostringstream f; std::ostringstream f;
f << data_path + "saved_game_" << id << ".lua"; f << data_path + "saved_game_" << id << ".lua";
Expand Down Expand Up @@ -1075,12 +1075,12 @@ bool BootMode::_SaveSettingsFile(const std::string &filename)
std::string fileTemp; std::string fileTemp;


// Load the settings file for reading in the original data // Load the settings file for reading in the original data
fileTemp = GetUserDataPath(false) + "/settings.lua"; fileTemp = GetUserConfigPath() + "/settings.lua";


if(filename.empty()) if(filename.empty())
file = fileTemp; file = fileTemp;
else 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 //copy the default file so we have an already set up lua file and then we can modify its settings
if(!DoesFileExist(file)) if(!DoesFileExist(file))
Expand Down
6 changes: 3 additions & 3 deletions src/modes/save/save_mode.cpp
Expand Up @@ -258,7 +258,7 @@ void SaveMode::Update()
// do not change unless you understand this and can test it properly! // do not change unless you understand this and can test it properly!
uint32 id = (uint32)_file_list.GetSelection(); uint32 id = (uint32)_file_list.GetSelection();
std::ostringstream f; std::ostringstream f;
f << GetUserDataPath(true) + "saved_game_" << id << ".lua"; f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str(); std::string filename = f.str();
// now, attempt to save the game. If failure, we need to tell the user that! // now, attempt to save the game. If failure, we need to tell the user that!
if(GlobalManager->SaveGame(filename, id, _x_position, _y_position)) { if(GlobalManager->SaveGame(filename, id, _x_position, _y_position)) {
Expand Down Expand Up @@ -411,7 +411,7 @@ void SaveMode::DrawPostEffects()
bool SaveMode::_LoadGame(uint32 id) bool SaveMode::_LoadGame(uint32 id)
{ {
std::ostringstream f; std::ostringstream f;
f << GetUserDataPath(true) + "saved_game_" << id << ".lua"; f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str(); std::string filename = f.str();


if(DoesFileExist(filename)) { if(DoesFileExist(filename)) {
Expand Down Expand Up @@ -460,7 +460,7 @@ void SaveMode::_ClearSaveData(bool selected_file_exists)
bool SaveMode::_PreviewGame(uint32 id) bool SaveMode::_PreviewGame(uint32 id)
{ {
std::ostringstream f; std::ostringstream f;
f << GetUserDataPath(true) + "saved_game_" << id << ".lua"; f << GetUserDataPath() + "saved_game_" << id << ".lua";
std::string filename = f.str(); std::string filename = f.str();


// Check for the file existence, prevents a useless warning // Check for the file existence, prevents a useless warning
Expand Down
234 changes: 216 additions & 18 deletions src/utils.cpp
Expand Up @@ -856,45 +856,152 @@ bool DeleteFile(const std::string &filename)
return false; 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__ #ifndef __MACH__
const std::string GetUserDataPath(bool user_files) for (uint32 i = 0; i < 6; ++i) {
{ std::stringstream save_filename;
#else save_filename << "saved_game_" << i << ".lua";
const std::string GetUserDataPath(bool /*user_files*/) 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 #endif
}

//! \brief Finds the OS specific directory path to save and retrieve user data
static const std::string _SetupUserDataPath()
{
#if defined _WIN32 #if defined _WIN32
TCHAR path[MAX_PATH]; TCHAR path[MAX_PATH];

// %APPDATA% (%USERPROFILE%\Application Data)
if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path))) { if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, path))) {
std::string user_path = std::string(path) + "/"APPUPCASEDIRNAME"/"; std::string user_path = std::string(path) + "/"APPUPCASEDIRNAME"/";
if(DoesFileExist(user_path) == false) if(!DoesFileExist(user_path))
MakeDirectory(user_path); MakeDirectory(user_path);

_CopyOldSaveFiles(user_path);

return user_path; return user_path;
} }


#elif defined __MACH__ #elif defined __MACH__
passwd *pw = getpwuid(getuid()); passwd *pw = getpwuid(getuid());
if(pw) { if(pw) {
std::string path = ""; std::string path = std::string(pw->pw_dir) + "/Library/Application Support/"APPUPCASEDIRNAME"/";
if(user_files) if(!DoesFileExist(path))
path = std::string(pw->pw_dir) + "/Library/Application Support/"APPUPCASEDIRNAME"/";
else
path = std::string(pw->pw_dir) + "/Library/Preferences/"APPUPCASEDIRNAME"/";
if(DoesFileExist(path) == false)
MakeDirectory(path); MakeDirectory(path);
return path; return path;
} }


#else // Linux, BSD, other POSIX systems #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()); passwd *pw = getpwuid(getuid());
if(pw) { if(pw) {
std::string path = std::string(pw->pw_dir) + "/."APPSHORTNAME"/"; std::string path = std::string(pw->pw_dir) + "/.local/";
if(DoesFileExist(path) == false) if(!DoesFileExist(path))
MakeDirectory(path);
path += "/share/";
if(!DoesFileExist(path))
MakeDirectory(path); MakeDirectory(path);
path += "/"APPSHORTNAME"/";
if(!DoesFileExist(path))
MakeDirectory(path);
_CopyOldSaveFiles(path);

return path; return path;
} }
#endif #endif
Expand All @@ -905,9 +1012,71 @@ const std::string GetUserDataPath(bool /*user_files*/)
return "dat/"; 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)) { if(!DoesFileExist(settings_file)) {
settings_file = "dat/config/settings.lua"; settings_file = "dat/config/settings.lua";
if(!DoesFileExist(settings_file)) if(!DoesFileExist(settings_file))
Expand All @@ -917,4 +1086,33 @@ const std::string GetSettingsFilename()
return settings_file; 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 } // namespace utils
13 changes: 6 additions & 7 deletions src/utils.h
Expand Up @@ -697,14 +697,13 @@ bool DeleteFile(const std::string &filename);


//! \name User directory and settings paths //! \name User directory and settings paths
//@{ //@{
/** \brief Finds the OS specific directory path to save and retrieve user data //! \brief Gives 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, const std::string GetUserDataPath();
*** retrieves the path for application settings. Default value is true.
*** \note Only OS X systems make any use of the user_files parameter. //! \brief Gives the OS specific directory path to save and retrieve user config data
**/ const std::string GetUserConfigPath();
const std::string GetUserDataPath(bool user_files = true);


/** \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 *** \return A string with the settings filename, or an empty string if the settings file could not be found
**/ **/
const std::string GetSettingsFilename(); const std::string GetSettingsFilename();
Expand Down

0 comments on commit c661263

Please sign in to comment.