diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2022-12-27 17:26:42 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2022-12-27 19:27:38 +0000 |
| commit | 425942c852f22d7d94f7643696522d32c0b02067 (patch) | |
| tree | 5c5d830ad6880690f461056699e47604aea74049 /tracks.c | |
| parent | 99d3c31e12ac5bb7c12d2b7a59c702cb671e9b62 (diff) | |
| download | puzzles-425942c852f22d7d94f7643696522d32c0b02067.zip puzzles-425942c852f22d7d94f7643696522d32c0b02067.tar.gz puzzles-425942c852f22d7d94f7643696522d32c0b02067.tar.bz2 puzzles-425942c852f22d7d94f7643696522d32c0b02067.tar.xz | |
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.
Diffstat (limited to 'tracks.c')
| -rw-r--r-- | tracks.c | 44 |
1 files changed, 37 insertions, 7 deletions
@@ -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; |