X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fmisc.c;h=c32aa55515b13650e2ba97a7f21cdfd85c38def3;hp=e60067ca3b6f293cd1ac60992655b3f76be67c3a;hb=c8dd3c1abd6a1daf4f7431a59db721ae7fba3d17;hpb=370a25a79d2e8df1e6e3e4cb4be39496d0190c28 diff --git a/src/misc.c b/src/misc.c index e60067ca..c32aa555 100644 --- a/src/misc.c +++ b/src/misc.c @@ -334,7 +334,12 @@ char *getPath3(char *path1, char *path2, char *path3) char *getStringCopy(char *s) { - char *s_copy = checked_malloc(strlen(s) + 1); + char *s_copy; + + if (s == NULL) + return NULL; + + s_copy = checked_malloc(strlen(s) + 1); strcpy(s_copy, s); return s_copy; @@ -438,7 +443,7 @@ void GetOptions(char *argv[]) "Options:\n" " -d, --display machine:0 X server display\n" " -b, --basepath directory alternative base directory\n" - " -l, --levels directory alternative level directory\n" + " -l, --level directory alternative level directory\n" " -s, --serveronly only start network server\n" " -n, --network network multiplayer game\n" " -v, --verbose verbose mode\n", @@ -1076,10 +1081,11 @@ struct LevelDirInfo *newLevelDirInfo() return checked_calloc(sizeof(struct LevelDirInfo)); } -void pushLevelDirInfo(struct LevelDirInfo *node) +void pushLevelDirInfo(struct LevelDirInfo **node_first, + struct LevelDirInfo *node_new) { - node->next = leveldir_first; - leveldir_first = node; + node_new->next = *node_first; + *node_first = node_new; } int numLevelDirInfo(struct LevelDirInfo *node) @@ -1095,9 +1101,47 @@ int numLevelDirInfo(struct LevelDirInfo *node) return num; } +boolean validLevelSeries(struct LevelDirInfo *node) +{ + return (node != NULL && !node->node_group && !node->parent_link); +} + +struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node) +{ + if (node == NULL) /* start with first level directory entry */ + return getFirstValidLevelSeries(leveldir_first); + else if (node->node_group) /* enter level group (step down into tree) */ + return getFirstValidLevelSeries(node->node_group); + else if (node->parent_link) /* skip start entry of level group */ + { + if (node->next) /* get first real level series entry */ + return getFirstValidLevelSeries(node->next); + else /* leave empty level group and go on */ + return getFirstValidLevelSeries(node->node_parent->next); + } + else /* this seems to be a regular level series */ + return node; +} + +struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node) +{ + if (node == NULL) + return NULL; + + if (node->node_parent == NULL) /* top level group */ + return leveldir_first; + else /* sub level group */ + return node->node_parent->node_group; +} + +int numLevelDirInfoInGroup(struct LevelDirInfo *node) +{ + return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node)); +} + int posLevelDirInfo(struct LevelDirInfo *node) { - struct LevelDirInfo *node_cmp = leveldir_first; + struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node); int pos = 0; while (node_cmp) @@ -1129,6 +1173,58 @@ struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos) return node_default; } +struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node, + char *filename) +{ + if (filename == NULL) + return NULL; + + while (node) + { + if (node->node_group) + { + struct LevelDirInfo *node_group; + + node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename); + + if (node_group) + return node_group; + } + else if (!node->parent_link) + { + if (strcmp(filename, node->filename) == 0) + return node; + } + + node = node->next; + } + + return NULL; +} + +struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename) +{ + return getLevelDirInfoFromFilenameExt(leveldir_first, filename); +} + +void dumpLevelDirInfo(struct LevelDirInfo *node, int depth) +{ + int i; + + while (node) + { + for (i=0; ifilename); + + if (node->node_group != NULL) + dumpLevelDirInfo(node->node_group, depth + 1); + + node = node->next; + } +} + void sortLevelDirInfo(struct LevelDirInfo **node_first, int (*compare_function)(const void *, const void *)) { @@ -1137,7 +1233,7 @@ void sortLevelDirInfo(struct LevelDirInfo **node_first, struct LevelDirInfo *node = *node_first; int i = 0; - if (num_nodes < 2) /* a list with only one element is always sorted... */ + if (num_nodes == 0) return; /* allocate array for sorting structure pointers */ @@ -1165,6 +1261,16 @@ void sortLevelDirInfo(struct LevelDirInfo **node_first, *node_first = sort_array[0]; free(sort_array); + + /* now recursively sort the level group structures */ + node = *node_first; + while (node) + { + if (node->node_group != NULL) + sortLevelDirInfo(&node->node_group, compare_function); + + node = node->next; + } }