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;
return (door_1_viewport_unchanged && door_1_contains_toolbox);
}
+static void DrawEditorDoorBackground(int graphic, int x, int y,
+ int width, int height)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+
+ if (g->bitmap != NULL)
+ BlitBitmap(g->bitmap, drawto, g->src_x, g->src_y,
+ MIN(width, g->width), MIN(height, g->height), x, y);
+ else
+ ClearRectangle(drawto, x, y, width, height);
+}
+
static void DrawEditorDoorContent(void)
{
// needed for gadgets drawn on background (like palette scrollbar)
SetDoorBackgroundImage(IMG_UNDEFINED);
// copy default editor door content to main double buffer
- BlitBitmap(graphic_info[IMG_BACKGROUND_PALETTE].bitmap, drawto,
- graphic_info[IMG_BACKGROUND_PALETTE].src_x,
- graphic_info[IMG_BACKGROUND_PALETTE].src_y,
- MIN(DXSIZE, graphic_info[IMG_BACKGROUND_PALETTE].width),
- MIN(DYSIZE, graphic_info[IMG_BACKGROUND_PALETTE].height),
- DX, DY);
+ DrawEditorDoorBackground(IMG_BACKGROUND_PALETTE, DX, DY, DXSIZE, DYSIZE);
// draw bigger door
DrawSpecialEditorDoor();
// draw new control window
- BlitBitmap(graphic_info[IMG_BACKGROUND_TOOLBOX].bitmap, drawto,
- graphic_info[IMG_BACKGROUND_TOOLBOX].src_x,
- graphic_info[IMG_BACKGROUND_TOOLBOX].src_y,
- MIN(EXSIZE, graphic_info[IMG_BACKGROUND_TOOLBOX].width),
- MIN(EYSIZE, graphic_info[IMG_BACKGROUND_TOOLBOX].height),
- EX, EY);
+ DrawEditorDoorBackground(IMG_BACKGROUND_TOOLBOX, EX, EY, EXSIZE, EYSIZE);
// draw all toolbox gadgets to editor doors
MapControlButtons();
FadeSoundsAndMusic();
- if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged())
+ if (CheckFadeAll())
fade_mask = REDRAW_ALL;
FadeOut(fade_mask);
{
int element = Feld[x][y];
- if (IS_GEM(element) ||
- element == EL_MM_KETTLE ||
- element == EL_DF_CELL)
- level.gems_needed++;
+ switch (element)
+ {
+ case EL_EMERALD:
+ case EL_EMERALD_YELLOW:
+ case EL_EMERALD_RED:
+ case EL_EMERALD_PURPLE:
+ case EL_BD_DIAMOND:
+ case EL_WALL_EMERALD:
+ case EL_WALL_EMERALD_YELLOW:
+ case EL_WALL_EMERALD_RED:
+ case EL_WALL_EMERALD_PURPLE:
+ case EL_WALL_BD_DIAMOND:
+ case EL_NUT:
+ case EL_SP_INFOTRON:
+ case EL_MM_KETTLE:
+ case EL_DF_CELL:
+ level.gems_needed++;
+ break;
+
+ case EL_DIAMOND:
+ case EL_WALL_DIAMOND:
+ level.gems_needed += 3;
+ break;
+
+ case EL_PEARL:
+ case EL_WALL_PEARL:
+ level.gems_needed += 5;
+ break;
+
+ case EL_CRYSTAL:
+ case EL_WALL_CRYSTAL:
+ level.gems_needed += 8;
+ break;
+
+ default:
+ break;
+ }
}
}
};
static int last_x = -1;
static int last_y = -1;
- int old_element = IntelliDrawBuffer[x][y];
if (new_element == EL_UNDEFINED)
{
return;
}
+ int old_element = IntelliDrawBuffer[x][y];
+
if (IS_TUBE(new_element))
{
int last_element_new = EL_UNDEFINED;
static boolean draw_mode_hires = FALSE;
+static boolean isHiresTileElement(int element)
+{
+ return (IS_MM_WALL(element) || element == EL_EMPTY);
+}
+
+static boolean isHiresDrawElement(int element)
+{
+ return (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY);
+}
+
static void SetDrawModeHiRes(int element)
{
draw_mode_hires =
(level.game_engine_type == GAME_ENGINE_TYPE_MM &&
- (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY));
+ isHiresDrawElement(element));
}
static boolean getDrawModeHiRes(void)
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;
}
}
}
else if (!button_press_event)
{
+ int old_element = (IN_LEV_FIELD(lx, ly) ? Feld[lx][ly] : EL_UNDEFINED);
+ boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM &&
+ isHiresTileElement(old_element) &&
+ isHiresDrawElement(new_element));
+
// prevent handling events for every pixel position when moving mouse
- if ((sx == last_sx && sy == last_sy &&
- !IS_MM_WALL_EDITOR(new_element) && new_element != EL_EMPTY) ||
+ if ((sx == last_sx && sy == last_sy && !hires_drawing) ||
(sx2 == last_sx2 && sy2 == last_sy2))
return;
}
{
SetDrawModeHiRes(new_element);
- if (new_element == EL_PLAYER_1)
+ if (ELEM_IS_PLAYER(new_element))
{
// remove player at old position
for (y = 0; y < lev_fieldy; y++)
+ {
for (x = 0; x < lev_fieldx; x++)
- if (Feld[x][y] == EL_PLAYER_1)
- SetElement(x, y, EL_EMPTY);
+ {
+ int old_element = Feld[x][y];
+
+ if (ELEM_IS_PLAYER(old_element))
+ {
+ int replaced_with_element =
+ (old_element == EL_SOKOBAN_FIELD_PLAYER &&
+ new_element == EL_PLAYER_1 ? EL_SOKOBAN_FIELD_EMPTY :
+
+ old_element == EL_SOKOBAN_FIELD_PLAYER &&
+ new_element == old_element ? EL_SOKOBAN_FIELD_EMPTY :
+
+ new_element == EL_SOKOBAN_FIELD_PLAYER &&
+ old_element == EL_PLAYER_1 ? EL_EMPTY :
+
+ new_element >= EL_PLAYER_1 &&
+ new_element <= EL_PLAYER_4 &&
+ new_element == old_element ? EL_EMPTY :
+
+ old_element);
+
+ SetElement(x, y, replaced_with_element);
+ }
+ }
+ }
}
SetElementButton(lx, ly, dx, dy, new_element, button);
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);