X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/66732e7ac332426ca7df01c88130da9db8f60a5f..81ff8295651d75cdd07ff6fbb5a52d8aebe84136:/guess.c diff --git a/guess.c b/guess.c index a6ef548..702a1ad 100644 --- a/guess.c +++ b/guess.c @@ -60,11 +60,6 @@ static game_params *default_params(void) 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); @@ -77,6 +72,32 @@ static game_params *dup_params(game_params *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; @@ -393,6 +414,7 @@ static void game_changed_state(game_ui *ui, game_state *oldstate, /* 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) @@ -400,6 +422,7 @@ static void game_changed_state(game_ui *ui, game_state *oldstate, #define HINTSZ (ds->hintsz) #define HINTOFF (ds->hintsz + ds->gapsz) +#define GAP (ds->gapsz) #define CGAP (ds->gapsz / 2) #define PEGRAD (ds->pegrad) @@ -423,7 +446,7 @@ static void game_changed_state(game_ui *ui, game_state *oldstate, #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 @@ -641,6 +664,7 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, } ui->drag_col = 0; ui->drag_opeg = -1; + ui->display_cur = 0; debug(("Stop dragging.")); ret = from; } else if (button == RIGHT_BUTTON) { @@ -676,6 +700,7 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, 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 { @@ -683,6 +708,7 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, 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; } @@ -763,7 +789,8 @@ static void game_size(game_params *params, game_drawstate *ds, 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]); @@ -833,10 +860,6 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours) 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; @@ -845,6 +868,25 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours) 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; } @@ -956,11 +998,12 @@ static void guess_redraw(frontend *fe, game_drawstate *ds, int guess, } 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); @@ -976,6 +1019,8 @@ static void hint_redraw(frontend *fe, game_drawstate *ds, int guess, 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; } @@ -983,10 +1028,14 @@ static void hint_redraw(frontend *fe, game_drawstate *ds, int guess, } 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; @@ -1009,13 +1058,17 @@ static void hint_redraw(frontend *fe, game_drawstate *ds, int guess, 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); } } @@ -1067,7 +1120,7 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, /* 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. */ @@ -1075,11 +1128,11 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, 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); } }