[Commit] grrobot/src args.c, 1.2, 1.3 args.h, 1.2, 1.3 grr_board_view.c, 1.10, 1.11 grr_board_view.h, 1.7, 1.8 grrobot.c, 1.12, 1.13

Carl Worth commit at keithp.com
Thu Jul 10 19:11:44 PDT 2003


Committed by: cworth

Update of /local/src/CVS/grrobot/src
In directory home.keithp.com:/tmp/cvs-serv11802/src

Modified Files:
	args.c args.h grr_board_view.c grr_board_view.h grrobot.c 
Log Message:
Added keybindings. Can now play a board from a file without any server.

Index: args.c
===================================================================
RCS file: /local/src/CVS/grrobot/src/args.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- args.c	5 Jul 2003 05:41:10 -0000	1.2
+++ args.c	11 Jul 2003 01:11:41 -0000	1.3
@@ -35,8 +35,7 @@
 
 static char doc[] = "grrobot - Ricochet Robot using GTK+ and Xr";
 
-/* XXX: SAMPLE: */
-static char args_doc[] = "<file>";
+static char args_doc[] = "[file]";
 
 static struct argp_option options[] = {
     /* name,		key, arg,	flags, doc */
@@ -71,15 +70,8 @@
 	break;
 
     case ARGP_KEY_ARG:
-	argp_usage (state);
-	break;
-
-/*
-    case ARGP_KEY_END:
-	if (state->arg_num < 1)
-	    argp_usage (state);
+	args->file = arg;
 	break;
-*/
 
     default:
 	return ARGP_ERR_UNKNOWN;
@@ -107,5 +99,9 @@
 	args->game = ARGS_GAME_DEFAULT;
     args->watch = 0;
 
-    return argp_parse (&argp, argc, argv, 0, 0, args);
+    args->file = NULL;
+
+    return argp_parse (&argp, argc, argv,
+		       ARGP_LONG_ONLY,
+		       NULL, args);
 }

Index: args.h
===================================================================
RCS file: /local/src/CVS/grrobot/src/args.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- args.h	5 Jul 2003 05:41:10 -0000	1.2
+++ args.h	11 Jul 2003 01:11:41 -0000	1.3
@@ -44,6 +44,8 @@
     char *port;
     char *user;
     char *game;
+
+    char *file;
     int watch;
 } args_t;
 

Index: grr_board_view.c
===================================================================
RCS file: /local/src/CVS/grrobot/src/grr_board_view.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- grr_board_view.c	27 Jun 2003 03:13:15 -0000	1.10
+++ grr_board_view.c	11 Jul 2003 01:11:41 -0000	1.11
@@ -150,7 +150,7 @@
     }
 }
 
-GtkWidget*
+grr_board_view_t *
 grr_board_view_new (rr_board_t *board)
 {
     grr_board_view_t *view;
@@ -161,7 +161,7 @@
 
     grr_board_view_update (view);
 
-    return GTK_WIDGET (view);
+    return view;
 }
 
 void
@@ -172,6 +172,36 @@
     view->client = client;
 }
 
+void
+grr_board_view_set_active_robot (grr_board_view_t *view, rr_robot_t robot)
+{
+    g_return_if_fail (view != NULL);
+
+    view->active_robot = robot;
+}
+
+void
+grr_board_view_move_active (grr_board_view_t *view, rr_direction_t dir)
+{
+    if (view->client) {
+	rr_client_move (view->client, view->active_robot, dir);
+    } else {
+	rr_board_move (view->board, view->active_robot, dir);
+	gtk_widget_queue_draw (GTK_WIDGET (view));
+    }
+}
+
+void
+grr_board_view_undo (grr_board_view_t *view)
+{
+    if (view->client) {
+	rr_client_undo (view->client);
+    } else {
+	rr_board_undo (view->board);
+	gtk_widget_queue_draw (GTK_WIDGET (view));
+    }
+}
+
 static void
 grr_board_view_destroy (GtkObject *object)
 {
@@ -458,15 +488,16 @@
     }
 
     /* Draw goal target in center of board */
