+void DrawBackgroundForFont(int x, int y, int width, int height, int font_nr)
+{
+ struct FontBitmapInfo *font = getFontBitmapInfo(font_nr);
+
+ if (font->bitmap == NULL)
+ return;
+
+ DrawBackground(x, y, width, height);
+}
+
+void DrawBackgroundForGraphic(int x, int y, int width, int height, int graphic)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+
+ if (g->bitmap == NULL)
+ return;
+
+ DrawBackground(x, y, width, height);
+}
+
+static int game_status_last = -1;
+static Bitmap *global_border_bitmap_last = NULL;
+static Bitmap *global_border_bitmap = NULL;
+static int real_sx_last = -1, real_sy_last = -1;
+static int full_sxsize_last = -1, full_sysize_last = -1;
+static int dx_last = -1, dy_last = -1;
+static int dxsize_last = -1, dysize_last = -1;
+static int vx_last = -1, vy_last = -1;
+static int vxsize_last = -1, vysize_last = -1;
+
+boolean CheckIfGlobalBorderHasChanged()
+{
+ // if game status has not changed, global border has not changed either
+ if (game_status == game_status_last)
+ return FALSE;
+
+ // determine and store new global border bitmap for current game status
+ global_border_bitmap = getGlobalBorderBitmapFromStatus(game_status);
+
+ return (global_border_bitmap_last != global_border_bitmap);
+}
+
+boolean CheckIfGlobalBorderRedrawIsNeeded()
+{
+ // if game status has not changed, nothing has to be redrawn
+ if (game_status == game_status_last)
+ return FALSE;
+
+ // redraw if last screen was title screen
+ if (game_status_last == GAME_MODE_TITLE)
+ return TRUE;
+
+ // redraw if global screen border has changed
+ if (CheckIfGlobalBorderHasChanged())
+ return TRUE;
+
+ // redraw if position or size of playfield area has changed
+ if (real_sx_last != REAL_SX || real_sy_last != REAL_SY ||
+ full_sxsize_last != FULL_SXSIZE || full_sysize_last != FULL_SYSIZE)
+ return TRUE;
+
+ // redraw if position or size of door area has changed
+ if (dx_last != DX || dy_last != DY ||
+ dxsize_last != DXSIZE || dysize_last != DYSIZE)
+ return TRUE;
+
+ // redraw if position or size of tape area has changed
+ if (vx_last != VX || vy_last != VY ||
+ vxsize_last != VXSIZE || vysize_last != VYSIZE)
+ return TRUE;
+
+ return FALSE;
+}
+
+void RedrawGlobalBorderFromBitmap(Bitmap *bitmap)
+{
+ if (bitmap)
+ BlitBitmap(bitmap, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ else
+ ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
+}
+
+void RedrawGlobalBorder()
+{
+ Bitmap *bitmap = getGlobalBorderBitmapFromStatus(game_status);
+
+ RedrawGlobalBorderFromBitmap(bitmap);
+
+ redraw_mask = REDRAW_ALL;
+}
+
+static void RedrawGlobalBorderIfNeeded()
+{
+ if (game_status == game_status_last)
+ return;
+
+ // copy current draw buffer to later copy back areas that have not changed
+ if (game_status_last != GAME_MODE_TITLE)
+ BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+
+ if (CheckIfGlobalBorderRedrawIsNeeded())
+ {
+ // redraw global screen border (or clear, if defined to be empty)
+ RedrawGlobalBorderFromBitmap(global_border_bitmap);
+
+ // copy previous playfield and door areas, if they are defined on both
+ // previous and current screen and if they still have the same size
+
+ if (real_sx_last != -1 && real_sy_last != -1 &&
+ REAL_SX != -1 && REAL_SY != -1 &&
+ full_sxsize_last == FULL_SXSIZE && full_sysize_last == FULL_SYSIZE)
+ BlitBitmap(bitmap_db_store_1, backbuffer,
+ real_sx_last, real_sy_last, FULL_SXSIZE, FULL_SYSIZE,
+ REAL_SX, REAL_SY);