From 370a25a79d2e8df1e6e3e4cb4be39496d0190c28 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 2 Oct 1999 15:07:09 +0200 Subject: [PATCH] rnd-19991002-1-src --- src/editor.c | 6 +- src/files.c | 218 ++++++++++++++++++++++++-------------------------- src/files.h | 6 +- src/game.c | 8 +- src/init.c | 2 +- src/main.c | 4 +- src/main.h | 7 +- src/misc.c | 107 ++++++++++++++++++++++++- src/misc.h | 9 ++- src/network.c | 35 +++++--- src/screens.c | 98 ++++++++++++----------- src/tools.c | 6 +- 12 files changed, 312 insertions(+), 194 deletions(-) diff --git a/src/editor.c b/src/editor.c index 091b0186..5b77b1fc 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1911,8 +1911,8 @@ static void MapControlButtons() /* map buttons to select level */ counter_id = ED_COUNTER_ID_SELECT_LEVEL; ModifyEditorCounterLimits(counter_id, - leveldir[leveldir_nr].first_level, - leveldir[leveldir_nr].last_level); + leveldir_current->first_level, + leveldir_current->last_level); ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value); MapCounterButtons(counter_id); } @@ -3832,7 +3832,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_SAVE: - if (leveldir[leveldir_nr].readonly) + if (leveldir_current->readonly) { Request("This level is read only !", REQ_CONFIRM); break; diff --git a/src/files.c b/src/files.c index f1b581fe..b3d280c6 100644 --- a/src/files.c +++ b/src/files.c @@ -284,10 +284,10 @@ static char *getLevelFilename(int nr) free(filename); sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION); - filename = getPath3((leveldir[leveldir_nr].user_defined ? + filename = getPath3((leveldir_current->user_defined ? getUserLevelDir("") : options.level_directory), - leveldir[leveldir_nr].filename, + leveldir_current->filename, basename); return filename; @@ -302,7 +302,7 @@ static char *getTapeFilename(int nr) free(filename); sprintf(basename, "%03d.%s", nr, TAPEFILE_EXTENSION); - filename = getPath2(getTapeDir(leveldir[leveldir_nr].filename), basename); + filename = getPath2(getTapeDir(leveldir_current->filename), basename); return filename; } @@ -316,7 +316,7 @@ static char *getScoreFilename(int nr) free(filename); sprintf(basename, "%03d.%s", nr, SCOREFILE_EXTENSION); - filename = getPath2(getScoreDir(leveldir[leveldir_nr].filename), basename); + filename = getPath2(getScoreDir(leveldir_current->filename), basename); return filename; } @@ -411,21 +411,21 @@ static void setLevelInfoToDefaults() BorderElement = EL_BETON; /* try to determine better author name than 'anonymous' */ - if (strcmp(leveldir[leveldir_nr].author, ANONYMOUS_NAME) != 0) + if (strcmp(leveldir_current->author, ANONYMOUS_NAME) != 0) { - strncpy(level.author, leveldir[leveldir_nr].author, MAX_LEVEL_AUTHOR_LEN); + strncpy(level.author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN); level.author[MAX_LEVEL_AUTHOR_LEN] = '\0'; } else { - switch (LEVELCLASS(&leveldir[leveldir_nr])) + switch (LEVELCLASS(leveldir_current)) { case LEVELCLASS_TUTORIAL: strcpy(level.author, PROGRAM_AUTHOR_STRING); break; case LEVELCLASS_CONTRIBUTION: - strncpy(level.author, leveldir[leveldir_nr].name,MAX_LEVEL_AUTHOR_LEN); + strncpy(level.author, leveldir_current->name,MAX_LEVEL_AUTHOR_LEN); level.author[MAX_LEVEL_AUTHOR_LEN] = '\0'; break; @@ -599,7 +599,7 @@ void LoadLevel(int level_nr) /* player was faster than monsters in pre-1.0 levels */ if (file_version == FILE_VERSION_1_0 && - IS_LEVELCLASS_CONTRIBUTION(&leveldir[leveldir_nr])) + IS_LEVELCLASS_CONTRIBUTION(leveldir_current)) { Error(ERR_WARN, "level file '%s' has version number 1.0", filename); Error(ERR_WARN, "using high speed movement for player"); @@ -868,7 +868,7 @@ void SaveTape(int level_nr) byte store_participating_players; int num_participating_players; - InitTapeDirectory(leveldir[leveldir_nr].filename); + InitTapeDirectory(leveldir_current->filename); /* if a tape still exists, ask to overwrite it */ if (access(filename, F_OK) == 0) @@ -993,7 +993,7 @@ void SaveScore(int level_nr) char *filename = getScoreFilename(level_nr); FILE *file; - InitScoreDirectory(leveldir[leveldir_nr].filename); + InitScoreDirectory(leveldir_current->filename); if (!(file = fopen(filename, "w"))) { @@ -1529,24 +1529,28 @@ static void decodeSetupFileList(struct SetupFileList *setup_file_list) } } -int getLevelSeriesNrFromLevelSeriesName(char *level_series_name) +struct LevelDirInfo *getLevelDirInfoFromLevelDirName(char *level_dir_name) { - int i; + struct LevelDirInfo *leveldir_node = leveldir_first; + + if (level_dir_name == NULL) + return NULL; - if (!level_series_name) - return 0; + while (leveldir_node) + { + if (strcmp(level_dir_name, leveldir_node->name) == 0) + return leveldir_node; /* return success value */ - for (i=0; inext; + } - return 0; + return NULL; } static int compareLevelDirInfoEntries(const void *object1, const void *object2) { - const struct LevelDirInfo *entry1 = object1; - const struct LevelDirInfo *entry2 = object2; + const struct LevelDirInfo *entry1 = *((struct LevelDirInfo **)object1); + const struct LevelDirInfo *entry2 = *((struct LevelDirInfo **)object2); int compare_result; if (entry1->sort_priority == entry2->sort_priority) @@ -1567,26 +1571,24 @@ static int compareLevelDirInfoEntries(const void *object1, const void *object2) return compare_result; } -static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry) +static void LoadLevelInfoFromLevelDir(char *level_directory) { DIR *dir; - struct stat file_status; - char *directory = NULL; - char *filename = NULL; - struct SetupFileList *setup_file_list = NULL; struct dirent *dir_entry; - int i, current_entry = start_entry; + boolean valid_entry_found = FALSE; if ((dir = opendir(level_directory)) == NULL) { Error(ERR_WARN, "cannot read level directory '%s'", level_directory); - return current_entry; + return; } - while (current_entry < MAX_LEVDIR_ENTRIES) + while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */ { - if ((dir_entry = readdir(dir)) == NULL) /* last directory entry */ - break; + struct stat file_status; + char *directory = NULL; + char *filename = NULL; + struct SetupFileList *setup_file_list = NULL; /* skip entries for current and parent directory */ if (strcmp(dir_entry->d_name, ".") == 0 || @@ -1607,51 +1609,47 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry) if (setup_file_list) { -#if 0 - DrawInitText(dir_entry->d_name, 150, FC_YELLOW); -#endif + struct LevelDirInfo *leveldir_new = newLevelDirInfo(); + int i; checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE); - setLevelDirInfoToDefaults(&leveldir[current_entry]); + setLevelDirInfoToDefaults(leveldir_new); - ldi = leveldir[current_entry]; + ldi = *leveldir_new; for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++) setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text)); - leveldir[current_entry] = ldi; + *leveldir_new = ldi; -#if 1 - DrawInitText(leveldir[current_entry].name, 150, FC_YELLOW); -#endif + DrawInitText(leveldir_new->name, 150, FC_YELLOW); + + if (leveldir_new->name_short == NULL) + leveldir_new->name_short = getStringCopy(leveldir_new->name); - if (leveldir[current_entry].name_short == NULL) - leveldir[current_entry].name_short = - getStringCopy(leveldir[current_entry].name); + if (leveldir_new->name_sorting == NULL) + leveldir_new->name_sorting = getStringCopy(leveldir_new->name); - if (leveldir[current_entry].name_sorting == NULL) - leveldir[current_entry].name_sorting = - getStringCopy(leveldir[current_entry].name); + leveldir_new->filename = getStringCopy(dir_entry->d_name); - leveldir[current_entry].filename = getStringCopy(dir_entry->d_name); - leveldir[current_entry].last_level = - leveldir[current_entry].first_level + - leveldir[current_entry].levels - 1; - leveldir[current_entry].user_defined = + if (leveldir_new->levels < 1) + leveldir_new->levels = 1; + + leveldir_new->last_level = + leveldir_new->first_level + leveldir_new->levels - 1; + + leveldir_new->user_defined = (level_directory == options.level_directory ? FALSE : TRUE); - leveldir[current_entry].color = LEVELCOLOR(&leveldir[current_entry]); - leveldir[current_entry].class_desc = - getLevelClassDescription(&leveldir[current_entry]); -#if 0 - leveldir[current_entry].handicap_level = - leveldir[current_entry].first_level; /* default value */ -#else - leveldir[current_entry].handicap_level = - (leveldir[current_entry].user_defined ? - leveldir[current_entry].last_level : - leveldir[current_entry].first_level); -#endif + leveldir_new->color = LEVELCOLOR(leveldir_new); + leveldir_new->class_desc = getLevelClassDescription(leveldir_new); + + leveldir_new->handicap_level = /* set handicap to default value */ + (leveldir_new->user_defined ? + leveldir_new->last_level : + leveldir_new->first_level); + + pushLevelDirInfo(leveldir_new); /* add new LevelDirInfo to list */ freeSetupFileList(setup_file_list); - current_entry++; + valid_entry_found = TRUE; } else Error(ERR_WARN, "ignoring level directory '%s'", directory); @@ -1662,39 +1660,34 @@ static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry) closedir(dir); - if (current_entry == MAX_LEVDIR_ENTRIES) - { - Error(ERR_WARN, "maximum of %d level directories reached", current_entry); - Error(ERR_WARN, "remaining level directories ignored in directory '%s'", - level_directory); - } - else if (current_entry == start_entry) + if (!valid_entry_found) Error(ERR_WARN, "cannot find any valid level series in directory '%s'", level_directory); - - return current_entry; } void LoadLevelInfo() { InitUserLevelDirectory(getLoginName()); - num_leveldirs = 0; - leveldir_nr = 0; - DrawInitText("Loading level series:", 120, FC_GREEN); - num_leveldirs = LoadLevelInfoFromLevelDir(options.level_directory, - num_leveldirs); - num_leveldirs = LoadLevelInfoFromLevelDir(getUserLevelDir(""), - num_leveldirs); + LoadLevelInfoFromLevelDir(options.level_directory); + LoadLevelInfoFromLevelDir(getUserLevelDir("")); + + num_leveldirs = numLevelDirInfo(leveldir_first); + leveldir_current = leveldir_first; if (num_leveldirs == 0) Error(ERR_EXIT, "cannot find any valid level series in any directory"); +#if 0 if (num_leveldirs > 1) qsort(leveldir, num_leveldirs, sizeof(struct LevelDirInfo), compareLevelDirInfoEntries); +#else + if (num_leveldirs > 1) + sortLevelDirInfo(&leveldir_first, compareLevelDirInfoEntries); +#endif } static void SaveUserLevelInfo() @@ -1896,7 +1889,7 @@ void LoadLevelSetup_LastSeries() struct SetupFileList *level_setup_list = NULL; /* always start with reliable default values */ - leveldir_nr = 0; + leveldir_current = leveldir_first; /* ----------------------------------------------------------------------- */ /* ~/.rocksndiamonds/levelsetup.conf */ @@ -1909,7 +1902,9 @@ void LoadLevelSetup_LastSeries() char *last_level_series = getTokenValue(level_setup_list, TOKEN_STR_LAST_LEVEL_SERIES); - leveldir_nr = getLevelSeriesNrFromLevelSeriesName(last_level_series); + leveldir_current = getLevelDirInfoFromLevelDirName(last_level_series); + if (leveldir_current == NULL) + leveldir_current = leveldir_first; checkSetupFileListIdentifier(level_setup_list, LEVELSETUP_COOKIE); @@ -1924,7 +1919,7 @@ void LoadLevelSetup_LastSeries() void SaveLevelSetup_LastSeries() { char *filename; - char *level_subdir = leveldir[leveldir_nr].filename; + char *level_subdir = leveldir_current->filename; FILE *file; /* ----------------------------------------------------------------------- */ @@ -1953,7 +1948,7 @@ void SaveLevelSetup_LastSeries() chmod(filename, SETUP_PERMS); } -static void checkSeriesInfo(int leveldir_nr) +static void checkSeriesInfo() { static char *level_directory = NULL; DIR *dir; @@ -1961,10 +1956,10 @@ static void checkSeriesInfo(int leveldir_nr) /* check for more levels besides the 'levels' field of 'levelinfo.conf' */ - level_directory = getPath2((leveldir[leveldir_nr].user_defined ? + level_directory = getPath2((leveldir_current->user_defined ? getUserLevelDir("") : options.level_directory), - leveldir[leveldir_nr].filename); + leveldir_current->filename); if ((dir = opendir(level_directory)) == NULL) { @@ -1986,15 +1981,15 @@ static void checkSeriesInfo(int leveldir_nr) levelnum_value = atoi(levelnum_str); - if (levelnum_value < leveldir[leveldir_nr].first_level) + if (levelnum_value < leveldir_current->first_level) { Error(ERR_WARN, "additional level %d found", levelnum_value); - leveldir[leveldir_nr].first_level = levelnum_value; + leveldir_current->first_level = levelnum_value; } - else if (levelnum_value > leveldir[leveldir_nr].last_level) + else if (levelnum_value > leveldir_current->last_level) { Error(ERR_WARN, "additional level %d found", levelnum_value); - leveldir[leveldir_nr].last_level = levelnum_value; + leveldir_current->last_level = levelnum_value; } } } @@ -2002,27 +1997,22 @@ static void checkSeriesInfo(int leveldir_nr) closedir(dir); } -void LoadLevelSetup_SeriesInfo(int leveldir_nr) +void LoadLevelSetup_SeriesInfo() { char *filename; struct SetupFileList *level_setup_list = NULL; - char *level_subdir = leveldir[leveldir_nr].filename; + char *level_subdir = leveldir_current->filename; /* always start with reliable default values */ -#if 0 - level_nr = 0; - leveldir[leveldir_nr].handicap_level = 0; -#else - level_nr = leveldir[leveldir_nr].first_level; -#endif + level_nr = leveldir_current->first_level; - checkSeriesInfo(leveldir_nr); + checkSeriesInfo(leveldir_current); /* ----------------------------------------------------------------------- */ /* ~/.rocksndiamonds/levelsetup//levelsetup.conf */ /* ----------------------------------------------------------------------- */ - level_subdir = leveldir[leveldir_nr].filename; + level_subdir = leveldir_current->filename; filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME); @@ -2036,10 +2026,10 @@ void LoadLevelSetup_SeriesInfo(int leveldir_nr) { level_nr = atoi(token_value); - if (level_nr < leveldir[leveldir_nr].first_level) - level_nr = leveldir[leveldir_nr].first_level; - if (level_nr > leveldir[leveldir_nr].last_level) - level_nr = leveldir[leveldir_nr].last_level; + if (level_nr < leveldir_current->first_level) + level_nr = leveldir_current->first_level; + if (level_nr > leveldir_current->last_level) + level_nr = leveldir_current->last_level; } token_value = getTokenValue(level_setup_list, TOKEN_STR_HANDICAP_LEVEL); @@ -2048,15 +2038,15 @@ void LoadLevelSetup_SeriesInfo(int leveldir_nr) { int level_nr = atoi(token_value); - if (level_nr < leveldir[leveldir_nr].first_level) - level_nr = leveldir[leveldir_nr].first_level; - if (level_nr > leveldir[leveldir_nr].last_level + 1) - level_nr = leveldir[leveldir_nr].last_level; + if (level_nr < leveldir_current->first_level) + level_nr = leveldir_current->first_level; + if (level_nr > leveldir_current->last_level + 1) + level_nr = leveldir_current->last_level; - if (leveldir[leveldir_nr].user_defined) - level_nr = leveldir[leveldir_nr].last_level; + if (leveldir_current->user_defined) + level_nr = leveldir_current->last_level; - leveldir[leveldir_nr].handicap_level = level_nr; + leveldir_current->handicap_level = level_nr; } checkSetupFileListIdentifier(level_setup_list, LEVELSETUP_COOKIE); @@ -2069,12 +2059,12 @@ void LoadLevelSetup_SeriesInfo(int leveldir_nr) free(filename); } -void SaveLevelSetup_SeriesInfo(int leveldir_nr) +void SaveLevelSetup_SeriesInfo() { char *filename; - char *level_subdir = leveldir[leveldir_nr].filename; + char *level_subdir = leveldir_current->filename; char *level_nr_str = int2str(level_nr, 0); - char *handicap_level_str = int2str(leveldir[leveldir_nr].handicap_level, 0); + char *handicap_level_str = int2str(leveldir_current->handicap_level, 0); FILE *file; /* ----------------------------------------------------------------------- */ diff --git a/src/files.h b/src/files.h index 79971cd6..cc094458 100644 --- a/src/files.h +++ b/src/files.h @@ -25,15 +25,15 @@ void SaveTape(int); void LoadScore(int); void SaveScore(int); -int getLastPlayedLevelOfLevelSeries(char *); +struct LevelDirInfo *getLevelDirInfoFromLevelDirName(char *); void LoadLevelInfo(void); void LoadSetup(void); void SaveSetup(void); void LoadLevelSetup_LastSeries(void); void SaveLevelSetup_LastSeries(void); -void LoadLevelSetup_SeriesInfo(int); -void SaveLevelSetup_SeriesInfo(int); +void LoadLevelSetup_SeriesInfo(void); +void SaveLevelSetup_SeriesInfo(void); #ifdef MSDOS void initErrorFile(); diff --git a/src/game.c b/src/game.c index 8c18d89c..da36f241 100644 --- a/src/game.c +++ b/src/game.c @@ -966,12 +966,12 @@ void GameWon() SaveTape(tape.level_nr); /* Ask to save tape */ } - if (level_nr == leveldir[leveldir_nr].handicap_level) + if (level_nr == leveldir_current->handicap_level) { - leveldir[leveldir_nr].handicap_level++; - SaveLevelSetup_SeriesInfo(leveldir_nr); + leveldir_current->handicap_level++; + SaveLevelSetup_SeriesInfo(); - if (level_nr < leveldir[leveldir_nr].last_level) + if (level_nr < leveldir_current->last_level) raise_level = TRUE; } diff --git a/src/init.c b/src/init.c index 3e98c552..64b0ae4e 100644 --- a/src/init.c +++ b/src/init.c @@ -111,7 +111,7 @@ void InitLevelAndPlayerInfo() LoadLevelInfo(); /* global level info */ LoadSetup(); /* global setup info */ LoadLevelSetup_LastSeries(); /* last played series info */ - LoadLevelSetup_SeriesInfo(leveldir_nr); /* last played level info */ + LoadLevelSetup_SeriesInfo(); /* last played level info */ } void InitNetworkServer() diff --git a/src/main.c b/src/main.c index cbaaab66..3182b47d 100644 --- a/src/main.c +++ b/src/main.c @@ -84,7 +84,7 @@ short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA]; unsigned long Elementeigenschaften1[MAX_ELEMENTS]; unsigned long Elementeigenschaften2[MAX_ELEMENTS]; -int level_nr, leveldir_nr, num_leveldirs; +int level_nr, num_leveldirs; int lev_fieldx,lev_fieldy, scroll_x,scroll_y; int FX = SX, FY = SY, ScrollStepSize; @@ -102,7 +102,7 @@ int FrameCounter, TimeFrames, TimePlayed, TimeLeft; boolean network_player_action_received = FALSE; -struct LevelDirInfo leveldir[MAX_LEVDIR_ENTRIES]; +struct LevelDirInfo *leveldir_first = NULL, *leveldir_current = NULL; struct LevelInfo level; struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL; struct HiScore highscore[MAX_SCORE_ENTRIES]; diff --git a/src/main.h b/src/main.h index 27acc1e1..0ec85dcb 100644 --- a/src/main.h +++ b/src/main.h @@ -217,7 +217,6 @@ typedef unsigned char byte; #define MAX_LEVEL_NAME_LEN 32 #define MAX_LEVEL_AUTHOR_LEN 32 #define MAX_TAPELEN (1000 * 50) /* max. time * framerate */ -#define MAX_LEVDIR_ENTRIES 250 /* max. level directories */ #define MAX_SCORE_ENTRIES 100 #define MAX_ELEMENTS 700 /* 500 static + 200 runtime */ #define MAX_NUM_AMOEBA 100 @@ -400,6 +399,8 @@ struct LevelDirInfo int color; /* color to use on selection screen for this level */ char *class_desc; /* description of level series class */ int handicap_level; /* number of the lowest unsolved level */ + + struct LevelDirInfo *next; }; struct TapeInfo @@ -495,7 +496,7 @@ extern short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA]; extern unsigned long Elementeigenschaften1[MAX_ELEMENTS]; extern unsigned long Elementeigenschaften2[MAX_ELEMENTS]; -extern int level_nr, leveldir_nr, num_leveldirs; +extern int level_nr, num_leveldirs; extern int lev_fieldx,lev_fieldy, scroll_x,scroll_y; extern int FX,FY, ScrollStepSize; @@ -514,7 +515,7 @@ extern int SiebCount; extern boolean network_player_action_received; -extern struct LevelDirInfo leveldir[]; +extern struct LevelDirInfo *leveldir_first, *leveldir_current; extern struct LevelInfo level; extern struct PlayerInfo stored_player[], *local_player; extern struct HiScore highscore[]; diff --git a/src/misc.c b/src/misc.c index 3da33597..e60067ca 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1067,9 +1067,110 @@ int getJoystickNrFromDeviceName(char *device_name) return joystick_nr; } -/* ----------------------------------------------------------------- */ -/* the following is only for debugging purpose and normally not used */ -/* ----------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ +/* some functions to handle lists of level directories */ +/* ------------------------------------------------------------------------- */ + +struct LevelDirInfo *newLevelDirInfo() +{ + return checked_calloc(sizeof(struct LevelDirInfo)); +} + +void pushLevelDirInfo(struct LevelDirInfo *node) +{ + node->next = leveldir_first; + leveldir_first = node; +} + +int numLevelDirInfo(struct LevelDirInfo *node) +{ + int num = 0; + + while (node) + { + num++; + node = node->next; + } + + return num; +} + +int posLevelDirInfo(struct LevelDirInfo *node) +{ + struct LevelDirInfo *node_cmp = leveldir_first; + int pos = 0; + + while (node_cmp) + { + if (node_cmp == node) + return pos; + + pos++; + node_cmp = node_cmp->next; + } + + return 0; +} + +struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos) +{ + struct LevelDirInfo *node_default = node; + int pos_cmp = 0; + + while (node) + { + if (pos_cmp == pos) + return node; + + pos_cmp++; + node = node->next; + } + + return node_default; +} + +void sortLevelDirInfo(struct LevelDirInfo **node_first, + int (*compare_function)(const void *, const void *)) +{ + int num_nodes = numLevelDirInfo(*node_first); + struct LevelDirInfo **sort_array; + struct LevelDirInfo *node = *node_first; + int i = 0; + + if (num_nodes < 2) /* a list with only one element is always sorted... */ + return; + + /* allocate array for sorting structure pointers */ + sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *)); + + /* writing structure pointers to sorting array */ + while (i < num_nodes && node) /* double boundary check... */ + { + sort_array[i] = node; + + i++; + node = node->next; + } + + /* sorting the structure pointers in the sorting array */ + qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *), + compare_function); + + /* update the linkage of list elements with the sorted node array */ + for (i=0; inext = sort_array[i + 1]; + sort_array[num_nodes - 1]->next = NULL; + + /* update the linkage of the main list anchor pointer */ + *node_first = sort_array[0]; + + free(sort_array); +} + + +/* ------------------------------------------------------------------------- */ +/* the following is only for debugging purpose and normally not used */ +/* ------------------------------------------------------------------------- */ #define DEBUG_NUM_TIMESTAMPS 3 diff --git a/src/misc.h b/src/misc.h index d45fceba..591ca06b 100644 --- a/src/misc.h +++ b/src/misc.h @@ -78,7 +78,14 @@ char *getJoyNameFromJoySymbol(int); int getJoySymbolFromJoyName(char *); int getJoystickNrFromDeviceName(char *); +struct LevelDirInfo *newLevelDirInfo(); +void pushLevelDirInfo(struct LevelDirInfo *); +int numLevelDirInfo(struct LevelDirInfo *); +int posLevelDirInfo(struct LevelDirInfo *); +struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *, int); +void sortLevelDirInfo(struct LevelDirInfo **, + int (*compare_function)(const void *, const void *)); + void debug_print_timestamp(int, char *); -void print_debug(char *); #endif /* MISC_H */ diff --git a/src/network.c b/src/network.c index e16c0d9f..b3b8eca2 100644 --- a/src/network.c +++ b/src/network.c @@ -223,20 +223,23 @@ void SendToServer_StartPlaying() { unsigned long new_random_seed = InitRND(NEW_RANDOMIZE); + int dummy = 0; /* !!! HAS NO MEANING ANYMORE !!! */ + /* the name of the level must be enough */ + buffer[1] = OP_START_PLAYING; buffer[2] = (byte)(level_nr >> 8); buffer[3] = (byte)(level_nr & 0xff); - buffer[4] = (byte)(leveldir_nr >> 8); - buffer[5] = (byte)(leveldir_nr & 0xff); + buffer[4] = (byte)(dummy >> 8); + buffer[5] = (byte)(dummy & 0xff); buffer[6] = (unsigned char)((new_random_seed >> 24) & 0xff); buffer[7] = (unsigned char)((new_random_seed >> 16) & 0xff); buffer[8] = (unsigned char)((new_random_seed >> 8) & 0xff); buffer[9] = (unsigned char)((new_random_seed >> 0) & 0xff); - strcpy((char *)&buffer[10], leveldir[leveldir_nr].name); + strcpy((char *)&buffer[10], leveldir_current->name); - SendBufferToServer(10 + strlen(leveldir[leveldir_nr].name)+1); + SendBufferToServer(10 + strlen(leveldir_current->name) + 1); } void SendToServer_PausePlaying() @@ -409,25 +412,33 @@ static void Handle_OP_PLAYER_DISCONNECTED() static void Handle_OP_START_PLAYING() { - int new_level_nr, new_leveldir_nr; + struct LevelDirInfo *new_leveldir; + int new_level_nr; + int dummy; /* !!! HAS NO MEANING ANYMORE !!! */ unsigned long new_random_seed; char *new_leveldir_name; new_level_nr = (buffer[2] << 8) + buffer[3]; - new_leveldir_nr = (buffer[4] << 8) + buffer[5]; + dummy = (buffer[4] << 8) + buffer[5]; new_random_seed = (buffer[6] << 24) | (buffer[7] << 16) | (buffer[8] << 8) | (buffer[9]); new_leveldir_name = (char *)&buffer[10]; + new_leveldir = getLevelDirInfoFromLevelDirName(new_leveldir_name); + if (new_leveldir == NULL) + { + Error(ERR_WARN, "no such level directory: '%s'", new_leveldir_name); + + new_leveldir = leveldir_first; + Error(ERR_WARN, "using default level directory: '%s'", new_leveldir->name); + } + printf("OP_START_PLAYING: %d\n", buffer[0]); Error(ERR_NETWORK_CLIENT, - "client %d starts game [level %d from levedir %d (%s)]\n", - buffer[0], new_level_nr, new_leveldir_nr, new_leveldir_name); - - if (strcmp(leveldir[new_leveldir_nr].name, new_leveldir_name) != 0) - Error(ERR_WARN, "no such level directory: '%s'",new_leveldir_name); + "client %d starts game [level %d from leveldir '%s']\n", + buffer[0], new_level_nr, new_leveldir->name); - leveldir_nr = new_leveldir_nr; + leveldir_current = new_leveldir; level_nr = new_level_nr; TapeErase(); diff --git a/src/screens.c b/src/screens.c index 2d53a4a2..4839ab39 100644 --- a/src/screens.c +++ b/src/screens.c @@ -91,8 +91,8 @@ void DrawMainMenu() MapTapeButtons(); /* level_nr may have set to value over handicap with level editor */ - if (setup.handicap && level_nr > leveldir[leveldir_nr].handicap_level) - level_nr = leveldir[leveldir_nr].handicap_level; + if (setup.handicap && level_nr > leveldir_current->handicap_level) + level_nr = leveldir_current->handicap_level; GetPlayerConfig(); LoadLevel(level_nr); @@ -103,7 +103,7 @@ void DrawMainMenu() DrawText(SX + 6*32, SY + 2*32, setup.player_name, FS_BIG, FC_RED); DrawText(SX + 32, SY + 3*32, "Level:", FS_BIG, FC_GREEN); DrawText(SX + 11*32, SY + 3*32, int2str(level_nr,3), FS_BIG, - (leveldir[leveldir_nr].readonly ? FC_RED : FC_YELLOW)); + (leveldir_current->readonly ? FC_RED : FC_YELLOW)); DrawText(SX + 32, SY + 4*32, "Hall Of Fame", FS_BIG, FC_GREEN); DrawText(SX + 32, SY + 5*32, "Level Creator", FS_BIG, FC_GREEN); DrawText(SY + 32, SY + 6*32, "Info Screen", FS_BIG, FC_GREEN); @@ -114,10 +114,10 @@ void DrawMainMenu() DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE); DrawTextF(7*32 + 6, 3*32 + 9, FC_RED, "%d-%d", - leveldir[leveldir_nr].first_level, - leveldir[leveldir_nr].last_level); + leveldir_current->first_level, + leveldir_current->last_level); - if (leveldir[leveldir_nr].readonly) + if (leveldir_current->readonly) { DrawTextF(15*32 + 6, 3*32 + 9 - 7, FC_RED, "READ"); DrawTextF(15*32 + 6, 3*32 + 9 + 7, FC_RED, "ONLY"); @@ -131,13 +131,13 @@ void DrawMainMenu() DrawText(SX + 56, SY + 326, "A Game by Artsoft Entertainment", FS_SMALL, FC_RED); - if (leveldir[leveldir_nr].name) + if (leveldir_current->name) { - int len = strlen(leveldir[leveldir_nr].name); + int len = strlen(leveldir_current->name); int lxpos = SX + (SXSIZE - len * FONT4_XSIZE) / 2; int lypos = SY + 352; - DrawText(lxpos, lypos, leveldir[leveldir_nr].name, FS_SMALL, FC_SPECIAL2); + DrawText(lxpos, lypos, leveldir_current->name, FS_SMALL, FC_SPECIAL2); } FadeToFront(); @@ -199,23 +199,23 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) y = choice; } - if (y == 4 && ((x == 11 && level_nr > leveldir[leveldir_nr].first_level) || - (x == 15 && level_nr < leveldir[leveldir_nr].last_level)) && + if (y == 4 && ((x == 11 && level_nr > leveldir_current->first_level) || + (x == 15 && level_nr < leveldir_current->last_level)) && button) { static unsigned long level_delay = 0; int step = (button == 1 ? 1 : button == 2 ? 5 : 10); int new_level_nr, old_level_nr = level_nr; - int font_color = (leveldir[leveldir_nr].readonly ? FC_RED : FC_YELLOW); + int font_color = (leveldir_current->readonly ? FC_RED : FC_YELLOW); new_level_nr = level_nr + (x == 11 ? -step : +step); - if (new_level_nr < leveldir[leveldir_nr].first_level) - new_level_nr = leveldir[leveldir_nr].first_level; - if (new_level_nr > leveldir[leveldir_nr].last_level) - new_level_nr = leveldir[leveldir_nr].last_level; + if (new_level_nr < leveldir_current->first_level) + new_level_nr = leveldir_current->first_level; + if (new_level_nr > leveldir_current->last_level) + new_level_nr = leveldir_current->last_level; - if (setup.handicap && new_level_nr > leveldir[leveldir_nr].handicap_level) - new_level_nr = leveldir[leveldir_nr].handicap_level; + if (setup.handicap && new_level_nr > leveldir_current->handicap_level) + new_level_nr = leveldir_current->handicap_level; if (old_level_nr == new_level_nr || !DelayReached(&level_delay, GADGET_FRAME_DELAY)) @@ -246,7 +246,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { if (y != choice) { - DrawGraphic(0, y-1, GFX_KUGEL_ROT); + DrawGraphic(0, y - 1, GFX_KUGEL_ROT); DrawGraphic(0, choice - 1, GFX_KUGEL_BLAU); choice = y; } @@ -264,7 +264,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { game_status = CHOOSELEVEL; SaveLevelSetup_LastSeries(); - SaveLevelSetup_SeriesInfo(leveldir_nr); + SaveLevelSetup_SeriesInfo(); DrawChooseLevel(); } } @@ -275,7 +275,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (y == 6) { - if (leveldir[leveldir_nr].readonly && + if (leveldir_current->readonly && strcmp(setup.player_name, "Artsoft") != 0) Request("This level is read only !", REQ_CONFIRM); game_status = LEVELED; @@ -310,7 +310,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) else if (y == 10) { SaveLevelSetup_LastSeries(); - SaveLevelSetup_SeriesInfo(leveldir_nr); + SaveLevelSetup_SeriesInfo(); if (Request("Do you really want to quit ?", REQ_ASK | REQ_STAY_CLOSED)) game_status = EXITGAME; } @@ -866,16 +866,15 @@ static void drawChooseLevelList(int first_entry, int num_page_entries) for(i=0; iname , max_buffer_len); buffer[max_buffer_len] = '\0'; -#endif - DrawText(SX + 32, SY + (i + 2) * 32, buffer, - FS_MEDIUM, leveldir[first_entry + i].color); + DrawText(SX + 32, SY + (i + 2) * 32, buffer, FS_MEDIUM, + leveldir_node->color); DrawGraphic(0, i + 2, GFX_KUGEL_BLAU); } @@ -886,21 +885,18 @@ static void drawChooseLevelList(int first_entry, int num_page_entries) DrawGraphic(0, MAX_LEVEL_SERIES_ON_SCREEN + 1, GFX_ARROW_BLUE_DOWN); } -static void drawChooseLevelInfo(int leveldir_nr) +static void drawChooseLevelInfo(int leveldir_pos) { + struct LevelDirInfo *leveldir_node; int x, last_redraw_mask = redraw_mask; + leveldir_node = getLevelDirInfoFromPos(leveldir_first, leveldir_pos); + XFillRectangle(display, drawto, gc, SX + 32, SY + 32, SXSIZE - 64, 32); -#if 0 - DrawTextFCentered(40, FC_RED, "%3d levels (%s)", - leveldir[leveldir_nr].levels, - leveldir[leveldir_nr].readonly ? "readonly" : "writable"); -#else DrawTextFCentered(40, FC_RED, "%3d levels (%s)", - leveldir[leveldir_nr].levels, - leveldir[leveldir_nr].class_desc); -#endif + leveldir_node->levels, + leveldir_node->class_desc); /* let BackToFront() redraw only what is needed */ redraw_mask = last_redraw_mask | REDRAW_TILES; @@ -925,10 +921,12 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button) if (button == MB_MENU_INITIALIZE) { + int leveldir_pos = posLevelDirInfo(leveldir_current); + if (first_entry == -1) { - first_entry = MAX(0, leveldir_nr - num_page_entries + 1); - choice = leveldir_nr - first_entry + 3; + first_entry = MAX(0, leveldir_pos - num_page_entries + 1); + choice = leveldir_pos - first_entry + 3; AdjustChooseLevelScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, first_entry); } @@ -936,7 +934,7 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button) first_entry = dy; drawChooseLevelList(first_entry, num_page_entries); - drawChooseLevelInfo(leveldir_nr); + drawChooseLevelInfo(leveldir_pos); redraw = TRUE; } @@ -1021,13 +1019,23 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button) } else { - leveldir_nr = first_entry + y - 3; - LoadLevelSetup_SeriesInfo(leveldir_nr); + int leveldir_pos = first_entry + y - 3; + + leveldir_current = getLevelDirInfoFromPos(leveldir_first, leveldir_pos); + + LoadLevelSetup_SeriesInfo(); SaveLevelSetup_LastSeries(); - SaveLevelSetup_SeriesInfo(leveldir_nr); + SaveLevelSetup_SeriesInfo(); TapeErase(); + + printf("first_level == %d, last_level == %d, levels == %d\n", + leveldir_current->first_level, + leveldir_current->last_level, + leveldir_current->levels); + + game_status = MAINMENU; DrawMainMenu(); redraw = TRUE; diff --git a/src/tools.c b/src/tools.c index 69203cf9..b2815d94 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1637,7 +1637,7 @@ static void DrawMicroLevelLabelExt(int mode) mode == MICROLABEL_LEVEL_AUTHOR ? level.author : mode == MICROLABEL_IMPORTED_FROM ? "imported from" : mode == MICROLABEL_LEVEL_IMPORT_INFO ? - leveldir[leveldir_nr].imported_from : ""), + leveldir_current->imported_from : ""), MAX_MICROLABEL_SIZE); label_text[MAX_MICROLABEL_SIZE] = '\0'; @@ -1720,12 +1720,12 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart) /* redraw micro level label, if needed */ if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 && strcmp(level.author, ANONYMOUS_NAME) != 0 && - strcmp(level.author, leveldir[leveldir_nr].name) != 0 && + strcmp(level.author, leveldir_current->name) != 0 && DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY)) { int max_label_counter = 23; - if (leveldir[leveldir_nr].imported_from != NULL) + if (leveldir_current->imported_from != NULL) max_label_counter += 14; label_counter = (label_counter + 1) % max_label_counter; -- 2.34.1