X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=c0fc04466e000ece5d8a5de2f9a75314f08214c7;hb=a1658d14b0ff3ddb46cc075aba1dddf7d01c6442;hp=b32cbd82fbbcedf767faf2f4e9814063571d5cf8;hpb=d9479668b752772803e523561bc544a6c7efe725;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index b32cbd82..c0fc0446 100644 --- a/src/editor.c +++ b/src/editor.c @@ -459,6 +459,9 @@ enum GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_INVENTORY_SIZE_UP, + GADGET_ID_MM_BALL_CONTENT_DOWN, + GADGET_ID_MM_BALL_CONTENT_TEXT, + GADGET_ID_MM_BALL_CONTENT_UP, GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_CUSTOM_SCORE_UP, @@ -539,6 +542,7 @@ enum GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_INVENTORY_CONTENT, + GADGET_ID_MM_BALL_CONTENT, GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_CONTENT, GADGET_ID_CUSTOM_MOVE_ENTER, @@ -570,6 +574,7 @@ enum GADGET_ID_LEVELSET_SAVE_MODE, GADGET_ID_WIND_DIRECTION, GADGET_ID_PLAYER_SPEED, + GADGET_ID_MM_BALL_CHOICE_MODE, GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_CUSTOM_DEADLINESS, @@ -682,6 +687,7 @@ enum GADGET_ID_DF_LASER_RED, GADGET_ID_DF_LASER_GREEN, GADGET_ID_DF_LASER_BLUE, + GADGET_ID_ROTATE_MM_BALL_CONTENT, GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_CUSTOM_EXPLODE_FIRE, @@ -750,6 +756,7 @@ enum ED_COUNTER_ID_ENVELOPE_XSIZE, ED_COUNTER_ID_ENVELOPE_YSIZE, ED_COUNTER_ID_INVENTORY_SIZE, + ED_COUNTER_ID_MM_BALL_CONTENT, ED_COUNTER_ID_CUSTOM_SCORE, ED_COUNTER_ID_CUSTOM_GEMCOUNT, ED_COUNTER_ID_CUSTOM_VALUE_FIX, @@ -856,6 +863,7 @@ enum ED_SELECTBOX_ID_LEVELSET_SAVE_MODE, ED_SELECTBOX_ID_WIND_DIRECTION, ED_SELECTBOX_ID_PLAYER_SPEED, + ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE, ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE, ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER, ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED, @@ -993,6 +1001,7 @@ enum ED_CHECKBUTTON_ID_DF_LASER_RED, ED_CHECKBUTTON_ID_DF_LASER_GREEN, ED_CHECKBUTTON_ID_DF_LASER_BLUE, + ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT, ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC, ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1, ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE, @@ -1079,6 +1088,7 @@ enum ED_DRAWING_ID_ARTWORK_ELEMENT, ED_DRAWING_ID_EXPLOSION_ELEMENT, ED_DRAWING_ID_INVENTORY_CONTENT, + ED_DRAWING_ID_MM_BALL_CONTENT, ED_DRAWING_ID_CUSTOM_GRAPHIC, ED_DRAWING_ID_CUSTOM_CONTENT, ED_DRAWING_ID_CUSTOM_MOVE_ENTER, @@ -1533,6 +1543,14 @@ static struct &level.initial_inventory_size[0], NULL, NULL, "number of inventory elements" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_ELEMENTS_IN_GROUP, MAX_MM_BALL_CONTENTS, + GADGET_ID_MM_BALL_CONTENT_DOWN, GADGET_ID_MM_BALL_CONTENT_UP, + GADGET_ID_MM_BALL_CONTENT_TEXT, GADGET_ID_NONE, + &level.num_mm_ball_contents, + NULL, NULL, "number of content elements" + }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -1743,7 +1761,7 @@ static struct int gadget_id; int xsize, ysize; char *value; - char *text_above, *infotext; + char *text_above, *text_above_cropped, *infotext; } textarea_info[ED_NUM_TEXTAREAS] = { { @@ -1751,7 +1769,7 @@ static struct GADGET_ID_ENVELOPE_INFO, MAX_ENVELOPE_XSIZE, MAX_ENVELOPE_YSIZE, NULL, - "Envelope Content:", "Envelope Content" + "Envelope Content:", "Envelope Content (cropped):", "Envelope Content" } }; @@ -2079,38 +2097,38 @@ static struct ValueTextInfo options_change_trigger_player[] = static struct ValueTextInfo options_change_trigger_page[] = { - { (1 << 0), "1" }, - { (1 << 1), "2" }, - { (1 << 2), "3" }, - { (1 << 3), "4" }, - { (1 << 4), "5" }, - { (1 << 5), "6" }, - { (1 << 6), "7" }, - { (1 << 7), "8" }, - { (1 << 8), "9" }, - { (1 << 9), "10" }, - { (1 << 10), "11" }, - { (1 << 11), "12" }, - { (1 << 12), "13" }, - { (1 << 13), "14" }, - { (1 << 14), "15" }, - { (1 << 15), "16" }, - { (1 << 16), "17" }, - { (1 << 17), "18" }, - { (1 << 18), "19" }, - { (1 << 19), "20" }, - { (1 << 20), "21" }, - { (1 << 21), "22" }, - { (1 << 22), "23" }, - { (1 << 23), "24" }, - { (1 << 24), "25" }, - { (1 << 25), "26" }, - { (1 << 26), "27" }, - { (1 << 27), "28" }, - { (1 << 28), "29" }, - { (1 << 29), "30" }, - { (1 << 30), "31" }, - { (1 << 31), "32" }, + { (1u << 0), "1" }, + { (1u << 1), "2" }, + { (1u << 2), "3" }, + { (1u << 3), "4" }, + { (1u << 4), "5" }, + { (1u << 5), "6" }, + { (1u << 6), "7" }, + { (1u << 7), "8" }, + { (1u << 8), "9" }, + { (1u << 9), "10" }, + { (1u << 10), "11" }, + { (1u << 11), "12" }, + { (1u << 12), "13" }, + { (1u << 13), "14" }, + { (1u << 14), "15" }, + { (1u << 15), "16" }, + { (1u << 16), "17" }, + { (1u << 17), "18" }, + { (1u << 18), "19" }, + { (1u << 19), "20" }, + { (1u << 20), "21" }, + { (1u << 21), "22" }, + { (1u << 22), "23" }, + { (1u << 23), "24" }, + { (1u << 24), "25" }, + { (1u << 25), "26" }, + { (1u << 26), "27" }, + { (1u << 27), "28" }, + { (1u << 28), "29" }, + { (1u << 29), "30" }, + { (1u << 30), "31" }, + { (1u << 31), "32" }, { CH_PAGE_ANY, "any" }, { -1, NULL } @@ -2555,6 +2573,14 @@ static struct &level.initial_player_stepsize[0], NULL, "initial player speed:", NULL, "initial player speed" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_MM_BALL_CHOICE_MODE, GADGET_ID_NONE, + -1, + options_group_choice_mode, + &level.mm_ball_choice_mode, + NULL, "choice type:", NULL, "type of content choice" + }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -3354,6 +3380,13 @@ static struct NULL, NULL, "blue", "use blue color components in laser" }, + { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_ROTATE_MM_BALL_CONTENT, GADGET_ID_NONE, + &level.rotate_mm_ball_content, + NULL, NULL, + "randomly rotate created content", "randomly rotate newly created content" + }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -3740,6 +3773,16 @@ static struct NULL, NULL, NULL, NULL, "content for initial inventory" }, + // ---------- gray ball content ----------------------------------------- + + { + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_MM_BALL_CONTENT, GADGET_ID_NONE, + &level.mm_ball_content[0], MAX_MM_BALL_CONTENTS, 1, + "content:", NULL, NULL, NULL, "content for gray ball" + }, + // ---------- element settings: configure 1 (custom elements) --------------- // ---------- custom graphic ------------------------------------------------ @@ -4610,7 +4653,12 @@ static int editor_el_mirror_magic[] = EL_MM_WOODEN_GRID_FIXED_1, EL_MM_WOODEN_GRID_FIXED_2, EL_MM_WOODEN_GRID_FIXED_3, - EL_MM_WOODEN_GRID_FIXED_4 + EL_MM_WOODEN_GRID_FIXED_4, + + EL_MM_ENVELOPE_1, + EL_MM_ENVELOPE_2, + EL_MM_ENVELOPE_3, + EL_MM_ENVELOPE_4 }; static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic; static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic; @@ -5557,6 +5605,14 @@ editor_elements_info[] = } }; +static struct XY xy_directions[] = +{ + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } +}; + // ---------------------------------------------------------------------------- // functions @@ -5610,7 +5666,7 @@ static char *getElementInfoText(int element) static char *getElementDescriptionFilenameExt(char *basename) { - char *elements_subdir = "elements"; + char *elements_subdir = ELEMENTS_DIRECTORY; static char *elements_subdir2 = NULL; static char *filename = NULL; @@ -5651,6 +5707,11 @@ static char *getElementDescriptionFilename(int element) if (filename != NULL) return filename; + // 3rd try: look for generic fallback text file for any element + filename = getElementDescriptionFilenameExt(FALLBACK_TEXT_FILENAME); + if (filename != NULL) + return filename; + return NULL; } @@ -5879,10 +5940,10 @@ static void ReinitializeElementList(void) // determine size of element list for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { - boolean found_inactive_cascade = FALSE; - if (*editor_elements_info[i].setup_value) { + boolean found_inactive_cascade = FALSE; + if (setup.editor.el_headlines) { // required for correct padding of palette headline buttons @@ -6489,11 +6550,9 @@ static void CreateCounterButtons(void) int graphic; struct GraphicInfo *gd; int gd_x1, gd_x2, gd_y1, gd_y2; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; char infotext[max_infotext_len + 1]; - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; - if (i == ED_COUNTER_ID_SELECT_LEVEL) { graphic = (j == 0 ? @@ -6633,7 +6692,6 @@ static void CreateDrawingAreas(void) for (i = 0; i < ED_NUM_DRAWING_AREAS; i++) { struct GadgetInfo *gi; - unsigned int event_mask; int id = drawingarea_info[i].gadget_id; int x = SX + ED_AREA_SETTINGS_X(drawingarea_info[i]); int y = SY + ED_AREA_SETTINGS_Y(drawingarea_info[i]); @@ -6641,8 +6699,7 @@ static void CreateDrawingAreas(void) int area_ysize = drawingarea_info[i].area_ysize; int item_size = (id == GADGET_ID_DRAWING_LEVEL ? ed_tilesize : ED_DRAWINGAREA_TILE_SIZE); - - event_mask = + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS | GD_EVENT_PIXEL_PRECISE; @@ -6689,7 +6746,7 @@ static void CreateTextInputGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textinput_info[i].gadget_id; int x, y; @@ -6716,8 +6773,6 @@ static void CreateTextInputGadgets(void) y = ED_SETTINGS_Y(textinput_info[i].y); } - event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; - sprintf(infotext, "Enter %s", textinput_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6760,14 +6815,12 @@ static void CreateTextAreaGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textarea_info[i].gadget_id; int area_xsize = textarea_info[i].xsize; int area_ysize = textarea_info[i].ysize; - event_mask = GD_EVENT_TEXT_LEAVING; - sprintf(infotext, "Enter %s", textarea_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6811,11 +6864,12 @@ static void CreateSelectboxGadgets(void) int gd_y2 = gd->src_y + gd->active_yoffset; int selectbox_button_xsize = gd2->width; struct GadgetInfo *gi; - unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = selectbox_info[i].gadget_id; int x = SX + ED_SETTINGS_X(selectbox_info[i].x); int y = SY + ED_SETTINGS_Y(selectbox_info[i].y); + unsigned int event_mask = + GD_EVENT_RELEASED | GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; if (selectbox_info[i].size == -1) // dynamically determine size { @@ -6831,9 +6885,6 @@ static void CreateSelectboxGadgets(void) selectbox_info[i].size++; // add one character empty space } - event_mask = GD_EVENT_RELEASED | - GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; - // 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] + @@ -6902,7 +6953,7 @@ static void CreateTextbuttonGadgets(void) int border_xsize = gd->border_size + gd->draw_xoffset; int border_ysize = gd->border_size; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_RELEASED; char infotext[MAX_OUTPUT_LINESIZE + 1]; int x = SX + ED_SETTINGS_X(textbutton_info[i].x); int y = SY + ED_SETTINGS_Y(textbutton_info[i].y); @@ -6910,8 +6961,6 @@ static void CreateTextbuttonGadgets(void) if (textbutton_info[i].size == -1) // dynamically determine size textbutton_info[i].size = strlen(textbutton_info[i].text); - event_mask = GD_EVENT_RELEASED; - sprintf(infotext, "%s", textbutton_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6964,7 +7013,6 @@ static void CreateTextbuttonGadgets(void) static void CreateGraphicbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; // create buttons for scrolling of drawing area and element list @@ -6979,8 +7027,7 @@ static void CreateGraphicbuttonGadgets(void) 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; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; // determine horizontal position to the right of specified gadget if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7072,7 +7119,7 @@ static void CreateScrollbarGadgets(void) int gd_y2 = gd->src_y + gd->pressed_yoffset; struct GadgetInfo *gi; int items_max, items_visible, item_position; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; if (i == ED_SCROLLBAR_ID_LIST_VERTICAL) { @@ -7096,8 +7143,6 @@ static void CreateScrollbarGadgets(void) } } - event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; - gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_IMAGE_ID, graphic, @@ -7133,11 +7178,8 @@ static void CreateScrollbarGadgets(void) static void CreateCheckbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_CHECKBUTTONS; i++) { int id = checkbutton_info[i].gadget_id; @@ -7154,6 +7196,7 @@ static void CreateCheckbuttonGadgets(void) 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); + unsigned int event_mask = GD_EVENT_PRESSED; // determine horizontal position to the right of specified gadget if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7205,16 +7248,14 @@ static void CreateRadiobuttonGadgets(void) 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 int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_RADIOBUTTONS; i++) { int id = radiobutton_info[i].gadget_id; int x = SX + ED_SETTINGS_X(radiobutton_info[i].x); int y = SY + ED_SETTINGS_Y(radiobutton_info[i].y); + unsigned int event_mask = GD_EVENT_PRESSED; int checked = (*radiobutton_info[i].value == radiobutton_info[i].checked_value); @@ -7283,6 +7324,8 @@ void CreateLevelEditorGadgets(void) use_permanent_palette = !editor.palette.show_as_separate_screen; + InitGadgetScreenBorders(-1, INFOTEXT_YPOS); + ReinitializeElementList(); CreateControlButtons(); @@ -7475,9 +7518,13 @@ static void MapTextAreaGadget(int id) 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; + char *text_above = textarea_info[id].text_above; + + if (gi->textarea.cropped && textarea_info[id].text_above_cropped) + text_above = textarea_info[id].text_above_cropped; - if (textarea_info[id].text_above) - DrawTextS(x_above, y_above, font_nr, textarea_info[id].text_above); + if (text_above) + DrawTextS(x_above, y_above, font_nr, text_above); ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END); @@ -8314,6 +8361,11 @@ static void CopyGroupElementPropertiesToEditor(int element) custom_element = element_info[element]; // needed for description } +static void CopyEmptyElementPropertiesToEditor(int element) +{ + custom_element = element_info[element]; +} + static void CopyClassicElementPropertiesToEditor(int element) { if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) @@ -8331,6 +8383,8 @@ static void CopyElementPropertiesToEditor(int element) CopyCustomElementPropertiesToEditor(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToEditor(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToEditor(element); else CopyClassicElementPropertiesToEditor(element); } @@ -8503,6 +8557,21 @@ static void CopyGroupElementPropertiesToGame(int element) InitElementPropertiesGfxElement(); } +static void CopyEmptyElementPropertiesToGame(int element) +{ + // mark that this empty element has been modified + custom_element.modified_settings = TRUE; + level.changed = TRUE; + + if (level.use_custom_template) + AskToCopyAndModifyLevelTemplate(); + + element_info[element] = custom_element; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); +} + static void CopyClassicElementPropertiesToGame(int element) { if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) @@ -8520,6 +8589,8 @@ static void CopyElementPropertiesToGame(int element) CopyCustomElementPropertiesToGame(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToGame(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToGame(element); else CopyClassicElementPropertiesToGame(element); } @@ -9475,7 +9546,7 @@ static void DrawMagicBallContentAreas(void) DrawText(x, y + 2 * tilesize, "active", font_nr); } -static void DrawAndroidElementArea(int element) +static void DrawAndroidElementArea(void) { int id = ED_DRAWING_ID_ANDROID_CONTENT; int num_elements = level.num_android_clone_elements; @@ -9503,7 +9574,7 @@ static void DrawAndroidElementArea(int element) MapDrawingArea(id); } -static void DrawGroupElementArea(int element) +static void DrawGroupElementArea(void) { int id = ED_DRAWING_ID_GROUP_CONTENT; int num_elements = group_element_info.num_elements; @@ -9560,13 +9631,40 @@ static void DrawPlayerInitialInventoryArea(int element) MapDrawingArea(id); } +static void DrawMMBallContentArea(void) +{ + int id = ED_DRAWING_ID_MM_BALL_CONTENT; + int num_elements = level.num_mm_ball_contents; + 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_MM_BALL_CONTENTS; + int ysize = 1; + + if (drawingarea_info[id].text_left != NULL) + sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left); + + UnmapDrawingArea(id); + + ModifyEditorDrawingArea(id, num_elements, 1); + + // delete content areas in case of reducing number of them + DrawBackground(sx, sy, + xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size, + ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size); + + MapDrawingArea(id); +} + static void DrawEnvelopeTextArea(int envelope_nr) { int id = ED_TEXTAREA_ID_ENVELOPE_INFO; struct GadgetInfo *gi = level_editor_gadget[textarea_info[id].gadget_id]; UnmapGadget(gi); - DrawBackground(gi->x, gi->y, gi->width, gi->height); + + DrawBackground(gi->x, gi->y, + gi->textarea.crop_width, gi->textarea.crop_height); if (envelope_nr != -1) textarea_info[id].value = level.envelope[envelope_nr].text; @@ -9883,8 +9981,10 @@ static boolean checkPropertiesConfig(int element) if (IS_GEM(element) || IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element) || + IS_EMPTY_ELEMENT(element) || IS_BALLOON_ELEMENT(element) || IS_ENVELOPE(element) || + IS_MM_ENVELOPE(element) || IS_MM_MCDUFFIN(element) || IS_DF_LASER(element) || IS_PLAYER_ELEMENT(element) || @@ -10041,7 +10141,15 @@ static void DrawPropertiesConfig(void) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE); } else if (properties_element == EL_EMC_ANDROID) - DrawAndroidElementArea(properties_element); + DrawAndroidElementArea(); + else if (properties_element == EL_MM_GRAY_BALL) + { + MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT); + MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT); + + DrawMMBallContentArea(); + } } if (IS_PLAYER_ELEMENT(properties_element)) @@ -10182,13 +10290,14 @@ static void DrawPropertiesConfig(void) if (IS_BALLOON_ELEMENT(properties_element)) MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION); - if (IS_ENVELOPE(properties_element)) + if (IS_ENVELOPE(properties_element) || + IS_MM_ENVELOPE(properties_element)) { int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE; int counter2_id = ED_COUNTER_ID_ENVELOPE_YSIZE; int button1_id = ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP; int button2_id = ED_CHECKBUTTON_ID_ENVELOPE_CENTERED; - int envelope_nr = properties_element - EL_ENVELOPE_1; + int envelope_nr = ENVELOPE_NR(properties_element); counterbutton_info[counter1_id].value = &level.envelope[envelope_nr].xsize; counterbutton_info[counter2_id].value = &level.envelope[envelope_nr].ysize; @@ -10296,7 +10405,7 @@ static void DrawPropertiesConfig(void) MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); // draw drawing area gadgets - DrawGroupElementArea(properties_element); + DrawGroupElementArea(); // draw text input gadgets MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME); @@ -10306,6 +10415,23 @@ static void DrawPropertiesConfig(void) draw_footer_line = TRUE; } + else if (IS_EMPTY_ELEMENT(properties_element)) + { + // draw stickybutton gadget + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); + + // draw checkbutton gadgets + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1); + + // draw textbutton gadgets + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); + + // 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) @@ -10396,12 +10522,12 @@ static void DrawEditorElementName(int x, int y, int font_nr) int font_height = getFontHeight(font_nr); 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]; if (strlen(element_name) <= max_chars_per_line) DrawTextS(x, y, font_nr, element_name); else { + char buffer[max_chars_per_line + 1]; int next_pos = max_chars_per_line; strncpy(buffer, element_name, max_chars_per_line); @@ -10788,13 +10914,7 @@ static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) static int getClosedTube(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromTube(element_old); int direction_new = MV_NONE; @@ -10802,8 +10922,8 @@ static int getClosedTube(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10818,13 +10938,7 @@ static int getClosedTube(int x, int y) static int getClosedBelt(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int nr = getBeltNrFromBeltElement(element_old); int direction_old = getOpenDirectionFromBelt(element_old); @@ -10833,8 +10947,8 @@ static int getClosedBelt(int x, int y) for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10849,13 +10963,7 @@ static int getClosedBelt(int x, int y) static int getClosedPool(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPool(element_old); int direction_new = MV_NONE; @@ -10863,8 +10971,8 @@ static int getClosedPool(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10880,13 +10988,7 @@ static int getClosedPool(int x, int y) static int getClosedPillar(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPillar(element_old); int direction_new = MV_NONE; @@ -10894,8 +10996,8 @@ static int getClosedPillar(int x, int y) for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10910,13 +11012,7 @@ static int getClosedPillar(int x, int y) static int getClosedSteel2(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromSteel2(element_old); int direction_new = MV_NONE; @@ -10924,8 +11020,8 @@ static int getClosedSteel2(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10940,13 +11036,7 @@ static int getClosedSteel2(int x, int y) static int getClosedChip(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromChip(element_old); int direction_new = MV_NONE; @@ -10954,8 +11044,8 @@ static int getClosedChip(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -11038,13 +11128,7 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, static void SetElementIntelliDraw(int x, int y, int new_element, boolean change_level, int button) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; static int last_x = -1; static int last_y = -1; @@ -11070,8 +11154,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_TUBE(IntelliDrawBuffer[last_x][last_y])) @@ -11108,8 +11192,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_BELT(IntelliDrawBuffer[last_x][last_y])) @@ -11146,8 +11230,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y])) @@ -11189,8 +11273,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y])) @@ -11226,8 +11310,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) @@ -11261,8 +11345,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) @@ -11322,8 +11406,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element)) @@ -12608,7 +12692,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) static int start_sx; static int last_sx, last_sy; static boolean typing = FALSE; - int letter_element = EL_CHAR_ASCII0 + letter; + int letter_element; int lx = 0, ly = 0; // map lower case letters to upper case and convert special characters @@ -12911,8 +12995,6 @@ static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; - static int last_sx = -1, last_sy = -1; - static int last_sx2 = -1, last_sy2 = -1; int id = gi->custom_id; int type_id = gi->custom_type_id; boolean button_press_event; @@ -12932,8 +13014,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int dx = sx2 % 2; int dy = sy2 % 2; 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; button_press_event = (gi->event.type == GD_EVENT_PRESSED); @@ -12945,6 +13025,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (draw_level) { + int min_lx = 0, min_ly = 0; + int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; + // get positions inside level field lx = sx + level_xpos; ly = sy + level_ypos; @@ -12973,15 +13056,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) sy2 = sy * 2 + dy; } - if (button_release_event) - { - last_sx = -1; - last_sy = -1; - last_sx2 = -1; - last_sy2 = -1; - } - else if (!button_press_event) + if (!button_press_event && !button_release_event) { + static int last_sx = -1; + static int last_sy = -1; + static int last_sx2 = -1; + static int last_sy2 = -1; int old_element = (IN_LEV_FIELD(lx, ly) ? Tile[lx][ly] : EL_UNDEFINED); boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM && isHiresTileElement(old_element) && @@ -12991,12 +13071,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if ((sx == last_sx && sy == last_sy && !hires_drawing) || (sx2 == last_sx2 && sy2 == last_sy2)) return; - } - last_sx = sx; - last_sy = sy; - last_sx2 = sx2; - last_sy2 = sy2; + last_sx = sx; + last_sy = sy; + last_sx2 = sx2; + last_sy2 = sy2; + } if (button_press_event) started_inside_drawing_area = inside_drawing_area; @@ -13007,9 +13087,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!IS_VALID_BUTTON(button)) return; - if (!button && !button_release_event) - return; - // handle info callback for each invocation of action callback gi->callback_info(gi); @@ -13045,10 +13122,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); - } - if (!button || button_release_event) break; + } if (draw_with_brush) { @@ -13133,22 +13209,19 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button_release_event) CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - if (button) - { - SetDrawModeHiRes(new_element); + SetDrawModeHiRes(new_element); - if (getDrawModeHiRes()) - { - sx = sx2; - sy = sy2; - } + if (getDrawModeHiRes()) + { + sx = sx2; + sy = sy2; + } - if (!button_press_event) - DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); + if (!button_press_event) + DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); - last_sx = sx; - last_sy = sy; - } + last_sx = sx; + last_sy = sy; } break; @@ -13331,11 +13404,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi) break; case ED_COUNTER_ID_ANDROID_CONTENT: - DrawAndroidElementArea(properties_element); + DrawAndroidElementArea(); break; case ED_COUNTER_ID_GROUP_CONTENT: - DrawGroupElementArea(properties_element); + DrawGroupElementArea(); CopyGroupElementPropertiesToGame(properties_element); break; @@ -13343,6 +13416,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) DrawPlayerInitialInventoryArea(properties_element); break; + case ED_COUNTER_ID_MM_BALL_CONTENT: + DrawMMBallContentArea(); + break; + case ED_COUNTER_ID_ENVELOPE_XSIZE: case ED_COUNTER_ID_ENVELOPE_YSIZE: DrawEnvelopeTextArea(-1); @@ -13698,9 +13775,11 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) boolean template_related_changes_found = FALSE; int i; - // check if any custom or group elements have been changed + // check if any custom, group or empty elements have been changed for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) && + if ((IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i)) && element_info[i].modified_settings) template_related_changes_found = TRUE; @@ -14235,7 +14314,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) id <= GADGET_ID_ELEMENTLIST_LAST) { int element_position = id - GADGET_ID_ELEMENTLIST_FIRST; - int new_element = editor_elements[element_position + element_shift]; + + new_element = editor_elements[element_position + element_shift]; if (IS_EDITOR_CASCADE(new_element)) { @@ -14475,11 +14555,12 @@ static void HandleLevelEditorIdle_Properties(void) 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; + static DelayCounter action_delay = { 0 }; int i; - if (!DelayReached(&action_delay, action_delay_value)) + action_delay.value = GameFrameDelay; + + if (!DelayReached(&action_delay)) return; for (i = 0; i < ED_NUM_SELECTBOX; i++) @@ -14528,7 +14609,6 @@ static void ClearEditorGadgetInfoText(void) void PrintEditorGadgetInfoText(struct GadgetInfo *gi) { char infotext[MAX_OUTPUT_LINESIZE + 1]; - char shortcut[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); if (gi == NULL || strlen(gi->info_text) == 0) @@ -14543,6 +14623,8 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) if (key) { + char shortcut[MAX_OUTPUT_LINESIZE + 1]; + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) sprintf(shortcut, " ('.' or '%c')", key); else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) @@ -14586,7 +14668,6 @@ void HandleEditorGadgetInfoText(void *ptr) static void HandleDrawingAreaInfo(struct GadgetInfo *gi) { - static int start_lx, start_ly; int id = gi->custom_id; int type_id = gi->custom_type_id; int sx = gi->event.x; @@ -14599,7 +14680,6 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) int actual_drawing_function = drawing_function; int max_infotext_len = getMaxInfoTextLength(); char infotext[MAX_OUTPUT_LINESIZE + 1]; - char *text; infotext[0] = '\0'; // start with empty info text @@ -14640,6 +14720,10 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) { if (button_status) // if (gi->state == GD_BUTTON_PRESSED) { + static int start_lx = 0; + static int start_ly = 0; + char *text; + if (gi->event.type == GD_EVENT_PRESSED) { start_lx = lx;