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;