X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=src%2Fgrr_board_view.c;h=1c918f2a23744594ad850227890edcdaeff17fe9;hb=cb69660363a21978e1919d8f30868e6a5c94a4d4;hp=66a261732e7f02793b21a5f1bca6a091b54b9d19;hpb=cb3aa78ccf916ab2153ce5594f4598f81500178b;p=grrobot diff --git a/src/grr_board_view.c b/src/grr_board_view.c index 66a2617..1c918f2 100644 --- a/src/grr_board_view.c +++ b/src/grr_board_view.c @@ -30,7 +30,7 @@ #include #include -#include +#include #include #include @@ -130,7 +130,11 @@ grr_board_view_init (grr_board_view_t *view) view->client = NULL; view->button = 0; + + view->time = 60.0; + view->drift_correct = 0.0; view->timer = 0; + view->zap_time = 0.0; view->cell_width = 0; view->cell_height = 0; @@ -481,6 +485,28 @@ grr_board_view_expose (GtkWidget *widget, cairo_fill (xrs); grr_icon_draw (view->target_icon[rr_target_idx (goal_target)], xrs); cairo_restore (xrs); + + /* Draw clock */ + if (view->time < 60.0) { + cairo_save (xrs); + cairo_new_path (xrs); + cairo_move_to (xrs, + (double) view->board_width / 2 * view->cell_width, + (double) view->board_height / 2 * view->cell_height); + cairo_arc (xrs, + (double) view->board_width / 2 * view->cell_width, + (double) view->board_height / 2 * view->cell_height, + .9 * view->cell_width, + - M_PI_2, + 2 * M_PI * (60.0 - view->time) / 60.0 - M_PI_2); + cairo_close_path (xrs); + + cairo_set_rgb_color (xrs, 0.0, 0.0, 0.0); + cairo_set_alpha (xrs, 0.5); + cairo_fill (xrs); + + cairo_restore (xrs); + } } /* Draw walls */ @@ -670,3 +696,96 @@ grr_board_view_mark_damage (grr_board_view_t *view, int i, int j) grr_board_view_transform_cell_to_pixel (view, i, j, &x, &y); gtk_widget_queue_draw_area (GTK_WIDGET (view), x, y, view->cell_width, view->cell_height); } + +#define TIMER_INTERVAL_MS 100.0 + +static void +grr_board_view_refresh_timer (grr_board_view_t *view) +{ + int x, y; + + grr_board_view_transform_cell_to_pixel (view, + view->board_width / 2 - 1, + view->board_height / 2 -1, + &x, &y); + gtk_widget_queue_draw_area (GTK_WIDGET (view), + x, y, + 2 * view->cell_width, + 2 * view->cell_height); +} + +static gboolean +grr_board_view_decrement_timer (void *widget) +{ + grr_board_view_t *view = widget; + + view->time -= TIMER_INTERVAL_MS / 1000.0; + view->time += view->drift_correct; + + if (view->zap_time) { + view->time -= view->zap_time; + view->zap_time += 1.0; + } + + grr_board_view_refresh_timer (view); + + if (view->time < 0) { + grr_board_view_stop_timer (view); + return FALSE; + } + + return TRUE; +} + +void +grr_board_view_set_timer (grr_board_view_t *view, double time) +{ + /* XXX: It would be good to adjust the clock for latency somewhere... */ + if (view->timer) { + double correction_time; + /* Correct any drift within the next 10 seconds, or half the + remaining time --- whichever is less. */ + if (time >= 20.0) + correction_time = 10.0; + else + correction_time = time / 2.0; + view->drift_correct = (time - view->time) / (correction_time * TIMER_INTERVAL_MS); + } else { + view->time = time; + view->drift_correct = 0.0; + view->zap_time = 0.0; + } +} + +void +grr_board_view_start_timer (grr_board_view_t *view) +{ + if (view->timer) + return; + + view->timer = gtk_timeout_add (TIMER_INTERVAL_MS, grr_board_view_decrement_timer, view); +} + +void +grr_board_view_stop_timer (grr_board_view_t *view) +{ + if (view->timer == 0) + return; + + gtk_timeout_remove (view->timer); + view->timer = 0; + view->time = 0.0; + view->drift_correct = 0.0; + view->zap_time = 0.0; + + grr_board_view_refresh_timer (view); +} + +void +grr_board_view_zap_timer (grr_board_view_t *view) +{ + view->zap_time = 4; + + grr_board_view_refresh_timer (view); +} +