int ui_get_machine_move () { byte *move; if (player_to_play == HUMAN || ui_stopped) return FALSE; if (!opt_infile) { move = move_fread_ack (move_fin); if (!move) { sb_error ("Couldn't make move\n", TRUE); ui_stopped = TRUE; sb_update (); return FALSE; } if (opt_logfile) move_fwrite (move, opt_logfile); } else // file mode { //TODO: should communicate the move to the engine move = move_fread (opt_infile); if (opt_logfile) move_fwrite (move, opt_logfile); } board_apply_refresh (move, NULL); if (!game_single_player) cur_pos.player = (cur_pos.player == WHITE ? BLACK : WHITE); cur_pos.num_moves ++; sound_play (SOUND_MACHINE_MOVE); ui_check_who_won (); sb_update (); ui_send_make_move (); return FALSE; }
void ui_check_who_won() { char *line, *who_str = NULL; int who, len; if (!move_fout) return; fprintf (move_fout, "WHO_WON \n"); fflush (move_fout); line = line_read(move_fin); if (g_strncasecmp(line, "ACK", 3)) { // NAK ==> not implemented ui_gameover = FALSE; sb_set_score (""); return; } line += 4; line = g_strstrip(line); who_str = line; while(!isspace(*line) && *line) line++; while(isspace(*line)) line++; sb_set_score (line); if (!g_strncasecmp(who_str, "NYET", 4)) { ui_gameover = FALSE; return; } ui_stopped = TRUE; ui_gameover = TRUE; if (opt_logfile) fprintf(opt_logfile, "RESULT: %s\n", who_str); if (!state_gui_active) ui_cleanup(); sb_update (); if (game_single_player && !ui_cheated && !g_strncasecmp(who_str, "WON", 3)) { gboolean retval; retval = prefs_add_highscore (line, sb_get_human_time ()); if (retval) sound_play (SOUND_HIGHSCORE); else sound_play (SOUND_WON); if (game_levels) { GameLevel *next_level = game_levels; while (next_level->name) { if (next_level->game == opt_game) break; next_level++; } next_level++; if (next_level->name) menu_put_level (next_level->name); } } if (game_single_player && !ui_cheated && !g_strncasecmp(who_str, "LOST", 4)) sound_play (SOUND_LOST); }
void ui_make_human_move (byte *move, int *rmove) { board_apply_refresh (move, rmove); if (!move) return; if (move_fout) { fprintf (move_fout, "TAKE_MOVE "); move_fwrite (move, move_fout); if (opt_logfile) move_fwrite (move, opt_logfile); } if (!game_single_player) { cur_pos.player = (cur_pos.player == WHITE ? BLACK : WHITE); } cur_pos.num_moves ++; ui_check_who_won (); sb_update (); ui_send_make_move (); }
void ui_terminate_game () { // FIXME: are we sure -1 is an invalid value? if (animate_tag >= 0) { gtk_timeout_remove (animate_tag); animate_tag = -1; } if (game_single_player) prefs_save_scores (menu_get_game_name_with_level()); board_free (); reset_game_params (); if (opt_infile) { fclose (opt_infile); opt_infile = NULL; } if (game_reset_uistate) game_reset_uistate(); sb_reset_human_time (); sb_update(); ui_stopped = TRUE; ui_cheated = FALSE; }
static void update_sb(UpClient *client) { guint u; guint bat_count = 0; gboolean ac_online = FALSE; for(u = 0; u < MAX_BATTERIES; u++) { sbe_batteries[u].sbe_visible = 0; } GPtrArray *devices = up_client_get_devices(client); for(u = 0; u < devices->len; u++) { UpDevice *device = (UpDevice*)g_ptr_array_index(devices, u); UpDeviceKind kind; g_object_get(device, "kind", &kind, NULL); if(kind == UP_DEVICE_KIND_LINE_POWER) { gboolean online; g_object_get(device, "online", &online, NULL); sbe_printf(&sbe_ac, "AC %s", (online ? "on" : "off")); if(online) { ac_online = TRUE; } } if(kind == UP_DEVICE_KIND_BATTERY) { if(bat_count < MAX_BATTERIES) { struct sb_entry *sbe = &sbe_batteries[bat_count]; gboolean bat_empty = FALSE; gboolean bat_charging = FALSE; gboolean bat_discharging = FALSE; guint state; double energy_rate; double energy_full; double energy_now; g_object_get(device, "state", &state, "energy", &energy_now, "energy-full", &energy_full, "energy-rate", &energy_rate, NULL); const char *str; switch(state) { case UP_DEVICE_STATE_CHARGING: if(energy_rate > 0.0) { bat_charging = TRUE; } str = "chrg"; break; case UP_DEVICE_STATE_DISCHARGING: if(energy_rate > 0.0) { bat_discharging = TRUE; } str = "dsch"; break; case UP_DEVICE_STATE_EMPTY: bat_empty = TRUE; str = "empt"; break; case UP_DEVICE_STATE_FULLY_CHARGED: str = "full"; break; case UP_DEVICE_STATE_PENDING_CHARGE: case UP_DEVICE_STATE_PENDING_DISCHARGE: str = "idle"; break; default: str = "unkn"; break; } double percent = (energy_now / energy_full) * 100.0; sbe_printf(sbe, "B%d %s %.1f%%", bat_count, str, percent); sbe->sbe_visible = 1; if(bat_empty) { sbe->sbe_background = COLOR_RED; } else if(bat_charging) { sbe->sbe_background = COLOR_YELLOW; } else if(bat_discharging) { if(percent < 5.0) { sbe->sbe_background = COLOR_RED; } else if(percent < 15.0) { sbe->sbe_background = COLOR_YELLOW; } else { sbe->sbe_background = COLOR_GREEN; } } else { sbe->sbe_background = 0x444444; } bat_count++; } } } if(ac_online) { sbe_ac.sbe_background = COLOR_GREEN; } else { sbe_ac.sbe_background = 0x444444; } sb_update(&sb); }
int main(int argc, char **argv) { int n, nfds, res; struct itimerspec timerits; struct epoll_event events[MAX_EVENTS]; struct epoll_event timerevent; IxpClient* client; struct sb sb; signals_setup(&quit_handler); struct sb_entry sbe_sda = { .sbe_path = "/rbar/60_sda", .sbe_private = "sda", .sbe_init = &init_block, .sbe_update = &update_block, .sbe_foreground = 0xbbbbbb, .sbe_background = 0x444444, .sbe_border = 0x555555, }; struct sb_entry sbe_sdb = { .sbe_path = "/rbar/61_sdb", .sbe_private = "sdb", .sbe_init = &init_block, .sbe_update = &update_block, .sbe_foreground = 0xbbbbbb, .sbe_background = 0x444444, .sbe_border = 0x555555, }; struct sb_entry sbe_sdc = { .sbe_path = "/rbar/62_sdc", .sbe_private = "sdc", .sbe_init = &init_block, .sbe_update = &update_block, .sbe_foreground = 0xbbbbbb, .sbe_background = 0x444444, .sbe_border = 0x555555, }; int epollfd = epoll_create1(EPOLL_CLOEXEC); if(epollfd == -1) { perror("epoll_create"); abort(); } int timerfd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK|TFD_CLOEXEC); if(timerfd == -1) { perror("timerfd_create"); abort(); } timerevent.events = EPOLLIN; timerevent.data.fd = timerfd; timerits.it_interval.tv_sec = 0; timerits.it_interval.tv_nsec = 250 * 1000 * 1000; timerits.it_value.tv_sec = timerits.it_interval.tv_sec; timerits.it_value.tv_nsec = timerits.it_interval.tv_nsec; client = ixp_nsmount("wmii"); if(client == NULL) { printf("ixp_nsmount: %s\n", ixp_errbuf()); abort(); } res = epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &timerevent); if(res == -1) { perror("epoll_ctl"); abort(); } res = timerfd_settime(timerfd, 0, &timerits, NULL); if(res == -1) { perror("timerfd_settime"); abort(); } sb_init(&sb, client); sb_add(&sb, &sbe_sda); sb_add(&sb, &sbe_sdb); sb_add(&sb, &sbe_sdc); while(1) { nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1); if(nfds == -1) { if(errno != EINTR) { perror("epoll_wait"); abort(); } } if(should_quit) { break; } for (n = 0; n < nfds; n++) { if(events[n].data.fd == timerfd) { uint64_t x; read(timerfd, &x, sizeof(x)); sb_update(&sb); } } } sb_finish(&sb); ixp_unmount(client); return 0; }
void gui_init () { GtkWidget *hbox = NULL, *vbox = NULL, *vbox1 = NULL, *frame = NULL; GtkWidget *separator; GtkAccelGroup *ag; GtkItemFactoryEntry game_items [num_games+1]; GtkItemFactoryEntry items[] = { #if GTK_MAJOR_VERSION == 1 /* { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/_Load game", "<control>L", menu_load_file_dialog, 0, "" }, { "/File/_Save game", NULL, NULL, 0, "" }, { "/File/_Quit", "<control>Q", (GtkSignalFunc) ui_cleanup, 0, "" }, */ { "/_Game", NULL, NULL, 0, "<Branch>" }, { "/Game/Select _Game", NULL, NULL, 0, "<LastBranch>" }, { "/Game/_Levels", NULL, NULL, 0, "<Branch>"}, { "/Game/Sep1", NULL, NULL, 0, "<Separator>" }, { "/Game/_New", "<control>N", menu_start_stop_game, MENU_RESET_GAME, "" }, { "/Game/_Start", "<control>G", menu_start_stop_game, MENU_START_GAME, "" }, { "/Game/_Pause", "<control>P", menu_start_stop_game, MENU_STOP_GAME, "" }, { "/Game/Sep2", NULL, NULL, 0, "<Separator>" }, { "/Game/_Highscores", NULL, prefs_show_scores, 0, ""}, { "/Game/_Zap Highscores", NULL, prefs_zap_highscores, 0, ""}, { "/Game/Sep3", NULL, NULL, 0, "<Separator>" }, { "/Game/_Quit", "<control>Q", (GtkSignalFunc) ui_cleanup, 0, "" }, { "/_Move", NULL, NULL, 0, "<Branch>" }, { "/Move/_Back", "<control>B", menu_back_forw, MENU_BACK, "" }, { "/Move/_Forward", "<control>F", menu_back_forw, MENU_FORW, "" }, { "/Move/Sep1", NULL, NULL, 0, "<Separator>" }, { "/Move/_Move Now", "<control>M", (GtkItemFactoryCallback) ui_move_now_cb, 0, "" }, #else /* { "/_File", NULL, NULL, 0, "<Branch>" }, { "/File/_Load game", "<control>L", menu_load_file_dialog, 0, "<StockItem>", GTK_STOCK_OPEN }, { "/File/_Save game", NULL, menu_save_file_dialog, 0, "<StockItem>", GTK_STOCK_SAVE }, { "/File/_Quit", "<control>Q", (GtkSignalFunc) ui_cleanup, 0, "<StockItem>", GTK_STOCK_QUIT }, */ { "/_Game", NULL, NULL, 0, "<Branch>" }, { "/Game/Select _Game", NULL, NULL, 0, "<LastBranch>" }, { "/Game/Levels", NULL, NULL, 0, "<Branch>"}, { "/Game/Sep1", NULL, NULL, 0, "<Separator>" }, { "/Game/_New", "<control>N", menu_start_stop_game, MENU_RESET_GAME, "<StockItem>", GTK_STOCK_NEW }, { "/Game/_Start", "<control>G", menu_start_stop_game, MENU_START_GAME, "<StockItem>", GTK_STOCK_YES }, { "/Game/_Pause", "<control>P", menu_start_stop_game, MENU_STOP_GAME, "<StockItem>", GTK_STOCK_STOP }, { "/Game/Sep2", NULL, NULL, 0, "<Separator>" }, //FIXME: there's a scores stock item but I can't seem to find it { "/Game/_Highscores", NULL, prefs_show_scores, 0, ""}, { "/Game/_Zap Highscores", NULL, prefs_zap_highscores, 0, ""}, { "/Game/Sep3", NULL, NULL, 0, "<Separator>" }, { "/Game/_Quit", "<control>Q", (GtkSignalFunc) ui_cleanup, 0, "<StockItem>", GTK_STOCK_QUIT }, { "/_Move", NULL, NULL, 0, "<Branch>" }, { "/Move/_Back", "<control>B", menu_back_forw, 1, "<StockItem>", GTK_STOCK_GO_BACK }, { "/Move/_Forward", "<control>F", menu_back_forw, 2, "<StockItem>", GTK_STOCK_GO_FORWARD }, { "/Move/Sep1", NULL, NULL, 0, "<Separator>" }, { "/Move/_Move Now", "<control>M", (GtkItemFactoryCallback) ui_move_now_cb, 0, "" }, #endif { "/_Settings", NULL, NULL, 0, "<Branch>" }, { "/Settings/_Player", NULL, NULL, 0, "<Branch>" }, { "/Settings/Player/File", NULL, NULL, 0, "<RadioItem>" }, { "/Settings/Player/Human-Human", NULL, menu_set_player, 1, "/Settings/Player/File" }, { "/Settings/Player/Human-Machine", NULL, menu_set_player, 2, "/Settings/Player/File" }, { "/Settings/Player/Machine-Human", NULL, menu_set_player, 3, "/Settings/Player/File" }, { "/Settings/Player/Machine-Machine", NULL, menu_set_player, 4, "/Settings/Player/File" }, // { "/Settings/_Eval function", NULL, NULL, 0, "<Branch>" }, // { "/Settings/_Eval function/_White", NULL, NULL, 0, "<Branch>" }, // { "/Settings/_Eval function/_Black", NULL, NULL, 0, "<Branch>" }, { "/Settings/_Flip Board", "<control>T", menu_board_flip_cb, 0, "" }, { "/Settings/_Enable Sound", NULL, menu_enable_sound_cb, 1, ""}, { "/Settings/_Disable Sound", NULL, menu_enable_sound_cb, 0, ""}, { "/Settings/_Time per move", NULL, NULL, 0, "<Branch>" }, { "/Settings/_Time per move/Default", NULL, menu_set_delay_cb, DEF_TIME_PER_MOVE, "<RadioItem>" }, { "/Settings/_Time per move/100 milliseconds", NULL, menu_set_delay_cb, 100, "/Settings/Time per move/Default" }, { "/Settings/Time per move/200 milliseconds", NULL, menu_set_delay_cb, 200, "/Settings/Time per move/Default" }, { "/Settings/Time per move/500 milliseconds", NULL, menu_set_delay_cb, 500, "/Settings/Time per move/Default" }, { "/Settings/Time per move/1 second", NULL, menu_set_delay_cb, 1000, "/Settings/Time per move/Default" }, { "/Settings/Time per move/2 seconds", NULL, menu_set_delay_cb, 2000, "/Settings/Time per move/Default" }, { "/Settings/Time per move/5 seconds", NULL, menu_set_delay_cb, 5000, "/Settings/Time per move/Default" }, { "/Settings/Time per move/10 seconds", NULL, menu_set_delay_cb, 10000, "/Settings/Time per move/Default" }, { "/Settings/Time per move/30 seconds", NULL, menu_set_delay_cb, 30000, "/Settings/Time per move/Default" }, { "/Settings/Time per move/1 minute", NULL, menu_set_delay_cb, 600000, "/Settings/Time per move/Default" }, { "/_Help", NULL, NULL, 0, "<Branch>" }, { "/Help/_About", NULL, menu_show_about_dialog, 0, ""}, #ifdef HAVE_GNOME { "/Help/_Home Page", NULL, menu_help_home_page, 0, "<StockItem>", GTK_STOCK_HOME}, #endif // TODO: implement context help // { "/Help/_Context help", NULL, ui_set_context_help, 0, ""}, }; int i; gdk_rgb_init (); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_policy (GTK_WINDOW (main_window), FALSE, FALSE, TRUE); gtk_signal_connect (GTK_OBJECT (main_window), "delete_event", GTK_SIGNAL_FUNC(ui_cleanup), NULL); gtk_window_set_title (GTK_WINDOW (main_window), "Gtkboard"); ag = gtk_accel_group_new(); menu_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", ag); gtk_window_add_accel_group (GTK_WINDOW (main_window), ag); gtk_item_factory_create_items (menu_factory, sizeof (items) / sizeof (items[0]), items, NULL); for (i=0; i<=num_games; i++) { if (i==0) game_items[i].path = "/Game/Select Game/none"; else { if (games[i-1]->group) { GtkItemFactoryEntry group_item = {NULL, NULL, NULL, 0, "<Branch>"}; group_item.path = g_strdup_printf ("/Game/Select Game/%s", games[i-1]->group); // FIXME: this is O(N^2) where N is the number of games if (gtk_item_factory_get_widget (menu_factory, group_item.path) == NULL) gtk_item_factory_create_item (menu_factory, &group_item, NULL, 1); game_items[i].path = g_strdup_printf ("/Game/Select Game/%s/%s", games[i-1]->group ? games[i-1]->group : "", games[i-1]->name); } else game_items[i].path = g_strdup_printf ("/Game/Select Game/%s", games[i-1]->name); } game_items[i].accelerator = NULL; game_items[i].callback = menu_set_game; game_items[i].callback_action = i-1; game_items[i].item_type = (i == 0 ? "<RadioItem>": "/Game/Select Game/none"); } gtk_item_factory_create_items (menu_factory, num_games+1, game_items, NULL); // ugly hack to create a group of radio button with no button selected by default gtk_item_factory_delete_item (menu_factory, "/Game/Select Game/none"); menu_main = gtk_item_factory_get_widget (menu_factory, "<main>"); gtk_widget_set_state (gtk_item_factory_get_widget (menu_factory, "/Settings/Player/File"), GTK_STATE_INSENSITIVE); for (i=1; i<=NUM_RECENT_GAMES; i++) { gchar *tmp; gchar *gamename; gamename = prefs_get_config_val (tmp = g_strdup_printf ("recent_game_%d", i)); g_free (tmp); if (gamename && gamename[0] != '\0') menu_insert_game_item (gamename, i); } menu_set_eval_function (); vbox = gtk_vbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX(vbox), menu_main, FALSE, FALSE, 0); frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); { GtkWidget *innerframe; board_colbox = gtk_vbox_new (FALSE, 0); board_area = gtk_drawing_area_new (); hbox = gtk_hbox_new (FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), board_colbox, FALSE, FALSE, 0); vbox1 = gtk_vbox_new (FALSE, 0); board_rowbox = gtk_hbox_new (FALSE, 0); innerframe = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (innerframe), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (vbox1), innerframe); gtk_container_add (GTK_CONTAINER (innerframe), board_area); gtk_container_add (GTK_CONTAINER (vbox1), board_rowbox); gtk_box_pack_start (GTK_BOX (hbox), vbox1, TRUE, FALSE, 0); gtk_container_add (GTK_CONTAINER (frame), hbox); gtk_signal_connect (GTK_OBJECT (board_area), "expose_event", GTK_SIGNAL_FUNC (board_redraw), NULL); gtk_widget_set_events(board_area, gtk_widget_get_events (board_area) | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK ); gtk_signal_connect (GTK_OBJECT (board_area), "leave_notify_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); gtk_signal_connect (GTK_OBJECT (board_area), "motion_notify_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); gtk_signal_connect (GTK_OBJECT (board_area), "button_release_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); gtk_signal_connect (GTK_OBJECT (board_area), "button_press_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); gtk_signal_connect (GTK_OBJECT (main_window), "key_press_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); gtk_signal_connect (GTK_OBJECT (main_window), "key_release_event", GTK_SIGNAL_FUNC (board_signal_handler), NULL); menu_info_bar = hbox = gtk_hbox_new (FALSE, 0); sb_game_label = gtk_label_new (opt_game ? opt_game->name : NULL); gtk_box_pack_start (GTK_BOX (hbox), sb_game_label, FALSE, FALSE, 3); sb_game_separator = gtk_vseparator_new (); gtk_box_pack_start (GTK_BOX (hbox), sb_game_separator, FALSE, FALSE, 0); sb_player_label = gtk_label_new (NULL); gtk_box_pack_start (GTK_BOX (hbox), sb_player_label, FALSE, FALSE, 3); sb_player_separator = gtk_vseparator_new (); gtk_box_pack_start (GTK_BOX (hbox), sb_player_separator, FALSE, FALSE, 0); sb_who_label = gtk_label_new (NULL); gtk_box_pack_start (GTK_BOX (hbox), sb_who_label, FALSE, FALSE, 3); sb_who_separator = gtk_vseparator_new (); gtk_box_pack_start (GTK_BOX (hbox), sb_who_separator, FALSE, FALSE, 0); sb_score_label = gtk_label_new (NULL); gtk_box_pack_start (GTK_BOX (hbox), sb_score_label, FALSE, FALSE, 3); sb_score_separator = gtk_vseparator_new (); gtk_box_pack_start (GTK_BOX (hbox), sb_score_separator, FALSE, FALSE, 0); #if GTK_MAJOR_VERSION == 2 sb_turn_image = gtk_image_new_from_stock (GTK_STOCK_YES, GTK_ICON_SIZE_MENU); gtk_box_pack_end (GTK_BOX (hbox), sb_turn_image, FALSE, FALSE, 0); sb_turn_separator = gtk_vseparator_new (); gtk_box_pack_end (GTK_BOX (hbox), sb_turn_separator, FALSE, FALSE, 0); #endif sb_time_label = gtk_label_new (NULL); gtk_box_pack_end (GTK_BOX (hbox), sb_time_label, FALSE, FALSE, 0); sb_time_separator = gtk_vseparator_new (); gtk_box_pack_end (GTK_BOX (hbox), sb_time_separator, FALSE, FALSE, 0); } menu_info_separator = separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); menu_warning_bar = gtk_label_new ("Warning: this game has not yet been completely implemented."); gtk_box_pack_start (GTK_BOX (vbox), menu_warning_bar, FALSE, FALSE, 0); sb_warning_separator = separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0); sb_message_label = gtk_label_new (NULL); gtk_misc_set_alignment (GTK_MISC (sb_message_label), 0, 0.5); hbox = gtk_hbox_new (TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), sb_message_label, TRUE, TRUE, 3); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (main_window), vbox); // FIXME: board_init() needs show() to be called to get a gc, but // leads to the whole window not popping up at once gtk_widget_show_all (main_window); if (!opt_game) board_init (); gtk_timeout_add (100, sb_update_periodic, NULL); // this should be called before setting state_gui_active = TRUE if (opt_game) menu_put_game (); state_gui_active = TRUE; if (opt_game) menu_start_game (); menu_put_player (TRUE); // if (!opt_game) sb_message ("Select a game from the Game menu", FALSE); sb_update (); }