return ret;
}
-static char *validate_params(game_params *params)
+static char *validate_params(game_params *params, int full)
{
if (params->w < 1 || params->h < 1)
return "Width and height must both be positive";
game_state *newstate)
{
sel_clear(ui, newstate);
+
+ /*
+ * If the game state has just changed into an unplayable one
+ * (either completed or impossible), we vanish the keyboard-
+ * control cursor.
+ */
+ if (newstate->complete || newstate->impossible)
+ ui->displaysel = 0;
}
static char *sel_movedesc(game_ui *ui, game_state *state)
int *tiles; /* contains colour and SELECTED. */
};
-static game_state *execute_move(game_state *from, char *move);
-
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
int x, int y, int button)
{
if (ISSEL(ui,tx,ty)) {
if (button == RIGHT_BUTTON)
sel_clear(ui, state);
- else {
- game_state *tmp;
-
+ else
ret = sel_movedesc(ui, state);
-
- /*
- * Unfortunately, we must check for completeness or
- * impossibility now, in order to update the game_ui;
- * and we can't do that without constructing the new
- * grid. Sigh.
- */
- tmp = execute_move(state, ret);
- if (tmp->complete || tmp->impossible)
- ui->displaysel = 0;
- free_game(tmp);
- }
} else {
sel_clear(ui, state); /* might be no-op */
sel_expand(ui, state, tx, ty);
* Drawing routines.
*/
-static void game_size(game_params *params, game_drawstate *ds, int *x, int *y,
- int expand)
+static void game_set_size(game_drawstate *ds, game_params *params,
+ int tilesize)
{
- double tsx, tsy, ts;
-
- /*
- * We could choose the tile gap dynamically as well if we
- * wanted to; for example, at low tile sizes it might be
- * sensible to leave it out completely. However, for the moment
- * and for the sake of simplicity I'm just going to fix it at
- * 2.
- */
ds->tilegap = 2;
+ ds->tileinner = tilesize - ds->tilegap;
+}
- /*
- * Each window dimension equals the tile size (inner plus gap)
- * times the grid dimension, plus another tile size (border is
- * half the width of a tile), minus one tile gap.
- *
- * We must cast to unsigned before adding to *x and *y, since
- * they might be INT_MAX!
- */
- tsx = ((double)*x + (double)ds->tilegap) / ((double)params->w + 1.0);
- tsy = ((double)*y + (double)ds->tilegap) / ((double)params->h + 1.0);
-
- ts = min(tsx, tsy);
- if (expand)
- ds->tileinner = (int)(ts+0.5) - ds->tilegap;
- else
- ds->tileinner = min((int)ts, PREFERRED_TILE_SIZE) - ds->tilegap;
+static void game_compute_size(game_params *params, int tilesize,
+ int *x, int *y)
+{
+ /* Ick: fake up tile size variables for macro expansion purposes */
+ game_drawstate ads, *ds = &ads;
+ game_set_size(ds, params, tilesize);
*x = TILE_SIZE * params->w + 2 * BORDER - TILE_GAP;
*y = TILE_SIZE * params->h + 2 * BORDER - TILE_GAP;
coords[9] = COORD(state->params.h) + HIGHLIGHT_WIDTH - 1 - TILE_GAP;
coords[6] = coords[8] + TILE_SIZE;
coords[7] = coords[9] - TILE_SIZE;
- draw_polygon(fe, coords, 5, TRUE, COL_HIGHLIGHT);
- draw_polygon(fe, coords, 5, FALSE, COL_HIGHLIGHT);
+ draw_polygon(fe, coords, 5, COL_HIGHLIGHT, COL_HIGHLIGHT);
coords[1] = COORD(0) - HIGHLIGHT_WIDTH;
coords[0] = COORD(0) - HIGHLIGHT_WIDTH;
- draw_polygon(fe, coords, 5, TRUE, COL_LOWLIGHT);
- draw_polygon(fe, coords, 5, FALSE, COL_LOWLIGHT);
+ draw_polygon(fe, coords, 5, COL_LOWLIGHT, COL_LOWLIGHT);
ds->started = 1;
}
return TRUE;
}
-static int game_timing_state(game_state *state)
+static int game_timing_state(game_state *state, game_ui *ui)
{
return TRUE;
}
game_changed_state,
interpret_move,
execute_move,
- game_size,
+ PREFERRED_TILE_SIZE, game_compute_size, game_set_size,
game_colours,
game_new_drawstate,
game_free_drawstate,