-    XrSave (xrs);
-    {
+    /* XXX: Not a perfect heuristic. Should check for the vacant box too. */
+    if (view->board_width == 16 && view->board_height == 16) {
+	XrSave (xrs);
 	XrTranslate (xrs,
 		     (view->board_width / 2 - 1) * view->cell_width,
 		     (view->board_height / 2 - 1) * view->cell_height);
 	grr_board_view_draw_cell (view, xrs, goal_target, goal_target,
 				  view->cell_width * 2, view->cell_height * 2);
+	XrRestore (xrs);
     }
-    XrRestore (xrs);
 
     /* Draw walls */
     for (j=0; j < view->board_height; j++) {
@@ -495,10 +526,9 @@
     *grid_y = (pointer_y - view->board_pad_y) / view->cell_height;
 }
 
-
 static gint
 grr_board_view_button_press (GtkWidget      *widget,
-		       GdkEventButton *event)
+			     GdkEventButton *event)
 {
     grr_board_view_t *view;
     rr_cell_t cell;
@@ -520,7 +550,7 @@
 	gtk_grab_add (widget);
 
 	view->button = event->button;
-	view->drag_robot = RR_CELL_GET_ROBOT (cell);
+	grr_board_view_set_active_robot (view, RR_CELL_GET_ROBOT (cell));
 
 	grr_board_view_update_mouse (view, event->x, event->y);
     }
@@ -551,7 +581,7 @@
 
     grr_board_view_pointer_coords_to_grid (view, event->x, event->y, &x, &y);
 
-    rr_board_find_robot (view->board, view->drag_robot, &robot_x, &robot_y);
+    rr_board_find_robot (view->board, view->active_robot, &robot_x, &robot_y);
     dx = x - robot_x;
     dy = y - robot_y;
     if (dx == 0 && dy == 0)
@@ -567,11 +597,10 @@
 	    dir = RR_DIRECTION_SOUTH;
 	else
 	    dir = RR_DIRECTION_NORTH;
-    
-    if (view->client)
-	rr_client_move (view->client, view->drag_robot, dir);
 
-  return FALSE;
+    grr_board_view_move_active (view, dir);
+
+    return FALSE;
 }
 
 static gint
@@ -623,7 +652,7 @@
     g_return_if_fail (view != NULL);
     g_return_if_fail (GRR_IS_BOARD_VIEW (view));
 
-    /* XXX: Should draw a robot here */
+    /* XXX: Perhaps should draw a robot here */
 }
 
 static void

Index: grr_board_view.h
===================================================================
RCS file: /local/src/CVS/grrobot/src/grr_board_view.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- grr_board_view.h	27 Jun 2003 03:13:15 -0000	1.7
+++ grr_board_view.h	11 Jul 2003 01:11:41 -0000	1.8
@@ -58,7 +58,7 @@
 
     int cell_width, cell_height;
 
-    rr_robot_t drag_robot;
+    rr_robot_t active_robot;
 
     rr_client_t *client;
     
@@ -80,7 +80,7 @@
     GtkWidgetClass parent_class;
 };
 
-GtkWidget*
+grr_board_view_t *
 grr_board_view_new (rr_board_t *board);
 
 void
@@ -88,6 +88,15 @@
 
 GtkType
 grr_board_view_get_type (void);
+
+void
+grr_board_view_set_active_robot (grr_board_view_t *view, rr_robot_t robot);
+
+void
+grr_board_view_move_active (grr_board_view_t *view, rr_direction_t dir);
+
+void
+grr_board_view_undo (grr_board_view_t *view);
 
 #ifdef __cplusplus
 }

Index: grrobot.c
===================================================================
RCS file: /local/src/CVS/grrobot/src/grrobot.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- grrobot.c	5 Jul 2003 05:41:10 -0000	1.12
+++ grrobot.c	11 Jul 2003 01:11:41 -0000	1.13
@@ -33,6 +33,7 @@
 #include <string.h>
 
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "grr_board_view.h"
 #include "grr_util.h"
@@ -43,7 +44,7 @@
     rr_board_t *board;
 
     GtkWidget *window;
-    GtkWidget *board_view;
+    grr_board_view_t *board_view;
     GtkWidget *command_entry;
 
     GtkTextBuffer *message_buffer;
@@ -85,38 +86,47 @@
     
     args_parse (&args, argc, argv);
 
