-/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
-*----------------------------------------------------------*
-* (c) 1995-2006 Artsoft Entertainment *
-* Holger Schemel *
-* Detmolder Strasse 189 *
-* 33604 Bielefeld *
-* Germany *
-* e-mail: info@artsoft.org *
-*----------------------------------------------------------*
-* editor.c *
-***********************************************************/
+// ============================================================================
+// Rocks'n'Diamonds - McDuffin Strikes Back!
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+// Holger Schemel
+// info@artsoft.org
+// http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// editor.c
+// ============================================================================
#include <math.h>
-----------------------------------------------------------------------------
*/
-/* positions in the level editor */
-#define ED_WIN_MB_LEFT_XPOS 6
-#define ED_WIN_MB_LEFT_YPOS 258
-#define ED_WIN_MB_MIDDLE_XPOS 42
-#define ED_WIN_MB_MIDDLE_YPOS ED_WIN_MB_LEFT_YPOS
-#define ED_WIN_MB_RIGHT_XPOS 78
-#define ED_WIN_MB_RIGHT_YPOS ED_WIN_MB_LEFT_YPOS
-
/* values for the control window */
-#define ED_CTRL_NO_BUTTONS_GFX_XPOS 6
-#define ED_CTRL_NO_BUTTONS_GFX_YPOS 286
-#define ED_CTRL1_BUTTONS_GFX_YPOS 236
-#define ED_CTRL2_BUTTONS_GFX_YPOS 236
-#define ED_CTRL3_BUTTONS_GFX_YPOS 324
-#define ED_CTRL4_BUTTONS_GFX_XPOS 44
-#define ED_CTRL4_BUTTONS_GFX_YPOS 214
-#define ED_CTRL1_BUTTONS_ALT_GFX_YPOS 142
-#define ED_CTRL3_BUTTONS_ALT_GFX_YPOS 302
-
-#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_BUTTON_XSIZE 30
-#define ED_CTRL2_BUTTON_YSIZE 20
-#define ED_CTRL2_BUTTONS_XPOS 5
-#define ED_CTRL2_BUTTONS_YPOS 99
-#define ED_CTRL3_BUTTON_XSIZE 22
-#define ED_CTRL3_BUTTON_YSIZE 22
-#define ED_CTRL3_BUTTONS_XPOS 6
-#define ED_CTRL3_BUTTONS_YPOS 6
-#define ED_CTRL4_BUTTON_XSIZE 22
-#define ED_CTRL4_BUTTON_YSIZE 22
-#define ED_CTRL4_BUTTONS_XPOS 6
-#define ED_CTRL4_BUTTONS_YPOS 6
-
-#define ED_CTRL1_BUTTONS_HORIZ 4
+#define ED_CTRL1_BUTTONS_HORIZ 4 /* toolbox */
#define ED_CTRL1_BUTTONS_VERT 4
-#define ED_CTRL2_BUTTONS_HORIZ 3
+#define ED_CTRL2_BUTTONS_HORIZ 3 /* level */
#define ED_CTRL2_BUTTONS_VERT 2
-#define ED_CTRL3_BUTTONS_HORIZ 3
+#define ED_CTRL3_BUTTONS_HORIZ 3 /* CE and GE */
#define ED_CTRL3_BUTTONS_VERT 1
-#define ED_CTRL4_BUTTONS_HORIZ 2
+#define ED_CTRL4_BUTTONS_HORIZ 2 /* CE and GE */
#define ED_CTRL4_BUTTONS_VERT 1
+#define ED_CTRL5_BUTTONS_HORIZ 1 /* properties */
+#define ED_CTRL5_BUTTONS_VERT 1
+#define ED_CTRL6_BUTTONS_HORIZ 3 /* properties */
+#define ED_CTRL6_BUTTONS_VERT 1
+#define ED_CTRL7_BUTTONS_HORIZ 1 /* palette */
+#define ED_CTRL7_BUTTONS_VERT 1
#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_CTRL3_BUTTONS (ED_CTRL3_BUTTONS_HORIZ * ED_CTRL3_BUTTONS_VERT)
#define ED_NUM_CTRL4_BUTTONS (ED_CTRL4_BUTTONS_HORIZ * ED_CTRL4_BUTTONS_VERT)
+#define ED_NUM_CTRL5_BUTTONS (ED_CTRL5_BUTTONS_HORIZ * ED_CTRL5_BUTTONS_VERT)
+#define ED_NUM_CTRL6_BUTTONS (ED_CTRL6_BUTTONS_HORIZ * ED_CTRL6_BUTTONS_VERT)
+#define ED_NUM_CTRL7_BUTTONS (ED_CTRL7_BUTTONS_HORIZ * ED_CTRL7_BUTTONS_VERT)
#define ED_NUM_CTRL1_2_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
#define ED_NUM_CTRL1_3_BUTTONS (ED_NUM_CTRL1_2_BUTTONS + ED_NUM_CTRL3_BUTTONS)
-#define ED_NUM_CTRL_BUTTONS (ED_NUM_CTRL1_BUTTONS + \
- ED_NUM_CTRL2_BUTTONS + \
- ED_NUM_CTRL3_BUTTONS + \
- ED_NUM_CTRL4_BUTTONS)
+#define ED_NUM_CTRL1_4_BUTTONS (ED_NUM_CTRL1_3_BUTTONS + ED_NUM_CTRL4_BUTTONS)
+#define ED_NUM_CTRL1_5_BUTTONS (ED_NUM_CTRL1_4_BUTTONS + ED_NUM_CTRL5_BUTTONS)
+#define ED_NUM_CTRL1_6_BUTTONS (ED_NUM_CTRL1_5_BUTTONS + ED_NUM_CTRL6_BUTTONS)
+#define ED_NUM_CTRL1_7_BUTTONS (ED_NUM_CTRL1_6_BUTTONS + ED_NUM_CTRL7_BUTTONS)
+#define ED_NUM_CTRL_BUTTONS ED_NUM_CTRL1_7_BUTTONS
/* values for the element list */
-#define ED_ELEMENTLIST_XPOS 5
-#define ED_ELEMENTLIST_YPOS 30
-#define ED_ELEMENTLIST_XSIZE 20
-#define ED_ELEMENTLIST_YSIZE 20
-#define ED_ELEMENTLIST_BUTTONS_HORIZ 4
-#define ED_ELEMENTLIST_BUTTONS_VERT 11
+#define ED_ELEMENTLIST_XPOS (editor.palette.x)
+#define ED_ELEMENTLIST_YPOS (editor.palette.y)
+#define ED_ELEMENTLIST_XSIZE (graphic_info[IMG_EDITOR_PALETTE_BUTTON].width)
+#define ED_ELEMENTLIST_YSIZE (graphic_info[IMG_EDITOR_PALETTE_BUTTON].height)
+#define ED_ELEMENTLIST_BUTTONS_HORIZ (editor.palette.cols)
+#define ED_ELEMENTLIST_BUTTONS_VERT (editor.palette.rows)
#define ED_NUM_ELEMENTLIST_BUTTONS (ED_ELEMENTLIST_BUTTONS_HORIZ * \
ED_ELEMENTLIST_BUTTONS_VERT)
/* standard distances */
-#define ED_BORDER_SIZE 3
-#define ED_BORDER_TEXT_XSIZE 5
-#define ED_BORDER_AREA_YSIZE 1
-
-#define ED_GADGET_DISTANCE 2
-#define ED_GADGET_TEXT_DISTANCE (2 * ED_GADGET_DISTANCE)
+#define ED_GADGET_NORMAL_DISTANCE (editor.gadget.normal_spacing)
+#define ED_GADGET_SMALL_DISTANCE (editor.gadget.small_spacing)
+#define ED_GADGET_TINY_DISTANCE (editor.gadget.tiny_spacing)
+#define ED_GADGET_LINE_DISTANCE (editor.gadget.line_spacing)
+#define ED_GADGET_TEXT_DISTANCE (editor.gadget.text_spacing)
+#define ED_TAB_BAR_HEIGHT (editor.gadget.separator_line.height)
#define ED_DRAWINGAREA_TEXT_DISTANCE (ED_GADGET_TEXT_DISTANCE + \
- MINI_TILEX / 2)
+ ED_DRAWINGAREA_BORDER_SIZE)
+#define ED_GADGET_SPACE_DISTANCE (getFontWidth(FONT_TEXT_1))
-/* values for the settings windows */
-#define ED_LEVEL_SETTINGS_XSTART (3 * MINI_TILEX / 2)
-#define ED_LEVEL_SETTINGS_YSTART (5 * MINI_TILEY)
+/* values for drawingarea gadgets */
+#define IMG_BORDER_1 IMG_EDITOR_ELEMENT_BORDER
+#define IMG_BORDER_2 IMG_EDITOR_ELEMENT_BORDER_INPUT
+#define ED_ELEMENT_BORDER (graphic_info[IMG_BORDER_1].border_size)
+#define ED_DRAWINGAREA_BORDER_SIZE (graphic_info[IMG_BORDER_2].border_size)
+#define ED_DRAWINGAREA_TILE_SIZE (editor.drawingarea.tile_size)
-#define ED_ELEMENT_SETTINGS_XSTART (3 * MINI_TILEX / 2)
-#define ED_ELEMENT_SETTINGS_YSTART (10 * MINI_TILEY)
-
-#define ED_XOFFSET_CHECKBOX (ED_CHECKBUTTON_XSIZE + \
- 2 * ED_GADGET_DISTANCE)
+/* values for checkbutton gadgets */
+#define ED_CHECKBUTTON_XSIZE (graphic_info[IMG_EDITOR_CHECKBOX].width)
+#define ED_CHECKBUTTON_YSIZE (graphic_info[IMG_EDITOR_CHECKBOX].height)
+
+#define ED_TABBUTTON_XSIZE (graphic_info[IMG_EDITOR_TABBUTTON].width)
+#define ED_TABBUTTON_YSIZE (graphic_info[IMG_EDITOR_TABBUTTON].height)
+
+#define ED_SETTINGS_LEVEL_TABS_X (editor.settings.tabs.x)
+#define ED_SETTINGS_LEVEL_TABS_Y (editor.settings.tabs.y)
+#define ED_SETTINGS_ELEMENT_TABS_X (editor.settings.tabs.x)
+#define ED_SETTINGS_ELEMENT_TABS_Y (editor.settings.tabs.y + \
+ editor.settings.tabs.yoffset2)
+
+#define ED_SETTINGS_TABS_XOFFSET (editor.settings.tabs.draw_xoffset)
+#define ED_SETTINGS_TABS_YOFFSET (editor.settings.tabs.draw_yoffset)
+
+#define ED_LEVEL_TABS_XSTART (ED_SETTINGS_LEVEL_TABS_X)
+#define ED_LEVEL_TABS_YSTART (ED_SETTINGS_LEVEL_TABS_Y)
+#define ED_LEVEL_SETTINGS_XSTART (ED_SETTINGS_LEVEL_TABS_X + \
+ ED_SETTINGS_TABS_XOFFSET)
+#define ED_LEVEL_SETTINGS_YSTART (ED_SETTINGS_LEVEL_TABS_Y + \
+ ED_TABBUTTON_YSIZE + \
+ ED_GADGET_TINY_DISTANCE + \
+ ED_TAB_BAR_HEIGHT + \
+ ED_SETTINGS_TABS_YOFFSET + \
+ getFontHeight(FONT_TEXT_1) + \
+ ED_GADGET_TEXT_DISTANCE)
+#define ED_ELEMENT_TABS_XSTART (ED_SETTINGS_ELEMENT_TABS_X)
+#define ED_ELEMENT_TABS_YSTART (ED_SETTINGS_ELEMENT_TABS_Y)
+#define ED_ELEMENT_SETTINGS_XSTART (ED_SETTINGS_ELEMENT_TABS_X + \
+ ED_SETTINGS_TABS_XOFFSET)
+#define ED_ELEMENT_SETTINGS_YSTART (ED_SETTINGS_ELEMENT_TABS_Y + \
+ ED_TABBUTTON_YSIZE + \
+ ED_GADGET_TINY_DISTANCE + \
+ ED_TAB_BAR_HEIGHT + \
+ ED_SETTINGS_TABS_YOFFSET)
+
+#define ED_SETTINGS_XOFFSET (ED_CHECKBUTTON_XSIZE + \
+ ED_GADGET_TEXT_DISTANCE)
+#define ED_SETTINGS_YOFFSET (ED_CHECKBUTTON_YSIZE + \
+ ED_GADGET_LINE_DISTANCE)
+
+#define ED_POS_RANGE (10000)
+#define ED_POS_LEVEL_TABS_FIRST (1 * ED_POS_RANGE)
+#define ED_POS_LEVEL_TABS_LAST (2 * ED_POS_RANGE - 1)
+#define ED_POS_LEVEL_SETTINGS_FIRST (2 * ED_POS_RANGE)
+#define ED_POS_LEVEL_SETTINGS_LAST (3 * ED_POS_RANGE - 1)
+#define ED_POS_ELEMENT_TABS_FIRST (3 * ED_POS_RANGE)
+#define ED_POS_ELEMENT_TABS_LAST (4 * ED_POS_RANGE - 1)
+#define ED_POS_ELEMENT_SETTINGS_FIRST (4 * ED_POS_RANGE)
+#define ED_POS_ELEMENT_SETTINGS_LAST (5 * ED_POS_RANGE - 1)
+
+#define ED_LEVEL_TABS_XPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n))
+#define ED_LEVEL_TABS_YPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n))
+
+#define ED_LEVEL_SETTINGS_XPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n))
+#define ED_LEVEL_SETTINGS_YPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n))
+
+#define ED_ELEMENT_TABS_XPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n))
+#define ED_ELEMENT_TABS_YPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n))
+
+#define ED_ELEMENT_SETTINGS_XPOS(n) (ED_POS_ELEMENT_SETTINGS_FIRST + (n))
+#define ED_ELEMENT_SETTINGS_YPOS(n) (ED_POS_ELEMENT_SETTINGS_FIRST + (n))
+
+#define IS_POS_LEVEL_TABS(n) ((n) >= ED_POS_LEVEL_TABS_FIRST && \
+ (n) <= ED_POS_LEVEL_TABS_LAST)
+#define IS_POS_LEVEL_SETTINGS(n) ((n) >= ED_POS_LEVEL_SETTINGS_FIRST && \
+ (n) <= ED_POS_LEVEL_SETTINGS_LAST)
+#define IS_POS_ELEMENT_TABS(n) ((n) >= ED_POS_ELEMENT_TABS_FIRST && \
+ (n) <= ED_POS_ELEMENT_TABS_LAST)
+#define IS_POS_ELEMENT_SETTINGS(n) ((n) >= ED_POS_ELEMENT_SETTINGS_FIRST && \
+ (n) <= ED_POS_ELEMENT_SETTINGS_LAST)
+
+#define ED_LEVEL_TABS_LINE(n) ((n) - ED_POS_LEVEL_TABS_FIRST)
+#define ED_LEVEL_SETTINGS_LINE(n) ((n) - ED_POS_LEVEL_SETTINGS_FIRST)
+#define ED_ELEMENT_TABS_LINE(n) ((n) - ED_POS_ELEMENT_TABS_FIRST)
+#define ED_ELEMENT_SETTINGS_LINE(n) ((n) - ED_POS_ELEMENT_SETTINGS_FIRST)
+
+#define ED_LEVEL_TABS_X(n) (ED_LEVEL_TABS_XSTART + \
+ (n) * ED_SETTINGS_TABS_XOFFSET)
+#define ED_LEVEL_TABS_Y(n) (ED_LEVEL_TABS_YSTART + \
+ (n) * ED_SETTINGS_TABS_YOFFSET)
+
+#define ED_LEVEL_SETTINGS_X(n) (ED_LEVEL_SETTINGS_XSTART + \
+ (n) * ED_SETTINGS_XOFFSET)
+#define ED_LEVEL_SETTINGS_Y(n) (ED_LEVEL_SETTINGS_YSTART + \
+ (n) * ED_SETTINGS_YOFFSET)
-#define ED_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX
-#define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2)
+#define ED_ELEMENT_TABS_X(n) (ED_ELEMENT_TABS_XSTART + \
+ (n) * ED_SETTINGS_TABS_XOFFSET)
+#define ED_ELEMENT_TABS_Y(n) (ED_ELEMENT_TABS_YSTART + \
+ (n) * ED_SETTINGS_TABS_YOFFSET)
-#define ED_LEVEL_SETTINGS_XPOS(n) (ED_LEVEL_SETTINGS_XSTART + \
- (n) * ED_SETTINGS_XOFFSET)
-#define ED_LEVEL_SETTINGS_YPOS(n) (ED_LEVEL_SETTINGS_YSTART + \
+#define ED_ELEMENT_SETTINGS_X(n) (ED_ELEMENT_SETTINGS_XSTART + \
+ (n) * ED_SETTINGS_XOFFSET)
+#define ED_ELEMENT_SETTINGS_Y(n) (ED_ELEMENT_SETTINGS_YSTART + \
(n) * ED_SETTINGS_YOFFSET)
-#define ED_ELEMENT_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XSTART + \
- (n) * ED_SETTINGS_XOFFSET)
-#define ED_ELEMENT_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YSTART + \
- (n) * ED_SETTINGS_YOFFSET)
+#define ED_POS_TO_LEVEL_TABS_X(n) \
+ (ED_LEVEL_TABS_X(ED_LEVEL_TABS_LINE(n)))
+#define ED_POS_TO_LEVEL_TABS_Y(n) \
+ (ED_LEVEL_TABS_Y(ED_LEVEL_TABS_LINE(n)))
+
+#define ED_POS_TO_LEVEL_SETTINGS_X(n) \
+ (ED_LEVEL_SETTINGS_X(ED_LEVEL_SETTINGS_LINE(n)))
+#define ED_POS_TO_LEVEL_SETTINGS_Y(n) \
+ (ED_LEVEL_SETTINGS_Y(ED_LEVEL_SETTINGS_LINE(n)))
+
+#define ED_POS_TO_ELEMENT_TABS_X(n) \
+ (ED_ELEMENT_TABS_X(ED_ELEMENT_TABS_LINE(n)))
+#define ED_POS_TO_ELEMENT_TABS_Y(n) \
+ (ED_ELEMENT_TABS_Y(ED_ELEMENT_TABS_LINE(n)))
+
+#define ED_POS_TO_ELEMENT_SETTINGS_X(n) \
+ (ED_ELEMENT_SETTINGS_X(ED_ELEMENT_SETTINGS_LINE(n)))
+#define ED_POS_TO_ELEMENT_SETTINGS_Y(n) \
+ (ED_ELEMENT_SETTINGS_Y(ED_ELEMENT_SETTINGS_LINE(n)))
+
+#define ED_SETTINGS_X(n) (IS_POS_LEVEL_TABS(n) ? \
+ ED_POS_TO_LEVEL_TABS_X(n) : \
+ IS_POS_LEVEL_SETTINGS(n) ? \
+ ED_POS_TO_LEVEL_SETTINGS_X(n) : \
+ IS_POS_ELEMENT_TABS(n) ? \
+ ED_POS_TO_ELEMENT_TABS_X(n) : \
+ IS_POS_ELEMENT_SETTINGS(n) ? \
+ ED_POS_TO_ELEMENT_SETTINGS_X(n) : (n))
+#define ED_SETTINGS_Y(n) (IS_POS_LEVEL_TABS(n) ? \
+ ED_POS_TO_LEVEL_TABS_Y(n) : \
+ IS_POS_LEVEL_SETTINGS(n) ? \
+ ED_POS_TO_LEVEL_SETTINGS_Y(n) : \
+ IS_POS_ELEMENT_TABS(n) ? \
+ ED_POS_TO_ELEMENT_TABS_Y(n) : \
+ IS_POS_ELEMENT_SETTINGS(n) ? \
+ ED_POS_TO_ELEMENT_SETTINGS_Y(n) : (n))
+
+#define ED_SETTINGS_XOFF(n) (5 * ((n) % 4) * \
+ ED_DRAWINGAREA_TILE_SIZE)
+#define ED_SETTINGS_YOFF(n) (5 * ((n) / 4) * \
+ ED_DRAWINGAREA_TILE_SIZE)
+
+#define ED_AREA_XOFFSET_1(n) ((n) != 0 ? \
+ ED_DRAWINGAREA_BORDER_SIZE : 0)
+#define ED_AREA_YOFFSET_1(n) ((n) != 0 ? \
+ (ED_CHECKBUTTON_YSIZE - \
+ ED_DRAWINGAREA_TILE_SIZE) / 2 : 0)
+
+#define ED_AREA_XOFFSET_2(n) (0)
+#define ED_AREA_YOFFSET_2(n) ((n) == 3 ? \
+ ((n) - 1) * ED_DRAWINGAREA_TILE_SIZE / 2 : 0)
+
+#define ED_AREA_SETTINGS_X(i) (ED_SETTINGS_X((i).x) + \
+ ED_SETTINGS_XOFF((i).xoffset) + \
+ ED_AREA_XOFFSET_1((i).x) - \
+ ED_AREA_XOFFSET_2((i).area_xsize))
+#define ED_AREA_SETTINGS_Y(i) (ED_SETTINGS_Y((i).y) + \
+ ED_SETTINGS_YOFF((i).yoffset) + \
+ ED_AREA_YOFFSET_1((i).y) - \
+ ED_AREA_YOFFSET_2((i).area_ysize))
-#define ED_SETTINGS1_YPOS MINI_TILEY
-#define ED_SETTINGS2_XPOS MINI_TILEX
-#define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2)
+/* values for element content drawing areas */
+#define ED_AREA_1X1_LSETTINGS_XPOS(n) ED_LEVEL_SETTINGS_XPOS(n)
+#define ED_AREA_1X1_LSETTINGS_YPOS(n) ED_LEVEL_SETTINGS_YPOS(n)
+#define ED_AREA_1X1_LSETTINGS_XOFF (0)
+#define ED_AREA_1X1_LSETTINGS_YOFF (0)
-/* values for counter gadgets */
-#define ED_COUNTER_YSTART (ED_SETTINGS1_YPOS + 2 * TILEY)
-#define ED_COUNTER_YDISTANCE (3 * MINI_TILEY)
-#define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \
- (n) * ED_COUNTER_YDISTANCE)
-#define ED_COUNTER2_YPOS(n) (ED_COUNTER_YSTART + \
- (n) * ED_COUNTER_YDISTANCE - 2)
+#define ED_AREA_1X1_SETTINGS_XPOS(n) ED_ELEMENT_SETTINGS_XPOS(n)
+#define ED_AREA_1X1_SETTINGS_YPOS(n) ED_ELEMENT_SETTINGS_YPOS(n)
+#define ED_AREA_1X1_SETTINGS_XOFF (0)
+#define ED_AREA_1X1_SETTINGS_YOFF (0)
-/* values for element content drawing areas */
-#define ED_AREA_1X1_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(n))
-#define ED_AREA_1X1_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YPOS(n) + \
- ED_GADGET_DISTANCE)
+#define ED_AREA_3X3_SETTINGS_XPOS(n) ED_ELEMENT_SETTINGS_XPOS(n)
+#define ED_AREA_3X3_SETTINGS_YPOS(n) ED_ELEMENT_SETTINGS_YPOS(n)
+#define ED_AREA_3X3_SETTINGS_XOFF (0)
+#define ED_AREA_3X3_SETTINGS_YOFF (0)
-#define ED_AREA_3X3_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(n))
-#define ED_AREA_3X3_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YPOS(n) + \
- ED_GADGET_DISTANCE - MINI_TILEY)
+/* element content */
+#define ED_AREA_ELEMENT_CONTENT_XOFF(n) (n)
+#define ED_AREA_ELEMENT_CONTENT_YOFF(n) (n)
/* yamyam content */
-#define ED_AREA_YAMYAM_CONTENT_XPOS(n) (2 * MINI_TILEX + \
- 5 * ((n) % 4) * MINI_TILEX)
-#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (11 * ED_SETTINGS_YOFFSET + \
- 6 * ((n) / 4) * MINI_TILEY)
+#define ED_XPOS_YAM 0
+#define ED_YPOS_YAM 5
+#define ED_AREA_YAMYAM_CONTENT_XPOS ED_ELEMENT_SETTINGS_XPOS(ED_XPOS_YAM)
+#define ED_AREA_YAMYAM_CONTENT_YPOS ED_ELEMENT_SETTINGS_YPOS(ED_YPOS_YAM)
+#define ED_AREA_YAMYAM_CONTENT_XOFF(n) ED_AREA_ELEMENT_CONTENT_XOFF(n)
+#define ED_AREA_YAMYAM_CONTENT_YOFF(n) ED_AREA_ELEMENT_CONTENT_YOFF(n)
+#define ED_AREA_YAMYAM_CONTENT_X(n) (ED_ELEMENT_SETTINGS_X(ED_XPOS_YAM) + \
+ ED_SETTINGS_XOFF(n))
+#define ED_AREA_YAMYAM_CONTENT_Y(n) (ED_ELEMENT_SETTINGS_Y(ED_YPOS_YAM) + \
+ ED_SETTINGS_YOFF(n) + \
+ ED_AREA_YOFFSET_1(ED_YPOS_YAM) - \
+ ED_AREA_YOFFSET_2(3))
/* magic ball content */
-#define ED_AREA_MAGIC_BALL_CONTENT_XPOS(n) (2 * MINI_TILEX + \
- 5 * ((n) % 4) * MINI_TILEX)
-#define ED_AREA_MAGIC_BALL_CONTENT_YPOS(n) (12 * ED_SETTINGS_YOFFSET + \
- 6 * ((n) / 4) * MINI_TILEY)
+#define ED_XPOS_BALL 0
+#define ED_YPOS_BALL 6
+#define ED_AREA_MAGIC_BALL_CONTENT_XPOS ED_ELEMENT_SETTINGS_XPOS(ED_XPOS_BALL)
+#define ED_AREA_MAGIC_BALL_CONTENT_YPOS ED_ELEMENT_SETTINGS_YPOS(ED_YPOS_BALL)
+#define ED_AREA_MAGIC_BALL_CONTENT_XOFF(n) ED_AREA_ELEMENT_CONTENT_XOFF(n)
+#define ED_AREA_MAGIC_BALL_CONTENT_YOFF(n) ED_AREA_ELEMENT_CONTENT_YOFF(n)
+#define ED_AREA_MAGIC_BALL_CONTENT_X(n) (ED_ELEMENT_SETTINGS_X(ED_XPOS_BALL) + \
+ ED_SETTINGS_XOFF(n))
+#define ED_AREA_MAGIC_BALL_CONTENT_Y(n) (ED_ELEMENT_SETTINGS_Y(ED_YPOS_BALL) + \
+ ED_SETTINGS_YOFF(n) + \
+ ED_AREA_YOFFSET_1(ED_YPOS_BALL) - \
+ ED_AREA_YOFFSET_2(3))
/* values for scrolling gadgets for drawing area */
-#define ED_SCROLLBUTTON_XPOS 24
-#define ED_SCROLLBUTTON_YPOS 0
-#define ED_SCROLLBAR_XPOS 24
-#define ED_SCROLLBAR_YPOS 64
-
-#define ED_SCROLLBUTTON_XSIZE 16
-#define ED_SCROLLBUTTON_YSIZE 16
+#define ED_SCROLLBUTTON_XSIZE (graphic_info[IMG_EDITOR_PLAYFIELD_SCROLLBAR].width)
+#define ED_SCROLLBUTTON_YSIZE (graphic_info[IMG_EDITOR_PLAYFIELD_SCROLLBAR].height)
#define ED_SCROLL_UP_XPOS (SXSIZE - ED_SCROLLBUTTON_XSIZE)
#define ED_SCROLL_UP_YPOS (0)
#define ED_SCROLL_VERTICAL_YSIZE (SYSIZE - 4 * ED_SCROLLBUTTON_YSIZE)
/* values for scrolling gadgets for element list */
-#define ED_SCROLLBUTTON2_XPOS 50
-#define ED_SCROLLBUTTON2_YPOS 0
-#define ED_SCROLLBAR2_XPOS 50
-#define ED_SCROLLBAR2_YPOS 20
+#define ED_SCROLLBUTTON2_XSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].width)
+#define ED_SCROLLBUTTON2_YSIZE (graphic_info[IMG_EDITOR_PALETTE_SCROLL_UP].height)
-#define ED_SCROLLBUTTON2_XSIZE 10
-#define ED_SCROLLBUTTON2_YSIZE 10
-
-#define ED_SCROLL2_UP_XPOS 85
-#define ED_SCROLL2_UP_YPOS 30
+#define ED_SCROLL2_UP_XPOS (ED_ELEMENTLIST_XPOS + \
+ ED_ELEMENTLIST_BUTTONS_HORIZ * \
+ ED_ELEMENTLIST_XSIZE)
+#define ED_SCROLL2_UP_YPOS ED_ELEMENTLIST_YPOS
#define ED_SCROLL2_DOWN_XPOS ED_SCROLL2_UP_XPOS
#define ED_SCROLL2_DOWN_YPOS (ED_SCROLL2_UP_YPOS + \
ED_ELEMENTLIST_BUTTONS_VERT * \
ED_ELEMENTLIST_YSIZE - \
2 * ED_SCROLLBUTTON2_YSIZE)
-/* values for checkbutton gadgets */
-#define ED_CHECKBUTTON_XSIZE ED_BUTTON_COUNT_XSIZE
-#define ED_CHECKBUTTON_YSIZE ED_BUTTON_COUNT_YSIZE
-#define ED_CHECKBUTTON_UNCHECKED_XPOS ED_BUTTON_MINUS_XPOS
-#define ED_CHECKBUTTON_CHECKED_XPOS ED_BUTTON_PLUS_XPOS
-#define ED_CHECKBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 22)
-#define ED_RADIOBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 44)
-#define ED_STICKYBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 66)
-
-/* values for some special graphic buttons */
-#define ED_COPY_CHANGE_PAGE_XPOS 25
-#define ED_COPY_CHANGE_PAGE_YPOS 50
-#define ED_PASTE_CHANGE_PAGE_XPOS 25
-#define ED_PASTE_CHANGE_PAGE_YPOS 70
-
-/* some values for text input, selectbox and counter gadgets */
-#define ED_BUTTON_COUNT_YPOS 60
-#define ED_BUTTON_COUNT_XSIZE 20
-#define ED_BUTTON_COUNT_YSIZE 20
-#define ED_WIN_COUNT_XPOS (2 + ED_BUTTON_COUNT_XSIZE + 2)
-#define ED_WIN_COUNT_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_WIN_COUNT_XSIZE 52
-#define ED_WIN_COUNT_YSIZE ED_BUTTON_COUNT_YSIZE
-#define ED_WIN_COUNT2_XPOS 27
-#define ED_WIN_COUNT2_YPOS 3
-#define ED_WIN_COUNT2_XSIZE 46
-#define ED_WIN_COUNT2_YSIZE ED_BUTTON_COUNT_YSIZE
-
-#define ED_BUTTON_MINUS_XPOS 2
-#define ED_BUTTON_MINUS_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_BUTTON_MINUS_XSIZE ED_BUTTON_COUNT_XSIZE
-#define ED_BUTTON_MINUS_YSIZE ED_BUTTON_COUNT_YSIZE
-#define ED_BUTTON_PLUS_XPOS (ED_WIN_COUNT_XPOS + \
- ED_WIN_COUNT_XSIZE + 2)
-#define ED_BUTTON_PLUS_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_BUTTON_PLUS_XSIZE ED_BUTTON_COUNT_XSIZE
-#define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE
-
-#define ED_SELECTBOX_XPOS ED_WIN_COUNT_XPOS
-#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + \
- 2 + ED_WIN_COUNT_YSIZE)
-#define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE
-#define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE
-
-#define ED_SELECTBOX_BUTTON_XSIZE 14
-
-#define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS
-#define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \
- 4 * (2 + ED_WIN_COUNT_YSIZE))
-#define ED_TEXTBUTTON_INACTIVE_YPOS ED_TEXTBUTTON_YPOS
-
-#define ED_TEXTBUTTON_TAB_XPOS ED_WIN_COUNT_XPOS
-#define ED_TEXTBUTTON_TAB_YPOS (ED_WIN_COUNT_YPOS + \
- 2 * (2 + ED_WIN_COUNT_YSIZE))
-#define ED_TEXTBUTTON_TAB_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \
- 3 * (2 + ED_WIN_COUNT_YSIZE))
-
-#define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE
-#define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE
-
/* values for ClearEditorGadgetInfoText() and HandleEditorGadgetInfoText() */
-#define INFOTEXT_XPOS SX
-#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2)
-#define INFOTEXT_XSIZE SXSIZE
-#define INFOTEXT_YSIZE MINI_TILEX
+#define INFOTEXT_FONT FONT_TEXT_2
+#define INFOTEXT_XSIZE SXSIZE
+#define INFOTEXT_YSIZE getFontHeight(INFOTEXT_FONT)
+#define INFOTEXT_YSIZE_FULL (INFOTEXT_YSIZE + ED_GADGET_SMALL_DISTANCE)
+#define INFOTEXT_XPOS SX
+#define INFOTEXT_YPOS (SY + SYSIZE - INFOTEXT_YSIZE)
/*
#define GADGET_ID_TEXT (GADGET_ID_TOOLBOX_FIRST + 7)
#define GADGET_ID_FLOOD_FILL (GADGET_ID_TOOLBOX_FIRST + 8)
#define GADGET_ID_WRAP_LEFT (GADGET_ID_TOOLBOX_FIRST + 9)
-#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 10)
+#define GADGET_ID_ZOOM (GADGET_ID_TOOLBOX_FIRST + 10)
#define GADGET_ID_WRAP_RIGHT (GADGET_ID_TOOLBOX_FIRST + 11)
#define GADGET_ID_RANDOM_PLACEMENT (GADGET_ID_TOOLBOX_FIRST + 12)
#define GADGET_ID_GRAB_BRUSH (GADGET_ID_TOOLBOX_FIRST + 13)
#define GADGET_ID_CUSTOM_COPY (GADGET_ID_TOOLBOX_FIRST + 25)
#define GADGET_ID_CUSTOM_PASTE (GADGET_ID_TOOLBOX_FIRST + 26)
+#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 27)
+#define GADGET_ID_ELEMENT_LEFT (GADGET_ID_TOOLBOX_FIRST + 28)
+#define GADGET_ID_ELEMENT_MIDDLE (GADGET_ID_TOOLBOX_FIRST + 29)
+#define GADGET_ID_ELEMENT_RIGHT (GADGET_ID_TOOLBOX_FIRST + 30)
+#define GADGET_ID_PALETTE (GADGET_ID_TOOLBOX_FIRST + 31)
+
/* counter gadget identifiers */
-#define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 27)
+#define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 32)
#define GADGET_ID_SELECT_LEVEL_DOWN (GADGET_ID_COUNTER_FIRST + 0)
#define GADGET_ID_SELECT_LEVEL_TEXT (GADGET_ID_COUNTER_FIRST + 1)
#define GADGET_ID_LEVEL_TIMESCORE_DOWN (GADGET_ID_COUNTER_FIRST + 18)
#define GADGET_ID_LEVEL_TIMESCORE_TEXT (GADGET_ID_COUNTER_FIRST + 19)
#define GADGET_ID_LEVEL_TIMESCORE_UP (GADGET_ID_COUNTER_FIRST + 20)
-#define GADGET_ID_ELEMENT_VALUE1_DOWN (GADGET_ID_COUNTER_FIRST + 21)
-#define GADGET_ID_ELEMENT_VALUE1_TEXT (GADGET_ID_COUNTER_FIRST + 22)
-#define GADGET_ID_ELEMENT_VALUE1_UP (GADGET_ID_COUNTER_FIRST + 23)
-#define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 24)
-#define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 25)
-#define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 26)
-#define GADGET_ID_ELEMENT_VALUE3_DOWN (GADGET_ID_COUNTER_FIRST + 27)
-#define GADGET_ID_ELEMENT_VALUE3_TEXT (GADGET_ID_COUNTER_FIRST + 28)
-#define GADGET_ID_ELEMENT_VALUE3_UP (GADGET_ID_COUNTER_FIRST + 29)
-#define GADGET_ID_ELEMENT_VALUE4_DOWN (GADGET_ID_COUNTER_FIRST + 30)
-#define GADGET_ID_ELEMENT_VALUE4_TEXT (GADGET_ID_COUNTER_FIRST + 31)
-#define GADGET_ID_ELEMENT_VALUE4_UP (GADGET_ID_COUNTER_FIRST + 32)
-#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 33)
-#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 34)
-#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 35)
-#define GADGET_ID_BALL_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 36)
-#define GADGET_ID_BALL_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 37)
-#define GADGET_ID_BALL_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 38)
-#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 39)
-#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 40)
-#define GADGET_ID_ANDROID_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 41)
-#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 42)
-#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 43)
-#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 44)
-#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 45)
-#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 46)
-#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 47)
-#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 48)
-#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 49)
-#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 50)
-#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 51)
-#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 52)
-#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 53)
-#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 54)
-#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 55)
-#define GADGET_ID_CUSTOM_VALUE_FIX_UP (GADGET_ID_COUNTER_FIRST + 56)
-#define GADGET_ID_CUSTOM_VALUE_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57)
-#define GADGET_ID_CUSTOM_VALUE_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58)
-#define GADGET_ID_CUSTOM_VALUE_RND_UP (GADGET_ID_COUNTER_FIRST + 59)
-#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 60)
-#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 61)
-#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 62)
-#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 63)
-#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 64)
-#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 65)
-#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66)
-#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67)
-#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68)
-#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69)
-#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70)
-#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71)
-#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 72)
-#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 73)
-#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 74)
-#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 75)
-#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 76)
-#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 77)
-#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 78)
-#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 79)
-#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 80)
-#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 81)
-#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 82)
-#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 83)
-#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 84)
-#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 85)
-#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 86)
-#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 87)
-#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 88)
-#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 89)
-#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 90)
-#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 91)
-#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 92)
-#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 93)
-#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 94)
-#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 95)
+#define GADGET_ID_LEVEL_RANDOM_SEED_DOWN (GADGET_ID_COUNTER_FIRST + 21)
+#define GADGET_ID_LEVEL_RANDOM_SEED_TEXT (GADGET_ID_COUNTER_FIRST + 22)
+#define GADGET_ID_LEVEL_RANDOM_SEED_UP (GADGET_ID_COUNTER_FIRST + 23)
+#define GADGET_ID_ELEMENT_VALUE1_DOWN (GADGET_ID_COUNTER_FIRST + 24)
+#define GADGET_ID_ELEMENT_VALUE1_TEXT (GADGET_ID_COUNTER_FIRST + 25)
+#define GADGET_ID_ELEMENT_VALUE1_UP (GADGET_ID_COUNTER_FIRST + 26)
+#define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 27)
+#define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 28)
+#define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 29)
+#define GADGET_ID_ELEMENT_VALUE3_DOWN (GADGET_ID_COUNTER_FIRST + 30)
+#define GADGET_ID_ELEMENT_VALUE3_TEXT (GADGET_ID_COUNTER_FIRST + 31)
+#define GADGET_ID_ELEMENT_VALUE3_UP (GADGET_ID_COUNTER_FIRST + 32)
+#define GADGET_ID_ELEMENT_VALUE4_DOWN (GADGET_ID_COUNTER_FIRST + 33)
+#define GADGET_ID_ELEMENT_VALUE4_TEXT (GADGET_ID_COUNTER_FIRST + 34)
+#define GADGET_ID_ELEMENT_VALUE4_UP (GADGET_ID_COUNTER_FIRST + 35)
+#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 36)
+#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 37)
+#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 38)
+#define GADGET_ID_BALL_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 39)
+#define GADGET_ID_BALL_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 40)
+#define GADGET_ID_BALL_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 41)
+#define GADGET_ID_ANDROID_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 42)
+#define GADGET_ID_ANDROID_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 43)
+#define GADGET_ID_ANDROID_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 44)
+#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 45)
+#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 46)
+#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 47)
+#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 48)
+#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 49)
+#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 50)
+#define GADGET_ID_INVENTORY_SIZE_DOWN (GADGET_ID_COUNTER_FIRST + 51)
+#define GADGET_ID_INVENTORY_SIZE_TEXT (GADGET_ID_COUNTER_FIRST + 52)
+#define GADGET_ID_INVENTORY_SIZE_UP (GADGET_ID_COUNTER_FIRST + 53)
+#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 54)
+#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 55)
+#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 56)
+#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 57)
+#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 58)
+#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 59)
+#define GADGET_ID_CUSTOM_VALUE_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 60)
+#define GADGET_ID_CUSTOM_VALUE_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 61)
+#define GADGET_ID_CUSTOM_VALUE_FIX_UP (GADGET_ID_COUNTER_FIRST + 62)
+#define GADGET_ID_CUSTOM_VALUE_RND_DOWN (GADGET_ID_COUNTER_FIRST + 63)
+#define GADGET_ID_CUSTOM_VALUE_RND_TEXT (GADGET_ID_COUNTER_FIRST + 64)
+#define GADGET_ID_CUSTOM_VALUE_RND_UP (GADGET_ID_COUNTER_FIRST + 65)
+#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66)
+#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67)
+#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68)
+#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69)
+#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70)
+#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71)
+#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 72)
+#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 73)
+#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 74)
+#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 75)
+#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 76)
+#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 77)
+#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 78)
+#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 79)
+#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 80)
+#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 81)
+#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 82)
+#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 83)
+#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 84)
+#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 85)
+#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 86)
+#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 87)
+#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 88)
+#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 89)
+#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 90)
+#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 91)
+#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 92)
+#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 93)
+#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 94)
+#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 95)
+#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 96)
+#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 97)
+#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 98)
+#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 99)
+#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 100)
+#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 101)
/* drawing area identifiers */
-#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 96)
+#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 102)
#define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0)
#define GADGET_ID_YAMYAM_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1)
#define GADGET_ID_START_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 19)
#define GADGET_ID_ARTWORK_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 20)
#define GADGET_ID_EXPLOSION_ELEMENT (GADGET_ID_DRAWING_AREA_FIRST + 21)
-#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 22)
-#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 23)
-#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 24)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 25)
-#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 26)
-#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 27)
-#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 28)
-#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 29)
-#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 30)
+#define GADGET_ID_INVENTORY_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 22)
+#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 23)
+#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 24)
+#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 25)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 26)
+#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 27)
+#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 28)
+#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 29)
+#define GADGET_ID_CUSTOM_CHANGE_ACTION (GADGET_ID_DRAWING_AREA_FIRST + 30)
+#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 31)
+#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 32)
/* text input identifiers */
-#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 31)
+#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 33)
#define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0)
#define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1)
/* textbutton identifiers */
#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 29)
-#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0)
-#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1)
-#define GADGET_ID_PROPERTIES_CONFIG_1 (GADGET_ID_TEXTBUTTON_FIRST + 2)
-#define GADGET_ID_PROPERTIES_CONFIG_2 (GADGET_ID_TEXTBUTTON_FIRST + 3)
-#define GADGET_ID_PROPERTIES_CHANGE (GADGET_ID_TEXTBUTTON_FIRST + 4)
-#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 5)
-#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 6)
-#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 7)
+#define GADGET_ID_LEVELINFO_LEVEL (GADGET_ID_TEXTBUTTON_FIRST + 0)
+#define GADGET_ID_LEVELINFO_EDITOR (GADGET_ID_TEXTBUTTON_FIRST + 1)
+#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 2)
+#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 3)
+#define GADGET_ID_PROPERTIES_CONFIG_1 (GADGET_ID_TEXTBUTTON_FIRST + 4)
+#define GADGET_ID_PROPERTIES_CONFIG_2 (GADGET_ID_TEXTBUTTON_FIRST + 5)
+#define GADGET_ID_PROPERTIES_CHANGE (GADGET_ID_TEXTBUTTON_FIRST + 6)
+#define GADGET_ID_SAVE_AS_TEMPLATE_1 (GADGET_ID_TEXTBUTTON_FIRST + 7)
+#define GADGET_ID_SAVE_AS_TEMPLATE_2 (GADGET_ID_TEXTBUTTON_FIRST + 8)
+#define GADGET_ID_ADD_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 9)
+#define GADGET_ID_DEL_CHANGE_PAGE (GADGET_ID_TEXTBUTTON_FIRST + 10)
/* graphicbutton identifiers */
-#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 8)
+#define GADGET_ID_GRAPHICBUTTON_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 11)
#define GADGET_ID_PREV_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 0)
#define GADGET_ID_NEXT_CHANGE_PAGE (GADGET_ID_GRAPHICBUTTON_FIRST + 1)
#define GADGET_ID_RANDOM_RESTRICTED (GADGET_ID_CHECKBUTTON_FIRST + 2)
#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 3)
#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 4)
-#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 5)
-#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6)
-#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 7)
-#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 8)
-#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 9)
-#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 10)
-#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 11)
-#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 12)
-#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13)
-#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 14)
-#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 15)
-#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 16)
-#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 17)
-#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 18)
-#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 19)
-#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 20)
-#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 21)
-#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 22)
-#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 23)
-#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 24)
-#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 25)
-#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 26)
-#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 27)
-#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 28)
-#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 29)
-#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 30)
-#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 31)
-#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 32)
-#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 33)
-#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 34)
-#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 35)
-#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 36)
-#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 37)
-#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 38)
-#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 39)
-#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 40)
-#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 41)
-#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 42)
-#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 43)
-#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 44)
-#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 45)
-#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 46)
-#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 47)
-#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 48)
-#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 49)
+#define GADGET_ID_EM_EXPLODES_BY_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 5)
+#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6)
+#define GADGET_ID_USE_TIME_ORB_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7)
+#define GADGET_ID_RANDOM_BALL_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_INITIAL_BALL_STATE (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_AUTO_EXIT_SOKOBAN (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CONTINUOUS_SNAPPING (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_BLOCK_SNAP_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 16)
+#define GADGET_ID_SHIFTED_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 17)
+#define GADGET_ID_LAZY_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 18)
+#define GADGET_ID_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 19)
+#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 20)
+#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 27)
+#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 28)
+#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 30)
+#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 31)
+#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 32)
+#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 33)
+#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 34)
+#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 35)
+#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 36)
+#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 37)
+#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 38)
+#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 39)
+#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 40)
+#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 41)
+#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 42)
+#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 43)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 44)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE_1 (GADGET_ID_CHECKBUTTON_FIRST + 45)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE_2 (GADGET_ID_CHECKBUTTON_FIRST + 46)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE_3 (GADGET_ID_CHECKBUTTON_FIRST + 47)
+#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 48)
+#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 49)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 50)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 51)
+#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 52)
+#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 53)
+#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 54)
+#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 55)
+#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 56)
/* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 50)
+#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 57)
#define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \
ED_NUM_ELEMENTLIST_BUTTONS - 1)
#define ED_COUNTER_ID_LEVEL_GEMSLIMIT 3
#define ED_COUNTER_ID_LEVEL_TIMELIMIT 4
#define ED_COUNTER_ID_LEVEL_TIMESCORE 5
-#define ED_COUNTER_ID_LEVEL_RANDOM 6
-#define ED_COUNTER_ID_ELEMENT_VALUE1 7
-#define ED_COUNTER_ID_ELEMENT_VALUE2 8
-#define ED_COUNTER_ID_ELEMENT_VALUE3 9
-#define ED_COUNTER_ID_ELEMENT_VALUE4 10
-#define ED_COUNTER_ID_YAMYAM_CONTENT 11
-#define ED_COUNTER_ID_BALL_CONTENT 12
-#define ED_COUNTER_ID_ANDROID_CONTENT 13
-#define ED_COUNTER_ID_ENVELOPE_XSIZE 14
-#define ED_COUNTER_ID_ENVELOPE_YSIZE 15
-#define ED_COUNTER_ID_CUSTOM_SCORE 16
-#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 17
-#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 18
-#define ED_COUNTER_ID_CUSTOM_VALUE_RND 19
-#define ED_COUNTER_ID_PUSH_DELAY_FIX 20
-#define ED_COUNTER_ID_PUSH_DELAY_RND 21
-#define ED_COUNTER_ID_DROP_DELAY_FIX 22
-#define ED_COUNTER_ID_DROP_DELAY_RND 23
-#define ED_COUNTER_ID_MOVE_DELAY_FIX 24
-#define ED_COUNTER_ID_MOVE_DELAY_RND 25
-#define ED_COUNTER_ID_EXPLOSION_DELAY 26
-#define ED_COUNTER_ID_IGNITION_DELAY 27
-#define ED_COUNTER_ID_GROUP_CONTENT 28
-#define ED_COUNTER_ID_CHANGE_DELAY_FIX 29
-#define ED_COUNTER_ID_CHANGE_DELAY_RND 30
-#define ED_COUNTER_ID_CHANGE_CONT_RND 31
-
-#define ED_NUM_COUNTERBUTTONS 32
+#define ED_COUNTER_ID_LEVEL_RANDOM_SEED 6
+#define ED_COUNTER_ID_LEVEL_RANDOM 7
+#define ED_COUNTER_ID_ELEMENT_VALUE1 8
+#define ED_COUNTER_ID_ELEMENT_VALUE2 9
+#define ED_COUNTER_ID_ELEMENT_VALUE3 10
+#define ED_COUNTER_ID_ELEMENT_VALUE4 11
+#define ED_COUNTER_ID_YAMYAM_CONTENT 12
+#define ED_COUNTER_ID_BALL_CONTENT 13
+#define ED_COUNTER_ID_ANDROID_CONTENT 14
+#define ED_COUNTER_ID_ENVELOPE_XSIZE 15
+#define ED_COUNTER_ID_ENVELOPE_YSIZE 16
+#define ED_COUNTER_ID_INVENTORY_SIZE 17
+#define ED_COUNTER_ID_CUSTOM_SCORE 18
+#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 19
+#define ED_COUNTER_ID_CUSTOM_VALUE_FIX 20
+#define ED_COUNTER_ID_CUSTOM_VALUE_RND 21
+#define ED_COUNTER_ID_PUSH_DELAY_FIX 22
+#define ED_COUNTER_ID_PUSH_DELAY_RND 23
+#define ED_COUNTER_ID_DROP_DELAY_FIX 24
+#define ED_COUNTER_ID_DROP_DELAY_RND 25
+#define ED_COUNTER_ID_MOVE_DELAY_FIX 26
+#define ED_COUNTER_ID_MOVE_DELAY_RND 27
+#define ED_COUNTER_ID_EXPLOSION_DELAY 28
+#define ED_COUNTER_ID_IGNITION_DELAY 29
+#define ED_COUNTER_ID_GROUP_CONTENT 30
+#define ED_COUNTER_ID_CHANGE_DELAY_FIX 31
+#define ED_COUNTER_ID_CHANGE_DELAY_RND 32
+#define ED_COUNTER_ID_CHANGE_CONT_RND 33
+
+#define ED_NUM_COUNTERBUTTONS 34
#define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE
-#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM
+#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM_SEED
+#define ED_COUNTER_ID_EDITOR_FIRST ED_COUNTER_ID_LEVEL_RANDOM
+#define ED_COUNTER_ID_EDITOR_LAST ED_COUNTER_ID_LEVEL_RANDOM
#define ED_COUNTER_ID_CUSTOM1_FIRST ED_COUNTER_ID_CUSTOM_SCORE
#define ED_COUNTER_ID_CUSTOM1_LAST ED_COUNTER_ID_DROP_DELAY_RND
#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_SELECT_CHANGE_PAGE
/* values for textbutton gadgets */
-#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 1
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1 2
-#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2 3
-#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE 4
-#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 5
-#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 6
-#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 7
-
-#define ED_NUM_TEXTBUTTONS 8
-
-#define ED_TEXTBUTTON_ID_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO
-#define ED_TEXTBUTTON_ID_PROPERTIES_LAST ED_TEXTBUTTON_ID_PROPERTIES_CHANGE
+#define ED_TEXTBUTTON_ID_LEVELINFO_LEVEL 0
+#define ED_TEXTBUTTON_ID_LEVELINFO_EDITOR 1
+#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 2
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 3
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1 4
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2 5
+#define ED_TEXTBUTTON_ID_PROPERTIES_CHANGE 6
+#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2 7
+#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1 8
+#define ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE 9
+#define ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE 10
+
+#define ED_NUM_TEXTBUTTONS 11
+
+#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_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO
+#define ED_TAB_BUTTON_ID_PROPERTIES_LAST ED_TEXTBUTTON_ID_PROPERTIES_CHANGE
#define ED_TEXTBUTTON_ID_CHANGE_FIRST ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE
#define ED_TEXTBUTTON_ID_CHANGE_LAST ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE
/* values for checkbutton gadgets */
#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 0
-#define ED_CHECKBUTTON_ID_STICK_ELEMENT 1
-#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 2
-#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 3
-#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 4
-#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 5
-#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 6
-#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 7
-#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 8
-#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 9
-#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 10
-#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 11
-#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 12
-#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 13
-#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 14
-#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 15
-#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 16
-#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 17
-#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 18
-#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 19
-#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 20
-#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 21
-#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 22
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 23
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 24
-#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 25
-#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 26
-#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 27
-#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 28
-#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 29
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 30
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 31
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 32
-#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 33
-#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 34
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 35
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 36
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 37
-#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 38
-#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 39
-#define ED_CHECKBUTTON_ID_CHANGE_DELAY 40
-#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 41
-#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 42
-#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 43
-#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 44
-#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 45
-#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 46
-#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 47
-
-#define ED_NUM_CHECKBUTTONS 48
-
-#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
-#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3 1
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 2
+#define ED_CHECKBUTTON_ID_STICK_ELEMENT 3
+#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4
+#define ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE 5
+#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 6
+#define ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG 7
+#define ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT 8
+#define ED_CHECKBUTTON_ID_INITIAL_BALL_STATE 9
+#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 10
+#define ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN 11
+#define ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING 12
+#define ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD 13
+#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 14
+#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 15
+#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 16
+#define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 17
+#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 18
+#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 19
+#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 20
+#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 21
+#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 22
+#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 23
+#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 24
+#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 25
+#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 26
+#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 27
+#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 28
+#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 29
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 30
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 31
+#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 32
+#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 33
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 34
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 35
+#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 36
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 37
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 38
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 39
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 40
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 41
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 42
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 43
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 44
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 45
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 46
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY 47
+#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 48
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 49
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 50
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 51
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 52
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 53
+#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 54
+
+#define ED_NUM_CHECKBUTTONS 55
+
+#define ED_CHECKBUTTON_ID_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
+#define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2
#define ED_CHECKBUTTON_ID_CUSTOM1_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC
#define ED_CHECKBUTTON_ID_CUSTOM1_LAST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE
#define ED_NUM_RADIOBUTTONS 2
-#define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE
-#define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY
+#define ED_RADIOBUTTON_ID_EDITOR_FIRST ED_RADIOBUTTON_ID_PERCENTAGE
+#define ED_RADIOBUTTON_ID_EDITOR_LAST ED_RADIOBUTTON_ID_QUANTITY
/* values for drawing area gadgets */
#define ED_DRAWING_ID_DRAWING_LEVEL 0
#define ED_DRAWING_ID_START_ELEMENT 19
#define ED_DRAWING_ID_ARTWORK_ELEMENT 20
#define ED_DRAWING_ID_EXPLOSION_ELEMENT 21
-#define ED_DRAWING_ID_CUSTOM_GRAPHIC 22
-#define ED_DRAWING_ID_CUSTOM_CONTENT 23
-#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 24
-#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 25
-#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 26
-#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 27
-#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 28
-#define ED_DRAWING_ID_GROUP_CONTENT 29
-#define ED_DRAWING_ID_RANDOM_BACKGROUND 30
+#define ED_DRAWING_ID_INVENTORY_CONTENT 22
+#define ED_DRAWING_ID_CUSTOM_GRAPHIC 23
+#define ED_DRAWING_ID_CUSTOM_CONTENT 24
+#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 25
+#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 26
+#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 27
+#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 28
+#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 29
+#define ED_DRAWING_ID_CUSTOM_CHANGE_ACTION 30
+#define ED_DRAWING_ID_GROUP_CONTENT 31
+#define ED_DRAWING_ID_RANDOM_BACKGROUND 32
-#define ED_NUM_DRAWING_AREAS 31
+#define ED_NUM_DRAWING_AREAS 33
+
+#define ED_DRAWING_ID_EDITOR_FIRST ED_DRAWING_ID_RANDOM_BACKGROUND
+#define ED_DRAWING_ID_EDITOR_LAST ED_DRAWING_ID_RANDOM_BACKGROUND
/*
#define ED_MODE_DRAWING 0
#define ED_MODE_INFO 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_EDITOR ED_TEXTBUTTON_ID_LEVELINFO_EDITOR
/* sub-screens in the element properties section */
#define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO
#define ED_MODE_PROPERTIES_CHANGE ED_TEXTBUTTON_ID_PROPERTIES_CHANGE
/* how many steps can be cancelled */
-#define NUM_UNDO_STEPS (10 + 1)
+#define NUM_UNDO_STEPS (64 + 1)
/* values for elements with score for certain actions */
#define MIN_SCORE 0
-#define MAX_SCORE 255
+#define MAX_SCORE 999
/* values for elements with count for collecting */
#define MIN_COLLECT_COUNT 0
-#define MAX_COLLECT_COUNT 255
+#define MAX_COLLECT_COUNT 999
/* values for random placement */
#define RANDOM_USE_PERCENTAGE 0
#define RANDOM_USE_QUANTITY 1
-/* maximal size of level editor drawing area */
-#define MAX_ED_FIELDX (2 * SCR_FIELDX)
-#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1)
+/* default value for element tile size in drawing area */
+#define DEFAULT_EDITOR_TILESIZE MINI_TILESIZE
/*
static struct
{
+ int graphic;
+ int gadget_id;
+ struct XYTileSize *pos;
+ int gadget_type;
+ char *infotext;
char shortcut;
- char *text;
-} control_info[ED_NUM_CTRL_BUTTONS] =
+} controlbutton_info[ED_NUM_CTRL_BUTTONS] =
{
/* note: some additional characters are already reserved for "cheat mode"
shortcuts (":XYZ" style) -- for details, see "events.c" */
- { 's', "draw single items" },
- { 'd', "draw connected items" },
- { 'l', "draw lines" },
- { 'a', "draw arcs" },
- { 'r', "draw outline rectangles" },
- { 'R', "draw filled rectangles" },
- { '\0', "wrap (rotate) level up" },
- { 't', "enter text elements" },
- { 'f', "flood fill" },
- { '\0', "wrap (rotate) level left" },
- { '?', "properties of drawing element" },
- { '\0', "wrap (rotate) level right" },
- { '\0', "random element placement" },
- { 'b', "grab brush" },
- { '\0', "wrap (rotate) level down" },
- { ',', "pick drawing element" },
-
- { 'U', "undo last operation" },
- { 'I', "level properties" },
- { 'S', "save level" },
- { 'C', "clear level" },
- { 'T', "test level" },
- { 'E', "exit level editor" },
-
- { '\0', "copy settings from other element" },
- { '\0', "copy settings to other element" },
- { '\0', "exchange element with other element" },
-
- { '\0', "copy settings from this element" },
- { '\0', "paste settings to this element" },
+ /* ---------- toolbox control buttons ------------------------------------ */
+
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_SINGLE, GADGET_ID_SINGLE_ITEMS,
+ &editor.button.draw_single, GD_TYPE_RADIO_BUTTON,
+ "draw single items", 's'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_CONNECTED, GADGET_ID_CONNECTED_ITEMS,
+ &editor.button.draw_connected, GD_TYPE_RADIO_BUTTON,
+ "draw connected items", 'd'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_LINE, GADGET_ID_LINE,
+ &editor.button.draw_line, GD_TYPE_RADIO_BUTTON,
+ "draw lines", 'l'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_ARC, GADGET_ID_ARC,
+ &editor.button.draw_arc, GD_TYPE_RADIO_BUTTON,
+ "draw arcs", 'a'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_RECTANGLE, GADGET_ID_RECTANGLE,
+ &editor.button.draw_rectangle, GD_TYPE_RADIO_BUTTON,
+ "draw outline rectangles", 'r'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_FILLED_BOX, GADGET_ID_FILLED_BOX,
+ &editor.button.draw_filled_box, GD_TYPE_RADIO_BUTTON,
+ "draw filled rectangles", 'R'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ROTATE_UP, GADGET_ID_WRAP_UP,
+ &editor.button.rotate_up, GD_TYPE_NORMAL_BUTTON,
+ "wrap (rotate) level up", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_TEXT, GADGET_ID_TEXT,
+ &editor.button.draw_text, GD_TYPE_RADIO_BUTTON,
+ "enter text elements", 't'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_FLOOD_FILL, GADGET_ID_FLOOD_FILL,
+ &editor.button.flood_fill, GD_TYPE_RADIO_BUTTON,
+ "flood fill", 'f'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ROTATE_LEFT, GADGET_ID_WRAP_LEFT,
+ &editor.button.rotate_left, GD_TYPE_NORMAL_BUTTON,
+ "wrap (rotate) level left", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ZOOM_LEVEL, GADGET_ID_ZOOM,
+ &editor.button.zoom_level, GD_TYPE_NORMAL_BUTTON,
+ "zoom level tile size", '+'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ROTATE_RIGHT, GADGET_ID_WRAP_RIGHT,
+ &editor.button.rotate_right, GD_TYPE_NORMAL_BUTTON,
+ "wrap (rotate) level right", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_DRAW_RANDOM, GADGET_ID_RANDOM_PLACEMENT,
+ &editor.button.draw_random, GD_TYPE_NORMAL_BUTTON,
+ "random element placement", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_GRAB_BRUSH, GADGET_ID_GRAB_BRUSH,
+ &editor.button.grab_brush, GD_TYPE_RADIO_BUTTON,
+ "grab brush", 'b'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ROTATE_DOWN, GADGET_ID_WRAP_DOWN,
+ &editor.button.rotate_down, GD_TYPE_NORMAL_BUTTON,
+ "wrap (rotate) level down", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_PICK_ELEMENT, GADGET_ID_PICK_ELEMENT,
+ &editor.button.pick_element, GD_TYPE_RADIO_BUTTON,
+ "pick drawing element", ','
+ },
+
+ /* ---------- level control buttons -------------------------------------- */
+
+ {
+ IMG_GFX_EDITOR_BUTTON_UNDO, GADGET_ID_UNDO,
+ &editor.button.undo, GD_TYPE_NORMAL_BUTTON,
+ "undo/redo last operation", 'u'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CONF, GADGET_ID_INFO,
+ &editor.button.conf, GD_TYPE_NORMAL_BUTTON,
+ "properties of level", 'I'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_SAVE, GADGET_ID_SAVE,
+ &editor.button.save, GD_TYPE_NORMAL_BUTTON,
+ "save level", 'S'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CLEAR, GADGET_ID_CLEAR,
+ &editor.button.clear, GD_TYPE_NORMAL_BUTTON,
+ "clear level", 'C'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_TEST, GADGET_ID_TEST,
+ &editor.button.test, GD_TYPE_NORMAL_BUTTON,
+ "test level", 'T'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_EXIT, GADGET_ID_EXIT,
+ &editor.button.exit, GD_TYPE_NORMAL_BUTTON,
+ "exit level editor", 'E'
+ },
+
+ /* ---------- CE and GE control buttons ---------------------------------- */
+
+ {
+ IMG_GFX_EDITOR_BUTTON_CE_COPY_FROM, GADGET_ID_CUSTOM_COPY_FROM,
+ &editor.button.ce_copy_from, GD_TYPE_RADIO_BUTTON,
+ "copy settings from other element", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CE_COPY_TO, GADGET_ID_CUSTOM_COPY_TO,
+ &editor.button.ce_copy_to, GD_TYPE_RADIO_BUTTON,
+ "copy settings to other element", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CE_SWAP, GADGET_ID_CUSTOM_EXCHANGE,
+ &editor.button.ce_swap, GD_TYPE_RADIO_BUTTON,
+ "exchange element with other element", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CE_COPY, GADGET_ID_CUSTOM_COPY,
+ &editor.button.ce_copy, GD_TYPE_NORMAL_BUTTON,
+ "copy settings from this element", 0
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_CE_PASTE, GADGET_ID_CUSTOM_PASTE,
+ &editor.button.ce_paste, GD_TYPE_NORMAL_BUTTON,
+ "paste settings to this element", 0
+ },
+
+ /* ---------- palette control buttons ------------------------------------ */
+
+ {
+ IMG_GFX_EDITOR_BUTTON_PROPERTIES, GADGET_ID_PROPERTIES,
+ &editor.button.properties, GD_TYPE_NORMAL_BUTTON,
+ "properties of drawing element", 'p'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ELEMENT_LEFT, GADGET_ID_ELEMENT_LEFT,
+ &editor.button.element_left, GD_TYPE_NORMAL_BUTTON,
+ "properties of drawing element 1", '1'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ELEMENT_MIDDLE, GADGET_ID_ELEMENT_MIDDLE,
+ &editor.button.element_middle, GD_TYPE_NORMAL_BUTTON,
+ "properties of drawing element 2", '2'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_ELEMENT_RIGHT, GADGET_ID_ELEMENT_RIGHT,
+ &editor.button.element_right, GD_TYPE_NORMAL_BUTTON,
+ "properties of drawing element 3", '3'
+ },
+ {
+ IMG_GFX_EDITOR_BUTTON_PALETTE, GADGET_ID_PALETTE,
+ &editor.button.palette, GD_TYPE_NORMAL_BUTTON,
+ "show list of elements", 'e'
+ }
};
static int random_placement_value = 10;
/* ---------- current level number --------------------------------------- */
{
- DX + 5 - SX, DY + 3 - SY,
+ -1, -1, /* these values are not constant, but can change at runtime */
1, 100,
GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP,
GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE,
GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP,
GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE,
&level.gems_needed,
- NULL, "number of gems to collect:", NULL
+ NULL, "number of gems to collect:", NULL
},
{
ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7),
},
{
ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(9),
- 0, 255,
+ 0, 999,
GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP,
GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE,
&level.score[SC_TIME_BONUS],
"score for each second/step left:", NULL, NULL
},
{
- ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12),
+ 0, 9999,
+ GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP,
+ GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE,
+ &level.random_seed,
+ NULL, "random seed:", "(0 => random)"
+ },
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0),
1, 100,
GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP,
GADGET_ID_LEVEL_RANDOM_TEXT, GADGET_ID_NONE,
NULL, /* will be set when used */
NULL, " ", "height",
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
+ MIN_INITIAL_INVENTORY_SIZE, MAX_INITIAL_INVENTORY_SIZE,
+ GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_UP,
+ GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_NONE,
+ &level.initial_inventory_size[0],
+ NULL, NULL, "number of inventory elements"
+ },
/* ---------- element settings: configure 1 (custom elements) ------------ */
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
MIN_SCORE, MAX_SCORE,
GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP,
GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE,
NULL, "CE score", " "
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(6),
+ -1, ED_ELEMENT_SETTINGS_YPOS(5),
MIN_COLLECT_COUNT, MAX_COLLECT_COUNT,
GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP,
GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP,
NULL, "CE count", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
0, 9999,
GADGET_ID_CUSTOM_VALUE_FIX_DOWN, GADGET_ID_CUSTOM_VALUE_FIX_UP,
GADGET_ID_CUSTOM_VALUE_FIX_TEXT, GADGET_ID_NONE,
NULL, "CE value", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
0, 9999,
GADGET_ID_CUSTOM_VALUE_RND_DOWN, GADGET_ID_CUSTOM_VALUE_RND_UP,
GADGET_ID_CUSTOM_VALUE_RND_TEXT, GADGET_ID_CUSTOM_VALUE_FIX_UP,
NULL, "+random", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7),
- 0, 255,
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6),
+ 0, 999,
GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP,
GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE,
&custom_element.push_delay_fixed,
NULL, "push delay", NULL
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(7),
- 0, 255,
+ -1, ED_ELEMENT_SETTINGS_YPOS(6),
+ 0, 999,
GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP,
GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP,
&custom_element.push_delay_random,
NULL, "+random", NULL
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
- 0, 255,
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7),
+ 0, 999,
GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP,
GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE,
&custom_element.drop_delay_fixed,
NULL, "drop delay", NULL
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(8),
- 0, 255,
+ -1, ED_ELEMENT_SETTINGS_YPOS(7),
+ 0, 999,
GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP,
GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP,
&custom_element.drop_delay_random,
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12),
- 0, 255,
+ 0, 999,
GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP,
GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE,
&custom_element.explosion_delay,
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
- 0, 255,
+ 0, 999,
GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP,
GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE,
&custom_element.ignition_delay,
/* ---------- element settings: configure (group elements) --------------- */
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP,
GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP,
GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE,
"Author:", "Author"
},
{
- 5 * MINI_TILEX - 2, 5 * MINI_TILEY - ED_BORDER_SIZE + 1,
+ -1, -1, /* these values are not constant, but can change at runtime */
GADGET_ID_ELEMENT_NAME,
MAX_ELEMENT_NAME_LEN - 2, /* currently 2 chars less editable */
custom_element.description,
{
{ GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" },
{ GAME_ENGINE_TYPE_EM, "Emerald Mine" },
+ { GAME_ENGINE_TYPE_SP, "Supaplex" },
+ { GAME_ENGINE_TYPE_MM, "Mirror Magic" },
{ -1, NULL }
};
{
{ EP_DONT_RUN_INTO, "running into" },
{ EP_DONT_COLLIDE_WITH, "colliding with" },
+ { EP_DONT_GET_HIT_BY, "getting hit by" },
{ EP_DONT_TOUCH, "touching" },
{ -1, NULL }
{
{ CA_NO_ACTION, "no action" },
{ CA_UNDEFINED, " " },
- { CA_HEADLINE_LEVEL_ACTIONS, "[level actions]" },
+ { CA_HEADLINE_LEVEL_ACTIONS, "[level]" },
{ CA_RESTART_LEVEL, "restart level" },
{ CA_SHOW_ENVELOPE, "show envelope" },
{ CA_SET_LEVEL_TIME, "set time" },
{ CA_SET_LEVEL_SCORE, "set score" },
- { CA_SET_LEVEL_GEMS, "set needed gems" },
+ { CA_SET_LEVEL_GEMS, "set gems" },
{ CA_SET_LEVEL_WIND, "set wind dir." },
+ { CA_SET_LEVEL_RANDOM_SEED, "set rand. seed" },
{ CA_UNDEFINED, " " },
- { CA_HEADLINE_PLAYER_ACTIONS, "[player actions]" },
+ { CA_HEADLINE_PLAYER_ACTIONS, "[player]" },
{ CA_MOVE_PLAYER, "move player" },
{ CA_EXIT_PLAYER, "exit player" },
{ CA_KILL_PLAYER, "kill player" },
{ CA_SET_PLAYER_SHIELD, "set shield" },
{ CA_SET_PLAYER_GRAVITY, "set gravity" },
{ CA_SET_PLAYER_ARTWORK, "set artwork" },
+ { CA_SET_PLAYER_INVENTORY, "set inventory" },
{ CA_UNDEFINED, " " },
- { CA_HEADLINE_CE_ACTIONS, "[CE actions]" },
+ { CA_HEADLINE_CE_ACTIONS, "[CE]" },
{ CA_SET_CE_VALUE, "set CE value" },
{ CA_SET_CE_SCORE, "set CE score" },
+ { CA_SET_CE_ARTWORK, "set CE artwork" },
{ CA_UNDEFINED, " " },
- { CA_HEADLINE_ENGINE_ACTIONS, "[engine actions]" },
+ { CA_HEADLINE_ENGINE_ACTIONS, "[engine]" },
{ CA_SET_ENGINE_SCAN_MODE, "set scan mode" },
{ -1, NULL }
{ CA_ARG_PLAYER_4, "4" },
{ CA_ARG_PLAYER_ANY, "any" },
{ CA_ARG_PLAYER_TRIGGER, "trigger" },
+ { CA_ARG_PLAYER_ACTION, "action ->" },
{ -1, NULL }
};
{ CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" },
{ CA_ARG_ELEMENT_CV_TARGET, "target" },
{ CA_ARG_ELEMENT_CV_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_CV_ACTION, "action ->" },
{ CA_ARG_UNDEFINED, " " },
{ CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" },
{ CA_ARG_ELEMENT_CS_TARGET, "target" },
{ CA_ARG_ELEMENT_CS_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_CS_ACTION, "action ->" },
{ -1, NULL }
};
{ CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" },
{ CA_ARG_ELEMENT_CV_TARGET, "target" },
{ CA_ARG_ELEMENT_CV_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_CV_ACTION, "action ->" },
{ CA_ARG_UNDEFINED, " " },
{ CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" },
{ CA_ARG_ELEMENT_CS_TARGET, "target" },
{ CA_ARG_ELEMENT_CS_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_CS_ACTION, "action ->" },
{ CA_ARG_UNDEFINED, " " },
{ CA_ARG_ELEMENT_NR_HEADLINE, "[element]" },
{ CA_ARG_ELEMENT_NR_TARGET, "target" },
{ CA_ARG_ELEMENT_NR_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_NR_ACTION, "action ->" },
{ -1, NULL }
};
{ CA_ARG_ELEMENT_HEADLINE, "[element]" },
{ CA_ARG_ELEMENT_TARGET, "target" },
{ CA_ARG_ELEMENT_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_ACTION, "action ->" },
{ -1, NULL }
};
{ CA_ARG_ELEMENT_HEADLINE, "[element]" },
{ CA_ARG_ELEMENT_TARGET, "target" },
{ CA_ARG_ELEMENT_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_ACTION, "action ->" },
{ -1, NULL }
};
{ CA_ARG_ELEMENT_HEADLINE, "[element]" },
{ CA_ARG_ELEMENT_TARGET, "target" },
{ CA_ARG_ELEMENT_TRIGGER, "trigger" },
+ { CA_ARG_ELEMENT_ACTION, "action ->" },
{ CA_ARG_UNDEFINED, " " },
{ CA_ARG_ELEMENT_RESET, "reset" },
{ -1, NULL }
};
+static struct ValueTextInfo options_action_arg_inventory[] =
+{
+ { CA_ARG_INVENTORY_HEADLINE, "[add]" },
+ { CA_ARG_ELEMENT_TARGET, "+ target" },
+ { CA_ARG_ELEMENT_TRIGGER, "+ trigger" },
+ { CA_ARG_ELEMENT_ACTION, "+ action" },
+ { CA_ARG_UNDEFINED, " " },
+ { CA_ARG_INVENTORY_RM_HEADLINE,"[remove]" },
+ { CA_ARG_INVENTORY_RM_TARGET, "- target" },
+ { CA_ARG_INVENTORY_RM_TRIGGER,"- trigger" },
+ { CA_ARG_INVENTORY_RM_ACTION, "- action" },
+ { CA_ARG_INVENTORY_RM_FIRST, "- first" },
+ { CA_ARG_INVENTORY_RM_LAST, "- last" },
+ { CA_ARG_INVENTORY_RM_ALL, "- all" },
+ { CA_ARG_UNDEFINED, " " },
+ { CA_ARG_INVENTORY_RESET, "reset" },
+
+ { -1, NULL }
+};
+
static char options_change_page_strings[MAX_CHANGE_PAGES][10];
static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] =
{
{ CA_SET_LEVEL_GEMS, 3, options_action_arg_number, },
{ CA_SET_LEVEL_SCORE, 3, options_action_arg_number, },
{ CA_SET_LEVEL_WIND, 1, options_action_arg_direction, },
+ { CA_SET_LEVEL_RANDOM_SEED, 1, options_action_arg_number, },
{ CA_SET_PLAYER_KEYS, 2, options_action_arg_key, },
{ CA_SET_PLAYER_SPEED, 1, options_action_arg_speed, },
{ CA_SET_PLAYER_SHIELD, 1, options_action_arg_shield, },
{ CA_SET_PLAYER_GRAVITY, 1, options_action_arg_gravity, },
{ CA_SET_PLAYER_ARTWORK, 1, options_action_arg_artwork, },
+ { CA_SET_PLAYER_INVENTORY, 0, options_action_arg_inventory, },
{ CA_SET_CE_VALUE, 3, options_action_arg_value, },
{ CA_SET_CE_SCORE, 3, options_action_arg_value, },
+ { CA_SET_CE_ARTWORK, 1, options_action_arg_artwork, },
{ CA_SET_ENGINE_SCAN_MODE, 1, options_action_arg_scan_mode, },
{ -1, FALSE, NULL }
/* ---------- element settings: configure (several elements) ------------- */
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE,
-1,
options_player_speed,
/* ---------- element settings: configure 1 (custom elements) ------------ */
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE,
-1,
options_access_type,
NULL, NULL, "type of access to this field"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(3),
+ -1, ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE,
-1,
options_access_layer,
NULL, NULL, "layer of access for this field"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(3),
+ -1, ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_ACCESS_PROTECTED, GADGET_ID_CUSTOM_ACCESS_LAYER,
-1,
options_access_protected,
NULL, NULL, "protected access for this field"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_ACCESS_DIRECTION, GADGET_ID_NONE,
-1,
options_access_direction,
"from", NULL, "access direction for this field"
},
{
- ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE,
-1,
options_walk_to_action,
-1,
options_move_leave_type,
&custom_element.move_leave_type,
- "can dig: can", ":", "leave behind or change element"
+ // left text with leading spaces to place gadget next to "can dig" gadget
+ // (needed because drawing area gadgets created after selectbox gadgets)
+ // "can dig: can", ":", "leave behind or change element"
+ " can", ":", "leave behind or change element"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(7),
/* ---------- element settings: configure (group elements) --------------- */
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_GROUP_CHOICE_MODE, GADGET_ID_NONE,
-1,
options_group_choice_mode,
int gadget_id_align;
int size;
char *text;
- char *text_left, *text_right, *infotext;
+ char *text_above, *text_left, *text_right, *infotext;
} textbutton_info[ED_NUM_TEXTBUTTONS] =
{
+ /* ---------- level and editor settings (tabs) --------------------------- */
+
+ {
+ ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0),
+ GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE,
+ 8, "Level",
+ NULL, NULL, NULL, "Configure level properties"
+ },
+ {
+ -1, -1,
+ GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_LEVELINFO_LEVEL,
+ 8, "Editor",
+ NULL, NULL, NULL, "Configure editor properties"
+ },
+
+ /* ---------- element settings (tabs) ------------------------------------ */
+
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
+ ED_ELEMENT_TABS_XPOS(0), ED_ELEMENT_TABS_YPOS(0),
GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE,
8, "Info",
- NULL, NULL, "Show information about element"
+ NULL, NULL, NULL, "Show information about element"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
- GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE,
+ -1, -1,
+ GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_INFO,
8, "Config",
- NULL, NULL, "Configure element properties"
+ NULL, NULL, NULL, "Configure element properties"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
- GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_NONE,
+ -1, -1,
+ GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_PROPERTIES_INFO,
8, "Config 1",
- NULL, NULL, "Configure custom element properties"
+ NULL, NULL, NULL, "Configure element properties, part 1"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0) + 248, ED_COUNTER_YPOS(1),
- GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_NONE,
+ -1, -1,
+ GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_PROPERTIES_CONFIG_1,
8, "Config 2",
- NULL, NULL, "Configure custom element properties"
+ NULL, NULL, NULL, "Configure element properties, part 2"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0) + 372, ED_COUNTER_YPOS(1),
- GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE,
+ -1, -1,
+ GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_PROPERTIES_CONFIG_2,
8, "Change",
- NULL, NULL, "Custom element change configuration"
+ NULL, NULL, NULL, "Configure custom element change pages"
+ },
+
+ /* ---------- level and editor settings (buttons) ------------------------ */
+
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6),
+ GADGET_ID_SAVE_AS_TEMPLATE_2, GADGET_ID_NONE,
+ -1, "Save",
+ NULL, NULL, "this level as level template",
+ "Save current settings as new template"
},
+
+ /* ---------- element settings (buttons) --------------------------------- */
+
{
- -1, ED_ELEMENT_SETTINGS_YPOS(2),
- GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE,
+ -1, -1,
+ GADGET_ID_SAVE_AS_TEMPLATE_1, GADGET_ID_CUSTOM_USE_TEMPLATE_1,
-1, "Save",
- " ", "As Template", "Save current settings as new template"
+ NULL, " ", "As Template",
+ "Save current settings as new template"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(14),
+ -1, -1,
GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_PASTE_CHANGE_PAGE,
-1, "New",
- NULL, NULL, "Add new change page"
+ NULL, NULL, NULL, "Add new change page"
},
{
- -1, ED_ELEMENT_SETTINGS_YPOS(14),
+ -1, -1,
GADGET_ID_DEL_CHANGE_PAGE, GADGET_ID_ADD_CHANGE_PAGE,
-1, "Delete",
- NULL, NULL, "Delete current change page"
+ NULL, NULL, NULL, "Delete current change page"
},
};
static struct
{
- int gd_x, gd_y;
+ int graphic;
int x, y;
- int width, height;
int gadget_id;
int gadget_id_align;
char *text_left, *text_right, *infotext;
} graphicbutton_info[ED_NUM_GRAPHICBUTTONS] =
{
{
- ED_BUTTON_MINUS_XPOS, ED_BUTTON_COUNT_YPOS,
+ IMG_EDITOR_COUNTER_DOWN,
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14),
- ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_PREV_CHANGE_PAGE, GADGET_ID_NONE,
NULL, NULL, "select previous change page"
},
{
- ED_BUTTON_PLUS_XPOS, ED_BUTTON_COUNT_YPOS,
+ IMG_EDITOR_COUNTER_UP,
-1, ED_ELEMENT_SETTINGS_YPOS(14),
- ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_NEXT_CHANGE_PAGE, GADGET_ID_SELECT_CHANGE_PAGE,
NULL, "change page", "select next change page"
},
{
- ED_COPY_CHANGE_PAGE_XPOS, ED_COPY_CHANGE_PAGE_YPOS,
+ IMG_GFX_EDITOR_BUTTON_CP_COPY,
-1, ED_ELEMENT_SETTINGS_YPOS(14),
- ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_COPY_CHANGE_PAGE, GADGET_ID_NEXT_CHANGE_PAGE,
" ", NULL, "copy settings from this change page"
},
{
- ED_PASTE_CHANGE_PAGE_XPOS, ED_PASTE_CHANGE_PAGE_YPOS,
+ IMG_GFX_EDITOR_BUTTON_CP_PASTE,
-1, ED_ELEMENT_SETTINGS_YPOS(14),
- ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_PASTE_CHANGE_PAGE, GADGET_ID_COPY_CHANGE_PAGE,
NULL, NULL, "paste settings to this change page"
},
static struct
{
- int gd_x, gd_y;
int x, y;
+} scrollbutton_pos[ED_NUM_SCROLLBUTTONS];
+
+static struct
+{
+ int graphic;
int gadget_id;
char *infotext;
} scrollbutton_info[ED_NUM_SCROLLBUTTONS] =
{
{
- ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 0 * ED_SCROLLBUTTON_YSIZE,
- ED_SCROLL_UP_XPOS, ED_SCROLL_UP_YPOS,
+ IMG_EDITOR_PLAYFIELD_SCROLL_UP,
GADGET_ID_SCROLL_UP,
"scroll level editing area up"
},
{
- ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 1 * ED_SCROLLBUTTON_YSIZE,
- ED_SCROLL_DOWN_XPOS, ED_SCROLL_DOWN_YPOS,
+ IMG_EDITOR_PLAYFIELD_SCROLL_DOWN,
GADGET_ID_SCROLL_DOWN,
"scroll level editing area down"
},
{
- ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 2 * ED_SCROLLBUTTON_YSIZE,
- ED_SCROLL_LEFT_XPOS, ED_SCROLL_LEFT_YPOS,
+ IMG_EDITOR_PLAYFIELD_SCROLL_LEFT,
GADGET_ID_SCROLL_LEFT,
"scroll level editing area left"
},
{
- ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 3 * ED_SCROLLBUTTON_YSIZE,
- ED_SCROLL_RIGHT_XPOS, ED_SCROLL_RIGHT_YPOS,
+ IMG_EDITOR_PLAYFIELD_SCROLL_RIGHT,
GADGET_ID_SCROLL_RIGHT,
"scroll level editing area right"
},
{
- ED_SCROLLBUTTON2_XPOS, ED_SCROLLBUTTON2_YPOS + 0 * ED_SCROLLBUTTON2_YSIZE,
- ED_SCROLL2_UP_XPOS, ED_SCROLL2_UP_YPOS,
+ IMG_EDITOR_PALETTE_SCROLL_UP,
GADGET_ID_SCROLL_LIST_UP,
"scroll element list up ('Page Up')"
},
{
- ED_SCROLLBUTTON2_XPOS, ED_SCROLLBUTTON2_YPOS + 1 * ED_SCROLLBUTTON2_YSIZE,
- ED_SCROLL2_DOWN_XPOS, ED_SCROLL2_DOWN_YPOS,
+ IMG_EDITOR_PALETTE_SCROLL_DOWN,
GADGET_ID_SCROLL_LIST_DOWN,
"scroll element list down ('Page Down')"
},
static struct
{
- int gd_x, gd_y;
int x, y;
int width, height;
int wheel_x, wheel_y;
int wheel_width, wheel_height;
+} scrollbar_pos[ED_NUM_SCROLLBARS];
+
+static struct
+{
+ int graphic;
int type;
int gadget_id;
char *infotext;
} scrollbar_info[ED_NUM_SCROLLBARS] =
{
{
- ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS,
- SX + ED_SCROLL_HORIZONTAL_XPOS, SY + ED_SCROLL_HORIZONTAL_YPOS,
- ED_SCROLL_HORIZONTAL_XSIZE, ED_SCROLL_HORIZONTAL_YSIZE,
-#if 1
- SX, SY,
- SXSIZE, SYSIZE,
-#else
- 0, 0,
- SX + SXSIZE + SX, WIN_YSIZE,
-#endif
+ IMG_EDITOR_PLAYFIELD_SCROLLBAR,
GD_TYPE_SCROLLBAR_HORIZONTAL,
GADGET_ID_SCROLL_HORIZONTAL,
"scroll level editing area horizontally"
},
{
- ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS,
- SX + ED_SCROLL_VERTICAL_XPOS, SY + ED_SCROLL_VERTICAL_YPOS,
- ED_SCROLL_VERTICAL_XSIZE, ED_SCROLL_VERTICAL_YSIZE,
-#if 1
- SX, SY,
- SXSIZE, SYSIZE,
-#else
- 0, 0,
- SX + SXSIZE + SX, WIN_YSIZE,
-#endif
+ IMG_EDITOR_PLAYFIELD_SCROLLBAR,
GD_TYPE_SCROLLBAR_VERTICAL,
GADGET_ID_SCROLL_VERTICAL,
"scroll level editing area vertically"
},
{
- ED_SCROLLBAR2_XPOS, ED_SCROLLBAR2_YPOS,
- DX + ED_SCROLL2_VERTICAL_XPOS, DY + ED_SCROLL2_VERTICAL_YPOS,
- ED_SCROLL2_VERTICAL_XSIZE, ED_SCROLL2_VERTICAL_YSIZE,
-#if 1
- DX, DY,
- DXSIZE, DYSIZE,
-#else
- SX + SXSIZE + SX, 0,
- WIN_XSIZE - (SX + SXSIZE + SX), WIN_YSIZE,
-#endif
+ IMG_EDITOR_PALETTE_SCROLLBAR,
GD_TYPE_SCROLLBAR_VERTICAL,
GADGET_ID_SCROLL_LIST_VERTICAL,
"scroll element list vertically"
}
};
+
static struct
{
int x, y;
} radiobutton_info[ED_NUM_RADIOBUTTONS] =
{
{
- -1, ED_COUNTER2_YPOS(8),
+ -1, ED_LEVEL_SETTINGS_YPOS(0),
GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_LEVEL_RANDOM_UP,
RADIO_NR_RANDOM_ELEMENTS,
&random_placement_method, RANDOM_USE_PERCENTAGE,
" ", "percentage", "use percentage for random elements"
},
{
- -1, ED_COUNTER2_YPOS(8),
+ -1, ED_LEVEL_SETTINGS_YPOS(0),
GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_PERCENTAGE,
RADIO_NR_RANDOM_ELEMENTS,
&random_placement_method, RANDOM_USE_QUANTITY,
int gadget_id;
int gadget_id_align;
boolean *value;
- char *text_left, *text_right, *infotext;
+ char *text_above, *text_left, *text_right, *infotext;
} checkbutton_info[ED_NUM_CHECKBUTTONS] =
{
/* ---------- level and editor settings ---------------------------------- */
{
- ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY,
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(1),
GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE,
&random_placement_background_restricted,
- NULL,
+ NULL, NULL,
"restrict random placement to:", "set random placement restriction"
},
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4),
+ GADGET_ID_CUSTOM_USE_TEMPLATE_3, GADGET_ID_NONE,
+ &setup.editor.use_template_for_new_levels,
+ "Template for new levels and CE/GE:", NULL,
+ "use template for new levels", "use template for level properties"
+ },
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5),
+ GADGET_ID_CUSTOM_USE_TEMPLATE_2, GADGET_ID_NONE,
+ &level.use_custom_template,
+ NULL, NULL,
+ "use template for custom elements", "use template for custom properties"
+ },
/* ---------- element settings: configure (various elements) ------------- */
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_STICK_ELEMENT, GADGET_ID_NONE,
&stick_element_properties_window,
- NULL,
+ NULL, NULL,
"stick this screen to edit content","stick this screen to edit content"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_NONE,
&level.em_slippery_gems,
- NULL,
+ NULL, NULL,
"slip down from certain flat walls","use EM/DC style slipping behaviour"
},
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
+ GADGET_ID_EM_EXPLODES_BY_FIRE, GADGET_ID_NONE,
+ &level.em_explodes_by_fire,
+ NULL, NULL,
+ "explodes with chain reaction", "use R'n'D style explosion behaviour"
+ },
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_USE_SPRING_BUG, GADGET_ID_NONE,
&level.use_spring_bug,
- NULL,
+ NULL, NULL,
"use spring pushing bug", "use odd spring pushing behaviour"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_NONE,
&level.use_time_orb_bug,
- NULL,
+ NULL, NULL,
"use time orb bug", "use odd time orb behaviour"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_RANDOM_BALL_CONTENT, GADGET_ID_NONE,
&level.ball_random,
- NULL,
+ NULL, NULL,
"create single random element", "only create one element from content"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_INITIAL_BALL_STATE, GADGET_ID_NONE,
&level.ball_state_initial,
- NULL,
+ NULL, NULL,
"magic ball initially activated", "activate magic ball after level start"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE,
&level.grow_into_diggable,
- NULL,
+ NULL, NULL,
"can grow into anything diggable", "grow into more than just sand"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
+ GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_NONE,
+ &level.auto_exit_sokoban,
+ NULL, NULL,
+ "exit level if all fields solved", "automatically finish Sokoban levels"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE,
&level.continuous_snapping,
- NULL,
- "continuos snapping", "use snapping without releasing key"
+ NULL, NULL,
+ "continuous snapping", "use snapping without releasing key"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE,
&level.block_snap_field,
- NULL,
+ NULL, NULL,
"block snapped field when snapping", "use snapping delay to show animation"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE,
&level.block_last_field,
- NULL,
+ NULL, NULL,
"block last field when moving", "player blocks last field when moving"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE,
&level.sp_block_last_field,
- NULL,
+ NULL, NULL,
"block last field when moving", "player blocks last field when moving"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE,
&level.instant_relocation,
- NULL,
+ NULL, NULL,
"no scrolling when relocating", "player gets relocated without delay"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
+ GADGET_ID_SHIFTED_RELOCATION, GADGET_ID_NONE,
+ &level.shifted_relocation,
+ NULL, NULL,
+ "no centering when relocating", "level not centered after relocation"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
+ GADGET_ID_LAZY_RELOCATION, GADGET_ID_NONE,
+ &level.lazy_relocation,
+ NULL, NULL,
+ "only redraw off-screen relocation","no redraw if relocation target visible"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE,
&level.use_start_element[0],
- NULL,
+ NULL, NULL,
"use level start element:", "start level at this element's position"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE,
&level.use_artwork_element[0],
- NULL,
+ NULL, NULL,
"use artwork from element:", "use player artwork from other element"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE,
&level.use_explosion_element[0],
- NULL,
+ NULL, NULL,
"use explosion from element:", "use explosion properties from element"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13),
GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE,
&level.initial_player_gravity[0],
- NULL,
+ NULL, NULL,
"use initial gravity", "set initial player gravity"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
+ GADGET_ID_USE_INITIAL_INVENTORY, GADGET_ID_NONE,
+ &level.use_initial_inventory[0],
+ NULL, NULL,
+ "use initial inventory:", "use collected elements on level start"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6),
GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE,
&level.can_pass_to_walkable,
- NULL,
+ NULL, NULL,
"can pass to walkable element", "player can pass to empty or walkable"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE_INTO_ACID],
- NULL,
+ NULL, NULL,
"can fall into acid (with gravity)","player can fall into acid pool"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_CAN_MOVE_INTO_ACID, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE_INTO_ACID],
- NULL,
+ NULL, NULL,
"can move into acid", "element can move into acid pool"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_DONT_COLLIDE_WITH, GADGET_ID_NONE,
&custom_element_properties[EP_DONT_COLLIDE_WITH],
- NULL,
+ NULL, NULL,
"deadly when colliding with", "element is deadly when hitting player"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_ENVELOPE_AUTOWRAP, GADGET_ID_NONE,
&level.envelope[0].autowrap,
- NULL,
+ NULL, NULL,
"auto-wrap", "automatically wrap envelope text"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_ENVELOPE_CENTERED, GADGET_ID_ENVELOPE_AUTOWRAP,
&level.envelope[0].centered,
- " ",
+ NULL, " ",
"centered", "automatically center envelope text"
},
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE,
&custom_element.use_gfx_element,
-
- /* !!! add separate "use existing element sound" !!! */
-#if 0
- NULL,
- "use graphic/sound of element:", "use existing graphic and sound"
-#else
- NULL,
+ NULL, NULL,
"use graphic of element:", "use existing element graphic"
-#endif
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
- GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE,
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14),
+ GADGET_ID_CUSTOM_USE_TEMPLATE_1, GADGET_ID_NONE,
&level.use_custom_template,
- NULL,
+ NULL, NULL,
"use template", "use template for custom properties"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_ACCESSIBLE, GADGET_ID_NONE,
&custom_element_properties[EP_ACCESSIBLE],
- NULL,
+ NULL, NULL,
NULL, "player can walk to or pass this field"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_GRAV_REACHABLE, GADGET_ID_NONE,
&custom_element_properties[EP_GRAVITY_REACHABLE],
- NULL,
+ NULL, NULL,
"reachable despite gravity", "player can walk/dig despite gravity"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_USE_LAST_VALUE, GADGET_ID_NONE,
&custom_element.use_last_ce_value,
- NULL,
+ NULL, NULL,
"use last CE value after change", "use last CE value after change"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE,
&custom_element_properties[EP_WALK_TO_OBJECT],
- NULL,
+ NULL, NULL,
NULL, "player can dig/collect/push element"
},
{
- ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_NONE,
&custom_element_properties[EP_INDESTRUCTIBLE],
- NULL,
+ NULL, NULL,
"indestructible", "element is indestructible"
},
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_CAN_MOVE, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE],
- NULL,
+ NULL, NULL,
NULL, "element can move with some pattern"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_FALL],
- NULL,
+ NULL, NULL,
"can fall", "element can fall down"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL,
&custom_element_properties[EP_CAN_SMASH],
- " ",
+ NULL, " ",
NULL, "element can smash other elements"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE,
&custom_element_properties[EP_SLIPPERY],
- NULL,
+ NULL, NULL,
NULL, "other elements can fall down from it"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE,
&custom_element_properties[EP_DEADLY],
- NULL,
+ NULL, NULL,
NULL, "element can kill the player"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_EXPLODE],
- NULL,
+ NULL, NULL,
NULL, "element can explode"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE,
&custom_element_properties[EP_EXPLODES_BY_FIRE],
- NULL,
+ NULL, NULL,
"by fire", "element can explode by fire/explosion"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE,
&custom_element_properties[EP_EXPLODES_SMASHED],
- " ",
+ NULL, " ",
"smashed", "element can explode when smashed"
},
{
-1, ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH,
&custom_element_properties[EP_EXPLODES_IMPACT],
- " ",
+ NULL, " ",
"impact", "element can explode on impact"
},
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE,
&custom_element_change.can_change,
- NULL,
+ NULL, NULL,
"element changes to:", "change element on specified condition"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CHANGE_DELAY, GADGET_ID_NONE,
&custom_element_change_events[CE_DELAY],
- NULL,
+ NULL, NULL,
NULL, "element changes after delay"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CHANGE_BY_DIRECT_ACT, GADGET_ID_NONE,
&custom_element_change_events[CE_BY_DIRECT_ACTION],
- NULL,
+ NULL, NULL,
NULL, "element changes by direct action"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
GADGET_ID_CHANGE_BY_OTHER_ACT, GADGET_ID_NONE,
&custom_element_change_events[CE_BY_OTHER_ACTION],
- NULL,
+ NULL, NULL,
NULL, "element changes by other element"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CHANGE_USE_EXPLOSION, GADGET_ID_NONE,
&custom_element_change.explode,
- NULL,
+ NULL, NULL,
"explode instead of change", "element explodes instead of change"
},
{
ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CHANGE_USE_CONTENT, GADGET_ID_NONE,
&custom_element_change.use_target_content,
- NULL,
+ NULL, NULL,
"use extended change target:", "element changes to more elements"
},
{
ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CHANGE_ONLY_COMPLETE, GADGET_ID_NONE,
&custom_element_change.only_if_complete,
- NULL,
+ NULL, NULL,
"replace all or nothing", "only replace when all can be changed"
},
{
ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_CHANGE_USE_RANDOM, GADGET_ID_NONE,
&custom_element_change.use_random_replace,
- NULL,
+ NULL, NULL,
NULL, "use percentage for random replace"
},
{
ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13),
GADGET_ID_CHANGE_HAS_ACTION, GADGET_ID_NONE,
&custom_element_change.has_action,
- NULL,
+ NULL, NULL,
NULL, "execute action on specified condition"
},
};
static struct
{
int x, y;
+ int xoffset, yoffset;
int gadget_id;
int gadget_id_align;
int *value;
/* ---------- level playfield content ------------------------------------ */
{
+ 0, 0,
0, 0,
GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE,
- NULL, MAX_ED_FIELDX, MAX_ED_FIELDY,
+ NULL,
+ -1, -1, /* these values are not constant, but can change at runtime */
NULL, NULL, NULL, NULL
},
/* ---------- yam yam content -------------------------------------------- */
{
- ED_AREA_YAMYAM_CONTENT_XPOS(0), ED_AREA_YAMYAM_CONTENT_YPOS(0),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(0), ED_AREA_YAMYAM_CONTENT_YOFF(0),
GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE,
&level.yamyam_content[0].e[0][0], 3, 3,
NULL, NULL, "1", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(1), ED_AREA_YAMYAM_CONTENT_YPOS(1),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(1), ED_AREA_YAMYAM_CONTENT_YOFF(1),
GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE,
&level.yamyam_content[1].e[0][0], 3, 3,
NULL, NULL, "2", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(2), ED_AREA_YAMYAM_CONTENT_YPOS(2),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(2), ED_AREA_YAMYAM_CONTENT_YOFF(2),
GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE,
&level.yamyam_content[2].e[0][0], 3, 3,
NULL, NULL, "3", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(3), ED_AREA_YAMYAM_CONTENT_YPOS(3),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(3), ED_AREA_YAMYAM_CONTENT_YOFF(3),
GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE,
&level.yamyam_content[3].e[0][0], 3, 3,
NULL, NULL, "4", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(4), ED_AREA_YAMYAM_CONTENT_YPOS(4),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(4), ED_AREA_YAMYAM_CONTENT_YOFF(4),
GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE,
&level.yamyam_content[4].e[0][0], 3, 3,
NULL, NULL, "5", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(5), ED_AREA_YAMYAM_CONTENT_YPOS(5),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(5), ED_AREA_YAMYAM_CONTENT_YOFF(5),
GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE,
&level.yamyam_content[5].e[0][0], 3, 3,
NULL, NULL, "6", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(6), ED_AREA_YAMYAM_CONTENT_YPOS(6),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(6), ED_AREA_YAMYAM_CONTENT_YOFF(6),
GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE,
&level.yamyam_content[6].e[0][0], 3, 3,
NULL, NULL, "7", NULL
},
{
- ED_AREA_YAMYAM_CONTENT_XPOS(7), ED_AREA_YAMYAM_CONTENT_YPOS(7),
+ ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS,
+ ED_AREA_YAMYAM_CONTENT_XOFF(7), ED_AREA_YAMYAM_CONTENT_YOFF(7),
GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE,
&level.yamyam_content[7].e[0][0], 3, 3,
NULL, NULL, "8", NULL
/* ---------- magic ball content ----------------------------------------- */
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(0), ED_AREA_MAGIC_BALL_CONTENT_YPOS(0),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(0), ED_AREA_MAGIC_BALL_CONTENT_YOFF(0),
GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE,
&level.ball_content[0].e[0][0], 3, 3,
NULL, NULL, "1", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(1), ED_AREA_MAGIC_BALL_CONTENT_YPOS(1),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(1), ED_AREA_MAGIC_BALL_CONTENT_YOFF(1),
GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE,
&level.ball_content[1].e[0][0], 3, 3,
NULL, NULL, "2", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(2), ED_AREA_MAGIC_BALL_CONTENT_YPOS(2),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(2), ED_AREA_MAGIC_BALL_CONTENT_YOFF(2),
GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE,
&level.ball_content[2].e[0][0], 3, 3,
NULL, NULL, "3", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(3), ED_AREA_MAGIC_BALL_CONTENT_YPOS(3),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(3), ED_AREA_MAGIC_BALL_CONTENT_YOFF(3),
GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE,
&level.ball_content[3].e[0][0], 3, 3,
NULL, NULL, "4", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(4), ED_AREA_MAGIC_BALL_CONTENT_YPOS(4),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(4), ED_AREA_MAGIC_BALL_CONTENT_YOFF(4),
GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE,
&level.ball_content[4].e[0][0], 3, 3,
NULL, NULL, "5", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(5), ED_AREA_MAGIC_BALL_CONTENT_YPOS(5),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(5), ED_AREA_MAGIC_BALL_CONTENT_YOFF(5),
GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE,
&level.ball_content[5].e[0][0], 3, 3,
NULL, NULL, "6", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(6), ED_AREA_MAGIC_BALL_CONTENT_YPOS(6),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(6), ED_AREA_MAGIC_BALL_CONTENT_YOFF(6),
GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE,
&level.ball_content[6].e[0][0], 3, 3,
NULL, NULL, "7", NULL
},
{
- ED_AREA_MAGIC_BALL_CONTENT_XPOS(7), ED_AREA_MAGIC_BALL_CONTENT_YPOS(7),
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS,
+ ED_AREA_MAGIC_BALL_CONTENT_XOFF(7), ED_AREA_MAGIC_BALL_CONTENT_YOFF(7),
GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE,
&level.ball_content[7].e[0][0], 3, 3,
NULL, NULL, "8", NULL
{
ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5),
+ ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE,
&level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1,
"elements:", NULL, NULL, "elements android can clone"
{
ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3),
+ ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE,
&level.amoeba_content, 1, 1,
"content:", NULL, NULL, "amoeba content"
/* ---------- level start element ---------------------------------------- */
{
- -1, ED_AREA_1X1_SETTINGS_YPOS(8),
+ -1, ED_AREA_1X1_SETTINGS_YPOS(10),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT,
&level.start_element[0], 1, 1,
NULL, NULL, NULL, "level start element"
/* ---------- player artwork element ------------------------------------- */
{
- -1, ED_AREA_1X1_SETTINGS_YPOS(9),
+ -1, ED_AREA_1X1_SETTINGS_YPOS(11),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT,
&level.artwork_element[0], 1, 1,
NULL, NULL, NULL, "element for player artwork"
/* ---------- player explosion element ----------------------------------- */
{
- -1, ED_AREA_1X1_SETTINGS_YPOS(10),
+ -1, ED_AREA_1X1_SETTINGS_YPOS(12),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT,
&level.explosion_element[0], 1, 1,
NULL, NULL, NULL, "element for player explosion"
},
+ /* ---------- player initial inventory ----------------------------------- */
+
+ {
+ -1, ED_AREA_1X1_SETTINGS_YPOS(1),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
+ GADGET_ID_INVENTORY_CONTENT, GADGET_ID_USE_INITIAL_INVENTORY,
+ &level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1,
+ NULL, NULL, NULL, "content for initial inventory"
+ },
+
/* ---------- element settings: configure 1 (custom elements) ----------- */
/* ---------- custom graphic --------------------------------------------- */
{
-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, 1, 1,
+ &custom_element.gfx_element_initial,1, 1,
NULL, NULL, NULL, "custom graphic element"
},
{
-1, ED_AREA_3X3_SETTINGS_YPOS(10),
+ 0, ED_AREA_3X3_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, /* align three rows */
&custom_element.content.e[0][0], 3, 3,
"content:", NULL, NULL, NULL
{
ED_AREA_1X1_SETTINGS_XPOS(1), ED_AREA_1X1_SETTINGS_YPOS(3),
+ ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE,
&custom_element.move_enter_element, 1, 1,
"can dig:", " ", NULL, "element that can be digged/collected"
},
{
-1, ED_AREA_1X1_SETTINGS_YPOS(3),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE,
&custom_element.move_leave_element, 1, 1,
NULL, NULL, NULL, "element that will be left behind"
{
-1, ED_AREA_1X1_SETTINGS_YPOS(1),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE,
&custom_element_change.target_element, 1, 1,
NULL, "after/when:", NULL, "new target element after change"
{
-1, ED_AREA_3X3_SETTINGS_YPOS(9),
+ 0, ED_AREA_3X3_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, /* align three rows */
&custom_element_change.target_content.e[0][0], 3, 3,
NULL, NULL, NULL, "new extended elements after change"
{
-1, ED_AREA_1X1_SETTINGS_YPOS(5),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION,
- &custom_element_change.trigger_element, 1, 1,
+ &custom_element_change.initial_trigger_element, 1, 1,
NULL, NULL, NULL, "other element triggering change"
},
+ /* ---------- custom change action (element used for action) ------------- */
+
+ {
+ -1, ED_AREA_1X1_SETTINGS_YPOS(13),
+ 0, ED_AREA_1X1_SETTINGS_YOFF,
+ GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG,
+ &custom_element_change.action_element, 1, 1,
+ NULL, NULL, NULL, "element used as action parameter"
+ },
+
/* ---------- group element content -------------------------------------- */
{
- ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(4),
+ ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2),
+ ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF,
GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE,
&group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1,
"content:", NULL, NULL, NULL
/* ---------- random background (for random painting) -------------------- */
{
- -1, ED_ELEMENT_SETTINGS_YPOS(14),
+ -1, ED_AREA_1X1_LSETTINGS_YPOS(1),
+ 0, ED_AREA_1X1_LSETTINGS_YOFF,
GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED,
&random_placement_background_element, 1, 1,
NULL, NULL, NULL, "random placement background"
-----------------------------------------------------------------------------
*/
+/* maximal size of level editor drawing area */
+static int MAX_ED_FIELDX, MAX_ED_FIELDY;
+
/* actual size of level editor drawing area */
-static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1;
+static int ed_fieldx, ed_fieldy;
/* actual position of level editor drawing area in level playfield */
static int level_xpos = -1, level_ypos = -1;
-#if 1
+/* actual tile size used to display playfield drawing area */
+static int ed_tilesize = DEFAULT_EDITOR_TILESIZE;
+
#define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy)
-#else
-#define IN_ED_FIELD(x,y) ((x)>=0 && (x)<ed_fieldx && (y)>=0 &&(y)<ed_fieldy)
-#endif
/* drawing elements on the three mouse buttons */
static int new_element1 = EL_WALL;
#define BUTTON_ELEMENT(button) ((button) == 1 ? new_element1 : \
(button) == 2 ? new_element2 : \
(button) == 3 ? new_element3 : EL_EMPTY)
-#define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10)
+
+#define BUTTON_TILE_SIZE(x) ((x) >= TILESIZE ? TILESIZE : MINI_TILESIZE)
+
+static int use_permanent_palette = TRUE;
+
+#define PX (use_permanent_palette ? DX : SX)
+#define PY (use_permanent_palette ? DY : SY)
+#define PXSIZE (use_permanent_palette ? DXSIZE : SXSIZE)
+#define PYSIZE (use_permanent_palette ? DYSIZE : SYSIZE)
/* forward declaration for internal use */
static void ModifyEditorCounterValue(int, int);
static void DrawDrawingWindow();
static void DrawLevelInfoWindow();
static void DrawPropertiesWindow();
+static void DrawPaletteWindow();
static void UpdateCustomElementGraphicGadgets();
static boolean checkPropertiesConfig(int);
static void CopyLevelToUndoBuffer(int);
static void HandleControlButtons(struct GadgetInfo *);
static void HandleDrawingAreaInfo(struct GadgetInfo *);
static void PrintEditorGadgetInfoText(struct GadgetInfo *);
+static boolean AskToCopyAndModifyLevelTemplate();
+
+static int num_editor_gadgets = 0; /* dynamically determined */
-static struct GadgetInfo *level_editor_gadget[NUM_EDITOR_GADGETS];
-static int right_gadget_border[NUM_EDITOR_GADGETS];
+static struct GadgetInfo **level_editor_gadget = NULL;
+static int *right_gadget_border = NULL;
static int drawing_function = GADGET_ID_SINGLE_ITEMS;
static int last_drawing_function = GADGET_ID_SINGLE_ITEMS;
static short IntelliDrawBuffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static int undo_buffer_position = 0;
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_properties;
static int element_shift = 0;
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+
+ EL_EM_EXIT_CLOSED,
+ EL_EM_EXIT_OPEN,
+ EL_EM_STEEL_EXIT_CLOSED,
+ EL_EM_STEEL_EXIT_OPEN,
};
static int *editor_hl_emerald_mine_ptr = editor_hl_emerald_mine;
static int *editor_el_emerald_mine_ptr = editor_el_emerald_mine;
EL_SP_GRAVITY_PORT_UP,
EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_ON_PORT_LEFT,
+ EL_SP_GRAVITY_ON_PORT_RIGHT,
+ EL_SP_GRAVITY_ON_PORT_UP,
+ EL_SP_GRAVITY_ON_PORT_DOWN,
+
+ EL_SP_GRAVITY_OFF_PORT_LEFT,
+ EL_SP_GRAVITY_OFF_PORT_RIGHT,
+ EL_SP_GRAVITY_OFF_PORT_UP,
+ EL_SP_GRAVITY_OFF_PORT_DOWN,
+
EL_SP_HARDWARE_GRAY,
EL_SP_HARDWARE_GREEN,
EL_SP_HARDWARE_BLUE,
EL_SWITCHGATE_SWITCH_UP,
EL_SWITCHGATE_SWITCH_DOWN,
- EL_EMPTY,
- EL_EMPTY,
- EL_DC_SWITCHGATE_SWITCH_UP,
- EL_DC_SWITCHGATE_SWITCH_DOWN,
-
- EL_SIGN_EXCLAMATION,
- EL_SIGN_STOP,
EL_LIGHT_SWITCH,
EL_LIGHT_SWITCH_ACTIVE,
+ EL_DC_SWITCHGATE_SWITCH_UP,
+ EL_DC_SWITCHGATE_SWITCH_DOWN,
+ EL_STEEL_EXIT_CLOSED,
+ EL_STEEL_EXIT_OPEN,
EL_STEELWALL_SLIPPERY,
EL_INVISIBLE_SAND,
+
+ EL_QUICKSAND_FAST_EMPTY,
+ EL_QUICKSAND_FAST_FULL,
EL_LANDMINE,
EL_DC_LANDMINE,
EL_SHIELD_NORMAL,
EL_SHIELD_DEADLY,
EL_EXTRA_TIME,
- EL_EMPTY,
+ EL_DC_MAGIC_WALL,
EL_ENVELOPE_1,
EL_ENVELOPE_2,
EL_SIGN_EMERGENCY_EXIT,
EL_SIGN_YIN_YANG,
+#if 0
EL_SIGN_SPERMS,
EL_SIGN_BULLET,
EL_SIGN_HEART,
EL_EMPTY,
EL_EMPTY,
EL_EMPTY,
+#endif
EL_DC_STEELWALL_2_SINGLE,
EL_DC_STEELWALL_2_TOP,
- EL_STEEL_EXIT_CLOSED,
- EL_STEEL_EXIT_OPEN,
+ EL_SIGN_EXCLAMATION,
+ EL_SIGN_STOP,
EL_DC_STEELWALL_2_LEFT,
EL_DC_STEELWALL_2_MIDDLE,
EL_DC_STEELWALL_1_TOPLEFT,
EL_DC_STEELWALL_2_VERTICAL,
EL_DC_STEELWALL_1_TOPRIGHT,
- EL_EMPTY,
+ EL_DC_GATE_WHITE,
EL_DC_STEELWALL_1_VERTICAL,
EL_DC_STEELWALL_2_BOTTOM,
- EL_EMPTY,
- EL_EMPTY,
+ EL_DC_KEY_WHITE,
+ EL_DC_GATE_WHITE_GRAY,
EL_DC_STEELWALL_1_BOTTOMLEFT,
EL_DC_STEELWALL_1_HORIZONTAL,
EL_DC_STEELWALL_1_BOTTOMRIGHT,
- EL_EMPTY,
+ EL_DC_GATE_FAKE_GRAY,
EL_DC_STEELWALL_1_BOTTOMRIGHT_2,
EL_DC_STEELWALL_1_BOTTOM,
EL_DC_STEELWALL_1_BOTTOMLEFT_2,
- EL_EMPTY,
+ EL_EXPANDABLE_STEELWALL_HORIZONTAL,
EL_DC_STEELWALL_1_RIGHT,
EL_EMPTY,
EL_DC_STEELWALL_1_LEFT,
- EL_EMPTY,
+ EL_EXPANDABLE_STEELWALL_VERTICAL,
EL_DC_STEELWALL_1_TOPRIGHT_2,
EL_DC_STEELWALL_1_TOP,
EL_DC_STEELWALL_1_TOPLEFT_2,
- EL_EMPTY,
-
- EL_EXPANDABLE_STEELWALL_HORIZONTAL,
- EL_EXPANDABLE_STEELWALL_VERTICAL,
EL_EXPANDABLE_STEELWALL_ANY,
- EL_EMPTY,
-
- EL_EM_EXIT_CLOSED,
- EL_EM_EXIT_OPEN,
- EL_EM_STEEL_EXIT_CLOSED,
- EL_EM_STEEL_EXIT_OPEN,
-
- EL_DC_KEY_WHITE,
- EL_DC_GATE_WHITE,
- EL_DC_GATE_WHITE_GRAY,
- EL_DC_GATE_FAKE_GRAY,
-
- EL_DC_MAGIC_WALL,
- EL_QUICKSAND_FAST_EMPTY,
- EL_QUICKSAND_FAST_FULL,
- EL_EMPTY,
};
static int *editor_hl_diamond_caves_ptr = editor_hl_diamond_caves;
static int *editor_el_diamond_caves_ptr = editor_el_diamond_caves;
static int num_editor_hl_dx_boulderdash = SIZEOF_ARRAY_INT(editor_hl_dx_boulderdash);
static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderdash);
+static int editor_hl_mirror_magic[] =
+{
+ EL_INTERNAL_CASCADE_MM_ACTIVE,
+ EL_CHAR('M'),
+ EL_CHAR('M'),
+ EL_EMPTY,
+};
+
+static int editor_el_mirror_magic[] =
+{
+ EL_MM_MCDUFFIN_RIGHT,
+ EL_MM_MCDUFFIN_UP,
+ EL_MM_MCDUFFIN_LEFT,
+ EL_MM_MCDUFFIN_DOWN,
+
+ EL_MM_MIRROR_START,
+ EL_MM_MIRROR_FIXED_START,
+ EL_MM_POLARISATOR_START,
+ EL_MM_POLARISATOR_CROSS_START,
+
+ EL_MM_BEAMER_RED_START,
+ EL_MM_BEAMER_YELLOW_START,
+ EL_MM_BEAMER_GREEN_START,
+ EL_MM_BEAMER_BLUE_START,
+
+ EL_MM_PRISM,
+ EL_MM_FUSE_ACTIVE,
+ EL_MM_PACMAN_RIGHT,
+ EL_MM_EXIT_CLOSED,
+
+ EL_MM_KETTLE,
+ EL_MM_BOMB,
+ EL_MM_KEY,
+ EL_MM_FUEL_FULL,
+
+ EL_MM_LIGHTBULB,
+ EL_MM_LIGHTBULB_ACTIVE,
+ EL_MM_GRAY_BALL,
+ EL_MM_LIGHTBALL,
+
+ EL_MM_STEEL_WALL,
+ EL_MM_WOODEN_WALL,
+ EL_MM_ICE_WALL,
+ EL_MM_AMOEBA_WALL,
+
+ EL_MM_STEEL_LOCK,
+ EL_MM_WOODEN_LOCK,
+ EL_MM_STEEL_BLOCK,
+ EL_MM_WOODEN_BLOCK,
+
+ EL_MM_STEEL_GRID_FIXED_1,
+ EL_MM_STEEL_GRID_FIXED_2,
+ EL_MM_STEEL_GRID_FIXED_3,
+ EL_MM_STEEL_GRID_FIXED_4,
+
+ EL_MM_WOODEN_GRID_FIXED_1,
+ EL_MM_WOODEN_GRID_FIXED_2,
+ EL_MM_WOODEN_GRID_FIXED_3,
+ EL_MM_WOODEN_GRID_FIXED_4
+};
+static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic;
+static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic;
+static int num_editor_hl_mirror_magic = SIZEOF_ARRAY_INT(editor_hl_mirror_magic);
+static int num_editor_el_mirror_magic = SIZEOF_ARRAY_INT(editor_el_mirror_magic);
+
+static int editor_hl_deflektor[] =
+{
+ EL_INTERNAL_CASCADE_DF_ACTIVE,
+ EL_CHAR('D'),
+ EL_CHAR('F'),
+ EL_EMPTY,
+};
+
+static int editor_el_deflektor[] =
+{
+ EL_DF_LASER_RIGHT,
+ EL_DF_LASER_UP,
+ EL_DF_LASER_LEFT,
+ EL_DF_LASER_DOWN,
+
+ EL_DF_RECEIVER_RIGHT,
+ EL_DF_RECEIVER_UP,
+ EL_DF_RECEIVER_LEFT,
+ EL_DF_RECEIVER_DOWN,
+
+ EL_DF_MIRROR_START,
+ EL_DF_MIRROR_ROTATING_START,
+ EL_DF_CELL,
+ EL_DF_MINE,
+
+ EL_DF_FIBRE_OPTIC_RED_1,
+ EL_DF_FIBRE_OPTIC_YELLOW_1,
+ EL_DF_FIBRE_OPTIC_GREEN_1,
+ EL_DF_FIBRE_OPTIC_BLUE_1,
+
+ EL_DF_STEEL_GRID_FIXED_START,
+ EL_DF_STEEL_GRID_ROTATING_START,
+ EL_DF_WOODEN_GRID_FIXED_START,
+ EL_DF_WOODEN_GRID_ROTATING_START,
+
+ EL_DF_STEEL_WALL,
+ EL_DF_WOODEN_WALL,
+ EL_DF_REFRACTOR,
+ EL_EMPTY
+};
+static int *editor_hl_deflektor_ptr = editor_hl_deflektor;
+static int *editor_el_deflektor_ptr = editor_el_deflektor;
+static int num_editor_hl_deflektor = SIZEOF_ARRAY_INT(editor_hl_deflektor);
+static int num_editor_el_deflektor = SIZEOF_ARRAY_INT(editor_el_deflektor);
+
static int editor_hl_chars[] =
{
EL_INTERNAL_CASCADE_CHARS_ACTIVE,
EL_CHAR('^'),
EL_CHAR('_'),
- EL_CHAR('©'),
- EL_CHAR('Ä'),
- EL_CHAR('Ö'),
- EL_CHAR('Ü'),
+ EL_CHAR(CHAR_BYTE_COPYRIGHT),
+ EL_CHAR(CHAR_BYTE_UMLAUT_A),
+ EL_CHAR(CHAR_BYTE_UMLAUT_O),
+ EL_CHAR(CHAR_BYTE_UMLAUT_U),
- EL_CHAR('°'),
- EL_CHAR('®'),
+ EL_CHAR(CHAR_BYTE_DEGREE),
+ EL_CHAR(CHAR_BYTE_REGISTERED),
EL_CHAR(FONT_ASCII_CURSOR),
EL_CHAR(FONT_ASCII_BUTTON),
EL_STEEL_CHAR('^'),
EL_STEEL_CHAR('_'),
- EL_STEEL_CHAR('©'),
- EL_STEEL_CHAR('Ä'),
- EL_STEEL_CHAR('Ö'),
- EL_STEEL_CHAR('Ü'),
+ EL_STEEL_CHAR(CHAR_BYTE_COPYRIGHT),
+ EL_STEEL_CHAR(CHAR_BYTE_UMLAUT_A),
+ EL_STEEL_CHAR(CHAR_BYTE_UMLAUT_O),
+ EL_STEEL_CHAR(CHAR_BYTE_UMLAUT_U),
- EL_STEEL_CHAR('°'),
- EL_STEEL_CHAR('®'),
+ EL_STEEL_CHAR(CHAR_BYTE_DEGREE),
+ EL_STEEL_CHAR(CHAR_BYTE_REGISTERED),
EL_STEEL_CHAR(FONT_ASCII_CURSOR),
EL_STEEL_CHAR(FONT_ASCII_BUTTON),
static int num_editor_hl_dynamic = SIZEOF_ARRAY_INT(editor_hl_dynamic);
static int num_editor_el_dynamic = 0;
-static int editor_hl_empty[] = { };
-static int editor_el_empty[ED_NUM_ELEMENTLIST_BUTTONS];
+static int editor_hl_empty[] = { EL_EMPTY };
+static int *editor_el_empty = NULL; /* dynamically allocated */
static int *editor_hl_empty_ptr = editor_hl_empty;
-static int *editor_el_empty_ptr = editor_el_empty;
+static int *editor_el_empty_ptr = NULL;
static int num_editor_hl_empty = 0;
static int num_editor_el_empty = 0; /* dynamically determined, if needed */
static int *editor_elements = NULL; /* dynamically allocated */
static int num_editor_elements = 0; /* dynamically determined */
-static boolean setup_editor_show_always = TRUE;
static boolean setup_editor_cascade_never = FALSE;
+static boolean setup_editor_el_players = TRUE;
+static boolean setup_editor_el_boulderdash = TRUE;
+static boolean setup_editor_el_emerald_mine = TRUE;
+static boolean setup_editor_el_emerald_mine_club = TRUE;
+static boolean setup_editor_el_more = TRUE;
+static boolean setup_editor_el_sokoban = TRUE;
+static boolean setup_editor_el_supaplex = TRUE;
+static boolean setup_editor_el_diamond_caves = TRUE;
+static boolean setup_editor_el_dx_boulderdash = TRUE;
+static boolean setup_editor_el_mirror_magic = TRUE;
+static boolean setup_editor_el_deflektor = TRUE;
+static boolean setup_editor_el_chars = TRUE;
+static boolean setup_editor_el_steel_chars = TRUE;
+static boolean setup_editor_el_custom = TRUE;
+static boolean setup_editor_el_user_defined = TRUE;
+static boolean setup_editor_el_dynamic = TRUE;
+
static int editor_hl_unused[] = { EL_EMPTY };
static int *editor_hl_unused_ptr = editor_hl_unused;
static int num_editor_hl_unused = 0;
editor_elements_info[] =
{
{
- &setup_editor_show_always,
+ &setup_editor_el_players,
&setup_editor_cascade_never,
&editor_hl_unused_ptr, &num_editor_hl_unused,
&editor_el_players_ptr, &num_editor_el_players
},
{
- &setup.editor.el_boulderdash,
+ &setup_editor_el_boulderdash,
&setup.editor_cascade.el_bd,
&editor_hl_boulderdash_ptr, &num_editor_hl_boulderdash,
&editor_el_boulderdash_ptr, &num_editor_el_boulderdash
},
{
- &setup.editor.el_emerald_mine,
+ &setup_editor_el_emerald_mine,
&setup.editor_cascade.el_em,
&editor_hl_emerald_mine_ptr, &num_editor_hl_emerald_mine,
&editor_el_emerald_mine_ptr, &num_editor_el_emerald_mine
},
{
- &setup.editor.el_emerald_mine_club,
+ &setup_editor_el_emerald_mine_club,
&setup.editor_cascade.el_emc,
&editor_hl_emerald_mine_club_ptr, &num_editor_hl_emerald_mine_club,
&editor_el_emerald_mine_club_ptr, &num_editor_el_emerald_mine_club
},
{
- &setup.editor.el_more,
+ &setup_editor_el_more,
&setup.editor_cascade.el_rnd,
&editor_hl_rnd_ptr, &num_editor_hl_rnd,
&editor_el_rnd_ptr, &num_editor_el_rnd
},
{
- &setup.editor.el_sokoban,
+ &setup_editor_el_sokoban,
&setup.editor_cascade.el_sb,
&editor_hl_sokoban_ptr, &num_editor_hl_sokoban,
&editor_el_sokoban_ptr, &num_editor_el_sokoban
},
{
- &setup.editor.el_supaplex,
+ &setup_editor_el_supaplex,
&setup.editor_cascade.el_sp,
&editor_hl_supaplex_ptr, &num_editor_hl_supaplex,
&editor_el_supaplex_ptr, &num_editor_el_supaplex
},
{
- &setup.editor.el_diamond_caves,
+ &setup_editor_el_diamond_caves,
&setup.editor_cascade.el_dc,
&editor_hl_diamond_caves_ptr, &num_editor_hl_diamond_caves,
&editor_el_diamond_caves_ptr, &num_editor_el_diamond_caves
},
{
- &setup.editor.el_dx_boulderdash,
+ &setup_editor_el_dx_boulderdash,
&setup.editor_cascade.el_dx,
&editor_hl_dx_boulderdash_ptr, &num_editor_hl_dx_boulderdash,
&editor_el_dx_boulderdash_ptr, &num_editor_el_dx_boulderdash
},
{
- &setup.editor.el_chars,
+ &setup_editor_el_mirror_magic,
+ &setup.editor_cascade.el_mm,
+ &editor_hl_mirror_magic_ptr, &num_editor_hl_mirror_magic,
+ &editor_el_mirror_magic_ptr, &num_editor_el_mirror_magic
+ },
+ {
+ &setup_editor_el_deflektor,
+ &setup.editor_cascade.el_df,
+ &editor_hl_deflektor_ptr, &num_editor_hl_deflektor,
+ &editor_el_deflektor_ptr, &num_editor_el_deflektor
+ },
+ {
+ &setup_editor_el_chars,
&setup.editor_cascade.el_chars,
&editor_hl_chars_ptr, &num_editor_hl_chars,
&editor_el_chars_ptr, &num_editor_el_chars
},
{
- &setup.editor.el_steel_chars,
+ &setup_editor_el_steel_chars,
&setup.editor_cascade.el_steel_chars,
&editor_hl_steel_chars_ptr, &num_editor_hl_steel_chars,
&editor_el_steel_chars_ptr, &num_editor_el_steel_chars
},
{
- &setup.editor.el_custom,
+ &setup_editor_el_custom,
&setup.editor_cascade.el_ce,
&editor_hl_custom_ptr, &num_editor_hl_custom,
&editor_el_custom_ptr, &num_editor_el_custom
},
{
- &setup.editor.el_custom,
+ &setup_editor_el_custom,
&setup.editor_cascade.el_ge,
&editor_hl_group_ptr, &num_editor_hl_group,
&editor_el_group_ptr, &num_editor_el_group
},
{
- &setup.editor.el_custom,
+ &setup_editor_el_custom,
&setup.editor_cascade.el_ref,
&editor_hl_reference_ptr, &num_editor_hl_reference,
&editor_el_reference_ptr, &num_editor_el_reference
},
{
- &setup.editor.el_user_defined,
+ &setup_editor_el_user_defined,
&setup.editor_cascade.el_user,
&editor_hl_user_defined_ptr, &num_editor_hl_user_defined,
&editor_el_user_defined_ptr, &num_editor_el_user_defined
},
{
- &setup.editor.el_dynamic,
+ &setup_editor_el_dynamic,
&setup.editor_cascade.el_dynamic,
&editor_hl_dynamic_ptr, &num_editor_hl_dynamic,
&editor_el_dynamic_ptr, &num_editor_el_dynamic,
static int getMaxInfoTextLength()
{
- return (SXSIZE / getFontWidth(FONT_TEXT_2));
+ return (SXSIZE / getFontWidth(INFOTEXT_FONT));
}
static int getTextWidthForGadget(char *text)
return info_text;
}
-char *getElementDescriptionFilename(int element)
+static char *getElementDescriptionFilenameExt(char *basename)
{
- char *docs_dir = options.docs_directory;
char *elements_subdir = "elements";
+ static char *elements_subdir2 = NULL;
static char *filename = NULL;
- char basename[MAX_FILENAME_LEN];
+
+ if (elements_subdir2 == NULL)
+ elements_subdir2 = getPath2(DOCS_DIRECTORY, elements_subdir);
checked_free(filename);
- /* 1st try: look for element description file for exactly this element */
- sprintf(basename, "%s.txt", element_info[element].token_name);
- filename = getPath3(docs_dir, elements_subdir, basename);
+ /* 1st try: look for element description in current level set directory */
+ filename = getPath3(getCurrentLevelDir(), elements_subdir2, basename);
if (fileExists(filename))
return filename;
free(filename);
+ /* 2nd try: look for element description in the game's base directory */
+ filename = getPath3(options.docs_directory, elements_subdir, basename);
+ if (fileExists(filename))
+ return filename;
+
+ return NULL;
+}
+
+char *getElementDescriptionFilename(int element)
+{
+ char basename[MAX_FILENAME_LEN];
+ char *filename;
+
+ /* 1st try: look for element description file for exactly this element */
+ sprintf(basename, "%s.txt", element_info[element].token_name);
+ filename = getElementDescriptionFilenameExt(basename);
+ if (filename != NULL)
+ return filename;
+
/* 2nd try: look for element description file for this element's class */
sprintf(basename, "%s.txt", element_info[element].class_name);
- filename = getPath3(docs_dir, elements_subdir, basename);
- if (fileExists(filename))
+ filename = getElementDescriptionFilenameExt(basename);
+ if (filename != NULL)
return filename;
return NULL;
(*elements)[(*num_elements)++] = EL_EMPTY;
}
+static void ReinitializeElementList_EnableSections()
+{
+ /* default: enable all element sections */
+
+ setup_editor_el_players = TRUE;
+ setup_editor_el_boulderdash = TRUE;
+ setup_editor_el_emerald_mine = TRUE;
+ setup_editor_el_emerald_mine_club = TRUE;
+ setup_editor_el_more = TRUE;
+ setup_editor_el_sokoban = TRUE;
+ setup_editor_el_supaplex = TRUE;
+ setup_editor_el_diamond_caves = TRUE;
+ setup_editor_el_dx_boulderdash = TRUE;
+ setup_editor_el_mirror_magic = TRUE;
+ setup_editor_el_deflektor = TRUE;
+ setup_editor_el_chars = TRUE;
+ setup_editor_el_steel_chars = TRUE;
+
+ setup_editor_el_custom = TRUE;
+ setup_editor_el_user_defined = TRUE;
+ setup_editor_el_dynamic = TRUE;
+
+ /* now disable all element sections not to be displayed */
+
+ if (!setup.editor.el_classic)
+ {
+ setup_editor_el_players = FALSE;
+ setup_editor_el_boulderdash = FALSE;
+ setup_editor_el_emerald_mine = FALSE;
+ setup_editor_el_emerald_mine_club = FALSE;
+ setup_editor_el_more = FALSE;
+ setup_editor_el_sokoban = FALSE;
+ setup_editor_el_supaplex = FALSE;
+ setup_editor_el_diamond_caves = FALSE;
+ setup_editor_el_dx_boulderdash = FALSE;
+ setup_editor_el_mirror_magic = FALSE;
+ setup_editor_el_deflektor = FALSE;
+ setup_editor_el_chars = FALSE;
+ setup_editor_el_steel_chars = FALSE;
+ }
+
+ if (!setup.editor.el_custom)
+ {
+ setup_editor_el_custom = FALSE;
+ }
+
+ if (!setup.editor.el_user_defined)
+ {
+ setup_editor_el_user_defined = FALSE;
+ }
+
+ if (!setup.editor.el_dynamic)
+ {
+ setup_editor_el_dynamic = FALSE;
+ }
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ {
+ setup_editor_el_mirror_magic = FALSE;
+ setup_editor_el_deflektor = FALSE;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ setup_editor_el_boulderdash = FALSE;
+ setup_editor_el_more = FALSE;
+ setup_editor_el_sokoban = FALSE;
+ setup_editor_el_supaplex = FALSE;
+ setup_editor_el_dx_boulderdash = FALSE;
+ setup_editor_el_mirror_magic = FALSE;
+ setup_editor_el_deflektor = FALSE;
+ setup_editor_el_steel_chars = FALSE;
+
+ setup_editor_el_custom = FALSE;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ {
+ setup_editor_el_players = FALSE;
+ setup_editor_el_boulderdash = FALSE;
+ setup_editor_el_emerald_mine = FALSE;
+ setup_editor_el_emerald_mine_club = FALSE;
+ setup_editor_el_more = FALSE;
+ setup_editor_el_sokoban = FALSE;
+ setup_editor_el_diamond_caves = FALSE;
+ setup_editor_el_dx_boulderdash = FALSE;
+ setup_editor_el_mirror_magic = FALSE;
+ setup_editor_el_deflektor = FALSE;
+ setup_editor_el_chars = FALSE;
+ setup_editor_el_steel_chars = FALSE;
+
+ setup_editor_el_custom = FALSE;
+ }
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+ {
+ setup_editor_el_players = FALSE;
+ setup_editor_el_boulderdash = FALSE;
+ setup_editor_el_emerald_mine = FALSE;
+ setup_editor_el_emerald_mine_club = FALSE;
+ setup_editor_el_more = FALSE;
+ setup_editor_el_sokoban = FALSE;
+ setup_editor_el_supaplex = FALSE;
+ setup_editor_el_diamond_caves = FALSE;
+ setup_editor_el_dx_boulderdash = FALSE;
+ setup_editor_el_steel_chars = FALSE;
+
+ setup_editor_el_custom = FALSE;
+ }
+}
+
static void ReinitializeElementList()
{
static boolean initialization_needed = TRUE;
int pos = 0;
int i, j;
+ ReinitializeElementList_EnableSections();
+
if (initialization_needed)
{
LoadSetup_EditorCascade(); /* load last editor cascade state */
Error(ERR_WARN, "editor element %d is runtime element", element);
if (strEqual(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT))
- Error(ERR_WARN, "no element description for element %d", element);
+ Error(ERR_WARN, "no element description text for element %d", element);
}
}
{
if (setup.editor.el_headlines)
{
- num_editor_elements += *editor_elements_info[i].headline_list_size;
+ // required for correct padding of palette headline buttons
+ if (*editor_elements_info[i].headline_list_size > 0)
+ num_editor_elements += editor.palette.cols;
for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
{
if (found_inactive_cascade)
continue;
- num_editor_elements += *editor_elements_info[i].element_list_size;
+ // required for correct padding of palette element buttons
+ int element_list_size = *editor_elements_info[i].element_list_size;
+ int element_rows =
+ (element_list_size + editor.palette.cols - 1) / editor.palette.cols;
+ int element_buttons = editor.palette.cols * element_rows;
+
+ num_editor_elements += element_buttons;
}
}
{
if (setup.editor.el_headlines)
{
- for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
+ // required for correct padding of palette headline buttons
+ int headline_size = (*editor_elements_info[i].headline_list_size > 0 ?
+ editor.palette.cols : 0);
+
+ for (j = 0; j < headline_size; j++)
{
- int element = (*editor_elements_info[i].headline_list)[j];
+ // use empty elements for padding of palette headline buttons
+ int element = (j < *editor_elements_info[i].headline_list_size ?
+ (*editor_elements_info[i].headline_list)[j] :
+ editor_el_empty[0]);
editor_elements[pos++] = element;
if (found_inactive_cascade)
continue;
- for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+ // required for correct padding of palette element buttons
+ int element_list_size = *editor_elements_info[i].element_list_size;
+ int element_rows =
+ (element_list_size + editor.palette.cols - 1) / editor.palette.cols;
+ int element_buttons = editor.palette.cols * element_rows;
+
+ // copy all elements from element list
+ for (j = 0; j < element_list_size; j++)
editor_elements[pos++] = (*editor_elements_info[i].element_list)[j];
+
+ // use empty elements for padding of palette element buttons
+ for (j = 0; j < element_buttons - element_list_size; j++)
+ editor_elements[pos++] = editor_el_empty[0];
}
}
int cascade_element_show = EL_CASCADE_INACTIVE(cascade_element);
char *headline = element_info[cascade_element_show].editor_description;
- printf_line_with_prefix("# ", "-", 77);
- printf("# %s\n", headline);
- printf_line_with_prefix("# ", "-", 77);
+ PrintLineWithPrefix("# ", "-", 77);
+ Print("# %s\n", headline);
+ PrintLineWithPrefix("# ", "-", 77);
}
for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
if (IS_EDITOR_CASCADE(element))
element = EL_CHAR_MINUS;
- printf("# %s\n", element_info[element].token_name);
+ Print("# %s\n", element_info[element].token_name);
}
if (j > 0)
- printf("#\n");
+ Print("#\n");
for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
{
int element = (*editor_elements_info[i].element_list)[j];
- printf("# %s\n", element_info[element].token_name);
+ Print("# %s\n", element_info[element].token_name);
}
if (j > 0)
- printf("#\n");
+ Print("#\n");
}
}
{
int border_graphic =
(input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER);
- Bitmap *src_bitmap;
- int src_x, src_y;
- int num_mini_tilex = width / MINI_TILEX + 1;
- int num_mini_tiley = height / MINI_TILEY + 1;
- int from_x = dest_x - MINI_TILEX / 2;
- int from_y = dest_y - MINI_TILEY / 2;
- int to_x = from_x + num_mini_tilex * MINI_TILEX - 1;
- int to_y = from_y + num_mini_tiley * MINI_TILEY - 1;
- int x, y;
+ struct GraphicInfo *g = &graphic_info[border_graphic];
+ Bitmap *src_bitmap = g->bitmap;
+ int src_x = g->src_x;
+ int src_y = g->src_y;
+ int border_size = g->border_size;
+ int border_xpos = g->width - border_size;
+ int border_ypos = g->height - border_size;
+ int tilesize = ED_DRAWINGAREA_TILE_SIZE;
+ int i;
- getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y,
+ border_size, border_size,
+ dest_x - border_size, dest_y - border_size);
+ BlitBitmap(src_bitmap, drawto, src_x + border_xpos, src_y,
+ border_size, border_size,
+ dest_x + width, dest_y - border_size);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y + border_ypos,
+ border_size, border_size,
+ dest_x - border_size, dest_y + height);
+ BlitBitmap(src_bitmap, drawto, src_x + border_xpos, src_y + border_ypos,
+ border_size, border_size,
+ dest_x + width, dest_y + height);
+
+ for (i = 0; i < width / tilesize; i++)
+ {
+ BlitBitmap(src_bitmap, drawto, src_x + border_size, src_y,
+ tilesize, border_size,
+ dest_x + i * tilesize, dest_y - border_size);
+ BlitBitmap(src_bitmap, drawto, src_x + border_size, src_y + border_ypos,
+ tilesize, border_size,
+ dest_x + i * tilesize, dest_y + height);
+ }
- for (y = 0; y < num_mini_tiley; y++)
- for (x = 0; x < num_mini_tilex; x++)
- BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY,
- from_x + x * MINI_TILEX, from_y + y * MINI_TILEY);
+ for (i = 0; i < height / tilesize; i++)
+ {
+ BlitBitmap(src_bitmap, drawto, src_x, src_y + border_size,
+ border_size, tilesize,
+ dest_x - border_size, dest_y + i * tilesize);
+ BlitBitmap(src_bitmap, drawto, src_x + border_xpos, src_y + border_size,
+ border_size, tilesize,
+ dest_x + width, dest_y + i * tilesize);
+ }
ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2);
+}
- DrawSimpleBlackLine(drawto, from_x, from_y, to_x, from_y);
- DrawSimpleBlackLine(drawto, to_x, from_y, to_x, to_y);
- DrawSimpleBlackLine(drawto, to_x, to_y, from_x, to_y);
- DrawSimpleBlackLine(drawto, from_x, to_y, from_x, from_y);
+static void DrawEditorElement(int x, int y, int element)
+{
+ DrawSizedElement(x, y, element, ed_tilesize);
+}
+
+static void DrawEditorElementOrWall(int x, int y, int scroll_x, int scroll_y)
+{
+ DrawSizedElementOrWall(x, y, scroll_x, scroll_y, ed_tilesize);
+}
+
+static void DrawEditorLevel(int size_x, int size_y, int scroll_x, int scroll_y)
+{
+ DrawSizedLevel(size_x, size_y, scroll_x, scroll_y, ed_tilesize);
}
static void DrawDrawingArea(int id)
int *value = drawingarea_info[id].value;
int area_xsize = drawingarea_info[id].area_xsize;
int area_ysize = drawingarea_info[id].area_ysize;
+ int tilesize = ED_DRAWINGAREA_TILE_SIZE;
for (x = 0; x < area_xsize; x++)
for (y = 0; y < area_ysize; y++)
- DrawMiniGraphicExt(drawto,
- gi->x + x * MINI_TILEX,
- gi->y + y * MINI_TILEY,
- el2edimg(value[x * area_ysize + y]));
+ DrawSizedGraphicExt(drawto,
+ gi->x + x * tilesize,
+ gi->y + y * tilesize,
+ el2edimg(value[x * area_ysize + y]), 0, tilesize);
}
-static void ScrollMiniLevel(int from_x, int from_y, int scroll)
+static void ScrollEditorLevel(int from_x, int from_y, int scroll)
{
- int x,y;
+ 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);
BlitBitmap(drawto, drawto,
- SX + (dx == -1 ? MINI_TILEX : 0),
- SY + (dy == -1 ? MINI_TILEY : 0),
- (ed_fieldx * MINI_TILEX) - (dx != 0 ? MINI_TILEX : 0),
- (ed_fieldy * MINI_TILEY) - (dy != 0 ? MINI_TILEY : 0),
- SX + (dx == +1 ? MINI_TILEX : 0),
- SY + (dy == +1 ? MINI_TILEY : 0));
+ SX + (dx == -1 ? ed_tilesize : 0),
+ SY + (dy == -1 ? ed_tilesize : 0),
+ (ed_fieldx * ed_tilesize) - (dx != 0 ? ed_tilesize : 0),
+ (ed_fieldy * ed_tilesize) - (dy != 0 ? ed_tilesize : 0),
+ SX + (dx == +1 ? ed_tilesize : 0),
+ SY + (dy == +1 ? ed_tilesize : 0));
+
if (dx)
{
x = (dx == 1 ? 0 : ed_fieldx - 1);
for (y = 0; y < ed_fieldy; y++)
- DrawMiniElementOrWall(x, y, from_x, from_y);
+ DrawEditorElementOrWall(x, y, from_x, from_y);
}
else if (dy)
{
y = (dy == 1 ? 0 : ed_fieldy - 1);
for (x = 0; x < ed_fieldx; x++)
- DrawMiniElementOrWall(x, y, from_x, from_y);
+ DrawEditorElementOrWall(x, y, from_x, from_y);
}
redraw_mask |= REDRAW_FIELD;
BackToFront();
}
+void getEditorGraphicSource(int element, int tile_size, Bitmap **bitmap,
+ int *x, int *y)
+{
+ getSizedGraphicSource(el2edimg(element), 0, tile_size, bitmap, x, y);
+}
+
static void CreateControlButtons()
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
- unsigned long event_mask;
int i;
/* create toolbox buttons */
for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
{
- int id = i;
- int width, height;
- int gd_xoffset, gd_yoffset;
- int gd_x1, gd_x2, gd_y1, gd_y2;
- int button_type;
- int radio_button_nr;
- boolean checked;
-
- if (id == GADGET_ID_SINGLE_ITEMS ||
- id == GADGET_ID_CONNECTED_ITEMS ||
- id == GADGET_ID_LINE ||
- id == GADGET_ID_ARC ||
- id == GADGET_ID_TEXT ||
- id == GADGET_ID_RECTANGLE ||
- id == GADGET_ID_FILLED_BOX ||
- id == GADGET_ID_FLOOD_FILL ||
- id == GADGET_ID_GRAB_BRUSH ||
- id == GADGET_ID_PICK_ELEMENT ||
- id == GADGET_ID_CUSTOM_COPY_FROM ||
- id == GADGET_ID_CUSTOM_COPY_TO ||
- id == GADGET_ID_CUSTOM_EXCHANGE)
+ int id = controlbutton_info[i].gadget_id;
+ int type = controlbutton_info[i].gadget_type;
+ int graphic = controlbutton_info[i].graphic;
+ struct XYTileSize *pos = controlbutton_info[i].pos;
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ Bitmap *deco_bitmap = NULL;
+ int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
+ int tile_size = 0, deco_shift = 0;
+ boolean deco_masked = FALSE;
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int gd_x1a = gd->src_x + gd->active_xoffset;
+ int gd_y1a = gd->src_y + gd->active_yoffset;
+ int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset;
+ int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset;
+ int x = pos->x;
+ int y = pos->y;
+ unsigned int event_mask;
+ int radio_button_nr = RADIO_NR_NONE;
+ boolean checked = FALSE;
+
+ if (type == GD_TYPE_RADIO_BUTTON)
{
- button_type = GD_TYPE_RADIO_BUTTON;
- radio_button_nr = RADIO_NR_DRAWING_TOOLBOX;
- checked = (id == drawing_function ? TRUE : FALSE);
event_mask = GD_EVENT_PRESSED;
+ radio_button_nr = RADIO_NR_DRAWING_TOOLBOX;
+
+ if (id == drawing_function)
+ checked = TRUE;
}
else
{
- button_type = GD_TYPE_NORMAL_BUTTON;
- radio_button_nr = RADIO_NR_NONE;
- checked = FALSE;
-
if (id == GADGET_ID_WRAP_LEFT ||
id == GADGET_ID_WRAP_RIGHT ||
id == GADGET_ID_WRAP_UP ||
event_mask = GD_EVENT_RELEASED;
}
- if (id < ED_NUM_CTRL1_BUTTONS)
+ if (id == GADGET_ID_PROPERTIES ||
+ id == GADGET_ID_PALETTE)
{
- 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;
-
- gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
- gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_GFX_YPOS + gd_yoffset;
- gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
- }
- else if (id < ED_NUM_CTRL1_2_BUTTONS)
- {
- 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_y1 = DOOR_GFX_PAGEY1 + ED_CTRL2_BUTTONS_GFX_YPOS + gd_yoffset;
- gd_y2 = 0; /* no alternative graphic for these buttons */
+ x += DX;
+ y += DY;
}
- else if (id < ED_NUM_CTRL1_3_BUTTONS)
+ else if (id == GADGET_ID_ELEMENT_LEFT ||
+ id == GADGET_ID_ELEMENT_MIDDLE ||
+ id == GADGET_ID_ELEMENT_RIGHT)
{
- int x = (i - ED_NUM_CTRL1_2_BUTTONS) % ED_CTRL3_BUTTONS_HORIZ + 1;
- int y = (i - ED_NUM_CTRL1_2_BUTTONS) / ED_CTRL3_BUTTONS_HORIZ;
-
- gd_xoffset = ED_CTRL3_BUTTONS_XPOS + x * ED_CTRL3_BUTTON_XSIZE;
- gd_yoffset = ED_CTRL3_BUTTONS_YPOS + y * ED_CTRL3_BUTTON_YSIZE;
- width = ED_CTRL3_BUTTON_XSIZE;
- height = ED_CTRL3_BUTTON_YSIZE;
-
- gd_x1 = DOOR_GFX_PAGEX6 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX5 + gd_xoffset;
- gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_GFX_YPOS + gd_yoffset;
- gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
+ x += DX;
+ y += DY;
+
+ int element = (id == GADGET_ID_ELEMENT_LEFT ? new_element1 :
+ id == GADGET_ID_ELEMENT_MIDDLE ? new_element2 :
+ id == GADGET_ID_ELEMENT_RIGHT ? new_element3 : EL_EMPTY);
+
+ tile_size = BUTTON_TILE_SIZE(id == GADGET_ID_ELEMENT_LEFT ?
+ editor.button.element_left.tile_size :
+ id == GADGET_ID_ELEMENT_MIDDLE ?
+ editor.button.element_middle.tile_size :
+ id == GADGET_ID_ELEMENT_RIGHT ?
+ editor.button.element_right.tile_size : 0);
+
+ // make sure that decoration does not overlap gadget border
+ tile_size = MIN(tile_size, MIN(gd->width, gd->height));
+
+ getEditorGraphicSource(element, tile_size, &deco_bitmap, &deco_x,&deco_y);
+
+ deco_xpos = (gd->width - tile_size) / 2;
+ deco_ypos = (gd->height - tile_size) / 2;
+ deco_shift = 1;
+ deco_masked = gd->draw_masked;
}
else
{
- int x = (i - ED_NUM_CTRL1_3_BUTTONS) % ED_CTRL4_BUTTONS_HORIZ;
- int y = (i - ED_NUM_CTRL1_3_BUTTONS) / ED_CTRL4_BUTTONS_HORIZ + 3;
-
- gd_xoffset = ED_CTRL4_BUTTONS_XPOS + x * ED_CTRL4_BUTTON_XSIZE;
- gd_yoffset = ED_CTRL4_BUTTONS_YPOS + y * ED_CTRL4_BUTTON_YSIZE;
- width = ED_CTRL4_BUTTON_XSIZE;
- height = ED_CTRL4_BUTTON_YSIZE;
-
- gd_x1 = DOOR_GFX_PAGEX6 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX5 + ED_CTRL4_BUTTONS_GFX_XPOS + gd_xoffset;
- gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL4_BUTTONS_GFX_YPOS + gd_yoffset;
- gd_y2 = 0; /* no alternative graphic for these buttons */
+ x += EX;
+ y += EY;
}
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_INFO_TEXT, control_info[i].text,
- GDI_X, EX + gd_xoffset,
- GDI_Y, EY + gd_yoffset,
- GDI_WIDTH, width,
- GDI_HEIGHT, height,
- GDI_TYPE, button_type,
+ GDI_INFO_TEXT, controlbutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
+ GDI_TYPE, type,
GDI_STATE, GD_BUTTON_UNPRESSED,
GDI_RADIO_NR, radio_button_nr,
GDI_CHECKED, checked,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
- GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
- GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a,
+ GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a,
+ GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
+ GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
+ GDI_DECORATION_SIZE, tile_size, tile_size,
+ GDI_DECORATION_SHIFTING, deco_shift, deco_shift,
+ GDI_DECORATION_MASKED, deco_masked,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleControlButtons,
level_editor_gadget[id] = gi;
}
+ /* these values are not constant, but can change at runtime */
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_UP].x = ED_SCROLL_UP_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_UP].y = ED_SCROLL_UP_YPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_DOWN].x = ED_SCROLL_DOWN_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_DOWN].y = ED_SCROLL_DOWN_YPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_LEFT].x = ED_SCROLL_LEFT_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_LEFT].y = ED_SCROLL_LEFT_YPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].x = ED_SCROLL_RIGHT_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_AREA_RIGHT].y = ED_SCROLL_RIGHT_YPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_UP].x = ED_SCROLL2_UP_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_UP].y = ED_SCROLL2_UP_YPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_DOWN].x = ED_SCROLL2_DOWN_XPOS;
+ scrollbutton_pos[ED_SCROLLBUTTON_ID_LIST_DOWN].y = ED_SCROLL2_DOWN_YPOS;
+
/* create buttons for scrolling of drawing area and element list */
for (i = 0; i < ED_NUM_SCROLLBUTTONS; i++)
{
int id = scrollbutton_info[i].gadget_id;
- int x, y, width, height;
- int gd_x1, gd_x2, gd_y1, gd_y2;
-
- x = scrollbutton_info[i].x;
- y = scrollbutton_info[i].y;
-
- event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
+ int graphic = scrollbutton_info[i].graphic;
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ Bitmap *gd_bitmap = gd->bitmap;
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int width = gd->width;
+ int height = gd->height;
+ int x = scrollbutton_pos[i].x;
+ int y = scrollbutton_pos[i].y;
+ unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
if (id == GADGET_ID_SCROLL_LIST_UP ||
id == GADGET_ID_SCROLL_LIST_DOWN)
{
- x += DX;
- y += DY;
- width = ED_SCROLLBUTTON2_XSIZE;
- height = ED_SCROLLBUTTON2_YSIZE;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
- gd_x2 = gd_x1 - ED_SCROLLBUTTON2_XSIZE;
- gd_y2 = gd_y1;
+ x += PX;
+ y += PY;
}
else
{
x += SX;
y += SY;
- width = ED_SCROLLBUTTON_XSIZE;
- height = ED_SCROLLBUTTON_YSIZE;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
- gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
- gd_y2 = gd_y1;
}
gi = CreateGadget(GDI_CUSTOM_ID, id,
/* create buttons for element list */
for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
{
+ int id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ int graphic = IMG_EDITOR_PALETTE_BUTTON;
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ Bitmap *gd_bitmap = gd->bitmap;
Bitmap *deco_bitmap;
int deco_x, deco_y, deco_xpos, deco_ypos;
- int gd_xoffset, gd_yoffset;
- int gd_x1, gd_x2, gd_y;
- int x = i % ED_ELEMENTLIST_BUTTONS_HORIZ;
- int y = i / ED_ELEMENTLIST_BUTTONS_HORIZ;
- int id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int xx = i % ED_ELEMENTLIST_BUTTONS_HORIZ;
+ int yy = i / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ int x = PX + ED_ELEMENTLIST_XPOS + xx * gd->width;
+ int y = PY + ED_ELEMENTLIST_YPOS + yy * gd->height;
int element = editor_elements[i];
+ int tile_size = BUTTON_TILE_SIZE(editor.palette.tile_size);
+ unsigned int event_mask = GD_EVENT_RELEASED;
- event_mask = GD_EVENT_RELEASED;
-
- gd_xoffset = ED_ELEMENTLIST_XPOS + x * ED_ELEMENTLIST_XSIZE;
- gd_yoffset = ED_ELEMENTLIST_YPOS + y * ED_ELEMENTLIST_YSIZE;
+ getEditorGraphicSource(element, tile_size, &deco_bitmap, &deco_x, &deco_y);
- gd_x1 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS + ED_ELEMENTLIST_XSIZE;
- gd_x2 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_ELEMENTLIST_YPOS;
-
- getMiniGraphicSource(el2edimg(element), &deco_bitmap, &deco_x, &deco_y);
- deco_xpos = (ED_ELEMENTLIST_XSIZE - MINI_TILEX) / 2;
- deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2;
+ deco_xpos = (gd->width - tile_size) / 2;
+ deco_ypos = (gd->height - tile_size) / 2;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, getElementInfoText(element),
- GDI_X, DX + gd_xoffset,
- GDI_Y, DY + gd_yoffset,
- GDI_WIDTH, ED_ELEMENTLIST_XSIZE,
- GDI_HEIGHT, ED_ELEMENTLIST_YSIZE,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
- GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_DECORATION_SIZE, tile_size, tile_size,
GDI_DECORATION_SHIFTING, 1, 1,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
for (i = 0; i < ED_NUM_COUNTERBUTTONS; i++)
{
int j;
- int x = SX + counterbutton_info[i].x; /* down count button */
- int y = SY + counterbutton_info[i].y;
+ int x = SX + ED_SETTINGS_X(counterbutton_info[i].x); /* down count button */
+ int y = SY + ED_SETTINGS_Y(counterbutton_info[i].y);
/* determine horizontal position to the right of specified gadget */
if (counterbutton_info[i].gadget_id_align != GADGET_ID_NONE)
for (j = 0; j < 2; j++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
int id = (j == 0 ?
counterbutton_info[i].gadget_id_down :
counterbutton_info[i].gadget_id_up);
- int gd_xoffset;
- int gd_x, gd_x1, gd_x2, gd_y;
- int x_size, y_size;
- unsigned long event_mask;
+ int graphic;
+ struct GraphicInfo *gd;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ unsigned int event_mask;
char infotext[max_infotext_len + 1];
event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
if (i == ED_COUNTER_ID_SELECT_LEVEL)
{
- int sid = (j == 0 ?
- ED_SCROLLBUTTON_ID_AREA_LEFT :
- ED_SCROLLBUTTON_ID_AREA_RIGHT);
+ graphic = (j == 0 ?
+ IMG_GFX_EDITOR_BUTTON_PREV_LEVEL :
+ IMG_GFX_EDITOR_BUTTON_NEXT_LEVEL);
event_mask |= GD_EVENT_RELEASED;
- if (j == 1)
- x += 2 * ED_GADGET_DISTANCE;
- y += ED_GADGET_DISTANCE;
-
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].gd_x;
- gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
- gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].gd_y;
- x_size = ED_SCROLLBUTTON_XSIZE;
- y_size = ED_SCROLLBUTTON_YSIZE;
+ if (j == 0)
+ {
+ x = DX + editor.button.prev_level.x;
+ y = DY + editor.button.prev_level.y;
+ }
+ else
+ {
+ x = DX + editor.button.next_level.x;
+ y = DY + editor.button.next_level.y;
+ }
}
else
{
- gd_xoffset = (j == 0 ? ED_BUTTON_MINUS_XPOS : ED_BUTTON_PLUS_XPOS);
- gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
- gd_y = DOOR_GFX_PAGEY1 + ED_BUTTON_COUNT_YPOS;
- x_size = ED_BUTTON_COUNT_XSIZE;
- y_size = ED_BUTTON_COUNT_YSIZE;
+ graphic = (j == 0 ?
+ IMG_EDITOR_COUNTER_DOWN :
+ IMG_EDITOR_COUNTER_UP);
}
+ gd = &graphic_info[graphic];
+
+ gd_x1 = gd->src_x;
+ gd_y1 = gd->src_y;
+ gd_x2 = gd->src_x + gd->pressed_xoffset;
+ gd_y2 = gd->src_y + gd->pressed_yoffset;
+
sprintf(infotext, "%s counter value by 1, 5 or 10",
(j == 0 ? "decrease" : "increase"));
GDI_INFO_TEXT, infotext,
GDI_X, x,
GDI_Y, y,
- GDI_WIDTH, x_size,
- GDI_HEIGHT, y_size,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleCounterButtons,
right_gadget_border[id] =
getRightGadgetBorder(gi, counterbutton_info[i].text_right);
- x += gi->width + ED_GADGET_DISTANCE; /* text count button */
+ x += gi->width + ED_GADGET_SMALL_DISTANCE; /* text count button */
if (j == 0)
{
int font_type = FONT_INPUT_1;
int font_type_active = FONT_INPUT_1_ACTIVE;
- int gd_width = ED_WIN_COUNT_XSIZE;
id = counterbutton_info[i].gadget_id_text;
+
event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
if (i == ED_COUNTER_ID_SELECT_LEVEL)
{
+ graphic = IMG_GFX_EDITOR_INPUT_LEVEL_NUMBER;
+
font_type = FONT_LEVEL_NUMBER;
-#if 1
font_type_active = FONT_LEVEL_NUMBER_ACTIVE;
-#else
- font_type_active = FONT_LEVEL_NUMBER;
-#endif
- x += 2 * ED_GADGET_DISTANCE;
- y -= ED_GADGET_DISTANCE;
- gd_x = DOOR_GFX_PAGEX6 + ED_WIN_COUNT2_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT2_YPOS;
- gd_width = ED_WIN_COUNT2_XSIZE;
+ x = DX + editor.input.level_number.x;
+ y = DY + editor.input.level_number.y;
}
else
{
- gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
+ graphic = IMG_EDITOR_COUNTER_INPUT;
}
+ gd = &graphic_info[graphic];
+
+ gd_x1 = gd->src_x;
+ gd_y1 = gd->src_y;
+ gd_x2 = gd->src_x + gd->active_xoffset;
+ gd_y2 = gd->src_y + gd->active_yoffset;
+
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, "enter counter value",
GDI_TEXT_SIZE, 3, /* minimal counter text size */
GDI_TEXT_FONT, font_type,
GDI_TEXT_FONT_ACTIVE, font_type_active,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_DESIGN_WIDTH, gd_width,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, gd->border_size, gd->border_size,
+ GDI_DESIGN_WIDTH, gd->width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleCounterButtons,
right_gadget_border[id] =
getRightGadgetBorder(gi, counterbutton_info[i].text_right);
- x += gi->width + ED_GADGET_DISTANCE; /* up count button */
+ x += gi->width + ED_GADGET_SMALL_DISTANCE; /* up count button */
}
}
}
{
int i;
+ /* these values are not constant, but can change at runtime */
+ drawingarea_info[ED_DRAWING_ID_DRAWING_LEVEL].area_xsize = MAX_ED_FIELDX;
+ drawingarea_info[ED_DRAWING_ID_DRAWING_LEVEL].area_ysize = MAX_ED_FIELDY;
+
for (i = 0; i < ED_NUM_DRAWING_AREAS; i++)
{
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
int id = drawingarea_info[i].gadget_id;
- int x = SX + drawingarea_info[i].x;
- int y = SY + drawingarea_info[i].y;
+ int x = SX + ED_AREA_SETTINGS_X(drawingarea_info[i]);
+ int y = SY + ED_AREA_SETTINGS_Y(drawingarea_info[i]);
int area_xsize = drawingarea_info[i].area_xsize;
int area_ysize = drawingarea_info[i].area_ysize;
+ int item_size = (id == GADGET_ID_DRAWING_LEVEL ?
+ ed_tilesize : ED_DRAWINGAREA_TILE_SIZE);
event_mask =
GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING |
GDI_Y, y,
GDI_TYPE, GD_TYPE_DRAWING_AREA,
GDI_AREA_SIZE, area_xsize, area_ysize,
- GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_ITEM_SIZE, item_size, item_size,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
GDI_CALLBACK_ACTION, HandleDrawingAreas,
static void CreateTextInputGadgets()
{
+ struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_INPUT_TEXT];
int max_infotext_len = getMaxInfoTextLength();
int i;
for (i = 0; i < ED_NUM_TEXTINPUT; i++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- int gd_x, gd_y;
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->active_xoffset;
+ int gd_y2 = gd->src_y + gd->active_yoffset;
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = textinput_info[i].gadget_id;
+ int x, y;
- event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
+ if (i == ED_TEXTINPUT_ID_ELEMENT_NAME)
+ {
+ int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size;
+ int border_size = gd->border_size;
+ int font_nr = FONT_INPUT_1;
+ int font_height = getFontHeight(font_nr);
+ int xoffset = element_border + TILEX + element_border + 3 * border_size;
+ int yoffset = element_border + (TILEY - font_height) / 2;
+
+ x = (editor.settings.element_name.x != -1 ?
+ editor.settings.element_name.x :
+ editor.settings.element_graphic.x + xoffset) - border_size;
+ y = (editor.settings.element_name.y != -1 ?
+ editor.settings.element_name.y :
+ editor.settings.element_graphic.y + yoffset) - border_size;
+ }
+ else
+ {
+ x = ED_SETTINGS_X(textinput_info[i].x);
+ y = ED_SETTINGS_Y(textinput_info[i].y);
+ }
- 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;
sprintf(infotext, "Enter %s", textinput_info[i].infotext);
infotext[max_infotext_len] = '\0';
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, infotext,
- GDI_X, SX + textinput_info[i].x,
- GDI_Y, SY + textinput_info[i].y,
+ GDI_X, SX + x,
+ GDI_Y, SY + y,
GDI_TYPE, GD_TYPE_TEXT_INPUT_ALPHANUMERIC,
GDI_TEXT_VALUE, textinput_info[i].value,
GDI_TEXT_SIZE, textinput_info[i].size,
GDI_TEXT_FONT, FONT_INPUT_1,
GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, gd->border_size, gd->border_size,
+ GDI_DESIGN_WIDTH, gd->width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleTextInputGadgets,
for (i = 0; i < ED_NUM_TEXTAREAS; i++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- int gd_x, gd_y;
+ struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_INPUT_TEXTAREA];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->active_xoffset;
+ int gd_y2 = gd->src_y + gd->active_yoffset;
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = textarea_info[i].gadget_id;
int area_xsize = textarea_info[i].xsize;
event_mask = GD_EVENT_TEXT_LEAVING;
- gd_x = DOOR_GFX_PAGEX4 + ED_WIN_COUNT_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
-
sprintf(infotext, "Enter %s", textarea_info[i].infotext);
infotext[max_infotext_len] = '\0';
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, infotext,
- GDI_X, SX + textarea_info[i].x,
- GDI_Y, SY + textarea_info[i].y,
+ GDI_X, SX + ED_SETTINGS_X(textarea_info[i].x),
+ GDI_Y, SY + ED_SETTINGS_Y(textarea_info[i].y),
GDI_TYPE, GD_TYPE_TEXT_AREA,
GDI_AREA_SIZE, area_xsize, area_ysize,
GDI_TEXT_FONT, FONT_INPUT_1,
GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, gd->border_size, gd->border_size,
+ GDI_DESIGN_WIDTH, gd->width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleTextAreaGadgets,
for (i = 0; i < ED_NUM_SELECTBOX; i++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- int gd_x, gd_y;
+ struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_SELECTBOX_INPUT];
+ struct GraphicInfo *gd2 = &graphic_info[IMG_EDITOR_SELECTBOX_BUTTON];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->active_xoffset;
+ int gd_y2 = gd->src_y + gd->active_yoffset;
+ int selectbox_button_xsize = gd2->width;
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = selectbox_info[i].gadget_id;
- int x = SX + selectbox_info[i].x;
- int y = SY + selectbox_info[i].y;
+ int x = SX + ED_SETTINGS_X(selectbox_info[i].x);
+ int y = SY + ED_SETTINGS_Y(selectbox_info[i].y);
if (selectbox_info[i].size == -1) /* dynamically determine size */
{
event_mask = GD_EVENT_RELEASED |
GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
- gd_x = DOOR_GFX_PAGEX4 + ED_SELECTBOX_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_SELECTBOX_YPOS;
-
/* determine horizontal position to the right of specified gadget */
if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE)
x = (right_gadget_border[selectbox_info[i].gadget_id_align] +
GDI_Y, y,
GDI_TYPE, GD_TYPE_SELECTBOX,
GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
+ GDI_SELECTBOX_CHAR_UNSELECTABLE, '[',
GDI_TEXT_SIZE, selectbox_info[i].size,
GDI_TEXT_FONT, FONT_INPUT_1,
GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_BORDER_SIZE_SELECTBUTTON, ED_SELECTBOX_BUTTON_XSIZE,
- GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_TEXT_FONT_UNSELECTABLE, FONT_TEXT_1,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, gd->border_size, gd->border_size,
+ GDI_BORDER_SIZE_SELECTBUTTON, selectbox_button_xsize,
+ GDI_DESIGN_WIDTH, gd->width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleSelectboxGadgets,
for (i = 0; i < ED_NUM_TEXTBUTTONS; i++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- int gd_x1, gd_x2, gd_y1, gd_y2;
+ int id = textbutton_info[i].gadget_id;
+ int is_tab_button =
+ ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) ||
+ (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE));
+ int graphic =
+ (is_tab_button ? IMG_EDITOR_TABBUTTON : IMG_EDITOR_TEXTBUTTON);
+ int gadget_distance =
+ (is_tab_button ? ED_GADGET_SMALL_DISTANCE : ED_GADGET_TEXT_DISTANCE);
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int gd_x1a = gd->src_x + gd->active_xoffset;
+ int gd_y1a = gd->src_y + gd->active_yoffset;
+ int border_xsize = gd->border_size + gd->draw_xoffset;
+ int border_ysize = gd->border_size;
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
- int id = textbutton_info[i].gadget_id;
- int x = SX + textbutton_info[i].x;
- int y = SY + textbutton_info[i].y;
+ int x = SX + ED_SETTINGS_X(textbutton_info[i].x);
+ int y = SY + ED_SETTINGS_Y(textbutton_info[i].y);
if (textbutton_info[i].size == -1) /* dynamically determine size */
textbutton_info[i].size = strlen(textbutton_info[i].text);
event_mask = GD_EVENT_RELEASED;
- if (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE)
- {
- gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_TAB_XPOS;
- gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_TAB_XPOS;
- gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_YPOS;
- gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_INACTIVE_YPOS;
- }
- else
- {
- gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_XPOS;
- gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_XPOS;
- gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_YPOS;
- gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_INACTIVE_YPOS;
- }
-
sprintf(infotext, "%s", textbutton_info[i].infotext);
infotext[max_infotext_len] = '\0';
/* determine horizontal position to the right of specified gadget */
if (textbutton_info[i].gadget_id_align != GADGET_ID_NONE)
- x = (right_gadget_border[textbutton_info[i].gadget_id_align] +
- ED_GADGET_TEXT_DISTANCE);
+ {
+ int gadget_id_align = textbutton_info[i].gadget_id_align;
+
+ x = right_gadget_border[gadget_id_align] + gadget_distance;
+
+ if (textbutton_info[i].y == -1)
+ y = level_editor_gadget[gadget_id_align]->y;
+ }
/* determine horizontal offset for leading text */
if (textbutton_info[i].text_left != NULL)
GDI_TYPE, GD_TYPE_TEXT_BUTTON,
GDI_TEXT_VALUE, textbutton_info[i].text,
GDI_TEXT_SIZE, textbutton_info[i].size,
- GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE,
- GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
- GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
- GDI_BORDER_SIZE, ED_BORDER_TEXT_XSIZE, ED_BORDER_SIZE,
- GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_TEXT_FONT, FONT_INPUT_2,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2_ACTIVE,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a,
+ GDI_BORDER_SIZE, border_xsize, border_ysize,
+ GDI_DESIGN_WIDTH, gd->width,
GDI_DECORATION_SHIFTING, 1, 1,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
static void CreateGraphicbuttonGadgets()
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
- unsigned long event_mask;
+ unsigned int event_mask;
int i;
/* create buttons for scrolling of drawing area and element list */
for (i = 0; i < ED_NUM_GRAPHICBUTTONS; i++)
{
int id = graphicbutton_info[i].gadget_id;
- int gd_x1, gd_x2, gd_y1, gd_y2;
- int x = SX + graphicbutton_info[i].x;
- int y = SY + graphicbutton_info[i].y;
+ int x = SX + ED_SETTINGS_X(graphicbutton_info[i].x);
+ int y = SY + ED_SETTINGS_Y(graphicbutton_info[i].y);
+ struct GraphicInfo *gd = &graphic_info[graphicbutton_info[i].graphic];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
- if (i <= ED_GRAPHICBUTTON_ID_NEXT_CHANGE_PAGE)
- {
- gd_x1 = DOOR_GFX_PAGEX4 + graphicbutton_info[i].gd_x;
- gd_y1 = DOOR_GFX_PAGEY1 + graphicbutton_info[i].gd_y;
- gd_x2 = DOOR_GFX_PAGEX3 + graphicbutton_info[i].gd_x;
- gd_y2 = gd_y1;
- }
- else /* (i <= ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE) */
- {
- gd_x1 = DOOR_GFX_PAGEX6 + graphicbutton_info[i].gd_x;
- gd_y1 = DOOR_GFX_PAGEY1 + graphicbutton_info[i].gd_y;
- gd_x2 = gd_x1 - ED_BUTTON_COUNT_XSIZE;
- gd_y2 = gd_y1;
- }
-
/* determine horizontal position to the right of specified gadget */
if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE)
x = (right_gadget_border[graphicbutton_info[i].gadget_id_align] +
GDI_INFO_TEXT, graphicbutton_info[i].infotext,
GDI_X, x,
GDI_Y, y,
- GDI_WIDTH, graphicbutton_info[i].width,
- GDI_HEIGHT, graphicbutton_info[i].height,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleGraphicbuttonGadgets,
{
int i;
+ /* these values are not constant, but can change at runtime */
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].x =
+ SX + ED_SCROLL_HORIZONTAL_XPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].y =
+ SY + ED_SCROLL_HORIZONTAL_YPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width =
+ ED_SCROLL_HORIZONTAL_XSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].height =
+ ED_SCROLL_HORIZONTAL_YSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_x = SX;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_y = SY;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_width = SXSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_height = SYSIZE;
+
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].x =
+ SX + ED_SCROLL_VERTICAL_XPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].y =
+ SY + ED_SCROLL_VERTICAL_YPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].width =
+ ED_SCROLL_VERTICAL_XSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].height =
+ ED_SCROLL_VERTICAL_YSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_x = SX;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_y = SY;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_width = SXSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_height = SYSIZE;
+
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].x =
+ PX + ED_SCROLL2_VERTICAL_XPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].y =
+ PY + ED_SCROLL2_VERTICAL_YPOS;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].width =
+ ED_SCROLL2_VERTICAL_XSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].height =
+ ED_SCROLL2_VERTICAL_YSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_x = PX;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_y = PY;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_width = PXSIZE;
+ scrollbar_pos[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_height = PYSIZE;
+
for (i = 0; i < ED_NUM_SCROLLBARS; i++)
{
int id = scrollbar_info[i].gadget_id;
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- int gd_x1, gd_x2, gd_y1, gd_y2;
+ int graphic = scrollbar_info[i].graphic;
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
struct GadgetInfo *gi;
int items_max, items_visible, item_position;
- unsigned long event_mask;
+ unsigned int event_mask;
if (i == ED_SCROLLBAR_ID_LIST_VERTICAL)
{
event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].gd_x;
- gd_x2 = (gd_x1 - (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL ?
- scrollbar_info[i].height : scrollbar_info[i].width));
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
- gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
-
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, scrollbar_info[i].infotext,
- GDI_X, scrollbar_info[i].x,
- GDI_Y, scrollbar_info[i].y,
- GDI_WIDTH, scrollbar_info[i].width,
- GDI_HEIGHT, scrollbar_info[i].height,
+ GDI_X, scrollbar_pos[i].x,
+ GDI_Y, scrollbar_pos[i].y,
+ GDI_WIDTH, scrollbar_pos[i].width,
+ GDI_HEIGHT, scrollbar_pos[i].height,
GDI_TYPE, scrollbar_info[i].type,
GDI_SCROLLBAR_ITEMS_MAX, items_max,
GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
GDI_SCROLLBAR_ITEM_POSITION, item_position,
- GDI_WHEEL_AREA_X, scrollbar_info[i].wheel_x,
- GDI_WHEEL_AREA_Y, scrollbar_info[i].wheel_y,
- GDI_WHEEL_AREA_WIDTH, scrollbar_info[i].wheel_width,
- GDI_WHEEL_AREA_HEIGHT, scrollbar_info[i].wheel_height,
+ GDI_WHEEL_AREA_X, scrollbar_pos[i].wheel_x,
+ GDI_WHEEL_AREA_Y, scrollbar_pos[i].wheel_y,
+ GDI_WHEEL_AREA_WIDTH, scrollbar_pos[i].wheel_width,
+ GDI_WHEEL_AREA_HEIGHT, scrollbar_pos[i].wheel_height,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
- GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, gd->border_size, gd->border_size,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleControlButtons,
static void CreateCheckbuttonGadgets()
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
- unsigned long event_mask;
- int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
+ unsigned int event_mask;
int i;
event_mask = GD_EVENT_PRESSED;
- gd_x1 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_UNCHECKED_XPOS;
- gd_x2 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_UNCHECKED_XPOS;
- gd_x3 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_CHECKED_XPOS;
- gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
-
for (i = 0; i < ED_NUM_CHECKBUTTONS; i++)
{
int id = checkbutton_info[i].gadget_id;
- int x = SX + checkbutton_info[i].x;
- int y = SY + checkbutton_info[i].y;
-
- if (id == GADGET_ID_STICK_ELEMENT)
- gd_y = DOOR_GFX_PAGEY1 + ED_STICKYBUTTON_YPOS;
- else
- gd_y = DOOR_GFX_PAGEY1 + ED_CHECKBUTTON_YPOS;
+ int graphic = (id == GADGET_ID_STICK_ELEMENT ? IMG_EDITOR_STICKYBUTTON :
+ IMG_EDITOR_CHECKBOX);
+ struct GraphicInfo *gd = &graphic_info[graphic];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int gd_x1a = gd->src_x + gd->active_xoffset;
+ int gd_y1a = gd->src_y + gd->active_yoffset;
+ int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset;
+ int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset;
+ int x = SX + ED_SETTINGS_X(checkbutton_info[i].x);
+ int y = SY + ED_SETTINGS_Y(checkbutton_info[i].y);
/* determine horizontal position to the right of specified gadget */
if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE)
GDI_INFO_TEXT, checkbutton_info[i].infotext,
GDI_X, x,
GDI_Y, y,
- GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
- GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
GDI_TYPE, GD_TYPE_CHECK_BUTTON,
GDI_CHECKED, *checkbutton_info[i].value,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
- GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
- GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a,
+ GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleCheckbuttons,
static void CreateRadiobuttonGadgets()
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_RADIOBUTTON];
+ int gd_x1 = gd->src_x;
+ int gd_y1 = gd->src_y;
+ int gd_x2 = gd->src_x + gd->pressed_xoffset;
+ int gd_y2 = gd->src_y + gd->pressed_yoffset;
+ int gd_x1a = gd->src_x + gd->active_xoffset;
+ int gd_y1a = gd->src_y + gd->active_yoffset;
+ int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset;
+ int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset;
struct GadgetInfo *gi;
- unsigned long event_mask;
- int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
+ unsigned int event_mask;
int i;
event_mask = GD_EVENT_PRESSED;
- gd_x1 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_UNCHECKED_XPOS;
- gd_x2 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_UNCHECKED_XPOS;
- gd_x3 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_CHECKED_XPOS;
- gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
- gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
-
for (i = 0; i < ED_NUM_RADIOBUTTONS; i++)
{
int id = radiobutton_info[i].gadget_id;
- int x = SX + radiobutton_info[i].x;
- int y = SY + radiobutton_info[i].y;
+ int x = SX + ED_SETTINGS_X(radiobutton_info[i].x);
+ int y = SY + ED_SETTINGS_Y(radiobutton_info[i].y);
int checked =
(*radiobutton_info[i].value == radiobutton_info[i].checked_value);
GDI_INFO_TEXT, radiobutton_info[i].infotext,
GDI_X, x,
GDI_Y, y,
- GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
- GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
+ GDI_WIDTH, gd->width,
+ GDI_HEIGHT, gd->height,
GDI_TYPE, GD_TYPE_RADIO_BUTTON,
GDI_RADIO_NR, radiobutton_info[i].radio_button_nr,
GDI_CHECKED, checked,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
- GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
- GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
+ GDI_DESIGN_UNPRESSED, gd->bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd->bitmap, gd_x2, gd_y2,
+ GDI_ALT_DESIGN_UNPRESSED, gd->bitmap, gd_x1a, gd_y1a,
+ GDI_ALT_DESIGN_PRESSED, gd->bitmap, gd_x2a, gd_y2a,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleRadiobuttons,
void CreateLevelEditorGadgets()
{
- int old_game_status = game_status;
+ /* force EDITOR font inside level editor */
+ SetFontStatus(GAME_MODE_EDITOR);
+
+ /* these values are not constant, but can change at runtime */
+ ed_fieldx = MAX_ED_FIELDX - 1;
+ ed_fieldy = MAX_ED_FIELDY - 1;
+
+ num_editor_gadgets = NUM_EDITOR_GADGETS;
- /* setting 'game_status' is needed to get the right fonts for the editor */
- game_status = GAME_MODE_EDITOR;
+ // printf("::: allocating %d gadgets ...\n", num_editor_gadgets);
+
+ level_editor_gadget =
+ checked_calloc(num_editor_gadgets * sizeof(struct GadgetInfo *));
+ right_gadget_border =
+ checked_calloc(num_editor_gadgets * sizeof(int));
+
+ editor_el_empty = checked_calloc(ED_NUM_ELEMENTLIST_BUTTONS * sizeof(int));
+ editor_el_empty_ptr = editor_el_empty;
+
+ use_permanent_palette = !editor.palette.show_as_separate_screen;
ReinitializeElementList();
CreateTextbuttonGadgets();
CreateDrawingAreas();
- game_status = old_game_status;
+ ResetFontStatus();
}
void FreeLevelEditorGadgets()
{
int i;
- for (i = 0; i < NUM_EDITOR_GADGETS; i++)
+ // printf("::: freeing %d gadgets ...\n", num_editor_gadgets);
+
+ for (i = 0; i < num_editor_gadgets; i++)
{
FreeGadget(level_editor_gadget[i]);
level_editor_gadget[i] = NULL;
}
+
+ checked_free(level_editor_gadget);
+ checked_free(right_gadget_border);
+
+ checked_free(editor_el_empty);
}
static void MapCounterButtons(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
int gadget_id_down = counterbutton_info[id].gadget_id_down;
int gadget_id_text = counterbutton_info[id].gadget_id_text;
int gadget_id_up = counterbutton_info[id].gadget_id_up;
struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up];
int xoffset_left = getTextWidthForGadget(counterbutton_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset_above = MINI_TILEX + ED_GADGET_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
+ int yoffset = (gi_down->height - font_height) / 2;
int x_left = gi_down->x - xoffset_left;
int x_right; /* set after gadget position was modified */
int y_above = gi_down->y - yoffset_above;
if (id >= ED_COUNTER_ID_ELEMENT_VALUE1 &&
id <= ED_COUNTER_ID_ELEMENT_VALUE4)
{
- ModifyGadget(gi_down, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
- ModifyGadget(gi_text, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
- ModifyGadget(gi_up, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
+ ModifyGadget(gi_down, GDI_Y,
+ SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
+ ModifyGadget(gi_text, GDI_Y,
+ SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
+ ModifyGadget(gi_up, GDI_Y,
+ SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END);
}
/* vertical position might have changed after setting position above */
y = gi_up->y + yoffset;
if (counterbutton_info[id].text_above)
- DrawText(x, y_above, counterbutton_info[id].text_above, FONT_TEXT_1);
+ DrawText(x, y_above, counterbutton_info[id].text_above, font_nr);
if (counterbutton_info[id].text_left)
- DrawText(x_left, y, counterbutton_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, counterbutton_info[id].text_left, font_nr);
if (counterbutton_info[id].text_right)
- DrawText(x_right, y, counterbutton_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, counterbutton_info[id].text_right, font_nr);
MapGadget(gi_down);
MapGadget(gi_text);
for (i = 0; i < ED_NUM_CTRL1_2_BUTTONS; i++)
MapGadget(level_editor_gadget[i]);
- /* map buttons to select elements */
- for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
- MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]);
- MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]);
- MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_UP]);
- MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_DOWN]);
+ /* map toolbox buttons (element properties buttons) */
+ for (i = ED_NUM_CTRL1_4_BUTTONS; i < ED_NUM_CTRL1_7_BUTTONS; i++)
+ MapGadget(level_editor_gadget[i]);
+
+ if (use_permanent_palette)
+ {
+ /* map buttons to select elements */
+ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_UP]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_DOWN]);
+ }
/* map buttons to select level */
counter_id = ED_COUNTER_ID_SELECT_LEVEL;
static void MapDrawingArea(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id];
int area_xsize = gi->drawing.area_xsize;
int area_ysize = gi->drawing.area_ysize;
- int xoffset_left= getTextWidthForDrawingArea(drawingarea_info[id].text_left);
- int xoffset_below= getTextWidth(drawingarea_info[id].text_below,FONT_TEXT_1);
+ int xoffset_left = getTextWidthForDrawingArea(drawingarea_info[id].text_left);
+ int xoffset_below = getTextWidth(drawingarea_info[id].text_below, font_nr);
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + ED_DRAWINGAREA_TEXT_DISTANCE;
int x_below = gi->x + (gi->width - xoffset_below) / 2;
- int y_side = gi->y + (gi->height - getFontHeight(FONT_TEXT_1)) / 2;
+ int y_side = gi->y + (gi->height - font_height) / 2;
int y_below = gi->y + gi->height + ED_DRAWINGAREA_TEXT_DISTANCE;
if (drawingarea_info[id].text_left)
- DrawText(x_left, y_side, drawingarea_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y_side, drawingarea_info[id].text_left, font_nr);
if (drawingarea_info[id].text_right)
- DrawText(x_right, y_side, drawingarea_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y_side, drawingarea_info[id].text_right, font_nr);
if (drawingarea_info[id].text_below)
- DrawText(x_below, y_below, drawingarea_info[id].text_below, FONT_TEXT_1);
+ DrawText(x_below, y_below, drawingarea_info[id].text_below, font_nr);
if (id != ED_DRAWING_ID_DRAWING_LEVEL)
{
DrawElementBorder(gi->x, gi->y,
- area_xsize * MINI_TILEX, area_ysize * MINI_TILEY, TRUE);
+ area_xsize * ED_DRAWINGAREA_TILE_SIZE,
+ area_ysize * ED_DRAWINGAREA_TILE_SIZE, TRUE);
DrawDrawingArea(id);
}
static void MapTextInputGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[textinput_info[id].gadget_id];
- int xoffset_above = 0;
- int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
- int x_above = textinput_info[id].x + xoffset_above;
- int y_above = textinput_info[id].y + yoffset_above;
+ int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
+ int x_above = ED_SETTINGS_X(textinput_info[id].x);
+ int y_above = ED_SETTINGS_Y(textinput_info[id].y) - yoffset_above;
if (textinput_info[id].text_above)
- DrawTextS(x_above, y_above, FONT_TEXT_1, textinput_info[id].text_above);
+ DrawTextS(x_above, y_above, font_nr, textinput_info[id].text_above);
ModifyGadget(gi, GDI_TEXT_VALUE, textinput_info[id].value, GDI_END);
static void MapTextAreaGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[textarea_info[id].gadget_id];
- int xoffset_above = 0;
- int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
- int x_above = textarea_info[id].x + xoffset_above;
- int y_above = textarea_info[id].y + yoffset_above;
+ int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
+ int x_above = ED_SETTINGS_X(textarea_info[id].x);
+ int y_above = ED_SETTINGS_Y(textarea_info[id].y) - yoffset_above;
if (textarea_info[id].text_above)
- DrawTextS(x_above, y_above, FONT_TEXT_1, textarea_info[id].text_above);
+ DrawTextS(x_above, y_above, font_nr, textarea_info[id].text_above);
ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END);
static void MapSelectboxGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id];
int xoffset_left = getTextWidthForGadget(selectbox_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset = (gi->height - font_height) / 2;
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + xoffset_right;
int y = gi->y + yoffset;
if (selectbox_info[id].text_left)
- DrawText(x_left, y, selectbox_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, selectbox_info[id].text_left, font_nr);
if (selectbox_info[id].text_right)
- DrawText(x_right, y, selectbox_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, selectbox_info[id].text_right, font_nr);
ModifyEditorSelectboxValue(id, *selectbox_info[id].value);
static void MapTextbuttonGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[textbutton_info[id].gadget_id];
int xoffset_left = getTextWidthForGadget(textbutton_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
+ int yoffset = (gi->height - font_height) / 2;
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + xoffset_right;
+ int y_above = gi->y - yoffset_above;
+ int x = gi->x;
int y = gi->y + yoffset;
/* only show button to delete change pages when more than minimum pages */
custom_element.num_change_pages == MIN_CHANGE_PAGES)
return;
+ if (textbutton_info[id].text_above)
+ DrawText(x, y_above, textbutton_info[id].text_above, font_nr);
+
if (textbutton_info[id].text_left)
- DrawText(x_left, y, textbutton_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, textbutton_info[id].text_left, font_nr);
if (textbutton_info[id].text_right)
- DrawText(x_right, y, textbutton_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, textbutton_info[id].text_right, font_nr);
MapGadget(gi);
}
static void MapGraphicbuttonGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi= level_editor_gadget[graphicbutton_info[id].gadget_id];
int xoffset_left = getTextWidthForGadget(graphicbutton_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset = (gi->height - font_height) / 2;
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + xoffset_right;
int y = gi->y + yoffset;
if (graphicbutton_info[id].text_left)
- DrawText(x_left, y, graphicbutton_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, graphicbutton_info[id].text_left, font_nr);
if (graphicbutton_info[id].text_right)
- DrawText(x_right, y, graphicbutton_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, graphicbutton_info[id].text_right, font_nr);
MapGadget(gi);
}
static void MapRadiobuttonGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[radiobutton_info[id].gadget_id];
int xoffset_left = getTextWidthForGadget(checkbutton_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset = (gi->height - font_height) / 2;
int x_left = gi->x - xoffset_left;
int x_right = gi->x + gi->width + xoffset_right;
int y = gi->y + yoffset;
(*radiobutton_info[id].value == radiobutton_info[id].checked_value);
if (radiobutton_info[id].text_left)
- DrawText(x_left, y, radiobutton_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, radiobutton_info[id].text_left, font_nr);
if (radiobutton_info[id].text_right)
- DrawText(x_right, y, radiobutton_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, radiobutton_info[id].text_right, font_nr);
ModifyGadget(gi, GDI_CHECKED, checked, GDI_END);
static void MapCheckbuttonGadget(int id)
{
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
struct GadgetInfo *gi = level_editor_gadget[checkbutton_info[id].gadget_id];
int xoffset_left = getTextWidthForGadget(checkbutton_info[id].text_left);
int xoffset_right = ED_GADGET_TEXT_DISTANCE;
- int yoffset = ED_BORDER_SIZE;
+ int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE;
+ int yoffset = (gi->height - font_height) / 2;
+ int y_above = gi->y - yoffset_above;
+ int x = gi->x;
int x_left, x_right, y; /* set after gadget position was modified */
/* set position for gadgets with dynamically determined position */
if (checkbutton_info[id].x != -1) /* do not change dynamic positions */
- ModifyGadget(gi, GDI_X, SX + checkbutton_info[id].x, GDI_END);
- ModifyGadget(gi, GDI_Y, SY + checkbutton_info[id].y, 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;
x_right = gi->x + gi->width + xoffset_right;
y = gi->y + yoffset;
+ if (checkbutton_info[id].text_above)
+ DrawText(x, y_above, checkbutton_info[id].text_above, font_nr);
+
if (checkbutton_info[id].text_left)
- DrawText(x_left, y, checkbutton_info[id].text_left, FONT_TEXT_1);
+ DrawText(x_left, y, checkbutton_info[id].text_left, font_nr);
if (checkbutton_info[id].text_right)
- DrawText(x_right, y, checkbutton_info[id].text_right, FONT_TEXT_1);
+ DrawText(x_right, y, checkbutton_info[id].text_right, font_nr);
ModifyGadget(gi, GDI_CHECKED, *checkbutton_info[id].value, GDI_END);
static void MapOrUnmapLevelEditorToolboxDrawingGadgets(boolean map)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
int i;
for (i = 0; i < ED_NUM_CTRL1_BUTTONS; i++)
{
if (i != GADGET_ID_SINGLE_ITEMS &&
- i != GADGET_ID_PROPERTIES &&
i != GADGET_ID_PICK_ELEMENT)
{
struct GadgetInfo *gi = level_editor_gadget[i];
if (map)
+ {
MapGadget(gi);
+ }
else
{
+ int graphic = IMG_EDITOR_NO_TOOLBOX_BUTTON;
+ struct GraphicInfo *gd = &graphic_info[graphic];
+
UnmapGadget(gi);
- BlitBitmap(gd_bitmap, drawto,
- DOOR_GFX_PAGEX6 + ED_CTRL_NO_BUTTONS_GFX_XPOS,
- DOOR_GFX_PAGEY1 + ED_CTRL_NO_BUTTONS_GFX_YPOS,
+ BlitBitmap(gd->bitmap, drawto, gd->src_x, gd->src_y,
gi->width, gi->height, gi->x, gi->y);
redraw_mask |= REDRAW_DOOR_3;
UnmapGadget(level_editor_gadget[drawingarea_info[id].gadget_id]);
}
-static void UnmapLevelEditorWindowGadgets()
+static void UnmapLevelEditorFieldGadgets()
{
int i;
- for (i = 0; i < NUM_EDITOR_GADGETS; i++)
- if (level_editor_gadget[i]->x < SX + SXSIZE)
+ for (i = 0; i < num_editor_gadgets; i++)
+ if (IN_GFX_FIELD_FULL(level_editor_gadget[i]->x,
+ level_editor_gadget[i]->y))
UnmapGadget(level_editor_gadget[i]);
}
{
int i;
- for (i = 0; i < NUM_EDITOR_GADGETS; i++)
+ for (i = 0; i < num_editor_gadgets; i++)
UnmapGadget(level_editor_gadget[i]);
}
{
undo_buffer_position = -1;
undo_buffer_steps = -1;
+ redo_buffer_steps = 0;
+
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
level.changed = FALSE;
DrawLevelInfoWindow();
else if (edit_mode == ED_MODE_PROPERTIES)
DrawPropertiesWindow();
+ else if (edit_mode == ED_MODE_PALETTE)
+ DrawPaletteWindow();
else /* edit_mode == ED_MODE_DRAWING */
DrawDrawingWindow();
}
+static void ChangeEditModeWindow(int new_edit_mode)
+{
+ edit_mode = (new_edit_mode != edit_mode ? new_edit_mode : ED_MODE_DRAWING);
+
+ DrawEditModeWindow();
+}
+
static boolean LevelChanged()
{
boolean field_changed = FALSE;
int x, y;
- if (leveldir_current->readonly)
- return FALSE;
-
for (y = 0; y < lev_fieldy; y++)
for (x = 0; x < lev_fieldx; x++)
if (Feld[x][y] != level.field[x][y])
return (level.changed || field_changed);
}
-static boolean LevelContainsPlayer()
+static boolean PrepareSavingIntoPersonalLevelSet()
{
- boolean player_found = FALSE;
- int x, y;
+ static LevelDirTree *last_copied_leveldir = NULL;
+ static LevelDirTree *last_written_leveldir = NULL;
+ static int last_copied_level_nr = -1;
+ static int last_written_level_nr = -1;
+ LevelDirTree *leveldir_former = leveldir_current;
+ int level_nr_former = level_nr;
+ int new_level_nr;
+
+ // remember last mod/save so that for current session, we write
+ // back to the same personal copy, asking only about overwrite.
+ if (leveldir_current == last_copied_leveldir &&
+ level_nr == last_copied_level_nr)
+ {
+ // "cd" to personal level set dir (as used when writing last copy)
+ leveldir_current = last_written_leveldir;
+ level_nr = last_written_level_nr;
+
+ return TRUE;
+ }
+
+ if (!Request("This level is read only! "
+ "Save into personal level set?", REQ_ASK))
+ return FALSE;
+
+ // "cd" to personal level set dir (for writing copy the first time)
+ leveldir_current =
+ getTreeInfoFromIdentifier(leveldir_first, getLoginName());
- return TRUE; /* !!! CURRENTLY DEACTIVATED !!! */
+ // find unused level number
+ for (new_level_nr = leveldir_current->first_level; ; new_level_nr++)
+ {
+ static char *level_filename = NULL;
+
+ setString(&level_filename, getDefaultLevelFilename(new_level_nr));
+
+ if (!fileExists(level_filename))
+ break;
+ }
+
+ last_copied_leveldir = leveldir_former;
+ last_copied_level_nr = level_nr_former;
+
+ last_written_leveldir = leveldir_current;
+ last_written_level_nr = level_nr = new_level_nr;
+
+ return TRUE;
+}
+
+static void ModifyLevelInfoForSavingIntoPersonalLevelSet(char *former_name)
+{
+ static char *filename_levelinfo = NULL, *mod_name = NULL;
+ FILE *file;
+
+ // annotate this copy-and-mod in personal levelinfo.conf
+ setString(&filename_levelinfo,
+ getPath2(getCurrentLevelDir(), LEVELINFO_FILENAME));
+
+ if ((file = fopen(filename_levelinfo, MODE_APPEND)))
+ {
+ fprintf(file, "\n");
+ fprintf(file, "# level %d was modified from:\n", level_nr);
+ fprintf(file, "# - previous level set name: %s\n",
+ former_name);
+ fprintf(file, "# - level within previous set: %d \"%s\"\n",
+ level.file_info.nr, level.name);
+ fprintf(file, "# - previous author: %s\n",
+ level.author);
+ fprintf(file, "# - previous save date: ");
+
+ if (level.creation_date.src == DATE_SRC_LEVELFILE)
+ {
+ fprintf(file, "%04d-%02d-%02d\n",
+ level.creation_date.year,
+ level.creation_date.month,
+ level.creation_date.day);
+ }
+ else
+ {
+ fprintf(file, "not recorded\n");
+ }
+
+ fclose(file);
+ }
- for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
+ if (level_nr > leveldir_current->last_level)
{
- if (Feld[x][y] == EL_PLAYER_1 ||
- Feld[x][y] == EL_SP_MURPHY)
- player_found = TRUE;
+ static char *temp_levelinfo = NULL;
+ FILE *temp_file = NULL;
+ char line[MAX_LINE_LEN];
+
+ setString(&temp_levelinfo,
+ getPath2(getCurrentLevelDir(),
+ getStringCat2(LEVELINFO_FILENAME, ".new")));
+
+ if ((file = fopen(filename_levelinfo, MODE_READ)) &&
+ (temp_file = fopen(temp_levelinfo, MODE_WRITE)))
+ {
+ while (fgets(line, MAX_LINE_LEN, file))
+ {
+ if (!strPrefix(line, "levels:"))
+ fputs(line, temp_file);
+ else
+ fprintf(temp_file, "%-32s%d\n", "levels:", level_nr + 9);
+ }
+ }
+
+ if (temp_file)
+ fclose(temp_file);
+
+ if (file)
+ fclose(file);
+
+ // needs error handling; also, ok on dos/win?
+ unlink(filename_levelinfo);
+ rename(temp_levelinfo, filename_levelinfo);
}
- return player_found;
+ // else: allow the save even if annotation failed
+
+ // now... spray graffiti on the old level vital statistics
+ // user can change these; just trying to set a good baseline
+
+ // don't truncate names for fear of making offensive or silly:
+ // long-named original author only recorded in levelinfo.conf.
+ // try to fit "Joe after Bob", "Joe (ed.)", then just "Joe"
+ if (!strEqual(level.author, leveldir_current->author))
+ {
+ setString(&mod_name, getStringCat3(leveldir_current->author,
+ " after ", level.author));
+
+ if (strlen(mod_name) > MAX_LEVEL_AUTHOR_LEN)
+ setString(&mod_name,
+ getStringCat2(leveldir_current->author, " (ed.)"));
+
+ if (strlen(mod_name) > MAX_LEVEL_AUTHOR_LEN)
+ setString(&mod_name, leveldir_current->author);
+
+ strncpy(level.author, mod_name, MAX_LEVEL_AUTHOR_LEN);
+
+ // less worried about truncation here
+ setString(&mod_name, getStringCat2("Mod: ", level.name));
+ strncpy(level.name, mod_name, MAX_LEVEL_NAME_LEN);
+ }
}
static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
if (change->target_element == element_from)
change->target_element = element_to;
- if (change->trigger_element == element_from)
- change->trigger_element = element_to;
+ if (change->initial_trigger_element == element_from)
+ change->initial_trigger_element = element_to;
+
+ if (change->action_element == element_from)
+ change->action_element = element_to;
for (y = 0; y < 3; y++)
for (x = 0; x < 3; x++)
static boolean CopyCustomElement(int element_old, int element_new,
int copy_mode)
{
+ int copy_mode_orig = copy_mode;
+
if (copy_mode == GADGET_ID_CUSTOM_COPY)
{
element_new = (IS_CUSTOM_ELEMENT(element_old) ?
}
else if (IS_CUSTOM_ELEMENT(element_old) && !IS_CUSTOM_ELEMENT(element_new))
{
- Request("Please choose custom element !", REQ_CONFIRM);
+ Request("Please choose custom element!", REQ_CONFIRM);
return FALSE;
}
else if (IS_GROUP_ELEMENT(element_old) && !IS_GROUP_ELEMENT(element_new))
{
- Request("Please choose group element !", REQ_CONFIRM);
+ Request("Please choose group element!", REQ_CONFIRM);
return FALSE;
}
level.changed = TRUE;
}
+ /* when modifying custom/group element, ask for copying level template */
+ if (copy_mode_orig != GADGET_ID_CUSTOM_COPY && level.use_custom_template)
+ {
+ if (!AskToCopyAndModifyLevelTemplate())
+ return FALSE;
+ }
+
if (copy_mode == GADGET_ID_CUSTOM_COPY_FROM)
{
copy_custom_element_settings(element_new, element_old);
/* set deadliness selectbox help value */
custom_element.deadliness =
(DONT_TOUCH(element) ? EP_DONT_TOUCH :
+ DONT_GET_HIT_BY(element) ? EP_DONT_GET_HIT_BY :
DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH :
DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO :
custom_element.deadliness);
custom_element_properties[EP_DEADLY] =
(DONT_TOUCH(element) ||
+ DONT_GET_HIT_BY(element) ||
DONT_COLLIDE_WITH(element) ||
DONT_RUN_INTO(element));
CopyClassicElementPropertiesToEditor(element);
}
+static boolean AskToCopyAndModifyLevelTemplate()
+{
+ if (Request("Copy and modify settings from level template?", REQ_ASK))
+ {
+ level.use_custom_template = FALSE;
+
+ ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE_1],
+ GDI_CHECKED, FALSE, GDI_END);
+ ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE_2],
+ GDI_CHECKED, FALSE, GDI_END);
+
+ return TRUE;
+ }
+ else
+ {
+ LoadLevelTemplate(-1); /* this resets all element modifications ... */
+
+ DrawEditModeWindow(); /* ... and copies them to 'custom_element' */
+
+ return FALSE;
+ }
+}
+
static void CopyCustomElementPropertiesToGame(int element)
{
int i;
level.changed = TRUE;
if (level.use_custom_template)
- {
- if (Request("Copy and modify level template ?", REQ_ASK))
- {
- level.use_custom_template = FALSE;
- ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE],
- GDI_CHECKED, FALSE, GDI_END);
- }
- else
- {
- LoadLevelTemplate(-1); /* this resets all element modifications ... */
-
- DrawEditModeWindow(); /* ... and copies them to 'custom_element' */
- }
- }
+ AskToCopyAndModifyLevelTemplate();
element_info[element] = custom_element;
*element_info[element].change = custom_element_change;
/* set deadliness property from checkbox and selectbox */
custom_element_properties[EP_DONT_RUN_INTO] = FALSE;
custom_element_properties[EP_DONT_COLLIDE_WITH] = FALSE;
+ custom_element_properties[EP_DONT_GET_HIT_BY] = FALSE;
custom_element_properties[EP_DONT_TOUCH] = FALSE;
custom_element_properties[custom_element.deadliness] =
custom_element_properties[EP_DEADLY];
static void CopyGroupElementPropertiesToGame(int element)
{
- element_info[element] = custom_element;
- *element_info[element].group = group_element_info;
-
/* mark that this group element has been modified */
- element_info[element].modified_settings = TRUE;
+ custom_element.modified_settings = TRUE;
level.changed = TRUE;
+
+ if (level.use_custom_template)
+ AskToCopyAndModifyLevelTemplate();
+
+ element_info[element] = custom_element;
+ *element_info[element].group = group_element_info;
}
static void CopyClassicElementPropertiesToGame(int element)
for (i = 0; i < NUM_FILE_ELEMENTS; i++)
if (getElementDescriptionFilename(i) == NULL && !IS_OBSOLETE(i))
- Error(ERR_WARN, "no element description for element '%s'", EL_NAME(i));
+ Error(ERR_WARN, "no element description file for element '%s'",
+ EL_NAME(i));
+}
+
+static int getMaxEdFieldX(boolean has_scrollbar)
+{
+ int scrollbar_width = (has_scrollbar ? ED_SCROLLBUTTON_XSIZE : 0);
+ int sxsize = SXSIZE - scrollbar_width;
+ int max_ed_fieldx = sxsize / ed_tilesize;
+
+ return max_ed_fieldx;
+}
+
+static int getMaxEdFieldY(boolean has_scrollbar)
+{
+ int infotext_height = INFOTEXT_YSIZE_FULL;
+ int scrollbar_height = (has_scrollbar ? ED_SCROLLBUTTON_YSIZE : 0);
+ int sysize = SYSIZE - scrollbar_height - infotext_height;
+ int max_ed_fieldy = sysize / ed_tilesize;
+
+ return max_ed_fieldy;
+}
+
+void InitZoomLevelSettings()
+{
+ MAX_ED_FIELDX = getMaxEdFieldX(FALSE);
+ MAX_ED_FIELDY = getMaxEdFieldY(FALSE);
}
void DrawLevelEd()
{
- CloseDoor(DOOR_CLOSE_ALL);
- OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY);
+ int fade_mask = REDRAW_FIELD;
+
+ FadeSoundsAndMusic();
+
+ if (CheckIfGlobalBorderHasChanged())
+ fade_mask = REDRAW_ALL;
+
+ FadeOut(fade_mask);
+
+ /* needed if different viewport properties defined for editor */
+ ChangeViewportPropertiesIfNeeded();
+
+ ClearField();
+
+ InitZoomLevelSettings();
+
+ OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY);
#if DEBUG
CheckElementDescriptions();
else
{
edit_mode = ED_MODE_DRAWING;
+ edit_mode_levelinfo = ED_MODE_LEVELINFO_LEVEL;
edit_mode_properties = ED_MODE_PROPERTIES_INFO;
ResetUndoBuffer();
level_ypos = -1;
}
+ /* needed for gadgets drawn on background (like palette scrollbar) */
+ SetDoorBackgroundImage(IMG_UNDEFINED);
+
/* copy default editor door content to main double buffer */
- BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
- DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+ BlitBitmap(graphic_info[IMG_BACKGROUND_PALETTE].bitmap, drawto,
+ graphic_info[IMG_BACKGROUND_PALETTE].src_x,
+ graphic_info[IMG_BACKGROUND_PALETTE].src_y,
+ MIN(DXSIZE, graphic_info[IMG_BACKGROUND_PALETTE].width),
+ MIN(DYSIZE, graphic_info[IMG_BACKGROUND_PALETTE].height),
+ DX, DY);
/* draw bigger door */
DrawSpecialEditorDoor();
/* draw new control window */
- BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
- DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY);
+ BlitBitmap(graphic_info[IMG_BACKGROUND_TOOLBOX].bitmap, drawto,
+ graphic_info[IMG_BACKGROUND_TOOLBOX].src_x,
+ graphic_info[IMG_BACKGROUND_TOOLBOX].src_y,
+ MIN(EXSIZE, graphic_info[IMG_BACKGROUND_TOOLBOX].width),
+ MIN(EYSIZE, graphic_info[IMG_BACKGROUND_TOOLBOX].height),
+ EX, EY);
- redraw_mask |= REDRAW_ALL;
+ // redraw_mask |= REDRAW_ALL;
+
+ FreeLevelEditorGadgets();
+ CreateLevelEditorGadgets();
ReinitializeElementList(); /* update dynamic level element list */
ReinitializeElementListButtons(); /* custom element may look different */
-#if 1
+ InitElementPropertiesGfxElement();
+
UnmapAllGadgets();
-#else
- UnmapTapeButtons();
-#endif
MapControlButtons();
DrawEditModeWindow();
- /* copy actual editor door content to door double buffer for OpenDoor() */
- BlitBitmap(drawto, bitmap_db_door,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ DrawMaskedBorder(fade_mask);
- OpenDoor(DOOR_OPEN_1);
+ FadeIn(fade_mask);
+
+ /* copy actual editor door content to door double buffer for OpenDoor() */
+ BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
}
static void AdjustDrawingAreaGadgets()
boolean horizontal_scrollbar_needed;
boolean vertical_scrollbar_needed;
int x, y, width, height;
- int xoffset, yoffset;
/* check if we need any scrollbars */
horizontal_scrollbar_needed = (ed_xsize > max_ed_fieldx);
- vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
+ vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
/* check if we have a smaller editor field because of scrollbars */
- if (horizontal_scrollbar_needed)
- max_ed_fieldy = MAX_ED_FIELDY - 1;
- if (vertical_scrollbar_needed)
- max_ed_fieldx = MAX_ED_FIELDX - 1;
+ max_ed_fieldx = getMaxEdFieldX(vertical_scrollbar_needed);
+ max_ed_fieldy = getMaxEdFieldY(horizontal_scrollbar_needed);
/* check again if we now need more scrollbars because of less space */
horizontal_scrollbar_needed = (ed_xsize > max_ed_fieldx);
- vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
+ vertical_scrollbar_needed = (ed_ysize > max_ed_fieldy);
/* check if editor field gets even smaller after adding new scrollbars */
- if (horizontal_scrollbar_needed)
- max_ed_fieldy = MAX_ED_FIELDY - 1;
- if (vertical_scrollbar_needed)
- max_ed_fieldx = MAX_ED_FIELDX - 1;
+ max_ed_fieldx = getMaxEdFieldX(vertical_scrollbar_needed);
+ max_ed_fieldy = getMaxEdFieldY(horizontal_scrollbar_needed);
+
+ ed_fieldx = (ed_xsize > max_ed_fieldx ? max_ed_fieldx : ed_xsize);
+ ed_fieldy = (ed_ysize > max_ed_fieldy ? max_ed_fieldy : ed_ysize);
- ed_fieldx = (ed_xsize < MAX_ED_FIELDX ? ed_xsize : max_ed_fieldx);
- ed_fieldy = (ed_ysize < MAX_ED_FIELDY ? ed_ysize : max_ed_fieldy);
+ x = SX + ed_fieldx * ed_tilesize;
+ y = SY + ed_fieldy * ed_tilesize;
+ width = ed_fieldx * ed_tilesize - 2 * ED_SCROLLBUTTON_XSIZE;
+ height = ed_fieldy * ed_tilesize - 2 * ED_SCROLLBUTTON_YSIZE;
+
+ /* adjust drawing area gadget */
ModifyGadget(level_editor_gadget[GADGET_ID_DRAWING_LEVEL],
- GDI_WIDTH, ed_fieldx * MINI_TILEX,
- GDI_HEIGHT, ed_fieldy * MINI_TILEY,
GDI_AREA_SIZE, ed_fieldx, ed_fieldy,
+ GDI_ITEM_SIZE, ed_tilesize, ed_tilesize,
GDI_END);
- xoffset = (ed_fieldx == MAX_ED_FIELDX ? ED_SCROLLBUTTON_XSIZE : 0);
- yoffset = (ed_fieldy == MAX_ED_FIELDY ? ED_SCROLLBUTTON_YSIZE : 0);
-
- x = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_RIGHT].x + xoffset;
- y = SX + scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_DOWN].y + yoffset;
-
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_RIGHT], GDI_X, x, GDI_END);
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_DOWN], GDI_Y, y, GDI_END);
-
- width = scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width + xoffset;
- height = scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].height + yoffset;
-
+ /* adjust horizontal scrollbar gadgets */
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LEFT],
+ GDI_Y, y,
+ GDI_END);
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_RIGHT],
+ GDI_X, x - ED_SCROLLBUTTON_XSIZE,
+ GDI_Y, y,
+ GDI_END);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL],
+ GDI_Y, y,
GDI_WIDTH, width,
GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldx,
GDI_END);
+
+ /* adjust vertical scrollbar gadgets */
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_UP],
+ GDI_X, x,
+ GDI_END);
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_DOWN],
+ GDI_X, x,
+ GDI_Y, y - ED_SCROLLBUTTON_YSIZE,
+ GDI_END);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL],
+ GDI_X, x,
GDI_HEIGHT, height,
GDI_SCROLLBAR_ITEMS_VISIBLE, ed_fieldy,
GDI_END);
struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up];
ModifyGadget(gi, GDI_TEXT_SIZE, (max < 10 ? 1 : 3), GDI_END);
- ModifyGadget(gi_up, GDI_X, gi->x + gi->width + ED_GADGET_DISTANCE,GDI_END);
+ ModifyGadget(gi_up, GDI_X, gi->x + gi->width + ED_GADGET_SMALL_DISTANCE,
+ GDI_END);
}
}
{
int i;
+ if (!use_permanent_palette && edit_mode != ED_MODE_PALETTE)
+ return;
+
for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
{
int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
struct GadgetInfo *gi = level_editor_gadget[gadget_id];
struct GadgetDesign *gd = &gi->deco.design;
int element = editor_elements[element_shift + i];
+ int tile_size = BUTTON_TILE_SIZE(editor.palette.tile_size);
UnmapGadget(gi);
- getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
+ getEditorGraphicSource(element, tile_size, &gd->bitmap, &gd->x, &gd->y);
+
ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
MapGadget(gi);
}
}
-static void PickDrawingElement(int button, int element)
+static void DrawDrawingElementGraphic(int element, struct XYTileSize *pos)
{
- if (button < 1 || button > 3)
+ int graphic = el2edimg(element);
+ int tile_size = BUTTON_TILE_SIZE(pos->tile_size);
+
+ if (pos->x == -1 &&
+ pos->y == -1)
return;
- if (button == 1)
- {
- new_element1 = element;
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
- el2edimg(new_element1));
- }
- else if (button == 2)
+ DrawSizedGraphicExt(drawto, DX + pos->x, DY + pos->y, graphic, 0, tile_size);
+}
+
+static void ModifyDrawingElementButton(int element, int id)
+{
+ struct GadgetInfo *gi = level_editor_gadget[id];
+ Bitmap *deco_bitmap;
+ int deco_x, deco_y;
+ int tile_size = gi->deco.width;
+
+ getEditorGraphicSource(element, tile_size, &deco_bitmap, &deco_x, &deco_y);
+
+ ModifyGadget(gi, GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y, GDI_END);
+}
+
+static void PickDrawingElement(int button, int element)
+{
+ struct
{
- new_element2 = element;
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
- el2edimg(new_element2));
- }
- else
+ int *new_element;
+ struct XYTileSize *pos;
+ int id;
+ } de, drawing_elements[] =
{
- new_element3 = element;
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
- el2edimg(new_element3));
- }
+ { &new_element1, &editor.palette.element_left, GADGET_ID_ELEMENT_LEFT },
+ { &new_element2, &editor.palette.element_middle, GADGET_ID_ELEMENT_MIDDLE },
+ { &new_element3, &editor.palette.element_right, GADGET_ID_ELEMENT_RIGHT },
+ };
+
+ if (button < 1 || button > 3)
+ return;
+
+ de = drawing_elements[button - 1];
+
+ *de.new_element = element; // update global drawing element variable
+
+ DrawDrawingElementGraphic(element, de.pos);
+ ModifyDrawingElementButton(element, de.id);
redraw_mask |= REDRAW_DOOR_1;
}
stick_element_properties_window = FALSE;
SetMainBackgroundImage(IMG_UNDEFINED);
- ClearWindow();
+ ClearField();
- UnmapLevelEditorWindowGadgets();
+ UnmapLevelEditorFieldGadgets();
UnmapLevelEditorToolboxCustomGadgets();
AdjustDrawingAreaGadgets();
AdjustEditorScrollbar(GADGET_ID_SCROLL_HORIZONTAL);
AdjustEditorScrollbar(GADGET_ID_SCROLL_VERTICAL);
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
MapMainDrawingArea();
MapLevelEditorToolboxDrawingGadgets();
}
-static void DrawLevelInfoWindow()
+static int getTabulatorBarWidth()
{
- int i;
-
- stick_element_properties_window = FALSE;
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ struct GadgetInfo *gd_gi4 = level_editor_gadget[GADGET_ID_PROPERTIES_CHANGE];
- SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
- ClearWindow();
- UnmapLevelEditorWindowGadgets();
+ return gd_gi4->x - gd_gi1->x + gd_gi4->width;
+}
-#if 0
- DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Level Settings");
- DrawTextSCentered(ED_SETTINGS2_YPOS, FONT_TITLE_1, "Editor Settings");
-#else
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS,
- "Level Settings", FONT_TITLE_1);
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS2_YPOS,
- "Editor Settings", FONT_TITLE_1);
-#endif
+static int getTabulatorBarHeight()
+{
+ return ED_TAB_BAR_HEIGHT;
+}
- /* draw counter gadgets */
- for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++)
+static void DrawLevelInfoTabulatorGadgets()
+{
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_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;
+ Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
+ int id_first = ED_TAB_BUTTON_ID_LEVELINFO_FIRST;
+ int id_last = ED_TAB_BUTTON_ID_LEVELINFO_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);
+
+ /* draw background line below tabulator button */
+ ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1);
+
+ /* draw solid line below inactive tabulator buttons */
+ if (!active && tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width,
+ ED_GADGET_TINY_DISTANCE, tab_color);
+
+ ModifyGadget(gi, GDI_ACTIVE, active, GDI_END);
+ MapTextbuttonGadget(i);
+ }
+
+ /* draw little border line below tabulator buttons */
+ if (tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height +
+ ED_GADGET_TINY_DISTANCE,
+ getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color);
+}
+
+static void DrawPropertiesTabulatorGadgets()
+{
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ 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;
+ Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
+ int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
+ int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG;
+ int i;
+
+ /* draw two config tabulators for player elements */
+ if (ELEM_IS_PLAYER(properties_element))
+ id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2;
+
+ /* draw two config and one "change" tabulator for custom elements */
+ if (IS_CUSTOM_ELEMENT(properties_element))
+ id_last = ED_TEXTBUTTON_ID_PROPERTIES_CHANGE;
+
+ 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_properties);
+
+ /* use "config 1" and "config 2" instead of "config" for players and CEs */
+ if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG &&
+ (ELEM_IS_PLAYER(properties_element) ||
+ IS_CUSTOM_ELEMENT(properties_element)))
+ continue;
+
+ /* draw background line below tabulator button */
+ ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1);
+
+ /* draw solid line below inactive tabulator buttons */
+ if (!active && tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width,
+ ED_GADGET_TINY_DISTANCE, tab_color);
+
+ ModifyGadget(gi, GDI_ACTIVE, active, GDI_END);
+ MapTextbuttonGadget(i);
+ }
+
+ /* draw little border line below tabulator buttons */
+ if (tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height +
+ ED_GADGET_TINY_DISTANCE,
+ getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color);
+}
+
+static void DrawLevelInfoLevel()
+{
+ int i;
+
+ /* draw counter gadgets */
+ for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++)
MapCounterButtons(i);
/* draw selectbox gadgets */
for (i = ED_SELECTBOX_ID_LEVEL_FIRST; i <= ED_SELECTBOX_ID_LEVEL_LAST; i++)
MapSelectboxGadget(i);
+ /* draw text input gadgets */
+ for (i = ED_TEXTINPUT_ID_LEVEL_FIRST; i <= ED_TEXTINPUT_ID_LEVEL_LAST; i++)
+ MapTextInputGadget(i);
+}
+
+static void DrawLevelInfoEditor()
+{
+ int i;
+
+ /* draw counter gadgets */
+ for (i = ED_COUNTER_ID_EDITOR_FIRST; i <= ED_COUNTER_ID_EDITOR_LAST; i++)
+ MapCounterButtons(i);
+
/* draw checkbutton gadgets */
- for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i <= ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
+ for (i=ED_CHECKBUTTON_ID_EDITOR_FIRST; i<= ED_CHECKBUTTON_ID_EDITOR_LAST; i++)
MapCheckbuttonGadget(i);
/* draw radiobutton gadgets */
- for (i=ED_RADIOBUTTON_ID_LEVEL_FIRST; i <= ED_RADIOBUTTON_ID_LEVEL_LAST; i++)
+ for (i=ED_RADIOBUTTON_ID_EDITOR_FIRST; i<= ED_RADIOBUTTON_ID_EDITOR_LAST; i++)
MapRadiobuttonGadget(i);
- /* draw text input gadgets */
- for (i = ED_TEXTINPUT_ID_LEVEL_FIRST; i <= ED_TEXTINPUT_ID_LEVEL_LAST; i++)
- MapTextInputGadget(i);
-
/* draw drawing area */
MapDrawingArea(ED_DRAWING_ID_RANDOM_BACKGROUND);
+
+ /* draw textbutton gadgets */
+ MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2);
+}
+
+static void DrawLevelInfoWindow()
+{
+ char *text = "Global Settings";
+ int font_nr = FONT_TITLE_1;
+ struct MenuPosInfo *pos = &editor.settings.headline;
+ int sx = SX + ALIGNED_XPOS(pos->x, getTextWidth(text, font_nr), pos->align);
+ int sy = SY + pos->y;
+
+ stick_element_properties_window = FALSE;
+
+ UnmapLevelEditorFieldGadgets();
+
+ SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
+ ClearField();
+
+ DrawText(sx, sy, text, font_nr);
+
+ DrawLevelInfoTabulatorGadgets();
+
+ if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL)
+ DrawLevelInfoLevel();
+ else /* (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR) */
+ DrawLevelInfoEditor();
}
static void DrawCustomContentArea()
int x1 = right_gadget_border[GADGET_ID_CUSTOM_DEADLINESS];
int x2 = right_gadget_border[GADGET_ID_CUSTOM_EXPLOSION_TYPE];
int x3 = right_gadget_border[GADGET_ID_CUSTOM_EXPLODE_IMPACT];
- int xoffset = ED_DRAWINGAREA_TEXT_DISTANCE;
+ int xoffset = ED_GADGET_SPACE_DISTANCE;
/* add distance for potential left text (without drawing area border) */
x2 += getTextWidthForGadget(drawingarea_info[id].text_left);
int x1 = right_gadget_border[GADGET_ID_CHANGE_USE_CONTENT];
int x2 = right_gadget_border[GADGET_ID_CHANGE_REPLACE_WHEN];
int x3 = right_gadget_border[GADGET_ID_CHANGE_ONLY_COMPLETE];
- int xoffset = ED_DRAWINGAREA_TEXT_DISTANCE;
+ int xoffset = ED_GADGET_SPACE_DISTANCE;
ModifyGadget(gi, GDI_X, MAX(x1, MAX(x2, x3)) + xoffset, GDI_END);
MapDrawingArea(id);
}
+static void RemoveElementContentArea(int id, int font_height)
+{
+ int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+
+ DrawBackground(SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size,
+ SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size,
+ 3 * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+ 3 * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size +
+ ED_GADGET_TEXT_DISTANCE + font_height);
+}
+
static void DrawYamYamContentAreas()
{
- int x = SX + ED_AREA_YAMYAM_CONTENT_XPOS(3) + 4 * MINI_TILEX;
- int y = SY + ED_AREA_YAMYAM_CONTENT_YPOS(0) + ED_BORDER_AREA_YSIZE;
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
+ int tilesize = ED_DRAWINGAREA_TILE_SIZE;
+ int yoffset = (tilesize - font_height) / 2;
+ int x = SX + ED_AREA_YAMYAM_CONTENT_X(3) + 4 * tilesize;
+ int y = SY + ED_AREA_YAMYAM_CONTENT_Y(3) + yoffset;
int i;
/* display counter to choose number of element content areas */
}
else
{
- int font_height = getFontHeight(FONT_TEXT_1);
-
UnmapDrawingArea(id);
/* delete content areas in case of reducing number of them */
- DrawBackground(SX + drawingarea_info[id].x - MINI_TILEX / 2,
- SY + drawingarea_info[id].y - MINI_TILEY / 2,
- 4 * MINI_TILEX,
- 4 * MINI_TILEY + ED_GADGET_TEXT_DISTANCE + font_height);
+ RemoveElementContentArea(id, font_height);
}
}
- DrawText(x, y + 0 * MINI_TILEY, "content", FONT_TEXT_1);
- DrawText(x, y + 1 * MINI_TILEY, "when", FONT_TEXT_1);
- DrawText(x, y + 2 * MINI_TILEY, "smashed", FONT_TEXT_1);
+ DrawText(x, y + 0 * tilesize, "content", font_nr);
+ DrawText(x, y + 1 * tilesize, "when", font_nr);
+ DrawText(x, y + 2 * tilesize, "smashed", font_nr);
}
static void DrawMagicBallContentAreas()
{
- int x = SX + ED_AREA_MAGIC_BALL_CONTENT_XPOS(3) + 4 * MINI_TILEX;
- int y = SY + ED_AREA_MAGIC_BALL_CONTENT_YPOS(0) + ED_BORDER_AREA_YSIZE;
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
+ int tilesize = ED_DRAWINGAREA_TILE_SIZE;
+ int yoffset = (tilesize - font_height) / 2;
+ int x = SX + ED_AREA_MAGIC_BALL_CONTENT_X(3) + 4 * tilesize;
+ int y = SY + ED_AREA_MAGIC_BALL_CONTENT_Y(3) + yoffset;
int i;
/* display counter to choose number of element content areas */
}
else
{
- int font_height = getFontHeight(FONT_TEXT_1);
-
UnmapDrawingArea(id);
/* delete content areas in case of reducing number of them */
- DrawBackground(SX + drawingarea_info[id].x - MINI_TILEX / 2,
- SY + drawingarea_info[id].y - MINI_TILEY / 2,
- 4 * MINI_TILEX,
- 4 * MINI_TILEY + ED_GADGET_TEXT_DISTANCE + font_height);
+ RemoveElementContentArea(id, font_height);
}
}
- DrawText(x, y + 0 * MINI_TILEY, "generated", FONT_TEXT_1);
- DrawText(x, y + 1 * MINI_TILEY, "when", FONT_TEXT_1);
- DrawText(x, y + 2 * MINI_TILEY, "active", FONT_TEXT_1);
+ DrawText(x, y + 0 * tilesize, "generated", font_nr);
+ DrawText(x, y + 1 * tilesize, "when", font_nr);
+ DrawText(x, y + 2 * tilesize, "active", font_nr);
}
static void DrawAndroidElementArea(int element)
{
- int num_elements = level.num_android_clone_elements;
int id = ED_DRAWING_ID_ANDROID_CONTENT;
- int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2;
- int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2;
+ int num_elements = level.num_android_clone_elements;
+ int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+ int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size;
+ int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size;
int xsize = MAX_ANDROID_ELEMENTS;
int ysize = 1;
ModifyEditorDrawingArea(id, num_elements, 1);
/* delete content areas in case of reducing number of them */
- DrawBackground(sx, sy, (xsize + 1) * MINI_TILEX, (ysize + 1) * MINI_TILEY);
+ DrawBackground(sx, sy,
+ xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+ ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size);
MapDrawingArea(id);
}
static void DrawGroupElementArea(int element)
{
- int num_elements = group_element_info.num_elements;
int id = ED_DRAWING_ID_GROUP_CONTENT;
- int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2;
- int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2;
+ int num_elements = group_element_info.num_elements;
+ int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+ int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size;
+ int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size;
int xsize = MAX_ELEMENTS_IN_GROUP;
int ysize = 1;
ModifyEditorDrawingArea(id, num_elements, 1);
/* delete content areas in case of reducing number of them */
- DrawBackground(sx, sy, (xsize + 1) * MINI_TILEX, (ysize + 1) * MINI_TILEY);
+ DrawBackground(sx, sy,
+ xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+ ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size);
+
+ MapDrawingArea(id);
+}
+
+static void DrawPlayerInitialInventoryArea(int element)
+{
+ int id = ED_DRAWING_ID_INVENTORY_CONTENT;
+ int player_nr = GET_PLAYER_NR(element);
+ int num_elements = level.initial_inventory_size[player_nr];
+ int border_size = ED_DRAWINGAREA_BORDER_SIZE;
+ int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size;
+ int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size;
+ int xsize = MAX_INITIAL_INVENTORY_SIZE;
+ int ysize = 1;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (drawingarea_info[id].gadget_id_align != GADGET_ID_NONE)
+ sx = (right_gadget_border[drawingarea_info[id].gadget_id_align] +
+ ED_DRAWINGAREA_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (drawingarea_info[id].text_left != NULL)
+ sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left);
+
+ UnmapDrawingArea(id);
+
+ ModifyEditorDrawingArea(id, num_elements, 1);
+
+ /* delete content areas in case of reducing number of them */
+ DrawBackground(sx, sy,
+ xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size,
+ ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size);
MapDrawingArea(id);
}
MapTextAreaGadget(ED_TEXTAREA_ID_ENVELOPE_INFO);
}
-static boolean PrintInfoText(char *text, int font_nr, int start_line)
+static void PrintInfoText(char *text, int font_nr, int xpos, int ypos)
{
- int font_height = getFontHeight(font_nr);
- int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
- int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
- int sx = SX + pad_x;
- int sy = SY + pad_y;
- int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
-
- if (start_line >= max_lines_per_screen)
- return FALSE;
-
- DrawText(sx, sy + start_line * font_height, text, font_nr);
-
- return TRUE;
+ DrawText(SX + xpos, SY + ypos, text, font_nr);
}
-static int PrintElementDescriptionFromFile(char *filename, int start_line)
+static int PrintElementDescriptionFromFile(char *filename, int font_nr,
+ int xpos, int ypos)
{
- int font_nr = FONT_TEXT_2;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
- int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
- int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
- int sx = SX + pad_x;
- int sy = SY + pad_y + start_line * font_height;
- int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
- int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
-
- return DrawTextFile(sx, sy, filename, font_nr, max_chars_per_line, -1,
- max_lines_per_screen, -1, TRUE, FALSE, FALSE);
-}
-
-static void DrawPropertiesTabulatorGadgets()
-{
- struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
- struct GadgetInfo *gd_gi4 = level_editor_gadget[GADGET_ID_PROPERTIES_CHANGE];
- 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;
- Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
- int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
- int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG;
-#if 1
-#else
- int max_tabs = 4;
-#endif
- int i;
-
- /* draw additional "change" tabulator for custom elements */
- if (IS_CUSTOM_ELEMENT(properties_element))
- id_last = ED_TEXTBUTTON_ID_PROPERTIES_CHANGE;
-
- 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_properties);
-
- /* use "config 1" and "config 2" instead of "config" */
- if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG &&
- IS_CUSTOM_ELEMENT(properties_element))
- continue;
-
- /* draw background line below tabulator button */
- ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1);
-
- /* draw solid line below inactive tabulator buttons */
- if (!active && tab_color != BLACK_PIXEL) /* black => transparent */
- FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, 1, tab_color);
+ int max_chars_per_line = (SXSIZE - 2 * xpos) / font_width;
+ int max_lines_drawable = (SYSIZE - ypos) / font_height - 1;
- ModifyGadget(gi, GDI_ACTIVE, active, GDI_END);
- MapTextbuttonGadget(i);
- }
-
-#if 1
- /* draw little border line below tabulator buttons */
- if (tab_color != BLACK_PIXEL) /* black => transparent */
- FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1,
- gd_gi4->x - gd_gi1->x + gd_gi4->width, ED_GADGET_DISTANCE,
- tab_color);
-#else
- /* draw little border line below tabulator buttons */
- if (tab_color != BLACK_PIXEL) /* black => transparent */
- FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + 1,
- max_tabs * gd_gi1->width + (max_tabs -1) * ED_GADGET_DISTANCE,
- ED_GADGET_DISTANCE, tab_color);
-#endif
+ return DrawTextFile(SX + xpos, SY + ypos, filename, font_nr,
+ max_chars_per_line, -1, max_lines_drawable, 0, -1,
+ TRUE, FALSE, FALSE);
}
static void DrawPropertiesInfo()
{ EP_DONT_RUN_INTO, "- deadly when running into" },
{ EP_DONT_COLLIDE_WITH, "- deadly when colliding with" },
+ { EP_DONT_GET_HIT_BY, "- deadly when getting hit by" },
{ EP_DONT_TOUCH, "- deadly when touching" },
{ EP_INDESTRUCTIBLE, "- indestructible" },
{ -1, NULL }
};
char *filename = getElementDescriptionFilename(properties_element);
- char *percentage_text = "In this level:";
- char *properties_text = "Standard properties:";
+ char *percentage_text = "In this level: ";
+ char *properties_text = "Standard properties: ";
+ char *description_text = "Description:";
+ char *no_description_text = "No description available.";
+ char *none_text = "None";
float percentage;
int num_elements_in_level;
int num_standard_properties = 0;
int font1_nr = FONT_TEXT_1;
int font2_nr = FONT_TEXT_2;
int font1_width = getFontWidth(font1_nr);
+ int font1_height = getFontHeight(font1_nr);
int font2_height = getFontHeight(font2_nr);
- int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
- int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
- int screen_line = 0;
+ int line1_height = font1_height + ED_GADGET_LINE_DISTANCE;
+ int font2_yoffset = (font1_height - font2_height) / 2;
+ int percentage_text_len = strlen(percentage_text) * font1_width;
+ int properties_text_len = strlen(properties_text) * font1_width;
+ int xpos = ED_ELEMENT_SETTINGS_X(0);
+ int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE;
int i, x, y;
if (setup.editor.show_element_token)
{
- DrawTextF(pad_x, pad_y + screen_line++ * font2_height, FONT_TEXT_3,
+ int font3_nr = FONT_TEXT_3;
+ int font3_height = getFontHeight(font3_nr);
+
+ DrawTextF(xpos, ypos, font3_nr,
"[%s]", element_info[properties_element].token_name);
- screen_line++;
+
+ ypos += 2 * font3_height;
}
/* ----- print number of elements / percentage of this element in level */
num_elements_in_level++;
percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
- DrawTextS(pad_x, pad_y + screen_line * font2_height, font1_nr,
- percentage_text);
- DrawTextF(pad_x + strlen(percentage_text) * font1_width,
- pad_y + screen_line++ * font2_height, font2_nr,
- "%d (%.2f%%)", num_elements_in_level, percentage);
+ DrawTextS(xpos, ypos, font1_nr, percentage_text);
+
+ if (num_elements_in_level > 0)
+ DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr,
+ "%d (%.2f %%)", num_elements_in_level, percentage);
+ else
+ DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr,
+ none_text);
- screen_line++;
+ ypos += 2 * MAX(font1_height, font2_height);
/* ----- print standard properties of this element */
- DrawTextS(pad_x, pad_y + screen_line++ * font2_height, font1_nr,
- properties_text);
+ DrawTextS(xpos, ypos, font1_nr, properties_text);
+
+ ypos += line1_height;
for (i = 0; properties[i].value != -1; i++)
{
if (!HAS_PROPERTY(properties_element, properties[i].value))
continue;
- DrawTextS(pad_x, pad_y + screen_line++ * font2_height, font2_nr,
- properties[i].text);
+ DrawTextS(xpos, ypos, font2_nr, properties[i].text);
+
+ ypos += font2_height;
+
num_standard_properties++;
}
if (num_standard_properties == 0)
- DrawTextS(pad_x + strlen(properties_text) * font1_width,
- pad_y + (screen_line - 1) * font2_height, font2_nr, "none");
+ {
+ DrawTextS(xpos + properties_text_len, ypos - line1_height + font2_yoffset,
+ font2_nr, none_text);
+
+ ypos -= (line1_height - font1_height);
+ }
- screen_line++;
+ ypos += MAX(font1_height, font2_height);
/* ----- print special description of this element */
- PrintInfoText("Description:", FONT_TEXT_1, screen_line);
- if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0)
- PrintInfoText("No description available.", FONT_TEXT_1, screen_line);
+ PrintInfoText(description_text, font1_nr, xpos, ypos);
+
+ ypos += line1_height;
+
+ if (PrintElementDescriptionFromFile(filename, font2_nr, xpos, ypos) == 0)
+ PrintInfoText(no_description_text, font1_nr, xpos, ypos - line1_height);
}
#define TEXT_COLLECTING "Score for collecting"
{ EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING },
{ EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING },
{ EL_EMC_KEY_8, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_DC_KEY_WHITE, &level.score[SC_KEY], TEXT_COLLECTING },
{ EL_AMOEBA_WET, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
{ EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
{ EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
HAS_EDITOR_CONTENT(element) ||
CAN_GROW(element) ||
COULD_MOVE_INTO_ACID(element) ||
- MAYBE_DONT_COLLIDE_WITH(element))
+ MAYBE_DONT_COLLIDE_WITH(element) ||
+ element == EL_SOKOBAN_OBJECT ||
+ element == EL_SOKOBAN_FIELD_EMPTY ||
+ element == EL_SOKOBAN_FIELD_FULL)
return TRUE;
else
for (i = 0; elements_with_counter[i].element != -1; i++)
static void DrawPropertiesConfig()
{
+ boolean draw_footer_line = FALSE;
int max_num_element_counters = 4;
int num_element_counters = 0;
int i;
if (!checkPropertiesConfig(properties_element))
{
- PrintInfoText("No configuration options available.", FONT_TEXT_1, 0);
+ int xpos = ED_ELEMENT_SETTINGS_X(0);
+ int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE;
+
+ PrintInfoText("No configuration options available.",
+ FONT_TEXT_1, xpos, ypos);
return;
}
/* these properties can be set for every player individually */
- drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value =
- &level.start_element[player_nr];
- drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value =
- &level.artwork_element[player_nr];
- drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value =
- &level.explosion_element[player_nr];
-
- checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value =
- &level.use_start_element[player_nr];
- checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value =
- &level.use_artwork_element[player_nr];
- checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value =
- &level.use_explosion_element[player_nr];
- checkbutton_info[ED_CHECKBUTTON_ID_INITIAL_GRAVITY].value =
- &level.initial_player_gravity[player_nr];
-
- selectbox_info[ED_SELECTBOX_ID_PLAYER_SPEED].value =
- &level.initial_player_stepsize[player_nr];
-
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID);
- MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ?
- ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD :
- ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_GRAVITY);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE);
-
- MapDrawingArea(ED_DRAWING_ID_START_ELEMENT);
- MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT);
- MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT);
-
- MapSelectboxGadget(ED_SELECTBOX_ID_PLAYER_SPEED);
+ if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_1)
+ {
+ drawingarea_info[ED_DRAWING_ID_START_ELEMENT].value =
+ &level.start_element[player_nr];
+ drawingarea_info[ED_DRAWING_ID_ARTWORK_ELEMENT].value =
+ &level.artwork_element[player_nr];
+ drawingarea_info[ED_DRAWING_ID_EXPLOSION_ELEMENT].value =
+ &level.explosion_element[player_nr];
+
+ checkbutton_info[ED_CHECKBUTTON_ID_USE_START_ELEMENT].value =
+ &level.use_start_element[player_nr];
+ checkbutton_info[ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT].value =
+ &level.use_artwork_element[player_nr];
+ checkbutton_info[ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT].value =
+ &level.use_explosion_element[player_nr];
+ checkbutton_info[ED_CHECKBUTTON_ID_INITIAL_GRAVITY].value =
+ &level.initial_player_gravity[player_nr];
+
+ selectbox_info[ED_SELECTBOX_ID_PLAYER_SPEED].value =
+ &level.initial_player_stepsize[player_nr];
+
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID);
+ MapCheckbuttonGadget(properties_element == EL_SP_MURPHY ?
+ ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD :
+ ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_SHIFTED_RELOCATION);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_LAZY_RELOCATION);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_START_ELEMENT);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_GRAVITY);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE);
+
+ MapDrawingArea(ED_DRAWING_ID_START_ELEMENT);
+ MapDrawingArea(ED_DRAWING_ID_ARTWORK_ELEMENT);
+ MapDrawingArea(ED_DRAWING_ID_EXPLOSION_ELEMENT);
+
+ MapSelectboxGadget(ED_SELECTBOX_ID_PLAYER_SPEED);
+ }
+ else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2)
+ {
+ drawingarea_info[ED_DRAWING_ID_INVENTORY_CONTENT].value =
+ &level.initial_inventory_content[player_nr][0];
+
+ counterbutton_info[ED_COUNTER_ID_INVENTORY_SIZE].value =
+ &level.initial_inventory_size[player_nr];
+
+ checkbutton_info[ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY].value =
+ &level.use_initial_inventory[player_nr];
+
+ /* draw checkbutton gadgets */
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY);
+
+ /* draw counter gadgets */
+ MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE);
+
+ /* draw drawing area gadgets */
+ DrawPlayerInitialInventoryArea(properties_element);
+ }
}
if (IS_GEM(properties_element))
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS);
+ if (properties_element == EL_EM_DYNAMITE)
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE);
+
if (COULD_MOVE_INTO_ACID(properties_element) &&
!ELEM_IS_PLAYER(properties_element) &&
(!IS_CUSTOM_ELEMENT(properties_element) ||
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE);
}
+ if (properties_element == EL_SOKOBAN_OBJECT ||
+ properties_element == EL_SOKOBAN_FIELD_EMPTY ||
+ properties_element == EL_SOKOBAN_FIELD_FULL)
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN);
+
if (IS_ENVELOPE(properties_element))
{
int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE;
MapSelectboxGadget(i);
/* draw textbutton gadgets */
- MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE);
+ MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1);
/* draw text input gadgets */
MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME);
/* draw drawing area gadgets */
MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC);
+
+ draw_footer_line = TRUE;
}
else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2)
{
/* draw checkbutton gadgets */
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC);
- MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1);
/* draw counter gadgets */
MapCounterButtons(ED_COUNTER_ID_GROUP_CONTENT);
MapSelectboxGadget(ED_SELECTBOX_ID_GROUP_CHOICE_MODE);
/* draw textbutton gadgets */
- MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE);
+ MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1);
/* draw drawing area gadgets */
DrawGroupElementArea(properties_element);
/* draw drawing area gadgets */
MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC);
+
+ draw_footer_line = TRUE;
+ }
+
+ /* draw little footer border line above CE/GE use/save template gadgets */
+ if (draw_footer_line)
+ {
+ struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ 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;
+ Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
+
+ if (tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto,
+ SX + ED_ELEMENT_SETTINGS_X(0),
+ SY + ED_ELEMENT_SETTINGS_Y(14) - ED_SETTINGS_TABS_YOFFSET -
+ ED_TAB_BAR_HEIGHT,
+ getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color);
}
}
{
MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TARGET);
MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER);
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_ACTION);
DrawCustomChangeContentArea();
}
ANIM_MODE(graphic) == ANIM_CE_SCORE ?
custom_element.collect_score_initial : FrameCounter);
- DrawGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING);
+ DrawFixedGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING);
}
-static void DrawEditorElementName(int x, int y, int element)
+static void DrawEditorElementName(int x, int y, int font_nr)
{
- char *element_name = getElementInfoText(element);
- int font_nr = FONT_TEXT_1;
+ char *element_name = getElementInfoText(properties_element);
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
- int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_XPOS(0);
+ int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_X(0);
int max_chars_per_line = max_text_width / font_width;
char buffer[max_chars_per_line + 1];
static void DrawPropertiesWindow()
{
- int xstart = 2;
- int ystart = 4;
+ struct GraphicInfo *gd = &graphic_info[IMG_EDITOR_INPUT_TEXT];
+ int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size;
+ int border_size = gd->border_size;
+ int font_nr = FONT_TEXT_1;
+ int font_height = getFontHeight(font_nr);
+ int xoffset = TILEX + element_border + 3 * border_size;
+ int yoffset = (TILEY - font_height) / 2;
+ int x1 = editor.settings.element_graphic.x + element_border;
+ int y1 = editor.settings.element_graphic.y + element_border;
+ int x2 = (editor.settings.element_name.x == -1 ? x1 + xoffset :
+ editor.settings.element_name.x);
+ int y2 = (editor.settings.element_name.y == -1 ? y1 + yoffset :
+ editor.settings.element_name.y);
+ char *text = "Element Settings";
+ int font2_nr = FONT_TITLE_1;
+ struct MenuPosInfo *pos = &editor.settings.headline;
+ int sx = SX + ALIGNED_XPOS(pos->x, getTextWidth(text, font2_nr), pos->align);
+ int sy = SY + pos->y;
stick_element_properties_window = FALSE;
/* make sure that previous properties edit mode exists for this element */
+ if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG_2 &&
+ !IS_CUSTOM_ELEMENT(properties_element))
+ edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2;
+
if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG &&
+ !ELEM_IS_PLAYER(properties_element) &&
!IS_CUSTOM_ELEMENT(properties_element))
edit_mode_properties = ED_MODE_PROPERTIES_CONFIG;
if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG &&
- IS_CUSTOM_ELEMENT(properties_element))
+ (ELEM_IS_PLAYER(properties_element) ||
+ IS_CUSTOM_ELEMENT(properties_element)))
edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1;
CopyElementPropertiesToEditor(properties_element);
- UnmapLevelEditorWindowGadgets();
+ UnmapLevelEditorFieldGadgets();
UnmapLevelEditorToolboxDrawingGadgets();
UnmapLevelEditorToolboxCustomGadgets();
MapLevelEditorToolboxCustomGadgets();
SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
- ClearWindow();
+ ClearField();
-#if 0
- DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Element Settings");
-#else
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS,
- "Element Settings", FONT_TITLE_1);
-#endif
+ DrawText(sx, sy, text, font2_nr);
FrameCounter = 0; /* restart animation frame counter */
- DrawElementBorder(SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY + MINI_TILEY / 2,
- TILEX, TILEY, FALSE);
-
- DrawEditorElementAnimation(SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY + MINI_TILEY / 2);
-
- DrawEditorElementName((xstart + 3) * MINI_TILEX + 1,
- (ystart + 1) * MINI_TILEY + 1,
- properties_element);
+ DrawElementBorder(SX + x1, SY + y1, TILEX, TILEY, FALSE);
+ DrawEditorElementAnimation(SX + x1, SY + y1);
+ DrawEditorElementName(x2, y2, font_nr);
DrawPropertiesTabulatorGadgets();
DrawPropertiesConfig();
}
+static void DrawPaletteWindow()
+{
+ int i;
+
+ UnmapLevelEditorFieldGadgets();
+
+ SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
+ ClearField();
+
+ /* map buttons to select elements */
+ for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_UP]);
+ MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_DOWN]);
+}
+
static void UpdateCustomElementGraphicGadgets()
{
int i;
+ InitElementPropertiesGfxElement();
+
ModifyEditorElementList();
RedrawDrawingElements();
}
}
-static int getDirectionFromTube(int element)
+static int getOpenDirectionFromTube(int element)
{
switch (element)
{
return MV_NONE;
}
-static int getTubeFromDirection(int direction)
+static int getTubeFromOpenDirection(int direction)
{
switch (direction)
{
return EL_EMPTY;
}
-static int getTubeFromDirectionNotEmpty(int direction, int element_old)
+static int getTubeFromOpenDirectionNotEmpty(int direction, int element_old)
{
- int element_new = getTubeFromDirection(direction);
+ int element_new = getTubeFromOpenDirection(direction);
return (element_new != EL_EMPTY ? element_new : element_old);
}
direction == MV_RIGHT ? MV_LEFT :
direction == MV_HORIZONTAL ? MV_NONE : direction);
+ if (direction == MV_NONE)
+ return EL_EMPTY;
+
return getBeltElementFromBeltNrAndBeltDir(nr, belt_dir);
}
-static int getClosedTube(int x, int y)
+static int getBeltFromNrAndOpenDirectionNotEmpty(int nr, int direction,
+ int element_old)
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
- int element_old = IntelliDrawBuffer[x][y];
- int tube_direction_old = getDirectionFromTube(element_old);
- int tube_direction_new = MV_NONE;
- int i;
+ int element_new = getBeltFromNrAndOpenDirection(nr, direction);
- for (i = 0; i < NUM_DIRECTIONS; i++)
- {
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
- int dir = MV_DIR_FROM_BIT(i);
- int dir_opposite = MV_DIR_OPPOSITE(dir);
+ return (element_new != EL_EMPTY ? element_new : element_old);
+}
+
+static int getOpenDirectionFromPool(int element)
+{
+ switch (element)
+ {
+ case EL_ACID_POOL_TOPLEFT: return (MV_DOWN | MV_RIGHT);
+ case EL_ACID_POOL_TOPRIGHT: return (MV_DOWN | MV_LEFT);
+ case EL_ACID_POOL_BOTTOMLEFT: return (MV_UP | MV_RIGHT);
+ case EL_ACID_POOL_BOTTOMRIGHT: return (MV_UP | MV_LEFT);
+ case EL_ACID_POOL_BOTTOM: return (MV_HORIZONTAL | MV_UP);
+ case EL_ACID: return (MV_HORIZONTAL | MV_DOWN);
+ }
+
+ return MV_NONE;
+}
+
+static int getPoolFromOpenDirection(int direction)
+{
+ switch (direction)
+ {
+ case (MV_DOWN | MV_RIGHT): return EL_ACID_POOL_TOPLEFT;
+ case (MV_DOWN | MV_LEFT): return EL_ACID_POOL_TOPRIGHT;
+ case (MV_UP | MV_RIGHT): return EL_ACID_POOL_BOTTOMLEFT;
+ case (MV_UP | MV_LEFT): return EL_ACID_POOL_BOTTOMRIGHT;
+ case (MV_HORIZONTAL | MV_UP): return EL_ACID_POOL_BOTTOM;
+ case (MV_HORIZONTAL | MV_DOWN): return EL_ACID;
+ }
+
+ return EL_EMPTY;
+}
+
+static int getPoolFromOpenDirectionExt(int direction, int help_element)
+{
+ int element = getPoolFromOpenDirection(direction);
+ int help_direction = getOpenDirectionFromPool(help_element);
+
+ if (element == EL_EMPTY)
+ {
+ int help_direction_vertical = help_direction & MV_VERTICAL;
+
+ element = getPoolFromOpenDirection(direction | help_direction_vertical);
+ }
+
+ if (element == EL_EMPTY)
+ {
+ int help_direction_horizontal = help_direction & MV_HORIZONTAL;
+
+ element = getPoolFromOpenDirection(direction | help_direction_horizontal);
+ }
+
+ return element;
+}
+
+static int getPoolFromOpenDirectionNotEmpty(int direction, int element_old)
+{
+ int element_new = getPoolFromOpenDirectionExt(direction, element_old);
+
+ return (element_new != EL_EMPTY ? element_new : element_old);
+}
+
+static int getOpenDirectionFromPillar(int element)
+{
+ switch (element)
+ {
+ case EL_EMC_WALL_1: return (MV_DOWN);
+ case EL_EMC_WALL_2: return (MV_VERTICAL);
+ case EL_EMC_WALL_3: return (MV_UP);
+ }
+
+ return MV_NONE;
+}
+
+static int getPillarFromOpenDirection(int direction)
+{
+ switch (direction)
+ {
+ case (MV_DOWN): return EL_EMC_WALL_1;
+ case (MV_VERTICAL): return EL_EMC_WALL_2;
+ case (MV_UP): return EL_EMC_WALL_3;
+ }
+
+ return EL_EMPTY;
+}
+
+static int getPillarFromOpenDirectionNotEmpty(int direction, int element_old)
+{
+ int element_new = getPillarFromOpenDirection(direction);
+
+ return (element_new != EL_EMPTY ? element_new : element_old);
+}
+
+static int getOpenDirectionFromSteel2(int element)
+{
+ switch (element)
+ {
+ case EL_DC_STEELWALL_2_LEFT: return (MV_RIGHT);
+ case EL_DC_STEELWALL_2_RIGHT: return (MV_LEFT);
+ case EL_DC_STEELWALL_2_TOP: return (MV_DOWN);
+ case EL_DC_STEELWALL_2_BOTTOM: return (MV_UP);
+ case EL_DC_STEELWALL_2_HORIZONTAL: return (MV_HORIZONTAL);
+ case EL_DC_STEELWALL_2_VERTICAL: return (MV_VERTICAL);
+ case EL_DC_STEELWALL_2_MIDDLE: return (MV_ANY_DIRECTION);
+ case EL_DC_STEELWALL_2_SINGLE: return (MV_NONE);
+ }
+
+ return MV_NONE;
+}
+
+static int getSteel2FromOpenDirection(int direction)
+{
+ switch (direction)
+ {
+ case (MV_RIGHT): return EL_DC_STEELWALL_2_LEFT;
+ case (MV_LEFT): return EL_DC_STEELWALL_2_RIGHT;
+ case (MV_DOWN): return EL_DC_STEELWALL_2_TOP;
+ case (MV_UP): return EL_DC_STEELWALL_2_BOTTOM;
+ case (MV_HORIZONTAL): return EL_DC_STEELWALL_2_HORIZONTAL;
+ case (MV_VERTICAL): return EL_DC_STEELWALL_2_VERTICAL;
+ case (MV_ANY_DIRECTION): return EL_DC_STEELWALL_2_MIDDLE;
+ case (MV_NONE): return EL_DC_STEELWALL_2_SINGLE;
+ }
+
+ return EL_EMPTY;
+}
+
+static int getSteel2FromOpenDirectionNotEmpty(int direction, int element_old)
+{
+ int element_new = getSteel2FromOpenDirection(direction);
+
+ return (element_new != EL_EMPTY ? element_new : element_old);
+}
+
+static int getOpenDirectionFromChip(int element)
+{
+ switch (element)
+ {
+ case EL_SP_CHIP_SINGLE: return (MV_NONE);
+ case EL_SP_CHIP_LEFT: return (MV_RIGHT);
+ case EL_SP_CHIP_RIGHT: return (MV_LEFT);
+ case EL_SP_CHIP_TOP: return (MV_DOWN);
+ case EL_SP_CHIP_BOTTOM: return (MV_UP);
+ }
+
+ return MV_NONE;
+}
+
+static int getChipFromOpenDirection(int direction)
+{
+ switch (direction)
+ {
+ case (MV_NONE): return EL_SP_CHIP_SINGLE;
+ case (MV_LEFT): return EL_SP_CHIP_RIGHT;
+ case (MV_RIGHT): return EL_SP_CHIP_LEFT;
+ case (MV_UP): return EL_SP_CHIP_BOTTOM;
+ case (MV_DOWN): return EL_SP_CHIP_TOP;
+ }
+
+ return EL_EMPTY;
+}
+
+static int getChipFromOpenDirectionNotEmpty(int direction, int element_old)
+{
+ int element_new = getChipFromOpenDirection(direction);
+
+ return (element_new != EL_EMPTY ? element_new : element_old);
+}
+
+static int getClosedTube(int x, int y)
+{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
+ int element_old = IntelliDrawBuffer[x][y];
+ int direction_old = getOpenDirectionFromTube(element_old);
+ int direction_new = MV_NONE;
+ int i;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
if (IN_LEV_FIELD(xx, yy) && IS_TUBE(IntelliDrawBuffer[xx][yy]) &&
- (tube_direction_old & dir) &&
- (getDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite))
- tube_direction_new |= dir;
+ (direction_old & dir) &&
+ (getOpenDirectionFromTube(IntelliDrawBuffer[xx][yy]) & dir_opposite))
+ direction_new |= dir;
}
- return getTubeFromDirectionNotEmpty(tube_direction_new, element_old);
+ return getTubeFromOpenDirectionNotEmpty(direction_new, element_old);
}
static int getClosedBelt(int x, int y)
{
- static int xy[2][2] =
+ static int xy[4][2] =
{
{ -1, 0 },
{ +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
};
int element_old = IntelliDrawBuffer[x][y];
- int belt_nr = getBeltNrFromBeltElement(element_old);
- int belt_direction_old = getOpenDirectionFromBelt(element_old);
- int belt_direction_new = MV_NONE;
+ int nr = getBeltNrFromBeltElement(element_old);
+ int direction_old = getOpenDirectionFromBelt(element_old);
+ int direction_new = MV_NONE;
int i;
- for (i = 0; i < 2; i++)
+ for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++)
{
int xx = x + xy[i][0];
int yy = y + xy[i][1];
int dir_opposite = MV_DIR_OPPOSITE(dir);
if (IN_LEV_FIELD(xx, yy) && IS_BELT(IntelliDrawBuffer[xx][yy]) &&
- (belt_direction_old & dir) &&
+ (direction_old & dir) &&
(getOpenDirectionFromBelt(IntelliDrawBuffer[xx][yy]) & dir_opposite))
- belt_direction_new |= dir;
+ direction_new |= dir;
}
- return getBeltFromNrAndOpenDirection(belt_nr, belt_direction_new);
+ return getBeltFromNrAndOpenDirection(nr, direction_new);
+}
+
+static int getClosedPool(int x, int y)
+{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
+ int element_old = IntelliDrawBuffer[x][y];
+ int direction_old = getOpenDirectionFromPool(element_old);
+ int direction_new = MV_NONE;
+ int i;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+
+ if (IN_LEV_FIELD(xx, yy) &&
+ IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[xx][yy]) &&
+ (direction_old & dir) &&
+ (getOpenDirectionFromPool(IntelliDrawBuffer[xx][yy]) & dir_opposite))
+ direction_new |= dir;
+ }
+
+ return getPoolFromOpenDirectionNotEmpty(direction_new, element_old);
+}
+
+static int getClosedPillar(int x, int y)
+{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
+ int element_old = IntelliDrawBuffer[x][y];
+ int direction_old = getOpenDirectionFromPillar(element_old);
+ int direction_new = MV_NONE;
+ int i;
+
+ for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+
+ if (IN_LEV_FIELD(xx, yy) && IS_EMC_PILLAR(IntelliDrawBuffer[xx][yy]) &&
+ (direction_old & dir) &&
+ (getOpenDirectionFromPillar(IntelliDrawBuffer[xx][yy]) & dir_opposite))
+ direction_new |= dir;
+ }
+
+ return getPillarFromOpenDirectionNotEmpty(direction_new, element_old);
+}
+
+static int getClosedSteel2(int x, int y)
+{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
+ int element_old = IntelliDrawBuffer[x][y];
+ int direction_old = getOpenDirectionFromSteel2(element_old);
+ int direction_new = MV_NONE;
+ int i;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+
+ if (IN_LEV_FIELD(xx, yy) && IS_DC_STEELWALL_2(IntelliDrawBuffer[xx][yy]) &&
+ (direction_old & dir) &&
+ (getOpenDirectionFromSteel2(IntelliDrawBuffer[xx][yy]) & dir_opposite))
+ direction_new |= dir;
+ }
+
+ return getSteel2FromOpenDirectionNotEmpty(direction_new, element_old);
+}
+
+static int getClosedChip(int x, int y)
+{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
+ int element_old = IntelliDrawBuffer[x][y];
+ int direction_old = getOpenDirectionFromChip(element_old);
+ int direction_new = MV_NONE;
+ int i;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+
+ if (IN_LEV_FIELD(xx, yy) && IS_SP_CHIP(IntelliDrawBuffer[xx][yy]) &&
+ (direction_old & dir) &&
+ (getOpenDirectionFromChip(IntelliDrawBuffer[xx][yy]) & dir_opposite))
+ direction_new |= dir;
+ }
+
+ return getChipFromOpenDirectionNotEmpty(direction_new, element_old);
}
static void SetElementSimple(int x, int y, int element, boolean change_level)
{
+ int sx = x - level_xpos;
+ int sy = y - level_ypos;
+
+ IntelliDrawBuffer[x][y] = element;
+
if (change_level)
Feld[x][y] = element;
- IntelliDrawBuffer[x][y] = element;
+ if (IN_ED_FIELD(sx, sy))
+ DrawEditorElement(sx, sy, element);
+}
+
+static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1,
+ int x2, int y2, int *element2,
+ int (*close_function)(int, int),
+ boolean change_level)
+{
+ /* set neighbour elements to newly determined connections */
+ SetElementSimple(x1, y1, *element1, change_level);
+ SetElementSimple(x2, y2, *element2, change_level);
- if (IN_ED_FIELD(x - level_xpos, y - level_ypos))
- DrawMiniElement(x - level_xpos, y - level_ypos, element);
+ /* remove all open connections of neighbour elements */
+ *element1 = close_function(x1, y1);
+ *element2 = close_function(x2, y2);
+
+ /* set neighbour elements to new, minimized connections */
+ SetElementSimple(x1, y1, *element1, change_level);
+ SetElementSimple(x2, y2, *element2, change_level);
}
static void SetElementIntelliDraw(int x, int y, int new_element,
- boolean change_level)
+ boolean change_level, int button)
{
+ static int xy[4][2] =
+ {
+ { -1, 0 },
+ { +1, 0 },
+ { 0, -1 },
+ { 0, +1 }
+ };
static int last_x = -1;
static int last_y = -1;
int old_element = IntelliDrawBuffer[x][y];
if (IS_TUBE(new_element))
{
- static int xy[4][2] =
- {
- { -1, 0 },
- { +1, 0 },
- { 0, -1 },
- { 0, +1 }
- };
- boolean last_element_is_neighbour = FALSE;
- int last_element_new;
+ int last_element_new = EL_UNDEFINED;
int direction = MV_NONE;
int i;
- /* if existing element is tube, keep all existing tube directions */
+ /* if old element is of same kind, keep all existing directions */
if (IS_TUBE(old_element))
- direction |= getDirectionFromTube(old_element);
+ direction |= getOpenDirectionFromTube(old_element);
for (i = 0; i < NUM_DIRECTIONS; i++)
{
int dir = MV_DIR_FROM_BIT(i);
int dir_opposite = MV_DIR_OPPOSITE(dir);
int last_element_old = IntelliDrawBuffer[last_x][last_y];
- int last_direction_old = getDirectionFromTube(last_element_old);
+ int last_direction_old = getOpenDirectionFromTube(last_element_old);
int last_direction_new = last_direction_old | dir_opposite;
- last_element_new = getTubeFromDirection(last_direction_new);
- last_element_is_neighbour = TRUE;
+ last_element_new = getTubeFromOpenDirection(last_direction_new);
direction |= dir;
}
}
- new_element = getTubeFromDirectionNotEmpty(direction, new_element);
-
- /* reduce connections of neighbour tube elements to minimal connections */
- if (last_element_is_neighbour)
- {
- /* set neighbour tube elements to newly determined tube connections */
- SetElementSimple(x, y, new_element, change_level);
- SetElementSimple(last_x, last_y, last_element_new, change_level);
-
- /* remove all open tube connections of neighbour tube elements */
- new_element = getClosedTube(x, y);
- last_element_new = getClosedTube(last_x, last_y);
+ new_element = getTubeFromOpenDirectionNotEmpty(direction, new_element);
- /* set neighbour tube elements to new, minimized tube connections */
- SetElementSimple(x, y, new_element, change_level);
- SetElementSimple(last_x, last_y, last_element_new, change_level);
- }
+ if (last_element_new != EL_UNDEFINED)
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedTube, change_level);
}
- else if (IS_ACID_POOL(new_element))
+ else if (IS_BELT(new_element))
{
+ int belt_nr = getBeltNrFromBeltElement(new_element);
int last_element_new = EL_UNDEFINED;
+ int direction = MV_NONE;
+ int i;
- if (IS_ACID_POOL(old_element))
- {
- new_element = old_element;
- }
+ /* if old element is of same kind, keep all existing directions */
+ if (IS_BELT(old_element))
+ direction |= getOpenDirectionFromBelt(old_element);
- if (last_x == x - 1 && last_y == y && IN_LEV_FIELD(last_x, last_y) &&
- IS_ACID_POOL(IntelliDrawBuffer[last_x][last_y]))
- {
- if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPLEFT)
- {
- new_element = EL_ACID_POOL_TOPRIGHT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPRIGHT)
- {
- last_element_new = EL_ACID;
- new_element = EL_ACID_POOL_TOPRIGHT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMLEFT)
- {
- new_element = EL_ACID_POOL_BOTTOMRIGHT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMRIGHT)
- {
- last_element_new = EL_ACID_POOL_BOTTOM;
- new_element = EL_ACID_POOL_BOTTOMRIGHT;
- }
- }
- else if (last_x == x + 1 && last_y == y && IN_LEV_FIELD(last_x, last_y) &&
- IS_ACID_POOL(IntelliDrawBuffer[last_x][last_y]))
+ for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++)
{
- if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPLEFT)
- {
- last_element_new = EL_ACID;
- new_element = EL_ACID_POOL_TOPLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPRIGHT)
- {
- new_element = EL_ACID_POOL_TOPLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMLEFT)
- {
- last_element_new = EL_ACID_POOL_BOTTOM;
- new_element = EL_ACID_POOL_BOTTOMLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMRIGHT)
- {
- new_element = EL_ACID_POOL_BOTTOMLEFT;
- }
- }
- else if (last_x == x && last_y == y - 1 && IN_LEV_FIELD(last_x, last_y) &&
- IS_ACID_POOL(IntelliDrawBuffer[last_x][last_y]))
- {
- if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPLEFT)
- {
- new_element = EL_ACID_POOL_BOTTOMLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPRIGHT)
- {
- new_element = EL_ACID_POOL_BOTTOMRIGHT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMLEFT)
- {
- last_element_new = EL_ACID_POOL_TOPLEFT;
- new_element = EL_ACID_POOL_BOTTOMLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMRIGHT)
- {
- last_element_new = EL_ACID_POOL_TOPRIGHT;
- new_element = EL_ACID_POOL_BOTTOMRIGHT;
- }
- else
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_BELT(IntelliDrawBuffer[last_x][last_y]))
{
- last_element_new = EL_ACID;
- new_element = EL_ACID_POOL_BOTTOM;
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+ int last_element_old = IntelliDrawBuffer[last_x][last_y];
+ int last_belt_nr = getBeltNrFromBeltElement(last_element_old);
+ int last_direction_old = getOpenDirectionFromBelt(last_element_old);
+ int last_direction_new = last_direction_old | dir_opposite;
+
+ last_element_new = getBeltFromNrAndOpenDirection(last_belt_nr,
+ last_direction_new);
+ direction |= dir;
}
}
- else if (last_x == x && last_y == y + 1 && IN_LEV_FIELD(last_x, last_y) &&
- IS_ACID_POOL(IntelliDrawBuffer[last_x][last_y]))
+
+ new_element = getBeltFromNrAndOpenDirectionNotEmpty(belt_nr, direction,
+ new_element);
+ if (last_element_new != EL_UNDEFINED)
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedBelt, change_level);
+ }
+ else if (IS_ACID_POOL_OR_ACID(new_element))
+ {
+ int last_element_new = EL_UNDEFINED;
+ int direction = MV_NONE;
+ int i;
+
+ /* if old element is of same kind, keep all existing directions */
+ if (IS_ACID_POOL_OR_ACID(old_element))
+ direction |= getOpenDirectionFromPool(old_element);
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
{
- if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPLEFT)
- {
- new_element = EL_ACID_POOL_TOPLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_TOPRIGHT)
- {
- new_element = EL_ACID_POOL_TOPRIGHT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMLEFT)
- {
- new_element = EL_ACID_POOL_TOPLEFT;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == EL_ACID_POOL_BOTTOMRIGHT)
- {
- new_element = EL_ACID_POOL_TOPRIGHT;
- }
- else
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y]))
{
- last_element_new = EL_ACID;
- new_element = EL_ACID;
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+ int last_element_old = IntelliDrawBuffer[last_x][last_y];
+ int last_direction_old = getOpenDirectionFromPool(last_element_old);
+ int last_direction_new = last_direction_old | dir_opposite;
+
+ last_element_new = getPoolFromOpenDirection(last_direction_new);
+
+ direction |= dir;
}
}
+ /* special corrections needed for intuitively correct acid pool drawing */
+ if (last_element_new == EL_EMPTY)
+ last_element_new = new_element;
+ else if (last_element_new != EL_UNDEFINED)
+ new_element = last_element_new;
+
+ new_element = getPoolFromOpenDirectionNotEmpty(direction, new_element);
+
if (last_element_new != EL_UNDEFINED)
- SetElementSimple(last_x, last_y, last_element_new, change_level);
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedPool, change_level);
}
- else if (IS_BELT(new_element))
+ else if (IS_EMC_PILLAR(new_element))
{
int last_element_new = EL_UNDEFINED;
- int belt_nr = getBeltNrFromBeltElement(new_element);
-#if 0
- int belt_left = getBeltElementFromBeltNrAndBeltDir(belt_nr, MV_LEFT);
-#endif
- int belt_middle = getBeltElementFromBeltNrAndBeltDir(belt_nr, MV_NONE);
-#if 0
- int belt_right = getBeltElementFromBeltNrAndBeltDir(belt_nr, MV_RIGHT);
-#endif
- boolean last_element_is_neighbour = FALSE;
+ int direction = MV_NONE;
+ int i;
-#if 0
- if (IS_BELT(old_element))
- {
- new_element = old_element;
- }
-#endif
+ /* if old element is of same kind, keep all existing directions */
+ if (IS_EMC_PILLAR(old_element))
+ direction |= getOpenDirectionFromPillar(old_element);
- if (last_x == x - 1 && last_y == y && IN_LEV_FIELD(last_x, last_y) &&
- IS_BELT(IntelliDrawBuffer[last_x][last_y]))
+ for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++)
{
- last_element_new = IntelliDrawBuffer[last_x][last_y];
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
-#if 1
- last_element_new = belt_middle;
- new_element = belt_middle;
-#else
- if (IntelliDrawBuffer[last_x][last_y] == belt_left)
- {
- new_element = belt_right;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == belt_right)
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y]))
{
- last_element_new = belt_middle;
- new_element = belt_right;
- }
-#endif
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+ int last_element_old = IntelliDrawBuffer[last_x][last_y];
+ int last_direction_old = getOpenDirectionFromPillar(last_element_old);
+ int last_direction_new = last_direction_old | dir_opposite;
- last_element_is_neighbour = TRUE;
- }
- else if (last_x == x + 1 && last_y == y && IN_LEV_FIELD(last_x, last_y) &&
- IS_BELT(IntelliDrawBuffer[last_x][last_y]))
- {
- last_element_new = IntelliDrawBuffer[last_x][last_y];
+ last_element_new = getPillarFromOpenDirection(last_direction_new);
-#if 1
- last_element_new = belt_middle;
- new_element = belt_middle;
-#else
- if (IntelliDrawBuffer[last_x][last_y] == belt_left)
- {
- last_element_new = belt_middle;
- new_element = belt_left;
- }
- else if (IntelliDrawBuffer[last_x][last_y] == belt_right)
- {
- new_element = belt_left;
+ direction |= dir;
}
-#endif
-
- last_element_is_neighbour = TRUE;
}
+ new_element = getPillarFromOpenDirectionNotEmpty(direction, new_element);
+
if (last_element_new != EL_UNDEFINED)
- SetElementSimple(last_x, last_y, last_element_new, change_level);
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedPillar, change_level);
+ }
+ else if (IS_DC_STEELWALL_2(new_element))
+ {
+ int last_element_new = EL_UNDEFINED;
+ int direction = MV_NONE;
+ int i;
+
+ /* if old element is of same kind, keep all existing directions */
+ if (IS_DC_STEELWALL_2(old_element))
+ direction |= getOpenDirectionFromSteel2(old_element);
- /* reduce connections of neighbour belt elements to minimal connections */
- if (last_element_is_neighbour)
+ for (i = 0; i < NUM_DIRECTIONS; i++)
{
- /* set neighbour belt elements to newly determined belt connections */
- SetElementSimple(x, y, new_element, change_level);
- SetElementSimple(last_x, last_y, last_element_new, change_level);
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y]))
+ {
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+ int last_element_old = IntelliDrawBuffer[last_x][last_y];
+ int last_direction_old = getOpenDirectionFromSteel2(last_element_old);
+ int last_direction_new = last_direction_old | dir_opposite;
- /* remove all open belt connections of neighbour belt elements */
- new_element = getClosedBelt(x, y);
- last_element_new = getClosedBelt(last_x, last_y);
+ last_element_new = getSteel2FromOpenDirection(last_direction_new);
- /* set neighbour belt elements to new, minimized belt connections */
- SetElementSimple(x, y, new_element, change_level);
- SetElementSimple(last_x, last_y, last_element_new, change_level);
+ direction |= dir;
+ }
}
+
+ new_element = getSteel2FromOpenDirectionNotEmpty(direction, new_element);
+
+ if (last_element_new != EL_UNDEFINED)
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedSteel2, change_level);
}
- else if (new_element == EL_EMC_WALL_1 ||
- new_element == EL_EMC_WALL_2 ||
- new_element == EL_EMC_WALL_3)
+ else if (IS_SP_CHIP(new_element))
{
int last_element_new = EL_UNDEFINED;
+ int direction = MV_NONE;
+ int i;
- if (last_x == x && last_y == y - 1 && IN_LEV_FIELD(last_x, last_y) &&
- (IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_1 ||
- IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_2 ||
- IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_3))
+ /* (do not keep existing directions, regardless of kind of old element) */
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
{
- if (IN_LEV_FIELD(last_x, last_y - 1))
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y]))
{
- if (IntelliDrawBuffer[last_x][last_y - 1] != EL_EMC_WALL_1 &&
- IntelliDrawBuffer[last_x][last_y - 1] != EL_EMC_WALL_2)
- last_element_new = EL_EMC_WALL_1;
- else if (IntelliDrawBuffer[last_x][last_y - 1] == EL_EMC_WALL_1 ||
- IntelliDrawBuffer[last_x][last_y - 1] == EL_EMC_WALL_2)
- last_element_new = EL_EMC_WALL_2;
- }
+ int dir = MV_DIR_FROM_BIT(i);
+ int dir_opposite = MV_DIR_OPPOSITE(dir);
+ int last_element_old = IntelliDrawBuffer[last_x][last_y];
+ int last_direction_old = getOpenDirectionFromChip(last_element_old);
+ int last_direction_new = last_direction_old | dir_opposite;
- new_element = EL_EMC_WALL_3;
+ if (last_direction_old == MV_NONE)
+ {
+ last_element_new = getChipFromOpenDirection(last_direction_new);
+ direction |= dir;
+ }
+ else if (last_direction_old & (dir | dir_opposite))
+ {
+ direction |= MV_DIR_OPPOSITE(last_direction_old);
+ }
+ else
+ {
+ direction |= MV_DIR_OPPOSITE(dir);
+ }
+ }
}
- else if (last_x == x && last_y == y + 1 && IN_LEV_FIELD(last_x, last_y) &&
- (IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_1 ||
- IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_2 ||
- IntelliDrawBuffer[last_x][last_y] == EL_EMC_WALL_3))
+
+ new_element = getChipFromOpenDirectionNotEmpty(direction, new_element);
+
+ if (last_element_new != EL_UNDEFINED)
+ MergeAndCloseNeighbourElements(x, y, &new_element,
+ last_x, last_y, &last_element_new,
+ getClosedChip, change_level);
+ }
+ else if (IS_SP_HARDWARE_BASE(new_element))
+ {
+ int nr = GetSimpleRandom(6);
+
+ new_element = (nr == 0 ? EL_SP_HARDWARE_BASE_1 :
+ nr == 1 ? EL_SP_HARDWARE_BASE_2 :
+ nr == 2 ? EL_SP_HARDWARE_BASE_3 :
+ nr == 3 ? EL_SP_HARDWARE_BASE_4 :
+ nr == 4 ? EL_SP_HARDWARE_BASE_5 : EL_SP_HARDWARE_BASE_6);
+ }
+ else if (new_element == EL_SP_HARDWARE_GREEN ||
+ new_element == EL_SP_HARDWARE_BLUE ||
+ new_element == EL_SP_HARDWARE_RED)
+ {
+ int nr = GetSimpleRandom(3);
+
+ new_element = (nr == 0 ? EL_SP_HARDWARE_GREEN :
+ nr == 1 ? EL_SP_HARDWARE_BLUE : EL_SP_HARDWARE_RED);
+ }
+ else if (IS_GROUP_ELEMENT(new_element))
+ {
+ boolean connected_drawing = FALSE;
+ int i;
+
+ for (i = 0; i < NUM_DIRECTIONS; i++)
{
- if (IN_LEV_FIELD(last_x, last_y + 1))
- {
- if (IntelliDrawBuffer[last_x][last_y + 1] != EL_EMC_WALL_2 &&
- IntelliDrawBuffer[last_x][last_y + 1] != EL_EMC_WALL_3)
- last_element_new = EL_EMC_WALL_3;
- else if (IntelliDrawBuffer[last_x][last_y + 1] == EL_EMC_WALL_2 ||
- IntelliDrawBuffer[last_x][last_y + 1] == EL_EMC_WALL_3)
- last_element_new = EL_EMC_WALL_2;
- }
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
- new_element = EL_EMC_WALL_1;
+ if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) &&
+ IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element))
+ connected_drawing = TRUE;
}
- if (last_element_new != EL_UNDEFINED)
- SetElementSimple(last_x, last_y, last_element_new, change_level);
+ if (!connected_drawing)
+ ResolveGroupElement(new_element);
+
+ new_element = GetElementFromGroupElement(new_element);
}
else if (IS_BELT_SWITCH(old_element))
{
{ -1, -1 },
};
- int i;
+ static int rotatable_elements[][4] =
+ {
+ {
+ EL_BUG_UP,
+ EL_BUG_RIGHT,
+ EL_BUG_DOWN,
+ EL_BUG_LEFT
+ },
+
+ {
+ EL_SPACESHIP_UP,
+ EL_SPACESHIP_RIGHT,
+ EL_SPACESHIP_DOWN,
+ EL_SPACESHIP_LEFT
+ },
+
+ {
+ EL_BD_BUTTERFLY_UP,
+ EL_BD_BUTTERFLY_RIGHT,
+ EL_BD_BUTTERFLY_DOWN,
+ EL_BD_BUTTERFLY_LEFT
+ },
+
+ {
+ EL_BD_FIREFLY_UP,
+ EL_BD_FIREFLY_RIGHT,
+ EL_BD_FIREFLY_DOWN,
+ EL_BD_FIREFLY_LEFT
+ },
+
+ {
+ EL_PACMAN_UP,
+ EL_PACMAN_RIGHT,
+ EL_PACMAN_DOWN,
+ EL_PACMAN_LEFT
+ },
+
+ {
+ EL_YAMYAM_UP,
+ EL_YAMYAM_RIGHT,
+ EL_YAMYAM_DOWN,
+ EL_YAMYAM_LEFT
+ },
+
+ {
+ EL_ARROW_UP,
+ EL_ARROW_RIGHT,
+ EL_ARROW_DOWN,
+ EL_ARROW_LEFT
+ },
+
+ {
+ EL_SP_PORT_UP,
+ EL_SP_PORT_RIGHT,
+ EL_SP_PORT_DOWN,
+ EL_SP_PORT_LEFT
+ },
+
+ {
+ EL_SP_GRAVITY_PORT_UP,
+ EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_LEFT
+ },
+
+ {
+ EL_SP_GRAVITY_ON_PORT_UP,
+ EL_SP_GRAVITY_ON_PORT_RIGHT,
+ EL_SP_GRAVITY_ON_PORT_DOWN,
+ EL_SP_GRAVITY_ON_PORT_LEFT
+ },
+
+ {
+ EL_SP_GRAVITY_OFF_PORT_UP,
+ EL_SP_GRAVITY_OFF_PORT_RIGHT,
+ EL_SP_GRAVITY_OFF_PORT_DOWN,
+ EL_SP_GRAVITY_OFF_PORT_LEFT
+ },
+
+ {
+ EL_MOLE_UP,
+ EL_MOLE_RIGHT,
+ EL_MOLE_DOWN,
+ EL_MOLE_LEFT
+ },
+
+ {
+ EL_BALLOON_SWITCH_UP,
+ EL_BALLOON_SWITCH_RIGHT,
+ EL_BALLOON_SWITCH_DOWN,
+ EL_BALLOON_SWITCH_LEFT
+ },
+
+ {
+ -1,
+ -1,
+ -1,
+ -1,
+ },
+ };
+ int i, j;
for (i = 0; swappable_elements[i][0] != -1; i++)
{
if (old_element == element1 || old_element == element2)
new_element = (old_element == element1 ? element2 : element1);
}
+
+ for (i = 0; rotatable_elements[i][0] != -1; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ int element = rotatable_elements[i][j];
+
+ if (old_element == element)
+ new_element = (button == 1 ? rotatable_elements[i][(j + 3) % 4] :
+ button == 2 ? rotatable_elements[i][0] :
+ button == 3 ? rotatable_elements[i][(j + 1) % 4] :
+ old_element);
+ }
+ }
}
SetElementSimple(x, y, new_element, change_level);
for (y = 0; y < lev_fieldy; y++)
IntelliDrawBuffer[x][y] = Feld[x][y];
- SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE);
+ SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1);
}
-static void SetElementExt(int x, int y, int element, boolean change_level)
+static void SetElementExt(int x, int y, int element, boolean change_level,
+ int button)
{
if (element < 0)
- {
- element = IntelliDrawBuffer[x][y] = Feld[x][y];
- SetElementSimple(x, y, element, change_level);
-
- return;
- }
-
- if (GetKeyModState() & KMOD_Shift)
- SetElementIntelliDraw(x, y, element, change_level);
+ SetElementSimple(x, y, Feld[x][y], change_level);
+ else if (GetKeyModState() & KMOD_Shift)
+ SetElementIntelliDraw(x, y, element, change_level, button);
else
SetElementSimple(x, y, element, change_level);
}
static void SetElement(int x, int y, int element)
{
- SetElementExt(x, y, element, TRUE);
+ SetElementExt(x, y, element, TRUE, -1);
}
-static void DrawLineElement(int sx, int sy, int element, boolean change_level)
+static void SetElementButton(int x, int y, int element, int button)
{
-#if 1
- int lx = sx + level_xpos;
- int ly = sy + level_ypos;
-
- SetElementExt(lx, ly, element, change_level);
-
-#else
+ SetElementExt(x, y, element, TRUE, button);
+}
+static void DrawLineElement(int sx, int sy, int element, boolean change_level)
+{
int lx = sx + level_xpos;
int ly = sy + level_ypos;
- int element_new = (element < 0 ? Feld[lx][ly] : element);
-
- DrawMiniElement(sx, sy, element_new);
- if (change_level)
- Feld[lx][ly] = element;
-#endif
+ SetElementExt(lx, ly, element, change_level, -1);
}
static void DrawLine(int from_x, int from_y, int to_x, int to_y,
int element, boolean change_level)
{
+ int xsize = ABS(to_x - from_x);
+ int ysize = ABS(to_y - from_y);
+ int dx = (to_x < from_x ? -1 : +1);
+ int dy = (to_y < from_y ? -1 : +1);
+ int i;
+
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, change_level);
+ for (i = 0; i <= xsize; i++)
+ DrawLineElement(from_x + i * dx, from_y, element, change_level);
}
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, change_level);
+ for (i = 0; i <= ysize; i++)
+ DrawLineElement(from_x, from_y + i * dy, element, change_level);
}
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) /* a < 1 */
+ if (ysize < xsize) /* a < 1 */
{
- float a = (float)len_y / (float)len_x;
+ float a = (float)ysize / (float)xsize;
- if (from_x > to_x)
- swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
-
- for (x = 0; x <= len_x; x++)
+ for (i = 0; i <= xsize; i++)
{
- y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1);
+ int x = dx * i;
+ int y = dy * (int)(a * i + 0.5);
+
DrawLineElement(from_x + x, from_y + y, element, change_level);
}
}
else /* a >= 1 */
{
- float a = (float)len_x / (float)len_y;
+ float a = (float)xsize / (float)ysize;
- if (from_y > to_y)
- swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
-
- for (y = 0; y <= len_y; y++)
+ for (i = 0; i <= ysize; i++)
{
- x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1);
+ int x = dx * (int)(a * i + 0.5);
+ int y = dy * i;
+
DrawLineElement(from_x + x, from_y + y, element, change_level);
}
}
if (from_y > to_y)
swap_numbers(&from_y, &to_y);
- from_sx = SX + from_x * MINI_TILEX;
- from_sy = SY + from_y * MINI_TILEY;
- to_sx = SX + to_x * MINI_TILEX + MINI_TILEX - 1;
- to_sy = SY + to_y * MINI_TILEY + MINI_TILEY - 1;
+ from_sx = SX + from_x * ed_tilesize;
+ from_sy = SY + from_y * ed_tilesize;
+ to_sx = SX + (to_x + 1) * ed_tilesize - 1;
+ to_sy = SY + (to_y + 1) * ed_tilesize - 1;
DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy);
DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy);
static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
int button, int mode)
{
- static short brush_buffer[MAX_ED_FIELDX][MAX_ED_FIELDY];
+ static short brush_buffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static int brush_width, brush_height;
static int last_cursor_x = -1, last_cursor_y = -1;
static boolean delete_old_brush;
else if (element >= NUM_FILE_ELEMENTS)
element_mapped = EL_UNKNOWN;
- printf("%c%03d", (mode == CB_DUMP_BRUSH ? '`' : '¸'), element_mapped);
+ // dump brush as level sketch text for the R'n'D forum:
+ // - large tiles: `xxx (0x60 ASCII)
+ // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8)
+ printf("%s%03d", (mode == CB_DUMP_BRUSH ? "`" : "¸"), element_mapped);
}
printf("\n");
static int DrawLevelText(int sx, int sy, char letter, int mode)
{
static short delete_buffer[MAX_LEV_FIELDX];
- static int start_sx, start_sy;
+ static int start_sx;
static int last_sx, last_sy;
static boolean typing = FALSE;
int letter_element = EL_CHAR_ASCII0 + letter;
/* map lower case letters to upper case and convert special characters */
if (letter >= 'a' && letter <= 'z')
letter_element = EL_CHAR_ASCII0 + letter + (int)('A' - 'a');
- else if (letter == 'ä' || letter == 'Ä')
+ else if (letter == CHAR_BYTE_UMLAUT_a || letter == CHAR_BYTE_UMLAUT_A)
letter_element = EL_CHAR_AUMLAUT;
- else if (letter == 'ö' || letter == 'Ö')
+ else if (letter == CHAR_BYTE_UMLAUT_o || letter == CHAR_BYTE_UMLAUT_O)
letter_element = EL_CHAR_OUMLAUT;
- else if (letter == 'ü' || letter == 'Ü')
+ else if (letter == CHAR_BYTE_UMLAUT_u || letter == CHAR_BYTE_UMLAUT_U)
letter_element = EL_CHAR_UUMLAUT;
else if (letter == '^')
letter_element = EL_CHAR_COPYRIGHT;
DrawLevelText(0, 0, 0, TEXT_END);
typing = TRUE;
- start_sx = last_sx = sx;
- start_sy = last_sy = sy;
+ start_sx = sx;
+ last_sx = sx;
+ last_sy = sy;
DrawLevelText(sx, sy, 0, TEXT_SETCURSOR);
break;
case TEXT_SETCURSOR:
- DrawMiniElement(last_sx, last_sy, Feld[lx][ly]);
+ DrawEditorElement(last_sx, last_sy, Feld[lx][ly]);
DrawAreaBorder(sx, sy, sx, sy);
last_sx = sx;
last_sy = sy;
case TEXT_WRITECHAR:
if (letter_element >= EL_CHAR_START && letter_element <= EL_CHAR_END)
{
+ if (new_element1 >= EL_STEEL_CHAR_START &&
+ new_element1 <= EL_STEEL_CHAR_END)
+ letter_element = letter_element - EL_CHAR_START + EL_STEEL_CHAR_START;
+
delete_buffer[sx - start_sx] = Feld[lx][ly];
Feld[lx][ly] = letter_element;
if (sx > start_sx)
{
Feld[lx - 1][ly] = delete_buffer[sx - start_sx - 1];
- DrawMiniElement(sx - 1, sy, Feld[lx - 1][ly]);
+ DrawEditorElement(sx - 1, sy, Feld[lx - 1][ly]);
DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR);
}
break;
case TEXT_END:
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
- DrawMiniElement(sx, sy, Feld[lx][ly]);
+ DrawEditorElement(sx, sy, Feld[lx][ly]);
typing = FALSE;
break;
int ly = sy + level_ypos;
if (element == -1)
- DrawMiniElement(sx, sy, Feld[lx][ly]);
+ DrawEditorElement(sx, sy, Feld[lx][ly]);
else
DrawAreaBorder(sx, sy, sx, sy);
}
SetBorderElement();
if (redraw_playfield && BorderElement != last_border_element)
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
}
static void CopyLevelToUndoBuffer(int mode)
boolean new_undo_buffer_position = TRUE;
int x, y;
+ if (undo_buffer_steps == 0)
+ accumulated_undo = FALSE;
+
switch (mode)
{
case UNDO_IMMEDIATE:
if (new_undo_buffer_position)
{
- /* new position in undo buffer ring */
+ /* advance position in undo buffer ring */
undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS;
if (undo_buffer_steps < NUM_UNDO_STEPS - 1)
undo_buffer_steps++;
}
+ /* always reset redo buffer when storing level change into undo buffer */
+ redo_buffer_steps = 0;
+
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
UndoBuffer[undo_buffer_position][x][y] = Feld[x][y];
int num_percentage, num_elements;
int x, y;
+ ResetIntelliDraw();
+
/* determine number of free positions for randomly placing the new element */
for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++)
{
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
if (free_position[x][y])
- Feld[x][y] = new_element;
+ SetElement(x, y, new_element);
}
else
{
while (num_elements > 0)
{
- x = RND(lev_fieldx);
- y = RND(lev_fieldy);
+ x = GetSimpleRandom(lev_fieldx);
+ y = GetSimpleRandom(lev_fieldy);
/* don't place element at the same position twice */
if (free_position[x][y])
{
free_position[x][y] = FALSE;
- Feld[x][y] = new_element;
+ SetElement(x, y, new_element);
num_elements--;
}
}
}
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
}
Feld[x][y] =
FieldBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy];
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
CopyLevelToUndoBuffer(UNDO_ACCUMULATE);
}
{
static boolean started_inside_drawing_area = FALSE;
int id = gi->custom_id;
+ int type_id = gi->custom_type_id;
boolean button_press_event;
boolean button_release_event;
boolean inside_drawing_area = !gi->event.off_borders;
if (edit_mode == ED_MODE_DRAWING && draw_with_brush &&
!inside_drawing_area)
DeleteBrushFromCursor();
-
-#if 0
- ResetIntelliDraw();
-#endif
}
if (!button || button_release_event)
if (draw_with_brush)
{
-#if 0
- if (!button_release_event)
-#endif
- CopyBrushToLevel(sx, sy, button);
+ CopyBrushToLevel(sx, sy, button);
}
-#if 1
else
-#else
- else if (new_element != Feld[lx][ly])
-#endif
{
if (new_element == EL_PLAYER_1)
{
/* remove player at old position */
for (y = 0; y < lev_fieldy; y++)
- {
for (x = 0; x < lev_fieldx; x++)
- {
if (Feld[x][y] == EL_PLAYER_1)
- {
-#if 1
SetElement(x, y, EL_EMPTY);
-#else
- Feld[x][y] = EL_EMPTY;
-#if 1
- if (IN_ED_FIELD(x - level_xpos, y - level_ypos))
- DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY);
-#else
- if (x - level_xpos >= 0 && x - level_xpos < ed_fieldx &&
- y - level_ypos >= 0 && y - level_ypos < ed_fieldy)
- DrawMiniElement(x - level_xpos, y - level_ypos, EL_EMPTY);
-#endif
-#endif
- }
- }
- }
}
-#if 1
- SetElement(lx, ly, new_element);
-#else
- Feld[lx][ly] = new_element;
- DrawMiniElement(sx, sy, new_element);
-#endif
+ SetElementButton(lx, ly, new_element, button);
}
}
- else
+ else if (!button_release_event)
{
- int type_id = gi->custom_type_id;
int pos = sx * drawingarea_info[type_id].area_ysize + sy;
if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY)
gi->y + sy * MINI_TILEY,
el2edimg(new_element));
else
- DrawGraphicExt(drawto,
- gi->x + sx * TILEX,
- gi->y + sy * TILEY,
- el2img(new_element), 0);
+ DrawFixedGraphicExt(drawto,
+ gi->x + sx * TILEX,
+ gi->y + sy * TILEY,
+ el2edimg(new_element), 0);
if (id == GADGET_ID_CUSTOM_GRAPHIC)
new_element = GFX_ELEMENT(new_element);
if (button_press_event && Feld[lx][ly] != new_element)
{
FloodFill(lx, ly, new_element);
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
}
break;
PickDrawingElement(button, Feld[lx][ly]);
else
{
- int type_id = gi->custom_type_id;
int pos = sx * drawingarea_info[type_id].area_ysize + sy;
PickDrawingElement(button, drawingarea_info[type_id].value[pos]);
}
- break;
-
default:
break;
}
+
+ /* do not mark level as modified for certain non-level-changing gadgets */
+ if ((type_id >= ED_DRAWING_ID_EDITOR_FIRST &&
+ type_id <= ED_DRAWING_ID_EDITOR_LAST) ||
+ actual_drawing_function == GADGET_ID_PICK_ELEMENT)
+ return;
+
+ level.changed = TRUE;
}
static void HandleCounterButtons(struct GadgetInfo *gi)
if ((level_changed && pressed) || (!level_changed && released))
return;
- if (level_changed && !Request("Level has changed ! Discard changes ?",
+ if (level_changed && !Request("Level has changed! Discard changes?",
REQ_ASK))
{
if (gadget_id == counterbutton_info[counter_id].gadget_id_text)
if (counter_id == ED_COUNTER_ID_SELECT_LEVEL)
{
LoadLevel(level_nr);
+ LoadScore(level_nr);
+
+ SaveLevelSetup_SeriesInfo();
+
TapeErase();
+
ResetUndoBuffer();
DrawEditModeWindow();
CopyGroupElementPropertiesToGame(properties_element);
break;
+ case ED_COUNTER_ID_INVENTORY_SIZE:
+ DrawPlayerInitialInventoryArea(properties_element);
+ break;
+
case ED_COUNTER_ID_ENVELOPE_XSIZE:
case ED_COUNTER_ID_ENVELOPE_YSIZE:
DrawEnvelopeTextArea(-1);
case ED_COUNTER_ID_LEVEL_YSIZE:
lev_fieldx = level.fieldx;
lev_fieldy = level.fieldy;
+
+ /* check if resizing of level results in change of border border */
+ SetBorderElement();
+
break;
default:
counter_id <= ED_COUNTER_ID_CHANGE_LAST))
CopyElementPropertiesToGame(properties_element);
+ /* do not mark level as modified for certain non-level-changing gadgets */
+ if (counter_id >= ED_COUNTER_ID_EDITOR_FIRST &&
+ counter_id <= ED_COUNTER_ID_EDITOR_LAST)
+ return;
+
level.changed = TRUE;
}
{
int type_id = gi->custom_type_id;
-#if 1
strncpy(textarea_info[type_id].value, gi->textarea.value,
MAX_ENVELOPE_TEXT_LEN);
textarea_info[type_id].value[MAX_ENVELOPE_TEXT_LEN] = '\0';
-#else
- /* !!! BUGGY !!! MAX_ENVELOPE_TEXT_LEN != MAX_GADGET_TEXTSIZE !!! */
- strcpy(textarea_info[type_id].value, gi->textarea.value);
-#endif
level.changed = TRUE;
}
level.changed = TRUE;
}
+ else if (type_id == ED_SELECTBOX_ID_GAME_ENGINE_TYPE)
+ {
+ /* update element selection list */
+ ReinitializeElementList();
+ ModifyEditorElementList();
+ }
}
static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
int type_id = gi->custom_type_id;
int i;
- if (type_id >= ED_TEXTBUTTON_ID_PROPERTIES_FIRST &&
- type_id <= ED_TEXTBUTTON_ID_PROPERTIES_LAST)
+ if (type_id >= ED_TAB_BUTTON_ID_LEVELINFO_FIRST &&
+ type_id <= ED_TAB_BUTTON_ID_LEVELINFO_LAST)
+ {
+ edit_mode_levelinfo = gi->custom_type_id;
+
+ DrawLevelInfoWindow();
+ }
+ else if (type_id >= ED_TAB_BUTTON_ID_PROPERTIES_FIRST &&
+ type_id <= ED_TAB_BUTTON_ID_PROPERTIES_LAST)
{
edit_mode_properties = gi->custom_type_id;
DrawPropertiesWindow();
}
- else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE)
+ else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1 ||
+ type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2)
{
- char *template_filename = getDefaultLevelFilename(-1);
- boolean new_template = !fileExists(template_filename);
+ boolean new_template = !fileExists(getLocalLevelTemplateFilename());
+
+ /* backup original "level.field" (needed to track playfield changes) */
+ CopyPlayfield(level.field, FieldBackup);
+
+ /* "SaveLevelTemplate()" uses "level.field", so copy editor playfield */
+ CopyPlayfield(Feld, level.field);
if (new_template ||
- Request("Save this template and kill the old ?", REQ_ASK))
+ Request("Save this template and kill the old?", REQ_ASK))
SaveLevelTemplate();
if (new_template)
- Request("Template saved !", REQ_CONFIRM);
+ Request("Template saved!", REQ_CONFIRM);
+
+ /* restore original "level.field" (needed to track playfield changes) */
+ CopyPlayfield(FieldBackup, level.field);
}
else if (type_id == ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE &&
custom_element.num_change_pages < MAX_CHANGE_PAGES)
{
struct ElementInfo *ei = &element_info[properties_element];
+ /* when modifying custom element, ask for copying level template */
+ if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate())
+ return;
+
setElementChangePages(ei, ei->num_change_pages + 1);
/* set new change page to be new current change page */
{
struct ElementInfo *ei = &element_info[properties_element];
+ /* when modifying custom element, ask for copying level template */
+ if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate())
+ return;
+
/* copy all change pages after change page to be deleted */
for (i = ei->current_change_page; i < ei->num_change_pages - 1; i++)
ei->change_page[i] = ei->change_page[i + 1];
int current_change_page = ei->current_change_page;
if (type_id == ED_GRAPHICBUTTON_ID_COPY_CHANGE_PAGE)
+ {
element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0] =
ei->change_page[current_change_page];
+ }
else if (type_id == ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE)
{
+ /* when modifying custom element, ask for copying level template */
+ if (level.use_custom_template && !AskToCopyAndModifyLevelTemplate())
+ return;
+
ei->change_page[current_change_page] =
element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0];
static void HandleRadiobuttons(struct GadgetInfo *gi)
{
- *radiobutton_info[gi->custom_type_id].value =
- radiobutton_info[gi->custom_type_id].checked_value;
+ int type_id = gi->custom_type_id;
+
+ *radiobutton_info[type_id].value =
+ radiobutton_info[type_id].checked_value;
+
+ /* do not mark level as modified for certain non-level-changing gadgets */
+ if (type_id >= ED_RADIOBUTTON_ID_EDITOR_FIRST &&
+ type_id <= ED_RADIOBUTTON_ID_EDITOR_LAST)
+ return;
level.changed = TRUE;
}
type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) ||
(type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST &&
type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST)) &&
- type_id != ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE))
+ type_id != ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1))
{
CopyElementPropertiesToGame(properties_element);
}
{
UpdateCustomElementGraphicGadgets();
}
- else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE)
+ else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1 ||
+ type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2)
{
- char *template_filename = getDefaultLevelFilename(-1);
+ boolean template_related_changes_found = FALSE;
+ int i;
+
+ /* check if any custom or group elements have been changed */
+ for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+ if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) &&
+ element_info[i].modified_settings)
+ template_related_changes_found = TRUE;
- if (level.use_custom_template && !fileExists(template_filename))
+ if (level.use_custom_template &&
+ !fileExists(getGlobalLevelTemplateFilename()))
{
- Request("No level template found !", REQ_CONFIRM);
+ Request("No level template found!", REQ_CONFIRM);
+
+ level.use_custom_template = FALSE;
+ ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END);
+
+ return;
+ }
+
+ if (level.use_custom_template &&
+ template_related_changes_found &&
+ !Request("Discard changes and use level template?", REQ_ASK))
+ {
level.use_custom_template = FALSE;
+
ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END);
return;
}
+ if (!level.use_custom_template &&
+ Request("Copy settings from level template?", REQ_ASK))
+ {
+ return;
+ }
+
LoadLevelTemplate(level.use_custom_template ? -1 : level_nr);
DrawEditModeWindow();
}
+ else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3)
+ {
+ if (setup.editor.use_template_for_new_levels &&
+ !fileExists(getGlobalLevelTemplateFilename()))
+ {
+ Request("No level template found!", REQ_CONFIRM);
+
+ return;
+ }
+
+ if (setup.editor.use_template_for_new_levels &&
+ level.changed &&
+ !Request("Discard level and load template?", REQ_ASK))
+ {
+ return;
+ }
+
+ if (!setup.editor.use_template_for_new_levels &&
+ level.changed &&
+ !Request("Discard level and use empty level?", REQ_ASK))
+ {
+ return;
+ }
+
+ LoadLevel(level_nr);
+ LoadScore(level_nr);
+
+ TapeErase();
+
+ ResetUndoBuffer();
+ DrawEditModeWindow();
+ }
+
+ /* do not mark level as modified for certain non-level-changing gadgets */
+ if ((type_id >= ED_CHECKBUTTON_ID_EDITOR_FIRST &&
+ type_id <= ED_CHECKBUTTON_ID_EDITOR_LAST) ||
+ type_id == ED_CHECKBUTTON_ID_STICK_ELEMENT)
+ return;
level.changed = TRUE;
}
static int last_level_drawing_function = GADGET_ID_SINGLE_ITEMS;
static int last_edit_mode = ED_MODE_DRAWING;
static int last_custom_copy_mode = -1;
+ static int last_button = 0;
int id = gi->custom_id;
int button = gi->event.button;
int step = BUTTON_STEPSIZE(button);
int new_element = BUTTON_ELEMENT(button);
+ int last_properties_element = properties_element;
int x, y;
if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT)
if (id < ED_NUM_CTRL1_BUTTONS &&
id != GADGET_ID_SINGLE_ITEMS &&
- id != GADGET_ID_PROPERTIES &&
id != GADGET_ID_PICK_ELEMENT &&
edit_mode != ED_MODE_DRAWING &&
drawing_function != GADGET_ID_PICK_ELEMENT &&
!(GetKeyModState() & KMOD_Control))
- {
- DrawDrawingWindow();
- edit_mode = ED_MODE_DRAWING;
- }
+ ChangeEditModeWindow(ED_MODE_DRAWING);
/* element copy mode active, but no element button pressed => deactivate */
if (last_custom_copy_mode != -1 && id < ED_NUM_CTRL_BUTTONS)
last_custom_copy_mode = -1;
+ /* when showing palette on element buttons, change element of button used */
+ if (editor.palette.show_on_element_buttons &&
+ id >= GADGET_ID_ELEMENT_LEFT && id <= GADGET_ID_ELEMENT_RIGHT)
+ {
+ last_button = id - GADGET_ID_ELEMENT_LEFT + 1;
+
+ id = GADGET_ID_PALETTE;
+ }
+
switch (id)
{
case GADGET_ID_SCROLL_LEFT:
if (level_xpos < -1)
level_xpos = -1;
if (button == 1)
- ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
+ ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_RIGHT);
else
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL],
GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END);
if (level_xpos > lev_fieldx - ed_fieldx + 1)
level_xpos = lev_fieldx - ed_fieldx + 1;
if (button == 1)
- ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
+ ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_LEFT);
else
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_HORIZONTAL],
GDI_SCROLLBAR_ITEM_POSITION, level_xpos + 1, GDI_END);
if (level_ypos < -1)
level_ypos = -1;
if (button == 1)
- ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
+ ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_DOWN);
else
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL],
GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END);
if (level_ypos > lev_fieldy - ed_fieldy + 1)
level_ypos = lev_fieldy - ed_fieldy + 1;
if (button == 1)
- ScrollMiniLevel(level_xpos, level_ypos, ED_SCROLL_UP);
+ ScrollEditorLevel(level_xpos, level_ypos, ED_SCROLL_UP);
else
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_VERTICAL],
GDI_SCROLLBAR_ITEM_POSITION, level_ypos + 1, GDI_END);
case GADGET_ID_SCROLL_HORIZONTAL:
level_xpos = gi->event.item_position - 1;
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ BackToFront();
+
break;
case GADGET_ID_SCROLL_VERTICAL:
level_ypos = gi->event.item_position - 1;
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ BackToFront();
+
break;
case GADGET_ID_SCROLL_LIST_UP:
break;
+ case GADGET_ID_PROPERTIES:
+ // always switch off element properties when they are already displayed
+ last_properties_element = new_element;
+ case GADGET_ID_ELEMENT_LEFT:
+ case GADGET_ID_ELEMENT_MIDDLE:
+ case GADGET_ID_ELEMENT_RIGHT:
+ properties_element = (id == GADGET_ID_ELEMENT_LEFT ? new_element1 :
+ id == GADGET_ID_ELEMENT_MIDDLE ? new_element2 :
+ id == GADGET_ID_ELEMENT_RIGHT ? new_element3 :
+ new_element);
+
+ if (edit_mode != ED_MODE_PROPERTIES)
+ {
+ last_edit_mode = edit_mode;
+
+ ChangeEditModeWindow(ED_MODE_PROPERTIES);
+
+ last_level_drawing_function = drawing_function;
+ ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],
+ MB_LEFTBUTTON);
+ }
+ else if (properties_element != last_properties_element)
+ {
+ DrawEditModeWindow();
+ }
+ else
+ {
+ ChangeEditModeWindow(last_edit_mode);
+
+ ClickOnGadget(level_editor_gadget[last_level_drawing_function],
+ MB_LEFTBUTTON);
+ }
+ break;
+
+ case GADGET_ID_PALETTE:
+ if (edit_mode != ED_MODE_PALETTE)
+ {
+ last_edit_mode = edit_mode;
+
+ ChangeEditModeWindow(ED_MODE_PALETTE);
+ }
+ else
+ {
+ ChangeEditModeWindow(last_edit_mode);
+ }
+ break;
+
case GADGET_ID_WRAP_LEFT:
WrapLevel(-step, 0);
break;
RandomPlacement(new_element);
break;
- case GADGET_ID_PROPERTIES:
- if (edit_mode != ED_MODE_PROPERTIES)
- {
- properties_element = new_element;
- DrawPropertiesWindow();
- edit_mode = ED_MODE_PROPERTIES;
+ case GADGET_ID_ZOOM:
+ // zoom level editor tile size in or out (or reset to default size)
+ ed_tilesize = (button == 1 ? ed_tilesize * 2 :
+ button == 2 ? DEFAULT_EDITOR_TILESIZE :
+ button == 3 ? ed_tilesize / 2 : ed_tilesize);
- last_level_drawing_function = drawing_function;
- ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],
- MB_LEFTBUTTON);
- }
- else
- {
+ // limit zoom level by upper and lower bound
+ ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE);
+
+ InitZoomLevelSettings();
+
+ if (edit_mode == ED_MODE_DRAWING)
DrawDrawingWindow();
- edit_mode = ED_MODE_DRAWING;
- ClickOnGadget(level_editor_gadget[last_level_drawing_function],
- MB_LEFTBUTTON);
- }
break;
case GADGET_ID_CUSTOM_COPY_FROM:
break;
case GADGET_ID_UNDO:
- if (undo_buffer_steps == 0)
+ if (button == 1 && undo_buffer_steps == 0)
+ {
+ Request("Undo buffer empty!", REQ_CONFIRM);
+
+ break;
+ }
+ else if (button == 2)
+ {
+ break;
+ }
+ else if (button == 3 && redo_buffer_steps == 0)
{
- Request("Undo buffer empty !", REQ_CONFIRM);
+ Request("Redo buffer empty!", REQ_CONFIRM);
+
break;
}
if (edit_mode != ED_MODE_DRAWING)
+ ChangeEditModeWindow(ED_MODE_DRAWING);
+
+ if (button == 1)
{
- DrawDrawingWindow();
- edit_mode = ED_MODE_DRAWING;
+ /* undo */
+
+ undo_buffer_position =
+ (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS;
+
+ undo_buffer_steps--;
+ redo_buffer_steps++;
}
+ else
+ {
+ /* redo */
+
+ undo_buffer_position = (undo_buffer_position + 1) % NUM_UNDO_STEPS;
- undo_buffer_position =
- (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS;
- undo_buffer_steps--;
+ undo_buffer_steps++;
+ redo_buffer_steps--;
+ }
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
/* check if undo operation forces change of border style */
CheckLevelBorderElement(FALSE);
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
break;
if (edit_mode != ED_MODE_INFO)
{
last_edit_mode = edit_mode;
- edit_mode = ED_MODE_INFO;
- DrawLevelInfoWindow();
+ ChangeEditModeWindow(ED_MODE_INFO);
}
else
{
- edit_mode = last_edit_mode;
-
- DrawEditModeWindow();
+ ChangeEditModeWindow(last_edit_mode);
}
break;
case GADGET_ID_CLEAR:
if (edit_mode != ED_MODE_DRAWING)
- {
- DrawDrawingWindow();
- edit_mode = ED_MODE_DRAWING;
- }
+ ChangeEditModeWindow(ED_MODE_DRAWING);
for (x = 0; x < MAX_LEV_FIELDX; x++)
for (y = 0; y < MAX_LEV_FIELDY; y++)
CopyLevelToUndoBuffer(GADGET_ID_CLEAR);
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+ DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
break;
case GADGET_ID_SAVE:
- if (leveldir_current->readonly)
- {
- Request("This level is read only !", REQ_CONFIRM);
+ {
+ /* saving read-only levels into personal level set modifies global vars
+ "leveldir_current" and "level_nr"; restore them after saving level */
+ LevelDirTree *leveldir_former = leveldir_current;
+ int level_nr_former = level_nr;
+ char *level_filename;
+ boolean new_level;
+
+ if (leveldir_current->readonly &&
+ !PrepareSavingIntoPersonalLevelSet())
break;
- }
- if (!LevelContainsPlayer())
- Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
- else
+ level_filename = getDefaultLevelFilename(level_nr);
+ new_level = !fileExists(level_filename);
+
+ if (new_level ||
+ Request("Save this level and kill the old?", REQ_ASK))
{
- char *level_filename = getDefaultLevelFilename(level_nr);
- boolean new_level = !fileExists(level_filename);
+ if (leveldir_former->readonly)
+ ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name);
- if (new_level ||
- Request("Save this level and kill the old ?", REQ_ASK))
- {
- CopyPlayfield(Feld, level.field);
+ CopyPlayfield(Feld, level.field);
+ SaveLevel(level_nr);
- SaveLevel(level_nr);
- }
+ level.changed = FALSE;
if (new_level)
- Request("Level saved !", REQ_CONFIRM);
+ {
+ char level_saved_msg[64];
- level.changed = FALSE;
+ if (leveldir_former->readonly)
+ sprintf(level_saved_msg,
+ "Level saved as level %d into personal level set!",
+ level_nr);
+ else
+ strcpy(level_saved_msg, "Level saved!");
+
+ Request(level_saved_msg, REQ_CONFIRM);
+ }
}
+
+ /* "cd" back to copied-from levelset (in case of saved read-only level) */
+ leveldir_current = leveldir_former;
+ level_nr = level_nr_former;
+
break;
+ }
case GADGET_ID_TEST:
- if (!LevelContainsPlayer())
- Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
- else
- {
- if (LevelChanged())
- level.game_version = GAME_VERSION_ACTUAL;
+ if (LevelChanged())
+ level.game_version = GAME_VERSION_ACTUAL;
- CopyPlayfield(level.field, FieldBackup);
- CopyPlayfield(Feld, level.field);
+ CopyPlayfield(level.field, FieldBackup);
+ CopyPlayfield(Feld, level.field);
- CopyNativeLevel_RND_to_Native(&level);
+ CopyNativeLevel_RND_to_Native(&level);
- UnmapLevelEditorGadgets();
- UndrawSpecialEditorDoor();
+ UnmapLevelEditorGadgets();
+ UndrawSpecialEditorDoor();
- CloseDoor(DOOR_CLOSE_ALL);
+ CloseDoor(DOOR_CLOSE_ALL);
- DrawCompleteVideoDisplay();
+ /* needed before playing if editor playfield area has different size */
+ ClearRectangle(drawto, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- level_editor_test_game = TRUE;
+ // redraw_mask = REDRAW_ALL;
+
+ level_editor_test_game = TRUE;
+
+ StartGameActions(FALSE, setup.autorecord, level.random_seed);
- StartGameActions(FALSE, setup.autorecord, NEW_RANDOMIZE);
- }
break;
case GADGET_ID_EXIT:
- RequestExitLevelEditor(TRUE); /* if level has changed, ask user */
+ RequestExitLevelEditor(TRUE, FALSE); /* if level has changed, ask user */
break;
default:
break;
}
+ /* change element of button used to show palette */
+ if (editor.palette.show_on_element_buttons)
+ button = last_button;
+
PickDrawingElement(button, new_element);
if (!stick_element_properties_window &&
if (drawing_function == GADGET_ID_PICK_ELEMENT)
ClickOnGadget(level_editor_gadget[last_drawing_function],
MB_LEFTBUTTON);
+
+ if (!use_permanent_palette)
+ ChangeEditModeWindow(last_edit_mode);
}
#ifdef DEBUG
else if (gi->event.type == GD_EVENT_PRESSED)
{
int id = GADGET_ID_NONE;
int new_element_shift = element_shift;
+ int step = ED_ELEMENTLIST_BUTTONS_VERT - 1;
int i;
switch (key)
case KSYM_Down:
id = GADGET_ID_SCROLL_DOWN;
break;
+
case KSYM_Page_Up:
- id = GADGET_ID_SCROLL_LIST_UP;
- button = MB_RIGHTBUTTON;
- break;
case KSYM_Page_Down:
- id = GADGET_ID_SCROLL_LIST_DOWN;
- button = MB_RIGHTBUTTON;
+ step *= (key == KSYM_Page_Up ? -1 : +1);
+ element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ;
+
+ if (element_shift < 0)
+ element_shift = 0;
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+
+ ModifyEditorElementList();
+
break;
case KSYM_Home:
case KSYM_Escape:
if (edit_mode == ED_MODE_DRAWING)
{
- RequestExitLevelEditor(setup.ask_on_escape_editor);
+ RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
}
else if (edit_mode == ED_MODE_INFO)
{
{
HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]);
}
+ else if (edit_mode == ED_MODE_PALETTE)
+ {
+ HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]);
+ }
else /* should never happen */
{
- DrawDrawingWindow();
- edit_mode = ED_MODE_DRAWING;
+ ChangeEditModeWindow(ED_MODE_DRAWING);
}
break;
if (id != GADGET_ID_NONE)
ClickOnGadget(level_editor_gadget[id], button);
+ else if (letter == '1' || letter == '?')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button);
+ else if (letter == '2')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button);
+ else if (letter == '3')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button);
else if (letter == '.')
ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
- else if (key == KSYM_Return || key == setup.shortcut.toggle_pause)
+ else if (letter == 'U')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3);
+ else if (letter == '-' || key == KSYM_KP_Subtract)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3);
+ else if (letter == '0' || key == KSYM_KP_0)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2);
+ else if (letter == '+' || key == KSYM_KP_Add ||
+ letter == '=') // ("Shift-=" is "+" on US keyboards)
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1);
+ else if (key == KSYM_Return ||
+ key == KSYM_space ||
+ key == setup.shortcut.toggle_pause)
ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
else
for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
- if (letter && letter == control_info[i].shortcut)
+ if (letter && letter == controlbutton_info[i].shortcut)
if (!anyTextGadgetActive())
ClickOnGadget(level_editor_gadget[i], button);
}
void HandleLevelEditorIdle()
{
- static unsigned long action_delay = 0;
- unsigned long action_delay_value = GameFrameDelay;
- int xpos = 1, ypos = 2;
+ int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size;
+ int x = editor.settings.element_graphic.x + element_border;
+ int y = editor.settings.element_graphic.y + element_border;
+ static unsigned int action_delay = 0;
+ unsigned int action_delay_value = GameFrameDelay;
+ int i;
if (edit_mode != ED_MODE_PROPERTIES)
return;
if (!DelayReached(&action_delay, action_delay_value))
return;
- DrawEditorElementAnimation(SX + xpos * TILEX,
- SY + ypos * TILEY + MINI_TILEY / 2);
+ for (i = 0; i < ED_NUM_SELECTBOX; i++)
+ {
+ struct GadgetInfo *gi = level_editor_gadget[selectbox_info[i].gadget_id];
+
+ if (gi->mapped && gi->active && gi->selectbox.open)
+ return;
+ }
- MarkTileDirty(xpos, ypos);
- MarkTileDirty(xpos, ypos + 1);
+ DrawEditorElementAnimation(SX + x, SY + y);
+
+ redraw_mask |= REDRAW_FIELD;
FrameCounter++; /* increase animation frame counter */
}
char shortcut[MAX_OUTPUT_LINESIZE + 1];
int max_infotext_len = getMaxInfoTextLength();
- if (gi == NULL || gi->info_text == NULL)
+ if (gi == NULL || strlen(gi->info_text) == 0)
return;
strncpy(infotext, gi->info_text, max_infotext_len);
if (gi->custom_id < ED_NUM_CTRL_BUTTONS)
{
- int key = control_info[gi->custom_id].shortcut;
+ int key = controlbutton_info[gi->custom_id].shortcut;
if (key)
{
- if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */
+ if (gi->custom_id == GADGET_ID_SINGLE_ITEMS)
sprintf(shortcut, " ('.' or '%c')", key);
- else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) /* special case 2 */
+ else if (gi->custom_id == GADGET_ID_PICK_ELEMENT)
sprintf(shortcut, " ('%c' or 'Ctrl')", key);
- else if (gi->custom_id == GADGET_ID_TEST) /* special case 3 */
+ else if (gi->custom_id == GADGET_ID_TEST)
sprintf(shortcut, " ('Enter' or 'Shift-%c')", key);
- else /* normal case */
+ else if (gi->custom_id == GADGET_ID_UNDO)
+ sprintf(shortcut, " ('%c/Shift-U')", key);
+ else if (gi->custom_id == GADGET_ID_ZOOM)
+ sprintf(shortcut, " ('%c', '0', '+')", key);
+ else
sprintf(shortcut, " ('%s%c')",
(key >= 'A' && key <= 'Z' ? "Shift-" : ""), key);
}
}
- DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2);
+ DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, INFOTEXT_FONT);
}
void HandleEditorGadgetInfoText(void *ptr)
infotext[max_infotext_len] = '\0';
if (strlen(infotext) > 0)
- DrawTextS(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, infotext);
+ DrawTextS(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, INFOTEXT_FONT, infotext);
}
-void RequestExitLevelEditor(boolean ask_if_level_has_changed)
+void RequestExitLevelEditor(boolean ask_if_level_has_changed,
+ boolean quick_quit)
{
if (!ask_if_level_has_changed ||
!LevelChanged() ||
- Request("Level has changed ! Exit without saving ?",
+ Request("Level has changed! Exit without saving?",
REQ_ASK | REQ_STAY_OPEN))
{
- CloseDoor(DOOR_CLOSE_1);
- SetDoorState(DOOR_CLOSE_2);
- game_status = GAME_MODE_MAIN;
+ struct RectWithBorder *vp_door_1 = &viewport.door_1[GAME_MODE_MAIN];
+ struct RectWithBorder *vp_door_2 = &viewport.door_2[GAME_MODE_MAIN];
+
+ /* draw normal door */
+ UndrawSpecialEditorDoor();
+
+ // close editor doors if viewport definition is the same as in main menu
+ if (vp_door_1->x == DX &&
+ vp_door_1->y == DY &&
+ vp_door_1->width == DXSIZE &&
+ vp_door_1->height == DYSIZE &&
+ vp_door_2->x == VX &&
+ vp_door_2->y == VY &&
+ vp_door_2->width == VXSIZE &&
+ vp_door_2->height == VYSIZE)
+ CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
+ else
+ SetDoorState(DOOR_CLOSE_2);
+
+ BackToFront();
+
+ if (quick_quit)
+ FadeSkipNextFadeIn();
+
+ SetGameStatus(GAME_MODE_MAIN);
+
DrawMainMenu();
}
else
{
- CloseDoor(DOOR_CLOSE_1);
- OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
+ if (!global.use_envelope_request)
+ {
+ CloseDoor(DOOR_CLOSE_1);
+ OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
+ }
}
}