version number set to 4.0.0.0 RC1
[rocksndiamonds.git] / src / main.c
index b00503ead130dc7253d5d930797ca700969e94d9..c33369729d47972a43a70f223f99cb7df4d3285e 100644 (file)
@@ -1,36 +1,37 @@
-/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back!               *
-*----------------------------------------------------------*
-* (c) 1995-2002 Artsoft Entertainment                      *
-*               Holger Schemel                             *
-*               Detmolder Strasse 189                      *
-*               33604 Bielefeld                            *
-*               Germany                                    *
-*               e-mail: info@artsoft.org                   *
-*----------------------------------------------------------*
-* main.c                                                   *
-***********************************************************/
+// ============================================================================
+// Rocks'n'Diamonds - McDuffin Strikes Back!
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+//                         Holger Schemel
+//                 info@artsoft.org
+//                 http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// main.c
+// ============================================================================
 
 #include "libgame/libgame.h"
 
 #include "main.h"
 #include "init.h"
 #include "game.h"
+#include "tape.h"
+#include "tools.h"
+#include "files.h"
 #include "events.h"
 #include "config.h"
 
-#if 0
-GC                     tile_clip_gc;
-Bitmap                *pix[NUM_BITMAPS];
-#endif
-Bitmap                *bitmap_db_field, *bitmap_db_door;
-#if 0
-Pixmap                 tile_clipmask[NUM_TILES];
-#endif
+Bitmap                *bitmap_db_store;
+Bitmap                *bitmap_db_cross;
+Bitmap                *bitmap_db_field;
+Bitmap                *bitmap_db_panel;
+Bitmap                *bitmap_db_door_1;
+Bitmap                *bitmap_db_door_2;
+Bitmap                *bitmap_db_toons;
 DrawBuffer            *fieldbuffer;
 DrawBuffer            *drawto_field;
 
 int                    game_status = -1;
+boolean                        game_status_last_screen = -1;
 boolean                        level_editor_test_game = FALSE;
 boolean                        network_playing = FALSE;
 
@@ -41,26 +42,25 @@ SDL_Thread         *server_thread;
 
 int                    key_joystick_mapping = 0;
 
