rnd-19990107-2
[rocksndiamonds.git] / src / editor.c
index a18b397617d2a493834a076fed51bd86ec7176ee..1265f4f72def1379441a5bd44af6991018146391 100644 (file)
@@ -18,6 +18,7 @@
 #include "buttons.h"
 #include "files.h"
 #include "game.h"
+#include "tape.h"
 
 /* positions in the level editor */
 #define ED_WIN_MB_LEFT_XPOS    7
 #define ED_NUM_CTRL2_BUTTONS   (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT)
 #define ED_NUM_CTRL_BUTTONS    (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
 
+/* values for properties window */
+#define ED_PROPERTIES_XPOS     (TILEX - MINI_TILEX/2)
 /* values for counter gadgets */
 #define ED_COUNT_VALUE_XOFFSET 5
 #define ED_COUNT_VALUE_YOFFSET 3
-#define ED_COUNT_SCORE_XPOS    (TILEX)
+#define ED_COUNT_SCORE_XPOS    ED_PROPERTIES_XPOS
 #define ED_COUNT_SCORE_YPOS    (14 * MINI_TILEY)
-#define ED_COUNT_ELEMCONT_XPOS (TILEX)
+#define ED_COUNT_ELEMCONT_XPOS ED_PROPERTIES_XPOS
 #define ED_COUNT_ELEMCONT_YPOS (17 * MINI_TILEY)
 
 /* values for element content drawing areas */
 #define ED_CTRL_ID_RANDOM_PLACEMENT    12
 #define ED_CTRL_ID_BRUSH               13
 #define ED_CTRL_ID_WRAP_DOWN           14
-#define ED_CTRL_ID_UNUSED2             15
+#define ED_CTRL_ID_PICK_ELEMENT                15
 #define ED_CTRL_ID_UNDO                        16
 #define ED_CTRL_ID_INFO                        17
 #define ED_CTRL_ID_SAVE                        18
 #define ED_CTRL_ID_ELEMCONT_7          34
 #define ED_CTRL_ID_AMOEBA_CONTENT      35
 
-#define ED_NUM_GADGETS                 36
+/* text input identifiers */
+#define ED_CTRL_ID_LEVEL_NAME          36
+
+#define ED_NUM_GADGETS                 37
 
 /* values for counter gadgets */
 #define ED_COUNTER_SCORE               0
@@ -143,14 +149,16 @@ static struct
 static void DrawDrawingWindow();
 static void DrawPropertiesWindow();
 static void CopyLevelToUndoBuffer();
-static void HandleDrawingAreas(struct GadgetInfo *);
-static void HandleCounterButtons(struct GadgetInfo *);
 static void HandleControlButtons(struct GadgetInfo *);
+static void HandleCounterButtons(struct GadgetInfo *);
+static void HandleDrawingAreas(struct GadgetInfo *);
+static void HandleTextInputGadgets(struct GadgetInfo *);
 
 static struct GadgetInfo *level_editor_gadget[ED_NUM_GADGETS];
 static boolean level_editor_gadgets_created = FALSE;
 
 static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS;
+static int last_drawing_function = ED_CTRL_ID_SINGLE_ITEMS;
 static int properties_element = 0;
 
 static short ElementContent[MAX_ELEMCONT][3][3];
@@ -178,7 +186,8 @@ static int new_element1 = EL_MAUERWERK;
 static int new_element2 = EL_LEERRAUM;
 static int new_element3 = EL_ERDREICH;
 
