From 7ee31401a35405ee700c8fab563cecc9f43db3a1 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 10 Nov 2003 15:45:45 +0000 Subject: [PATCH] * src/grrobot.c (grr_game_read_notices): Call new board_view timer functions on the appropriate state transitions. * src/grr_board_view.c (grr_board_view_expose): Add code to draw a cute alpha-blended timer which shows off the use of cairo_arc. (grr_board_view_refresh_timer): (grr_board_view_decrement_timer): (grr_board_view_start_timer): (grr_board_view_stop_timer): (grr_board_view_reset_timer): New functions for managing the timer. --- ChangeLog | 13 ++++++ src/grr_board_view.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ src/grr_board_view.h | 14 ++++++- src/grrobot.c | 6 ++- 4 files changed, 126 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index cac1149..4836baa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-11-10 Carl Worth + + * src/grrobot.c (grr_game_read_notices): Call new board_view timer + functions on the appropriate state transitions. + + * src/grr_board_view.c (grr_board_view_expose): Add code to draw a + cute alpha-blended timer which shows off the use of cairo_arc. + (grr_board_view_refresh_timer): + (grr_board_view_decrement_timer): + (grr_board_view_start_timer): + (grr_board_view_stop_timer): + (grr_board_view_reset_timer): New functions for managing the timer. + 2003-09-04 Carl Worth * configure.in (PKG_CHECK_MODULES): Require Cairo 0.1.1 or newer. diff --git a/src/grr_board_view.c b/src/grr_board_view.c index 66a2617..8d85988 100644 --- a/src/grr_board_view.c +++ b/src/grr_board_view.c @@ -130,6 +130,9 @@ 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->cell_width = 0; @@ -481,6 +484,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 +695,75 @@ 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 + +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; + + grr_board_view_refresh_timer (view); + + return TRUE; +} + +void +grr_board_view_start_timer (grr_board_view_t *view, double time) +{ + /* XXX: It would be good to adjust the clock for latency somewhere... */ + /* Correct any drift within the next 10 seconds, or half the + remaining time --- whichever is less. */ + if (view->timer) { + double correction_time; + 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->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; + + grr_board_view_refresh_timer (view); +} + +void +grr_board_view_reset_timer (grr_board_view_t *view) +{ + grr_board_view_stop_timer (view); + + view->time = 60.0; + view->drift_correct = 0.0; +} diff --git a/src/grr_board_view.h b/src/grr_board_view.h index 2f7ebbe..92cf981 100644 --- a/src/grr_board_view.h +++ b/src/grr_board_view.h @@ -67,8 +67,9 @@ struct grr_board_view /* Button currently pressed or 0 if none */ guint8 button; - /* ID of update timer, or 0 if none */ - guint32 timer; + double time; + double drift_correct; + guint timer; grr_icon_t *cell1_icon; grr_icon_t *cell2_icon; @@ -104,6 +105,15 @@ grr_board_view_undo (grr_board_view_t *view); void grr_board_view_mark_damage (grr_board_view_t *view, int i, int j); +void +grr_board_view_start_timer (grr_board_view_t *view, double time); + +void +grr_board_view_stop_timer (grr_board_view_t *view); + +void +grr_board_view_reset_timer (grr_board_view_t *view); + void grr_board_view_transform_pixel_to_cell (grr_board_view_t *view, int pixel_x, int pixel_y, diff --git a/src/grrobot.c b/src/grrobot.c index a1746c3..8df5b98 100644 --- a/src/grrobot.c +++ b/src/grrobot.c @@ -273,6 +273,7 @@ grr_game_read_notices (grr_game_t *game) here. */ game->state = RR_GAMESTATE_NEW; + grr_board_view_reset_timer (game->board_view); grr_game_print (game, "\nNew round!"); rr_board_set_goal_target (board, notice->u.target); gtk_widget_queue_draw (GTK_WIDGET (game->window)); @@ -338,13 +339,14 @@ grr_game_read_notices (grr_game_t *game) notice->u.number); break; case RR_NOTICE_ACTIVE: + grr_board_view_stop_timer (game->board_view); grr_game_printf (game, "\nUser %s now active to demonstrate solution in %d moves.", notice->u.bid.username, notice->u.bid.number); break; case RR_NOTICE_TIMER: - grr_game_printf (game, "\nTime remaining: %d seconds.", - notice->u.number); + grr_board_view_start_timer (game->board_view, + notice->u.number); break; case RR_NOTICE_POSITION: { -- 2.43.0