I've dithered a bit in the past about whether or not it's allowable
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 5 Sep 2005 17:18:03 +0000 (17:18 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 5 Sep 2005 17:18:03 +0000 (17:18 +0000)
to call game_set_size() twice on the same drawstate. Finally, a
definite decision: it isn't. Accordingly, midend.c arranges never to
do so, the devel docs state that puzzles may enforce by assertion
that it never happens, and the four puzzles which care (i.e. use
blitters) do so.

git-svn-id: svn://svn.tartarus.org/sgt/puzzles@6274 cda61777-01e9-0310-a592-d414129be87e

devel.but
guess.c
inertia.c
map.c
midend.c
pegs.c

index ed5c914..ef43baa 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -1097,6 +1097,11 @@ allocating a blitter (see \k{drawing-blitter}).
 The parameter \c{dr} is a drawing object (see \k{drawing}), which is
 required if a blitter needs to be allocated.
 
+Back ends may assume (and may enforce by assertion) that this
+function will be called at most once for any \c{game_drawstate}. If
+a puzzle needs to be redrawn at a different size, the mid-end will
+create a fresh drawstate.
+
 \S{backend-colours} \cw{colours()}
 
 \c float *(*colours)(frontend *fe, game_state *state, int *ncolours);
@@ -4115,9 +4120,7 @@ piece of saved background needs to be.
 
 \b In the game's \cw{set_size()} function, once you know the size of
 the object you'll be dragging around the display and hence the
-required size of the blitter, actually allocate the blitter (making
-sure to free a previous one if present \dash it's possible that
-\cw{set_size()} might be called twice on the same draw state).
+required size of the blitter, actually allocate the blitter.
 
 \b In \cw{free_drawstate()}, free the blitter if it's not \cw{NULL}.
 
diff --git a/guess.c b/guess.c
index 778a6f5..aa37049 100644 (file)
--- a/guess.c
+++ b/guess.c
@@ -860,7 +860,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
     ds->solny = ds->guessy + ((ds->pegsz + ds->gapsz) * params->nguesses) + ds->gapsz;
 
     assert(ds->pegsz > 0);
-    if (ds->blit_peg) blitter_free(dr, ds->blit_peg);
+    assert(!ds->blit_peg);             /* set_size is never called twice */
     ds->blit_peg = blitter_new(dr, ds->pegsz, ds->pegsz);
 }
 
index 95bdcc8..b490e04 100644 (file)
--- a/inertia.c
+++ b/inertia.c
@@ -875,10 +875,9 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
 {
     ds->tilesize = tilesize;
 
+    assert(!ds->player_background);    /* set_size is never called twice */
     assert(!ds->player_bg_saved);
 
-    if (ds->player_background)
-       blitter_free(dr, ds->player_background);
     ds->player_background = blitter_new(dr, TILESIZE, TILESIZE);
 }
 
diff --git a/map.c b/map.c
index e850d01..ef17efb 100644 (file)
--- a/map.c
+++ b/map.c
@@ -2505,8 +2505,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
 {
     ds->tilesize = tilesize;
 
-    if (ds->bl)
-        blitter_free(dr, ds->bl);
+    assert(!ds->bl);                   /* set_size is never called twice */
     ds->bl = blitter_new(dr, TILESIZE+3, TILESIZE+3);
 }
 
index 1f564f3..64edfd3 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -218,6 +218,17 @@ void midend_size(midend *me, int *x, int *y, int expand)
     int rx, ry;
 
     /*
+     * We can't set the size on the same drawstate twice. So if
+     * we've already sized one drawstate, we must throw it away and
+     * create a new one.
+     */
+    if (me->drawstate && me->tilesize > 0) {
+        me->ourgame->free_drawstate(me->drawing, me->drawstate);
+        me->drawstate = me->ourgame->new_drawstate(me->drawing,
+                                                   me->states[0].state);
+    }
+
+    /*
      * Find the tile size that best fits within the given space. If
      * `expand' is TRUE, we must actually find the _largest_ such
      * tile size; otherwise, we bound above at the game's preferred
diff --git a/pegs.c b/pegs.c
index 427633a..e4549db 100644 (file)
--- a/pegs.c
+++ b/pegs.c
@@ -936,8 +936,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
 
     assert(TILESIZE > 0);
 
-    if (ds->drag_background)
-       blitter_free(dr, ds->drag_background);
+    assert(!ds->drag_background);      /* set_size is never called twice */
     ds->drag_background = blitter_new(dr, TILESIZE, TILESIZE);
 }