X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ffiles.c;h=c14b9d994ec128b1c451f2bd87a96ec71792bcd8;hp=ac1b0fa74a380246fa12e2f8880e3240648f6fae;hb=c878cb2be6a0bffee850bf4f2dcb1939d5d2cd4f;hpb=40a487dcc5d3028343ff9123a72b8b3839a42861 diff --git a/src/files.c b/src/files.c index ac1b0fa7..c14b9d99 100644 --- a/src/files.c +++ b/src/files.c @@ -12,6 +12,9 @@ ***********************************************************/ #include +#include +#include +#include #include "files.h" #include "tools.h" @@ -105,52 +108,6 @@ static void InitScoreDirectory(char *level_subdir) createDirectory(getScoreDir(level_subdir), "level score"); } -boolean LoadLevelInfo() -{ - int i; - char filename[MAX_FILENAME_LEN]; - char cookie[MAX_FILENAME_LEN]; - FILE *file; - - sprintf(filename, "%s/%s", options.level_directory, LEVDIR_FILENAME); - - if (!(file = fopen(filename, "r"))) - { - Error(ERR_WARN, "cannot read level info '%s'", filename); - return(FALSE); - } - - fscanf(file, "%s\n", cookie); - if (strcmp(cookie, LEVELDIR_COOKIE)) - { - Error(ERR_WARN, "wrong format of level info file"); - fclose(file); - return(FALSE); - } - - num_leveldirs = 0; - leveldir_nr = 0; - for(i=0; inext = NULL; freeSetupFileList(setup_file_list); - if (!first_valid_list_entry) - Error(ERR_WARN, "setup file is empty"); + if (first_valid_list_entry == NULL) + Error(ERR_WARN, "setup/info file '%s' is empty", filename); return first_valid_list_entry; } @@ -875,7 +849,7 @@ static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list, { if (strcmp(setup_file_list->value, identifier) != 0) { - Error(ERR_WARN, "setup file has wrong version"); + Error(ERR_WARN, "setup/info file has wrong version"); return; } else @@ -886,15 +860,25 @@ static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list, checkSetupFileListIdentifier(setup_file_list->next, identifier); else { - Error(ERR_WARN, "setup file has no version information"); + Error(ERR_WARN, "setup/info file has no version information"); return; } } +static void setLevelDirInfoToDefaults(struct LevelDirInfo *ldi) +{ + ldi->name = getStringCopy("non-existing"); + ldi->levels = 0; + ldi->sort_priority = 999; /* default: least priority */ + ldi->readonly = TRUE; +} + static void setSetupInfoToDefaults(struct SetupInfo *si) { int i; + si->player_name = getStringCopy(getLoginName()); + si->sound = TRUE; si->sound_loops = FALSE; si->sound_music = FALSE; @@ -908,15 +892,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->autorecord = FALSE; si->quick_doors = FALSE; - strncpy(si->login_name, getLoginName(), MAX_NAMELEN-1); - si->login_name[MAX_NAMELEN-1] = '\0'; - strncpy(si->alias_name, getLoginName(), MAX_NAMELEN-1); - si->alias_name[MAX_NAMELEN-1] = '\0'; - for (i=0; iinput[i].use_joystick = FALSE; - strcpy(si->input[i].joy.device_name, joystick_device_name[i]); + si->input[i].joy.device_name = getStringCopy(joystick_device_name[i]); si->input[i].joy.xleft = JOYSTICK_XLEFT; si->input[i].joy.xmiddle = JOYSTICK_XMIDDLE; si->input[i].joy.xright = JOYSTICK_XRIGHT; @@ -959,7 +938,9 @@ static void setSetupInfo(int token_nr, char *token_value) break; case TYPE_STRING: - strcpy((char *)setup_value, token_value); + if (*(char **)setup_value != NULL) + free(*(char **)setup_value); + *(char **)setup_value = getStringCopy(token_value); break; default: @@ -1039,6 +1020,85 @@ int getLastPlayedLevelOfLevelSeries(char *level_series_name) return last_level_nr; } +void LoadLevelInfo() +{ + DIR *dir; + struct stat file_status; + char *level_directory = options.level_directory; + char *directory = NULL; + char *filename = NULL; + struct SetupFileList *setup_file_list = NULL; + struct dirent *dir_entry; + int i, num_entries = 0; + + if ((dir = opendir(level_directory)) == NULL) + Error(ERR_EXIT, "cannot read level directory '%s'", level_directory); + + while (num_entries < MAX_LEVDIR_ENTRIES) + { + if ((dir_entry = readdir(dir)) == NULL) /* last directory entry */ + break; + + /* skip entries for current and parent directory */ + if (strcmp(dir_entry->d_name, ".") == 0 || + strcmp(dir_entry->d_name, "..") == 0) + continue; + + /* find out if directory entry is itself a directory */ + directory = getPath2(level_directory, dir_entry->d_name); + if (stat(directory, &file_status) != 0 || /* cannot stat file */ + (file_status.st_mode & S_IFMT) != S_IFDIR) /* not a directory */ + { + free(directory); + continue; + } + + if (strlen(dir_entry->d_name) >= MAX_LEVDIR_FILENAME) + { + Error(ERR_WARN, "filename of level directory '%s' too long -- ignoring", + dir_entry->d_name); + continue; + } + + filename = getPath2(directory, LEVELINFO_FILENAME); + setup_file_list = loadSetupFileList(filename); + + if (setup_file_list) + { + checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE); + setLevelDirInfoToDefaults(&leveldir[num_entries]); + + ldi = leveldir[num_entries]; + for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++) + setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text)); + leveldir[num_entries] = ldi; + + leveldir[num_entries].filename = getStringCopy(dir_entry->d_name); + + freeSetupFileList(setup_file_list); + num_entries++; + } + else + Error(ERR_WARN, "ignoring level directory '%s'", directory); + + free(directory); + free(filename); + } + + if (num_entries == MAX_LEVDIR_ENTRIES) + Error(ERR_WARN, "using %d level directories -- ignoring the rest", + num_entries); + + closedir(dir); + + num_leveldirs = num_entries; + leveldir_nr = 0; + + if (!num_leveldirs) + Error(ERR_EXIT, "cannot find any valid level series in directory '%s'", + level_directory); +} + void LoadSetup() { char filename[MAX_FILENAME_LEN]; @@ -1059,6 +1119,18 @@ void LoadSetup() setup.direct_draw = !setup.double_buffering; freeSetupFileList(setup_file_list); + + /* needed to work around problems with fixed length strings */ + if (strlen(setup.player_name) >= MAX_NAMELEN) + setup.player_name[MAX_NAMELEN - 1] = '\0'; + else if (strlen(setup.player_name) < MAX_NAMELEN - 1) + { + char *new_name = checked_malloc(MAX_NAMELEN); + + strcpy(new_name, setup.player_name); + free(setup.player_name); + setup.player_name = new_name; + } } else Error(ERR_WARN, "using default setup values"); @@ -1117,7 +1189,7 @@ static char *getSetupLine(char *prefix, int token_nr) break; case TYPE_STRING: - strcat(entry, (char *)setup_value); + strcat(entry, *(char **)setup_value); break; default: @@ -1151,11 +1223,11 @@ void SaveSetup() si = setup; for (i=FIRST_GLOBAL_SETUP_TOKEN; i<=LAST_GLOBAL_SETUP_TOKEN; i++) { + fprintf(file, "%s\n", getSetupLine("", i)); + /* just to make things nicer :) */ - if (i == SETUP_TOKEN_ALIAS_NAME) + if (i == SETUP_TOKEN_PLAYER_NAME) fprintf(file, "\n"); - - fprintf(file, "%s\n", getSetupLine("", i)); } /* handle player specific setup values */ @@ -1203,7 +1275,11 @@ void LoadLevelSetup() checkSetupFileListIdentifier(level_setup_list, LEVELSETUP_COOKIE); } else + { + level_setup_list = newSetupFileList(TOKEN_STR_FILE_IDENTIFIER, + LEVELSETUP_COOKIE); Error(ERR_WARN, "using default setup values"); + } } void SaveLevelSetup()