mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
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]
This commit is contained in:
6
cube.c
6
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 {
|
struct game_drawstate {
|
||||||
int ox, oy; /* pixel position of float origin */
|
int ox, oy; /* pixel position of float origin */
|
||||||
};
|
};
|
||||||
@ -1637,6 +1642,7 @@ const struct game thegame = {
|
|||||||
FALSE, game_text_format,
|
FALSE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button) {
|
int x, int y, int button) {
|
||||||
int gx, gy, dx, dy, ux, uy, up, p;
|
int gx, gy, dx, dy, ux, uy, up, p;
|
||||||
@ -835,6 +840,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
16
midend.c
16
midend.c
@ -228,6 +228,10 @@ void midend_new_game(midend_data *me)
|
|||||||
static int midend_undo(midend_data *me)
|
static int midend_undo(midend_data *me)
|
||||||
{
|
{
|
||||||
if (me->statepos > 1) {
|
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->statepos--;
|
||||||
me->dir = -1;
|
me->dir = -1;
|
||||||
return 1;
|
return 1;
|
||||||
@ -238,6 +242,10 @@ static int midend_undo(midend_data *me)
|
|||||||
static int midend_redo(midend_data *me)
|
static int midend_redo(midend_data *me)
|
||||||
{
|
{
|
||||||
if (me->statepos < me->nstates) {
|
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->statepos++;
|
||||||
me->dir = +1;
|
me->dir = +1;
|
||||||
return 1;
|
return 1;
|
||||||
@ -308,6 +316,10 @@ void midend_restart_game(midend_data *me)
|
|||||||
me->states[me->nstates].state = s;
|
me->states[me->nstates].state = s;
|
||||||
me->states[me->nstates].special = TRUE; /* we just restarted */
|
me->states[me->nstates].special = TRUE; /* we just restarted */
|
||||||
me->statepos = ++me->nstates;
|
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;
|
me->anim_time = 0.0;
|
||||||
midend_finish_move(me);
|
midend_finish_move(me);
|
||||||
midend_redraw(me);
|
midend_redraw(me);
|
||||||
@ -936,6 +948,10 @@ char *midend_solve(midend_data *me)
|
|||||||
me->states[me->nstates].state = s;
|
me->states[me->nstates].state = s;
|
||||||
me->states[me->nstates].special = TRUE; /* created using solve */
|
me->states[me->nstates].special = TRUE; /* created using solve */
|
||||||
me->statepos = ++me->nstates;
|
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;
|
me->anim_time = 0.0;
|
||||||
midend_finish_move(me);
|
midend_finish_move(me);
|
||||||
midend_redraw(me);
|
midend_redraw(me);
|
||||||
|
6
mines.c
6
mines.c
@ -2475,6 +2475,11 @@ static void free_ui(game_ui *ui)
|
|||||||
sfree(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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button)
|
int x, int y, int button)
|
||||||
{
|
{
|
||||||
@ -3044,6 +3049,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
6
net.c
6
net.c
@ -1786,6 +1786,11 @@ static void free_ui(game_ui *ui)
|
|||||||
sfree(ui);
|
sfree(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void game_changed_state(game_ui *ui, game_state *oldstate,
|
||||||
|
game_state *newstate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* Process a move.
|
* Process a move.
|
||||||
*/
|
*/
|
||||||
@ -2591,6 +2596,7 @@ const struct game thegame = {
|
|||||||
FALSE, game_text_format,
|
FALSE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -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);
|
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,
|
static game_state *make_move(game_state *state, game_ui *ui,
|
||||||
game_drawstate *ds, int x, int y, int button)
|
game_drawstate *ds, int x, int y, int button)
|
||||||
{
|
{
|
||||||
@ -1749,6 +1754,7 @@ const struct game thegame = {
|
|||||||
FALSE, game_text_format,
|
FALSE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button)
|
int x, int y, int button)
|
||||||
{
|
{
|
||||||
@ -244,6 +249,7 @@ const struct game thegame = {
|
|||||||
FALSE, game_text_format,
|
FALSE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -758,6 +758,11 @@ static void free_ui(game_ui *ui)
|
|||||||
sfree(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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button) {
|
int x, int y, int button) {
|
||||||
game_state *ret;
|
game_state *ret;
|
||||||
@ -1127,6 +1132,7 @@ const struct game thegame = {
|
|||||||
FALSE, game_text_format,
|
FALSE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -252,6 +252,8 @@ struct game {
|
|||||||
char *(*text_format)(game_state *state);
|
char *(*text_format)(game_state *state);
|
||||||
game_ui *(*new_ui)(game_state *state);
|
game_ui *(*new_ui)(game_state *state);
|
||||||
void (*free_ui)(game_ui *ui);
|
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,
|
game_state *(*make_move)(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button);
|
int x, int y, int button);
|
||||||
void (*size)(game_params *params, int *x, int *y);
|
void (*size)(game_params *params, int *x, int *y);
|
||||||
|
6
rect.c
6
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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button) {
|
int x, int y, int button) {
|
||||||
int xc, yc;
|
int xc, yc;
|
||||||
@ -2549,6 +2554,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button) {
|
int x, int y, int button) {
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
@ -1006,6 +1011,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
17
solo.c
17
solo.c
@ -1853,6 +1853,22 @@ static void free_ui(game_ui *ui)
|
|||||||
sfree(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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button)
|
int x, int y, int button)
|
||||||
{
|
{
|
||||||
@ -2278,6 +2294,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
@ -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,
|
static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
|
||||||
int x, int y, int button)
|
int x, int y, int button)
|
||||||
{
|
{
|
||||||
@ -1174,6 +1179,7 @@ const struct game thegame = {
|
|||||||
TRUE, game_text_format,
|
TRUE, game_text_format,
|
||||||
new_ui,
|
new_ui,
|
||||||
free_ui,
|
free_ui,
|
||||||
|
game_changed_state,
|
||||||
make_move,
|
make_move,
|
||||||
game_size,
|
game_size,
|
||||||
game_colours,
|
game_colours,
|
||||||
|
Reference in New Issue
Block a user