rnd-19981205-2
[rocksndiamonds.git] / src / files.c
index d28c1f48279502d5dcfa181d4f271e802c212ef0..21309b825bf505ea3fc4ba98271d55874a3f0fb0 100644 (file)
@@ -58,8 +58,9 @@
 #define LEVELSETUP_FILENAME    "lvlsetup.cnf"
 #define LEVELINFO_FILENAME     "lvlinfo.cnf"
 #define LEVELFILE_EXTENSION    "lvl"
-#define TAPEFILE_EXTENSION     "rec"
+#define TAPEFILE_EXTENSION     "tap"
 #define SCOREFILE_EXTENSION    "sco"
+#define ERROR_FILENAME         "error.out"
 #endif
 
 /* file permissions for newly written files */
@@ -80,7 +81,7 @@ static char *getGlobalDataDir()
   return GAME_DIR;
 }
 
-static char *getUserDataDir()
+char *getUserDataDir()
 {
   static char *userdata_dir = NULL;
 
@@ -89,8 +90,7 @@ static char *getUserDataDir()
     char *home_dir = getHomeDir();
     char *data_dir = USERDATA_DIRECTORY;
 
-    userdata_dir = checked_malloc(strlen(home_dir) + strlen(data_dir) + 2);
-    sprintf(userdata_dir, "%s/%s", home_dir, data_dir);
+    userdata_dir = getPath2(home_dir, data_dir);
   }
 
   return userdata_dir;
@@ -110,10 +110,10 @@ static char *getUserLevelDir(char *level_subdir)
   if (userlevel_dir)
     free(userlevel_dir);
 
-  userlevel_dir = checked_malloc(strlen(data_dir) + strlen(userlevel_subdir) +
-                                strlen(level_subdir) + 3);
-  sprintf(userlevel_dir, "%s/%s%s%s", data_dir, userlevel_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    userlevel_dir = getPath3(data_dir, userlevel_subdir, level_subdir);
+  else
+    userlevel_dir = getPath2(data_dir, userlevel_subdir);
 
   return userlevel_dir;
 }
@@ -127,10 +127,10 @@ static char *getTapeDir(char *level_subdir)
   if (tape_dir)
     free(tape_dir);
 
-  tape_dir = checked_malloc(strlen(data_dir) + strlen(tape_subdir) +
-                           strlen(level_subdir) + 3);
-  sprintf(tape_dir, "%s/%s%s%s", data_dir, tape_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    tape_dir = getPath3(data_dir, tape_subdir, level_subdir);
+  else
+    tape_dir = getPath2(data_dir, tape_subdir);
 
   return tape_dir;
 }
@@ -144,10 +144,10 @@ static char *getScoreDir(char *level_subdir)
   if (score_dir)
     free(score_dir);
 
-  score_dir = checked_malloc(strlen(data_dir) + strlen(score_subdir) +
-                            strlen(level_subdir) + 3);
-  sprintf(score_dir, "%s/%s%s%s", data_dir, score_subdir,
-         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+  if (strlen(level_subdir) > 0)
+    score_dir = getPath3(data_dir, score_subdir, level_subdir);
+  else
+    score_dir = getPath2(data_dir, score_subdir);
 
   return score_dir;
 }
