static char *getScoreDir(char *level_subdir)
{
static char *score_dir = NULL;
- char *data_dir = getCommonDataDir();
+ static char *score_level_dir = NULL;
char *score_subdir = SCORES_DIRECTORY;
- checked_free(score_dir);
+ if (score_dir == NULL)
+ {
+ if (program.global_scores)
+ score_dir = getPath2(getCommonDataDir(), score_subdir);
+ else
+ score_dir = getPath2(getUserGameDataDir(), score_subdir);
+ }
if (level_subdir != NULL)
- score_dir = getPath3(data_dir, score_subdir, level_subdir);
- else
- score_dir = getPath2(data_dir, score_subdir);
+ {
+ checked_free(score_level_dir);
+
+ score_level_dir = getPath2(score_dir, level_subdir);
+
+ return score_level_dir;
+ }
return score_dir;
}
return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
}
+char *getProgramConfigFilename(char *command_filename_ptr)
+{
+ char *command_filename_1 = getStringCopy(command_filename_ptr);
+
+ // strip trailing executable suffix from command filename
+ if (strSuffix(command_filename_1, ".exe"))
+ command_filename_1[strlen(command_filename_1) - 4] = '\0';
+
+ char *command_basepath = getBasePath(command_filename_ptr);
+ char *command_basename = getBaseNameNoSuffix(command_filename_ptr);
+ char *command_filename_2 = getPath2(command_basepath, command_basename);
+
+ char *config_filename_1 = getStringCat2(command_filename_1, ".conf");
+ char *config_filename_2 = getStringCat2(command_filename_2, ".conf");
+
+ // 1st try: look for config file that exactly matches the binary filename
+ if (fileExists(config_filename_1))
+ return config_filename_1;
+
+ // 2nd try: return config filename that matches binary filename without suffix
+ return config_filename_2;
+}
+
char *getTapeFilename(int nr)
{
static char *filename = NULL;
return filename;
}
+char *getDefaultSetupFilename()
+{
+ return program.config_filename;
+}
+
char *getEditorSetupFilename()
{
static char *filename = NULL;
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(GFX_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getImg2(options.graphics_directory, GFX_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getImg2(options.graphics_directory, GFX_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(SND_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getPath2(options.sounds_directory, SND_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getPath2(options.sounds_directory, SND_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
if (fileExists(filename))
return filename;
-#if defined(CREATE_SPECIAL_EDITION)
- free(filename);
+ if (!strEqual(MUS_FALLBACK_FILENAME, UNDEFINED_FILENAME))
+ {
+ free(filename);
- if (options.debug)
- Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)", basename);
+ if (options.debug)
+ Error(ERR_WARN, "cannot find artwork file '%s' (using fallback)",
+ basename);
- /* 6th try: look for fallback artwork in old default artwork directory */
- /* (needed to prevent errors when trying to access unused artwork files) */
- filename = getPath2(options.music_directory, MUS_FALLBACK_FILENAME);
- if (fileExists(filename))
- return filename;
-#endif
+ /* 6th try: look for fallback artwork in old default artwork directory */
+ /* (needed to prevent errors when trying to access unused artwork files) */
+ filename = getPath2(options.music_directory, MUS_FALLBACK_FILENAME);
+ if (fileExists(filename))
+ return filename;
+ }
return NULL; /* cannot find specified artwork file anywhere */
}
void InitScoreDirectory(char *level_subdir)
{
- createDirectory(getCommonDataDir(), "common data", PERMS_PUBLIC);
- createDirectory(getScoreDir(NULL), "main score", PERMS_PUBLIC);
- createDirectory(getScoreDir(level_subdir), "level score", PERMS_PUBLIC);
+ int permissions = (program.global_scores ? PERMS_PUBLIC : PERMS_PRIVATE);
+
+ if (program.global_scores)
+ createDirectory(getCommonDataDir(), "common data", permissions);
+ else
+ createDirectory(getUserGameDataDir(), "user data", permissions);
+
+ createDirectory(getScoreDir(NULL), "main score", permissions);
+ createDirectory(getScoreDir(level_subdir), "level score", permissions);
}
static void SaveUserLevelInfo();
#define MODE_X_ALL (S_IXUSR | S_IXGRP | S_IXOTH)
#define MODE_W_PRIVATE (S_IWUSR)
-#define MODE_W_PUBLIC (S_IWUSR | S_IWGRP)
+#define MODE_W_PUBLIC_FILE (S_IWUSR | S_IWGRP)
#define MODE_W_PUBLIC_DIR (S_IWUSR | S_IWGRP | S_ISGID)
#define DIR_PERMS_PRIVATE (MODE_R_ALL | MODE_X_ALL | MODE_W_PRIVATE)
#define DIR_PERMS_PUBLIC (MODE_R_ALL | MODE_X_ALL | MODE_W_PUBLIC_DIR)
+#define DIR_PERMS_PUBLIC_ALL (MODE_R_ALL | MODE_X_ALL | MODE_W_ALL)
#define FILE_PERMS_PRIVATE (MODE_R_ALL | MODE_W_PRIVATE)
-#define FILE_PERMS_PUBLIC (MODE_R_ALL | MODE_W_PUBLIC)
+#define FILE_PERMS_PUBLIC (MODE_R_ALL | MODE_W_PUBLIC_FILE)
+#define FILE_PERMS_PUBLIC_ALL (MODE_R_ALL | MODE_W_ALL)
+
char *getHomeDir()
{
#if defined(PLATFORM_ANDROID)
if (user_game_data_dir == NULL)
- user_game_data_dir = (char *)SDL_AndroidGetInternalStoragePath();
+ user_game_data_dir = (char *)(SDL_AndroidGetExternalStorageState() &
+ SDL_ANDROID_EXTERNAL_STORAGE_WRITE ?
+ SDL_AndroidGetExternalStoragePath() :
+ SDL_AndroidGetInternalStoragePath());
#else
if (user_game_data_dir == NULL)
user_game_data_dir = getPath2(getPersonalDataDir(),
return user_game_data_dir;
}
-void updateUserGameDataDir()
-{
-#if defined(PLATFORM_MACOSX)
- char *userdata_dir_old = getPath2(getHomeDir(), program.userdata_subdir_unix);
- char *userdata_dir_new = getUserGameDataDir(); /* do not free() this */
-
- /* convert old Unix style game data directory to Mac OS X style, if needed */
- if (directoryExists(userdata_dir_old) && !directoryExists(userdata_dir_new))
- {
- if (rename(userdata_dir_old, userdata_dir_new) != 0)
- {
- Error(ERR_WARN, "cannot move game data directory '%s' to '%s'",
- userdata_dir_old, userdata_dir_new);
-
- /* continue using Unix style data directory -- this should not happen */
- program.userdata_path = getPath2(getPersonalDataDir(),
- program.userdata_subdir_unix);
- }
- }
-
- free(userdata_dir_old);
-#endif
-}
-
char *getSetupDir()
{
return getUserGameDataDir();
void createDirectory(char *dir, char *text, int permission_class)
{
+ if (directoryExists(dir))
+ return;
+
/* leave "other" permissions in umask untouched, but ensure group parts
of USERDATA_DIR_MODE are not masked */
mode_t dir_mode = (permission_class == PERMS_PRIVATE ?
mode_t group_umask = ~(dir_mode & S_IRWXG);
int running_setgid = posix_process_running_setgid();
- /* if we're setgid, protect files against "other" */
- /* else keep umask(0) to make the dir world-writable */
+ if (permission_class == PERMS_PUBLIC)
+ {
+ /* if we're setgid, protect files against "other" */
+ /* else keep umask(0) to make the dir world-writable */
- if (running_setgid)
- posix_umask(last_umask & group_umask);
- else
- dir_mode |= MODE_W_ALL;
+ if (running_setgid)
+ posix_umask(last_umask & group_umask);
+ else
+ dir_mode = DIR_PERMS_PUBLIC_ALL;
+ }
- if (!directoryExists(dir))
- if (posix_mkdir(dir, dir_mode) != 0)
- Error(ERR_WARN, "cannot create %s directory '%s': %s",
- text, dir, strerror(errno));
+ if (posix_mkdir(dir, dir_mode) != 0)
+ Error(ERR_WARN, "cannot create %s directory '%s': %s",
+ text, dir, strerror(errno));
if (permission_class == PERMS_PUBLIC && !running_setgid)
chmod(dir, dir_mode);
FILE_PERMS_PRIVATE : FILE_PERMS_PUBLIC);
if (permission_class == PERMS_PUBLIC && !running_setgid)
- perms |= MODE_W_ALL;
+ perms = FILE_PERMS_PUBLIC_ALL;
chmod(filename, perms);
}
/* always start with reliable default values */
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-#if defined(CREATE_SPECIAL_EDITION_RND_JUE)
- leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
- "jue_start");
- if (leveldir_current == NULL)
- leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-#endif
+ if (!strEqual(DEFAULT_LEVELSET, UNDEFINED_LEVELSET))
+ {
+ leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+ DEFAULT_LEVELSET);
+ if (leveldir_current == NULL)
+ leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
+ }
if ((level_setup_hash = loadSetupFileHash(filename)))
{
LevelStats_setSolved(i, 0);
}
- checkSeriesInfo(leveldir_current);
+ checkSeriesInfo();
/* ----------------------------------------------------------------------- */
/* ~/.<program>/levelsetup/<level series>/levelsetup.conf */