X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsetup.c;h=dbfec24dd8202d1a924230408950d822064c0dd6;hb=9d46a87f054d241cbfd96c9bec4694c7d1c30f53;hp=315c615f28b41395bb9e89b779f0b0ef587832d4;hpb=42f2880cf77f775665ed25badf639e963a6dbdbf;p=rocksndiamonds.git diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 315c615f..dbfec24d 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -49,6 +49,16 @@ static char *levelclass_desc[NUM_LEVELCLASS_DESC] = #define MAX_COOKIE_LEN 256 +#define TREE_NODE_TYPE_DEFAULT 0 +#define TREE_NODE_TYPE_PARENT 1 +#define TREE_NODE_TYPE_GROUP 2 +#define TREE_NODE_TYPE_COPY 3 + +#define TREE_NODE_TYPE(ti) (ti->node_group ? TREE_NODE_TYPE_GROUP : \ + ti->parent_link ? TREE_NODE_TYPE_PARENT : \ + ti->is_copy ? TREE_NODE_TYPE_COPY : \ + TREE_NODE_TYPE_DEFAULT) + static void setTreeInfoToDefaults(TreeInfo *, int); static TreeInfo *getTreeInfoCopy(TreeInfo *ti); @@ -104,6 +114,19 @@ static char *getScoreDir(char *level_subdir) return score_dir; } +static char *getScoreTapeDir(char *level_subdir, int nr) +{ + static char *score_tape_dir = NULL; + char tape_subdir[MAX_FILENAME_LEN]; + + checked_free(score_tape_dir); + + sprintf(tape_subdir, "%03d", nr); + score_tape_dir = getPath2(getScoreDir(level_subdir), tape_subdir); + + return score_tape_dir; +} + static char *getUserSubdir(int nr) { static char user_subdir[16] = { 0 }; @@ -584,6 +607,34 @@ char *getScoreFilename(int nr) return filename; } +char *getScoreTapeBasename(char *name) +{ + static char basename[MAX_FILENAME_LEN]; + char basename_raw[MAX_FILENAME_LEN]; + char timestamp[20]; + + sprintf(timestamp, "%s", getCurrentTimestamp()); + sprintf(basename_raw, "%s-%s", timestamp, name); + sprintf(basename, "%s-%08x", timestamp, get_hash_from_key(basename_raw)); + + return basename; +} + +char *getScoreTapeFilename(char *basename_no_ext, int nr) +{ + static char *filename = NULL; + char basename[MAX_FILENAME_LEN]; + + checked_free(filename); + + sprintf(basename, "%s.%s", basename_no_ext, TAPEFILE_EXTENSION); + + // used instead of "leveldir_current->subdir" (for network games) + filename = getPath2(getScoreTapeDir(levelset.identifier, nr), basename); + + return filename; +} + char *getSetupFilename(void) { static char *filename = NULL; @@ -1065,6 +1116,15 @@ void InitScoreDirectory(char *level_subdir) createDirectory(getScoreDir(level_subdir), "level score", permissions); } +void InitScoreTapeDirectory(char *level_subdir, int nr) +{ + int permissions = (program.global_scores ? PERMS_PUBLIC : PERMS_PRIVATE); + + InitScoreDirectory(level_subdir); + + createDirectory(getScoreTapeDir(level_subdir, nr), "score tape", permissions); +} + static void SaveUserLevelInfo(void); void InitUserLevelDirectory(char *level_subdir) @@ -1154,7 +1214,21 @@ int numTreeInfo(TreeInfo *node) boolean validLevelSeries(TreeInfo *node) { - return (node != NULL && !node->node_group && !node->parent_link); + // in a number of cases, tree node is no valid level set + if (node == NULL || node->node_group || node->parent_link || node->is_copy) + return FALSE; + + return TRUE; +} + +TreeInfo *getValidLevelSeries(TreeInfo *node, TreeInfo *default_node) +{ + if (validLevelSeries(node)) + return node; + else if (node->is_copy) + return getTreeInfoFromIdentifier(leveldir_first, node->identifier); + else + return getFirstValidTreeInfoEntry(default_node); } TreeInfo *getFirstValidTreeInfoEntry(TreeInfo *node) @@ -1226,29 +1300,25 @@ TreeInfo *getTreeInfoFromPos(TreeInfo *node, int pos) } static TreeInfo *getTreeInfoFromIdentifierExt(TreeInfo *node, char *identifier, - boolean include_node_groups) + int node_type_wanted) { if (identifier == NULL) return NULL; while (node) { + if (TREE_NODE_TYPE(node) == node_type_wanted && + strEqual(identifier, node->identifier)) + return node; + if (node->node_group) { - if (include_node_groups && strEqual(identifier, node->identifier)) - return node; - TreeInfo *node_group = getTreeInfoFromIdentifierExt(node->node_group, identifier, - include_node_groups); + node_type_wanted); if (node_group) return node_group; } - else if (!node->parent_link) - { - if (strEqual(identifier, node->identifier)) - return node; - } node = node->next; } @@ -1258,7 +1328,7 @@ static TreeInfo *getTreeInfoFromIdentifierExt(TreeInfo *node, char *identifier, TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier) { - return getTreeInfoFromIdentifierExt(node, identifier, FALSE); + return getTreeInfoFromIdentifierExt(node, identifier, TREE_NODE_TYPE_DEFAULT); } static TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent, @@ -2520,6 +2590,7 @@ static void setTreeInfoToDefaults(TreeInfo *ti, int type) ti->sort_priority = LEVELCLASS_UNDEFINED; // default: least priority ti->latest_engine = FALSE; // default: get from level ti->parent_link = FALSE; + ti->is_copy = FALSE; ti->in_user_dir = FALSE; ti->user_defined = FALSE; ti->color = 0; @@ -2601,6 +2672,7 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ti, TreeInfo *parent) ti->sort_priority = parent->sort_priority; ti->latest_engine = parent->latest_engine; ti->parent_link = FALSE; + ti->is_copy = FALSE; ti->in_user_dir = parent->in_user_dir; ti->user_defined = parent->user_defined; ti->color = parent->color; @@ -2701,6 +2773,7 @@ static TreeInfo *getTreeInfoCopy(TreeInfo *ti) ti_copy->level_group = ti->level_group; ti_copy->parent_link = ti->parent_link; + ti_copy->is_copy = ti->is_copy; ti_copy->in_user_dir = ti->in_user_dir; ti_copy->user_defined = ti->user_defined; ti_copy->readonly = ti->readonly; @@ -4523,7 +4596,6 @@ static void InitLastPlayedLevels_ParentNode(void) void UpdateLastPlayedLevels_TreeInfo(void) { char **last_level_series = setup.level_setup.last_level_series; - boolean reset_leveldir_current = FALSE; LevelDirTree *leveldir_last; TreeInfo **node_new = NULL; int i; @@ -4533,13 +4605,9 @@ void UpdateLastPlayedLevels_TreeInfo(void) InitLastPlayedLevels_ParentNode(); - // check if current level set is from "last played" sub-tree to be rebuilt - reset_leveldir_current = strEqual(leveldir_current->node_parent->identifier, - TOKEN_STR_LAST_LEVEL_SERIES); - leveldir_last = getTreeInfoFromIdentifierExt(leveldir_first, TOKEN_STR_LAST_LEVEL_SERIES, - TRUE); + TREE_NODE_TYPE_GROUP); if (leveldir_last == NULL) return; @@ -4547,16 +4615,22 @@ void UpdateLastPlayedLevels_TreeInfo(void) freeTreeInfo(*node_new); + *node_new = NULL; + for (i = 0; last_level_series[i] != NULL; i++) { LevelDirTree *node_last = getTreeInfoFromIdentifier(leveldir_first, last_level_series[i]); + if (node_last == NULL) + continue; *node_new = getTreeInfoCopy(node_last); // copy complete node (*node_new)->node_top = &leveldir_first; // correct top node link (*node_new)->node_parent = leveldir_last; // correct parent node link + (*node_new)->is_copy = TRUE; // mark entry as node copy + (*node_new)->node_group = NULL; (*node_new)->next = NULL; @@ -4564,10 +4638,6 @@ void UpdateLastPlayedLevels_TreeInfo(void) node_new = &((*node_new)->next); } - - if (reset_leveldir_current) - leveldir_current = getTreeInfoFromIdentifier(leveldir_first, - last_level_series[0]); } static void UpdateLastPlayedLevels_List(void) @@ -4589,6 +4659,35 @@ static void UpdateLastPlayedLevels_List(void) setString(&last_level_series[0], leveldir_current->identifier); } +static TreeInfo *StoreOrRestoreLastPlayedLevels(TreeInfo *node, boolean store) +{ + static char *identifier = NULL; + + if (store) + { + setString(&identifier, (node && node->is_copy ? node->identifier : NULL)); + + return NULL; // not used + } + else + { + TreeInfo *node_new = getTreeInfoFromIdentifierExt(leveldir_first, + identifier, + TREE_NODE_TYPE_COPY); + return (node_new != NULL ? node_new : node); + } +} + +void StoreLastPlayedLevels(TreeInfo *node) +{ + StoreOrRestoreLastPlayedLevels(node, TRUE); +} + +void RestoreLastPlayedLevels(TreeInfo **node) +{ + *node = StoreOrRestoreLastPlayedLevels(*node, FALSE); +} + void LoadLevelSetup_LastSeries(void) { // --------------------------------------------------------------------------