added optional button to restart game (door, panel and touch variants)
[rocksndiamonds.git] / src / editor.c
index c01689237136127918ef39267e0e587b895e1c9f..671ac61de7551324c23e7c14ecf4d6dd8b83eb3d 100644 (file)
@@ -2465,6 +2465,7 @@ static struct ValueTextInfo options_group_choice_mode[] =
   { ANIM_LINEAR,               "linear"                        },
   { ANIM_PINGPONG,             "pingpong"                      },
   { ANIM_PINGPONG2,            "pingpong 2"                    },
+  { ANIM_LEVEL_NR,             "level number"                  },
 
   { -1,                                NULL                            }
 };
@@ -4713,7 +4714,12 @@ static int editor_el_deflektor[] =
   EL_DF_STEEL_WALL,
   EL_DF_WOODEN_WALL,
   EL_DF_REFRACTOR,
-  EL_DF_MINE
+  EL_DF_MINE,
+
+  EL_DF_SLOPE_1,
+  EL_DF_SLOPE_2,
+  EL_DF_SLOPE_3,
+  EL_DF_SLOPE_4
 };
 static int *editor_hl_deflektor_ptr = editor_hl_deflektor;
 static int *editor_el_deflektor_ptr = editor_el_deflektor;
@@ -8912,8 +8918,8 @@ static void AdjustDrawingAreaGadgets(void)
 
   if (suppressBorderElement())
   {
-    ed_xsize = max_ed_fieldx;
-    ed_ysize = max_ed_fieldy;
+    ed_xsize = lev_fieldx;
+    ed_ysize = lev_fieldy;
   }
 
   // check if we need any scrollbars
@@ -11702,6 +11708,12 @@ static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element,
        EL_DF_RECEIVER_DOWN,
        EL_DF_RECEIVER_LEFT
       },
+      {
+       EL_DF_SLOPE_1,
+       EL_DF_SLOPE_4,
+       EL_DF_SLOPE_3,
+       EL_DF_SLOPE_2
+      },
 
       {
        -1,
@@ -12043,19 +12055,10 @@ static boolean isHiresDrawElement(int element)
 
 static int numHiresTiles(int element)
 {
-  if (!IS_MM_WALL(element))
-    return 1;
-
-  int bits = MM_WALL_BITS(element);
-  int num_bits = 0;
-
-  while (bits)
-  {
-    bits &= bits - 1;
-    num_bits++;
-  }
+  if (IS_MM_WALL(element))
+    return get_number_of_bits(MM_WALL_BITS(element));
 
-  return num_bits;
+  return 1;
 }
 
 static void SetDrawModeHiRes(int element)
@@ -12356,280 +12359,144 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y,
                                 MAX_CB_NUM_LINES *     \
                                 MAX_CB_PART_SIZE)
 
