/***********************************************************
-* 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 <ctype.h>
#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"
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;
{
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;
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;
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 */
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)
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))
+ {
+ /* 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
{
- 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;
+ /* 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 */
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;
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 */
/* 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 */
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 */
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)
}
}
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save level recording file '%s'", filename);
return;
highscore[i].Score = 0;
}
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
return;
/* check file identifier */
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; i<MAX_SCORE_ENTRIES; i++)
{
InitScoreDirectory(leveldir_current->filename);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save score for level %d", level_nr);
return;
FILE *file;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
return NULL;
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);
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);
struct SetupFileList *level_setup_list = NULL;
/* always start with reliable default values */
- leveldir_current = leveldir_first;
+ leveldir_current = getFirstValidLevelSeries(leveldir_first);
/* ----------------------------------------------------------------------- */
/* ~/.rocksndiamonds/levelsetup.conf */
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);
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);
chmod(filename, SETUP_PERMS);
}
+/* LocalWords: Rocks'n
+ */