-boolean                        redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
-int                    redraw_x1 = 0, redraw_y1 = 0;
-
 short                  Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  ChangePage[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  CustomValue[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 boolean                        Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 boolean                        Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-unsigned long          Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-unsigned long          ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  ChangeCount[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short                  CheckImpact[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 short                  AmoebaCnt[MAX_NUM_AMOEBA];
 short                  AmoebaCnt2[MAX_NUM_AMOEBA];
@@ -70,26 +70,59 @@ short                       ExplodeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
-unsigned long          Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
-
 int                    GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 int                    GfxDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+int                    GfxRedraw[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+int                    ActiveElement[MAX_NUM_ELEMENTS];
+int                    ActiveButton[NUM_IMAGE_FILES];
+int                    ActiveFont[NUM_FONTS];
 
 int                    lev_fieldx, lev_fieldy;
 int                    scroll_x, scroll_y;
 
-int                    FX = SX, FY = SY;
+int                    WIN_XSIZE = WIN_XSIZE_DEFAULT;
+int                    WIN_YSIZE = WIN_YSIZE_DEFAULT;
+
+int                    SCR_FIELDX = SCR_FIELDX_DEFAULT;
+int                    SCR_FIELDY = SCR_FIELDY_DEFAULT;
+
+int                    REAL_SX = 6, REAL_SY = 6;
+int                    SX = 8, SY = 8;
+int                    DX = 566, DY = 60;
+int                    VX = 566, VY = 400;
+int                    EX = 566, EY = 356;
+int                    dDX, dDY;
+
+int                    FULL_SXSIZE = 2 + SXSIZE_DEFAULT + 2;
+int                    FULL_SYSIZE = 2 + SYSIZE_DEFAULT + 2;
+int                    SXSIZE = SXSIZE_DEFAULT;
+int                    SYSIZE = SYSIZE_DEFAULT;
+
+int                    FADE_SX = 6, FADE_SY = 6;
+int                    FADE_SXSIZE = 2 + SXSIZE_DEFAULT + 2;
+int                    FADE_SYSIZE = 2 + SXSIZE_DEFAULT + 2;
+
+int                    DXSIZE = 100;
+int                    DYSIZE = 280;
+int                    VXSIZE = 100;
+int                    VYSIZE = 100;
+int                    EXSIZE = 100;
+int                    EYSIZE = 144;
+int                    TILESIZE_VAR = TILESIZE;
+
+int                    FX, FY;
 int                    ScrollStepSize;
-int                    ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
+int                    ScreenMovDir = MV_NONE, ScreenMovPos = 0;
 int                    ScreenGfxPos = 0;
 int                    BorderElement = EL_STEELWALL;
 int                    GameFrameDelay = GAME_FRAME_DELAY;
 int                    FfwdFrameDelay = FFWD_FRAME_DELAY;
-int                    BX1 = 0, BY1 = 0;
-int                    BX2 = SCR_FIELDX - 1, BY2 = SCR_FIELDY - 1;
+int                    BX1, BY1;
+int                    BX2, BY2;
 int                    SBX_Left, SBX_Right;
 int                    SBY_Upper, SBY_Lower;
 int                    ZX, ZY;
@@ -108,14 +141,42 @@ struct TapeInfo           tape;
 struct SetupInfo       setup;
 struct GameInfo                game;
 struct GlobalInfo      global;
+struct BorderInfo      border;
+struct ViewportInfo    viewport;
+struct TitleFadingInfo fading;
+struct TitleFadingInfo title_initial_default;
+struct TitleFadingInfo title_default;
+struct TitleMessageInfo        titlescreen_initial_default;
+struct TitleMessageInfo        titlescreen_initial_first[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen_initial[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen_default;
+struct TitleMessageInfo        titlescreen_first[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlescreen[MAX_NUM_TITLE_IMAGES];
+struct TitleMessageInfo        titlemessage_initial_default;
+struct TitleMessageInfo        titlemessage_initial_first[MAX_NUM_TITLE_MESSAGES];
+struct TitleMessageInfo        titlemessage_initial[MAX_NUM_TITLE_MESSAGES];
+struct TitleMessageInfo        titlemessage_default;
+struct TitleMessageInfo        titlemessage_first[MAX_NUM_TITLE_MESSAGES];
+struct TitleMessageInfo        titlemessage[MAX_NUM_TITLE_MESSAGES];
+struct TitleMessageInfo        readme;
+struct InitInfo                init, init_last;
 struct MenuInfo                menu;
 struct DoorInfo                door_1, door_2;
+struct RequestInfo     request;
+struct PreviewInfo     preview;
+struct EditorInfo      editor;
+
 struct GraphicInfo     *graphic_info = NULL;
 struct SoundInfo       *sound_info = NULL;
 struct MusicInfo       *music_info = NULL;
 struct MusicFileInfo   *music_file_info = NULL;
 struct HelpAnimInfo    *helpanim_info = NULL;
+
 SetupFileHash          *helptext_info = NULL;
+SetupFileHash         *image_config_hash = NULL;
+SetupFileHash         *element_token_hash = NULL;
+SetupFileHash         *graphic_token_hash = NULL;
+SetupFileHash         *font_token_hash = NULL;
 
 
 /* ------------------------------------------------------------------------- */
@@ -191,7 +252,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "yamyam",
     "yamyam",
-    "yam yam"
+    "yam yam (random start direction)"
   },
   {
     "robot",
@@ -200,7 +261,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "steelwall",
-    "wall",
+    "steelwall",
     "steel wall"
   },
   {
@@ -216,12 +277,12 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "quicksand_empty",
     "quicksand",
-    "empty quicksand"
+    "quicksand (empty)"
   },
   {
     "quicksand_full",
     "quicksand",
-    "quicksand with rock"
+    "quicksand (with rock)"
   },
   {
     "amoeba_drop",
@@ -251,7 +312,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "amoeba_wet",
     "amoeba",
-    "dropping amoeba"
+    "dropping amoeba (EM style)"
   },
   {
     "amoeba_dry",
@@ -296,60 +357,63 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "key_1",
     "key",
-    "red key"
+    "key 1"
   },
   {
     "key_2",
     "key",
-    "yellow key"
+    "key 2"
   },
   {
     "key_3",
     "key",
-    "green key"
+    "key 3"
   },
   {
     "key_4",
     "key",
-    "blue key"
+    "key 4"
   },
   {
     "gate_1",
     "gate",
-    "red door"
+    "door 1"
   },
   {
     "gate_2",
     "gate",
-    "yellow door"
+    "door 2"
   },
   {
     "gate_3",
     "gate",
-    "green door"
+    "door 3"
   },
   {
     "gate_4",
     "gate",
-    "blue door"
+    "door 4"
   },
   {
     "gate_1_gray",
     "gate",
-    "gray door (opened by red key)"
+    "gray door (opened by key 1)"
   },
   {
     "gate_2_gray",
     "gate",
-    "gray door (opened by yellow key)"},
+    "gray door (opened by key 2)"
+  },
   {
     "gate_3_gray",
     "gate",
-    "gray door (opened by green key)"},
+    "gray door (opened by key 3)"
+  },
   {
     "gate_4_gray",
     "gate",
-    "gray door (opened by blue key)"},
+    "gray door (opened by key 4)"
+  },
   {
     "dynamite",
     "dynamite",
@@ -408,7 +472,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "expandable_wall",
     "wall",
-    "growing wall"
+    "growing wall (horizontal, visible)"
   },
   {
     "bd_diamond",
@@ -442,7 +506,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "invisible_steelwall",
-    "wall",
+    "steelwall",
     "invisible steel wall"
   },
   {
@@ -530,22 +594,22 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "player_1",
     "player",
-    "yellow player"
+    "player 1"
   },
   {
     "player_2",
     "player",
-    "red player"
+    "player 2"
   },
   {
     "player_3",
     "player",
-    "green player"
+    "player 3"
   },
   {
     "player_4",
     "player",
-    "blue player"
+    "player 4"
   },
   {
     "bug.right",
@@ -1047,37 +1111,37 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "char_copyright",
     "char",
-    "letter '©'"
+    "letter '\xa9'"
   },
   {
     "char_aumlaut",
     "char",
-    "letter 'Ä'"
+    "letter '\xc4'"
   },
   {
     "char_oumlaut",
     "char",
-    "letter 'Ö'"
+    "letter '\xd6'"
   },
   {
     "char_uumlaut",
     "char",
-    "letter 'Ü'"
+    "letter '\xdc'"
   },
   {
     "char_degree",
     "char",
-    "letter '°'"
+    "letter '\xb0'"
   },
   {
     "char_trademark",
     "char",
-    "letter '®'"
+    "letter '\xae'"
   },
   {
     "char_cursor",
     "char",
-    "letter ' '"
+    "letter '\xa0'"
   },
   {
     "char_unused",
@@ -1112,17 +1176,17 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "char_unused",
     "char",
-    "letter ''"
+    "letter 'button'"
   },
   {
     "char_unused",
     "char",
-    "letter ''"
+    "letter 'up'"
   },
   {
     "char_unused",
     "char",
-    "letter ''"
+    "letter 'down'"
   },
   {
     "expandable_wall_horizontal",
@@ -1142,22 +1206,22 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "em_gate_1",
     "gate",
-    "red door (EM style)"
+    "door 1 (EM style)"
   },
   {
     "em_gate_2",
     "gate",
-    "yellow door (EM style)"
+    "door 2 (EM style)"
   },
   {
     "em_gate_3",
     "gate",
-    "green door (EM style)"
+    "door 3 (EM style)"
   },
   {
     "em_gate_4",
     "gate",
-    "blue door (EM style)"
+    "door 4 (EM style)"
   },
   {
     "em_key_2_file_obsolete",
@@ -1241,23 +1305,23 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "sp_gravity_port_right",
-    "sp_port",
-    "gravity port (leading right)"
+    "sp_gravity_port",
+    "gravity-on/off port (leading right)"
   },
   {
     "sp_gravity_port_down",
-    "sp_port",
-    "gravity port (leading down)"
+    "sp_gravity_port",
+    "gravity-on/off port (leading down)"
   },
   {
     "sp_gravity_port_left",
-    "sp_port",
-    "gravity port (leading left)"
+    "sp_gravity_port",
+    "gravity-on/off port (leading left)"
   },
   {
     "sp_gravity_port_up",
-    "sp_port",
-    "gravity port (leading up)"
+    "sp_gravity_port",
+    "gravity-on/off port (leading up)"
   },
   {
     "sp_sniksnak",
@@ -1377,32 +1441,32 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "em_gate_1_gray",
     "gate",
-    "gray door (EM style, red key)"
+    "gray door (EM style, key 1)"
   },
   {
     "em_gate_2_gray",
     "gate",
-    "gray door (EM style, yellow key)"
+    "gray door (EM style, key 2)"
   },
   {
     "em_gate_3_gray",
     "gate",
-    "gray door (EM style, green key)"
+    "gray door (EM style, key 3)"
   },
   {
     "em_gate_4_gray",
     "gate",
-    "gray door (EM style, blue key)"
+    "gray door (EM style, key 4)"
   },
   {
-    "unused_254",
-    "unused",
-    "(not used)"
+    "em_dynamite",
+    "dynamite",
+    "dynamite (EM style)"
   },
   {
-    "unused_255",
-    "unused",
-    "(not used)"
+    "em_dynamite.active",
+    "dynamite",
+    "burning dynamite (EM style)"
   },
   {
     "pearl",
@@ -1425,17 +1489,17 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "wall with crystal"
   },
   {
-    "door_white",
+    "dc_gate_white",
     "gate",
     "white door"
   },
   {
-    "door_white_gray",
+    "dc_gate_white_gray",
     "gate",
     "gray door (opened by white key)"
   },
   {
-    "key_white",
+    "dc_key_white",
     "key",
     "white key"
   },
@@ -1482,127 +1546,127 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "conveyor_belt_1_left",
     "conveyor_belt",
-    "red conveyor belt (left)"
+    "conveyor belt 1 (left)"
   },
   {
     "conveyor_belt_1_middle",
     "conveyor_belt",
-    "red conveyor belt (middle)"
+    "conveyor belt 1 (middle)"
   },
   {
     "conveyor_belt_1_right",
     "conveyor_belt",
-    "red conveyor belt (right)"
+    "conveyor belt 1 (right)"
   },
   {
     "conveyor_belt_1_switch_left",
     "conveyor_belt_switch",
-    "switch for red conveyor belt (left)"
+    "switch for conveyor belt 1 (left)"
   },
   {
     "conveyor_belt_1_switch_middle",
     "conveyor_belt_switch",
-    "switch for red conveyor belt (middle)"
+    "switch for conveyor belt 1 (middle)"
   },
   {
     "conveyor_belt_1_switch_right",
     "conveyor_belt_switch",
-    "switch for red conveyor belt (right)"
+    "switch for conveyor belt 1 (right)"
   },
   {
     "conveyor_belt_2_left",
     "conveyor_belt",
-    "yellow conveyor belt (left)"
+    "conveyor belt 2 (left)"
   },
   {
     "conveyor_belt_2_middle",
     "conveyor_belt",
-    "yellow conveyor belt (middle)"
+    "conveyor belt 2 (middle)"
   },
   {
     "conveyor_belt_2_right",
     "conveyor_belt",
-    "yellow conveyor belt (right)"
+    "conveyor belt 2 (right)"
   },
   {
     "conveyor_belt_2_switch_left",
     "conveyor_belt_switch",
-    "switch for yellow conveyor belt (left)"
+    "switch for conveyor belt 2 (left)"
   },
   {
     "conveyor_belt_2_switch_middle",
     "conveyor_belt_switch",
-    "switch for yellow conveyor belt (middle)"
+    "switch for conveyor belt 2 (middle)"
   },
   {
     "conveyor_belt_2_switch_right",
     "conveyor_belt_switch",
-    "switch for yellow conveyor belt (right)"
+    "switch for conveyor belt 2 (right)"
   },
   {
     "conveyor_belt_3_left",
     "conveyor_belt",
-    "green conveyor belt (left)"
+    "conveyor belt 3 (left)"
   },
   {
     "conveyor_belt_3_middle",
     "conveyor_belt",
-    "green conveyor belt (middle)"
+    "conveyor belt 3 (middle)"
   },
   {
     "conveyor_belt_3_right",
     "conveyor_belt",
-    "green conveyor belt (right)"
+    "conveyor belt 3 (right)"
   },
   {
     "conveyor_belt_3_switch_left",
     "conveyor_belt_switch",
-    "switch for green conveyor belt (left)"
+    "switch for conveyor belt 3 (left)"
   },
   {
     "conveyor_belt_3_switch_middle",
     "conveyor_belt_switch",
-    "switch for green conveyor belt (middle)"
+    "switch for conveyor belt 3 (middle)"
   },
   {
     "conveyor_belt_3_switch_right",
     "conveyor_belt_switch",
-    "switch for green conveyor belt (right)"
+    "switch for conveyor belt 3 (right)"
   },
   {
     "conveyor_belt_4_left",
     "conveyor_belt",
-    "blue conveyor belt (left)"
+    "conveyor belt 4 (left)"
   },
   {
     "conveyor_belt_4_middle",
     "conveyor_belt",
-    "blue conveyor belt (middle)"
+    "conveyor belt 4 (middle)"
   },
   {
     "conveyor_belt_4_right",
     "conveyor_belt",
-    "blue conveyor belt (right)"
+    "conveyor belt 4 (right)"
   },
   {
     "conveyor_belt_4_switch_left",
     "conveyor_belt_switch",
-    "switch for blue conveyor belt (left)"
+    "switch for conveyor belt 4 (left)"
   },
   {
     "conveyor_belt_4_switch_middle",
     "conveyor_belt_switch",
-    "switch for blue conveyor belt (middle)"
+    "switch for conveyor belt 4 (middle)"
   },
   {
     "conveyor_belt_4_switch_right",
     "conveyor_belt_switch",
-    "switch for blue conveyor belt (right)"
+    "switch for conveyor belt 4 (right)"
   },
   {
     "landmine",
-    "sand",
-    "land mine"
+    "landmine",
+    "land mine (not removable)"
   },
   {
     "envelope_obsolete",
@@ -1621,63 +1685,63 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "sign_exclamation",
-    "wall",
+    "sign",
     "sign (exclamation)"
   },
   {
     "sign_radioactivity",
-    "wall",
+    "sign",
     "sign (radio activity)"
   },
   {
     "sign_stop",
-    "wall",
+    "sign",
     "sign (stop)"
   },
   {
     "sign_wheelchair",
-    "wall",
+    "sign",
     "sign (wheel chair)"
   },
   {
     "sign_parking",
-    "wall",
+    "sign",
     "sign (parking)"
   },
   {
-    "sign_oneway",
-    "wall",
-    "sign (one way)"
+    "sign_no_entry",
+    "sign",
+    "sign (no entry)"
   },
   {
-    "sign_heart",
-    "wall",
-    "sign (heart)"
+    "sign_unused_1",
+    "sign",
+    "sign (unused)"
   },
   {
-    "sign_triangle",
-    "wall",
-    "sign (triangle)"
+    "sign_give_way",
+    "sign",
+    "sign (give way)"
   },
   {
-    "sign_round",
-    "wall",
-    "sign (round)"
+    "sign_entry_forbidden",
+    "sign",
+    "sign (entry forbidden)"
   },
   {
-    "sign_exit",
-    "wall",
-    "sign (exit)"
+    "sign_emergency_exit",
+    "sign",
+    "sign (emergency exit)"
   },
   {
-    "sign_yinyang",
-    "wall",
+    "sign_yin_yang",
+    "sign",
     "sign (yin yang)"
   },
   {
-    "sign_other",
-    "wall",
-    "sign (other)"
+    "sign_unused_2",
+    "sign",
+    "sign (unused)"
   },
   {
     "mole.left",
@@ -1701,7 +1765,7 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "steelwall_slippery",
-    "wall",
+    "steelwall",
     "slippery steel wall"
   },
   {
@@ -1762,46 +1826,46 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "balloon_switch_left",
     "balloon_switch",
-    "send balloon to the left"
+    "wind switch (left)"
   },
   {
     "balloon_switch_right",
     "balloon_switch",
-    "send balloon to the right"
+    "wind switch (right)"
   },
   {
     "balloon_switch_up",
     "balloon_switch",
-    "send balloon up"
+    "wind switch (up)"
   },
   {
     "balloon_switch_down",
     "balloon_switch",
-    "send balloon down"
+    "wind switch (down)"
   },
   {
     "balloon_switch_any",
     "balloon_switch",
-    "send balloon in pressed direction"
+    "wind switch (any direction)"
   },
   {
     "emc_steelwall_1",
-    "wall",
+    "steelwall",
     "steel wall"
   },
   {
     "emc_steelwall_2",
-    "wall",
+    "steelwall",
     "steel wall"
   },
   {
     "emc_steelwall_3",
-    "wall",
+    "steelwall",
     "steel wall"
   },
   {
     "emc_steelwall_4",
-    "wall",
+    "steelwall",
     "steel wall"
   },
   {
@@ -3207,22 +3271,22 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   {
     "em_key_1",
     "key",
-    "red key (EM style)"
+    "key 1 (EM style)"
     },
   {
     "em_key_2",
     "key",
-    "yellow key (EM style)"
+    "key 2 (EM style)"
     },
   {
     "em_key_3",
     "key",
-    "green key (EM style)"
+    "key 3 (EM style)"
   },
   {
     "em_key_4",
     "key",
-    "blue key (EM style)"
+    "key 4 (EM style)"
   },
   {
     "envelope_1",
@@ -3421,106 +3485,106 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "sp_gravity_on_port_right",
-    "sp_port",
-    "gravity on port (leading right)"
+    "sp_gravity_on_port",
+    "gravity-on port (leading right)"
   },
   {
     "sp_gravity_on_port_down",
-    "sp_port",
-    "gravity on port (leading down)"
+    "sp_gravity_on_port",
+    "gravity-on port (leading down)"
   },
   {
     "sp_gravity_on_port_left",
-    "sp_port",
-    "gravity on port (leading left)"
+    "sp_gravity_on_port",
+    "gravity-on port (leading left)"
   },
   {
     "sp_gravity_on_port_up",
-    "sp_port",
-    "gravity on port (leading up)"
+    "sp_gravity_on_port",
+    "gravity-on port (leading up)"
   },
   {
     "sp_gravity_off_port_right",
-    "sp_port",
-    "gravity off port (leading right)"
+    "sp_gravity_off_port",
+    "gravity-off port (leading right)"
   },
   {
     "sp_gravity_off_port_down",
-    "sp_port",
-    "gravity off port (leading down)"
+    "sp_gravity_off_port",
+    "gravity-off port (leading down)"
   },
   {
     "sp_gravity_off_port_left",
-    "sp_port",
-    "gravity off port (leading left)"
+    "sp_gravity_off_port",
+    "gravity-off port (leading left)"
   },
   {
     "sp_gravity_off_port_up",
-    "sp_port",
-    "gravity off port (leading up)"
+    "sp_gravity_off_port",
+    "gravity-off port (leading up)"
   },
   {
     "balloon_switch_none",
     "balloon_switch",
-    "stop moving balloon"
+    "wind switch (off)"
   },
   {
-    "em_gate_5",
+    "emc_gate_5",
     "gate",
     "door 5 (EMC style)",
   },
   {
-    "em_gate_6",
+    "emc_gate_6",
     "gate",
     "door 6 (EMC style)",
   },
   {
-    "em_gate_7",
+    "emc_gate_7",
     "gate",
     "door 7 (EMC style)",
   },
   {
-    "em_gate_8",
+    "emc_gate_8",
     "gate",
     "door 8 (EMC style)",
   },
   {
-    "em_gate_5_gray",
+    "emc_gate_5_gray",
     "gate",
     "gray door (EMC style, key 5)",
   },
   {
-    "em_gate_6_gray",
+    "emc_gate_6_gray",
     "gate",
     "gray door (EMC style, key 6)",
   },
   {
-    "em_gate_7_gray",
+    "emc_gate_7_gray",
     "gate",
     "gray door (EMC style, key 7)",
   },
   {
-    "em_gate_8_gray",
+    "emc_gate_8_gray",
     "gate",
     "gray door (EMC style, key 8)",
   },
   {
-    "em_key_5",
+    "emc_key_5",
     "key",
     "key 5 (EMC style)",
   },
   {
-    "em_key_6",
+    "emc_key_6",
     "key",
     "key 6 (EMC style)",
   },
   {
-    "em_key_7",
+    "emc_key_7",
     "key",
     "key 7 (EMC style)",
   },
   {
-    "em_key_8",
+    "emc_key_8",
     "key",
     "key 8 (EMC style)",
   },
@@ -3636,307 +3700,1248 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
   },
   {
     "emc_fake_grass",
-    "fake grass",
+    "fake_grass",
     "fake grass"
   },
+  {
+    "emc_fake_acid",
+    "fake_acid",
+    "fake acid"
+  },
   {
     "emc_dripper",
     "dripper",
     "dripper"
   },
-
-  /* ----------------------------------------------------------------------- */
-  /* "real" (and therefore drawable) runtime elements                        */
-  /* ----------------------------------------------------------------------- */
-
   {
-    "dynabomb_player_1.active",
-    "dynabomb",
-    "-"
+    "trigger_ce_value",
+    "trigger",
+    "CE value of element triggering change"
   },
   {
-    "dynabomb_player_2.active",
-    "dynabomb",
-    "-"
+    "trigger_ce_score",
+    "trigger",
+    "CE score of element triggering change"
   },
   {
-    "dynabomb_player_3.active",
-    "dynabomb",
-    "-"
+    "current_ce_value",
+    "current",
+    "CE value of current element"
   },
   {
-    "dynabomb_player_4.active",
-    "dynabomb",
-    "-"
+    "current_ce_score",
+    "current",
+    "CE score of current element"
   },
   {
-    "sp_disk_red.active",
-    "dynamite",
-    "-"
+    "yamyam.left",
+    "yamyam",
+    "yam yam (starts moving left)"
   },
   {
-    "switchgate.opening",
-    "switchgate",
-    "-"
+    "yamyam.right",
+    "yamyam",
+    "yam yam (starts moving right)"
   },
   {
-    "switchgate.closing",
-    "switchgate",
-    "-"
+    "yamyam.up",
+    "yamyam",
+    "yam yam (starts moving up)"
   },
   {
-    "timegate.opening",
-    "timegate",
-    "-"
+    "yamyam.down",
+    "yamyam",
+    "yam yam (starts moving down)"
   },
   {
-    "timegate.closing",
-    "timegate",
-    "-"
+    "bd_expandable_wall",
+    "wall",
+    "growing wall (horizontal, BD style)"
   },
   {
-    "pearl.breaking",
-    "pearl",
-    "-"
+    "prev_ce_8",
+    "prev_ce",
+    "CE 8 positions earlier in list"
   },
   {
-    "trap.active",
-    "trap",
-    "-"
+    "prev_ce_7",
+    "prev_ce",
+    "CE 7 positions earlier in list"
   },
   {
-    "invisible_steelwall.active",
-    "wall",
-    "-"
+    "prev_ce_6",
+    "prev_ce",
+    "CE 6 positions earlier in list"
   },
   {
-    "invisible_wall.active",
-    "wall",
-    "-"
+    "prev_ce_5",
+    "prev_ce",
+    "CE 5 positions earlier in list"
   },
   {
-    "invisible_sand.active",
-    "sand",
-    "-"
+    "prev_ce_4",
+    "prev_ce",
+    "CE 4 positions earlier in list"
   },
   {
-    "conveyor_belt_1_left.active",
-    "conveyor_belt",
-    "-"
+    "prev_ce_3",
+    "prev_ce",
+    "CE 3 positions earlier in list"
   },
   {
-    "conveyor_belt_1_middle.active",
-    "conveyor_belt",
-    "-"
+    "prev_ce_2",
+    "prev_ce",
+    "CE 2 positions earlier in list"
   },
   {
-    "conveyor_belt_1_right.active",
-    "conveyor_belt",
-    "-"
+    "prev_ce_1",
+    "prev_ce",
+    "CE 1 position earlier in list"
   },
   {
-    "conveyor_belt_2_left.active",
-    "conveyor_belt",
-    "-"
+    "self",
+    "self",
+    "the current custom element"
   },
   {
-    "conveyor_belt_2_middle.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_1",
+    "next_ce",
+    "CE 1 position later in list"
   },
   {
-    "conveyor_belt_2_right.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_2",
+    "next_ce",
+    "CE 2 positions later in list"
   },
   {
-    "conveyor_belt_3_left.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_3",
+    "next_ce",
+    "CE 3 positions later in list"
   },
   {
-    "conveyor_belt_3_middle.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_4",
+    "next_ce",
+    "CE 4 positions later in list"
   },
   {
-    "conveyor_belt_3_right.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_5",
+    "next_ce",
+    "CE 5 positions later in list"
   },
   {
-    "conveyor_belt_4_left.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_6",
+    "next_ce",
+    "CE 6 positions later in list"
   },
   {
-    "conveyor_belt_4_middle.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_7",
+    "next_ce",
+    "CE 7 positions later in list"
   },
   {
-    "conveyor_belt_4_right.active",
-    "conveyor_belt",
-    "-"
+    "next_ce_8",
+    "next_ce",
+    "CE 8 positions later in list"
   },
   {
-    "exit.opening",
-    "exit",
-    "-"
+    "any_element",
+    "any_element",
+    "this element matches any element"
   },
   {
-    "exit.closing",
-    "exit",
-    "-"
+    "steel_char_space",
+    "steel_char",
+    "steel letter ' '"
   },
   {
-    "sp_exit.opening",
-    "sp_exit",
-    "-"
+    "steel_char_exclam",
+    "steel_char",
+    "steel letter '!'"
   },
   {
-    "sp_exit.closing",
-    "sp_exit",
-    "-"
+    "steel_char_quotedbl",
+    "steel_char",
+    "steel letter '\"'"
   },
   {
-    "sp_exit_open",
-    "sp_exit",
-    "-"
+    "steel_char_numbersign",
+    "steel_char",
+    "steel letter '#'"
   },
   {
-    "sp_terminal.active",
-    "sp_terminal",
-    "-"
+    "steel_char_dollar",
+    "steel_char",
+    "steel letter '$'"
   },
   {
-    "sp_buggy_base.activating",
-    "sp_buggy_base",
-    "-"
+    "steel_char_percent",
+    "steel_char",
+    "steel letter '%'"
   },
   {
-    "sp_buggy_base.active",
-    "sp_buggy_base",
-    "-"
+    "steel_char_ampersand",
+    "steel_char",
+    "steel letter '&'"
   },
   {
-    "sp_murphy_clone",
-    "murphy_clone",
-    "-"
+    "steel_char_apostrophe",
+    "steel_char",
+    "steel letter '''"
   },
   {
-    "amoeba.dropping",
-    "amoeba",
-    "-"
+    "steel_char_parenleft",
+    "steel_char",
+    "steel letter '('"
   },
   {
-    "quicksand.emptying",
-    "quicksand",
-    "-"
+    "steel_char_parenright",
+    "steel_char",
+    "steel letter ')'"
   },
   {
-    "magic_wall.active",
-    "magic_wall",
-    "-"
+    "steel_char_asterisk",
+    "steel_char",
+    "steel letter '*'"
   },
   {
-    "bd_magic_wall.active",
-    "magic_wall",
-    "-"
+    "steel_char_plus",
+    "steel_char",
+    "steel letter '+'"
   },
   {
-    "magic_wall_full",
-    "magic_wall",
-    "-"
+    "steel_char_comma",
+    "steel_char",
+    "steel letter ','"
   },
   {
-    "bd_magic_wall_full",
-    "magic_wall",
-    "-"
+    "steel_char_minus",
+    "steel_char",
+    "steel letter '-'"
   },
   {
-    "magic_wall.emptying",
-    "magic_wall",
-    "-"
+    "steel_char_period",
+    "steel_char",
+    "steel letter '.'"
   },
   {
-    "bd_magic_wall.emptying",
-    "magic_wall",
-    "-"
+    "steel_char_slash",
+    "steel_char",
+    "steel letter '/'"
   },
   {
-    "magic_wall_dead",
-    "magic_wall",
-    "-"
+    "steel_char_0",
+    "steel_char",
+    "steel letter '0'"
   },
   {
-    "bd_magic_wall_dead",
-    "magic_wall",
-    "-"
+    "steel_char_1",
+    "steel_char",
+    "steel letter '1'"
   },
-
-  /* ----------------------------------------------------------------------- */
-  /* "unreal" (and therefore not drawable) runtime elements                  */
-  /* ----------------------------------------------------------------------- */
-
   {
-    "blocked",
-    "-",
-    "-"
+    "steel_char_2",
+    "steel_char",
+    "steel letter '2'"
   },
   {
-    "explosion",
-    "-",
-    "-"
+    "steel_char_3",
+    "steel_char",
+    "steel letter '3'"
   },
   {
-    "nut.breaking",
-    "-",
-    "-"
+    "steel_char_4",
+    "steel_char",
+    "steel letter '4'"
   },
   {
-    "diamond.breaking",
-    "-",
-    "-"
+    "steel_char_5",
+    "steel_char",
+    "steel letter '5'"
   },
   {
-    "acid_splash_left",
-    "-",
-    "-"
+    "steel_char_6",
+    "steel_char",
+    "steel letter '6'"
   },
   {
-    "acid_splash_right",
-    "-",
-    "-"
+    "steel_char_7",
+    "steel_char",
+    "steel letter '7'"
   },
   {
-    "amoeba.growing",
-    "-",
-    "-"
+    "steel_char_8",
+    "steel_char",
+    "steel letter '8'"
   },
   {
-    "amoeba.shrinking",
-    "-",
-    "-"
+    "steel_char_9",
+    "steel_char",
+    "steel letter '9'"
   },
   {
-    "expandable_wall.growing",
-    "-",
-    "-"
+    "steel_char_colon",
+    "steel_char",
+    "steel letter ':'"
   },
   {
-    "flames",
-    "-",
-    "-"
+    "steel_char_semicolon",
+    "steel_char",
+    "steel letter ';'"
   },
   {
-    "player_is_leaving",
-    "-",
-    "-"
+    "steel_char_less",
+    "steel_char",
+    "steel letter '<'"
   },
   {
-    "player_is_exploding_1",
-    "-",
+    "steel_char_equal",
+    "steel_char",
+    "steel letter '='"
+  },
+  {
+    "steel_char_greater",
+    "steel_char",
+    "steel letter '>'"
+  },
+  {
+    "steel_char_question",
+    "steel_char",
+    "steel letter '?'"
+  },
+  {
+    "steel_char_at",
+    "steel_char",
+    "steel letter '@'"
+  },
+  {
+    "steel_char_a",
+    "steel_char",
+    "steel letter 'A'"
+  },
+  {
+    "steel_char_b",
+    "steel_char",
+    "steel letter 'B'"
+  },
+  {
+    "steel_char_c",
+    "steel_char",
+    "steel letter 'C'"
+  },
+  {
+    "steel_char_d",
+    "steel_char",
+    "steel letter 'D'"
+  },
+  {
+    "steel_char_e",
+    "steel_char",
+    "steel letter 'E'"
+  },
+  {
+    "steel_char_f",
+    "steel_char",
+    "steel letter 'F'"
+  },
+  {
+    "steel_char_g",
+    "steel_char",
+    "steel letter 'G'"
+  },
+  {
+    "steel_char_h",
+    "steel_char",
+    "steel letter 'H'"
+  },
+  {
+    "steel_char_i",
+    "steel_char",
+    "steel letter 'I'"
+  },
+  {
+    "steel_char_j",
+    "steel_char",
+    "steel letter 'J'"
+  },
+  {
+    "steel_char_k",
+    "steel_char",
+    "steel letter 'K'"
+  },
+  {
+    "steel_char_l",
+    "steel_char",
+    "steel letter 'L'"
+  },
+  {
+    "steel_char_m",
+    "steel_char",
+    "steel letter 'M'"
+  },
+  {
+    "steel_char_n",
+    "steel_char",
+    "steel letter 'N'"
+  },
+  {
+    "steel_char_o",
+    "steel_char",
+    "steel letter 'O'"
+  },
+  {
+    "steel_char_p",
+    "steel_char",
+    "steel letter 'P'"
+  },
+  {
+    "steel_char_q",
+    "steel_char",
+    "steel letter 'Q'"
+  },
+  {
+    "steel_char_r",
+    "steel_char",
+    "steel letter 'R'"
+  },
+  {
+    "steel_char_s",
+    "steel_char",
+    "steel letter 'S'"
+  },
+  {
+    "steel_char_t",
+    "steel_char",
+    "steel letter 'T'"
+  },
+  {
+    "steel_char_u",
+    "steel_char",
+    "steel letter 'U'"
+  },
+  {
+    "steel_char_v",
+    "steel_char",
+    "steel letter 'V'"
+  },
+  {
+    "steel_char_w",
+    "steel_char",
+    "steel letter 'W'"
+  },
+  {
+    "steel_char_x",
+    "steel_char",
+    "steel letter 'X'"
+  },
+  {
+    "steel_char_y",
+    "steel_char",
+    "steel letter 'Y'"
+  },
+  {
+    "steel_char_z",
+    "steel_char",
+    "steel letter 'Z'"
+  },
+  {
+    "steel_char_bracketleft",
+    "steel_char",
+    "steel letter '['"
+  },
+  {
+    "steel_char_backslash",
+    "steel_char",
+    "steel letter '\\'"
+  },
+  {
+    "steel_char_bracketright",
+    "steel_char",
+    "steel letter ']'"
+  },
+  {
+    "steel_char_asciicircum",
+    "steel_char",
+    "steel letter '^'"
+  },
+  {
+    "steel_char_underscore",
+    "steel_char",
+    "steel letter '_'"
+  },
+  {
+    "steel_char_copyright",
+    "steel_char",
+    "steel letter '\xa9'"
+  },
+  {
+    "steel_char_aumlaut",
+    "steel_char",
+    "steel letter '\xc4'"
+  },
+  {
+    "steel_char_oumlaut",
+    "steel_char",
+    "steel letter '\xd6'"
+  },
+  {
+    "steel_char_uumlaut",
+    "steel_char",
+    "steel letter '\xdc'"
+  },
+  {
+    "steel_char_degree",
+    "steel_char",
+    "steel letter '\xb0'"
+  },
+  {
+    "steel_char_trademark",
+    "steel_char",
+    "steel letter '\xae'"
+  },
+  {
+    "steel_char_cursor",
+    "steel_char",
+    "steel letter '\xa0'"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter ''"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter 'button'"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter 'up'"
+  },
+  {
+    "steel_char_unused",
+    "steel_char",
+    "steel letter 'down'"
+  },
+  {
+    "sperms",
+    "frankie",
+    "sperms"
+  },
+  {
+    "bullet",
+    "frankie",
+    "bullet"
+  },
+  {
+    "heart",
+    "frankie",
+    "heart"
+  },
+  {
+    "cross",
+    "frankie",
+    "cross"
+  },
+  {
+    "frankie",
+    "frankie",
+    "frankie"
+  },
+  {
+    "sign_sperms",
+    "sign",
+    "sign (sperms)"
+  },
+  {
+    "sign_bullet",
+    "sign",
+    "sign (bullet)"
+  },
+  {
+    "sign_heart",
+    "sign",
+    "sign (heart)"
+  },
+  {
+    "sign_cross",
+    "sign",
+    "sign (cross)"
+  },
+  {
+    "sign_frankie",
+    "sign",
+    "sign (frankie)"
+  },
+  {
+    "steel_exit_closed",
+    "steel_exit",
+    "closed steel exit"
+  },
+  {
+    "steel_exit_open",
+    "steel_exit",
+    "open steel exit"
+  },
+  {
+    "dc_steelwall_1_left",
+    "steelwall",
+    "steel wall (left)"
+  },
+  {
+    "dc_steelwall_1_right",
+    "steelwall",
+    "steel wall (right)"
+  },
+  {
+    "dc_steelwall_1_top",
+    "steelwall",
+    "steel wall (top)"
+  },
+  {
+    "dc_steelwall_1_bottom",
+    "steelwall",
+    "steel wall (bottom)"
+  },
+  {
+    "dc_steelwall_1_horizontal",
+    "steelwall",
+    "steel wall (top/bottom)"
+  },
+  {
+    "dc_steelwall_1_vertical",
+    "steelwall",
+    "steel wall (left/right)"
+  },
+  {
+    "dc_steelwall_1_topleft",
+    "steelwall",
+    "steel wall (top/left)"
+  },
+  {
+    "dc_steelwall_1_topright",
+    "steelwall",
+    "steel wall (top/right)"
+  },
+  {
+    "dc_steelwall_1_bottomleft",
+    "steelwall",
+    "steel wall (bottom/left)"
+  },
+  {
+    "dc_steelwall_1_bottomright",
+    "steelwall",
+    "steel wall (bottom/right)"
+  },
+  {
+    "dc_steelwall_1_topleft_2",
+    "steelwall",
+    "steel wall (top/left corner)"
+  },
+  {
+    "dc_steelwall_1_topright_2",
+    "steelwall",
+    "steel wall (top/right corner)"
+  },
+  {
+    "dc_steelwall_1_bottomleft_2",
+    "steelwall",
+    "steel wall (bottom/left corner)"
+  },
+  {
+    "dc_steelwall_1_bottomright_2",
+    "steelwall",
+    "steel wall (bottom/right corner)"
+  },
+  {
+    "dc_steelwall_2_left",
+    "steelwall",
+    "steel wall (left)"
+  },
+  {
+    "dc_steelwall_2_right",
+    "steelwall",
+    "steel wall (right)"
+  },
+  {
+    "dc_steelwall_2_top",
+    "steelwall",
+    "steel wall (top)"
+  },
+  {
+    "dc_steelwall_2_bottom",
+    "steelwall",
+    "steel wall (bottom)"
+  },
+  {
+    "dc_steelwall_2_horizontal",
+    "steelwall",
+    "steel wall (horizontal)"
+  },
+  {
+    "dc_steelwall_2_vertical",
+    "steelwall",
+    "steel wall (vertical)"
+  },
+  {
+    "dc_steelwall_2_middle",
+    "steelwall",
+    "steel wall (middle)"
+  },
+  {
+    "dc_steelwall_2_single",
+    "steelwall",
+    "steel wall (single)"
+  },
+  {
+    "dc_switchgate_switch_up",
+    "switchgate_switch",
+    "switch for switch gate (steel)"
+  },
+  {
+    "dc_switchgate_switch_down",
+    "switchgate_switch",
+    "switch for switch gate (steel)"
+  },
+  {
+    "dc_timegate_switch",
+    "timegate_switch",
+    "switch for time gate (steel)"
+  },
+  {
+    "dc_timegate_switch.active",
+    "timegate_switch",
+    "switch for time gate (steel)"
+  },
+  {
+    "dc_landmine",
+    "dc_landmine",
+    "land mine (DC style, removable)"
+  },
+  {
+    "expandable_steelwall",
+    "steelwall",
+    "growing steel wall"
+  },
+  {
+    "expandable_steelwall_horizontal",
+    "steelwall",
+    "growing steel wall (horizontal)"
+  },
+  {
+    "expandable_steelwall_vertical",
+    "steelwall",
+    "growing steel wall (vertical)"
+  },
+  {
+    "expandable_steelwall_any",
+    "steelwall",
+    "growing steel wall (any direction)"
+  },
+  {
+    "em_exit_closed",
+    "em_exit",
+    "closed exit (EM style)"
+  },
+  {
+    "em_exit_open",
+    "em_exit",
+    "open exit (EM style)"
+  },
+  {
+    "em_steel_exit_closed",
+    "em_steel_exit",
+    "closed steel exit (EM style)"
+  },
+  {
+    "em_steel_exit_open",
+    "em_steel_exit",
+    "open steel exit (EM style)"
+  },
+  {
+    "dc_gate_fake_gray",
+    "gate",
+    "gray door (opened by no key)"
+  },
+  {
+    "dc_magic_wall",
+    "dc_magic_wall",
+    "magic wall (DC style)"
+  },
+  {
+    "quicksand_fast_empty",
+    "quicksand",
+    "fast quicksand (empty)"
+  },
+  {
+    "quicksand_fast_full",
+    "quicksand",
+    "fast quicksand (with rock)"
+  },
+  {
+    "from_level_template",
+    "from_level_template",
+    "element taken from level template"
+  },
+
+  /* ----------------------------------------------------------------------- */
+  /* "real" (and therefore drawable) runtime elements                        */
+  /* ----------------------------------------------------------------------- */
+
+  {
+    "dynabomb_player_1.active",
+    "dynabomb",
+    "-"
+  },
+  {
+    "dynabomb_player_2.active",
+    "dynabomb",
+    "-"
+  },
+  {
+    "dynabomb_player_3.active",
+    "dynabomb",
+    "-"
+  },
+  {
+    "dynabomb_player_4.active",
+    "dynabomb",
+    "-"
+  },
+  {
+    "sp_disk_red.active",
+    "dynamite",
+    "-"
+  },
+  {
+    "switchgate.opening",
+    "switchgate",
+    "-"
+  },
+  {
+    "switchgate.closing",
+    "switchgate",
+    "-"
+  },
+  {
+    "timegate.opening",
+    "timegate",
+    "-"
+  },
+  {
+    "timegate.closing",
+    "timegate",
+    "-"
+  },
+  {
+    "pearl.breaking",
+    "pearl",
+    "-"
+  },
+  {
+    "trap.active",
+    "trap",
+    "-"
+  },
+  {
+    "invisible_steelwall.active",
+    "steelwall",
+    "-"
+  },
+  {
+    "invisible_wall.active",
+    "wall",
+    "-"
+  },
+  {
+    "invisible_sand.active",
+    "sand",
+    "-"
+  },
+  {
+    "conveyor_belt_1_left.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_1_middle.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_1_right.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_2_left.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_2_middle.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_2_right.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_3_left.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_3_middle.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_3_right.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_4_left.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_4_middle.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "conveyor_belt_4_right.active",
+    "conveyor_belt",
+    "-"
+  },
+  {
+    "exit.opening",
+    "exit",
+    "-"
+  },
+  {
+    "exit.closing",
+    "exit",
+    "-"
+  },
+  {
+    "steel_exit.opening",
+    "steel_exit",
+    "-"
+  },
+  {
+    "steel_exit.closing",
+    "steel_exit",
+    "-"
+  },
+  {
+    "em_exit.opening",
+    "em_exit",
+    "-"
+  },
+  {
+    "em_exit.closing",
+    "em_exit",
+    "-"
+  },
+  {
+    "em_steel_exit.opening",
+    "em_steel_exit",
+    "-"
+  },
+  {
+    "em_steel_exit.closing",
+    "em_steel_exit",
+    "-"
+  },
+  {
+    "sp_exit.opening",
+    "sp_exit",
+    "-"
+  },
+  {
+    "sp_exit.closing",
+    "sp_exit",
+    "-"
+  },
+  {
+    "sp_exit_open",
+    "sp_exit",
+    "-"
+  },
+  {
+    "sp_terminal.active",
+    "sp_terminal",
+    "-"
+  },
+  {
+    "sp_buggy_base.activating",
+    "sp_buggy_base",
+    "-"
+  },
+  {
+    "sp_buggy_base.active",
+    "sp_buggy_base",
+    "-"
+  },
+  {
+    "sp_murphy_clone",
+    "murphy_clone",
+    "-"
+  },
+  {
+    "amoeba.dropping",
+    "amoeba",
+    "-"
+  },
+  {
+    "quicksand.emptying",
+    "quicksand",
+    "-"
+  },
+  {
+    "quicksand_fast.emptying",
+    "quicksand",
+    "-"
+  },
+  {
+    "magic_wall.active",
+    "magic_wall",
+    "-"
+  },
+  {
+    "bd_magic_wall.active",
+    "magic_wall",
+    "-"
+  },
+  {
+    "dc_magic_wall.active",
+    "magic_wall",
+    "-"
+  },
+  {
+    "magic_wall_full",
+    "magic_wall",
+    "-"
+  },
+  {
+    "bd_magic_wall_full",
+    "magic_wall",
+    "-"
+  },
+  {
+    "dc_magic_wall_full",
+    "magic_wall",
+    "-"
+  },
+  {
+    "magic_wall.emptying",
+    "magic_wall",
+    "-"
+  },
+  {
+    "bd_magic_wall.emptying",
+    "magic_wall",
+    "-"
+  },
+  {
+    "dc_magic_wall.emptying",
+    "magic_wall",
+    "-"
+  },
+  {
+    "magic_wall_dead",
+    "magic_wall",
+    "-"
+  },
+  {
+    "bd_magic_wall_dead",
+    "magic_wall",
+    "-"
+  },
+  {
+    "dc_magic_wall_dead",
+    "magic_wall",
+    "-"
+  },
+
+  {
+    "emc_fake_grass.active",
+    "fake_grass",
+    "-"
+  },
+  {
+    "gate_1_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "gate_2_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "gate_3_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "gate_4_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "em_gate_1_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "em_gate_2_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "em_gate_3_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "em_gate_4_gray.active",
+    "gate",
+    ""
+  },
+  {
+    "emc_gate_5_gray.active",
+    "gate",
+    "",
+  },
+  {
+    "emc_gate_6_gray.active",
+    "gate",
+    "",
+  },
+  {
+    "emc_gate_7_gray.active",
+    "gate",
+    "",
+  },
+  {
+    "emc_gate_8_gray.active",
+    "gate",
+    "",
+  },
+  {
+    "dc_gate_white_gray.active",
+    "gate",
+    "",
+  },
+  {
+    "emc_dripper.active",
+    "dripper",
+    "dripper"
+  },
+  {
+    "emc_spring_bumper.active",
+    "emc_spring_bumper",
+    "spring bumper",
+  },
+
+  /* ----------------------------------------------------------------------- */
+  /* "unreal" (and therefore not drawable) runtime elements                  */
+  /* ----------------------------------------------------------------------- */
+
+  {
+    "blocked",
+    "-",
+    "-"
+  },
+  {
+    "explosion",
+    "-",
+    "-"
+  },
+  {
+    "nut.breaking",
+    "-",
+    "-"
+  },
+  {
+    "diamond.breaking",
+    "-",
+    "-"
+  },
+  {
+    "acid_splash_left",
+    "-",
+    "-"
+  },
+  {
+    "acid_splash_right",
+    "-",
+    "-"
+  },
+  {
+    "amoeba.growing",
+    "-",
+    "-"
+  },
+  {
+    "amoeba.shrinking",
+    "-",
+    "-"
+  },
+  {
+    "expandable_wall.growing",
+    "-",
+    "-"
+  },
+  {
+    "expandable_steelwall.growing",
+    "-",
+    "-"
+  },
+  {
+    "flames",
+    "-",
+    "-"
+  },
+  {
+    "player_is_leaving",
+    "-",
+    "-"
+  },
+  {
+    "player_is_exploding_1",
+    "-",
     "-"
   },
   {
@@ -3959,6 +4964,11 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "quicksand",
     "-"
   },
+  {
+    "quicksand_fast.filling",
+    "quicksand",
+    "-"
+  },
   {
     "magic_wall.filling",
     "-",
@@ -3969,6 +4979,26 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "-",
     "-"
   },
+  {
+    "dc_magic_wall.filling",
+    "-",
+    "-"
+  },
+  {
+    "element.snapping",
+    "-",
+    "-"
+  },
+  {
+    "diagonal.shrinking",
+    "-",
+    "-"
+  },
+  {
+    "diagonal.growing",
+    "-",
+    "-"
+  },
 
   /* ----------------------------------------------------------------------- */
   /* dummy elements (never used as game elements, only used as graphics)     */
@@ -4099,6 +5129,46 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "sb_default",
     "-"
   },
+  {
+    "graphic_1",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_2",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_3",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_4",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_5",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_6",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_7",
+    "graphic",
+    "-"
+  },
+  {
+    "graphic_8",
+    "graphic",
+    "-"
+  },
   {
     "internal_clipboard_custom",
     "internal",
@@ -4119,6 +5189,156 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
     "internal",
     "-"
   },
+  {
+    "internal_cascade_bd",
+    "internal",
+    "show Boulder Dash elements"
+  },
+  {
+    "internal_cascade_bd.active",
+    "internal",
+    "hide Boulder Dash elements"
+  },
+  {
+    "internal_cascade_em",
+    "internal",
+    "show Emerald Mine elements"
+  },
+  {
+    "internal_cascade_em.active",
+    "internal",
+    "hide Emerald Mine elements"
+  },
+  {
+    "internal_cascade_emc",
+    "internal",
+    "show Emerald Mine Club elements"
+  },
+  {
+    "internal_cascade_emc.active",
+    "internal",
+    "hide Emerald Mine Club elements"
+  },
+  {
+    "internal_cascade_rnd",
+    "internal",
+    "show Rocks'n'Diamonds elements"
+  },
+  {
+    "internal_cascade_rnd.active",
+    "internal",
+    "hide Rocks'n'Diamonds elements"
+  },
+  {
+    "internal_cascade_sb",
+    "internal",
+    "show Sokoban elements"
+  },
+  {
+    "internal_cascade_sb.active",
+    "internal",
+    "hide Sokoban elements"
+  },
+  {
+    "internal_cascade_sp",
+    "internal",
+    "show Supaplex elements"
+  },
+  {
+    "internal_cascade_sp.active",
+    "internal",
+    "hide Supaplex elements"
+  },
+  {
+    "internal_cascade_dc",
+    "internal",
+    "show Diamond Caves II elements"
+  },
+  {
+    "internal_cascade_dc.active",
+    "internal",
+    "hide Diamond Caves II elements"
+  },
+  {
+    "internal_cascade_dx",
+    "internal",
+    "show DX Boulderdash elements"
+  },
+  {
+    "internal_cascade_dx.active",
+    "internal",
+    "hide DX Boulderdash elements"
+  },
+  {
+    "internal_cascade_chars",
+    "internal",
+    "show text elements"
+  },
+  {
+    "internal_cascade_chars.active",
+    "internal",
+    "hide text elements"
+  },
+  {
+    "internal_cascade_steel_chars",
+    "internal",
+    "show steel text elements"
+  },
+  {
+    "internal_cascade_steel_chars.active",
+    "internal",
+    "hide steel text elements"
+  },
+  {
+    "internal_cascade_ce",
+    "internal",
+    "show custom elements"
+  },
+  {
+    "internal_cascade_ce.active",
+    "internal",
+    "hide custom elements"
+  },
+  {
+    "internal_cascade_ge",
+    "internal",
+    "show group elements"
+  },
+  {
+    "internal_cascade_ge.active",
+    "internal",
+    "hide group elements"
+  },
+  {
+    "internal_cascade_ref",
+    "internal",
+    "show reference elements"
+  },
+  {
+    "internal_cascade_ref.active",
+    "internal",
+    "hide reference elements"
+  },
+  {
+    "internal_cascade_user",
+    "internal",
+    "show user defined elements"
+  },
+  {
+    "internal_cascade_user.active",
+    "internal",
+    "hide user defined elements"
+  },
+  {
+    "internal_cascade_dynamic",
+    "internal",
+    "show elements used in this level"
+  },
+  {
+    "internal_cascade_dynamic.active",
+    "internal",
+    "hide elements used in this level"
+  },
 
   /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */
 
@@ -4185,8 +5405,49 @@ struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] =
   { ".turning_from_down",      ACTION_TURNING_FROM_DOWN,       FALSE   },
   { ".smashed_by_rock",                ACTION_SMASHED_BY_ROCK,         FALSE   },
   { ".smashed_by_spring",      ACTION_SMASHED_BY_SPRING,       FALSE   },
-  { ".slurped_by_spring",      ACTION_SLURPED_BY_SPRING,       FALSE   },
+  { ".eating",                 ACTION_EATING,                  FALSE   },
   { ".twinkling",              ACTION_TWINKLING,               FALSE   },
+  { ".splashing",              ACTION_SPLASHING,               FALSE   },
+  { ".page[1]",                        ACTION_PAGE_1,                  FALSE   },
+  { ".page[2]",                        ACTION_PAGE_2,                  FALSE   },
+  { ".page[3]",                        ACTION_PAGE_3,                  FALSE   },
+  { ".page[4]",                        ACTION_PAGE_4,                  FALSE   },
+  { ".page[5]",                        ACTION_PAGE_5,                  FALSE   },
+  { ".page[6]",                        ACTION_PAGE_6,                  FALSE   },
+  { ".page[7]",                        ACTION_PAGE_7,                  FALSE   },
+  { ".page[8]",                        ACTION_PAGE_8,                  FALSE   },
+  { ".page[9]",                        ACTION_PAGE_9,                  FALSE   },
+  { ".page[10]",               ACTION_PAGE_10,                 FALSE   },
+  { ".page[11]",               ACTION_PAGE_11,                 FALSE   },
+  { ".page[12]",               ACTION_PAGE_12,                 FALSE   },
+  { ".page[13]",               ACTION_PAGE_13,                 FALSE   },
+  { ".page[14]",               ACTION_PAGE_14,                 FALSE   },
+  { ".page[15]",               ACTION_PAGE_15,                 FALSE   },
+  { ".page[16]",               ACTION_PAGE_16,                 FALSE   },
+  { ".page[17]",               ACTION_PAGE_17,                 FALSE   },
+  { ".page[18]",               ACTION_PAGE_18,                 FALSE   },
+  { ".page[19]",               ACTION_PAGE_19,                 FALSE   },
+  { ".page[20]",               ACTION_PAGE_20,                 FALSE   },
+  { ".page[21]",               ACTION_PAGE_21,                 FALSE   },
+  { ".page[22]",               ACTION_PAGE_22,                 FALSE   },
+  { ".page[23]",               ACTION_PAGE_23,                 FALSE   },
+  { ".page[24]",               ACTION_PAGE_24,                 FALSE   },
+  { ".page[25]",               ACTION_PAGE_25,                 FALSE   },
+  { ".page[26]",               ACTION_PAGE_26,                 FALSE   },
+  { ".page[27]",               ACTION_PAGE_27,                 FALSE   },
+  { ".page[28]",               ACTION_PAGE_28,                 FALSE   },
+  { ".page[29]",               ACTION_PAGE_29,                 FALSE   },
+  { ".page[30]",               ACTION_PAGE_30,                 FALSE   },
+  { ".page[31]",               ACTION_PAGE_31,                 FALSE   },
+  { ".page[32]",               ACTION_PAGE_32,                 FALSE   },
+  { ".part_1",                 ACTION_PART_1,                  FALSE   },
+  { ".part_2",                 ACTION_PART_2,                  FALSE   },
+  { ".part_3",                 ACTION_PART_3,                  FALSE   },
+  { ".part_4",                 ACTION_PART_4,                  FALSE   },
+  { ".part_5",                 ACTION_PART_5,                  FALSE   },
+  { ".part_6",                 ACTION_PART_6,                  FALSE   },
+  { ".part_7",                 ACTION_PART_7,                  FALSE   },
+  { ".part_8",                 ACTION_PART_8,                  FALSE   },
   { ".other",                  ACTION_OTHER,                   FALSE   },
 
   /* empty suffix always matches -- check as last entry in InitSoundInfo() */
@@ -4195,76 +5456,64 @@ struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] =
   { NULL,                      0,                              0       }
 };
 
-struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS + 1] =
+struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS_FULL + 1] =
 {
-  { ".left",           MV_BIT_LEFT                     },
-  { ".right",          MV_BIT_RIGHT                    },
-  { ".up",             MV_BIT_UP                       },
-  { ".down",           MV_BIT_DOWN                     },
+  { ".left",                   MV_BIT_LEFT                             },
+  { ".right",                  MV_BIT_RIGHT                            },
+  { ".up",                     MV_BIT_UP                               },
+  { ".down",                   MV_BIT_DOWN                             },
+  { ".upleft",                 MV_BIT_UP                               },
+  { ".upright",                        MV_BIT_RIGHT                            },
+  { ".downleft",               MV_BIT_LEFT                             },
+  { ".downright",              MV_BIT_DOWN                             },
 
-  { NULL,              0                               }
+  { NULL,                      0                                       }
 };
 
 struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] =
 {
-  { ".[DEFAULT]",      GAME_MODE_DEFAULT,              },
-  { ".MAIN",           GAME_MODE_MAIN,                 },
-  { ".LEVELS",         GAME_MODE_LEVELS                },
-  { ".SCORES",         GAME_MODE_SCORES,               },
-  { ".EDITOR",         GAME_MODE_EDITOR,               },
-  { ".INFO",           GAME_MODE_INFO,                 },
-  { ".SETUP",          GAME_MODE_SETUP,                },
-  { ".PLAYING",                GAME_MODE_PLAYING,              },
-  { ".DOOR",           GAME_MODE_PSEUDO_DOOR,          },
-  { ".PREVIEW",                GAME_MODE_PSEUDO_PREVIEW,       },
-  { ".CRUMBLED",       GAME_MODE_PSEUDO_CRUMBLED,      },
+  { ".[DEFAULT]",              GFX_SPECIAL_ARG_DEFAULT,                },
+  { ".LOADING",                        GFX_SPECIAL_ARG_LOADING,                },
+  { ".TITLE_INITIAL",          GFX_SPECIAL_ARG_TITLE_INITIAL,          },
+  { ".TITLE_INITIAL_1",                GFX_SPECIAL_ARG_TITLE_INITIAL_1,        },
+  { ".TITLE_INITIAL_2",                GFX_SPECIAL_ARG_TITLE_INITIAL_2,        },
+  { ".TITLE_INITIAL_3",                GFX_SPECIAL_ARG_TITLE_INITIAL_3,        },
+  { ".TITLE_INITIAL_4",                GFX_SPECIAL_ARG_TITLE_INITIAL_4,        },
+  { ".TITLE_INITIAL_5",                GFX_SPECIAL_ARG_TITLE_INITIAL_5,        },
+  { ".TITLE",                  GFX_SPECIAL_ARG_TITLE,                  },
+  { ".TITLE_1",                        GFX_SPECIAL_ARG_TITLE_1,                },
+  { ".TITLE_2",                        GFX_SPECIAL_ARG_TITLE_2,                },
+  { ".TITLE_3",                        GFX_SPECIAL_ARG_TITLE_3,                },
+  { ".TITLE_4",                        GFX_SPECIAL_ARG_TITLE_4,                },
+  { ".TITLE_5",                        GFX_SPECIAL_ARG_TITLE_5,                },
+  { ".MAIN",                   GFX_SPECIAL_ARG_MAIN,                   },
+  { ".LEVELS",                 GFX_SPECIAL_ARG_LEVELS                  },
+  { ".LEVELNR",                        GFX_SPECIAL_ARG_LEVELNR                 },
+  { ".SCORES",                 GFX_SPECIAL_ARG_SCORES,                 },
+  { ".EDITOR",                 GFX_SPECIAL_ARG_EDITOR,                 },
+  { ".INFO",                   GFX_SPECIAL_ARG_INFO,                   },
+  { ".SETUP",                  GFX_SPECIAL_ARG_SETUP,                  },
+  { ".PLAYING",                        GFX_SPECIAL_ARG_PLAYING,                },
+  { ".DOOR",                   GFX_SPECIAL_ARG_DOOR,                   },
+  { ".TAPE",                   GFX_SPECIAL_ARG_TAPE,                   },
+  { ".PANEL",                  GFX_SPECIAL_ARG_PANEL,                  },
+  { ".PREVIEW",                        GFX_SPECIAL_ARG_PREVIEW,                },
+  { ".CRUMBLED",               GFX_SPECIAL_ARG_CRUMBLED,               },
+  { ".MAINONLY",               GFX_SPECIAL_ARG_MAINONLY,               },
+  { ".TYPENAME",               GFX_SPECIAL_ARG_TYPENAME,               },
+  { ".SUBMENU",                        GFX_SPECIAL_ARG_SUBMENU,                },
+  { ".MENU",                   GFX_SPECIAL_ARG_MENU,                   },
+  { ".TOONS",                  GFX_SPECIAL_ARG_TOONS,                  },
+  { ".FADING",                 GFX_SPECIAL_ARG_FADING,                 },
+  { ".QUIT",                   GFX_SPECIAL_ARG_QUIT,                   },
 
   /* empty suffix always matches -- check as last entry in InitMusicInfo() */
-  { "",                        GAME_MODE_DEFAULT,              },
+  { "",                                GFX_SPECIAL_ARG_DEFAULT,                },
 
-  { NULL,              0,                              }
+  { NULL,                      0,                                      }
 };
 