-static int getFlippedTileX(int element)
+static int getFlippedTileExt(int map[], int element)
 {
-  switch (element)
-  {
-    case EL_BD_BUTTERFLY_LEFT:         return EL_BD_BUTTERFLY_RIGHT;
-    case EL_BD_BUTTERFLY_RIGHT:                return EL_BD_BUTTERFLY_LEFT;
-
-    case EL_BD_FIREFLY_LEFT:           return EL_BD_FIREFLY_RIGHT;
-    case EL_BD_FIREFLY_RIGHT:          return EL_BD_FIREFLY_LEFT;
-
-    case EL_BUG_LEFT:                  return EL_BUG_RIGHT;
-    case EL_BUG_RIGHT:                 return EL_BUG_LEFT;
-
-    case EL_SPACESHIP_LEFT:            return EL_SPACESHIP_RIGHT;
-    case EL_SPACESHIP_RIGHT:           return EL_SPACESHIP_LEFT;
-
-    case EL_PACMAN_LEFT:               return EL_PACMAN_RIGHT;
-    case EL_PACMAN_RIGHT:              return EL_PACMAN_LEFT;
-
-    case EL_ARROW_LEFT:                        return EL_ARROW_RIGHT;
-    case EL_ARROW_RIGHT:               return EL_ARROW_LEFT;
-
-    case EL_MOLE_LEFT:                 return EL_MOLE_RIGHT;
-    case EL_MOLE_RIGHT:                        return EL_MOLE_LEFT;
-
-    case EL_BALLOON_SWITCH_LEFT:       return EL_BALLOON_SWITCH_RIGHT;
-    case EL_BALLOON_SWITCH_RIGHT:      return EL_BALLOON_SWITCH_LEFT;
-
-    case EL_YAMYAM_LEFT:               return EL_YAMYAM_RIGHT;
-    case EL_YAMYAM_RIGHT:              return EL_YAMYAM_LEFT;
-
-    case EL_SP_PORT_LEFT:              return EL_SP_PORT_RIGHT;
-    case EL_SP_PORT_RIGHT:             return EL_SP_PORT_LEFT;
-
-    case EL_SP_GRAVITY_PORT_LEFT:      return EL_SP_GRAVITY_PORT_RIGHT;
-    case EL_SP_GRAVITY_PORT_RIGHT:     return EL_SP_GRAVITY_PORT_LEFT;
-
-    case EL_SP_GRAVITY_ON_PORT_LEFT:   return EL_SP_GRAVITY_ON_PORT_RIGHT;
-    case EL_SP_GRAVITY_ON_PORT_RIGHT:  return EL_SP_GRAVITY_ON_PORT_LEFT;
-
-    case EL_SP_GRAVITY_OFF_PORT_LEFT:  return EL_SP_GRAVITY_OFF_PORT_RIGHT;
-    case EL_SP_GRAVITY_OFF_PORT_RIGHT: return EL_SP_GRAVITY_OFF_PORT_LEFT;
-
-    case EL_CONVEYOR_BELT_1_LEFT:      return EL_CONVEYOR_BELT_1_RIGHT;
-    case EL_CONVEYOR_BELT_1_RIGHT:     return EL_CONVEYOR_BELT_1_LEFT;
-
-    case EL_CONVEYOR_BELT_2_LEFT:      return EL_CONVEYOR_BELT_2_RIGHT;
-    case EL_CONVEYOR_BELT_2_RIGHT:     return EL_CONVEYOR_BELT_2_LEFT;
-
-    case EL_CONVEYOR_BELT_3_LEFT:      return EL_CONVEYOR_BELT_3_RIGHT;
-    case EL_CONVEYOR_BELT_3_RIGHT:     return EL_CONVEYOR_BELT_3_LEFT;
-
-    case EL_CONVEYOR_BELT_4_LEFT:      return EL_CONVEYOR_BELT_4_RIGHT;
-    case EL_CONVEYOR_BELT_4_RIGHT:     return EL_CONVEYOR_BELT_4_LEFT;
-
-    case EL_SPRING_LEFT:               return EL_SPRING_RIGHT;
-    case EL_SPRING_RIGHT:              return EL_SPRING_LEFT;
-
-    case EL_SP_CHIP_LEFT:              return EL_SP_CHIP_RIGHT;
-    case EL_SP_CHIP_RIGHT:             return EL_SP_CHIP_LEFT;
-
-    case EL_TUBE_VERTICAL_LEFT:                return EL_TUBE_VERTICAL_RIGHT;
-    case EL_TUBE_VERTICAL_RIGHT:       return EL_TUBE_VERTICAL_LEFT;
-    case EL_TUBE_LEFT_UP:              return EL_TUBE_RIGHT_UP;
-    case EL_TUBE_LEFT_DOWN:            return EL_TUBE_RIGHT_DOWN;
-    case EL_TUBE_RIGHT_UP:             return EL_TUBE_LEFT_UP;
-    case EL_TUBE_RIGHT_DOWN:           return EL_TUBE_LEFT_DOWN;
-
-    case EL_DC_STEELWALL_1_LEFT:       return EL_DC_STEELWALL_1_RIGHT;
-    case EL_DC_STEELWALL_1_RIGHT:      return EL_DC_STEELWALL_1_LEFT;
-    case EL_DC_STEELWALL_1_TOPLEFT:    return EL_DC_STEELWALL_1_TOPRIGHT;
-    case EL_DC_STEELWALL_1_TOPRIGHT:   return EL_DC_STEELWALL_1_TOPLEFT;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT: return EL_DC_STEELWALL_1_BOTTOMRIGHT;
-    case EL_DC_STEELWALL_1_BOTTOMRIGHT:        return EL_DC_STEELWALL_1_BOTTOMLEFT;
-    case EL_DC_STEELWALL_1_TOPLEFT_2:  return EL_DC_STEELWALL_1_TOPRIGHT_2;
-    case EL_DC_STEELWALL_1_TOPRIGHT_2: return EL_DC_STEELWALL_1_TOPLEFT_2;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT_2: return EL_DC_STEELWALL_1_BOTTOMRIGHT_2;
-    case EL_DC_STEELWALL_1_BOTTOMRIGHT_2: return EL_DC_STEELWALL_1_BOTTOMLEFT_2;
+  int i;
 
-    case EL_DC_STEELWALL_2_LEFT:       return EL_DC_STEELWALL_2_RIGHT;
-    case EL_DC_STEELWALL_2_RIGHT:      return EL_DC_STEELWALL_2_LEFT;
-
-    case EL_ACID_POOL_TOPLEFT:         return EL_ACID_POOL_TOPRIGHT;
-    case EL_ACID_POOL_TOPRIGHT:                return EL_ACID_POOL_TOPLEFT;
-    case EL_ACID_POOL_BOTTOMLEFT:      return EL_ACID_POOL_BOTTOMRIGHT;
-    case EL_ACID_POOL_BOTTOMRIGHT:     return EL_ACID_POOL_BOTTOMLEFT;
-  }
+  for (i = 0; map[i] != -1; i++)
+    if (map[i] == element)
+      return map[i ^ 1];       // get flipped element by flipping LSB of index
 
   return element;
 }
 