-int element_shift;
+int element_shift = 0;
+
 int editor_element[] =
 {
   EL_CHAR_A + ('B' - 'A'),
@@ -202,7 +211,7 @@ int editor_element[] =
   EL_BETON,
 
   EL_FELSBODEN,
-  EL_SIEB2_LEER,
+  EL_SIEB2_INAKTIV,
   EL_AUSGANG_ZU,
   EL_AUSGANG_AUF,
 
@@ -249,7 +258,7 @@ int editor_element[] =
   EL_BETON,
   EL_MAUERWERK,
   EL_FELSBODEN,
-  EL_SIEB_LEER,
+  EL_SIEB_INAKTIV,
 
   EL_EDELSTEIN,
   EL_DIAMANT,
@@ -361,6 +370,11 @@ int editor_element[] =
   EL_MAUER_Y,
   EL_MAUER_XY,
 
+  EL_SPEED_PILL,
+  EL_LEERRAUM,
+  EL_LEERRAUM,
+  EL_LEERRAUM,
+
   EL_CHAR_A + ('S' - 'A'),
   EL_CHAR_A + ('O' - 'A'),
   EL_CHAR_A + ('K' - 'A'),
@@ -376,6 +390,71 @@ int editor_element[] =
   EL_SOKOBAN_FELD_VOLL,
   EL_BETON,
 
+  EL_LEERRAUM,
+  EL_LEERRAUM,
+  EL_LEERRAUM,
+  EL_LEERRAUM,
+
+  EL_CHAR('S'),
+  EL_CHAR('U'),
+  EL_CHAR('P'),
+  EL_CHAR('A'),
+
+  EL_CHAR('P'),
+  EL_CHAR('L'),
+  EL_CHAR('E'),
+  EL_CHAR('X'),
+
+  EL_SP_EMPTY,
+  EL_SP_ZONK,
+  EL_SP_BASE,
+  EL_SP_MURPHY,
+
+  EL_SP_INFOTRON,
+  EL_SP_CHIP_SINGLE,
+  EL_SP_HARD_GRAY,
+  EL_SP_EXIT,
+
+  EL_SP_DISK_ORANGE,
+  EL_SP_PORT1_RIGHT,
+  EL_SP_PORT1_DOWN,
+  EL_SP_PORT1_LEFT,
+
+  EL_SP_PORT1_UP,
+  EL_SP_PORT2_RIGHT,
+  EL_SP_PORT2_DOWN,
+  EL_SP_PORT2_LEFT,
+
+  EL_SP_PORT2_UP,
+  EL_SP_SNIKSNAK,
+  EL_SP_DISK_YELLOW,
+  EL_SP_TERMINAL,
+
+  EL_SP_DISK_RED,
+  EL_SP_PORT_Y,
+  EL_SP_PORT_X,
+  EL_SP_PORT_XY,
+
+  EL_SP_ELECTRON,
+  EL_SP_BUG,
+  EL_SP_CHIP_LEFT,
+  EL_SP_CHIP_RIGHT,
+
+  EL_SP_HARD_BASE1,
+  EL_SP_HARD_GREEN,
+  EL_SP_HARD_BLUE,
+  EL_SP_HARD_RED,
+
+  EL_SP_HARD_YELLOW,
+  EL_SP_HARD_BASE2,
+  EL_SP_HARD_BASE3,
+  EL_SP_HARD_BASE4,
+
+  EL_SP_HARD_BASE5,
+  EL_SP_HARD_BASE6,
+  EL_SP_CHIP_UPPER,
+  EL_SP_CHIP_LOWER,
+
 /*
   EL_CHAR_A + ('D' - 'A'),
   EL_CHAR_A + ('Y' - 'A'),
@@ -470,7 +549,8 @@ int editor_element[] =
 
   EL_CHAR_OE,
   EL_CHAR_UE,
-  EL_CHAR_COPY
+  EL_CHAR_COPY,
+  EL_LEERRAUM
 };
 int elements_in_list = sizeof(editor_element)/sizeof(int);
 
@@ -533,7 +613,8 @@ static void CreateControlButtons()
        id == ED_CTRL_ID_RECTANGLE ||
        id == ED_CTRL_ID_FILLED_BOX ||
        id == ED_CTRL_ID_FLOOD_FILL ||
-       id == ED_CTRL_ID_BRUSH)
+       id == ED_CTRL_ID_BRUSH ||
+       id == ED_CTRL_ID_PICK_ELEMENT)
     {
       button_type = GD_TYPE_RADIO_BUTTON;
       radio_button_nr = 1;
@@ -720,6 +801,39 @@ static void CreateDrawingAreas()
   level_editor_gadget[id] = gi;
 }
 
+static void CreateTextInputGadgets()
+{
+  Pixmap gd_pixmap = pix[PIX_DOOR];
+  int gd_x, gd_y;
+  struct GadgetInfo *gi;
+  unsigned long event_mask;
+  int id;
+
+  gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
+  gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+  event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+
+  /* text input gadget for the level name */
+  id = ED_CTRL_ID_LEVEL_NAME;
+  gi = CreateGadget(GDI_CUSTOM_ID, id,
+                   GDI_X, SX + ED_COUNT_ELEMCONT_XPOS,
+                   GDI_Y, SY + ED_AREA_ELEMCONT_YPOS + 3 * TILEX,
+                   GDI_TYPE, GD_TYPE_TEXTINPUT,
+                   GDI_TEXT_VALUE, level.name,
+                   GDI_TEXT_SIZE, 30,
+                   GDI_TEXT_BORDER, 3,
+                   GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y,
+                   GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y,
+                   GDI_EVENT_MASK, event_mask,
+                   GDI_CALLBACK, HandleTextInputGadgets,
+                   GDI_END);
+
+  if (gi == NULL)
+    Error(ERR_EXIT, "cannot create gadget");
+
+  level_editor_gadget[id] = gi;
+}
+
 static void CreateLevelEditorGadgets()
 {
   if (level_editor_gadgets_created)
@@ -728,6 +842,7 @@ static void CreateLevelEditorGadgets()
   CreateControlButtons();
   CreateCounterButtons();
   CreateDrawingAreas();
+  CreateTextInputGadgets();
 
   level_editor_gadgets_created = TRUE;
 }
