#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 16 /* unused level header bytes */
+#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 /* old 1.0 file version */
-#define FILE_VERSION_1_2 12 /* actual file version */
+#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) */
/* file identifier strings */
-#define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.2"
+#define LEVEL_COOKIE "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_1.4"
#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"
#define LEVELINFO_COOKIE "ROCKSNDIAMONDS_LEVELINFO_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 TAPE_COOKIE_10 "ROCKSNDIAMONDS_LEVELREC_FILE_VERSION_1.0"
/* file names and filename extensions */
#define LEVELCLASS_CONTRIBUTION_END 299
#define LEVELCLASS_USER_START 300
#define LEVELCLASS_USER_END 399
+#define LEVELCLASS_BD_START 400
+#define LEVELCLASS_BD_END 499
+#define LEVELCLASS_EM_START 500
+#define LEVELCLASS_EM_END 599
+#define LEVELCLASS_SP_START 600
+#define LEVELCLASS_SP_END 699
+#define LEVELCLASS_DX_START 700
+#define LEVELCLASS_DX_END 799
#define LEVELCLASS_TUTORIAL LEVELCLASS_TUTORIAL_START
#define LEVELCLASS_CLASSICS LEVELCLASS_CLASSICS_START
#define LEVELCLASS_CONTRIBUTION LEVELCLASS_CONTRIBUTION_START
#define LEVELCLASS_USER LEVELCLASS_USER_START
+#define LEVELCLASS_BD LEVELCLASS_BD_START
+#define LEVELCLASS_EM LEVELCLASS_EM_START
+#define LEVELCLASS_SP LEVELCLASS_SP_START
+#define LEVELCLASS_DX LEVELCLASS_DX_START
+
#define LEVELCLASS_UNDEFINED 999
-#define IS_LEVELCLASS_TUTORIAL(n) \
- (leveldir[n].sort_priority >= LEVELCLASS_TUTORIAL_START && \
- leveldir[n].sort_priority <= LEVELCLASS_TUTORIAL_END)
-#define IS_LEVELCLASS_CLASSICS(n) \
- (leveldir[n].sort_priority >= LEVELCLASS_CLASSICS_START && \
- leveldir[n].sort_priority <= LEVELCLASS_CLASSICS_END)
-#define IS_LEVELCLASS_CONTRIBUTION(n) \
- (leveldir[n].sort_priority >= LEVELCLASS_CONTRIBUTION_START && \
- leveldir[n].sort_priority <= LEVELCLASS_CONTRIBUTION_END)
-#define IS_LEVELCLASS_USER(n) \
- (leveldir[n].sort_priority >= LEVELCLASS_USER_START && \
- leveldir[n].sort_priority <= LEVELCLASS_USER_END)
+#define NUM_LEVELCLASS_DESC 8
+char *levelclass_desc[NUM_LEVELCLASS_DESC] =
+{
+ "Tutorial Levels",
+ "Classic Originals",
+ "Contributions",
+ "Private Levels",
+ "Boulderdash",
+ "Emerald Mine",
+ "Supaplex",
+ "DX Boulderdash"
+};
+
+#define IS_LEVELCLASS_TUTORIAL(p) \
+ ((p)->sort_priority >= LEVELCLASS_TUTORIAL_START && \
+ (p)->sort_priority <= LEVELCLASS_TUTORIAL_END)
+#define IS_LEVELCLASS_CLASSICS(p) \
+ ((p)->sort_priority >= LEVELCLASS_CLASSICS_START && \
+ (p)->sort_priority <= LEVELCLASS_CLASSICS_END)
+#define IS_LEVELCLASS_CONTRIBUTION(p) \
+ ((p)->sort_priority >= LEVELCLASS_CONTRIBUTION_START && \
+ (p)->sort_priority <= LEVELCLASS_CONTRIBUTION_END)
+#define IS_LEVELCLASS_USER(p) \
+ ((p)->sort_priority >= LEVELCLASS_USER_START && \
+ (p)->sort_priority <= LEVELCLASS_USER_END)
+#define IS_LEVELCLASS_BD(p) \
+ ((p)->sort_priority >= LEVELCLASS_BD_START && \
+ (p)->sort_priority <= LEVELCLASS_BD_END)
+#define IS_LEVELCLASS_EM(p) \
+ ((p)->sort_priority >= LEVELCLASS_EM_START && \
+ (p)->sort_priority <= LEVELCLASS_EM_END)
+#define IS_LEVELCLASS_SP(p) \
+ ((p)->sort_priority >= LEVELCLASS_SP_START && \
+ (p)->sort_priority <= LEVELCLASS_SP_END)
+#define IS_LEVELCLASS_DX(p) \
+ ((p)->sort_priority >= LEVELCLASS_DX_START && \
+ (p)->sort_priority <= LEVELCLASS_DX_END)
#define LEVELCLASS(n) (IS_LEVELCLASS_TUTORIAL(n) ? LEVELCLASS_TUTORIAL : \
IS_LEVELCLASS_CLASSICS(n) ? LEVELCLASS_CLASSICS : \
IS_LEVELCLASS_CONTRIBUTION(n) ? LEVELCLASS_CONTRIBUTION : \
IS_LEVELCLASS_USER(n) ? LEVELCLASS_USER : \
+ IS_LEVELCLASS_BD(n) ? LEVELCLASS_BD : \
+ IS_LEVELCLASS_EM(n) ? LEVELCLASS_EM : \
+ IS_LEVELCLASS_SP(n) ? LEVELCLASS_SP : \
+ IS_LEVELCLASS_DX(n) ? LEVELCLASS_DX : \
LEVELCLASS_UNDEFINED)
-#define LEVELCOLOR(n) (IS_LEVELCLASS_TUTORIAL(n) ? FC_BLUE : \
- IS_LEVELCLASS_CLASSICS(n) ? FC_YELLOW : \
- IS_LEVELCLASS_CONTRIBUTION(n) ? FC_GREEN : \
- IS_LEVELCLASS_USER(n) ? FC_RED : FC_BLUE)
+#define LEVELCOLOR(n) (IS_LEVELCLASS_TUTORIAL(n) ? FC_BLUE : \
+ IS_LEVELCLASS_CLASSICS(n) ? FC_RED : \
+ IS_LEVELCLASS_BD(n) ? FC_GREEN : \
+ IS_LEVELCLASS_EM(n) ? FC_YELLOW : \
+ IS_LEVELCLASS_SP(n) ? FC_GREEN : \
+ IS_LEVELCLASS_DX(n) ? FC_YELLOW : \
+ IS_LEVELCLASS_CONTRIBUTION(n) ? FC_GREEN : \
+ IS_LEVELCLASS_USER(n) ? FC_RED : \
+ FC_BLUE)
+
+#define LEVELSORTING(n) (IS_LEVELCLASS_TUTORIAL(n) ? 0 : \
+ IS_LEVELCLASS_CLASSICS(n) ? 1 : \
+ IS_LEVELCLASS_BD(n) ? 2 : \
+ IS_LEVELCLASS_EM(n) ? 3 : \
+ IS_LEVELCLASS_SP(n) ? 4 : \
+ IS_LEVELCLASS_DX(n) ? 5 : \
+ IS_LEVELCLASS_CONTRIBUTION(n) ? 6 : \
+ IS_LEVELCLASS_USER(n) ? 7 : \
+ 9)
+
+char *getLevelClassDescription(struct LevelDirInfo *ldi)
+{
+ int position = ldi->sort_priority / 100;
+
+ if (position >= 0 && position < NUM_LEVELCLASS_DESC)
+ return levelclass_desc[position];
+ else
+ return "Unknown Level Class";
+}
static void SaveUserLevelInfo(); /* for 'InitUserLevelDir()' */
static char *getSetupLine(char *, int); /* for 'SaveUserLevelInfo()' */
}
else
{
- switch (LEVELCLASS(leveldir_nr))
+ switch (LEVELCLASS(&leveldir[leveldir_nr]))
{
case LEVELCLASS_TUTORIAL:
strcpy(level.author, PROGRAM_AUTHOR_STRING);
char *filename = getLevelFilename(level_nr);
char cookie[MAX_LINE_LEN];
char chunk[CHUNK_ID_LEN + 1];
- int file_version = FILE_VERSION_1_2; /* last version of level files */
+ boolean encoding_16bit = FALSE; /* default: maximal 256 elements */
+ int file_version = FILE_VERSION_1_4; /* last version of level files */
int chunk_length;
FILE *file;
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 */
+ file_version = FILE_VERSION_1_2;
else if (strcmp(cookie, LEVEL_COOKIE) != 0) /* unknown level format */
{
Error(ERR_WARN, "wrong file identifier of level file '%s'", filename);
level.double_speed = (fgetc(file) == 1 ? TRUE : FALSE);
level.gravity = (fgetc(file) == 1 ? TRUE : FALSE);
+ encoding_16bit = (fgetc(file) == 1 ? TRUE : FALSE);
+
for(i=0; i<LEVEL_HEADER_UNUSED; i++) /* skip unused header bytes */
fgetc(file);
- /* read chunk "BODY" */
if (file_version >= FILE_VERSION_1_2)
{
getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
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] = fgetc(file);
+ level.yam_content[i][x][y] =
+ (encoding_16bit ?
+ getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN) :
+ fgetc(file));
getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_BIG_ENDIAN);
}
/* now read in the valid level fields from level file */
for(y=0; y<lev_fieldy; y++)
for(x=0; x<lev_fieldx; x++)
- Feld[x][y] = Ur[x][y] = fgetc(file);
+ Feld[x][y] = Ur[x][y] =
+ (encoding_16bit ?
+ getFile16BitInteger(file, BYTE_ORDER_BIG_ENDIAN) :
+ fgetc(file));
fclose(file);
/* player was faster than monsters in pre-1.0 levels */
if (file_version == FILE_VERSION_1_0 &&
- IS_LEVELCLASS_CONTRIBUTION(leveldir_nr))
+ IS_LEVELCLASS_CONTRIBUTION(&leveldir[leveldir_nr]))
{
Error(ERR_WARN, "level file '%s' has version number 1.0", filename);
Error(ERR_WARN, "using high speed movement for player");
{
int i, x, y;
char *filename = getLevelFilename(level_nr);
+ boolean encoding_16bit = FALSE; /* default: maximal 256 elements */
+ char *oldest_possible_cookie;
FILE *file;
if (!(file = fopen(filename, "w")))
return;
}
- fputs(LEVEL_COOKIE, file); /* file identifier */
+ /* check yam content for 16-bit elements */
+ for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ if (level.yam_content[i][x][y] > 255)
+ encoding_16bit = TRUE;
+
+ /* check level field for 16-bit elements */
+ for(y=0; y<lev_fieldy; y++)
+ for(x=0; x<lev_fieldx; x++)
+ if (Ur[x][y] > 255)
+ encoding_16bit = TRUE;
+
+ oldest_possible_cookie = (encoding_16bit ? LEVEL_COOKIE : LEVEL_COOKIE_12);
+
+ fputs(oldest_possible_cookie, file); /* file identifier */
fputc('\n', file);
putFileChunk(file, "HEAD", LEVEL_HEADER_SIZE, BYTE_ORDER_BIG_ENDIAN);
for(i=0; i<STD_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- fputc(level.yam_content[i][x][y], file);
+ fputc(encoding_16bit ? EL_LEERRAUM : level.yam_content[i][x][y], file);
fputc(level.amoeba_speed, file);
fputc(level.time_magic_wall, file);
fputc(level.time_wheel, file);
fputc((level.double_speed ? 1 : 0), file);
fputc((level.gravity ? 1 : 0), file);
+ fputc((encoding_16bit ? 1 : 0), file);
+
for(i=0; i<LEVEL_HEADER_UNUSED; i++) /* set unused header bytes to zero */
fputc(0, file);
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- fputc(level.yam_content[i][x][y], file);
+ if (encoding_16bit)
+ putFile16BitInteger(file, level.yam_content[i][x][y],
+ BYTE_ORDER_BIG_ENDIAN);
+ else
+ fputc(level.yam_content[i][x][y], file);
putFileChunk(file, "BODY", lev_fieldx * lev_fieldy, BYTE_ORDER_BIG_ENDIAN);
for(y=0; y<lev_fieldy; y++)
for(x=0; x<lev_fieldx; x++)
- fputc(Ur[x][y], file);
+ if (encoding_16bit)
+ putFile16BitInteger(file, Ur[x][y], BYTE_ORDER_BIG_ENDIAN);
+ else
+ fputc(Ur[x][y], file);
fclose(file);
/* level directory info */
#define LEVELINFO_TOKEN_NAME 29
-#define LEVELINFO_TOKEN_AUTHOR 30
-#define LEVELINFO_TOKEN_LEVELS 31
-#define LEVELINFO_TOKEN_FIRST_LEVEL 32
-#define LEVELINFO_TOKEN_SORT_PRIORITY 33
-#define LEVELINFO_TOKEN_READONLY 34
+#define LEVELINFO_TOKEN_NAME_SHORT 30
+#define LEVELINFO_TOKEN_AUTHOR 31
+#define LEVELINFO_TOKEN_IMPORTED_FROM 32
+#define LEVELINFO_TOKEN_LEVELS 33
+#define LEVELINFO_TOKEN_FIRST_LEVEL 34
+#define LEVELINFO_TOKEN_SORT_PRIORITY 35
+#define LEVELINFO_TOKEN_READONLY 36
#define FIRST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_PLAYER_NAME
#define LAST_GLOBAL_SETUP_TOKEN SETUP_TOKEN_TEAM_MODE
{ TYPE_STRING, &ldi.name, "name" },
{ TYPE_STRING, &ldi.name_short, "name_short" },
{ TYPE_STRING, &ldi.author, "author" },
+ { TYPE_STRING, &ldi.imported_from, "imported_from" },
{ TYPE_INTEGER, &ldi.levels, "levels" },
{ TYPE_INTEGER, &ldi.first_level, "first_level" },
{ TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
ldi->name = getStringCopy(ANONYMOUS_NAME);
ldi->name_short = NULL;
ldi->author = getStringCopy(ANONYMOUS_NAME);
+ ldi->imported_from = NULL;
ldi->levels = 0;
ldi->first_level = 0;
ldi->sort_priority = LEVELCLASS_UNDEFINED; /* default: least priority */
const struct LevelDirInfo *entry2 = object2;
int compare_result;
- if (entry1->sort_priority != entry2->sort_priority)
- compare_result = entry1->sort_priority - entry2->sort_priority;
- else
+ if (entry1->sort_priority == entry2->sort_priority)
{
- char *name1 = getStringToLower(entry1->name);
- char *name2 = getStringToLower(entry2->name);
+ char *name1 = getStringToLower(entry1->name_short);
+ char *name2 = getStringToLower(entry2->name_short);
compare_result = strcmp(name1, name2);
free(name1);
free(name2);
}
+ else if (LEVELSORTING(entry1) == LEVELSORTING(entry2))
+ compare_result = entry1->sort_priority - entry2->sort_priority;
+ else
+ compare_result = LEVELSORTING(entry1) - LEVELSORTING(entry2);
return compare_result;
}
leveldir[current_entry].levels - 1;
leveldir[current_entry].user_defined =
(level_directory == options.level_directory ? FALSE : TRUE);
- leveldir[current_entry].color = LEVELCOLOR(current_entry);
+ leveldir[current_entry].color = LEVELCOLOR(&leveldir[current_entry]);
+ leveldir[current_entry].class_desc =
+ getLevelClassDescription(&leveldir[current_entry]);
freeSetupFileList(setup_file_list);
current_entry++;
setLevelDirInfoToDefaults(&ldi);
ldi.name = getLoginName();
- ldi.name_short = getLoginName();
ldi.author = getRealName();
ldi.levels = 100;
ldi.first_level = 1;
getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, LEVELINFO_COOKIE));
for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++)
- fprintf(file, "%s\n", getSetupLine("", i));
+ if (i != LEVELINFO_TOKEN_NAME_SHORT && i != LEVELINFO_TOKEN_IMPORTED_FROM)
+ fprintf(file, "%s\n", getSetupLine("", i));
fclose(file);
free(filename);
"yellow door",
"green door",
"blue door",
- "grey door (opened by red key)",
- "grey door (opened by yellow key)",
- "grey door (opened by green key)",
- "grey door (opened by blue key)",
+ "gray door (opened by red key)",
+ "gray door (opened by yellow key)",
+ "gray door (opened by green key)",
+ "gray door (opened by blue key)",
"dynamite",
"pac man",
"invisible normal wall",
"unknown",
"unknown",
"unknown",
- "unknown"
+ "unknown",
+
+ /* 256 */
+
+ "pearl",
+ "crystal",
+ "wall with pearl",
+ "wall with crystal",
+ "white door",
+ "gray door (opened by white key)",
+ "white key",
+ "force field",
+ "extra time",
+ "switch gate (open)",
+ "switch gate (closed)",
+ "switch for switch gate",
+ "time gate",
+ "time gate with magic wheel",
+ "green conveyor belt (left)",
+ "green conveyor belt (middle)",
+ "green conveyor belt (right)",
+ "switch for green conveyor belt",
+ "red conveyor belt (left)",
+ "red conveyor belt (middle)",
+ "red conveyor belt (right)",
+ "switch for red conveyor belt",
+ "blue conveyor belt (left)",
+ "blue conveyor belt (middle)",
+ "blue conveyor belt (right)",
+ "switch for blue conveyor belt",
+ "land mine",
+ "mail envelope",
+ "light switch",
+ "sign (exclamation)",
+ "sign (radio activity)",
+ "sign (stop)",
+ "sign (wheel chair)",
+ "sign (parking)",
+ "sign (one way)",
+ "sign (heart)",
+ "sign (triangle)",
+ "sign (round)",
+ "sign (exit)",
+ "sign (yin yang)",
+ "sign (other)",
+ "mole (starts moving left)",
+ "mole (starts moving right)",
+ "mole (starts moving up)",
+ "mole (starts moving down)",
+ "steel (?)",
+ "invisible sand",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-",
+ "-"
+
+ /*
+ "-------------------------------",
+ */
};
int main(int argc, char *argv[])
struct LevelDirInfo
{
- char *filename;
- char *name;
+ char *filename; /* level series sub-directory inside level directory */
+ char *name; /* level series name, as displayed on main screen */
char *name_short; /* optional short name for level selection screen */
- char *author;
- int levels;
- int first_level;
- int last_level;
- int sort_priority;
- boolean user_defined;
- boolean readonly;
- int color;
+ char *author; /* level series author name levels without author */
+ char *imported_from; /* optional comment for imported level series */
+ int levels; /* number of levels in level series */
+ int first_level; /* first level number (to allow start with 0 or 1) */
+ int last_level; /* last level number (automatically calculated) */
+ int sort_priority; /* sort levels by 'sort_priority' and then by name */
+ boolean user_defined; /* user defined levels are stored in home directory */
+ boolean readonly; /* readonly levels can not be changed with editor */
+ int color; /* color to use on selection screen for this level */
+ char *class_desc; /* description of level series class */
};
struct TapeInfo
#define EL_UNUSED_254 254
#define EL_UNUSED_255 255
+#define EL_PEARL 256
+#define EL_CRYSTAL 257
+#define EL_WALL_PEARL 258
+#define EL_WALL_CRYSTAL 259
+#define EL_DOOR_WHITE 260
+#define EL_DOOR_WHITE_GRAY 261
+#define EL_KEY_WHITE 262
+#define EL_FORCE_FIELD 263
+#define EL_EXTRA_TIME 264
+#define EL_SWITCH_GATE_OPEN 265
+#define EL_SWITCH_GATE_CLOSED 266
+#define EL_SWITCH_GATE_SWITCH 267
+#define EL_TIME_GATE 268
+#define EL_TIME_GATE_WHEEL 269
+#define EL_BELT_GREEN_LEFT 270
+#define EL_BELT_GREEN_MIDDLE 271
+#define EL_BELT_GREEN_RIGHT 272
+#define EL_BELT_GREEN_SWITCH 273
+#define EL_BELT_RED_LEFT 274
+#define EL_BELT_RED_MIDDLE 275
+#define EL_BELT_RED_RIGHT 276
+#define EL_BELT_RED_SWITCH 277
+#define EL_BELT_BLUE_LEFT 278
+#define EL_BELT_BLUE_MIDDLE 279
+#define EL_BELT_BLUE_RIGHT 280
+#define EL_BELT_BLUE_SWITCH 281
+#define EL_LANDMINE 282
+#define EL_ENVELOPE 283
+#define EL_LIGHT_SWITCH 284
+#define EL_SIGN_EXCLAMATION 285
+#define EL_SIGN_RADIOACTIVITY 286
+#define EL_SIGN_STOP 287
+#define EL_SIGN_WHEELCHAIR 288
+#define EL_SIGN_PARKING 289
+#define EL_SIGN_ONEWAY 290
+#define EL_SIGN_HEART 291
+#define EL_SIGN_TRIANGLE 292
+#define EL_SIGN_ROUND 293
+#define EL_SIGN_EXIT 294
+#define EL_SIGN_YINYANG 295
+#define EL_SIGN_OTHER 296
+#define EL_MOLE_LEFT 297
+#define EL_MOLE_RIGHT 298
+#define EL_MOLE_UP 299
+#define EL_MOLE_DOWN 300
+#define EL_STEEL_SLANTED 301
+#define EL_SAND_INVISIBLE 302
+
/* "real" (and therefore drawable) runtime elements */
-#define EL_SIEB_LEER 300
-#define EL_SIEB2_LEER 301
-#define EL_SIEB_VOLL 302
-#define EL_SIEB2_VOLL 303
-#define EL_SIEB_TOT 304
-#define EL_SIEB2_TOT 305
-#define EL_AUSGANG_ACT 306
-#define EL_SP_TERMINAL_ACTIVE 307
-#define EL_SP_BUG_ACTIVE 308
-#define EL_EM_KEY_1 309
-#define EL_EM_KEY_2 310
-#define EL_EM_KEY_3 311
-#define EL_EM_KEY_4 312
-#define EL_DYNABOMB_ACTIVE_1 313
-#define EL_DYNABOMB_ACTIVE_2 314
-#define EL_DYNABOMB_ACTIVE_3 315
-#define EL_DYNABOMB_ACTIVE_4 316
+#define EL_SIEB_LEER 1000
+#define EL_SIEB2_LEER 1001
+#define EL_SIEB_VOLL 1002
+#define EL_SIEB2_VOLL 1003
+#define EL_SIEB_TOT 1004
+#define EL_SIEB2_TOT 1005
+#define EL_AUSGANG_ACT 1006
+#define EL_SP_TERMINAL_ACTIVE 1007
+#define EL_SP_BUG_ACTIVE 1008
+#define EL_EM_KEY_1 1009
+#define EL_EM_KEY_2 1010
+#define EL_EM_KEY_3 1011
+#define EL_EM_KEY_4 1012
+#define EL_DYNABOMB_ACTIVE_1 1013
+#define EL_DYNABOMB_ACTIVE_2 1014
+#define EL_DYNABOMB_ACTIVE_3 1015
+#define EL_DYNABOMB_ACTIVE_4 1016
/* "unreal" (and therefore not drawable) runtime elements */
-#define EL_BLOCKED 400
-#define EL_EXPLODING 401
-#define EL_CRACKINGNUT 402
-#define EL_BLURB_LEFT 403
-#define EL_BLURB_RIGHT 404
-#define EL_AMOEBING 405
-#define EL_MAUERND 406
-#define EL_BURNING 407
-#define EL_PLAYER_IS_LEAVING 408
+#define EL_BLOCKED 2000
+#define EL_EXPLODING 2001
+#define EL_CRACKINGNUT 2002
+#define EL_BLURB_LEFT 2003
+#define EL_BLURB_RIGHT 2004
+#define EL_AMOEBING 2005
+#define EL_MAUERND 2006
+#define EL_BURNING 2007
+#define EL_PLAYER_IS_LEAVING 2008
/* game graphics:
** 0 - 255: graphics from "RocksScreen"
#define GFX_CHAR_COPY (GFX_CHAR_ASCII0 + 94)
#define GFX_CHAR_END (GFX_CHAR_START + 79)
+/* new elements which still have no graphic */
+#define GFX_PEARL GFX_CHAR_FRAGE
+#define GFX_CRYSTAL GFX_CHAR_FRAGE
+#define GFX_WALL_PEARL GFX_CHAR_FRAGE
+#define GFX_WALL_CRYSTAL GFX_CHAR_FRAGE
+#define GFX_DOOR_WHITE GFX_CHAR_FRAGE
+#define GFX_DOOR_WHITE_GRAY GFX_CHAR_FRAGE
+#define GFX_KEY_WHITE GFX_CHAR_FRAGE
+#define GFX_FORCE_FIELD GFX_CHAR_FRAGE
+#define GFX_EXTRA_TIME GFX_CHAR_FRAGE
+#define GFX_SWITCH_GATE_OPEN GFX_CHAR_FRAGE
+#define GFX_SWITCH_GATE_CLOSED GFX_CHAR_FRAGE
+#define GFX_SWITCH_GATE_SWITCH GFX_CHAR_FRAGE
+#define GFX_TIME_GATE GFX_CHAR_FRAGE
+#define GFX_TIME_GATE_WHEEL GFX_CHAR_FRAGE
+#define GFX_BELT_GREEN_LEFT GFX_CHAR_FRAGE
+#define GFX_BELT_GREEN_MIDDLE GFX_CHAR_FRAGE
+#define GFX_BELT_GREEN_RIGHT GFX_CHAR_FRAGE
+#define GFX_BELT_GREEN_SWITCH GFX_CHAR_FRAGE
+#define GFX_BELT_RED_LEFT GFX_CHAR_FRAGE
+#define GFX_BELT_RED_MIDDLE GFX_CHAR_FRAGE
+#define GFX_BELT_RED_RIGHT GFX_CHAR_FRAGE
+#define GFX_BELT_RED_SWITCH GFX_CHAR_FRAGE
+#define GFX_BELT_BLUE_LEFT GFX_CHAR_FRAGE
+#define GFX_BELT_BLUE_MIDDLE GFX_CHAR_FRAGE
+#define GFX_BELT_BLUE_RIGHT GFX_CHAR_FRAGE
+#define GFX_BELT_BLUE_SWITCH GFX_CHAR_FRAGE
+#define GFX_LANDMINE GFX_CHAR_FRAGE
+#define GFX_ENVELOPE GFX_CHAR_FRAGE
+#define GFX_LIGHT_SWITCH GFX_CHAR_FRAGE
+#define GFX_SIGN_EXCLAMATION GFX_CHAR_FRAGE
+#define GFX_SIGN_RADIOACTIVITY GFX_CHAR_FRAGE
+#define GFX_SIGN_STOP GFX_CHAR_FRAGE
+#define GFX_SIGN_WHEELCHAIR GFX_CHAR_FRAGE
+#define GFX_SIGN_PARKING GFX_CHAR_FRAGE
+#define GFX_SIGN_ONEWAY GFX_CHAR_FRAGE
+#define GFX_SIGN_HEART GFX_CHAR_FRAGE
+#define GFX_SIGN_TRIANGLE GFX_CHAR_FRAGE
+#define GFX_SIGN_ROUND GFX_CHAR_FRAGE
+#define GFX_SIGN_EXIT GFX_CHAR_FRAGE
+#define GFX_SIGN_YINYANG GFX_CHAR_FRAGE
+#define GFX_SIGN_OTHER GFX_CHAR_FRAGE
+#define GFX_MOLE_LEFT GFX_CHAR_FRAGE
+#define GFX_MOLE_RIGHT GFX_CHAR_FRAGE
+#define GFX_MOLE_UP GFX_CHAR_FRAGE
+#define GFX_MOLE_DOWN GFX_CHAR_FRAGE
+#define GFX_STEEL_SLANTED GFX_CHAR_FRAGE
+#define GFX_SAND_INVISIBLE GFX_CHAR_FRAGE
+
/* the names of the sounds */
#define SND_ALCHEMY 0
#define SND_AMOEBE 1
int x, last_redraw_mask = redraw_mask;
XFillRectangle(display, drawto, gc, SX + 32, SY + 32, SXSIZE - 32, 32);
+
+#if 0
DrawTextFCentered(40, FC_RED, "%3d levels (%s)",
leveldir[leveldir_nr].levels,
leveldir[leveldir_nr].readonly ? "readonly" : "writable");
+#else
+ DrawTextFCentered(40, FC_RED, "%3d levels (%s)",
+ leveldir[leveldir_nr].levels,
+ leveldir[leveldir_nr].class_desc);
+#endif
/* let BackToFront() redraw only what is needed */
redraw_mask = last_redraw_mask | REDRAW_TILES;
first_entry = 0;
drawChooseLevelList(first_entry, num_page_entries);
- drawChooseLevelInfo(first_entry);
+ drawChooseLevelInfo(first_entry + choice - 3);
DrawGraphic(0, choice - 1, GFX_KUGEL_ROT);
return;
}
first_entry = MAX(0, num_leveldirs - num_page_entries);
drawChooseLevelList(first_entry, num_page_entries);
- drawChooseLevelInfo(first_entry + num_page_entries - 1);
+ drawChooseLevelInfo(first_entry + choice - 3);
DrawGraphic(0, choice - 1, GFX_KUGEL_ROT);
return;
}
redraw_mask |= REDRAW_MICROLEVEL;
}
+#define MICROLABEL_EMPTY 0
+#define MICROLABEL_LEVEL_NAME 1
+#define MICROLABEL_CREATED_BY 2
+#define MICROLABEL_LEVEL_AUTHOR 3
+#define MICROLABEL_IMPORTED_FROM 4
+#define MICROLABEL_LEVEL_IMPORT_INFO 5
+
+#define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
+
static void DrawMicroLevelLabelExt(int mode)
{
- char label_text[100];
+ char label_text[MAX_MICROLABEL_SIZE + 1];
XFillRectangle(display, drawto,gc,
SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
- strcpy(label_text, (mode == 1 ? level.name :
- mode == 2 ? "created by" :
- mode == 3 ? level.author : ""));
+ strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
+ mode == MICROLABEL_CREATED_BY ? "created by" :
+ mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+ mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
+ mode == MICROLABEL_LEVEL_IMPORT_INFO ?
+ leveldir[leveldir_nr].imported_from : ""),
+ MAX_MICROLABEL_SIZE);
+ label_text[MAX_MICROLABEL_SIZE] = '\0';
if (strlen(label_text) > 0)
{
- int size, lxpos, lypos;
-
- label_text[SXSIZE / FONT4_XSIZE] = '\0';
-
- size = strlen(label_text);
- lxpos = SX + (SXSIZE - size * FONT4_XSIZE) / 2;
- lypos = MICROLABEL_YPOS;
+ int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
+ int lypos = MICROLABEL_YPOS;
DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
}
strcmp(level.author, leveldir[leveldir_nr].name) != 0 &&
DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
{
- label_counter = (label_counter + 1) % 23;
- label_state = (label_counter >= 0 && label_counter <= 7 ? 1 :
- label_counter >= 9 && label_counter <= 12 ? 2 :
- label_counter >= 14 && label_counter <= 21 ? 3 : 0);
+ int max_label_counter = 23;
+
+ if (leveldir[leveldir_nr].imported_from != NULL)
+ max_label_counter += 14;
+
+ label_counter = (label_counter + 1) % max_label_counter;
+ label_state = (label_counter >= 0 && label_counter <= 7 ?
+ MICROLABEL_LEVEL_NAME :
+ label_counter >= 9 && label_counter <= 12 ?
+ MICROLABEL_CREATED_BY :
+ label_counter >= 14 && label_counter <= 21 ?
+ MICROLABEL_LEVEL_AUTHOR :
+ label_counter >= 23 && label_counter <= 26 ?
+ MICROLABEL_IMPORTED_FROM :
+ label_counter >= 28 && label_counter <= 35 ?
+ MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
DrawMicroLevelLabelExt(label_state);
}
}
case EL_EM_KEY_2: return GFX_EM_KEY_2;
case EL_EM_KEY_3: return GFX_EM_KEY_3;
case EL_EM_KEY_4: return GFX_EM_KEY_4;
+ case EL_PEARL: return GFX_PEARL;
+ case EL_CRYSTAL: return GFX_CRYSTAL;
+ case EL_WALL_PEARL: return GFX_WALL_PEARL;
+ case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
+ case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
+ case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
+ case EL_KEY_WHITE: return GFX_KEY_WHITE;
+ case EL_FORCE_FIELD: return GFX_FORCE_FIELD;
+ case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
+ case EL_SWITCH_GATE_OPEN: return GFX_SWITCH_GATE_OPEN;
+ case EL_SWITCH_GATE_CLOSED: return GFX_SWITCH_GATE_CLOSED;
+ case EL_SWITCH_GATE_SWITCH: return GFX_SWITCH_GATE_SWITCH;
+ case EL_TIME_GATE: return GFX_TIME_GATE;
+ case EL_TIME_GATE_WHEEL: return GFX_TIME_GATE_WHEEL;
+ case EL_BELT_GREEN_LEFT: return GFX_BELT_GREEN_LEFT;
+ case EL_BELT_GREEN_MIDDLE: return GFX_BELT_GREEN_MIDDLE;
+ case EL_BELT_GREEN_RIGHT: return GFX_BELT_GREEN_RIGHT;
+ case EL_BELT_GREEN_SWITCH: return GFX_BELT_GREEN_SWITCH;
+ case EL_BELT_RED_LEFT: return GFX_BELT_RED_LEFT;
+ case EL_BELT_RED_MIDDLE: return GFX_BELT_RED_MIDDLE;
+ case EL_BELT_RED_RIGHT: return GFX_BELT_RED_RIGHT;
+ case EL_BELT_RED_SWITCH: return GFX_BELT_RED_SWITCH;
+ case EL_BELT_BLUE_LEFT: return GFX_BELT_BLUE_LEFT;
+ case EL_BELT_BLUE_MIDDLE: return GFX_BELT_BLUE_MIDDLE;
+ case EL_BELT_BLUE_RIGHT: return GFX_BELT_BLUE_RIGHT;
+ case EL_BELT_BLUE_SWITCH: return GFX_BELT_BLUE_SWITCH;
+ case EL_LANDMINE: return GFX_LANDMINE;
+ case EL_ENVELOPE: return GFX_ENVELOPE;
+ case EL_LIGHT_SWITCH: return GFX_LIGHT_SWITCH;
+ case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
+ case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
+ case EL_SIGN_STOP: return GFX_SIGN_STOP;
+ case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
+ case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
+ case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
+ case EL_SIGN_HEART: return GFX_SIGN_HEART;
+ case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
+ case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
+ case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
+ case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
+ case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
+ case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
+ case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
+ case EL_MOLE_UP: return GFX_MOLE_UP;
+ case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
+ case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
+ case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
default:
{