+ int lx = LEVELX(x), ly = LEVELY(y);
+ int element, content;
+
+ if (!IN_LEV_FIELD(lx, ly))
+ {
+ if (lx < -1 || lx > lev_fieldx || ly < -1 || ly > lev_fieldy)
+ element = EL_EMPTY;
+ else
+ element = getBorderElement(lx, ly);
+
+ DrawScreenElement(x, y, element);
+ return;
+ }
+
+ element = Feld[lx][ly];
+ content = Store[lx][ly];
+
+ if (IS_MOVING(lx, ly))
+ {
+ int horiz_move = (MovDir[lx][ly] == MV_LEFT || MovDir[lx][ly] == MV_RIGHT);
+ boolean cut_mode = NO_CUTTING;
+
+ if (element == EL_QUICKSAND_EMPTYING ||
+ element == EL_MAGIC_WALL_EMPTYING ||
+ element == EL_BD_MAGIC_WALL_EMPTYING ||
+ element == EL_AMOEBA_DROPPING)
+ cut_mode = CUT_ABOVE;
+ else if (element == EL_QUICKSAND_FILLING ||
+ element == EL_MAGIC_WALL_FILLING ||
+ element == EL_BD_MAGIC_WALL_FILLING)
+ cut_mode = CUT_BELOW;
+
+ if (cut_mode == CUT_ABOVE)
+ DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
+ else
+ DrawScreenElement(x, y, EL_EMPTY);
+
+ if (horiz_move)
+ DrawScreenElementShifted(x, y, MovPos[lx][ly], 0, element, NO_CUTTING);
+ else if (cut_mode == NO_CUTTING)
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], element, cut_mode);
+ else
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], content, cut_mode);
+
+ if (content == EL_ACID)
+ DrawLevelElementThruMask(lx, ly + 1, EL_ACID);
+ }
+ else if (IS_BLOCKED(lx, ly))
+ {
+ int oldx, oldy;
+ int sx, sy;
+ int horiz_move;
+ boolean cut_mode = NO_CUTTING;
+ int element_old, content_old;
+
+ Blocked2Moving(lx, ly, &oldx, &oldy);
+ sx = SCREENX(oldx);
+ sy = SCREENY(oldy);
+ horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
+ MovDir[oldx][oldy] == MV_RIGHT);
+
+ element_old = Feld[oldx][oldy];
+ content_old = Store[oldx][oldy];
+
+ if (element_old == EL_QUICKSAND_EMPTYING ||
+ element_old == EL_MAGIC_WALL_EMPTYING ||
+ element_old == EL_BD_MAGIC_WALL_EMPTYING ||
+ element_old == EL_AMOEBA_DROPPING)
+ cut_mode = CUT_ABOVE;
+
+ DrawScreenElement(x, y, EL_EMPTY);
+
+ if (horiz_move)
+ DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
+ NO_CUTTING);
+ else if (cut_mode == NO_CUTTING)
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
+ cut_mode);
+ else
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
+ cut_mode);
+ }
+ else if (IS_DRAWABLE(element))
+ DrawScreenElement(x, y, element);
+ else
+ DrawScreenElement(x, y, EL_EMPTY);
+}
+
+void DrawLevelField(int x, int y)
+{
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawScreenField(SCREENX(x), SCREENY(y));
+ else if (IS_MOVING(x, y))
+ {
+ int newx,newy;
+
+ Moving2Blocked(x, y, &newx, &newy);
+ if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
+ DrawScreenField(SCREENX(newx), SCREENY(newy));
+ }
+ else if (IS_BLOCKED(x, y))
+ {
+ int oldx, oldy;
+
+ Blocked2Moving(x, y, &oldx, &oldy);
+ if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
+ DrawScreenField(SCREENX(oldx), SCREENY(oldy));
+ }
+}
+
+void DrawMiniElement(int x, int y, int element)
+{
+ int graphic;
+
+ graphic = el2edimg(element);
+ DrawMiniGraphic(x, y, graphic);
+}
+
+void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
+{
+ int x = sx + scroll_x, y = sy + scroll_y;
+
+ if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
+ DrawMiniElement(sx, sy, EL_EMPTY);
+ else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
+ DrawMiniElement(sx, sy, Feld[x][y]);
+ else
+ DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
+}
+
+#if 1
+void DrawEnvelopeBackground(int startx, int starty, int x, int y,
+ int xsize, int ysize, int font_nr)
+{
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int graphic = IMG_GAME_ENVELOPE_BACKGROUND;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int dst_x = SX + startx + x * font_width;
+ int dst_y = SY + starty + y * font_height;
+ int width = graphic_info[graphic].width;
+ int height = graphic_info[graphic].height;
+ int inner_width = MAX(width - 2 * font_width, font_width);
+ int inner_height = MAX(height - 2 * font_height, font_height);
+ int inner_sx = (width >= 3 * font_width ? font_width : 0);
+ int inner_sy = (height >= 3 * font_height ? font_height : 0);
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+
+ getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+
+ if (src_bitmap == NULL || width < font_width || height < font_height)
+ {
+ ClearRectangle(drawto, dst_x, dst_y, font_width, font_height);
+ return;
+ }
+
+ src_x += (x == 0 ? 0 : x == xsize - 1 ? width - font_width :
+ inner_sx + (x - 1) * font_width % inner_width);
+ src_y += (y == 0 ? 0 : y == ysize - 1 ? height - font_height :
+ inner_sy + (y - 1) * font_height % inner_height);
+
+ if (draw_masked)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+}
+
+#else
+
+void DrawEnvelopeBackground(int dst_x, int dst_y, int ex, int ey, int font_nr)
+{
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int graphic = IMG_GAME_ENVELOPE_BACKGROUND;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int width = graphic_info[graphic].width;
+ int height = graphic_info[graphic].height;
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+
+ getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+
+ if (src_bitmap == NULL)
+ {
+ ClearRectangle(drawto, dst_x, dst_y, font_width, font_height);
+ return;
+ }
+
+ src_x += (ex == -1 ? 0 : ex == +1 ? width - font_width : font_width);
+ src_y += (ey == -1 ? 0 : ey == +1 ? height - font_height : font_height);
+
+ if (draw_masked)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+}
+#endif
+
+void ShowEnvelope()
+{
+ int graphic = IMG_GAME_ENVELOPE_BACKGROUND;
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+ int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
+ int font_nr = FONT_TEXT_1;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ int anim_delay = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
+ int wait_delay = (ffwd_delay ? 500 : 1000);
+ int i, x, y;
+
+ /* open envelope window horizontally */
+ for (i = 0; i <= level.envelope_xsize; i++)
+ {
+ int xsize = i + 2;
+ int ysize = 2;
+ int startx = (SXSIZE - xsize * font_width) / 2;
+ int starty = (SYSIZE - ysize * font_height) / 2;
+
+ SetDrawtoField(DRAW_BUFFERED);
+
+ BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
+
+ SetDrawtoField(DRAW_BACKBUFFER);
+
+#if 1
+ for (y=0; y < ysize; y++) for (x=0; x < xsize; x++)
+ DrawEnvelopeBackground(startx, starty, x, y, xsize, ysize, font_nr);
+#else
+ for (y=0; y < ysize; y++) for (x=0; x < xsize; x++)
+ {
+ int sx = SX + startx + x * font_width;
+ int sy = SY + starty + y * font_height;
+ int ex = (x == 0 ? -1 : x == xsize - 1 ? +1 : 0);
+ int ey = (y == 0 ? -1 : y == ysize - 1 ? +1 : 0);
+
+ DrawEnvelopeBackground(sx, sy, ex, ey, font_nr);
+ }
+#endif