From 7270af24b41bc33fbb89a97227a7696e343eacbb Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Thu, 24 Jan 2019 01:11:17 +0100 Subject: [PATCH] improved handling and displaying dropped level set zip files into window This change added the possibility to drop and extract zip files into the currently displayed level set sub-directory on the "choose level set" screen. After dropping and extracting zip files on the "choose level set" or "choose custom artwork" screens, the newly added level or artwork set is displayed and pre-selected in the list of level or artwork sets, so it can easily be loaded. (When dropping and extracting zip files with level sets on the main menu screen, the last added level set will be automatically selected and loaded.) --- src/events.c | 41 +++++++++++++------------ src/libgame/setup.c | 72 +++++++++++++++++++++++--------------------- src/libgame/setup.h | 3 +- src/libgame/system.h | 10 ++++++ src/screens.c | 68 +++++++++++++++++++++++++++++++++++++++++ src/screens.h | 1 + 6 files changed, 141 insertions(+), 54 deletions(-) diff --git a/src/events.c b/src/events.c index 3b48fc01..bc6e2eb0 100644 --- a/src/events.c +++ b/src/events.c @@ -1537,6 +1537,7 @@ static boolean HandleDropFileEvent(char *filename) return FALSE; } + TreeInfo *tree_node = NULL; int tree_type = GetZipFileTreeType(filename); char *directory = TREE_USERDIR(tree_type); @@ -1547,6 +1548,23 @@ static boolean HandleDropFileEvent(char *filename) return FALSE; } + if (tree_type == TREE_TYPE_LEVEL_DIR && + game_status == GAME_MODE_LEVELS && + leveldir_current->node_parent != NULL) + { + // extract new level set next to currently selected level set + tree_node = leveldir_current; + + // get parent directory of currently selected level set directory + directory = getLevelDirFromTreeInfo(leveldir_current->node_parent); + + // use private level directory instead of top-level package level directory + if (strPrefix(directory, options.level_directory) && + strEqual(leveldir_current->node_parent->fullpath, ".")) + directory = getUserLevelDir(NULL); + } + + // extract level or artwork set from zip file to target directory char *top_dir = ExtractZipFileIntoDirectory(filename, directory, tree_type); if (top_dir == NULL) @@ -1556,26 +1574,11 @@ static boolean HandleDropFileEvent(char *filename) return FALSE; } - AddUserTreeSetToTreeInfo(top_dir, tree_type); + // add extracted level or artwork set to tree info structure + AddTreeSetToTreeInfo(tree_node, directory, top_dir, tree_type); - // when adding new level set in main menu, select it as current level set - if (tree_type == TREE_TYPE_LEVEL_DIR && - game_status == GAME_MODE_MAIN && - !game.request_active) - { - // change current level set to newly added level set from zip file - leveldir_current = getTreeInfoFromIdentifier(leveldir_first, top_dir); - - // change current level number to first level of newly added level set - level_nr = leveldir_current->first_level; - - // redraw screen to reflect changed level set - DrawMainMenu(); - - // save this level set and level number as last selected level set - SaveLevelSetup_LastSeries(); - SaveLevelSetup_SeriesInfo(); - } + // update menu screen (and possibly change current level set) + DrawScreenAfterAddingSet(top_dir, tree_type); return TRUE; } diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 85f6e1f0..c64c95c8 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -178,7 +178,7 @@ static char *getNetworkDir(void) return network_dir; } -static char *getLevelDirFromTreeInfo(TreeInfo *node) +char *getLevelDirFromTreeInfo(TreeInfo *node) { static char *level_dir = NULL; @@ -3860,32 +3860,29 @@ void LoadLevelArtworkInfo(void) print_timestamp_done("LoadLevelArtworkInfo"); } -static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) +static boolean AddTreeSetToTreeInfoExt(TreeInfo *tree_node_old, char *tree_dir, + char *tree_subdir_new, int type) { - TreeInfo **tree_node_first, *tree_node_old, *tree_node_new; - char *tree_user_dir = TREE_USERDIR(type); - - if (tree_user_dir == NULL) // should not happen - return FALSE; - - // get first node of level or artwork tree - tree_node_first = TREE_FIRST_NODE_PTR(type); - - if (tree_node_first == NULL) // should not happen - return FALSE; - - if (type == TREE_TYPE_LEVEL_DIR) + if (tree_node_old == NULL) { - // get level info tree node of personal user level set - tree_node_old = getTreeInfoFromIdentifier(*tree_node_first, getLoginName()); - } - else - { - // get artwork info tree node of first artwork set - tree_node_old = *tree_node_first; + if (type == TREE_TYPE_LEVEL_DIR) + { + // get level info tree node of personal user level set + tree_node_old = getTreeInfoFromIdentifier(leveldir_first, getLoginName()); + } + else + { + // get artwork info tree node of first artwork set + tree_node_old = ARTWORK_FIRST_NODE(artwork, type); + } } - if (tree_node_old == NULL) // should not happen + if (tree_dir == NULL) + tree_dir = TREE_USERDIR(type); + + if (tree_node_old == NULL || + tree_dir == NULL || + tree_subdir_new == NULL) // should not happen return FALSE; int draw_deactivation_mask = GetDrawDeactivationMask(); @@ -3896,21 +3893,27 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) if (type == TREE_TYPE_LEVEL_DIR) { // load new level set config and add it next to first user level set - LoadLevelInfoFromLevelConf(&tree_node_old->next, NULL, - tree_user_dir, tree_subdir_new); + LoadLevelInfoFromLevelConf(&tree_node_old->next, + tree_node_old->node_parent, + tree_dir, tree_subdir_new); } else { // load new artwork set config and add it next to first artwork set - LoadArtworkInfoFromArtworkConf(&tree_node_old->next, NULL, - tree_user_dir, tree_subdir_new, type); + LoadArtworkInfoFromArtworkConf(&tree_node_old->next, + tree_node_old->node_parent, + tree_dir, tree_subdir_new, type); } // set draw deactivation mask to previous value SetDrawDeactivationMask(draw_deactivation_mask); - // get tree info tree node of newly added tree set - tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, tree_subdir_new); + // get first node of level or artwork info tree + TreeInfo **tree_node_first = TREE_FIRST_NODE_PTR(type); + + // get tree info node of newly added level or artwork set + TreeInfo *tree_node_new = getTreeInfoFromIdentifier(*tree_node_first, + tree_subdir_new); if (tree_node_new == NULL) // should not happen return FALSE; @@ -3919,21 +3922,22 @@ static boolean AddUserTreeSetToTreeInfoExt(char *tree_subdir_new, int type) tree_node_new->node_top = tree_node_old->node_top; tree_node_new->node_parent = tree_node_old->node_parent; - // sort tree info tree to adjust position of newly added tree set + // sort tree info to adjust position of newly added tree set sortTreeInfo(tree_node_first); return TRUE; } -void AddUserTreeSetToTreeInfo(char *tree_subdir_new, int type) +void AddTreeSetToTreeInfo(TreeInfo *tree_node, char *tree_dir, + char *tree_subdir_new, int type) { - if (!AddUserTreeSetToTreeInfoExt(tree_subdir_new, type)) - Error(ERR_EXIT, "internal tree set structure corrupted -- aborting"); + if (!AddTreeSetToTreeInfoExt(tree_node, tree_dir, tree_subdir_new, type)) + Error(ERR_EXIT, "internal tree info structure corrupted -- aborting"); } void AddUserLevelSetToLevelInfo(char *level_subdir_new) { - AddUserTreeSetToTreeInfo(level_subdir_new, TREE_TYPE_LEVEL_DIR); + AddTreeSetToTreeInfo(NULL, NULL, level_subdir_new, TREE_TYPE_LEVEL_DIR); } char *getArtworkIdentifierForUserLevelSet(int type) diff --git a/src/libgame/setup.h b/src/libgame/setup.h index 581ebb17..a6058599 100644 --- a/src/libgame/setup.h +++ b/src/libgame/setup.h @@ -280,6 +280,7 @@ char *getCommonDataDir(void); char *getPersonalDataDir(void); char *getUserGameDataDir(void); char *getSetupDir(void); +char *getLevelDirFromTreeInfo(TreeInfo *); char *getUserLevelDir(char *); char *getNetworkLevelDir(char *); char *getCurrentLevelDir(void); @@ -330,7 +331,7 @@ char *getArtworkIdentifierForUserLevelSet(int); TreeInfo *getArtworkTreeInfoForUserLevelSet(int); boolean checkIfCustomArtworkExistsForCurrentLevelSet(void); void AddUserLevelSetToLevelInfo(char *); -void AddUserTreeSetToTreeInfo(char *, int); +void AddTreeSetToTreeInfo(TreeInfo *, char *, char *, int); boolean UpdateUserLevelSet(char *, char *, char *, int); boolean CreateUserLevelSet(char *, char *, char *, int, boolean); diff --git a/src/libgame/system.h b/src/libgame/system.h index 5249adfc..bab4957e 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -753,6 +753,16 @@ &artwork.mus_first : \ NULL) +#define TREE_FIRST_NODE(t) ((t) == TREE_TYPE_LEVEL_DIR ? \ + leveldir_first : \ + (t) == TREE_TYPE_GRAPHICS_DIR ? \ + artwork.gfx_first : \ + (t) == TREE_TYPE_SOUNDS_DIR ? \ + artwork.snd_first : \ + (t) == TREE_TYPE_MUSIC_DIR ? \ + artwork.mus_first : \ + NULL) + // values for artwork handling #define LEVELDIR_ARTWORK_SET_PTR(leveldir, type) \ ((type) == ARTWORK_TYPE_GRAPHICS ? \ diff --git a/src/screens.c b/src/screens.c index 92c752af..c8324210 100644 --- a/src/screens.c +++ b/src/screens.c @@ -8905,3 +8905,71 @@ boolean DoScreenAction(int image_id) return FALSE; } + +void DrawScreenAfterAddingSet(char *tree_subdir_new, int tree_type) +{ + // get tree info node of newly added level or artwork set + TreeInfo *tree_node_first = TREE_FIRST_NODE(tree_type); + TreeInfo *tree_node_new = getTreeInfoFromIdentifier(tree_node_first, + tree_subdir_new); + if (tree_node_new == NULL) // should not happen + return; + + // if request dialog is active, do nothing + if (game.request_active) + return; + + if (game_status == GAME_MODE_MAIN && + tree_type == TREE_TYPE_LEVEL_DIR) + { + // when adding new level set in main menu, select it as current level set + + // change current level set to newly added level set from zip file + leveldir_current = tree_node_new; + + // change current level number to first level of newly added level set + level_nr = leveldir_current->first_level; + + // redraw screen to reflect changed level set + DrawMainMenu(); + + // save this level set and level number as last selected level set + SaveLevelSetup_LastSeries(); + SaveLevelSetup_SeriesInfo(); + } + else if (game_status == GAME_MODE_LEVELS && + tree_type == TREE_TYPE_LEVEL_DIR) + { + // when adding new level set in level set menu, set cursor and update screen + + leveldir_current = tree_node_new; + + DrawChooseTree(&leveldir_current); + } + else if (game_status == GAME_MODE_SETUP) + { + // when adding new artwork set in setup menu, set cursor and update screen + + if (setup_mode == SETUP_MODE_CHOOSE_GRAPHICS && + tree_type == TREE_TYPE_GRAPHICS_DIR) + { + artwork.gfx_current = tree_node_new; + + DrawChooseTree(&artwork.gfx_current); + } + else if (setup_mode == SETUP_MODE_CHOOSE_SOUNDS && + tree_type == TREE_TYPE_SOUNDS_DIR) + { + artwork.snd_current = tree_node_new; + + DrawChooseTree(&artwork.snd_current); + } + else if (setup_mode == SETUP_MODE_CHOOSE_MUSIC && + tree_type == TREE_TYPE_MUSIC_DIR) + { + artwork.mus_current = tree_node_new; + + DrawChooseTree(&artwork.mus_current); + } + } +} diff --git a/src/screens.h b/src/screens.h index 256fddb0..7d282efa 100644 --- a/src/screens.h +++ b/src/screens.h @@ -23,6 +23,7 @@ void DrawMainMenuExt(int); void DrawAndFadeInMainMenu(int); void DrawMainMenu(void); void DrawHallOfFame(int, int); +void DrawScreenAfterAddingSet(char *, int); void RedrawSetupScreenAfterFullscreenToggle(void); void RedrawSetupScreenAfterScreenRotation(int); -- 2.34.1