leveldir_current =
getTreeInfoFromIdentifier(leveldir_first, getLoginName());
+ // this may happen if "setup.internal.create_user_levelset" is FALSE
+ // or if file "levelinfo.conf" is missing in personal user level set
+ if (leveldir_current == NULL)
+ {
+ Request("Cannot find personal level set?!", REQ_CONFIRM);
+
+ leveldir_current = leveldir_former;
+
+ return FALSE;
+ }
+
// find unused level number
for (new_level_nr = leveldir_current->first_level; ; new_level_nr++)
{
// copy change events also to special level editor variable
custom_element = element_info[element];
custom_element_change = *element_info[element].change;
+
+ // needed here to restore runtime value "element_info[element].gfx_element"
+ InitElementPropertiesGfxElement();
}
static void CopyGroupElementPropertiesToGame(int element)
element_info[element] = custom_element;
*element_info[element].group = group_element_info;
+
+ // needed here to restore runtime value "element_info[element].gfx_element"
+ InitElementPropertiesGfxElement();
}
static void CopyClassicElementPropertiesToGame(int element)
ed_tilesize = setup.auto_setup.editor_zoom_tilesize;
ed_tilesize_default = DEFAULT_EDITOR_TILESIZE;
+ // make sure that tile size is always a power of 2
+ ed_tilesize = (1 << log_2(ed_tilesize));
+
if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
{
ed_tilesize = DEFAULT_EDITOR_TILESIZE_MM;
char text[MAX_CB_TEXT_SIZE + 1] = "";
int width = (draw_with_brush ? brush_width : lev_fieldx);
int height = (draw_with_brush ? brush_height : lev_fieldy);
+ char *format = "%s%03d";
+
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ if ((draw_with_brush ? brush_buffer[x][y] : Feld[x][y]) > 999)
+ format = "%s%04d";
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
int element = (draw_with_brush ? brush_buffer[x][y] : Feld[x][y]);
- int element_mapped = element;
char *prefix = (mode == CB_DUMP_BRUSH ||
mode == CB_BRUSH_TO_CLIPBOARD ? "`" : "¸");
- if (IS_CUSTOM_ELEMENT(element))
- element_mapped = EL_CUSTOM_START;
- else if (IS_GROUP_ELEMENT(element))
- element_mapped = EL_GROUP_START;
- else if (element >= NUM_FILE_ELEMENTS)
- element_mapped = EL_UNKNOWN;
+ if (element >= NUM_FILE_ELEMENTS)
+ element = EL_UNKNOWN;
// copy brush to level sketch text buffer for the R'n'D forum:
- // - large tiles: `xxx (0x60 ASCII)
- // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8)
- snprintf(part, MAX_CB_PART_SIZE + 1, "%s%03d", prefix, element_mapped);
+ // - large tiles: `xxx or `xxxx (0x60 ASCII)
+ // - small tiles: ¸xxx or ¸xxxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8)
+ snprintf(part, MAX_CB_PART_SIZE + 1, format, prefix, element);
strcat(text, part);
}
char *clipboard_text = SDL_GetClipboardText();
char *ptr = clipboard_text;
+ boolean allow_new_row = FALSE;
boolean stop = FALSE;
while (*ptr && !stop)
{
boolean prefix_found = FALSE;
+ boolean start_new_row = FALSE;
// level sketch element number prefixes (may be multi-byte characters)
char *prefix_list[] = { "`", "¸" };
}
}
- // continue with next character if prefix not found
- if (!prefix_found)
- {
- ptr++; // !!! FIX THIS for real UTF-8 handling !!!
-
- continue;
- }
-
- // continue with next character if prefix not found
- if (strlen(ptr) < 3)
- break;
-
- if (ptr[0] >= '0' && ptr[0] <= '9' &&
+ // check if prefix found and followed by (at least) three digits
+ if (prefix_found &&
+ strlen(ptr) >= 3 &&
+ ptr[0] >= '0' && ptr[0] <= '9' &&
ptr[1] >= '0' && ptr[1] <= '9' &&
ptr[2] >= '0' && ptr[2] <= '9')
{
ptr += 3;
+ // level sketch element number might consist of four digits
+ if (ptr[0] >= '0' && ptr[0] <= '9')
+ {
+ element = element * 10 + (ptr[0] - '0');
+ ptr++;
+ }
+
if (element >= NUM_FILE_ELEMENTS)
element = EL_UNKNOWN;
x++;
- if (x >= MAX_LEV_FIELDX || *ptr == '\n')
- {
- x = 0;
- y++;
+ if (x >= MAX_LEV_FIELDX)
+ start_new_row = TRUE;
- if (y >= MAX_LEV_FIELDY)
- stop = TRUE;
- }
+ allow_new_row = TRUE;
+ }
+ else
+ {
+ if ((*ptr == '\n' || *ptr == '\r') && allow_new_row)
+ start_new_row = TRUE;
+
+ ptr++; // !!! FIX THIS for real UTF-8 handling !!!
+ }
+
+ if (start_new_row)
+ {
+ x = 0;
+ y++;
+
+ if (y >= MAX_LEV_FIELDY)
+ stop = TRUE;
+
+ allow_new_row = FALSE;
}
}
CopyBrushExt(0, 0, 0, 0, 0, CB_BRUSH_TO_CLIPBOARD_SMALL);
}
+void UndoLevelEditorOperation(void)
+{
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], -1);
+}
+
+void RedoLevelEditorOperation(void)
+{
+ ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3);
+}
+
static void FloodFill(int from_x, int from_y, int fill_element)
{
FloodFillLevel(from_x, from_y, fill_element, Feld, lev_fieldx, lev_fieldy);
button == 2 ? ed_tilesize_default :
button == 3 ? ed_tilesize / 2 : ed_tilesize);
+ // when using touch device, cycle through all zoom tilesizes
+ if (runtime.uses_touch_device && ed_tilesize > TILESIZE)
+ ed_tilesize = MICRO_TILESIZE;
+
// limit zoom level by upper and lower bound
ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE);
break;
case GADGET_ID_UNDO:
- if (button == 1 && GetKeyModState() & (KMOD_Shift|KMOD_Control))
+ if (button < 0) // keep button value (even if modifier keys are pressed)
+ button = -button;
+ else if (button == 1 && GetKeyModState() & (KMOD_Shift | KMOD_Control))
button = 3;
if (button == 1 && undo_buffer_steps == 0)
void HandleLevelEditorKeyInput(Key key)
{
char letter = getCharFromKey(key);
- int button = MB_LEFTBUTTON;
if (drawing_function == GADGET_ID_TEXT &&
DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE)
DrawLevelText(0, 0, 0, TEXT_NEWLINE);
else if (key == KSYM_Escape)
DrawLevelText(0, 0, 0, TEXT_END);
+
+ return;
}
- else if (button_status == MB_RELEASED)
- {
- int id = GADGET_ID_NONE;
- int new_element_shift = element_shift;
- int step = ED_ELEMENTLIST_BUTTONS_VERT - 1;
- int i;
- switch (key)
- {
- case KSYM_Left:
- id = GADGET_ID_SCROLL_LEFT;
- break;
- case KSYM_Right:
- id = GADGET_ID_SCROLL_RIGHT;
- break;
- case KSYM_Up:
- id = GADGET_ID_SCROLL_UP;
- break;
- case KSYM_Down:
- id = GADGET_ID_SCROLL_DOWN;
- break;
+ int id = GADGET_ID_NONE;
+ int new_element_shift = element_shift;
+ int step = ED_ELEMENTLIST_BUTTONS_VERT - 1;
+ int button = MB_LEFTBUTTON;
+ int i;
- case KSYM_Page_Up:
- case KSYM_Page_Down:
- step *= (key == KSYM_Page_Up ? -1 : +1);
- element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ;
+ switch (key)
+ {
+ case KSYM_Left:
+ id = GADGET_ID_SCROLL_LEFT;
+ break;
+ case KSYM_Right:
+ id = GADGET_ID_SCROLL_RIGHT;
+ break;
+ case KSYM_Up:
+ id = GADGET_ID_SCROLL_UP;
+ break;
+ case KSYM_Down:
+ id = GADGET_ID_SCROLL_DOWN;
+ break;
- 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;
+ case KSYM_Page_Up:
+ case KSYM_Page_Down:
+ step *= (key == KSYM_Page_Up ? -1 : +1);
+ element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ;
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ 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;
- ModifyEditorElementList();
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- break;
+ ModifyEditorElementList();
- case KSYM_Home:
- case KSYM_End:
- element_shift = (key == KSYM_Home ? 0 :
- num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS);
+ break;
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ case KSYM_Home:
+ case KSYM_End:
+ element_shift = (key == KSYM_Home ? 0 :
+ num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS);
- ModifyEditorElementList();
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- break;
+ ModifyEditorElementList();
- case KSYM_Insert:
- case KSYM_Delete:
+ break;
- // this is needed to prevent interference with running "True X-Mouse"
- if (GetKeyModStateFromEvents() & KMOD_Control)
- break;
+ case KSYM_Insert:
+ case KSYM_Delete:
- // check for last or next editor cascade block in element list
- for (i = 0; i < num_editor_elements; i++)
- {
- if ((key == KSYM_Insert && i == element_shift) ||
- (key == KSYM_Delete && new_element_shift > element_shift))
- break;
+ // this is needed to prevent interference with running "True X-Mouse"
+ if (GetKeyModStateFromEvents() & KMOD_Control)
+ break;
- // jump to next cascade block (or to start of element list)
- if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i]))
- new_element_shift = i;
- }
+ // check for last or next editor cascade block in element list
+ for (i = 0; i < num_editor_elements; i++)
+ {
+ if ((key == KSYM_Insert && i == element_shift) ||
+ (key == KSYM_Delete && new_element_shift > element_shift))
+ break;
- if (i < num_editor_elements)
- element_shift = new_element_shift;
+ // jump to next cascade block (or to start of element list)
+ if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i]))
+ new_element_shift = i;
+ }
- if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
- element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
+ if (i < num_editor_elements)
+ element_shift = new_element_shift;
- ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
- GDI_SCROLLBAR_ITEM_POSITION,
- element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
- ModifyEditorElementList();
+ ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
+ GDI_SCROLLBAR_ITEM_POSITION,
+ element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
- break;
+ ModifyEditorElementList();
- case KSYM_Escape:
- if (edit_mode == ED_MODE_DRAWING)
- {
- RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
- }
- else if (edit_mode == ED_MODE_INFO)
- {
- HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]);
- }
- else if (edit_mode == ED_MODE_PROPERTIES)
- {
- 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
- {
- ChangeEditModeWindow(ED_MODE_DRAWING);
- }
+ break;
- break;
+ case KSYM_Escape:
+ if (edit_mode == ED_MODE_DRAWING)
+ RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE);
+ else if (edit_mode == ED_MODE_INFO)
+ HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]);
+ else if (edit_mode == ED_MODE_PROPERTIES)
+ 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
+ ChangeEditModeWindow(ED_MODE_DRAWING);
- default:
- break;
- }
+ break;
- if (id != GADGET_ID_NONE)
- ClickOnGadget(level_editor_gadget[id], button);
- else if (letter == '1' || letter == '?')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button);
- else if (letter == '2')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button);
- else if (letter == '3')
- ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button);
- else if (letter == '.')
- ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
- else if (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 == controlbutton_info[i].shortcut)
- if (!anyTextGadgetActive())
- ClickOnGadget(level_editor_gadget[i], button);
+ default:
+ break;
}
+
+ if (id != GADGET_ID_NONE)
+ ClickOnGadget(level_editor_gadget[id], button);
+ else if (letter == '1' || letter == '?')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button);
+ else if (letter == '2')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button);
+ else if (letter == '3')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button);
+ else if (letter == '.')
+ ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button);
+ else if (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 == controlbutton_info[i].shortcut)
+ if (!anyTextGadgetActive())
+ ClickOnGadget(level_editor_gadget[i], button);
}
void HandleLevelEditorIdle(void)