X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=ab28fe0cf4d002a8d4760c7243992b925f634650;hb=fd18ece8535cd87bd72989d7d39092d55b283939;hp=dcb2f6e67f69e1ba8b85c820627dc5fe1ec09b7a;hpb=20c6b8920ccb37a41b9f7467135ecd6550816f59;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index dcb2f6e6..ab28fe0c 100644 --- a/src/editor.c +++ b/src/editor.c @@ -47,10 +47,6 @@ /* how many steps can be cancelled */ #define NUM_UNDO_STEPS (10 + 1) -/* values for random placement */ -#define RANDOM_USE_PERCENTAGE 0 -#define RANDOM_USE_NUM_OBJECTS 1 - /* values for elements with score */ #define MIN_SCORE 0 #define MAX_SCORE 255 @@ -98,31 +94,35 @@ #define ED_NUM_ELEMENTLIST_BUTTONS (ED_ELEMENTLIST_BUTTONS_HORIZ * \ ED_ELEMENTLIST_BUTTONS_VERT) -/* values for element properties window */ -#define ED_PROPERTIES_XPOS (TILEX - MINI_TILEX/2) - -/* values for level information window */ -#define ED_LEVELINFO_XPOS (TILEX - MINI_TILEX/2) -#define ED_LEVELINFO_YPOS (TILEY - MINI_TILEY/2) +/* values for the setting windows */ +#define ED_SETTINGS_XPOS (MINI_TILEX + 8) +#define ED_SETTINGS2_XPOS MINI_TILEX +#define ED_SETTINGS_YPOS MINI_TILEY +#define ED_SETTINGS2_YPOS (ED_SETTINGS_YPOS + 12 * TILEY - 2) /* values for counter gadgets */ -#define ED_COUNT_VALUE_XOFFSET 5 -#define ED_COUNT_VALUE_YOFFSET 3 -#define ED_COUNT_ELEM_SCORE_XPOS ED_PROPERTIES_XPOS +#define ED_COUNT_ELEM_SCORE_XPOS ED_SETTINGS_XPOS #define ED_COUNT_ELEM_SCORE_YPOS (14 * MINI_TILEY) -#define ED_COUNT_ELEM_CONTENT_XPOS ED_PROPERTIES_XPOS -#define ED_COUNT_ELEM_CONTENT_YPOS (17 * MINI_TILEY) -#define ED_COUNTER_YSTART (ED_LEVELINFO_YPOS + 3 * TILEY) +#define ED_COUNT_ELEM_CONTENT_XPOS ED_SETTINGS_XPOS +#define ED_COUNT_ELEM_CONTENT_YPOS (19 * MINI_TILEY) + +#define ED_COUNTER_YSTART (ED_SETTINGS_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) /* standard distances */ #define ED_BORDER_SIZE 3 #define ED_GADGET_DISTANCE 2 /* values for element content drawing areas */ -#define ED_AREA_ELEM_CONTENT_XPOS (TILEX) -#define ED_AREA_ELEM_CONTENT_YPOS (10 * TILEY) +#define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX) +#define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY) + +/* values for random placement background drawing area */ +#define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX) +#define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY) /* values for scrolling gadgets */ #define ED_SCROLLBUTTON_XPOS 24 @@ -150,9 +150,17 @@ #define ED_SCROLL_VERTICAL_XSIZE ED_SCROLLBUTTON_XSIZE #define ED_SCROLL_VERTICAL_YSIZE (SYSIZE - 4 * ED_SCROLLBUTTON_YSIZE) -/* control button identifiers */ +/* 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_STICKYBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 88) + #define GADGET_ID_NONE -1 +/* drawing toolbox buttons */ #define GADGET_ID_SINGLE_ITEMS 0 #define GADGET_ID_CONNECTED_ITEMS 1 #define GADGET_ID_LINE 2 @@ -234,33 +242,51 @@ #define GADGET_ID_ELEMENTLIST_FIRST 66 #define GADGET_ID_ELEMENTLIST_LAST 105 -#define NUM_EDITOR_GADGETS 106 +/* buttons for level settings */ +#define GADGET_ID_RANDOM_PERCENTAGE 106 +#define GADGET_ID_RANDOM_QUANTITY 107 +#define GADGET_ID_RANDOM_RESTRICTED 108 +#define GADGET_ID_DOUBLE_SPEED 109 +#define GADGET_ID_STICK_ELEMENT 110 + +/* another drawing area for random placement */ +#define GADGET_ID_RANDOM_BACKGROUND 111 + +#define NUM_EDITOR_GADGETS 112 + +/* radio button numbers */ +#define RADIO_NR_NONE 0 +#define RADIO_NR_DRAWING_TOOLBOX 1 +#define RADIO_NR_RANDOM_ELEMENTS 2 /* values for counter gadgets */ #define ED_COUNTER_ID_ELEM_SCORE 0 #define ED_COUNTER_ID_ELEM_CONTENT 1 #define ED_COUNTER_ID_LEVEL_XSIZE 2 #define ED_COUNTER_ID_LEVEL_YSIZE 3 -#define ED_COUNTER_ID_LEVEL_RANDOM 4 -#define ED_COUNTER_ID_LEVEL_COLLECT 5 -#define ED_COUNTER_ID_LEVEL_TIMELIMIT 6 -#define ED_COUNTER_ID_LEVEL_TIMESCORE 7 +#define ED_COUNTER_ID_LEVEL_COLLECT 4 +#define ED_COUNTER_ID_LEVEL_TIMELIMIT 5 +#define ED_COUNTER_ID_LEVEL_TIMESCORE 6 +#define ED_COUNTER_ID_LEVEL_RANDOM 7 #define ED_NUM_COUNTERBUTTONS 8 +#define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE +#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM + /* values for scrollbutton gadgets */ -#define ED_SCROLLBUTTON_AREA_UP 0 -#define ED_SCROLLBUTTON_AREA_DOWN 1 -#define ED_SCROLLBUTTON_AREA_LEFT 2 -#define ED_SCROLLBUTTON_AREA_RIGHT 3 -#define ED_SCROLLBUTTON_LIST_UP 4 -#define ED_SCROLLBUTTON_LIST_DOWN 5 +#define ED_SCROLLBUTTON_ID_AREA_UP 0 +#define ED_SCROLLBUTTON_ID_AREA_DOWN 1 +#define ED_SCROLLBUTTON_ID_AREA_LEFT 2 +#define ED_SCROLLBUTTON_ID_AREA_RIGHT 3 +#define ED_SCROLLBUTTON_ID_LIST_UP 4 +#define ED_SCROLLBUTTON_ID_LIST_DOWN 5 #define ED_NUM_SCROLLBUTTONS 6 /* values for scrollbar gadgets */ -#define ED_SCROLLBAR_HORIZONTAL 0 -#define ED_SCROLLBAR_VERTICAL 1 +#define ED_SCROLLBAR_ID_HORIZONTAL 0 +#define ED_SCROLLBAR_ID_VERTICAL 1 #define ED_NUM_SCROLLBARS 2 @@ -270,16 +296,38 @@ #define ED_NUM_TEXTINPUT 2 +#define ED_TEXTINPUT_ID_LEVEL_FIRST ED_TEXTINPUT_ID_LEVEL_NAME +#define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR + +/* values for checkbutton gadgets */ +#define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0 +#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 1 +#define ED_CHECKBUTTON_ID_STICK_ELEMENT 2 + +#define ED_NUM_CHECKBUTTONS 3 + +#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED +#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED + +/* values for radiobutton gadgets */ +#define ED_RADIOBUTTON_ID_PERCENTAGE 0 +#define ED_RADIOBUTTON_ID_QUANTITY 1 + +#define ED_NUM_RADIOBUTTONS 2 + +#define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE +#define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY + /* values for CopyLevelToUndoBuffer() */ #define UNDO_IMMEDIATE 0 #define UNDO_ACCUMULATE 1 /* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */ -#define INFOTEXT_XPOS SX -#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) -#define INFOTEXT_XSIZE SXSIZE -#define INFOTEXT_YSIZE MINI_TILEX -#define MAX_INFOTEXT_LEN (SXSIZE / FONT2_XSIZE) +#define INFOTEXT_XPOS SX +#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2) +#define INFOTEXT_XSIZE SXSIZE +#define INFOTEXT_YSIZE MINI_TILEX +#define MAX_INFOTEXT_LEN (SXSIZE / FONT2_XSIZE) static struct { @@ -328,7 +376,7 @@ static struct int gadget_id_down, gadget_id_up; int gadget_id_text; int **counter_value; - char *infotext; + char *infotext_above, *infotext_right; } counterbutton_info[ED_NUM_COUNTERBUTTONS] = { { @@ -337,7 +385,7 @@ static struct GADGET_ID_ELEM_SCORE_DOWN, GADGET_ID_ELEM_SCORE_UP, GADGET_ID_ELEM_SCORE_TEXT, &gadget_elem_score_value, - "element score" + "element score", NULL }, { ED_COUNT_ELEM_CONTENT_XPOS, ED_COUNT_ELEM_CONTENT_YPOS, @@ -345,77 +393,80 @@ static struct GADGET_ID_ELEM_CONTENT_DOWN, GADGET_ID_ELEM_CONTENT_UP, GADGET_ID_ELEM_CONTENT_TEXT, &gadget_elem_content_value, - "element content" + "element content", NULL }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(0), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(2), MIN_LEV_FIELDX, MAX_LEV_FIELDX, GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP, GADGET_ID_LEVEL_XSIZE_TEXT, &gadget_level_xsize_value, - "playfield width" + "playfield size", "width", }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(1), + ED_SETTINGS_XPOS + 2 * DXSIZE, ED_COUNTER_YPOS(2), MIN_LEV_FIELDY, MAX_LEV_FIELDY, GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP, GADGET_ID_LEVEL_YSIZE_TEXT, &gadget_level_ysize_value, - "playfield height" - }, - { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(2), - 0, 100, - GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, - GADGET_ID_LEVEL_RANDOM_TEXT, - &gadget_level_random_value, - "number of random elements" + NULL, "height", }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(3), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3), 0, 999, GADGET_ID_LEVEL_COLLECT_DOWN, GADGET_ID_LEVEL_COLLECT_UP, GADGET_ID_LEVEL_COLLECT_TEXT, &gadget_level_collect_value, - "number of emeralds to collect" + "number of emeralds to collect", NULL }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(4), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4), 0, 999, GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP, GADGET_ID_LEVEL_TIMELIMIT_TEXT, &gadget_level_timelimit_value, - "time available to solve level" + "time available to solve level", "(0 => no time limit)" }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(5), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(5), 0, 255, GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, &gadget_level_timescore_value, - "score for each 10 seconds left" + "score for each 10 seconds left", NULL }, + { + ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(8), + 1, 100, + GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, + GADGET_ID_LEVEL_RANDOM_TEXT, + &gadget_level_random_value, + "random element placement", "in" + } }; static struct { int x, y; int gadget_id; + int size; char *value; char *infotext; } textinput_info[ED_NUM_TEXTINPUT] = { { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(6), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(0), GADGET_ID_LEVEL_NAME, + MAX_LEVEL_NAME_LEN, level.name, - "Level Title" + "Title" }, { - ED_LEVELINFO_XPOS, ED_COUNTER_YPOS(7), + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(1), GADGET_ID_LEVEL_AUTHOR, + MAX_LEVEL_AUTHOR_LEN, level.author, - "Level Author" + "Author" } }; @@ -455,13 +506,13 @@ static struct ED_ELEMENTLIST_UP_XPOS, ED_ELEMENTLIST_UP_ALT_YPOS, ED_ELEMENTLIST_UP_XPOS, ED_ELEMENTLIST_UP_YPOS, GADGET_ID_ELEMENTLIST_UP, - "scroll element list up" + "scroll element list up ('Page Up')" }, { ED_ELEMENTLIST_DOWN_XPOS, ED_ELEMENTLIST_DOWN_ALT_YPOS, ED_ELEMENTLIST_DOWN_XPOS, ED_ELEMENTLIST_DOWN_YPOS, GADGET_ID_ELEMENTLIST_DOWN, - "scroll element list down" + "scroll element list down ('Page Down')" } }; @@ -490,18 +541,77 @@ static struct GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_VERTICAL, "scroll level editing area vertically" + } +}; + +/* values for random placement */ +#define RANDOM_USE_PERCENTAGE 0 +#define RANDOM_USE_QUANTITY 1 + +static int random_placement_value = 10; +static int random_placement_method = RANDOM_USE_QUANTITY; +static int random_placement_background_element = EL_ERDREICH; +static boolean random_placement_background_restricted = FALSE; +static boolean stick_element_properties_window = FALSE; + +static struct +{ + int x, y; + int gadget_id; + int radio_button_nr; + int *value; + int checked_value; + char *text, *infotext; +} radiobutton_info[ED_NUM_RADIOBUTTONS] = +{ + { + ED_SETTINGS_XPOS + 160, ED_COUNTER2_YPOS(8), + GADGET_ID_RANDOM_PERCENTAGE, + RADIO_NR_RANDOM_ELEMENTS, + &random_placement_method, RANDOM_USE_PERCENTAGE, + "percentage", "use percentage for random elements" + }, + { + ED_SETTINGS_XPOS + 340, ED_COUNTER2_YPOS(8), + GADGET_ID_RANDOM_QUANTITY, + RADIO_NR_RANDOM_ELEMENTS, + &random_placement_method, RANDOM_USE_QUANTITY, + "quantity", "use quantity for random elements" + } +}; + +static struct +{ + int x, y; + int gadget_id; + boolean *value; + char *text, *infotext; +} checkbutton_info[ED_NUM_CHECKBUTTONS] = +{ + { + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(6) - MINI_TILEY, + GADGET_ID_DOUBLE_SPEED, + &level.double_speed, + "double speed movement", "set movement speed of player" }, + { + ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(9) - MINI_TILEY, + GADGET_ID_RANDOM_RESTRICTED, + &random_placement_background_restricted, + "restrict random placement to", "set random placement restriction" + }, + { + ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4), + GADGET_ID_STICK_ELEMENT, + &stick_element_properties_window, + "stick window to edit content", "stick window to edit content" + } }; /* maximal size of level editor drawing area */ #define MAX_ED_FIELDX (2 * SCR_FIELDX) #define MAX_ED_FIELDY (2 * SCR_FIELDY - 1) -/* -#define ED_FIELDX (2 * SCR_FIELDX - 1) -#define ED_FIELDY (2 * SCR_FIELDY - 2) -*/ - /* actual size of level editor drawing area */ static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1; @@ -510,6 +620,15 @@ static int level_xpos = -1, level_ypos = -1; #define IN_ED_FIELD(x,y) ((x)>=0 && (x)=0 &&(y)'), + EL_CHAR('?'), + + EL_CHAR('@'), + EL_CHAR('A'), + EL_CHAR('B'), + EL_CHAR('C'), + + EL_CHAR('D'), + EL_CHAR('E'), + EL_CHAR('F'), + EL_CHAR('G'), - EL_CHAR_APOSTR, - EL_CHAR_KLAMM1, - EL_CHAR_KLAMM2, - EL_CHAR_PLUS, + EL_CHAR('H'), + EL_CHAR('I'), + EL_CHAR('J'), + EL_CHAR('K'), - EL_CHAR_KOMMA, - EL_CHAR_MINUS, - EL_CHAR_PUNKT, - EL_CHAR_SLASH, - - EL_CHAR_0 + 0, - EL_CHAR_0 + 1, - EL_CHAR_0 + 2, - EL_CHAR_0 + 3, - - EL_CHAR_0 + 4, - EL_CHAR_0 + 5, - EL_CHAR_0 + 6, - EL_CHAR_0 + 7, - - EL_CHAR_0 + 8, - EL_CHAR_0 + 9, - EL_CHAR_DOPPEL, - EL_CHAR_SEMIKL, - - EL_CHAR_LT, - EL_CHAR_GLEICH, - EL_CHAR_GT, - EL_CHAR_FRAGE, - - EL_CHAR_AT, - EL_CHAR_A + 0, - EL_CHAR_A + 1, - EL_CHAR_A + 2, - - EL_CHAR_A + 3, - EL_CHAR_A + 4, - EL_CHAR_A + 5, - EL_CHAR_A + 6, - - EL_CHAR_A + 7, - EL_CHAR_A + 8, - EL_CHAR_A + 9, - EL_CHAR_A + 10, - - EL_CHAR_A + 11, - EL_CHAR_A + 12, - EL_CHAR_A + 13, - EL_CHAR_A + 14, - - EL_CHAR_A + 15, - EL_CHAR_A + 16, - EL_CHAR_A + 17, - EL_CHAR_A + 18, - - EL_CHAR_A + 19, - EL_CHAR_A + 20, - EL_CHAR_A + 21, - EL_CHAR_A + 22, - - EL_CHAR_A + 23, - EL_CHAR_A + 24, - EL_CHAR_A + 25, - EL_CHAR_AE, - - EL_CHAR_OE, - EL_CHAR_UE, - EL_CHAR_COPY, - EL_LEERRAUM + EL_CHAR('L'), + EL_CHAR('M'), + EL_CHAR('N'), + EL_CHAR('O'), + + EL_CHAR('P'), + EL_CHAR('Q'), + EL_CHAR('R'), + EL_CHAR('S'), + + EL_CHAR('T'), + EL_CHAR('U'), + EL_CHAR('V'), + EL_CHAR('W'), + + EL_CHAR('X'), + EL_CHAR('Y'), + EL_CHAR('Z'), + EL_CHAR('Ä'), + + EL_CHAR('Ö'), + EL_CHAR('Ü'), + EL_CHAR('^'), + EL_CHAR(' ') }; int elements_in_list = sizeof(editor_element)/sizeof(int); @@ -977,14 +1090,14 @@ static void CreateControlButtons() id == GADGET_ID_PICK_ELEMENT) { button_type = GD_TYPE_RADIO_BUTTON; - radio_button_nr = 1; + radio_button_nr = RADIO_NR_DRAWING_TOOLBOX; checked = (id == drawing_function ? TRUE : FALSE); event_mask = GD_EVENT_PRESSED; } else { button_type = GD_TYPE_NORMAL_BUTTON; - radio_button_nr = 0; + radio_button_nr = RADIO_NR_NONE; checked = FALSE; if (id == GADGET_ID_WRAP_LEFT || @@ -1128,7 +1241,7 @@ static void CreateControlButtons() deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_INFO_TEXT, "choose element", + GDI_INFO_TEXT, element_info[editor_element[i]], GDI_X, DX + gd_xoffset, GDI_Y, DY + gd_yoffset, GDI_WIDTH, ED_ELEMENTLIST_XSIZE, @@ -1292,7 +1405,7 @@ static void CreateDrawingAreas() level_editor_gadget[id] = gi; } - /* ... and one for the amoeba content */ + /* ... one for the amoeba content */ id = GADGET_ID_AMOEBA_CONTENT; gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_X, SX + ED_AREA_ELEM_CONTENT_XPOS, @@ -1310,6 +1423,26 @@ static void CreateDrawingAreas() Error(ERR_EXIT, "cannot create gadget"); level_editor_gadget[id] = gi; + + /* ... and one for random placement background restrictions */ + + id = GADGET_ID_RANDOM_BACKGROUND; + gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS, + GDI_Y, SY + ED_AREA_RANDOM_BACKGROUND_YPOS, + GDI_WIDTH, MINI_TILEX, + GDI_HEIGHT, MINI_TILEY, + GDI_TYPE, GD_TYPE_DRAWING_AREA, + GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY, + GDI_EVENT_MASK, event_mask, + GDI_CALLBACK_INFO, HandleDrawingAreaInfo, + GDI_CALLBACK_ACTION, HandleDrawingAreas, + GDI_END); + + if (gi == NULL) + Error(ERR_EXIT, "cannot create gadget"); + + level_editor_gadget[id] = gi; } static void CreateTextInputGadgets() @@ -1323,7 +1456,7 @@ static void CreateTextInputGadgets() struct GadgetInfo *gi; unsigned long event_mask; char infotext[1024]; - int id = GADGET_ID_LEVEL_NAME + i; + int id = textinput_info[i].gadget_id; event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; @@ -1339,7 +1472,7 @@ static void CreateTextInputGadgets() GDI_Y, SY + textinput_info[i].y, GDI_TYPE, GD_TYPE_TEXTINPUT_ALPHANUMERIC, GDI_TEXT_VALUE, textinput_info[i].value, - GDI_TEXT_SIZE, 30, + GDI_TEXT_SIZE, textinput_info[i].size, GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x, gd_y, GDI_DESIGN_PRESSED, gd_pixmap, gd_x, gd_y, GDI_DESIGN_BORDER, ED_BORDER_SIZE, @@ -1412,6 +1545,85 @@ static void CreateScrollbarGadgets() } } +static void CreateCheckbuttonGadgets() +{ + Pixmap gd_pixmap = pix[PIX_DOOR]; + struct GadgetInfo *gi; + unsigned long event_mask; + int gd_x1, gd_x2, gd_x3, gd_x4, gd_y; + boolean checked; + 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_CHECKBUTTON_YPOS; + + for (i=0; i= 'a' && letter <= 'z') @@ -2687,7 +2848,7 @@ static void DrawLevelText(int sx, int sy, char letter, int mode) if (mode != TEXT_INIT) { if (!typing) - return; + return FALSE; if (mode != TEXT_SETCURSOR) { @@ -2737,7 +2898,7 @@ static void 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, new_element3); + DrawMiniElement(sx - 1, sy, Feld[lx - 1][ly]); DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR); } break; @@ -2755,9 +2916,14 @@ static void DrawLevelText(int sx, int sy, char letter, int mode) typing = FALSE; break; + case TEXT_QUERY_TYPING: + break; + default: break; } + + return typing; } static void SetTextCursor(int unused_sx, int unused_sy, int sx, int sy, @@ -2776,6 +2942,7 @@ static void CopyLevelToUndoBuffer(int mode) { static boolean accumulated_undo = FALSE; boolean new_undo_buffer_position = TRUE; + int last_border_element; int x, y; switch (mode) @@ -2806,6 +2973,13 @@ static void CopyLevelToUndoBuffer(int mode) for(x=0; x= num_free_positions) { - for(x=0; x 0) { - int elements_left = random_placement_num_objects; + x = RND(lev_fieldx); + y = RND(lev_fieldy); - while (elements_left > 0) + /* don't place element at the same position twice */ + if (free_position[x][y]) { - x = RND(lev_fieldx); - y = RND(lev_fieldy); - - if (Feld[x][y] != new_element) - { - Feld[x][y] = new_element; - elements_left--; - } + free_position[x][y] = FALSE; + Feld[x][y] = new_element; + num_elements--; } } @@ -2877,12 +3069,13 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) boolean button_release_event; boolean inside_drawing_area = !gi->event.off_borders; boolean draw_level = (id == GADGET_ID_DRAWING_LEVEL); - int new_element; + int actual_drawing_function; int button = gi->event.button; + int new_element = BUTTON_ELEMENT(button); int sx = gi->event.x, sy = gi->event.y; int min_sx = 0, min_sy = 0; int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1; - int lx, ly; + int lx = 0, ly = 0; int min_lx = 0, min_ly = 0; int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; int x, y; @@ -2929,21 +3122,22 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!button && !button_release_event) return; - new_element = (button == 1 ? new_element1 : - button == 2 ? new_element2 : - button == 3 ? new_element3 : 0); - #if 0 if (button_release_event) button = 0; #endif - +#if 0 if (!draw_level && drawing_function != GADGET_ID_SINGLE_ITEMS) return; +#endif + + /* automatically switch to 'single item' drawing mode, if needed */ + actual_drawing_function = + (draw_level ? drawing_function : GADGET_ID_SINGLE_ITEMS); - switch (drawing_function) + switch (actual_drawing_function) { case GADGET_ID_SINGLE_ITEMS: if (draw_level) @@ -3003,6 +3197,8 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (id == GADGET_ID_AMOEBA_CONTENT) level.amoebe_inhalt = new_element; + else if (id == GADGET_ID_RANDOM_BACKGROUND) + random_placement_background_element = new_element; else if (id >= GADGET_ID_ELEM_CONTENT_0 && id <= GADGET_ID_ELEM_CONTENT_7) level.mampfer_inhalt[id - GADGET_ID_ELEM_CONTENT_0][sx][sy] = @@ -3071,7 +3267,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { CopyAreaToBrush(start_sx, start_sy, sx, sy, button); CopyBrushToCursor(sx, sy); - ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS]); + ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],MB_LEFT); draw_with_brush = TRUE; } else if (drawing_function == GADGET_ID_TEXT) @@ -3099,10 +3295,17 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) break; case GADGET_ID_PICK_ELEMENT: + + /* if (button_press_event) PickDrawingElement(button, Feld[lx][ly]); + */ + if (button_release_event) - ClickOnGadget(level_editor_gadget[last_drawing_function]); + ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFT); + else + PickDrawingElement(button, Feld[lx][ly]); + break; default: @@ -3233,15 +3436,11 @@ static void HandleControlButtons(struct GadgetInfo *gi) int id = gi->custom_id; int button = gi->event.button; int step = (button == 1 ? 1 : button == 2 ? 5 : 10); - int new_element; + int new_element = BUTTON_ELEMENT(button); int player_present = FALSE; int level_changed = FALSE; int i, x, y; - new_element = (button == 1 ? new_element1 : - button == 2 ? new_element2 : - button == 3 ? new_element3 : 0); - if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT) DrawLevelText(0, 0, 0, TEXT_END); @@ -3362,11 +3561,12 @@ static void HandleControlButtons(struct GadgetInfo *gi) { int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - struct GadgetDesign *design = &gi->deco.design; + struct GadgetDesign *gd = &gi->deco.design; + int element = editor_element[element_shift + i]; UnmapGadget(gi); - getMiniGraphicSource(el2gfx(editor_element[element_shift + i]), - &design->pixmap, &design->x, &design->y); + getMiniGraphicSource(el2gfx(element), &gd->pixmap, &gd->x, &gd->y); + ModifyGadget(gi, GDI_INFO_TEXT, element_info[element], GDI_END); MapGadget(gi); } break; @@ -3403,7 +3603,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_RANDOM_PLACEMENT: - RandomPlacement(button); + RandomPlacement(new_element); break; case GADGET_ID_PROPERTIES: @@ -3453,7 +3653,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) case GADGET_ID_CLEAR: for(x=0; x= GADGET_ID_ELEMENTLIST_FIRST && id <= GADGET_ID_ELEMENTLIST_LAST) @@ -3586,22 +3808,26 @@ static void HandleControlButtons(struct GadgetInfo *gi) PickDrawingElement(button, new_element); - if (!HAS_CONTENT(properties_element)) + if (!HAS_CONTENT(properties_element) || + !stick_element_properties_window) { properties_element = new_element; if (edit_mode == ED_MODE_PROPERTIES) DrawPropertiesWindow(); } + + if (drawing_function == GADGET_ID_PICK_ELEMENT) + ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFT); } #ifdef DEBUG else if (gi->event.type == GD_EVENT_PRESSED) - printf("default: HandleControlButtons: GD_EVENT_PRESSED\n"); + printf("default: HandleControlButtons: GD_EVENT_PRESSED(%d)\n", id); else if (gi->event.type == GD_EVENT_RELEASED) - printf("default: HandleControlButtons: GD_EVENT_RELEASED\n"); + printf("default: HandleControlButtons: GD_EVENT_RELEASED(%d)\n", id); else if (gi->event.type == GD_EVENT_MOVING) - printf("default: HandleControlButtons: GD_EVENT_MOVING\n"); + printf("default: HandleControlButtons: GD_EVENT_MOVING(%d)\n", id); else - printf("default: HandleControlButtons: ?\n"); + printf("default: HandleControlButtons: ? (id == %d)\n", id); #endif break; } @@ -3609,52 +3835,60 @@ static void HandleControlButtons(struct GadgetInfo *gi) void HandleLevelEditorKeyInput(KeySym key) { - if (edit_mode == ED_MODE_DRAWING) + char letter = getCharFromKeySym(key); + int button = MB_LEFT; + + if (drawing_function == GADGET_ID_TEXT && + DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE) { - char letter = getCharFromKeySym(key); + if (letter) + DrawLevelText(0, 0, letter, TEXT_WRITECHAR); + else if (key == XK_Delete || key == XK_BackSpace) + DrawLevelText(0, 0, 0, TEXT_BACKSPACE); + else if (key == XK_Return) + DrawLevelText(0, 0, 0, TEXT_NEWLINE); + } + else if (button_status == MB_RELEASED) + { + int i, id; - if (drawing_function == GADGET_ID_TEXT) - { - if (letter) - DrawLevelText(0, 0, letter, TEXT_WRITECHAR); - else if (key == XK_Delete || key == XK_BackSpace) - DrawLevelText(0, 0, 0, TEXT_BACKSPACE); - else if (key == XK_Return) - DrawLevelText(0, 0, 0, TEXT_NEWLINE); - } - else if (button_status == MB_RELEASED) + switch (key) { - int i, id; - - switch (key) - { - case XK_Left: - id = GADGET_ID_SCROLL_LEFT; - break; - case XK_Right: - id = GADGET_ID_SCROLL_RIGHT; - break; - case XK_Up: - id = GADGET_ID_SCROLL_UP; - break; - case XK_Down: - id = GADGET_ID_SCROLL_DOWN; - break; - - default: - id = GADGET_ID_NONE; - break; - } + case XK_Left: + id = GADGET_ID_SCROLL_LEFT; + break; + case XK_Right: + id = GADGET_ID_SCROLL_RIGHT; + break; + case XK_Up: + id = GADGET_ID_SCROLL_UP; + break; + case XK_Down: + id = GADGET_ID_SCROLL_DOWN; + break; + case XK_Page_Up: + id = GADGET_ID_ELEMENTLIST_UP; + button = 3; + break; + case XK_Page_Down: + id = GADGET_ID_ELEMENTLIST_DOWN; + button = 3; + break; - if (id != GADGET_ID_NONE) - ClickOnGadget(level_editor_gadget[id]); - else if (letter == '.') - ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS]); - else - for (i=0; ievent.y; int lx = sx + level_xpos; int ly = sy + level_ypos; + int min_sx = 0, min_sy = 0; + int max_sx = gi->drawing.area_xsize - 1; + int max_sy = gi->drawing.area_ysize - 1; ClearEditorGadgetInfoText(); + /* make sure to stay inside drawing area boundaries */ + sx = (sx < min_sx ? min_sx : sx > max_sx ? max_sx : sx); + sy = (sy < min_sy ? min_sy : sy > max_sy ? max_sy : sy); + if (id == GADGET_ID_DRAWING_LEVEL) { if (button_status) { - int min_sx = 0, min_sy = 0; - int max_sx = gi->drawing.area_xsize - 1; - int max_sy = gi->drawing.area_ysize - 1; int min_lx = 0, min_ly = 0; int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; - /* make sure to stay inside drawing area boundaries */ - sx = (sx < min_sx ? min_sx : sx > max_sx ? max_sx : sx); - sy = (sy < min_sy ? min_sy : sy > max_sy ? max_sy : sy); - /* get positions inside level field */ lx = sx + level_xpos; ly = sy + level_ypos; @@ -3789,11 +4023,17 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) break; } - DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, - "%s: %d, %d", infotext, - ABS(lx - start_lx) + 1, - ABS(ly - start_ly) + 1); + if (drawing_function == GADGET_ID_PICK_ELEMENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, + "%s: %d, %d", infotext, lx, ly); + else + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, + "%s: %d, %d", infotext, + ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); } + else if (drawing_function == GADGET_ID_PICK_ELEMENT) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, + "%s", element_info[Feld[lx][ly]]); else DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, "Level position: %d, %d", lx, ly); @@ -3811,8 +4051,11 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) else if (id == GADGET_ID_AMOEBA_CONTENT) DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, "Amoeba content"); + else if (id == GADGET_ID_RANDOM_BACKGROUND) + DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, + "Random placement background"); else DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW, - "Cruncher %d content: %d, %d", + "Content area %d position: %d, %d", id - GADGET_ID_ELEM_CONTENT_0 + 1, sx, sy); }