added optional button to restart game (door, panel and touch variants)
[rocksndiamonds.git] / src / editor.c
index 415b54dc9b52bfd68a309eacac0bdd49929963ff..671ac61de7551324c23e7c14ecf4d6dd8b83eb3d 100644 (file)
@@ -382,7 +382,7 @@ enum
   GADGET_ID_PICK_ELEMENT,
 
   GADGET_ID_UNDO,
-  GADGET_ID_INFO,
+  GADGET_ID_CONF,
   GADGET_ID_SAVE,
   GADGET_ID_CLEAR,
   GADGET_ID_TEST,
@@ -603,9 +603,9 @@ enum
 
   // textbutton identifiers
 
-  GADGET_ID_LEVELINFO_LEVEL,
-  GADGET_ID_LEVELINFO_LEVELSET,
-  GADGET_ID_LEVELINFO_EDITOR,
+  GADGET_ID_LEVELCONFIG_LEVEL,
+  GADGET_ID_LEVELCONFIG_LEVELSET,
+  GADGET_ID_LEVELCONFIG_EDITOR,
   GADGET_ID_PROPERTIES_INFO,
   GADGET_ID_PROPERTIES_CONFIG,
   GADGET_ID_PROPERTIES_CONFIG_1,
@@ -913,9 +913,9 @@ enum
 // values for textbutton gadgets
 enum
 {
-  ED_TEXTBUTTON_ID_LEVELINFO_LEVEL,
-  ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET,
-  ED_TEXTBUTTON_ID_LEVELINFO_EDITOR,
+  ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL,
+  ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET,
+  ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR,
   ED_TEXTBUTTON_ID_PROPERTIES_INFO,
   ED_TEXTBUTTON_ID_PROPERTIES_CONFIG,
   ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1,
@@ -930,8 +930,8 @@ enum
   ED_NUM_TEXTBUTTONS
 };
 
-#define ED_TAB_BUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
-#define ED_TAB_BUTTON_ID_LEVELINFO_LAST  ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
+#define ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL
+#define ED_TAB_BUTTON_ID_LEVELCONFIG_LAST  ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR
 
 #define ED_TAB_BUTTON_ID_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO
 #define ED_TAB_BUTTON_ID_PROPERTIES_LAST  ED_TEXTBUTTON_ID_PROPERTIES_CHANGE
@@ -1126,14 +1126,14 @@ enum
 
 // screens in the level editor
 #define ED_MODE_DRAWING                        0
-#define ED_MODE_INFO                   1
+#define ED_MODE_LEVELCONFIG            1
 #define ED_MODE_PROPERTIES             2
 #define ED_MODE_PALETTE                        3
 
 // sub-screens in the global settings section
-#define ED_MODE_LEVELINFO_LEVEL                ED_TEXTBUTTON_ID_LEVELINFO_LEVEL
-#define ED_MODE_LEVELINFO_LEVELSET     ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET
-#define ED_MODE_LEVELINFO_EDITOR       ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
+#define ED_MODE_LEVELCONFIG_LEVEL      ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL
+#define ED_MODE_LEVELCONFIG_LEVELSET   ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET
+#define ED_MODE_LEVELCONFIG_EDITOR     ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR
 
 // sub-screens in the element properties section
 #define ED_MODE_PROPERTIES_INFO                ED_TEXTBUTTON_ID_PROPERTIES_INFO
@@ -1274,9 +1274,9 @@ static struct
     "undo/redo last operation",                        'u'
   },
   {
-    IMG_GFX_EDITOR_BUTTON_CONF,                        GADGET_ID_INFO,
+    IMG_GFX_EDITOR_BUTTON_CONF,                        GADGET_ID_CONF,
     &editor.button.conf,                       GD_TYPE_NORMAL_BUTTON,
-    "properties of level",                     'I'
+    "level and editor settings",               'I'
   },
   {
     IMG_GFX_EDITOR_BUTTON_SAVE,                        GADGET_ID_SAVE,
@@ -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                            }
 };