-static int getFlippedTileY(int element)
+static int getFlippedTileX(int element)
 {
-  switch (element)
-  {
-    case EL_BD_BUTTERFLY_UP:           return EL_BD_BUTTERFLY_DOWN;
-    case EL_BD_BUTTERFLY_DOWN:         return EL_BD_BUTTERFLY_UP;
-
-    case EL_BD_FIREFLY_UP:             return EL_BD_FIREFLY_DOWN;
-    case EL_BD_FIREFLY_DOWN:           return EL_BD_FIREFLY_UP;
-
-    case EL_BUG_UP:                    return EL_BUG_DOWN;
-    case EL_BUG_DOWN:                  return EL_BUG_UP;
-
-    case EL_SPACESHIP_UP:              return EL_SPACESHIP_DOWN;
-    case EL_SPACESHIP_DOWN:            return EL_SPACESHIP_UP;
-
-    case EL_PACMAN_UP:                 return EL_PACMAN_DOWN;
-    case EL_PACMAN_DOWN:               return EL_PACMAN_UP;
-
-    case EL_ARROW_UP:                  return EL_ARROW_DOWN;
-    case EL_ARROW_DOWN:                        return EL_ARROW_UP;
-
-    case EL_MOLE_UP:                   return EL_MOLE_DOWN;
-    case EL_MOLE_DOWN:                 return EL_MOLE_UP;
-
-    case EL_BALLOON_SWITCH_UP:         return EL_BALLOON_SWITCH_DOWN;
-    case EL_BALLOON_SWITCH_DOWN:       return EL_BALLOON_SWITCH_UP;
-
-    case EL_YAMYAM_UP:                 return EL_YAMYAM_DOWN;
-    case EL_YAMYAM_DOWN:               return EL_YAMYAM_UP;
-
-    case EL_SP_PORT_UP:                        return EL_SP_PORT_DOWN;
-    case EL_SP_PORT_DOWN:              return EL_SP_PORT_UP;
-
-    case EL_SP_GRAVITY_PORT_UP:                return EL_SP_GRAVITY_PORT_DOWN;
-    case EL_SP_GRAVITY_PORT_DOWN:      return EL_SP_GRAVITY_PORT_UP;
-
-    case EL_SP_GRAVITY_ON_PORT_UP:     return EL_SP_GRAVITY_ON_PORT_DOWN;
-    case EL_SP_GRAVITY_ON_PORT_DOWN:   return EL_SP_GRAVITY_ON_PORT_UP;
-
-    case EL_SP_GRAVITY_OFF_PORT_UP:    return EL_SP_GRAVITY_OFF_PORT_DOWN;
-    case EL_SP_GRAVITY_OFF_PORT_DOWN:  return EL_SP_GRAVITY_OFF_PORT_UP;
-
-    case EL_SP_CHIP_TOP:               return EL_SP_CHIP_BOTTOM;
-    case EL_SP_CHIP_BOTTOM:            return EL_SP_CHIP_TOP;
-
-    case EL_TUBE_HORIZONTAL_UP:                return EL_TUBE_HORIZONTAL_DOWN;
-    case EL_TUBE_HORIZONTAL_DOWN:      return EL_TUBE_HORIZONTAL_UP;
-    case EL_TUBE_LEFT_UP:              return EL_TUBE_LEFT_DOWN;
-    case EL_TUBE_LEFT_DOWN:            return EL_TUBE_LEFT_UP;
-    case EL_TUBE_RIGHT_UP:             return EL_TUBE_RIGHT_DOWN;
-    case EL_TUBE_RIGHT_DOWN:           return EL_TUBE_RIGHT_UP;
-
-    case EL_DC_STEELWALL_1_TOP:                return EL_DC_STEELWALL_1_BOTTOM;
-    case EL_DC_STEELWALL_1_BOTTOM:     return EL_DC_STEELWALL_1_TOP;
-    case EL_DC_STEELWALL_1_TOPLEFT:    return EL_DC_STEELWALL_1_BOTTOMLEFT;
-    case EL_DC_STEELWALL_1_TOPRIGHT:   return EL_DC_STEELWALL_1_BOTTOMRIGHT;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT: return EL_DC_STEELWALL_1_TOPLEFT;
-    case EL_DC_STEELWALL_1_BOTTOMRIGHT:        return EL_DC_STEELWALL_1_TOPRIGHT;
-    case EL_DC_STEELWALL_1_TOPLEFT_2:  return EL_DC_STEELWALL_1_BOTTOMLEFT_2;
-    case EL_DC_STEELWALL_1_TOPRIGHT_2: return EL_DC_STEELWALL_1_BOTTOMRIGHT_2;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT_2: return EL_DC_STEELWALL_1_TOPLEFT_2;
-    case EL_DC_STEELWALL_1_BOTTOMRIGHT_2: return EL_DC_STEELWALL_1_TOPRIGHT_2;
+  int map[] =
+  {
+    EL_BD_BUTTERFLY_LEFT,              EL_BD_BUTTERFLY_RIGHT,
+    EL_BD_FIREFLY_LEFT,                        EL_BD_FIREFLY_RIGHT,
+    EL_BUG_LEFT,                       EL_BUG_RIGHT,
+    EL_SPACESHIP_LEFT,                 EL_SPACESHIP_RIGHT,
+    EL_PACMAN_LEFT,                    EL_PACMAN_RIGHT,
+    EL_ARROW_LEFT,                     EL_ARROW_RIGHT,
+    EL_MOLE_LEFT,                      EL_MOLE_RIGHT,
+    EL_BALLOON_SWITCH_LEFT,            EL_BALLOON_SWITCH_RIGHT,
+    EL_YAMYAM_LEFT,                    EL_YAMYAM_RIGHT,
+    EL_SP_PORT_LEFT,                   EL_SP_PORT_RIGHT,
+    EL_SP_GRAVITY_PORT_LEFT,           EL_SP_GRAVITY_PORT_RIGHT,
+    EL_SP_GRAVITY_ON_PORT_LEFT,                EL_SP_GRAVITY_ON_PORT_RIGHT,
+    EL_SP_GRAVITY_OFF_PORT_LEFT,       EL_SP_GRAVITY_OFF_PORT_RIGHT,
+    EL_CONVEYOR_BELT_1_LEFT,           EL_CONVEYOR_BELT_1_RIGHT,
+    EL_CONVEYOR_BELT_2_LEFT,           EL_CONVEYOR_BELT_2_RIGHT,
+    EL_CONVEYOR_BELT_3_LEFT,           EL_CONVEYOR_BELT_3_RIGHT,
+    EL_CONVEYOR_BELT_4_LEFT,           EL_CONVEYOR_BELT_4_RIGHT,
+    EL_SPRING_LEFT,                    EL_SPRING_RIGHT,
+    EL_SP_CHIP_LEFT,                   EL_SP_CHIP_RIGHT,
+    EL_TUBE_VERTICAL_LEFT,             EL_TUBE_VERTICAL_RIGHT,
+    EL_TUBE_LEFT_UP,                   EL_TUBE_RIGHT_UP,
+    EL_TUBE_LEFT_DOWN,                 EL_TUBE_RIGHT_DOWN,
+    EL_DC_STEELWALL_1_LEFT,            EL_DC_STEELWALL_1_RIGHT,
+    EL_DC_STEELWALL_1_TOPLEFT,         EL_DC_STEELWALL_1_TOPRIGHT,
+    EL_DC_STEELWALL_1_BOTTOMLEFT,      EL_DC_STEELWALL_1_BOTTOMRIGHT,
+    EL_DC_STEELWALL_1_TOPLEFT_2,       EL_DC_STEELWALL_1_TOPRIGHT_2,
+    EL_DC_STEELWALL_1_BOTTOMLEFT_2,    EL_DC_STEELWALL_1_BOTTOMRIGHT_2,
+    EL_DC_STEELWALL_2_LEFT,            EL_DC_STEELWALL_2_RIGHT,
+    EL_ACID_POOL_TOPLEFT,              EL_ACID_POOL_TOPRIGHT,
+    EL_ACID_POOL_BOTTOMLEFT,           EL_ACID_POOL_BOTTOMRIGHT,
+
+    -1
+  };
 
-    case EL_DC_STEELWALL_2_TOP:                return EL_DC_STEELWALL_2_BOTTOM;
-    case EL_DC_STEELWALL_2_BOTTOM:     return EL_DC_STEELWALL_2_TOP;
+  return getFlippedTileExt(map, element);
+}
 
-    case EL_EMC_WALL_1:                        return EL_EMC_WALL_3;
-    case EL_EMC_WALL_3:                        return EL_EMC_WALL_1;
-  }
+static int getFlippedTileY(int element)
+{
+  int map[] =
+  {
+    EL_BD_BUTTERFLY_UP,                        EL_BD_BUTTERFLY_DOWN,
+    EL_BD_FIREFLY_UP,                  EL_BD_FIREFLY_DOWN,
+    EL_BUG_UP,                         EL_BUG_DOWN,
+    EL_SPACESHIP_UP,                   EL_SPACESHIP_DOWN,
+    EL_PACMAN_UP,                      EL_PACMAN_DOWN,
+    EL_ARROW_UP,                       EL_ARROW_DOWN,
+    EL_MOLE_UP,                                EL_MOLE_DOWN,
+    EL_BALLOON_SWITCH_UP,              EL_BALLOON_SWITCH_DOWN,
+    EL_YAMYAM_UP,                      EL_YAMYAM_DOWN,
+    EL_SP_PORT_UP,                     EL_SP_PORT_DOWN,
+    EL_SP_GRAVITY_PORT_UP,             EL_SP_GRAVITY_PORT_DOWN,
+    EL_SP_GRAVITY_ON_PORT_UP,          EL_SP_GRAVITY_ON_PORT_DOWN,
+    EL_SP_GRAVITY_OFF_PORT_UP,         EL_SP_GRAVITY_OFF_PORT_DOWN,
+    EL_SP_CHIP_TOP,                    EL_SP_CHIP_BOTTOM,
+    EL_TUBE_HORIZONTAL_UP,             EL_TUBE_HORIZONTAL_DOWN,
+    EL_TUBE_LEFT_UP,                   EL_TUBE_LEFT_DOWN,
+    EL_TUBE_RIGHT_UP,                  EL_TUBE_RIGHT_DOWN,
+    EL_DC_STEELWALL_1_TOP,             EL_DC_STEELWALL_1_BOTTOM,
+    EL_DC_STEELWALL_1_TOPLEFT,         EL_DC_STEELWALL_1_BOTTOMLEFT,
+    EL_DC_STEELWALL_1_TOPRIGHT,                EL_DC_STEELWALL_1_BOTTOMRIGHT,
+    EL_DC_STEELWALL_1_TOPLEFT_2,       EL_DC_STEELWALL_1_BOTTOMLEFT_2,
+    EL_DC_STEELWALL_1_TOPRIGHT_2,      EL_DC_STEELWALL_1_BOTTOMRIGHT_2,
+    EL_DC_STEELWALL_2_TOP,             EL_DC_STEELWALL_2_BOTTOM,
+    EL_EMC_WALL_1,                     EL_EMC_WALL_3,
+
+    -1
+  };
 
-  return element;
+  return getFlippedTileExt(map, element);
 }
 
 static int getFlippedTileXY(int element)
 {
-  switch (element)
-  {
-    case EL_BD_BUTTERFLY_LEFT:         return EL_BD_BUTTERFLY_UP;
-    case EL_BD_BUTTERFLY_RIGHT:                return EL_BD_BUTTERFLY_DOWN;
-    case EL_BD_BUTTERFLY_UP:           return EL_BD_BUTTERFLY_LEFT;
-    case EL_BD_BUTTERFLY_DOWN:         return EL_BD_BUTTERFLY_RIGHT;
-
-    case EL_BD_FIREFLY_LEFT:           return EL_BD_FIREFLY_UP;
-    case EL_BD_FIREFLY_RIGHT:          return EL_BD_FIREFLY_DOWN;
-    case EL_BD_FIREFLY_UP:             return EL_BD_FIREFLY_LEFT;
-    case EL_BD_FIREFLY_DOWN:           return EL_BD_FIREFLY_RIGHT;
-
-    case EL_BUG_LEFT:                  return EL_BUG_UP;
-    case EL_BUG_RIGHT:                 return EL_BUG_DOWN;
-    case EL_BUG_UP:                    return EL_BUG_LEFT;
-    case EL_BUG_DOWN:                  return EL_BUG_RIGHT;
-
-    case EL_SPACESHIP_LEFT:            return EL_SPACESHIP_UP;
-    case EL_SPACESHIP_RIGHT:           return EL_SPACESHIP_DOWN;
-    case EL_SPACESHIP_UP:              return EL_SPACESHIP_LEFT;
-    case EL_SPACESHIP_DOWN:            return EL_SPACESHIP_RIGHT;
-
-    case EL_PACMAN_LEFT:               return EL_PACMAN_UP;
-    case EL_PACMAN_RIGHT:              return EL_PACMAN_DOWN;
-    case EL_PACMAN_UP:                 return EL_PACMAN_LEFT;
-    case EL_PACMAN_DOWN:               return EL_PACMAN_RIGHT;
-
-    case EL_ARROW_LEFT:                        return EL_ARROW_UP;
-    case EL_ARROW_RIGHT:               return EL_ARROW_DOWN;
-    case EL_ARROW_UP:                  return EL_ARROW_LEFT;
-    case EL_ARROW_DOWN:                        return EL_ARROW_RIGHT;
-
-    case EL_MOLE_LEFT:                 return EL_MOLE_UP;
-    case EL_MOLE_RIGHT:                        return EL_MOLE_DOWN;
-    case EL_MOLE_UP:                   return EL_MOLE_LEFT;
-    case EL_MOLE_DOWN:                 return EL_MOLE_RIGHT;
-
-    case EL_BALLOON_SWITCH_LEFT:       return EL_BALLOON_SWITCH_UP;
-    case EL_BALLOON_SWITCH_RIGHT:      return EL_BALLOON_SWITCH_DOWN;
-    case EL_BALLOON_SWITCH_UP:         return EL_BALLOON_SWITCH_LEFT;
-    case EL_BALLOON_SWITCH_DOWN:       return EL_BALLOON_SWITCH_RIGHT;
-
-    case EL_YAMYAM_LEFT:               return EL_YAMYAM_UP;
-    case EL_YAMYAM_RIGHT:              return EL_YAMYAM_DOWN;
-    case EL_YAMYAM_UP:                 return EL_YAMYAM_LEFT;
-    case EL_YAMYAM_DOWN:               return EL_YAMYAM_RIGHT;
-
-    case EL_SP_PORT_LEFT:              return EL_SP_PORT_UP;
-    case EL_SP_PORT_RIGHT:             return EL_SP_PORT_DOWN;
-    case EL_SP_PORT_UP:                        return EL_SP_PORT_LEFT;
-    case EL_SP_PORT_DOWN:              return EL_SP_PORT_RIGHT;
-
-    case EL_SP_GRAVITY_PORT_LEFT:      return EL_SP_GRAVITY_PORT_UP;
-    case EL_SP_GRAVITY_PORT_RIGHT:     return EL_SP_GRAVITY_PORT_DOWN;
-    case EL_SP_GRAVITY_PORT_UP:                return EL_SP_GRAVITY_PORT_LEFT;
-    case EL_SP_GRAVITY_PORT_DOWN:      return EL_SP_GRAVITY_PORT_RIGHT;
-
-    case EL_SP_GRAVITY_ON_PORT_LEFT:   return EL_SP_GRAVITY_ON_PORT_UP;
-    case EL_SP_GRAVITY_ON_PORT_RIGHT:  return EL_SP_GRAVITY_ON_PORT_DOWN;
-    case EL_SP_GRAVITY_ON_PORT_UP:     return EL_SP_GRAVITY_ON_PORT_LEFT;
-    case EL_SP_GRAVITY_ON_PORT_DOWN:   return EL_SP_GRAVITY_ON_PORT_RIGHT;
-
-    case EL_SP_GRAVITY_OFF_PORT_LEFT:  return EL_SP_GRAVITY_OFF_PORT_UP;
-    case EL_SP_GRAVITY_OFF_PORT_RIGHT: return EL_SP_GRAVITY_OFF_PORT_DOWN;
-    case EL_SP_GRAVITY_OFF_PORT_UP:    return EL_SP_GRAVITY_OFF_PORT_LEFT;
-    case EL_SP_GRAVITY_OFF_PORT_DOWN:  return EL_SP_GRAVITY_OFF_PORT_RIGHT;
-
-    case EL_SP_CHIP_LEFT:              return EL_SP_CHIP_TOP;
-    case EL_SP_CHIP_RIGHT:             return EL_SP_CHIP_BOTTOM;
-    case EL_SP_CHIP_TOP:               return EL_SP_CHIP_LEFT;
-    case EL_SP_CHIP_BOTTOM:            return EL_SP_CHIP_RIGHT;
-
-    case EL_TUBE_VERTICAL:             return EL_TUBE_HORIZONTAL;
-    case EL_TUBE_HORIZONTAL:           return EL_TUBE_VERTICAL;
-    case EL_TUBE_VERTICAL_LEFT:                return EL_TUBE_HORIZONTAL_UP;
-    case EL_TUBE_VERTICAL_RIGHT:       return EL_TUBE_HORIZONTAL_DOWN;
-    case EL_TUBE_HORIZONTAL_UP:                return EL_TUBE_VERTICAL_LEFT;
-    case EL_TUBE_HORIZONTAL_DOWN:      return EL_TUBE_VERTICAL_RIGHT;
-    case EL_TUBE_LEFT_DOWN:            return EL_TUBE_RIGHT_UP;
-    case EL_TUBE_RIGHT_UP:             return EL_TUBE_LEFT_DOWN;
-
-    case EL_DC_STEELWALL_1_LEFT:       return EL_DC_STEELWALL_1_TOP;
-    case EL_DC_STEELWALL_1_RIGHT:      return EL_DC_STEELWALL_1_BOTTOM;
-    case EL_DC_STEELWALL_1_TOP:                return EL_DC_STEELWALL_1_LEFT;
-    case EL_DC_STEELWALL_1_BOTTOM:     return EL_DC_STEELWALL_1_RIGHT;
-    case EL_DC_STEELWALL_1_HORIZONTAL: return EL_DC_STEELWALL_1_VERTICAL;
-    case EL_DC_STEELWALL_1_VERTICAL:   return EL_DC_STEELWALL_1_HORIZONTAL;
-    case EL_DC_STEELWALL_1_TOPRIGHT:   return EL_DC_STEELWALL_1_BOTTOMLEFT;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT: return EL_DC_STEELWALL_1_TOPRIGHT;
-    case EL_DC_STEELWALL_1_TOPRIGHT_2: return EL_DC_STEELWALL_1_BOTTOMLEFT_2;
-    case EL_DC_STEELWALL_1_BOTTOMLEFT_2: return EL_DC_STEELWALL_1_TOPRIGHT_2;
-
-    case EL_DC_STEELWALL_2_LEFT:       return EL_DC_STEELWALL_2_TOP;
-    case EL_DC_STEELWALL_2_RIGHT:      return EL_DC_STEELWALL_2_BOTTOM;
-    case EL_DC_STEELWALL_2_TOP:                return EL_DC_STEELWALL_2_LEFT;
-    case EL_DC_STEELWALL_2_BOTTOM:     return EL_DC_STEELWALL_2_RIGHT;
-    case EL_DC_STEELWALL_2_HORIZONTAL: return EL_DC_STEELWALL_2_VERTICAL;
-    case EL_DC_STEELWALL_2_VERTICAL:   return EL_DC_STEELWALL_2_HORIZONTAL;
-
-    case EL_EXPANDABLE_WALL_HORIZONTAL:        return EL_EXPANDABLE_WALL_VERTICAL;
-    case EL_EXPANDABLE_WALL_VERTICAL:  return EL_EXPANDABLE_WALL_HORIZONTAL;
-
-    case EL_EXPANDABLE_STEELWALL_HORIZONTAL:   return EL_EXPANDABLE_STEELWALL_VERTICAL;
-    case EL_EXPANDABLE_STEELWALL_VERTICAL:     return EL_EXPANDABLE_STEELWALL_HORIZONTAL;
-  }
+  int map[] =
+  {
+    EL_BD_BUTTERFLY_LEFT,              EL_BD_BUTTERFLY_UP,
+    EL_BD_BUTTERFLY_RIGHT,             EL_BD_BUTTERFLY_DOWN,
+    EL_BD_FIREFLY_LEFT,                        EL_BD_FIREFLY_UP,
+    EL_BD_FIREFLY_RIGHT,               EL_BD_FIREFLY_DOWN,
+    EL_BUG_LEFT,                       EL_BUG_UP,
+    EL_BUG_RIGHT,                      EL_BUG_DOWN,
+    EL_SPACESHIP_LEFT,                 EL_SPACESHIP_UP,
+    EL_SPACESHIP_RIGHT,                        EL_SPACESHIP_DOWN,
+    EL_PACMAN_LEFT,                    EL_PACMAN_UP,
+    EL_PACMAN_RIGHT,                   EL_PACMAN_DOWN,
+    EL_ARROW_LEFT,                     EL_ARROW_UP,
+    EL_ARROW_RIGHT,                    EL_ARROW_DOWN,
+    EL_MOLE_LEFT,                      EL_MOLE_UP,
+    EL_MOLE_RIGHT,                     EL_MOLE_DOWN,
+    EL_BALLOON_SWITCH_LEFT,            EL_BALLOON_SWITCH_UP,
+    EL_BALLOON_SWITCH_RIGHT,           EL_BALLOON_SWITCH_DOWN,
+    EL_YAMYAM_LEFT,                    EL_YAMYAM_UP,
+    EL_YAMYAM_RIGHT,                   EL_YAMYAM_DOWN,
+    EL_SP_PORT_LEFT,                   EL_SP_PORT_UP,
+    EL_SP_PORT_RIGHT,                  EL_SP_PORT_DOWN,
+    EL_SP_GRAVITY_PORT_LEFT,           EL_SP_GRAVITY_PORT_UP,
+    EL_SP_GRAVITY_PORT_RIGHT,          EL_SP_GRAVITY_PORT_DOWN,
+    EL_SP_GRAVITY_ON_PORT_LEFT,                EL_SP_GRAVITY_ON_PORT_UP,
+    EL_SP_GRAVITY_ON_PORT_RIGHT,       EL_SP_GRAVITY_ON_PORT_DOWN,
+    EL_SP_GRAVITY_OFF_PORT_LEFT,       EL_SP_GRAVITY_OFF_PORT_UP,
+    EL_SP_GRAVITY_OFF_PORT_RIGHT,      EL_SP_GRAVITY_OFF_PORT_DOWN,
+    EL_SP_CHIP_LEFT,                   EL_SP_CHIP_TOP,
+    EL_SP_CHIP_RIGHT,                  EL_SP_CHIP_BOTTOM,
+    EL_TUBE_VERTICAL,                  EL_TUBE_HORIZONTAL,
+    EL_TUBE_VERTICAL_LEFT,             EL_TUBE_HORIZONTAL_UP,
+    EL_TUBE_VERTICAL_RIGHT,            EL_TUBE_HORIZONTAL_DOWN,
+    EL_TUBE_LEFT_DOWN,                 EL_TUBE_RIGHT_UP,
+    EL_DC_STEELWALL_1_LEFT,            EL_DC_STEELWALL_1_TOP,
+    EL_DC_STEELWALL_1_RIGHT,           EL_DC_STEELWALL_1_BOTTOM,
+    EL_DC_STEELWALL_1_HORIZONTAL,      EL_DC_STEELWALL_1_VERTICAL,
+    EL_DC_STEELWALL_1_TOPRIGHT,                EL_DC_STEELWALL_1_BOTTOMLEFT,
+    EL_DC_STEELWALL_1_TOPRIGHT_2,      EL_DC_STEELWALL_1_BOTTOMLEFT_2,
+    EL_DC_STEELWALL_2_LEFT,            EL_DC_STEELWALL_2_TOP,
+    EL_DC_STEELWALL_2_RIGHT,           EL_DC_STEELWALL_2_BOTTOM,
+    EL_DC_STEELWALL_2_HORIZONTAL,      EL_DC_STEELWALL_2_VERTICAL,
+    EL_EXPANDABLE_WALL_HORIZONTAL,     EL_EXPANDABLE_WALL_VERTICAL,
+    EL_EXPANDABLE_STEELWALL_HORIZONTAL,        EL_EXPANDABLE_STEELWALL_VERTICAL,
+
+    -1
+  };
 
-  return element;
+  return getFlippedTileExt(map, element);
 }
 
 static int getFlippedTile(int element, int mode)
