From 5dd3c868d9df906623a5fc0ff2124655a14e3715 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sun, 25 Jan 2004 00:34:30 +0100 Subject: [PATCH] rnd-20040125-1-src --- Makefile | 4 +- src/Makefile | 3 +- src/conftime.h | 2 +- src/files.c | 105 +++++++++++++++++++++++++++++-------------- src/libgame/setup.c | 80 ++++++++++++++++----------------- src/libgame/system.h | 5 ++- 6 files changed, 119 insertions(+), 80 deletions(-) diff --git a/Makefile b/Makefile index 63962f78..e97587db 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,8 @@ CROSS_PATH_WIN32=/usr/local/cross-tools/i386-mingw32msvc SRC_DIR = src MAKE_CMD = $(MAKE) -C $(SRC_DIR) -DEFAULT_TARGET = x11 -# DEFAULT_TARGET = sdl +# DEFAULT_TARGET = x11 +DEFAULT_TARGET = sdl # ----------------------------------------------------------------------------- diff --git a/src/Makefile b/src/Makefile index a0d7cfa2..976f86bc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -76,8 +76,7 @@ endif ifeq ($(TARGET),x11) SYS_CFLAGS = -DTARGET_X11 $(X11_INCL) -# SYS_LDFLAGS = $(X11_LIBS) -lX11 -SYS_LDFLAGS = $(XLIB_PATH)/libX11.a +SYS_LDFLAGS = $(X11_LIBS) -lX11 endif ifeq ($(TARGET),sdl) diff --git a/src/conftime.h b/src/conftime.h index 333e8073..3655d811 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2004-01-19 19:09]" +#define COMPILE_DATE_STRING "[2004-01-25 00:33]" diff --git a/src/files.c b/src/files.c index 21da8121..1f98f641 100644 --- a/src/files.c +++ b/src/files.c @@ -329,8 +329,9 @@ static char *getSingleLevelBasename(int nr, int type) { static char basename[MAX_FILENAME_LEN]; - if (leveldir_current->filename == NULL) - leveldir_current->filename = getStringCat2("%%03d.%s",LEVELFILE_EXTENSION); + if (leveldir_current->level_filename == NULL) + leveldir_current->level_filename = + getStringCat2("%%03d.", LEVELFILE_EXTENSION); switch (type) { @@ -347,7 +348,7 @@ static char *getSingleLevelBasename(int nr, int type) case LEVEL_FILE_TYPE_UNKNOWN: default: - sprintf(basename, leveldir_current->filename, nr); + sprintf(basename, leveldir_current->level_filename, nr); break; } @@ -357,14 +358,48 @@ static char *getSingleLevelBasename(int nr, int type) static char *getPackedLevelBasename(int type) { static char basename[MAX_FILENAME_LEN]; + char *directory = getCurrentLevelDir(); + DIR *dir; + struct dirent *dir_entry; - switch (type) + strcpy(basename, UNDEFINED_FILENAME); /* default: undefined file */ + + if ((dir = opendir(directory)) == NULL) { - default: - strcpy(basename, UNDEFINED_FILENAME); + Error(ERR_WARN, "cannot read current level directory '%s'", directory); + + return basename; + } + + while ((dir_entry = readdir(dir)) != NULL) /* loop until last dir entry */ + { + char *entry_basename = dir_entry->d_name; + boolean valid_entry_found = FALSE; + + switch (type) + { + case LEVEL_FILE_TYPE_SP: + if (strlen(entry_basename) == 10 && + (strncmp(entry_basename, "levels.d", 8) == 0 || + strncmp(entry_basename, "LEVELS.D", 8) == 0)) + { + /* looks like a typical filename of a Supaplex level package file */ + strcpy(basename, entry_basename); + valid_entry_found = TRUE; + } + break; + + default: + valid_entry_found = TRUE; + break; + } + + if (valid_entry_found) break; } + closedir(dir); + return basename; } @@ -389,32 +424,35 @@ static void setLevelFileInfo_Filename(struct LevelFileInfo *lfi) if (lfi->nr < 0) { lfi->type = LEVEL_FILE_TYPE_RND; - lfi->filename = getDefaultLevelFilename(nr); + lfi->filename = getDefaultLevelFilename(lfi->nr); return; } - if (leveldir_current->filename != NULL) + if (leveldir_current->level_filename != NULL) { - /* 1st try: check for file name/pattern specified in "levelinfo.conf" */ + /* check for file name/pattern specified in "levelinfo.conf" */ lfi->type = LEVEL_FILE_TYPE_UNKNOWN; lfi->filename = getSingleLevelFilename(lfi->nr, lfi->type); - if (fileExists(lfi->filename)) return; } - /* 2nd try: check for native Rocks'n'Diamonds level file */ + /* check for native Rocks'n'Diamonds level file */ lfi->type = LEVEL_FILE_TYPE_RND; lfi->filename = getSingleLevelFilename(lfi->nr, lfi->type); - if (fileExists(lfi->filename)) return; - /* 3rd try: check for classic Emerald Mine level file */ + /* check for classic Emerald Mine level file */ lfi->type = LEVEL_FILE_TYPE_EM; lfi->filename = getSingleLevelFilename(lfi->nr, lfi->type); + if (fileExists(lfi->filename)) + return; + /* check for packed Supaplex level file */ + lfi->type = LEVEL_FILE_TYPE_SP; + lfi->filename = getPackedLevelFilename(lfi->type); if (fileExists(lfi->filename)) return; @@ -427,18 +465,16 @@ static void setLevelFileInfo_Filetype(struct LevelFileInfo *lfi) { struct stat file_status; - if (level_file_info.type != LEVEL_FILE_TYPE_UNKNOWN) + if (lfi->type != LEVEL_FILE_TYPE_UNKNOWN) return; /* ---------- try to determine file type from filename ---------- */ if (strlen(lfi->filename) == 10 && (strncmp(lfi->filename, "levels.d", 8) == 0 || - strncmp(lfi->filename, "LEVELS.D", 8) == 0) && - lfi->filename[8] >= '0' && lfi->filename[8] <= '9' && - lfi->filename[9] >= '0' && lfi->filename[9] <= '9') + strncmp(lfi->filename, "LEVELS.D", 8) == 0)) { - /* this looks like a typical filename of a Supaplex level package file */ + /* looks like a typical filename of a Supaplex level package file */ lfi->type = LEVEL_FILE_TYPE_SP; return; @@ -448,9 +484,9 @@ static void setLevelFileInfo_Filetype(struct LevelFileInfo *lfi) if (stat(lfi->filename, &file_status) == 0) { - if (file_status.off_t == 170496) + if (file_status.st_size == 170496) { - /* this looks like a typical filesize of a Supaplex level package file */ + /* looks like a typical filesize of a Supaplex level package file */ lfi->type = LEVEL_FILE_TYPE_SP; return; @@ -1487,7 +1523,8 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, #define SP_LEVEL_YSIZE 24 #define SP_LEVEL_NAME_LEN 23 -static void LoadLevelFromFileStream_SP(struct LevelInfo *level, FILE *file) +static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, + int nr) { int i, x, y; @@ -1500,15 +1537,15 @@ static void LoadLevelFromFileStream_SP(struct LevelInfo *level, FILE *file) int element_new; if (element_old <= 0x27) - element_new = EL_SP_START + element_old; + element_new = getMappedElement(EL_SP_START + element_old); else if (element_old == 0x28) element_new = EL_INVISIBLE_WALL; else { - Error(ERR_WARN, "in level %d, at position %d, %d:", l, x, y); + Error(ERR_WARN, "in level %d, at position %d, %d:", nr, x, y); Error(ERR_WARN, "invalid level element %d", element_old); - element_new = EL_CHAR_FRAGE; + element_new = EL_CHAR_QUESTION; } level->field[x][y] = element_new; @@ -1518,7 +1555,7 @@ static void LoadLevelFromFileStream_SP(struct LevelInfo *level, FILE *file) ReadUnusedBytesFromFile(file, 4); /* Initial gravitation: 1 == "on", anything else (0) == "off" */ - level->gravity = (fgetc(file) == 1 ? TRUE : FALSE); + level->initial_gravity = (fgetc(file) == 1 ? TRUE : FALSE); ReadUnusedBytesFromFile(file, 1); @@ -1562,7 +1599,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, { char *filename = level_file_info->filename; FILE *file; - int nr = level_file_info->nr; + int nr = level_file_info->nr - leveldir_current->first_level; int i, l, x, y; char name_first, name_last; struct LevelInfo multipart_level; @@ -1601,7 +1638,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, for (l = nr; l < NUM_SUPAPLEX_LEVELS_PER_PACKAGE; l++) { - LoadLevelFromFileStream_SP(level, file); + LoadLevelFromFileStream_SP(file, level, l); /* check if this level is a part of a bigger multi-part level */ @@ -1667,12 +1704,12 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, if (is_first_part) /* start with first part of new multi-part level */ { /* copy level info structure from first part */ - multipart_level = level; + multipart_level = *level; /* clear playfield of new multi-part level */ for (y = 0; y < MAX_LEV_FIELDY; y++) for (x = 0; x < MAX_LEV_FIELDX; x++) - multipart_level->field[x][y] = EL_EMPTY; + multipart_level.field[x][y] = EL_EMPTY; } if (name_first == '?') @@ -1683,8 +1720,8 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, multipart_xpos = (int)(name_first - '0'); multipart_ypos = (int)(name_last - '0'); -#if 1 - printf("----------> Part (%d/%d) of multi-part level '%s'\n", +#if 0 + printf("----------> part (%d/%d) of multi-part level '%s'\n", multipart_xpos, multipart_ypos, multipart_level.name); #endif @@ -1709,7 +1746,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, int start_x = (multipart_xpos - 1) * SP_LEVEL_XSIZE; int start_y = (multipart_ypos - 1) * SP_LEVEL_YSIZE; - multipart_level->field[start_x + x][start_y + y] = level->field[x][y]; + multipart_level.field[start_x + x][start_y + y] = level->field[x][y]; } } } @@ -2992,7 +3029,7 @@ void SaveTape(int nr) int body_chunk_size; int i; - InitTapeDirectory(leveldir_current->filename); + InitTapeDirectory(leveldir_current->subdir); /* if a tape still exists, ask to overwrite it */ if (access(filename, F_OK) == 0) @@ -3154,7 +3191,7 @@ void SaveScore(int nr) char *filename = getScoreFilename(nr); FILE *file; - InitScoreDirectory(leveldir_current->filename); + InitScoreDirectory(leveldir_current->subdir); if (!(file = fopen(filename, MODE_WRITE))) { diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 7942ee79..8fa4317c 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -357,7 +357,7 @@ char *getTapeFilename(int nr) checked_free(filename); sprintf(basename, "%03d.%s", nr, TAPEFILE_EXTENSION); - filename = getPath2(getTapeDir(leveldir_current->filename), basename); + filename = getPath2(getTapeDir(leveldir_current->subdir), basename); return filename; } @@ -383,7 +383,7 @@ char *getScoreFilename(int nr) checked_free(filename); sprintf(basename, "%03d.%s", nr, SCOREFILE_EXTENSION); - filename = getPath2(getScoreDir(leveldir_current->filename), basename); + filename = getPath2(getScoreDir(leveldir_current->subdir), basename); return filename; } @@ -928,11 +928,11 @@ void dumpTreeInfo(TreeInfo *node, int depth) printf(" "); #if 1 - printf("filename == '%s' ['%s', '%s'] [%d])\n", - node->filename, node->fullpath, node->basepath, node->user_defined); + printf("subdir == '%s' ['%s', '%s'] [%d])\n", + node->subdir, node->fullpath, node->basepath, node->user_defined); #else - printf("filename == '%s' (%s) [%s] (%d)\n", - node->filename, node->name, node->identifier, node->sort_priority); + printf("subdir == '%s' (%s) [%s] (%d)\n", + node->subdir, node->name, node->identifier, node->sort_priority); #endif if (node->node_group != NULL) @@ -1605,9 +1605,9 @@ static struct TokenInfo levelinfo_tokens[] = { TYPE_BOOLEAN, &ldi.readonly, "readonly" }, { TYPE_STRING, &ldi.graphics_set, "graphics_set" }, { TYPE_STRING, &ldi.sounds_set, "sounds_set" }, - { TYPE_STRING, &ldi.music_set, "music_set" } - { TYPE_STRING, &ldi.filename, "filename" } - { TYPE_STRING, &ldi.filetype, "filetype" } + { TYPE_STRING, &ldi.music_set, "music_set" }, + { TYPE_STRING, &ldi.level_filename, "filename" }, + { TYPE_STRING, &ldi.level_filetype, "filetype" } }; static void setTreeInfoToDefaults(TreeInfo *ldi, int type) @@ -1627,7 +1627,7 @@ static void setTreeInfoToDefaults(TreeInfo *ldi, int type) ldi->cl_first = -1; ldi->cl_cursor = -1; - ldi->filename = NULL; + ldi->subdir = NULL; ldi->fullpath = NULL; ldi->basepath = NULL; ldi->identifier = NULL; @@ -1653,8 +1653,8 @@ static void setTreeInfoToDefaults(TreeInfo *ldi, int type) ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME); ldi->music_path = getStringCopy(UNDEFINED_FILENAME); - ldi->filename = NULL; - ldi->filetype = NULL; + ldi->level_filename = NULL; + ldi->level_filetype = NULL; ldi->levels = 0; ldi->first_level = 0; @@ -1689,7 +1689,7 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) ldi->cl_first = -1; ldi->cl_cursor = -1; - ldi->filename = NULL; + ldi->subdir = NULL; ldi->fullpath = NULL; ldi->basepath = NULL; ldi->identifier = NULL; @@ -1715,8 +1715,8 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME); ldi->music_path = getStringCopy(UNDEFINED_FILENAME); - ldi->filename = NULL; - ldi->filetype = NULL; + ldi->level_filename = NULL; + ldi->level_filetype = NULL; ldi->levels = 0; ldi->first_level = 0; @@ -1739,7 +1739,7 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) other structure's pointer may point to them! */ - ldi->filename = NULL; + ldi->subdir = NULL; ldi->fullpath = NULL; ldi->basepath = NULL; ldi->identifier = NULL; @@ -1770,7 +1770,7 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent) static void freeTreeInfo(TreeInfo *ldi) { - checked_free(ldi->filename); + checked_free(ldi->subdir); checked_free(ldi->fullpath); checked_free(ldi->basepath); checked_free(ldi->identifier); @@ -1888,7 +1888,7 @@ static void createParentTreeInfoNode(TreeInfo *node_parent) setString(&ti_new->name, ".. (parent directory)"); setString(&ti_new->name_sorting, ti_new->name); - setString(&ti_new->filename, ".."); + setString(&ti_new->subdir, ".."); setString(&ti_new->fullpath, node_parent->fullpath); ti_new->sort_priority = node_parent->sort_priority; @@ -1900,7 +1900,7 @@ static void createParentTreeInfoNode(TreeInfo *node_parent) ti_new->name = ".. (parent directory)"; ti_new->name_sorting = getStringCopy(ti_new->name); - ti_new->filename = ".."; + ti_new->subdir = ".."; ti_new->fullpath = getStringCopy(node_parent->fullpath); ti_new->sort_priority = node_parent->sort_priority; @@ -1943,7 +1943,7 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, else setTreeInfoToDefaults(leveldir_new, TREE_TYPE_LEVEL_DIR); - leveldir_new->filename = getStringCopy(directory_name); + leveldir_new->subdir = getStringCopy(directory_name); checkSetupFileHashIdentifier(setup_file_hash, getCookie("LEVELINFO")); @@ -1956,19 +1956,19 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, #if 1 if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0) - setString(&leveldir_new->name, leveldir_new->filename); + setString(&leveldir_new->name, leveldir_new->subdir); #else if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0) { free(leveldir_new->name); - leveldir_new->name = getStringCopy(leveldir_new->filename); + leveldir_new->name = getStringCopy(leveldir_new->subdir); } #endif DrawInitText(leveldir_new->name, 150, FC_YELLOW); if (leveldir_new->identifier == NULL) - leveldir_new->identifier = getStringCopy(leveldir_new->filename); + leveldir_new->identifier = getStringCopy(leveldir_new->subdir); if (leveldir_new->name_sorting == NULL) leveldir_new->name_sorting = getStringCopy(leveldir_new->name); @@ -1976,7 +1976,7 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first, if (node_parent == NULL) /* top level group */ { leveldir_new->basepath = getStringCopy(level_directory); - leveldir_new->fullpath = getStringCopy(leveldir_new->filename); + leveldir_new->fullpath = getStringCopy(leveldir_new->subdir); } else /* sub level group */ { @@ -2169,7 +2169,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, else setTreeInfoToDefaults(artwork_new, type); - artwork_new->filename = getStringCopy(directory_name); + artwork_new->subdir = getStringCopy(directory_name); if (setup_file_hash) /* (before defining ".color" and ".class_desc") */ { @@ -2186,12 +2186,12 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, #if 1 if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0) - setString(&artwork_new->name, artwork_new->filename); + setString(&artwork_new->name, artwork_new->subdir); #else if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0) { free(artwork_new->name); - artwork_new->name = getStringCopy(artwork_new->filename); + artwork_new->name = getStringCopy(artwork_new->subdir); } #endif @@ -2200,7 +2200,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, #endif if (artwork_new->identifier == NULL) - artwork_new->identifier = getStringCopy(artwork_new->filename); + artwork_new->identifier = getStringCopy(artwork_new->subdir); if (artwork_new->name_sorting == NULL) artwork_new->name_sorting = getStringCopy(artwork_new->name); @@ -2209,7 +2209,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, if (node_parent == NULL) /* top level group */ { artwork_new->basepath = getStringCopy(base_directory); - artwork_new->fullpath = getStringCopy(artwork_new->filename); + artwork_new->fullpath = getStringCopy(artwork_new->subdir); } else /* sub level group */ { @@ -2251,7 +2251,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, } #endif - if (strcmp(artwork_new->filename, ".") == 0) + if (strcmp(artwork_new->subdir, ".") == 0) { if (artwork_new->user_defined) { @@ -2284,9 +2284,9 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first, else { #if 1 - setString(&artwork_new->identifier, artwork_new->filename); + setString(&artwork_new->identifier, artwork_new->subdir); #else - artwork_new->identifier = getStringCopy(artwork_new->filename); + artwork_new->identifier = getStringCopy(artwork_new->subdir); #endif } @@ -2375,7 +2375,7 @@ static TreeInfo *getDummyArtworkInfo(int type) setTreeInfoToDefaults(artwork_new, type); #if 1 - setString(&artwork_new->filename, UNDEFINED_FILENAME); + setString(&artwork_new->subdir, UNDEFINED_FILENAME); setString(&artwork_new->fullpath, UNDEFINED_FILENAME); setString(&artwork_new->basepath, UNDEFINED_FILENAME); @@ -2383,7 +2383,7 @@ static TreeInfo *getDummyArtworkInfo(int type) setString(&artwork_new->name, UNDEFINED_FILENAME); setString(&artwork_new->name_sorting, UNDEFINED_FILENAME); #else - artwork_new->filename = getStringCopy(UNDEFINED_FILENAME); + artwork_new->subdir = getStringCopy(UNDEFINED_FILENAME); artwork_new->fullpath = getStringCopy(UNDEFINED_FILENAME); artwork_new->basepath = getStringCopy(UNDEFINED_FILENAME); @@ -2488,7 +2488,7 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, #if 0 if (!level_node->parent_link) printf("CHECKING '%s' ['%s', '%s'] ...\n", path, - level_node->filename, level_node->name); + level_node->subdir, level_node->name); #endif if (!level_node->parent_link) @@ -2504,7 +2504,7 @@ void LoadArtworkInfoFromLevelInfo(ArtworkDirTree **artwork_node, free((*artwork_node)->name); free((*artwork_node)->name_sorting); - (*artwork_node)->identifier = getStringCopy(level_node->filename); + (*artwork_node)->identifier = getStringCopy(level_node->subdir); (*artwork_node)->name = getStringCopy(level_node->name); (*artwork_node)->name_sorting = getStringCopy(level_node->name); @@ -2759,7 +2759,7 @@ void SaveLevelSetup_LastSeries() /* ----------------------------------------------------------------------- */ char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME); - char *level_subdir = leveldir_current->filename; + char *level_subdir = leveldir_current->subdir; FILE *file; InitUserDataDirectory(); @@ -2838,7 +2838,7 @@ void LoadLevelSetup_SeriesInfo() { char *filename; SetupFileHash *level_setup_hash = NULL; - char *level_subdir = leveldir_current->filename; + char *level_subdir = leveldir_current->subdir; /* always start with reliable default values */ level_nr = leveldir_current->first_level; @@ -2849,7 +2849,7 @@ void LoadLevelSetup_SeriesInfo() /* ~/./levelsetup//levelsetup.conf */ /* ----------------------------------------------------------------------- */ - level_subdir = leveldir_current->filename; + level_subdir = leveldir_current->subdir; filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME); @@ -2899,7 +2899,7 @@ void LoadLevelSetup_SeriesInfo() void SaveLevelSetup_SeriesInfo() { char *filename; - char *level_subdir = leveldir_current->filename; + char *level_subdir = leveldir_current->subdir; char *level_nr_str = int2str(level_nr, 0); char *handicap_level_str = int2str(leveldir_current->handicap_level, 0); FILE *file; diff --git a/src/libgame/system.h b/src/libgame/system.h index abed03f0..af6b95a2 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -617,7 +617,7 @@ struct TreeInfo /* fields for "type == TREE_TYPE_LEVEL_DIR" */ - char *filename; /* tree info sub-directory basename (may be ".") */ + char *subdir; /* tree info sub-directory basename (may be ".") */ char *fullpath; /* complete path relative to tree base directory */ char *basepath; /* absolute base path of tree base directory */ char *identifier; /* identifier string for configuration files */ @@ -633,6 +633,9 @@ struct TreeInfo char *sounds_path; /* path to optional custom sounds set (level only) */ char *music_path; /* path to optional custom music set (level only) */ + char *level_filename; /* filename of level file (for packed level file) */ + char *level_filetype; /* type of levels in level directory or level file */ + int levels; /* number of levels in level series */ int first_level; /* first level number (to allow start with 0 or 1) */ int last_level; /* last level number (automatically calculated) */ -- 2.34.1