@@ -2814,21 +2815,21 @@ static struct
 
   {
     ED_LEVEL_TABS_XPOS(0),             ED_LEVEL_TABS_YPOS(0),
-    GADGET_ID_LEVELINFO_LEVEL,         GADGET_ID_NONE,
+    GADGET_ID_LEVELCONFIG_LEVEL,       GADGET_ID_NONE,
     8,                                 "Level",
-    NULL, NULL, NULL,                  "Configure level properties"
+    NULL, NULL, NULL,                  "Configure level settings"
   },
   {
     -1,                                        -1,
-    GADGET_ID_LEVELINFO_LEVELSET,      GADGET_ID_LEVELINFO_LEVEL,
+    GADGET_ID_LEVELCONFIG_LEVELSET,    GADGET_ID_LEVELCONFIG_LEVEL,
     8,                                 "Levelset",
     NULL, NULL, NULL,                  "Update this or create new level set"
   },
   {
     -1,                                        -1,
-    GADGET_ID_LEVELINFO_EDITOR,                GADGET_ID_LEVELINFO_LEVELSET,
+    GADGET_ID_LEVELCONFIG_EDITOR,      GADGET_ID_LEVELCONFIG_LEVELSET,
     8,                                 "Editor",
-    NULL, NULL, NULL,                  "Configure editor properties"
+    NULL, NULL, NULL,                  "Configure editor settings"
   },
 
   // ---------- element settings (tabs) ---------------------------------------
@@ -3800,7 +3801,7 @@ static struct
     -1,                                        ED_AREA_1X1_SETTINGS_YPOS(1),
     0,                                 ED_AREA_1X1_SETTINGS_YOFF,
     GADGET_ID_CUSTOM_GRAPHIC,          GADGET_ID_CUSTOM_USE_GRAPHIC,
-    &custom_element.gfx_element_initial,1, 1,
+    &custom_element.gfx_element_initial, 1, 1,
     NULL, NULL, NULL, NULL,            "custom graphic element"
   },
 
@@ -3914,7 +3915,7 @@ static int level_xpos = -1, level_ypos = -1;
 static int ed_tilesize = DEFAULT_EDITOR_TILESIZE;
 static int ed_tilesize_default = DEFAULT_EDITOR_TILESIZE;
 
-#define IN_ED_FIELD(x,y)       IN_FIELD(x, y, ed_fieldx, ed_fieldy)
+#define IN_ED_FIELD(x, y)      IN_FIELD(x, y, ed_fieldx, ed_fieldy)
 
 // drawing elements on the three mouse buttons
 static int new_element1 = EL_WALL;
@@ -3948,7 +3949,7 @@ static void AdjustElementListScrollbar(void);
 static void RedrawDrawingElements(void);
 static void DrawDrawingWindowExt(boolean);
 static void DrawDrawingWindow(void);
-static void DrawLevelInfoWindow(void);
+static void DrawLevelConfigWindow(void);
 static void DrawPropertiesWindow(void);
 static void DrawPaletteWindow(void);
 static void UpdateCustomElementGraphicGadgets(void);
@@ -3993,7 +3994,7 @@ static int undo_buffer_steps = 0;
 static int redo_buffer_steps = 0;
 
 static int edit_mode;
-static int edit_mode_levelinfo;
+static int edit_mode_levelconfig;
 static int edit_mode_properties;
 
 static int element_shift = 0;
@@ -4697,8 +4698,8 @@ static int editor_el_deflektor[] =
 
   EL_DF_MIRROR_START,
   EL_DF_MIRROR_ROTATING_START,
+  EL_DF_MIRROR_FIXED_START,
   EL_DF_CELL,
-  EL_DF_MINE,
 
   EL_DF_FIBRE_OPTIC_RED_1,
   EL_DF_FIBRE_OPTIC_YELLOW_1,
@@ -4713,7 +4714,12 @@ static int editor_el_deflektor[] =
   EL_DF_STEEL_WALL,
   EL_DF_WOODEN_WALL,
   EL_DF_REFRACTOR,
-  EL_EMPTY
+  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;
@@ -5743,9 +5749,18 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements)
 
   // find all elements used in current level
   for (y = 0; y < lev_fieldy; y++)
