added support for more event types for global animations (yet to be added)
[rocksndiamonds.git] / src / files.c
index 33990a38ff52adf06fb7fe560981c012e6469188..9f20487fb0e4f5aebb8bd2108b2f7e19040db114 100644 (file)
 
 #include "files.h"
 #include "init.h"
+#include "screens.h"
 #include "tools.h"
 #include "tape.h"
 #include "config.h"
 
-#define ENABLE_UNUSED_CODE     0       /* currently unused functions */
-#define ENABLE_HISTORIC_CHUNKS 0       /* only for historic reference */
-#define ENABLE_RESERVED_CODE   0       /* reserved for later use */
+#define ENABLE_UNUSED_CODE     0       // currently unused functions
+#define ENABLE_HISTORIC_CHUNKS 0       // only for historic reference
+#define ENABLE_RESERVED_CODE   0       // reserved for later use
 
-#define CHUNK_ID_LEN           4       /* IFF style chunk id length  */
-#define CHUNK_SIZE_UNDEFINED   0       /* undefined chunk size == 0  */
-#define CHUNK_SIZE_NONE                -1      /* do not write chunk size    */
+#define CHUNK_ID_LEN           4       // IFF style chunk id length
+#define CHUNK_SIZE_UNDEFINED   0       // undefined chunk size == 0
+#define CHUNK_SIZE_NONE                -1      // do not write chunk size
 
 #define LEVEL_CHUNK_NAME_SIZE  MAX_LEVEL_NAME_LEN
 #define LEVEL_CHUNK_AUTH_SIZE  MAX_LEVEL_AUTHOR_LEN
 
-#define LEVEL_CHUNK_VERS_SIZE  8       /* size of file version chunk */
-#define LEVEL_CHUNK_DATE_SIZE  4       /* size of file date chunk    */
-#define LEVEL_CHUNK_HEAD_SIZE  80      /* size of level file header  */
-#define LEVEL_CHUNK_HEAD_UNUSED        0       /* unused level header bytes  */
-#define LEVEL_CHUNK_CNT2_SIZE  160     /* size of level CNT2 chunk   */
-#define LEVEL_CHUNK_CNT2_UNUSED        11      /* unused CNT2 chunk bytes    */
-#define LEVEL_CHUNK_CNT3_HEADER        16      /* size of level CNT3 header  */
-#define LEVEL_CHUNK_CNT3_UNUSED        10      /* unused CNT3 chunk bytes    */
-#define LEVEL_CPART_CUS3_SIZE  134     /* size of CUS3 chunk part    */
-#define LEVEL_CPART_CUS3_UNUSED        15      /* unused CUS3 bytes / part   */
-#define LEVEL_CHUNK_GRP1_SIZE  74      /* size of level GRP1 chunk   */
-
-/* (element number, number of change pages, change page number) */
+#define LEVEL_CHUNK_VERS_SIZE  8       // size of file version chunk
+#define LEVEL_CHUNK_DATE_SIZE  4       // size of file date chunk
+#define LEVEL_CHUNK_HEAD_SIZE  80      // size of level file header
+#define LEVEL_CHUNK_HEAD_UNUSED        0       // unused level header bytes
+#define LEVEL_CHUNK_CNT2_SIZE  160     // size of level CNT2 chunk
+#define LEVEL_CHUNK_CNT2_UNUSED        11      // unused CNT2 chunk bytes
+#define LEVEL_CHUNK_CNT3_HEADER        16      // size of level CNT3 header
+#define LEVEL_CHUNK_CNT3_UNUSED        10      // unused CNT3 chunk bytes
+#define LEVEL_CPART_CUS3_SIZE  134     // size of CUS3 chunk part
+#define LEVEL_CPART_CUS3_UNUSED        15      // unused CUS3 bytes / part
+#define LEVEL_CHUNK_GRP1_SIZE  74      // size of level GRP1 chunk
+
+// (element number, number of change pages, change page number)
 #define LEVEL_CHUNK_CUSX_UNCHANGED     (2 + (1 + 1) + (1 + 1))
 
-/* (element number only) */
+// (element number only)
 #define LEVEL_CHUNK_GRPX_UNCHANGED     2
 #define LEVEL_CHUNK_NOTE_UNCHANGED     2
 
-/* (nothing at all if unchanged) */
+// (nothing at all if unchanged)
 #define LEVEL_CHUNK_ELEM_UNCHANGED     0
 
-#define TAPE_CHUNK_VERS_SIZE   8       /* size of file version chunk */
-#define TAPE_CHUNK_HEAD_SIZE   20      /* size of tape file header   */
-#define TAPE_CHUNK_HEAD_UNUSED 3       /* unused tape header bytes   */
+#define TAPE_CHUNK_VERS_SIZE   8       // size of file version chunk
+#define TAPE_CHUNK_HEAD_SIZE   20      // size of tape file header
+#define TAPE_CHUNK_HEAD_UNUSED 2       // unused tape header bytes
 
 #define LEVEL_CHUNK_CNT3_SIZE(x)        (LEVEL_CHUNK_CNT3_HEADER + (x))
 #define LEVEL_CHUNK_CUS3_SIZE(x)        (2 + (x) * LEVEL_CPART_CUS3_SIZE)
 #define LEVEL_CHUNK_CUS4_SIZE(x)        (96 + (x) * 48)
 
-/* file identifier strings */
+// file identifier strings
 #define LEVEL_COOKIE_TMPL              "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x"
 #define TAPE_COOKIE_TMPL               "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x"
 #define SCORE_COOKIE                   "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2"
 
-/* values for deciding when (not) to save configuration data */
+// values for deciding when (not) to save configuration data
 #define SAVE_CONF_NEVER                        0
 #define SAVE_CONF_ALWAYS               1
 #define SAVE_CONF_WHEN_CHANGED         -1
 
-/* values for chunks using micro chunks */
+// values for chunks using micro chunks
 #define CONF_MASK_1_BYTE               0x00
 #define CONF_MASK_2_BYTE               0x40
 #define CONF_MASK_4_BYTE               0x80
@@ -87,7 +88,7 @@
 #define CONF_VALUE_4_BYTE(x)           (CONF_MASK_4_BYTE       | (x))
 #define CONF_VALUE_MULTI_BYTES(x)      (CONF_MASK_MULTI_BYTES  | (x))
 
-/* these definitions are just for convenience of use and readability */
+// these definitions are just for convenience of use and readability
 #define CONF_VALUE_8_BIT(x)            CONF_VALUE_1_BYTE(x)
 #define CONF_VALUE_16_BIT(x)           CONF_VALUE_2_BYTE(x)
 #define CONF_VALUE_32_BIT(x)           CONF_VALUE_4_BYTE(x)
 #define CONF_CONTENTS_ELEMENT(b,c,x,y) ((b[CONF_CONTENT_BYTE_POS(c,x,y)]<< 8)|\
                                        (b[CONF_CONTENT_BYTE_POS(c,x,y) + 1]))
 
-/* temporary variables used to store pointers to structure members */
+// temporary variables used to store pointers to structure members
 static struct LevelInfo li;
 static struct ElementInfo xx_ei, yy_ei;
 static struct ElementChangeInfo xx_change;
@@ -134,26 +135,26 @@ static int xx_string_length_unused;
 
 struct LevelFileConfigInfo
 {
-  int element;                 /* element for which data is to be stored */
-  int save_type;               /* save data always, never or when changed */
-  int data_type;               /* data type (used internally, not stored) */
-  int conf_type;               /* micro chunk identifier (stored in file) */
-
-  /* (mandatory) */
-  void *value;                 /* variable that holds the data to be stored */
-  int default_value;           /* initial default value for this variable */
-
-  /* (optional) */
-  void *value_copy;            /* variable that holds the data to be copied */
-  void *num_entities;          /* number of entities for multi-byte data */
-  int default_num_entities;    /* default number of entities for this data */
-  int max_num_entities;                /* maximal number of entities for this data */
-  char *default_string;                /* optional default string for string data */
+  int element;                 // element for which data is to be stored
+  int save_type;               // save data always, never or when changed
+  int data_type;               // data type (used internally, not stored)
+  int conf_type;               // micro chunk identifier (stored in file)
+
+  // (mandatory)
+  void *value;                 // variable that holds the data to be stored
+  int default_value;           // initial default value for this variable
+
+  // (optional)
+  void *value_copy;            // variable that holds the data to be copied
+  void *num_entities;          // number of entities for multi-byte data
+  int default_num_entities;    // default number of entities for this data
+  int max_num_entities;                // maximal number of entities for this data
+  char *default_string;                // optional default string for string data
 };
 
 static struct LevelFileConfigInfo chunk_config_INFO[] =
 {
-  /* ---------- values not related to single elements ----------------------- */
+  // ---------- values not related to single elements -------------------------
 
   {
     -1,                                        SAVE_CONF_ALWAYS,
@@ -217,13 +218,13 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_32_BIT(1),
-    &li.can_move_into_acid_bits,       ~0      /* default: everything can */
+    &li.can_move_into_acid_bits,       ~0      // default: everything can
   },
 
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_8_BIT(7),
-    &li.dont_collide_with_bits,                ~0      /* default: always deadly */
+    &li.dont_collide_with_bits,                ~0      // default: always deadly
   },
 
   {
@@ -244,6 +245,18 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
     &li.auto_exit_sokoban,             FALSE
   },
 
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(10),
+    &li.auto_count_gems,               FALSE
+  },
+
+  {
+    -1,                                        -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(11),
+    &li.solved_by_one_player,          FALSE
+  },
+
   {
     -1,                                        -1,
     -1,                                        -1,
@@ -253,16 +266,16 @@ static struct LevelFileConfigInfo chunk_config_INFO[] =
 
 static struct LevelFileConfigInfo chunk_config_ELEM[] =
 {
-  /* (these values are the same for each player) */
+  // (these values are the same for each player)
   {
     EL_PLAYER_1,                       -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
-    &li.block_last_field,              FALSE   /* default case for EM levels */
+    &li.block_last_field,              FALSE   // default case for EM levels
   },
   {
     EL_PLAYER_1,                       -1,
     TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
-    &li.sp_block_last_field,           TRUE    /* default case for SP levels */
+    &li.sp_block_last_field,           TRUE    // default case for SP levels
   },
   {
     EL_PLAYER_1,                       -1,
@@ -295,7 +308,7 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     &li.lazy_relocation,               FALSE
   },
 
-  /* (these values are different for each player) */
+  // (these values are different for each player)
   {
     EL_PLAYER_1,                       -1,
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(7),
@@ -655,6 +668,11 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     TYPE_INTEGER,                      CONF_VALUE_8_BIT(4),
     &li.game_of_life[3],               3
   },
+  {
+    EL_GAME_OF_LIFE,                   -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(5),
+    &li.use_life_bugs,                 FALSE
+  },
 
   {
     EL_BIOMAZE,                                -1,
@@ -800,16 +818,81 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     &li.num_ball_contents,             4, MAX_ELEMENT_CONTENTS
   },
 
-  /* ---------- unused values ----------------------------------------------- */
+  {
+    EL_SOKOBAN_FIELD_EMPTY,            -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.sb_fields_needed,              TRUE
+  },
+
+  {
+    EL_SOKOBAN_OBJECT,                 -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.sb_objects_needed,             TRUE
+  },
 
   {
-    EL_UNKNOWN,                                SAVE_CONF_NEVER,
+    EL_MM_MCDUFFIN,                    -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.mm_laser_red,                  FALSE
+  },
+  {
+    EL_MM_MCDUFFIN,                    -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.mm_laser_green,                        FALSE
+  },
+  {
+    EL_MM_MCDUFFIN,                    -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(3),
+    &li.mm_laser_blue,                 TRUE
+  },
+
+  {
+    EL_DF_LASER,                       -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.df_laser_red,                  TRUE
+  },
+  {
+    EL_DF_LASER,                       -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.df_laser_green,                        TRUE
+  },
+  {
+    EL_DF_LASER,                       -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(3),
+    &li.df_laser_blue,                 FALSE
+  },
+
+  {
+    EL_MM_FUSE_ACTIVE,                 -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
+    &li.mm_time_fuse,                  25
+  },
+  {
+    EL_MM_BOMB,                                -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
+    &li.mm_time_bomb,                  75
+  },
+  {
+    EL_MM_GRAY_BALL,                   -1,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
-    &li.score[SC_UNKNOWN_14],          10
+    &li.mm_time_ball,                  75
   },
+  {
+    EL_MM_STEEL_BLOCK,                 -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
+    &li.mm_time_block,                 75
+  },
+  {
+    EL_MM_LIGHTBALL,                   -1,
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
+    &li.score[SC_ELEM_BONUS],          10
+  },
+
+  // ---------- unused values -------------------------------------------------
+
   {
     EL_UNKNOWN,                                SAVE_CONF_NEVER,
-    TYPE_INTEGER,                      CONF_VALUE_16_BIT(2),
+    TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
     &li.score[SC_UNKNOWN_15],          10
   },
 
@@ -877,7 +960,7 @@ static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
     &yy_ei.properties[EP_BITFIELD_BASE_NR]
   },
 #if ENABLE_RESERVED_CODE
-  /* (reserved for later use) */
+  // (reserved for later use)
   {
     -1,                                        -1,
     TYPE_BITFIELD,                     CONF_VALUE_32_BIT(2),
@@ -1047,7 +1130,7 @@ static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
     &xx_num_contents,                  1, 1
   },
 
-  /* ---------- "num_change_pages" must be the last entry ------------------- */
+  // ---------- "num_change_pages" must be the last entry ---------------------
 
   {
     -1,                                        SAVE_CONF_ALWAYS,
@@ -1066,7 +1149,7 @@ static struct LevelFileConfigInfo chunk_config_CUSX_base[] =
 
 static struct LevelFileConfigInfo chunk_config_CUSX_change[] =
 {
-  /* ---------- "current_change_page" must be the first entry --------------- */
+  // ---------- "current_change_page" must be the first entry -----------------
 
   {
     -1,                                        SAVE_CONF_ALWAYS,
@@ -1074,7 +1157,7 @@ static struct LevelFileConfigInfo chunk_config_CUSX_change[] =
     &xx_current_change_page,           -1
   },
 
-  /* ---------- (the remaining entries can be in any order) ----------------- */
+  // ---------- (the remaining entries can be in any order) -------------------
 
   {
     -1,                                        -1,
@@ -1250,7 +1333,7 @@ static struct LevelFileConfigInfo chunk_config_GRPX[] =
   }
 };
 
-static struct LevelFileConfigInfo chunk_config_CONF[] =                /* (OBSOLETE) */
+static struct LevelFileConfigInfo chunk_config_CONF[] =                // (OBSOLETE)
 {
   {
     EL_PLAYER_1,                       -1,
@@ -1325,9 +1408,9 @@ filetype_id_list[] =
 };
 
 
-/* ========================================================================= */
-/* level file functions                                                      */
-/* ========================================================================= */
+// ============================================================================
+// level file functions
+// ============================================================================
 
 static boolean check_special_flags(char *flag)
 {
@@ -1338,7 +1421,7 @@ static boolean check_special_flags(char *flag)
   return FALSE;
 }
 
-static struct DateInfo getCurrentDate()
+static struct DateInfo getCurrentDate(void)
 {
   time_t epoch_seconds = time(NULL);
   struct tm *now = localtime(&epoch_seconds);
@@ -1361,7 +1444,7 @@ static void resetEventFlags(struct ElementChangeInfo *change)
     change->has_event[i] = FALSE;
 }
 
-static void resetEventBits()
+static void resetEventBits(void)
 {
   int i;
 
@@ -1405,11 +1488,11 @@ static char *getDefaultElementDescription(struct ElementInfo *ei)
                               ei->editor_description);
   int i;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   for (i = 0; i < MAX_ELEMENT_NAME_LEN + 1; i++)
     description[i] = '\0';
 
-  /* truncate element description to MAX_ELEMENT_NAME_LEN bytes */
+  // truncate element description to MAX_ELEMENT_NAME_LEN bytes
   strncpy(description, default_description, MAX_ELEMENT_NAME_LEN);
 
   return &description[0];
@@ -1468,7 +1551,7 @@ static void setConfigToDefaultsFromConfigList(struct LevelFileConfigInfo *conf)
              content[c].e[x][y] = default_value;
       }
     }
-    else       /* constant size configuration data (1, 2 or 4 bytes) */
+    else       // constant size configuration data (1, 2 or 4 bytes)
     {
       if (data_type == TYPE_BOOLEAN)
        *(boolean *)(conf[i].value) = default_value;
@@ -1520,7 +1603,7 @@ static void copyConfigFromConfigList(struct LevelFileConfigInfo *conf)
              content_copy[c].e[x][y] = content[c].e[x][y];
       }
     }
-    else       /* constant size configuration data (1, 2 or 4 bytes) */
+    else       // constant size configuration data (1, 2 or 4 bytes)
     {
       if (data_type == TYPE_BOOLEAN)
        *(boolean *)(conf[i].value_copy) = *(boolean *)(conf[i].value);
@@ -1534,15 +1617,15 @@ void copyElementInfo(struct ElementInfo *ei_from, struct ElementInfo *ei_to)
 {
   int i;
 
-  xx_ei = *ei_from;    /* copy element data into temporary buffer */
-  yy_ei = *ei_to;      /* copy element data into temporary buffer */
+  xx_ei = *ei_from;    // copy element data into temporary buffer
+  yy_ei = *ei_to;      // copy element data into temporary buffer
 
   copyConfigFromConfigList(chunk_config_CUSX_base);
 
   *ei_from = xx_ei;
   *ei_to   = yy_ei;
 
-  /* ---------- reinitialize and copy change pages ---------- */
+  // ---------- reinitialize and copy change pages ----------
 
   ei_to->num_change_pages = ei_from->num_change_pages;
   ei_to->current_change_page = ei_from->current_change_page;
@@ -1552,11 +1635,11 @@ void copyElementInfo(struct ElementInfo *ei_from, struct ElementInfo *ei_to)
   for (i = 0; i < ei_to->num_change_pages; i++)
     ei_to->change_page[i] = ei_from->change_page[i];
 
-  /* ---------- copy group element info ---------- */
-  if (ei_from->group != NULL && ei_to->group != NULL)  /* group or internal */
+  // ---------- copy group element info ----------
+  if (ei_from->group != NULL && ei_to->group != NULL)  // group or internal
     *ei_to->group = *ei_from->group;
 
-  /* mark this custom element as modified */
+  // mark this custom element as modified
   ei_to->modified_settings = TRUE;
 }
 
@@ -1577,7 +1660,7 @@ void setElementChangePages(struct ElementInfo *ei, int change_pages)
 
 void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
 {
-  xx_change = *change;         /* copy change data into temporary buffer */
+  xx_change = *change;         // copy change data into temporary buffer
 
   setConfigToDefaultsFromConfigList(chunk_config_CUSX_change);
 
@@ -1597,12 +1680,13 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level)
 {
   int i, x, y;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
   setConfigToDefaultsFromConfigList(chunk_config_INFO);
-  *level = li;         /* copy temporary buffer back to level data */
+  *level = li;         // copy temporary buffer back to level data
 
   setLevelInfoToDefaults_EM();
   setLevelInfoToDefaults_SP();
+  setLevelInfoToDefaults_MM();
 
   level->native_em_level = &native_em_level;
   level->native_sp_level = &native_sp_level;
@@ -1617,17 +1701,17 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level)
   level->encoding_16bit_yamyam = TRUE;
   level->encoding_16bit_amoeba = TRUE;
 
-  /* clear level name and level author string buffers */
+  // clear level name and level author string buffers
   for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
     level->name[i] = '\0';
   for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++)
     level->author[i] = '\0';
 
-  /* set level name and level author to default values */
+  // set level name and level author to default values
   strcpy(level->name, NAMELESS_LEVEL_NAME);
   strcpy(level->author, ANONYMOUS_NAME);
 
-  /* set level playfield to playable default level with player and exit */
+  // set level playfield to playable default level with player and exit
   for (x = 0; x < MAX_LEV_FIELDX; x++)
     for (y = 0; y < MAX_LEV_FIELDY; y++)
       level->field[x][y] = EL_SAND;
@@ -1637,12 +1721,15 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level)
 
   BorderElement = EL_STEELWALL;
 
-  /* set all bug compatibility flags to "false" => do not emulate this bug */
+  // detect custom elements when loading them
+  level->file_has_custom_elements = FALSE;
+
+  // set all bug compatibility flags to "false" => do not emulate this bug
   level->use_action_after_change_bug = FALSE;
 
   if (leveldir_current)
   {
-    /* try to determine better author name than 'anonymous' */
+    // try to determine better author name than 'anonymous'
     if (!strEqual(leveldir_current->author, ANONYMOUS_NAME))
     {
       strncpy(level->author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN);
@@ -1667,7 +1754,7 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level)
          break;
 
         default:
-         /* keep default value */
+         // keep default value
          break;
       }
     }
@@ -1681,17 +1768,17 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
 
   InitElementPropertiesStatic();
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
   setConfigToDefaultsFromConfigList(chunk_config_ELEM);
-  *level = li;         /* copy temporary buffer back to level data */
+  *level = li;         // copy temporary buffer back to level data
 
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     int element = i;
     struct ElementInfo *ei = &element_info[element];
 
-    /* never initialize clipboard elements after the very first time */
-    /* (to be able to use clipboard elements between several levels) */
+    // never initialize clipboard elements after the very first time
+    // (to be able to use clipboard elements between several levels)
     if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized)
       continue;
 
@@ -1708,7 +1795,7 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
        IS_GROUP_ELEMENT(element) ||
        IS_INTERNAL_ELEMENT(element))
     {
-      xx_ei = *ei;     /* copy element data into temporary buffer */
+      xx_ei = *ei;     // copy element data into temporary buffer
 
       setConfigToDefaultsFromConfigList(chunk_config_CUSX_base);
 
@@ -1730,7 +1817,7 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
     if (IS_CUSTOM_ELEMENT(element) ||
        IS_INTERNAL_ELEMENT(element))
     {
-      /* internal values used in level editor */
+      // internal values used in level editor
 
       ei->access_type = 0;
       ei->access_layer = 0;
@@ -1751,13 +1838,13 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
     {
       struct ElementGroupInfo *group;
 
-      /* initialize memory for list of elements in group */
+      // initialize memory for list of elements in group
       if (ei->group == NULL)
        ei->group = checked_malloc(sizeof(struct ElementGroupInfo));
 
       group = ei->group;
 
-      xx_group = *group;       /* copy group data into temporary buffer */
+      xx_group = *group;       // copy group data into temporary buffer
 
       setConfigToDefaultsFromConfigList(chunk_config_GRPX);
 
@@ -1791,19 +1878,20 @@ static void setFileInfoToDefaults(struct LevelFileInfo *level_file_info)
   level_file_info->nr = 0;
   level_file_info->type = LEVEL_FILE_TYPE_UNKNOWN;
   level_file_info->packed = FALSE;
-  level_file_info->basename = NULL;
-  level_file_info->filename = NULL;
+
+  setString(&level_file_info->basename, NULL);
+  setString(&level_file_info->filename, NULL);
 }
 
 int getMappedElement_SB(int, boolean);
 
-static void ActivateLevelTemplate()
+static void ActivateLevelTemplate(void)
 {
   int x, y;
 
   if (check_special_flags("load_xsb_to_ces"))
   {
-    /* fill smaller playfields with padding "beyond border wall" elements */
+    // fill smaller playfields with padding "beyond border wall" elements
     if (level.fieldx < level_template.fieldx ||
        level.fieldy < level_template.fieldy)
     {
@@ -1813,15 +1901,15 @@ static void ActivateLevelTemplate()
       int pos_fieldx = (new_fieldx - level.fieldx) / 2;
       int pos_fieldy = (new_fieldy - level.fieldy) / 2;
 
-      /* copy old playfield (which is smaller than the visible area) */
+      // copy old playfield (which is smaller than the visible area)
       for (y = 0; y < level.fieldy; y++) for (x = 0; x < level.fieldx; x++)
        field[x][y] = level.field[x][y];
 
-      /* fill new, larger playfield with "beyond border wall" elements */
+      // fill new, larger playfield with "beyond border wall" elements
       for (y = 0; y < new_fieldy; y++) for (x = 0; x < new_fieldx; x++)
        level.field[x][y] = getMappedElement_SB('_', TRUE);
 
-      /* copy the old playfield to the middle of the new playfield */
+      // copy the old playfield to the middle of the new playfield
       for (y = 0; y < level.fieldy; y++) for (x = 0; x < level.fieldx; x++)
        level.field[pos_fieldx + x][pos_fieldy + y] = field[x][y];
 
@@ -1830,13 +1918,13 @@ static void ActivateLevelTemplate()
     }
   }
 
-  /* Currently there is no special action needed to activate the template
-     data, because 'element_info' property settings overwrite the original
-     level data, while all other variables do not change. */
+  // Currently there is no special action needed to activate the template
+  // data, because 'element_info' property settings overwrite the original
+  // level data, while all other variables do not change.
 
-  /* Exception: 'from_level_template' elements in the original level playfield
-     are overwritten with the corresponding elements at the same position in
-     playfield from the level template. */
+  // Exception: 'from_level_template' elements in the original level playfield
+  // are overwritten with the corresponding elements at the same position in
+  // playfield from the level template.
 
   for (x = 0; x < level.fieldx; x++)
     for (y = 0; y < level.fieldy; y++)
@@ -1847,70 +1935,72 @@ static void ActivateLevelTemplate()
   {
     struct LevelInfo level_backup = level;
 
-    /* overwrite all individual level settings from template level settings */
+    // overwrite all individual level settings from template level settings
     level = level_template;
 
-    /* restore playfield size */
+    // restore level file info
+    level.file_info = level_backup.file_info;
+
+    // restore playfield size
     level.fieldx = level_backup.fieldx;
     level.fieldy = level_backup.fieldy;
 
-    /* restore playfield content */
+    // restore playfield content
     for (x = 0; x < level.fieldx; x++)
       for (y = 0; y < level.fieldy; y++)
        level.field[x][y] = level_backup.field[x][y];
 
-    /* restore name and author from individual level */
+    // restore name and author from individual level
     strcpy(level.name,   level_backup.name);
     strcpy(level.author, level_backup.author);
 
-    /* restore flag "use_custom_template" */
+    // restore flag "use_custom_template"
     level.use_custom_template = level_backup.use_custom_template;
   }
 }
 
 static char *getLevelFilenameFromBasename(char *basename)
 {
-  static char *filename[2] = { NULL, NULL };
-  int pos = (strEqual(basename, LEVELTEMPLATE_FILENAME) ? 0 : 1);
+  static char *filename = NULL;
 
-  checked_free(filename[pos]);
+  checked_free(filename);
 
-  filename[pos] = getPath2(getCurrentLevelDir(), basename);
+  filename = getPath2(getCurrentLevelDir(), basename);
 
-  return filename[pos];
+  return filename;
 }
 
 static int getFileTypeFromBasename(char *basename)
 {
-  /* !!! ALSO SEE COMMENT IN checkForPackageFromBasename() !!! */
+  // !!! ALSO SEE COMMENT IN checkForPackageFromBasename() !!!
 
   static char *filename = NULL;
   struct stat file_status;
 
-  /* ---------- try to determine file type from filename ---------- */
+  // ---------- try to determine file type from filename ----------
 
-  /* check for typical filename of a Supaplex level package file */
+  // check for typical filename of a Supaplex level package file
   if (strlen(basename) == 10 && strPrefixLower(basename, "levels.d"))
     return LEVEL_FILE_TYPE_SP;
 
-  /* check for typical filename of a Diamond Caves II level package file */
+  // check for typical filename of a Diamond Caves II level package file
   if (strSuffixLower(basename, ".dc") ||
       strSuffixLower(basename, ".dc2"))
     return LEVEL_FILE_TYPE_DC;
 
-  /* check for typical filename of a Sokoban level package file */
+  // check for typical filename of a Sokoban level package file
   if (strSuffixLower(basename, ".xsb") &&
       strchr(basename, '%') == NULL)
     return LEVEL_FILE_TYPE_SB;
 
-  /* ---------- try to determine file type from filesize ---------- */
+  // ---------- try to determine file type from filesize ----------
 
   checked_free(filename);
   filename = getPath2(getCurrentLevelDir(), basename);
 
   if (stat(filename, &file_status) == 0)
   {
-    /* check for typical filesize of a Supaplex level package file */
+    // check for typical filesize of a Supaplex level package file
     if (file_status.st_size == 170496)
       return LEVEL_FILE_TYPE_SP;
   }
@@ -1940,8 +2030,8 @@ static int getFileTypeFromMagicBytes(char *filename, int type)
 
 static boolean checkForPackageFromBasename(char *basename)
 {
-  /* !!! WON'T WORK ANYMORE IF getFileTypeFromBasename() ALSO DETECTS !!!
-     !!! SINGLE LEVELS (CURRENTLY ONLY DETECTS LEVEL PACKAGES         !!! */
+  // !!! WON'T WORK ANYMORE IF getFileTypeFromBasename() ALSO DETECTS !!!
+  // !!! SINGLE LEVELS (CURRENTLY ONLY DETECTS LEVEL PACKAGES         !!!
 
   return (getFileTypeFromBasename(basename) != LEVEL_FILE_TYPE_UNKNOWN);
 }
@@ -1970,7 +2060,7 @@ static char *getPackedLevelBasename(int type)
   Directory *dir;
   DirectoryEntry *dir_entry;
 
-  strcpy(basename, UNDEFINED_FILENAME);                /* default: undefined file */
+  strcpy(basename, UNDEFINED_FILENAME);                // default: undefined file
 
   if ((dir = openDirectory(directory)) == NULL)
   {
@@ -1979,12 +2069,12 @@ static char *getPackedLevelBasename(int type)
     return basename;
   }
 
-  while ((dir_entry = readDirectory(dir)) != NULL)     /* loop all entries */
+  while ((dir_entry = readDirectory(dir)) != NULL)     // loop all entries
   {
     char *entry_basename = dir_entry->basename;
     int entry_type = getFileTypeFromBasename(entry_basename);
 
-    if (entry_type != LEVEL_FILE_TYPE_UNKNOWN) /* found valid level package */
+    if (entry_type != LEVEL_FILE_TYPE_UNKNOWN) // found valid level package
     {
       if (type == LEVEL_FILE_TYPE_UNKNOWN ||
          type == entry_type)
@@ -2024,8 +2114,9 @@ static void setLevelFileInfo_SingleLevelFilename(struct LevelFileInfo *lfi,
 {
   lfi->type = type;
   lfi->packed = FALSE;
-  lfi->basename = getSingleLevelBasename(lfi->nr, lfi->type);
-  lfi->filename = getLevelFilenameFromBasename(lfi->basename);
+
+  setString(&lfi->basename, getSingleLevelBasename(lfi->nr, lfi->type));
+  setString(&lfi->filename, getLevelFilenameFromBasename(lfi->basename));
 }
 #endif
 
@@ -2041,8 +2132,9 @@ static void setLevelFileInfo_FormatLevelFilename(struct LevelFileInfo *lfi,
 
   lfi->type = type;
   lfi->packed = FALSE;
-  lfi->basename = basename;
-  lfi->filename = getLevelFilenameFromBasename(lfi->basename);
+
+  setString(&lfi->basename, basename);
+  setString(&lfi->filename, getLevelFilenameFromBasename(lfi->basename));
 }
 
 static void setLevelFileInfo_PackedLevelFilename(struct LevelFileInfo *lfi,
@@ -2050,8 +2142,9 @@ static void setLevelFileInfo_PackedLevelFilename(struct LevelFileInfo *lfi,
 {
   lfi->type = type;
   lfi->packed = TRUE;
-  lfi->basename = getPackedLevelBasename(lfi->type);
-  lfi->filename = getLevelFilenameFromBasename(lfi->basename);
+
+  setString(&lfi->basename, getPackedLevelBasename(lfi->type));
+  setString(&lfi->filename, getLevelFilenameFromBasename(lfi->basename));
 }
 
 static int getFiletypeFromID(char *filetype_id)
@@ -2083,18 +2176,18 @@ static int getFiletypeFromID(char *filetype_id)
   return filetype;
 }
 
-char *getLocalLevelTemplateFilename()
+char *getLocalLevelTemplateFilename(void)
 {
   return getDefaultLevelFilename(-1);
 }
 
-char *getGlobalLevelTemplateFilename()
+char *getGlobalLevelTemplateFilename(void)
 {
-  /* global variable "leveldir_current" must be modified in the loop below */
+  // global variable "leveldir_current" must be modified in the loop below
   LevelDirTree *leveldir_current_last = leveldir_current;
   char *filename = NULL;
 
-  /* check for template level in path from current to topmost tree node */
+  // check for template level in path from current to topmost tree node
 
   while (leveldir_current != NULL)
   {
@@ -2106,7 +2199,7 @@ char *getGlobalLevelTemplateFilename()
     leveldir_current = leveldir_current->node_parent;
   }
 
-  /* restore global variable "leveldir_current" modified in above loop */
+  // restore global variable "leveldir_current" modified in above loop
   leveldir_current = leveldir_current_last;
 
   return filename;
@@ -2116,20 +2209,20 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
 {
   int nr = lfi->nr;
 
-  /* special case: level number is negative => check for level template file */
+  // special case: level number is negative => check for level template file
   if (nr < 0)
   {
     setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
                                         getSingleLevelBasename(-1));
 
-    /* replace local level template filename with global template filename */
-    lfi->filename = getGlobalLevelTemplateFilename();
+    // replace local level template filename with global template filename
+    setString(&lfi->filename, getGlobalLevelTemplateFilename());
 
-    /* no fallback if template file not existing */
+    // no fallback if template file not existing
     return;
   }
 
-  /* special case: check for file name/pattern specified in "levelinfo.conf" */
+  // special case: check for file name/pattern specified in "levelinfo.conf"
   if (leveldir_current->level_filename != NULL)
   {
     int filetype = getFiletypeFromID(leveldir_current->level_filetype);
@@ -2146,20 +2239,20 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
   {
     int filetype = getFiletypeFromID(leveldir_current->level_filetype);
 
-    /* check for specified native level file with standard file name */
+    // check for specified native level file with standard file name
     setLevelFileInfo_FormatLevelFilename(lfi, filetype,
                                         "%03d.%s", nr, LEVELFILE_EXTENSION);
     if (fileExists(lfi->filename))
       return;
   }
 
-  /* check for native Rocks'n'Diamonds level file */
+  // check for native Rocks'n'Diamonds level file
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
                                       "%03d.%s", nr, LEVELFILE_EXTENSION);
   if (fileExists(lfi->filename))
     return;
 
-  /* check for Emerald Mine level file (V1) */
+  // check for Emerald Mine level file (V1)
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "a%c%c",
                                       'a' + (nr / 10) % 26, '0' + nr % 10);
   if (fileExists(lfi->filename))
@@ -2169,12 +2262,12 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
   if (fileExists(lfi->filename))
     return;
 
-  /* check for Emerald Mine level file (V2 to V5) */
+  // check for Emerald Mine level file (V2 to V5)
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%d", nr);
   if (fileExists(lfi->filename))
     return;
 
-  /* check for Emerald Mine level file (V6 / single mode) */
+  // check for Emerald Mine level file (V6 / single mode)
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02ds", nr);
   if (fileExists(lfi->filename))
     return;
@@ -2182,7 +2275,7 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
   if (fileExists(lfi->filename))
     return;
 
-  /* check for Emerald Mine level file (V6 / teamwork mode) */
+  // check for Emerald Mine level file (V6 / teamwork mode)
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dt", nr);
   if (fileExists(lfi->filename))
     return;
@@ -2190,12 +2283,12 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
   if (fileExists(lfi->filename))
     return;
 
-  /* check for various packed level file formats */
+  // check for various packed level file formats
   setLevelFileInfo_PackedLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN);
   if (fileExists(lfi->filename))
     return;
 
-  /* no known level file found -- use default values (and fail later) */
+  // no known level file found -- use default values (and fail later)
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
                                       "%03d.%s", nr, LEVELFILE_EXTENSION);
 }
@@ -2211,22 +2304,33 @@ static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi)
 
 static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr)
 {
-  /* always start with reliable default values */
+  // always start with reliable default values
   setFileInfoToDefaults(level_file_info);
 
-  level_file_info->nr = nr;    /* set requested level number */
+  level_file_info->nr = nr;    // set requested level number
 
   determineLevelFileInfo_Filename(level_file_info);
   determineLevelFileInfo_Filetype(level_file_info);
 }
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading R'n'D level                                         */
-/* ------------------------------------------------------------------------- */
+static void copyLevelFileInfo(struct LevelFileInfo *lfi_from,
+                             struct LevelFileInfo *lfi_to)
+{
+  lfi_to->nr     = lfi_from->nr;
+  lfi_to->type   = lfi_from->type;
+  lfi_to->packed = lfi_from->packed;
+
+  setString(&lfi_to->basename, lfi_from->basename);
+  setString(&lfi_to->filename, lfi_from->filename);
+}
+
+// ----------------------------------------------------------------------------
+// functions for loading R'n'D level
+// ----------------------------------------------------------------------------
 
-int getMappedElement(int element)
+static int getMappedElement(int element)
 {
-  /* remap some (historic, now obsolete) elements */
+  // remap some (historic, now obsolete) elements
 
   switch (element)
   {
@@ -2275,13 +2379,13 @@ int getMappedElement(int element)
   return element;
 }
 
-int getMappedElementByVersion(int element, int game_version)
+static int getMappedElementByVersion(int element, int game_version)
 {
-  /* remap some elements due to certain game version */
+  // remap some elements due to certain game version
 
   if (game_version <= VERSION_IDENT(2,2,0,0))
   {
-    /* map game font elements */
+    // map game font elements
     element = (element == EL_CHAR('[')  ? EL_CHAR_AUMLAUT :
               element == EL_CHAR('\\') ? EL_CHAR_OUMLAUT :
               element == EL_CHAR(']')  ? EL_CHAR_UUMLAUT :
@@ -2290,7 +2394,7 @@ int getMappedElementByVersion(int element, int game_version)
 
   if (game_version < VERSION_IDENT(3,0,0,0))
   {
-    /* map Supaplex gravity tube elements */
+    // map Supaplex gravity tube elements
     element = (element == EL_SP_GRAVITY_PORT_LEFT  ? EL_SP_PORT_LEFT  :
               element == EL_SP_GRAVITY_PORT_RIGHT ? EL_SP_PORT_RIGHT :
               element == EL_SP_GRAVITY_PORT_UP    ? EL_SP_PORT_UP    :
@@ -2460,7 +2564,7 @@ static int LoadLevel_CONT(File *file, int chunk_size, struct LevelInfo *level)
   getFile8Bit(file);
   getFile8Bit(file);
 
-  /* correct invalid number of content fields -- should never happen */
+  // correct invalid number of content fields -- should never happen
   if (level->num_yamyam_contents < 1 ||
       level->num_yamyam_contents > MAX_ELEMENT_CONTENTS)
     level->num_yamyam_contents = STD_ELEMENT_CONTENTS;
@@ -2484,8 +2588,8 @@ static int LoadLevel_CNT2(File *file, int chunk_size, struct LevelInfo *level)
   element = getMappedElement(getFile16BitBE(file));
   num_contents = getFile8Bit(file);
 
-  getFile8Bit(file);   /* content x size (unused) */
-  getFile8Bit(file);   /* content y size (unused) */
+  getFile8Bit(file);   // content x size (unused)
+  getFile8Bit(file);   // content y size (unused)
 
   ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT2_UNUSED);
 
@@ -2494,7 +2598,7 @@ static int LoadLevel_CNT2(File *file, int chunk_size, struct LevelInfo *level)
       for (x = 0; x < 3; x++)
        content_array[i][x][y] = getMappedElement(getFile16BitBE(file));
 
-  /* correct invalid number of content fields -- should never happen */
+  // correct invalid number of content fields -- should never happen
   if (num_contents < 1 || num_contents > MAX_ELEMENT_CONTENTS)
     num_contents = STD_ELEMENT_CONTENTS;
 
@@ -2575,12 +2679,14 @@ static int LoadLevel_CUS1(File *file, int chunk_size, struct LevelInfo *level)
     else
       Error(ERR_WARN, "invalid custom element number %d", element);
 
-    /* older game versions that wrote level files with CUS1 chunks used
-       different default push delay values (not yet stored in level file) */
+    // older game versions that wrote level files with CUS1 chunks used
+    // different default push delay values (not yet stored in level file)
     element_info[element].push_delay_fixed = 2;
     element_info[element].push_delay_random = 8;
   }
 
+  level->file_has_custom_elements = TRUE;
+
   return chunk_size;
 }
 
@@ -2607,6 +2713,8 @@ static int LoadLevel_CUS2(File *file, int chunk_size, struct LevelInfo *level)
       Error(ERR_WARN, "invalid custom element number %d", element);
   }
 
+  level->file_has_custom_elements = TRUE;
+
   return chunk_size;
 }
 
@@ -2641,7 +2749,7 @@ static int LoadLevel_CUS3(File *file, int chunk_size, struct LevelInfo *level)
 
     ei->properties[EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
 
-    /* some free bytes for future properties and padding */
+    // some free bytes for future properties and padding
     ReadUnusedBytesFromFile(file, 7);
 
     ei->use_gfx_element = getFile8Bit(file);
@@ -2691,13 +2799,15 @@ static int LoadLevel_CUS3(File *file, int chunk_size, struct LevelInfo *level)
 
     ei->slippery_type = getFile8Bit(file);
 
-    /* some free bytes for future properties and padding */
+    // some free bytes for future properties and padding
     ReadUnusedBytesFromFile(file, LEVEL_CPART_CUS3_UNUSED);
 
-    /* mark that this custom element has been modified */
+    // mark that this custom element has been modified
     ei->modified_settings = TRUE;
   }
 
+  level->file_has_custom_elements = TRUE;
+
   return chunk_size;
 }
 
@@ -2708,7 +2818,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
   int element;
   int i, j, x, y;
 
-  /* ---------- custom element base property values (96 bytes) ------------- */
+  // ---------- custom element base property values (96 bytes) ----------------
 
   element = getMappedElement(getFile16BitBE(file));
 
@@ -2728,7 +2838,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
 
   ei->properties[EP_BITFIELD_BASE_NR] = getFile32BitBE(file);
 
-  ReadUnusedBytesFromFile(file, 4);    /* reserved for more base properties */
+  ReadUnusedBytesFromFile(file, 4);    // reserved for more base properties
 
   ei->num_change_pages = getFile8Bit(file);
 
@@ -2756,7 +2866,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
   ei->move_delay_fixed = getFile16BitBE(file);
   ei->move_delay_random = getFile16BitBE(file);
 
-  /* bits 0 - 15 of "move_pattern" ... */
+  // bits 0 - 15 of "move_pattern" ...
   ei->move_pattern = getFile16BitBE(file);
   ei->move_direction_initial = getFile8Bit(file);
   ei->move_stepsize = getFile8Bit(file);
@@ -2771,7 +2881,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
   ei->move_leave_element = getMappedElement(getFile16BitBE(file));
   ei->move_leave_type = getFile8Bit(file);
 
-  /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
+  // ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible)
   ei->move_pattern |= (getFile16BitBE(file) << 16);
 
   ei->access_direction = getFile8Bit(file);
@@ -2780,10 +2890,10 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
   ei->ignition_delay = getFile8Bit(file);
   ei->explosion_type = getFile8Bit(file);
 
-  /* some free bytes for future custom property values and padding */
+  // some free bytes for future custom property values and padding
   ReadUnusedBytesFromFile(file, 1);
 
-  /* ---------- change page property values (48 bytes) --------------------- */
+  // ---------- change page property values (48 bytes) ------------------------
 
   setElementChangePages(ei, ei->num_change_pages);
 
@@ -2792,10 +2902,10 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
     struct ElementChangeInfo *change = &ei->change_page[i];
     unsigned int event_bits;
 
-    /* always start with reliable default values */
+    // always start with reliable default values
     setElementChangeInfoToDefaults(change);
 
-    /* bits 0 - 31 of "has_event[]" ... */
+    // bits 0 - 31 of "has_event[]" ...
     event_bits = getFile32BitBE(file);
     for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++)
       if (event_bits & (1 << j))
@@ -2836,16 +2946,18 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
     change->action_mode = getFile8Bit(file);
     change->action_arg = getFile16BitBE(file);
 
-    /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */
+    // ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible)
     event_bits = getFile8Bit(file);
     for (j = 32; j < NUM_CHANGE_EVENTS; j++)
       if (event_bits & (1 << (j - 32)))
        change->has_event[j] = TRUE;
   }
 
