rnd-19981214-2
authorHolger Schemel <info@artsoft.org>
Mon, 14 Dec 1998 20:32:38 +0000 (21:32 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:32:19 +0000 (10:32 +0200)
src/buttons.c
src/buttons.h
src/editor.c
src/editor.h
src/events.c
src/main.h
src/screens.c
src/tools.c

index d990bc131ee03ef263c29edff8fd73643c4ca810..8148e4489c555c926ddfe74ffbdf14ca4bcc262d 100644 (file)
@@ -840,7 +840,7 @@ void DrawElemButton(int button_nr, int button_state)
     DrawMiniGraphicExt(drawto,gc,
                       DX+ED_BUTTON_ELEM_XPOS+3+shift + 
                       (elem_pos % MAX_ELEM_X)*ED_BUTTON_ELEM_XSIZE,
-                      DY+ED_BUTTON_ELEM_YPOS+3-shift +
+                      DY+ED_BUTTON_ELEM_YPOS+3+shift +
                       (elem_pos / MAX_ELEM_X)*ED_BUTTON_ELEM_YSIZE,
                       graphic);
   }
@@ -1470,6 +1470,41 @@ int CheckCountButtons(int mx, int my, int button)
 
 static struct GadgetInfo *gadget_list_first_entry = NULL;
 static struct GadgetInfo *gadget_list_last_entry = NULL;