+  {
     for (x = 0; x < lev_fieldx; x++)
-      if (Tile[x][y] < NUM_FILE_ELEMENTS)      // should always be true
+    {
+      if (Tile[x][y] >= NUM_FILE_ELEMENTS)     // should never happen
+       continue;
+
+      if (IS_MM_WALL(Tile[x][y]))
+       element_found[map_mm_wall_element(Tile[x][y])] = TRUE;
+      else
        element_found[Tile[x][y]] = TRUE;
+    }
+  }
 
   *num_elements = 0;
 
@@ -6951,7 +6966,7 @@ static void CreateTextbuttonGadgets(void)
   {
     int id = textbutton_info[i].gadget_id;
     int is_tab_button =
-      ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) ||
+      ((id >= GADGET_ID_LEVELCONFIG_LEVEL && id <= GADGET_ID_LEVELCONFIG_EDITOR) ||
        (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE));
     int graphic =
       (is_tab_button ? IMG_EDITOR_TABBUTTON : IMG_EDITOR_TEXTBUTTON);
@@ -7041,7 +7056,7 @@ static void CreateGraphicbuttonGadgets(void)
     int gd_y1 = gd->src_y;
     int gd_x2 = gd->src_x + gd->pressed_xoffset;
     int gd_y2 = gd->src_y + gd->pressed_yoffset;
-    unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+    unsigned int event_mask = GD_EVENT_RELEASED;
 
     // determine horizontal position to the right of specified gadget
     if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE)
@@ -7667,7 +7682,7 @@ static void MapCheckbuttonGadget(int id)
 
   // set position for gadgets with dynamically determined position
   if (checkbutton_info[id].x != -1)    // do not change dynamic positions
-    ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x),GDI_END);
+    ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x), GDI_END);
   ModifyGadget(gi, GDI_Y, SY + ED_SETTINGS_Y(checkbutton_info[id].y), GDI_END);
 
   x_left = gi->x - xoffset_left;
@@ -7750,6 +7765,14 @@ static void MapLevelEditorToolboxCustomGadgets(void)
   MapOrUnmapLevelEditorToolboxCustomGadgets(TRUE);
 }
 
+static void MapLevelEditorToolboxCustomGadgetsIfNeeded(void)
+{
+  if (IS_CUSTOM_ELEMENT(properties_element) ||
+      IS_GROUP_ELEMENT(properties_element) ||
+      IS_EMPTY_ELEMENT(properties_element))
+    MapLevelEditorToolboxCustomGadgets();
+}
+
 static void UnmapLevelEditorToolboxCustomGadgets(void)
 {
   MapOrUnmapLevelEditorToolboxCustomGadgets(FALSE);
@@ -7838,8 +7861,8 @@ static void DrawEditModeWindowExt(boolean remap_toolbox_gadgets)
     RedrawDrawingElements();
   }
 
-  if (edit_mode == ED_MODE_INFO)
-    DrawLevelInfoWindow();
+  if (edit_mode == ED_MODE_LEVELCONFIG)
+    DrawLevelConfigWindow();
   else if (edit_mode == ED_MODE_PROPERTIES)
     DrawPropertiesWindow();
   else if (edit_mode == ED_MODE_PALETTE)
@@ -7939,7 +7962,7 @@ static boolean PrepareSavingIntoPersonalLevelSet(void)
   return TRUE;
 }
 
