diff --git a/cube.c b/cube.c index e9c6e9a..1bc08f6 100644 --- a/cube.c +++ b/cube.c @@ -1206,7 +1206,7 @@ void game_free_drawstate(game_drawstate *ds) } void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, - game_state *state, float animtime) + game_state *state, float animtime, float flashtime) { int i, j; struct bbox bb = find_bbox(&state->params); @@ -1355,3 +1355,8 @@ float game_anim_length(game_state *oldstate, game_state *newstate) { return ROLLTIME; } + +float game_flash_length(game_state *oldstate, game_state *newstate) +{ + return 0.0F; +} diff --git a/midend.c b/midend.c index cafc8ea..3b1a0e4 100644 --- a/midend.c +++ b/midend.c @@ -24,6 +24,7 @@ struct midend_data { game_drawstate *drawstate; game_state *oldstate; float anim_time, anim_pos; + float flash_time, flash_pos; }; #define ensure(me) do { \ @@ -47,6 +48,8 @@ midend_data *midend_new(frontend *frontend) me->presets = NULL; me->preset_names = NULL; me->npresets = me->presetsize = 0; + me->anim_time = me->anim_pos = 0.0F; + me->flash_time = me->flash_pos = 0.0F; return me; } @@ -117,17 +120,38 @@ static int midend_redo(midend_data *me) return 0; } +static void midend_finish_move(midend_data *me) +{ + float flashtime; + + if (me->oldstate || me->statepos > 1) { + flashtime = game_flash_length(me->oldstate ? me->oldstate : + me->states[me->statepos-2], + me->states[me->statepos-1]); + if (flashtime > 0) { + me->flash_pos = 0.0F; + me->flash_time = flashtime; + } + } + + if (me->oldstate) + free_game(me->oldstate); + me->oldstate = NULL; + me->anim_pos = me->anim_time = 0; + + if (me->flash_time == 0 && me->anim_time == 0) + deactivate_timer(me->frontend); + else + activate_timer(me->frontend); +} + int midend_process_key(midend_data *me, int x, int y, int button) { game_state *oldstate = dup_game(me->states[me->statepos - 1]); float anim_time; if (me->oldstate || me->anim_time) { - if (me->oldstate) - free_game(me->oldstate); - me->oldstate = NULL; - me->anim_pos = me->anim_time = 0; - deactivate_timer(me->frontend); + midend_finish_move(me); midend_redraw(me); } @@ -169,13 +193,12 @@ int midend_process_key(midend_data *me, int x, int y, int button) */ anim_time = game_anim_length(oldstate, me->states[me->statepos-1]); + me->oldstate = oldstate; if (anim_time > 0) { - me->oldstate = oldstate; me->anim_time = anim_time; } else { - free_game(oldstate); - me->oldstate = NULL; me->anim_time = 0.0; + midend_finish_move(me); } me->anim_pos = 0.0; @@ -193,10 +216,11 @@ void midend_redraw(midend_data *me) if (me->oldstate && me->anim_time > 0 && me->anim_pos < me->anim_time) { game_redraw(me->frontend, me->drawstate, me->oldstate, - me->states[me->statepos-1], me->anim_pos); + me->states[me->statepos-1], me->anim_pos, + me->flash_pos); } else { game_redraw(me->frontend, me->drawstate, NULL, - me->states[me->statepos-1], 0.0); + me->states[me->statepos-1], 0.0, me->flash_pos); } end_draw(me->frontend); } @@ -207,12 +231,15 @@ void midend_timer(midend_data *me, float tplus) me->anim_pos += tplus; if (me->anim_pos >= me->anim_time || me->anim_time == 0 || !me->oldstate) { - if (me->oldstate) - free_game(me->oldstate); - me->oldstate = NULL; - me->anim_pos = me->anim_time = 0; - deactivate_timer(me->frontend); + if (me->anim_time > 0) + midend_finish_move(me); } + me->flash_pos += tplus; + if (me->flash_pos >= me->flash_time || me->flash_time == 0) { + me->flash_pos = me->flash_time = 0; + } + if (me->flash_time == 0 && me->anim_time == 0) + deactivate_timer(me->frontend); midend_redraw(me); } diff --git a/net.c b/net.c index 001eaae..268fbca 100644 --- a/net.c +++ b/net.c @@ -1060,7 +1060,7 @@ static void draw_tile(frontend *fe, game_state *state, int x, int y, int tile, } void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, - game_state *state, float t) + game_state *state, float t, float ft) { int x, y, tx, ty, frame; unsigned char *active; @@ -1118,7 +1118,6 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, } tx = ty = -1; - frame = -1; if (oldstate && (t < ROTATE_TIME)) { /* * We're animating a tile rotation. Find the turning tile, @@ -1140,12 +1139,15 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, angle = state->last_rotate_dir * -90.0F * (t / ROTATE_TIME); state = oldstate; } - } else if (t > ROTATE_TIME) { + } + + frame = -1; + if (ft > 0) { /* * We're animating a completion flash. Find which frame * we're at. */ - frame = (int)((t - ROTATE_TIME) / FLASH_FRAME); + frame = (int)(ft / FLASH_FRAME); } /* @@ -1192,7 +1194,6 @@ void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, float game_anim_length(game_state *oldstate, game_state *newstate) { - float ret = 0.0F; int x, y; /* @@ -1202,14 +1203,17 @@ float game_anim_length(game_state *oldstate, game_state *newstate) for (x = 0; x < oldstate->width; x++) for (y = 0; y < oldstate->height; y++) if ((tile(oldstate, x, y) ^ tile(newstate, x, y)) & 0xF) { - ret = ROTATE_TIME; - goto break_label; /* leave both loops at once */ + return ROTATE_TIME; } - break_label: + return 0.0F; +} + +float game_flash_length(game_state *oldstate, game_state *newstate) +{ /* - * Also, if the game has just been completed, allow time for a - * completion flash. + * If the game has just been completed, we display a completion + * flash. */ if (!oldstate->completed && newstate->completed) { int size; @@ -1222,8 +1226,8 @@ float game_anim_length(game_state *oldstate, game_state *newstate) size = newstate->width - newstate->cx; if (size < newstate->height - newstate->cy) size = newstate->height - newstate->cy; - ret += FLASH_FRAME * (size+4); + return FLASH_FRAME * (size+4); } - return ret; + return 0.0F; } diff --git a/puzzles.h b/puzzles.h index ae14848..5b75697 100644 --- a/puzzles.h +++ b/puzzles.h @@ -108,7 +108,8 @@ float *game_colours(frontend *fe, game_state *state, int *ncolours); game_drawstate *game_new_drawstate(game_state *state); void game_free_drawstate(game_drawstate *ds); void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, - game_state *newstate, float t); + game_state *newstate, float anim_time, float flash_time); float game_anim_length(game_state *oldstate, game_state *newstate); +float game_flash_length(game_state *oldstate, game_state *newstate); #endif /* PUZZLES_PUZZLES_H */