+static int next_free_gadget_id = 1;
+static boolean gadget_id_wrapped = FALSE;
+
+static struct GadgetInfo *getGadgetInfoFromGadgetID(int id)
+{
+  struct GadgetInfo *gi = gadget_list_first_entry;
+
+  while (gi && gi->id != id)
+    gi = gi->next;
+
+  return gi;
+}
+
+static int getNewGadgetID()
+{
+  int id = next_free_gadget_id++;
+
+  if (next_free_gadget_id <= 0)                /* counter overrun */
+  {
+    gadget_id_wrapped = TRUE;          /* now we must check each ID */
+    next_free_gadget_id = 0;
+  }
+
+  if (gadget_id_wrapped)
+  {
+    next_free_gadget_id++;
+    while (getGadgetInfoFromGadgetID(next_free_gadget_id) != NULL)
+      next_free_gadget_id++;
+  }
+
+  if (next_free_gadget_id <= 0)                /* cannot get new gadget id */
+    Error(ERR_EXIT, "too much gadgets -- this should not happen");
+
+  return id;
+}
 
 static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
 {
@@ -1477,7 +1512,8 @@ static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
 
   while (gi)
   {
-    if (mx >= gi->x && mx < gi->x + gi->width &&
+    if (gi->mapped &&
+       mx >= gi->x && mx < gi->x + gi->width &&
        my >= gi->y && my < gi->y + gi->height)
       break;
 
@@ -1498,13 +1534,24 @@ struct GadgetInfo *CreateGadget(int first_tag, ...)
   /* always start with reliable default values */
   memset(new_gadget, 0, sizeof(struct GadgetInfo));
 
+  new_gadget->id = getNewGadgetID();
+
   while (tag != GDI_END)
   {
+
+
+
+#if 0
     printf("tag: %d\n", tag);
+#endif
+
 
 
     switch(tag)
     {
+      case GDI_ID:
+       new_gadget->id = va_arg(ap, int);
+       break;
       case GDI_X:
        new_gadget->x = va_arg(ap, int);
        break;
@@ -1552,6 +1599,9 @@ struct GadgetInfo *CreateGadget(int first_tag, ...)
        new_gadget->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
        new_gadget->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
        break;
+      case GDI_EVENT_MASK:
+       new_gadget->event_mask = va_arg(ap, unsigned long);
+       break;
       case GDI_CALLBACK:
        new_gadget->callback = va_arg(ap, gadget_callback_function);
        break;
@@ -1609,19 +1659,17 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
                             &gi->alt_design[state] :
                             &gi->design[state]);
 
-  XCopyArea(display, gd->pixmap, drawto, gc,
+  XCopyArea(display, gd->pixmap, (direct ? window : drawto), gc,
            gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
-
-  if (direct)
-    XCopyArea(display, gd->pixmap, window, gc,
-             gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
 }
 
 void MapGadget(struct GadgetInfo *gi)
 {
   gi->mapped = TRUE;
 
-  DrawGadget(gi, (gi->state == GD_BUTTON_PRESSED), TRUE);
+  DrawGadget(gi, (gi->state == GD_BUTTON_PRESSED), FALSE);
+
+  redraw_mask |= REDRAW_ALL;
 }
 
 void UnmapGadget(struct GadgetInfo *gi)
@@ -1631,47 +1679,52 @@ void UnmapGadget(struct GadgetInfo *gi)
 
 void HandleGadgets(int mx, int my, int button)
 {
-  static struct GadgetInfo *choice = NULL;
+  static struct GadgetInfo *gi = NULL;
   static boolean pressed = FALSE;
-  struct GadgetInfo *new_choice;
+  struct GadgetInfo *new_gi;
 
   if (gadget_list_first_entry == NULL)
     return;
 
-  new_choice = getGadgetInfoFromMousePosition(mx,my);
+  new_gi = getGadgetInfoFromMousePosition(mx,my);
 
   if (button)
   {
     if (!motion_status)                /* mouse button just pressed */
     {
-      if (new_choice != NULL)
+      if (new_gi != NULL)
       {
-       choice = new_choice;
-       choice->state = GD_BUTTON_PRESSED;
-       choice->event = GD_EVENT_PRESSED;
-       DrawGadget(choice, TRUE, TRUE);
-       choice->callback(choice);
+       gi = new_gi;
+       gi->state = GD_BUTTON_PRESSED;
+       gi->event.type = GD_EVENT_PRESSED;
+       gi->event.button = button;
+       DrawGadget(gi, TRUE, TRUE);
+
+       if (gi->event_mask & GD_EVENT_PRESSED)
+         gi->callback(gi);
+
        pressed = TRUE;
       }
     }
     else                       /* mouse movement with pressed mouse button */
     {
-      if ((new_choice == NULL || new_choice != choice) &&
-         choice != NULL && pressed)
+      if ((new_gi == NULL || new_gi != gi) &&
+         gi != NULL && pressed)
       {
-       choice->state = GD_BUTTON_UNPRESSED;
-       DrawGadget(choice, FALSE, TRUE);
+       gi->state = GD_BUTTON_UNPRESSED;
+       DrawGadget(gi, FALSE, TRUE);
        pressed = FALSE;
       }
-      else if (new_choice != NULL && new_choice == choice)
+      else if (new_gi != NULL && new_gi == gi)
       {
        if (!pressed)
-         DrawGadget(choice, TRUE, TRUE);
-       choice->state = GD_BUTTON_PRESSED;
+         DrawGadget(gi, TRUE, TRUE);
+       gi->state = GD_BUTTON_PRESSED;
+       gi->event.type = GD_EVENT_MOVING;
+       gi->event.button = button;
 
-       /*
-       choice->callback(choice);
-       */
+       if (gi->event_mask & GD_EVENT_MOVING)
+         gi->callback(gi);
 
        pressed = TRUE;
       }
@@ -1679,18 +1732,22 @@ void HandleGadgets(int mx, int my, int button)
   }
   else                         /* mouse button just released */
   {
-    if (new_choice != NULL && new_choice == choice && pressed)
+    if (new_gi != NULL && new_gi == gi && pressed)
     {
-      choice->state = GD_BUTTON_UNPRESSED;
-      choice->event = GD_EVENT_RELEASED;
-      DrawGadget(choice, FALSE, TRUE);
-      choice->callback(choice);
-      choice = NULL;
+      gi->state = GD_BUTTON_UNPRESSED;
+      gi->event.type = GD_EVENT_RELEASED;
+      gi->event.button = button;
+      DrawGadget(gi, FALSE, TRUE);
+
+      if (gi->event_mask & GD_EVENT_RELEASED)
+       gi->callback(gi);
+
+      gi = NULL;
       pressed = FALSE;
     }
     else
     {
-      choice = NULL;
+      gi = NULL;
       pressed = FALSE;
     }
   }
index d52b4a628b529c3cf3ba193cdb9a3a8418bee7ee..695aef6bf1219cbe0b7adfbb82bb28f92ca25d85 100644 (file)
@@ -293,21 +293,23 @@ int CheckCountButtons(int, int, int);
 
 /* gadget creation tags */
 #define GDI_END                                0
-#define GDI_X                          1
-#define GDI_Y                          2
-#define GDI_WIDTH                      3
-#define GDI_HEIGHT                     4
-#define GDI_TYPE                       5
-#define GDI_STATE                      6
-#define GDI_ALT_STATE                  7
-#define GDI_NUMBER_VALUE               8
-#define GDI_TEXT_VALUE                 9
-#define GDI_DESIGN_UNPRESSED           10
-#define GDI_DESIGN_PRESSED             11
-#define GDI_ALT_DESIGN_UNPRESSED       12
-#define GDI_ALT_DESIGN_PRESSED         13
-#define GDI_EVENT                      14
-#define GDI_CALLBACK                   15
+#define GDI_ID                         1
+#define GDI_X                          2
+#define GDI_Y                          3
+#define GDI_WIDTH                      4
+#define GDI_HEIGHT                     5
+#define GDI_TYPE                       6
+#define GDI_STATE                      7
+#define GDI_ALT_STATE                  8
+#define GDI_NUMBER_VALUE               9
+#define GDI_TEXT_VALUE                 10
+#define GDI_DESIGN_UNPRESSED           11
+#define GDI_DESIGN_PRESSED             12
+#define GDI_ALT_DESIGN_UNPRESSED       13
+#define GDI_ALT_DESIGN_PRESSED         14
+#define GDI_EVENT_MASK                 15
+#define GDI_EVENT                      16
+#define GDI_CALLBACK                   17
 
 typedef void (*gadget_callback_function)(void *);
 
@@ -317,8 +319,15 @@ struct GadgetDesign
   int x, y;                            /* position of rectangle in Pixmap */
 };
 
+struct GadgetEvent
+{
+  unsigned long type;                  /* event type */
+  int button;                          /* button number for button events */
+};
+
 struct GadgetInfo
 {
+  int id;                              /* gadget identifier */
   int x, y;                            /* gadget position */
   int width, height;                   /* gadget size */
   unsigned long type;                  /* type (button, text input, ...) */
@@ -329,30 +338,12 @@ struct GadgetInfo
   char text_value[MAX_GADGET_TEXTSIZE];
   struct GadgetDesign design[2];       /* 0: normal; 1: pressed */
   struct GadgetDesign alt_design[2];   /* alternative design */
-  unsigned long event;                 /* actual gadget event */
+  unsigned long event_mask;            /* possible events for this gadget */
+  struct GadgetEvent event;            /* actual gadget event */
   gadget_callback_function callback;
   struct GadgetInfo *next;             /* next list entry */
 };
 
-
-#if 0
-struct NewGadget
-{
-  int x, y;                            /* screen position */
-  int width, height;                   /* screen size */
-  unsigned long type;                  /* type (button, text input, ...) */
-  struct GadgetDesign *design[2];      /* 0: normal; 1: pressed */
-  struct GadgetDesign *alt_design[2];  /* alternative design */
-  unsigned long value_mask;            /* actual gadget event */
-};
-#endif
-
-struct GadgetEvent
-{
-  unsigned long state;                 /* state (pressed, released, ...) */
-  int x,y;                             /* position inside drawing area */
-};
-
 struct GadgetInfo *CreateGadget(int, ...);
 void FreeGadget(struct GadgetInfo *);
 
index 1b40735e534c999ce503e86cabd0cee885e04257..96718762f880db4f65f92143322db6eb5318033b 100644 (file)
 /* delay value to avoid too fast scrolling etc. */
 #define CHOICE_DELAY_VALUE     100
 
+/* values for the control window */
+#define ED_CTRL_BUTTONS_GFX_YPOS 236
+#define ED_CTRL1_BUTTONS_HORIZ 4
+#define ED_CTRL1_BUTTONS_VERT  4
+#define ED_CTRL1_BUTTON_XSIZE  22
+#define ED_CTRL1_BUTTON_YSIZE  22
+#define ED_CTRL1_BUTTONS_XPOS  6
+#define ED_CTRL1_BUTTONS_YPOS  6
+#define ED_CTRL2_BUTTONS_HORIZ 3
+#define ED_CTRL2_BUTTONS_VERT  2
+#define ED_CTRL2_BUTTON_XSIZE  30
+#define ED_CTRL2_BUTTON_YSIZE  20
+#define ED_CTRL2_BUTTONS_XPOS  5
+#define ED_CTRL2_BUTTONS_YPOS  100
+#define ED_NUM_CTRL1_BUTTONS   (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT)
+#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)
+
+/* control button names */
+#define ED_CTRL_ID_SINGLE_ITEMS                0
+#define ED_CTRL_ID_CONNECTED_ITEMS     1
+#define ED_CTRL_ID_LINES               2
+#define ED_CTRL_ID_TEXT                        3
+#define ED_CTRL_ID_RECTANGLE           4
+#define ED_CTRL_ID_BOX                 5
+#define ED_CTRL_ID_WRAP_UP             6
+#define ED_CTRL_ID_ITEM_PROPERTIES     7
+#define ED_CTRL_ID_FLOOD_FILL          8
+#define ED_CTRL_ID_WRAP_LEFT           9
+#define ED_CTRL_ID_WRAP_RIGHT          11
+#define ED_CTRL_ID_RANDOM_PLACEMENT    12
+#define ED_CTRL_ID_BRUSH               13
+#define ED_CTRL_ID_WRAP_DOWN           14
+#define ED_CTRL_ID_UNDO                        16
+#define ED_CTRL_ID_INFO                        17
+#define ED_CTRL_ID_SAVE                        18
+#define ED_CTRL_ID_CLEAR               19
+#define ED_CTRL_ID_TEST                        20
+#define ED_CTRL_ID_EXIT                        21
+
+/* forward declaration for internal use */
+void HandleDrawingFunction(int, int, int);
+
+static struct GadgetInfo *control_button_gadget[ED_NUM_CTRL_BUTTONS];
+static boolean control_button_gadgets_created = FALSE;
+
+static int drawing_function = ED_CTRL_ID_SINGLE_ITEMS;
+
 static int level_xpos,level_ypos;
 static boolean edit_mode;
 static boolean name_typing;
@@ -341,6 +389,336 @@ int editor_element[] =
 };
 int elements_in_list = sizeof(editor_element)/sizeof(int);
 
+void ScrollMiniLevel(int from_x, int from_y, int scroll)
+{
+  int x,y;
+  int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
+  int dy = (scroll==ED_SCROLL_UP   ? -1 : scroll==ED_SCROLL_DOWN  ? 1 : 0);
+
+  XCopyArea(display,drawto,drawto,gc,
+           SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
+           SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
+           SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
+  if (dx)
+  {
+    x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
+    for(y=0;y<2*SCR_FIELDY;y++)
+      DrawMiniElementOrWall(x,y,from_x,from_y);
+  }
+  else if (dy)
+  {
+    y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
+    for(x=0;x<2*SCR_FIELDX;x++)
+      DrawMiniElementOrWall(x,y,from_x,from_y);
+  }
+
+  redraw_mask |= REDRAW_FIELD;
+  BackToFront();
+}
+
+void HandlePressedControlButtons()
+{
+  static unsigned long button_delay = 0;
+  int i = 0;
+
+  /* buttons with action when held pressed */
+  int gadget_id[] =
+  {
+    ED_CTRL_ID_WRAP_UP,
+    ED_CTRL_ID_WRAP_LEFT,
+    ED_CTRL_ID_WRAP_RIGHT,
+    ED_CTRL_ID_WRAP_DOWN,
+    -1
+  };
+
+  if (!DelayReached(&button_delay, CHOICE_DELAY_VALUE))
+    return;
+
+  while (gadget_id[i] != -1)
+  {
+    int id = gadget_id[i++];
+    int state = control_button_gadget[id]->state;
+    int button = control_button_gadget[id]->event.button;
+    int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
+
+    if (state != GD_BUTTON_PRESSED)
+      continue;
+  
+    switch (id)
+    {
+      case ED_CTRL_ID_WRAP_LEFT:
+       if (level_xpos >= 0)
+       {
+         if (lev_fieldx < 2*SCR_FIELDX - 2)
+           break;
+  
+         level_xpos -= step;
+         if (level_xpos <- 1)
+           level_xpos = -1;
+         if (button == 1)
+           ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
+         else
+           DrawMiniLevel(level_xpos, level_ypos);
+       }
+       break;
+  
+      case ED_CTRL_ID_WRAP_RIGHT:
+       if (level_xpos <= lev_fieldx - 2*SCR_FIELDX)
+       {
+         if (lev_fieldx < 2*SCR_FIELDX - 2)
+           break;
+  
+         level_xpos += step;
+         if (level_xpos > lev_fieldx - 2*SCR_FIELDX + 1)
+           level_xpos = lev_fieldx - 2*SCR_FIELDX + 1;
+         if (button == 1)
+           ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
+         else
+           DrawMiniLevel(level_xpos, level_ypos);
+       }
+       break;
+  
+      case ED_CTRL_ID_WRAP_UP:
+       if (level_ypos >= 0)
+       {
+         if (lev_fieldy < 2*SCR_FIELDY - 2)
+           break;
+  
+         level_ypos -= step;
+         if (level_ypos < -1)
+           level_ypos = -1;
+         if (button == 1)
+           ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
+         else
+           DrawMiniLevel(level_xpos, level_ypos);
+       }
+       break;
+  
+      case ED_CTRL_ID_WRAP_DOWN:
+       if (level_ypos <= lev_fieldy - 2*SCR_FIELDY)
+       {
+         if (lev_fieldy < 2*SCR_FIELDY - 2)
+           break;
+  
+         level_ypos += step;
+         if (level_ypos > lev_fieldy - 2*SCR_FIELDY + 1)
+           level_ypos = lev_fieldy - 2*SCR_FIELDY + 1;
+         if (button == 1)
+           ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP);
+         else
+           DrawMiniLevel(level_xpos, level_ypos);
+       }
+       break;
+  
+      default:
+       break;
+    }
+  }
+}
+
+void HandleLevelEditorControlButtons(struct GadgetInfo *gi)
+{
+  int event_type = gi->event.type;
+
+  /*
+  int button = gi->event.button;
+  */
+
+  int id;
+  int i, x, y;
+
+  /* get the button id */
+  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+    if (gi->id == control_button_gadget[i]->id)
+      id = i;
+
+  switch (id)
+  {
+    case ED_CTRL_ID_SINGLE_ITEMS:
+    case ED_CTRL_ID_CONNECTED_ITEMS:
+    case ED_CTRL_ID_LINES:
+    case ED_CTRL_ID_TEXT:
+    case ED_CTRL_ID_RECTANGLE:
+    case ED_CTRL_ID_BOX:
+    case ED_CTRL_ID_FLOOD_FILL:
+    case ED_CTRL_ID_RANDOM_PLACEMENT:
+    case ED_CTRL_ID_BRUSH:
+      drawing_function = id;
+      break;
+
+    case ED_CTRL_ID_CLEAR:
+      if (Request("Are you sure to clear this level ?", REQ_ASK))
+      {
+       for(x=0; x<MAX_LEV_FIELDX; x++) 
+         for(y=0; y<MAX_LEV_FIELDY; y++) 
+           Feld[x][y] = EL_ERDREICH;
+
+       DrawMiniLevel(level_xpos, level_ypos);
+      }
+      break;
+
+    case ED_CTRL_ID_SAVE:
+      {
+       int player_present = FALSE;
+
+       if (leveldir[leveldir_nr].readonly)
+       {
+         Request("This level is read only !", REQ_CONFIRM);
+         break;
+       }
+
+       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) 
+             player_present = TRUE;
+
+       if (!player_present)
+         Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
+       else
+       {
+         if (Request("Save this level and kill the old ?", REQ_ASK))
+         {
+           for(x=0; x<lev_fieldx; x++)
+             for(y=0; y<lev_fieldy; y++) 
+               Ur[x][y] = Feld[x][y];
+           SaveLevel(level_nr);
+         }
+       }
+      }
+      break;
+
+    case ED_CTRL_ID_EXIT:
+      if (Request("Exit level editor ?", REQ_ASK | REQ_STAY_OPEN))
+      {
+       CloseDoor(DOOR_CLOSE_1);
+
+       /*
+       CloseDoor(DOOR_CLOSE_BOTH);
+       */
+
+       /* draw smaller door */
+       XCopyArea(display, pix[PIX_DOOR], drawto, gc,
+                 DOOR_GFX_PAGEX7, 64,
+                 108, 64,
+                 EX - 4, EY - 12);
+       redraw_mask |= REDRAW_ALL;
+
+       game_status = MAINMENU;
+       DrawMainMenu();
+      }
+      else
+      {
+       CloseDoor(DOOR_CLOSE_1);
+       XCopyArea(display, pix[PIX_DB_DOOR], pix[PIX_DB_DOOR], gc,
+                 DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
+                 DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+       OpenDoor(DOOR_OPEN_1);
+      }
+      break;
+
+    default:
+      if (event_type == GD_EVENT_PRESSED)
+       printf("test_func2: GD_EVENT_PRESSED\n");
+      else if (event_type == GD_EVENT_RELEASED)
+       printf("test_func2: GD_EVENT_RELEASED\n");
+      else
+       printf("test_func2: ?\n");
+      break;
+  }
+}
+
+void CreateLevelEditorControlButtons()
+{
+  int i;
+
+  if (control_button_gadgets_created)
+    return;
+
+  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+  {
+    Pixmap gd_pixmap = pix[PIX_DOOR];
+    struct GadgetInfo *gi;
+    int gd_xoffset, gd_yoffset;
+    int gd_x1, gd_x2, gd_y;
+    int width, height;
+    unsigned long event_mask;
+
+    if (i < ED_NUM_CTRL1_BUTTONS)
+    {
+      int x = i % ED_CTRL1_BUTTONS_HORIZ;
+      int y = i / ED_CTRL1_BUTTONS_HORIZ;
+
+      gd_xoffset = ED_CTRL1_BUTTONS_XPOS + x * ED_CTRL1_BUTTON_XSIZE;
+      gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE;
+      width = ED_CTRL1_BUTTON_XSIZE;
+      height = ED_CTRL1_BUTTON_YSIZE;
+    }
+    else
+    {
+      int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ;
+      int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ;
+
+      gd_xoffset = ED_CTRL2_BUTTONS_XPOS + x * ED_CTRL2_BUTTON_XSIZE;
+      gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE;
+      width = ED_CTRL2_BUTTON_XSIZE;
+      height = ED_CTRL2_BUTTON_YSIZE;
+    }
+
+    gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
+    gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
+    gd_y  = DOOR_GFX_PAGEY1 + ED_CTRL_BUTTONS_GFX_YPOS + gd_yoffset;
+
+    if (i == ED_CTRL_ID_WRAP_LEFT ||
+       i == ED_CTRL_ID_WRAP_RIGHT ||
+       i == ED_CTRL_ID_WRAP_UP ||
+       i == ED_CTRL_ID_WRAP_DOWN)
+      event_mask = GD_EVENT_PRESSED;
+    else
+      event_mask = GD_EVENT_RELEASED;
+
+    gi = CreateGadget(GDI_X, EX + gd_xoffset,
+                     GDI_Y, EY + gd_yoffset,
+                     GDI_WIDTH, width,
+                     GDI_HEIGHT, height,
+                     GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+                     GDI_STATE, GD_BUTTON_UNPRESSED,
+                     GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
+                     GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
+                     GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK, HandleLevelEditorControlButtons,
+                     GDI_END);
+
+    if (gi == NULL)
+      Error(ERR_EXIT, "cannot create gadget");
+
+    control_button_gadget[i] = gi;
+  }
+
+  control_button_gadgets_created = TRUE;
+}
+
+void MapLevelEditorControlButtons()
+{
+  int i;
+
+  if (!control_button_gadgets_created)
+    CreateLevelEditorControlButtons();
+
+  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+    MapGadget(control_button_gadget[i]);
+}
+
+void UnmapLevelEditorControlButtons()
+{
+  int i;
+
+  if (!control_button_gadgets_created)
+    return;
+
+  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+    UnmapGadget(control_button_gadget[i]);
+}
+
 void DrawLevelEd()
 {
   int i, graphic;
@@ -416,24 +794,28 @@ void DrawLevelEd()
            VXSIZE,VYSIZE,
            DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
 
-  OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
-}
-
-
+  /* draw bigger door */
+  XCopyArea(display, pix[PIX_DOOR], drawto, gc,
+           DOOR_GFX_PAGEX7, 0,
+           108, 64,
+           EX - 4, EY - 12);
 
-void test_func(struct GadgetInfo *gi)
-{
-  if (gi->event == GD_EVENT_PRESSED)
-    printf("test_func: GD_EVENT_PRESSED\n");
-  else if (gi->event == GD_EVENT_RELEASED)
-    printf("test_func: GD_EVENT_RELEASED\n");
-  else 
-    printf("test_func: ?\n");
-}
+  /* draw new control window */
+  XCopyArea(display, pix[PIX_DOOR], drawto, gc,
+           DOOR_GFX_PAGEX8, 236,
+           EXSIZE, EYSIZE,
+           EX, EY);
 
+  redraw_mask |= REDRAW_ALL;
 
+  OpenDoor(DOOR_OPEN_1);
 
+  MapLevelEditorControlButtons();
 
+  /*
+  OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
+  */
+}
 
 void DrawControlWindow()
 {
@@ -591,59 +973,6 @@ void DrawControlWindow()
           int2str(level.fieldx,3),FS_SMALL,FC_YELLOW);
   DrawText(ED_SIZE_VALUE_XPOS,ED_SIZE_VALUE_YPOS+1*ED_SIZE_GADGET_YSIZE,
           int2str(level.fieldy,3),FS_SMALL,FC_YELLOW);
-
-  {
-    Pixmap gd_pixmap = pix[PIX_DOOR];
-    int gd_x1 = DOOR_GFX_PAGEX4 + ED_BUTTON_MINUS_XPOS;
-    int gd_x2 = DOOR_GFX_PAGEX3 + ED_BUTTON_MINUS_XPOS;
-    int gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_MINUS_YPOS;
-    struct GadgetInfo *gi;
-
-    gi = CreateGadget(GDI_X, 100,
-                     GDI_Y, 100,
-                     GDI_WIDTH, ED_BUTTON_MINUS_XSIZE,
-                     GDI_HEIGHT, ED_BUTTON_MINUS_YSIZE,
-                     GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
-                     GDI_STATE, GD_BUTTON_UNPRESSED,
-                     GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y,
-                     GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y,
-                     GDI_CALLBACK, test_func,
-                     GDI_END);
-
-    if (gi == NULL)
-      Error(ERR_EXIT, "cannot create gadget");
-
-    MapGadget(gi);
-  }
-
-
-}
-
-void ScrollMiniLevel(int from_x, int from_y, int scroll)
-{
-  int x,y;
-  int dx = (scroll==ED_SCROLL_LEFT ? -1 : scroll==ED_SCROLL_RIGHT ? 1 : 0);
-  int dy = (scroll==ED_SCROLL_UP   ? -1 : scroll==ED_SCROLL_DOWN  ? 1 : 0);
-
-  XCopyArea(display,drawto,drawto,gc,
-           SX+MINI_TILEX*(dx==-1),SY+MINI_TILEY*(dy==-1),
-           SXSIZE-MINI_TILEX*ABS(dx),SYSIZE-MINI_TILEY*ABS(dy),
-           SX+MINI_TILEX*(dx==+1),SY+MINI_TILEY*(dy==+1));
-  if (dx)
-  {
-    x = (dx==1 ? 0 : 2*SCR_FIELDX-1);
-    for(y=0;y<2*SCR_FIELDY;y++)
-      DrawMiniElementOrWall(x,y,from_x,from_y);
-  }
-  else if (dy)
-  {
-    y = (dy==1 ? 0 : 2*SCR_FIELDY-1);
-    for(x=0;x<2*SCR_FIELDX;x++)
-      DrawMiniElementOrWall(x,y,from_x,from_y);
-  }
-
-  redraw_mask |= REDRAW_FIELD;
-  BackToFront();
 }
 
 void AdjustLevelScrollPosition()
@@ -663,47 +992,28 @@ void AdjustLevelScrollPosition()
     level_ypos = -1;
 }
 
-void FloodFill(int from_x, int from_y, int fill_element)
-{
-  int i,x,y;
-  int old_element;
-  static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
-  static int safety = 0;
-
-  /* check if starting field still has the desired content */
-  if (Feld[from_x][from_y] == fill_element)
-    return;
-
-  safety++;
-
-  if (safety > lev_fieldx*lev_fieldy)
-    Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
-
-  old_element = Feld[from_x][from_y];
-  Feld[from_x][from_y] = fill_element;
-
-  for(i=0;i<4;i++)
-  {
-    x = from_x + check[i][0];
-    y = from_y + check[i][1];
-
-    if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
-      FloodFill(x, y, fill_element);
-  }
-
-  safety--;
-}
-
 void LevelEd(int mx, int my, int button)
 {
   static int last_button = 0;
   static int in_field_pressed = FALSE;
   static boolean use_floodfill = FALSE;
+
+
+  /*
   int x = (mx-SX)/MINI_TILEX; 
   int y = (my-SY)/MINI_TILEY; 
+  */
+
+
+  HandlePressedControlButtons();
+  HandleDrawingFunction(mx, my, button);
 
   if (use_floodfill)           /********** FLOOD FILL **********/
   {
+
+
+#if 0
+
     if (button)
     {
       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
@@ -733,6 +1043,11 @@ void LevelEd(int mx, int my, int button)
       OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
     }
     return;
+
+#endif
+
+
+
   }
   else                         /********** EDIT/CTRL-FENSTER **********/
   {
@@ -793,6 +1108,11 @@ void LevelEd(int mx, int my, int button)
   
     if (edit_mode)             /********** EDIT-FENSTER **********/
     {
+
+
+
+#if 0
+
       switch(CheckEditButtons(mx,my,button))
       {
        case ED_BUTTON_CTRL:
@@ -882,6 +1202,12 @@ void LevelEd(int mx, int my, int button)
          break;
       }
 
+#endif
+
+
+
+#if 0
+
       if (mx>=SX && mx<SX+SXSIZE && my>=SY && my<SY+SYSIZE)
       {
        int new_element;
@@ -925,6 +1251,11 @@ void LevelEd(int mx, int my, int button)
       }
       else if (!motion_status) /* Mauszeiger nicht im Level-Feld */
        in_field_pressed = FALSE;
+
+#endif
+
+
+
     }
     else                       /********** KONTROLL-FENSTER **********/
     {
@@ -1057,6 +1388,10 @@ void LevelEd(int mx, int my, int button)
        XFlush(display);
       }
 
+
+
+#if 0
+
       switch(CheckCtrlButtons(mx,my,button))
       {
        case ED_BUTTON_EDIT:
@@ -1131,6 +1466,10 @@ void LevelEd(int mx, int my, int button)
          break;
       }
 
+#endif
+
+
+
       if (mx>=ED_COUNT_GADGET_XPOS &&
          mx<ED_COUNT_GADGET_XPOS+31*FONT2_XSIZE+10 &&
          my>=ED_COUNT_GADGET_YPOS+16*ED_COUNT_GADGET_YSIZE &&
@@ -1312,3 +1651,232 @@ void LevelNameTyping(KeySym key)
     name_typing = FALSE;
   }
 }
+
+static void swap_numbers(int *i1, int *i2)
+{
+  int help = *i1;
+
+  *i1 = *i2;
+  *i2 = help;
+}
+
+static void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
+{
+  int help_x = *x1;
+  int help_y = *y1;
+
+  *x1 = *x2;
+  *x2 = help_x;
+
+  *y1 = *y2;
+  *y2 = help_y;
+}
+
+static void DrawLineElement(int sx, int sy, int element)
+{
+  int lx = sx + level_xpos;
+  int ly = sy + level_ypos;
+
+  if (element < 0)
+    DrawMiniElement(sx, sy, Feld[lx][ly]);
+  else
+  {
+    Feld[lx][ly] = element;
+    DrawMiniElement(sx, sy, element);
+  }
+}
+
+void DrawLine(int from_x, int from_y, int to_x, int to_y, int element)
+{
+  if (from_y == to_y)                  /* horizontal line */
+  {
+    int x;
+    int y = from_y;
+
+    if (from_x > to_x)
+      swap_numbers(&from_x, &to_x);
+
+    for (x=from_x; x<=to_x; x++)
+      DrawLineElement(x, y, element);
+  }
+  else if (from_x == to_x)             /* vertical line */
+  {
+    int x = from_x;
+    int y;
+
+    if (from_y > to_y)
+      swap_numbers(&from_y, &to_y);
+
+    for (y=from_y; y<=to_y; y++)
+      DrawLineElement(x, y, element);
+  }
+  else                                 /* diagonal line */
+  {
+    int len_x = ABS(to_x - from_x);
+    int len_y = ABS(to_y - from_y);
+    int x, y;
+
+    if (len_y < len_x)                 /* < 45° */
+    {
+      float a = (float)len_y / (float)len_x;
+
+      if (from_x > to_x)
+       swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
+
+      for (x=0; x<len_x; x++)
+      {
+       int y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1);
+
+       DrawLineElement(from_x + x, from_y + y, element);
+      }
+    }
+    else                               /* >= 45° */
+    {
+      float a = (float)len_x / (float)len_y;
+
+      if (from_y > to_y)
+       swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
+
+      for (y=0; y<len_y; y++)
+      {
+       int x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1);
+
+       DrawLineElement(from_x + x, from_y + y, element);
+      }
+    }
+  }
+}
+
+void FloodFill(int from_x, int from_y, int fill_element)
+{
+  int i,x,y;
+  int old_element;
+  static int check[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} };
+  static int safety = 0;
+
+  /* check if starting field still has the desired content */
+  if (Feld[from_x][from_y] == fill_element)
+    return;
+
+  safety++;
+
+  if (safety > lev_fieldx*lev_fieldy)
+    Error(ERR_EXIT, "Something went wrong in 'FloodFill()'. Please debug.");
+
+  old_element = Feld[from_x][from_y];
+  Feld[from_x][from_y] = fill_element;
+
+  for(i=0;i<4;i++)
+  {
+    x = from_x + check[i][0];
+    y = from_y + check[i][1];
+
+    if (IN_LEV_FIELD(x,y) && Feld[x][y] == old_element)
+      FloodFill(x, y, fill_element);
+  }
+
+  safety--;
+}
+
+void HandleDrawingFunction(int mx, int my, int button)
+{
+  static int in_field_pressed = FALSE;
+  int new_element;
+  int sx = (mx - SX) / MINI_TILEX; 
+  int sy = (my - SY) / MINI_TILEY; 
+  int lx = sx + level_xpos;
+  int ly = sy + level_ypos;
+  int x, y;
+
+  if (mx < SX || mx >= SX + SXSIZE || my < SY || my >= SY + SYSIZE)
+  {
+    /* pointer ouside drawing area */
+
+    if (!motion_status)        /* button pressed or released outside drawing area */
+      in_field_pressed = FALSE;
+
+    return;
+  }
+
+  if (button && !motion_status)
+    in_field_pressed = TRUE;
+
+  if (!button ||
+      !in_field_pressed ||
+      button < 1 || button > 3 ||
+      sx > lev_fieldx || sy > lev_fieldy ||
+      (sx == 0 && level_xpos<0) ||
+      (sx == 2*SCR_FIELDX - 1 && level_xpos > lev_fieldx - 2*SCR_FIELDX) ||
+      (sy == 0 && level_ypos < 0) ||
+      (sy == 2*SCR_FIELDY - 1 && level_ypos > lev_fieldy - 2*SCR_FIELDY))
+    return;
+
+  new_element = (button == 1 ? new_element1 :
+                button == 2 ? new_element2 :
+                button == 3 ? new_element3 : 0);
+
+  switch (drawing_function)
+  {
+    case ED_CTRL_ID_SINGLE_ITEMS:
+      if (new_element != Feld[lx][ly])
+      {
+       if (new_element == EL_SPIELFIGUR)
+       {
+         /* remove player at old position */
+         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)
+             {
+               Feld[x][y] = EL_LEERRAUM;
+               if (x - level_xpos >= 0 && x - level_xpos < 2*SCR_FIELDX &&
+                   y - level_ypos >= 0 && y - level_ypos < 2*SCR_FIELDY)
+                 DrawMiniElement(x - level_xpos, y - level_ypos, EL_LEERRAUM);
+             }
+           }
+         }
+       }
+
+       Feld[lx][ly] = new_element;
+       DrawMiniElement(sx, sy, new_element);
+      }
+      break;
+
+    case ED_CTRL_ID_CONNECTED_ITEMS:
+      {
+       static int last_x = -1;
+       static int last_y = -1;
+
+       if (last_x == -1)
+       {
+         Feld[lx][ly] = new_element;
+         DrawMiniElement(sx, sy, new_element);
+
+         last_x = sx;
+         last_y = sy;
+       }
+       else if (last_x != sx || last_y != sy)
+       {
+         DrawLine(last_x, last_y, sx, sy, new_element);
+
+         last_x = -1;
+         last_y = -1;
+       }
+
+       /*
+       last_x = sx;
+       last_y = sy;
+       */
+      }
+      break;
+
+    case ED_CTRL_ID_FLOOD_FILL:
+      FloodFill(lx, ly, new_element);
+      DrawMiniLevel(level_xpos, level_ypos);
+      break;
+
+    default:
+      break;
+  }
+}
index dae87c12e6d4a72a1f115a6acabc9e993142c1fe..169fbce7185532f215385085db14db9a80784f82 100644 (file)
@@ -24,6 +24,7 @@ extern int element_shift;
 extern int editor_element[];
 extern int elements_in_list;
 
