+ BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ for (yy = 0; yy < 2; yy++)
+ {
+ for (xx = 0; xx < 2; xx++)
+ {
+ int src_xx = src_x + xx * max_xsize_pos;
+ int src_yy = src_y + yy * max_ysize_pos;
+ int dst_xx = dst_x + xx * xsize_size_left;
+ int dst_yy = dst_y + yy * ysize_size_top;
+ int xx_size = (xx ? tile_size : xsize_size_left);
+ int yy_size = (yy ? tile_size : ysize_size_top);
+
+ if (draw_masked)
+ BlitBitmapMasked(bitmap_db_cross, backbuffer,
+ src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
+ else
+ BlitBitmap(bitmap_db_cross, backbuffer,
+ src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
+ }
+ }
+
+ redraw_mask |= REDRAW_FIELD;
+
+ DoAnimation();
+ BackToFront();
+
+ SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
+ }
+}
+
+void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
+{
+ int graphic = IMG_BACKGROUND_REQUEST;
+ int sound_opening = SND_REQUEST_OPENING;
+ int sound_closing = SND_REQUEST_CLOSING;
+ int anim_mode_1 = request.anim_mode; /* (higher priority) */
+ int anim_mode_2 = graphic_info[graphic].anim_mode; /* (lower priority) */
+ int anim_mode = (anim_mode_1 != ANIM_DEFAULT ? anim_mode_1 : anim_mode_2);
+ int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
+ anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
+
+ if (game_status == GAME_MODE_PLAYING)
+ BlitScreenToBitmap(backbuffer);
+
+ SetDrawtoField(DRAW_BACKBUFFER);
+
+ // SetDrawBackgroundMask(REDRAW_NONE);
+
+ if (action == ACTION_OPENING)
+ {
+ BlitBitmap(backbuffer, bitmap_db_store, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ if (req_state & REQ_ASK)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_NO]);
+ }
+ else if (req_state & REQ_CONFIRM)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_CONFIRM]);
+ }
+ else if (req_state & REQ_PLAYER)
+ {
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_1]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_2]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_3]);
+ MapGadget(tool_gadget[TOOL_CTRL_ID_PLAYER_4]);
+ }
+
+ DrawEnvelopeRequest(text);
+
+ if (game_status != GAME_MODE_MAIN)
+ InitAnimation();
+ }
+
+ game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+
+ if (action == ACTION_OPENING)
+ {
+ PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelopeRequest(ANIM_DEFAULT, ACTION_OPENING);
+
+ AnimateEnvelopeRequest(main_anim_mode, ACTION_OPENING);
+ }
+ else
+ {
+ PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE);
+
+ if (anim_mode != ANIM_NONE)
+ AnimateEnvelopeRequest(main_anim_mode, ACTION_CLOSING);
+
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelopeRequest(ANIM_DEFAULT, ACTION_CLOSING);
+ }
+
+ game.envelope_active = FALSE;
+
+ if (action == ACTION_CLOSING)
+ {
+ if (game_status != GAME_MODE_MAIN)
+ StopAnimation();
+
+ BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ }
+
+ // SetDrawBackgroundMask(last_draw_background_mask);
+
+ redraw_mask |= REDRAW_FIELD;
+
+ if (game_status == GAME_MODE_MAIN)
+ DoAnimation();
+
+ BackToFront();
+
+ if (action == ACTION_CLOSING &&
+ game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_RND)
+ SetDrawtoField(DRAW_FIELDBUFFER);
+}
+
+void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
+{
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int graphic = el2preimg(element);
+
+ getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize, dst_x,dst_y);
+}
+
+void DrawLevel(int draw_background_mask)
+{
+ int x,y;
+
+ SetMainBackgroundImage(IMG_BACKGROUND_PLAYING);
+ SetDrawBackgroundMask(draw_background_mask);
+
+ ClearField();
+
+ for (x = BX1; x <= BX2; x++)
+ for (y = BY1; y <= BY2; y++)
+ DrawScreenField(x, y);
+
+ redraw_mask |= REDRAW_FIELD;
+}
+
+void DrawSizedLevel(int size_x, int size_y, int scroll_x, int scroll_y,
+ int tilesize)
+{
+ int x,y;
+
+ for (x = 0; x < size_x; x++)
+ for (y = 0; y < size_y; y++)
+ DrawSizedElementOrWall(x, y, scroll_x, scroll_y, tilesize);
+
+ redraw_mask |= REDRAW_FIELD;
+}
+
+void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
+{
+ int x,y;
+
+ for (x = 0; x < size_x; x++)
+ for (y = 0; y < size_y; y++)
+ DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
+
+ redraw_mask |= REDRAW_FIELD;
+}
+
+static void DrawPreviewLevelPlayfieldExt(int from_x, int from_y)
+{
+ boolean show_level_border = (BorderElement != EL_EMPTY);
+ int level_xsize = lev_fieldx + (show_level_border ? 2 : 0);
+ int level_ysize = lev_fieldy + (show_level_border ? 2 : 0);
+ int tile_size = preview.tile_size;
+ int preview_width = preview.xsize * tile_size;
+ int preview_height = preview.ysize * tile_size;
+ int real_preview_xsize = MIN(level_xsize, preview.xsize);
+ int real_preview_ysize = MIN(level_ysize, preview.ysize);
+ int real_preview_width = real_preview_xsize * tile_size;
+ int real_preview_height = real_preview_ysize * tile_size;
+ int dst_x = SX + ALIGNED_XPOS(preview.x, preview_width, preview.align);
+ int dst_y = SY + ALIGNED_YPOS(preview.y, preview_height, preview.valign);
+ int x, y;
+
+ if (!IN_GFX_FIELD_FULL(dst_x, dst_y + preview_height - 1))
+ return;
+
+ DrawBackground(dst_x, dst_y, preview_width, preview_height);
+
+ dst_x += (preview_width - real_preview_width) / 2;
+ dst_y += (preview_height - real_preview_height) / 2;
+
+ for (x = 0; x < real_preview_xsize; x++)
+ {
+ for (y = 0; y < real_preview_ysize; y++)
+ {
+ int lx = from_x + x + (show_level_border ? -1 : 0);
+ int ly = from_y + y + (show_level_border ? -1 : 0);
+ int element = (IN_LEV_FIELD(lx, ly) ? level.field[lx][ly] :
+ getBorderElement(lx, ly));
+
+ DrawPreviewElement(dst_x + x * tile_size, dst_y + y * tile_size,
+ element, tile_size);
+ }
+ }
+
+ redraw_mask |= REDRAW_FIELD;
+}
+
+#define MICROLABEL_EMPTY 0
+#define MICROLABEL_LEVEL_NAME 1
+#define MICROLABEL_LEVEL_AUTHOR_HEAD 2
+#define MICROLABEL_LEVEL_AUTHOR 3
+#define MICROLABEL_IMPORTED_FROM_HEAD 4
+#define MICROLABEL_IMPORTED_FROM 5
+#define MICROLABEL_IMPORTED_BY_HEAD 6
+#define MICROLABEL_IMPORTED_BY 7
+
+static int getMaxTextLength(struct TextPosInfo *pos, int font_nr)
+{
+ int max_text_width = SXSIZE;
+ int font_width = getFontWidth(font_nr);
+
+ if (pos->align == ALIGN_CENTER)
+ max_text_width = (pos->x < SXSIZE / 2 ? pos->x * 2 : (SXSIZE - pos->x) * 2);
+ else if (pos->align == ALIGN_RIGHT)
+ max_text_width = pos->x;
+ else
+ max_text_width = SXSIZE - pos->x;
+
+ return max_text_width / font_width;
+}
+
+static void DrawPreviewLevelLabelExt(int mode)
+{
+ struct TextPosInfo *pos = &menu.main.text.level_info_2;
+ char label_text[MAX_OUTPUT_LINESIZE + 1];
+ int max_len_label_text;
+ int font_nr = pos->font;
+ int i;
+
+ if (!IN_GFX_FIELD_FULL(pos->x, pos->y + getFontHeight(pos->font)))
+ return;
+
+ if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+ mode == MICROLABEL_IMPORTED_BY_HEAD)
+ font_nr = pos->font_alt;
+
+ max_len_label_text = getMaxTextLength(pos, font_nr);
+
+ if (pos->size != -1)
+ max_len_label_text = pos->size;
+
+ for (i = 0; i < max_len_label_text; i++)
+ label_text[i] = ' ';
+ label_text[max_len_label_text] = '\0';
+
+ if (strlen(label_text) > 0)
+ DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+
+ strncpy(label_text,
+ (mode == MICROLABEL_LEVEL_NAME ? level.name :
+ mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" :
+ mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" :
+ mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from :
+ mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" :
+ mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""),
+ max_len_label_text);
+ label_text[max_len_label_text] = '\0';
+
+ if (strlen(label_text) > 0)
+ DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
+
+ redraw_mask |= REDRAW_FIELD;