-struct TokenIntPtrInfo image_config_vars[] =
-{
-  { "global.num_toons",                &global.num_toons                          },
-
-  { "menu.draw_xoffset",       &menu.draw_xoffset_default                 },
-  { "menu.draw_yoffset",       &menu.draw_yoffset_default                 },
-  { "menu.draw_xoffset.MAIN",  &menu.draw_xoffset[GFX_SPECIAL_ARG_MAIN]   },
-  { "menu.draw_yoffset.MAIN",  &menu.draw_yoffset[GFX_SPECIAL_ARG_MAIN]   },
-  { "menu.draw_xoffset.LEVELS",        &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELS] },
-  { "menu.draw_yoffset.LEVELS",        &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] },
-  { "menu.draw_xoffset.SCORES",        &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] },
-  { "menu.draw_yoffset.SCORES",        &menu.draw_yoffset[GFX_SPECIAL_ARG_SCORES] },
-  { "menu.draw_xoffset.EDITOR",        &menu.draw_xoffset[GFX_SPECIAL_ARG_EDITOR] },
-  { "menu.draw_yoffset.EDITOR",        &menu.draw_yoffset[GFX_SPECIAL_ARG_EDITOR] },
-  { "menu.draw_xoffset.INFO",  &menu.draw_xoffset[GFX_SPECIAL_ARG_INFO]   },
-  { "menu.draw_yoffset.INFO",  &menu.draw_yoffset[GFX_SPECIAL_ARG_INFO]   },
-  { "menu.draw_xoffset.SETUP", &menu.draw_xoffset[GFX_SPECIAL_ARG_SETUP]  },
-  { "menu.draw_yoffset.SETUP", &menu.draw_yoffset[GFX_SPECIAL_ARG_SETUP]  },
-
-  { "menu.scrollbar_xoffset",  &menu.scrollbar_xoffset                    },
-
-  { "menu.list_size",          &menu.list_size_default                    },
-  { "menu.list_size.LEVELS",   &menu.list_size[GFX_SPECIAL_ARG_LEVELS]    },
-  { "menu.list_size.SCORES",   &menu.list_size[GFX_SPECIAL_ARG_SCORES]    },
-  { "menu.list_size.INFO",     &menu.list_size[GFX_SPECIAL_ARG_INFO]      },
-
-  { "door_1.step_offset",      &door_1.step_offset                        },
-  { "door_1.step_delay",       &door_1.step_delay                         },
-  { "door_1.anim_mode",                &door_1.anim_mode                          },
-  { "door_2.step_offset",      &door_2.step_offset                        },
-  { "door_2.step_delay",       &door_2.step_delay                         },
-  { "door_2.anim_mode",                &door_2.anim_mode                          },
-
-  { "[player].boring_delay_fixed",     &game.player_boring_delay_fixed    },
-  { "[player].boring_delay_random",    &game.player_boring_delay_random   },
-  { "[player].sleeping_delay_fixed",   &game.player_sleeping_delay_fixed  },
-  { "[player].sleeping_delay_random",  &game.player_sleeping_delay_random },
-
-  { NULL,                      NULL,                                      }
-};
+#include "conf_var.c"  /* include auto-generated data structure definitions */
 
 
 /* ------------------------------------------------------------------------- */