@@ -155,7 +155,7 @@ static char *getScoreDir(char *level_subdir)
 static char *getLevelFilename(int nr)
 {
   static char *filename = NULL;
-  char basename[20 + strlen(LEVELFILE_EXTENSION)];
+  char basename[MAX_FILENAME_LEN];
 
   if (filename != NULL)
     free(filename);
@@ -173,7 +173,7 @@ static char *getLevelFilename(int nr)
 static char *getTapeFilename(int nr)
 {
   static char *filename = NULL;
-  char basename[20 + strlen(LEVELFILE_EXTENSION)];
+  char basename[MAX_FILENAME_LEN];
 
   if (filename != NULL)
     free(filename);
@@ -187,7 +187,7 @@ static char *getTapeFilename(int nr)
 static char *getScoreFilename(int nr)
 {
   static char *filename = NULL;
-  char basename[20 + strlen(LEVELFILE_EXTENSION)];
+  char basename[MAX_FILENAME_LEN];
 
   if (filename != NULL)
     free(filename);
@@ -443,6 +443,17 @@ void LoadTape(int level_nr)
   int file_version = FILE_VERSION_1_2; /* last version of tape files */
   int chunk_length;
 
+  /* always start with reliable default values (empty tape) */
+  TapeErase();
+
+  /* default values (also for pre-1.2 tapes) with only the first player */
+  tape.player_participates[0] = TRUE;
+  for(i=1; i<MAX_PLAYERS; i++)
+    tape.player_participates[i] = FALSE;
+
+  /* at least one (default: the first) player participates in every tape */
+  num_participating_players = 1;
+
   if (!(file = fopen(filename, "r")))
     return;
 
@@ -491,7 +502,7 @@ void LoadTape(int level_nr)
     for(i=0; i<TAPE_HEADER_UNUSED; i++)                /* skip unused header bytes */
       fgetc(file);
 
-    /* check which players participate in this tape recording */
+    /* since version 1.2, tapes store which players participate in the tape */
     num_participating_players = 0;
     for(i=0; i<MAX_PLAYERS; i++)
     {
@@ -538,10 +549,6 @@ void LoadTape(int level_nr)
     {
       tape.pos[i].action[j] = MV_NO_MOVING;
 
-      /* pre-1.2 tapes store data for only one player */
-      if (file_version == FILE_VERSION_1_0 && j > 0)
-       continue;
-
       if (tape.player_participates[j])
        tape.pos[i].action[j] = fgetc(file);
     }
@@ -699,7 +706,7 @@ void LoadScore(int level_nr)
   /* always start with reliable default values */
   for(i=0; i<MAX_SCORE_ENTRIES; i++)
   {
-    strcpy(highscore[i].Name, EMPTY_ALIAS);
+    strcpy(highscore[i].Name, EMPTY_PLAYER_NAME);
     highscore[i].Score = 0;
   }
 
@@ -1144,16 +1151,16 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->player_name = getStringCopy(getLoginName());
 
   si->sound = TRUE;
-  si->sound_loops = FALSE;
-  si->sound_music = FALSE;
-  si->sound_simple = FALSE;
+  si->sound_loops = TRUE;
+  si->sound_music = TRUE;
+  si->sound_simple = TRUE;
   si->toons = TRUE;
   si->double_buffering = TRUE;
   si->direct_draw = !si->double_buffering;
-  si->scroll_delay = FALSE;
+  si->scroll_delay = TRUE;
   si->soft_scrolling = TRUE;
   si->fading = FALSE;
-  si->autorecord = FALSE;
+  si->autorecord = TRUE;
   si->quick_doors = FALSE;
 
   for (i=0; i<MAX_PLAYERS; i++)
@@ -1403,16 +1410,16 @@ void LoadLevelInfo()
 
 static void SaveUserLevelInfo()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   FILE *file;
   int i;
 
-  sprintf(filename, "%s/%s",
-         getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
+  filename = getPath2(getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write level info file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1428,19 +1435,20 @@ static void SaveUserLevelInfo()
     fprintf(file, "%s\n", getSetupLine("", i));
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
 
 void LoadSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   struct SetupFileList *setup_file_list = NULL;
 
   /* always start with reliable default values */
   setSetupInfoToDefaults(&setup);
 
-  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+  filename = getPath2(getSetupDir(), SETUP_FILENAME);
 
   setup_file_list = loadSetupFileList(filename);
 
@@ -1467,6 +1475,8 @@ void LoadSetup()
   }
   else
     Error(ERR_WARN, "using default setup values");
+
+  free(filename);
 }
 
 static char *getSetupLine(char *prefix, int token_nr)
@@ -1535,16 +1545,17 @@ static char *getSetupLine(char *prefix, int token_nr)
 void SaveSetup()
 {
   int i, pnr;
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   FILE *file;
 
   InitUserDataDirectory();
 
-  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+  filename = getPath2(getSetupDir(), SETUP_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1577,19 +1588,20 @@ void SaveSetup()
   }
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
 
 void LoadLevelSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
 
   /* always start with reliable default values */
   leveldir_nr = 0;
   level_nr = 0;
 
-  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
 
   if (level_setup_list)
     freeSetupFileList(level_setup_list);
@@ -1612,11 +1624,13 @@ void LoadLevelSetup()
                                        LEVELSETUP_COOKIE);
     Error(ERR_WARN, "using default setup values");
   }
+
+  free(filename);
 }
 
 void SaveLevelSetup()
 {
-  char filename[MAX_FILENAME_LEN];
+  char *filename;
   struct SetupFileList *list_entry = level_setup_list;
   FILE *file;
 
@@ -1628,11 +1642,12 @@ void SaveLevelSetup()
   setTokenValue(level_setup_list,
                leveldir[leveldir_nr].filename, int2str(level_nr, 0));
 
-  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
 
   if (!(file = fopen(filename, "w")))
   {
     Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    free(filename);
     return;
   }
 
@@ -1652,6 +1667,67 @@ void SaveLevelSetup()
   }
 
   fclose(file);
+  free(filename);
 
   chmod(filename, SETUP_PERMS);
 }
+
+#ifdef MSDOS
+static boolean initErrorFile()
+{
+  char *filename;
+  FILE *error_file;
+
+  InitUserDataDirectory();
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "w");
+  free(filename);
+
+  if (error_file == NULL)
+    return FALSE;
+
+  fclose(error_file);
+
+  return TRUE;
+}
+
+FILE *openErrorFile()
+{
+  static boolean first_access = TRUE;
+  char *filename;
+  FILE *error_file;
+
+  if (first_access)
+  {
+    if (!initErrorFile())
+      return NULL;
+
+    first_access = FALSE;
+  }
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "a");
+  free(filename);
+
+  return error_file;
+}
+
+void dumpErrorFile()
+{
+  char *filename;
+  FILE *error_file;
+
+  filename = getPath2(getUserDataDir(), ERROR_FILENAME);
+  error_file = fopen(filename, "r");
+  free(filename);
+
+  if (error_file != NULL)
+  {
+    while (!feof(error_file))
+      fputc(fgetc(error_file), stderr);
+
+    fclose(error_file);
+  }
+}
+#endif