-    game.client = rr_client_create (args.host, args.port, args.user);
-    if (game.client == NULL) {
-	fprintf (stderr, "Failed connecting to %s:%s as %s\n",
-		 args.host, args.port, args.user);
-	return 1;
-    }
-
-    if (args.watch) {
-	status = rr_client_watch (game.client, args.game);
-	if (status == RR_STATUS_NO_GAME) {
-	    fprintf (stderr, "No game %s to watch\n", args.game);
+    if (args.file) {
+	game.board = rr_board_create_from_file (args.file);
+	if (game.board == NULL) {
+	    fprintf (stderr, "Failed to parse board from %s\n", args.file);
+	    return 1;
 	}
+	game.client = NULL;
     } else {
-	status = rr_client_join (game.client, args.game);
-	if (status == RR_STATUS_NO_GAME) {
-	    status = rr_client_new (game.client, args.game);
+	game.client = rr_client_create (args.host, args.port, args.user);
+	if (game.client == NULL) {
+	    fprintf (stderr, "Failed connecting to %s:%s as %s\n",
+		     args.host, args.port, args.user);
+	    return 1;
 	}
-    }
 
-    game.board = rr_board_create (16, 16);
-    game.msg_id = 0;
-    game.last_move_msg_id = 0;
-    game.last_move_robot = RR_ROBOT_NONE;
+	if (args.watch) {
+	    status = rr_client_watch (game.client, args.game);
+	    if (status == RR_STATUS_NO_GAME) {
+		fprintf (stderr, "No game %s to watch\n", args.game);
+	    }
+	} else {
+	    status = rr_client_join (game.client, args.game);
+	    if (status == RR_STATUS_NO_GAME) {
+		status = rr_client_new (game.client, args.game);
+	    }
+	}
 
-    source = grr_game_notices_source_new (&game);
-    g_source_set_priority (source, GDK_PRIORITY_EVENTS);
-    g_source_attach (source, NULL);
-    g_source_unref (source);
+	game.board = rr_board_create (16, 16);
+	game.msg_id = 0;
+	game.last_move_msg_id = 0;
+	game.last_move_robot = RR_ROBOT_NONE;
 
-    rr_client_show (game.client, &diagram);
-    rr_board_parse (game.board, diagram);
-    free (diagram);
+	source = grr_game_notices_source_new (&game);
+	g_source_set_priority (source, GDK_PRIORITY_EVENTS);
+	g_source_attach (source, NULL);
+	g_source_unref (source);
+
+	rr_client_show (game.client, &diagram);
+	rr_board_parse (game.board, diagram);
+	free (diagram);
+    }
 
     return grr_game_start_gui (&game);
 }
@@ -229,6 +239,10 @@
 			     notice->u.message.username,
 			     notice->u.message.text);
 	    break;
+	case RR_NOTICE_BOARD:
+	    rr_board_parse (board, notice->u.string);
+	    gtk_widget_queue_draw (GTK_WIDGET (game->window));
+	    break;
 	case RR_NOTICE_GAMESTATE:
 	    grr_game_printf (game, "\nGame state changed to: %s.",
 			     rr_gamestate_str (notice->u.gamestate));
@@ -239,16 +253,8 @@
 	    gtk_widget_queue_draw (GTK_WIDGET (game->window));
 	    break;
 	case RR_NOTICE_GAMEOVER:
-	{
-	    char *diagram;
 	    grr_game_printf (game, "\nGame over. New game will begin now.");
-	    /* XXX: Can drop this when the BOARD NOTICE is added in the server */
-	    rr_client_show (game->client, &diagram);
-	    rr_board_parse (board, diagram);
-	    free (diagram);
-	    gtk_widget_queue_draw (GTK_WIDGET (game->window));
-	}
-	break;
+	    break;
 	case RR_NOTICE_JOIN:
 	    grr_game_printf (game, "\nUser %s has joined the game.",
 			     notice->u.string);
@@ -316,15 +322,87 @@
 			     notice->u.number);
 	    break;
 	case RR_NOTICE_POSITION:
-	    rr_board_position_robot (board, notice->u.position.robot,
-				     notice->u.position.x, notice->u.position.y);
+	    rr_board_add_robot (board, notice->u.position.robot,
+				notice->u.position.x, notice->u.position.y);
 	    gtk_widget_queue_draw (GTK_WIDGET (game->window));
 	    break;
+	default:
+	    fprintf (stderr, "Unknown notice: %d\n", notice->type);
+	    break;
 	}
 	free (notice);
     }
 }
 