@@ -4272,7 +5521,8 @@ struct TokenIntPtrInfo image_config_vars[] =
 /* ------------------------------------------------------------------------- */
 
 /* Important: When one entry is a prefix of another entry, the longer entry
-   must come first, because the dynamic configuration does prefix matching! */
+   must come first, because the dynamic configuration does prefix matching!
+   (These definitions must match the corresponding definitions in "main.h"!) */
 
 struct FontInfo font_info[NUM_FONTS + 1] =
 {
@@ -4282,6 +5532,8 @@ struct FontInfo font_info[NUM_FONTS + 1] =
   { "font.initial_4"           },
   { "font.title_1"             },
   { "font.title_2"             },
+  { "font.menu_1.active"       },
+  { "font.menu_2.active"       },
   { "font.menu_1"              },
   { "font.menu_2"              },
   { "font.text_1.active"       },
@@ -4296,18 +5548,52 @@ struct FontInfo font_info[NUM_FONTS + 1] =
   { "font.envelope_2"          },
   { "font.envelope_3"          },
   { "font.envelope_4"          },
+  { "font.request"             },
   { "font.input_1.active"      },
   { "font.input_2.active"      },
   { "font.input_1"             },
   { "font.input_2"             },
+  { "font.option_off_narrow"   },
   { "font.option_off"          },
+  { "font.option_on_narrow"    },
   { "font.option_on"           },
   { "font.value_1"             },
   { "font.value_2"             },
   { "font.value_old"           },
+  { "font.value_narrow"                },
+  { "font.level_number.active" },
   { "font.level_number"                },
   { "font.tape_recorder"       },
   { "font.game_info"           },
+  { "font.info.elements"       },
+  { "font.info.levelset"       },
+
+  { NULL                       }
+};
+
+struct GlobalAnimInfo global_anim_info[NUM_GLOBAL_ANIM_TOKENS + 1] =
+{
+  /* (real) graphic definitions used to define animation graphics */
+  { "global.anim_1.gfx",       },
+  { "global.anim_2.gfx",       },
+  { "global.anim_3.gfx",       },
+  { "global.anim_4.gfx",       },
+  { "global.anim_5.gfx",       },
+  { "global.anim_6.gfx",       },
+  { "global.anim_7.gfx",       },
+  { "global.anim_8.gfx",       },
+
+  /* (dummy) graphic definitions used to define animation controls */
+  { "global.anim_1",           },
+  { "global.anim_2",           },
+  { "global.anim_3",           },
+  { "global.anim_4",           },
+  { "global.anim_5",           },
+  { "global.anim_6",           },
+  { "global.anim_7",           },
+  { "global.anim_8",           },
+
+  { NULL                       }
 };
 
 
