aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2005-06-06 11:21:36 +0000
committerSimon Tatham <anakin@pobox.com>2005-06-06 11:21:36 +0000
commit69f7e7f8f5890946f4625fc071eb3f8313b17238 (patch)
tree6d6dfa8255a2d7a2b5a3529bb3b9a4b0f6101e66
parent57b3982c83694eb61dd97762ecfb3d53eeabf4f4 (diff)
downloadpuzzles-69f7e7f8f5890946f4625fc071eb3f8313b17238.zip
puzzles-69f7e7f8f5890946f4625fc071eb3f8313b17238.tar.gz
puzzles-69f7e7f8f5890946f4625fc071eb3f8313b17238.tar.bz2
puzzles-69f7e7f8f5890946f4625fc071eb3f8313b17238.tar.xz
Introduce a new game backend function (there seem to have been a lot
of these recently) whose job is to update a game_ui to be consistent with a new game_state. This is called by midend.c in every situation where the current game_state changes _other_ than as a result of make_move (Undo, Redo, Restart, Solve). The introduction of this function allows a game_ui to contain information about selections or highlights within a game_state which simply wouldn't make sense when transferred to another game_state. In particular, I've used it to fix a subtle bug in Solo whereby, although you couldn't right-click to pencil-mode highlight a filled square, you could _get_ a pencil-mode highlight in a filled square if you used Undo and Redo. (Undo to before the square was filled, right-click to highlight it, then Redo. Alternatively, left-click and clear the square, right-click to highlight it, then Undo.) [originally from svn r5912]
-rw-r--r--cube.c6
-rw-r--r--fifteen.c6
-rw-r--r--midend.c16
-rw-r--r--mines.c6
-rw-r--r--net.c6
-rw-r--r--netslide.c6
-rw-r--r--nullgame.c6
-rw-r--r--pattern.c6
-rw-r--r--puzzles.h2
-rw-r--r--rect.c6
-rw-r--r--sixteen.c6
-rw-r--r--solo.c17
-rw-r--r--twiddle.c6
13 files changed, 95 insertions, 0 deletions
diff --git a/cube.c b/cube.c
index 0ff952f..ffefa2f 100644
--- a/cube.c
+++ b/cube.c
@@ -1003,6 +1003,11 @@ static void free_ui(game_ui *ui)
{
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
struct game_drawstate {
int ox, oy; /* pixel position of float origin */
};
@@ -1637,6 +1642,7 @@ const struct game thegame = {
FALSE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/fifteen.c b/fifteen.c
index bf2cdf1..a6402c9 100644
--- a/fifteen.c
+++ b/fifteen.c
@@ -451,6 +451,11 @@ static void free_ui(game_ui *ui)
{
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button) {
int gx, gy, dx, dy, ux, uy, up, p;
@@ -835,6 +840,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/midend.c b/midend.c
index b6b1720..d8960a7 100644
--- a/midend.c
+++ b/midend.c
@@ -228,6 +228,10 @@ void midend_new_game(midend_data *me)
static int midend_undo(midend_data *me)
{
if (me->statepos > 1) {
+ if (me->ui)
+ me->ourgame->changed_state(me->ui,
+ me->states[me->statepos-1].state,
+ me->states[me->statepos-2].state);
me->statepos--;
me->dir = -1;
return 1;
@@ -238,6 +242,10 @@ static int midend_undo(midend_data *me)
static int midend_redo(midend_data *me)
{
if (me->statepos < me->nstates) {
+ if (me->ui)
+ me->ourgame->changed_state(me->ui,
+ me->states[me->statepos-1].state,
+ me->states[me->statepos].state);
me->statepos++;
me->dir = +1;
return 1;
@@ -308,6 +316,10 @@ void midend_restart_game(midend_data *me)
me->states[me->nstates].state = s;
me->states[me->nstates].special = TRUE; /* we just restarted */
me->statepos = ++me->nstates;
+ if (me->ui)
+ me->ourgame->changed_state(me->ui,
+ me->states[me->statepos-2].state,
+ me->states[me->statepos-1].state);
me->anim_time = 0.0;
midend_finish_move(me);
midend_redraw(me);
@@ -936,6 +948,10 @@ char *midend_solve(midend_data *me)
me->states[me->nstates].state = s;
me->states[me->nstates].special = TRUE; /* created using solve */
me->statepos = ++me->nstates;
+ if (me->ui)
+ me->ourgame->changed_state(me->ui,
+ me->states[me->statepos-2].state,
+ me->states[me->statepos-1].state);
me->anim_time = 0.0;
midend_finish_move(me);
midend_redraw(me);
diff --git a/mines.c b/mines.c
index 4b9620e..286f76d 100644
--- a/mines.c
+++ b/mines.c
@@ -2475,6 +2475,11 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
@@ -3044,6 +3049,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/net.c b/net.c
index 8a4f706..fe9b846 100644
--- a/net.c
+++ b/net.c
@@ -1786,6 +1786,11 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
/* ----------------------------------------------------------------------
* Process a move.
*/
@@ -2591,6 +2596,7 @@ const struct game thegame = {
FALSE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/netslide.c b/netslide.c
index 0ab3e34..e6751fe 100644
--- a/netslide.c
+++ b/netslide.c
@@ -1045,6 +1045,11 @@ static void slide_col(game_state *state, int dir, int col)
slide_col_int(state->width, state->height, state->tiles, dir, col);
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *state, game_ui *ui,
game_drawstate *ds, int x, int y, int button)
{
@@ -1749,6 +1754,7 @@ const struct game thegame = {
FALSE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/nullgame.c b/nullgame.c
index 49173b6..3bcfe46 100644
--- a/nullgame.c
+++ b/nullgame.c
@@ -142,6 +142,11 @@ static void free_ui(game_ui *ui)
{
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
@@ -244,6 +249,7 @@ const struct game thegame = {
FALSE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/pattern.c b/pattern.c
index f8e8fc5..dd8626a 100644
--- a/pattern.c
+++ b/pattern.c
@@ -758,6 +758,11 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button) {
game_state *ret;
@@ -1127,6 +1132,7 @@ const struct game thegame = {
FALSE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/puzzles.h b/puzzles.h
index fbef531..1451f12 100644
--- a/puzzles.h
+++ b/puzzles.h
@@ -252,6 +252,8 @@ struct game {
char *(*text_format)(game_state *state);
game_ui *(*new_ui)(game_state *state);
void (*free_ui)(game_ui *ui);
+ void (*changed_state)(game_ui *ui, game_state *oldstate,
+ game_state *newstate);
game_state *(*make_move)(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button);
void (*size)(game_params *params, int *x, int *y);
diff --git a/rect.c b/rect.c
index 0448958..c040efa 100644
--- a/rect.c
+++ b/rect.c
@@ -2183,6 +2183,11 @@ static void ui_draw_rect(game_state *state, game_ui *ui,
}
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button) {
int xc, yc;
@@ -2549,6 +2554,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/sixteen.c b/sixteen.c
index feab05d..9a347fa 100644
--- a/sixteen.c
+++ b/sixteen.c
@@ -578,6 +578,11 @@ static void free_ui(game_ui *ui)
{
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button) {
int cx, cy;
@@ -1006,6 +1011,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/solo.c b/solo.c
index 97acf76..922f748 100644
--- a/solo.c
+++ b/solo.c
@@ -1853,6 +1853,22 @@ static void free_ui(game_ui *ui)
sfree(ui);
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+ int c = newstate->c, r = newstate->r, cr = c*r;
+ /*
+ * We prevent pencil-mode highlighting of a filled square. So
+ * if the user has just filled in a square which we had a
+ * pencil-mode highlight in (by Undo, or by Redo, or by Solve),
+ * then we cancel the highlight.
+ */
+ if (ui->hx >= 0 && ui->hy >= 0 && ui->hpencil &&
+ newstate->grid[ui->hy * cr + ui->hx] != 0) {
+ ui->hx = ui->hy = -1;
+ }
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
@@ -2278,6 +2294,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,
diff --git a/twiddle.c b/twiddle.c
index 9ac4a3a..b554879 100644
--- a/twiddle.c
+++ b/twiddle.c
@@ -616,6 +616,11 @@ static void free_ui(game_ui *ui)
{
}
+static void game_changed_state(game_ui *ui, game_state *oldstate,
+ game_state *newstate)
+{
+}
+
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
@@ -1174,6 +1179,7 @@ const struct game thegame = {
TRUE, game_text_format,
new_ui,
free_ui,
+ game_changed_state,
make_move,
game_size,
game_colours,