@@ -753,6 +868,11 @@ static void MapDrawingArea(int id)
   MapGadget(level_editor_gadget[id]);
 }
 
+static void MapTextInputGadget(int id)
+{
+  MapGadget(level_editor_gadget[id]);
+}
+
 static void MapMainDrawingArea()
 {
   MapDrawingArea(ED_CTRL_ID_DRAWING_LEVEL);
@@ -787,10 +907,11 @@ void DrawLevelEd()
   level_ypos=-1;
   edit_mode = ED_MODE_DRAWING;
   name_typing = FALSE;
-  element_shift = 0;
 
   CloseDoor(DOOR_CLOSE_ALL);
 
+  OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY);
+
   if (level_editor_test_game)
   {
     for(x=0; x<lev_fieldx; x++)
@@ -827,7 +948,7 @@ void DrawLevelEd()
   for(i=0;i<MAX_ELEM_X*MAX_ELEM_Y;i++)
   {
     if (i < elements_in_list)
-      graphic = el2gfx(editor_element[i]);
+      graphic = el2gfx(editor_element[i + element_shift]);
     else
       graphic = GFX_LEERRAUM;
 
@@ -1076,6 +1197,39 @@ void AdjustLevelScrollPosition()
     level_ypos = -1;
 }
 
+static void PickDrawingElement(int button, int element)
+{
+  if (button < 1 || button > 3)
+    return;
+
+  if (button == 1)
+  {
+    new_element1 = element;
+    DrawMiniGraphicExt(drawto, gc,
+                      DX + ED_WIN_MB_LEFT_XPOS,
+                      DY + ED_WIN_MB_LEFT_YPOS,
+                      el2gfx(new_element1));
+  }
+  else if (button == 2)
+  {
+    new_element2 = element;
+    DrawMiniGraphicExt(drawto, gc,
+                      DX + ED_WIN_MB_MIDDLE_XPOS,
+                      DY + ED_WIN_MB_MIDDLE_YPOS,
+                      el2gfx(new_element2));
+  }
+  else
+  {
+    new_element3 = element;
+    DrawMiniGraphicExt(drawto, gc,
+                      DX + ED_WIN_MB_RIGHT_XPOS,
+                      DY + ED_WIN_MB_RIGHT_YPOS,
+                      el2gfx(new_element3));
+  }
+
+  redraw_mask |= REDRAW_DOOR_1;
+}
+
 void LevelEd(int mx, int my, int button)
 {
   static int last_button = 0;
@@ -1176,33 +1330,14 @@ void LevelEd(int mx, int my, int button)
       else
        new_element = EL_LEERRAUM;
 
-      if (last_button==1)
-       new_element1 = new_element;
-      else if (last_button==2)
-       new_element2 = new_element;
-      else if (last_button==3)
-       new_element3 = new_element;
-
-      DrawMiniGraphicExt(drawto,gc,
-                        DX+ED_WIN_MB_LEFT_XPOS,
-                        DY+ED_WIN_MB_LEFT_YPOS,
-                        el2gfx(new_element1));
-      DrawMiniGraphicExt(drawto,gc,
-                        DX+ED_WIN_MB_MIDDLE_XPOS,
-                        DY+ED_WIN_MB_MIDDLE_YPOS,
-                        el2gfx(new_element2));
-      DrawMiniGraphicExt(drawto,gc,
-                        DX+ED_WIN_MB_RIGHT_XPOS,
-                        DY+ED_WIN_MB_RIGHT_YPOS,
-                        el2gfx(new_element3));
-      redraw_mask |= REDRAW_DOOR_1;
-
-      /*
-      properties_element = new_element;
-      if (edit_mode == ED_MODE_PROPERTIES)
-       DrawPropertiesWindow();
-      */
+      PickDrawingElement(last_button, new_element);
 
+      if (!HAS_CONTENT(properties_element))
+      {
+       properties_element = new_element;
+       if (edit_mode == ED_MODE_PROPERTIES)
+         DrawPropertiesWindow();
+      }
     }
   
     if (edit_mode == ED_MODE_DRAWING)  /********** EDIT-FENSTER **********/
@@ -1539,7 +1674,9 @@ void LevelEd(int mx, int my, int button)
 
            for(y=0;y<lev_fieldy;y++) 
              for(x=0;x<lev_fieldx;x++)
-               if (Feld[x][y]==EL_SPIELFIGUR || Feld[x][y]==EL_SPIELER1) 
+               if (Feld[x][y] == EL_SPIELFIGUR ||
+                   Feld[x][y] == EL_SPIELER1 ||
+                   Feld[x][y] == EL_SP_MURPHY) 
                  figur_vorhanden = TRUE;
 
            if (!figur_vorhanden)
@@ -1766,12 +1903,6 @@ static void DrawCounterValueField(int counter_id, int value)
           int2str(value, 3), FS_SMALL, FC_YELLOW);
 }
 