@@ -4329,49 +5615,151 @@ struct MusicPrefixInfo music_prefix_info[NUM_MUSIC_PREFIXES + 1] =
 
 static void print_usage()
 {
-  printf("\n"
-        "Usage: %s [OPTION]... [HOSTNAME [PORT]]\n"
-        "\n"
-        "Options:\n"
-        "  -d, --display HOSTNAME[:SCREEN]  specify X server display\n"
-        "  -b, --basepath DIRECTORY         alternative base DIRECTORY\n"
-        "  -l, --level DIRECTORY            alternative level DIRECTORY\n"
-        "  -g, --graphics DIRECTORY         alternative graphics DIRECTORY\n"
-        "  -s, --sounds DIRECTORY           alternative sounds DIRECTORY\n"
-        "  -m, --music DIRECTORY            alternative music DIRECTORY\n"
-        "  -n, --network                    network multiplayer game\n"
-        "      --serveronly                 only start network server\n"
-        "  -v, --verbose                    verbose mode\n"
-        "      --debug                      display debugging information\n"
-        "  -e, --execute COMMAND            execute batch COMMAND\n"
-        "\n"
-        "Valid commands for '--execute' option:\n"
-        "  \"print graphicsinfo.conf\"        print default graphics config\n"
-        "  \"print soundsinfo.conf\"          print default sounds config\n"
-        "  \"print musicinfo.conf\"           print default music config\n"
-        "  \"print editorsetup.conf\"         print default editor config\n"
-        "  \"print helpanim.conf\"            print default helpanim config\n"
-        "  \"print helptext.conf\"            print default helptext config\n"
-        "  \"dump level FILE\"                dump level data from FILE\n"
-        "  \"dump tape FILE\"                 dump tape data from FILE\n"
-        "  \"autoplay LEVELDIR [NR]\"         play level tapes for LEVELDIR\n"
-        "  \"convert LEVELDIR [NR]\"          convert levels in LEVELDIR\n"
-        "\n",
-        program.command_basename);
+  Print("\n"
+       "Usage: %s [OPTION]... [HOSTNAME [PORT]]\n"
+       "\n"
+       "Options:\n"
+       "  -b, --basepath DIRECTORY         alternative base DIRECTORY\n"
+       "  -l, --level DIRECTORY            alternative level DIRECTORY\n"
+       "  -g, --graphics DIRECTORY         alternative graphics DIRECTORY\n"
+       "  -s, --sounds DIRECTORY           alternative sounds DIRECTORY\n"
+       "  -m, --music DIRECTORY            alternative music DIRECTORY\n"
+       "  -n, --network                    network multiplayer game\n"
+       "      --serveronly                 only start network server\n"
+       "  -v, --verbose                    verbose mode\n"
+       "  -V, --version                    show program version\n"
+       "      --debug                      display debugging information\n"
+       "  -e, --execute COMMAND            execute batch COMMAND\n"
+       "\n"
+       "Valid commands for '--execute' option:\n"
+       "  \"print graphicsinfo.conf\"        print default graphics config\n"
+       "  \"print soundsinfo.conf\"          print default sounds config\n"
+       "  \"print musicinfo.conf\"           print default music config\n"
+       "  \"print editorsetup.conf\"         print default editor config\n"
+       "  \"print helpanim.conf\"            print default helpanim config\n"
+       "  \"print helptext.conf\"            print default helptext config\n"
+       "  \"dump level FILE\"                dump level data from FILE\n"
+       "  \"dump tape FILE\"                 dump tape data from FILE\n"
+       "  \"autotest LEVELDIR [NR ...]\"     test level tapes for LEVELDIR\n"
+       "  \"autoplay LEVELDIR [NR ...]\"     play level tapes for LEVELDIR\n"
+       "  \"autoffwd LEVELDIR [NR ...]\"     ffwd level tapes for LEVELDIR\n"
+       "  \"convert LEVELDIR [NR]\"          convert levels in LEVELDIR\n"
+       "  \"create images DIRECTORY\"        write BMP images to DIRECTORY\n"
+       "  \"create CE image DIRECTORY\"      write BMP image to DIRECTORY\n"
+       "\n",
+       program.command_basename);
+}
+
+static void print_version()
+{
+  Print("%s %d.%d.%d.%d%s\n",
+       PROGRAM_TITLE_STRING,
+       PROGRAM_VERSION_MAJOR,
+       PROGRAM_VERSION_MINOR,
+       PROGRAM_VERSION_PATCH,
+       PROGRAM_VERSION_BUILD,
+       PROGRAM_VERSION_EXTRA);
+
+  if (options.debug)
+  {
+    SDL_version sdl_version;
+
+    SDL_VERSION(&sdl_version);
+    Print("- SDL %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
+
+    SDL_IMAGE_VERSION(&sdl_version);
+    Print("- SDL_image %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
+
+    SDL_MIXER_VERSION(&sdl_version);
+    Print("- SDL_mixer %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
+
+    SDL_NET_VERSION(&sdl_version);
+    Print("- SDL_net %d.%d.%d\n",
+         sdl_version.major,
+         sdl_version.minor,
+         sdl_version.patch);
+  }
+}
+
+static void InitProgramConfig(char *command_filename)
+{
+  char *program_title = PROGRAM_TITLE_STRING;
+  char *program_icon_file = PROGRAM_ICON_FILENAME;
+  char *config_filename = getProgramConfigFilename(command_filename);
+  char *userdata_basename = getBaseNameNoSuffix(command_filename);
+  char *userdata_subdir;
+  char *userdata_subdir_unix;
+
+  // read default program config, if existing
+  if (fileExists(config_filename))
+  {
+    // if program config file exists, derive Unix user data directory from it
+    userdata_basename = getBaseName(config_filename);
+
+    if (strSuffix(userdata_basename, ".conf"))
+      userdata_basename[strlen(userdata_basename) - 5] = '\0';
+
+    LoadSetupFromFilename(config_filename);
+  }
+
+  // set user data directory for Linux/Unix (but not Mac OS X)
+  userdata_subdir_unix = getStringCat2(".", userdata_basename);
+
+  // set program title from potentially redefined program title
+  if (setup.internal.program_title != NULL &&
+      strlen(setup.internal.program_title) > 0)
+    program_title = getStringCopy(setup.internal.program_title);
+
+  // set program icon file from potentially redefined program icon file
+  if (setup.internal.program_icon_file != NULL &&
+      strlen(setup.internal.program_icon_file) > 0)
+    program_icon_file = getStringCopy(setup.internal.program_icon_file);
+
+#if defined(PLATFORM_WIN32) || defined(PLATFORM_MACOSX)
+  userdata_subdir = program_title;
+#elif defined(PLATFORM_UNIX)
+  userdata_subdir = userdata_subdir_unix;
+#else
+  userdata_subdir = USERDATA_DIRECTORY_OTHER;
+#endif
+
+  // set default window size (only relevant on program startup)
+  if (setup.internal.default_window_width  != 0 &&
+      setup.internal.default_window_height != 0)
+  {
+    WIN_XSIZE = setup.internal.default_window_width;
+    WIN_YSIZE = setup.internal.default_window_height;
+  }
+
+  InitProgramInfo(command_filename,
+                 config_filename,
+                 userdata_subdir,
+                 program_title,
+                 program_title,
+                 program_icon_file,
+                 COOKIE_PREFIX,
+                 GAME_VERSION_ACTUAL);
 }
 
 int main(int argc, char *argv[])
 {
-  InitProgramInfo(argv[0], USERDATA_DIRECTORY,
-                 PROGRAM_TITLE_STRING, getWindowTitleString(),
-                 ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
-                 MSDOS_POINTER_FILENAME,
-                 COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
+  InitProgramConfig(argv[0]);
 
+  InitWindowTitleFunction(getWindowTitleString);
+  InitExitMessageFunction(DisplayExitMessage);
   InitExitFunction(CloseAllAndExit);
   InitPlatformDependentStuff();
 
-  GetOptions(argv, print_usage);
+  GetOptions(argc, argv, print_usage, print_version);
   OpenAll();
 
   EventLoop();