@@ -13440,7 +13307,8 @@ static void WrapLevel(int dx, int dy)
   CopyLevelToUndoBuffer(UNDO_ACCUMULATE);
 }
 
-static void DrawAreaElementHighlight(boolean highlighted)
+static void DrawAreaElementHighlight(boolean highlighted,
+                                    boolean highlighted_similar)
 {
   DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
 
@@ -13453,26 +13321,69 @@ static void DrawAreaElementHighlight(boolean highlighted)
   {
     for (y = 0; y < ed_fieldy; y++)
     {
+      boolean highlight = FALSE;
       int lx = x + level_xpos;
       int ly = y + level_ypos;
 
       if (!IN_LEV_FIELD(lx, ly))
        continue;
 
-      if (Tile[lx][ly] != new_element1)
+      // check if element is the same
+      if (Tile[lx][ly] == new_element1)
+       highlight = TRUE;
+
+      // check if element is similar
+      if (highlighted_similar &&
+         strEqual(element_info[Tile[lx][ly]].class_name,
+                  element_info[new_element1].class_name))
+       highlight = TRUE;
+
+      // check if element is matching MM style wall
+      if (IS_MM_WALL(Tile[lx][ly]) &&
+         map_mm_wall_element(Tile[lx][ly]) == new_element1)
+       highlight = TRUE;
+
+      if (!highlight)
        continue;
 
-      int sx = SX + x * ed_tilesize;
-      int sy = SY + y * ed_tilesize;
-      int from_sx = sx;
-      int from_sy = sy;
-      int to_sx = sx + ed_tilesize - 1;
-      int to_sy = sy + ed_tilesize - 1;
-
-      DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx,   from_sy);
-      DrawSimpleWhiteLine(drawto, to_sx,   from_sy, to_sx,   to_sy);
-      DrawSimpleWhiteLine(drawto, to_sx,   to_sy,   from_sx, to_sy);
-      DrawSimpleWhiteLine(drawto, from_sx, to_sy,   from_sx, from_sy);
+      if (IS_MM_WALL(Tile[lx][ly]) && !highlighted_similar)
+      {
+       int i;
+
+       for (i = 0; i < 4; i++)
+       {
+         if (!(MM_WALL_BITS(Tile[lx][ly]) & (1 << i)))
+           continue;
+
+         int xx = x * 2 + (i % 2);
+         int yy = y * 2 + (i / 2);
+         int sx = SX + xx * ed_tilesize / 2;
+         int sy = SY + yy * ed_tilesize / 2;
+         int from_sx = sx;
+         int from_sy = sy;
+         int to_sx = sx + ed_tilesize / 2 - 1;
+         int to_sy = sy + ed_tilesize / 2 - 1;
+
+         DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx,   from_sy);
+         DrawSimpleWhiteLine(drawto, to_sx,   from_sy, to_sx,   to_sy);
+         DrawSimpleWhiteLine(drawto, to_sx,   to_sy,   from_sx, to_sy);
+         DrawSimpleWhiteLine(drawto, from_sx, to_sy,   from_sx, from_sy);
+       }
+      }
+      else
+      {
+       int sx = SX + x * ed_tilesize;
+       int sy = SY + y * ed_tilesize;
+       int from_sx = sx;
+       int from_sy = sy;
+       int to_sx = sx + ed_tilesize - 1;
+       int to_sy = sy + ed_tilesize - 1;
+
+       DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx,   from_sy);
+       DrawSimpleWhiteLine(drawto, to_sx,   from_sy, to_sx,   to_sy);
+       DrawSimpleWhiteLine(drawto, to_sx,   to_sy,   from_sx, to_sy);
+       DrawSimpleWhiteLine(drawto, from_sx, to_sy,   from_sx, from_sy);
+      }
     }
   }
 }
@@ -15095,16 +15006,20 @@ static void HandleLevelEditorIdle_Properties(void)
 static void HandleLevelEditorIdle_Drawing(void)
 {
   static boolean last_highlighted = FALSE;
+  static boolean last_highlighted_similar = FALSE;
   boolean highlighted = (GetKeyModState() & KMOD_Alt);
+  boolean highlighted_similar = (GetKeyModState() & KMOD_Shift);
 
-  if (highlighted != last_highlighted)
+  if (highlighted != last_highlighted ||
+      (highlighted && highlighted_similar != last_highlighted_similar))
   {
-    DrawAreaElementHighlight(highlighted);
-
-    last_highlighted = highlighted;
+    DrawAreaElementHighlight(highlighted, highlighted_similar);
 
     redraw_mask |= REDRAW_FIELD;
   }
+
+  last_highlighted = highlighted;
+  last_highlighted_similar = highlighted_similar;
 }
 
 void HandleLevelEditorIdle(void)
@@ -15368,7 +15283,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed,
        vp_door_2->height == VYSIZE)
       CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
     else
-      SetDoorState(DOOR_CLOSE_2);
+      SetDoorState(DOOR_CLOSE_ALL);
 
     BackToFront();