-#define TEXT_COLLECTING                "Score for collecting"
-#define TEXT_SMASHING          "Score for smashing"
-#define TEXT_CRACKING          "Score for cracking"
-#define TEXT_SPEED             "Speed of growth"
-#define TEXT_DURATION          "Duration when activated"
-
 static void DrawDrawingWindow()
 {
   ClearWindow();
@@ -1783,7 +1914,7 @@ static void DrawDrawingWindow()
 
 static void DrawElementContentAreas()
 {
-  static int num_areas = MAX_ELEMCONT;
+  int *num_areas = &MampferMax;
   int area_x = ED_AREA_ELEMCONT_XPOS / MINI_TILEX;
   int area_y = ED_AREA_ELEMCONT_YPOS / MINI_TILEY;
   int area_sx = SX + ED_AREA_ELEMCONT_XPOS;
@@ -1793,14 +1924,13 @@ static void DrawElementContentAreas()
   for (i=0; i<MAX_ELEMCONT; i++)
     for (y=0; y<3; y++)
       for (x=0; x<3; x++)
-       ElementContent[i][x][y] =
-         (i < 4 ? level.mampfer_inhalt[i][x][y] : EL_LEERRAUM);
+       ElementContent[i][x][y] = level.mampfer_inhalt[i][x][y];
 
   for (i=0; i<MAX_ELEMCONT; i++)
     UnmapDrawingArea(ED_CTRL_ID_ELEMCONT_0 + i);
 
   /* display counter to choose number of element content areas */
-  gadget_areas_value = &num_areas;
+  gadget_areas_value = num_areas;
   DrawCounterValueField(ED_COUNTER_ELEMCONT, *gadget_areas_value);
   x = counter_info[ED_COUNTER_ELEMCONT].x + DXSIZE;
   y = counter_info[ED_COUNTER_ELEMCONT].y;
@@ -1814,7 +1944,7 @@ static void DrawElementContentAreas()
                 SXSIZE, 12 * MINI_TILEY);
 
   /* draw some decorative border for the objects */
-  for (i=0; i<num_areas; i++)
+  for (i=0; i<*num_areas; i++)
   {
     for (y=0; y<4; y++)
       for (x=0; x<4; x++)
@@ -1832,7 +1962,14 @@ static void DrawElementContentAreas()
            area_sx, area_sy, (5 * 4 + 1) * MINI_TILEX, 12 * MINI_TILEY,
            area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
 
-  for (i=0; i<num_areas; i++)
+  DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 0 * MINI_TILEY + 1,
+          "Content", FS_SMALL, FC_YELLOW);
+  DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 1 * MINI_TILEY + 1,
+          "when", FS_SMALL, FC_YELLOW);
+  DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 2 * MINI_TILEY + 1,
+          "smashed", FS_SMALL, FC_YELLOW);
+
+  for (i=0; i<*num_areas; i++)
   {
     for (y=0; y<3; y++)
       for (x=0; x<3; x++)
@@ -1844,7 +1981,7 @@ static void DrawElementContentAreas()
              FC_YELLOW, "%d", i + 1);
   }
 
