#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 */
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;
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;
}
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
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)
{
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)
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)
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;
}
/* 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)
{
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];
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++)
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;
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);
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;
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;
/* 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,