-static void ModifyLevelInfoForSavingIntoPersonalLevelSet(char *former_name)
+static void ModifyLevelConfigForSavingIntoPersonalLevelSet(char *former_name)
 {
   static char *filename_levelinfo = NULL, *mod_name = NULL;
   FILE *file;
@@ -8172,6 +8195,12 @@ static boolean CopyCustomElement(int element_old, int element_new,
 
     return FALSE;
   }
+  else if (IS_EMPTY_ELEMENT(element_old) && !IS_EMPTY_ELEMENT(element_new))
+  {
+    Request("Please choose empty element!", REQ_CONFIRM);
+
+    return FALSE;
+  }
   else
   {
     level.changed = TRUE;
@@ -8782,6 +8811,15 @@ static void DrawEditorDoorContent(void)
   // draw all toolbox gadgets to editor doors
   MapControlButtons();
 
+  // when returning from test game to properties page, redraw toolbox gadgets
+  if (edit_mode == ED_MODE_PROPERTIES)
+  {
+    UnmapLevelEditorToolboxDrawingGadgets();
+    UnmapLevelEditorToolboxCustomGadgets();
+
+    MapLevelEditorToolboxCustomGadgetsIfNeeded();
+  }
+
   // draw all palette gadgets to editor doors
   ModifyEditorElementList();
   RedrawDrawingElements();
@@ -8824,7 +8862,7 @@ void DrawLevelEd(void)
   else
   {
     edit_mode = ED_MODE_DRAWING;
-    edit_mode_levelinfo = ED_MODE_LEVELINFO_LEVEL;
+    edit_mode_levelconfig = ED_MODE_LEVELCONFIG_LEVEL;
     edit_mode_properties = ED_MODE_PROPERTIES_INFO;
 
     ResetUndoBuffer();
@@ -8880,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
@@ -9207,7 +9245,7 @@ static int getTabulatorBarHeight(void)
 
 static Pixel getTabulatorBarColor(void)
 {
-  struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL];
+  struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL];
   struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED];
   int gd_x = gd->x + gd_gi1->border.width / 2;
   int gd_y = gd->y + gd_gi1->height - 1;
@@ -9215,19 +9253,19 @@ static Pixel getTabulatorBarColor(void)
   return GetPixel(gd->bitmap, gd_x, gd_y);
 }
 
-static void DrawLevelInfoTabulatorGadgets(void)
+static void DrawLevelConfigTabulatorGadgets(void)
 {
-  struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL];
+  struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL];
   Pixel tab_color = getTabulatorBarColor();
-  int id_first = ED_TAB_BUTTON_ID_LEVELINFO_FIRST;
-  int id_last  = ED_TAB_BUTTON_ID_LEVELINFO_LAST;
+  int id_first = ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST;
+  int id_last  = ED_TAB_BUTTON_ID_LEVELCONFIG_LAST;
   int i;
 
   for (i = id_first; i <= id_last; i++)
   {
     int gadget_id = textbutton_info[i].gadget_id;
     struct GadgetInfo *gi = level_editor_gadget[gadget_id];
-    boolean active = (i != edit_mode_levelinfo);
+    boolean active = (i != edit_mode_levelconfig);
 
     // draw background line below tabulator button
     ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1);
@@ -9316,7 +9354,7 @@ static int PrintElementDescriptionFromFile(char *filename, int font_nr,
                      TRUE, FALSE, FALSE);
 }
 
-static void DrawLevelInfoLevel(void)
+static void DrawLevelConfigLevel(void)
 {
   int i;
 
@@ -9345,7 +9383,7 @@ static char *getLevelSubdirFromSaveMode(int save_mode)
   return leveldir_current->subdir;
 }
 
-static void DrawLevelInfoLevelSet_DirectoryInfo(void)
+static void DrawLevelConfigLevelSet_DirectoryInfo(void)
 {
   char *directory_text = "Level set directory:";
   char *directory_name = getLevelSubdirFromSaveMode(levelset_save_mode);
@@ -9360,7 +9398,7 @@ static void DrawLevelInfoLevelSet_DirectoryInfo(void)
   PrintInfoText(directory_name, font2_nr, x, y);
 }
 
-static void DrawLevelInfoLevelSet(void)
+static void DrawLevelConfigLevelSet(void)
 {
   boolean artwork_exists = checkIfCustomArtworkExistsForCurrentLevelSet();
   boolean template_exists = fileExists(getLocalLevelTemplateFilename());
@@ -9393,10 +9431,10 @@ static void DrawLevelInfoLevelSet(void)
   MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_LEVELSET);
 
   // draw info text
-  DrawLevelInfoLevelSet_DirectoryInfo();
+  DrawLevelConfigLevelSet_DirectoryInfo();
 }
 
-static void DrawLevelInfoEditor(void)
+static void DrawLevelConfigEditor(void)
 {
   int i;
 
@@ -9419,7 +9457,7 @@ static void DrawLevelInfoEditor(void)
   MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2);
 }
 