-  for (i=0; i<num_areas; i++)
+  for (i=0; i<*num_areas; i++)
     MapDrawingArea(ED_CTRL_ID_ELEMCONT_0 + i);
 }
 
@@ -1872,11 +2009,20 @@ static void DrawAmoebaContentArea()
            area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
            area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
 
+  DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba",
+          FS_SMALL, FC_YELLOW);
+
   DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
 
   MapDrawingArea(ED_CTRL_ID_AMOEBA_CONTENT);
 }
 
+#define TEXT_COLLECTING                "Score for collecting"
+#define TEXT_SMASHING          "Score for smashing"
+#define TEXT_CRACKING          "Score for cracking"
+#define TEXT_SPEED             "Speed of amoeba growth"
+#define TEXT_DURATION          "Duration when activated"
+
 static void DrawPropertiesWindow()
 {
   int i, x, y;
@@ -1927,7 +2073,7 @@ static void DrawPropertiesWindow()
     { EL_AMOEBE_NORM,  &level.tempo_amoebe,    TEXT_SPEED },
     { EL_AMOEBE_VOLL,  &level.tempo_amoebe,    TEXT_SPEED },
     { EL_AMOEBE_BD,    &level.tempo_amoebe,    TEXT_SPEED },
-    { EL_SIEB_LEER,    &level.dauer_sieb,      TEXT_DURATION },
+    { EL_SIEB_INAKTIV, &level.dauer_sieb,      TEXT_DURATION },
     { EL_ABLENK_AUS,   &level.dauer_ablenk,    TEXT_DURATION },
     { -1, NULL, NULL }
   };
@@ -1961,7 +2107,7 @@ static void DrawPropertiesWindow()
       if (Feld[x][y] == properties_element)
        num_elements_in_level++;
 
-  DrawTextF(TILEX, 5*TILEY, FC_YELLOW, "%d x contained in level",
+  DrawTextF(ED_PROPERTIES_XPOS, 5*TILEY, FC_YELLOW, "%d x contained in level",
            num_elements_in_level);
 
   /* check if there are elements where a score can be chosen for */
@@ -1981,10 +2127,16 @@ static void DrawPropertiesWindow()
     }
   }
 
-  if (properties_element == EL_MAMPFER)
-    DrawElementContentAreas();
-  else if (IS_AMOEBOID(properties_element))
-    DrawAmoebaContentArea();
+  if (HAS_CONTENT(properties_element))
+  {
+    if (IS_AMOEBOID(properties_element))
+      DrawAmoebaContentArea();
+    else
+      DrawElementContentAreas();
+  }
+
+  /* TEST ONLY: level name text input gadget */
+  MapTextInputGadget(ED_CTRL_ID_LEVEL_NAME);
 }
 
 static void swap_numbers(int *i1, int *i2)
