ref: b75ce341793ecb8584a8681e0932b2711cc59645
parent: b74dac6de22e783ac6619411743df6bca1755a8b
author: Jacob Nevins <jacobn@chiark.greenend.org.uk>
date: Tue Jul 5 14:57:34 EDT 2005
Add a completion flash when you get down to a single peg. [originally from svn r6061]
--- a/pegs.c
+++ b/pegs.c
@@ -42,6 +42,8 @@
static char const *const pegs_lowertypes[] = { TYPELIST(LOWER) };
#define TYPECONFIG TYPELIST(CONFIG)
+#define FLASH_FRAME 0.13F
+
struct game_params {
int w, h;
int type;
@@ -49,6 +51,7 @@
struct game_state {
int w, h;
+ int completed;
unsigned char *grid;
};
@@ -574,6 +577,7 @@
state->w = w;
state->h = h;
+ state->completed = 0;
state->grid = snewn(w*h, unsigned char);
for (i = 0; i < w*h; i++)
state->grid[i] = (desc[i] == 'P' ? GRID_PEG :
@@ -589,6 +593,7 @@
ret->w = state->w;
ret->h = state->h;
+ ret->completed = state->completed;
ret->grid = snewn(w*h, unsigned char);
memcpy(ret->grid, state->grid, w*h);
@@ -682,6 +687,7 @@
int w, h;
unsigned char *grid;
int started;
+ int bgcolour;
};
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
@@ -789,6 +795,21 @@
ret->grid[my*w+mx] = GRID_HOLE;
ret->grid[ty*w+tx] = GRID_PEG;
+ /*
+ * Opinion varies on whether getting to a single peg counts as
+ * completing the game, or whether that peg has to be at a
+ * specific location (central in the classic cross game, for
+ * instance). For now we take the former, rather lax position.
+ */
+ if (!ret->completed) {
+ int count = 0, i;
+ for (i = 0; i < w*h; i++)
+ if (ret->grid[i] == GRID_PEG)
+ count++;
+ if (count == 1)
+ ret->completed = 1;
+ }
+
return ret;
}
return NULL;
@@ -873,6 +894,7 @@
memset(ds->grid, 255, w*h);
ds->started = FALSE;
+ ds->bgcolour = -1;
return ds;
}
@@ -886,10 +908,10 @@
}
static void draw_tile(frontend *fe, game_drawstate *ds,
- int x, int y, int v, int erasebg)
+ int x, int y, int v, int bgcolour)
{
- if (erasebg) {
- draw_rect(fe, x, y, TILESIZE, TILESIZE, COL_BACKGROUND);
+ if (bgcolour >= 0) {
+ draw_rect(fe, x, y, TILESIZE, TILESIZE, bgcolour);
}
if (v == GRID_HOLE) {
@@ -909,7 +931,14 @@
{
int w = state->w, h = state->h;
int x, y;
+ int bgcolour;
+ if (flashtime > 0) {
+ int frame = (int)(flashtime / FLASH_FRAME);
+ bgcolour = (frame % 2 ? COL_LOWLIGHT : COL_HIGHLIGHT);
+ } else
+ bgcolour = COL_BACKGROUND;
+
/*
* Erase the sprite currently being dragged, if any.
*/
@@ -1025,8 +1054,10 @@
*/
if (ui->dragging && ui->sx == x && ui->sy == y && v == GRID_PEG)
v = GRID_HOLE;
- if (v != ds->grid[y*w+x] && v != GRID_OBST) {
- draw_tile(fe, ds, COORD(x), COORD(y), v, TRUE);
+ if (v != GRID_OBST &&
+ (bgcolour != ds->bgcolour || /* always redraw when flashing */
+ v != ds->grid[y*w+x])) {
+ draw_tile(fe, ds, COORD(x), COORD(y), v, bgcolour);
}
}
@@ -1038,8 +1069,10 @@
ds->dragx = ui->dx - TILESIZE/2;
ds->dragy = ui->dy - TILESIZE/2;
blitter_save(fe, ds->drag_background, ds->dragx, ds->dragy);
- draw_tile(fe, ds, ds->dragx, ds->dragy, GRID_PEG, FALSE);
+ draw_tile(fe, ds, ds->dragx, ds->dragy, GRID_PEG, -1);
}
+
+ ds->bgcolour = bgcolour;
}
static float game_anim_length(game_state *oldstate, game_state *newstate,
@@ -1051,7 +1084,10 @@
static float game_flash_length(game_state *oldstate, game_state *newstate,
int dir, game_ui *ui)
{
- return 0.0F;
+ if (!oldstate->completed && newstate->completed)
+ return 2 * FLASH_FRAME;
+ else
+ return 0.0F;
}
static int game_wants_statusbar(void)