X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=473a73926cbcaa9f24502582db6844c9746b786a;hb=983b7bc7f3493b1522d08d8e7bdecb3bd8e462eb;hp=3651ace4252b631058278db15b17c4a9ad544727;hpb=e6c0b4c0114691d197018f878e0150a3f5d8490e;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 3651ace4..473a7392 100644 --- a/src/files.c +++ b/src/files.c @@ -49,6 +49,23 @@ #define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x" #define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2" +static struct +{ + int filetype; + char *id; +} +filetype_id_list[] = +{ + { LEVEL_FILE_TYPE_RND, "RND" }, + { LEVEL_FILE_TYPE_BD, "BD" }, + { LEVEL_FILE_TYPE_EM, "EM" }, + { LEVEL_FILE_TYPE_SP, "SP" }, + { LEVEL_FILE_TYPE_DX, "DX" }, + { LEVEL_FILE_TYPE_SB, "SB" }, + { LEVEL_FILE_TYPE_DC, "DC" }, + { -1, NULL }, +}; + /* ========================================================================= */ /* level file functions */ @@ -111,9 +128,10 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change) static void setLevelInfoToDefaults(struct LevelInfo *level) { static boolean clipboard_elements_initialized = FALSE; - int i, j, x, y; + setLevelInfoToDefaults_EM(); + level->native_em_level = &native_em_level; level->game_engine_type = GAME_ENGINE_TYPE_RND; @@ -410,34 +428,14 @@ static int getFileTypeFromBasename(char *basename) return LEVEL_FILE_TYPE_UNKNOWN; } -static char *getSingleLevelBasename(int nr, int type) +static char *getSingleLevelBasename(int nr) { static char basename[MAX_FILENAME_LEN]; - char *level_filename = getStringCopy(leveldir_current->level_filename); - - if (level_filename == NULL) - level_filename = getStringCat2("%03d.", LEVELFILE_EXTENSION); - switch (type) - { - case LEVEL_FILE_TYPE_RND: - if (nr < 0) - sprintf(basename, "template.%s", LEVELFILE_EXTENSION); - else - sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION); - break; - - case LEVEL_FILE_TYPE_EM: - sprintf(basename, "%d", nr); - break; - - case LEVEL_FILE_TYPE_UNKNOWN: - default: - sprintf(basename, level_filename, nr); - break; - } - - free(level_filename); + if (nr < 0) + sprintf(basename, "template.%s", LEVELFILE_EXTENSION); + else + sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION); return basename; } @@ -480,9 +478,9 @@ static char *getPackedLevelBasename(int type) return basename; } -static char *getSingleLevelFilename(int nr, int type) +static char *getSingleLevelFilename(int nr) { - return getLevelFilenameFromBasename(getSingleLevelBasename(nr, type)); + return getLevelFilenameFromBasename(getSingleLevelBasename(nr)); } #if 0 @@ -494,9 +492,10 @@ static char *getPackedLevelFilename(int type) char *getDefaultLevelFilename(int nr) { - return getSingleLevelFilename(nr, LEVEL_FILE_TYPE_RND); + return getSingleLevelFilename(nr); } +#if 0 static void setLevelFileInfo_SingleLevelFilename(struct LevelFileInfo *lfi, int type) { @@ -505,6 +504,23 @@ static void setLevelFileInfo_SingleLevelFilename(struct LevelFileInfo *lfi, lfi->basename = getSingleLevelBasename(lfi->nr, lfi->type); lfi->filename = getLevelFilenameFromBasename(lfi->basename); } +#endif + +static void setLevelFileInfo_FormatLevelFilename(struct LevelFileInfo *lfi, + int type, char *format, ...) +{ + static char basename[MAX_FILENAME_LEN]; + va_list ap; + + va_start(ap, format); + vsprintf(basename, format, ap); + va_end(ap); + + lfi->type = type; + lfi->packed = FALSE; + lfi->basename = basename; + lfi->filename = getLevelFilenameFromBasename(lfi->basename); +} static void setLevelFileInfo_PackedLevelFilename(struct LevelFileInfo *lfi, int type) @@ -515,7 +531,37 @@ static void setLevelFileInfo_PackedLevelFilename(struct LevelFileInfo *lfi, lfi->filename = getLevelFilenameFromBasename(lfi->basename); } -static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) +static int getFiletypeFromID(char *filetype_id) +{ + char *filetype_id_lower; + int filetype = LEVEL_FILE_TYPE_UNKNOWN; + int i; + + if (filetype_id == NULL) + return LEVEL_FILE_TYPE_UNKNOWN; + + filetype_id_lower = getStringToLower(filetype_id); + + for (i = 0; filetype_id_list[i].id != NULL; i++) + { + char *id_lower = getStringToLower(filetype_id_list[i].id); + + if (strcmp(filetype_id_lower, id_lower) == 0) + filetype = filetype_id_list[i].filetype; + + free(id_lower); + + if (filetype != LEVEL_FILE_TYPE_UNKNOWN) + break; + } + + free(filetype_id_lower); + + return filetype; +} + +#if 0 +static void OLD_determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) { /* special case: level number is negative => check for level template file */ if (lfi->nr < 0) @@ -527,8 +573,11 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) if (leveldir_current->level_filename != NULL) { + int filetype = getFiletypeFromID(leveldir_current->level_filetype); + /* check for file name/pattern specified in "levelinfo.conf" */ - setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN); + setLevelFileInfo_SingleLevelFilename(lfi, filetype); + if (fileExists(lfi->filename)) return; } @@ -551,6 +600,79 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) /* no known level file found -- try to use default values */ setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN); } +#endif + +static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) +{ + int nr = lfi->nr; + + /* special case: level number is negative => check for level template file */ + if (nr < 0) + { + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND, + "template.%s", LEVELFILE_EXTENSION); + + /* no fallback if template file not existing */ + return; + } + + /* special case: check for file name/pattern specified in "levelinfo.conf" */ + if (leveldir_current->level_filename != NULL) + { + int filetype = getFiletypeFromID(leveldir_current->level_filetype); + + setLevelFileInfo_FormatLevelFilename(lfi, filetype, + leveldir_current->level_filename, nr); + if (fileExists(lfi->filename)) + return; + } + + /* check for native Rocks'n'Diamonds level file */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND, + "%03d.%s", nr, LEVELFILE_EXTENSION); + if (fileExists(lfi->filename)) + return; + + /* check for Emerald Mine level file (V1) */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "a%c%c", + 'a' + (nr / 10) % 26, '0' + nr % 10); + if (fileExists(lfi->filename)) + return; + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "A%c%c", + 'A' + (nr / 10) % 26, '0' + nr % 10); + if (fileExists(lfi->filename)) + return; + + /* check for Emerald Mine level file (V2 to V5) */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%d", nr); + if (fileExists(lfi->filename)) + return; + + /* check for Emerald Mine level file (V6 / single mode) */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02ds", nr); + if (fileExists(lfi->filename)) + return; + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dS", nr); + if (fileExists(lfi->filename)) + return; + + /* check for Emerald Mine level file (V6 / teamwork mode) */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dt", nr); + if (fileExists(lfi->filename)) + return; + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dT", nr); + if (fileExists(lfi->filename)) + return; + + /* check for various packed level file formats */ + setLevelFileInfo_PackedLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN); + if (fileExists(lfi->filename)) + return; + + /* no known level file found -- use default values (and fail later) */ + setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND, + "%03d.%s", nr, LEVELFILE_EXTENSION); +} static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi) { @@ -1808,7 +1930,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->width = MIN(level->fieldx, EM_MAX_CAVE_WIDTH); lev->height = MIN(level->fieldy, EM_MAX_CAVE_HEIGHT); - lev->time_initial = level->time; + lev->time_seconds = level->time; lev->required_initial = level->gems_needed; lev->emerald_score = level->score[SC_EMERALD]; @@ -1819,7 +1941,8 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->eater_score = level->score[SC_YAMYAM]; lev->nut_score = level->score[SC_NUT]; lev->dynamite_score = level->score[SC_DYNAMITE]; - lev->key_score = level->score[SC_TIME_BONUS]; /* ??? CHECK THIS */ + lev->key_score = level->score[SC_KEY]; + lev->exit_score = level->score[SC_TIME_BONUS]; for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) for (y = 0; y < 3; y++) @@ -1836,9 +1959,11 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) lev->ball_random = level->ball_random; lev->ball_state_initial = level->ball_state_initial; lev->ball_time = level->ball_time; + lev->lenses_score = level->lenses_score; lev->magnify_score = level->magnify_score; lev->slurp_score = level->slurp_score; + lev->lenses_time = level->lenses_time; lev->magnify_time = level->magnify_time; lev->wind_direction_initial = level->wind_direction_initial; @@ -1914,7 +2039,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->fieldx = MIN(lev->width, MAX_LEV_FIELDX); level->fieldy = MIN(lev->height, MAX_LEV_FIELDY); - level->time = lev->time_initial; + level->time = lev->time_seconds; level->gems_needed = lev->required_initial; sprintf(level->name, "Level %d", level->file_info.nr); @@ -1927,7 +2052,8 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->score[SC_YAMYAM] = lev->eater_score; level->score[SC_NUT] = lev->nut_score; level->score[SC_DYNAMITE] = lev->dynamite_score; - level->score[SC_TIME_BONUS] = lev->key_score; /* ??? CHECK THIS */ + level->score[SC_KEY] = lev->key_score; + level->score[SC_TIME_BONUS] = lev->exit_score; level->num_yamyam_contents = MAX_ELEMENT_CONTENTS; @@ -1946,9 +2072,11 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) level->ball_random = lev->ball_random; level->ball_state_initial = lev->ball_state_initial; level->ball_time = lev->ball_time; + level->lenses_score = lev->lenses_score; level->magnify_score = lev->magnify_score; level->slurp_score = lev->slurp_score; + level->lenses_time = lev->lenses_time; level->magnify_time = lev->magnify_time; level->wind_direction_initial = lev->wind_direction_initial; @@ -1975,6 +2103,10 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) /* in case of both players set to the same field, use the first player */ level->field[ply2->x_initial - 1][ply2->y_initial - 1] = EL_PLAYER_2; level->field[ply1->x_initial - 1][ply1->y_initial - 1] = EL_PLAYER_1; + +#if 0 + printf("::: native Emerald Mine file version: %d\n", level_em->file_version); +#endif } static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, @@ -2369,10 +2501,17 @@ void LoadLevelFromFileInfo(struct LevelInfo *level, break; } + /* if level file is invalid, restore level structure to default values */ + if (level->no_valid_file) + setLevelInfoToDefaults(level); + if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN) level->game_engine_type = GAME_ENGINE_TYPE_RND; - CopyNativeLevel_Native_to_RND(level); + if (level_file_info->type == LEVEL_FILE_TYPE_RND) + CopyNativeLevel_RND_to_Native(level); + else + CopyNativeLevel_Native_to_RND(level); } void LoadLevelFromFilename(struct LevelInfo *level, char *filename) @@ -3866,7 +4005,7 @@ void SaveTape(int nr) tape.changed = FALSE; if (new_tape) - Request("tape saved !", REQ_CONFIRM); + Request("Tape saved !", REQ_CONFIRM); } void DumpTape(struct TapeInfo *tape) @@ -4030,17 +4169,18 @@ void SaveScore(int nr) #define SETUP_TOKEN_QUICK_DOORS 10 #define SETUP_TOKEN_TEAM_MODE 11 #define SETUP_TOKEN_HANDICAP 12 -#define SETUP_TOKEN_TIME_LIMIT 13 -#define SETUP_TOKEN_FULLSCREEN 14 -#define SETUP_TOKEN_ASK_ON_ESCAPE 15 -#define SETUP_TOKEN_GRAPHICS_SET 16 -#define SETUP_TOKEN_SOUNDS_SET 17 -#define SETUP_TOKEN_MUSIC_SET 18 -#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS 19 -#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS 20 -#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC 21 - -#define NUM_GLOBAL_SETUP_TOKENS 22 +#define SETUP_TOKEN_SKIP_LEVELS 13 +#define SETUP_TOKEN_TIME_LIMIT 14 +#define SETUP_TOKEN_FULLSCREEN 15 +#define SETUP_TOKEN_ASK_ON_ESCAPE 16 +#define SETUP_TOKEN_GRAPHICS_SET 17 +#define SETUP_TOKEN_SOUNDS_SET 18 +#define SETUP_TOKEN_MUSIC_SET 19 +#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS 20 +#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS 21 +#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC 22 + +#define NUM_GLOBAL_SETUP_TOKENS 23 /* editor setup */ #define SETUP_TOKEN_EDITOR_EL_BOULDERDASH 0 @@ -4120,6 +4260,7 @@ static struct TokenInfo global_setup_tokens[] = { TYPE_SWITCH, &si.quick_doors, "quick_doors" }, { TYPE_SWITCH, &si.team_mode, "team_mode" }, { TYPE_SWITCH, &si.handicap, "handicap" }, + { TYPE_SWITCH, &si.skip_levels, "skip_levels" }, { TYPE_SWITCH, &si.time_limit, "time_limit" }, { TYPE_SWITCH, &si.fullscreen, "fullscreen" }, { TYPE_SWITCH, &si.ask_on_escape, "ask_on_escape" }, @@ -4221,6 +4362,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->quick_doors = FALSE; si->team_mode = FALSE; si->handicap = TRUE; + si->skip_levels = TRUE; si->time_limit = TRUE; si->fullscreen = FALSE; si->ask_on_escape = TRUE; @@ -4549,7 +4691,19 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements) { char *value = getHashEntry(element_hash, list->token); - if (value) + if (value == NULL) /* try to find obsolete token mapping */ + { + char *mapped_token = get_mapped_token(list->token); + + if (mapped_token != NULL) + { + value = getHashEntry(element_hash, mapped_token); + + free(mapped_token); + } + } + + if (value != NULL) { (*elements)[(*num_elements)++] = atoi(value); }