@@ -2369,14 +2521,19 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
 {
   static boolean started_inside_drawing_area = FALSE;
   static boolean draw_with_brush = FALSE;
+  int id = gi->custom_id;
   boolean inside_drawing_area = !gi->event.off_borders;
   boolean button_press_event;
   boolean button_release_event;
-  boolean draw_level = (gi->custom_id == ED_CTRL_ID_DRAWING_LEVEL);
+  boolean draw_level = (id == ED_CTRL_ID_DRAWING_LEVEL);
   int new_element;
   int button = gi->event.button;
   int sx = gi->event.x, sy = gi->event.y;
+  int min_sx = 0, min_sy = 0;
+  int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1;
   int lx, ly;
+  int min_lx = 0, min_ly = 0;
+  int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
   int x, y;
 
   /*
@@ -2387,23 +2544,24 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
   button_press_event = (gi->event.type == GD_EVENT_PRESSED);
   button_release_event = (gi->event.type == GD_EVENT_RELEASED);
 
+  /* make sure to stay inside drawing area boundaries */
+  sx = (sx < min_sx ? min_sx : sx > max_sx ? max_sx : sx);
+  sy = (sy < min_sy ? min_sy : sy > max_sy ? max_sy : sy);
+
   if (draw_level)
   {
-    sx = (sx < 0 ? 0 : sx > 2*SCR_FIELDX - 1 ? 2*SCR_FIELDX - 1 : sx);
-    sy = (sy < 0 ? 0 : sy > 2*SCR_FIELDY - 1 ? 2*SCR_FIELDY - 1 : sy);
+    /* get positions inside level field */
     lx = sx + level_xpos;
     ly = sy + level_ypos;
 
-    lx = (lx < 0 ? 0 : lx > lev_fieldx - 1 ? lev_fieldx - 1 : lx);
-    ly = (ly < 0 ? 0 : ly > lev_fieldy - 1 ? lev_fieldy - 1 : ly);
+    /* make sure to stay inside level field boundaries */
+    lx = (lx < min_lx ? min_lx : lx > max_lx ? max_lx : lx);
+    ly = (ly < min_ly ? min_ly : ly > max_ly ? max_ly : ly);
+
+    /* correct drawing area positions accordingly */
     sx = lx - level_xpos;
     sy = ly - level_ypos;
   }
-  else
-  {
-    sx = (sx < 0 ? 0 : sx > 2 ? 2 : sx);
-    sy = (sy < 0 ? 0 : sy > 2 ? 2 : sy);
-  }
 
   if (button_press_event)
     started_inside_drawing_area = inside_drawing_area;
@@ -2467,6 +2625,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
                           gi->x + sx * MINI_TILEX,
                           gi->y + sy * MINI_TILEY,
                           el2gfx(new_element));
+
+       if (id == ED_CTRL_ID_AMOEBA_CONTENT)
+         level.amoebe_inhalt = new_element;
+       else if (id >= ED_CTRL_ID_ELEMCONT_0 && id <= ED_CTRL_ID_ELEMCONT_7)
+         level.mampfer_inhalt[id - ED_CTRL_ID_ELEMCONT_0][sx][sy] =
+           new_element;
       }
       break;
 
@@ -2550,6 +2714,13 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
       }
       break;
 
+    case ED_CTRL_ID_PICK_ELEMENT:
+      if (button_press_event)
+       PickDrawingElement(button, Feld[lx][ly]);
+      if (button_release_event)
+       ClickOnGadget(level_editor_gadget[last_drawing_function]);
+      break;
+
     default:
       break;
   }
@@ -2624,6 +2795,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
     case ED_CTRL_ID_FILLED_BOX:
     case ED_CTRL_ID_FLOOD_FILL:
     case ED_CTRL_ID_BRUSH:
