Fix GTK casts to restore correct compilation on GTK 2.0 after r6022.
[sgt/puzzles] / guess.c
diff --git a/guess.c b/guess.c
index a6ef548..702a1ad 100644 (file)
--- 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);
         }
     }