X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Feditor.c;h=4a9491d0fbc2c0481cdae62704cba03a865b09cf;hp=7f1ec19f128fd20935d2fce1332786339313a9c9;hb=7438ace9ddf2b1f08cf76cfa8bc63396aac405d3;hpb=c6d59064aa782b8ad71eddac2797fdc50e4858f9 diff --git a/src/editor.c b/src/editor.c index 7f1ec19f..4a9491d0 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1,15 +1,13 @@ -/*********************************************************** -* 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 @@ -33,157 +31,275 @@ ----------------------------------------------------------------------------- */ -/* 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) - -/* values for the settings windows */ -#define ED_LEVEL_SETTINGS_XSTART (3 * MINI_TILEX / 2) -#define ED_LEVEL_SETTINGS_YSTART (7 * MINI_TILEY) - -#define ED_ELEMENT_SETTINGS_XSTART (3 * MINI_TILEX / 2) -#define ED_ELEMENT_SETTINGS_YSTART (10 * MINI_TILEY) + ED_DRAWINGAREA_BORDER_SIZE) +#define ED_GADGET_SPACE_DISTANCE (getFontWidth(FONT_TEXT_1)) -#define ED_XOFFSET_CHECKBOX (ED_CHECKBUTTON_XSIZE + \ - 2 * ED_GADGET_DISTANCE) +/* 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_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX -#define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2) -#define ED_SETTINGS_TAB_XOFFSET 124 - -#define ED_LEVEL_SETTINGS_XPOS(n) (ED_LEVEL_SETTINGS_XSTART + \ - (n) * ED_SETTINGS_XOFFSET) -#define ED_LEVEL_SETTINGS_YPOS(n) (ED_LEVEL_SETTINGS_YSTART + \ +/* 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_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_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_TABS_XPOS(n) (ED_LEVEL_SETTINGS_XPOS(0) + \ - (n) * ED_SETTINGS_TAB_XOFFSET) -#define ED_LEVEL_SETTINGS_TABS_YPOS(n) (ED_LEVEL_SETTINGS_YSTART - \ - 3 * MINI_TILEY) +#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_TABS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(0) + \ - (n) * ED_SETTINGS_TAB_XOFFSET) -#define ED_ELEMENT_SETTINGS_TABS_YPOS(n) (ED_ELEMENT_SETTINGS_YSTART - \ - 2 * MINI_TILEY) +#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) @@ -205,16 +321,13 @@ #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 * \ @@ -228,71 +341,13 @@ 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) /* @@ -315,7 +370,7 @@ #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) @@ -335,8 +390,14 @@ #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) @@ -583,45 +644,46 @@ #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_USE_START_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 18) -#define GADGET_ID_USE_ARTWORK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 19) -#define GADGET_ID_USE_EXPLOSION_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 20) -#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 21) -#define GADGET_ID_USE_INITIAL_INVENTORY (GADGET_ID_CHECKBUTTON_FIRST + 22) -#define GADGET_ID_CAN_PASS_TO_WALKABLE (GADGET_ID_CHECKBUTTON_FIRST + 23) -#define GADGET_ID_CAN_FALL_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 24) -#define GADGET_ID_CAN_MOVE_INTO_ACID (GADGET_ID_CHECKBUTTON_FIRST + 25) -#define GADGET_ID_DONT_COLLIDE_WITH (GADGET_ID_CHECKBUTTON_FIRST + 26) -#define GADGET_ID_ENVELOPE_AUTOWRAP (GADGET_ID_CHECKBUTTON_FIRST + 27) -#define GADGET_ID_ENVELOPE_CENTERED (GADGET_ID_CHECKBUTTON_FIRST + 28) -#define GADGET_ID_CUSTOM_INDESTRUCTIBLE (GADGET_ID_CHECKBUTTON_FIRST + 29) -#define GADGET_ID_CUSTOM_CAN_EXPLODE (GADGET_ID_CHECKBUTTON_FIRST + 30) -#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 31) -#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 32) -#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 33) -#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 34) -#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 35) -#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 36) -#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 37) -#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 38) -#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 39) -#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 40) -#define GADGET_ID_CUSTOM_GRAV_REACHABLE (GADGET_ID_CHECKBUTTON_FIRST + 41) -#define GADGET_ID_CUSTOM_USE_LAST_VALUE (GADGET_ID_CHECKBUTTON_FIRST + 42) -#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 43) -#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 44) -#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 45) -#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 46) -#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 47) -#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 48) -#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 49) -#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 50) -#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 51) -#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 52) -#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 53) +#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 (GADGET_ID_CHECKBUTTON_FIRST + 45) +#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 46) +#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 47) +#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 48) +#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 49) +#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 50) +#define GADGET_ID_CHANGE_HAS_ACTION (GADGET_ID_CHECKBUTTON_FIRST + 51) +#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 52) +#define GADGET_ID_CHANGE_BY_DIRECT_ACT (GADGET_ID_CHECKBUTTON_FIRST + 53) +#define GADGET_ID_CHANGE_BY_OTHER_ACT (GADGET_ID_CHECKBUTTON_FIRST + 54) /* gadgets for buttons in element list */ -#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 54) +#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 55) #define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \ ED_NUM_ELEMENTLIST_BUTTONS - 1) @@ -823,44 +885,45 @@ #define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 13 #define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 14 #define ED_CHECKBUTTON_ID_SHIFTED_RELOCATION 15 -#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 16 -#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 17 -#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 18 -#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 19 -#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 20 -#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 21 -#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 22 -#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 23 -#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 24 -#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 25 -#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 26 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 27 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 28 -#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 29 -#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 30 -#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 31 -#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 32 -#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 33 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 34 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 35 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 36 -#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 37 -#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 38 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 39 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 40 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 41 -#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 42 -#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 43 -#define ED_CHECKBUTTON_ID_CHANGE_DELAY 44 -#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 45 -#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 46 -#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 47 -#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 48 -#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 49 -#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 50 -#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 51 - -#define ED_NUM_CHECKBUTTONS 52 +#define ED_CHECKBUTTON_ID_LAZY_RELOCATION 16 +#define ED_CHECKBUTTON_ID_USE_START_ELEMENT 17 +#define ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT 18 +#define ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT 19 +#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 20 +#define ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY 21 +#define ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE 22 +#define ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID 23 +#define ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID 24 +#define ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH 25 +#define ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP 26 +#define ED_CHECKBUTTON_ID_ENVELOPE_CENTERED 27 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 28 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 29 +#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 30 +#define ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE 31 +#define ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE 32 +#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 33 +#define ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE 34 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 35 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 36 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 37 +#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 38 +#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 39 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE 40 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 41 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 42 +#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 43 +#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 44 +#define ED_CHECKBUTTON_ID_CHANGE_DELAY 45 +#define ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT 46 +#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT 47 +#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 48 +#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 49 +#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 50 +#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 51 +#define ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION 52 + +#define ED_NUM_CHECKBUTTONS 53 #define ED_CHECKBUTTON_ID_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED @@ -921,6 +984,9 @@ #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 + /* ----------------------------------------------------------------------------- @@ -943,6 +1009,7 @@ #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 @@ -956,7 +1023,7 @@ #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 @@ -970,9 +1037,8 @@ #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 /* @@ -983,43 +1049,188 @@ 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', "properties of level" }, - { '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; @@ -1047,11 +1258,7 @@ static struct /* ---------- current level number --------------------------------------- */ { -#if 1 -1, -1, /* these values are not constant, but can change at runtime */ -#else - DX + 5 - SX, DY + 3 - SY, -#endif 1, 100, GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE, @@ -1204,7 +1411,7 @@ static struct /* ---------- 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, @@ -1212,7 +1419,7 @@ static struct 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, @@ -1220,7 +1427,7 @@ static struct 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, @@ -1228,7 +1435,7 @@ static struct 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, @@ -1236,7 +1443,7 @@ static struct NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), + 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, @@ -1244,7 +1451,7 @@ static struct NULL, "push delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), + -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, @@ -1252,7 +1459,7 @@ static struct NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), + 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, @@ -1260,7 +1467,7 @@ static struct NULL, "drop delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(8), + -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, @@ -1306,7 +1513,7 @@ static struct /* ---------- 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, @@ -1366,7 +1573,7 @@ static struct "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, @@ -2135,7 +2342,7 @@ static struct /* ---------- element settings: configure (several elements) ------------- */ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, -1, options_player_speed, @@ -2146,7 +2353,7 @@ static struct /* ---------- 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, @@ -2154,7 +2361,7 @@ static struct 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, @@ -2162,7 +2369,7 @@ static struct 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, @@ -2170,7 +2377,7 @@ static struct 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, @@ -2178,7 +2385,7 @@ static struct "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, @@ -2218,7 +2425,10 @@ static struct -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), @@ -2347,7 +2557,7 @@ static struct /* ---------- 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, @@ -2366,62 +2576,70 @@ static struct char *text_left, *text_right, *infotext; } textbutton_info[ED_NUM_TEXTBUTTONS] = { + /* ---------- level and editor settings (tabs) --------------------------- */ + { - ED_LEVEL_SETTINGS_TABS_XPOS(0), ED_LEVEL_SETTINGS_TABS_YPOS(0), + ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0), GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE, 8, "Level", NULL, NULL, "Configure level properties" }, { - ED_LEVEL_SETTINGS_TABS_XPOS(1), ED_LEVEL_SETTINGS_TABS_YPOS(0), - GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_NONE, + -1, -1, + GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_LEVELINFO_LEVEL, 8, "Editor", NULL, NULL, "Configure editor properties" }, + + /* ---------- element settings (tabs) ------------------------------------ */ + { - ED_ELEMENT_SETTINGS_TABS_XPOS(0), ED_ELEMENT_SETTINGS_TABS_YPOS(0), + 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" }, { - ED_ELEMENT_SETTINGS_TABS_XPOS(1), ED_ELEMENT_SETTINGS_TABS_YPOS(0), - GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE, + -1, -1, + GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_INFO, 8, "Config", NULL, NULL, "Configure element properties" }, { - ED_ELEMENT_SETTINGS_TABS_XPOS(1), ED_ELEMENT_SETTINGS_TABS_YPOS(0), - 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 element properties, part 1" }, { - ED_ELEMENT_SETTINGS_TABS_XPOS(2), ED_ELEMENT_SETTINGS_TABS_YPOS(0), - 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 element properties, part 2" }, { - ED_ELEMENT_SETTINGS_TABS_XPOS(3), ED_ELEMENT_SETTINGS_TABS_YPOS(0), - GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE, + -1, -1, + GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_PROPERTIES_CONFIG_2, 8, "Change", NULL, NULL, "Configure custom element change pages" }, + + /* ---------- element settings (buttons) --------------------------------- */ + { - -1, ED_ELEMENT_SETTINGS_YPOS(2), + -1, -1, GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE, -1, "Save", " ", "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" }, { - -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" @@ -2430,39 +2648,34 @@ static struct 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" }, @@ -2470,61 +2683,43 @@ static struct 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, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ -#else - ED_SCROLL_UP_XPOS, ED_SCROLL_UP_YPOS, -#endif + IMG_EDITOR_PLAYFIELD_SCROLL_UP, GADGET_ID_SCROLL_UP, "scroll level editing area up" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 1 * ED_SCROLLBUTTON_YSIZE, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ -#else - ED_SCROLL_DOWN_XPOS, ED_SCROLL_DOWN_YPOS, -#endif + IMG_EDITOR_PLAYFIELD_SCROLL_DOWN, GADGET_ID_SCROLL_DOWN, "scroll level editing area down" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 2 * ED_SCROLLBUTTON_YSIZE, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ -#else - ED_SCROLL_LEFT_XPOS, ED_SCROLL_LEFT_YPOS, -#endif + IMG_EDITOR_PLAYFIELD_SCROLL_LEFT, GADGET_ID_SCROLL_LEFT, "scroll level editing area left" }, { - ED_SCROLLBUTTON_XPOS, ED_SCROLLBUTTON_YPOS + 3 * ED_SCROLLBUTTON_YSIZE, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ -#else - ED_SCROLL_RIGHT_XPOS, ED_SCROLL_RIGHT_YPOS, -#endif + 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')" }, @@ -2532,68 +2727,41 @@ static struct 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, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ -#else - SX + ED_SCROLL_HORIZONTAL_XPOS, SY + ED_SCROLL_HORIZONTAL_YPOS, - ED_SCROLL_HORIZONTAL_XSIZE, ED_SCROLL_HORIZONTAL_YSIZE, - SX, SY, - SXSIZE, SYSIZE, -#endif + IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_HORIZONTAL, GADGET_ID_SCROLL_HORIZONTAL, "scroll level editing area horizontally" }, { - ED_SCROLLBAR_XPOS, ED_SCROLLBAR_YPOS, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ - -1, -1, /* these values are not constant, but can change at runtime */ -#else - SX + ED_SCROLL_VERTICAL_XPOS, SY + ED_SCROLL_VERTICAL_YPOS, - ED_SCROLL_VERTICAL_XSIZE, ED_SCROLL_VERTICAL_YSIZE, - SX, SY, - SXSIZE, SYSIZE, -#endif + IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_VERTICAL, "scroll level editing area vertically" }, { - ED_SCROLLBAR2_XPOS, ED_SCROLLBAR2_YPOS, -#if 1 - -1, -1, /* these values are not constant, but can change at runtime */ - ED_SCROLL2_VERTICAL_XSIZE, ED_SCROLL2_VERTICAL_YSIZE, - -1, -1, /* these values are not constant, but can change at runtime */ -#else - DX + ED_SCROLL2_VERTICAL_XPOS, DY + ED_SCROLL2_VERTICAL_YPOS, - ED_SCROLL2_VERTICAL_XSIZE, ED_SCROLL2_VERTICAL_YSIZE, - DX, DY, -#endif - DXSIZE, DYSIZE, + IMG_EDITOR_PALETTE_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_LIST_VERTICAL, "scroll element list vertically" } }; + static struct { int x, y; @@ -2706,14 +2874,14 @@ static struct "exit level if all fields solved", "automatically finish Sokoban levels" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + 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" + "continuous snapping", "use snapping without releasing key" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, &level.block_snap_field, NULL, @@ -2748,28 +2916,35 @@ static struct "no centering when relocating", "level not centered after relocation" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_LAZY_RELOCATION, GADGET_ID_NONE, + &level.lazy_relocation, + 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, "use level start element:", "start level at this element's position" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, &level.use_artwork_element[0], NULL, "use artwork from element:", "use player artwork from other element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, &level.use_explosion_element[0], NULL, "use explosion from element:", "use explosion properties from element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE, &level.initial_player_gravity[0], NULL, @@ -2783,7 +2958,7 @@ static struct "use initial inventory:", "use collected elements on level start" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + 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, @@ -2831,53 +3006,46 @@ static struct 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, "use graphic of element:", "use existing element graphic" -#endif }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE, &level.use_custom_template, 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, "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, "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, "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, "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, @@ -3020,6 +3188,7 @@ static struct static struct { int x, y; + int xoffset, yoffset; int gadget_id; int gadget_id_align; int *value; @@ -3030,63 +3199,68 @@ static struct /* ---------- level playfield content ------------------------------------ */ { + 0, 0, 0, 0, GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, NULL, -#if 1 -1, -1, /* these values are not constant, but can change at runtime */ -#else - MAX_ED_FIELDX, MAX_ED_FIELDY, -#endif 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 @@ -3095,49 +3269,57 @@ static struct /* ---------- 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 @@ -3147,6 +3329,7 @@ static struct { 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" @@ -3156,6 +3339,7 @@ static struct { 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" @@ -3164,7 +3348,8 @@ static struct /* ---------- level start element ---------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(9), + -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" @@ -3173,7 +3358,8 @@ static struct /* ---------- player artwork element ------------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(10), + -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" @@ -3182,7 +3368,8 @@ static struct /* ---------- player explosion element ----------------------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(11), + -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" @@ -3192,6 +3379,7 @@ static struct { -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" @@ -3203,6 +3391,7 @@ static struct { -1, ED_AREA_1X1_SETTINGS_YPOS(1), + 0, ED_AREA_1X1_SETTINGS_YOFF, GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, &custom_element.gfx_element_initial,1, 1, NULL, NULL, NULL, "custom graphic element" @@ -3214,6 +3403,7 @@ static struct { -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 @@ -3223,12 +3413,14 @@ static struct { 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" @@ -3240,6 +3432,7 @@ static struct { -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" @@ -3249,6 +3442,7 @@ static struct { -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" @@ -3258,6 +3452,7 @@ static struct { -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.initial_trigger_element, 1, 1, NULL, NULL, NULL, "other element triggering change" @@ -3267,6 +3462,7 @@ static struct { -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" @@ -3275,7 +3471,8 @@ static struct /* ---------- 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 @@ -3284,7 +3481,8 @@ static struct /* ---------- random background (for random painting) -------------------- */ { - -1, ED_AREA_1X1_SETTINGS_YPOS(-1), + -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" @@ -3298,21 +3496,19 @@ static struct ----------------------------------------------------------------------------- */ +/* maximal size of level editor drawing area */ +static int MAX_ED_FIELDX, MAX_ED_FIELDY; + /* actual size of level editor drawing area */ -#if 1 static int ed_fieldx, ed_fieldy; -#else -static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1; -#endif /* 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)=0 &&(y)= 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); @@ -3337,6 +3541,7 @@ static void RedrawDrawingElements(); static void DrawDrawingWindow(); static void DrawLevelInfoWindow(); static void DrawPropertiesWindow(); +static void DrawPaletteWindow(); static void UpdateCustomElementGraphicGadgets(); static boolean checkPropertiesConfig(int); static void CopyLevelToUndoBuffer(int); @@ -3352,9 +3557,12 @@ static void HandleCheckbuttons(struct GadgetInfo *); 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; @@ -3366,6 +3574,7 @@ static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; 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; @@ -4065,13 +4274,13 @@ static int editor_el_chars[] = 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), @@ -4175,13 +4384,13 @@ static int editor_el_steel_chars[] = 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), @@ -4656,11 +4865,11 @@ static int *editor_el_dynamic_ptr = NULL; 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 */ @@ -4669,7 +4878,6 @@ static boolean use_el_empty = FALSE; 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 int editor_hl_unused[] = { EL_EMPTY }; @@ -4692,67 +4900,67 @@ static struct editor_elements_info[] = { { - &setup_editor_show_always, + &setup.editor.el_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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_classic, &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 @@ -4810,7 +5018,7 @@ editor_elements_info[] = static int getMaxInfoTextLength() { - return (SXSIZE / getFontWidth(FONT_TEXT_2)); + return (SXSIZE / getFontWidth(INFOTEXT_FONT)); } static int getTextWidthForGadget(char *text) @@ -4854,27 +5062,47 @@ static char *getElementInfoText(int element) 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; @@ -4993,7 +5221,9 @@ static void ReinitializeElementList() { 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++) { @@ -5007,7 +5237,13 @@ static void ReinitializeElementList() 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; } } @@ -5031,9 +5267,16 @@ static void ReinitializeElementList() { 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; @@ -5045,8 +5288,19 @@ static void ReinitializeElementList() 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]; } } @@ -5068,9 +5322,9 @@ void PrintEditorElementList() 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++) @@ -5080,21 +5334,21 @@ void PrintEditorElementList() 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"); } } @@ -5135,44 +5389,67 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height, { int border_graphic = (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER); - Bitmap *src_bitmap; - int src_x, src_y; - int bx = (input ? 4 : 8); - int by = (input ? 4 : 8); - int bx2 = TILEX - bx; - int by2 = TILEY - by; + 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; - getGraphicSource(border_graphic, 0, &src_bitmap, &src_x, &src_y); - BlitBitmap(src_bitmap, drawto, src_x, src_y, - bx, by, dest_x - bx, dest_y - by); - BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y, - bx, by, dest_x + width, dest_y - by); - BlitBitmap(src_bitmap, drawto, src_x, src_y + by2, - bx, by, dest_x - bx, dest_y + height); - BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y + by2, - bx, by, dest_x + width, dest_y + height); - - for (i = 0; i < width / MINI_TILEX; i++) - { - BlitBitmap(src_bitmap, drawto, src_x + bx, src_y, MINI_TILEX, by, - dest_x + i * MINI_TILEX, dest_y - by); - BlitBitmap(src_bitmap, drawto, src_x + bx, src_y + by2, MINI_TILEX, by, - dest_x + i * MINI_TILEX, dest_y + height); - } - - for (i = 0; i < height / MINI_TILEY; i++) - { - BlitBitmap(src_bitmap, drawto, src_x, src_y + by, bx, MINI_TILEY, - dest_x - bx, dest_y + i * MINI_TILEY); - BlitBitmap(src_bitmap, drawto, src_x + bx2, src_y + by, bx, MINI_TILEY, - dest_x + width, dest_y + i * MINI_TILEY); + 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 (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); } +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) { struct GadgetInfo *gi = level_editor_gadget[drawingarea_info[id].gadget_id]; @@ -5181,89 +5458,94 @@ 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 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 || @@ -5273,82 +5555,66 @@ static void CreateControlButtons() 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, @@ -5361,49 +5627,46 @@ static void CreateControlButtons() } /* these values are not constant, but can change at runtime */ - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_UP].x = ED_SCROLL_UP_XPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_UP].y = ED_SCROLL_UP_YPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_DOWN].x = ED_SCROLL_DOWN_XPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_DOWN].y = ED_SCROLL_DOWN_YPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_LEFT].x = ED_SCROLL_LEFT_XPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_LEFT].y = ED_SCROLL_LEFT_YPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_RIGHT].x = ED_SCROLL_RIGHT_XPOS; - scrollbutton_info[ED_SCROLLBUTTON_ID_AREA_RIGHT].y = ED_SCROLL_RIGHT_YPOS; + 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, @@ -5431,42 +5694,43 @@ static void CreateControlButtons() /* 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; + getEditorGraphicSource(element, tile_size, &deco_bitmap, &deco_x, &deco_y); - gd_xoffset = ED_ELEMENTLIST_XPOS + x * ED_ELEMENTLIST_XSIZE; - gd_yoffset = ED_ELEMENTLIST_YPOS + y * ED_ELEMENTLIST_YSIZE; - - 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, @@ -5485,15 +5749,11 @@ static void CreateCounterButtons() int max_infotext_len = getMaxInfoTextLength(); int i; - /* these values are not constant, but can change at runtime */ - counterbutton_info[ED_COUNTER_ID_SELECT_LEVEL].x = DX + 5 - SX; - counterbutton_info[ED_COUNTER_ID_SELECT_LEVEL].y = DY + 3 - SY; - 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) @@ -5506,47 +5766,51 @@ static void CreateCounterButtons() 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")); @@ -5555,12 +5819,12 @@ static void CreateCounterButtons() 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, @@ -5573,38 +5837,39 @@ static void CreateCounterButtons() 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", @@ -5617,10 +5882,10 @@ static void CreateCounterButtons() 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, @@ -5633,7 +5898,7 @@ static void CreateCounterButtons() 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 */ } } } @@ -5650,12 +5915,14 @@ static void CreateDrawingAreas() 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 | @@ -5676,7 +5943,7 @@ static void CreateDrawingAreas() 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, @@ -5693,22 +5960,45 @@ static void CreateDrawingAreas() 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'; @@ -5716,17 +6006,17 @@ static void CreateTextInputGadgets() 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, @@ -5746,10 +6036,13 @@ static void CreateTextAreaGadgets() 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; @@ -5757,25 +6050,22 @@ static void CreateTextAreaGadgets() 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, @@ -5795,14 +6085,19 @@ static void CreateSelectboxGadgets() 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 */ { @@ -5821,9 +6116,6 @@ static void CreateSelectboxGadgets() 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] + @@ -5843,14 +6135,16 @@ static void CreateSelectboxGadgets() 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, @@ -5872,43 +6166,47 @@ static void CreateTextbuttonGadgets() 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_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) || - (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) @@ -5922,13 +6220,13 @@ static void CreateTextbuttonGadgets() 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, @@ -5946,36 +6244,24 @@ static void CreateTextbuttonGadgets() 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] + @@ -5990,12 +6276,12 @@ static void CreateGraphicbuttonGadgets() 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, @@ -6015,47 +6301,57 @@ static void CreateScrollbarGadgets() int i; /* these values are not constant, but can change at runtime */ - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].x = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].x = SX + ED_SCROLL_HORIZONTAL_XPOS; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].y = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].y = SY + ED_SCROLL_HORIZONTAL_YPOS; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].width = ED_SCROLL_HORIZONTAL_XSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].height = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_HORIZONTAL].height = ED_SCROLL_HORIZONTAL_YSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_x = SX; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_y = SY; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_width = SXSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_HORIZONTAL].wheel_height = SYSIZE; + 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_info[ED_SCROLLBAR_ID_AREA_VERTICAL].x = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].x = SX + ED_SCROLL_VERTICAL_XPOS; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].y = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].y = SY + ED_SCROLL_VERTICAL_YPOS; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].width = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].width = ED_SCROLL_VERTICAL_XSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].height = + scrollbar_pos[ED_SCROLLBAR_ID_AREA_VERTICAL].height = ED_SCROLL_VERTICAL_YSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_x = SX; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_y = SY; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_width = SXSIZE; - scrollbar_info[ED_SCROLLBAR_ID_AREA_VERTICAL].wheel_height = SYSIZE; - - scrollbar_info[ED_SCROLLBAR_ID_LIST_VERTICAL].x = - DX + ED_SCROLL2_VERTICAL_XPOS; - scrollbar_info[ED_SCROLLBAR_ID_LIST_VERTICAL].y = - DY + ED_SCROLL2_VERTICAL_YPOS; - scrollbar_info[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_x = DX; - scrollbar_info[ED_SCROLLBAR_ID_LIST_VERTICAL].wheel_y = DY; + 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) { @@ -6081,31 +6377,25 @@ static void CreateScrollbarGadgets() 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, @@ -6120,30 +6410,28 @@ static void CreateScrollbarGadgets() 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) @@ -6159,14 +6447,14 @@ static void CreateCheckbuttonGadgets() 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, @@ -6183,25 +6471,26 @@ static void CreateCheckbuttonGadgets() 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); @@ -6220,15 +6509,15 @@ static void CreateRadiobuttonGadgets() 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, @@ -6245,15 +6534,27 @@ static void CreateRadiobuttonGadgets() void CreateLevelEditorGadgets() { - int old_game_status = game_status; - - /* setting 'game_status' is needed to get the right fonts for the editor */ - game_status = GAME_MODE_EDITOR; + /* 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; + + // 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(); CreateControlButtons(); @@ -6270,23 +6571,32 @@ void CreateLevelEditorGadgets() 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; @@ -6295,8 +6605,8 @@ static void MapCounterButtons(int id) 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; @@ -6316,22 +6626,25 @@ static void MapCounterButtons(int id) 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); @@ -6347,12 +6660,19 @@ static void MapControlButtons() 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; @@ -6363,30 +6683,33 @@ static void MapControlButtons() 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); } @@ -6396,14 +6719,15 @@ static void MapDrawingArea(int 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); @@ -6412,14 +6736,15 @@ static void MapTextInputGadget(int id) 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); @@ -6428,19 +6753,21 @@ static void MapTextAreaGadget(int id) 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); @@ -6449,10 +6776,12 @@ static void MapSelectboxGadget(int id) 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 = (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; @@ -6463,39 +6792,43 @@ static void MapTextbuttonGadget(int id) return; 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; @@ -6503,10 +6836,10 @@ static void MapRadiobuttonGadget(int id) (*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); @@ -6515,26 +6848,28 @@ static void MapRadiobuttonGadget(int id) 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 = (gi->height - font_height) / 2; 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_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); @@ -6604,26 +6939,27 @@ static void UnmapLevelEditorToolboxCustomGadgets() 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; @@ -6647,12 +6983,13 @@ static void UnmapDrawingArea(int id) 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]); } @@ -6660,7 +6997,7 @@ void UnmapLevelEditorGadgets() { int i; - for (i = 0; i < NUM_EDITOR_GADGETS; i++) + for (i = 0; i < num_editor_gadgets; i++) UnmapGadget(level_editor_gadget[i]); } @@ -6668,6 +7005,8 @@ static void ResetUndoBuffer() { undo_buffer_position = -1; undo_buffer_steps = -1; + redo_buffer_steps = 0; + CopyLevelToUndoBuffer(UNDO_IMMEDIATE); level.changed = FALSE; @@ -6682,22 +7021,24 @@ static void DrawEditModeWindow() 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 1 - /* changed read-only levels can now be saved in personal level set */ -#else - if (leveldir_current->readonly) - return FALSE; -#endif - for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) if (Feld[x][y] != level.field[x][y]) @@ -6728,8 +7069,8 @@ static boolean PrepareSavingIntoPersonalLevelSet() return TRUE; } - if (!Request("This level is read only ! " - "Save into personal level set ?", REQ_ASK)) + 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) @@ -6991,6 +7332,8 @@ static void replace_custom_element_in_playfield(int element_from, 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) ? @@ -7007,13 +7350,13 @@ static boolean CopyCustomElement(int element_old, int element_new, } 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; } @@ -7022,6 +7365,13 @@ static boolean CopyCustomElement(int element_old, int element_new, 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); @@ -7227,6 +7577,27 @@ static void CopyElementPropertiesToEditor(int 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], + 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; @@ -7237,20 +7608,7 @@ static void CopyCustomElementPropertiesToGame(int element) 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; @@ -7361,12 +7719,15 @@ static void CopyCustomElementPropertiesToGame(int element) 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) @@ -7399,22 +7760,50 @@ void CheckElementDescriptions() Error(ERR_WARN, "no element description 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() { - StopAnimation(); + int fade_mask = REDRAW_FIELD; - CloseDoor(DOOR_CLOSE_ALL); + FadeSoundsAndMusic(); -#if 1 - FadeOut(REDRAW_FIELD); -#endif + if (CheckIfGlobalBorderHasChanged()) + fade_mask = REDRAW_ALL; + + FadeOut(fade_mask); -#if 1 /* needed if different viewport properties defined for editor */ ChangeViewportPropertiesIfNeeded(); -#endif - OpenDoor(DOOR_OPEN_2 | DOOR_NO_DELAY); + ClearField(); + + InitZoomLevelSettings(); + + OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2 | DOOR_NO_DELAY); #if DEBUG CheckElementDescriptions(); @@ -7439,61 +7828,49 @@ void DrawLevelEd() level_ypos = -1; } - /* 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); + /* needed for gadgets drawn on background (like palette scrollbar) */ + SetDoorBackgroundImage(IMG_UNDEFINED); -#if 0 - printf("::: %d, %d / %d, %d\n", VX, VY, EX, EY); -#endif + /* copy default editor door content to main double buffer */ + 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; -#if 1 FreeLevelEditorGadgets(); CreateLevelEditorGadgets(); -#endif ReinitializeElementList(); /* update dynamic level element list */ ReinitializeElementListButtons(); /* custom element may look different */ InitElementPropertiesGfxElement(); -#if 1 UnmapAllGadgets(); -#else - UnmapTapeButtons(); -#endif MapControlButtons(); -#if 0 - FadeOut(REDRAW_FIELD); -#endif - DrawEditModeWindow(); -#if 1 - FadeIn(REDRAW_FIELD); -#endif + DrawMaskedBorder(fade_mask); - /* 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); + FadeIn(fade_mask); -#if 1 - /* draw new control window (with border) to window */ - redraw_mask |= REDRAW_ALL; - BackToFront(); -#endif - - OpenDoor(DOOR_OPEN_1); + /* 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() @@ -7505,54 +7882,62 @@ 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); @@ -7646,7 +8031,8 @@ static void ModifyEditorCounterLimits(int counter_id, int min, int max) 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); } } @@ -7687,48 +8073,74 @@ static void ModifyEditorElementList() { 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; } @@ -7747,7 +8159,7 @@ static void DrawDrawingWindow() SetMainBackgroundImage(IMG_UNDEFINED); ClearField(); - UnmapLevelEditorWindowGadgets(); + UnmapLevelEditorFieldGadgets(); UnmapLevelEditorToolboxCustomGadgets(); AdjustDrawingAreaGadgets(); @@ -7755,7 +8167,7 @@ static void DrawDrawingWindow() 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(); @@ -7769,6 +8181,11 @@ static int getTabulatorBarWidth() return gd_gi4->x - gd_gi1->x + gd_gi4->width; } +static int getTabulatorBarHeight() +{ + return ED_TAB_BAR_HEIGHT; +} + static void DrawLevelInfoTabulatorGadgets() { struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL]; @@ -7778,10 +8195,6 @@ static void DrawLevelInfoTabulatorGadgets() Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y); int id_first = ED_TEXTBUTTON_ID_LEVELINFO_LEVEL; int id_last = ED_TEXTBUTTON_ID_LEVELINFO_EDITOR; -#if 1 -#else - int max_tabs = 2; -#endif int i; for (i = id_first; i <= id_last; i++) @@ -7795,25 +8208,18 @@ static void DrawLevelInfoTabulatorGadgets() /* 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); + 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); } -#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, - getTabulatorBarWidth(), 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 + FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + + ED_GADGET_TINY_DISTANCE, + getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color); } static void DrawPropertiesTabulatorGadgets() @@ -7825,10 +8231,6 @@ static void DrawPropertiesTabulatorGadgets() 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 two config tabulators for player elements */ @@ -7856,25 +8258,18 @@ static void DrawPropertiesTabulatorGadgets() /* 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); + 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); } -#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, - getTabulatorBarWidth(), 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 + FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + + ED_GADGET_TINY_DISTANCE, + getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color); } static void DrawLevelInfoLevel() @@ -7916,26 +8311,20 @@ static void DrawLevelInfoEditor() 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; - UnmapLevelEditorWindowGadgets(); + UnmapLevelEditorFieldGadgets(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearField(); -#if 1 -#if 1 - DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Global Settings"); -#else - DrawTextSCentered(ED_SETTINGS1_YPOS, FONT_TITLE_1, "Level Settings"); - DrawTextSCentered(ED_SETTINGS2_YPOS, FONT_TITLE_1, "Editor Settings"); -#endif -#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 + DrawText(sx, sy, text, font_nr); DrawLevelInfoTabulatorGadgets(); @@ -7952,7 +8341,7 @@ 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); @@ -7969,17 +8358,32 @@ static void DrawCustomChangeContentArea() 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 */ @@ -7995,27 +8399,26 @@ static void DrawYamYamContentAreas() } 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 */ @@ -8031,29 +8434,25 @@ static void DrawMagicBallContentAreas() } 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; @@ -8068,17 +8467,20 @@ static void DrawAndroidElementArea(int element) 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; @@ -8090,25 +8492,28 @@ static void DrawGroupElementArea(int element) 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 id = ED_DRAWING_ID_INVENTORY_CONTENT; - int sx = SX + drawingarea_info[id].x - MINI_TILEX / 2; - int sy = SY + drawingarea_info[id].y - MINI_TILEY / 2; + 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); + 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) @@ -8119,7 +8524,9 @@ static void DrawPlayerInitialInventoryArea(int element) 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); } @@ -8146,8 +8553,8 @@ static void DrawEnvelopeTextArea(int envelope_nr) static boolean PrintInfoText(char *text, int font_nr, int start_line) { 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 pad_x = ED_ELEMENT_SETTINGS_X(0); + int pad_y = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; int sx = SX + pad_x; int sy = SY + pad_y; int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1; @@ -8165,15 +8572,19 @@ static int PrintElementDescriptionFromFile(char *filename, int start_line) 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 pad_x = ED_ELEMENT_SETTINGS_X(0); + int pad_y = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; 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; + int max_lines_drawable = max_lines_per_screen - start_line; + + if (start_line >= max_lines_per_screen) + return FALSE; return DrawTextFile(sx, sy, filename, font_nr, max_chars_per_line, -1, - max_lines_per_screen, -1, TRUE, FALSE, FALSE); + max_lines_drawable, 0, -1, TRUE, FALSE, FALSE); } static void DrawPropertiesInfo() @@ -8237,8 +8648,8 @@ static void DrawPropertiesInfo() { -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: "; float percentage; int num_elements_in_level; int num_standard_properties = 0; @@ -8246,8 +8657,8 @@ static void DrawPropertiesInfo() int font2_nr = FONT_TEXT_2; int font1_width = getFontWidth(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 pad_x = ED_ELEMENT_SETTINGS_X(0); + int pad_y = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; int screen_line = 0; int i, x, y; @@ -8456,6 +8867,7 @@ static boolean checkPropertiesConfig(int element) static void DrawPropertiesConfig() { + boolean draw_footer_line = FALSE; int max_num_element_counters = 4; int num_element_counters = 0; int i; @@ -8566,6 +8978,7 @@ static void DrawPropertiesConfig() 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); @@ -8698,6 +9111,8 @@ static void DrawPropertiesConfig() /* draw drawing area gadgets */ MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC); + + draw_footer_line = TRUE; } else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2) { @@ -8748,6 +9163,25 @@ static void DrawPropertiesConfig() /* 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); } } @@ -8812,16 +9246,15 @@ static void DrawEditorElementAnimation(int x, int y) 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]; @@ -8862,8 +9295,24 @@ static void DrawEditorElementName(int x, int y, int element) 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; @@ -8884,7 +9333,7 @@ static void DrawPropertiesWindow() CopyElementPropertiesToEditor(properties_element); - UnmapLevelEditorWindowGadgets(); + UnmapLevelEditorFieldGadgets(); UnmapLevelEditorToolboxDrawingGadgets(); UnmapLevelEditorToolboxCustomGadgets(); @@ -8895,25 +9344,13 @@ static void DrawPropertiesWindow() SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearField(); -#if 1 - 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(); @@ -8925,13 +9362,28 @@ static void DrawPropertiesWindow() 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() { - struct ElementInfo *ei = &element_info[properties_element]; int i; - ei->gfx_element = (ei->use_gfx_element ? ei->gfx_element_initial : - properties_element); + InitElementPropertiesGfxElement(); ModifyEditorElementList(); RedrawDrawingElements(); @@ -9387,7 +9839,7 @@ static void SetElementSimple(int x, int y, int element, boolean change_level) Feld[x][y] = element; if (IN_ED_FIELD(sx, sy)) - DrawMiniElement(sx, sy, element); + DrawEditorElement(sx, sy, element); } static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, @@ -10088,10 +10540,10 @@ static void DrawAreaBorder(int from_x, int from_y, int to_x, int to_y) 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); @@ -10124,11 +10576,7 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, int button, int mode) { -#if 1 static short brush_buffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -#else - static short brush_buffer[MAX_ED_FIELDX][MAX_ED_FIELDY]; -#endif static int brush_width, brush_height; static int last_cursor_x = -1, last_cursor_y = -1; static boolean delete_old_brush; @@ -10159,7 +10607,10 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, 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"); @@ -10309,7 +10760,7 @@ static void FloodFill(int from_x, int from_y, int fill_element) 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; @@ -10318,11 +10769,11 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) /* 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; @@ -10351,13 +10802,14 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) 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; @@ -10366,6 +10818,10 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) 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; @@ -10384,7 +10840,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) 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; @@ -10398,7 +10854,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_END: CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - DrawMiniElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Feld[lx][ly]); typing = FALSE; break; @@ -10419,7 +10875,7 @@ static void SetTextCursor(int unused_sx, int unused_sy, int sx, int sy, 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); } @@ -10431,7 +10887,7 @@ static void CheckLevelBorderElement(boolean redraw_playfield) 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) @@ -10440,6 +10896,9 @@ 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: @@ -10458,13 +10917,16 @@ static void CopyLevelToUndoBuffer(int mode) 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]; @@ -10482,9 +10944,7 @@ static void RandomPlacement(int new_element) int num_percentage, num_elements; int x, y; -#if 1 ResetIntelliDraw(); -#endif /* 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++) @@ -10509,11 +10969,7 @@ static void RandomPlacement(int new_element) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) if (free_position[x][y]) -#if 1 SetElement(x, y, new_element); -#else - Feld[x][y] = new_element; -#endif } else { @@ -10526,17 +10982,13 @@ static void RandomPlacement(int new_element) if (free_position[x][y]) { free_position[x][y] = FALSE; -#if 1 SetElement(x, y, new_element); -#else - Feld[x][y] = new_element; -#endif num_elements--; } } } - DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_IMMEDIATE); } @@ -10555,7 +11007,7 @@ void WrapLevel(int dx, int dy) 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); } @@ -10563,6 +11015,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { 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; @@ -10649,10 +11102,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); - -#if 0 - ResetIntelliDraw(); -#endif } if (!button || button_release_event) @@ -10660,55 +11109,24 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) 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 SetElementButton(lx, ly, new_element, button); -#else - Feld[lx][ly] = new_element; - DrawMiniElement(sx, sy, new_element); -#endif } } - 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) @@ -10717,10 +11135,10 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) 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); @@ -10822,7 +11240,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) 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; @@ -10835,17 +11253,22 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) 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) @@ -10866,7 +11289,7 @@ 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) @@ -10926,6 +11349,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) 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: @@ -10938,6 +11365,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi) 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; } @@ -10961,14 +11393,9 @@ static void HandleTextAreaGadgets(struct GadgetInfo *gi) { 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; } @@ -11029,8 +11456,7 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) } else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE) { - 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); @@ -11039,11 +11465,11 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) 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); @@ -11053,6 +11479,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) { 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 */ @@ -11070,6 +11500,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) { 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]; @@ -11109,10 +11543,16 @@ static void HandleGraphicbuttonGadgets(struct GadgetInfo *gi) 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]; @@ -11125,8 +11565,15 @@ static void HandleGraphicbuttonGadgets(struct GadgetInfo *gi) 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; } @@ -11155,23 +11602,55 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) } else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE) { - char *template_filename = getDefaultLevelFilename(-1); + boolean template_related_changes_found = FALSE; + int i; - if (level.use_custom_template && !fileExists(template_filename)) + /* 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(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(); } + /* 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; } @@ -11180,10 +11659,12 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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) @@ -11191,20 +11672,25 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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: @@ -11217,9 +11703,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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); @@ -11236,9 +11722,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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); @@ -11255,9 +11741,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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); @@ -11274,9 +11760,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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); @@ -11285,12 +11771,18 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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: @@ -11317,6 +11809,53 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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; @@ -11353,25 +11892,20 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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: @@ -11390,21 +11924,45 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_UNDO: - if (undo_buffer_steps == 0) + if (button == 1 && undo_buffer_steps == 0) { - Request("Undo buffer empty !", REQ_CONFIRM); + Request("Undo buffer empty!", REQ_CONFIRM); + + break; + } + else if (button == 2) + { + break; + } + else if (button == 3 && redo_buffer_steps == 0) + { + 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++) @@ -11413,7 +11971,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) /* 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; @@ -11421,24 +11979,18 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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++) @@ -11446,7 +11998,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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: @@ -11466,7 +12018,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) new_level = !fileExists(level_filename); if (new_level || - Request("Save this level and kill the old ?", REQ_ASK)) + Request("Save this level and kill the old?", REQ_ASK)) { if (leveldir_former->readonly) ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name); @@ -11482,10 +12034,10 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (leveldir_former->readonly) sprintf(level_saved_msg, - "Level saved as level %d into personal level set !", + "Level saved as level %d into personal level set!", level_nr); else - strcpy(level_saved_msg, "Level saved !"); + strcpy(level_saved_msg, "Level saved!"); Request(level_saved_msg, REQ_CONFIRM); } @@ -11512,11 +12064,10 @@ static void HandleControlButtons(struct GadgetInfo *gi) CloseDoor(DOOR_CLOSE_ALL); - BackToFront(); /* force redraw of undrawn special door */ + /* needed before playing if editor playfield area has different size */ + ClearRectangle(drawto, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); -#if 0 - DrawCompleteVideoDisplay(); -#endif + // redraw_mask = REDRAW_ALL; level_editor_test_game = TRUE; @@ -11580,6 +12131,10 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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 && @@ -11594,6 +12149,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) 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) @@ -11630,6 +12188,7 @@ void HandleLevelEditorKeyInput(Key key) { int id = GADGET_ID_NONE; int new_element_shift = element_shift; + int step = ED_ELEMENTLIST_BUTTONS_VERT - 1; int i; switch (key) @@ -11646,13 +12205,23 @@ void HandleLevelEditorKeyInput(Key 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: @@ -11714,10 +12283,13 @@ void HandleLevelEditorKeyInput(Key key) { 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; @@ -11728,15 +12300,30 @@ void HandleLevelEditorKeyInput(Key key) 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 (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); } @@ -11744,9 +12331,11 @@ void HandleLevelEditorKeyInput(Key key) 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) @@ -11763,11 +12352,9 @@ void HandleLevelEditorIdle() return; } - DrawEditorElementAnimation(SX + xpos * TILEX, - SY + ypos * TILEY + MINI_TILEY / 2); + DrawEditorElementAnimation(SX + x, SY + y); - MarkTileDirty(xpos, ypos); - MarkTileDirty(xpos, ypos + 1); + redraw_mask |= REDRAW_FIELD; FrameCounter++; /* increase animation frame counter */ } @@ -11783,7 +12370,7 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) 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); @@ -11791,17 +12378,21 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) 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); @@ -11810,7 +12401,7 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) } } - DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2); + DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, INFOTEXT_FONT); } void HandleEditorGadgetInfoText(void *ptr) @@ -11983,7 +12574,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) 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, @@ -11991,30 +12582,43 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed, { 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); + 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 1 if (quick_quit) FadeSkipNextFadeIn(); -#else - if (quick_quit) - fading = fading_none; -#endif - game_status = GAME_MODE_MAIN; -#if 1 - DrawAndFadeInMainMenu(REDRAW_FIELD); -#else + SetGameStatus(GAME_MODE_MAIN); + DrawMainMenu(); -#endif } 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); + } } }