+static gboolean
+grr_game_key_press_callback (GtkWidget *widget,
+			     GdkEventKey *event,
+			     grr_game_t *game)
+{
+    if (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (game->command_entry))) {
+	if (event->keyval == GDK_Escape) {
+	    gtk_entry_set_text (GTK_ENTRY (game->command_entry), "");
+	    gtk_widget_grab_focus (GTK_WIDGET (game->message_view));
+
+	    return TRUE;
+	} else {
+	    return FALSE;
+	}
+    }
+
+    switch (event->keyval) {
+    case GDK_B:
+    case GDK_b:
+	grr_board_view_set_active_robot (game->board_view, RR_ROBOT_BLUE);
+	break;
+    case GDK_G:
+    case GDK_g:
+	grr_board_view_set_active_robot (game->board_view, RR_ROBOT_GREEN);
+	break;
+    case GDK_R:
+    case GDK_r:
+	grr_board_view_set_active_robot (game->board_view, RR_ROBOT_RED);
+	break;
+    case GDK_Y:
+    case GDK_y:
+	grr_board_view_set_active_robot (game->board_view, RR_ROBOT_YELLOW);
+	break;
+    case GDK_Up:
+	grr_board_view_move_active (game->board_view, RR_DIRECTION_NORTH);
+	break;
+    case GDK_Right:
+	grr_board_view_move_active (game->board_view, RR_DIRECTION_EAST);
+	break;
+    case GDK_Down:
+	grr_board_view_move_active (game->board_view, RR_DIRECTION_SOUTH);
+	break;
+    case GDK_Left:
+	grr_board_view_move_active (game->board_view, RR_DIRECTION_WEST);
+	break;
+    case GDK_BackSpace:
+	grr_board_view_undo (game->board_view);
+	break;
+    case GDK_space:
+    case GDK_slash:
+	gtk_widget_grab_focus (GTK_WIDGET (game->command_entry));
+	if (event->keyval == GDK_slash) {
+	    int pos = -1;
+	    gtk_editable_insert_text (GTK_EDITABLE (game->command_entry),
+				      "/", 1, &pos);
+	    gtk_editable_set_position (GTK_EDITABLE (game->command_entry), -1);
+	}
+	break;
+    case GDK_Q:
+    case GDK_q:
+	if (event->state & GDK_CONTROL_MASK) {
+	    gtk_exit (0);
+	}
+	break;
+    }
+
+    return TRUE;
+}
+
 static void
 grr_game_entry_callback (GtkWidget *widget,
 			 grr_game_t *game)
@@ -336,18 +414,25 @@
 
     entry_text = gtk_entry_get_text (GTK_ENTRY (game->command_entry));
 
-    status = rr_client_request (game->client, entry_text, &response);
-    if (status) {
-	grr_game_printf (game, "\nERROR: %s.", rr_status_str (status));
-    } else {
-	if (response[0]) {
-	    grr_game_print (game, "\n");
-	    for (i=0; response[i]; i++)
-		grr_game_printf (game, "%s ", response[i]);
+    if (entry_text && entry_text[0] && game->client) {
+	if (entry_text[0] == '/') {
+	    status = rr_client_request (game->client, entry_text + 1, &response);
+	    if (status) {
+		grr_game_printf (game, "\nERROR: %s.", rr_status_str (status));
+	    } else {
+		if (response[0]) {
+		    grr_game_print (game, "\n");
+		    for (i=0; response[i]; i++)
+			grr_game_printf (game, "%s ", response[i]);
+		}
+	    }
+	} else {
+	    rr_client_message (game->client, entry_text);
 	}
     }
 
     gtk_entry_set_text (GTK_ENTRY (game->command_entry), "");
+    gtk_widget_grab_focus (GTK_WIDGET (game->message_view));
 
 /* XXX: Huh? Why is this triggering valgrind?
     free (response);
@@ -452,8 +537,8 @@
 	    board_frame = gtk_aspect_frame_new (NULL, 0.5, 0.5, 1.0, FALSE);
 	    gtk_paned_pack1 (GTK_PANED (vpaned), board_frame, TRUE, TRUE);
 	    {
-		gtk_container_add (GTK_CONTAINER (board_frame), game->board_view);
-		gtk_widget_show (game->board_view);
+		gtk_container_add (GTK_CONTAINER (board_frame), GTK_WIDGET (game->board_view));
+		gtk_widget_show (GTK_WIDGET (game->board_view));
 	    }
 	    gtk_widget_show (board_frame);
 
@@ -482,6 +567,10 @@
 			  (gpointer) game);
     }
     gtk_widget_show (vbox);
+
+    g_signal_connect (G_OBJECT (window), "key_press_event",
+		      G_CALLBACK (grr_game_key_press_callback),
+		      (gpointer) game);
 
     gtk_widget_show (window);
     




More information about the Commit mailing list