+void UnmapLevelEditorControlButtons();
 void DrawLevelEd(void);
 void LevelEd(int, int, int);
 void LevelNameTyping(KeySym);
index 2fe47e4de408086cd4b5d5cc7e1a8c0923c8830d..53b8171422ab97d250b7f66508d5944fff877726 100644 (file)
@@ -429,7 +429,17 @@ void HandleKey(KeySym key, int key_status)
   /* allow quick escape to the main menu with the Escape key */
   if (key == XK_Escape && game_status != MAINMENU)
   {
-    CloseDoor(DOOR_CLOSE_1 | DOOR_NO_DELAY);
+    if (game_status == LEVELED)
+    {
+      /* 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_1 | DOOR_OPEN_2 | DOOR_NO_DELAY);
     game_status = MAINMENU;
     DrawMainMenu();
     return;
index fed17ca6a049a68e12801eb688aaf460c4420ad8..8f2a6440e4f1d912de8a9ce3e5f45e8737f0eb7a 100644 (file)
@@ -460,6 +460,8 @@ extern int          num_bg_loops;
 #define DY                     60
 #define VX                     DX
 #define VY                     400
+#define EX                     DX
+#define EY                     (VY - 44)
 #define TILEX                  32
 #define TILEY                  32
 #define MINI_TILEX             (TILEX/2)
@@ -476,6 +478,8 @@ extern int          num_bg_loops;
 #define DYSIZE                 280
 #define VXSIZE                 DXSIZE
 #define VYSIZE                 100
+#define EXSIZE                 DXSIZE
+#define EYSIZE                 (VXSIZE + 44)
 #define FULL_SXSIZE            (2+SXSIZE+2)
 #define FULL_SYSIZE            (2+SYSIZE+2)
 #define MICROLEV_XPOS          (SX+4*32+16)
@@ -1084,17 +1088,18 @@ extern int              num_bg_loops;
 #endif
 
 /* values for redraw_mask */
-#define REDRAW_ALL             (1L<<0)
-#define REDRAW_FIELD           (1L<<1)
-#define REDRAW_TILES           (1L<<2)
-#define REDRAW_DOOR_1          (1L<<3)
-#define REDRAW_VIDEO_1         (1L<<4)
-#define REDRAW_VIDEO_2         (1L<<5)
-#define REDRAW_VIDEO_3         (1L<<6)
-#define REDRAW_MICROLEV                (1L<<7)
-#define REDRAW_FROM_BACKBUFFER (1L<<8)
+#define REDRAW_ALL             (1L << 0)
+#define REDRAW_FIELD           (1L << 1)
+#define REDRAW_TILES           (1L << 2)
+#define REDRAW_DOOR_1          (1L << 3)
+#define REDRAW_VIDEO_1         (1L << 4)
+#define REDRAW_VIDEO_2         (1L << 5)
+#define REDRAW_VIDEO_3         (1L << 6)
+#define REDRAW_MICROLEV                (1L << 7)
+#define REDRAW_FROM_BACKBUFFER (1L << 8)
 #define REDRAW_DOOR_2  (REDRAW_VIDEO_1 | REDRAW_VIDEO_2 | REDRAW_VIDEO_3)
-#define REDRAW_DOORS   (REDRAW_DOOR_1 | REDRAW_DOOR_2)
+#define REDRAW_DOOR_3          (1L << 9)
+#define REDRAW_DOORS   (REDRAW_DOOR_1 | REDRAW_DOOR_2 | REDRAW_DOOR_3)
 #define REDRAW_MAIN    (REDRAW_FIELD | REDRAW_TILES | REDRAW_MICROLEV)
 #define REDRAWTILES_THRESHOLD  SCR_FIELDX*SCR_FIELDY/2
 
@@ -1112,6 +1117,8 @@ extern int                num_bg_loops;
 #define DOOR_GFX_PAGEX4                (3 * DOOR_GFX_PAGESIZE)
 #define DOOR_GFX_PAGEX5                (4 * DOOR_GFX_PAGESIZE)
 #define DOOR_GFX_PAGEX6                (5 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX7                (6 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX8                (7 * DOOR_GFX_PAGESIZE)
 #define DOOR_GFX_PAGEY1                0
 #define DOOR_GFX_PAGEY2                DYSIZE
 
index c0a3b8c64a93b851a9b24380d3cde2c3786cc0b5..0da69783facb5efcaa718d3191a2a785a44ed3c9 100644 (file)
@@ -58,6 +58,9 @@ void DrawMainMenu()
   int i;
   char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:");
 
+  /* needed if last screen was the level editor */
+  UnmapLevelEditorControlButtons();
+
   FadeSounds();
   GetPlayerConfig();
   LoadLevel(level_nr);
index d2645960674a93a8112d1c9b9db28fe0bf379cbe..4bbe67f21b9bf21be5ecf2d1c2b7f93ec78183bb 100644 (file)
@@ -161,6 +161,10 @@ void BackToFront()
                    VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
       }
     }
+    if (redraw_mask & REDRAW_DOOR_3)
+      XCopyArea(display, backbuffer, window, gc,
+               EX, EY, EXSIZE, EYSIZE,
+               EX, EY);
     redraw_mask &= ~REDRAW_DOORS;
   }