[Tux4kids-commits] r353 - in tuxmath/trunk: data/missions doc src
tholy-guest at alioth.debian.org
tholy-guest at alioth.debian.org
Mon Dec 3 11:24:55 UTC 2007
Author: tholy-guest
Date: 2007-12-03 11:24:55 +0000 (Mon, 03 Dec 2007)
New Revision: 353
Modified:
tuxmath/trunk/data/missions/options
tuxmath/trunk/doc/README.txt
tuxmath/trunk/doc/changelog
tuxmath/trunk/src/fileops.c
tuxmath/trunk/src/fileops.h
tuxmath/trunk/src/highscore.c
tuxmath/trunk/src/highscore.h
tuxmath/trunk/src/titlescreen.c
Log:
Add global config support for multi-user home directories, and also
allow users to share a highscores file.
--This line, and those below, will be ignored--
M src/fileops.c
M src/fileops.h
M src/highscore.c
M src/highscore.h
M src/titlescreen.c
M doc/changelog
M doc/README.txt
M data/missions/options
Modified: tuxmath/trunk/data/missions/options
===================================================================
--- tuxmath/trunk/data/missions/options 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/data/missions/options 2007-12-03 11:24:55 UTC (rev 353)
@@ -218,7 +218,7 @@
# Use fullscreen at 640x480 resolution instead of
# 640x480 window. Change to 0 if SDL has trouble with
# fullscreen on your system:
-fullscreen = 1
+fullscreen = 0
# Display jpg images for background:
use_bkgd = 1
@@ -488,10 +488,12 @@
############################################################
# #
-# Restricting User Settings #
+# Managing User Settings #
# #
# Parameter: per_user_config (boolean) #
# Default: 1 #
+# Parameter: homedir (string) #
+# Default: <none supplied> #
# #
# 'per_user_config' determines whether Tuxmath will look #
# in the user's home directory for settings. Default is 1 #
@@ -499,10 +501,18 @@
# .tuxmath file and use the the global settings in the #
# installation-wide config file. #
# #
-# This setting cannot be changed by an ordinary user, i.e. #
-# it is ignored unless the config file is Tuxmath's global #
-# config file. Thus, users cannot 'lock themselves out' #
-# by accidentally setting this to 0. #
+# 'homedir' allows you to specify the location to look for #
+# user home directories. You probably do not want to #
+# specify this unless all users share the same login #
+# account. See the README for details on configuration. #
+# To enable this feature, remove the '#' comment mark and #
+# set the path as desired. #
+# #
+# These settings cannot be changed by an ordinary user, as #
+# they are ignored unless the config file is Tuxmath's #
+# global config file. Thus, users cannot 'lock themselves #
+# out' by accidentally setting per_user_config to 0. #
############################################################
per_user_config = 1
+# homedir = /servervolume/tuxmath_users
Modified: tuxmath/trunk/doc/README.txt
===================================================================
--- tuxmath/trunk/doc/README.txt 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/doc/README.txt 2007-12-03 11:24:55 UTC (rev 353)
@@ -25,9 +25,10 @@
Configuration
-------------
- School-type settings in which all students have a single username
- may benefit from additional configuration---see below under
- "Configuring multiple users."
+ If all players are using a single account (e.g., a home computer
+ that is always logged in, or a school setting in which all students
+ have a single username), you may want to do some additional
+ configuration---see below under "Configuring multiple users."
Running The Program
@@ -406,14 +407,26 @@
you?" If you omit this file, then students will simply be
presented with the list without any kind of prompt.
- 7. Finally, adjust the launch command for tuxmath to pass the
+ 7. Optionally, you can create an empty file called "highscores"
+ ("highscores.txt" on Windows) at whatever level of the
+ hierarchy you want users to be competing for the high score.
+ For example, if you want the high scores to be grade-wide,
+ then put a "highscores" file in each grade's directory.
+ Alternatively, each classroom could have it's own, or even
+ each student. If you do nothing, then each student will have
+ a private high score table. (In case of multiple highscores
+ files, the one at the lowest level of the hierarchy wins.)
+
+ 8. Finally, adjust the global configuration file's "homedir"
+ property (at the very end of the file) to point to your
+ home directory tree. Alternatively, you can employ the
command line option "--homedir /severvolume/tuxmath_users"
(along with any other options) upon launching tuxmath. Note
that an individual classroom could make use of this
- school-wide service by specifying "--homedir
- /servervolume/tuxmath_users/2nd\ grade/Mrs.\ Johnson" so that
- students in a particular classroom only have to choose among
- their own class.
+ school-wide service by specifying (in the option-file syntax)
+ homedir = /servervolume/tuxmath_users/2nd\ grade/Mrs.\ Johnson
+ so that students in a particular classroom only have to choose
+ among their own class.
You have to make sure that all the write permissions are set
correctly.
Modified: tuxmath/trunk/doc/changelog
===================================================================
--- tuxmath/trunk/doc/changelog 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/doc/changelog 2007-12-03 11:24:55 UTC (rev 353)
@@ -1,6 +1,14 @@
-2007.Nov.26 (svn.debian.org/tux4kids - revision 350)
+2007.Dec.03 (svn.debian.org/tux4kids - revision 353)
Options:
+ * Added global config file support for specifying a home directory
+ (tree) location.
+ Game:
+ * Allow users to share a single high score file.
+ Tim Holy <holy at wustl.edu>
+
+2007.Dec.02 (svn.debian.org/tux4kids - revision 350)
+ Options:
* Reworked the user login to make it more robust and
user-friendly. This version should be pretty generally usable.
Modified: tuxmath/trunk/src/fileops.c
===================================================================
--- tuxmath/trunk/src/fileops.c 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/src/fileops.c 2007-12-03 11:24:55 UTC (rev 353)
@@ -61,7 +61,6 @@
((sizeof(struct dirent) - sizeof(dp)->d_name) + \
(((dp)->d_reclen + 1 + 3) &~ 3))
-
/*-----------------------------------------------------------------------*/
/*
Alphabetic order comparison routine for those who want it.
@@ -208,6 +207,8 @@
static int write_config_file(FILE* fp, int verbose);
static int is_lesson_file(const struct dirent *lfdirent);
static int read_goldstars(void);
+static int read_lines_from_file(FILE *fp,char ***lines);
+static void dirname_up(char *dirname);
/* fix HOME on windows */
@@ -411,6 +412,7 @@
/* This functions keep and returns the user data directory application path */
static char* user_data_dir = NULL;
static int add_subdir = 1;
+static char* high_scores_file_path = NULL;
char *get_user_data_dir ()
{
@@ -975,6 +977,49 @@
}
+/* Look for a highscore table file in the current user */
+/* data directory. Return 1 if found, 0 if not. This */
+/* is used for the multi-user login code, in deciding */
+/* where to put the highscore information. */
+int high_scores_found_in_user_dir(void)
+{
+ FILE* fp;
+ char opt_path[PATH_MAX];
+
+ /* find $HOME and tack on file name: */
+ get_user_data_dir_with_subdir(opt_path);
+ strcat(opt_path, HIGHSCORE_FILENAME);
+
+ #ifdef TUXMATH_DEBUG
+ printf("\nIn read_high_scores() full path to file is: = %s\n", opt_path);
+ #endif
+
+ fp = fopen(opt_path, "r");
+ if (fp) /* file exists */
+ {
+ fclose(fp);
+ return 1;
+ }
+ else
+ return 0;
+}
+
+/* Set the path to the high score file to the current */
+/* user data dir */
+void set_high_score_path(void)
+{
+ char opt_path[PATH_MAX];
+
+ /* find $HOME and tack on file name: */
+ get_user_data_dir_with_subdir(opt_path);
+
+ // Free any previous allocation
+ if (high_scores_file_path != NULL)
+ free(high_scores_file_path);
+
+ high_scores_file_path = strdup(opt_path);
+}
+
/* Look for a high score table file in the user's homedir */
/* and if found, pass the FILE* to read_high_scores_fp() in */
/* highscore.c to actually read in scores. (A "global" */
@@ -987,7 +1032,10 @@
char opt_path[PATH_MAX];
/* find $HOME and tack on file name: */
- get_user_data_dir_with_subdir(opt_path);
+ if (high_scores_file_path == NULL)
+ get_user_data_dir_with_subdir(opt_path);
+ else
+ strncpy(opt_path,high_scores_file_path,PATH_MAX);
strcat(opt_path, HIGHSCORE_FILENAME);
#ifdef TUXMATH_DEBUG
@@ -1008,11 +1056,47 @@
}
}
-/* Write high score table in user's homedir in format */
-/* compatible with read_high_scores() above. For human- */
-/* readable output for debugging purposes, print_high_ */
-/* scores() in highscore.c is better. */
-int write_high_scores(void)
+/* On File Locking: With multiple users possibly updating the same
+ high-scores table simultaneously, we have to be concerned with the
+ possibility that the high score information might change between
+ the time at which it was determined that the user gets a high
+ score, and time at which the high score table actually gets
+ written. This is especially problematic if it takes kids a while
+ to type in their name, and it's being assumed that the high scores
+ table is valid over that entire time.
+
+ As a first (easy) step, it's best to simply append new information
+ to the high scores file, rather than re-writing the whole file; the
+ read function can make sure that only the top scores are used.
+ That way, the only time there would be trouble is if two appends
+ start at exactly the same moment; and since the amount of
+ information per line is small (and is thus written quickly) and
+ updates are unlikely to be occurring on a
+ millisecond-by-millisecond basis, it's pretty unlikely that
+ problems will crop up.
+
+ An even more robust alternative is to use real file locking. One
+ would need to design a cross-platform solution that also does
+ sensible things (like, say, delete the lock if it's been held for
+ more than 1s, so that locking doesn't block the application). In
+ researching this, the best approach seems to be:
+ a) Open a second file - a lock file of a specific name - for read/write.
+ b) If the lock file already contains your process ID, proceed
+ c) If the lock file already contains a different process ID, deny
+ d) If the lock file is new / empty write and flush your process ID
+ to it, then go back to step (a)
+
+ However, given that this information may not be "mission critical"
+ (pun intended) and might be cleared on a somewhat regular basis
+ anyway, it seems reasonable to just use the append strategy.
+*/
+
+/* Append a new high score to the high-scores file. */
+/* Using this approach is safer than writing the whole */
+/* high scores table if you're in an environment where */
+/* multiple users might be updating the table */
+/* simultaneously. */
+int append_high_score(int tableid,int score,char *player_name)
{
char opt_path[PATH_MAX];
FILE* fp;
@@ -1024,17 +1108,20 @@
}
/* find $HOME and add rest of path to config file: */
- get_user_data_dir_with_subdir(opt_path);
+ if (high_scores_file_path == NULL)
+ get_user_data_dir_with_subdir(opt_path);
+ else
+ strncpy(opt_path,high_scores_file_path,PATH_MAX);
strcat(opt_path, HIGHSCORE_FILENAME);
#ifdef TUXMATH_DEBUG
printf("\nIn write_high_scores() full path to file is: = %s\n", opt_path);
#endif
- fp = fopen(opt_path, "w");
+ fp = fopen(opt_path, "a");
if (fp)
{
- write_high_scores_fp(fp);
+ fprintf(fp,"%d\t%d\t%s\t\n",tableid,score,player_name);
fclose(fp);
fp = NULL;
return 1;
@@ -1042,8 +1129,83 @@
else
return 0;
}
+
+/* Checks to see if the current homedir has a menu_entries file, and if */
+/* so returns the names of the menu entries. This is used in cases */
+/* where users must select their login information. Returns the number */
+/* of menu entries (0 if there are none), and sets the input */
+/* argument to a malloc-ed array of names (sets to NULL if there are no */
+/* choices to be made). */
+int read_user_menu_entries(char ***user_names)
+{
+ FILE *fp;
+ int n_entries;
+ char opt_path[PATH_MAX],menu_entries_file[PATH_MAX];
+
+ // Look for a menu_entries file
+ get_user_data_dir_with_subdir(opt_path);
+ strncpy(menu_entries_file,opt_path,PATH_MAX);
+ strncat(menu_entries_file,"user_menu_entries",PATH_MAX-strlen(menu_entries_file));
+ n_entries = 0;
+ fp = fopen(menu_entries_file,"r");
+ if (fp)
+ {
+ // There is a menu_entries file, read it
+ n_entries = read_lines_from_file(fp,user_names);
+ fclose(fp);
+ }
+
+ return n_entries;
+}
+
+/* Reads the user_login_questions file. The syntax is identical to
+ read_user_menu_entries. */
+int read_user_login_questions(char ***user_login_questions)
+{
+ FILE *fp;
+ int n_entries;
+ char opt_path[PATH_MAX],user_login_questions_file[PATH_MAX];
+
+ // Look for a user_login_questions file
+ get_user_data_dir_with_subdir(opt_path);
+ strncpy(user_login_questions_file,opt_path,PATH_MAX);
+ strncat(user_login_questions_file,"user_login_questions",PATH_MAX-strlen(user_login_questions_file));
+ n_entries = 0;
+ fp = fopen(user_login_questions_file,"r");
+ if (fp)
+ {
+ // There is a user_login_questions file, read it
+ n_entries = read_lines_from_file(fp,user_login_questions);
+ fclose(fp);
+ }
+
+ return n_entries;
+}
+
+void user_data_dirname_up(void)
+{
+ dirname_up(user_data_dir);
+}
+
+void user_data_dirname_down(char *subdir)
+{
+ DIR *dir;
+
+ if (user_data_dir != NULL)
+ strcat(user_data_dir,subdir);
+ else
+ user_data_dir = strdup(subdir);
+ strcat(user_data_dir,"/");
+ dir = opendir(user_data_dir);
+ if (dir == NULL) {
+ printf("User data directory cannot be opened, there is a configuration error\n");
+ printf("Continuing anyway without saving or loading individual settings.\n");
+ }
+}
+
+
/***********************************************************
* *
* "Private methods" with file scope only *
@@ -1186,6 +1348,19 @@
}
}
+ else if(0 == strcasecmp(parameter, "homedir"))
+ {
+ /* Only let administrator change this setting */
+ if (file_type == GLOBAL_CONFIG_FILE)
+ {
+ /* Check to see whether the specified homedir exists */
+ if (opendir(value) == NULL)
+ fprintf(stderr,"homedir: %s is not a directory, or it could not be read\n", value);
+ else
+ set_user_data_dir(value); /* copy the homedir setting */
+ }
+ }
+
else if(0 == strcasecmp(parameter, "use_sound"))
{
int v = str_to_bool(value);
@@ -2337,10 +2512,12 @@
{
fprintf (fp, "\n\n############################################################\n"
"# #\n"
- "# Restricting User Settings #\n"
+ "# Managing User Settings #\n"
"# #\n"
"# Parameter: per_user_config (boolean) #\n"
"# Default: 1 #\n"
+ "# Parameter: homedir (string) #\n"
+ "# Default: <none supplied> #\n"
"# #\n"
"# 'per_user_config' determines whether Tuxmath will look #\n"
"# in the user's home directory for settings. Default is 1 #\n"
@@ -2348,13 +2525,21 @@
"# .tuxmath file and use the the global settings in the #\n"
"# installation-wide config file. #\n"
"# #\n"
- "# This setting cannot be changed by an ordinary user, i.e. #\n"
- "# it is ignored unless the config file is Tuxmath's global #\n"
- "# config file. Thus, users cannot 'lock themselves out' #\n"
- "# by accidentally setting this to 0. #\n"
+ "# 'homedir' allows you to specify the location to look for #\n"
+ "# user home directories. You probably do not want to #\n"
+ "# specify this unless all users share the same login #\n"
+ "# account. See the README for details on configuration. #\n"
+ "# To enable this feature, remove the '#' comment mark and #\n"
+ "# set the path as desired. #\n"
+ "# #\n"
+ "# These settings cannot be changed by an ordinary user, as #\n"
+ "# they are ignored unless the config file is Tuxmath's #\n"
+ "# global config file. Thus, users cannot 'lock themselves #\n"
+ "# out' by accidentally setting per_user_config to 0. #\n"
"############################################################\n\n");
}
fprintf(fp, "per_user_config = %d\n", Opts_PerUserConfig());
+ fprintf(fp, "# homedir = /servervolume/tuxmath_users\n");
/* print general game options (passing '1' as second arg causes */
@@ -2587,38 +2772,7 @@
}
-/* Utility function to test whether a given dirent represents a directory */
-/* Note this assumes a base of the user's current data directory, it's
- not a general function. */
-/*
-int isdir(const struct dirent *dirEntry)
-{
- struct stat fileStat;
- char opt_path[PATH_MAX];
- // Exclude "." from consideration
- if (strcmp(dirEntry->d_name,".") == 0)
- return 0;
- // Exclude ".." from consideration
- if (strcmp(dirEntry->d_name,"..") == 0)
- return 0;
-
- // Prepend the pathname
- get_user_data_dir_with_subdir(opt_path);
- strncat(opt_path, dirEntry->d_name,PATH_MAX-strlen(opt_path));
-
- if (stat(opt_path, &fileStat) < 0) {
- printf("error parsing %s\n",opt_path);
- return 0;
- }
- printf("Entry: %s, IsDir: %d\n",opt_path, S_ISDIR(fileStat.st_mode));
- if (S_ISDIR(fileStat.st_mode))
- return 1;
- else
- return 0;
-}
-*/
-
/* A utility function to read lines from a textfile. Upon exit, it */
/* returns the # of lines successfully read, and sets the pointer */
/* array so that (*lines)[i] is a pointer to the text on the ith */
@@ -2626,7 +2780,7 @@
/* and skips blank lines. */
/* On entry, *lines must be NULL, as a sign that any previously */
/* allocated memory has been freed. */
-int read_lines_from_file(FILE *fp,char ***lines)
+static int read_lines_from_file(FILE *fp,char ***lines)
{
char *fgets_return_val;
char name_buf[NAME_BUF_SIZE];
@@ -2672,60 +2826,8 @@
return n_entries;
}
-/* Checks to see if the current homedir has a menu_entries file, and if */
-/* so returns the names of the menu entries. This is used in cases */
-/* where users must select their login information. Returns the number */
-/* of menu entries (0 if there are none), and sets the input */
-/* argument to a malloc-ed array of names (sets to NULL if there are no */
-/* choices to be made). */
-int read_user_menu_entries(char ***user_names)
-{
- FILE *fp;
- int n_entries;
- char opt_path[PATH_MAX],menu_entries_file[PATH_MAX];
-
- // Look for a menu_entries file
- get_user_data_dir_with_subdir(opt_path);
- strncpy(menu_entries_file,opt_path,PATH_MAX);
- strncat(menu_entries_file,"user_menu_entries",PATH_MAX-strlen(menu_entries_file));
- n_entries = 0;
- fp = fopen(menu_entries_file,"r");
- if (fp)
- {
- // There is a menu_entries file, read it
- n_entries = read_lines_from_file(fp,user_names);
- fclose(fp);
- }
-
- return n_entries;
-}
-
-/* Reads the user_login_questions file. The syntax is identical to
- read_user_menu_entries. */
-int read_user_login_questions(char ***user_login_questions)
-{
- FILE *fp;
- int n_entries;
- char opt_path[PATH_MAX],user_login_questions_file[PATH_MAX];
-
- // Look for a user_login_questions file
- get_user_data_dir_with_subdir(opt_path);
- strncpy(user_login_questions_file,opt_path,PATH_MAX);
- strncat(user_login_questions_file,"user_login_questions",PATH_MAX-strlen(user_login_questions_file));
- n_entries = 0;
- fp = fopen(user_login_questions_file,"r");
- if (fp)
- {
- // There is a user_login_questions file, read it
- n_entries = read_lines_from_file(fp,user_login_questions);
- fclose(fp);
- }
-
- return n_entries;
-}
-
/* A utility function to go up one level in a directory hierarchy */
-void dirname_up(char *dirname)
+static void dirname_up(char *dirname)
{
int len;
Modified: tuxmath/trunk/src/fileops.h
===================================================================
--- tuxmath/trunk/src/fileops.h 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/src/fileops.h 2007-12-03 11:24:55 UTC (rev 353)
@@ -227,16 +227,25 @@
NUM_SUMMARIES
};
-/* These functions used by setup() to read in settings: */
+/* These functions used by setup() and titlescreen() to read in settings: */
int read_global_config_file(void);
int read_user_config_file(void);
int parse_lesson_file_directory(void);
int read_named_config_file(const unsigned char* filename);
int write_user_config_file(void);
int read_high_scores(void);
-int write_high_scores(void);
+int append_high_scores(int tableid,int score,char *player_name);
+void set_high_score_path(void);
int write_goldstars(void);
+/* These functions are used by titlescreen() to assist with the login */
+int read_user_menu_entries(char ***user_names);
+int read_user_login_questions(char ***user_login_questions);
+int high_scores_found_in_user_dir(void);
+void set_high_score_path(void);
+void user_data_dirname_up(void);
+void user_data_dirname_down(char *subdir);
+
/* These functions used by game() to record game summary: */
int write_pregame_summary(void);
int write_postgame_summary(void);
Modified: tuxmath/trunk/src/highscore.c
===================================================================
--- tuxmath/trunk/src/highscore.c 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/src/highscore.c 2007-12-03 11:24:55 UTC (rev 353)
@@ -769,36 +769,7 @@
return 1;
}
-/* Write high score table to provided FILE* in format */
-/* compatible with read_high_scores() above. For human- */
-/* readable output for debugging purposes, print_high_ */
-/* scores() in highscore.c is better. write_high_scores() */
-/* in fileops.c takes care of checking paths, opening */
-/* and closing the file, etc. */
-void write_high_scores_fp(FILE* fp)
-{
- int i, j;
- /* get out if file pointer invalid: */
- if(!fp)
- {
- fprintf(stderr, "In write_high_scores_fp(), file pointer invalid!\n");
- return;
- }
-
- for (i = 0; i < NUM_HIGH_SCORE_LEVELS; i++)
- {
- for (j = 0; j < HIGH_SCORES_SAVED; j++)
- {
- fprintf(fp, "%d\t%d\t%s\t\n", i,
- high_scores[i][j].score,
- high_scores[i][j].name);
- }
- }
- return;
-}
-
-
/* Return the score associated with a table entry: */
/* Note: the place is given as the array index, i.e. */
/* 0 for the top of the list. */
Modified: tuxmath/trunk/src/highscore.h
===================================================================
--- tuxmath/trunk/src/highscore.h 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/src/highscore.h 2007-12-03 11:24:55 UTC (rev 353)
@@ -25,7 +25,7 @@
void initialize_scores(void);
void print_high_scores(FILE* fp);
int read_high_scores_fp(FILE* fp);
-void write_high_scores_fp(FILE* fp);
+/* Note: for writing, use append_high_score in fileops.c */
int HS_Score(int diff_level, int place);
unsigned char* HS_Name(int diff_level, int place);
Modified: tuxmath/trunk/src/titlescreen.c
===================================================================
--- tuxmath/trunk/src/titlescreen.c 2007-12-02 07:59:56 UTC (rev 352)
+++ tuxmath/trunk/src/titlescreen.c 2007-12-03 11:24:55 UTC (rev 353)
@@ -687,6 +687,7 @@
audioMusicLoad( "tuxi.ogg", -1 );
}
/* See if player made high score list! */
+ read_high_scores(); /* Update, in case other users have added to it */
hs_table = arcade_high_score_tables[choice];
if (check_score_place(hs_table, Opts_LastScore()) < HIGH_SCORES_SAVED){
@@ -695,9 +696,13 @@
/* Get name from player: */
HighScoreNameEntry(&player_name[0]);
insert_score(player_name, hs_table, Opts_LastScore());
+ /* Show the high scores. Note the user will see his/her */
+ /* achievement even if (in the meantime) another player */
+ /* has in fact already bumped this score off the table. */
DisplayHighScores(hs_table);
/* save to disk: */
- write_high_scores();
+ /* See "On File Locking" in fileops.c */
+ append_high_score(choice,Opts_LastScore(),&player_name[0]);
#ifdef TUXMATH_DEBUG
print_high_scores(stderr);
@@ -928,14 +933,11 @@
menu_options menu_opts;
int chosen_login = -1;
- char *user_home;
int level;
int i;
char *trailer_quit = "Quit";
char *trailer_back = "Back";
- DIR *dir;
-
// Check for & read user_login_questions file
n_login_questions = read_user_login_questions(&user_login_questions);
@@ -945,8 +947,11 @@
if (n_users == 0)
return 0; // a quick exit, there's only one user
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
+
level = 0;
- user_home = get_user_data_dir();
set_default_menu_options(&menu_opts);
if (n_login_questions > 0)
menu_opts.title = user_login_questions[0];
@@ -965,25 +970,20 @@
}
else {
// Go back up one level of the directory tree
- dirname_up(user_home);
+ user_data_dirname_up();
level--;
menu_opts.starting_entry = -1;
}
}
else {
// User chose an entry, set it up
- strcat(user_home,user_names[chosen_login]);
- strcat(user_home,"/");
- dir = opendir(user_home);
- if (dir == NULL) {
- printf("Directory cannot be opened, there is a configuration error\n");
- // We can continue anyway, and tuxmath will simply be going in
- // no-save mode. It will bail and go straight to the main menu
- // next.
- }
+ user_data_dirname_down(user_names[chosen_login]);
level++;
menu_opts.starting_entry = 0;
}
+ // Check for a highscores file
+ if (high_scores_found_in_user_dir())
+ set_high_score_path();
// Free the entries from the previous menu
for (i = 0; i < n_users; i++)
free(user_names[i]);
More information about the Tux4kids-commits
mailing list