X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=bc12226d7b066a0c5117a51308c41bc0b0dcb16c;hb=fd2761fde6102017cd3be6b59c3be9140f96f703;hp=dd68c91411386c94261c6076f98995f1ba2d9b73;hpb=39af00f43cf5c4cea174d0e90633877df08a2f7c;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index dd68c914..bc12226d 100644 --- a/src/files.c +++ b/src/files.c @@ -13,6 +13,8 @@ #include #include +#include +#include #include "libgame/libgame.h" @@ -612,7 +614,7 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level) { Error(ERR_WARN, "invalid custom element number %d", element); - element = EL_DEFAULT; /* dummy element used for artwork config */ + element = EL_DUMMY; } for(j=0; jeditor.el_custom_more = FALSE; si->editor.el_headlines = TRUE; + si->editor.el_user_defined = FALSE; si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME; si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME; @@ -2756,3 +2761,460 @@ void LoadSpecialMenuDesignSettings() freeSetupFileHash(setup_file_hash); } + +static char *itoa(unsigned int i) +{ + static char *a = NULL; + + if (a != NULL) + free(a); + + if (i > 2147483647) /* yes, this is a kludge */ + i = 2147483647; + + a = checked_malloc(10 + 1); + + sprintf(a, "%d", i); + + return a; +} + +void LoadUserDefinedEditorElementList(int **elements, int *num_elements) +{ + char *filename = getEditorSetupFilename(); + SetupFileList *setup_file_list, *list; + SetupFileHash *element_hash; + int num_unknown_tokens = 0; + int i; + + if ((setup_file_list = loadSetupFileList(filename)) == NULL) + return; + + element_hash = newSetupFileHash(); + + for (i=0; i < NUM_FILE_ELEMENTS; i++) + setHashEntry(element_hash, element_info[i].token_name, itoa(i)); + + /* determined size may be larger than needed (due to unknown elements) */ + *num_elements = 0; + for (list = setup_file_list; list != NULL; list = list->next) + (*num_elements)++; + + /* add space for up to 3 more elements for padding that may be needed */ + *num_elements += 3; + + *elements = checked_malloc(*num_elements * sizeof(int)); + + *num_elements = 0; + for (list = setup_file_list; list != NULL; list = list->next) + { + char *value = getHashEntry(element_hash, list->token); + + if (value) + { + (*elements)[(*num_elements)++] = atoi(value); + } + else + { + if (num_unknown_tokens == 0) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: unknown token(s) found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", filename); + + num_unknown_tokens++; + } + + Error(ERR_RETURN, "- token: '%s'", list->token); + } + } + + if (num_unknown_tokens > 0) + Error(ERR_RETURN_LINE, "-"); + + while (*num_elements % 4) /* pad with empty elements, if needed */ + (*elements)[(*num_elements)++] = EL_EMPTY; + + freeSetupFileList(setup_file_list); + freeSetupFileHash(element_hash); + +#if 0 + /* TEST-ONLY */ + for (i=0; i < *num_elements; i++) + printf("editor: element '%s' [%d]\n", + element_info[(*elements)[i]].token_name, (*elements)[i]); +#endif +} + +static struct MusicFileInfo *get_music_file_info(char *basename) +{ + SetupFileHash *setup_file_hash = NULL; + struct MusicFileInfo tmp_music_file_info, *new_music_file_info; + char *filename_music = getCustomMusicFilename(basename); + char *filename_prefix, *filename_info; + struct + { + char *token; + char **value_ptr; + } + token_to_value_ptr[] = + { + { "context", &tmp_music_file_info.context }, + { "title", &tmp_music_file_info.title }, + { "artist", &tmp_music_file_info.artist }, + { "album", &tmp_music_file_info.album }, + { "year", &tmp_music_file_info.year }, + { NULL, NULL }, + }; + int i; + + if (filename_music == NULL) + return NULL; + + /* ---------- try to replace file extension ---------- */ + + filename_prefix = getStringCopy(filename_music); + if (strrchr(filename_prefix, '.') != NULL) + *strrchr(filename_prefix, '.') = '\0'; + filename_info = getStringCat2(filename_prefix, ".txt"); + +#if 0 + printf("trying to load file '%s'...\n", filename_info); +#endif + + if (fileExists(filename_info)) + setup_file_hash = loadSetupFileHash(filename_info); + + free(filename_prefix); + free(filename_info); + + if (setup_file_hash == NULL) + { + /* ---------- try to add file extension ---------- */ + + filename_prefix = getStringCopy(filename_music); + filename_info = getStringCat2(filename_prefix, ".txt"); + +#if 0 + printf("trying to load file '%s'...\n", filename_info); +#endif + + if (fileExists(filename_info)) + setup_file_hash = loadSetupFileHash(filename_info); + + free(filename_prefix); + free(filename_info); + } + + if (setup_file_hash == NULL) + return NULL; + + /* ---------- music file info found ---------- */ + + for (i = 0; token_to_value_ptr[i].token != NULL; i++) + { + char *value = getHashEntry(setup_file_hash, token_to_value_ptr[i].token); + + *token_to_value_ptr[i].value_ptr = getStringCopy(value); /* may be NULL */ + } + + new_music_file_info = checked_calloc(sizeof(struct MusicFileInfo)); + *new_music_file_info = tmp_music_file_info; + + return new_music_file_info; +} + +void LoadMusicInfo() +{ + char *music_directory = getCustomMusicDirectory(); + int num_music = getMusicListSize(); + DIR *dir; + struct dirent *dir_entry; + struct FileInfo *music; + struct MusicFileInfo *next, **new; + int i; + + while (music_file_info != NULL) + { + next = music_file_info->next; + + if (music_file_info->context) + free(music_file_info->context); + if (music_file_info->title) + free(music_file_info->title); + if (music_file_info->artist) + free(music_file_info->artist); + if (music_file_info->album) + free(music_file_info->album); + if (music_file_info->year) + free(music_file_info->year); + + free(music_file_info); + + music_file_info = next; + } + + new = &music_file_info; + + for (i=0; i < num_music; i++) + { + music = getMusicListEntry(i); + + if (strcmp(music->filename, UNDEFINED_FILENAME) == 0) + continue; + +#if 0 + printf("::: -> '%s'\n", music->filename); +#endif + + *new = get_music_file_info(music->filename); + if (*new != NULL) + new = &(*new)->next; + } + + if ((dir = opendir(music_directory)) == NULL) + { + Error(ERR_WARN, "cannot read music directory '%s'", music_directory); + return; + } + + while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */ + { + char *basename = dir_entry->d_name; + boolean music_already_used = FALSE; + int i; + + for (i=0; i < num_music; i++) + { + music = getMusicListEntry(i); + + if (strcmp(basename, music->filename) == 0) + { + music_already_used = TRUE; + break; + } + } + + if (music_already_used) + continue; + + if (!FileIsSound(basename) && !FileIsMusic(basename)) + continue; + +#if 0 + printf("::: -> '%s'\n", basename); +#endif + + *new = get_music_file_info(basename); + if (*new != NULL) + new = &(*new)->next; + } + + closedir(dir); + +#if 0 + /* TEST-ONLY */ + for (next = music_file_info; next != NULL; next = next->next) + printf("::: title == '%s'\n", next->title); +#endif +} + +void add_info_animation(int element, int action, int direction, int delay, + int *num_list_entries) +{ + struct InfoAnimationInfo *new_list_entry; + (*num_list_entries)++; + + info_animation_info = + checked_realloc(info_animation_info, + *num_list_entries * sizeof(struct InfoAnimationInfo)); + new_list_entry = &info_animation_info[*num_list_entries - 1]; + + new_list_entry->element = element; + new_list_entry->action = action; + new_list_entry->direction = direction; + new_list_entry->delay = delay; +} + +void print_unknown_token(char *filename, char *token, int token_nr) +{ + if (token_nr == 0) + { + Error(ERR_RETURN_LINE, "-"); + Error(ERR_RETURN, "warning: unknown token(s) found in config file:"); + Error(ERR_RETURN, "- config file: '%s'", filename); + } + + Error(ERR_RETURN, "- token: '%s'", token); +} + +void print_unknown_token_end(int token_nr) +{ + if (token_nr > 0) + Error(ERR_RETURN_LINE, "-"); +} + +void LoadInfoAnimations() +{ + char *filename = getElementInfoFilename(); + SetupFileList *setup_file_list, *list; + SetupFileHash *element_hash, *action_hash, *direction_hash; + int num_list_entries = 0; + int num_unknown_tokens = 0; + int i; + + if ((setup_file_list = loadSetupFileList(filename)) == NULL) + return; + + element_hash = newSetupFileHash(); + action_hash = newSetupFileHash(); + direction_hash = newSetupFileHash(); + + for (i=0; i < MAX_NUM_ELEMENTS; i++) + setHashEntry(element_hash, element_info[i].token_name, itoa(i)); + + for (i=0; i < NUM_ACTIONS; i++) + setHashEntry(action_hash, element_action_info[i].suffix, + itoa(element_action_info[i].value)); + + for (i=0; i < NUM_DIRECTIONS; i++) + setHashEntry(direction_hash, element_direction_info[i].suffix, + itoa(element_direction_info[i].value)); + + for (list = setup_file_list; list != NULL; list = list->next) + { + char *element_token, *action_token, *direction_token; + char *element_value, *action_value, *direction_value; + int delay = atoi(list->value); + + if (strcmp(list->token, "end") == 0) + { + add_info_animation(-1, -1, -1, -1, &num_list_entries); + + continue; + } + + element_token = list->token; + element_value = getHashEntry(element_hash, element_token); + + if (element_value != NULL) + { + /* element found */ + add_info_animation(atoi(element_value), -1, -1, + delay, &num_list_entries); + + continue; + } + + if (strchr(element_token, '.') == NULL) + { + /* no further suffixes found -- this is not an element */ + print_unknown_token(filename, list->token, num_unknown_tokens++); + + continue; + } + + action_token = strchr(element_token, '.'); + element_token = getStringCopy(element_token); + *strchr(element_token, '.') = '\0'; + + element_value = getHashEntry(element_hash, element_token); + + if (element_value == NULL) + { + /* this is not an element */ + print_unknown_token(filename, list->token, num_unknown_tokens++); + free(element_token); + + continue; + } + + action_value = getHashEntry(action_hash, action_token); + + if (action_value != NULL) + { + /* action found */ + add_info_animation(atoi(element_value), atoi(action_value), -1, + delay, &num_list_entries); + free(element_token); + + continue; + } + + direction_token = action_token; + direction_value = getHashEntry(direction_hash, direction_token); + + if (direction_value != NULL) + { + /* direction found */ + add_info_animation(atoi(element_value), -1, atoi(direction_value), + delay, &num_list_entries); + free(element_token); + + continue; + } + + if (strchr(action_token + 1, '.') == NULL) + { + /* no further suffixes found -- this is not an action or direction */ + print_unknown_token(filename, list->token, num_unknown_tokens++); + free(element_token); + + continue; + } + + direction_token = strchr(action_token + 1, '.'); + action_token = getStringCopy(action_token); + *strchr(action_token + 1, '.') = '\0'; + + action_value = getHashEntry(action_hash, action_token); + + if (action_value == NULL) + { + /* this is not an action */ + print_unknown_token(filename, list->token, num_unknown_tokens++); + free(element_token); + free(action_token); + + continue; + } + + direction_value = getHashEntry(direction_hash, direction_token); + + if (direction_value != NULL) + { + /* direction found */ + add_info_animation(atoi(element_value), atoi(action_value), + atoi(direction_value), + delay, &num_list_entries); + free(element_token); + free(action_token); + + continue; + } + + print_unknown_token(filename, list->token, num_unknown_tokens++); + + free(element_token); + free(action_token); + } + + print_unknown_token_end(num_unknown_tokens); + + add_info_animation(-999, -999, -999, -999, &num_list_entries); + + freeSetupFileList(setup_file_list); + freeSetupFileHash(element_hash); + freeSetupFileHash(action_hash); + freeSetupFileHash(direction_hash); + +#if 0 + /* TEST ONLY */ + for (i=0; i < num_list_entries; i++) + printf("::: %d, %d, %d => %d\n", + info_animation_info[i].element, + info_animation_info[i].action, + info_animation_info[i].direction, + info_animation_info[i].delay); +#endif +}