shithub: puzzles

Download patch

ref: 3b250baa02a7332510685948bf17576c397b8ceb
parent: 55748a60cbd964f697f84ed57c8fc5299406fcdf
author: Simon Tatham <anakin@pobox.com>
date: Sun Sep 9 14:40:12 EDT 2012

New rule: interpret_move() is passed a pointer to the game_drawstate
basically just so that it can divide mouse coordinates by the tile
size, but is definitely not expected to _write_ to it, and it hadn't
previously occurred to me that anyone might try. Therefore,
interpret_move() now gets a pointer to a _const_ game_drawstate
instead of a writable one.

All existing puzzles cope fine with this API change (as long as the
new const qualifier is also added to a couple of subfunctions to which
interpret_move delegates work), except for the just-committed Undead,
which somehow had ds->ascii and ui->ascii the wrong way round but is
otherwise unproblematic.

[originally from svn r9657]

--- a/blackbox.c
+++ b/blackbox.c
@@ -879,7 +879,7 @@
     int flash_laserno, isflash;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int gx = -1, gy = -1, rangeno = -1, wouldflash = 0;
--- a/bridges.c
+++ b/bridges.c
@@ -2157,8 +2157,8 @@
     int show_hints;
 };
 
-static char *update_drag_dst(game_state *state, game_ui *ui, game_drawstate *ds,
-                            int nx, int ny)
+static char *update_drag_dst(game_state *state, game_ui *ui,
+                             const game_drawstate *ds, int nx, int ny)
 {
     int ox, oy, dx, dy, i, currl, maxb;
     struct island *is;
@@ -2253,7 +2253,7 @@
     return dupstr(buf);
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int gx = FROMCOORD(x), gy = FROMCOORD(y);
--- a/cube.c
+++ b/cube.c
@@ -1100,7 +1100,7 @@
     return dest;
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int direction, mask, i;
--- a/devel.but
+++ b/devel.but
@@ -856,7 +856,7 @@
 \S{backend-interpret-move} \cw{interpret_move()}
 
 \c char *(*interpret_move)(game_state *state, game_ui *ui,
-\c                         game_drawstate *ds,
+\c                         const game_drawstate *ds,
 \c                         int x, int y, int button);
 
 This function receives user input and processes it. Its input
@@ -867,6 +867,11 @@
 \c{button} is a mouse event, \c{x} and \c{y} contain the pixel
 coordinates of the mouse pointer relative to the top left of the
 puzzle's drawing area.
+
+(The pointer to the \c{game_drawstate} is marked \c{const}, because
+\c{interpret_move} should not write to it. The normal use of that
+pointer will be to read the game's tile size parameter in order to
+divide mouse coordinates by it.)
 
 \cw{interpret_move()} may return in three different ways:
 
--- a/dominosa.c
+++ b/dominosa.c
@@ -1001,7 +1001,7 @@
     unsigned long *visible;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->w, h = state->h;
--- a/fifteen.c
+++ b/fifteen.c
@@ -460,7 +460,7 @@
     int tilesize;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int gx, gy, dx, dy;
--- a/filling.c
+++ b/filling.c
@@ -1036,7 +1036,7 @@
     int *dsf_scratch, *border_scratch;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
                             int x, int y, int button)
 {
     const int w = state->shared->params.w;
--- a/flip.c
+++ b/flip.c
@@ -899,7 +899,7 @@
     int tilesize;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->w, h = state->h, wh = w * h;
--- a/galaxies.c
+++ b/galaxies.c
@@ -2369,7 +2369,7 @@
 #endif
 
 #ifdef EDITOR
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     char buf[80];
@@ -2404,7 +2404,7 @@
     return NULL;
 }
 #else
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     /* UI operations (play mode):
--- a/guess.c
+++ b/guess.c
@@ -632,7 +632,7 @@
     return buf;
 }
 
-static char *interpret_move(game_state *from, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *from, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int over_col = 0;           /* one-indexed */
--- a/inertia.c
+++ b/inertia.c
@@ -1534,7 +1534,7 @@
 #define COORD(x)  ( (x) * TILESIZE + BORDER )
 #define FROMCOORD(x)  ( ((x) - BORDER + TILESIZE) / TILESIZE - 1 )
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->p.w, h = state->p.h /*, wh = w*h */;
--- a/keen.c
+++ b/keen.c
@@ -1512,7 +1512,7 @@
     return errs;
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->par.w;
--- a/lightup.c
+++ b/lightup.c
@@ -1871,7 +1871,7 @@
             (pc)) -1 (nil)
         (nil))
  */
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     enum { NONE, FLIP_LIGHT, FLIP_IMPOSSIBLE } action = NONE;
--- a/loopy.c
+++ b/loopy.c
@@ -2813,7 +2813,7 @@
  * Drawing and mouse-handling
  */
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
                             int x, int y, int button)
 {
     grid *g = state->game_grid;
--- a/magnets.c
+++ b/magnets.c
@@ -1754,7 +1754,7 @@
 #define COORD(x) ( (x+1) * TILE_SIZE + BORDER )
 #define FROMCOORD(x) ( (x - BORDER) / TILE_SIZE - 1 )
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int gx = FROMCOORD(x), gy = FROMCOORD(y), idx, curr;
--- a/map.c
+++ b/map.c
@@ -2342,7 +2342,7 @@
                            ((button) == CURSOR_UP)    ? -1 : 0)
 
 
