shithub: puzzles

Download patch

ref: c0da615a933a6676e2c6b957368067ca1bc10abd
parent: c6a48bfc1c65c5f696a6e53be6c458692c6579f8
author: Simon Tatham <anakin@pobox.com>
date: Sun Apr 25 07:24:40 EDT 2021

Centralise initial clearing of the puzzle window.

I don't know how I've never thought of this before! Pretty much every
game in this collection has to have a mechanism for noticing when
game_redraw is called for the first time on a new drawstate, and if
so, start by covering the whole window with a filled rectangle of the
background colour. This is a pain for implementers, and also awkward
because the drawstate often has to _work out_ its own pixel size (or
else remember it from when its size method was called).

The backends all do that so that the frontends don't have to guarantee
anything about the initial window contents. But that's a silly
tradeoff to begin with (there are way more backends than frontends, so
this _adds_ work rather than saving it), and also, in this code base
there's a standard way to handle things you don't want to have to do
in every backend _or_ every frontend: do them just once in the midend!

So now that rectangle-drawing operation happens in midend_redraw, and
I've been able to remove it from almost every puzzle. (A couple of
puzzles have other approaches: Slant didn't have a rectangle-draw
because it handles even the game borders using its per-tile redraw
function, and Untangle clears the whole window on every redraw
_anyway_ because it would just be too confusing not to.)

In some cases I've also been able to remove the 'started' flag from
the drawstate. But in many cases that has to stay because it also
triggers drawing of static display furniture other than the
background.

--- a/blackbox.c
+++ b/blackbox.c
@@ -1377,10 +1377,6 @@
         int x0 = TODRAW(0)-1, y0 = TODRAW(0)-1;
         int x1 = TODRAW(state->w+2), y1 = TODRAW(state->h+2);
 
-        draw_rect(dr, 0, 0,
-                  TILE_SIZE * (state->w+3), TILE_SIZE * (state->h+3),
-                  COL_BACKGROUND);
-
         /* clockwise around the outline starting at pt behind (1,1). */
         draw_line(dr, x0+ts, y0+ts, x0+ts, y0,    COL_HIGHLIGHT);
         draw_line(dr, x0+ts, y0,    x1-ts, y0,    COL_HIGHLIGHT);