+    case ED_CTRL_ID_PICK_ELEMENT:
+      last_drawing_function = drawing_function;
       drawing_function = id;
       break;
 
@@ -2726,8 +2899,7 @@ static void HandleControlButtons(struct GadgetInfo *gi)
       }
       else
       {
-       AdjustLevelScrollPosition();
-       DrawMiniLevel(level_xpos, level_ypos);
+       DrawDrawingWindow();
        edit_mode = ED_MODE_DRAWING;
       }
       break;
@@ -2753,7 +2925,7 @@ static void HandleControlButtons(struct GadgetInfo *gi)
          if (Feld[x][y] != Ur[x][y])
            level_changed = TRUE;
 
-      if (!level_changed)
+      if (0 && !level_changed)
       {
        Request("Level has not changed !", REQ_CONFIRM);
        break;
@@ -2761,7 +2933,9 @@ static void HandleControlButtons(struct GadgetInfo *gi)
 
       for(y=0; y<lev_fieldy; y++) 
        for(x=0; x<lev_fieldx; x++)
-         if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1) 
+         if (Feld[x][y] == EL_SPIELFIGUR ||
+             Feld[x][y] == EL_SPIELER1 ||
+             Feld[x][y] == EL_SP_MURPHY) 
            player_present = TRUE;
 
       if (!player_present)
@@ -2781,7 +2955,9 @@ static void HandleControlButtons(struct GadgetInfo *gi)
     case ED_CTRL_ID_TEST:
       for(y=0; y<lev_fieldy; y++) 
        for(x=0; x<lev_fieldx; x++)
-         if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1) 
+         if (Feld[x][y] == EL_SPIELFIGUR ||
+             Feld[x][y] == EL_SPIELER1 ||
+             Feld[x][y] == EL_SP_MURPHY) 
            player_present = TRUE;
 
       if (!player_present)
@@ -2796,8 +2972,25 @@ static void HandleControlButtons(struct GadgetInfo *gi)
          for(y=0; y<lev_fieldy; y++)
            Ur[x][y] = Feld[x][y];
 
+       UnmapLevelEditorGadgets();
+
+       /* draw smaller door */
+       XCopyArea(display, pix[PIX_DOOR], drawto, gc,
+                 DOOR_GFX_PAGEX7, 64,
+                 108, 64,
+                 EX - 4, EY - 12);
+       redraw_mask |= REDRAW_ALL;
+
+       CloseDoor(DOOR_CLOSE_ALL);
+
+       DrawCompleteVideoDisplay();
+
+       if (setup.autorecord)
+         TapeStartRecording();
+
        level_editor_test_game = TRUE;
        game_status = PLAYING;
+
        InitGame();
       }
       break;
@@ -2855,19 +3048,7 @@ void HandleLevelEditorKeyInput(KeySym key)
 {
   if (edit_mode == ED_MODE_DRAWING && drawing_function == ED_CTRL_ID_TEXT)
   {
-    char *keyname = getKeyNameFromKeySym(key);
-    char letter = 0;
-
-    if (strlen(keyname) == 1)
-      letter = keyname[0];
-    else if (strcmp(keyname, "space") == 0)
-      letter = ' ';
-    else if (strcmp(keyname, "less") == 0)
-      letter = '<';
-    else if (strcmp(keyname, "equal") == 0)
-      letter = '=';
-    else if (strcmp(keyname, "greater") == 0)
-      letter = '>';
+    char letter = getCharFromKeySym(key);
 
     /* map lower case letters to upper case */
     if (letter >= 'a' && letter <= 'z')
@@ -2887,3 +3068,19 @@ void HandleLevelEditorKeyInput(KeySym key)
       DrawLevelText(0, 0, 0, TEXT_NEWLINE);
   }
 }
+
+
+static void HandleTextInputGadgets(struct GadgetInfo *gi)
+{
+  int id = gi->custom_id;
+
+  switch (id)
+  {
+    case ED_CTRL_ID_LEVEL_NAME:
+      strcpy(level.name, gi->text_value);
+      break;
+
+    default:
+      break;
+  }
+}