-static int region_from_coords(game_state *state, game_drawstate *ds,
+static int region_from_coords(game_state *state, const game_drawstate *ds,
                               int x, int y)
 {
     int w = state->p.w, h = state->p.h, wh = w*h /*, n = state->p.n */;
@@ -2361,7 +2361,7 @@
     return state->map->map[quadrant * wh + ty*w+tx];
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     char *bufp, buf[256];
--- a/mines.c
+++ b/mines.c
@@ -2415,7 +2415,7 @@
     int cur_x, cur_y; /* -1, -1 for no cursor displayed. */
 };
 
-static char *interpret_move(game_state *from, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *from, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int cx, cy;
--- a/net.c
+++ b/net.c
@@ -1922,7 +1922,7 @@
  * Process a move.
  */
 static char *interpret_move(game_state *state, game_ui *ui,
-			    game_drawstate *ds, int x, int y, int button)
+			    const game_drawstate *ds, int x, int y, int button)
 {
     char *nullret;
     int tx = -1, ty = -1, dir = 0;
--- a/netslide.c
+++ b/netslide.c
@@ -1056,7 +1056,7 @@
 };
 
 static char *interpret_move(game_state *state, game_ui *ui,
-			    game_drawstate *ds, int x, int y, int button)
+			    const game_drawstate *ds, int x, int y, int button)
 {
     int cx, cy;
     int dx, dy;
--- a/nullgame.c
+++ b/nullgame.c
@@ -161,7 +161,7 @@
     int FIXME;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     return NULL;
--- a/pattern.c
+++ b/pattern.c
@@ -833,7 +833,7 @@
     int cur_x, cur_y;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     button &= ~MOD_MASK;
--- a/pearl.c
+++ b/pearl.c
@@ -1962,7 +1962,7 @@
     (btn) == CURSOR_DOWN ? D : (btn) == CURSOR_UP ? U :\
     (btn) == CURSOR_LEFT ? L : R)
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->shared->w, h = state->shared->h /*, sz = state->shared->sz */;
--- a/pegs.c
+++ b/pegs.c
@@ -814,7 +814,7 @@
     int bgcolour;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->w, h = state->h;
--- a/puzzles.h
+++ b/puzzles.h
@@ -499,8 +499,8 @@
     void (*decode_ui)(game_ui *ui, char *encoding);
     void (*changed_state)(game_ui *ui, game_state *oldstate,
                           game_state *newstate);
-    char *(*interpret_move)(game_state *state, game_ui *ui, game_drawstate *ds,
-			    int x, int y, int button);
+    char *(*interpret_move)(game_state *state, game_ui *ui,
+                            const game_drawstate *ds, int x, int y, int button);
     game_state *(*execute_move)(game_state *state, char *move);
     int preferred_tilesize;
     void (*compute_size)(game_params *params, int tilesize, int *x, int *y);
--- a/range.c
+++ b/range.c
@@ -1248,7 +1248,7 @@
 #define COORD(x) ((x) * TILESIZE + BORDER)
 #define FROMCOORD(x) (((x) - BORDER) / TILESIZE)
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
                             int x, int y, int button)
 {
     enum {none, forwards, backwards, hint};
--- a/rect.c
+++ b/rect.c
@@ -2365,7 +2365,7 @@
     unsigned long *visible;
 };
 
