Bah, not good enough. Extend those background erases by one more
[sgt/puzzles] / guess.c
diff --git a/guess.c b/guess.c
index 6d96ea3..888901f 100644 (file)
--- a/guess.c
+++ b/guess.c
@@ -488,6 +488,8 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
 {
     int over_col = 0;           /* one-indexed */
     int over_guess = -1;        /* zero-indexed */
+    int over_past_guess_y = -1; /* zero-indexed */
+    int over_past_guess_x = -1; /* zero-indexed */
     int over_hint = 0;          /* zero or one */
     game_state *ret = NULL;
 
@@ -506,9 +508,14 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
         } else {
             over_hint = 1;
         }
+    } else if (x >= guess_ox &&
+               y >= GUESS_OY && y < guess_oy) {
+        over_past_guess_y = (y - GUESS_OY) / PEGOFF;
+        over_past_guess_x = (x - guess_ox) / PEGOFF;
     }
-    debug(("make_move: over_col %d, over_guess %d, over_hint %d",
-           over_col, over_guess, over_hint));
+    debug(("make_move: over_col %d, over_guess %d, over_hint %d,"
+           " over_past_guess %d", over_col, over_guess, over_hint,
+           over_past_guess));
 
     assert(ds->blit_peg);
 
@@ -523,6 +530,13 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
                 ui->drag_col = col;
                 debug(("Start dragging from a guess"));
             }
+        } else if (over_past_guess_y > -1) {
+            int col =
+                from->guesses[over_past_guess_y]->pegs[over_past_guess_x];
+            if (col) {
+                ui->drag_col = col;
+                debug(("Start dragging from a past guess"));
+            }
         }
         if (ui->drag_col) {
             ui->drag_x = x;
@@ -639,9 +653,8 @@ static void game_size(game_params *params, game_drawstate *ds,
     ds->pegrad  = (ds->pegsz -1)/2; /* radius of peg to fit in pegsz (which is 2r+1) */
     ds->hintrad = (ds->hintsz-1)/2;
 
-    *x = (int)((double)ds->pegsz * hmul);
-    *y = (int)((double)ds->pegsz * vmul);
-
+    *x = (int)ceil((double)ds->pegsz * hmul);
+    *y = (int)ceil((double)ds->pegsz * vmul);
     ds->w = *x; ds->h = *y;
 
     colh = ((ds->pegsz + ds->gapsz) * params->ncolours) - ds->gapsz;
@@ -667,44 +680,54 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours)
 
     frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
 
-    ret[COL_1 * 3 + 0] = 0.0F;
+    /* red */
+    ret[COL_1 * 3 + 0] = 1.0F;
     ret[COL_1 * 3 + 1] = 0.0F;
-    ret[COL_1 * 3 + 2] = 1.0F;
+    ret[COL_1 * 3 + 2] = 0.0F;
 
-    ret[COL_2 * 3 + 0] = 0.0F;
-    ret[COL_2 * 3 + 1] = 0.5F;
+    /* yellow (toned down a bit due to pale grey background) */
+    ret[COL_2 * 3 + 0] = 0.7F;
+    ret[COL_2 * 3 + 1] = 0.7F;
     ret[COL_2 * 3 + 2] = 0.0F;
 
-    ret[COL_3 * 3 + 0] = 1.0F;
-    ret[COL_3 * 3 + 1] = 0.0F;
+    /* green (also toned down) */
+    ret[COL_3 * 3 + 0] = 0.0F;
+    ret[COL_3 * 3 + 1] = 0.5F;
     ret[COL_3 * 3 + 2] = 0.0F;
 
-    ret[COL_4 * 3 + 0] = 1.0F;
-    ret[COL_4 * 3 + 1] = 1.0F;
-    ret[COL_4 * 3 + 2] = 0.0F;
+    /* blue */
+    ret[COL_4 * 3 + 0] = 0.0F;
+    ret[COL_4 * 3 + 1] = 0.0F;
+    ret[COL_4 * 3 + 2] = 1.0F;
 
+    /* orange */
     ret[COL_5 * 3 + 0] = 1.0F;
-    ret[COL_5 * 3 + 1] = 0.0F;
-    ret[COL_5 * 3 + 2] = 1.0F;
-
-    ret[COL_6 * 3 + 0] = 0.0F;
-    ret[COL_6 * 3 + 1] = 1.0F;
-    ret[COL_6 * 3 + 2] = 1.0F;
-
-    ret[COL_7 * 3 + 0] = 0.5F;
-    ret[COL_7 * 3 + 1] = 0.5F;
-    ret[COL_7 * 3 + 2] = 1.0F;
-
-    ret[COL_8 * 3 + 0] = 0.5F;
-    ret[COL_8 * 3 + 1] = 1.0F;
-    ret[COL_8 * 3 + 2] = 0.5F;
-
-    ret[COL_9 * 3 + 0] = 1.0F;
-    ret[COL_9 * 3 + 1] = 0.5F;
+    ret[COL_5 * 3 + 1] = 0.5F;
+    ret[COL_5 * 3 + 2] = 0.0F;
+
+    /* purple */
+    ret[COL_6 * 3 + 0] = 0.5F;
+    ret[COL_6 * 3 + 1] = 0.0F;
+    ret[COL_6 * 3 + 2] = 0.7F;
+
+    /* brown */
+    ret[COL_7 * 3 + 0] = 0.4F;
+    ret[COL_7 * 3 + 1] = 0.2F;
+    ret[COL_7 * 3 + 2] = 0.2F;
+
+    /* light blue */
+    ret[COL_8 * 3 + 0] = 0.4F;
+    ret[COL_8 * 3 + 1] = 0.7F;
+    ret[COL_8 * 3 + 2] = 1.0F;
+
+    /* light green */
+    ret[COL_9 * 3 + 0] = 0.5F;
+    ret[COL_9 * 3 + 1] = 0.8F;
     ret[COL_9 * 3 + 2] = 0.5F;
 
+    /* pink */
     ret[COL_10 * 3 + 0] = 1.0F;
-    ret[COL_10 * 3 + 1] = 1.0F;
+    ret[COL_10 * 3 + 1] = 0.6F;
     ret[COL_10 * 3 + 2] = 1.0F;
 
     ret[COL_FRAME * 3 + 0] = 0.0F;
@@ -731,7 +754,7 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours)
     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] = 1.0F;
