/***********************************************************
-* 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 <dirent.h>
#include <sys/stat.h>
+#include "libgame/libgame.h"
+
#include "files.h"
#include "tools.h"
-#include "misc.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"
+#define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_2.0"
#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2"
#define TAPE_COOKIE "ROCKSNDIAMONDS_TAPE_FILE_VERSION_1.2"
#define SETUP_COOKIE "ROCKSNDIAMONDS_SETUP_FILE_VERSION_1.2"
/* old file identifiers for backward compatibility */
#define LEVEL_COOKIE_10 "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.0"
#define LEVEL_COOKIE_12 "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.2"
+#define LEVEL_COOKIE_14 "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.4"
#define TAPE_COOKIE_10 "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0"
/* file names and filename extensions */
-#ifndef MSDOS
-#define USERDATA_DIRECTORY ".rocksndiamonds"
+#if !defined(PLATFORM_MSDOS)
#define LEVELSETUP_DIRECTORY "levelsetup"
#define SETUP_FILENAME "setup.conf"
#define LEVELSETUP_FILENAME "levelsetup.conf"
#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"
#define SCOREFILE_EXTENSION "sco"
#endif
-#if defined(MSDOS) || defined(WIN32)
-#define ERROR_FILENAME "error.out"
-#endif
-
-#ifdef WIN32
+#if defined(PLATFORM_WIN32)
#ifndef S_IRGRP
#define S_IRGRP S_IRUSR
#endif
#ifndef S_IXOTH
#define S_IXOTH S_IXUSR
#endif
-#endif
+#endif /* PLATFORM_WIN32 */
/* file permissions for newly written files */
#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
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;
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();
return filename;
}
-static void createDirectory(char *dir, char *text)
-{
- if (access(dir, F_OK) != 0)
-#ifdef 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");
{
int i, x, y;
+ level.file_version = FILE_VERSION_ACTUAL;
+ level.game_version = GAME_VERSION_ACTUAL;
+
+ level.encoding_16bit = FALSE; /* default: only 8-bit elements */
+
lev_fieldx = level.fieldx = STD_LEV_FIELDX;
lev_fieldy = level.fieldy = STD_LEV_FIELDY;
return element;
}
-void LoadLevel(int level_nr)
+void OLD_LoadLevel(int level_nr)
{
int i, x, y;
char *filename = getLevelFilename(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;
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)
}
/* next check body chunk identifier and chunk length */
- if (strcmp(chunk, "BODY") || chunk_length != lev_fieldx * lev_fieldy)
+ if (strcmp(chunk, "BODY") != 0 || chunk_length != lev_fieldx * lev_fieldy)
{
Error(ERR_WARN, "wrong 'BODY' chunk of level file '%s'", filename);
fclose(file);
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
+ {
+ /* 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 */
+ SetBorderElement();
+}
+
+static void SkipBytesInFile(FILE *file, unsigned long bytes)
+{
+ while (bytes--)
+ fgetc(file);
+}
+
+static void LoadLevel_HEAD(struct LevelInfo *level, FILE *file)
+{
+ int i, x, y;
+
+ lev_fieldx = level->fieldx = fgetc(file);
+ lev_fieldy = level->fieldy = fgetc(file);
+
+ level->time = getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN);
+ level->gems_needed = getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN);
+
+ for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
+ level->name[i] = fgetc(file);
+ level->name[MAX_LEVEL_NAME_LEN] = 0;
+
+ for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
+ level->score[i] = fgetc(file);
+
+ level->num_yam_contents = STD_ELEMENT_CONTENTS;
+ for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ {
+ for(y=0; y<3; y++)
+ {
+ for(x=0; x<3; x++)
+ {
+ if (i < STD_ELEMENT_CONTENTS)
+ level->yam_content[i][x][y] = checkLevelElement(fgetc(file));
+ else
+ level->yam_content[i][x][y] = EL_LEERRAUM;
+ }
+ }
+ }
+
+ level->amoeba_speed = fgetc(file);
+ level->time_magic_wall = fgetc(file);
+ level->time_wheel = fgetc(file);
+ level->amoeba_content = checkLevelElement(fgetc(file));
+ level->double_speed = (fgetc(file) == 1 ? TRUE : FALSE);
+ level->gravity = (fgetc(file) == 1 ? TRUE : FALSE);
+
+ level->encoding_16bit = (fgetc(file) == 1 ? TRUE : FALSE);
+
+ SkipBytesInFile(file, LEVEL_HEADER_UNUSED); /* skip unused header bytes */
+}
+
+static void LoadLevel_AUTH(struct LevelInfo *level, FILE *file)
+{
+ int i;
+
+ for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
+ level->author[i] = fgetc(file);
+ level->author[MAX_LEVEL_NAME_LEN] = 0;
+}
+
+static void LoadLevel_CONT(struct LevelInfo *level, FILE *file)
+{
+ int i, x, y;
+
+ fgetc(file);
+ level->num_yam_contents = fgetc(file);
+ fgetc(file);
+ fgetc(file);
+
+ if (level->num_yam_contents < 1 ||
+ level->num_yam_contents > MAX_ELEMENT_CONTENTS)
+ {
+#if DEBUG
+ printf("WARNING: num_yam_contents == %d (corrected)\n",
+ level->num_yam_contents);
+#endif
+ level->num_yam_contents = STD_ELEMENT_CONTENTS;
+ }
+
+ for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ level->yam_content[i][x][y] =
+ checkLevelElement(level->encoding_16bit ?
+ getFile16BitInteger(file,
+ BYTE_ORDER_BIG_ENDIAN) :
+ fgetc(file));
+}
+
+static void LoadLevel_BODY(struct LevelInfo *level, FILE *file)
+{
+ int x, y;
+
+ for(y=0; y<level->fieldy; y++)
+ for(x=0; x<level->fieldx; x++)
+ Feld[x][y] = Ur[x][y] =
+ checkLevelElement(level->encoding_16bit ?
+ getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN) :
+ fgetc(file));
+}
+
+void LoadLevel(int level_nr)
+{
+ char *filename = getLevelFilename(level_nr);
+ char cookie[MAX_LINE_LEN];
+ char chunk[CHUNK_ID_LEN + 1];
+ int chunk_length;
+ FILE *file;
+
+ /* always start with reliable default values */
+ setLevelInfoToDefaults();
+
+ if (!(file = fopen(filename, MODE_READ)))
+ {
+ Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
+ return;
+ }
+
+ /* check file identifier */
+ fgets(cookie, MAX_LINE_LEN, file);
+ if (strlen(cookie) > 0 && cookie[strlen(cookie) - 1] == '\n')
+ cookie[strlen(cookie) - 1] = '\0';
+
+ if (!checkCookieString(cookie, LEVEL_COOKIE)) /* unknown file format */
+ {
+ Error(ERR_WARN, "unknown format of level file '%s'", filename);
+ fclose(file);
+ return;
+ }
+
+ if ((level.file_version = getFileVersionFromCookieString(cookie)) == -1)
+ {
+ Error(ERR_WARN, "unsupported version of level file '%s'", filename);
+ fclose(file);
+ return;
+ }
+
+ if (level.file_version < FILE_VERSION_1_2)
+ {
+ /* level files from versions before 1.2.0 without chunk structure */
+ LoadLevel_HEAD(&level, file);
+ LoadLevel_BODY(&level, file);
+ }
+ else
+ {
+ static struct
+ {
+ char *chunk_name;
+ void (*chunk_loader)(struct LevelInfo *, FILE *);
+ int chunk_length;
+ }
+ chunk_info[] =
+ {
+ { "HEAD", LoadLevel_HEAD, LEVEL_HEADER_SIZE },
+ { "AUTH", LoadLevel_AUTH, MAX_LEVEL_AUTHOR_LEN },
+ { "CONT", LoadLevel_CONT, 4 + MAX_ELEMENT_CONTENTS * 3 * 3 },
+ { "BODY", LoadLevel_BODY, 0 }, /* depends on contents of "HEAD" */
+ { NULL, NULL, 0 }
+ };
+
+ while (getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN))
+ {
+ int i = 0;
+
+ while (chunk_info[i].chunk_name != NULL &&
+ strcmp(chunk, chunk_info[i].chunk_name) != 0)
+ i++;
+
+ if (chunk_info[i].chunk_name == NULL)
+ {
+ Error(ERR_WARN, "unknown chunk '%s' in level file '%s'",
+ chunk, filename);
+ SkipBytesInFile(file, chunk_length);
+ }
+ else if (chunk_length != chunk_info[i].chunk_length)
+ {
+ Error(ERR_WARN, "wrong size (%d) of chunk '%s' in level file '%s'",
+ chunk_length, chunk, filename);
+ SkipBytesInFile(file, chunk_length);
+ }
+ else
+ {
+ /* call function to load this level chunk */
+ (chunk_info[i].chunk_loader)(&level, file);
+
+ if (strcmp(chunk, "HEAD") == 0)
+ {
+ /* Note: "chunk_length" for CONT and BODY is wrong when elements are
+ stored with 16-bit encoding (and should be twice as big then). */
+
+ chunk_info[3].chunk_length = level.fieldx * level.fieldy;
+ }
+ }
+ }
+
+#if 0
+ getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
+ if (strcmp(chunk, "HEAD") || chunk_length != LEVEL_HEADER_SIZE)
+ {
+ Error(ERR_WARN, "wrong 'HEAD' chunk of level file '%s'", filename);
+ fclose(file);
+ return;
+ }
+
+ LoadLevel_HEAD(&level, file);
+
+ getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
+
+ /* look for optional author chunk */
+ if (strcmp(chunk, "AUTH") == 0 && chunk_length == MAX_LEVEL_AUTHOR_LEN)
+ {
+ LoadLevel_AUTH(&level, file);
+
+ getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
+ }
+
+ /* look for optional content chunk */
+ if (strcmp(chunk, "CONT") == 0 &&
+ chunk_length == 4 + MAX_ELEMENT_CONTENTS * 3 * 3)
+ {
+ LoadLevel_CONT(&level, file);
+
+ getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
+ }
+
+ /* next check body chunk identifier and chunk length */
+ if (strcmp(chunk, "BODY") != 0 || chunk_length != lev_fieldx * lev_fieldy)
+ {
+ Error(ERR_WARN, "wrong 'BODY' chunk of level file '%s'", filename);
+ fclose(file);
+ return;
+ }
+
+ LoadLevel_BODY(&level, file);
+#endif
+ }
+
+ fclose(file);
+
+ 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 = level.file_version;
+
+ /* player was faster than monsters in pre-1.0 levels */
+ if (level.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 */
{
int i, x, y;
char *filename = getLevelFilename(level_nr);
- boolean encoding_16bit = FALSE; /* default: maximal 256 elements */
+#if 0
+ boolean encoding_16bit_amoeba = FALSE;
+ boolean encoding_16bit_yamyam = FALSE;
+#endif
+ boolean encoding_16bit = FALSE; /* default: only 8-bit elements */
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;
#define SETUP_TOKEN_TEAM_MODE 10
#define SETUP_TOKEN_HANDICAP 11
#define SETUP_TOKEN_TIME_LIMIT 12
+#define SETUP_TOKEN_FULLSCREEN 13
/* player setup */
-#define SETUP_TOKEN_USE_JOYSTICK 13
-#define SETUP_TOKEN_JOY_DEVICE_NAME 14
-#define SETUP_TOKEN_JOY_XLEFT 15
-#define SETUP_TOKEN_JOY_XMIDDLE 16
-#define SETUP_TOKEN_JOY_XRIGHT 17
-#define SETUP_TOKEN_JOY_YUPPER 18
-#define SETUP_TOKEN_JOY_YMIDDLE 19
-#define SETUP_TOKEN_JOY_YLOWER 20
-#define SETUP_TOKEN_JOY_SNAP 21
-#define SETUP_TOKEN_JOY_BOMB 22
-#define SETUP_TOKEN_KEY_LEFT 23
-#define SETUP_TOKEN_KEY_RIGHT 24
-#define SETUP_TOKEN_KEY_UP 25
-#define SETUP_TOKEN_KEY_DOWN 26
-#define SETUP_TOKEN_KEY_SNAP 27
-#define SETUP_TOKEN_KEY_BOMB 28
+#define SETUP_TOKEN_USE_JOYSTICK 14
+#define SETUP_TOKEN_JOY_DEVICE_NAME 15
+#define SETUP_TOKEN_JOY_XLEFT 16
+#define SETUP_TOKEN_JOY_XMIDDLE 17
+#define SETUP_TOKEN_JOY_XRIGHT 18
+#define SETUP_TOKEN_JOY_YUPPER 19
+#define SETUP_TOKEN_JOY_YMIDDLE 20
+#define SETUP_TOKEN_JOY_YLOWER 21
+#define SETUP_TOKEN_JOY_SNAP 22
+#define SETUP_TOKEN_JOY_BOMB 23
+#define SETUP_TOKEN_KEY_LEFT 24
+#define SETUP_TOKEN_KEY_RIGHT 25
+#define SETUP_TOKEN_KEY_UP 26
+#define SETUP_TOKEN_KEY_DOWN 27
+#define SETUP_TOKEN_KEY_SNAP 28
+#define SETUP_TOKEN_KEY_BOMB 29
/* level directory info */
-#define LEVELINFO_TOKEN_NAME 29
-#define LEVELINFO_TOKEN_NAME_SHORT 30
-#define LEVELINFO_TOKEN_NAME_SORTING 31
-#define LEVELINFO_TOKEN_AUTHOR 32
-#define LEVELINFO_TOKEN_IMPORTED_FROM 33
-#define LEVELINFO_TOKEN_LEVELS 34
-#define LEVELINFO_TOKEN_FIRST_LEVEL 35
-#define LEVELINFO_TOKEN_SORT_PRIORITY 36
-#define LEVELINFO_TOKEN_LEVEL_GROUP 37
-#define LEVELINFO_TOKEN_READONLY 38
+#define LEVELINFO_TOKEN_NAME 30
+#define LEVELINFO_TOKEN_NAME_SHORT 31
+#define LEVELINFO_TOKEN_NAME_SORTING 32
+#define LEVELINFO_TOKEN_AUTHOR 33
+#define LEVELINFO_TOKEN_IMPORTED_FROM 34
+#define LEVELINFO_TOKEN_LEVELS 35
+#define LEVELINFO_TOKEN_FIRST_LEVEL 36
+#define LEVELINFO_TOKEN_SORT_PRIORITY 37
+#define LEVELINFO_TOKEN_LEVEL_GROUP 38
+#define LEVELINFO_TOKEN_READONLY 39
#define FIRST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_PLAYER_NAME
-#define LAST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_TIME_LIMIT
+#define LAST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_FULLSCREEN
#define FIRST_PLAYER_SETUP_TOKEN SETUP_TOKEN_USE_JOYSTICK
#define LAST_PLAYER_SETUP_TOKEN SETUP_TOKEN_KEY_BOMB
{ TYPE_SWITCH, &si.team_mode, "team_mode" },
{ TYPE_SWITCH, &si.handicap, "handicap" },
{ TYPE_SWITCH, &si.time_limit, "time_limit" },
+ { TYPE_SWITCH, &si.fullscreen, "fullscreen" },
/* player setup */
{ TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" },
FILE *file;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
return NULL;
si->team_mode = FALSE;
si->handicap = TRUE;
si->time_limit = TRUE;
+ si->fullscreen = FALSE;
for (i=0; i<MAX_PLAYERS; i++)
{
si->input[i].joy.ylower = JOYSTICK_YLOWER;
si->input[i].joy.snap = (i == 0 ? JOY_BUTTON_1 : 0);
si->input[i].joy.bomb = (i == 0 ? JOY_BUTTON_2 : 0);
- si->input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KEY_UNDEFINED);
- si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KEY_UNDEFINED);
- si->input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KEY_UNDEFINED);
- si->input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KEY_UNDEFINED);
- si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KEY_UNDEFINED);
- si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KEY_UNDEFINED);
+ si->input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KSYM_UNDEFINED);
+ si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KSYM_UNDEFINED);
+ si->input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KSYM_UNDEFINED);
+ si->input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KSYM_UNDEFINED);
+ si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED);
+ si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED);
}
}
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);
level_directory = getPath2((leveldir_current->user_defined ?
getUserLevelDir("") :
options.level_directory),
- leveldir_current->filename);
+ leveldir_current->fullpath);
if ((dir = opendir(level_directory)) == NULL)
{
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);
}
-
-#if defined(MSDOS) || defined(WIN32)
-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
+ */