-static void DrawLevelInfoWindow(void)
+static void DrawLevelConfigWindow(void)
 {
   char *text = "Global Settings";
   int font_nr = FONT_TITLE_1;
@@ -9438,14 +9476,14 @@ static void DrawLevelInfoWindow(void)
 
   DrawText(sx, sy, text, font_nr);
 
-  DrawLevelInfoTabulatorGadgets();
+  DrawLevelConfigTabulatorGadgets();
 
-  if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL)
-    DrawLevelInfoLevel();
-  else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVELSET)
-    DrawLevelInfoLevelSet();
-  else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR)
-    DrawLevelInfoEditor();
+  if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVEL)
+    DrawLevelConfigLevel();
+  else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVELSET)
+    DrawLevelConfigLevelSet();
+  else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_EDITOR)
+    DrawLevelConfigEditor();
 }
 
 static void DrawCustomContentArea(void)
@@ -9963,9 +10001,9 @@ static struct
   { EL_NUT,            &level.score[SC_NUT],           TEXT_CRACKING   },
   { EL_DYNAMITE,       &level.score[SC_DYNAMITE],      TEXT_COLLECTING },
   { EL_EM_DYNAMITE,    &level.score[SC_DYNAMITE],      TEXT_COLLECTING },
-  { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE],TEXT_COLLECTING },
-  { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE],TEXT_COLLECTING },
-  { EL_DYNABOMB_INCREASE_POWER,        &level.score[SC_DYNAMITE],TEXT_COLLECTING },
+  { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE], TEXT_COLLECTING },
+  { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
+  { EL_DYNABOMB_INCREASE_POWER,        &level.score[SC_DYNAMITE], TEXT_COLLECTING },
   { EL_SHIELD_NORMAL,  &level.score[SC_SHIELD],        TEXT_COLLECTING },
   { EL_SHIELD_DEADLY,  &level.score[SC_SHIELD],        TEXT_COLLECTING },
   { EL_EXTRA_TIME,     &level.extra_time_score,        TEXT_COLLECTING },
@@ -10667,9 +10705,7 @@ static void DrawPropertiesWindow(void)
   UnmapLevelEditorToolboxDrawingGadgets();
   UnmapLevelEditorToolboxCustomGadgets();
 
-  if (IS_CUSTOM_ELEMENT(properties_element) ||
-      IS_GROUP_ELEMENT(properties_element))
-    MapLevelEditorToolboxCustomGadgets();
+  MapLevelEditorToolboxCustomGadgetsIfNeeded();
 
   SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
   ClearField();
@@ -11672,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,
@@ -11888,6 +11930,24 @@ static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element,
        EL_DF_MIRROR_ROTATING_3,
        EL_DF_MIRROR_ROTATING_2
       },
+      {
+       EL_DF_MIRROR_FIXED_1,
+       EL_DF_MIRROR_FIXED_16,
+       EL_DF_MIRROR_FIXED_15,
+       EL_DF_MIRROR_FIXED_14,
+       EL_DF_MIRROR_FIXED_13,
+       EL_DF_MIRROR_FIXED_12,
+       EL_DF_MIRROR_FIXED_11,
+       EL_DF_MIRROR_FIXED_10,
+       EL_DF_MIRROR_FIXED_9,
+       EL_DF_MIRROR_FIXED_8,
+       EL_DF_MIRROR_FIXED_7,
+       EL_DF_MIRROR_FIXED_6,
+       EL_DF_MIRROR_FIXED_5,
+       EL_DF_MIRROR_FIXED_4,
+       EL_DF_MIRROR_FIXED_3,
+       EL_DF_MIRROR_FIXED_2
+      },
 
       {
        -1,
@@ -11995,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)
@@ -12240,7 +12291,7 @@ static void DrawCircle(int from_x, int from_y, int to_x, int to_y,
   DrawArcExt(from_x, from_y, to_x2, to_y2, element, change_level);
   DrawArcExt(from_x, from_y, mirror_to_x2, to_y2, element, change_level);
   DrawArcExt(from_x, from_y, to_x2, mirror_to_y2, element, change_level);
-  DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element,change_level);
+  DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element, change_level);
 }
 #endif
 
@@ -12297,6 +12348,9 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y,
 #define CB_BRUSH_TO_CLIPBOARD          7
 #define CB_BRUSH_TO_CLIPBOARD_SMALL    8
 #define CB_UPDATE_BRUSH_POSITION       9