+    ret[COL_CORRECTPLACE*3 + 0] = 0.0F;
     ret[COL_CORRECTPLACE*3 + 1] = 0.0F;
     ret[COL_CORRECTPLACE*3 + 2] = 0.0F;
 
@@ -785,11 +808,23 @@ static void game_free_drawstate(game_drawstate *ds)
     sfree(ds);
 }
 
-static void draw_peg(frontend *fe, game_drawstate *ds, int cx, int cy, int col)
+static void draw_peg(frontend *fe, game_drawstate *ds, int cx, int cy,
+                    int moving, int col)
 {
-    if (PEGRAD > 0)
+    /*
+     * Some platforms antialias circles, which means we shouldn't
+     * overwrite a circle of one colour with a circle of another
+     * colour without erasing the background first. However, if the
+     * peg is the one being dragged, we don't erase the background
+     * because we _want_ it to alpha-blend nicely into whatever's
+     * behind it.
+     */
+    if (!moving)
+       draw_rect(fe, cx-1, cy-1, PEGSZ+2, PEGSZ+2, COL_BACKGROUND);
+    if (PEGRAD > 0) {
         draw_circle(fe, cx+PEGRAD, cy+PEGRAD, PEGRAD, 1, COL_EMPTY + col);
-    else
+        draw_circle(fe, cx+PEGRAD, cy+PEGRAD, PEGRAD, 0, COL_EMPTY + col);
+    } else
         draw_rect(fe, cx, cy, PEGSZ, PEGSZ, COL_EMPTY + col);
     draw_update(fe, cx, cy, PEGSZ, PEGSZ);
 }
@@ -814,7 +849,7 @@ static void guess_redraw(frontend *fe, game_drawstate *ds, int guess,
     for (i = 0; i < dest->npegs; i++) {
         scol = src ? src->pegs[i] : 0;
         if ((dest->pegs[i] != scol) || force)
-           draw_peg(fe, ds, rowx + PEGOFF * i, rowy, scol);
+           draw_peg(fe, ds, rowx + PEGOFF * i, rowy, FALSE, scol);
         dest->pegs[i] = scol;
     }
 }
@@ -842,10 +877,14 @@ static void hint_redraw(frontend *fe, game_drawstate *ds, int guess,
                 rowx += HINTOFF * (i - hintlen);
                 rowy += HINTOFF;
             }
-            if (HINTRAD > 0)
+           /* erase background for antialiasing platforms */
+           draw_rect(fe, rowx-1, rowy-1, HINTSZ+2, HINTSZ+2, COL_BACKGROUND);
+            if (HINTRAD > 0) {
                 draw_circle(fe, rowx+HINTRAD, rowy+HINTRAD, HINTRAD, 1, col);
-            else
+                draw_circle(fe, rowx+HINTRAD, rowy+HINTRAD, HINTRAD, 0, col);
+            } else {
                 draw_rect(fe, rowx, rowy, HINTSZ, HINTSZ, col);
+            }
             draw_update(fe, rowx, rowy, HINTSZ, HINTSZ);
         }
         dest->feedback[i] = scol;
@@ -924,7 +963,7 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
     /* draw the colours */
     for (i = 0; i < state->params.ncolours; i++) {
         if (ds->colours->pegs[i] != i+1) {
-           draw_peg(fe, ds, COL_X(i), COL_Y(i), i+1);
+           draw_peg(fe, ds, COL_X(i), COL_Y(i), FALSE, i+1);
             ds->colours->pegs[i] = i+1;
         }
     }
@@ -1007,7 +1046,7 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
         int oy = ui->drag_y - (PEGSZ/2);
         debug(("Saving to blitter at (%d,%d)", ox, oy));
         blitter_save(fe, ds->blit_peg, ox, oy);
-        draw_peg(fe, ds, ox, oy, ui->drag_col);
+        draw_peg(fe, ds, ox, oy, TRUE, ui->drag_col);
 
         ds->blit_ox = ox; ds->blit_oy = oy;
     }
@@ -1043,7 +1082,7 @@ static int game_timing_state(game_state *state)
 #endif
 
 const struct game thegame = {
-    "Guess", "games.guess",
+    "Guess", NULL,
     default_params,
     game_fetch_preset,
     decode_params,