[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