return ret;
}
-static int game_fetch_preset(int i, char **name, game_params **params)
-{
- return FALSE;
-}
-
static void free_params(game_params *params)
{
sfree(params);
return ret;
}
+static const struct {
+ char *name;
+ game_params params;
+} guess_presets[] = {
+ {"Standard", {6, 4, 10, FALSE, TRUE}},
+ {"Super", {8, 5, 12, FALSE, TRUE}},
+};
+
+
+static int game_fetch_preset(int i, char **name, game_params **params)
+{
+ if (i < 0 || i >= lenof(guess_presets))
+ return FALSE;
+
+ *name = dupstr(guess_presets[i].name);
+ /*
+ * get round annoying const issues
+ */
+ {
+ game_params tmp = guess_presets[i].params;
+ *params = dup_params(&tmp);
+ }
+
+ return TRUE;
+}
+
static void decode_params(game_params *params, char const *string)
{
char const *p = string;
/* just clear the row-in-progress when we have an undo/redo. */
for (i = 0; i < ui->curr_pegs->npegs; i++)
ui->curr_pegs->pegs[i] = 0;
+ ui->markable = FALSE;
}
#define PEGSZ (ds->pegsz)
#define HINTSZ (ds->hintsz)
#define HINTOFF (ds->hintsz + ds->gapsz)
+#define GAP (ds->gapsz)
#define CGAP (ds->gapsz / 2)
#define PEGRAD (ds->pegrad)
#define HINT_OY (GUESS_OY + (PEGSZ - HINTOFF - HINTSZ) / 2)
#define HINT_X(g) HINT_OX
#define HINT_Y(g) (HINT_OY + (g)*PEGOFF)
-#define HINT_W (ds->hintw*HINTOFF)
+#define HINT_W ((ds->hintw*HINTOFF) - GAP)
#define HINT_H GUESS_H
#define SOLN_OX GUESS_OX
}
ui->drag_col = 0;
ui->drag_opeg = -1;
+ ui->display_cur = 0;
debug(("Stop dragging."));
ret = from;
} else if (button == RIGHT_BUTTON) {
ret = from;
} else if (button == CURSOR_SELECT || button == ' ' || button == '\r' ||
button == '\n') {
+ ui->display_cur = 1;
if (ui->peg_cur == from->params.npegs) {
ret = mark_move(from, ui);
} else {
ret = from;
}
} else if (button == 'H' || button == 'h') {
+ ui->display_cur = 1;
ui->holds[ui->peg_cur] = 1 - ui->holds[ui->peg_cur];
ret = from;
}
static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
- float *ret = snewn(3 * NCOLOURS, float);
+ float *ret = snewn(3 * NCOLOURS, float), max;
+ int i;
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
ret[COL_HOLD * 3 + 1] = 0.5F;
ret[COL_HOLD * 3 + 2] = 0.5F;
- ret[COL_EMPTY * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 2.0 / 3.0;
- ret[COL_EMPTY * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 2.0 / 3.0;
- ret[COL_EMPTY * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 2.0 / 3.0;
-
ret[COL_CORRECTPLACE*3 + 0] = 0.0F;
ret[COL_CORRECTPLACE*3 + 1] = 0.0F;
ret[COL_CORRECTPLACE*3 + 2] = 0.0F;
ret[COL_CORRECTCOLOUR*3 + 1] = 1.0F;
ret[COL_CORRECTCOLOUR*3 + 2] = 1.0F;
+ /* We want to make sure we can distinguish COL_CORRECTCOLOUR
+ * (which we hard-code as white) from COL_BACKGROUND (which
+ * could default to white on some platforms).
+ * Code borrowed from fifteen.c. */
+ max = ret[COL_BACKGROUND*3];
+ for (i = 1; i < 3; i++)
+ if (ret[COL_BACKGROUND*3+i] > max)
+ max = ret[COL_BACKGROUND*3+i];
+ if (max * 1.2F > 1.0F) {
+ for (i = 0; i < 3; i++)
+ ret[COL_BACKGROUND*3+i] /= (max * 1.2F);
+ }
+
+ /* We also want to be able to tell the difference between BACKGROUND
+ * and EMPTY, for similar distinguishing-hint reasons. */
+ ret[COL_EMPTY * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 2.0 / 3.0;
+ ret[COL_EMPTY * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 2.0 / 3.0;
+ ret[COL_EMPTY * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 2.0 / 3.0;
+
*ncolours = NCOLOURS;
return ret;
}
}
static void hint_redraw(frontend *fe, game_drawstate *ds, int guess,
- pegrow src, int force, int cursor, int emptycol)
+ pegrow src, int force, int cursor, int markable)
{
pegrow dest = ds->guesses[guess];
int rowx, rowy, i, scol, col, hintlen;
int need_redraw;
+ int emptycol = (markable ? COL_FLASH : COL_EMPTY);
if (src) assert(src->npegs == dest->npegs);
scol = src ? src->feedback[i] : 0;
if (i == 0 && cursor)
scol |= 0x1000;
+ if (i == 0 && markable)
+ scol |= 0x2000;
if ((scol != dest->feedback[i]) || force) {
need_redraw = TRUE;
}
}
if (need_redraw) {
+ int hinth = HINTSZ + GAP + HINTSZ;
+ int hx,hy,hw,hh;
+
+ hx = HINT_X(guess)-GAP; hy = HINT_Y(guess)-GAP;
+ hw = HINT_W+GAP*2; hh = hinth+GAP*2;
+
/* erase a large background rectangle */
- draw_rect(fe, GUESS_X(guess, dest->npegs)-CGAP,
- GUESS_Y(guess, dest->npegs)-CGAP,
- PEGSZ+CGAP*2, PEGSZ+CGAP*2, COL_BACKGROUND);
+ draw_rect(fe, hx, hy, hw, hh, COL_BACKGROUND);
for (i = 0; i < dest->npegs; i++) {
scol = src ? src->feedback[i] : 0;
draw_rect(fe, rowx, rowy, HINTSZ, HINTSZ, col);
}
}
- if (cursor)
- draw_cursor(fe, ds, GUESS_X(guess, dest->npegs),
- GUESS_Y(guess, dest->npegs));
+ if (cursor) {
+ int x1,y1,x2,y2;
+ x1 = hx + CGAP; y1 = hy + CGAP;
+ x2 = hx + hw - CGAP; y2 = hy + hh - CGAP;
+ draw_line(fe, x1, y1, x2, y1, COL_CURSOR);
+ draw_line(fe, x2, y1, x2, y2, COL_CURSOR);
+ draw_line(fe, x2, y2, x1, y2, COL_CURSOR);
+ draw_line(fe, x1, y2, x1, y1, COL_CURSOR);
+ }
- draw_update(fe, GUESS_X(guess, dest->npegs)-CGAP,
- GUESS_Y(guess, dest->npegs)-CGAP,
- PEGSZ+CGAP*2, PEGSZ+CGAP*2);
+ draw_update(fe, hx, hy, hw, hh);
}
}
/* this info is stored in the game_state already */
guess_redraw(fe, ds, i, state->guesses[i], NULL, -1, 0);
hint_redraw(fe, ds, i, state->guesses[i],
- i == (state->next_go-1) ? 1 : 0, FALSE, COL_EMPTY);
+ i == (state->next_go-1) ? 1 : 0, FALSE, FALSE);
} else if (state->next_go == i) {
/* this is the one we're on; the (incomplete) guess is
* stored in the game_ui. */
ui->holds, ui->display_cur ? ui->peg_cur : -1, 0);
hint_redraw(fe, ds, i, NULL, 1,
ui->display_cur && ui->peg_cur == state->params.npegs,
- ui->markable ? COL_FLASH : COL_EMPTY);
+ ui->markable);
} else {
/* we've not got here yet; it's blank. */
guess_redraw(fe, ds, i, NULL, NULL, -1, 0);
- hint_redraw(fe, ds, i, NULL, 0, FALSE, COL_EMPTY);
+ hint_redraw(fe, ds, i, NULL, 0, FALSE, FALSE);
}
}