-  /* mark this custom element as modified */
+  // mark this custom element as modified
   ei->modified_settings = TRUE;
 
+  level->file_has_custom_elements = TRUE;
+
   return chunk_size;
 }
 
@@ -2881,15 +2993,17 @@ static int LoadLevel_GRP1(File *file, int chunk_size, struct LevelInfo *level)
 
   group->choice_mode = getFile8Bit(file);
 
-  /* some free bytes for future values and padding */
+  // some free bytes for future values and padding
   ReadUnusedBytesFromFile(file, 3);
 
   for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
     group->element[i] = getMappedElement(getFile16BitBE(file));
 
-  /* mark this group element as modified */
+  // mark this group element as modified
   element_info[element].modified_settings = TRUE;
 
+  level->file_has_custom_elements = TRUE;
+
   return chunk_size;
 }
 
@@ -2932,13 +3046,13 @@ static int LoadLevel_MicroChunk(File *file, struct LevelFileConfigInfo *conf,
        if (num_entities == 0 && (data_type == TYPE_ELEMENT_LIST ||
                                  data_type == TYPE_CONTENT_LIST))
        {
-         /* for element and content lists, zero entities are not allowed */
+         // for element and content lists, zero entities are not allowed
          Error(ERR_WARN, "found empty list of entities for element %d",
                element);
 
-         /* do not set "num_entities" here to prevent reading behind buffer */
+         // do not set "num_entities" here to prevent reading behind buffer
 
-         *(int *)(conf[i].num_entities) = 1;   /* at least one is required */
+         *(int *)(conf[i].num_entities) = 1;   // at least one is required
        }
        else
        {
@@ -2986,7 +3100,7 @@ static int LoadLevel_MicroChunk(File *file, struct LevelFileConfigInfo *conf,
 
     micro_chunk_size += 2 + num_bytes;
   }
-  else         /* constant size configuration data (1, 2 or 4 bytes) */
+  else         // constant size configuration data (1, 2 or 4 bytes)
   {
     int value = (byte_mask == CONF_MASK_1_BYTE ? getFile8Bit   (file) :
                 byte_mask == CONF_MASK_2_BYTE ? getFile16BitBE(file) :
@@ -3037,7 +3151,7 @@ static int LoadLevel_INFO(File *file, int chunk_size, struct LevelInfo *level)
 {
   int real_chunk_size = 0;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
 
   while (!checkEndOfFile(file))
   {
@@ -3047,7 +3161,7 @@ static int LoadLevel_INFO(File *file, int chunk_size, struct LevelInfo *level)
       break;
   }
 
-  *level = li;         /* copy temporary buffer back to level data */
+  *level = li;         // copy temporary buffer back to level data
 
   return real_chunk_size;
 }
@@ -3056,7 +3170,7 @@ static int LoadLevel_CONF(File *file, int chunk_size, struct LevelInfo *level)
 {
   int real_chunk_size = 0;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
 
   while (!checkEndOfFile(file))
   {
@@ -3069,7 +3183,7 @@ static int LoadLevel_CONF(File *file, int chunk_size, struct LevelInfo *level)
       break;
   }
 
-  *level = li;         /* copy temporary buffer back to level data */
+  *level = li;         // copy temporary buffer back to level data
 
   return real_chunk_size;
 }
@@ -3078,7 +3192,7 @@ static int LoadLevel_ELEM(File *file, int chunk_size, struct LevelInfo *level)
 {
   int real_chunk_size = 0;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
 
   while (!checkEndOfFile(file))
   {
@@ -3091,7 +3205,7 @@ static int LoadLevel_ELEM(File *file, int chunk_size, struct LevelInfo *level)
       break;
   }
 
-  *level = li;         /* copy temporary buffer back to level data */
+  *level = li;         // copy temporary buffer back to level data
 
   return real_chunk_size;
 }
@@ -3102,7 +3216,7 @@ static int LoadLevel_NOTE(File *file, int chunk_size, struct LevelInfo *level)
   int envelope_nr = element - EL_ENVELOPE_1;
   int real_chunk_size = 2;
 
-  xx_envelope = level->envelope[envelope_nr];  /* copy into temporary buffer */
+  xx_envelope = level->envelope[envelope_nr];  // copy into temporary buffer
 
   while (!checkEndOfFile(file))
   {
@@ -3113,7 +3227,7 @@ static int LoadLevel_NOTE(File *file, int chunk_size, struct LevelInfo *level)
       break;
   }
 
-  level->envelope[envelope_nr] = xx_envelope;  /* copy from temporary buffer */
+  level->envelope[envelope_nr] = xx_envelope;  // copy from temporary buffer
 
   return real_chunk_size;
 }
@@ -3125,7 +3239,7 @@ static int LoadLevel_CUSX(File *file, int chunk_size, struct LevelInfo *level)
   struct ElementInfo *ei = &element_info[element];
   int i;
 
-  xx_ei = *ei;         /* copy element data into temporary buffer */
+  xx_ei = *ei;         // copy element data into temporary buffer
 
   xx_ei.num_change_pages = -1;
 
@@ -3155,21 +3269,21 @@ static int LoadLevel_CUSX(File *file, int chunk_size, struct LevelInfo *level)
     return real_chunk_size;
   }
 
-  /* initialize number of change pages stored for this custom element */
+  // initialize number of change pages stored for this custom element
   setElementChangePages(ei, ei->num_change_pages);
   for (i = 0; i < ei->num_change_pages; i++)
     setElementChangeInfoToDefaults(&ei->change_page[i]);
 
-  /* start with reading properties for the first change page */
+  // start with reading properties for the first change page
   xx_current_change_page = 0;
 
   while (!checkEndOfFile(file))
   {
     struct ElementChangeInfo *change = &ei->change_page[xx_current_change_page];
 
-    xx_change = *change;       /* copy change data into temporary buffer */
+    xx_change = *change;       // copy change data into temporary buffer
 
-    resetEventBits();          /* reset bits; change page might have changed */
+    resetEventBits();          // reset bits; change page might have changed
 
     real_chunk_size += LoadLevel_MicroChunk(file, chunk_config_CUSX_change,
                                            -1, element);
@@ -3182,6 +3296,8 @@ static int LoadLevel_CUSX(File *file, int chunk_size, struct LevelInfo *level)
       break;
   }
 
+  level->file_has_custom_elements = TRUE;
+
   return real_chunk_size;
 }
 
@@ -3192,8 +3308,8 @@ static int LoadLevel_GRPX(File *file, int chunk_size, struct LevelInfo *level)
   struct ElementInfo *ei = &element_info[element];
   struct ElementGroupInfo *group = ei->group;
 
-  xx_ei = *ei;         /* copy element data into temporary buffer */
-  xx_group = *group;   /* copy group data into temporary buffer */
+  xx_ei = *ei;         // copy element data into temporary buffer
+  xx_group = *group;   // copy group data into temporary buffer
 
   while (!checkEndOfFile(file))
   {
@@ -3207,6 +3323,8 @@ static int LoadLevel_GRPX(File *file, int chunk_size, struct LevelInfo *level)
   *ei = xx_ei;
   *group = xx_group;
 
+  level->file_has_custom_elements = TRUE;
+
   return real_chunk_size;
 }
 
@@ -3233,13 +3351,13 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
     if (!setup.editor.use_template_for_new_levels)
       return;
 
-    /* if level file not found, try to initialize level data from template */
+    // if level file not found, try to initialize level data from template
     filename = getGlobalLevelTemplateFilename();
 
     if (!(file = openFile(filename, MODE_READ)))
       return;
 
-    /* default: for empty levels, use level template for custom elements */
+    // default: for empty levels, use level template for custom elements
     level->use_custom_template = TRUE;
 
     level->no_valid_file = FALSE;
@@ -3248,7 +3366,7 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
   getFileChunkBE(file, chunk_name, NULL);
   if (strEqual(chunk_name, "RND1"))
   {
-    getFile32BitBE(file);              /* not used */
+    getFile32BitBE(file);              // not used
 
     getFileChunkBE(file, chunk_name, NULL);
     if (!strEqual(chunk_name, "CAVE"))
@@ -3262,7 +3380,7 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
       return;
     }
   }
-  else /* check for pre-2.0 file format with cookie string */
+  else // check for pre-2.0 file format with cookie string
   {
     strcpy(cookie, chunk_name);
     if (getStringFromFile(file, &cookie[4], MAX_LINE_LEN - 4) == NULL)
@@ -3292,13 +3410,13 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
       return;
     }
 
-    /* pre-2.0 level files have no game version, so use file version here */
+    // pre-2.0 level files have no game version, so use file version here
     level->game_version = level->file_version;
   }
 
   if (level->file_version < FILE_VERSION_1_2)
   {
-    /* level files from versions before 1.2.0 without chunk structure */
+    // level files from versions before 1.2.0 without chunk structure
     LoadLevel_HEAD(file, LEVEL_CHUNK_HEAD_SIZE,         level);
     LoadLevel_BODY(file, level->fieldx * level->fieldy, level);
   }
@@ -3359,13 +3477,13 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
       }
       else
       {
-       /* call function to load this level chunk */
+       // call function to load this level chunk
        int chunk_size_expected =
          (chunk_info[i].loader)(file, chunk_size, level);
 
-       /* the size of some chunks cannot be checked before reading other
-          chunks first (like "HEAD" and "BODY") that contain some header
-          information, so check them here */
+       // the size of some chunks cannot be checked before reading other
+       // chunks first (like "HEAD" and "BODY") that contain some header
+       // information, so check them here
        if (chunk_size_expected != chunk_size)
        {
          Error(ERR_WARN, "wrong size (%d) of chunk '%s' in level file '%s'",
@@ -3379,11 +3497,11 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level,
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading EM level                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading EM level
+// ----------------------------------------------------------------------------
 
-void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
+static void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
 {
   static int ball_xy[8][2] =
   {
@@ -3455,7 +3573,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
 
   map_android_clone_elements_RND_to_EM(level);
 
-  /* first fill the complete playfield with the default border element */
+  // first fill the complete playfield with the default border element
   for (y = 0; y < EM_MAX_CAVE_HEIGHT; y++)
     for (x = 0; x < EM_MAX_CAVE_WIDTH; x++)
       level_em->cave[x][y] = ZBORDER;
@@ -3467,7 +3585,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
        level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_STEELWALL);
   }
 
-  /* then copy the real level contents from level file into the playfield */
+  // then copy the real level contents from level file into the playfield
   for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++)
   {
     int new_element = map_element_RND_to_EM(level->field[x][y]);
@@ -3487,7 +3605,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
     ply[i]->y_initial = 0;
   }
 
-  /* initialize player positions and delete players from the playfield */
+  // initialize player positions and delete players from the playfield
   for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++)
   {
     if (ELEM_IS_PLAYER(level->field[x][y]))
@@ -3511,7 +3629,7 @@ void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
   }
 }
 
-void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
+static void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
 {
   static int ball_xy[8][2] =
   {
@@ -3584,7 +3702,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
 
   map_android_clone_elements_EM_to_RND(level);
 
-  /* convert the playfield (some elements need special treatment) */
+  // convert the playfield (some elements need special treatment)
   for (y = 0; y < level->fieldy; y++) for (x = 0; x < level->fieldx; x++)
   {
     int new_element = map_element_EM_to_RND(level_em->cave[x + 1][y + 1]);
@@ -3597,7 +3715,7 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
 
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    /* in case of all players set to the same field, use the first player */
+    // in case of all players set to the same field, use the first player
     int nr = MAX_PLAYERS - i - 1;
     int jx = ply[nr]->x_initial - 1;
     int jy = ply[nr]->y_initial - 1;
@@ -3608,11 +3726,11 @@ void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading SP level                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading SP level
+// ----------------------------------------------------------------------------
 
-void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
+static void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
 {
   struct LevelInfo_SP *level_sp = level->native_sp_level;
   LevelInfoType *header = &level_sp->header;
@@ -3629,7 +3747,7 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
 
   for (i = 0; i < SP_LEVEL_NAME_LEN; i++)
     header->LevelTitle[i] = level->name[i];
-  /* !!! NO STRING TERMINATION IN SUPAPLEX VB CODE YET -- FIX THIS !!! */
+  // !!! NO STRING TERMINATION IN SUPAPLEX VB CODE YET -- FIX THIS !!!
 
   header->InfotronsNeeded = level->gems_needed;
 
@@ -3662,8 +3780,8 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
     else if (element >= EL_SP_GRAVITY_PORT_RIGHT &&
             element <= EL_SP_GRAVITY_PORT_UP)
     {
-      /* change R'n'D style gravity inverting special port to normal port
-        (there are no gravity inverting ports in native Supaplex engine) */
+      // change R'n'D style gravity inverting special port to normal port
+      // (there are no gravity inverting ports in native Supaplex engine)
 
       gravity_port_found = TRUE;
       gravity_port_valid = FALSE;
@@ -3686,7 +3804,7 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
       }
       else
       {
-       /* change special gravity port to normal port */
+       // change special gravity port to normal port
 
        element += EL_SP_PORT_RIGHT - gravity_port_base_element;
       }
@@ -3696,7 +3814,7 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
   }
 }
 
-void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
+static void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
 {
   struct LevelInfo_SP *level_sp = level->native_sp_level;
   LevelInfoType *header = &level_sp->header;
@@ -3733,17 +3851,17 @@ void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
     level->initial_player_gravity[i] =
       (header->InitialGravity == 1 ? TRUE : FALSE);
 
-  /* skip leading spaces */
+  // skip leading spaces
   for (i = 0; i < SP_LEVEL_NAME_LEN; i++)
     if (header->LevelTitle[i] != ' ')
       break;
 
-  /* copy level title */
+  // copy level title
   for (j = 0; i < SP_LEVEL_NAME_LEN; i++, j++)
     level->name[j] = header->LevelTitle[i];
   level->name[j] = '\0';
 
-  /* cut trailing spaces */
+  // cut trailing spaces
   for (; j > 0; j--)
     if (level->name[j - 1] == ' ' && level->name[j] == '\0')
       level->name[j - 1] = '\0';
@@ -3779,34 +3897,34 @@ void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
       continue;
     }
 
-    /* change previous (wrong) gravity inverting special port to either
-       gravity enabling special port or gravity disabling special port */
+    // change previous (wrong) gravity inverting special port to either
+    // gravity enabling special port or gravity disabling special port
     level->field[port_x][port_y] +=
       (gravity == 1 ? EL_SP_GRAVITY_ON_PORT_RIGHT :
        EL_SP_GRAVITY_OFF_PORT_RIGHT) - EL_SP_GRAVITY_PORT_RIGHT;
   }
 
-  /* change special gravity ports without database entries to normal ports */
+  // change special gravity ports without database entries to normal ports
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
       if (level->field[x][y] >= EL_SP_GRAVITY_PORT_RIGHT &&
          level->field[x][y] <= EL_SP_GRAVITY_PORT_UP)
        level->field[x][y] += EL_SP_PORT_RIGHT - EL_SP_GRAVITY_PORT_RIGHT;
 
-  level->time = 0;                     /* no time limit */
+  level->time = 0;                     // no time limit
   level->amoeba_speed = 0;
   level->time_magic_wall = 0;
   level->time_wheel = 0;
   level->amoeba_content = EL_EMPTY;
 
 #if 1
-  /* original Supaplex does not use score values -- use default values */
+  // original Supaplex does not use score values -- use default values
 #else
   for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
     level->score[i] = 0;
 #endif
 
-  /* there are no yamyams in supaplex levels */
+  // there are no yamyams in supaplex levels
   for (i = 0; i < level->num_yamyam_contents; i++)
     for (x = 0; x < 3; x++)
       for (y = 0; y < 3; y++)
@@ -3819,14 +3937,14 @@ static void CopyNativeTape_RND_to_SP(struct LevelInfo *level)
   struct DemoInfo_SP *demo = &level_sp->demo;
   int i, j;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   demo->is_available = FALSE;
   demo->length = 0;
 
   if (TAPE_IS_EMPTY(tape))
     return;
 
-  demo->level_nr = tape.level_nr;      /* (currently not used) */
+  demo->level_nr = tape.level_nr;      // (currently not used)
 
   level_sp->header.DemoRandomSeed = tape.random_seed;
 
@@ -3856,7 +3974,7 @@ static void CopyNativeTape_RND_to_SP(struct LevelInfo *level)
   demo->is_available = TRUE;
 }
 
-static void setTapeInfoToDefaults();
+static void setTapeInfoToDefaults(void);
 
 static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
 {
@@ -3865,13 +3983,13 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
   char *filename = level->file_info.filename;
   int i;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   setTapeInfoToDefaults();
 
   if (!demo->is_available)
     return;
 
-  tape.level_nr = demo->level_nr;      /* (currently not used) */
+  tape.level_nr = demo->level_nr;      // (currently not used)
   tape.random_seed = level_sp->header.DemoRandomSeed;
 
   TapeSetDateFromEpochSeconds(getFileTimestampEpochSeconds(filename));
@@ -3905,38 +4023,40 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading MM level                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading MM level
+// ----------------------------------------------------------------------------
 
-void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
+static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
 {
   struct LevelInfo_MM *level_mm = level->native_mm_level;
   int x, y;
 
-  level_mm->file_version = level->file_version;
-  level_mm->game_version = level->game_version;
-  level_mm->encoding_16bit_field = level->encoding_16bit_field;
-
   level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH);
   level_mm->fieldy = MIN(level->fieldy, MM_MAX_PLAYFIELD_HEIGHT);
 
   level_mm->time = level->time;
   level_mm->kettles_needed = level->gems_needed;
-  level_mm->auto_count_kettles = FALSE;
-  level_mm->laser_red = FALSE;
-  level_mm->laser_green = FALSE;
-  level_mm->laser_blue = TRUE;
+  level_mm->auto_count_kettles = level->auto_count_gems;
+
+  level_mm->laser_red = level->mm_laser_red;
+  level_mm->laser_green = level->mm_laser_green;
+  level_mm->laser_blue = level->mm_laser_blue;
 
   strcpy(level_mm->name, level->name);
   strcpy(level_mm->author, level->author);
 
+  level_mm->score[SC_EMERALD]    = level->score[SC_EMERALD];
   level_mm->score[SC_PACMAN]     = level->score[SC_PACMAN];
-  level_mm->score[SC_KEY]        = level->score[SC_PACMAN];
+  level_mm->score[SC_KEY]        = level->score[SC_KEY];
   level_mm->score[SC_TIME_BONUS] = level->score[SC_TIME_BONUS];
+  level_mm->score[SC_ELEM_BONUS] = level->score[SC_ELEM_BONUS];
 
   level_mm->amoeba_speed = level->amoeba_speed;
-  level_mm->time_fuse = 0;
+  level_mm->time_fuse    = level->mm_time_fuse;
+  level_mm->time_bomb    = level->mm_time_bomb;
+  level_mm->time_ball    = level->mm_time_ball;
+  level_mm->time_block   = level->mm_time_block;
 
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
@@ -3944,57 +4064,54 @@ void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
        level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]);
 }
 
-void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
+static void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
 {
   struct LevelInfo_MM *level_mm = level->native_mm_level;
   int x, y;
 
-  level->file_version = level_mm->file_version;
-  level->game_version = level_mm->game_version;
-  level->encoding_16bit_field = level_mm->encoding_16bit_field;
-
   level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX);
   level->fieldy = MIN(level_mm->fieldy, MAX_LEV_FIELDY);
 
   level->time = level_mm->time;
   level->gems_needed = level_mm->kettles_needed;
+  level->auto_count_gems = level_mm->auto_count_kettles;
+
+  level->mm_laser_red = level_mm->laser_red;
+  level->mm_laser_green = level_mm->laser_green;
+  level->mm_laser_blue = level_mm->laser_blue;
 
   strcpy(level->name, level_mm->name);
 
-  /* only overwrite author from 'levelinfo.conf' if author defined in level */
+  // only overwrite author from 'levelinfo.conf' if author defined in level
   if (!strEqual(level_mm->author, ANONYMOUS_NAME))
     strcpy(level->author, level_mm->author);
 
+  level->score[SC_EMERALD]    = level_mm->score[SC_EMERALD];
   level->score[SC_PACMAN]     = level_mm->score[SC_PACMAN];
-  level->score[SC_KEY]        = level_mm->score[SC_PACMAN];
+  level->score[SC_KEY]        = level_mm->score[SC_KEY];
   level->score[SC_TIME_BONUS] = level_mm->score[SC_TIME_BONUS];
+  level->score[SC_ELEM_BONUS] = level_mm->score[SC_ELEM_BONUS];
 
-  level->amoeba_speed = level_mm->amoeba_speed;
+  level->amoeba_speed  = level_mm->amoeba_speed;
+  level->mm_time_fuse  = level_mm->time_fuse;
+  level->mm_time_bomb  = level_mm->time_bomb;
+  level->mm_time_ball  = level_mm->time_ball;
+  level->mm_time_block = level_mm->time_block;
 
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
       level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]);
-
-  if (level_mm->auto_count_kettles)
-  {
-    level->gems_needed = 0;
-
-    for (x = 0; x < level->fieldx; x++)
-      for (y = 0; y < level->fieldy; y++)
-       if (level->field[x][y] == EL_MM_KETTLE ||
-           level->field[x][y] == EL_DF_CELL)
-         level->gems_needed++;
-  }
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading DC level                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading DC level
+// ----------------------------------------------------------------------------
 
 #define DC_LEVEL_HEADER_SIZE           344
 
-unsigned short getDecodedWord_DC(unsigned short data_encoded, boolean init)
+static unsigned short getDecodedWord_DC(unsigned short data_encoded,
+                                       boolean init)
 {
   static int last_data_encoded;
   static int offset1;
@@ -4033,7 +4150,7 @@ unsigned short getDecodedWord_DC(unsigned short data_encoded, boolean init)
   return data_decoded;
 }
 
