X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=226cab31face1b9965a5bcb0e3f4601a97bda121;hb=673c51c61ad415fbdb1a69148fa67dfbeb0afcae;hp=f8bbea80a85ffde79aaacdc092af0171e55117f8;hpb=da14f69fd95c7bd5a0d70cdf4935af06f1f20a04;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index f8bbea80..226cab31 100644 --- a/src/files.c +++ b/src/files.c @@ -1,14 +1,14 @@ /*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * +* Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * +* (c) 1995-2001 Artsoft Entertainment * +* Holger Schemel * +* Detmolder Strasse 189 * +* 33604 Bielefeld * +* Germany * +* e-mail: info@artsoft.org * *----------------------------------------------------------* -* files.h * +* files.c * ***********************************************************/ #include @@ -22,16 +22,19 @@ #include "tape.h" #include "joystick.h" -#define MAX_FILENAME_LEN 256 /* maximal filename length */ +#define MAX_FILENAME_LEN 256 /* maximal filename length */ #define MAX_LINE_LEN 1000 /* maximal input line length */ #define CHUNK_ID_LEN 4 /* IFF style chunk id length */ #define LEVEL_HEADER_SIZE 80 /* size of level file header */ #define LEVEL_HEADER_UNUSED 15 /* unused level header bytes */ -#define TAPE_HEADER_SIZE 20 /* size of tape file header */ -#define TAPE_HEADER_UNUSED 7 /* unused tape header bytes */ -#define FILE_VERSION_1_0 10 /* 1.0 file version (old) */ +#define TAPE_HEADER_SIZE 20 /* size of tape file header */ +#define TAPE_HEADER_UNUSED 7 /* unused tape header bytes */ + +#if 0 +#define FILE_VERSION_1_0 10 /* 1.0 file version (old) */ #define FILE_VERSION_1_2 12 /* 1.2 file version (still in use) */ -#define FILE_VERSION_1_4 14 /* 1.4 file version (new) */ +#define FILE_VERSION_1_4 14 /* 1.4 file version (new) */ +#endif /* file identifier strings */ #define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.4" @@ -47,7 +50,6 @@ /* file names and filename extensions */ #if !defined(PLATFORM_MSDOS) -#define USERDATA_DIRECTORY ".rocksndiamonds" #define LEVELSETUP_DIRECTORY "levelsetup" #define SETUP_FILENAME "setup.conf" #define LEVELSETUP_FILENAME "levelsetup.conf" @@ -56,7 +58,6 @@ #define TAPEFILE_EXTENSION "tape" #define SCOREFILE_EXTENSION "score" #else -#define USERDATA_DIRECTORY "userdata" #define LEVELSETUP_DIRECTORY "lvlsetup" #define SETUP_FILENAME "setup.cnf" #define LEVELSETUP_FILENAME "lvlsetup.cnf" @@ -66,10 +67,6 @@ #define SCOREFILE_EXTENSION "sco" #endif -#if !defined(PLATFORM_UNIX) -#define ERROR_FILENAME "error.out" -#endif - #if defined(PLATFORM_WIN32) #ifndef S_IRGRP #define S_IRGRP S_IRUSR @@ -95,7 +92,6 @@ #define MODE_R_ALL (S_IRUSR | S_IRGRP | S_IROTH) #define MODE_W_ALL (S_IWUSR | S_IWGRP | S_IWOTH) #define MODE_X_ALL (S_IXUSR | S_IXGRP | S_IXOTH) -#define USERDATA_DIR_MODE (MODE_R_ALL | MODE_X_ALL | S_IWUSR) #define LEVEL_PERMS (MODE_R_ALL | MODE_W_ALL) #define SCORE_PERMS LEVEL_PERMS #define TAPE_PERMS LEVEL_PERMS @@ -198,6 +194,53 @@ char *levelclass_desc[NUM_LEVELCLASS_DESC] = IS_LEVELCLASS_USER(n) ? 7 : \ 9) +static int getFileVersionFromCookieString(const char *cookie) +{ + const char *ptr_cookie1, *ptr_cookie2; + const char *pattern1 = "_FILE_VERSION_"; + const char *pattern2 = "?.?"; + const int len_cookie = strlen(cookie); + const int len_pattern1 = strlen(pattern1); + const int len_pattern2 = strlen(pattern2); + const int len_pattern = len_pattern1 + len_pattern2; + int version_major, version_minor; + + if (len_cookie <= len_pattern) + return -1; + + ptr_cookie1 = &cookie[len_cookie - len_pattern]; + ptr_cookie2 = &cookie[len_cookie - len_pattern2]; + + if (strncmp(ptr_cookie1, pattern1, len_pattern1) != 0) + return -1; + + if (ptr_cookie2[0] <= '0' || ptr_cookie2[0] >= '9' || + ptr_cookie2[1] != '.' || + ptr_cookie2[2] <= '0' || ptr_cookie2[2] >= '9') + return -1; + + version_major = ptr_cookie2[0] - '0'; + version_minor = ptr_cookie2[2] - '0'; + + return (version_major * 10 + version_minor); +} + +boolean checkCookieString(const char *cookie, const char *template) +{ + const char *pattern = "_FILE_VERSION_?.?"; + const int len_cookie = strlen(cookie); + const int len_template = strlen(template); + const int len_pattern = strlen(pattern); + + if (len_cookie != len_template) + return FALSE; + + if (strncmp(cookie, template, len_cookie - len_pattern) != 0) + return FALSE; + + return TRUE; +} + char *getLevelClassDescription(struct LevelDirInfo *ldi) { int position = ldi->sort_priority / 100; @@ -211,21 +254,6 @@ char *getLevelClassDescription(struct LevelDirInfo *ldi) static void SaveUserLevelInfo(); /* for 'InitUserLevelDir()' */ static char *getSetupLine(char *, int); /* for 'SaveUserLevelInfo()' */ -char *getUserDataDir() -{ - static char *userdata_dir = NULL; - - if (!userdata_dir) - { - char *home_dir = getHomeDir(); - char *data_dir = USERDATA_DIRECTORY; - - userdata_dir = getPath2(home_dir, data_dir); - } - - return userdata_dir; -} - static char *getSetupDir() { return getUserDataDir(); @@ -345,22 +373,6 @@ static char *getScoreFilename(int nr) return filename; } -static void createDirectory(char *dir, char *text) -{ - if (access(dir, F_OK) != 0) -#if defined(PLATFORM_WIN32) - if (mkdir(dir) != 0) -#else - if (mkdir(dir, USERDATA_DIR_MODE) != 0) -#endif - Error(ERR_WARN, "cannot create %s directory '%s'", text, dir); -} - -static void InitUserDataDirectory() -{ - createDirectory(getUserDataDir(), "user data"); -} - static void InitTapeDirectory(char *level_subdir) { createDirectory(getUserDataDir(), "user data"); @@ -397,6 +409,9 @@ static void setLevelInfoToDefaults() { int i, x, y; + level.file_version = FILE_VERSION_ACTUAL; + level.game_version = GAME_VERSION_ACTUAL; + lev_fieldx = level.fieldx = STD_LEV_FIELDX; lev_fieldy = level.fieldy = STD_LEV_FIELDY; @@ -487,14 +502,14 @@ void LoadLevel(int level_nr) char cookie[MAX_LINE_LEN]; char chunk[CHUNK_ID_LEN + 1]; boolean encoding_16bit = FALSE; /* default: maximal 256 elements */ - int file_version = FILE_VERSION_1_4; /* last version of level files */ + int file_version = FILE_VERSION_ACTUAL; int chunk_length; FILE *file; /* always start with reliable default values */ setLevelInfoToDefaults(); - if (!(file = fopen(filename, "r"))) + if (!(file = fopen(filename, MODE_READ))) { Error(ERR_WARN, "cannot read level '%s' - creating new level", filename); return; @@ -505,6 +520,7 @@ void LoadLevel(int level_nr) if (strlen(cookie) > 0 && cookie[strlen(cookie) - 1] == '\n') cookie[strlen(cookie) - 1] = '\0'; +#if 0 if (strcmp(cookie, LEVEL_COOKIE_10) == 0) /* old 1.0 level format */ file_version = FILE_VERSION_1_0; else if (strcmp(cookie, LEVEL_COOKIE_12) == 0)/* 1.2 (8 bit) level format */ @@ -515,6 +531,18 @@ void LoadLevel(int level_nr) fclose(file); return; } +#else + if (!checkCookieString(cookie, LEVEL_COOKIE)) /* unknown file format */ + { + Error(ERR_WARN, "unknown format of level file '%s'", filename); + fclose(file); + return; + } + + file_version = getFileVersionFromCookieString(cookie); +#endif + + level.file_version = file_version; /* read chunk "HEAD" */ if (file_version >= FILE_VERSION_1_2) @@ -637,13 +665,26 @@ void LoadLevel(int level_nr) fclose(file); - /* player was faster than monsters in pre-1.0 levels */ - if (file_version == FILE_VERSION_1_0 && - IS_LEVELCLASS_CONTRIBUTION(leveldir_current)) + if (IS_LEVELCLASS_CONTRIBUTION(leveldir_current) || + IS_LEVELCLASS_USER(leveldir_current)) { - Error(ERR_WARN, "level file '%s' has version number 1.0", filename); - Error(ERR_WARN, "using high speed movement for player"); - level.double_speed = TRUE; + /* for user contributed and private levels, use the version of + the game engine the levels were created for */ + level.game_version = file_version; + + /* player was faster than monsters in pre-1.0 levels */ + if (file_version == FILE_VERSION_1_0) + { + Error(ERR_WARN, "level file '%s' has version number 1.0", filename); + Error(ERR_WARN, "using high speed movement for player"); + level.double_speed = TRUE; + } + } + else + { + /* always use the latest version of the game engine for all but + user contributed and private levels */ + level.game_version = GAME_VERSION_ACTUAL; } /* determine border element for this level */ @@ -658,7 +699,7 @@ void SaveLevel(int level_nr) char *oldest_possible_cookie; FILE *file; - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot save level file '%s'", filename); return; @@ -754,10 +795,12 @@ void LoadTape(int level_nr) char chunk[CHUNK_ID_LEN + 1]; FILE *file; int num_participating_players; - int file_version = FILE_VERSION_1_2; /* last version of tape files */ + int file_version = FILE_VERSION_ACTUAL; /* last version of tape files */ int chunk_length; /* always start with reliable default values (empty tape) */ + tape.file_version = FILE_VERSION_ACTUAL; + tape.game_version = GAME_VERSION_ACTUAL; TapeErase(); /* default values (also for pre-1.2 tapes) with only the first player */ @@ -768,7 +811,7 @@ void LoadTape(int level_nr) /* at least one (default: the first) player participates in every tape */ num_participating_players = 1; - if (!(file = fopen(filename, "r"))) + if (!(file = fopen(filename, MODE_READ))) return; /* check file identifier */ @@ -776,6 +819,7 @@ void LoadTape(int level_nr) if (strlen(cookie) > 0 && cookie[strlen(cookie) - 1] == '\n') cookie[strlen(cookie) - 1] = '\0'; +#if 0 if (strcmp(cookie, TAPE_COOKIE_10) == 0) /* old 1.0 tape format */ file_version = FILE_VERSION_1_0; else if (strcmp(cookie, TAPE_COOKIE) != 0) /* unknown tape format */ @@ -784,6 +828,19 @@ void LoadTape(int level_nr) fclose(file); return; } +#else + if (!checkCookieString(cookie, TAPE_COOKIE)) /* unknown file format */ + { + Error(ERR_WARN, "unknown format of tape file '%s'", filename); + fclose(file); + return; + } + + file_version = getFileVersionFromCookieString(cookie); +#endif + + tape.file_version = file_version; + tape.game_version = file_version; /* read chunk "HEAD" */ if (file_version >= FILE_VERSION_1_2) @@ -930,7 +987,7 @@ void SaveTape(int level_nr) } } - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot save level recording file '%s'", filename); return; @@ -990,7 +1047,7 @@ void LoadScore(int level_nr) highscore[i].Score = 0; } - if (!(file = fopen(filename, "r"))) + if (!(file = fopen(filename, MODE_READ))) return; /* check file identifier */ @@ -998,12 +1055,21 @@ void LoadScore(int level_nr) if (strlen(cookie) > 0 && cookie[strlen(cookie) - 1] == '\n') cookie[strlen(cookie) - 1] = '\0'; +#if 0 if (strcmp(cookie, SCORE_COOKIE) != 0) { Error(ERR_WARN, "wrong file identifier of score file '%s'", filename); fclose(file); return; } +#else + if (!checkCookieString(cookie, SCORE_COOKIE)) /* unknown file format */ + { + Error(ERR_WARN, "unknown format of score file '%s'", filename); + fclose(file); + return; + } +#endif for(i=0; ifilename); - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot save score for level %d", level_nr); return; @@ -1342,7 +1408,7 @@ static struct SetupFileList *loadSetupFileList(char *filename) FILE *file; - if (!(file = fopen(filename, "r"))) + if (!(file = fopen(filename, MODE_READ))) { Error(ERR_WARN, "cannot open configuration file '%s'", filename); return NULL; @@ -1820,7 +1886,7 @@ static void SaveUserLevelInfo() filename = getPath2(getUserLevelDir(getLoginName()), LEVELINFO_FILENAME); - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot write level info file '%s'", filename); free(filename); @@ -1964,7 +2030,7 @@ void SaveSetup() filename = getPath2(getSetupDir(), SETUP_FILENAME); - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot write setup file '%s'", filename); free(filename); @@ -2052,7 +2118,7 @@ void SaveLevelSetup_LastSeries() filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME); - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot write setup file '%s'", filename); free(filename); @@ -2197,7 +2263,7 @@ void SaveLevelSetup_SeriesInfo() filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME); - if (!(file = fopen(filename, "w"))) + if (!(file = fopen(filename, MODE_WRITE))) { Error(ERR_WARN, "cannot write setup file '%s'", filename); free(filename); @@ -2216,46 +2282,5 @@ void SaveLevelSetup_SeriesInfo() chmod(filename, SETUP_PERMS); } - -#if !defined(PLATFORM_UNIX) -void initErrorFile() -{ - char *filename; - - InitUserDataDirectory(); - - filename = getPath2(getUserDataDir(), ERROR_FILENAME); - unlink(filename); - free(filename); -} - -FILE *openErrorFile() -{ - char *filename; - FILE *error_file; - - filename = getPath2(getUserDataDir(), ERROR_FILENAME); - error_file = fopen(filename, "a"); - free(filename); - - return error_file; -} - -void dumpErrorFile() -{ - char *filename; - FILE *error_file; - - filename = getPath2(getUserDataDir(), ERROR_FILENAME); - error_file = fopen(filename, "r"); - free(filename); - - if (error_file != NULL) - { - while (!feof(error_file)) - fputc(fgetc(error_file), stderr); - - fclose(error_file); - } -} -#endif +/* LocalWords: Rocks'n + */