+#define CB_FLIP_BRUSH_X                        10
+#define CB_FLIP_BRUSH_Y                        11
+#define CB_FLIP_BRUSH_XY               12
 
 #define MAX_CB_PART_SIZE       10
 #define MAX_CB_LINE_SIZE       (MAX_LEV_FIELDX + 1)    // text plus newline
@@ -12305,6 +12359,185 @@ 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 getFlippedTileExt(int map[], int element)
+{
+  int i;
+
+  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 getFlippedTileX(int element)
+{
+  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
+  };
+
+  return getFlippedTileExt(map, element);
+}
+
+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 getFlippedTileExt(map, element);
+}
+
+static int getFlippedTileXY(int element)
+{
+  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 getFlippedTileExt(map, element);
+}
+
+static int getFlippedTile(int element, int mode)
+{
+  if (IS_MM_ELEMENT(element))
+  {
+    // get MM game element
+    element = map_element_RND_to_MM(element);
+
+    // get flipped game element
+    element = (mode == CB_FLIP_BRUSH_X  ? getFlippedTileX_MM(element) :
+              mode == CB_FLIP_BRUSH_Y  ? getFlippedTileY_MM(element) :
+              mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY_MM(element) :
+              element);
+
+    // get RND game element again
+    element = map_element_MM_to_RND(element);
+  }
+  else
+  {
+    // get flipped game element
+    element = (mode == CB_FLIP_BRUSH_X  ? getFlippedTileX(element) :
+              mode == CB_FLIP_BRUSH_Y  ? getFlippedTileY(element) :
+              mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY(element) :
+              element);
+  }
+
+  return element;
+}
+
+static void SwapFlippedTiles(short *tile1, short *tile2, int mode)
+{
+  // flip tiles
+  short tile1_flipped = getFlippedTile(*tile1, mode);
+  short tile2_flipped = getFlippedTile(*tile2, mode);
+
+  // swap tiles
+  *tile1 = tile2_flipped;
+  *tile2 = tile1_flipped;
+}
+
 static void DrawBrushElement(int sx, int sy, int element, boolean change_level)
 {
   DrawLineElement(sx, sy, element, change_level);
@@ -12665,6 +12898,37 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
 
     delete_old_brush = TRUE;
   }
+  else if (mode == CB_FLIP_BRUSH_X)
+  {
+    for (y = 0; y < brush_height; y++)
+      for (x = 0; x < (brush_width + 1) / 2; x++)
+       SwapFlippedTiles(&brush_buffer[x][y],
+                        &brush_buffer[brush_width - x - 1][y], mode);
+
+    CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+  }
+  else if (mode == CB_FLIP_BRUSH_Y)
+  {
+    for (y = 0; y < (brush_height + 1) / 2; y++)
+      for (x = 0; x < brush_width; x++)
+       SwapFlippedTiles(&brush_buffer[x][y],
+                        &brush_buffer[x][brush_height - y - 1], mode);
+
+    CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+  }
+  else if (mode == CB_FLIP_BRUSH_XY)
+  {
+    CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR);
+
+    for (y = 0; y < MAX(brush_width, brush_height); y++)
+      for (x = 0; x <= y; x++)
+       SwapFlippedTiles(&brush_buffer[x][y],
+                        &brush_buffer[y][x], mode);
+
+    swap_numbers(&brush_width, &brush_height);
+
+    CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR);
+  }
 
   if (mode == CB_UPDATE_BRUSH_POSITION)
   {
@@ -12699,6 +12963,22 @@ static void DeleteBrushFromCursor(void)
   CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR);
 }
 
+static void FlipBrushX(void)
+{
+  CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X);
+}
+
+static void FlipBrushY(void)
+{
+  CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_Y);
+}
+
+static void RotateBrush(void)
+{
+  CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_XY);
+  CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X);
+}
+
 void DumpBrush(void)
 {
   CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH);
@@ -13027,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);
 
@@ -13040,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);
+      }
     }
   }
 }