-int getMappedElement_DC(int element)
+static int getMappedElement_DC(int element)
 {
   switch (element)
   {
@@ -4041,11 +4158,11 @@ int getMappedElement_DC(int element)
       element = EL_ROCK;
       break;
 
-      /* 0x0117 - 0x036e: (?) */
-      /* EL_DIAMOND */
+      // 0x0117 - 0x036e: (?)
+      // EL_DIAMOND
 
-      /* 0x042d - 0x0684: (?) */
-      /* EL_EMERALD */
+      // 0x042d - 0x0684: (?)
+      // EL_EMERALD
 
     case 0x06f1:
       element = EL_NUT;
@@ -4063,11 +4180,11 @@ int getMappedElement_DC(int element)
       element = EL_CRYSTAL;
       break;
 
-    case 0x0e77:       /* quicksand (boulder) */
+    case 0x0e77:       // quicksand (boulder)
       element = EL_QUICKSAND_FAST_FULL;
       break;
 
-    case 0x0e99:       /* slow quicksand (boulder) */
+    case 0x0e99:       // slow quicksand (boulder)
       element = EL_QUICKSAND_FULL;
       break;
 
@@ -4087,19 +4204,19 @@ int getMappedElement_DC(int element)
       element = EL_EM_STEEL_EXIT_CLOSED;
       break;
 
-    case 0x0f4f:       /* dynamite (lit 1) */
+    case 0x0f4f:       // dynamite (lit 1)
       element = EL_EM_DYNAMITE_ACTIVE;
       break;
 
-    case 0x0f57:       /* dynamite (lit 2) */
+    case 0x0f57:       // dynamite (lit 2)
       element = EL_EM_DYNAMITE_ACTIVE;
       break;
 
-    case 0x0f5f:       /* dynamite (lit 3) */
+    case 0x0f5f:       // dynamite (lit 3)
       element = EL_EM_DYNAMITE_ACTIVE;
       break;
 
-    case 0x0f67:       /* dynamite (lit 4) */
+    case 0x0f67:       // dynamite (lit 4)
       element = EL_EM_DYNAMITE_ACTIVE;
       break;
 
@@ -4190,15 +4307,15 @@ int getMappedElement_DC(int element)
       element = EL_TIMEGATE_CLOSED;
       break;
 
-    case 0x144c:       /* conveyor belt switch (green) */
+    case 0x144c:       // conveyor belt switch (green)
       element = EL_CONVEYOR_BELT_3_SWITCH_MIDDLE;
       break;
 
-    case 0x144f:       /* conveyor belt switch (red) */
+    case 0x144f:       // conveyor belt switch (red)
       element = EL_CONVEYOR_BELT_1_SWITCH_MIDDLE;
       break;
 
-    case 0x1452:       /* conveyor belt switch (blue) */
+    case 0x1452:       // conveyor belt switch (blue)
       element = EL_CONVEYOR_BELT_4_SWITCH_MIDDLE;
       break;
 
@@ -4250,15 +4367,15 @@ int getMappedElement_DC(int element)
       element = EL_EXPANDABLE_WALL_ANY;
       break;
 
-    case 0x14ce:       /* growing steel wall (left/right) */
+    case 0x14ce:       // growing steel wall (left/right)
       element = EL_EXPANDABLE_STEELWALL_HORIZONTAL;
       break;
 
-    case 0x14df:       /* growing steel wall (up/down) */
+    case 0x14df:       // growing steel wall (up/down)
       element = EL_EXPANDABLE_STEELWALL_VERTICAL;
       break;
 
-    case 0x14e8:       /* growing steel wall (up/down/left/right) */
+    case 0x14e8:       // growing steel wall (up/down/left/right)
       element = EL_EXPANDABLE_STEELWALL_ANY;
       break;
 
@@ -4278,41 +4395,41 @@ int getMappedElement_DC(int element)
       element = EL_EMPTY_SPACE;
       break;
 
-    case 0x1578:       /* quicksand (empty) */
+    case 0x1578:       // quicksand (empty)
       element = EL_QUICKSAND_FAST_EMPTY;
       break;
 
-    case 0x1579:       /* slow quicksand (empty) */
+    case 0x1579:       // slow quicksand (empty)
       element = EL_QUICKSAND_EMPTY;
       break;
 
-      /* 0x157c - 0x158b: */
-      /* EL_SAND */
+      // 0x157c - 0x158b:
+      // EL_SAND
 
-      /* 0x1590 - 0x159f: */
-      /* EL_DC_LANDMINE */
+      // 0x1590 - 0x159f:
+      // EL_DC_LANDMINE
 
     case 0x15a0:
       element = EL_EM_DYNAMITE;
       break;
 
-    case 0x15a1:       /* key (red) */
+    case 0x15a1:       // key (red)
       element = EL_EM_KEY_1;
       break;
 
-    case 0x15a2:       /* key (yellow) */
+    case 0x15a2:       // key (yellow)
       element = EL_EM_KEY_2;
       break;
 
-    case 0x15a3:       /* key (blue) */
+    case 0x15a3:       // key (blue)
       element = EL_EM_KEY_4;
       break;
 
-    case 0x15a4:       /* key (green) */
+    case 0x15a4:       // key (green)
       element = EL_EM_KEY_3;
       break;
 
-    case 0x15a5:       /* key (white) */
+    case 0x15a5:       // key (white)
       element = EL_DC_KEY_WHITE;
       break;
 
@@ -4324,915 +4441,915 @@ int getMappedElement_DC(int element)
       element = EL_WALL;
       break;
 
-    case 0x15a8:       /* wall (not round) */
+    case 0x15a8:       // wall (not round)
       element = EL_WALL;
       break;
 
-    case 0x15a9:       /* (blue) */
+    case 0x15a9:       // (blue)
       element = EL_CHAR_A;
       break;
 
-    case 0x15aa:       /* (blue) */
+    case 0x15aa:       // (blue)
       element = EL_CHAR_B;
       break;
 
-    case 0x15ab:       /* (blue) */
+    case 0x15ab:       // (blue)
       element = EL_CHAR_C;
       break;
 
-    case 0x15ac:       /* (blue) */
+    case 0x15ac:       // (blue)
       element = EL_CHAR_D;
       break;
 
-    case 0x15ad:       /* (blue) */
+    case 0x15ad:       // (blue)
       element = EL_CHAR_E;
       break;
 
-    case 0x15ae:       /* (blue) */
+    case 0x15ae:       // (blue)
       element = EL_CHAR_F;
       break;
 
-    case 0x15af:       /* (blue) */
+    case 0x15af:       // (blue)
       element = EL_CHAR_G;
       break;
 
-    case 0x15b0:       /* (blue) */
+    case 0x15b0:       // (blue)
       element = EL_CHAR_H;
       break;
 
-    case 0x15b1:       /* (blue) */
+    case 0x15b1:       // (blue)
       element = EL_CHAR_I;
       break;
 
-    case 0x15b2:       /* (blue) */
+    case 0x15b2:       // (blue)
       element = EL_CHAR_J;
       break;
 
-    case 0x15b3:       /* (blue) */
+    case 0x15b3:       // (blue)
       element = EL_CHAR_K;
       break;
 
-    case 0x15b4:       /* (blue) */
+    case 0x15b4:       // (blue)
       element = EL_CHAR_L;
       break;
 
-    case 0x15b5:       /* (blue) */
+    case 0x15b5:       // (blue)
       element = EL_CHAR_M;
       break;
 
-    case 0x15b6:       /* (blue) */
+    case 0x15b6:       // (blue)
       element = EL_CHAR_N;
       break;
 
-    case 0x15b7:       /* (blue) */
+    case 0x15b7:       // (blue)
       element = EL_CHAR_O;
       break;
 
-    case 0x15b8:       /* (blue) */
+    case 0x15b8:       // (blue)
       element = EL_CHAR_P;
       break;
 
-    case 0x15b9:       /* (blue) */
+    case 0x15b9:       // (blue)
       element = EL_CHAR_Q;
       break;
 
-    case 0x15ba:       /* (blue) */
+    case 0x15ba:       // (blue)
       element = EL_CHAR_R;
       break;
 
-    case 0x15bb:       /* (blue) */
+    case 0x15bb:       // (blue)
       element = EL_CHAR_S;
       break;
 
-    case 0x15bc:       /* (blue) */
+    case 0x15bc:       // (blue)
       element = EL_CHAR_T;
       break;
 
-    case 0x15bd:       /* (blue) */
+    case 0x15bd:       // (blue)
       element = EL_CHAR_U;
       break;
 
-    case 0x15be:       /* (blue) */
+    case 0x15be:       // (blue)
       element = EL_CHAR_V;
       break;
 
-    case 0x15bf:       /* (blue) */
+    case 0x15bf:       // (blue)
       element = EL_CHAR_W;
       break;
 
-    case 0x15c0:       /* (blue) */
+    case 0x15c0:       // (blue)
       element = EL_CHAR_X;
       break;
 
-    case 0x15c1:       /* (blue) */
+    case 0x15c1:       // (blue)
       element = EL_CHAR_Y;
       break;
 
-    case 0x15c2:       /* (blue) */
+    case 0x15c2:       // (blue)
       element = EL_CHAR_Z;
       break;
 
-    case 0x15c3:       /* (blue) */
+    case 0x15c3:       // (blue)
       element = EL_CHAR_AUMLAUT;
       break;
 
-    case 0x15c4:       /* (blue) */
+    case 0x15c4:       // (blue)
       element = EL_CHAR_OUMLAUT;
       break;
 
-    case 0x15c5:       /* (blue) */
+    case 0x15c5:       // (blue)
       element = EL_CHAR_UUMLAUT;
       break;
 
-    case 0x15c6:       /* (blue) */
+    case 0x15c6:       // (blue)
       element = EL_CHAR_0;
       break;
 
-    case 0x15c7:       /* (blue) */
+    case 0x15c7:       // (blue)
       element = EL_CHAR_1;
       break;
 
-    case 0x15c8:       /* (blue) */
+    case 0x15c8:       // (blue)
       element = EL_CHAR_2;
       break;
 
-    case 0x15c9:       /* (blue) */
+    case 0x15c9:       // (blue)
       element = EL_CHAR_3;
       break;
 
-    case 0x15ca:       /* (blue) */
+    case 0x15ca:       // (blue)
       element = EL_CHAR_4;
       break;
 
-    case 0x15cb:       /* (blue) */
+    case 0x15cb:       // (blue)
       element = EL_CHAR_5;
       break;
 
-    case 0x15cc:       /* (blue) */
+    case 0x15cc:       // (blue)
       element = EL_CHAR_6;
       break;
 
-    case 0x15cd:       /* (blue) */
+    case 0x15cd:       // (blue)
       element = EL_CHAR_7;
       break;
 
-    case 0x15ce:       /* (blue) */
+    case 0x15ce:       // (blue)
       element = EL_CHAR_8;
       break;
 
-    case 0x15cf:       /* (blue) */
+    case 0x15cf:       // (blue)
       element = EL_CHAR_9;
       break;
 
-    case 0x15d0:       /* (blue) */
+    case 0x15d0:       // (blue)
       element = EL_CHAR_PERIOD;
       break;
 
-    case 0x15d1:       /* (blue) */
+    case 0x15d1:       // (blue)
       element = EL_CHAR_EXCLAM;
       break;
 
-    case 0x15d2:       /* (blue) */
+    case 0x15d2:       // (blue)
       element = EL_CHAR_COLON;
       break;
 
-    case 0x15d3:       /* (blue) */
+    case 0x15d3:       // (blue)
       element = EL_CHAR_LESS;
       break;
 
-    case 0x15d4:       /* (blue) */
+    case 0x15d4:       // (blue)
       element = EL_CHAR_GREATER;
       break;
 
-    case 0x15d5:       /* (blue) */
+    case 0x15d5:       // (blue)
       element = EL_CHAR_QUESTION;
       break;
 
-    case 0x15d6:       /* (blue) */
+    case 0x15d6:       // (blue)
       element = EL_CHAR_COPYRIGHT;
       break;
 
-    case 0x15d7:       /* (blue) */
+    case 0x15d7:       // (blue)
       element = EL_CHAR_UP;
       break;
 
-    case 0x15d8:       /* (blue) */
+    case 0x15d8:       // (blue)
       element = EL_CHAR_DOWN;
       break;
 
-    case 0x15d9:       /* (blue) */
+    case 0x15d9:       // (blue)
       element = EL_CHAR_BUTTON;
       break;
 
-    case 0x15da:       /* (blue) */
+    case 0x15da:       // (blue)
       element = EL_CHAR_PLUS;
       break;
 
-    case 0x15db:       /* (blue) */
+    case 0x15db:       // (blue)
       element = EL_CHAR_MINUS;
       break;
 
-    case 0x15dc:       /* (blue) */
+    case 0x15dc:       // (blue)
       element = EL_CHAR_APOSTROPHE;
       break;
 
-    case 0x15dd:       /* (blue) */
+    case 0x15dd:       // (blue)
       element = EL_CHAR_PARENLEFT;
       break;
 
-    case 0x15de:       /* (blue) */
+    case 0x15de:       // (blue)
       element = EL_CHAR_PARENRIGHT;
       break;
 
-    case 0x15df:       /* (green) */
+    case 0x15df:       // (green)
       element = EL_CHAR_A;
       break;
 
-    case 0x15e0:       /* (green) */
+    case 0x15e0:       // (green)
       element = EL_CHAR_B;
       break;
 
-    case 0x15e1:       /* (green) */
+    case 0x15e1:       // (green)
       element = EL_CHAR_C;
       break;
 
-    case 0x15e2:       /* (green) */
+    case 0x15e2:       // (green)
       element = EL_CHAR_D;
       break;
 
-    case 0x15e3:       /* (green) */
+    case 0x15e3:       // (green)
       element = EL_CHAR_E;
       break;
 
-    case 0x15e4:       /* (green) */
+    case 0x15e4:       // (green)
       element = EL_CHAR_F;
       break;
 
-    case 0x15e5:       /* (green) */
+    case 0x15e5:       // (green)
       element = EL_CHAR_G;
       break;
 
-    case 0x15e6:       /* (green) */
+    case 0x15e6:       // (green)
       element = EL_CHAR_H;
       break;
 
-    case 0x15e7:       /* (green) */
+    case 0x15e7:       // (green)
       element = EL_CHAR_I;
       break;
 
-    case 0x15e8:       /* (green) */
+    case 0x15e8:       // (green)
       element = EL_CHAR_J;
       break;
 
-    case 0x15e9:       /* (green) */
+    case 0x15e9:       // (green)
       element = EL_CHAR_K;
       break;
 
-    case 0x15ea:       /* (green) */
+    case 0x15ea:       // (green)
       element = EL_CHAR_L;
       break;
 
-    case 0x15eb:       /* (green) */
+    case 0x15eb:       // (green)
       element = EL_CHAR_M;
       break;
 
-    case 0x15ec:       /* (green) */
+    case 0x15ec:       // (green)
       element = EL_CHAR_N;
       break;
 
-    case 0x15ed:       /* (green) */
+    case 0x15ed:       // (green)
       element = EL_CHAR_O;
       break;
 
-    case 0x15ee:       /* (green) */
+    case 0x15ee:       // (green)
       element = EL_CHAR_P;
       break;
 
-    case 0x15ef:       /* (green) */
+    case 0x15ef:       // (green)
       element = EL_CHAR_Q;
       break;
 
-    case 0x15f0:       /* (green) */
+    case 0x15f0:       // (green)
       element = EL_CHAR_R;
       break;
 
-    case 0x15f1:       /* (green) */
+    case 0x15f1:       // (green)
       element = EL_CHAR_S;
       break;
 
-    case 0x15f2:       /* (green) */
+    case 0x15f2:       // (green)
       element = EL_CHAR_T;
       break;
 
-    case 0x15f3:       /* (green) */
+    case 0x15f3:       // (green)
       element = EL_CHAR_U;
       break;
 
-    case 0x15f4:       /* (green) */
+    case 0x15f4:       // (green)
       element = EL_CHAR_V;
       break;
 
-    case 0x15f5:       /* (green) */
+    case 0x15f5:       // (green)
       element = EL_CHAR_W;
       break;
 
-    case 0x15f6:       /* (green) */
+    case 0x15f6:       // (green)
       element = EL_CHAR_X;
       break;
 
-    case 0x15f7:       /* (green) */
+    case 0x15f7:       // (green)
       element = EL_CHAR_Y;
       break;
 
-    case 0x15f8:       /* (green) */
+    case 0x15f8:       // (green)
       element = EL_CHAR_Z;
       break;
 
-    case 0x15f9:       /* (green) */
+    case 0x15f9:       // (green)
       element = EL_CHAR_AUMLAUT;
       break;
 
-    case 0x15fa:       /* (green) */
+    case 0x15fa:       // (green)
       element = EL_CHAR_OUMLAUT;
       break;
 
-    case 0x15fb:       /* (green) */
+    case 0x15fb:       // (green)
       element = EL_CHAR_UUMLAUT;
       break;
 
-    case 0x15fc:       /* (green) */
+    case 0x15fc:       // (green)
       element = EL_CHAR_0;
       break;
 
-    case 0x15fd:       /* (green) */
+    case 0x15fd:       // (green)
       element = EL_CHAR_1;
       break;
 
-    case 0x15fe:       /* (green) */
+    case 0x15fe:       // (green)
       element = EL_CHAR_2;
       break;
 
-    case 0x15ff:       /* (green) */
+    case 0x15ff:       // (green)
       element = EL_CHAR_3;
       break;
 
-    case 0x1600:       /* (green) */
+    case 0x1600:       // (green)
       element = EL_CHAR_4;
       break;
 
-    case 0x1601:       /* (green) */
+    case 0x1601:       // (green)
       element = EL_CHAR_5;
       break;
 
-    case 0x1602:       /* (green) */
+    case 0x1602:       // (green)
       element = EL_CHAR_6;
       break;
 
-    case 0x1603:       /* (green) */
+    case 0x1603:       // (green)
       element = EL_CHAR_7;
       break;
 
-    case 0x1604:       /* (green) */
+    case 0x1604:       // (green)
       element = EL_CHAR_8;
       break;
 
-    case 0x1605:       /* (green) */
+    case 0x1605:       // (green)
       element = EL_CHAR_9;
       break;
 
-    case 0x1606:       /* (green) */
+    case 0x1606:       // (green)
       element = EL_CHAR_PERIOD;
       break;
 
-    case 0x1607:       /* (green) */
+    case 0x1607:       // (green)
       element = EL_CHAR_EXCLAM;
       break;
 
-    case 0x1608:       /* (green) */
+    case 0x1608:       // (green)
       element = EL_CHAR_COLON;
       break;
 
-    case 0x1609:       /* (green) */
+    case 0x1609:       // (green)
       element = EL_CHAR_LESS;
       break;
 
-    case 0x160a:       /* (green) */
+    case 0x160a:       // (green)
       element = EL_CHAR_GREATER;
       break;
 
-    case 0x160b:       /* (green) */
+    case 0x160b:       // (green)
       element = EL_CHAR_QUESTION;
       break;
 
-    case 0x160c:       /* (green) */
+    case 0x160c:       // (green)
       element = EL_CHAR_COPYRIGHT;
       break;
 
-    case 0x160d:       /* (green) */
+    case 0x160d:       // (green)
       element = EL_CHAR_UP;
       break;
 
-    case 0x160e:       /* (green) */
+    case 0x160e:       // (green)
       element = EL_CHAR_DOWN;
       break;
 
-    case 0x160f:       /* (green) */
+    case 0x160f:       // (green)
       element = EL_CHAR_BUTTON;
       break;
 
-    case 0x1610:       /* (green) */
+    case 0x1610:       // (green)
       element = EL_CHAR_PLUS;
       break;
 
-    case 0x1611:       /* (green) */
+    case 0x1611:       // (green)
       element = EL_CHAR_MINUS;
       break;
 
-    case 0x1612:       /* (green) */
+    case 0x1612:       // (green)
       element = EL_CHAR_APOSTROPHE;
       break;
 
-    case 0x1613:       /* (green) */
+    case 0x1613:       // (green)
       element = EL_CHAR_PARENLEFT;
       break;
 
-    case 0x1614:       /* (green) */
+    case 0x1614:       // (green)
       element = EL_CHAR_PARENRIGHT;
       break;
 
-    case 0x1615:       /* (blue steel) */
+    case 0x1615:       // (blue steel)
       element = EL_STEEL_CHAR_A;
       break;
 
-    case 0x1616:       /* (blue steel) */
+    case 0x1616:       // (blue steel)
       element = EL_STEEL_CHAR_B;
       break;
 
-    case 0x1617:       /* (blue steel) */
+    case 0x1617:       // (blue steel)
       element = EL_STEEL_CHAR_C;
       break;
 
-    case 0x1618:       /* (blue steel) */
+    case 0x1618:       // (blue steel)
       element = EL_STEEL_CHAR_D;
       break;
 
-    case 0x1619:       /* (blue steel) */
+    case 0x1619:       // (blue steel)
       element = EL_STEEL_CHAR_E;
       break;
 
-    case 0x161a:       /* (blue steel) */
+    case 0x161a:       // (blue steel)
       element = EL_STEEL_CHAR_F;
       break;
 
-    case 0x161b:       /* (blue steel) */
+    case 0x161b:       // (blue steel)
       element = EL_STEEL_CHAR_G;
       break;
 
-    case 0x161c:       /* (blue steel) */
+    case 0x161c:       // (blue steel)
       element = EL_STEEL_CHAR_H;
       break;
 
-    case 0x161d:       /* (blue steel) */
+    case 0x161d:       // (blue steel)
       element = EL_STEEL_CHAR_I;
       break;
 
-    case 0x161e:       /* (blue steel) */
+    case 0x161e:       // (blue steel)
       element = EL_STEEL_CHAR_J;
       break;
 
-    case 0x161f:       /* (blue steel) */
+    case 0x161f:       // (blue steel)
       element = EL_STEEL_CHAR_K;
       break;
 
-    case 0x1620:       /* (blue steel) */
+    case 0x1620:       // (blue steel)
       element = EL_STEEL_CHAR_L;
       break;
 
-    case 0x1621:       /* (blue steel) */
+    case 0x1621:       // (blue steel)
       element = EL_STEEL_CHAR_M;
       break;
 
-    case 0x1622:       /* (blue steel) */
+    case 0x1622:       // (blue steel)
       element = EL_STEEL_CHAR_N;
       break;
 
-    case 0x1623:       /* (blue steel) */
+    case 0x1623:       // (blue steel)
       element = EL_STEEL_CHAR_O;
       break;
 
-    case 0x1624:       /* (blue steel) */
+    case 0x1624:       // (blue steel)
       element = EL_STEEL_CHAR_P;
       break;
 
-    case 0x1625:       /* (blue steel) */
+    case 0x1625:       // (blue steel)
       element = EL_STEEL_CHAR_Q;
       break;
 
-    case 0x1626:       /* (blue steel) */
+    case 0x1626:       // (blue steel)
       element = EL_STEEL_CHAR_R;
       break;
 
-    case 0x1627:       /* (blue steel) */
+    case 0x1627:       // (blue steel)
       element = EL_STEEL_CHAR_S;
       break;
 
-    case 0x1628:       /* (blue steel) */
+    case 0x1628:       // (blue steel)
       element = EL_STEEL_CHAR_T;
       break;
 
-    case 0x1629:       /* (blue steel) */
+    case 0x1629:       // (blue steel)
       element = EL_STEEL_CHAR_U;
       break;
 
-    case 0x162a:       /* (blue steel) */
+    case 0x162a:       // (blue steel)
       element = EL_STEEL_CHAR_V;
       break;
 
-    case 0x162b:       /* (blue steel) */
+    case 0x162b:       // (blue steel)
       element = EL_STEEL_CHAR_W;
       break;
 
-    case 0x162c:       /* (blue steel) */
+    case 0x162c:       // (blue steel)
       element = EL_STEEL_CHAR_X;
       break;
 
-    case 0x162d:       /* (blue steel) */
+    case 0x162d:       // (blue steel)
       element = EL_STEEL_CHAR_Y;
       break;
 
-    case 0x162e:       /* (blue steel) */
+    case 0x162e:       // (blue steel)
       element = EL_STEEL_CHAR_Z;
       break;
 
-    case 0x162f:       /* (blue steel) */
+    case 0x162f:       // (blue steel)
       element = EL_STEEL_CHAR_AUMLAUT;
       break;
 
-    case 0x1630:       /* (blue steel) */
+    case 0x1630:       // (blue steel)
       element = EL_STEEL_CHAR_OUMLAUT;
       break;
 
-    case 0x1631:       /* (blue steel) */
+    case 0x1631:       // (blue steel)
       element = EL_STEEL_CHAR_UUMLAUT;
       break;
 
-    case 0x1632:       /* (blue steel) */
+    case 0x1632:       // (blue steel)
       element = EL_STEEL_CHAR_0;
       break;
 
-    case 0x1633:       /* (blue steel) */
+    case 0x1633:       // (blue steel)
       element = EL_STEEL_CHAR_1;
       break;
 
-    case 0x1634:       /* (blue steel) */
+    case 0x1634:       // (blue steel)
       element = EL_STEEL_CHAR_2;
       break;
 
-    case 0x1635:       /* (blue steel) */
+    case 0x1635:       // (blue steel)
       element = EL_STEEL_CHAR_3;
       break;
 
-    case 0x1636:       /* (blue steel) */
+    case 0x1636:       // (blue steel)
       element = EL_STEEL_CHAR_4;
       break;
 
-    case 0x1637:       /* (blue steel) */
+    case 0x1637:       // (blue steel)
       element = EL_STEEL_CHAR_5;
       break;
 
-    case 0x1638:       /* (blue steel) */
+    case 0x1638:       // (blue steel)
       element = EL_STEEL_CHAR_6;
       break;
 
-    case 0x1639:       /* (blue steel) */
+    case 0x1639:       // (blue steel)
       element = EL_STEEL_CHAR_7;
       break;
 
-    case 0x163a:       /* (blue steel) */
+    case 0x163a:       // (blue steel)
       element = EL_STEEL_CHAR_8;
       break;
 
-    case 0x163b:       /* (blue steel) */
+    case 0x163b:       // (blue steel)
       element = EL_STEEL_CHAR_9;
       break;
 
-    case 0x163c:       /* (blue steel) */
+    case 0x163c:       // (blue steel)
       element = EL_STEEL_CHAR_PERIOD;
       break;
 
-    case 0x163d:       /* (blue steel) */
+    case 0x163d:       // (blue steel)
       element = EL_STEEL_CHAR_EXCLAM;
       break;
 
-    case 0x163e:       /* (blue steel) */
+    case 0x163e:       // (blue steel)
       element = EL_STEEL_CHAR_COLON;
       break;
 
-    case 0x163f:       /* (blue steel) */
+    case 0x163f:       // (blue steel)
       element = EL_STEEL_CHAR_LESS;
       break;
 
-    case 0x1640:       /* (blue steel) */
+    case 0x1640:       // (blue steel)
       element = EL_STEEL_CHAR_GREATER;
       break;
 
-    case 0x1641:       /* (blue steel) */
+    case 0x1641:       // (blue steel)
       element = EL_STEEL_CHAR_QUESTION;
       break;
 
-    case 0x1642:       /* (blue steel) */
+    case 0x1642:       // (blue steel)
       element = EL_STEEL_CHAR_COPYRIGHT;
       break;
 
-    case 0x1643:       /* (blue steel) */
+    case 0x1643:       // (blue steel)
       element = EL_STEEL_CHAR_UP;
       break;
 
-    case 0x1644:       /* (blue steel) */
+    case 0x1644:       // (blue steel)
       element = EL_STEEL_CHAR_DOWN;
       break;
 
-    case 0x1645:       /* (blue steel) */
+    case 0x1645:       // (blue steel)
       element = EL_STEEL_CHAR_BUTTON;
       break;
 
-    case 0x1646:       /* (blue steel) */
+    case 0x1646:       // (blue steel)
       element = EL_STEEL_CHAR_PLUS;
       break;
 
-    case 0x1647:       /* (blue steel) */
+    case 0x1647:       // (blue steel)
       element = EL_STEEL_CHAR_MINUS;
       break;
 
-    case 0x1648:       /* (blue steel) */
+    case 0x1648:       // (blue steel)
       element = EL_STEEL_CHAR_APOSTROPHE;
       break;
 
-    case 0x1649:       /* (blue steel) */
+    case 0x1649:       // (blue steel)
       element = EL_STEEL_CHAR_PARENLEFT;
       break;
 
-    case 0x164a:       /* (blue steel) */
+    case 0x164a:       // (blue steel)
       element = EL_STEEL_CHAR_PARENRIGHT;
       break;
 
-    case 0x164b:       /* (green steel) */
+    case 0x164b:       // (green steel)
       element = EL_STEEL_CHAR_A;
       break;
 
-    case 0x164c:       /* (green steel) */
+    case 0x164c:       // (green steel)
       element = EL_STEEL_CHAR_B;
       break;
 
-    case 0x164d:       /* (green steel) */
+    case 0x164d:       // (green steel)
       element = EL_STEEL_CHAR_C;
       break;
 
-    case 0x164e:       /* (green steel) */
+    case 0x164e:       // (green steel)
       element = EL_STEEL_CHAR_D;
       break;
 
-    case 0x164f:       /* (green steel) */
+    case 0x164f:       // (green steel)
       element = EL_STEEL_CHAR_E;
       break;
 
-    case 0x1650:       /* (green steel) */
+    case 0x1650:       // (green steel)
       element = EL_STEEL_CHAR_F;
       break;
 
-    case 0x1651:       /* (green steel) */
+    case 0x1651:       // (green steel)
       element = EL_STEEL_CHAR_G;
       break;
 
-    case 0x1652:       /* (green steel) */
+    case 0x1652:       // (green steel)
       element = EL_STEEL_CHAR_H;
       break;
 
-    case 0x1653:       /* (green steel) */
+    case 0x1653:       // (green steel)
       element = EL_STEEL_CHAR_I;
       break;
 
-    case 0x1654:       /* (green steel) */
+    case 0x1654:       // (green steel)
       element = EL_STEEL_CHAR_J;
       break;
 
-    case 0x1655:       /* (green steel) */
+    case 0x1655:       // (green steel)
       element = EL_STEEL_CHAR_K;
       break;
 
-    case 0x1656:       /* (green steel) */
+    case 0x1656:       // (green steel)
       element = EL_STEEL_CHAR_L;
       break;
 
-    case 0x1657:       /* (green steel) */
+    case 0x1657:       // (green steel)
       element = EL_STEEL_CHAR_M;
       break;
 
-    case 0x1658:       /* (green steel) */
+    case 0x1658:       // (green steel)
       element = EL_STEEL_CHAR_N;
       break;
 
-    case 0x1659:       /* (green steel) */
+    case 0x1659:       // (green steel)
       element = EL_STEEL_CHAR_O;
       break;
 
-    case 0x165a:       /* (green steel) */
+    case 0x165a:       // (green steel)
       element = EL_STEEL_CHAR_P;
       break;
 
-    case 0x165b:       /* (green steel) */
+    case 0x165b:       // (green steel)
       element = EL_STEEL_CHAR_Q;
       break;
 
-    case 0x165c:       /* (green steel) */
+    case 0x165c:       // (green steel)
       element = EL_STEEL_CHAR_R;
       break;
 
-    case 0x165d:       /* (green steel) */
+    case 0x165d:       // (green steel)
       element = EL_STEEL_CHAR_S;
       break;
 
-    case 0x165e:       /* (green steel) */
+    case 0x165e:       // (green steel)
       element = EL_STEEL_CHAR_T;
       break;
 
-    case 0x165f:       /* (green steel) */
+    case 0x165f:       // (green steel)
       element = EL_STEEL_CHAR_U;
       break;
 
-    case 0x1660:       /* (green steel) */
+    case 0x1660:       // (green steel)
       element = EL_STEEL_CHAR_V;
       break;
 
-    case 0x1661:       /* (green steel) */
+    case 0x1661:       // (green steel)
       element = EL_STEEL_CHAR_W;
       break;
 
-    case 0x1662:       /* (green steel) */
+    case 0x1662:       // (green steel)
       element = EL_STEEL_CHAR_X;
       break;
 
-    case 0x1663:       /* (green steel) */
+    case 0x1663:       // (green steel)
       element = EL_STEEL_CHAR_Y;
       break;
 
-    case 0x1664:       /* (green steel) */
+    case 0x1664:       // (green steel)
       element = EL_STEEL_CHAR_Z;
       break;
 
-    case 0x1665:       /* (green steel) */
+    case 0x1665:       // (green steel)
       element = EL_STEEL_CHAR_AUMLAUT;
       break;
 
-    case 0x1666:       /* (green steel) */
+    case 0x1666:       // (green steel)
       element = EL_STEEL_CHAR_OUMLAUT;
       break;
 
-    case 0x1667:       /* (green steel) */
+    case 0x1667:       // (green steel)
       element = EL_STEEL_CHAR_UUMLAUT;
       break;
 
-    case 0x1668:       /* (green steel) */
+    case 0x1668:       // (green steel)
       element = EL_STEEL_CHAR_0;
       break;
 
-    case 0x1669:       /* (green steel) */
+    case 0x1669:       // (green steel)
       element = EL_STEEL_CHAR_1;
       break;
 
-    case 0x166a:       /* (green steel) */
+    case 0x166a:       // (green steel)
       element = EL_STEEL_CHAR_2;
       break;
 
-    case 0x166b:       /* (green steel) */
+    case 0x166b:       // (green steel)
       element = EL_STEEL_CHAR_3;
       break;
 
-    case 0x166c:       /* (green steel) */
+    case 0x166c:       // (green steel)
       element = EL_STEEL_CHAR_4;
       break;
 
-    case 0x166d:       /* (green steel) */
+    case 0x166d:       // (green steel)
       element = EL_STEEL_CHAR_5;
       break;
 
-    case 0x166e:       /* (green steel) */
+    case 0x166e:       // (green steel)
       element = EL_STEEL_CHAR_6;
       break;
 
-    case 0x166f:       /* (green steel) */
+    case 0x166f:       // (green steel)
       element = EL_STEEL_CHAR_7;
       break;
 
-    case 0x1670:       /* (green steel) */
+    case 0x1670:       // (green steel)
       element = EL_STEEL_CHAR_8;
       break;
 
-    case 0x1671:       /* (green steel) */
+    case 0x1671:       // (green steel)
       element = EL_STEEL_CHAR_9;
       break;
 
-    case 0x1672:       /* (green steel) */
+    case 0x1672:       // (green steel)
       element = EL_STEEL_CHAR_PERIOD;
       break;
 
-    case 0x1673:       /* (green steel) */
+    case 0x1673:       // (green steel)
       element = EL_STEEL_CHAR_EXCLAM;
       break;
 
-    case 0x1674:       /* (green steel) */
+    case 0x1674:       // (green steel)
       element = EL_STEEL_CHAR_COLON;
       break;
 
-    case 0x1675:       /* (green steel) */
+    case 0x1675:       // (green steel)
       element = EL_STEEL_CHAR_LESS;
       break;
 
-    case 0x1676:       /* (green steel) */
+    case 0x1676:       // (green steel)
       element = EL_STEEL_CHAR_GREATER;
       break;
 
-    case 0x1677:       /* (green steel) */
+    case 0x1677:       // (green steel)
       element = EL_STEEL_CHAR_QUESTION;
       break;
 
-    case 0x1678:       /* (green steel) */
+    case 0x1678:       // (green steel)
       element = EL_STEEL_CHAR_COPYRIGHT;
       break;
 
-    case 0x1679:       /* (green steel) */
+    case 0x1679:       // (green steel)
       element = EL_STEEL_CHAR_UP;
       break;
 
-    case 0x167a:       /* (green steel) */
+    case 0x167a:       // (green steel)
       element = EL_STEEL_CHAR_DOWN;
       break;
 
-    case 0x167b:       /* (green steel) */
+    case 0x167b:       // (green steel)
       element = EL_STEEL_CHAR_BUTTON;
       break;
 
-    case 0x167c:       /* (green steel) */
+    case 0x167c:       // (green steel)
       element = EL_STEEL_CHAR_PLUS;
       break;
 
-    case 0x167d:       /* (green steel) */
+    case 0x167d:       // (green steel)
       element = EL_STEEL_CHAR_MINUS;
       break;
 
-    case 0x167e:       /* (green steel) */
+    case 0x167e:       // (green steel)
       element = EL_STEEL_CHAR_APOSTROPHE;
       break;
 
-    case 0x167f:       /* (green steel) */
+    case 0x167f:       // (green steel)
       element = EL_STEEL_CHAR_PARENLEFT;
       break;
 
-    case 0x1680:       /* (green steel) */
+    case 0x1680:       // (green steel)
       element = EL_STEEL_CHAR_PARENRIGHT;
       break;
 
-    case 0x1681:       /* gate (red) */
+    case 0x1681:       // gate (red)
       element = EL_EM_GATE_1;
       break;
 
-    case 0x1682:       /* secret gate (red) */
+    case 0x1682:       // secret gate (red)
       element = EL_GATE_1_GRAY;
       break;
 
-    case 0x1683:       /* gate (yellow) */
+    case 0x1683:       // gate (yellow)
       element = EL_EM_GATE_2;
       break;
 
-    case 0x1684:       /* secret gate (yellow) */
+    case 0x1684:       // secret gate (yellow)
       element = EL_GATE_2_GRAY;
       break;
 
-    case 0x1685:       /* gate (blue) */
+    case 0x1685:       // gate (blue)
       element = EL_EM_GATE_4;
       break;
 
-    case 0x1686:       /* secret gate (blue) */
+    case 0x1686:       // secret gate (blue)
       element = EL_GATE_4_GRAY;
       break;
 
-    case 0x1687:       /* gate (green) */
+    case 0x1687:       // gate (green)
       element = EL_EM_GATE_3;
       break;
 
-    case 0x1688:       /* secret gate (green) */
+    case 0x1688:       // secret gate (green)
       element = EL_GATE_3_GRAY;
       break;
 
-    case 0x1689:       /* gate (white) */
+    case 0x1689:       // gate (white)
       element = EL_DC_GATE_WHITE;
       break;
 
-    case 0x168a:       /* secret gate (white) */
+    case 0x168a:       // secret gate (white)
       element = EL_DC_GATE_WHITE_GRAY;
       break;
 
-    case 0x168b:       /* secret gate (no key) */
+    case 0x168b:       // secret gate (no key)
       element = EL_DC_GATE_FAKE_GRAY;
       break;
 
@@ -5272,91 +5389,91 @@ int getMappedElement_DC(int element)
       element = EL_STEELWALL_SLIPPERY;
       break;
 
-    case 0x1695:       /* steel wall (not round) */
+    case 0x1695:       // steel wall (not round)
       element = EL_STEELWALL;
       break;
 
-    case 0x1696:       /* steel wall (left) */
+    case 0x1696:       // steel wall (left)
       element = EL_DC_STEELWALL_1_LEFT;
       break;
 
-    case 0x1697:       /* steel wall (bottom) */
+    case 0x1697:       // steel wall (bottom)
       element = EL_DC_STEELWALL_1_BOTTOM;
       break;
 
-    case 0x1698:       /* steel wall (right) */
+    case 0x1698:       // steel wall (right)
       element = EL_DC_STEELWALL_1_RIGHT;
       break;
 
-    case 0x1699:       /* steel wall (top) */
+    case 0x1699:       // steel wall (top)
       element = EL_DC_STEELWALL_1_TOP;
       break;
 
-    case 0x169a:       /* steel wall (left/bottom) */
+    case 0x169a:       // steel wall (left/bottom)
       element = EL_DC_STEELWALL_1_BOTTOMLEFT;
       break;
 
-    case 0x169b:       /* steel wall (right/bottom) */
+    case 0x169b:       // steel wall (right/bottom)
       element = EL_DC_STEELWALL_1_BOTTOMRIGHT;
       break;
 
-    case 0x169c:       /* steel wall (right/top) */
+    case 0x169c:       // steel wall (right/top)
       element = EL_DC_STEELWALL_1_TOPRIGHT;
       break;
 
-    case 0x169d:       /* steel wall (left/top) */
+    case 0x169d:       // steel wall (left/top)
       element = EL_DC_STEELWALL_1_TOPLEFT;
       break;
 
-    case 0x169e:       /* steel wall (right/bottom small) */
+    case 0x169e:       // steel wall (right/bottom small)
       element = EL_DC_STEELWALL_1_BOTTOMRIGHT_2;
       break;
 
-    case 0x169f:       /* steel wall (left/bottom small) */
+    case 0x169f:       // steel wall (left/bottom small)
       element = EL_DC_STEELWALL_1_BOTTOMLEFT_2;
       break;
 
-    case 0x16a0:       /* steel wall (right/top small) */
+    case 0x16a0:       // steel wall (right/top small)
       element = EL_DC_STEELWALL_1_TOPRIGHT_2;
       break;
 
-    case 0x16a1:       /* steel wall (left/top small) */
+    case 0x16a1:       // steel wall (left/top small)
       element = EL_DC_STEELWALL_1_TOPLEFT_2;
       break;
 
-    case 0x16a2:       /* steel wall (left/right) */
+    case 0x16a2:       // steel wall (left/right)
       element = EL_DC_STEELWALL_1_VERTICAL;
       break;
 
-    case 0x16a3:       /* steel wall (top/bottom) */
+    case 0x16a3:       // steel wall (top/bottom)
       element = EL_DC_STEELWALL_1_HORIZONTAL;
       break;
 
-    case 0x16a4:       /* steel wall 2 (left end) */
+    case 0x16a4:       // steel wall 2 (left end)
       element = EL_DC_STEELWALL_2_LEFT;
       break;
 
-    case 0x16a5:       /* steel wall 2 (right end) */
+    case 0x16a5:       // steel wall 2 (right end)
       element = EL_DC_STEELWALL_2_RIGHT;
       break;
 
-    case 0x16a6:       /* steel wall 2 (top end) */
+    case 0x16a6:       // steel wall 2 (top end)
       element = EL_DC_STEELWALL_2_TOP;
       break;
 
-    case 0x16a7:       /* steel wall 2 (bottom end) */
+    case 0x16a7:       // steel wall 2 (bottom end)
       element = EL_DC_STEELWALL_2_BOTTOM;
       break;
 
-    case 0x16a8:       /* steel wall 2 (left/right) */
+    case 0x16a8:       // steel wall 2 (left/right)
       element = EL_DC_STEELWALL_2_HORIZONTAL;
       break;
 
-    case 0x16a9:       /* steel wall 2 (up/down) */
+    case 0x16a9:       // steel wall 2 (up/down)
       element = EL_DC_STEELWALL_2_VERTICAL;
       break;
 
-    case 0x16aa:       /* steel wall 2 (mid) */
+    case 0x16aa:       // steel wall 2 (mid)
       element = EL_DC_STEELWALL_2_MIDDLE;
       break;
 
@@ -5428,8 +5545,8 @@ int getMappedElement_DC(int element)
       element = EL_INVISIBLE_STEELWALL;
       break;
 
-      /* 0x16bc - 0x16cb: */
-      /* EL_INVISIBLE_SAND */
+      // 0x16bc - 0x16cb:
+      // EL_INVISIBLE_SAND
 
     case 0x16cc:
       element = EL_LIGHT_SWITCH;
@@ -5440,9 +5557,9 @@ int getMappedElement_DC(int element)
       break;
 
     default:
-      if (element >= 0x0117 && element <= 0x036e)      /* (?) */
+      if (element >= 0x0117 && element <= 0x036e)      // (?)
        element = EL_DIAMOND;
-      else if (element >= 0x042d && element <= 0x0684) /* (?) */
+      else if (element >= 0x042d && element <= 0x0684) // (?)
        element = EL_EMERALD;
       else if (element >= 0x157c && element <= 0x158b)
        element = EL_SAND;
@@ -5478,7 +5595,7 @@ static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level,
   int num_yamyam_contents;
   int i, x, y;
 
-  getDecodedWord_DC(0, TRUE);          /* initialize DC2 decoding engine */
+  getDecodedWord_DC(0, TRUE);          // initialize DC2 decoding engine
 
   for (i = 0; i < DC_LEVEL_HEADER_SIZE / 2; i++)
   {
@@ -5488,12 +5605,12 @@ static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level,
     header[i * 2 + 1] = header_word & 0xff;
   }
 
-  /* read some values from level header to check level decoding integrity */
+  // read some values from level header to check level decoding integrity
   fieldx = header[6] | (header[7] << 8);
   fieldy = header[8] | (header[9] << 8);
   num_yamyam_contents = header[60] | (header[61] << 8);
 
-  /* do some simple sanity checks to ensure that level was correctly decoded */
+  // do some simple sanity checks to ensure that level was correctly decoded
   if (fieldx < 1 || fieldx > 256 ||
       fieldy < 1 || fieldy > 256 ||
       num_yamyam_contents < 1 || num_yamyam_contents > 8)
@@ -5505,14 +5622,14 @@ static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level,
     return;
   }
 
-  /* maximum envelope header size is 31 bytes */
+  // maximum envelope header size is 31 bytes
   envelope_header_len  = header[envelope_header_pos];
-  /* maximum envelope content size is 110 (156?) bytes */
+  // maximum envelope content size is 110 (156?) bytes
   envelope_content_len = header[envelope_content_pos];
 
-  /* maximum level title size is 40 bytes */
+  // maximum level title size is 40 bytes
   level_name_len       = MIN(header[level_name_pos],   MAX_LEVEL_NAME_LEN);
-  /* maximum level author size is 30 (51?) bytes */
+  // maximum level author size is 30 (51?) bytes
   level_author_len     = MIN(header[level_author_pos], MAX_LEVEL_AUTHOR_LEN);
 
   envelope_size = 0;
@@ -5613,8 +5730,8 @@ static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level,
   level->extra_time            = header[56] | (header[57] << 8);
   level->shield_normal_time    = header[58] | (header[59] << 8);
 
-  /* Diamond Caves has the same (strange) behaviour as Emerald Mine that gems
-     can slip down from flat walls, like normal walls and steel walls */
+  // Diamond Caves has the same (strange) behaviour as Emerald Mine that gems
+  // can slip down from flat walls, like normal walls and steel walls
   level->em_slippery_gems = TRUE;
 }
 