--- a/bridges.c
+++ b/bridges.c
@@ -2987,9 +2987,6 @@
 
     /* Clear screen, if required. */
     if (!ds->started) {
-        draw_rect(dr, 0, 0,
-                  TILE_SIZE * ds->w + 2 * BORDER,
-                  TILE_SIZE * ds->h + 2 * BORDER, COL_BACKGROUND);
 #ifdef DRAW_GRID
         draw_rect_outline(dr,
                           COORD(0)-1, COORD(0)-1,
--- a/dominosa.c
+++ b/dominosa.c
@@ -2746,7 +2746,6 @@
 #define FROMCOORD(x) ( ((x) - BORDER + TILESIZE) / TILESIZE - 1 )
 
 struct game_drawstate {
-    bool started;
     int w, h, tilesize;
     unsigned long *visible;
 };
@@ -3059,7 +3058,6 @@
     struct game_drawstate *ds = snew(struct game_drawstate);
     int i;
 
-    ds->started = false;
     ds->w = state->w;
     ds->h = state->h;
     ds->visible = snewn(ds->w * ds->h, unsigned long);
@@ -3224,14 +3222,6 @@
     int n = state->params.n, w = state->w, h = state->h, wh = w*h;
     int x, y, i;
     unsigned char *used;
-
-    if (!ds->started) {
-        int pw, ph;
-        game_compute_size(&state->params, TILESIZE, &pw, &ph);
-	draw_rect(dr, 0, 0, pw, ph, COL_BACKGROUND);
-	draw_update(dr, 0, 0, pw, ph);
-	ds->started = true;
-    }
 
     /*
      * See how many dominoes of each type there are, so we can
--- a/fifteen.c
+++ b/fifteen.c
@@ -904,13 +904,6 @@
     if (!ds->started) {
         int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILE_SIZE * state->w + 2 * BORDER,
-		  TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILE_SIZE * state->w + 2 * BORDER,
-		    TILE_SIZE * state->h + 2 * BORDER);
-
         /*
          * Recessed area containing the whole puzzle.
          */
--- a/filling.c
+++ b/filling.c
@@ -2021,17 +2021,8 @@
         (flashtime <= FLASH_TIME/3 || flashtime >= FLASH_TIME*2/3);
 
     if (!ds->started) {
-        /*
-         * The initial contents of the window are not guaranteed and
-         * can vary with front ends. To be on the safe side, all games
-         * should start by drawing a big background-colour rectangle
-         * covering the whole window.
-         */
-        draw_rect(dr, 0, 0, w*TILE_SIZE + 2*BORDER, h*TILE_SIZE + 2*BORDER,
-                  COL_BACKGROUND);
-
 	/*
-	 * Smaller black rectangle which is the main grid.
+	 * Black rectangle which is the main grid.
 	 */
 	draw_rect(dr, BORDER - BORDER_WIDTH, BORDER - BORDER_WIDTH,
 		  w*TILE_SIZE + 2*BORDER_WIDTH + 1,
--- a/flip.c
+++ b/flip.c
@@ -1202,9 +1202,6 @@
     int i, flashframe;
 
     if (!ds->started) {
-        draw_rect(dr, 0, 0, TILE_SIZE * w + 2 * BORDER,
-                  TILE_SIZE * h + 2 * BORDER, COL_BACKGROUND);
-
         /*
          * Draw the grid lines.
          */
--- a/flood.c
+++ b/flood.c
@@ -1128,13 +1128,6 @@
     if (!ds->started) {
 	int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILESIZE * w + 2 * BORDER,
-		  TILESIZE * h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILESIZE * w + 2 * BORDER,
-		    TILESIZE * h + 2 * BORDER);
-
 	/*
 	 * Recessed area containing the whole puzzle.
 	 */
--- a/galaxies.c
+++ b/galaxies.c
@@ -3285,7 +3285,6 @@
     }
 
     if (!ds->started) {
-        draw_rect(dr, 0, 0, DRAW_WIDTH, DRAW_HEIGHT, COL_BACKGROUND);
         draw_rect(dr, BORDER - EDGE_THICKNESS + 1, BORDER - EDGE_THICKNESS + 1,
                   w*TILE_SIZE + EDGE_THICKNESS*2 - 1,
                   h*TILE_SIZE + EDGE_THICKNESS*2 - 1, COL_EDGE);
--- a/guess.c
+++ b/guess.c
@@ -1349,7 +1349,6 @@
     new_move = (state->next_go != ds->next_go) || !ds->started;
 
     if (!ds->started) {
-      draw_rect(dr, 0, 0, ds->w, ds->h, COL_BACKGROUND);
       draw_rect(dr, SOLN_OX, SOLN_OY - ds->gapsz - 1, SOLN_W, 2, COL_FRAME);
       draw_update(dr, 0, 0, ds->w, ds->h);
     }
--- a/inertia.c
+++ b/inertia.c
@@ -2008,15 +2008,6 @@
      * Initialise a fresh drawstate.
      */
     if (!ds->started) {
-	int wid, ht;
-
-	/*
-	 * Blank out the window initially.
-	 */
-	game_compute_size(&ds->p, TILESIZE, &wid, &ht);
-	draw_rect(dr, 0, 0, wid, ht, COL_BACKGROUND);
-	draw_update(dr, 0, 0, wid, ht);
-
 	/*
 	 * Draw the grid lines.
 	 */
--- a/keen.c
+++ b/keen.c
@@ -2134,14 +2134,6 @@
 
     if (!ds->started) {
 	/*
-	 * The initial contents of the window are not guaranteed and
-	 * can vary with front ends. To be on the safe side, all
-	 * games should start by drawing a big background-colour
-	 * rectangle covering the whole window.
-	 */
-	draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND);
-
-	/*
 	 * Big containing rectangle.
 	 */
 	draw_rect(dr, COORD(0) - GRIDEXTRA, COORD(0) - GRIDEXTRA,
--- a/lightup.c
+++ b/lightup.c
@@ -2176,10 +2176,6 @@
     if (flashtime) flashing = (int)(flashtime * 3 / FLASH_TIME) != 1;
 
     if (!ds->started) {
-        draw_rect(dr, 0, 0,
-                  TILE_SIZE * ds->w + 2 * BORDER,
-                  TILE_SIZE * ds->h + 2 * BORDER, COL_BACKGROUND);
-
         draw_rect_outline(dr, COORD(0)-1, COORD(0)-1,
                           TILE_SIZE * ds->w + 2,
                           TILE_SIZE * ds->h + 2,
--- a/magnets.c
+++ b/magnets.c
@@ -2205,12 +2205,7 @@
     flash = (int)(flashtime * 5 / FLASH_TIME) % 2;
 
     if (!ds->started) {
-        /* draw background, corner +-. */
-        draw_rect(dr, 0, 0,
-                  TILE_SIZE * (w+2) + 2 * BORDER,
-                  TILE_SIZE * (h+2) + 2 * BORDER,
-                  COL_BACKGROUND);
-
+        /* draw corner +-. */
         draw_sym(dr, ds, -1, -1, POSITIVE, COL_TEXT);
         draw_sym(dr, ds, state->w, state->h, NEGATIVE, COL_TEXT);
 
--- a/map.c
+++ b/map.c
@@ -2872,21 +2872,10 @@
         ds->drag_visible = false;
     }
 
-    /*
-     * The initial contents of the window are not guaranteed and
-     * can vary with front ends. To be on the safe side, all games
-     * should start by drawing a big background-colour rectangle
-     * covering the whole window.
-     */
     if (!ds->started) {
-	int ww, wh;
-
-	game_compute_size(&state->p, TILESIZE, &ww, &wh);
-	draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
 	draw_rect(dr, COORD(0), COORD(0), w*TILESIZE+1, h*TILESIZE+1,
 		  COL_GRID);
-
-	draw_update(dr, 0, 0, ww, wh);
+	draw_update(dr, COORD(0), COORD(0), w*TILESIZE+1, h*TILESIZE+1);
 	ds->started = true;
     }
 
--- a/midend.c
+++ b/midend.c
@@ -73,6 +73,7 @@
 
     game_params *params, *curparams;
     game_drawstate *drawstate;
+    bool first_draw;
     game_ui *ui;
 
     game_state *oldstate;
@@ -196,6 +197,7 @@
     me->aux_info = NULL;
     me->genmode = GOT_NOTHING;
     me->drawstate = NULL;
+    me->first_draw = true;
     me->oldstate = NULL;
     me->preset_menu = NULL;
     me->anim_time = me->anim_pos = 0.0F;
@@ -318,6 +320,7 @@
         me->ourgame->free_drawstate(me->drawing, me->drawstate);
         me->drawstate = me->ourgame->new_drawstate(me->drawing,
                                                    me->states[0].state);
+        me->first_draw = true;
     }
 
     /*
@@ -1140,7 +1143,24 @@
     assert(me->drawing);
 
     if (me->statepos > 0 && me->drawstate) {
+        bool first_draw = me->first_draw;
+        me->first_draw = false;
+
         start_draw(me->drawing);
+
+        if (first_draw) {
+            /*
+             * The initial contents of the window are not guaranteed
+             * by the front end. But we also don't want to require
+             * every single game to go to the effort of clearing the
+             * window on setup. So we centralise here the operation of
+             * covering the whole window with colour 0 (assumed to be
+             * the puzzle's background colour) the first time we do a
+             * redraw operation with a new drawstate.
+             */
+            draw_rect(me->drawing, 0, 0, me->winwidth, me->winheight, 0);
+        }
+
         if (me->oldstate && me->anim_time > 0 &&
             me->anim_pos < me->anim_time) {
             assert(me->dir != 0);
@@ -1152,6 +1172,15 @@
 				me->states[me->statepos-1].state, +1 /*shrug*/,
 				me->ui, 0.0, me->flash_pos);
         }
+
+        if (first_draw) {
+            /*
+             * Call a big draw_update on the whole window, in case the
+             * game backend didn't.
+             */
+            draw_update(me->drawing, 0, 0, me->winwidth, me->winheight);
+        }
+
         end_draw(me->drawing);
     }
 }
--- a/mines.c
+++ b/mines.c
@@ -2978,13 +2978,6 @@
     if (!ds->started) {
         int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILE_SIZE * state->w + 2 * BORDER,
-		  TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILE_SIZE * state->w + 2 * BORDER,
-		    TILE_SIZE * state->h + 2 * BORDER);
-
         /*
          * Recessed area containing the whole puzzle.
          */
--- a/mosaic.c
+++ b/mosaic.c
@@ -127,7 +127,6 @@
 
 struct game_drawstate {
     int tilesize;
-    bool started;
     int *state;
     int cur_x, cur_y;           /* -1, -1 for no cursor displayed. */
     int prev_cur_x, prev_cur_y;
@@ -1413,7 +1412,6 @@
     int i;
 
     ds->tilesize = 0;
-    ds->started = false;
     ds->state = NULL;
     ds->state = snewn(state->width * state->height, int);
     for (i = 0; i < state->width * state->height; i++)
@@ -1474,19 +1472,6 @@
     bool flashing = (flashtime > 0 && (flashtime <= FLASH_TIME / 3 ||
                                        flashtime > 2*FLASH_TIME / 3));
 
-    if (!ds->started) {
-        /*
-         * The initial contents of the window are not guaranteed and
-         * can vary with front ends. To be on the safe side, all games
-         * should start by drawing a big background-colour rectangle
-         * covering the whole window.
-         */
-        draw_rect(dr, 0, 0, (state->width + 1) * ds->tilesize,
-                  (state->height + 1) * ds->tilesize, COL_BACKGROUND);
-        draw_update(dr, 0, 0, (state->width + 1) * ds->tilesize,
-                    (state->height + 1) * ds->tilesize);
-        ds->started = true;
-    }
     for (y = 0; y < state->height; y++) {
         for (x = 0; x < state->width; x++) {
             int cell = state->cells_contents[(y * state->width) + x];
--- a/net.c
+++ b/net.c
@@ -2054,7 +2054,6 @@
 }
 
 struct game_drawstate {
-    bool started;
     int width, height;
     int tilesize;
     unsigned long *visible, *to_draw;
@@ -2441,7 +2440,6 @@
     game_drawstate *ds = snew(game_drawstate);
     int i, ncells;
 
-    ds->started = false;
     ds->width = state->width;
     ds->height = state->height;
     ncells = (state->width+2) * (state->height+2);
@@ -2837,23 +2835,6 @@
     unsigned char *active;
     int *loops;
     float angle = 0.0;
-
-    /*
-     * Clear the screen on our first call.
-     */
-    if (!ds->started) {
-        int w, h;
-        game_params params;
-
-        ds->started = true;
-
-        params.width = ds->width;
-        params.height = ds->height;
-        game_compute_size(&params, TILE_SIZE, &w, &h);
-
-        draw_rect(dr, 0, 0, w, h, COL_BACKGROUND);
-        draw_update(dr, 0, 0, w, h);
-    }
 
     tx = ty = -1;
     last_rotate_dir = dir==-1 ? oldstate->last_rotate_dir :
--- a/netslide.c
+++ b/netslide.c
@@ -1589,21 +1589,12 @@
     int cur_x = -1, cur_y = -1;
 
     /*
-     * Clear the screen and draw the exterior barrier lines if this
-     * is our first call.
+     * Draw the exterior barrier lines if this is our first call.
      */
     if (!ds->started) {
         int phase;
 
         ds->started = true;
-
-        draw_rect(dr, 0, 0, 
-                  BORDER * 2 + WINDOW_OFFSET * 2 + TILE_SIZE * state->width + TILE_BORDER,
-                  BORDER * 2 + WINDOW_OFFSET * 2 + TILE_SIZE * state->height + TILE_BORDER,
-                  COL_BACKGROUND);
-        draw_update(dr, 0, 0, 
-                    BORDER * 2 + WINDOW_OFFSET*2 + TILE_SIZE*state->width + TILE_BORDER,
-                    BORDER * 2 + WINDOW_OFFSET*2 + TILE_SIZE*state->height + TILE_BORDER);
 
         for (phase = 0; phase < 2; phase++) {
 
--- a/palisade.c
+++ b/palisade.c
@@ -1174,7 +1174,6 @@
     if (!ds->grid) {
         char buf[40];
         int bgw = (w+1) * ds->tilesize, bgh = (h+1) * ds->tilesize;
-        draw_rect(dr, 0, 0, bgw, bgh, COL_BACKGROUND);
 
         for (r = 0; r <= h; ++r)
             for (c = 0; c <= w; ++c)
--- a/pattern.c
+++ b/pattern.c
@@ -1806,14 +1806,6 @@
 
     if (!ds->started) {
         /*
-         * The initial contents of the window are not guaranteed
-         * and can vary with front ends. To be on the safe side,
-         * all games should start by drawing a big background-
-         * colour rectangle covering the whole window.
-         */
-        draw_rect(dr, 0, 0, SIZE(ds->w), SIZE(ds->h), COL_BACKGROUND);
-
-        /*
          * Draw the grid outline.
          */
         draw_rect(dr, TOCOORD(ds->w, 0) - 1, TOCOORD(ds->h, 0) - 1,
--- a/pearl.c
+++ b/pearl.c
@@ -2458,18 +2458,9 @@
     bool force = false;
 
     if (!ds->started) {
-        /*
-         * The initial contents of the window are not guaranteed and
-         * can vary with front ends. To be on the safe side, all games
-         * should start by drawing a big background-colour rectangle
-         * covering the whole window.
-         */
-        draw_rect(dr, 0, 0, w*TILE_SIZE + 2*BORDER, h*TILE_SIZE + 2*BORDER,
-                  COL_BACKGROUND);
-
         if (get_gui_style() == GUI_MASYU) {
             /*
-             * Smaller black rectangle which is the main grid.
+             * Black rectangle which is the main grid.
              */
             draw_rect(dr, BORDER - BORDER_WIDTH, BORDER - BORDER_WIDTH,
                       w*TILE_SIZE + 2*BORDER_WIDTH + 1,
--- a/pegs.c
+++ b/pegs.c
@@ -1135,10 +1135,6 @@
     }
 
     if (!ds->started) {
-	draw_rect(dr, 0, 0,
-		  TILESIZE * state->w + 2 * BORDER,
-		  TILESIZE * state->h + 2 * BORDER, COL_BACKGROUND);
-
 	/*
 	 * Draw relief marks around all the squares that aren't
 	 * GRID_OBST.
--- a/range.c
+++ b/range.c
@@ -1253,7 +1253,6 @@
 struct game_drawstate {
     int tilesize;
     drawcell *grid;
-    bool started;
 };
 
 #define TILESIZE (ds->tilesize)
@@ -1655,7 +1654,6 @@
     int i;
 
     ds->tilesize = 0;
-    ds->started = false;
 
     ds->grid = snewn(n, drawcell);
     for (i = 0; i < n; ++i)
@@ -1690,7 +1688,6 @@
                         float animtime, float flashtime)
 {
     int const w = state->params.w, h = state->params.h, n = w * h;
-    int const wpx = (w+1) * ds->tilesize, hpx = (h+1) * ds->tilesize;
     int const flash = ((int) (flashtime * 5 / FLASH_TIME)) % 2;
 
     int r, c, i;
@@ -1700,12 +1697,6 @@
     find_errors(state, errors);
 
     assert (oldstate == NULL); /* only happens if animating moves */
-
-    if (!ds->started) {
-        ds->started = true;
-        draw_rect(dr, 0, 0, wpx, hpx, COL_BACKGROUND);
-        draw_update(dr, 0, 0, wpx, hpx);
-    }
 
     for (i = r = 0; r < h; ++r) {
         for (c = 0; c < w; ++c, ++i) {
--- a/rect.c
+++ b/rect.c
@@ -2793,9 +2793,6 @@
 	}
 
     if (!ds->started) {
-	draw_rect(dr, 0, 0,
-		  state->w * TILE_SIZE + 2*BORDER + 1,
-		  state->h * TILE_SIZE + 2*BORDER + 1, COL_BACKGROUND);
 	draw_rect(dr, COORD(0)-1, COORD(0)-1,
 		  ds->w*TILE_SIZE+3, ds->h*TILE_SIZE+3, COL_LINE);
 	ds->started = true;
--- a/samegame.c
+++ b/samegame.c
@@ -1512,13 +1512,6 @@
     if (!ds->started) {
 	int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILE_SIZE * state->params.w + 2 * BORDER,
-		  TILE_SIZE * state->params.h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILE_SIZE * state->params.w + 2 * BORDER,
-		    TILE_SIZE * state->params.h + 2 * BORDER);
-
 	/*
 	 * Recessed area containing the whole puzzle.
 	 */
--- a/signpost.c
+++ b/signpost.c
@@ -2081,7 +2081,6 @@
     if (!ds->started) {
         int aw = TILE_SIZE * state->w;
         int ah = TILE_SIZE * state->h;
-        draw_rect(dr, 0, 0, aw + 2 * BORDER, ah + 2 * BORDER, COL_BACKGROUND);
         draw_rect_outline(dr, BORDER - 1, BORDER - 1, aw + 2, ah + 2, COL_GRID);
         draw_update(dr, 0, 0, aw + 2 * BORDER, ah + 2 * BORDER);
     }
--- a/singles.c
+++ b/singles.c
@@ -1708,7 +1708,6 @@
     if (!ds->started) {
         int wsz = TILE_SIZE * state->w + 2 * BORDER;
         int hsz = TILE_SIZE * state->h + 2 * BORDER;
-        draw_rect(dr, 0, 0, wsz, hsz, COL_BACKGROUND);
         draw_rect_outline(dr, COORD(0)-1, COORD(0)-1,
 			  TILE_SIZE * state->w + 2, TILE_SIZE * state->h + 2,
                           COL_GRID);
--- a/sixteen.c
+++ b/sixteen.c
@@ -936,13 +936,6 @@
     if (!ds->started) {
         int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILE_SIZE * state->w + 2 * BORDER,
-		  TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILE_SIZE * state->w + 2 * BORDER,
-		    TILE_SIZE * state->h + 2 * BORDER);
-
         /*
          * Recessed area containing the whole puzzle.
          */
--- a/slant.c
+++ b/slant.c
@@ -1638,7 +1638,6 @@
 
 struct game_drawstate {
     int tilesize;
-    bool started;
     long *grid;
     long *todraw;
 };
@@ -1832,7 +1831,6 @@
     struct game_drawstate *ds = snew(struct game_drawstate);
 
     ds->tilesize = 0;
-    ds->started = false;
     ds->grid = snewn((w+2)*(h+2), long);
     ds->todraw = snewn((w+2)*(h+2), long);
     for (i = 0; i < (w+2)*(h+2); i++)
@@ -1971,14 +1969,6 @@
 	flashing = (int)(flashtime * 3 / FLASH_TIME) != 1;
     else
 	flashing = false;
-
-    if (!ds->started) {
-	int ww, wh;
-	game_compute_size(&state->p, TILESIZE, &ww, &wh);
-	draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
-	draw_update(dr, 0, 0, ww, wh);
-	ds->started = true;
-    }
 
     /*
      * Loop over the grid and work out where all the slashes are.
--- a/solo.c
+++ b/solo.c
@@ -5175,14 +5175,6 @@
 
     if (!ds->started) {
 	/*
-	 * The initial contents of the window are not guaranteed
-	 * and can vary with front ends. To be on the safe side,
-	 * all games should start by drawing a big
-	 * background-colour rectangle covering the whole window.
-	 */
-	draw_rect(dr, 0, 0, SIZE(cr), SIZE(cr), COL_BACKGROUND);
-
-	/*
 	 * Draw the grid. We draw it as a big thick rectangle of
 	 * COL_GRID initially; individual calls to draw_number()
 	 * will poke the right-shaped holes in it.
--- a/tents.c
+++ b/tents.c
@@ -1461,7 +1461,6 @@
 
 struct game_drawstate {
     int tilesize;
-    bool started;
     game_params p;
     int *drawn, *numbersdrawn;
     int cx, cy;         /* last-drawn cursor pos, or (-1,-1) if absent. */
@@ -1940,7 +1939,6 @@
     int i;
 
     ds->tilesize = 0;
-    ds->started = false;
     ds->p = state->p;                  /* structure copy */
     ds->drawn = snewn(w*h, int);
     for (i = 0; i < w*h; i++)
@@ -2410,21 +2408,11 @@
       if (cx != ds->cx || cy != ds->cy) cmoved = true;
     }
 
-    if (printing || !ds->started) {
-	if (!printing) {
-	    int ww, wh;
-	    game_compute_size(&state->p, TILESIZE, &ww, &wh);
-	    draw_rect(dr, 0, 0, ww, wh, COL_BACKGROUND);
-	    draw_update(dr, 0, 0, ww, wh);
-	    ds->started = true;
-	}
-
-	if (printing)
-	    print_line_width(dr, TILESIZE/64);
-
+    if (printing) {
         /*
          * Draw the grid.
          */
+        print_line_width(dr, TILESIZE/64);
         for (y = 0; y <= h; y++)
             draw_line(dr, COORD(0), COORD(y), COORD(w), COORD(y), COL_GRID);
         for (x = 0; x <= w; x++)
--- a/towers.c
+++ b/towers.c
@@ -1222,7 +1222,6 @@
 struct game_drawstate {
     int tilesize;
     bool three_d;       /* default 3D graphics are user-disableable */
-    bool started;
     long *tiles;		       /* (w+2)*(w+2) temp space */
     long *drawn;		       /* (w+2)*(w+2)*4: current drawn data */
     bool *errtmp;
@@ -1615,7 +1614,6 @@
 
     ds->tilesize = 0;
     ds->three_d = !getenv("TOWERS_2D");
-    ds->started = false;
     ds->tiles = snewn((w+2)*(w+2), long);
     ds->drawn = snewn((w+2)*(w+2)*4, long);
     for (i = 0; i < (w+2)*(w+2)*4; i++)
@@ -1820,20 +1818,6 @@
 {
     int w = state->par.w /*, a = w*w */;
     int i, x, y;
-
-    if (!ds->started) {
-	/*
-	 * The initial contents of the window are not guaranteed and
-	 * can vary with front ends. To be on the safe side, all
-	 * games should start by drawing a big background-colour
-	 * rectangle covering the whole window.
-	 */
-	draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND);
-
-	draw_update(dr, 0, 0, SIZE(w), SIZE(w));
-
-	ds->started = true;
-    }
 
     check_errors(state, ds->errtmp);
 
--- a/tracks.c
+++ b/tracks.c
@@ -2782,15 +2782,6 @@
     game_state *drag_state = NULL;
 
     if (!ds->started) {
-        /*
-         * The initial contents of the window are not guaranteed and
-         * can vary with front ends. To be on the safe side, all games
-         * should start by drawing a big background-colour rectangle
-         * covering the whole window.
-         */
-        draw_rect(dr, 0, 0, (w+2)*TILE_SIZE + 2*BORDER, (h+2)*TILE_SIZE + 2*BORDER,
-                  COL_BACKGROUND);
-
         draw_loop_ends(dr, ds, state, COL_CLUE);
 
         draw_rect(dr, COORD(0) - GRID_LINE_BR, COORD(0) - GRID_LINE_BR,
--- a/twiddle.c
+++ b/twiddle.c
@@ -1133,13 +1133,6 @@
     if (!ds->started) {
         int coords[10];
 
-	draw_rect(dr, 0, 0,
-		  TILE_SIZE * state->w + 2 * BORDER,
-		  TILE_SIZE * state->h + 2 * BORDER, COL_BACKGROUND);
-	draw_update(dr, 0, 0,
-		    TILE_SIZE * state->w + 2 * BORDER,
-		    TILE_SIZE * state->h + 2 * BORDER);
-
         /*
          * Recessed area containing the whole puzzle.
          */
--- a/undead.c
+++ b/undead.c
@@ -2605,8 +2605,6 @@
 
     /* Draw static grid components at startup */    
     if (!ds->started) { 
-        draw_rect(dr, 0, 0, 2*BORDER+(ds->w+2)*TILESIZE,
-                  2*BORDER+(ds->h+3)*TILESIZE, COL_BACKGROUND);
         draw_rect(dr, BORDER+TILESIZE-1, BORDER+2*TILESIZE-1,
                   (ds->w)*TILESIZE +3, (ds->h)*TILESIZE +3, COL_GRID);
         for (i=0;i<ds->w;i++)
--- a/unfinished/group.c
+++ b/unfinished/group.c
@@ -2057,14 +2057,6 @@
 
     if (!ds->started) {
 	/*
-	 * The initial contents of the window are not guaranteed and
-	 * can vary with front ends. To be on the safe side, all
-	 * games should start by drawing a big background-colour
-	 * rectangle covering the whole window.
-	 */
-	draw_rect(dr, 0, 0, SIZE(w), SIZE(w), COL_BACKGROUND);
-
-	/*
 	 * Big containing rectangle.
 	 */
 	draw_rect(dr, COORD(0) - GRIDEXTRA, COORD(0) - GRIDEXTRA,
--- a/unfinished/separate.c
+++ b/unfinished/separate.c
@@ -778,13 +778,6 @@
                         int dir, const game_ui *ui,
                         float animtime, float flashtime)
 {
-    /*
-     * The initial contents of the window are not guaranteed and
-     * can vary with front ends. To be on the safe side, all games
-     * should start by drawing a big background-colour rectangle
-     * covering the whole window.
-     */
-    draw_rect(dr, 0, 0, 10*ds->tilesize, 10*ds->tilesize, COL_BACKGROUND);
 }
 
 static float game_anim_length(const game_state *oldstate,
--- a/unfinished/slide.c
+++ b/unfinished/slide.c
@@ -1242,7 +1242,6 @@
     int tilesize;
     int w, h;
     unsigned long *grid;	       /* what's currently displayed */
-    bool started;
 };
 
 static char *interpret_move(const game_state *state, game_ui *ui,
@@ -1680,7 +1679,6 @@
     ds->tilesize = 0;
     ds->w = w;
     ds->h = h;
-    ds->started = false;
     ds->grid = snewn(wh, unsigned long);
     for (i = 0; i < wh; i++)
 	ds->grid[i] = ~(unsigned long)0;
@@ -2128,17 +2126,6 @@
     unsigned char *board;
     int *dsf;
     int x, y, mainanchor, mainpos, dragpos, solvepos, solvesrc, solvedst;
-
-    if (!ds->started) {
-	/*
-	 * The initial contents of the window are not guaranteed
-	 * and can vary with front ends. To be on the safe side,
-	 * all games should start by drawing a big
-	 * background-colour rectangle covering the whole window.
-	 */
-	draw_rect(dr, 0, 0, 10*ds->tilesize, 10*ds->tilesize, COL_BACKGROUND);
-	ds->started = true;
-    }
 
     /*
      * Construct the board we'll be displaying (which may be
--- a/unfinished/sokoban.c
+++ b/unfinished/sokoban.c
@@ -1353,15 +1353,6 @@
      * Initialise a fresh drawstate.
      */
     if (!ds->started) {
-	int wid, ht;
-
-	/*
-	 * Blank out the window initially.
-	 */
-	game_compute_size(&ds->p, TILESIZE, &wid, &ht);
-	draw_rect(dr, 0, 0, wid, ht, COL_BACKGROUND);
-	draw_update(dr, 0, 0, wid, ht);
-
 	/*
 	 * Draw the grid lines.
 	 */
--- a/unruly.c
+++ b/unruly.c
@@ -1788,9 +1788,6 @@
     int x, y, i;
 
     if (!ds->started) {
-        /* Main window background */
-        draw_rect(dr, 0, 0, TILE_SIZE * (w2+1), TILE_SIZE * (h2+1),
-                  COL_BACKGROUND);
         /* Outer edge of grid */
         draw_rect(dr, COORD(0)-TILE_SIZE/10, COORD(0)-TILE_SIZE/10,
                   TILE_SIZE*w2 + 2*(TILE_SIZE/10) - 1,