@@ -13218,7 +13542,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
        {
          SetDrawModeHiRes(new_element);
 
-         if (IS_PLAYER_ELEMENT(new_element))
+         if (IS_PLAYER_ELEMENT(new_element) || IS_MM_MCDUFFIN(new_element))
          {
            // remove player at old position
            for (y = 0; y < lev_fieldy; y++)
@@ -13227,7 +13551,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
              {
                int old_element = Tile[x][y];
 
-               if (IS_PLAYER_ELEMENT(old_element))
+               if (IS_PLAYER_ELEMENT(old_element) &&
+                   IS_PLAYER_ELEMENT(new_element))
                {
                  int replaced_with_element =
                    (old_element == EL_SOKOBAN_FIELD_PLAYER &&
@@ -13247,6 +13572,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
 
                  SetElement(x, y, replaced_with_element);
                }
+               else if (IS_MM_MCDUFFIN(old_element) &&
+                        IS_MM_MCDUFFIN(new_element))
+               {
+                 // remove McDuffin at old position
+                 SetElement(x, y, EL_EMPTY);
+               }
              }
            }
          }
@@ -13581,7 +13912,7 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi)
 
   if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE)
   {
-    DrawLevelInfoWindow();
+    DrawLevelConfigWindow();
   }
   else if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE)
   {
@@ -13626,12 +13957,12 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
   int type_id = gi->custom_type_id;
   int i;
 
-  if (type_id >= ED_TAB_BUTTON_ID_LEVELINFO_FIRST &&
-      type_id <= ED_TAB_BUTTON_ID_LEVELINFO_LAST)
+  if (type_id >= ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST &&
+      type_id <= ED_TAB_BUTTON_ID_LEVELCONFIG_LAST)
   {
-    edit_mode_levelinfo = gi->custom_type_id;
+    edit_mode_levelconfig = gi->custom_type_id;
 
-    DrawLevelInfoWindow();
+    DrawLevelConfigWindow();
   }
   else if (type_id >= ED_TAB_BUTTON_ID_PROPERTIES_FIRST &&
           type_id <= ED_TAB_BUTTON_ID_PROPERTIES_LAST)
@@ -14287,12 +14618,12 @@ static void HandleControlButtons(struct GadgetInfo *gi)
 
       break;
 
-    case GADGET_ID_INFO:
-      if (edit_mode != ED_MODE_INFO)
+    case GADGET_ID_CONF:
+      if (edit_mode != ED_MODE_LEVELCONFIG)
       {
        last_edit_mode = edit_mode;
 
-       ChangeEditModeWindow(ED_MODE_INFO);
+       ChangeEditModeWindow(ED_MODE_LEVELCONFIG);
       }
       else
       {
@@ -14333,7 +14664,7 @@ static void HandleControlButtons(struct GadgetInfo *gi)
          Request("Save this level and kill the old?", REQ_ASK))
       {
        if (leveldir_former->readonly)
-         ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name);
+         ModifyLevelConfigForSavingIntoPersonalLevelSet(leveldir_former->name);
 
        SetAutomaticNumberOfGemsNeeded();
 
@@ -14589,8 +14920,8 @@ void HandleLevelEditorKeyInput(Key key)
     case KSYM_Escape:
       if (edit_mode == ED_MODE_DRAWING)
        RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
-      else if (edit_mode == ED_MODE_INFO)
-       HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]);
+      else if (edit_mode == ED_MODE_LEVELCONFIG)
+       HandleControlButtons(level_editor_gadget[GADGET_ID_CONF]);
       else if (edit_mode == ED_MODE_PROPERTIES)
        HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]);
       else if (edit_mode == ED_MODE_PALETTE)
@@ -14632,6 +14963,16 @@ void HandleLevelEditorKeyInput(Key key)
       if (letter && letter == controlbutton_info[i].shortcut)
        if (!anyTextGadgetActive())
          ClickOnGadget(level_editor_gadget[i], button);
+
+  if (draw_with_brush)
+  {
+    if (letter == 'x')
+      FlipBrushX();
+    else if (letter == 'y')
+      FlipBrushY();
+    else if (letter == 'z')
+      RotateBrush();
+  }
 }
 
 static void HandleLevelEditorIdle_Properties(void)
@@ -14665,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)
@@ -14800,7 +15145,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
       sy = ly - level_ypos;
     }
 
-    if (IN_ED_FIELD(sx,sy) && IN_LEV_FIELD(lx, ly))
+    if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly))
     {
       if (button_status)       // if (gi->state == GD_BUTTON_PRESSED)
       {
@@ -14938,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();