@@ -5642,11 +5759,11 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level,
 
   if (level_file_info->packed)
   {
-    /* read "magic bytes" from start of file */
+    // read "magic bytes" from start of file
     if (getStringFromFile(file, magic_bytes, num_magic_bytes + 1) == NULL)
       magic_bytes[0] = '\0';
 
-    /* check "magic bytes" for correct file format */
+    // check "magic bytes" for correct file format
     if (!strPrefix(magic_bytes, "DC2"))
     {
       level->no_valid_file = TRUE;
@@ -5664,16 +5781,16 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level,
       int extra_bytes = 4;
       int skip_bytes;
 
-      /* advance file stream to first level inside the level package */
+      // advance file stream to first level inside the level package
       skip_bytes = position_first_level - num_magic_bytes - extra_bytes;
 
-      /* each block of level data is followed by block of non-level data */
+      // each block of level data is followed by block of non-level data
       num_levels_to_skip *= 2;
 
-      /* at least skip header bytes, therefore use ">= 0" instead of "> 0" */
+      // at least skip header bytes, therefore use ">= 0" instead of "> 0"
       while (num_levels_to_skip >= 0)
       {
-       /* advance file stream to next level inside the level package */
+       // advance file stream to next level inside the level package
        if (seekFile(file, skip_bytes, SEEK_CUR) != 0)
        {
          level->no_valid_file = TRUE;
@@ -5684,10 +5801,10 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level,
          return;
        }
 
-       /* skip apparently unused extra bytes following each level */
+       // skip apparently unused extra bytes following each level
        ReadUnusedBytesFromFile(file, extra_bytes);
 
-       /* read size of next level in level package */
+       // read size of next level in level package
        skip_bytes = getFile32BitLE(file);
 
        num_levels_to_skip--;
@@ -5710,9 +5827,9 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level,
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading SB level                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading SB level
+// ----------------------------------------------------------------------------
 
 int getMappedElement_SB(int element_ascii, boolean use_ces)
 {
@@ -5724,14 +5841,14 @@ int getMappedElement_SB(int element_ascii, boolean use_ces)
   }
   sb_element_mapping[] =
   {
-    { ' ', EL_EMPTY,                EL_CUSTOM_1 },  /* floor (space) */
-    { '#', EL_STEELWALL,            EL_CUSTOM_2 },  /* wall */
-    { '@', EL_PLAYER_1,             EL_CUSTOM_3 },  /* player */
-    { '$', EL_SOKOBAN_OBJECT,       EL_CUSTOM_4 },  /* box */
-    { '.', EL_SOKOBAN_FIELD_EMPTY,  EL_CUSTOM_5 },  /* goal square */
-    { '*', EL_SOKOBAN_FIELD_FULL,   EL_CUSTOM_6 },  /* box on goal square */
-    { '+', EL_SOKOBAN_FIELD_PLAYER, EL_CUSTOM_7 },  /* player on goal square */
-    { '_', EL_INVISIBLE_STEELWALL,  EL_FROM_LEVEL_TEMPLATE },  /* floor beyond border */
+    { ' ', EL_EMPTY,                EL_CUSTOM_1 },  // floor (space)
+    { '#', EL_STEELWALL,            EL_CUSTOM_2 },  // wall
+    { '@', EL_PLAYER_1,             EL_CUSTOM_3 },  // player
+    { '$', EL_SOKOBAN_OBJECT,       EL_CUSTOM_4 },  // box
+    { '.', EL_SOKOBAN_FIELD_EMPTY,  EL_CUSTOM_5 },  // goal square
+    { '*', EL_SOKOBAN_FIELD_FULL,   EL_CUSTOM_6 },  // box on goal square
+    { '+', EL_SOKOBAN_FIELD_PLAYER, EL_CUSTOM_7 },  // player on goal square
+    { '_', EL_INVISIBLE_STEELWALL,  EL_FROM_LEVEL_TEMPLATE },  // floor beyond border
 
     { 0,   -1,                      -1          },
   };
@@ -5763,7 +5880,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
   boolean load_xsb_to_ces = check_special_flags("load_xsb_to_ces");
   int file_level_nr = 0;
   int line_nr = 0;
-  int x = 0, y = 0;            /* initialized to make compilers happy */
+  int x = 0, y = 0;            // initialized to make compilers happy
 
   last_comment[0] = '\0';
   level_name[0] = '\0';
@@ -5780,10 +5897,10 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
 
   while (!checkEndOfFile(file))
   {
-    /* level successfully read, but next level may follow here */
+    // level successfully read, but next level may follow here
     if (!got_valid_playfield_line && reading_playfield)
     {
-      /* read playfield from single level file -- skip remaining file */
+      // read playfield from single level file -- skip remaining file
       if (!level_file_info->packed)
        break;
 
@@ -5800,49 +5917,49 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
 
     got_valid_playfield_line = FALSE;
 
-    /* read next line of input file */
+    // read next line of input file
     if (!getStringFromFile(file, line, MAX_LINE_LEN))
       break;
 
-    /* check if line was completely read and is terminated by line break */
+    // check if line was completely read and is terminated by line break
     if (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
       line_nr++;
 
-    /* cut trailing line break (this can be newline and/or carriage return) */
+    // cut trailing line break (this can be newline and/or carriage return)
     for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--)
       if ((*line_ptr == '\n' || *line_ptr == '\r') && *(line_ptr + 1) == '\0')
         *line_ptr = '\0';
 
-    /* copy raw input line for later use (mainly debugging output) */
+    // copy raw input line for later use (mainly debugging output)
     strcpy(line_raw, line);
 
     if (read_continued_line)
     {
-      /* append new line to existing line, if there is enough space */
+      // append new line to existing line, if there is enough space
       if (strlen(previous_line) + strlen(line_ptr) < MAX_LINE_LEN)
         strcat(previous_line, line_ptr);
 
-      strcpy(line, previous_line);      /* copy storage buffer to line */
+      strcpy(line, previous_line);      // copy storage buffer to line
 
       read_continued_line = FALSE;
     }
 
-    /* if the last character is '\', continue at next line */
+    // if the last character is '\', continue at next line
     if (strlen(line) > 0 && line[strlen(line) - 1] == '\\')
     {
-      line[strlen(line) - 1] = '\0';    /* cut off trailing backslash */
-      strcpy(previous_line, line);      /* copy line to storage buffer */
+      line[strlen(line) - 1] = '\0';    // cut off trailing backslash
+      strcpy(previous_line, line);      // copy line to storage buffer
 
       read_continued_line = TRUE;
 
       continue;
     }
 
-    /* skip empty lines */
+    // skip empty lines
     if (line[0] == '\0')
       continue;
 
-    /* extract comment text from comment line */
+    // extract comment text from comment line
     if (line[0] == ';')
     {
       for (line_ptr = line; *line_ptr; line_ptr++)
@@ -5854,7 +5971,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
       continue;
     }
 
-    /* extract level title text from line containing level title */
+    // extract level title text from line containing level title
     if (line[0] == '\'')
     {
       strcpy(level_name, &line[1]);
@@ -5865,14 +5982,14 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
       continue;
     }
 
-    /* skip lines containing only spaces (or empty lines) */
+    // skip lines containing only spaces (or empty lines)
     for (line_ptr = line; *line_ptr; line_ptr++)
       if (*line_ptr != ' ')
        break;
     if (*line_ptr == '\0')
       continue;
 
-    /* at this point, we have found a line containing part of a playfield */
+    // at this point, we have found a line containing part of a playfield
 
     got_valid_playfield_line = TRUE;
 
@@ -5888,23 +6005,23 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
       level->fieldx = 0;
       level->fieldy = 0;
 
-      /* start with topmost tile row */
+      // start with topmost tile row
       y = 0;
     }
 
-    /* skip playfield line if larger row than allowed */
+    // skip playfield line if larger row than allowed
     if (y >= MAX_LEV_FIELDY)
       continue;
 
-    /* start with leftmost tile column */
+    // start with leftmost tile column
     x = 0;
 
-    /* read playfield elements from line */
+    // read playfield elements from line
     for (line_ptr = line; *line_ptr; line_ptr++)
     {
       int mapped_sb_element = getMappedElement_SB(*line_ptr, load_xsb_to_ces);
 
-      /* stop parsing playfield line if larger column than allowed */
+      // stop parsing playfield line if larger column than allowed
       if (x >= MAX_LEV_FIELDX)
        break;
 
@@ -5917,7 +6034,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
 
       level->field[x][y] = mapped_sb_element;
 
-      /* continue with next tile column */
+      // continue with next tile column
       x++;
 
       level->fieldx = MAX(x, level->fieldx);
@@ -5925,14 +6042,14 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
 
     if (invalid_playfield_char)
     {
-      /* if first playfield line, treat invalid lines as comment lines */
+      // if first playfield line, treat invalid lines as comment lines
       if (y == 0)
        reading_playfield = FALSE;
 
       continue;
     }
 
-    /* continue with next tile row */
+    // continue with next tile row
     y++;
   }
 
@@ -5967,7 +6084,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
     sprintf(level->name, "--> Level %d <--", level_file_info->nr);
   }
 
-  /* set all empty fields beyond the border walls to invisible steel wall */
+  // set all empty fields beyond the border walls to invisible steel wall
   for (y = 0; y < level->fieldy; y++) for (x = 0; x < level->fieldx; x++)
   {
     if ((x == 0 || x == level->fieldx - 1 ||
@@ -5977,23 +6094,23 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
                     level->field, level->fieldx, level->fieldy);
   }
 
-  /* set special level settings for Sokoban levels */
+  // set special level settings for Sokoban levels
 
   level->time = 0;
   level->use_step_counter = TRUE;
 
   if (load_xsb_to_ces)
   {
-    /* special global settings can now be set in level template */
+    // special global settings can now be set in level template
 
     level->use_custom_template = TRUE;
   }
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for handling native levels                                      */
-/* ------------------------------------------------------------------------- */
+// -------------------------------------------------------------------------
+// functions for handling native levels
+// -------------------------------------------------------------------------
 
 static void LoadLevelFromFileInfo_EM(struct LevelInfo *level,
                                     struct LevelFileInfo *level_file_info,
@@ -6009,7 +6126,7 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level,
 {
   int pos = 0;
 
-  /* determine position of requested level inside level package */
+  // determine position of requested level inside level package
   if (level_file_info->packed)
     pos = level_file_info->nr - leveldir_current->first_level;
 
@@ -6060,15 +6177,15 @@ void SaveNativeLevel(struct LevelInfo *level)
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* functions for loading generic level                                       */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// functions for loading generic level
+// ----------------------------------------------------------------------------
 
 static void LoadLevelFromFileInfo(struct LevelInfo *level,
                                  struct LevelFileInfo *level_file_info,
                                  boolean level_info_only)
 {
-  /* always start with reliable default values */
+  // always start with reliable default values
   setLevelInfoToDefaults(level, level_info_only, TRUE);
 
   switch (level_file_info->type)
@@ -6105,7 +6222,7 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level,
       break;
   }
 
-  /* if level file is invalid, restore level structure to default values */
+  // if level file is invalid, restore level structure to default values
   if (level->no_valid_file)
     setLevelInfoToDefaults(level, level_info_only, FALSE);
 
@@ -6120,33 +6237,34 @@ void LoadLevelFromFilename(struct LevelInfo *level, char *filename)
 {
   static struct LevelFileInfo level_file_info;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   setFileInfoToDefaults(&level_file_info);
 
-  level_file_info.nr = 0;                      /* unknown level number */
-  level_file_info.type = LEVEL_FILE_TYPE_RND;  /* no others supported yet */
-  level_file_info.filename = filename;
+  level_file_info.nr = 0;                      // unknown level number
+  level_file_info.type = LEVEL_FILE_TYPE_RND;  // no others supported yet
+
+  setString(&level_file_info.filename, filename);
 
   LoadLevelFromFileInfo(level, &level_file_info, FALSE);
 }
 
-static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
+static void LoadLevel_InitVersion(struct LevelInfo *level)
 {
   int i, j;
 
-  if (leveldir_current == NULL)                /* only when dumping level */
+  if (leveldir_current == NULL)                // only when dumping level
     return;
 
-  /* all engine modifications also valid for levels which use latest engine */
+  // all engine modifications also valid for levels which use latest engine
   if (level->game_version < VERSION_IDENT(3,2,0,5))
   {
-    /* time bonus score was given for 10 s instead of 1 s before 3.2.0-5 */
+    // time bonus score was given for 10 s instead of 1 s before 3.2.0-5
     level->score[SC_TIME_BONUS] /= 10;
   }
 
   if (leveldir_current->latest_engine)
   {
-    /* ---------- use latest game engine ----------------------------------- */
+    // ---------- use latest game engine --------------------------------------
 
     /* For all levels which are forced to use the latest game engine version
        (normally all but user contributed, private and undefined levels), set
@@ -6171,7 +6289,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     return;
   }
 
-  /* ---------- use game engine the level was created with ----------------- */
+  // ---------- use game engine the level was created with --------------------
 
   /* For all levels which are not forced to use the latest game engine
      version (normally user contributed, private and undefined levels),
@@ -6183,45 +6301,45 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
      pre-2.0 levels, where the game version is still taken from the
      file format version used to store the level -- see above). */
 
-  /* player was faster than enemies in 1.0.0 and before */
+  // player was faster than enemies in 1.0.0 and before
   if (level->file_version == FILE_VERSION_1_0)
     for (i = 0; i < MAX_PLAYERS; i++)
       level->initial_player_stepsize[i] = STEPSIZE_FAST;
 
-  /* default behaviour for EM style gems was "slippery" only in 2.0.1 */
+  // default behaviour for EM style gems was "slippery" only in 2.0.1
   if (level->game_version == VERSION_IDENT(2,0,1,0))
     level->em_slippery_gems = TRUE;
 
-  /* springs could be pushed over pits before (pre-release version) 2.2.0 */
+  // springs could be pushed over pits before (pre-release version) 2.2.0
   if (level->game_version < VERSION_IDENT(2,2,0,0))
     level->use_spring_bug = TRUE;
 
   if (level->game_version < VERSION_IDENT(3,2,0,5))
   {
-    /* time orb caused limited time in endless time levels before 3.2.0-5 */
+    // time orb caused limited time in endless time levels before 3.2.0-5
     level->use_time_orb_bug = TRUE;
 
-    /* default behaviour for snapping was "no snap delay" before 3.2.0-5 */
+    // default behaviour for snapping was "no snap delay" before 3.2.0-5
     level->block_snap_field = FALSE;
 
-    /* extra time score was same value as time left score before 3.2.0-5 */
+    // extra time score was same value as time left score before 3.2.0-5
     level->extra_time_score = level->score[SC_TIME_BONUS];
   }
 
   if (level->game_version < VERSION_IDENT(3,2,0,7))
   {
-    /* default behaviour for snapping was "not continuous" before 3.2.0-7 */
+    // default behaviour for snapping was "not continuous" before 3.2.0-7
     level->continuous_snapping = FALSE;
   }
 
-  /* only few elements were able to actively move into acid before 3.1.0 */
-  /* trigger settings did not exist before 3.1.0; set to default "any" */
+  // only few elements were able to actively move into acid before 3.1.0
+  // trigger settings did not exist before 3.1.0; set to default "any"
   if (level->game_version < VERSION_IDENT(3,1,0,0))
   {
-    /* correct "can move into acid" settings (all zero in old levels) */
+    // correct "can move into acid" settings (all zero in old levels)
 
-    level->can_move_into_acid_bits = 0; /* nothing can move into acid */
-    level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */
+    level->can_move_into_acid_bits = 0; // nothing can move into acid
+    level->dont_collide_with_bits = 0; // nothing is deadly when colliding
 
     setMoveIntoAcidProperty(level, EL_ROBOT,     TRUE);
     setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE);
@@ -6231,7 +6349,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
       SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE);
 
-    /* correct trigger settings (stored as zero == "none" in old levels) */
+    // correct trigger settings (stored as zero == "none" in old levels)
 
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
@@ -6248,7 +6366,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* try to detect and fix "Snake Bite" levels, which are broken with 3.2.0 */
+  // try to detect and fix "Snake Bite" levels, which are broken with 3.2.0
   {
     int element = EL_CUSTOM_256;
     struct ElementInfo *ei = &element_info[element];
@@ -6270,7 +6388,7 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
       change->target_element = EL_PLAYER_1;
   }
 
-  /* try to detect and fix "Zelda" style levels, which are broken with 3.2.5 */
+  // try to detect and fix "Zelda" style levels, which are broken with 3.2.5
   if (level->game_version < VERSION_IDENT(3,2,5,0))
   {
     /* This is needed to fix a problem that was caused by a bugfix in function
@@ -6294,30 +6412,58 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     level->use_action_after_change_bug = TRUE;
   }
 
-  /* not centering level after relocating player was default only in 3.2.3 */
-  if (level->game_version == VERSION_IDENT(3,2,3,0))   /* (no pre-releases) */
+  // not centering level after relocating player was default only in 3.2.3
+  if (level->game_version == VERSION_IDENT(3,2,3,0))   // (no pre-releases)
     level->shifted_relocation = TRUE;
 
-  /* EM style elements always chain-exploded in R'n'D engine before 3.2.6 */
+  // EM style elements always chain-exploded in R'n'D engine before 3.2.6
   if (level->game_version < VERSION_IDENT(3,2,6,0))
     level->em_explodes_by_fire = TRUE;
+
+  // levels were solved by the first player entering an exit up to 4.1.0.0
+  if (level->game_version <= VERSION_IDENT(4,1,0,0))
+    level->solved_by_one_player = TRUE;
+
+  // game logic of "game of life" and "biomaze" was buggy before 4.1.1.1
+  if (level->game_version < VERSION_IDENT(4,1,1,1))
+    level->use_life_bugs = TRUE;
+
+  // only Sokoban fields (but not objects) had to be solved before 4.1.1.1
+  if (level->game_version < VERSION_IDENT(4,1,1,1))
+    level->sb_objects_needed = FALSE;
 }
 
-static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
+static void LoadLevel_InitStandardElements(struct LevelInfo *level)
 {
-  int i, j, x, y;
+  int i, x, y;
+
+  // map elements that have changed in newer versions
+  level->amoeba_content = getMappedElementByVersion(level->amoeba_content,
+                                                   level->game_version);
+  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
+    for (x = 0; x < 3; x++)
+      for (y = 0; y < 3; y++)
+       level->yamyam_content[i].e[x][y] =
+         getMappedElementByVersion(level->yamyam_content[i].e[x][y],
+                                   level->game_version);
+
+}
+
+static void LoadLevel_InitCustomElements(struct LevelInfo *level)
+{
+  int i, j;
 
-  /* map custom element change events that have changed in newer versions
-     (these following values were accidentally changed in version 3.0.1)
-     (this seems to be needed only for 'ab_levelset3' and 'ab_levelset4') */
+  // map custom element change events that have changed in newer versions
+  // (these following values were accidentally changed in version 3.0.1)
+  // (this seems to be needed only for 'ab_levelset3' and 'ab_levelset4')
   if (level->game_version <= VERSION_IDENT(3,0,0,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
       int element = EL_CUSTOM_START + i;
 
-      /* order of checking and copying events to be mapped is important */
-      /* (do not change the start and end value -- they are constant) */
+      // order of checking and copying events to be mapped is important
+      // (do not change the start and end value -- they are constant)
       for (j = CE_BY_OTHER_ACTION; j >= CE_VALUE_GETS_ZERO; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 2))
@@ -6327,8 +6473,8 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
        }
       }
 
-      /* order of checking and copying events to be mapped is important */
-      /* (do not change the start and end value -- they are constant) */
+      // order of checking and copying events to be mapped is important
+      // (do not change the start and end value -- they are constant)
       for (j = CE_PLAYER_COLLECTS_X; j >= CE_HITTING_SOMETHING; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 1))
@@ -6340,7 +6486,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* initialize "can_change" field for old levels with only one change page */
+  // initialize "can_change" field for old levels with only one change page
   if (level->game_version <= VERSION_IDENT(3,0,2,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -6352,7 +6498,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* correct custom element values (for old levels without these options) */
+  // correct custom element values (for old levels without these options)
   if (level->game_version < VERSION_IDENT(3,1,1,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -6365,7 +6511,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* correct custom element values (fix invalid values for all versions) */
+  // correct custom element values (fix invalid values for all versions)
   if (1)
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -6386,8 +6532,8 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* initialize "can_explode" field for old levels which did not store this */
-  /* !!! CHECK THIS -- "<= 3,1,0,0" IS PROBABLY WRONG !!! */
+  // initialize "can_explode" field for old levels which did not store this
+  // !!! CHECK THIS -- "<= 3,1,0,0" IS PROBABLY WRONG !!!
   if (level->game_version <= VERSION_IDENT(3,1,0,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -6403,7 +6549,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
-  /* correct previously hard-coded move delay values for maze runner style */
+  // correct previously hard-coded move delay values for maze runner style
   if (level->game_version < VERSION_IDENT(3,1,1,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -6412,62 +6558,73 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
 
       if (element_info[element].move_pattern & MV_MAZE_RUNNER_STYLE)
       {
-       /* previously hard-coded and therefore ignored */
+       // previously hard-coded and therefore ignored
        element_info[element].move_delay_fixed = 9;
        element_info[element].move_delay_random = 0;
       }
     }
   }
 
-  /* map elements that have changed in newer versions */
-  level->amoeba_content = getMappedElementByVersion(level->amoeba_content,
-                                                   level->game_version);
-  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
-    for (x = 0; x < 3; x++)
-      for (y = 0; y < 3; y++)
-       level->yamyam_content[i].e[x][y] =
-         getMappedElementByVersion(level->yamyam_content[i].e[x][y],
-                                   level->game_version);
+  // set some other uninitialized values of custom elements in older levels
+  if (level->game_version < VERSION_IDENT(3,1,0,0))
+  {
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+
+      element_info[element].access_direction = MV_ALL_DIRECTIONS;
+
+      element_info[element].explosion_delay = 17;
+      element_info[element].ignition_delay = 8;
+    }
+  }
+}
+
+static void LoadLevel_InitElements(struct LevelInfo *level)
+{
+  LoadLevel_InitStandardElements(level);
 
-  /* initialize element properties for level editor etc. */
+  if (level->file_has_custom_elements)
+    LoadLevel_InitCustomElements(level);
+
+  // initialize element properties for level editor etc.
   InitElementPropertiesEngine(level->game_version);
-  InitElementPropertiesAfterLoading(level->game_version);
   InitElementPropertiesGfxElement();
 }
 
-static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
+static void LoadLevel_InitPlayfield(struct LevelInfo *level)
 {
   int x, y;
 
-  /* map elements that have changed in newer versions */
+  // map elements that have changed in newer versions
   for (y = 0; y < level->fieldy; y++)
     for (x = 0; x < level->fieldx; x++)
       level->field[x][y] = getMappedElementByVersion(level->field[x][y],
                                                     level->game_version);
 
-  /* clear unused playfield data (nicer if level gets resized in editor) */
+  // clear unused playfield data (nicer if level gets resized in editor)
   for (x = 0; x < MAX_LEV_FIELDX; x++)
     for (y = 0; y < MAX_LEV_FIELDY; y++)
       if (x >= level->fieldx || y >= level->fieldy)
        level->field[x][y] = EL_EMPTY;
 
-  /* copy elements to runtime playfield array */
+  // copy elements to runtime playfield array
   for (x = 0; x < MAX_LEV_FIELDX; x++)
     for (y = 0; y < MAX_LEV_FIELDY; y++)
       Feld[x][y] = level->field[x][y];
 
-  /* initialize level size variables for faster access */
+  // initialize level size variables for faster access
   lev_fieldx = level->fieldx;
   lev_fieldy = level->fieldy;
 
-  /* determine border element for this level */
+  // determine border element for this level
   if (level->file_info.type == LEVEL_FILE_TYPE_DC)
-    BorderElement = EL_EMPTY;  /* (in editor, SetBorderElement() is used) */
+    BorderElement = EL_EMPTY;  // (in editor, SetBorderElement() is used)
   else
     SetBorderElement();
 }
 
-static void LoadLevel_InitNativeEngines(struct LevelInfo *level,char *filename)
+static void LoadLevel_InitNativeEngines(struct LevelInfo *level)
 {
   struct LevelFileInfo *level_file_info = &level->file_info;
 
@@ -6475,38 +6632,63 @@ static void LoadLevel_InitNativeEngines(struct LevelInfo *level,char *filename)
     CopyNativeLevel_RND_to_Native(level);
 }
 
-void LoadLevelTemplate(int nr)
+static void LoadLevelTemplate_LoadAndInit(void)
 {
-  char *filename;
-
-  setLevelFileInfo(&level_template.file_info, nr);
-  filename = level_template.file_info.filename;
-
   LoadLevelFromFileInfo(&level_template, &level_template.file_info, FALSE);
 
-  LoadLevel_InitVersion(&level_template, filename);
-  LoadLevel_InitElements(&level_template, filename);
+  LoadLevel_InitVersion(&level_template);
+  LoadLevel_InitElements(&level_template);
 
   ActivateLevelTemplate();
 }
 
-void LoadLevel(int nr)
+void LoadLevelTemplate(int nr)
 {
-  char *filename;
+  if (!fileExists(getGlobalLevelTemplateFilename()))
+  {
+    Error(ERR_WARN, "no level template found for this level");
 
-  setLevelFileInfo(&level.file_info, nr);
-  filename = level.file_info.filename;
+    return;
+  }
+
+  setLevelFileInfo(&level_template.file_info, nr);
+
+  LoadLevelTemplate_LoadAndInit();
+}
+
+static void LoadNetworkLevelTemplate(struct NetworkLevelInfo *network_level)
+{
+  copyLevelFileInfo(&network_level->tmpl_info, &level_template.file_info);
+
+  LoadLevelTemplate_LoadAndInit();
+}
 
+static void LoadLevel_LoadAndInit(struct NetworkLevelInfo *network_level)
+{
   LoadLevelFromFileInfo(&level, &level.file_info, FALSE);
 
   if (level.use_custom_template)
-    LoadLevelTemplate(-1);
+  {
+    if (network_level != NULL)
+      LoadNetworkLevelTemplate(network_level);
+    else
+      LoadLevelTemplate(-1);
+  }
+
+  LoadLevel_InitVersion(&level);
+  LoadLevel_InitElements(&level);
+  LoadLevel_InitPlayfield(&level);
+
+  LoadLevel_InitNativeEngines(&level);
+}
 
-  LoadLevel_InitVersion(&level, filename);
-  LoadLevel_InitElements(&level, filename);
-  LoadLevel_InitPlayfield(&level, filename);
+void LoadLevel(int nr)
+{
+  SetLevelSetInfo(leveldir_current->identifier, nr);
+
+  setLevelFileInfo(&level.file_info, nr);
 
-  LoadLevel_InitNativeEngines(&level, filename);
+  LoadLevel_LoadAndInit(NULL);
 }
 
 void LoadLevelInfoOnly(int nr)
@@ -6516,6 +6698,16 @@ void LoadLevelInfoOnly(int nr)
   LoadLevelFromFileInfo(&level, &level.file_info, TRUE);
 }
 
+void LoadNetworkLevel(struct NetworkLevelInfo *network_level)
+{
+  SetLevelSetInfo(network_level->leveldir_identifier,
+                 network_level->file_info.nr);
+
+  copyLevelFileInfo(&network_level->file_info, &level.file_info);
+
+  LoadLevel_LoadAndInit(network_level);
+}
+
 static int SaveLevel_VERS(FILE *file, struct LevelInfo *level)
 {
   int chunk_size = 0;
@@ -6692,7 +6884,7 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
   }
   else
   {
-    /* chunk header already written -- write empty chunk data */
+    // chunk header already written -- write empty chunk data
     WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT2_SIZE);
 
     Error(ERR_WARN, "cannot save content for element '%d'", element);
@@ -6762,7 +6954,7 @@ static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level,
     }
   }
 
-  if (check != num_changed_custom_elements)    /* should not happen */
+  if (check != num_changed_custom_elements)    // should not happen
     Error(ERR_WARN, "inconsistent number of custom element properties");
 }
 #endif
@@ -6791,7 +6983,7 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
     }
   }
 
-  if (check != num_changed_custom_elements)    /* should not happen */
+  if (check != num_changed_custom_elements)    // should not happen
     Error(ERR_WARN, "inconsistent number of custom target elements");
 }
 #endif
@@ -6820,7 +7012,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
 
        putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
 
-       /* some free bytes for future properties and padding */
+       // some free bytes for future properties and padding
        WriteUnusedBytesToFile(file, 7);
 
        putFile8Bit(file, ei->use_gfx_element);
@@ -6866,7 +7058,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
 
        putFile8Bit(file, ei->slippery_type);
 
-       /* some free bytes for future properties and padding */
+       // some free bytes for future properties and padding
        WriteUnusedBytesToFile(file, LEVEL_CPART_CUS3_UNUSED);
       }
 
@@ -6874,7 +7066,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
     }
   }
 
-  if (check != num_changed_custom_elements)    /* should not happen */
+  if (check != num_changed_custom_elements)    // should not happen
     Error(ERR_WARN, "inconsistent number of custom element properties");
 }
 #endif
@@ -6885,7 +7077,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   struct ElementInfo *ei = &element_info[element];
   int i, j, x, y;
 
-  /* ---------- custom element base property values (96 bytes) ------------- */
+  // ---------- custom element base property values (96 bytes) ----------------
 
   putFile16BitBE(file, element);
 
@@ -6894,7 +7086,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   putFile32BitBE(file, ei->properties[EP_BITFIELD_BASE_NR]);
 
-  WriteUnusedBytesToFile(file, 4);     /* reserved for more base properties */
+  WriteUnusedBytesToFile(file, 4);     // reserved for more base properties
 
   putFile8Bit(file, ei->num_change_pages);
 
@@ -6915,7 +7107,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   putFile16BitBE(file, ei->move_delay_fixed);
   putFile16BitBE(file, ei->move_delay_random);
 
-  /* bits 0 - 15 of "move_pattern" ... */
+  // bits 0 - 15 of "move_pattern" ...
   putFile16BitBE(file, ei->move_pattern & 0xffff);
   putFile8Bit(file, ei->move_direction_initial);
   putFile8Bit(file, ei->move_stepsize);
@@ -6930,7 +7122,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   putFile16BitBE(file, ei->move_leave_element);
   putFile8Bit(file, ei->move_leave_type);
 
-  /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
+  // ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible)
   putFile16BitBE(file, (ei->move_pattern >> 16) & 0xffff);
 
   putFile8Bit(file, ei->access_direction);
@@ -6939,17 +7131,17 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   putFile8Bit(file, ei->ignition_delay);
   putFile8Bit(file, ei->explosion_type);
 
-  /* some free bytes for future custom property values and padding */
+  // some free bytes for future custom property values and padding
   WriteUnusedBytesToFile(file, 1);
 
-  /* ---------- change page property values (48 bytes) --------------------- */
+  // ---------- change page property values (48 bytes) ------------------------
 
   for (i = 0; i < ei->num_change_pages; i++)
   {
     struct ElementChangeInfo *change = &ei->change_page[i];
     unsigned int event_bits;
 
-    /* bits 0 - 31 of "has_event[]" ... */
+    // bits 0 - 31 of "has_event[]" ...
     event_bits = 0;
     for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++)
       if (change->has_event[j])
@@ -6989,7 +7181,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
     putFile8Bit(file, change->action_mode);
     putFile16BitBE(file, change->action_arg);
 
-    /* ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible) */
+    // ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible)
     event_bits = 0;
     for (j = 32; j < NUM_CHANGE_EVENTS; j++)
       if (change->has_event[j])
@@ -7018,7 +7210,7 @@ static void SaveLevel_GRP1(FILE *file, struct LevelInfo *level, int element)
 
   putFile8Bit(file, group->choice_mode);
 
-  /* some free bytes for future values and padding */
+  // some free bytes for future values and padding
   WriteUnusedBytesToFile(file, 3);
 
   for (i = 0; i < MAX_ELEMENTS_IN_GROUP; i++)
@@ -7044,11 +7236,11 @@ static int SaveLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *entry,
     int value = (data_type == TYPE_BOOLEAN ? *(boolean *)value_ptr :
                 *(int *)value_ptr);
 
-    /* check if any settings have been modified before saving them */
+    // check if any settings have been modified before saving them
     if (value != default_value)
       modified = TRUE;
 
