#define ED_COUNT_CHANGE_DELAY_XPOS (ED_SETTINGS_XPOS2 + 9 * MINI_TILEX)
+#define ED_COUNT_CHANGE_DELAY_XPOS (ED_SETTINGS_XPOS2 + 9 * MINI_TILEX)
+
#define ED_COUNTER_YSTART (ED_SETTINGS_YPOS + 2 * TILEY)
#define ED_COUNTER_YDISTANCE (3 * MINI_TILEY)
#define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \
#define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY)
#define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX)
-#define ED_AREA_ELEM_CONTENT2_YPOS ED_COUNTER_YPOS2(4)
+#define ED_AREA_ELEM_CONTENT2_YPOS (ED_COUNTER_YPOS2(5) + \
+ ED_GADGET_DISTANCE)
/* values for random placement background drawing area */
#define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
#define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE
#define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE
+#define ED_SELECTBOX_CHANGE_UNITS_XPOS (ED_SETTINGS_XPOS2 + \
+ ED_CHECKBUTTON_XSIZE + \
+ 2 * ED_GADGET_DISTANCE)
+
#define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS
#define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \
2 * (2 + ED_WIN_COUNT_YSIZE))
#define GADGET_ID_ELEMENT_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 7)
#define GADGET_ID_ELEMENT_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 8)
#define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 9)
-#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 10)
-#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 11)
+#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10)
+#define GADGET_ID_CUSTOM_CHANGED (GADGET_ID_DRAWING_AREA_FIRST + 11)
+#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 12)
/* text input identifiers */
-#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 12)
+#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 13)
#define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0)
#define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1)
/* selectbox identifiers */
#define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 2)
-#define GADGET_ID_CUSTOM_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 0)
+#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 0)
+#define GADGET_ID_CHANGE_CAUSE (GADGET_ID_SELECTBOX_FIRST + 1)
/* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 1)
+#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 2)
#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0)
#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1)
#define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR
/* values for selectbox gadgets */
-#define ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE 0
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 0
+#define ED_SELECTBOX_ID_CHANGE_CAUSE 1
-#define ED_NUM_SELECTBOX 1
+#define ED_NUM_SELECTBOX 2
+
+#define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS
+#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_CAUSE
/* values for textbutton gadgets */
#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0
"element content", NULL
},
{
- ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(5),
+ ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(6),
0, 999,
GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP,
GADGET_ID_CHANGE_DELAY_FIX_TEXT,
&custom_element_change.delay_fixed,
- NULL, "seconds (fixed)"
+ NULL, "units (fixed)"
},
{
- ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(6),
+ ED_COUNT_CHANGE_DELAY_XPOS, ED_COUNTER_YPOS2(7),
0, 999,
GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP,
GADGET_ID_CHANGE_DELAY_RND_TEXT,
&custom_element_change.delay_random,
- NULL, "seconds (random)"
+ NULL, "units (random)"
}
};
}
};
+static struct ValueTextInfo options_change_time_units[] =
+{
+ { 50, "seconds" },
+ { 1, "frames" },
+ { -1, NULL }
+};
+static int index_change_time_units = 0;
+
static struct ValueTextInfo options_change_cause[] =
{
{ 1, "specified delay" },
{ 5, "pressed by player" },
{ -1, NULL }
};
-static int index_change_cause = 0;
+static int index_change_cause = 0, value_change_cause = 0;
static struct
{
int x, y;
int gadget_id;
- int size;
+ int size; /* size of selectbox (chars) or '0' (dynamically determined) */
struct ValueTextInfo *options;
- int *index;
+ int *index, *value;
char *text, *infotext;
} selectbox_info[ED_NUM_SELECTBOX] =
{
+ {
+ ED_SELECTBOX_CHANGE_UNITS_XPOS, ED_COUNTER_YPOS2(8),
+ GADGET_ID_CHANGE_TIME_UNITS,
+ 0,
+ options_change_time_units, &index_change_time_units,
+ &custom_element_change.delay_frames,
+ "delay units given in", "time units for change"
+ },
{
ED_SETTINGS_XPOS, ED_COUNTER_YPOS(8),
- GADGET_ID_CUSTOM_CHANGE_CAUSE,
- 17,
+ GADGET_ID_CHANGE_CAUSE,
+ 0,
options_change_cause, &index_change_cause,
+ &value_change_cause,
"test:", "test-selectbox entry"
},
};
"restrict random placement to", "set random placement restriction"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
+ ED_SETTINGS_XPOS, 0, /* set at runtime */
GADGET_ID_STICK_ELEMENT,
&stick_element_properties_window,
- "stick window to edit content", "stick window to edit content"
+ "stick this screen to edit content","stick this screen to edit content"
},
{
ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
"player can walk under", "player can walk under this element"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(4),
+ ED_SETTINGS_XPOS, ED_COUNTER_YPOS2(5),
GADGET_ID_CUSTOM_CHANGEABLE,
&custom_element_properties[EP_CHANGEABLE],
"element changes to after:", "element can change to other element"
},
{
- ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(5),
+ ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(6),
GADGET_ID_CHANGE_DELAY_FIXED,
&custom_element_change_events[CE_DELAY_FIXED],
"delay of", "element changes after fixed delay"
},
{
- ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(6),
+ ED_SETTINGS_XPOS2, ED_COUNTER_YPOS2(7),
GADGET_ID_CHANGE_DELAY_RANDOM,
&custom_element_change_events[CE_DELAY_RANDOM],
"delay of", "element changes after random delay"
/* forward declaration for internal use */
static void ModifyEditorCounter(int, int);
static void ModifyEditorCounterLimits(int, int, int);
+static void ModifyEditorSelectbox(int, int);
+static void ModifyEditorElementList();
static void DrawDrawingWindow();
static void DrawLevelInfoWindow();
static void DrawPropertiesWindow();
level_editor_gadget[id] = gi;
+ /* ... one for each custom element optional graphic element ... */
+ id = GADGET_ID_CUSTOM_GRAPHIC;
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_X, SX + 2 * MINI_TILEX,
+ GDI_Y, SY + 4 * MINI_TILEY + MINI_TILEY / 2,
+ GDI_WIDTH, TILEX,
+ GDI_HEIGHT, TILEY,
+ GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ GDI_ITEM_SIZE, TILEX, 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;
+
/* ... one for each custom element change target element ... */
id = GADGET_ID_CUSTOM_CHANGED;
gi = CreateGadget(GDI_CUSTOM_ID, id,
static void CreateSelectboxGadgets()
{
int max_infotext_len = getMaxInfoTextLength();
- int i;
+ int i, j;
for (i=0; i<ED_NUM_SELECTBOX; i++)
{
Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
int gd_x, gd_y;
+ int xoffset;
struct GadgetInfo *gi;
unsigned long event_mask;
char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = selectbox_info[i].gadget_id;
+ /* (we cannot use -1 for uninitialized values if we directly compare
+ with results from strlen(), because the '<' and '>' operation will
+ implicitely cast -1 to an unsigned integer value!) */
+
+ if (selectbox_info[i].size == 0) /* dynamically determined */
+ for (j=0; selectbox_info[i].options[j].text != NULL; j++)
+ if (strlen(selectbox_info[i].options[j].text) > selectbox_info[i].size)
+ selectbox_info[i].size = strlen(selectbox_info[i].options[j].text);
+
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;
+ xoffset = (getFontWidth(FONT_TEXT_1) * strlen(selectbox_info[i].text) +
+ 2 * ED_GADGET_DISTANCE);
+
sprintf(infotext, "Select %s", selectbox_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 + selectbox_info[i].x,
+ GDI_X, SX + selectbox_info[i].x + xoffset,
GDI_Y, SY + selectbox_info[i].y,
GDI_TYPE, GD_TYPE_SELECTBOX,
GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END);
}
+static void ModifyEditorSelectbox(int selectbox_id, int new_value)
+{
+ int gadget_id = selectbox_info[selectbox_id].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ int new_index_value = 0;
+ int i;
+
+ for(i=0; selectbox_info[selectbox_id].options[i].text != NULL; i++)
+ if (selectbox_info[selectbox_id].options[i].value == new_value)
+ new_index_value = i;
+
+ *selectbox_info[selectbox_id].value =
+ selectbox_info[selectbox_id].options[new_index_value].value;
+
+ ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END);
+}
+
+static void ModifyEditorElementList()
+{
+ int i;
+
+ 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];
+
+ UnmapGadget(gi);
+ getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
+ ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
+ MapGadget(gi);
+ }
+}
+
static void PickDrawingElement(int button, int element)
{
if (button < 1 || button > 3)
static void DrawCustomChangedArea()
{
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGED];
#if 0
int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
int yoffset_right2 = ED_BORDER_SIZE;
ElementContent[0][0][0] = custom_element_change.successor;
DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY);
+#if 1
+ DrawMiniGraphicExt(drawto,
+ gi->x,
+ gi->y,
+ el2edimg(ElementContent[0][0][0]));
+#else
DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
+#endif
#if 0
DrawText(area_sx + TILEX, area_sy + 1, "Element after change", FONT_TEXT_1);
{
/* draw stickybutton gadget */
i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+ checkbutton_info[i].y = ED_COUNTER_YPOS(4);
x = checkbutton_info[i].x + xoffset_right2;
y = checkbutton_info[i].y + yoffset_right2;
DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
- GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+ GDI_CHECKED, *checkbutton_info[i].value,
+ GDI_Y, SY + checkbutton_info[i].y, GDI_END);
MapCheckbuttonGadget(i);
if (HAS_CONTENT(properties_element))
if (IS_CUSTOM_ELEMENT(properties_element))
{
- CopyCustomElementPropertiesToEditor(properties_element);
-
/* draw checkbutton gadgets */
for (i = ED_CHECKBUTTON_ID_CUSTOM_FIRST;
i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++)
int yoffset_right2 = ED_BORDER_SIZE;
int i, x, y;
- CopyCustomElementPropertiesToEditor(properties_element);
-
/* draw stickybutton gadget */
i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+ checkbutton_info[i].y = ED_COUNTER_YPOS2(4);
x = checkbutton_info[i].x + xoffset_right2;
y = checkbutton_info[i].y + yoffset_right2;
DrawTextF(x, y, FONT_TEXT_1, checkbutton_info[i].text);
ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
- GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+ GDI_CHECKED, *checkbutton_info[i].value,
+ GDI_Y, SY + checkbutton_info[i].y, GDI_END);
MapCheckbuttonGadget(i);
/* draw counter gadgets */
MapCheckbuttonGadget(i);
}
+ /* map gadget for optional graphic element */
+ MapDrawingArea(GADGET_ID_CUSTOM_GRAPHIC);
+
DrawCustomChangedArea();
- /* draw selectbox gadget */
- i = ED_SELECTBOX_ID_CUSTOM_CHANGE_CAUSE;
- x = selectbox_info[i].x + xoffset_right2;
- y = selectbox_info[i].y + yoffset_right2;
+ /* draw selectbox gadgets */
+ for (i=ED_SELECTBOX_ID_CHANGE_FIRST; i<=ED_SELECTBOX_ID_CHANGE_LAST; i++)
+ {
+ int yoffset = ED_BORDER_SIZE;
- selectbox_info[i].index = &index_change_cause;
+ x = selectbox_info[i].x;
+ y = selectbox_info[i].y + yoffset;
- DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
- ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
- GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
- MapSelectboxGadget(i);
+ DrawTextF(x, y, FONT_TEXT_1, selectbox_info[i].text);
+#if 1
+ ModifyEditorSelectbox(i, *selectbox_info[i].value);
+#else
+ ModifyGadget(level_editor_gadget[selectbox_info[i].gadget_id],
+ GDI_SELECTBOX_INDEX, *selectbox_info[i].index, GDI_END);
+#endif
+ MapSelectboxGadget(i);
+ }
}
static void DrawPropertiesWindow()
!checkPropertiesConfig())
edit_mode_properties = ED_MODE_PROPERTIES_INFO;
+ if (IS_CUSTOM_ELEMENT(properties_element))
+ CopyCustomElementPropertiesToEditor(properties_element);
+
UnmapLevelEditorWindowGadgets();
SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
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 item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize;
int lx = 0, ly = 0;
int min_lx = 0, min_ly = 0;
int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
}
else
{
- DrawMiniGraphicExt(drawto,
- gi->x + sx * MINI_TILEX,
- gi->y + sy * MINI_TILEY,
- el2edimg(new_element));
- DrawMiniGraphicExt(window,
- gi->x + sx * MINI_TILEX,
- gi->y + sy * MINI_TILEY,
- el2edimg(new_element));
+ if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY)
+ DrawMiniGraphicExt(drawto,
+ gi->x + sx * MINI_TILEX,
+ gi->y + sy * MINI_TILEY,
+ el2edimg(new_element));
+ else
+ DrawGraphicExt(drawto,
+ gi->x + sx * TILEX,
+ gi->y + sy * TILEY,
+ el2img(new_element), 0);
if (id == GADGET_ID_AMOEBA_CONTENT)
level.amoeba_content = new_element;
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC &&
+ IS_CUSTOM_ELEMENT(properties_element))
+ {
+ int i = properties_element - EL_CUSTOM_START;
+
+ if (IS_CUSTOM_ELEMENT(new_element))
+ new_element = CUSTOM_ELEMENT_INFO(new_element).change.gfx_element;
+
+ custom_element_change.gfx_element = new_element;
+ level.custom_element[i].change = custom_element_change;
+
+ ModifyEditorElementList();
+
+ FrameCounter = 0; /* restart animation frame counter */
+ }
else if (id == GADGET_ID_CUSTOM_CHANGED &&
IS_CUSTOM_ELEMENT(properties_element))
{
int type_id = gi->custom_type_id;
*selectbox_info[type_id].index = gi->selectbox.index;
+ *selectbox_info[type_id].value =
+ selectbox_info[type_id].options[gi->selectbox.index].value;
+
+ if (type_id >= ED_SELECTBOX_ID_CHANGE_FIRST &&
+ type_id <= ED_SELECTBOX_ID_CHANGE_LAST)
+ CopyCustomElementPropertiesToGame(properties_element);
#if 0
printf("Selected text value: '%s' [%d]\n",
int button = gi->event.button;
int step = BUTTON_STEPSIZE(button);
int new_element = BUTTON_ELEMENT(button);
- int i, x, y;
+ int x, y;
if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT)
DrawLevelText(0, 0, 0, TEXT_END);
element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
}
- 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];
-
- UnmapGadget(gi);
- getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
- ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
- MapGadget(gi);
- }
+ ModifyEditorElementList();
+
break;
case GADGET_ID_WRAP_LEFT:
else if (id == GADGET_ID_AMOEBA_CONTENT)
DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"Amoeba content");
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Optional custom graphic element");
else if (id == GADGET_ID_CUSTOM_CHANGED)
DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"New element after change");