mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
Fancier completion flash for Tracks
It now runs along the track from A to B, spending the first half of FLASH_TIME lighting all the segments and the second half extinguishing them.
This commit is contained in:
44
tracks.c
44
tracks.c
@ -242,6 +242,7 @@ static const int nbits[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
||||
#define S_CLUE 8
|
||||
#define S_MARK 16
|
||||
|
||||
#define S_FLASH_SHIFT 8 /* Position of tile in solved track, 8 bits */
|
||||
#define S_TRACK_SHIFT 16 /* U/D/L/R flags for edge track indicators */
|
||||
#define S_NOTRACK_SHIFT 20 /* U/D/L/R flags for edge no-track indicators */
|
||||
|
||||
@ -1820,6 +1821,29 @@ static int tracks_neighbour(int vertex, void *vctx)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The completion flash moves along the track, so we want to label
|
||||
* each tile with how far along the track it is. This is represented
|
||||
* as an eight-bit field, which is more than enough when the
|
||||
* completion flash is only 0.5 s long.
|
||||
*/
|
||||
static void set_flash_data(game_state *state)
|
||||
{
|
||||
int ntrack = 0, x, y, n, d;
|
||||
const int w = state->p.w;
|
||||
|
||||
for (x = 0; x < w; x++)
|
||||
ntrack += state->numbers->numbers[x];
|
||||
n = 0; x = 0; y = state->numbers->row_s; d = R;
|
||||
do {
|
||||
/* Don't bother clearing; this only runs at completion. */
|
||||
state->sflags[y*w + x] |= (n++ * 255 / (ntrack - 1)) << S_FLASH_SHIFT;
|
||||
d = F(d); /* Find the direction we just arrived from. */
|
||||
d = S_E_DIRS(state, x, y, E_TRACK) & ~d; /* Other track from here. */
|
||||
x += DX(d); y += DY(d); /* Move to the next tile. */
|
||||
} while (INGRID(state, x, y));
|
||||
}
|
||||
|
||||
static bool check_completion(game_state *state, bool mark)
|
||||
{
|
||||
int w = state->p.w, h = state->p.h, x, y, i, target;
|
||||
@ -1961,8 +1985,10 @@ static bool check_completion(game_state *state, bool mark)
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (mark)
|
||||
if (mark) {
|
||||
state->completed = ret;
|
||||
if (ret) set_flash_data(state);
|
||||
}
|
||||
sfree(dsf);
|
||||
return ret;
|
||||
}
|
||||
@ -2829,7 +2855,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldst
|
||||
const game_state *state, int dir, const game_ui *ui,
|
||||
float animtime, float flashtime)
|
||||
{
|
||||
int i, x, y, flashing = 0, w = ds->w, h = ds->h;
|
||||
int i, x, y, flashing, w = ds->w, h = ds->h;
|
||||
bool force = false;
|
||||
game_state *drag_state = NULL;
|
||||
|
||||
@ -2855,11 +2881,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldst
|
||||
}
|
||||
}
|
||||
|
||||
if (flashtime > 0 &&
|
||||
(flashtime <= FLASH_TIME/3 ||
|
||||
flashtime >= FLASH_TIME*2/3))
|
||||
flashing = DS_FLASH;
|
||||
|
||||
if (ui->dragging)
|
||||
drag_state = copy_and_apply_drag(state, ui);
|
||||
|
||||
@ -2867,6 +2888,15 @@ static void game_redraw(drawing *dr, game_drawstate *ds, const game_state *oldst
|
||||
for (y = 0; y < h; y++) {
|
||||
unsigned int f, f_d;
|
||||
|
||||
flashing = 0;
|
||||
if (flashtime > 0) {
|
||||
float flashpos =
|
||||
(state->sflags[y*w+x] >> S_FLASH_SHIFT & 0xff) / 255.0F;
|
||||
if (flashtime > FLASH_TIME / 2 * flashpos &&
|
||||
flashtime <= FLASH_TIME / 2 * (flashpos + 1.0F))
|
||||
flashing = DS_FLASH;
|
||||
}
|
||||
|
||||
f = s2d_flags(state, x, y, ui) | flashing;
|
||||
f_d = drag_state ? s2d_flags(drag_state, x, y, ui) : f;
|
||||
|
||||
|
Reference in New Issue
Block a user