X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/1482ee76f9b9a587ea12a09d4c971f5ed92cb6fe..ccd4e210f26dbe842ef9417e0df8c0a06f5c822f:/midend.c diff --git a/midend.c b/midend.c index d309068..79e6d7d 100644 --- a/midend.c +++ b/midend.c @@ -14,11 +14,17 @@ struct midend_data { frontend *frontend; char *seed; int nstates, statesize, statepos; + + game_params **presets; + char **preset_names; + int npresets, presetsize; + game_params *params; game_state **states; game_drawstate *drawstate; game_state *oldstate; float anim_time, anim_pos; + float flash_time, flash_pos; }; #define ensure(me) do { \ @@ -39,6 +45,11 @@ midend_data *midend_new(frontend *frontend) me->seed = NULL; me->drawstate = NULL; me->oldstate = NULL; + 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; } @@ -59,7 +70,7 @@ void midend_size(midend_data *me, int *x, int *y) void midend_set_params(midend_data *me, game_params *params) { free_params(me->params); - me->params = params; + me->params = dup_params(params); } void midend_new_game(midend_data *me, char *seed) @@ -109,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); } @@ -161,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; @@ -185,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); } @@ -199,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); } @@ -227,3 +262,40 @@ float *midend_colours(midend_data *me, int *ncolours) return ret; } + +int midend_num_presets(midend_data *me) +{ + if (!me->npresets) { + char *name; + game_params *preset; + + while (game_fetch_preset(me->npresets, &name, &preset)) { + if (me->presetsize <= me->npresets) { + me->presetsize = me->npresets + 10; + me->presets = sresize(me->presets, me->presetsize, + game_params *); + me->preset_names = sresize(me->preset_names, me->presetsize, + char *); + } + + me->presets[me->npresets] = preset; + me->preset_names[me->npresets] = name; + me->npresets++; + } + } + + return me->npresets; +} + +void midend_fetch_preset(midend_data *me, int n, + char **name, game_params **params) +{ + assert(n >= 0 && n < me->npresets); + *name = me->preset_names[n]; + *params = me->presets[n]; +} + +int midend_wants_statusbar(midend_data *me) +{ + return game_wants_statusbar(); +}