-static char *interpret_move(game_state *from, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *from, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int xc, yc;
--- a/samegame.c
+++ b/samegame.c
@@ -1267,7 +1267,7 @@
     int *tiles; /* contains colour and SELECTED. */
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int tx, ty;
--- a/signpost.c
+++ b/signpost.c
@@ -1418,7 +1418,7 @@
     blitter *dragb;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int mx, int my, int button)
 {
     int x = FROMCOORD(mx), y = FROMCOORD(my), w = state->w;
--- a/singles.c
+++ b/singles.c
@@ -1471,7 +1471,7 @@
     unsigned int *flags;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int mx, int my, int button)
 {
     char buf[80], c;
--- a/sixteen.c
+++ b/sixteen.c
@@ -595,7 +595,7 @@
     int cur_x, cur_y;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int cx = -1, cy = -1, dx, dy;
--- a/slant.c
+++ b/slant.c
@@ -1666,7 +1666,7 @@
     long *todraw;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->p.w, h = state->p.h;
--- a/solo.c
+++ b/solo.c
@@ -4511,7 +4511,7 @@
     int nregions, *entered_items;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int cr = state->cr;
--- a/tents.c
+++ b/tents.c
@@ -1520,7 +1520,7 @@
     return v;
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->p.w, h = state->p.h;
--- a/towers.c
+++ b/towers.c
@@ -1255,7 +1255,7 @@
     return errs;
 }
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->par.w;
--- a/twiddle.c
+++ b/twiddle.c
@@ -640,7 +640,7 @@
     int cur_x, cur_y;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int w = state->w, h = state->h, n = state->n /* , wh = w*h */;
--- a/undead.c
+++ b/undead.c
@@ -1646,8 +1646,9 @@
 #define TILESIZE (ds->tilesize)
 #define BORDER (TILESIZE/2)
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
-                            int x, int y, int button) {
+static char *interpret_move(game_state *state, game_ui *ui,
+                            const game_drawstate *ds, int x, int y, int button)
+{
     int gx,gy;
     int g,xi;
     char buf[80]; 
@@ -1656,7 +1657,7 @@
     gy = ((y-BORDER-2) / TILESIZE ) - 1;
 
     if (button == 'a' || button == 'A') {
-        ds->ascii = ui->ascii ? FALSE : TRUE;
+        ui->ascii = !ui->ascii;
         return "";      
     }
     
@@ -2395,7 +2396,7 @@
             game_state *state, int dir, game_ui *ui,
             float animtime, float flashtime) {
     int i,j,x,y,xy;
-    int stale, xi, c, hflash, hchanged;
+    int stale, xi, c, hflash, hchanged, changed_ascii;
 
     hflash = (int)(flashtime * 5 / FLASH_TIME) % 2;
 
@@ -2419,6 +2420,11 @@
         ds->hshow != ui->hshow || ds->hpencil != ui->hpencil)
         hchanged = TRUE;
 
+    if (ds->ascii != ui->ascii) {
+        ds->ascii = ui->ascii;
+        changed_ascii = TRUE;
+    }
+
     /* Draw monster count hints */
 
     for (i=0;i<3;i++) {
@@ -2425,7 +2431,7 @@
         stale = FALSE;
         if (!ds->started) stale = TRUE;
         if (ds->hflash != hflash) stale = TRUE;
-        if (ds->ascii != ui->ascii) stale = TRUE;
+        if (changed_ascii) stale = TRUE;
         if (ds->count_errors[i] != state->count_errors[i]) {
             stale = TRUE;
             ds->count_errors[i] = state->count_errors[i];
@@ -2481,7 +2487,7 @@
     
         if (!ds->started) stale = TRUE;
         if (ds->hflash != hflash) stale = TRUE;
-        if (ds->ascii != ui->ascii) stale = TRUE;
+        if (changed_ascii) stale = TRUE;
         
         if (hchanged) {
             if ((x == ui->hx && y == ui->hy) ||
@@ -2520,7 +2526,6 @@
     ds->hshow = ui->hshow;
     ds->hpencil = ui->hpencil;
     ds->hflash = hflash;
-    ui->ascii = ds->ascii;
     ds->started = TRUE;
     return;
 }
--- a/unequal.c
+++ b/unequal.c
@@ -1371,7 +1371,7 @@
     int hflash;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int ox, int oy, int button)
 {
     int x = FROMCOORD(ox), y = FROMCOORD(oy), n;
--- a/untangle.c
+++ b/untangle.c
@@ -1072,7 +1072,7 @@
     long *x, *y;
 };
 
-static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
+static char *interpret_move(game_state *state, game_ui *ui, const game_drawstate *ds,
 			    int x, int y, int button)
 {
     int n = state->params.n;