-    /* do not save if explicitly told or if unmodified default settings */
+    // do not save if explicitly told or if unmodified default settings
     if ((save_type == SAVE_CONF_NEVER) ||
        (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
       return 0;
@@ -7069,11 +7261,11 @@ static int SaveLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *entry,
     int string_length = strlen(string);
     int i;
 
-    /* check if any settings have been modified before saving them */
+    // check if any settings have been modified before saving them
     if (!strEqual(string, default_string))
       modified = TRUE;
 
-    /* do not save if explicitly told or if unmodified default settings */
+    // do not save if explicitly told or if unmodified default settings
     if ((save_type == SAVE_CONF_NEVER) ||
        (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
       return 0;
@@ -7093,12 +7285,12 @@ static int SaveLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *entry,
     int num_elements = *(int *)(entry->num_entities);
     int i;
 
-    /* check if any settings have been modified before saving them */
+    // check if any settings have been modified before saving them
     for (i = 0; i < num_elements; i++)
       if (element_array[i] != default_value)
        modified = TRUE;
 
-    /* do not save if explicitly told or if unmodified default settings */
+    // do not save if explicitly told or if unmodified default settings
     if ((save_type == SAVE_CONF_NEVER) ||
        (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
       return 0;
@@ -7118,14 +7310,14 @@ static int SaveLevel_MicroChunk(FILE *file, struct LevelFileConfigInfo *entry,
     int num_contents = *(int *)(entry->num_entities);
     int i, x, y;
 
-    /* check if any settings have been modified before saving them */
+    // check if any settings have been modified before saving them
     for (i = 0; i < num_contents; i++)
       for (y = 0; y < 3; y++)
        for (x = 0; x < 3; x++)
          if (content[i].e[x][y] != default_value)
            modified = TRUE;
 
-    /* do not save if explicitly told or if unmodified default settings */
+    // do not save if explicitly told or if unmodified default settings
     if ((save_type == SAVE_CONF_NEVER) ||
        (save_type == SAVE_CONF_WHEN_CHANGED && !modified))
       return 0;
@@ -7150,7 +7342,7 @@ static int SaveLevel_INFO(FILE *file, struct LevelInfo *level)
   int chunk_size = 0;
   int i;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
 
   for (i = 0; chunk_config_INFO[i].data_type != -1; i++)
     chunk_size += SaveLevel_MicroChunk(file, &chunk_config_INFO[i], FALSE);
@@ -7163,7 +7355,7 @@ static int SaveLevel_ELEM(FILE *file, struct LevelInfo *level)
   int chunk_size = 0;
   int i;
 
-  li = *level;         /* copy level data into temporary buffer */
+  li = *level;         // copy level data into temporary buffer
 
   for (i = 0; chunk_config_ELEM[i].data_type != -1; i++)
     chunk_size += SaveLevel_MicroChunk(file, &chunk_config_ELEM[i], TRUE);
@@ -7179,7 +7371,7 @@ static int SaveLevel_NOTE(FILE *file, struct LevelInfo *level, int element)
 
   chunk_size += putFile16BitBE(file, element);
 
-  /* copy envelope data into temporary buffer */
+  // copy envelope data into temporary buffer
   xx_envelope = level->envelope[envelope_nr];
 
   for (i = 0; chunk_config_NOTE[i].data_type != -1; i++)
@@ -7196,9 +7388,9 @@ static int SaveLevel_CUSX(FILE *file, struct LevelInfo *level, int element)
 
   chunk_size += putFile16BitBE(file, element);
 
-  xx_ei = *ei;         /* copy element data into temporary buffer */
+  xx_ei = *ei;         // copy element data into temporary buffer
 
-  /* set default description string for this specific element */
+  // set default description string for this specific element
   strcpy(xx_default_description, getDefaultElementDescription(ei));
 
   for (i = 0; chunk_config_CUSX_base[i].data_type != -1; i++)
@@ -7210,7 +7402,7 @@ static int SaveLevel_CUSX(FILE *file, struct LevelInfo *level, int element)
 
     xx_current_change_page = i;
 
-    xx_change = *change;       /* copy change data into temporary buffer */
+    xx_change = *change;       // copy change data into temporary buffer
 
     resetEventBits();
     setEventBitsFromEventFlags(change);
@@ -7232,10 +7424,10 @@ static int SaveLevel_GRPX(FILE *file, struct LevelInfo *level, int element)
 
   chunk_size += putFile16BitBE(file, element);
 
-  xx_ei = *ei;         /* copy element data into temporary buffer */
-  xx_group = *group;   /* copy group data into temporary buffer */
+  xx_ei = *ei;         // copy element data into temporary buffer
+  xx_group = *group;   // copy group data into temporary buffer
 
-  /* set default description string for this specific element */
+  // set default description string for this specific element
   strcpy(xx_default_description, getDefaultElementDescription(ei));
 
   for (i = 0; chunk_config_GRPX[i].data_type != -1; i++)
@@ -7290,7 +7482,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
   SaveLevel_BODY(file, level);
 
   chunk_size = SaveLevel_ELEM(NULL, level);
-  if (chunk_size > LEVEL_CHUNK_ELEM_UNCHANGED)         /* save if changed */
+  if (chunk_size > LEVEL_CHUNK_ELEM_UNCHANGED)         // save if changed
   {
     putFileChunkBE(file, "ELEM", chunk_size);
     SaveLevel_ELEM(file, level);
@@ -7301,14 +7493,14 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
     int element = EL_ENVELOPE_1 + i;
 
     chunk_size = SaveLevel_NOTE(NULL, level, element);
-    if (chunk_size > LEVEL_CHUNK_NOTE_UNCHANGED)       /* save if changed */
+    if (chunk_size > LEVEL_CHUNK_NOTE_UNCHANGED)       // save if changed
     {
       putFileChunkBE(file, "NOTE", chunk_size);
       SaveLevel_NOTE(file, level, element);
     }
   }
 
-  /* if not using template level, check for non-default custom/group elements */
+  // if not using template level, check for non-default custom/group elements
   if (!level->use_custom_template || save_as_template)
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -7316,7 +7508,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
       int element = EL_CUSTOM_START + i;
 
       chunk_size = SaveLevel_CUSX(NULL, level, element);
-      if (chunk_size > LEVEL_CHUNK_CUSX_UNCHANGED)     /* save if changed */
+      if (chunk_size > LEVEL_CHUNK_CUSX_UNCHANGED)     // save if changed
       {
        putFileChunkBE(file, "CUSX", chunk_size);
        SaveLevel_CUSX(file, level, element);
@@ -7328,7 +7520,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename,
       int element = EL_GROUP_START + i;
 
       chunk_size = SaveLevel_GRPX(NULL, level, element);
-      if (chunk_size > LEVEL_CHUNK_GRPX_UNCHANGED)     /* save if changed */
+      if (chunk_size > LEVEL_CHUNK_GRPX_UNCHANGED)     // save if changed
       {
        putFileChunkBE(file, "GRPX", chunk_size);
        SaveLevel_GRPX(file, level, element);
@@ -7348,7 +7540,7 @@ void SaveLevel(int nr)
   SaveLevelFromFilename(&level, filename, FALSE);
 }
 
-void SaveLevelTemplate()
+void SaveLevelTemplate(void)
 {
   char *filename = getLocalLevelTemplateFilename();
 
@@ -7414,23 +7606,23 @@ void DumpLevel(struct LevelInfo *level)
 }
 
 
-/* ========================================================================= */
-/* tape file functions                                                       */
-/* ========================================================================= */
+// ============================================================================
+// tape file functions
+// ============================================================================
 
-static void setTapeInfoToDefaults()
+static void setTapeInfoToDefaults(void)
 {
   int i;
 
-  /* always start with reliable default values (empty tape) */
+  // always start with reliable default values (empty tape)
   TapeErase();
 
-  /* default values (also for pre-1.2 tapes) with only the first player */
+  // default values (also for pre-1.2 tapes) with only the first player
   tape.player_participates[0] = TRUE;
   for (i = 1; i < MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
 
-  /* at least one (default: the first) player participates in every tape */
+  // at least one (default: the first) player participates in every tape
   tape.num_participating_players = 1;
 
   tape.level_nr = level_nr;
@@ -7460,13 +7652,13 @@ static int LoadTape_HEAD(File *file, int chunk_size, struct TapeInfo *tape)
   tape->date        = getFile32BitBE(file);
   tape->length      = getFile32BitBE(file);
 
-  /* read header fields that are new since version 1.2 */
+  // read header fields that are new since version 1.2
   if (tape->file_version >= FILE_VERSION_1_2)
   {
     byte store_participating_players = getFile8Bit(file);
     int engine_version;
 
-    /* since version 1.2, tapes store which players participate in the tape */
+    // since version 1.2, tapes store which players participate in the tape
     tape->num_participating_players = 0;
     for (i = 0; i < MAX_PLAYERS; i++)
     {
@@ -7479,6 +7671,8 @@ static int LoadTape_HEAD(File *file, int chunk_size, struct TapeInfo *tape)
       }
     }
 
+    tape->use_mouse = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+
     ReadUnusedBytesFromFile(file, TAPE_CHUNK_HEAD_UNUSED);
 
     engine_version = getFileVersion(file);
@@ -7514,8 +7708,9 @@ static int LoadTape_INFO(File *file, int chunk_size, struct TapeInfo *tape)
 static int LoadTape_BODY(File *file, int chunk_size, struct TapeInfo *tape)
 {
   int i, j;
-  int chunk_size_expected =
-    (tape->num_participating_players + 1) * tape->length;
+  int tape_pos_size =
+    (tape->use_mouse ? 3 : tape->num_participating_players) + 1;
+  int chunk_size_expected = tape_pos_size * tape->length;
 
   if (chunk_size_expected != chunk_size)
   {
@@ -7537,20 +7732,31 @@ static int LoadTape_BODY(File *file, int chunk_size, struct TapeInfo *tape)
       break;
     }
 
-    for (j = 0; j < MAX_PLAYERS; j++)
+    if (tape->use_mouse)
     {
-      tape->pos[i].action[j] = MV_NONE;
+      tape->pos[i].action[TAPE_ACTION_LX]     = getFile8Bit(file);
+      tape->pos[i].action[TAPE_ACTION_LY]     = getFile8Bit(file);
+      tape->pos[i].action[TAPE_ACTION_BUTTON] = getFile8Bit(file);
 
-      if (tape->player_participates[j])
-       tape->pos[i].action[j] = getFile8Bit(file);
+      tape->pos[i].action[TAPE_ACTION_UNUSED] = 0;
+    }
+    else
+    {
+      for (j = 0; j < MAX_PLAYERS; j++)
+      {
+       tape->pos[i].action[j] = MV_NONE;
+
+       if (tape->player_participates[j])
+         tape->pos[i].action[j] = getFile8Bit(file);
+      }
     }
 
     tape->pos[i].delay = getFile8Bit(file);
 
     if (tape->file_version == FILE_VERSION_1_0)
     {
-      /* eliminate possible diagonal moves in old tapes */
-      /* this is only for backward compatibility */
+      // eliminate possible diagonal moves in old tapes
+      // this is only for backward compatibility
 
       byte joy_dir[4] = { JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN };
       byte action = tape->pos[i].action[0];
@@ -7576,15 +7782,15 @@ static int LoadTape_BODY(File *file, int chunk_size, struct TapeInfo *tape)
     }
     else if (tape->file_version < FILE_VERSION_2_0)
     {
-      /* convert pre-2.0 tapes to new tape format */
+      // convert pre-2.0 tapes to new tape format
 
       if (tape->pos[i].delay > 1)
       {
-       /* action part */
+       // action part
        tape->pos[i + 1] = tape->pos[i];
        tape->pos[i + 1].delay = 1;
 
-       /* delay part */
+       // delay part
        for (j = 0; j < MAX_PLAYERS; j++)
          tape->pos[i].action[j] = MV_NONE;
        tape->pos[i].delay--;
@@ -7599,12 +7805,12 @@ static int LoadTape_BODY(File *file, int chunk_size, struct TapeInfo *tape)
   }
 
   if (i != tape->length)
-    chunk_size = (tape->num_participating_players + 1) * i;
+    chunk_size = tape_pos_size * i;
 
   return chunk_size;
 }
 
-void LoadTape_SokobanSolution(char *filename)
+static void LoadTape_SokobanSolution(char *filename)
 {
   File *file;
   int move_delay = TILESIZE / level.initial_player_stepsize[0];
@@ -7657,7 +7863,7 @@ void LoadTape_SokobanSolution(char *filename)
       case '\r':
       case '\t':
       case ' ':
-       /* ignore white-space characters */
+       // ignore white-space characters
        break;
 
       default:
@@ -7685,7 +7891,7 @@ void LoadTapeFromFilename(char *filename)
   File *file;
   int chunk_size;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   setTapeInfoToDefaults();
 
   if (strSuffix(filename, ".sln"))
@@ -7705,7 +7911,7 @@ void LoadTapeFromFilename(char *filename)
   getFileChunkBE(file, chunk_name, NULL);
   if (strEqual(chunk_name, "RND1"))
   {
-    getFile32BitBE(file);              /* not used */
+    getFile32BitBE(file);              // not used
 
     getFileChunkBE(file, chunk_name, NULL);
     if (!strEqual(chunk_name, "TAPE"))
@@ -7719,7 +7925,7 @@ void LoadTapeFromFilename(char *filename)
       return;
     }
   }
-  else /* check for pre-2.0 file format with cookie string */
+  else // check for pre-2.0 file format with cookie string
   {
     strcpy(cookie, chunk_name);
     if (getStringFromFile(file, &cookie[4], MAX_LINE_LEN - 4) == NULL)
@@ -7749,13 +7955,13 @@ void LoadTapeFromFilename(char *filename)
       return;
     }
 
-    /* pre-2.0 tape files have no game version, so use file version here */
+    // pre-2.0 tape files have no game version, so use file version here
     tape.game_version = tape.file_version;
   }
 
   if (tape.file_version < FILE_VERSION_1_2)
   {
-    /* tape files from versions before 1.2.0 without chunk structure */
+    // tape files from versions before 1.2.0 without chunk structure
     LoadTape_HEAD(file, TAPE_CHUNK_HEAD_SIZE, &tape);
     LoadTape_BODY(file, 2 * tape.length,      &tape);
   }
@@ -7799,13 +8005,13 @@ void LoadTapeFromFilename(char *filename)
       }
       else
       {
-       /* call function to load this tape chunk */
+       // call function to load this tape chunk
        int chunk_size_expected =
          (chunk_info[i].loader)(file, chunk_size, &tape);
 
-       /* the size of some chunks cannot be checked before reading other
-          chunks first (like "HEAD" and "BODY") that contain some header
-          information, so check them here */
+       // the size of some chunks cannot be checked before reading other
+       // chunks first (like "HEAD" and "BODY") that contain some header
+       // information, so check them here
        if (chunk_size_expected != chunk_size)
        {
          Error(ERR_WARN, "wrong size (%d) of chunk '%s' in tape file '%s'",
@@ -7857,7 +8063,7 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape)
   int i;
   byte store_participating_players = 0;
 
-  /* set bits for participating players for compact storage */
+  // set bits for participating players for compact storage
   for (i = 0; i < MAX_PLAYERS; i++)
     if (tape->player_participates[i])
       store_participating_players |= (1 << i);
@@ -7868,7 +8074,9 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape)
 
   putFile8Bit(file, store_participating_players);
 
-  /* unused bytes not at the end here for 4-byte alignment of engine_version */
+  putFile8Bit(file, (tape->use_mouse ? 1 : 0));
+
+  // unused bytes not at the end here for 4-byte alignment of engine_version
   WriteUnusedBytesToFile(file, TAPE_CHUNK_HEAD_UNUSED);
 
   putFileVersion(file, tape->engine_version);
@@ -7893,9 +8101,18 @@ static void SaveTape_BODY(FILE *file, struct TapeInfo *tape)
 
   for (i = 0; i < tape->length; i++)
   {
-    for (j = 0; j < MAX_PLAYERS; j++)
-      if (tape->player_participates[j])
-       putFile8Bit(file, tape->pos[i].action[j]);
+    if (tape->use_mouse)
+    {
+      putFile8Bit(file, tape->pos[i].action[TAPE_ACTION_LX]);
+      putFile8Bit(file, tape->pos[i].action[TAPE_ACTION_LY]);
+      putFile8Bit(file, tape->pos[i].action[TAPE_ACTION_BUTTON]);
+    }
+    else
+    {
+      for (j = 0; j < MAX_PLAYERS; j++)
+       if (tape->player_participates[j])
+         putFile8Bit(file, tape->pos[i].action[j]);
+    }
 
     putFile8Bit(file, tape->pos[i].delay);
   }
@@ -7906,6 +8123,7 @@ void SaveTape(int nr)
   char *filename = getTapeFilename(nr);
   FILE *file;
   int num_participating_players = 0;
+  int tape_pos_size;
   int info_chunk_size;
   int body_chunk_size;
   int i;
@@ -7921,13 +8139,15 @@ void SaveTape(int nr)
   tape.file_version = FILE_VERSION_ACTUAL;
   tape.game_version = GAME_VERSION_ACTUAL;
 
-  /* count number of participating players  */
+  // count number of participating players
   for (i = 0; i < MAX_PLAYERS; i++)
     if (tape.player_participates[i])
       num_participating_players++;
 
+  tape_pos_size = (tape.use_mouse ? 3 : num_participating_players) + 1;
+
   info_chunk_size = 2 + (strlen(tape.level_identifier) + 1) + 2;
-  body_chunk_size = (num_participating_players + 1) * tape.length;
+  body_chunk_size = tape_pos_size * tape.length;
 
   putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
   putFileChunkBE(file, "TAPE", CHUNK_SIZE_NONE);
@@ -7951,18 +8171,19 @@ void SaveTape(int nr)
   tape.changed = FALSE;
 }
 
-boolean SaveTapeChecked(int nr)
+static boolean SaveTapeCheckedExt(int nr, char *msg_replace, char *msg_saved,
+                                 unsigned int req_state_added)
 {
   char *filename = getTapeFilename(nr);
   boolean new_tape = !fileExists(filename);
   boolean tape_saved = FALSE;
 
-  if (new_tape || Request("Replace old tape?", REQ_ASK))
+  if (new_tape || Request(msg_replace, REQ_ASK | req_state_added))
   {
     SaveTape(nr);
 
     if (new_tape)
-      Request("Tape saved!", REQ_CONFIRM);
+      Request(msg_saved, REQ_CONFIRM | req_state_added);
 
     tape_saved = TRUE;
   }
@@ -7970,6 +8191,17 @@ boolean SaveTapeChecked(int nr)
   return tape_saved;
 }
 
+boolean SaveTapeChecked(int nr)
+{
+  return SaveTapeCheckedExt(nr, "Replace old tape?", "Tape saved!", 0);
+}
+
+boolean SaveTapeChecked_LevelSolved(int nr)
+{
+  return SaveTapeCheckedExt(nr, "Level solved! Replace old tape?",
+                               "Level solved! Tape saved!", REQ_STAY_OPEN);
+}
+
 void DumpTape(struct TapeInfo *tape)
 {
   int tape_frame_counter;
@@ -8026,9 +8258,9 @@ void DumpTape(struct TapeInfo *tape)
 }
 
 
-/* ========================================================================= */
-/* score file functions                                                      */
-/* ========================================================================= */
+// ============================================================================
+// score file functions
+// ============================================================================
 
 void LoadScore(int nr)
 {
@@ -8039,7 +8271,7 @@ void LoadScore(int nr)
   char *line_ptr;
   FILE *file;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   for (i = 0; i < MAX_SCORE_ENTRIES; i++)
   {
     strcpy(highscore[i].Name, EMPTY_PLAYER_NAME);
@@ -8049,7 +8281,7 @@ void LoadScore(int nr)
   if (!(file = fopen(filename, MODE_READ)))
     return;
 
-  /* check file identifier */
+  // check file identifier
   if (fgets(cookie, MAX_LINE_LEN, file) == NULL)
     cookie[0] = '\0';
   if (strlen(cookie) > 0 && cookie[strlen(cookie) - 1] == '\n')
@@ -8093,7 +8325,8 @@ void SaveScore(int nr)
   char *filename = getScoreFilename(nr);
   FILE *file;
 
-  InitScoreDirectory(leveldir_current->subdir);
+  // used instead of "leveldir_current->subdir" (for network games)
+  InitScoreDirectory(levelset.identifier);
 
   if (!(file = fopen(filename, MODE_WRITE)))
   {
@@ -8112,404 +8345,768 @@ void SaveScore(int nr)
 }
 
 
-/* ========================================================================= */
-/* setup file functions                                                      */
-/* ========================================================================= */
+// ============================================================================
+// setup file functions
+// ============================================================================
 
 #define TOKEN_STR_PLAYER_PREFIX                        "player_"
 
-/* global setup */
-#define SETUP_TOKEN_PLAYER_NAME                        0
-#define SETUP_TOKEN_SOUND                      1
-#define SETUP_TOKEN_SOUND_LOOPS                        2
-#define SETUP_TOKEN_SOUND_MUSIC                        3
-#define SETUP_TOKEN_SOUND_SIMPLE               4
-#define SETUP_TOKEN_TOONS                      5
-#define SETUP_TOKEN_SCROLL_DELAY               6
-#define SETUP_TOKEN_SCROLL_DELAY_VALUE         7
-#define SETUP_TOKEN_ENGINE_SNAPSHOT_MODE       8
-#define SETUP_TOKEN_ENGINE_SNAPSHOT_MEMORY     9
-#define SETUP_TOKEN_FADE_SCREENS               10
-#define SETUP_TOKEN_AUTORECORD                 11
-#define SETUP_TOKEN_SHOW_TITLESCREEN           12
-#define SETUP_TOKEN_QUICK_DOORS                        13
-#define SETUP_TOKEN_TEAM_MODE                  14
-#define SETUP_TOKEN_HANDICAP                   15
-#define SETUP_TOKEN_SKIP_LEVELS                        16
-#define SETUP_TOKEN_INCREMENT_LEVELS           17
-#define SETUP_TOKEN_TIME_LIMIT                 18
-#define SETUP_TOKEN_FULLSCREEN                 19
-#define SETUP_TOKEN_WINDOW_SCALING_PERCENT     20
-#define SETUP_TOKEN_WINDOW_SCALING_QUALITY     21
-#define SETUP_TOKEN_SCREEN_RENDERING_MODE      22
-#define SETUP_TOKEN_ASK_ON_ESCAPE              23
-#define SETUP_TOKEN_ASK_ON_ESCAPE_EDITOR       24
-#define SETUP_TOKEN_QUICK_SWITCH               25
-#define SETUP_TOKEN_INPUT_ON_FOCUS             26
-#define SETUP_TOKEN_PREFER_AGA_GRAPHICS                27
-#define SETUP_TOKEN_GAME_FRAME_DELAY           28
-#define SETUP_TOKEN_SP_SHOW_BORDER_ELEMENTS    29
-#define SETUP_TOKEN_SMALL_GAME_GRAPHICS                30
-#define SETUP_TOKEN_SHOW_SNAPSHOT_BUTTONS      31
-#define SETUP_TOKEN_GRAPHICS_SET               32
-#define SETUP_TOKEN_SOUNDS_SET                 33
-#define SETUP_TOKEN_MUSIC_SET                  34
-#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS    35
-#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS      36
-#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC       37
-#define SETUP_TOKEN_VOLUME_SIMPLE              38
-#define SETUP_TOKEN_VOLUME_LOOPS               39
-#define SETUP_TOKEN_VOLUME_MUSIC               40
-#define SETUP_TOKEN_TOUCH_CONTROL_TYPE         41
-#define SETUP_TOKEN_TOUCH_MOVE_DISTANCE                42
-#define SETUP_TOKEN_TOUCH_DROP_DISTANCE                43
-
-#define NUM_GLOBAL_SETUP_TOKENS                        44
-
-/* editor setup */
-#define SETUP_TOKEN_EDITOR_EL_CLASSIC          0
-#define SETUP_TOKEN_EDITOR_EL_CUSTOM           1
-#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED     2
-#define SETUP_TOKEN_EDITOR_EL_DYNAMIC          3
-#define SETUP_TOKEN_EDITOR_EL_HEADLINES                4
-#define SETUP_TOKEN_EDITOR_SHOW_ELEMENT_TOKEN  5
-
-#define NUM_EDITOR_SETUP_TOKENS                        6
-
-/* editor cascade setup */
-#define SETUP_TOKEN_EDITOR_CASCADE_BD          0
-#define SETUP_TOKEN_EDITOR_CASCADE_EM          1
-#define SETUP_TOKEN_EDITOR_CASCADE_EMC         2
-#define SETUP_TOKEN_EDITOR_CASCADE_RND         3
-#define SETUP_TOKEN_EDITOR_CASCADE_SB          4
-#define SETUP_TOKEN_EDITOR_CASCADE_SP          5
-#define SETUP_TOKEN_EDITOR_CASCADE_DC          6
-#define SETUP_TOKEN_EDITOR_CASCADE_DX          7
-#define SETUP_TOKEN_EDITOR_CASCADE_TEXT                8
-#define SETUP_TOKEN_EDITOR_CASCADE_STEELTEXT   9
-#define SETUP_TOKEN_EDITOR_CASCADE_CE          10
-#define SETUP_TOKEN_EDITOR_CASCADE_GE          11
-#define SETUP_TOKEN_EDITOR_CASCADE_REF         12
-#define SETUP_TOKEN_EDITOR_CASCADE_USER                13
-#define SETUP_TOKEN_EDITOR_CASCADE_DYNAMIC     14
-
-#define NUM_EDITOR_CASCADE_SETUP_TOKENS                15
-
-/* shortcut setup */
-#define SETUP_TOKEN_SHORTCUT_SAVE_GAME         0
-#define SETUP_TOKEN_SHORTCUT_LOAD_GAME         1
-#define SETUP_TOKEN_SHORTCUT_TOGGLE_PAUSE      2
-#define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_1    3
-#define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_2    4
-#define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_3    5
-#define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_4    6
-#define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_ALL  7
-#define SETUP_TOKEN_SHORTCUT_TAPE_EJECT                8
-#define SETUP_TOKEN_SHORTCUT_TAPE_EXTRA                9
-#define SETUP_TOKEN_SHORTCUT_TAPE_STOP         10
-#define SETUP_TOKEN_SHORTCUT_TAPE_PAUSE                11
-#define SETUP_TOKEN_SHORTCUT_TAPE_RECORD       12
-#define SETUP_TOKEN_SHORTCUT_TAPE_PLAY         13
-#define SETUP_TOKEN_SHORTCUT_SOUND_SIMPLE      14
-#define SETUP_TOKEN_SHORTCUT_SOUND_LOOPS       15
-#define SETUP_TOKEN_SHORTCUT_SOUND_MUSIC       16
-#define SETUP_TOKEN_SHORTCUT_SNAP_LEFT         17
-#define SETUP_TOKEN_SHORTCUT_SNAP_RIGHT                18
-#define SETUP_TOKEN_SHORTCUT_SNAP_UP           19
-#define SETUP_TOKEN_SHORTCUT_SNAP_DOWN         20
-
-#define NUM_SHORTCUT_SETUP_TOKENS              21
-
-/* player setup */
-#define SETUP_TOKEN_PLAYER_USE_JOYSTICK                0
-#define SETUP_TOKEN_PLAYER_JOY_DEVICE_NAME     1
-#define SETUP_TOKEN_PLAYER_JOY_XLEFT           2
-#define SETUP_TOKEN_PLAYER_JOY_XMIDDLE         3
-#define SETUP_TOKEN_PLAYER_JOY_XRIGHT          4
-#define SETUP_TOKEN_PLAYER_JOY_YUPPER          5
-#define SETUP_TOKEN_PLAYER_JOY_YMIDDLE         6
-#define SETUP_TOKEN_PLAYER_JOY_YLOWER          7
-#define SETUP_TOKEN_PLAYER_JOY_SNAP            8
-#define SETUP_TOKEN_PLAYER_JOY_DROP            9
-#define SETUP_TOKEN_PLAYER_KEY_LEFT            10
-#define SETUP_TOKEN_PLAYER_KEY_RIGHT           11
-#define SETUP_TOKEN_PLAYER_KEY_UP              12
-#define SETUP_TOKEN_PLAYER_KEY_DOWN            13
-#define SETUP_TOKEN_PLAYER_KEY_SNAP            14
-#define SETUP_TOKEN_PLAYER_KEY_DROP            15
-
-#define NUM_PLAYER_SETUP_TOKENS                        16
-
-/* system setup */
-#define SETUP_TOKEN_SYSTEM_SDL_VIDEODRIVER     0
-#define SETUP_TOKEN_SYSTEM_SDL_AUDIODRIVER     1
-#define SETUP_TOKEN_SYSTEM_AUDIO_FRAGMENT_SIZE 2
-
-#define NUM_SYSTEM_SETUP_TOKENS                        3
-
-/* internal setup */
-#define SETUP_TOKEN_INT_PROGRAM_TITLE          0
-#define SETUP_TOKEN_INT_PROGRAM_VERSION                1
-#define SETUP_TOKEN_INT_PROGRAM_AUTHOR         2
-#define SETUP_TOKEN_INT_PROGRAM_EMAIL          3
-#define SETUP_TOKEN_INT_PROGRAM_WEBSITE                4
-#define SETUP_TOKEN_INT_PROGRAM_COPYRIGHT      5
-#define SETUP_TOKEN_INT_PROGRAM_COMPANY                6
-#define SETUP_TOKEN_INT_PROGRAM_ICON_FILE      7
-#define SETUP_TOKEN_INT_DEFAULT_GRAPHICS_SET   8
-#define SETUP_TOKEN_INT_DEFAULT_SOUNDS_SET     9
-#define SETUP_TOKEN_INT_DEFAULT_MUSIC_SET      10
-#define SETUP_TOKEN_INT_FALLBACK_GRAPHICS_FILE 11
-#define SETUP_TOKEN_INT_FALLBACK_SOUNDS_FILE   12
-#define SETUP_TOKEN_INT_FALLBACK_MUSIC_FILE    13
-#define SETUP_TOKEN_INT_DEFAULT_LEVEL_SERIES   14
-#define SETUP_TOKEN_INT_CHOOSE_FROM_TOP_LEVELDIR 15
-#define SETUP_TOKEN_INT_SHOW_SCALING_IN_TITLE  16
-#define SETUP_TOKEN_INT_DEFAULT_WINDOW_WIDTH   17
-#define SETUP_TOKEN_INT_DEFAULT_WINDOW_HEIGHT  18
-
-#define NUM_INTERNAL_SETUP_TOKENS              19
-
-/* debug setup */
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_0                0
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_1                1
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_2                2
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_3                3
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_4                4
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_5                5
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_6                6
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_7                7
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_8                8
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_9                9
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_0    10
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_1    11
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_2    12
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_3    13
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_4    14
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_5    15
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_6    16
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_7    17
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_8    18
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_KEY_9    19
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_USE_MOD_KEY 20
-#define SETUP_TOKEN_DEBUG_FRAME_DELAY_GAME_ONLY        21
-#define SETUP_TOKEN_DEBUG_SHOW_FRAMES_PER_SECOND 22
-
-#define NUM_DEBUG_SETUP_TOKENS                 23
-
-/* options setup */
-#define SETUP_TOKEN_OPTIONS_VERBOSE            0
-
-#define NUM_OPTIONS_SETUP_TOKENS               1
-
-
-static struct SetupInfo si;
-static struct SetupEditorInfo sei;
-static struct SetupEditorCascadeInfo seci;
-static struct SetupShortcutInfo ssi;
-static struct SetupInputInfo sii;
-static struct SetupSystemInfo syi;
-static struct SetupInternalInfo sxi;
-static struct SetupDebugInfo sdi;
-static struct OptionInfo soi;
 
 static struct TokenInfo global_setup_tokens[] =
 {
-  { TYPE_STRING, &si.player_name,             "player_name"            },
-  { TYPE_SWITCH, &si.sound,                   "sound"                  },
-  { TYPE_SWITCH, &si.sound_loops,             "repeating_sound_loops"  },
-  { TYPE_SWITCH, &si.sound_music,             "background_music"       },
-  { TYPE_SWITCH, &si.sound_simple,            "simple_sound_effects"   },
-  { TYPE_SWITCH, &si.toons,                   "toons"                  },
-  { TYPE_SWITCH, &si.scroll_delay,            "scroll_delay"           },
-  { TYPE_INTEGER,&si.scroll_delay_value,      "scroll_delay_value"     },
-  { TYPE_STRING, &si.engine_snapshot_mode,    "engine_snapshot_mode"   },
-  { TYPE_INTEGER,&si.engine_snapshot_memory,  "engine_snapshot_memory" },
-  { TYPE_SWITCH, &si.fade_screens,            "fade_screens"           },
-  { TYPE_SWITCH, &si.autorecord,              "automatic_tape_recording"},
-  { TYPE_SWITCH, &si.show_titlescreen,        "show_titlescreen"       },
-  { TYPE_SWITCH, &si.quick_doors,             "quick_doors"            },
-  { TYPE_SWITCH, &si.team_mode,               "team_mode"              },
-  { TYPE_SWITCH, &si.handicap,                "handicap"               },
-  { TYPE_SWITCH, &si.skip_levels,             "skip_levels"            },
-  { TYPE_SWITCH, &si.increment_levels,        "increment_levels"       },
-  { TYPE_SWITCH, &si.time_limit,              "time_limit"             },
-  { TYPE_SWITCH, &si.fullscreen,              "fullscreen"             },
-  { TYPE_INTEGER,&si.window_scaling_percent,  "window_scaling_percent" },
-  { TYPE_STRING, &si.window_scaling_quality,  "window_scaling_quality" },
-  { TYPE_STRING, &si.screen_rendering_mode,   "screen_rendering_mode"  },
-  { TYPE_SWITCH, &si.ask_on_escape,           "ask_on_escape"          },
-  { TYPE_SWITCH, &si.ask_on_escape_editor,    "ask_on_escape_editor"   },
-  { TYPE_SWITCH, &si.quick_switch,            "quick_player_switch"    },
-  { TYPE_SWITCH, &si.input_on_focus,          "input_on_focus"         },
-  { TYPE_SWITCH, &si.prefer_aga_graphics,     "prefer_aga_graphics"    },
-  { TYPE_INTEGER,&si.game_frame_delay,        "game_frame_delay"       },
-  { TYPE_SWITCH, &si.sp_show_border_elements, "sp_show_border_elements"        },
-  { TYPE_SWITCH, &si.small_game_graphics,     "small_game_graphics"    },
-  { TYPE_SWITCH, &si.show_snapshot_buttons,   "show_snapshot_buttons"  },
-  { TYPE_STRING, &si.graphics_set,            "graphics_set"           },
-  { TYPE_STRING, &si.sounds_set,              "sounds_set"             },
-  { TYPE_STRING, &si.music_set,               "music_set"              },
-  { TYPE_SWITCH3,&si.override_level_graphics, "override_level_graphics"        },
-  { TYPE_SWITCH3,&si.override_level_sounds,   "override_level_sounds"  },
-  { TYPE_SWITCH3,&si.override_level_music,    "override_level_music"   },
-  { TYPE_INTEGER,&si.volume_simple,           "volume_simple"          },
-  { TYPE_INTEGER,&si.volume_loops,            "volume_loops"           },
-  { TYPE_INTEGER,&si.volume_music,            "volume_music"           },
-  { TYPE_STRING, &si.touch.control_type,      "touch.control_type"     },
-  { TYPE_INTEGER,&si.touch.move_distance,     "touch.move_distance"    },
-  { TYPE_INTEGER,&si.touch.drop_distance,     "touch.drop_distance"    },
-};
-
-static struct TokenInfo editor_setup_tokens[] =
-{
-  { TYPE_SWITCH, &sei.el_classic,      "editor.el_classic"             },
-  { TYPE_SWITCH, &sei.el_custom,       "editor.el_custom"              },
-  { TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined"        },
-  { TYPE_SWITCH, &sei.el_dynamic,      "editor.el_dynamic"             },
-  { TYPE_SWITCH, &sei.el_headlines,    "editor.el_headlines"           },
-  { TYPE_SWITCH, &sei.show_element_token,"editor.show_element_token"   },
-};
-
-static struct TokenInfo editor_cascade_setup_tokens[] =
-{
-  { TYPE_SWITCH, &seci.el_bd,          "editor.cascade.el_bd"          },
-  { TYPE_SWITCH, &seci.el_em,          "editor.cascade.el_em"          },
-  { TYPE_SWITCH, &seci.el_emc,         "editor.cascade.el_emc"         },
-  { TYPE_SWITCH, &seci.el_rnd,         "editor.cascade.el_rnd"         },
-  { TYPE_SWITCH, &seci.el_sb,          "editor.cascade.el_sb"          },
-  { TYPE_SWITCH, &seci.el_sp,          "editor.cascade.el_sp"          },
-  { TYPE_SWITCH, &seci.el_dc,          "editor.cascade.el_dc"          },
-  { TYPE_SWITCH, &seci.el_dx,          "editor.cascade.el_dx"          },
-  { TYPE_SWITCH, &seci.el_mm,          "editor.cascade.el_mm"          },
-  { TYPE_SWITCH, &seci.el_df,          "editor.cascade.el_df"          },
-  { TYPE_SWITCH, &seci.el_chars,       "editor.cascade.el_chars"       },
-  { TYPE_SWITCH, &seci.el_steel_chars, "editor.cascade.el_steel_chars" },
-  { TYPE_SWITCH, &seci.el_ce,          "editor.cascade.el_ce"          },
-  { TYPE_SWITCH, &seci.el_ge,          "editor.cascade.el_ge"          },
-  { TYPE_SWITCH, &seci.el_ref,         "editor.cascade.el_ref"         },
-  { TYPE_SWITCH, &seci.el_user,                "editor.cascade.el_user"        },
-  { TYPE_SWITCH, &seci.el_dynamic,     "editor.cascade.el_dynamic"     },
-};
-
-static struct TokenInfo shortcut_setup_tokens[] =
-{
-  { TYPE_KEY_X11, &ssi.save_game,      "shortcut.save_game"            },
-  { TYPE_KEY_X11, &ssi.load_game,      "shortcut.load_game"            },
-  { TYPE_KEY_X11, &ssi.toggle_pause,   "shortcut.toggle_pause"         },
-  { TYPE_KEY_X11, &ssi.focus_player[0],        "shortcut.focus_player_1"       },
-  { TYPE_KEY_X11, &ssi.focus_player[1],        "shortcut.focus_player_2"       },
-  { TYPE_KEY_X11, &ssi.focus_player[2],        "shortcut.focus_player_3"       },
-  { TYPE_KEY_X11, &ssi.focus_player[3],        "shortcut.focus_player_4"       },
-  { TYPE_KEY_X11, &ssi.focus_player_all,"shortcut.focus_player_all"    },
-  { TYPE_KEY_X11, &ssi.tape_eject,     "shortcut.tape_eject"           },
-  { TYPE_KEY_X11, &ssi.tape_extra,     "shortcut.tape_extra"           },
-  { TYPE_KEY_X11, &ssi.tape_stop,      "shortcut.tape_stop"            },
-  { TYPE_KEY_X11, &ssi.tape_pause,     "shortcut.tape_pause"           },
-  { TYPE_KEY_X11, &ssi.tape_record,    "shortcut.tape_record"          },
-  { TYPE_KEY_X11, &ssi.tape_play,      "shortcut.tape_play"            },
-  { TYPE_KEY_X11, &ssi.sound_simple,   "shortcut.sound_simple"         },
-  { TYPE_KEY_X11, &ssi.sound_loops,    "shortcut.sound_loops"          },
-  { TYPE_KEY_X11, &ssi.sound_music,    "shortcut.sound_music"          },
-  { TYPE_KEY_X11, &ssi.snap_left,      "shortcut.snap_left"            },
-  { TYPE_KEY_X11, &ssi.snap_right,     "shortcut.snap_right"           },
-  { TYPE_KEY_X11, &ssi.snap_up,                "shortcut.snap_up"              },
-  { TYPE_KEY_X11, &ssi.snap_down,      "shortcut.snap_down"            },
-};
-
-static struct TokenInfo player_setup_tokens[] =
-{
-  { TYPE_BOOLEAN, &sii.use_joystick,   ".use_joystick"                 },
-  { TYPE_STRING,  &sii.joy.device_name,        ".joy.device_name"              },
-  { TYPE_INTEGER, &sii.joy.xleft,      ".joy.xleft"                    },
-  { TYPE_INTEGER, &sii.joy.xmiddle,    ".joy.xmiddle"                  },
-  { TYPE_INTEGER, &sii.joy.xright,     ".joy.xright"                   },
-  { TYPE_INTEGER, &sii.joy.yupper,     ".joy.yupper"                   },
-  { TYPE_INTEGER, &sii.joy.ymiddle,    ".joy.ymiddle"                  },
-  { TYPE_INTEGER, &sii.joy.ylower,     ".joy.ylower"                   },
-  { TYPE_INTEGER, &sii.joy.snap,       ".joy.snap_field"               },
-  { TYPE_INTEGER, &sii.joy.drop,       ".joy.place_bomb"               },
-  { TYPE_KEY_X11, &sii.key.left,       ".key.move_left"                },
-  { TYPE_KEY_X11, &sii.key.right,      ".key.move_right"               },
-  { TYPE_KEY_X11, &sii.key.up,         ".key.move_up"                  },
-  { TYPE_KEY_X11, &sii.key.down,       ".key.move_down"                },
-  { TYPE_KEY_X11, &sii.key.snap,       ".key.snap_field"               },
-  { TYPE_KEY_X11, &sii.key.drop,       ".key.place_bomb"               },
-};
-
-static struct TokenInfo system_setup_tokens[] =
-{
-  { TYPE_STRING,  &syi.sdl_videodriver,    "system.sdl_videodriver"    },
-  { TYPE_STRING,  &syi.sdl_audiodriver,           "system.sdl_audiodriver"     },
-  { TYPE_INTEGER, &syi.audio_fragment_size,"system.audio_fragment_size"        },
-};
-
-static struct TokenInfo internal_setup_tokens[] =
-{
-  { TYPE_STRING, &sxi.program_title,           "program_title"         },
-  { TYPE_STRING, &sxi.program_version,         "program_version"       },
-  { TYPE_STRING, &sxi.program_author,          "program_author"        },
-  { TYPE_STRING, &sxi.program_email,           "program_email"         },
-  { TYPE_STRING, &sxi.program_website,         "program_website"       },
-  { TYPE_STRING, &sxi.program_copyright,       "program_copyright"     },
-  { TYPE_STRING, &sxi.program_company,         "program_company"       },
-  { TYPE_STRING, &sxi.program_icon_file,       "program_icon_file"     },
-  { TYPE_STRING, &sxi.default_graphics_set,    "default_graphics_set"  },
-  { TYPE_STRING, &sxi.default_sounds_set,      "default_sounds_set"    },
-  { TYPE_STRING, &sxi.default_music_set,       "default_music_set"     },
-  { TYPE_STRING, &sxi.fallback_graphics_file,  "fallback_graphics_file"},
-  { TYPE_STRING, &sxi.fallback_sounds_file,    "fallback_sounds_file"  },
-  { TYPE_STRING, &sxi.fallback_music_file,     "fallback_music_file"   },
-  { TYPE_STRING, &sxi.default_level_series,    "default_level_series"  },
-  { TYPE_BOOLEAN,&sxi.choose_from_top_leveldir,        "choose_from_top_leveldir" },
-  { TYPE_BOOLEAN,&sxi.show_scaling_in_title,   "show_scaling_in_title" },
-  { TYPE_INTEGER,&sxi.default_window_width,    "default_window_width"  },
-  { TYPE_INTEGER,&sxi.default_window_height,   "default_window_height" },
-};
-
-static struct TokenInfo debug_setup_tokens[] =
-{
-  { TYPE_INTEGER, &sdi.frame_delay[0],         "debug.frame_delay_0"   },
-  { TYPE_INTEGER, &sdi.frame_delay[1],         "debug.frame_delay_1"   },
-  { TYPE_INTEGER, &sdi.frame_delay[2],         "debug.frame_delay_2"   },
-  { TYPE_INTEGER, &sdi.frame_delay[3],         "debug.frame_delay_3"   },
-  { TYPE_INTEGER, &sdi.frame_delay[4],         "debug.frame_delay_4"   },
-  { TYPE_INTEGER, &sdi.frame_delay[5],         "debug.frame_delay_5"   },
-  { TYPE_INTEGER, &sdi.frame_delay[6],         "debug.frame_delay_6"   },
-  { TYPE_INTEGER, &sdi.frame_delay[7],         "debug.frame_delay_7"   },
-  { TYPE_INTEGER, &sdi.frame_delay[8],         "debug.frame_delay_8"   },
-  { TYPE_INTEGER, &sdi.frame_delay[9],         "debug.frame_delay_9"   },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[0],     "debug.key.frame_delay_0" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[1],     "debug.key.frame_delay_1" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[2],     "debug.key.frame_delay_2" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[3],     "debug.key.frame_delay_3" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[4],     "debug.key.frame_delay_4" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[5],     "debug.key.frame_delay_5" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[6],     "debug.key.frame_delay_6" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[7],     "debug.key.frame_delay_7" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[8],     "debug.key.frame_delay_8" },
-  { TYPE_KEY_X11, &sdi.frame_delay_key[9],     "debug.key.frame_delay_9" },
-  { TYPE_BOOLEAN, &sdi.frame_delay_use_mod_key,"debug.frame_delay.use_mod_key"},
-  { TYPE_BOOLEAN, &sdi.frame_delay_game_only,  "debug.frame_delay.game_only" },
-  { TYPE_BOOLEAN, &sdi.show_frames_per_second, "debug.show_frames_per_second" },
-};
-
-static struct TokenInfo options_setup_tokens[] =
-{
-  { TYPE_BOOLEAN, &soi.verbose,                "options.verbose"               },
-};
-
-static char *get_corrected_login_name(char *login_name)
-{
-  /* needed because player name must be a fixed length string */
-  char *login_name_new = checked_malloc(MAX_PLAYER_NAME_LEN + 1);
-
-  strncpy(login_name_new, login_name, MAX_PLAYER_NAME_LEN);
-  login_name_new[MAX_PLAYER_NAME_LEN] = '\0';
-
-  if (strlen(login_name) > MAX_PLAYER_NAME_LEN)                /* name has been cut */
-    if (strchr(login_name_new, ' '))
-      *strchr(login_name_new, ' ') = '\0';
+  {
+    TYPE_STRING,
+    &setup.player_name,                                "player_name"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.sound,                              "sound"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.sound_loops,                                "repeating_sound_loops"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.sound_music,                                "background_music"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.sound_simple,                       "simple_sound_effects"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.toons,                              "toons"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.scroll_delay,                       "scroll_delay"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.scroll_delay_value,                 "scroll_delay_value"
+  },
+  {
+    TYPE_STRING,
+    &setup.engine_snapshot_mode,               "engine_snapshot_mode"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.engine_snapshot_memory,             "engine_snapshot_memory"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.fade_screens,                       "fade_screens"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.autorecord,                         "automatic_tape_recording"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.show_titlescreen,                   "show_titlescreen"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.quick_doors,                                "quick_doors"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.team_mode,                          "team_mode"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.handicap,                           "handicap"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.skip_levels,                                "skip_levels"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.increment_levels,                   "increment_levels"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.auto_play_next_level,               "auto_play_next_level"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.skip_scores_after_game,             "skip_scores_after_game"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.time_limit,                         "time_limit"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.fullscreen,                         "fullscreen"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.window_scaling_percent,             "window_scaling_percent"
+  },
+  {
+    TYPE_STRING,
+    &setup.window_scaling_quality,             "window_scaling_quality"
+  },
+  {
+    TYPE_STRING,
+    &setup.screen_rendering_mode,              "screen_rendering_mode"
+  },
+  {
+    TYPE_STRING,
+    &setup.vsync_mode,                         "vsync_mode"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.ask_on_escape,                      "ask_on_escape"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.ask_on_escape_editor,               "ask_on_escape_editor"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.ask_on_game_over,                   "ask_on_game_over"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.quick_switch,                       "quick_player_switch"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.input_on_focus,                     "input_on_focus"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.prefer_aga_graphics,                        "prefer_aga_graphics"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.game_speed_extended,                        "game_speed_extended"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.game_frame_delay,                   "game_frame_delay"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.sp_show_border_elements,            "sp_show_border_elements"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.small_game_graphics,                        "small_game_graphics"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.show_snapshot_buttons,              "show_snapshot_buttons"
+  },
+  {
+    TYPE_STRING,
+    &setup.graphics_set,                       "graphics_set"
+  },
+  {
+    TYPE_STRING,
+    &setup.sounds_set,                         "sounds_set"
+  },
+  {
+    TYPE_STRING,
+    &setup.music_set,                          "music_set"
+  },
+  {
+    TYPE_SWITCH3,
+    &setup.override_level_graphics,            "override_level_graphics"
+  },
+  {
+    TYPE_SWITCH3,
+    &setup.override_level_sounds,              "override_level_sounds"
+  },
+  {
+    TYPE_SWITCH3,
+    &setup.override_level_music,               "override_level_music"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.volume_simple,                      "volume_simple"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.volume_loops,                       "volume_loops"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.volume_music,                       "volume_music"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.network_mode,                       "network_mode"
+  },
+  {
+    TYPE_PLAYER,
+    &setup.network_player_nr,                  "network_player"
+  },
+  {
+    TYPE_STRING,
+    &setup.network_server_hostname,            "network_server_hostname"
+  },
+  {
+    TYPE_STRING,
+    &setup.touch.control_type,                 "touch.control_type"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.move_distance,                        "touch.move_distance"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.drop_distance,                        "touch.drop_distance"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.transparency,                 "touch.transparency"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.draw_outlined,                        "touch.draw_outlined"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.draw_pressed,                 "touch.draw_pressed"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.grid_xsize[0],                        "touch.virtual_buttons.0.xsize"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.grid_ysize[0],                        "touch.virtual_buttons.0.ysize"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.grid_xsize[1],                        "touch.virtual_buttons.1.xsize"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.touch.grid_ysize[1],                        "touch.virtual_buttons.1.ysize"
+  },
+};
+
+static struct TokenInfo auto_setup_tokens[] =
+{
+  {
+    TYPE_INTEGER,
+    &setup.auto_setup.editor_zoom_tilesize,    "editor.zoom_tilesize"
+  },
+};
+
+static struct TokenInfo editor_setup_tokens[] =
+{
+  {
+    TYPE_SWITCH,
+    &setup.editor.el_classic,                  "editor.el_classic"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor.el_custom,                   "editor.el_custom"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor.el_user_defined,             "editor.el_user_defined"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor.el_dynamic,                  "editor.el_dynamic"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor.el_headlines,                        "editor.el_headlines"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor.show_element_token,          "editor.show_element_token"
+  },
+};
+
+static struct TokenInfo editor_cascade_setup_tokens[] =
+{
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_bd,               "editor.cascade.el_bd"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_em,               "editor.cascade.el_em"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_emc,              "editor.cascade.el_emc"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_rnd,              "editor.cascade.el_rnd"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_sb,               "editor.cascade.el_sb"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_sp,               "editor.cascade.el_sp"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_dc,               "editor.cascade.el_dc"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_dx,               "editor.cascade.el_dx"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_mm,               "editor.cascade.el_mm"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_df,               "editor.cascade.el_df"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_chars,            "editor.cascade.el_chars"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_steel_chars,      "editor.cascade.el_steel_chars"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_ce,               "editor.cascade.el_ce"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_ge,               "editor.cascade.el_ge"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_ref,              "editor.cascade.el_ref"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_user,             "editor.cascade.el_user"
+  },
+  {
+    TYPE_SWITCH,
+    &setup.editor_cascade.el_dynamic,          "editor.cascade.el_dynamic"
+  },
+};
+
+static struct TokenInfo shortcut_setup_tokens[] =
+{
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.save_game,                 "shortcut.save_game"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.load_game,                 "shortcut.load_game"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.toggle_pause,              "shortcut.toggle_pause"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.focus_player[0],           "shortcut.focus_player_1"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.focus_player[1],           "shortcut.focus_player_2"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.focus_player[2],           "shortcut.focus_player_3"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.focus_player[3],           "shortcut.focus_player_4"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.focus_player_all,          "shortcut.focus_player_all"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_eject,                        "shortcut.tape_eject"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_extra,                        "shortcut.tape_extra"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_stop,                 "shortcut.tape_stop"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_pause,                        "shortcut.tape_pause"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_record,               "shortcut.tape_record"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.tape_play,                 "shortcut.tape_play"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.sound_simple,              "shortcut.sound_simple"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.sound_loops,               "shortcut.sound_loops"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.sound_music,               "shortcut.sound_music"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.snap_left,                 "shortcut.snap_left"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.snap_right,                        "shortcut.snap_right"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.snap_up,                   "shortcut.snap_up"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.shortcut.snap_down,                 "shortcut.snap_down"
+  },
+};
+
+static struct SetupInputInfo setup_input;
+static struct TokenInfo player_setup_tokens[] =
+{
+  {
+    TYPE_BOOLEAN,
+    &setup_input.use_joystick,                 ".use_joystick"
+  },
+  {
+    TYPE_STRING,
+    &setup_input.joy.device_name,              ".joy.device_name"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.xleft,                    ".joy.xleft"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.xmiddle,                  ".joy.xmiddle"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.xright,                   ".joy.xright"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.yupper,                   ".joy.yupper"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.ymiddle,                  ".joy.ymiddle"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.ylower,                   ".joy.ylower"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.snap,                     ".joy.snap_field"
+  },
+  {
+    TYPE_INTEGER,
+    &setup_input.joy.drop,                     ".joy.place_bomb"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.left,                     ".key.move_left"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.right,                    ".key.move_right"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.up,                       ".key.move_up"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.down,                     ".key.move_down"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.snap,                     ".key.snap_field"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup_input.key.drop,                     ".key.place_bomb"
+  },
+};
+
+static struct TokenInfo system_setup_tokens[] =
+{
+  {
+    TYPE_STRING,
+    &setup.system.sdl_videodriver,             "system.sdl_videodriver"
+  },
+  {
+    TYPE_STRING,
+    &setup.system.sdl_audiodriver,             "system.sdl_audiodriver"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.system.audio_fragment_size,         "system.audio_fragment_size"
+  },
+};
+
+static struct TokenInfo internal_setup_tokens[] =
+{
+  {
+    TYPE_STRING,
+    &setup.internal.program_title,             "program_title"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_version,           "program_version"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_author,            "program_author"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_email,             "program_email"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_website,           "program_website"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_copyright,         "program_copyright"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_company,           "program_company"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.program_icon_file,         "program_icon_file"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.default_graphics_set,      "default_graphics_set"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.default_sounds_set,                "default_sounds_set"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.default_music_set,         "default_music_set"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.fallback_graphics_file,    "fallback_graphics_file"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.fallback_sounds_file,      "fallback_sounds_file"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.fallback_music_file,       "fallback_music_file"
+  },
+  {
+    TYPE_STRING,
+    &setup.internal.default_level_series,      "default_level_series"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.internal.default_window_width,      "default_window_width"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.internal.default_window_height,     "default_window_height"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.choose_from_top_leveldir,  "choose_from_top_leveldir"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.show_scaling_in_title,     "show_scaling_in_title"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_game,                 "menu_game"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_editor,               "menu_editor"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_graphics,             "menu_graphics"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_sound,                        "menu_sound"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_artwork,              "menu_artwork"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_input,                        "menu_input"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_touch,                        "menu_touch"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts,            "menu_shortcuts"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_exit,                 "menu_exit"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_save_and_exit,                "menu_save_and_exit"
+  },
+};
+
+static struct TokenInfo debug_setup_tokens[] =
+{
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[0],               "debug.frame_delay_0"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[1],               "debug.frame_delay_1"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[2],               "debug.frame_delay_2"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[3],               "debug.frame_delay_3"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[4],               "debug.frame_delay_4"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[5],               "debug.frame_delay_5"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[6],               "debug.frame_delay_6"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[7],               "debug.frame_delay_7"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[8],               "debug.frame_delay_8"
+  },
+  {
+    TYPE_INTEGER,
+    &setup.debug.frame_delay[9],               "debug.frame_delay_9"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[0],           "debug.key.frame_delay_0"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[1],           "debug.key.frame_delay_1"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[2],           "debug.key.frame_delay_2"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[3],           "debug.key.frame_delay_3"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[4],           "debug.key.frame_delay_4"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[5],           "debug.key.frame_delay_5"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[6],           "debug.key.frame_delay_6"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[7],           "debug.key.frame_delay_7"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[8],           "debug.key.frame_delay_8"
+  },
+  {
+    TYPE_KEY_X11,
+    &setup.debug.frame_delay_key[9],           "debug.key.frame_delay_9"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.debug.frame_delay_use_mod_key,      "debug.frame_delay.use_mod_key"},
+  {
+    TYPE_BOOLEAN,
+    &setup.debug.frame_delay_game_only,                "debug.frame_delay.game_only"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.debug.show_frames_per_second,       "debug.show_frames_per_second"
+  },
+};
+
+static struct TokenInfo options_setup_tokens[] =
+{
+  {
+    TYPE_BOOLEAN,
+    &setup.options.verbose,                    "options.verbose"
+  },
+};
+
+static char *get_corrected_login_name(char *login_name)
+{
+  // needed because player name must be a fixed length string
+  char *login_name_new = checked_malloc(MAX_PLAYER_NAME_LEN + 1);
+
+  strncpy(login_name_new, login_name, MAX_PLAYER_NAME_LEN);
+  login_name_new[MAX_PLAYER_NAME_LEN] = '\0';
+
+  if (strlen(login_name) > MAX_PLAYER_NAME_LEN)                // name has been cut
+    if (strchr(login_name_new, ' '))
+      *strchr(login_name_new, ' ') = '\0';
 
   return login_name_new;
 }
@@ -8537,16 +9134,21 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->handicap = TRUE;
   si->skip_levels = TRUE;
   si->increment_levels = TRUE;
+  si->auto_play_next_level = TRUE;
+  si->skip_scores_after_game = FALSE;
   si->time_limit = TRUE;
   si->fullscreen = FALSE;
   si->window_scaling_percent = STD_WINDOW_SCALING_PERCENT;
   si->window_scaling_quality = getStringCopy(SCALING_QUALITY_DEFAULT);
   si->screen_rendering_mode = getStringCopy(STR_SPECIAL_RENDERING_DEFAULT);
+  si->vsync_mode = getStringCopy(STR_VSYNC_MODE_DEFAULT);
   si->ask_on_escape = TRUE;
   si->ask_on_escape_editor = TRUE;
+  si->ask_on_game_over = TRUE;
   si->quick_switch = FALSE;
   si->input_on_focus = FALSE;
   si->prefer_aga_graphics = TRUE;
+  si->game_speed_extended = FALSE;
   si->game_frame_delay = GAME_FRAME_DELAY;
   si->sp_show_border_elements = FALSE;
   si->small_game_graphics = FALSE;
@@ -8560,13 +9162,69 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->override_level_sounds = FALSE;
   si->override_level_music = FALSE;
 
-  si->volume_simple = 100;             /* percent */
-  si->volume_loops = 100;              /* percent */
-  si->volume_music = 100;              /* percent */
+  si->volume_simple = 100;             // percent
+  si->volume_loops = 100;              // percent
+  si->volume_music = 100;              // percent
+
+  si->network_mode = FALSE;
+  si->network_player_nr = 0;           // first player
+  si->network_server_hostname = getStringCopy(STR_NETWORK_AUTO_DETECT);
 
   si->touch.control_type = getStringCopy(TOUCH_CONTROL_DEFAULT);
-  si->touch.move_distance = TOUCH_MOVE_DISTANCE_DEFAULT;       /* percent */
-  si->touch.drop_distance = TOUCH_DROP_DISTANCE_DEFAULT;       /* percent */
+  si->touch.move_distance = TOUCH_MOVE_DISTANCE_DEFAULT;       // percent
+  si->touch.drop_distance = TOUCH_DROP_DISTANCE_DEFAULT;       // percent
+  si->touch.transparency = TOUCH_TRANSPARENCY_DEFAULT;         // percent
+  si->touch.draw_outlined = TRUE;
+  si->touch.draw_pressed = TRUE;
+
+  for (i = 0; i < 2; i++)
+  {
+    char *default_grid_button[6][2] =
+    {
+      { "      ", "  ^^  " },
+      { "      ", "  ^^  " },
+      { "      ", "<<  >>" },
+      { "      ", "<<  >>" },
+      { "111222", "  vv  " },
+      { "111222", "  vv  " }
+    };
+    int grid_xsize = DEFAULT_GRID_XSIZE(i);
+    int grid_ysize = DEFAULT_GRID_YSIZE(i);
+    int min_xsize = MIN(6, grid_xsize);
+    int min_ysize = MIN(6, grid_ysize);
+    int startx = grid_xsize - min_xsize;
+    int starty = grid_ysize - min_ysize;
+    int x, y;
+
+    // virtual buttons grid can only be set to defaults if video is initialized
+    // (this will be repeated if virtual buttons are not loaded from setup file)
+    if (video.initialized)
+    {
+      si->touch.grid_xsize[i] = grid_xsize;
+      si->touch.grid_ysize[i] = grid_ysize;
+    }
+    else
+    {
+      si->touch.grid_xsize[i] = -1;
+      si->touch.grid_ysize[i] = -1;
+    }
+
+    for (x = 0; x < MAX_GRID_XSIZE; x++)
+      for (y = 0; y < MAX_GRID_YSIZE; y++)
+       si->touch.grid_button[i][x][y] = CHAR_GRID_BUTTON_NONE;
+
+    for (x = 0; x < min_xsize; x++)
+      for (y = 0; y < min_ysize; y++)
+       si->touch.grid_button[i][x][starty + y] =
+         default_grid_button[y][0][x];
+
+    for (x = 0; x < min_xsize; x++)
+      for (y = 0; y < min_ysize; y++)
+       si->touch.grid_button[i][startx + x][starty + y] =
+         default_grid_button[y][1][x];
+  }
+
+  si->touch.grid_initialized           = video.initialized;
 
   si->editor.el_boulderdash            = TRUE;
   si->editor.el_emerald_mine           = TRUE;
@@ -8704,6 +9362,11 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
 #endif
 }
 
+static void setSetupInfoToDefaults_AutoSetup(struct SetupInfo *si)
+{
+  si->auto_setup.editor_zoom_tilesize = MINI_TILESIZE;
+}
+
 static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)
 {
   si->editor_cascade.el_bd             = TRUE;
@@ -8739,11 +9402,8 @@ static char *getHideSetupToken(void *setup_value)
   return hide_setup_token;
 }
 
-static void setHideSetupEntry(void *setup_value_raw)
+void setHideSetupEntry(void *setup_value)
 {
-  /* !!! DIRTY WORKAROUND; TO BE FIXED AFTER THE MM ENGINE RELEASE !!! */
-  void *setup_value = setup_value_raw - (void *)&si + (void *)&setup;
-
   char *hide_setup_token = getHideSetupToken(setup_value);
 
   if (setup_value != NULL)
@@ -8765,10 +9425,10 @@ static void setSetupInfoFromTokenText(SetupFileHash *setup_file_hash,
   char *token_hide_text = getStringCat2(token_text, ".hide");
   char *token_hide_value = getHashEntry(setup_file_hash, token_hide_text);
 
-  /* set the value of this setup option in the setup option structure */
+  // set the value of this setup option in the setup option structure
   setSetupInfo(token_info, token_nr, getHashEntry(setup_file_hash, token_text));
 
-  /* check if this setup option should be hidden in the setup menu */
+  // check if this setup option should be hidden in the setup menu
   if (token_hide_value != NULL && get_boolean_from_string(token_hide_value))
     setHideSetupEntry(token_info[token_nr].value);
 }
@@ -8781,43 +9441,71 @@ static void setSetupInfoFromTokenInfo(SetupFileHash *setup_file_hash,
                            token_info[token_nr].text);
 }
 
-static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
-{
-  int i, pnr;
+static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
+{
+  int i, pnr;
+
+  if (!setup_file_hash)
+    return;
+
+  if (hide_setup_hash == NULL)
+    hide_setup_hash = newSetupFileHash();
+
+  for (i = 0; i < ARRAY_SIZE(global_setup_tokens); i++)
+    setSetupInfoFromTokenInfo(setup_file_hash, global_setup_tokens, i);
+
+  setup.touch.grid_initialized = TRUE;
+  for (i = 0; i < 2; i++)
+  {
+    int grid_xsize = setup.touch.grid_xsize[i];
+    int grid_ysize = setup.touch.grid_ysize[i];
+    int x, y;
+
+    // if virtual buttons are not loaded from setup file, repeat initializing
+    // virtual buttons grid with default values later when video is initialized
+    if (grid_xsize == -1 ||
+       grid_ysize == -1)
+    {
+      setup.touch.grid_initialized = FALSE;
+
+      continue;
+    }
+
+    for (y = 0; y < grid_ysize; y++)
+    {
+      char token_string[MAX_LINE_LEN];
 
-  if (!setup_file_hash)
-    return;
+      sprintf(token_string, "touch.virtual_buttons.%d.%02d", i, y);
 
-  if (hide_setup_hash == NULL)
-    hide_setup_hash = newSetupFileHash();
+      char *value_string = getHashEntry(setup_file_hash, token_string);
 
-  /* global setup */
-  si = setup;
-  for (i = 0; i < NUM_GLOBAL_SETUP_TOKENS; i++)
-    setSetupInfoFromTokenInfo(setup_file_hash, global_setup_tokens, i);
-  setup = si;
+      if (value_string == NULL)
+       continue;
+
+      for (x = 0; x < grid_xsize; x++)
+      {
+       char c = value_string[x];
+
+       setup.touch.grid_button[i][x][y] =
+         (c == '.' ? CHAR_GRID_BUTTON_NONE : c);
+      }
+    }
+  }
 
-  /* editor setup */
-  sei = setup.editor;
-  for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(editor_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, editor_setup_tokens, i);
-  setup.editor = sei;
 
-  /* shortcut setup */
-  ssi = setup.shortcut;
-  for (i = 0; i < NUM_SHORTCUT_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(shortcut_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, shortcut_setup_tokens, i);
-  setup.shortcut = ssi;
 
-  /* player setup */
   for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
   {
     char prefix[30];
 
     sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
 
-    sii = setup.input[pnr];
-    for (i = 0; i < NUM_PLAYER_SETUP_TOKENS; i++)
+    setup_input = setup.input[pnr];
+    for (i = 0; i < ARRAY_SIZE(player_setup_tokens); i++)
     {
       char full_token[100];
 
@@ -8825,32 +9513,35 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
       setSetupInfoFromTokenText(setup_file_hash, player_setup_tokens, i,
                                full_token);
     }
-    setup.input[pnr] = sii;
+    setup.input[pnr] = setup_input;
   }
 
-  /* system setup */
-  syi = setup.system;
-  for (i = 0; i < NUM_SYSTEM_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(system_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, system_setup_tokens, i);
-  setup.system = syi;
 
-  /* internal setup */
-  sxi = setup.internal;
-  for (i = 0; i < NUM_INTERNAL_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(internal_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, internal_setup_tokens, i);
-  setup.internal = sxi;
 
-  /* debug setup */
-  sdi = setup.debug;
-  for (i = 0; i < NUM_DEBUG_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(debug_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, debug_setup_tokens, i);
-  setup.debug = sdi;
 
-  /* options setup */
-  soi = setup.options;
-  for (i = 0; i < NUM_OPTIONS_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(options_setup_tokens); i++)
     setSetupInfoFromTokenInfo(setup_file_hash, options_setup_tokens, i);
-  setup.options = soi;
+
+  setHideRelatedSetupEntries();
+}
+
+static void decodeSetupFileHash_AutoSetup(SetupFileHash *setup_file_hash)
+{
+  int i;
+
+  if (!setup_file_hash)
+    return;
+
+  for (i = 0; i < ARRAY_SIZE(auto_setup_tokens); i++)
+    setSetupInfo(auto_setup_tokens, i,
+                getHashEntry(setup_file_hash,
+                             auto_setup_tokens[i].text));
 }
 
 static void decodeSetupFileHash_EditorCascade(SetupFileHash *setup_file_hash)
@@ -8860,13 +9551,10 @@ static void decodeSetupFileHash_EditorCascade(SetupFileHash *setup_file_hash)
   if (!setup_file_hash)
     return;
 
-  /* editor cascade setup */
-  seci = setup.editor_cascade;
-  for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(editor_cascade_setup_tokens); i++)
     setSetupInfo(editor_cascade_setup_tokens, i,
                 getHashEntry(setup_file_hash,
                              editor_cascade_setup_tokens[i].text));
-  setup.editor_cascade = seci;
 }
 
 void LoadSetupFromFilename(char *filename)
@@ -8885,41 +9573,41 @@ void LoadSetupFromFilename(char *filename)
   }
 }
 
-static void LoadSetup_SpecialPostProcessing()
+static void LoadSetup_SpecialPostProcessing(void)
 {
   char *player_name_new;
 
-  /* needed to work around problems with fixed length strings */
+  // needed to work around problems with fixed length strings
   player_name_new = get_corrected_login_name(setup.player_name);
   free(setup.player_name);
   setup.player_name = player_name_new;
 
-  /* "scroll_delay: on(3) / off(0)" was replaced by scroll delay value */
+  // "scroll_delay: on(3) / off(0)" was replaced by scroll delay value
   if (setup.scroll_delay == FALSE)
   {
     setup.scroll_delay_value = MIN_SCROLL_DELAY;
-    setup.scroll_delay = TRUE;                 /* now always "on" */
+    setup.scroll_delay = TRUE;                 // now always "on"
   }
 
-  /* make sure that scroll delay value stays inside valid range */
+  // make sure that scroll delay value stays inside valid range
   setup.scroll_delay_value =
     MIN(MAX(MIN_SCROLL_DELAY, setup.scroll_delay_value), MAX_SCROLL_DELAY);
 }
 
-void LoadSetup()
+void LoadSetup(void)
 {
   char *filename;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   setSetupInfoToDefaults(&setup);
 
-  /* try to load setup values from default setup file */
+  // try to load setup values from default setup file
   filename = getDefaultSetupFilename();
 
   if (fileExists(filename))
     LoadSetupFromFilename(filename);
 
-  /* try to load setup values from user setup file */
+  // try to load setup values from user setup file
   filename = getSetupFilename();
 
   LoadSetupFromFilename(filename);
@@ -8927,12 +9615,32 @@ void LoadSetup()
   LoadSetup_SpecialPostProcessing();
 }
 
-void LoadSetup_EditorCascade()
+void LoadSetup_AutoSetup(void)
+{
+  char *filename = getPath2(getSetupDir(), AUTOSETUP_FILENAME);
+  SetupFileHash *setup_file_hash = NULL;
+
+  // always start with reliable default values
+  setSetupInfoToDefaults_AutoSetup(&setup);
+
+  setup_file_hash = loadSetupFileHash(filename);
+
+  if (setup_file_hash)
+  {
+    decodeSetupFileHash_AutoSetup(setup_file_hash);
+
+    freeSetupFileHash(setup_file_hash);
+  }
+
+  free(filename);
+}
+
+void LoadSetup_EditorCascade(void)
 {
   char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME);
   SetupFileHash *setup_file_hash = NULL;
 
-  /* always start with reliable default values */
+  // always start with reliable default values
   setSetupInfoToDefaults_EditorCascade(&setup);
 
   setup_file_hash = loadSetupFileHash(filename);
@@ -8996,7 +9704,7 @@ static void LoadSetup_ReadGameControllerMappings(SetupFileHash *mappings_hash,
   fclose(file);
 }
 
-void SaveSetup()
+void SaveSetup(void)
 {
   char *filename = getSetupFilename();
   FILE *file;
@@ -9012,33 +9720,57 @@ void SaveSetup()
 
   fprintFileHeader(file, SETUP_FILENAME);
 
-  /* global setup */
-  si = setup;
-  for (i = 0; i < NUM_GLOBAL_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(global_setup_tokens); i++)
   {
-    /* just to make things nicer :) */
-    if (i == SETUP_TOKEN_PLAYER_NAME + 1 ||
-       i == SETUP_TOKEN_GRAPHICS_SET ||
-       i == SETUP_TOKEN_VOLUME_SIMPLE ||
-       i == SETUP_TOKEN_TOUCH_CONTROL_TYPE)
+    // just to make things nicer :)
+    if (global_setup_tokens[i].value == &setup.sound                   ||
+       global_setup_tokens[i].value == &setup.graphics_set             ||
+       global_setup_tokens[i].value == &setup.volume_simple            ||
+       global_setup_tokens[i].value == &setup.network_mode             ||
+       global_setup_tokens[i].value == &setup.touch.control_type       ||
+       global_setup_tokens[i].value == &setup.touch.grid_xsize[0]      ||
+       global_setup_tokens[i].value == &setup.touch.grid_xsize[1])
       fprintf(file, "\n");
 
     fprintf(file, "%s\n", getSetupLine(global_setup_tokens, "", i));
   }
 
-  /* editor setup */
-  sei = setup.editor;
+  for (i = 0; i < 2; i++)
+  {
+    int grid_xsize = setup.touch.grid_xsize[i];
+    int grid_ysize = setup.touch.grid_ysize[i];
+    int x, y;
+
+    fprintf(file, "\n");
+
+    for (y = 0; y < grid_ysize; y++)
+    {
+      char token_string[MAX_LINE_LEN];
+      char value_string[MAX_LINE_LEN];
+
+      sprintf(token_string, "touch.virtual_buttons.%d.%02d", i, y);
+
+      for (x = 0; x < grid_xsize; x++)
+      {
+       char c = setup.touch.grid_button[i][x][y];
+
+       value_string[x] = (c == CHAR_GRID_BUTTON_NONE ? '.' : c);
+      }
+
+      value_string[grid_xsize] = '\0';
+
+      fprintf(file, "%s\n", getFormattedSetupEntry(token_string, value_string));
+    }
+  }
+
   fprintf(file, "\n");
-  for (i = 0; i < NUM_EDITOR_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(editor_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(editor_setup_tokens, "", i));
 
-  /* shortcut setup */
-  ssi = setup.shortcut;
   fprintf(file, "\n");
-  for (i = 0; i < NUM_SHORTCUT_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(shortcut_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(shortcut_setup_tokens, "", i));
 
-  /* player setup */
   for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
   {
     char prefix[30];
@@ -9046,30 +9778,23 @@ void SaveSetup()
     sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
     fprintf(file, "\n");
 
-    sii = setup.input[pnr];
-    for (i = 0; i < NUM_PLAYER_SETUP_TOKENS; i++)
+    setup_input = setup.input[pnr];
+    for (i = 0; i < ARRAY_SIZE(player_setup_tokens); i++)
       fprintf(file, "%s\n", getSetupLine(player_setup_tokens, prefix, i));
   }
 
-  /* system setup */
-  syi = setup.system;
   fprintf(file, "\n");
-  for (i = 0; i < NUM_SYSTEM_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(system_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(system_setup_tokens, "", i));
 
-  /* internal setup */
-  /* (internal setup values not saved to user setup file) */
+  // (internal setup values not saved to user setup file)
 
-  /* debug setup */
-  sdi = setup.debug;
   fprintf(file, "\n");
-  for (i = 0; i < NUM_DEBUG_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(debug_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(debug_setup_tokens, "", i));
 
-  /* options setup */
-  soi = setup.options;
   fprintf(file, "\n");
-  for (i = 0; i < NUM_OPTIONS_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(options_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(options_setup_tokens, "", i));
 
   fclose(file);
@@ -9077,7 +9802,34 @@ void SaveSetup()
   SetFilePermissions(filename, PERMS_PRIVATE);
 }
 
-void SaveSetup_EditorCascade()
+void SaveSetup_AutoSetup(void)
+{
+  char *filename = getPath2(getSetupDir(), AUTOSETUP_FILENAME);
+  FILE *file;
+  int i;
+
+  InitUserDataDirectory();
+
+  if (!(file = fopen(filename, MODE_WRITE)))
+  {
+    Error(ERR_WARN, "cannot write auto setup file '%s'", filename);
+    free(filename);
+    return;
+  }
+
+  fprintFileHeader(file, AUTOSETUP_FILENAME);
+
+  for (i = 0; i < ARRAY_SIZE(auto_setup_tokens); i++)
+    fprintf(file, "%s\n", getSetupLine(auto_setup_tokens, "", i));
+
+  fclose(file);
+
+  SetFilePermissions(filename, PERMS_PRIVATE);
+
+  free(filename);
+}
+
+void SaveSetup_EditorCascade(void)
 {
   char *filename = getPath2(getSetupDir(), EDITORCASCADE_FILENAME);
   FILE *file;
@@ -9094,100 +9846,492 @@ void SaveSetup_EditorCascade()
 
   fprintFileHeader(file, EDITORCASCADE_FILENAME);
 
-  seci = setup.editor_cascade;
-  for (i = 0; i < NUM_EDITOR_CASCADE_SETUP_TOKENS; i++)
+  for (i = 0; i < ARRAY_SIZE(editor_cascade_setup_tokens); i++)
     fprintf(file, "%s\n", getSetupLine(editor_cascade_setup_tokens, "", i));
 
   fclose(file);
 
   SetFilePermissions(filename, PERMS_PRIVATE);
 
-  free(filename);
+  free(filename);
+}
+
+static void SaveSetup_WriteGameControllerMappings(SetupFileHash *mappings_hash,
+                                                 char *filename)
+{
+  FILE *file;
+
+  if (!(file = fopen(filename, MODE_WRITE)))
+  {
+    Error(ERR_WARN, "cannot write game controller mappings file '%s'",filename);
+
+    return;
+  }
+
+  BEGIN_HASH_ITERATION(mappings_hash, itr)
+  {
+    fprintf(file, "%s\n", HASH_ITERATION_VALUE(itr));
+  }
+  END_HASH_ITERATION(mappings_hash, itr)
+
+  fclose(file);
+}
+
+void SaveSetup_AddGameControllerMapping(char *mapping)
+{
+  char *filename = getPath2(getSetupDir(), GAMECONTROLLER_BASENAME);
+  SetupFileHash *mappings_hash = newSetupFileHash();
+
+  InitUserDataDirectory();
+
+  // load existing personal game controller mappings
+  LoadSetup_ReadGameControllerMappings(mappings_hash, filename);
+
+  // add new mapping to personal game controller mappings
+  addGameControllerMappingToHash(mappings_hash, mapping);
+
+  // save updated personal game controller mappings
+  SaveSetup_WriteGameControllerMappings(mappings_hash, filename);
+
+  freeSetupFileHash(mappings_hash);
+  free(filename);
+}
+
+void LoadCustomElementDescriptions(void)
+{
+  char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+  SetupFileHash *setup_file_hash;
+  int i;
+
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+  {
+    if (element_info[i].custom_description != NULL)
+    {
+      free(element_info[i].custom_description);
+      element_info[i].custom_description = NULL;
+    }
+  }
+
+  if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
+    return;
+
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+  {
+    char *token = getStringCat2(element_info[i].token_name, ".name");
+    char *value = getHashEntry(setup_file_hash, token);
+
+    if (value != NULL)
+      element_info[i].custom_description = getStringCopy(value);
+
+    free(token);
+  }
+
+  freeSetupFileHash(setup_file_hash);
+}
+
+static int getElementFromToken(char *token)
+{
+  char *value = getHashEntry(element_token_hash, token);
+
+  if (value != NULL)
+    return atoi(value);
+
+  Error(ERR_WARN, "unknown element token '%s'", token);
+
+  return EL_UNDEFINED;
+}
+
+void FreeGlobalAnimEventInfo(void)
+{
+  struct GlobalAnimEventInfo *gaei = &global_anim_event_info;
+
+  if (gaei->event_list == NULL)
+    return;
+
+  int i;
+
+  for (i = 0; i < gaei->num_event_lists; i++)
+  {
+    checked_free(gaei->event_list[i]->event_value);
+    checked_free(gaei->event_list[i]);
+  }
+
+  checked_free(gaei->event_list);
+
+  gaei->event_list = NULL;
+  gaei->num_event_lists = 0;
+}
+
+static int AddGlobalAnimEventList(void)
+{
+  struct GlobalAnimEventInfo *gaei = &global_anim_event_info;
+  int list_pos = gaei->num_event_lists++;
+
+  gaei->event_list = checked_realloc(gaei->event_list, gaei->num_event_lists *
+                                    sizeof(struct GlobalAnimEventListInfo *));
+
+  gaei->event_list[list_pos] =
+    checked_calloc(sizeof(struct GlobalAnimEventListInfo));
+
+  struct GlobalAnimEventListInfo *gaeli = gaei->event_list[list_pos];
+
+  gaeli->event_value = NULL;
+  gaeli->num_event_values = 0;
+
+  return list_pos;
+}
+
+static int AddGlobalAnimEventValue(int list_pos, int event_value)
+{
+  // do not add empty global animation events
+  if (event_value == ANIM_EVENT_NONE)
+    return list_pos;
+
+  // if list position is undefined, create new list
+  if (list_pos == ANIM_EVENT_UNDEFINED)
+    list_pos = AddGlobalAnimEventList();
+
+  struct GlobalAnimEventInfo *gaei = &global_anim_event_info;
+  struct GlobalAnimEventListInfo *gaeli = gaei->event_list[list_pos];
+  int value_pos = gaeli->num_event_values++;
+
+  gaeli->event_value = checked_realloc(gaeli->event_value,
+                                      gaeli->num_event_values * sizeof(int *));
+
+  gaeli->event_value[value_pos] = event_value;
+
+  return list_pos;
+}
+
+int GetGlobalAnimEventValue(int list_pos, int value_pos)
+{
+  if (list_pos == ANIM_EVENT_UNDEFINED)
+    return ANIM_EVENT_NONE;
+
+  struct GlobalAnimEventInfo *gaei = &global_anim_event_info;
+  struct GlobalAnimEventListInfo *gaeli = gaei->event_list[list_pos];
+
+  return gaeli->event_value[value_pos];
+}
+
+int GetGlobalAnimEventValueCount(int list_pos)
+{
+  if (list_pos == ANIM_EVENT_UNDEFINED)
+    return 0;
+
+  struct GlobalAnimEventInfo *gaei = &global_anim_event_info;
+  struct GlobalAnimEventListInfo *gaeli = gaei->event_list[list_pos];
+
+  return gaeli->num_event_values;
+}
+
+// This function checks if a string <s> of the format "string1, string2, ..."
+// exactly contains a string <s_contained>.
+
+static boolean string_has_parameter(char *s, char *s_contained)
+{
+  char *substring;
+
+  if (s == NULL || s_contained == NULL)
+    return FALSE;
+
+  if (strlen(s_contained) > strlen(s))
+    return FALSE;
+
+  if (strncmp(s, s_contained, strlen(s_contained)) == 0)
+  {
+    char next_char = s[strlen(s_contained)];
+
+    // check if next character is delimiter or whitespace
+    return (next_char == ',' || next_char == '\0' ||
+           next_char == ' ' || next_char == '\t' ? TRUE : FALSE);
+  }
+
+  // check if string contains another parameter string after a comma
+  substring = strchr(s, ',');
+  if (substring == NULL)       // string does not contain a comma
+    return FALSE;
+
+  // advance string pointer to next character after the comma
+  substring++;
+
+  // skip potential whitespaces after the comma
+  while (*substring == ' ' || *substring == '\t')
+    substring++;
+
+  return string_has_parameter(substring, s_contained);
+}
+
+static int get_anim_parameter_value(char *s)
+{
+  int event_value[] =
+  {
+    ANIM_EVENT_CLICK
+  };
+  char *pattern_1[] =
+  {
+    "click:anim_"
+  };
+  char *pattern_2 = ".part_";
+  char *matching_char = NULL;
+  char *s_ptr = s;
+  int pattern_1_len = 0;
+  int result = ANIM_EVENT_NONE;
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE(event_value); i++)
+  {
+    matching_char = strstr(s_ptr, pattern_1[i]);
+    pattern_1_len = strlen(pattern_1[i]);
+    result = event_value[i];
+
+    if (matching_char != NULL)
+      break;
+  }
+
+  if (matching_char == NULL)
+    return ANIM_EVENT_NONE;
+
+  s_ptr = matching_char + pattern_1_len;
+
+  // check for main animation number ("anim_X" or "anim_XX")
+  if (*s_ptr >= '0' && *s_ptr <= '9')
+  {
+    int gic_anim_nr = (*s_ptr++ - '0');
+
+    if (*s_ptr >= '0' && *s_ptr <= '9')
+      gic_anim_nr = 10 * gic_anim_nr + (*s_ptr++ - '0');
+
+    if (gic_anim_nr < 1 || gic_anim_nr > MAX_GLOBAL_ANIMS)
+      return ANIM_EVENT_NONE;
+
+    result |= gic_anim_nr << ANIM_EVENT_ANIM_BIT;
+  }
+  else
+  {
+    // invalid main animation number specified
+
+    return ANIM_EVENT_NONE;
+  }
+
+  // check for animation part number ("part_X" or "part_XX") (optional)
+  if (strPrefix(s_ptr, pattern_2))
+  {
+    s_ptr += strlen(pattern_2);
+
+    if (*s_ptr >= '0' && *s_ptr <= '9')
+    {
+      int gic_part_nr = (*s_ptr++ - '0');
+
+      if (*s_ptr >= '0' && *s_ptr <= '9')
+       gic_part_nr = 10 * gic_part_nr + (*s_ptr++ - '0');
+
+      if (gic_part_nr < 1 || gic_part_nr > MAX_GLOBAL_ANIM_PARTS)
+       return ANIM_EVENT_NONE;
+
+      result |= gic_part_nr << ANIM_EVENT_PART_BIT;
+    }
+    else
+    {
+      // invalid animation part number specified
+
+      return ANIM_EVENT_NONE;
+    }
+  }
+
+  // discard result if next character is neither delimiter nor whitespace
+  if (!(*s_ptr == ',' || *s_ptr == '\0' ||
+       *s_ptr == ' ' || *s_ptr == '\t'))
+    return ANIM_EVENT_NONE;
+
+  return result;
 }
 
-static void SaveSetup_WriteGameControllerMappings(SetupFileHash *mappings_hash,
-                                                 char *filename)
+static int get_anim_parameter_values(char *s)
 {
-  FILE *file;
+  int list_pos = ANIM_EVENT_UNDEFINED;
+  int event_value = ANIM_EVENT_DEFAULT;
 
-  if (!(file = fopen(filename, MODE_WRITE)))
-  {
-    Error(ERR_WARN, "cannot write game controller mappings file '%s'",filename);
+  if (string_has_parameter(s, "any"))
+    event_value |= ANIM_EVENT_ANY;
 
-    return;
-  }
+  if (string_has_parameter(s, "click:self") ||
+      string_has_parameter(s, "click") ||
+      string_has_parameter(s, "self"))
+    event_value |= ANIM_EVENT_SELF;
 
-  BEGIN_HASH_ITERATION(mappings_hash, itr)
+  // if animation event found, add it to global animation event list
+  if (event_value != ANIM_EVENT_NONE)
+    list_pos = AddGlobalAnimEventValue(list_pos, event_value);
+
+  while (s != NULL)
   {
-    fprintf(file, "%s\n", HASH_ITERATION_VALUE(itr));
+    // add optional "click:anim_X" or "click:anim_X.part_X" parameter
+    event_value = get_anim_parameter_value(s);
+
+    // if animation event found, add it to global animation event list
+    if (event_value != ANIM_EVENT_NONE)
+      list_pos = AddGlobalAnimEventValue(list_pos, event_value);
+
+    // continue with next part of the string, starting with next comma
+    s = strchr(s + 1, ',');
   }
-  END_HASH_ITERATION(mappings_hash, itr)
 
-  fclose(file);
+  return list_pos;
 }
 
-void SaveSetup_AddGameControllerMapping(char *mapping)
+static int get_anim_action_parameter_value(char *token)
 {
-  char *filename = getPath2(getSetupDir(), GAMECONTROLLER_BASENAME);
-  SetupFileHash *mappings_hash = newSetupFileHash();
+  int result = getImageIDFromToken(token);
 
-  InitUserDataDirectory();
+  if (result == -1)
+  {
+    char *gfx_token = getStringCat2("gfx.", token);
 
-  // load existing personal game controller mappings
-  LoadSetup_ReadGameControllerMappings(mappings_hash, filename);
+    result = getImageIDFromToken(gfx_token);
 
-  // add new mapping to personal game controller mappings
-  addGameControllerMappingToHash(mappings_hash, mapping);
+    checked_free(gfx_token);
+  }
 
-  // save updated personal game controller mappings
-  SaveSetup_WriteGameControllerMappings(mappings_hash, filename);
+  if (result == -1)
+  {
+    Key key = getKeyFromX11KeyName(token);
 
-  freeSetupFileHash(mappings_hash);
-  free(filename);
+    if (key != KSYM_UNDEFINED)
+      result = -(int)key;
+  }
+
+  if (result == -1)
+    result = ANIM_EVENT_ACTION_NONE;
+
+  return result;
 }
 
-void LoadCustomElementDescriptions()
+int get_parameter_value(char *value_raw, char *suffix, int type)
 {
-  char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
-  SetupFileHash *setup_file_hash;
-  int i;
+  char *value = getStringToLower(value_raw);
+  int result = 0;      // probably a save default value
 
-  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+  if (strEqual(suffix, ".direction"))
   {
-    if (element_info[i].custom_description != NULL)
-    {
-      free(element_info[i].custom_description);
-      element_info[i].custom_description = NULL;
-    }
+    result = (strEqual(value, "left")  ? MV_LEFT :
+             strEqual(value, "right") ? MV_RIGHT :
+             strEqual(value, "up")    ? MV_UP :
+             strEqual(value, "down")  ? MV_DOWN : MV_NONE);
+  }
+  else if (strEqual(suffix, ".position"))
+  {
+    result = (strEqual(value, "left")   ? POS_LEFT :
+             strEqual(value, "right")  ? POS_RIGHT :
+             strEqual(value, "top")    ? POS_TOP :
+             strEqual(value, "upper")  ? POS_UPPER :
+             strEqual(value, "middle") ? POS_MIDDLE :
+             strEqual(value, "lower")  ? POS_LOWER :
+             strEqual(value, "bottom") ? POS_BOTTOM :
+             strEqual(value, "any")    ? POS_ANY :
+             strEqual(value, "last")   ? POS_LAST : POS_UNDEFINED);
+  }
+  else if (strEqual(suffix, ".align"))
+  {
+    result = (strEqual(value, "left")   ? ALIGN_LEFT :
+             strEqual(value, "right")  ? ALIGN_RIGHT :
+             strEqual(value, "center") ? ALIGN_CENTER :
+             strEqual(value, "middle") ? ALIGN_CENTER : ALIGN_DEFAULT);
+  }
+  else if (strEqual(suffix, ".valign"))
+  {
+    result = (strEqual(value, "top")    ? VALIGN_TOP :
+             strEqual(value, "bottom") ? VALIGN_BOTTOM :
+             strEqual(value, "middle") ? VALIGN_MIDDLE :
+             strEqual(value, "center") ? VALIGN_MIDDLE : VALIGN_DEFAULT);
   }
+  else if (strEqual(suffix, ".anim_mode"))
+  {
+    result = (string_has_parameter(value, "none")      ? ANIM_NONE :
+             string_has_parameter(value, "loop")       ? ANIM_LOOP :
+             string_has_parameter(value, "linear")     ? ANIM_LINEAR :
+             string_has_parameter(value, "pingpong")   ? ANIM_PINGPONG :
+             string_has_parameter(value, "pingpong2")  ? ANIM_PINGPONG2 :
+             string_has_parameter(value, "random")     ? ANIM_RANDOM :
+             string_has_parameter(value, "ce_value")   ? ANIM_CE_VALUE :
+             string_has_parameter(value, "ce_score")   ? ANIM_CE_SCORE :
+             string_has_parameter(value, "ce_delay")   ? ANIM_CE_DELAY :
+             string_has_parameter(value, "horizontal") ? ANIM_HORIZONTAL :
+             string_has_parameter(value, "vertical")   ? ANIM_VERTICAL :
+             string_has_parameter(value, "centered")   ? ANIM_CENTERED :
+             string_has_parameter(value, "all")        ? ANIM_ALL :
+             ANIM_DEFAULT);
 
-  if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
-    return;
+    if (string_has_parameter(value, "once"))
+      result |= ANIM_ONCE;
 
-  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
-  {
-    char *token = getStringCat2(element_info[i].token_name, ".name");
-    char *value = getHashEntry(setup_file_hash, token);
+    if (string_has_parameter(value, "reverse"))
+      result |= ANIM_REVERSE;
 
-    if (value != NULL)
-      element_info[i].custom_description = getStringCopy(value);
+    if (string_has_parameter(value, "opaque_player"))
+      result |= ANIM_OPAQUE_PLAYER;
 
-    free(token);
+    if (string_has_parameter(value, "static_panel"))
+      result |= ANIM_STATIC_PANEL;
+  }
+  else if (strEqual(suffix, ".init_event") ||
+          strEqual(suffix, ".anim_event"))
+  {
+    result = get_anim_parameter_values(value);
+  }
+  else if (strEqual(suffix, ".init_event_action") ||
+          strEqual(suffix, ".anim_event_action"))
+  {
+    result = get_anim_action_parameter_value(value_raw);
+  }
+  else if (strEqual(suffix, ".class"))
+  {
+    result = (strEqual(value, ARG_UNDEFINED) ? ARG_UNDEFINED_VALUE :
+             get_hash_from_key(value));
   }
+  else if (strEqual(suffix, ".style"))
+  {
+    result = STYLE_DEFAULT;
 
-  freeSetupFileHash(setup_file_hash);
-}
+    if (string_has_parameter(value, "accurate_borders"))
+      result |= STYLE_ACCURATE_BORDERS;
 
-static int getElementFromToken(char *token)
-{
-  char *value = getHashEntry(element_token_hash, token);
+    if (string_has_parameter(value, "inner_corners"))
+      result |= STYLE_INNER_CORNERS;
 
-  if (value != NULL)
-    return atoi(value);
+    if (string_has_parameter(value, "reverse"))
+      result |= STYLE_REVERSE;
 
-  Error(ERR_WARN, "unknown element token '%s'", token);
+    if (string_has_parameter(value, "passthrough_clicks"))
+      result |= STYLE_PASSTHROUGH;
 
-  return EL_UNDEFINED;
+    if (string_has_parameter(value, "multiple_actions"))
+      result |= STYLE_MULTIPLE_ACTIONS;
+  }
+  else if (strEqual(suffix, ".fade_mode"))
+  {
+    result = (string_has_parameter(value, "none")      ? FADE_MODE_NONE :
+             string_has_parameter(value, "fade")       ? FADE_MODE_FADE :
+             string_has_parameter(value, "crossfade")  ? FADE_MODE_CROSSFADE :
+             string_has_parameter(value, "melt")       ? FADE_MODE_MELT :
+             string_has_parameter(value, "curtain")    ? FADE_MODE_CURTAIN :
+             FADE_MODE_DEFAULT);
+  }
+  else if (strPrefix(suffix, ".font"))         // (may also be ".font_xyz")
+  {
+    result = gfx.get_font_from_token_function(value);
+  }
+  else         // generic parameter of type integer or boolean
+  {
+    result = (strEqual(value, ARG_UNDEFINED) ? ARG_UNDEFINED_VALUE :
+             type == TYPE_INTEGER ? get_integer_from_string(value) :
+             type == TYPE_BOOLEAN ? get_boolean_from_string(value) :
+             ARG_UNDEFINED_VALUE);
+  }
+
+  free(value);
+
+  return result;
 }
 
 static int get_token_parameter_value(char *token, char *value_raw)
@@ -9204,15 +10348,15 @@ static int get_token_parameter_value(char *token, char *value_raw)
   if (strEqual(suffix, ".element"))
     return getElementFromToken(value_raw);
 
-  /* !!! USE CORRECT VALUE TYPE (currently works also for TYPE_BOOLEAN) !!! */
+  // !!! USE CORRECT VALUE TYPE (currently works also for TYPE_BOOLEAN) !!!
   return get_parameter_value(value_raw, suffix, TYPE_INTEGER);
 }
 
-void InitMenuDesignSettings_Static()
+void InitMenuDesignSettings_Static(void)
 {
   int i;
 
-  /* always start with reliable default values from static default config */
+  // always start with reliable default values from static default config
   for (i = 0; image_config_vars[i].token != NULL; i++)
   {
     char *value = getHashEntry(image_config_hash, image_config_vars[i].token);
@@ -9223,14 +10367,14 @@ void InitMenuDesignSettings_Static()
   }
 }
 
-static void InitMenuDesignSettings_SpecialPreProcessing()
+static void InitMenuDesignSettings_SpecialPreProcessing(void)
 {
   int i;
 
-  /* the following initializes hierarchical values from static configuration */
+  // the following initializes hierarchical values from static configuration
 
-  /* special case: initialize "ARG_DEFAULT" values in static default config */
-  /* (e.g., initialize "[titlemessage].fade_mode" from "[title].fade_mode") */
+  // special case: initialize "ARG_DEFAULT" values in static default config
+  // (e.g., initialize "[titlemessage].fade_mode" from "[title].fade_mode")
   titlescreen_initial_first_default.fade_mode  =
     title_initial_first_default.fade_mode;
   titlescreen_initial_first_default.fade_delay =
@@ -9273,8 +10417,8 @@ static void InitMenuDesignSettings_SpecialPreProcessing()
   titlemessage_default.post_delay = title_default.post_delay;
   titlemessage_default.auto_delay = title_default.auto_delay;
 
-  /* special case: initialize "ARG_DEFAULT" values in static default config */
-  /* (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode") */
+  // special case: initialize "ARG_DEFAULT" values in static default config
+  // (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode")
   for (i = 0; i < MAX_NUM_TITLE_MESSAGES; i++)
   {
     titlescreen_initial_first[i] = titlescreen_initial_first_default;
@@ -9288,11 +10432,11 @@ static void InitMenuDesignSettings_SpecialPreProcessing()
     titlemessage[i] = titlemessage_default;
   }
 
-  /* special case: initialize "ARG_DEFAULT" values in static default config */
-  /* (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz") */
+  // special case: initialize "ARG_DEFAULT" values in static default config
+  // (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz")
   for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
   {
-    if (i == GFX_SPECIAL_ARG_TITLE)    /* title values already initialized */
+    if (i == GFX_SPECIAL_ARG_TITLE)    // title values already initialized
       continue;
 
     menu.enter_screen[i] = menu.enter_screen[GFX_SPECIAL_ARG_DEFAULT];
@@ -9300,22 +10444,22 @@ static void InitMenuDesignSettings_SpecialPreProcessing()
     menu.next_screen[i]  = menu.next_screen[GFX_SPECIAL_ARG_DEFAULT];
   }
 
-  /* special case: initialize "ARG_DEFAULT" values in static default config */
-  /* (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz") */
+  // special case: initialize "ARG_DEFAULT" values in static default config
+  // (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz")
   for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
   {
     viewport.window[i]    = viewport.window[GFX_SPECIAL_ARG_DEFAULT];
     viewport.playfield[i] = viewport.playfield[GFX_SPECIAL_ARG_DEFAULT];
     viewport.door_1[i]    = viewport.door_1[GFX_SPECIAL_ARG_DEFAULT];
 
-    if (i == GFX_SPECIAL_ARG_EDITOR)   /* editor values already initialized */
+    if (i == GFX_SPECIAL_ARG_EDITOR)   // editor values already initialized
       continue;
 
     viewport.door_2[i] = viewport.door_2[GFX_SPECIAL_ARG_DEFAULT];
   }
 }
 
-static void InitMenuDesignSettings_SpecialPostProcessing()
+static void InitMenuDesignSettings_SpecialPostProcessing(void)
 {
   static struct
   {
@@ -9331,20 +10475,251 @@ static void InitMenuDesignSettings_SpecialPostProcessing()
 
     { NULL,                    NULL                    }
   };
-  int i;
+  int i, j;
 
-  /* special case: initialize later added SETUP list size from LEVELS value */
+  // special case: initialize later added SETUP list size from LEVELS value
   if (menu.list_size[GAME_MODE_SETUP] == -1)
     menu.list_size[GAME_MODE_SETUP] = menu.list_size[GAME_MODE_LEVELS];
 
-  /* set default position for snapshot buttons to stop/pause/play buttons */
+  // set default position for snapshot buttons to stop/pause/play buttons
   for (i = 0; game_buttons_xy[i].dst != NULL; i++)
     if ((*game_buttons_xy[i].dst).x == -1 &&
        (*game_buttons_xy[i].dst).y == -1)
       *game_buttons_xy[i].dst = *game_buttons_xy[i].src;
+
+  // --------------------------------------------------------------------------
+  // dynamic viewports (including playfield margins, borders and alignments)
+  // --------------------------------------------------------------------------
+
+  // dynamic viewports currently only supported for landscape mode
+  int display_width  = MAX(video.display_width, video.display_height);
+  int display_height = MIN(video.display_width, video.display_height);
+
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+  {
+    struct RectWithBorder *vp_window    = &viewport.window[i];
+    struct RectWithBorder *vp_playfield = &viewport.playfield[i];
+    struct RectWithBorder *vp_door_1    = &viewport.door_1[i];
+    struct RectWithBorder *vp_door_2    = &viewport.door_2[i];
+    boolean dynamic_window_width     = (vp_window->min_width     != -1);
+    boolean dynamic_window_height    = (vp_window->min_height    != -1);
+    boolean dynamic_playfield_width  = (vp_playfield->min_width  != -1);
+    boolean dynamic_playfield_height = (vp_playfield->min_height != -1);
+
+    // adjust window size if min/max width/height is specified
+
+    if (vp_window->min_width != -1)
+    {
+      int window_width = display_width;
+
+      // when using static window height, use aspect ratio of display
+      if (vp_window->min_height == -1)
+       window_width = vp_window->height * display_width / display_height;
+
+      vp_window->width = MAX(vp_window->min_width, window_width);
+    }
+
+    if (vp_window->min_height != -1)
+    {
+      int window_height = display_height;
+
+      // when using static window width, use aspect ratio of display
+      if (vp_window->min_width == -1)
+       window_height = vp_window->width * display_height / display_width;
+
+      vp_window->height = MAX(vp_window->min_height, window_height);
+    }
+
+    if (vp_window->max_width != -1)
+      vp_window->width = MIN(vp_window->width, vp_window->max_width);
+
+    if (vp_window->max_height != -1)
+      vp_window->height = MIN(vp_window->height, vp_window->max_height);
+
+    int playfield_width  = vp_window->width;
+    int playfield_height = vp_window->height;
+
+    // adjust playfield size and position according to specified margins
+
+    playfield_width  -= vp_playfield->margin_left;
+    playfield_width  -= vp_playfield->margin_right;
+
+    playfield_height -= vp_playfield->margin_top;
+    playfield_height -= vp_playfield->margin_bottom;
+
+    // adjust playfield size if min/max width/height is specified
+
+    if (vp_playfield->min_width != -1)
+      vp_playfield->width = MAX(vp_playfield->min_width, playfield_width);
+
+    if (vp_playfield->min_height != -1)
+      vp_playfield->height = MAX(vp_playfield->min_height, playfield_height);
+
+    if (vp_playfield->max_width != -1)
+      vp_playfield->width = MIN(vp_playfield->width, vp_playfield->max_width);
+
+    if (vp_playfield->max_height != -1)
+      vp_playfield->height = MIN(vp_playfield->height,vp_playfield->max_height);
+
+    // adjust playfield position according to specified alignment
+
+    if (vp_playfield->align == ALIGN_LEFT || vp_playfield->x > 0)
+      vp_playfield->x = ALIGNED_VP_XPOS(vp_playfield);
+    else if (vp_playfield->align == ALIGN_CENTER)
+      vp_playfield->x = playfield_width / 2 - vp_playfield->width / 2;
+    else if (vp_playfield->align == ALIGN_RIGHT)
+      vp_playfield->x += playfield_width - vp_playfield->width;
+
+    if (vp_playfield->valign == VALIGN_TOP || vp_playfield->y > 0)
+      vp_playfield->y = ALIGNED_VP_YPOS(vp_playfield);
+    else if (vp_playfield->valign == VALIGN_MIDDLE)
+      vp_playfield->y = playfield_height / 2 - vp_playfield->height / 2;
+    else if (vp_playfield->valign == VALIGN_BOTTOM)
+      vp_playfield->y += playfield_height - vp_playfield->height;
+
+    vp_playfield->x += vp_playfield->margin_left;
+    vp_playfield->y += vp_playfield->margin_top;
+
+    // adjust individual playfield borders if only default border is specified
+
+    if (vp_playfield->border_left == -1)
+      vp_playfield->border_left = vp_playfield->border_size;
+    if (vp_playfield->border_right == -1)
+      vp_playfield->border_right = vp_playfield->border_size;
+    if (vp_playfield->border_top == -1)
+      vp_playfield->border_top = vp_playfield->border_size;
+    if (vp_playfield->border_bottom == -1)
+      vp_playfield->border_bottom = vp_playfield->border_size;
+
+    // set dynamic playfield borders if borders are specified as undefined
+    // (but only if window size was dynamic and playfield size was static)
+
+    if (dynamic_window_width && !dynamic_playfield_width)
+    {
+      if (vp_playfield->border_left == -1)
+      {
+       vp_playfield->border_left = (vp_playfield->x -
+                                    vp_playfield->margin_left);
+       vp_playfield->x     -= vp_playfield->border_left;
+       vp_playfield->width += vp_playfield->border_left;
+      }
+
+      if (vp_playfield->border_right == -1)
+      {
+       vp_playfield->border_right = (vp_window->width -
+                                     vp_playfield->x -
+                                     vp_playfield->width -
+                                     vp_playfield->margin_right);
+       vp_playfield->width += vp_playfield->border_right;
+      }
+    }
+
+    if (dynamic_window_height && !dynamic_playfield_height)
+    {
+      if (vp_playfield->border_top == -1)
+      {
+       vp_playfield->border_top = (vp_playfield->y -
+                                   vp_playfield->margin_top);
+       vp_playfield->y      -= vp_playfield->border_top;
+       vp_playfield->height += vp_playfield->border_top;
+      }
+
+      if (vp_playfield->border_bottom == -1)
+      {
+       vp_playfield->border_bottom = (vp_window->height -
+                                      vp_playfield->y -
+                                      vp_playfield->height -
+                                      vp_playfield->margin_bottom);
+       vp_playfield->height += vp_playfield->border_bottom;
+      }
+    }
+
+    // adjust playfield size to be a multiple of a defined alignment tile size
+
+    int align_size = vp_playfield->align_size;
+    int playfield_xtiles = vp_playfield->width  / align_size;
+    int playfield_ytiles = vp_playfield->height / align_size;
+    int playfield_width_corrected  = playfield_xtiles * align_size;
+    int playfield_height_corrected = playfield_ytiles * align_size;
+    boolean is_playfield_mode = (i == GFX_SPECIAL_ARG_PLAYING ||
+                                i == GFX_SPECIAL_ARG_EDITOR);
+
+    if (is_playfield_mode &&
+       dynamic_playfield_width &&
+       vp_playfield->width != playfield_width_corrected)
+    {
+      int playfield_xdiff = vp_playfield->width - playfield_width_corrected;
+
+      vp_playfield->width = playfield_width_corrected;
+
+      if (vp_playfield->align == ALIGN_LEFT)
+      {
+       vp_playfield->border_left += playfield_xdiff;
+      }
+      else if (vp_playfield->align == ALIGN_RIGHT)
+      {
+       vp_playfield->border_right += playfield_xdiff;
+      }
+      else if (vp_playfield->align == ALIGN_CENTER)
+      {
+       int border_left_diff  = playfield_xdiff / 2;
+       int border_right_diff = playfield_xdiff - border_left_diff;
+
+       vp_playfield->border_left  += border_left_diff;
+       vp_playfield->border_right += border_right_diff;
+      }
+    }
+
+    if (is_playfield_mode &&
+       dynamic_playfield_height &&
+       vp_playfield->height != playfield_height_corrected)
+    {
+      int playfield_ydiff = vp_playfield->height - playfield_height_corrected;
+
+      vp_playfield->height = playfield_height_corrected;
+
+      if (vp_playfield->valign == VALIGN_TOP)
+      {
+       vp_playfield->border_top += playfield_ydiff;
+      }
+      else if (vp_playfield->align == VALIGN_BOTTOM)
+      {
+       vp_playfield->border_right += playfield_ydiff;
+      }
+      else if (vp_playfield->align == VALIGN_MIDDLE)
+      {
+       int border_top_diff    = playfield_ydiff / 2;
+       int border_bottom_diff = playfield_ydiff - border_top_diff;
+
+       vp_playfield->border_top    += border_top_diff;
+       vp_playfield->border_bottom += border_bottom_diff;
+      }
+    }
+
+    // adjust door positions according to specified alignment
+
+    for (j = 0; j < 2; j++)
+    {
+      struct RectWithBorder *vp_door = (j == 0 ? vp_door_1 : vp_door_2);
+
+      if (vp_door->align == ALIGN_LEFT || vp_door->x > 0)
+       vp_door->x = ALIGNED_VP_XPOS(vp_door);
+      else if (vp_door->align == ALIGN_CENTER)
+       vp_door->x = vp_window->width / 2 - vp_door->width / 2;
+      else if (vp_door->align == ALIGN_RIGHT)
+       vp_door->x += vp_window->width - vp_door->width;
+
+      if (vp_door->valign == VALIGN_TOP || vp_door->y > 0)
+       vp_door->y = ALIGNED_VP_YPOS(vp_door);
+      else if (vp_door->valign == VALIGN_MIDDLE)
+       vp_door->y = vp_window->height / 2 - vp_door->height / 2;
+      else if (vp_door->valign == VALIGN_BOTTOM)
+       vp_door->y += vp_window->height - vp_door->height;
+    }
+  }
 }
 
-static void InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics()
+static void InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics(void)
 {
   static struct
   {
@@ -9370,7 +10745,7 @@ static void InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics()
   };
   int i;
 
-  /* set default position for element buttons to element graphics */
+  // set default position for element buttons to element graphics
   for (i = 0; editor_buttons_xy[i].dst != NULL; i++)
   {
     if ((*editor_buttons_xy[i].dst).x == -1 &&
@@ -9383,6 +10758,40 @@ static void InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics()
       *editor_buttons_xy[i].dst = *editor_buttons_xy[i].src;
     }
   }
+
+  // adjust editor palette rows and columns if specified to be dynamic
+
+  if (editor.palette.cols == -1)
+  {
+    int vp_width = viewport.playfield[GFX_SPECIAL_ARG_EDITOR].width;
+    int bt_width = graphic_info[IMG_EDITOR_PALETTE_BUTTON].width;
+    int sc_width = graphic_info[IMG_EDITOR_PALETTE_SCROLLBAR].width;
+
+    editor.palette.cols = (vp_width - sc_width) / bt_width;
+
+    if (editor.palette.x == -1)
+    {
+      int palette_width = editor.palette.cols * bt_width + sc_width;
+
+      editor.palette.x = (vp_width - palette_width) / 2;
+    }
+  }
+
+  if (editor.palette.rows == -1)
+  {
+    int vp_height = viewport.playfield[GFX_SPECIAL_ARG_EDITOR].height;
+    int bt_height = graphic_info[IMG_EDITOR_PALETTE_BUTTON].height;
+    int tx_height = getFontHeight(FONT_TEXT_2);
+
+    editor.palette.rows = (vp_height - tx_height) / bt_height;
+
+    if (editor.palette.y == -1)
+    {
+      int palette_height = editor.palette.rows * bt_height + tx_height;
+
+      editor.palette.y = (vp_height - palette_height) / 2;
+    }
+  }
 }
 
 static void LoadMenuDesignSettingsFromFilename(char *filename)
@@ -9427,11 +10836,11 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
   }
   title_info[] =
   {
-    /* initialize first titles from "enter screen" definitions, if defined */
+    // initialize first titles from "enter screen" definitions, if defined
     { &title_initial_first_default,    "menu.enter_screen.TITLE"       },
     { &title_first_default,            "menu.enter_screen.TITLE"       },
 
-    /* initialize title screens from "next screen" definitions, if defined */
+    // initialize title screens from "next screen" definitions, if defined
     { &title_initial_default,          "menu.next_screen.TITLE"        },
     { &title_default,                  "menu.next_screen.TITLE"        },
 
@@ -9444,19 +10853,19 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
   }
   titlemessage_arrays[] =
   {
-    /* initialize first titles from "enter screen" definitions, if defined */
+    // initialize first titles from "enter screen" definitions, if defined
     { titlescreen_initial_first,       "menu.enter_screen.TITLE"       },
     { titlescreen_first,               "menu.enter_screen.TITLE"       },
     { titlemessage_initial_first,      "menu.enter_screen.TITLE"       },
     { titlemessage_first,              "menu.enter_screen.TITLE"       },
 
-    /* initialize titles from "next screen" definitions, if defined */
+    // initialize titles from "next screen" definitions, if defined
     { titlescreen_initial,             "menu.next_screen.TITLE"        },
     { titlescreen,                     "menu.next_screen.TITLE"        },
     { titlemessage_initial,            "menu.next_screen.TITLE"        },
     { titlemessage,                    "menu.next_screen.TITLE"        },
 
-    /* overwrite titles with title definitions, if defined */
+    // overwrite titles with title definitions, if defined
     { titlescreen_initial_first,       "[title_initial]"               },
     { titlescreen_first,               "[title]"                       },
     { titlemessage_initial_first,      "[title_initial]"               },
@@ -9467,7 +10876,7 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
     { titlemessage_initial,            "[title_initial]"               },
     { titlemessage,                    "[title]"                       },
 
-    /* overwrite titles with title screen/message definitions, if defined */
+    // overwrite titles with title screen/message definitions, if defined
     { titlescreen_initial_first,       "[titlescreen_initial]"         },
     { titlescreen_first,               "[titlescreen]"                 },
     { titlemessage_initial_first,      "[titlemessage_initial]"        },
@@ -9486,192 +10895,183 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
   if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
     return;
 
-  /* the following initializes hierarchical values from dynamic configuration */
+  // the following initializes hierarchical values from dynamic configuration
 
-  /* special case: initialize with default values that may be overwritten */
-  /* (e.g., init "menu.draw_xoffset.INFO" from "menu.draw_xoffset") */
+  // special case: initialize with default values that may be overwritten
+  // (e.g., init "menu.draw_xoffset.INFO" from "menu.draw_xoffset")
   for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
   {
-    char *value_1 = getHashEntry(setup_file_hash, "menu.draw_xoffset");
-    char *value_2 = getHashEntry(setup_file_hash, "menu.draw_yoffset");
-    char *value_3 = getHashEntry(setup_file_hash, "menu.list_size");
+    struct TokenIntPtrInfo menu_config[] =
+    {
+      { "menu.draw_xoffset",   &menu.draw_xoffset[i]   },
+      { "menu.draw_yoffset",   &menu.draw_yoffset[i]   },
+      { "menu.list_size",      &menu.list_size[i]      }
+    };
+
+    for (j = 0; j < ARRAY_SIZE(menu_config); j++)
+    {
+      char *token = menu_config[j].token;
+      char *value = getHashEntry(setup_file_hash, token);
 
-    if (value_1 != NULL)
-      menu.draw_xoffset[i] = get_integer_from_string(value_1);
-    if (value_2 != NULL)
-      menu.draw_yoffset[i] = get_integer_from_string(value_2);
-    if (value_3 != NULL)
-      menu.list_size[i] = get_integer_from_string(value_3);
+      if (value != NULL)
+        *menu_config[j].value = get_integer_from_string(value);
+    }
   }
 
-  /* special case: initialize with default values that may be overwritten */
-  /* (eg, init "menu.draw_xoffset.INFO[XXX]" from "menu.draw_xoffset.INFO") */
+  // special case: initialize with default values that may be overwritten
+  // (eg, init "menu.draw_xoffset.INFO[XXX]" from "menu.draw_xoffset.INFO")
   for (i = 0; i < NUM_SPECIAL_GFX_INFO_ARGS; i++)
   {
-    char *value_1 = getHashEntry(setup_file_hash, "menu.draw_xoffset.INFO");
-    char *value_2 = getHashEntry(setup_file_hash, "menu.draw_yoffset.INFO");
-
-    if (value_1 != NULL)
-      menu.draw_xoffset_info[i] = get_integer_from_string(value_1);
-    if (value_2 != NULL)
-      menu.draw_yoffset_info[i] = get_integer_from_string(value_2);
+    struct TokenIntPtrInfo menu_config[] =
+    {
+      { "menu.draw_xoffset.INFO",      &menu.draw_xoffset_info[i]      },
+      { "menu.draw_yoffset.INFO",      &menu.draw_yoffset_info[i]      },
+      { "menu.list_size.INFO",         &menu.list_size_info[i]         }
+    };
 
-    if (i == GFX_SPECIAL_ARG_INFO_ELEMENTS)
+    for (j = 0; j < ARRAY_SIZE(menu_config); j++)
     {
-      char *value_1 = getHashEntry(setup_file_hash, "menu.list_size.INFO");
+      char *token = menu_config[j].token;
+      char *value = getHashEntry(setup_file_hash, token);
 
-      if (value_1 != NULL)
-       menu.list_size_info[i] = get_integer_from_string(value_1);
+      if (value != NULL)
+        *menu_config[j].value = get_integer_from_string(value);
     }
   }
 
-  /* special case: initialize with default values that may be overwritten */
-  /* (eg, init "menu.draw_xoffset.SETUP[XXX]" from "menu.draw_xoffset.SETUP") */
+  // special case: initialize with default values that may be overwritten
+  // (eg, init "menu.draw_xoffset.SETUP[XXX]" from "menu.draw_xoffset.SETUP")
   for (i = 0; i < NUM_SPECIAL_GFX_SETUP_ARGS; i++)
   {
-    char *value_1 = getHashEntry(setup_file_hash, "menu.draw_xoffset.SETUP");
-    char *value_2 = getHashEntry(setup_file_hash, "menu.draw_yoffset.SETUP");
+    struct TokenIntPtrInfo menu_config[] =
+    {
+      { "menu.draw_xoffset.SETUP",     &menu.draw_xoffset_setup[i]     },
+      { "menu.draw_yoffset.SETUP",     &menu.draw_yoffset_setup[i]     }
+    };
+
+    for (j = 0; j < ARRAY_SIZE(menu_config); j++)
+    {
+      char *token = menu_config[j].token;
+      char *value = getHashEntry(setup_file_hash, token);
+
+      if (value != NULL)
+        *menu_config[j].value = get_integer_from_string(value);
+    }
+  }
+
+  // special case: initialize with default values that may be overwritten
+  // (eg, init "menu.line_spacing.INFO[XXX]" from "menu.line_spacing.INFO")
+  for (i = 0; i < NUM_SPECIAL_GFX_INFO_ARGS; i++)
+  {
+    struct TokenIntPtrInfo menu_config[] =
+    {
+      { "menu.left_spacing.INFO",      &menu.left_spacing_info[i]      },
+      { "menu.right_spacing.INFO",     &menu.right_spacing_info[i]     },
+      { "menu.top_spacing.INFO",       &menu.top_spacing_info[i]       },
+      { "menu.bottom_spacing.INFO",    &menu.bottom_spacing_info[i]    },
+      { "menu.paragraph_spacing.INFO", &menu.paragraph_spacing_info[i] },
+      { "menu.headline1_spacing.INFO", &menu.headline1_spacing_info[i] },
+      { "menu.headline2_spacing.INFO", &menu.headline2_spacing_info[i] },
+      { "menu.line_spacing.INFO",      &menu.line_spacing_info[i]      },
+      { "menu.extra_spacing.INFO",     &menu.extra_spacing_info[i]     },
+    };
+
+    for (j = 0; j < ARRAY_SIZE(menu_config); j++)
+    {
+      char *token = menu_config[j].token;
+      char *value = getHashEntry(setup_file_hash, token);
 
-    if (value_1 != NULL)
-      menu.draw_xoffset_setup[i] = get_integer_from_string(value_1);
-    if (value_2 != NULL)
-      menu.draw_yoffset_setup[i] = get_integer_from_string(value_2);
+      if (value != NULL)
+        *menu_config[j].value = get_integer_from_string(value);
+    }
   }
 
-  /* special case: initialize with default values that may be overwritten */
-  /* (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz") */
+  // special case: initialize with default values that may be overwritten
+  // (eg, init "menu.enter_screen.SCORES.xyz" from "menu.enter_screen.xyz")
   for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
   {
-    char *token_1 = "menu.enter_screen.fade_mode";
-    char *token_2 = "menu.enter_screen.fade_delay";
-    char *token_3 = "menu.enter_screen.post_delay";
-    char *token_4 = "menu.leave_screen.fade_mode";
-    char *token_5 = "menu.leave_screen.fade_delay";
-    char *token_6 = "menu.leave_screen.post_delay";
-    char *token_7 = "menu.next_screen.fade_mode";
-    char *token_8 = "menu.next_screen.fade_delay";
-    char *token_9 = "menu.next_screen.post_delay";
-    char *value_1 = getHashEntry(setup_file_hash, token_1);
-    char *value_2 = getHashEntry(setup_file_hash, token_2);
-    char *value_3 = getHashEntry(setup_file_hash, token_3);
-    char *value_4 = getHashEntry(setup_file_hash, token_4);
-    char *value_5 = getHashEntry(setup_file_hash, token_5);
-    char *value_6 = getHashEntry(setup_file_hash, token_6);
-    char *value_7 = getHashEntry(setup_file_hash, token_7);
-    char *value_8 = getHashEntry(setup_file_hash, token_8);
-    char *value_9 = getHashEntry(setup_file_hash, token_9);
-
-    if (value_1 != NULL)
-      menu.enter_screen[i].fade_mode = get_token_parameter_value(token_1,
-                                                                value_1);
-    if (value_2 != NULL)
-      menu.enter_screen[i].fade_delay = get_token_parameter_value(token_2,
-                                                                 value_2);
-    if (value_3 != NULL)
-      menu.enter_screen[i].post_delay = get_token_parameter_value(token_3,
-                                                                 value_3);
-    if (value_4 != NULL)
-      menu.leave_screen[i].fade_mode = get_token_parameter_value(token_4,
-                                                                value_4);
-    if (value_5 != NULL)
-      menu.leave_screen[i].fade_delay = get_token_parameter_value(token_5,
-                                                                 value_5);
-    if (value_6 != NULL)
-      menu.leave_screen[i].post_delay = get_token_parameter_value(token_6,
-                                                                 value_6);
-    if (value_7 != NULL)
-      menu.next_screen[i].fade_mode = get_token_parameter_value(token_7,
-                                                               value_7);
-    if (value_8 != NULL)
-      menu.next_screen[i].fade_delay = get_token_parameter_value(token_8,
-                                                                value_8);
-    if (value_9 != NULL)
-      menu.next_screen[i].post_delay = get_token_parameter_value(token_9,
-                                                                value_9);
-  }
-
-  /* special case: initialize with default values that may be overwritten */
-  /* (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz") */
+    struct TokenIntPtrInfo menu_config[] =
+    {
+      { "menu.enter_screen.fade_mode", &menu.enter_screen[i].fade_mode  },
+      { "menu.enter_screen.fade_delay",        &menu.enter_screen[i].fade_delay },
+      { "menu.enter_screen.post_delay",        &menu.enter_screen[i].post_delay },
+      { "menu.leave_screen.fade_mode", &menu.leave_screen[i].fade_mode  },
+      { "menu.leave_screen.fade_delay",        &menu.leave_screen[i].fade_delay },
+      { "menu.leave_screen.post_delay",        &menu.leave_screen[i].post_delay },
+      { "menu.next_screen.fade_mode",  &menu.next_screen[i].fade_mode   },
+      { "menu.next_screen.fade_delay", &menu.next_screen[i].fade_delay  },
+      { "menu.next_screen.post_delay", &menu.next_screen[i].post_delay  }
+    };
+
+    for (j = 0; j < ARRAY_SIZE(menu_config); j++)
+    {
+      char *token = menu_config[j].token;
+      char *value = getHashEntry(setup_file_hash, token);
+
+      if (value != NULL)
+        *menu_config[j].value = get_token_parameter_value(token, value);
+    }
+  }
+
+  // special case: initialize with default values that may be overwritten
+  // (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz")
   for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
   {
-    char *token_w1 = "viewport.window.width";
-    char *token_w2 = "viewport.window.height";
-    char *token_01 = "viewport.playfield.x";
-    char *token_02 = "viewport.playfield.y";
-    char *token_03 = "viewport.playfield.width";
-    char *token_04 = "viewport.playfield.height";
-    char *token_05 = "viewport.playfield.border_size";
-    char *token_06 = "viewport.door_1.x";
-    char *token_07 = "viewport.door_1.y";
-    char *token_08 = "viewport.door_1.width";
-    char *token_09 = "viewport.door_1.height";
-    char *token_10 = "viewport.door_1.border_size";
-    char *token_11 = "viewport.door_2.x";
-    char *token_12 = "viewport.door_2.y";
-    char *token_13 = "viewport.door_2.width";
-    char *token_14 = "viewport.door_2.height";
-    char *token_15 = "viewport.door_2.border_size";
-    char *value_w1 = getHashEntry(setup_file_hash, token_w1);
-    char *value_w2 = getHashEntry(setup_file_hash, token_w2);
-    char *value_01 = getHashEntry(setup_file_hash, token_01);
-    char *value_02 = getHashEntry(setup_file_hash, token_02);
-    char *value_03 = getHashEntry(setup_file_hash, token_03);
-    char *value_04 = getHashEntry(setup_file_hash, token_04);
-    char *value_05 = getHashEntry(setup_file_hash, token_05);
-    char *value_06 = getHashEntry(setup_file_hash, token_06);
-    char *value_07 = getHashEntry(setup_file_hash, token_07);
-    char *value_08 = getHashEntry(setup_file_hash, token_08);
-    char *value_09 = getHashEntry(setup_file_hash, token_09);
-    char *value_10 = getHashEntry(setup_file_hash, token_10);
-    char *value_11 = getHashEntry(setup_file_hash, token_11);
-    char *value_12 = getHashEntry(setup_file_hash, token_12);
-    char *value_13 = getHashEntry(setup_file_hash, token_13);
-    char *value_14 = getHashEntry(setup_file_hash, token_14);
-    char *value_15 = getHashEntry(setup_file_hash, token_15);
-
-    if (value_w1 != NULL)
-      viewport.window[i].width = get_token_parameter_value(token_w1, value_w1);
-    if (value_w2 != NULL)
-      viewport.window[i].height = get_token_parameter_value(token_w2, value_w2);
-    if (value_01 != NULL)
-      viewport.playfield[i].x = get_token_parameter_value(token_01, value_01);
-    if (value_02 != NULL)
-      viewport.playfield[i].y = get_token_parameter_value(token_02, value_02);
-    if (value_03 != NULL)
-      viewport.playfield[i].width = get_token_parameter_value(token_03,
-                                                             value_03);
-    if (value_04 != NULL)
-      viewport.playfield[i].height = get_token_parameter_value(token_04,
-                                                              value_04);
-    if (value_05 != NULL)
-      viewport.playfield[i].border_size = get_token_parameter_value(token_05,
-                                                                   value_05);
-    if (value_06 != NULL)
-      viewport.door_1[i].x = get_token_parameter_value(token_06, value_06);
-    if (value_07 != NULL)
-      viewport.door_1[i].y = get_token_parameter_value(token_07, value_07);
-    if (value_08 != NULL)
-      viewport.door_1[i].width = get_token_parameter_value(token_08, value_08);
-    if (value_09 != NULL)
-      viewport.door_1[i].height = get_token_parameter_value(token_09, value_09);
-    if (value_10 != NULL)
-      viewport.door_1[i].border_size = get_token_parameter_value(token_10,
-                                                                value_10);
-    if (value_11 != NULL)
-      viewport.door_2[i].x = get_token_parameter_value(token_11, value_11);
-    if (value_12 != NULL)
-      viewport.door_2[i].y = get_token_parameter_value(token_12, value_12);
-    if (value_13 != NULL)
-      viewport.door_2[i].width = get_token_parameter_value(token_13, value_13);
-    if (value_14 != NULL)
-      viewport.door_2[i].height = get_token_parameter_value(token_14, value_14);
-    if (value_15 != NULL)
-      viewport.door_1[i].border_size = get_token_parameter_value(token_15,
-                                                                value_15);
-  }
-
-  /* special case: initialize with default values that may be overwritten */
-  /* (e.g., init "[title].fade_mode" from "menu.next_screen.TITLE.fade_mode") */
+    struct
+    {
+      char *token_prefix;
+      struct RectWithBorder *struct_ptr;
+    }
+    vp_struct[] =
+    {
+      { "viewport.window",     &viewport.window[i]     },
+      { "viewport.playfield",  &viewport.playfield[i]  },
+      { "viewport.door_1",     &viewport.door_1[i]     },
+      { "viewport.door_2",     &viewport.door_2[i]     }
+    };
+
+    for (j = 0; j < ARRAY_SIZE(vp_struct); j++)
+    {
+      struct TokenIntPtrInfo vp_config[] =
+      {
+        { ".x",                        &vp_struct[j].struct_ptr->x             },
+        { ".y",                        &vp_struct[j].struct_ptr->y             },
+        { ".width",            &vp_struct[j].struct_ptr->width         },
+        { ".height",           &vp_struct[j].struct_ptr->height        },
+        { ".min_width",                &vp_struct[j].struct_ptr->min_width     },
+        { ".min_height",       &vp_struct[j].struct_ptr->min_height    },
+        { ".max_width",                &vp_struct[j].struct_ptr->max_width     },
+        { ".max_height",       &vp_struct[j].struct_ptr->max_height    },
+        { ".margin_left",      &vp_struct[j].struct_ptr->margin_left   },
+        { ".margin_right",     &vp_struct[j].struct_ptr->margin_right  },
+        { ".margin_top",       &vp_struct[j].struct_ptr->margin_top    },
+        { ".margin_bottom",    &vp_struct[j].struct_ptr->margin_bottom },
+        { ".border_left",      &vp_struct[j].struct_ptr->border_left   },
+        { ".border_right",     &vp_struct[j].struct_ptr->border_right  },
+        { ".border_top",       &vp_struct[j].struct_ptr->border_top    },
+        { ".border_bottom",    &vp_struct[j].struct_ptr->border_bottom },
+        { ".border_size",      &vp_struct[j].struct_ptr->border_size   },
+        { ".align_size",       &vp_struct[j].struct_ptr->align_size    },
+        { ".align",            &vp_struct[j].struct_ptr->align         },
+        { ".valign",           &vp_struct[j].struct_ptr->valign        }
+      };
+
+      for (k = 0; k < ARRAY_SIZE(vp_config); k++)
+      {
+        char *token = getStringCat2(vp_struct[j].token_prefix,
+                                    vp_config[k].token);
+        char *value = getHashEntry(setup_file_hash, token);
+
+        if (value != NULL)
+          *vp_config[k].value = get_token_parameter_value(token, value);
+
+        free(token);
+      }
+    }
+  }
+
+  // special case: initialize with default values that may be overwritten
+  // (e.g., init "[title].fade_mode" from "menu.next_screen.TITLE.fade_mode")
   for (i = 0; title_info[i].info != NULL; i++)
   {
     struct TitleFadingInfo *info = title_info[i].info;
@@ -9697,8 +11097,8 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
     }
   }
 
-  /* special case: initialize with default values that may be overwritten */
-  /* (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode") */
+  // special case: initialize with default values that may be overwritten
+  // (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode")
   for (i = 0; titlemessage_arrays[i].array != NULL; i++)
   {
     struct TitleMessageInfo *array = titlemessage_arrays[i].array;
@@ -9730,12 +11130,31 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
     }
   }
 
-  /* read (and overwrite with) values that may be specified in config file */
+  // special case: check if network and preview player positions are redefined,
+  // to compare this later against the main menu level preview being redefined
+  struct TokenIntPtrInfo menu_config_players[] =
+  {
+    { "main.network_players.x",        &menu.main.network_players.redefined    },
+    { "main.network_players.y",        &menu.main.network_players.redefined    },
+    { "main.preview_players.x",        &menu.main.preview_players.redefined    },
+    { "main.preview_players.y",        &menu.main.preview_players.redefined    },
+    { "preview.x",             &preview.redefined                      },
+    { "preview.y",             &preview.redefined                      }
+  };
+
+  for (i = 0; i < ARRAY_SIZE(menu_config_players); i++)
+    *menu_config_players[i].value = FALSE;
+
+  for (i = 0; i < ARRAY_SIZE(menu_config_players); i++)
+    if (getHashEntry(setup_file_hash, menu_config_players[i].token) != NULL)
+      *menu_config_players[i].value = TRUE;
+
+  // read (and overwrite with) values that may be specified in config file
   for (i = 0; image_config_vars[i].token != NULL; i++)
   {
     char *value = getHashEntry(setup_file_hash, image_config_vars[i].token);
 
-    /* (ignore definitions set to "[DEFAULT]" which are already initialized) */
+    // (ignore definitions set to "[DEFAULT]" which are already initialized)
     if (value != NULL && !strEqual(value, ARG_DEFAULT))
       *image_config_vars[i].value =
        get_token_parameter_value(image_config_vars[i].token, value);
@@ -9744,7 +11163,7 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
   freeSetupFileHash(setup_file_hash);
 }
 
-void LoadMenuDesignSettings()
+void LoadMenuDesignSettings(void)
 {
   char *filename_base = UNDEFINED_FILENAME, *filename_local;
 
@@ -9753,7 +11172,7 @@ void LoadMenuDesignSettings()
 
   if (!GFX_OVERRIDE_ARTWORK(ARTWORK_TYPE_GRAPHICS))
   {
-    /* first look for special settings configured in level series config */
+    // first look for special settings configured in level series config
     filename_base = getCustomArtworkLevelConfigFilename(ARTWORK_TYPE_GRAPHICS);
 
     if (fileExists(filename_base))
@@ -9768,7 +11187,7 @@ void LoadMenuDesignSettings()
   InitMenuDesignSettings_SpecialPostProcessing();
 }
 
-void LoadMenuDesignSettings_AfterGraphics()
+void LoadMenuDesignSettings_AfterGraphics(void)
 {
   InitMenuDesignSettings_SpecialPostProcessing_AfterGraphics();
 }
@@ -9789,18 +11208,18 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements)
   for (i = 0; i < NUM_FILE_ELEMENTS; i++)
     setHashEntry(element_hash, element_info[i].token_name, i_to_a(i));
 
-  /* determined size may be larger than needed (due to unknown elements) */
+  // determined size may be larger than needed (due to unknown elements)
   *num_elements = 0;
   for (list = setup_file_list; list != NULL; list = list->next)
     (*num_elements)++;
 
-  /* add space for up to 3 more elements for padding that may be needed */
+  // add space for up to 3 more elements for padding that may be needed
   *num_elements += 3;
 
-  /* free memory for old list of elements, if needed */
+  // free memory for old list of elements, if needed
   checked_free(*elements);
 
-  /* allocate memory for new list of elements */
+  // allocate memory for new list of elements
   *elements = checked_malloc(*num_elements * sizeof(int));
 
   *num_elements = 0;
@@ -9808,7 +11227,7 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements)
   {
     char *value = getHashEntry(element_hash, list->token);
 
-    if (value == NULL)         /* try to find obsolete token mapping */
+    if (value == NULL)         // try to find obsolete token mapping
     {
       char *mapped_token = get_mapped_token(list->token);
 
@@ -9842,7 +11261,7 @@ void LoadUserDefinedEditorElementList(int **elements, int *num_elements)
   if (num_unknown_tokens > 0)
     Error(ERR_INFO_LINE, "-");
 
-  while (*num_elements % 4)    /* pad with empty elements, if needed */
+  while (*num_elements % 4)    // pad with empty elements, if needed
     (*elements)[(*num_elements)++] = EL_EMPTY;
 
   freeSetupFileList(setup_file_list);
@@ -9888,7 +11307,7 @@ static struct MusicFileInfo *get_music_file_info_ext(char *basename, int music,
   if (filename_music == NULL)
     return NULL;
 
-  /* ---------- try to replace file extension ---------- */
+  // ---------- try to replace file extension ----------
 
   filename_prefix = getStringCopy(filename_music);
   if (strrchr(filename_prefix, '.') != NULL)
@@ -9903,7 +11322,7 @@ static struct MusicFileInfo *get_music_file_info_ext(char *basename, int music,
 
   if (setup_file_hash == NULL)
   {
-    /* ---------- try to add file extension ---------- */
+    // ---------- try to add file extension ----------
 
     filename_prefix = getStringCopy(filename_music);
     filename_info = getStringCat2(filename_prefix, ".txt");
@@ -9918,7 +11337,7 @@ static struct MusicFileInfo *get_music_file_info_ext(char *basename, int music,
   if (setup_file_hash == NULL)
     return NULL;
 
-  /* ---------- music file info found ---------- */
+  // ---------- music file info found ----------
 
   clear_mem(&tmp_music_file_info, sizeof(struct MusicFileInfo));
 
@@ -9970,7 +11389,7 @@ static boolean sound_info_listed(struct MusicFileInfo *list, char *basename)
   return music_info_listed_ext(list, basename, TRUE);
 }
 
-void LoadMusicInfo()
+void LoadMusicInfo(void)
 {
   char *music_directory = getCustomMusicDirectory();
   int num_music = getMusicListSize();
@@ -10015,7 +11434,7 @@ void LoadMusicInfo()
     if (strEqual(music->filename, UNDEFINED_FILENAME))
       continue;
 
-    /* a configured file may be not recognized as music */
+    // a configured file may be not recognized as music
     if (!FileIsMusic(music->filename))
       continue;
 
@@ -10034,13 +11453,13 @@ void LoadMusicInfo()
     return;
   }
 
-  while ((dir_entry = readDirectory(dir)) != NULL)     /* loop all entries */
+  while ((dir_entry = readDirectory(dir)) != NULL)     // loop all entries
   {
     char *basename = dir_entry->basename;
     boolean music_already_used = FALSE;
     int i;
 
-    /* skip all music files that are configured in music config file */
+    // skip all music files that are configured in music config file
     for (i = 0; i < num_music; i++)
     {
       music = getMusicListEntry(i);
@@ -10084,7 +11503,7 @@ void LoadMusicInfo()
     if (strEqual(sound->filename, UNDEFINED_FILENAME))
       continue;
 
-    /* a configured file may be not recognized as sound */
+    // a configured file may be not recognized as sound
     if (!FileIsSound(sound->filename))
       continue;
 
@@ -10097,8 +11516,8 @@ void LoadMusicInfo()
   }
 }
 
-void add_helpanim_entry(int element, int action, int direction, int delay,
-                       int *num_list_entries)
+static void add_helpanim_entry(int element, int action, int direction,
+                              int delay, int *num_list_entries)
 {
   struct HelpAnimInfo *new_list_entry;
   (*num_list_entries)++;
@@ -10114,7 +11533,7 @@ void add_helpanim_entry(int element, int action, int direction, int delay,
   new_list_entry->delay = delay;
 }
 
-void print_unknown_token(char *filename, char *token, int token_nr)
+static void print_unknown_token(char *filename, char *token, int token_nr)
 {
   if (token_nr == 0)
   {
@@ -10126,13 +11545,13 @@ void print_unknown_token(char *filename, char *token, int token_nr)
   Error(ERR_INFO, "- token: '%s'", token);
 }
 
-void print_unknown_token_end(int token_nr)
+static void print_unknown_token_end(int token_nr)
 {
   if (token_nr > 0)
     Error(ERR_INFO_LINE, "-");
 }
 
-void LoadHelpAnimInfo()
+void LoadHelpAnimInfo(void)
 {
   char *filename = getHelpAnimFilename();
   SetupFileList *setup_file_list = NULL, *list;
@@ -10146,7 +11565,7 @@ void LoadHelpAnimInfo()
 
   if (setup_file_list == NULL)
   {
-    /* use reliable default values from static configuration */
+    // use reliable default values from static configuration
     SetupFileList *insert_ptr;
 
     insert_ptr = setup_file_list =
@@ -10170,7 +11589,7 @@ void LoadHelpAnimInfo()
     setHashEntry(action_hash, element_action_info[i].suffix,
                 i_to_a(element_action_info[i].value));
 
-  /* do not store direction index (bit) here, but direction value! */
+  // do not store direction index (bit) here, but direction value!
   for (i = 0; i < NUM_DIRECTIONS_FULL; i++)
     setHashEntry(direction_hash, element_direction_info[i].suffix,
                 i_to_a(1 << element_direction_info[i].value));
@@ -10192,35 +11611,35 @@ void LoadHelpAnimInfo()
        if this does not work, also accept combined "element[.act][.dir]"
        elements (like "dynamite.active"), which are unique elements */
 
-    if (strchr(list->token, '.') == NULL)      /* token contains no '.' */
+    if (strchr(list->token, '.') == NULL)      // token contains no '.'
     {
       element_value = getHashEntry(element_hash, list->token);
-      if (element_value != NULL)       /* element found */
+      if (element_value != NULL)       // element found
        add_helpanim_entry(atoi(element_value), -1, -1, delay,
                           &num_list_entries);
       else
       {
-       /* no further suffixes found -- this is not an element */
+       // no further suffixes found -- this is not an element
        print_unknown_token(filename, list->token, num_unknown_tokens++);
       }
 
       continue;
     }
 
-    /* token has format "<prefix>.<something>" */
+    // token has format "<prefix>.<something>"
 
-    action_token = strchr(list->token, '.');   /* suffix may be action ... */
-    direction_token = action_token;            /* ... or direction */
+    action_token = strchr(list->token, '.');   // suffix may be action ...
+    direction_token = action_token;            // ... or direction
 
     element_token = getStringCopy(list->token);
     *strchr(element_token, '.') = '\0';
 
     element_value = getHashEntry(element_hash, element_token);
 
-    if (element_value == NULL)         /* this is no element */
+    if (element_value == NULL)         // this is no element
     {
       element_value = getHashEntry(element_hash, list->token);
-      if (element_value != NULL)       /* combined element found */
+      if (element_value != NULL)       // combined element found
        add_helpanim_entry(atoi(element_value), -1, -1, delay,
                           &num_list_entries);
       else
@@ -10233,7 +11652,7 @@ void LoadHelpAnimInfo()
 
     action_value = getHashEntry(action_hash, action_token);
 
-    if (action_value != NULL)          /* action found */
+    if (action_value != NULL)          // action found
     {
       add_helpanim_entry(atoi(element_value), atoi(action_value), -1, delay,
                    &num_list_entries);
@@ -10245,7 +11664,7 @@ void LoadHelpAnimInfo()
 
     direction_value = getHashEntry(direction_hash, direction_token);
 
-    if (direction_value != NULL)       /* direction found */
+    if (direction_value != NULL)       // direction found
     {
       add_helpanim_entry(atoi(element_value), -1, atoi(direction_value), delay,
                         &num_list_entries);
@@ -10257,10 +11676,10 @@ void LoadHelpAnimInfo()
 
     if (strchr(action_token + 1, '.') == NULL)
     {
-      /* no further suffixes found -- this is not an action nor direction */
+      // no further suffixes found -- this is not an action nor direction
 
       element_value = getHashEntry(element_hash, list->token);
-      if (element_value != NULL)       /* combined element found */
+      if (element_value != NULL)       // combined element found
        add_helpanim_entry(atoi(element_value), -1, -1, delay,
                           &num_list_entries);
       else
@@ -10271,7 +11690,7 @@ void LoadHelpAnimInfo()
       continue;
     }
 
-    /* token has format "<prefix>.<suffix>.<something>" */
+    // token has format "<prefix>.<suffix>.<something>"
 
     direction_token = strchr(action_token + 1, '.');
 
@@ -10280,10 +11699,10 @@ void LoadHelpAnimInfo()
 
     action_value = getHashEntry(action_hash, action_token);
 
-    if (action_value == NULL)          /* this is no action */
+    if (action_value == NULL)          // this is no action
     {
       element_value = getHashEntry(element_hash, list->token);
-      if (element_value != NULL)       /* combined element found */
+      if (element_value != NULL)       // combined element found
        add_helpanim_entry(atoi(element_value), -1, -1, delay,
                           &num_list_entries);
       else
@@ -10297,7 +11716,7 @@ void LoadHelpAnimInfo()
 
     direction_value = getHashEntry(direction_hash, direction_token);
 
-    if (direction_value != NULL)       /* direction found */
+    if (direction_value != NULL)       // direction found
     {
       add_helpanim_entry(atoi(element_value), atoi(action_value),
                         atoi(direction_value), delay, &num_list_entries);
@@ -10308,10 +11727,10 @@ void LoadHelpAnimInfo()
       continue;
     }
 
-    /* this is no direction */
+    // this is no direction
 
     element_value = getHashEntry(element_hash, list->token);
-    if (element_value != NULL)         /* combined element found */
+    if (element_value != NULL)         // combined element found
       add_helpanim_entry(atoi(element_value), -1, -1, delay,
                         &num_list_entries);
     else
@@ -10342,7 +11761,7 @@ void LoadHelpAnimInfo()
 #endif
 }
 
-void LoadHelpTextInfo()
+void LoadHelpTextInfo(void)
 {
   char *filename = getHelpTextFilename();
   int i;
@@ -10358,7 +11777,7 @@ void LoadHelpTextInfo()
 
   if (helptext_info == NULL)
   {
-    /* use reliable default values from static configuration */
+    // use reliable default values from static configuration
     helptext_info = newSetupFileHash();
 
     for (i = 0; helptext_config[i].token; i++)
@@ -10378,13 +11797,13 @@ void LoadHelpTextInfo()
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* convert levels                                                            */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// convert levels
+// ----------------------------------------------------------------------------
 
 #define MAX_NUM_CONVERT_LEVELS         1000
 
-void ConvertLevels()
+void ConvertLevels(void)
 {
   static LevelDirTree *convert_leveldir = NULL;
   static int convert_level_nr = -1;
@@ -10492,13 +11911,12 @@ void ConvertLevels()
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* create and save images for use in level sketches (raw BMP format)         */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// create and save images for use in level sketches (raw BMP format)
+// ----------------------------------------------------------------------------
 
-void CreateLevelSketchImages()
+void CreateLevelSketchImages(void)
 {
-#if defined(TARGET_SDL)
   Bitmap *bitmap1;
   Bitmap *bitmap2;
   int i;
@@ -10510,30 +11928,26 @@ void CreateLevelSketchImages()
 
   for (i = 0; i < NUM_FILE_ELEMENTS; i++)
   {
-    Bitmap *src_bitmap;
-    int src_x, src_y;
     int element = getMappedElement(i);
-    int graphic = el2edimg(element);
     char basename1[16];
     char basename2[16];
     char *filename1;
     char *filename2;
 
-    sprintf(basename1, "%03d.bmp", i);
-    sprintf(basename2, "%03ds.bmp", i);
+    sprintf(basename1, "%04d.bmp", i);
+    sprintf(basename2, "%04ds.bmp", i);
 
     filename1 = getPath2(global.create_images_dir, basename1);
     filename2 = getPath2(global.create_images_dir, basename2);
 
-    getFixedGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
-    BlitBitmap(src_bitmap, bitmap1, src_x, src_y, TILEX, TILEY,
-              0, 0);
+    DrawSizedElement(0, 0, element, TILESIZE);
+    BlitBitmap(drawto, bitmap1, SX, SY, TILEX, TILEY, 0, 0);
 
     if (SDL_SaveBMP(bitmap1->surface, filename1) != 0)
       Error(ERR_EXIT, "cannot save level sketch image file '%s'", filename1);
 
-    getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
-    BlitBitmap(src_bitmap, bitmap2, src_x, src_y, MINI_TILEX, MINI_TILEY, 0, 0);
+    DrawSizedElement(0, 0, element, MINI_TILESIZE);
+    BlitBitmap(drawto, bitmap2, SX, SY, MINI_TILEX, MINI_TILEY, 0, 0);
 
     if (SDL_SaveBMP(bitmap2->surface, filename2) != 0)
       Error(ERR_EXIT, "cannot save level sketch image file '%s'", filename2);
@@ -10541,30 +11955,39 @@ void CreateLevelSketchImages()
     free(filename1);
     free(filename2);
 
+    // create corresponding SQL statements (for normal and small images)
+    if (i < 1000)
+    {
+      printf("insert into phpbb_words values (NULL, '`%03d', '<IMG class=\"levelsketch\" src=\"/I/%04d.png\"/>');\n", i, i);
+      printf("insert into phpbb_words values (NULL, '¸%03d', '<IMG class=\"levelsketch\" src=\"/I/%04ds.png\"/>');\n", i, i);
+    }
+
+    printf("insert into phpbb_words values (NULL, '`%04d', '<IMG class=\"levelsketch\" src=\"/I/%04d.png\"/>');\n", i, i);
+    printf("insert into phpbb_words values (NULL, '¸%04d', '<IMG class=\"levelsketch\" src=\"/I/%04ds.png\"/>');\n", i, i);
+
+    // optional: create content for forum level sketch demonstration post
     if (options.debug)
-      printf("%03d `%03d%c", i, i, (i % 10 < 9 ? ' ' : '\n'));
+      fprintf(stderr, "%03d `%03d%c", i, i, (i % 10 < 9 ? ' ' : '\n'));
   }
 
   FreeBitmap(bitmap1);
   FreeBitmap(bitmap2);
 
   if (options.debug)
-    printf("\n");
+    fprintf(stderr, "\n");
 
   Error(ERR_INFO, "%d normal and small images created", NUM_FILE_ELEMENTS);
 
   CloseAllAndExit(0);
-#endif
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* create and save images for custom and group elements (raw BMP format)     */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// create and save images for custom and group elements (raw BMP format)
+// ----------------------------------------------------------------------------
 
 void CreateCustomElementImages(char *directory)
 {
-#if defined(TARGET_SDL)
   char *src_basename = "RocksCE-template.ilbm";
   char *dst_basename = "RocksCE.bmp";
   char *src_filename = getPath2(directory, src_basename);
@@ -10575,7 +11998,7 @@ void CreateCustomElementImages(char *directory)
   int yoffset_ge = (TILEY * NUM_CUSTOM_ELEMENTS / 16);
   int i;
 
-  SDLInitVideoDisplay();
+  InitVideoDefaults();
 
   ReCreateBitmap(&backbuffer, video.width, video.height);
 
@@ -10656,5 +12079,4 @@ void CreateCustomElementImages(char *directory)
   FreeBitmap(bitmap);
 
   CloseAllAndExit(0);
-#endif
 }