diff options
| author | Bradley Smith | 2008-08-03 16:22:59 +0100 | 
|---|---|---|
| committer | Bradley Smith | 2008-08-03 16:22:59 +0100 | 
| commit | ae3a780491b700be0258b1c2243c86cf10729fcc (patch) | |
| tree | f274f87c4d0bd3bc91e29f0dcc8c90da4b59c028 | |
| parent | Add more uitest stuff. (diff) | |
| download | gnurobots-ae3a780491b700be0258b1c2243c86cf10729fcc.tar.gz | |
Add Gtk interface. Using a Vte for guile input.
Signed-off-by: Bradley Smith <brad@brad-smith.co.uk>
| -rw-r--r-- | Makefile.am | 2 | ||||
| -rw-r--r-- | configure.ac | 52 | ||||
| -rw-r--r-- | include/Makefile.am | 16 | ||||
| -rw-r--r-- | include/grobot.h | 6 | ||||
| -rw-r--r-- | include/ui-arena.h (renamed from ui/ui-arena.h) | 27 | ||||
| -rw-r--r-- | include/ui-cmdwin.h (renamed from ui/ui-cmdwin.h) | 2 | ||||
| -rw-r--r-- | include/ui-window-private.h (renamed from ui/ui-window-private.h) | 0 | ||||
| -rw-r--r-- | include/ui-window.h (renamed from ui/ui-window.h) | 5 | ||||
| -rw-r--r-- | include/userinterface.h | 180 | ||||
| -rw-r--r-- | src/Makefile.am | 20 | ||||
| -rw-r--r-- | src/grobot.c | 1449 | ||||
| -rw-r--r-- | src/main.c | 737 | ||||
| -rw-r--r-- | src/ui-arena.c | 466 | ||||
| -rw-r--r-- | src/ui-cmdwin.c (renamed from ui/ui-cmdwin.c) | 46 | ||||
| -rw-r--r-- | src/ui-window.c (renamed from ui/ui-window.c) | 38 | ||||
| -rw-r--r-- | src/userinterface.c | 736 | ||||
| -rw-r--r-- | ui/Makefile.am | 23 | ||||
| -rw-r--r-- | ui/design.glade | 317 | ||||
| -rw-r--r-- | ui/main.c | 34 | ||||
| -rw-r--r-- | ui/ui-arena.c | 45 | 
20 files changed, 1686 insertions, 2515 deletions
| diff --git a/Makefile.am b/Makefile.am index 4eb65b9..fdc4977 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,7 @@  ## along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>.  AUTOMAKE_OPTIONS     = 1.8.5 -SUBDIRS              = contrib doc include maps scheme src xpm ui +SUBDIRS              = contrib doc include maps scheme src xpm  EXTRA_DIST           = build  MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure diff --git a/configure.ac b/configure.ac index d4c7838..ff26b62 100644 --- a/configure.ac +++ b/configure.ac @@ -28,41 +28,23 @@ dnl Checks for programs.  AC_PROG_CC  dnl libtool stuff -AC_LIBTOOL_DLOPEN -dnl AC_LIBLTDL_CONVENIENCE  AC_DISABLE_STATIC  AC_PROG_LIBTOOL -AC_SUBST(INCLTDL) -AC_SUBST(LIBLTDL) - -dnl Locate X Windows -dnl We need AC_PATH_XTRA to also locate extra libaries X depends on. -dnl It will ``export'' X_CFLAGS, X_PRE_LIBS, X_EXTRA_LIBS and X_LIBS, -dnl but for some reason we need to add -lX11 ourselves. -AC_PATH_XTRA - -dnl Check for math library -AC_CHECK_LIB(m, pow) -  dnl Check for guile  GUILE_FLAGS -dnl Some sytems need -ldl for dynamic library support. -dnl AC_CHECK_LIB(dl, dlopen) +PKG_CHECK_MODULES(GTHREAD2, gthread-2.0 >= 2.4) +AC_SUBST(GTHREAD2_LIBS) +AC_SUBST(GTHREAD2_CFLAGS) -PKG_CHECK_MODULES(X,x11 xpm, HAVE_X=yes,HAVE_X=no) -AC_SUBST(X_LIBS) -AC_SUBST(X_CFLAGS) +PKG_CHECK_MODULES(GTK2, gtk+-2.0 >= 2.4) +AC_SUBST(GTK2_LIBS) +AC_SUBST(GTK2_CFLAGS) -dnl Check for glib2 -PKG_CHECK_MODULES(GLIB2,glib-2.0 >= 2.4 gobject-2.0 gmodule-2.0,HAVE_GLIB2=yes,HAVE_GLIB2=no) -AC_SUBST(GLIB2_LIBS) -AC_SUBST(GLIB2_CFLAGS) - -PKG_CHECK_MODULES(GTK,gtk+-2.0 >= 2.4, HAVE_GTK=yes,HAVE_GTK=no) -AC_SUBST(GTK_LIBS) -AC_SUBST(GTK_CFLAGS) +PKG_CHECK_MODULES(VTE, vte) +AC_SUBST(VTE_LIBS) +AC_SUBST(VTE_CFLAGS)  schemedir="\$(pkgdatadir)/scheme"  AC_SUBST(schemedir) @@ -70,10 +52,6 @@ AC_SUBST(schemedir)  mapsdir="\$(pkgdatadir)/maps"  AC_SUBST(mapsdir) -if test "x$HAVE_GLIB2" = "xno"; then -  AC_MSG_ERROR([GNU Robots requires GLib2 to compile.]) -fi -  for termlib in ncurses curses termcap terminfo termlib ; do  	AC_CHECK_LIB(${termlib}, tgoto,  		[READLINE_EXTRA="-l${termlib}"; break]) @@ -86,8 +64,8 @@ You need the GNU Readline library to build this program.  ]),[$READLINE_EXTRA]) -AC_CHECK_HEADER(readline/readline.h,[READLINE_CFLAGS=-I/usr/include/readline/], -	AC_MSG_ERROR([ +AC_CHECK_HEADER(readline/readline.h, +    [READLINE_CFLAGS=-I/usr/include/readline/],	AC_MSG_ERROR([  You need the GNU Readline headers to build this program. @@ -102,6 +80,13 @@ dnl Checks for header files.  AC_HEADER_STDC  AC_CHECK_HEADERS(unistd.h)  AC_CHECK_HEADERS(getopt.h) +AC_CHECK_HEADERS(pty.h) + +AC_CHECK_LIB(util, openpty,	[], AC_MSG_ERROR([ + +You need openpty to build the program. + +]))  dnl Checks for typedefs, structures, and compiler characteristics.  AC_C_CONST @@ -117,7 +102,6 @@ AC_CONFIG_FILES([Makefile   maps/Makefile   scheme/Makefile   src/Makefile - ui/Makefile   ])  AC_OUTPUT diff --git a/include/Makefile.am b/include/Makefile.am index bb2a455..47a3c86 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -15,10 +15,12 @@  ## You should have received a copy of the GNU General Public License  ## along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. -EXTRA_DIST =\ - api.h\ - configs.h\ - map.h\ - main.h\ - grobot.h\ - userinterface.h +EXTRA_DIST = \ + api.h \ + configs.h \ + map.h \ + main.h \ + grobot.h \ + ui-window.h \ + ui-arena.h \ + ui-cmdwin.h diff --git a/include/grobot.h b/include/grobot.h index fd7f794..52a7039 100644 --- a/include/grobot.h +++ b/include/grobot.h @@ -21,7 +21,7 @@  #include <glib-object.h>  #include <glib.h> -#include "userinterface.h" +#include "ui-arena.h"  #include "map.h"  G_BEGIN_DECLS @@ -53,7 +53,7 @@ struct _GRobot {    glong     shots;    glong     units; -  UserInterface *ui; +  UIArena *ui;    Map *map;  }; @@ -73,7 +73,7 @@ GType g_robot_get_type(void) G_GNUC_CONST;  /* Our object functions */  GRobot* g_robot_new(int x, int y, int dir, long score, long energy, -        long shield, long units, long shots, UserInterface *ui, Map *map); +        long shield, long units, long shots, UIArena *ui, Map *map);  void        g_robot_turn            (GRobot *robot, gint num_turns);  gboolean    g_robot_move            (GRobot *robot, gint steps); diff --git a/ui/ui-arena.h b/include/ui-arena.h index 5277f54..2fee88f 100644 --- a/ui/ui-arena.h +++ b/include/ui-arena.h @@ -21,6 +21,8 @@  #include <gtk/gtk.h> +#include "map.h" +  G_BEGIN_DECLS  #define UI_TYPE_ARENA \ @@ -34,6 +36,8 @@ G_BEGIN_DECLS  #define IS_UI_ARENA_CLASS(klass) \      G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_ARENA) +#define dist(f_x, f_y, t_x, t_y) (abs((f_x)-(t_x))+abs((f_y)-(t_y))) +  typedef struct _UIArena UIArena;  typedef struct _UIArenaClass UIArenaClass;  typedef struct _UIArenaPrivate UIArenaPrivate; @@ -51,7 +55,28 @@ struct _UIArenaClass  GType ui_arena_get_type(void) G_GNUC_CONST; -GtkWidget *ui_arena_new(void); +GtkWidget *ui_arena_new(); + +void ui_arena_set_map(UIArena *arena, Map *map); +void ui_arena_postinit(UIArena *arena); +void ui_arena_draw(UIArena *arena); +void ui_arena_update_status(UIArena *arena, const gchar *s, glong energy, +	glong score, glong shields); + +void ui_arena_add_thing(UIArena *arena, gint x, gint y, gint thing); +void ui_arena_move_robot(UIArena *arena, gint from_x, gint from_y, +	gint to_x, gint to_y, gint cdir, glong energy, glong score, +	glong shields); +void ui_arena_robot_smell(UIArena *arena, gint x, gint y, gint cdir, +	glong energy, glong score, glong shields); +void ui_arena_robot_zap(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields); +void ui_arena_robot_feel(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields); +void ui_arena_robot_grab(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields); +void ui_arena_robot_look(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields);  G_END_DECLS diff --git a/ui/ui-cmdwin.h b/include/ui-cmdwin.h index c3bcf8a..1c6196d 100644 --- a/ui/ui-cmdwin.h +++ b/include/ui-cmdwin.h @@ -52,6 +52,8 @@ struct _UICmdWinClass  GType ui_cmdwin_get_type(void) G_GNUC_CONST;  GtkWidget *ui_cmdwin_new(void); +void ui_cmdwin_get_string(UICmdWin *cmdwin, gchar *prompt, gchar *buf, +	gint len);  G_END_DECLS diff --git a/ui/ui-window-private.h b/include/ui-window-private.h index cfb8b63..cfb8b63 100644 --- a/ui/ui-window-private.h +++ b/include/ui-window-private.h diff --git a/ui/ui-window.h b/include/ui-window.h index 450223b..7b6c06f 100644 --- a/ui/ui-window.h +++ b/include/ui-window.h @@ -19,6 +19,8 @@  #ifndef __UI_WINDOW_H__  #define __UI_WINDOW_H__ +#include "map.h" +  #include <gtk/gtkwindow.h>  G_BEGIN_DECLS @@ -51,7 +53,8 @@ struct _UIWindowClass  GType ui_window_get_type(void) G_GNUC_CONST; -GtkWidget *ui_window_new(void); +GtkWidget *ui_window_new(); +void ui_window_postinit(UIWindow *window, Map* map);  G_END_DECLS diff --git a/include/userinterface.h b/include/userinterface.h deleted file mode 100644 index fc92e9c..0000000 --- a/include/userinterface.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNU Robots is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __USER_INTERFACE_H__ -#define __USER_INTERFACE_H__ - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/xpm.h> -#include <X11/keysym.h> - -#include <glib-object.h> -/*#include "userinterface.h"*/ -#include "map.h" - -G_BEGIN_DECLS - -#define G_TYPE_USER_INTERFACE			  user_interface_get_type() -#define G_IS_USER_INTERFACE(obj)		  G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ -                                          G_TYPE_USER_INTERFACE) -#define G_IS_USER_INTERFACE_CLASS(klass)  G_TYPE_CHECK_CLASS_TYPE ((klass), \ -                                          G_TYPE_USER_INTERFACE) -#define USER_INTERFACE_GET_CLASS(obj)	  G_TYPE_INSTANCE_GET_CLASS ((obj), \ -                                          G_TYPE_USER_INTERFACE, \ -                                          UserInterfaceClass) -#define USER_INTERFACE(obj)			      G_TYPE_CHECK_INSTANCE_CAST ((obj), \ -                                          G_TYPE_USER_INTERFACE, UserInterface) -#define USER_INTERFACE_CLASS(klass)		  G_TYPE_CHECK_CLASS_CAST ((klass), \ -                                          G_TYPE_USER_INTERFACE, \ -                                          UserInterfaceClass) - -typedef struct _UserInterface UserInterface; -typedef struct _UserInterfaceClass UserInterfaceClass; - -struct _UserInterface { -  GObject 	object; -  Map 		*map; -  MapSize 	*map_size; - -  Display 	*dpy; -  Window 	x_win; -  Atom      wm_delete_win; -  Atom      wm_protocols; -  GC 		gc; -  GC 		buf_gc; -  Font 		text; - -#ifdef USE_MITSHM -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> -  XShmSegmentInfo shm_info; -  guchar 	      use_mitshm = 1; -#endif - -  gint 		win_width; -  gint 		win_height; - -  Pixmap 	win_buf; - -  XImage 	*win_bufi; -  XImage 	*statusbar; -  XImage 	*space; -  XImage 	*food; -  XImage 	*wall; -  XImage 	*prize; -  XImage 	*baddie; -  XImage 	*robotDirs[4]; -  XImage 	*robotPix; -}; - -struct _UserInterfaceClass { -  GObjectClass	parent_class; -}; - -/* normal GObject stuff */ -GType       user_interface_get_type		(void); - -UserInterface*	user_interface_new 		(Map* map); - -void    user_interface_add_thing        (UserInterface *ui, -                     gint x, -                     gint y, -                     gint thing); - -void    user_interface_run              (UserInterface *ui); - -void    user_interface_draw             (UserInterface *ui); - -void    user_interface_update_status    (UserInterface *ui, -                     const gchar *s, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_move_robot       (UserInterface *ui, -                     gint from_x, -                     gint from_y, -                     gint to_x, -                     gint to_y, -                     gint cdir, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_robot_smell      (UserInterface *ui, -                     gint x, -                     gint y, -                     gint cdir, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_robot_zap        (UserInterface *ui, -                     gint x, -                     gint y, -                     gint cdir, -                     gint x_to, -                     gint y_to, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_robot_feel       (UserInterface *ui, -                     gint x, -                     gint y, -                     gint cdir, -                     gint x_to, -                     gint y_to, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_robot_grab       (UserInterface *ui, -                     gint x, -                     gint y, -                     gint cdir, -                     gint x_to, -                     gint y_to, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_robot_look       (UserInterface *ui, -                     gint x, -                     gint y, -                     gint cdir, -                     gint x_to, -                     gint y_to, -                     glong energy, -                     glong score, -                     glong shields); - -void    user_interface_get_string       (UserInterface *ui, -                     gchar *prompt, -                     gchar *buff, -                     gint len); - -/* SYMBOLIC CONSTANTS */ -#define dist(f_x, f_y, t_x, t_y) (abs((f_x)-(t_x))+abs((f_y)-(t_y))) - -G_END_DECLS - -#endif /* __USER_INTERFACE_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index b839875..75522e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,14 +17,16 @@  bin_PROGRAMS = gnurobots -INCLUDES = $(GLIB2_CFLAGS) $(GUILE_CFLAGS) $(READLINE_CFLAGS) $(X_FLAGS) \ +INCLUDES = $(GUILE_CFLAGS) $(READLINE_CFLAGS) $(GTK2_CFLAGS) $(VTE_CFLAGS) \ +		$(GTHREAD2_CFLAGS) \  		-I$(top_builddir)/include \ -	   -DPKGLIBDIR=\"$(pkglibdir)\" \ -	   -DABS_TOP_BUILDDIR=\"$(abs_top_builddir)\" \ -	   -DPKGDATADIR=\"$(pkgdatadir)\" \ -	   -DMAPS_PATH=\"$(mapsdir)\" \ -	   -DSCRIPTS_PATH=\"$(schemedir)\" +	   	-DPKGLIBDIR=\"$(pkglibdir)\" \ +	   	-DABS_TOP_BUILDDIR=\"$(abs_top_builddir)\" \ +	   	-DPKGDATADIR=\"$(pkgdatadir)\" \ +	   	-DMAPS_PATH=\"$(mapsdir)\" \ +	   	-DSCRIPTS_PATH=\"$(schemedir)\" -gnurobots_SOURCES = main.c api.c map.c grobot.c userinterface.c -gnurobots_LDFLAGS = $(GLIB2_LIBS) $(GUILE_LDFLAGS) $(READLINE_LIBS) \ -		$(X_LIBS) -lltdl -lgthread-2.0 +gnurobots_SOURCES = main.c api.c map.c grobot.c \ +		ui-window.c ui-cmdwin.c ui-arena.c +gnurobots_LDFLAGS = $(GUILE_LDFLAGS) $(READLINE_LIBS) $(GTHREAD2_LIBS) \ +		$(GTK2_LIBS) $(VTE_LIBS) -lutil diff --git a/src/grobot.c b/src/grobot.c index 22eb777..bf3c394 100644 --- a/src/grobot.c +++ b/src/grobot.c @@ -19,7 +19,6 @@  #include "grobot.h"  #include "configs.h" -#include "userinterface.h"  /* GNU Robots UI */  #include <stdio.h>  #include <glib.h>  #include <string.h> @@ -29,834 +28,798 @@ G_DEFINE_TYPE(GRobot, g_robot, G_TYPE_OBJECT)  enum  { -  DEATH, -  LAST_SIGNAL +	DEATH, +	LAST_SIGNAL  };  enum  { -  ARG_0, -  ARG_POS_X, -  ARG_POS_Y, -  ARG_DIRECTION, -  ARG_SCORE, -  ARG_ENERGY, -  ARG_SHIELDS, -  ARG_UNITS, -  ARG_SHOTS, -  ARG_USER_INTERFACE, -  ARG_MAP +	ARG_0, +	ARG_POS_X, +	ARG_POS_Y, +	ARG_DIRECTION, +	ARG_SCORE, +	ARG_ENERGY, +	ARG_SHIELDS, +	ARG_UNITS, +	ARG_SHOTS, +	ARG_USER_INTERFACE, +	ARG_MAP  };  static gchar *things[] = { "space", "food", "prize", "wall", "baddie", -    "robot" }; +	"robot" +};  static gint cthings[] = { SPACE, FOOD, PRIZE, WALL, BADDIE, ROBOT };  static guint g_robot_signals[LAST_SIGNAL] = { 0 }; -static void g_robot_dispose (GObject * object); -static void g_robot_finalize (GObject * object); +static void g_robot_dispose(GObject *object); +static void g_robot_finalize(GObject *object); -static void g_robot_set_property (GObject * object, guint prop_id, -    const GValue * value, GParamSpec * pspec); +static void g_robot_set_property(GObject *object, guint prop_id, +	const GValue *value, GParamSpec *pspec); -static void g_robot_get_property (GObject * object, guint prop_id, -    GValue * value, GParamSpec * pspec); +static void g_robot_get_property(GObject *object, guint prop_id, +	GValue *value, GParamSpec * pspec);  static GObjectClass *parent_class = NULL; -static gint what_thing (const gchar *th); +static gint what_thing(const gchar *th); -static void -g_robot_init (GRobot* robot) +static void g_robot_init(GRobot *robot)  { -  /* Nothing yet, need to do priv stuff */ +	/* Nothing yet, need to do priv stuff */  } -static void -g_robot_class_init (GRobotClass *klass) +static void g_robot_class_init(GRobotClass *klass)  { -  GObjectClass *gobject_class; - -  gobject_class = (GObjectClass *) klass; - -  parent_class = g_type_class_ref (G_TYPE_OBJECT); - -  gobject_class->dispose = g_robot_dispose; -  gobject_class->finalize = g_robot_finalize; -  gobject_class->set_property = g_robot_set_property; -  gobject_class->get_property = g_robot_get_property; - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_POS_X, -                  g_param_spec_int ("x", -                          "x", -                          "X co-ordinate of current Position of the Robot", -                           G_MININT, -                           G_MAXINT, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_POS_Y, -                  g_param_spec_int ("y", -                           "y", -                           "y co-ordinate of current Position of the Robot", -                           G_MININT, -                           G_MAXINT, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DIRECTION, -                  g_param_spec_int ("direction", -                           "direction", -                           "current Direction of the Robot", -                           G_MININT, -                           G_MAXINT, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SCORE, -                  g_param_spec_long ("score", -                           "Score", -                           "current Score of the Robot", -                           G_MINLONG, -                           G_MAXLONG, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ENERGY, -                  g_param_spec_long ("energy", -                           "Energy", -                           "current Energy-level of the Robot", -                           G_MINLONG, -                           G_MAXLONG, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SHIELDS, -                  g_param_spec_long ("shields", -                           "Shields", -                           "current Shield-level of the Robot", -                           G_MINLONG, -                           G_MAXLONG, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_UNITS, -                  g_param_spec_long ("units", -                           "Units", -                           "Units walked by the Robot so far", -                           G_MINLONG, -                           G_MAXLONG, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SHOTS, -                  g_param_spec_long ("shots", -                           "Shots", -                           "Number of Shots fired by the Robot", -                           G_MINLONG, -                           G_MAXLONG, -                           0, -                           G_PARAM_READWRITE | -                           G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), -      ARG_USER_INTERFACE, -                  g_param_spec_object ("user-interface", -                          "UserInterface", -                          "Reference to the UI object", -                          G_TYPE_OBJECT, -                          G_PARAM_READWRITE | -                          G_PARAM_CONSTRUCT)); - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAP, -                  g_param_spec_object ("map", -                          "Map", -                          "Reference to the Game Map object", -                          G_TYPE_OBJECT, -                          G_PARAM_READWRITE | -                          G_PARAM_CONSTRUCT)); - -  g_robot_signals[DEATH] = -                  g_signal_new ("death", -                          G_TYPE_FROM_CLASS (klass), -                          G_SIGNAL_RUN_LAST, -                          G_STRUCT_OFFSET (GRobotClass, death), -                          NULL, -                          NULL, -                          g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, -                          NULL); +	GObjectClass *gobject_class; + +	gobject_class = (GObjectClass *) klass; + +	parent_class = g_type_class_ref(G_TYPE_OBJECT); + +	gobject_class->dispose = g_robot_dispose; +	gobject_class->finalize = g_robot_finalize; +	gobject_class->set_property = g_robot_set_property; +	gobject_class->get_property = g_robot_get_property; + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_POS_X, +		g_param_spec_int("x", +			"x", +			"X co-ordinate of current Position of the Robot", +			G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_POS_Y, +		g_param_spec_int("y", +			"y", +			"y co-ordinate of current Position of the Robot", +			G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DIRECTION, +		g_param_spec_int("direction", +			"direction", +			"current Direction of the Robot", +			G_MININT, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SCORE, +		g_param_spec_long("score", +			"Score", +			"current Score of the Robot", +			G_MINLONG, G_MAXLONG, 0, +			G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ENERGY, +		g_param_spec_long("energy", +			"Energy", +			"current Energy-level of the Robot", +			G_MINLONG, G_MAXLONG, 0, +			G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SHIELDS, +		g_param_spec_long("shields", +			"Shields", +			"current Shield-level of the Robot", +			G_MINLONG, G_MAXLONG, 0, +			G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_UNITS, +		g_param_spec_long("units", +			"Units", +			"Units walked by the Robot so far", +			G_MINLONG, G_MAXLONG, 0, +			G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SHOTS, +		g_param_spec_long("shots", +			"Shots", +			"Number of Shots fired by the Robot", +			G_MINLONG, G_MAXLONG, 0, +			G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), +		ARG_USER_INTERFACE, +		g_param_spec_object("user-interface", +			"UserInterface", +			"Reference to the UI object", +			G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MAP, +		g_param_spec_object("map", +			"Map", +			"Reference to the Game Map object", +			G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + +	g_robot_signals[DEATH] = +		g_signal_new("death", +		G_TYPE_FROM_CLASS(klass), +		G_SIGNAL_RUN_LAST, +		G_STRUCT_OFFSET(GRobotClass, death), +		NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, NULL);  }  static void -g_robot_set_property (GObject *object, guint prop_id, const GValue *value, -        GParamSpec *pspec) +g_robot_set_property(GObject *object, guint prop_id, const GValue *value, +	GParamSpec *pspec)  { -  GRobot *robot; -  GObject *obj; - -  /* it's not null if we got it, but it might not be ours */ -  g_return_if_fail (G_IS_ROBOT (object)); - -  robot = G_ROBOT (object); - -  switch (prop_id) -  { -  case ARG_POS_X: -    robot->x = g_value_get_int (value); -    break; -  case ARG_POS_Y: -    robot->y = g_value_get_int (value); -    break; -  case ARG_DIRECTION: -    robot->dir = g_value_get_int (value); -    break; -  case ARG_SCORE: -    robot->score = g_value_get_long (value); -    break; -  case ARG_ENERGY: -    robot->energy = g_value_get_long (value); -    break; -  case ARG_SHIELDS: -    robot->shields = g_value_get_long (value); -    break; -  case ARG_SHOTS: -    robot->shots = g_value_get_long (value); -    break; -  case ARG_UNITS: -    robot->units = g_value_get_long (value); -    break; -  case ARG_USER_INTERFACE: -    if (robot->ui != NULL) -    { -      g_object_unref (robot->ui); -    } - -    obj = g_value_get_object (value); -    if (obj != NULL) -    { -      robot->ui = g_object_ref (obj); -    } - -    else -    { -      robot->ui = NULL; -    } -    break; -  case ARG_MAP: -    if (robot->map != NULL) -    { -      g_object_unref (robot->map); -    } - -    obj = g_value_get_object (value); -    if (obj != NULL) -    { -      robot->map = g_object_ref (obj); -    } - -    else -    { -      robot->map = NULL; -    } -    break; -  default: -    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -    break; -  } +	GRobot *robot; +	GObject *obj; + +	/* it's not null if we got it, but it might not be ours */ +	g_return_if_fail(G_IS_ROBOT(object)); + +	robot = G_ROBOT(object); + +	switch (prop_id) +	{ +	case ARG_POS_X: +		robot->x = g_value_get_int(value); +		break; +	case ARG_POS_Y: +		robot->y = g_value_get_int(value); +		break; +	case ARG_DIRECTION: +		robot->dir = g_value_get_int(value); +		break; +	case ARG_SCORE: +		robot->score = g_value_get_long(value); +		break; +	case ARG_ENERGY: +		robot->energy = g_value_get_long(value); +		break; +	case ARG_SHIELDS: +		robot->shields = g_value_get_long(value); +		break; +	case ARG_SHOTS: +		robot->shots = g_value_get_long(value); +		break; +	case ARG_UNITS: +		robot->units = g_value_get_long(value); +		break; +	case ARG_USER_INTERFACE: +		if (robot->ui != NULL) +		{ +			g_object_unref(robot->ui); +		} + +		obj = g_value_get_object(value); +		if (obj != NULL) +		{ +			robot->ui = g_object_ref(obj); +		} + +		else +		{ +			robot->ui = NULL; +		} +		break; +	case ARG_MAP: +		if (robot->map != NULL) +		{ +			g_object_unref(robot->map); +		} + +		obj = g_value_get_object(value); +		if (obj != NULL) +		{ +			robot->map = g_object_ref(obj); +		} + +		else +		{ +			robot->map = NULL; +		} +		break; +	default: +		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +		break; +	}  }  static void -g_robot_get_property (GObject *object, guint prop_id, GValue *value, -        GParamSpec *pspec) +g_robot_get_property(GObject *object, guint prop_id, GValue *value, +	GParamSpec *pspec)  { -  GRobot *robot; - -  /* it's not null if we got it, but it might not be ours */ -  g_return_if_fail (G_IS_ROBOT (object)); - -  robot = G_ROBOT (object); - -  switch (prop_id) -  { -  case ARG_POS_X: -    g_value_set_int (value, robot->x); -    break; -  case ARG_POS_Y: -    g_value_set_int (value, robot->y); -    break; -  case ARG_DIRECTION: -    g_value_set_int (value, robot->dir); -    break; -  case ARG_SCORE: -    g_value_set_long (value, robot->score); -    break; -  case ARG_ENERGY: -    g_value_set_long (value, robot->energy); -    break; -  case ARG_SHIELDS: -    g_value_set_long (value, robot->shields); -    break; -  case ARG_SHOTS: -    g_value_set_long (value, robot->shots); -    break; -  case ARG_UNITS: -    g_value_set_long (value, robot->units); -    break; -  case ARG_USER_INTERFACE: -    g_value_set_object (value, g_object_ref (G_OBJECT (robot->ui))); -    break; -  case ARG_MAP: -    g_value_set_object (value, g_object_ref (G_OBJECT (robot->map))); -    break; -  default: -    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -    break; -  } +	GRobot *robot; + +	/* it's not null if we got it, but it might not be ours */ +	g_return_if_fail(G_IS_ROBOT(object)); + +	robot = G_ROBOT(object); + +	switch (prop_id) +	{ +	case ARG_POS_X: +		g_value_set_int(value, robot->x); +		break; +	case ARG_POS_Y: +		g_value_set_int(value, robot->y); +		break; +	case ARG_DIRECTION: +		g_value_set_int(value, robot->dir); +		break; +	case ARG_SCORE: +		g_value_set_long(value, robot->score); +		break; +	case ARG_ENERGY: +		g_value_set_long(value, robot->energy); +		break; +	case ARG_SHIELDS: +		g_value_set_long(value, robot->shields); +		break; +	case ARG_SHOTS: +		g_value_set_long(value, robot->shots); +		break; +	case ARG_UNITS: +		g_value_set_long(value, robot->units); +		break; +	case ARG_USER_INTERFACE: +		g_value_set_object(value, g_object_ref(G_OBJECT(robot->ui))); +		break; +	case ARG_MAP: +		g_value_set_object(value, g_object_ref(G_OBJECT(robot->map))); +		break; +	default: +		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +		break; +	}  } -GRobot * -g_robot_new (gint x, gint y, gint dir, glong score, glong energy, -         glong shields, glong units, glong shots, UserInterface *ui, -         Map *map) +GRobot *g_robot_new(gint x, gint y, gint dir, glong score, glong energy, +	glong shields, glong units, glong shots, UIArena *ui, Map *map)  { -  return G_ROBOT(g_object_new (g_robot_get_type(), -               "x", x, -               "y", y, -               "direction", dir, -               "score", score, -               "energy", energy, -               "shields", shields, -               "units", units, -               "shots", shots, -               "user_interface", ui, "map", map, NULL)); +	return G_ROBOT(g_object_new(g_robot_get_type(), +			"x", x, +			"y", y, +			"direction", dir, +			"score", score, +			"energy", energy, +			"shields", shields, +			"units", units, +			"shots", shots, "user_interface", ui, "map", map, NULL));  } -static void -g_robot_dispose (GObject *object) +static void g_robot_dispose(GObject *object)  { -  GRobot *robot = G_ROBOT (object); +	GRobot *robot = G_ROBOT(object); -  if (robot->ui != NULL) -  { -    g_object_unref (G_OBJECT (robot->ui)); -  } +	if (robot->ui != NULL) +	{ +		g_object_unref(G_OBJECT(robot->ui)); +	} -  if (robot->map != NULL) -  { -    g_object_unref (G_OBJECT (robot->map)); -  } +	if (robot->map != NULL) +	{ +		g_object_unref(G_OBJECT(robot->map)); +	} -  parent_class->dispose (object); +	parent_class->dispose(object);  } -static void -g_robot_finalize (GObject *object) +static void g_robot_finalize(GObject *object)  { -  parent_class->finalize (object); +	parent_class->finalize(object);  } -void -g_robot_turn (GRobot *robot, gint num_turns) +void g_robot_turn(GRobot *robot, gint num_turns)  { -  gint i; -  gint incr; +	gint i; +	gint incr; -  /* turn left or right? */ +	/* turn left or right? */ -  incr = sign(num_turns); +	incr = sign(num_turns); -  for (i = 0; i < abs (num_turns); i++) -  { -    robot->dir += incr; +	for (i = 0; i < abs(num_turns); i++) +	{ +		robot->dir += incr; -    if (robot->dir > 3) -    { -      robot->dir = 0; -    } +		if (robot->dir > 3) +		{ +			robot->dir = 0; +		} -    else if (robot->dir < 0) -    { -      robot->dir = 3; -    } +		else if (robot->dir < 0) +		{ +			robot->dir = 3; +		} -    /* animate the robot */ -    user_interface_move_robot (robot->ui, robot->x, robot->y, robot->x, -                   robot->y, robot->dir, robot->energy, -                   robot->score, robot->shields); +		/* animate the robot */ +		gdk_threads_enter(); +		ui_arena_move_robot(robot->ui, robot->x, robot->y, robot->x, +			robot->y, robot->dir, robot->energy, +			robot->score, robot->shields); +		gdk_threads_leave(); -    robot->energy -= 2; +		robot->energy -= 2; -    if (robot->energy < 1) -    { -      g_signal_emit (robot, g_robot_signals[DEATH], 0); -    } -  }             /* for */ +		if (robot->energy < 1) +		{ +			g_signal_emit(robot, g_robot_signals[DEATH], 0); +		} +	}							/* for */  } -gboolean -g_robot_move (GRobot *robot, gint steps) +gboolean g_robot_move(GRobot *robot, gint steps)  { -  gint x_to, y_to; -  gint dx, dy; -  gint i; - -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); - -  /* determine changes to x,y */ - -  switch (robot->dir) -  { -  case NORTH:           /* N */ -    dx = 0; -    dy = -1 * sign (steps); -    break; -  case EAST:            /* E */ -    dx = sign (steps); -    dy = 0; -    break; -  case SOUTH:           /* S */ -    dx = 0; -    dy = sign (steps); -    break; -  case WEST:            /* W */ -    dx = -1 * sign (steps); -    dy = 0; -    break; -  } - -  /* Move the robot */ - -  for (i = 0; i < abs (steps); i++) -  { -    /* check for a space */ - -    x_to = robot->x + dx; -    y_to = robot->y + dy; - -    /* no matter what, this took energy */ - -    robot->energy -= 2; -    if (robot->energy < 1) -    { -      g_signal_emit (robot, g_robot_signals[DEATH], 0); -    } - -    switch (MAP_GET_OBJECT (robot->map, x_to, y_to)) -    { -    case SPACE: -      /* move the robot there */ -      MAP_SET_OBJECT (robot->map, robot->x, robot->y, SPACE); -      MAP_SET_OBJECT (robot->map, x_to, y_to, ROBOT); - -      user_interface_move_robot (robot->ui, robot->x, robot->y, x_to, y_to, -                 robot->dir, robot->energy, robot->score, -                 robot->shields); - -      robot->x = x_to; -      robot->y = y_to; -      robot->units++; - -      break; - -    case BADDIE: -      /* Damage */ -      robot->shields -= 10; -      if (robot->shields < 1) -      { -        g_signal_emit (robot, g_robot_signals[DEATH], 0); -      } -      return FALSE; - -      break; - -    case WALL: -      /* less damage */ -      robot->shields -= 2; -      if (robot->shields < 1) -      { -        g_signal_emit (robot, g_robot_signals[DEATH], 0); -      } -      return FALSE; - -      break; - -    default: -      /* even less damage */ -      if (--robot->shields < 1) -      { -        g_signal_emit (robot, g_robot_signals[DEATH], 0); -      } -      return FALSE; - -      break; -    } -  }             /* for */ - -  return TRUE; +	gint x_to, y_to; +	gint dx, dy; +	gint i; + +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); + +	/* determine changes to x,y */ + +	switch (robot->dir) +	{ +	case NORTH:				/* N */ +		dx = 0; +		dy = -1 * sign(steps); +		break; +	case EAST:					/* E */ +		dx = sign(steps); +		dy = 0; +		break; +	case SOUTH:				/* S */ +		dx = 0; +		dy = sign(steps); +		break; +	case WEST:					/* W */ +		dx = -1 * sign(steps); +		dy = 0; +		break; +	} + +	/* Move the robot */ + +	for (i = 0; i < abs(steps); i++) +	{ +		/* check for a space */ + +		x_to = robot->x + dx; +		y_to = robot->y + dy; + +		/* no matter what, this took energy */ + +		robot->energy -= 2; +		if (robot->energy < 1) +		{ +			g_signal_emit(robot, g_robot_signals[DEATH], 0); +		} + +		switch (MAP_GET_OBJECT(robot->map, x_to, y_to)) +		{ +		case SPACE: +			/* move the robot there */ +			MAP_SET_OBJECT(robot->map, robot->x, robot->y, SPACE); +			MAP_SET_OBJECT(robot->map, x_to, y_to, ROBOT); + +			gdk_threads_enter(); +			ui_arena_move_robot(robot->ui, robot->x, robot->y, x_to, y_to, +				robot->dir, robot->energy, robot->score, robot->shields); +			gdk_threads_leave(); + +			robot->x = x_to; +			robot->y = y_to; +			robot->units++; + +			break; + +		case BADDIE: +			/* Damage */ +			robot->shields -= 10; +			if (robot->shields < 1) +			{ +				g_signal_emit(robot, g_robot_signals[DEATH], 0); +			} +			return FALSE; + +			break; + +		case WALL: +			/* less damage */ +			robot->shields -= 2; +			if (robot->shields < 1) +			{ +				g_signal_emit(robot, g_robot_signals[DEATH], 0); +			} +			return FALSE; + +			break; + +		default: +			/* even less damage */ +			if (--robot->shields < 1) +			{ +				g_signal_emit(robot, g_robot_signals[DEATH], 0); +			} +			return FALSE; + +			break; +		} +	}							/* for */ + +	return TRUE;  } -gboolean -g_robot_smell (GRobot *robot, gchar *str) +gboolean g_robot_smell(GRobot *robot, gchar *str)  { -  gint th; -  gint i, j; +	gint th; +	gint i, j; -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); -  th = what_thing (str); +	th = what_thing(str); -  /* no matter what, this took energy */ +	/* no matter what, this took energy */ -  if (--robot->energy < 1) -  { -    g_signal_emit (robot, g_robot_signals[DEATH], 0); -  } +	if (--robot->energy < 1) +	{ +		g_signal_emit(robot, g_robot_signals[DEATH], 0); +	} -  user_interface_robot_smell (robot->ui, robot->x, robot->y, robot->dir, -                  robot->energy, robot->score, robot->shields); +	gdk_threads_enter(); +	ui_arena_robot_smell(robot->ui, robot->x, robot->y, robot->dir, +		robot->energy, robot->score, robot->shields); +	gdk_threads_leave(); -  /* Smell for the thing */ +	/* Smell for the thing */ -  for (i = robot->x - 1; i <= robot->x + 1; i++) -  { -    for (j = robot->y - 1; j <= robot->y + 1; j++) -    { -      if (!(i == robot->x && j == robot->y) -      && MAP_GET_OBJECT (robot->map, i, j) == th) -      { -        /* Found it */ -        return TRUE; -      } -    }               /* for */ -  }             /* for */ +	for (i = robot->x - 1; i <= robot->x + 1; i++) +	{ +		for (j = robot->y - 1; j <= robot->y + 1; j++) +		{ +			if (!(i == robot->x && j == robot->y) +				&& MAP_GET_OBJECT(robot->map, i, j) == th) +			{ +				/* Found it */ +				return TRUE; +			} +		}						/* for */ +	}							/* for */ -  /* Failed to find it */ +	/* Failed to find it */ -  return FALSE; +	return FALSE;  } -gboolean -g_robot_feel (GRobot *robot, gchar *str) +gboolean g_robot_feel(GRobot *robot, gchar *str)  { -  gint th; -  gint x_to, y_to; -  gint dx, dy; - -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); - -  th = what_thing (str); - -  /* determine changes to x,y */ -  switch (robot->dir) -  { -  case NORTH:           /* N */ -    dx = 0; -    dy = -1; -    break; -  case EAST:            /* E */ -    dx = 1; -    dy = 0; -    break; -  case SOUTH:           /* S */ -    dx = 0; -    dy = 1; -    break; -  case WEST:            /* W */ -    dx = -1; -    dy = 0; -    break; -  } - -  /* no matter what, this took energy */ -  if (--robot->energy < 1) -  { -    g_signal_emit (robot, g_robot_signals[DEATH], 0); -  } - -  /* Feel for the thing */ -  x_to = robot->x + dx; -  y_to = robot->y + dy; - -  user_interface_robot_feel (robot->ui, -                 robot->x, robot->y, -                 robot->dir, x_to, y_to, -                 robot->energy, robot->score, robot->shields); - -  if (MAP_GET_OBJECT (robot->map, x_to, y_to) == BADDIE) -  { -    /* touching a baddie is hurtful */ -    if (robot->shields < 1) -    { -      g_signal_emit (robot, g_robot_signals[DEATH], 0); -    } -  } - -  if (MAP_GET_OBJECT (robot->map, x_to, y_to) == th) -  { -    return TRUE; -  } - -  /* Did not feel it */ -  return FALSE; +	gint th; +	gint x_to, y_to; +	gint dx, dy; + +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); + +	th = what_thing(str); + +	/* determine changes to x,y */ +	switch (robot->dir) +	{ +	case NORTH:				/* N */ +		dx = 0; +		dy = -1; +		break; +	case EAST:					/* E */ +		dx = 1; +		dy = 0; +		break; +	case SOUTH:				/* S */ +		dx = 0; +		dy = 1; +		break; +	case WEST:					/* W */ +		dx = -1; +		dy = 0; +		break; +	} + +	/* no matter what, this took energy */ +	if (--robot->energy < 1) +	{ +		g_signal_emit(robot, g_robot_signals[DEATH], 0); +	} + +	/* Feel for the thing */ +	x_to = robot->x + dx; +	y_to = robot->y + dy; + +	gdk_threads_enter(); +	ui_arena_robot_feel(robot->ui, robot->x, robot->y, robot->dir, x_to, +		y_to, robot->energy, robot->score, robot->shields); +	gdk_threads_leave(); + +	if (MAP_GET_OBJECT(robot->map, x_to, y_to) == BADDIE) +	{ +		/* touching a baddie is hurtful */ +		if (robot->shields < 1) +		{ +			g_signal_emit(robot, g_robot_signals[DEATH], 0); +		} +	} + +	if (MAP_GET_OBJECT(robot->map, x_to, y_to) == th) +	{ +		return TRUE; +	} + +	/* Did not feel it */ +	return FALSE;  } -gboolean -g_robot_look (GRobot *robot, gchar *str) +gboolean g_robot_look(GRobot *robot, gchar *str)  { -  gint th; -  gint x_to, y_to; -  gint dx, dy; - -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); - -  th = what_thing (str); - -  /* determine changes to x,y */ -  switch (robot->dir) -  { -  case 0:           /* N */ -    dx = 0; -    dy = -1; -    break; -  case 1:           /* E */ -    dx = 1; -    dy = 0; -    break; -  case 2:           /* S */ -    dx = 0; -    dy = 1; -    break; -  case 3:           /* W */ -    dx = -1; -    dy = 0; -    break; -  } - -  /* no matter what, this took energy */ -  if (--robot->energy < 1) -  { -    g_signal_emit (robot, g_robot_signals[DEATH], 0); -  } - -  /* Look for the thing */ -  x_to = robot->x + dx; -  y_to = robot->y + dy; - -  user_interface_robot_look (robot->ui, -                 robot->x, robot->y, -                 robot->dir, x_to, y_to, -                 robot->energy, robot->score, robot->shields); - -  while (MAP_GET_OBJECT (robot->map, x_to, y_to) == SPACE) -  { -    /* move the focus */ -    x_to += dx; -    y_to += dy; -  } - -  /* Outside the loop, we have found something */ -  if (MAP_GET_OBJECT (robot->map, x_to, y_to) == th) -  { -    return TRUE; -  } - -  /* else, we did not find it */ -  return FALSE; +	gint th; +	gint x_to, y_to; +	gint dx, dy; + +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); + +	th = what_thing(str); + +	/* determine changes to x,y */ +	switch (robot->dir) +	{ +	case 0:					/* N */ +		dx = 0; +		dy = -1; +		break; +	case 1:					/* E */ +		dx = 1; +		dy = 0; +		break; +	case 2:					/* S */ +		dx = 0; +		dy = 1; +		break; +	case 3:					/* W */ +		dx = -1; +		dy = 0; +		break; +	} + +	/* no matter what, this took energy */ +	if (--robot->energy < 1) +	{ +		g_signal_emit(robot, g_robot_signals[DEATH], 0); +	} + +	/* Look for the thing */ +	x_to = robot->x + dx; +	y_to = robot->y + dy; + +	gdk_threads_enter(); +	ui_arena_robot_look(robot->ui, robot->x, robot->y, robot->dir, x_to, +		y_to, robot->energy, robot->score, robot->shields); +	gdk_threads_leave(); + +	while (MAP_GET_OBJECT(robot->map, x_to, y_to) == SPACE) +	{ +		/* move the focus */ +		x_to += dx; +		y_to += dy; +	} + +	/* Outside the loop, we have found something */ +	if (MAP_GET_OBJECT(robot->map, x_to, y_to) == th) +	{ +		return TRUE; +	} + +	/* else, we did not find it */ +	return FALSE;  } -gboolean -g_robot_grab (GRobot *robot) +gboolean g_robot_grab(GRobot *robot)  { -  gint x_to, y_to; -  gint dx, dy; - -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); - -  /* determine changes to x,y */ - -  switch (robot->dir) -  { -  case NORTH:           /* N */ -    dx = 0; -    dy = -1; -    break; -  case EAST:            /* E */ -    dx = 1; -    dy = 0; -    break; -  case SOUTH:           /* S */ -    dx = 0; -    dy = 1; -    break; -  case WEST:            /* W */ -    dx = -1; -    dy = 0; -    break; -  } - -  /* Try to grab the thing */ - -  x_to = robot->x + dx; -  y_to = robot->y + dy; - -  robot->energy -= 5; -  if (robot->energy < 1) -  { -    g_signal_emit (robot, g_robot_signals[DEATH], 0); -  } - -  user_interface_robot_grab (robot->ui, robot->x, robot->y, robot->dir, x_to, -                 y_to, robot->energy, robot->score, -                 robot->shields); - -  /* Did we grab it? */ - -  switch (MAP_GET_OBJECT (robot->map, x_to, y_to)) -  { -  case SPACE: -  case WALL: -  case ROBOT: -    return FALSE; -    break; - -  case BADDIE: -    robot->shields -= 10; -    if (robot->shields < 1) -    { -      g_signal_emit (robot, g_robot_signals[DEATH], 0); -    } -    return (FALSE); - -  case FOOD: -    /* I want the net gain to be +10 */ -    robot->energy += 15; -    break; - -  case PRIZE: -    robot->score++; -    break; -  } - -  /* only successful grabs get here */ -  MAP_SET_OBJECT (robot->map, x_to, y_to, SPACE); -  user_interface_add_thing (robot->ui, x_to, y_to, SPACE); - -  return TRUE; +	gint x_to, y_to; +	gint dx, dy; + +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); + +	/* determine changes to x,y */ + +	switch (robot->dir) +	{ +	case NORTH:				/* N */ +		dx = 0; +		dy = -1; +		break; +	case EAST:					/* E */ +		dx = 1; +		dy = 0; +		break; +	case SOUTH:				/* S */ +		dx = 0; +		dy = 1; +		break; +	case WEST:					/* W */ +		dx = -1; +		dy = 0; +		break; +	} + +	/* Try to grab the thing */ + +	x_to = robot->x + dx; +	y_to = robot->y + dy; + +	robot->energy -= 5; +	if (robot->energy < 1) +	{ +		g_signal_emit(robot, g_robot_signals[DEATH], 0); +	} + +	gdk_threads_enter(); +	ui_arena_robot_grab(robot->ui, robot->x, robot->y, robot->dir, x_to, +		y_to, robot->energy, robot->score, robot->shields); +	gdk_threads_leave(); + +	/* Did we grab it? */ + +	switch (MAP_GET_OBJECT(robot->map, x_to, y_to)) +	{ +	case SPACE: +	case WALL: +	case ROBOT: +		return FALSE; +		break; + +	case BADDIE: +		robot->shields -= 10; +		if (robot->shields < 1) +		{ +			g_signal_emit(robot, g_robot_signals[DEATH], 0); +		} +		return (FALSE); + +	case FOOD: +		/* I want the net gain to be +10 */ +		robot->energy += 15; +		break; + +	case PRIZE: +		robot->score++; +		break; +	} + +	/* only successful grabs get here */ +	MAP_SET_OBJECT(robot->map, x_to, y_to, SPACE); +	gdk_threads_enter(); +	ui_arena_add_thing(robot->ui, x_to, y_to, SPACE); +	gdk_threads_leave(); + +	return TRUE;  } -gboolean -g_robot_zap (GRobot *robot) +gboolean g_robot_zap(GRobot *robot)  { -  gint x_to, y_to; -  gint dx, dy; - -  g_return_val_if_fail (robot->ui != NULL && robot->map != NULL, FALSE); - -  /* determine changes to x,y */ - -  switch (robot->dir) -  { -  case NORTH:           /* N */ -    dx = 0; -    dy = -1; -    break; -  case EAST:            /* E */ -    dx = 1; -    dy = 0; -    break; -  case SOUTH:           /* S */ -    dx = 0; -    dy = 1; -    break; -  case WEST:            /* W */ -    dx = -1; -    dy = 0; -    break; -  } - -  /* Try to zap the thing */ - -  x_to = robot->x + dx; -  y_to = robot->y + dy; - -  robot->energy -= 10; -  if (robot->energy < 1) -  { -    g_signal_emit (robot, g_robot_signals[DEATH], 0); -  } -  robot->shots++; -  user_interface_robot_zap (robot->ui, robot->x, robot->y, robot->dir, x_to, -                y_to, robot->energy, robot->score, -                robot->shields); - -  /* Did we destroy it? */ -  switch (MAP_GET_OBJECT (robot->map, x_to, y_to)) -  { -  case SPACE: -  case WALL: -  case ROBOT:           /* what to w/ robots? */ -    return (FALSE); -    break; - -  case BADDIE: -  case FOOD: -  case PRIZE: -    user_interface_add_thing (robot->ui, x_to, y_to, SPACE); -    break; -  } - -  /* only success gets here */ -  MAP_SET_OBJECT (robot->map, x_to, y_to, SPACE); -  user_interface_add_thing (robot->ui, x_to, y_to, SPACE); - -  return TRUE; +	gint x_to, y_to; +	gint dx, dy; + +	g_return_val_if_fail(robot->ui != NULL && robot->map != NULL, FALSE); + +	/* determine changes to x,y */ + +	switch (robot->dir) +	{ +	case NORTH:				/* N */ +		dx = 0; +		dy = -1; +		break; +	case EAST:					/* E */ +		dx = 1; +		dy = 0; +		break; +	case SOUTH:				/* S */ +		dx = 0; +		dy = 1; +		break; +	case WEST:					/* W */ +		dx = -1; +		dy = 0; +		break; +	} + +	/* Try to zap the thing */ + +	x_to = robot->x + dx; +	y_to = robot->y + dy; + +	robot->energy -= 10; +	if (robot->energy < 1) +	{ +		g_signal_emit(robot, g_robot_signals[DEATH], 0); +	} +	robot->shots++; +	gdk_threads_enter(); +	ui_arena_robot_zap(robot->ui, robot->x, robot->y, robot->dir, x_to, +		y_to, robot->energy, robot->score, robot->shields); +	gdk_threads_leave(); + +	/* Did we destroy it? */ +	switch (MAP_GET_OBJECT(robot->map, x_to, y_to)) +	{ +	case SPACE: +	case WALL: +	case ROBOT:				/* what to w/ robots? */ +		return (FALSE); +		break; + +	case BADDIE: +	case FOOD: +	case PRIZE: +		gdk_threads_enter(); +		ui_arena_add_thing(robot->ui, x_to, y_to, SPACE); +		gdk_threads_leave(); +		break; +	} + +	/* only success gets here */ +	MAP_SET_OBJECT(robot->map, x_to, y_to, SPACE); +	gdk_threads_enter(); +	ui_arena_add_thing(robot->ui, x_to, y_to, SPACE); +	gdk_threads_leave(); + +	return TRUE;  } -gboolean -g_robot_stop (GRobot *robot) +gboolean g_robot_stop(GRobot *robot)  { -  /* Must be a SCM function, even though it returns no value */ -  /* Stop the robot immediately */ +	/* Must be a SCM function, even though it returns no value */ +	/* Stop the robot immediately */ -  g_signal_emit (robot, g_robot_signals[DEATH], 0); +	g_signal_emit(robot, g_robot_signals[DEATH], 0); -  return TRUE;        /* never gets here */ +	return TRUE;				/* never gets here */  } -static gint -what_thing (const gchar *th) +static gint what_thing(const gchar *th)  { -  /* what_thing - this function scans the list of possible things -     (strings) and returns a cthing.  Returns -1 if not found in the -     list. */ - -  /* My idea here is that by return -1 on error, this won't match -     anything in the list of cthings.  That way, the function that -     uses what_thing to determine the cthing doesn't have to care if -     the call failed or not.  This helps me keep the code simple, -     since now I don't have to add a branch for failure, but which -     also decrements energy. */ - -  gint i; - -  for (i = 0; i < 6; i++) -  { -    if (strcmp (th, things[i]) == 0) -    { -      return cthings[i]; -    } -  }             /* for */ - -  /* not found */ - -  return -1; +	/* what_thing - this function scans the list of possible things +	   (strings) and returns a cthing.  Returns -1 if not found in the +	   list. */ + +	/* My idea here is that by return -1 on error, this won't match +	   anything in the list of cthings.  That way, the function that +	   uses what_thing to determine the cthing doesn't have to care if +	   the call failed or not.  This helps me keep the code simple, +	   since now I don't have to add a branch for failure, but which +	   also decrements energy. */ + +	gint i; + +	for (i = 0; i < 6; i++) +	{ +		if (strcmp(th, things[i]) == 0) +		{ +			return cthings[i]; +		} +	}							/* for */ + +	/* not found */ + +	return -1;  } @@ -19,254 +19,255 @@   */  #include <stdio.h> -#include <unistd.h>     /* for getopt */ -#include <string.h>     /* for strdup */ +#include <unistd.h>			/* for getopt */ +#include <string.h>			/* for strdup */  #include <glib.h>  #include <glib/gprintf.h>  #include <libguile.h> -#include <getopt.h>     /* for GNU getopt_long */ +#include <getopt.h>			/* for GNU getopt_long */ -#include "grobot.h"     /* the robot structure, and robot manipulation -                           routines */ +#include "grobot.h"			/* the robot structure, and robot manipulation +								   routines */ -#include "api.h"        /* robot API, as Scheme functions */ -#include "userinterface.h" +#include "api.h"			/* robot API, as Scheme functions */ +#include "ui-cmdwin.h" +#include "ui-arena.h" +#include "ui-window.h" +#include "ui-window-private.h"  #include "config.h"  #include "configs.h" -#include "map.h"        /* Game Map */ -#include "main.h"       /* for this source file */ +#include "map.h"			/* Game Map */ +#include "main.h"			/* for this source file */  #define BUFF_LEN 1024  /* Globals (share with api.c) */  GList *robots = NULL; -GRobot *robot = NULL;       /* The current robot */ -UserInterface *ui; +GRobot *robot = NULL;		/* The current robot */ +UIWindow *ui; +UIArena *arena;  Map *map;  gpointer callback(gpointer data); -SCM catch_handler (void *data, SCM tag, SCM throw_args); -gint is_file_readable (const gchar *filename); +SCM catch_handler(void *data, SCM tag, SCM throw_args); +gint is_file_readable(const gchar * filename);  /************************************************************************   * gint main(gint argc, gchar *argv[])                                  *   *                                                                      *   * Entry point                                                          *   ************************************************************************/ -gint -main (gint argc, gchar *argv[]) +gint main(gint argc, gchar *argv[])  { -  gint opt;         /* the option read from getopt */ -  gint flag;        /* flag passed back from getopt - NOT USED */ - -  gchar maps_path[MAX_PATH], scripts_path[MAX_PATH]; - -  gchar *main_argv[5] = { "GNU Robots", -    NULL, -    NULL, -    NULL, -    NULL -  }; - -  struct option long_opts[] = { -    {"version", 0, NULL, 'V'}, -    {"help", 0, NULL, 'h'}, -    {"map-file", 1, NULL, 'f'}, -    {"shields", 1, NULL, 's'}, -    {"energy", 1, NULL, 'e'}, -    {NULL, 0, NULL, 0} -  }; - -  /* Initialize the GType system first */ -  g_type_init (); - -  /* Check command line */ - -  /* Create a robot Object */ -  robot = g_robot_new (1, 1, 1, 0, DEFAULT_ENERGY, DEFAULT_SHIELDS, 0, 0, -               NULL, NULL); - -  g_assert (robot != NULL); - -  /* And add to to the list of robots */ -  robots = g_list_append (robots, robot); - -  while ((opt = getopt_long (argc, argv, "Vhf:s:e:p:", long_opts, -                 &flag)) != EOF) -  { -    switch (opt) -    { -    case 'V': -      /* Display version, then quit */ -      g_printf ("%s\n\n", PKGINFO); -      g_printf ("%s\n\n", COPYRIGHT); -      g_printf -  ("GNU Robots is free software: you can redistribute it and/or modify\n" -   "it under the terms of the GNU General Public License as published by\n" -   "the Free Software Foundation, either version 3 of the License, or\n" -   "(at your option) any later version.\n"); -      g_printf -  ("\nGNU Robots is distributed in the hope that it will be useful,\n" -   "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" -   "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" -   "GNU General Public License for more details.\n"); -      g_printf -  ("\nYou should have received a copy of the GNU General Public License\n" -   "along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>.\n"); - -      exit (0); -      break; - -    case 'h': -      /* Display help, then quit. */ -      usage (argv[0]); -      exit (0); -      break; - -    case 'f': -      /* Set map file */ -      main_argv[1] = optarg;    /* pointer assignment */ -      break; - -    case 's': -      /* Set shields */ -      robot->shields = (glong) atol (optarg); -      break; - -    case 'e': -      /* Set energy */ -      robot->energy = (glong) atol (optarg); -      break; - -    default: -      /* invalid option */ -      usage (argv[0]); -      exit (1); -      break; -    }               /* switch */ -  }             /* while */ - -  /* Extra arg is the Scheme file */ - -  if (optind < argc) -  { -    /* Set Scheme file */ -    main_argv[2] = argv[optind];    /* pointer assignment */ -  } - -  /* Check that files have been given */ -  if (main_argv[1] == NULL) -  { -    main_argv[1] = g_malloc (MAX_PATH); -    g_strlcpy (main_argv[1], DEFAULT_MAP, MAX_PATH); -    g_fprintf (stderr, "map file not specified, trying default: %s\n", -           main_argv[1]); -  } - -  /* Check that files exist */ -  g_strlcpy (maps_path, main_argv[1], MAX_PATH); - -  if (!is_file_readable (maps_path)) -  { -    g_strlcpy (maps_path, MAPS_PATH, MAX_PATH); -    g_strlcat (maps_path, "/", MAX_PATH); -    g_strlcat (maps_path, main_argv[1], MAX_PATH); - -    if (!is_file_readable (maps_path)) -    { -      gchar *env = getenv (MAPS_PATH_ENV); - -      if (env != NULL) -      { -        g_strlcpy (maps_path, env, MAX_PATH); -        g_strlcat (maps_path, "/", MAX_PATH); -        g_strlcat (maps_path, main_argv[1], MAX_PATH); - -        if (!is_file_readable (maps_path)) -        { -          g_fprintf (stderr, -                  "%s: %s: game map file does not exist or is not \ -                  readable\n", -                  argv[0], main_argv[1]); -          exit (1); -        } -      } -      else -      { -        g_fprintf (stderr, -                "%s: %s: game map file does not exist or is not readable\n", -                argv[0], main_argv[1]); -        exit (1); -      } -    } -  } - -  main_argv[1] = maps_path; - -  /* Now the Scheme file */ -  if (main_argv[2] != NULL) -  { -    g_strlcpy (scripts_path, main_argv[2], MAX_PATH); - -    if (!is_file_readable (scripts_path)) -    { -      g_strlcpy (scripts_path, SCRIPTS_PATH, MAX_PATH); -      g_strlcat (scripts_path, "/", MAX_PATH); -      g_strlcat (scripts_path, main_argv[2], MAX_PATH); - -      if (!is_file_readable (scripts_path)) -      { -        gchar *env = getenv (SCRIPTS_PATH_ENV); - -        if (env != NULL) -        { -          g_strlcpy (scripts_path, env, MAX_PATH); -          g_strlcat (scripts_path, "/", MAX_PATH); -          g_strlcat (scripts_path, main_argv[2], MAX_PATH); - -          if (!is_file_readable (scripts_path)) -          { -            g_fprintf (stderr, -                    "%s: %s: Scheme file does not exist or is not \ -                    readable\n", -                    argv[0], main_argv[2]); -            exit (1); -          } -        } -        else -        { -          g_fprintf (stderr, -                  "%s: %s: Scheme file does not exist or is not readable\n", -                  argv[0], main_argv[2]); -          exit (1); -        } -      } -    } - -    main_argv[2] = scripts_path; -  } -  else -  { -    /* argv[2] can't be NULL as argv[3] may also be NULL */ -    main_argv[2] = ""; -  } - -  /* Start Guile environment.  Does not exit */ -  g_printf ("%s\n", PKGINFO); -  g_printf ("%s\n", COPYRIGHT); -  g_printf ("GNU Robots comes with ABSOLUTELY NO WARRANTY\n"); -  g_printf -    ("This is free software, and you are welcome to redistribute it\n"); -  g_printf -    ("under certain conditions; see the file `COPYING' for details.\n"); -  g_printf ("Loading Guile ... Please wait\n\n"); - -  scm_boot_guile (3, main_argv, main_prog, NULL); - -  return 0;         /* never gets here, but keeps compiler happy */ +	gint opt;				/* the option read from getopt */ +	gint flag;				/* flag passed back from getopt - NOT USED */ + +	gchar maps_path[MAX_PATH], scripts_path[MAX_PATH]; + +	gchar *main_argv[5] = { "GNU Robots", +		NULL, +		NULL, +		NULL, +		NULL +	}; + +	struct option long_opts[] = { +		{"version", 0, NULL, 'V'}, +		{"help", 0, NULL, 'h'}, +		{"map-file", 1, NULL, 'f'}, +		{"shields", 1, NULL, 's'}, +		{"energy", 1, NULL, 'e'}, +		{NULL, 0, NULL, 0} +	}; + +	/* Initialize the GType system first */ +	g_type_init(); + +	/* Check command line */ + +	/* Create a robot Object */ +	robot = g_robot_new(1, 1, 1, 0, DEFAULT_ENERGY, DEFAULT_SHIELDS, 0, 0, +		NULL, NULL); + +	g_assert(robot != NULL); + +	/* And add to to the list of robots */ +	robots = g_list_append(robots, robot); + +	while ((opt = getopt_long(argc, argv, "Vhf:s:e:p:", long_opts, +				&flag)) != EOF) +	{ +		switch (opt) +		{ +		case 'V': +			/* Display version, then quit */ +			g_printf("%s\n\n", PKGINFO); +			g_printf("%s\n\n", COPYRIGHT); +			g_printf +("GNU Robots is free software: you can redistribute it and/or modify\n" + "it under the terms of the GNU General Public License as published by\n" + "the Free Software Foundation, either version 3 of the License, or\n" + "(at your option) any later version.\n"); +			g_printf +("\nGNU Robots is distributed in the hope that it will be useful,\n" + "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" + "GNU General Public License for more details.\n"); +			g_printf +("\nYou should have received a copy of the GNU General Public License\n" + "along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>.\n"); + +			exit(0); +			break; + +		case 'h': +			/* Display help, then quit. */ +			usage(argv[0]); +			exit(0); +			break; + +		case 'f': +			/* Set map file */ +			main_argv[1] = optarg;	/* pointer assignment */ +			break; + +		case 's': +			/* Set shields */ +			robot->shields = (glong) atol(optarg); +			break; + +		case 'e': +			/* Set energy */ +			robot->energy = (glong) atol(optarg); +			break; + +		default: +			/* invalid option */ +			usage(argv[0]); +			exit(1); +			break; +		}						/* switch */ +	}							/* while */ + +	/* Extra arg is the Scheme file */ + +	if (optind < argc) +	{ +		/* Set Scheme file */ +		main_argv[2] = argv[optind];	/* pointer assignment */ +	} + +	/* Check that files have been given */ +	if (main_argv[1] == NULL) +	{ +		main_argv[1] = g_malloc(MAX_PATH); +		g_strlcpy(main_argv[1], DEFAULT_MAP, MAX_PATH); +		g_fprintf(stderr, "map file not specified, trying default: %s\n", +			main_argv[1]); +	} + +	/* Check that files exist */ +	g_strlcpy(maps_path, main_argv[1], MAX_PATH); + +	if (!is_file_readable(maps_path)) +	{ +		g_strlcpy(maps_path, MAPS_PATH, MAX_PATH); +		g_strlcat(maps_path, "/", MAX_PATH); +		g_strlcat(maps_path, main_argv[1], MAX_PATH); + +		if (!is_file_readable(maps_path)) +		{ +			gchar *env = getenv(MAPS_PATH_ENV); + +			if (env != NULL) +			{ +				g_strlcpy(maps_path, env, MAX_PATH); +				g_strlcat(maps_path, "/", MAX_PATH); +				g_strlcat(maps_path, main_argv[1], MAX_PATH); + +				if (!is_file_readable(maps_path)) +				{ +					g_fprintf(stderr, +				"%s: %s: game map file does not exist or is not readable\n", +						argv[0], main_argv[1]); +					exit(1); +				} +			} +			else +			{ +				g_fprintf(stderr, +				"%s: %s: game map file does not exist or is not readable\n", +					argv[0], main_argv[1]); +				exit(1); +			} +		} +	} + +	main_argv[1] = maps_path; + +	/* Now the Scheme file */ +	if (main_argv[2] != NULL) +	{ +		g_strlcpy(scripts_path, main_argv[2], MAX_PATH); + +		if (!is_file_readable(scripts_path)) +		{ +			g_strlcpy(scripts_path, SCRIPTS_PATH, MAX_PATH); +			g_strlcat(scripts_path, "/", MAX_PATH); +			g_strlcat(scripts_path, main_argv[2], MAX_PATH); + +			if (!is_file_readable(scripts_path)) +			{ +				gchar *env = getenv(SCRIPTS_PATH_ENV); + +				if (env != NULL) +				{ +					g_strlcpy(scripts_path, env, MAX_PATH); +					g_strlcat(scripts_path, "/", MAX_PATH); +					g_strlcat(scripts_path, main_argv[2], MAX_PATH); + +					if (!is_file_readable(scripts_path)) +					{ +						g_fprintf(stderr, +				"%s: %s: Scheme file does not exist or is not readable\n", +							argv[0], main_argv[2]); +						exit(1); +					} +				} +				else +				{ +					g_fprintf(stderr, +				"%s: %s: Scheme file does not exist or is not readable\n", +						argv[0], main_argv[2]); +					exit(1); +				} +			} +		} + +		main_argv[2] = scripts_path; +	} +	else +	{ +		/* argv[2] can't be NULL as argv[3] may also be NULL */ +		main_argv[2] = ""; +	} + +	/* Start Guile environment.  Does not exit */ +	g_printf("%s\n", PKGINFO); +	g_printf("%s\n", COPYRIGHT); +	g_printf("GNU Robots comes with ABSOLUTELY NO WARRANTY\n"); +	g_printf +		("This is free software, and you are welcome to redistribute it\n"); +	g_printf +		("under certain conditions; see the file `COPYING' for details.\n"); +	g_printf("Loading Guile ... Please wait\n\n"); + +	scm_boot_guile(3, main_argv, main_prog, NULL); + +	return 0;				/* never gets here, but keeps compiler happy */  }  /************************************************************************ @@ -276,79 +277,91 @@ main (gint argc, gchar *argv[])   * the Scheme program as argv[1] and the map file as argv[2]. The       *   * program name is still argv[0].                                       *   ************************************************************************/ -void -main_prog (void *closure, gint argc, gchar *argv[]) +void main_prog(void *closure, gint argc, gchar *argv[])  { -  gchar *map_file = argv[1]; -  gchar *robot_program = argv[2]; +	gchar *map_file = argv[1]; +	gchar *robot_program = argv[2]; +	gboolean loading = TRUE; -  api_init (); +	api_init(); -  g_printf ("Map file: %s\n", map_file); +	g_printf("Map file: %s\n", map_file); -  map = map_new_from_file (map_file, DEFAULT_MAP_ROWS, DEFAULT_MAP_COLUMNS); +	map = map_new_from_file(map_file, DEFAULT_MAP_ROWS, +		DEFAULT_MAP_COLUMNS); -  if (map == NULL) -  { -    exit_nicely (); -  } +	if (map == NULL) +	{ +		exit_nicely(); +	} -  /* ensure the robot is placed properly */ -  MAP_SET_OBJECT (map, -          G_ROBOT_POSITION_Y (robot), -          G_ROBOT_POSITION_X (robot), ROBOT); +	g_thread_init(NULL); +	gdk_threads_init(); +	g_thread_create(callback, &loading, FALSE, NULL); -  ui = user_interface_new (map); +	/* ensure the robot is placed properly */ +	MAP_SET_OBJECT(map, G_ROBOT_POSITION_Y(robot), +		G_ROBOT_POSITION_X(robot), ROBOT); -  if (ui == NULL) -  { -    exit_nicely (); -  } +	g_printf("Loading GTK Interface ... Please wait\n\n"); +	while(loading); -  /* Now initialize the rest of the Robot properties */ -  g_object_set (G_OBJECT (robot), -        "user-interface", G_OBJECT (ui), "map", G_OBJECT (map), NULL); +	/* Now initialize the rest of the Robot properties */ +	g_object_set(G_OBJECT(robot), +		"user-interface", G_OBJECT(arena), "map", G_OBJECT(map), NULL); -  g_signal_connect (G_OBJECT (robot), "death", G_CALLBACK (death), NULL); +	g_signal_connect(G_OBJECT(robot), "death", G_CALLBACK(death), NULL); -  /* draw the map */ -  user_interface_draw (ui); -  user_interface_update_status (ui, "Welcome to GNU Robots", -1,-1, -1); +	if (strlen(robot_program) != 0) +	{ +		/* execute a Scheme file */ +		g_printf("Robot program: %s\n", robot_program); +		scm_c_primitive_load(robot_program); +	} +	else +	{ +		gchar buf[BUFF_LEN]; -  g_thread_init(NULL); -  g_thread_create(callback, NULL, FALSE, NULL); +		g_printf +			("Robot program not specified. Entering interactive mode..\n"); -  if (strlen (robot_program) != 0) -  { -    /* execute a Scheme file */ -    g_printf ("Robot program: %s\n", robot_program); -    scm_c_primitive_load (robot_program); -  } - -  else -  { -    gchar buff[BUFF_LEN]; +		while (1) +		{ +			memset(&buf, 0, BUFF_LEN); -    g_printf("Robot program not specified. Entering interactive mode..\n"); +			ui_cmdwin_get_string(UI_CMDWIN(ui->priv->cmdwin), "guile> ", +				buf, BUFF_LEN); -    while(1) -    { -      user_interface_get_string (ui, "guile> ", buff, BUFF_LEN); +			scm_internal_catch(SCM_BOOL_T, +				(scm_t_catch_body) scm_c_eval_string, buf, +				catch_handler, NULL); +		} +	} -      scm_internal_catch (SCM_BOOL_T, (scm_t_catch_body) scm_c_eval_string, -            (void *) buff, catch_handler, NULL); -    } -  } - -  /* done */ -  exit_nicely (); +	/* done */ +	exit_nicely();  }  gpointer callback(gpointer data)  { -  user_interface_run(ui); +	gtk_init(0, NULL); + +	ui = UI_WINDOW(ui_window_new()); +	ui_window_postinit(ui, map); + +	arena = UI_ARENA(ui->priv->arena); -  return NULL; +	/* draw the map */ +	ui_arena_draw(arena); +	ui_arena_update_status(arena, "Welcome to GNU Robots", -1, -1, -1); + +	*(gboolean*)data = FALSE; + +	gdk_threads_enter(); +	gtk_main(); +	gdk_threads_leave(); + +	return NULL;  }  /************************************************************************ @@ -356,8 +369,7 @@ gpointer callback(gpointer data)   *                                                                      *   * Responsible for handling errors                                      *   ************************************************************************/ -SCM -catch_handler (void *data, SCM tag, SCM throw_args) +SCM catch_handler(void *data, SCM tag, SCM throw_args)  {  /* @@ -377,18 +389,17 @@ catch_handler (void *data, SCM tag, SCM throw_args)    user_interface_update_status (ui, message, -1, -1, -1);  */ -  g_printf("Invalid Instruction\n"); +	g_printf("Invalid Instruction\n"); -  return SCM_BOOL_F; +	return SCM_BOOL_F;  } -void -death (GRobot *robot) +void death(GRobot *robot)  { -  /* We get a ref increment on a signal */ -  g_object_unref (G_OBJECT (robot)); +	/* We get a ref increment on a signal */ +	g_object_unref(G_OBJECT(robot)); -  exit_nicely (); +	exit_nicely();  }  /************************************************************************ @@ -397,52 +408,52 @@ death (GRobot *robot)   * A function that allows the program to exit nicely, after freeing all *   * memory pointers, etc.                                                *   ************************************************************************/ -void -exit_nicely () +void exit_nicely()  { -  glong score, energy, shields, shots, units; - -  /* Stop the UI */ -  if (ui != NULL) -  { -    g_object_unref (G_OBJECT (ui)); -  } - -  /* Get rid of the map object */ -  if (map != NULL) -  { -    g_object_unref (G_OBJECT (map)); -  } - -  /* Show statistics */ -  g_object_get (G_OBJECT (robot), -        "shields", &shields, -        "energy", &energy, -        "units", &units, "shots", &shots, "score", &score, NULL); - -  g_list_foreach (robots, (GFunc)g_object_unref, NULL); -  g_list_free (robots); - -  g_printf ("\n-----------------------STATISTICS-----------------------\n"); -  g_printf ("Shields: %ld\n", (shields < 0 ? 0 : shields)); -  g_printf ("Energy: %ld\n", (energy < 0 ? 0 : energy)); -  g_printf ("Units walked: %ld\n", (units < 0 ? 0 : units)); -  g_printf ("Shots: %ld\n", (shots < 0 ? 0 : shots)); -  g_printf ("Score: %ld\n", score); - -  /* Show results, if any */ -  if (shields < 1) -  { -    g_printf ("** Robot took too much damage, and died.\n"); -  } - -  else if (energy < 1) -  { -    g_printf ("** Robot ran out of energy.\n"); -  } - -  /* Quit program */ -  exit (0); +	glong score, energy, shields, shots, units; + +	/* Stop the UI */ +	if (ui != NULL) +	{ +		g_object_unref(G_OBJECT(ui)); +	} + +	/* Get rid of the map object */ +	if (map != NULL) +	{ +		g_object_unref(G_OBJECT(map)); +	} + +	/* Show statistics */ +	g_object_get(G_OBJECT(robot), +		"shields", &shields, +		"energy", &energy, +		"units", &units, "shots", &shots, "score", &score, NULL); + +	g_list_foreach(robots, (GFunc) g_object_unref, NULL); +	g_list_free(robots); + +	g_printf( +		"\n-----------------------STATISTICS-----------------------\n"); +	g_printf("Shields: %ld\n", (shields < 0 ? 0 : shields)); +	g_printf("Energy: %ld\n", (energy < 0 ? 0 : energy)); +	g_printf("Units walked: %ld\n", (units < 0 ? 0 : units)); +	g_printf("Shots: %ld\n", (shots < 0 ? 0 : shots)); +	g_printf("Score: %ld\n", score); + +	/* Show results, if any */ +	if (shields < 1) +	{ +		g_printf("** Robot took too much damage, and died.\n"); +	} + +	else if (energy < 1) +	{ +		g_printf("** Robot ran out of energy.\n"); +	} + +	/* Quit program */ +	exit(0);  }  /************************************************************************ @@ -451,28 +462,27 @@ exit_nicely ()   * A function that prints the usage of GNU Robots to the user. Assume   *   * text mode for this function. We have not initialized X Windows yet.  *   ************************************************************************/ -void -usage (const gchar *argv0) +void usage(const gchar *argv0)  { -  g_printf ("%s\n", PKGINFO); -  g_printf ("%s\n", COPYRIGHT); -  g_printf -    ("Game/diversion where you construct a program for a little robot\n"); -  g_printf -    ("then set him loose and watch him explore a world on his own.\n\n"); - -  g_printf ("Usage: %s [OPTION]... [FILE]\n\n", argv0); -  g_printf -    ("  -f, --map-file=FILE    Load map file\n"); -  g_printf ("  -s, --shields=N        Set initial shields to N\n"); -  g_printf ("  -e, --energy=N         Set initial energy to N\n"); -  g_printf ("  -V, --version          Output version information and exit\n"); -  g_printf ("  -h, --help             Display this help and exit\n"); -  g_printf ("\nNote: FILE refers to a scheme file and %s enters into \n", -        argv0); -  g_printf ("      interactive mode if it is not specified.\n"); - -  g_printf ("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT); +	g_printf("%s\n", PKGINFO); +	g_printf("%s\n", COPYRIGHT); +	g_printf +	("Game/diversion where you construct a program for a little robot\n"); +	g_printf +	("then set him loose and watch him explore a world on his own.\n\n"); + +	g_printf("Usage: %s [OPTION]... [FILE]\n\n", argv0); +	g_printf("  -f, --map-file=FILE    Load map file\n"); +	g_printf("  -s, --shields=N        Set initial shields to N\n"); +	g_printf("  -e, --energy=N         Set initial energy to N\n"); +	g_printf +		("  -V, --version          Output version information and exit\n"); +	g_printf("  -h, --help             Display this help and exit\n"); +	g_printf("\nNote: FILE refers to a scheme file and %s enters into \n", +		argv0); +	g_printf("      interactive mode if it is not specified.\n"); + +	g_printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);  }  /************************************************************************ @@ -483,19 +493,18 @@ usage (const gchar *argv0)   * files. This will save on error checking later on, when we may have   *   * already initialized another environment (Curses, X Windows, ...)     *   ************************************************************************/ -gint -is_file_readable (const gchar *filename) +gint is_file_readable(const gchar *filename)  { -  FILE *stream; - -  stream = fopen (filename, "r"); -  if (stream == NULL) -  { -    /* Failed */ -    return (0); -  } - -  /* Success */ -  fclose (stream); -  return (1); +	FILE *stream; + +	stream = fopen(filename, "r"); +	if (stream == NULL) +	{ +		/* Failed */ +		return (0); +	} + +	/* Success */ +	fclose(stream); +	return (1);  } diff --git a/src/ui-arena.c b/src/ui-arena.c new file mode 100644 index 0000000..39cbf55 --- /dev/null +++ b/src/ui-arena.c @@ -0,0 +1,466 @@ +/* Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> + * + * GNU Robots, ui-arena.c + * + * GNU Robots is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNU Robots is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ui-arena.h" + +#include "xpm/statusbar.xpm" +#include "xpm/space.xpm" +#include "xpm/food.xpm" +#include "xpm/wall.xpm" +#include "xpm/prize.xpm" +#include "xpm/baddie.xpm" +#include "xpm/robot_north.xpm" +#include "xpm/robot_east.xpm" +#include "xpm/robot_south.xpm" +#include "xpm/robot_west.xpm" +#include "xpm/robot.xpm" + +#include "map.h" +#include "configs.h" + +#include <stdlib.h> + +#include <glib/gprintf.h> + +#define TILE_SIZE	16 + +enum +{ +	ARG_0, +	ARG_MAP +}; + +struct _UIArenaPrivate +{ +	Map *map; +	MapSize *map_size; + +	GdkPixmap *buf; +	GdkFont *font; + +	int width; +	int height; + +	GdkPixmap *win_bufi; +	GdkPixmap *statusbar; +	GdkPixmap *space; +	GdkPixmap *food; +	GdkPixmap *wall; +	GdkPixmap *prize; +	GdkPixmap *baddie; +	GdkPixmap *robotDirs[4]; +	GdkPixmap *robotPix; +}; + +#define UI_ARENA_GET_PRIVATE(obj) \ +    G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_ARENA, UIArenaPrivate) + +G_DEFINE_TYPE(UIArena, ui_arena, GTK_TYPE_DRAWING_AREA) + +static gboolean ui_arena_expose(GtkWidget *widget, GdkEventExpose *event, +	UIArena *arena); +static gboolean ui_arena_configure(GtkWidget *widget, +	GdkEventConfigure *event, UIArena *arena); +static void create_image (UIArena *arena, gchar **data, GdkPixmap **image); +static void put_tile(UIArena *arena, GdkPixmap *image, gint x, gint y); + +GtkWidget *ui_arena_new() +{ +	return GTK_WIDGET(g_object_new(UI_TYPE_ARENA, NULL)); +} + +static void ui_arena_init(UIArena *arena) +{ +	arena->priv = UI_ARENA_GET_PRIVATE(arena); + +	arena->priv->map = NULL; +	arena->priv->map_size = NULL; +	arena->priv->width = 400; +	arena->priv->height = 200; +	arena->priv->font = gdk_font_from_description( +		pango_font_description_from_string("Fixed 18")); + +	gtk_widget_set_size_request(GTK_WIDGET(arena), arena->priv->width, +		arena->priv->height); + +	g_signal_connect(G_OBJECT(arena), "expose_event", +		G_CALLBACK(ui_arena_expose), arena); +	g_signal_connect(G_OBJECT(arena), "configure_event", +		G_CALLBACK(ui_arena_configure), arena); + +	gtk_widget_set_events(GTK_WIDGET(arena), +		GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); +} + +static void ui_arena_class_init(UIArenaClass *klass) +{ +	g_type_class_add_private(G_OBJECT_CLASS(klass), +		sizeof(UIArenaPrivate)); +} + +static gboolean ui_arena_expose(GtkWidget *widget, GdkEventExpose *event, +	UIArena *arena) +{ +	gdk_draw_drawable(widget->window, +		widget->style->fg_gc[GTK_WIDGET_STATE(widget)], arena->priv->buf, +		event->area.x, event->area.y, event->area.x, event->area.y, +		event->area.width, event->area.height); + +	if(arena->priv->map) +	{ +		gdk_draw_rectangle(widget->window, widget->style->black_gc, FALSE, +			0, 0, widget->allocation.width - 2, +			widget->allocation.height - 1); +	} + +	return FALSE; +} + +static gboolean ui_arena_configure(GtkWidget *widget, +	GdkEventConfigure *event, UIArena *arena) +{ +	if(arena->priv->buf) +		g_object_unref(arena->priv->buf); + +	arena->priv->buf = gdk_pixmap_new(widget->window, +		widget->allocation.width - 1, widget->allocation.height, -1); + +	gdk_draw_rectangle(arena->priv->buf, widget->style->white_gc, TRUE, +		0, 0, widget->allocation.width, widget->allocation.height); + +	return TRUE; +} + +void ui_arena_set_map(UIArena *arena, Map *map) +{ +	arena->priv->map = map; + +	g_object_get(G_OBJECT(arena->priv->map), "size", +		&arena->priv->map_size, NULL); + +	arena->priv->width = arena->priv->map_size->num_cols * TILE_SIZE; +	arena->priv->height = arena->priv->map_size->num_rows * TILE_SIZE + 32; + +	gtk_widget_set_size_request(GTK_WIDGET(arena), arena->priv->width, +		arena->priv->height); +} + +void ui_arena_draw(UIArena *arena) +{ +	gint i, j; + +	if(!arena->priv->map) +		return; + +	for (j = 0; j < arena->priv->map_size->num_rows; j++) +	{ +		for (i = 0; i < arena->priv->map_size->num_cols; i++) +		{ +			switch(MAP_GET_OBJECT(arena->priv->map, i, j)) +			{ +			case '\0': +				put_tile(arena, arena->priv->wall, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case SPACE: +				put_tile(arena, arena->priv->space, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case FOOD: +				put_tile(arena, arena->priv->food, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case PRIZE: +				put_tile(arena, arena->priv->prize, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case WALL: +				put_tile(arena, arena->priv->wall, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case BADDIE: +				put_tile(arena, arena->priv->baddie, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			case ROBOT: +				put_tile(arena, arena->priv->robotPix, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			default: +				put_tile(arena, arena->priv->wall, i * TILE_SIZE, +					j * TILE_SIZE); +				break; +			} +		} +	} + +	gtk_widget_queue_draw_area(GTK_WIDGET(arena), 0, 0, arena->priv->width, +		arena->priv->height); +} + +void ui_arena_postinit(UIArena *arena) +{ +	create_image(arena, statusbar_xpm, &arena->priv->statusbar); +	create_image(arena, space_xpm, &arena->priv->space); +	create_image(arena, food_xpm, &arena->priv->food); +	create_image(arena, wall_xpm, &arena->priv->wall); +	create_image(arena, prize_xpm, &arena->priv->prize); +	create_image(arena, baddie_xpm, &arena->priv->baddie); +	create_image(arena, robot_north_xpm, &arena->priv->robotDirs[0]); +	create_image(arena, robot_east_xpm, &arena->priv->robotDirs[1]); +	create_image(arena, robot_south_xpm, &arena->priv->robotDirs[2]); +	create_image(arena, robot_west_xpm, &arena->priv->robotDirs[3]); +	create_image(arena, robot_xpm, &arena->priv->robotPix); +} + +static void create_image (UIArena *arena, gchar **data, GdkPixmap **image) +{ +	*image = gdk_pixmap_create_from_xpm_d(GDK_DRAWABLE(arena->priv->buf), +		NULL, NULL, data); +	if (*image == NULL) +		g_fprintf (stderr, "Cannot create image from xpm\n"); +} + +static void put_tile(UIArena *arena, GdkPixmap *image, gint x, gint y) +{ +	gdk_draw_drawable(arena->priv->buf, +		GTK_WIDGET(arena)->style->fg_gc[GTK_WIDGET_STATE(arena)], +		GDK_DRAWABLE(image), 0, 0, x, y, TILE_SIZE, TILE_SIZE); +} + +void ui_arena_update_status(UIArena *arena, const gchar *s, glong energy, +	glong score, glong shields) +{ +	gchar status[20]; +	gint x = 0; + +	while(x < arena->priv->width) +	{ +		gdk_draw_drawable(arena->priv->buf, +			GTK_WIDGET(arena)->style->white_gc, +			arena->priv->statusbar, 0, 0, x, +			arena->priv->map_size->num_rows * TILE_SIZE, 96, 32); +		x += 96; +	} + +	gdk_draw_string(arena->priv->buf, arena->priv->font, +		GTK_WIDGET(arena)->style->white_gc, 3, +		arena->priv->map_size->num_rows * TILE_SIZE + 16, s); + +	if(energy > -1) +	{ +		g_sprintf(status, "Robot Energy: %3ld", energy); +		gdk_draw_string(arena->priv->buf, arena->priv->font, +			GTK_WIDGET(arena)->style->white_gc, 240, +			arena->priv->map_size->num_rows * TILE_SIZE + 12, status); +	} + +	if (score > -1) +	{ +		g_sprintf (status, "Robot Score: %3ld", score); +		gdk_draw_string(arena->priv->buf, arena->priv->font, +			GTK_WIDGET(arena)->style->white_gc, 240, +			arena->priv->map_size->num_rows * TILE_SIZE + 25, status); +	} + +	if (shields > -1) +	{ +		g_sprintf (status, "Robot Shields: %3ld", shields); +		gdk_draw_string(arena->priv->buf, arena->priv->font, +			GTK_WIDGET(arena)->style->white_gc, 480, +			arena->priv->map_size->num_rows * TILE_SIZE + 12, status); +	} + +	gtk_widget_queue_draw_area(GTK_WIDGET(arena), 0, 0, arena->priv->width, +		arena->priv->height); +} + +/* note that hook_delete_thing(x,y) is the same as + * hook_add_thing(x,y,space) */ +void ui_arena_add_thing(UIArena *arena, gint x, gint y, gint thing) +{ +	gint w_x, w_y; + +	w_x = x * TILE_SIZE; +	w_y = y * TILE_SIZE; + +	switch (thing) +	{ +	case SPACE: +		put_tile(arena, arena->priv->space, w_x, w_y); +		break; +	case FOOD: +		put_tile(arena, arena->priv->food, w_x, w_y); +		break; +	case PRIZE: +		put_tile(arena, arena->priv->prize, w_x, w_y); +		break; +	case WALL: +		put_tile(arena, arena->priv->wall, w_x, w_y); +		break; +	case BADDIE: +		put_tile(arena, arena->priv->baddie, w_x, w_y); +		break; +	case ROBOT: +		put_tile(arena, arena->priv->robotPix, w_x, w_y); +		break; +	default: +		put_tile(arena, arena->priv->wall, w_x, w_y); +		break; +	} + +	gtk_widget_queue_draw_area(GTK_WIDGET(arena), 0, 0, arena->priv->width, +		arena->priv->height); +} + +void ui_arena_move_robot(UIArena *arena, gint from_x, gint from_y, +	gint to_x, gint to_y, gint cdir, glong energy, glong score, +	glong shields) +{ +	const static gint movement = TILE_SIZE / 16; +	guint8 distance = dist(from_x, from_y, to_x, to_y); +	guint w_x = to_x * TILE_SIZE, w_y = to_y * TILE_SIZE, tw_x, tw_y; +	gboolean ok; + +	g_assert(distance <= 1); + +	ui_arena_update_status(arena, "Robot moves..", energy, score, shields); + +	/* Check if robot is moving withing a single box */ +	if (distance == 0) +	{ +		put_tile(arena, arena->priv->space, from_x * TILE_SIZE, +			from_y * TILE_SIZE); +		put_tile(arena, arena->priv->robotDirs[cdir], to_x * TILE_SIZE, +			to_y * TILE_SIZE); + +		gtk_widget_queue_draw_area(GTK_WIDGET(arena), 0, 0, +			arena->priv->width,	arena->priv->height); + +		return; +	} + +	from_x *= TILE_SIZE; +	from_y *= TILE_SIZE; +	tw_y = w_y; +	tw_x = w_x; +	switch (cdir) +	{ +	case NORTH: +		tw_y = from_y - movement; +		break; +	case SOUTH: +		tw_y = from_y + movement; +		break; +	case EAST: +		tw_x = from_x + movement; +		break; +	case WEST: +		tw_x = from_x - movement; +		break; +	default: +		g_printf("Weird unknown robot direction. I'm Confused.\n"); +	} + + +	while (1) +	{ +		put_tile(arena, arena->priv->space, from_x, from_y); +		put_tile(arena, arena->priv->robotDirs[cdir], tw_x, tw_y); + +		ok = FALSE; +		if (tw_x < w_x) +		{ +			tw_x += movement; +			ok = TRUE; +		} +		else if (tw_x > w_x) +		{ +			tw_x -= movement; +			ok = TRUE; +		} +		if (tw_y < w_y) +		{ +			tw_y += movement; +			ok = TRUE; +		} +		else if (tw_y > w_y) +		{ +			tw_y -= movement; +			ok = TRUE; +		} + +		gtk_widget_queue_draw_area(GTK_WIDGET(arena), 0, 0, +			arena->priv->width,	arena->priv->height); +		gdk_window_process_all_updates(); + +		g_usleep(USLEEP_TIME / 16); + +		if (!ok) +			break; +	} + +	g_usleep(USLEEP_TIME); +} + +/* hooks to animate the robot */ +void ui_arena_robot_smell(UIArena *arena, gint x, gint y, gint cdir, +	glong energy, glong score, glong shields) +{ +	/* If we want to change the pic, do it here */ +	ui_arena_update_status(arena, "Robot sniffs...", energy, score, +		shields); + +	g_usleep(USLEEP_TIME); +} + +void ui_arena_robot_zap(UIArena *arena,	gint x,	gint y,	gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields) +{ +	ui_arena_update_status(arena, "Robot fires his little gun...", energy, +		score, shields); + +	g_usleep(USLEEP_TIME); +} + +void ui_arena_robot_feel(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields) +{ +	ui_arena_update_status(arena, "Robot feels for a thing...", energy, +		score, shields); + +	g_usleep(USLEEP_TIME); +} + +void ui_arena_robot_grab(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields) +{ +	ui_arena_update_status(arena, "Robot grabs thing...", energy, score, +		shields); + +	g_usleep(USLEEP_TIME); +} + +void ui_arena_robot_look(UIArena *arena, gint x, gint y, gint cdir, +	gint x_to, gint y_to, glong energy, glong score, glong shields) +{ +	ui_arena_update_status(arena, "Robot looks for a thing...", energy, +		score, shields); + +	g_usleep(USLEEP_TIME); +} diff --git a/ui/ui-cmdwin.c b/src/ui-cmdwin.c index b743687..71f7b53 100644 --- a/ui/ui-cmdwin.c +++ b/src/ui-cmdwin.c @@ -18,9 +18,16 @@  #include "ui-cmdwin.h" +#include <stdlib.h> +#include <pty.h> + +#include <vte/vte.h> +#include <readline.h> +#include <history.h> +  struct _UICmdWinPrivate  { -	int dummy; +	GtkWidget *vte;  };  #define UI_CMDWIN_GET_PRIVATE(obj) \ @@ -35,7 +42,26 @@ GtkWidget *ui_cmdwin_new(void)  static void ui_cmdwin_init(UICmdWin *cmdwin)  { -	gtk_widget_set_size_request(GTK_WIDGET(cmdwin), 40*16,200); +	int master_pty, slave_pty; +	FILE *in, *out; + +	cmdwin->priv = UI_CMDWIN_GET_PRIVATE(cmdwin); + +	cmdwin->priv->vte = vte_terminal_new(); + +	gtk_box_pack_start(GTK_BOX(cmdwin), cmdwin->priv->vte, TRUE, TRUE, 0); + +	gtk_widget_set_size_request(GTK_WIDGET(cmdwin), -1, 200); + +	g_assert(openpty(&master_pty, &slave_pty, NULL, NULL, NULL) >= 0); +	vte_terminal_set_pty(VTE_TERMINAL(cmdwin->priv->vte), master_pty); +	in = fdopen(slave_pty, "r"); +	out = fdopen(slave_pty, "w"); + +	rl_instream = in; +	rl_outstream = out; + +	gtk_widget_show(cmdwin->priv->vte);  }  static void ui_cmdwin_class_init(UICmdWinClass *klass) @@ -43,3 +69,19 @@ static void ui_cmdwin_class_init(UICmdWinClass *klass)  	g_type_class_add_private(G_OBJECT_CLASS(klass),  		sizeof(UICmdWinPrivate));  } + +void ui_cmdwin_get_string(UICmdWin *cmdwin, gchar *prompt, gchar *buf, +	gint len) +{ +	char *line = (char *)NULL; + +	line = readline(prompt); + +	if (line && *line) +	{ +		add_history(line); +		g_strlcpy(buf, line, len); +	} + +	free(line); +} diff --git a/ui/ui-window.c b/src/ui-window.c index 27c49e9..8758c64 100644 --- a/ui/ui-window.c +++ b/src/ui-window.c @@ -22,6 +22,10 @@  #include "ui-cmdwin.h"  #include "ui-arena.h" +#include "main.h" +#include "map.h" +#include "configs.h" +  #include <gtk/gtkmain.h>  #define UI_WINDOW_GET_PRIVATE(obj) \ @@ -31,7 +35,7 @@ G_DEFINE_TYPE(UIWindow, ui_window, GTK_TYPE_WINDOW)  static void on_ui_window_destroy(GtkWidget *widget, gpointer data); -GtkWidget *ui_window_new(void) +GtkWidget *ui_window_new()  {  	return GTK_WIDGET(g_object_new(UI_TYPE_WINDOW, NULL));  } @@ -40,37 +44,41 @@ static void on_ui_window_destroy(GtkWidget *widget, gpointer data)  {  	gtk_widget_hide(widget);  	gtk_main_quit(); +	exit_nicely();  }  static void ui_window_init(UIWindow *window)  { -	GtkWidget *vbox; -	GtkWidget *vpaned; -  	window->priv = UI_WINDOW_GET_PRIVATE(window); -	vbox = gtk_vbox_new(FALSE, 0); -	vpaned = gtk_vpaned_new(); +	g_signal_connect(G_OBJECT(window), "destroy", +		G_CALLBACK(on_ui_window_destroy), NULL); + +	gtk_window_set_title(GTK_WINDOW(window), "UI Test"); +	gtk_window_set_resizable(GTK_WINDOW(window), FALSE); +} + +void ui_window_postinit(UIWindow *window, Map* map) +{ +	GtkWidget *vbox; + +	vbox = gtk_vbox_new(FALSE, 2);  	window->priv->cmdwin = ui_cmdwin_new();  	window->priv->arena = ui_arena_new(); - -	gtk_paned_add1(GTK_PANED(vpaned), window->priv->arena); -	gtk_paned_add2(GTK_PANED(vpaned), window->priv->cmdwin); +	ui_arena_set_map(UI_ARENA(window->priv->arena), map);  	/* TODO: Add menu first etc */ -	gtk_box_pack_start(GTK_BOX(vbox), vpaned, TRUE, TRUE, 0); +	gtk_box_pack_start(GTK_BOX(vbox), window->priv->arena, TRUE, TRUE, 0); +	gtk_box_pack_start(GTK_BOX(vbox), window->priv->cmdwin, TRUE, TRUE, 0);  	gtk_container_add(GTK_CONTAINER(window), vbox); -	g_signal_connect(G_OBJECT(window), "destroy", -		G_CALLBACK(on_ui_window_destroy), NULL); - -	gtk_window_set_title(GTK_WINDOW(window), "UI Test");  	gtk_widget_show(window->priv->cmdwin);  	gtk_widget_show(window->priv->arena); -	gtk_widget_show(vpaned);  	gtk_widget_show(vbox);  	gtk_widget_show(GTK_WIDGET(window)); + +	ui_arena_postinit(UI_ARENA(window->priv->arena));  }  static void ui_window_class_init(UIWindowClass *klass) diff --git a/src/userinterface.c b/src/userinterface.c deleted file mode 100644 index b2702e4..0000000 --- a/src/userinterface.c +++ /dev/null @@ -1,736 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNU Robots is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <glib.h> -#include <glib/gprintf.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "configs.h" -#include "userinterface.h" - -#include <readline.h> -#include <history.h> - -G_DEFINE_TYPE(UserInterface, user_interface, G_TYPE_OBJECT) - -enum -{ -  ARG_0, -  ARG_MAP -}; - -static GObject * user_interface_constructor (GType type, -    guint n_construct_properties, -    GObjectConstructParam *construct_properties); - -static void user_interface_finalize (GObject * object); -static void user_interface_dispose (GObject * object); - -static void user_interface_set_property (GObject * object, guint prop_id, -    const GValue * value, GParamSpec * pspec); - -static void user_interface_get_property (GObject * object, guint prop_id, -    GValue * value, GParamSpec * pspec); - -static void put_tile (UserInterface *ui, XImage *image, gint x, gint y); -static void put_winbuf (UserInterface *ui); -static void setup_winbuf (UserInterface *ui); -void create_image (UserInterface *ui, gchar **data, XImage ** image); - -static GObjectClass *parent_class = NULL; - -static void -user_interface_class_init (UserInterfaceClass * klass) -{ -  GObjectClass *gobject_class; - -  gobject_class = (GObjectClass *) klass; - -  parent_class = g_type_class_ref (G_TYPE_OBJECT); - -  gobject_class->constructor = user_interface_constructor; -  gobject_class->set_property = user_interface_set_property; -  gobject_class->get_property = user_interface_get_property; -  gobject_class->dispose = user_interface_dispose; -  gobject_class->finalize = user_interface_finalize; - -  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAP, -      g_param_spec_object ("map", -            "Map", -            "Reference to the Game Map object", -            G_TYPE_MAP, -            G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -static void -user_interface_init (UserInterface* ui) -{ -  ui->map = NULL; -  ui->map_size = NULL; -} - -static GObject * -user_interface_constructor (GType type, -    guint n_construct_properties, -    GObjectConstructParam *construct_properties) -{ -  /* Initialize ui */ -  GObject *object; -  UserInterface *ui; -#include "xpm/statusbar.xpm" -#include "xpm/space.xpm" -#include "xpm/food.xpm" -#include "xpm/wall.xpm" -#include "xpm/prize.xpm" -#include "xpm/baddie.xpm" -#include "xpm/robot_north.xpm" -#include "xpm/robot_east.xpm" -#include "xpm/robot_south.xpm" -#include "xpm/robot_west.xpm" -#include "xpm/robot.xpm" -  XClassHint classhint; -  XWMHints wmhints; -  XGCValues values; - -  /* Chain up to the parent first */ -  object = parent_class->constructor (type, n_construct_properties, -          construct_properties); - -  ui = USER_INTERFACE (object); - -  XInitThreads(); - -  if ((ui->dpy = XOpenDisplay ("")) == NULL) { -    g_printf ("Couldn't open the X Server Display!\n"); -    exit (1);       /* Exit nicely isn't needed yet, and causes segfault */ -  } - -  ui->wm_delete_win = XInternAtom (ui->dpy, "WM_DELETE_WINDOW", False); - -  ui->win_width = ui->map_size->num_cols * TILE_SIZE; -  ui->win_height = ui->map_size->num_rows * TILE_SIZE + 32; -  ui->x_win = XCreateSimpleWindow (ui->dpy, DefaultRootWindow (ui->dpy), -          0, 0, ui->win_width, ui->win_height, 0, 0, 0); - -  XSetWMProtocols (ui->dpy, ui->x_win, &(ui->wm_delete_win), 1); - -  ui->wm_protocols = XInternAtom(ui->dpy, "WM_PROTOCOLS", False); - -  XStoreName (ui->dpy, ui->x_win, "GNU Robots"); - -  classhint.res_name = "robots"; -  classhint.res_class = "Robots"; -  XSetClassHint (ui->dpy, ui->x_win, &classhint); - -  /* XSetCommand() seems to segfault... */ - -  wmhints.input = True; -  wmhints.flags = InputHint; -  XSetWMHints (ui->dpy, ui->x_win, &wmhints); - -  XSelectInput (ui->dpy, ui->x_win, -      ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask -      | FocusChangeMask); - -  XMapWindow (ui->dpy, ui->x_win); - -  ui->text = XLoadFont (ui->dpy, -          "-*-fixed-medium-r-*-*-*-120-*-*-*-*-*-*"); -  values.font = ui->text; -  values.foreground = WhitePixel (ui->dpy, DefaultScreen (ui->dpy)); - -  ui->gc = XCreateGC (ui->dpy, ui->x_win, -          GCFont | GCForeground, &values); - -  create_image (ui, statusbar_xpm, &ui->statusbar); -  create_image (ui, space_xpm, &ui->space); -  create_image (ui, food_xpm, &ui->food); -  create_image (ui, wall_xpm, &ui->wall); -  create_image (ui, prize_xpm, &ui->prize); -  create_image (ui, baddie_xpm, &ui->baddie); -  create_image (ui, robot_north_xpm, &ui->robotDirs[0]); -  create_image (ui, robot_east_xpm, &ui->robotDirs[1]); -  create_image (ui, robot_south_xpm, &ui->robotDirs[2]); -  create_image (ui, robot_west_xpm, &ui->robotDirs[3]); -  create_image (ui, robot_xpm, &ui->robotPix); - -  setup_winbuf (ui); - -  return object; -} - -static void -user_interface_dispose (GObject * object) -{ -  UserInterface *ui; -  ui = USER_INTERFACE (object); - -  if (ui->map != NULL) { -    g_object_unref (G_OBJECT (ui->map)); - -    if (ui->map_size != NULL) { -      g_free (ui->map_size); -    } -  } - -  parent_class->dispose (object); -} - -/* finalize is called when the object has to free its resources */ -static void -user_interface_finalize (GObject * object) -{ -  UserInterface *ui = USER_INTERFACE (object); - -  /* End ui mode */ -#ifdef USE_MITSHM -  if (use_mitshm) { -    XShmDetach (ui->dpy, &shm_info); -    if (shm_info.shmaddr) -      shmdt (shm_info.shmaddr); -    if (shm_info.shmid >= 0) -      shmctl (shm_info.shmid, IPC_RMID, 0); -  } -#endif -  XDestroyWindow (ui->dpy, ui->x_win); -  XUnloadFont (ui->dpy, ui->text); - -  parent_class->finalize (object); -} - -static void -user_interface_set_property (GObject * object, guint prop_id, -    const GValue * value, GParamSpec * pspec) -{ -  UserInterface *ui; -  GObject *obj; - -  /* it's not null if we got it, but it might not be ours */ -  g_return_if_fail (G_IS_USER_INTERFACE (object)); - -  ui = USER_INTERFACE (object); - -  switch (prop_id) { -    case ARG_MAP: -      obj = g_value_get_object (value); -      g_return_if_fail (obj != NULL); - -      if (ui->map != NULL) { -	g_object_unref (ui->map); -      } - -      ui->map = MAP (g_object_ref (obj)); - -      if (ui->map_size != NULL) { -        g_free (ui->map_size); -      } - -      g_object_get (G_OBJECT (ui->map), -		"size", &ui->map_size, -		NULL); -      break; -    default: -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -      break; -  } -} - -static void -user_interface_get_property (GObject * object, guint prop_id, -    GValue * value, GParamSpec * pspec) -{ -  UserInterface *ui; - -  /* it's not null if we got it, but it might not be ours */ -  g_return_if_fail (G_IS_USER_INTERFACE (object)); - -  ui = USER_INTERFACE (object); - -  switch (prop_id) { -    case ARG_MAP: -      g_value_set_object (value, g_object_ref (G_OBJECT (ui->map))); -      break; -    default: -      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -      break; -  } -} - -UserInterface * -user_interface_new (Map *map) -{ -  UserInterface *ui; - -  g_return_val_if_fail (map != NULL, NULL); - -  ui = USER_INTERFACE (g_object_new (user_interface_get_type (), -				  "map", map, -				  NULL)); - -  return USER_INTERFACE (ui); -} - -/* note that hook_delete_thing(x,y) is the same as -   hook_add_thing(x,y,space) */ -void user_interface_add_thing (UserInterface *ui, -				      gint x, -				      gint y, -				      gint thing) -{ -  gint w_x, w_y; - -  w_x = x * TILE_SIZE; -  w_y = y * TILE_SIZE; - -  switch (thing) { -    case SPACE: -      put_tile (ui, ui->space, w_x, w_y); -      break; -    case FOOD: -      put_tile (ui, ui->food, w_x, w_y); -      break; -    case PRIZE: -      put_tile (ui, ui->prize, w_x, w_y); -      break; -    case WALL: -      put_tile (ui, ui->wall, w_x, w_y); -      break; -    case BADDIE: -      put_tile (ui, ui->baddie, w_x, w_y); -      break; -    case ROBOT: -      put_tile (ui, ui->robotPix, w_x, w_y); -      break; -    default: -      put_tile (ui, ui->wall, w_x, w_y); -      break; -  } - -  put_winbuf (ui); -  XFlush (ui->dpy); -} - -void user_interface_draw (UserInterface *ui) -{ -  gint i, j; - -  /* Draw the map for the GNU Robots game. */ -  for (j = 0; j < ui->map_size->num_rows; j++) { -    for (i = 0; i < ui->map_size->num_cols; i++) { -      /* Special cases */ -      switch (MAP_GET_OBJECT (ui->map, i, j)) { -          /* Add something for the ROBOT?? */ -        case '\0': -          put_tile (ui, ui->wall, i * TILE_SIZE, j * TILE_SIZE); -          break; -        case SPACE: -          put_tile (ui, ui->space, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -    	case FOOD: -      	  put_tile (ui, ui->food, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -    	case PRIZE: -      	  put_tile (ui, ui->prize, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -    	case WALL: -      	  put_tile (ui, ui->wall, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -    	case BADDIE: -      	  put_tile (ui, ui->baddie, i * TILE_SIZE, j * TILE_SIZE); -          break; -    	case ROBOT: -      	  put_tile (ui, ui->robotPix, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -    	default: -      	  put_tile (ui, ui->wall, i * TILE_SIZE, j * TILE_SIZE); -      	  break; -      }                         /* switch */ -    }                           /* for i */ -  }                             /* for j */ - -  put_winbuf (ui); -  XSync (ui->dpy, FALSE); -} - -void user_interface_move_robot (UserInterface *ui, -				       gint from_x, -				       gint from_y, -				       gint to_x, -				       gint to_y, -				       gint cdir, -				       glong energy, -				       glong score, -				       glong shields) -{ -  const static gint movement = TILE_SIZE / 16; -  guint8 distance = dist (from_x, from_y, to_x, to_y); -  guint w_x = to_x * TILE_SIZE, w_y = to_y * TILE_SIZE, tw_x, tw_y; -  Bool ok; - -  g_assert (distance <= 1); - -  user_interface_update_status (ui, "robot moves..", energy, score, shields); - -  /* Check if robot is moving withing a single box */ -  if (distance == 0) { -    put_tile (ui, ui->space, from_x * TILE_SIZE, from_y * TILE_SIZE); -    put_tile (ui, ui->robotDirs[cdir], to_x * TILE_SIZE, to_y * TILE_SIZE); - -    put_winbuf (ui); -    XSync (ui->dpy, False); -    g_usleep (USLEEP_TIME / 16); - -    return; -  } - -  from_x *= TILE_SIZE; -  from_y *= TILE_SIZE; -  tw_y = w_y; -  tw_x = w_x; -  switch (cdir) { -    case NORTH: -      tw_y = from_y - movement; -      break; -    case SOUTH: -      tw_y = from_y + movement; -      break; -    case EAST: -      tw_x = from_x + movement; -      break; -    case WEST: -      tw_x = from_x - movement; -      break; -    default: -      g_printf ("Weird unknown robot direction. I'm Confused.\n"); -  } - -  while (1) { -    put_tile (ui, ui->space, from_x, from_y); -    put_tile (ui, ui->robotDirs[cdir], tw_x, tw_y); - -    ok = False; -    if (tw_x < w_x) { -      tw_x += movement; -      ok = True; -    } else if (tw_x > w_x) { -      tw_x -= movement; -      ok = True; -    } -    if (tw_y < w_y) { -      tw_y += movement; -      ok = True; -    } else if (tw_y > w_y) { -      tw_y -= movement; -      ok = True; -    } -    put_winbuf (ui); -    XSync (ui->dpy, False); -    g_usleep (USLEEP_TIME / 16); -    if (!ok) -      break; -  } - -  g_usleep (USLEEP_TIME); -} - -/* hooks to animate the robot */ -void user_interface_robot_smell (UserInterface *ui, -					gint x, -					gint y, -					gint cdir, -				        glong energy, -				        glong score, -				        glong shields) -{ -  /* If we want to change the pic, do it here */ -  user_interface_update_status (ui, "robot sniffs...", energy, score, shields); -  g_usleep (USLEEP_TIME); -} - -void user_interface_robot_zap (UserInterface *ui, -				      gint x, -				      gint y, -				      gint cdir, -				      gint x_to, -				      gint y_to, -				      glong energy, -				      glong score, -				      glong shields) -{ -  user_interface_update_status (ui, "robot fires his little gun...", energy, score, shields); -  g_usleep (USLEEP_TIME); -} - -void user_interface_robot_feel (UserInterface *ui, -				       gint x, -				       gint y, -				       gint cdir, -				       gint x_to, -				       gint y_to, -				       glong energy, -				       glong score, -				       glong shields) -{ -  user_interface_update_status (ui, "robot feels for a thing...", energy, score, shields); -  g_usleep (USLEEP_TIME); -} - -void user_interface_robot_grab (UserInterface *ui, -				       gint x, -				       gint y, -				       gint cdir, -				       gint x_to, -				       gint y_to, -				       glong energy, -				       glong score, -				       glong shields) -{ -  user_interface_update_status (ui, "robot grabs thing...", energy, score, shields); -  g_usleep (USLEEP_TIME); -} - -void user_interface_robot_look (UserInterface *ui, -				       gint x, -				       gint y, -				       gint cdir, -				       gint x_to, -				       gint y_to, -				       glong energy, -				       glong score, -				       glong shields) -{ -  user_interface_update_status (ui, "robot looks for a thing...", energy, score, shields); -  g_usleep (USLEEP_TIME); -} - -/* hooks to get/display data from/to user */ -void user_interface_get_string (UserInterface *ui, -				       gchar *prompt, -				       gchar *buff, -				       gint len) -{ -  char* line = (char*)NULL; - -  line = readline(prompt); - -  if(line && *line) -  { -    add_history(line); - -    g_strlcpy(buff, line, len); -  } -  else -    buff = ""; - -  free(line); -} - -void ui_update_status (UserInterface *ui, -				   const gchar *s, -				   glong energy, -				   glong score, -				   glong shields) -{ -  gchar status[20]; -  gint x = 0; - -  while (x < ui->win_width) { -    XPutImage (ui->dpy, ui->win_buf, ui->buf_gc, ui->statusbar, 0, 0, x, ui->map_size->num_rows * TILE_SIZE, 96, -        32); -    x = x + 96; -  } - -  XDrawString (ui->dpy, ui->win_buf, ui->gc, 3, ui->map_size->num_rows * TILE_SIZE + 16, s, strlen (s)); - -  if (energy > -1) { -    g_sprintf (status, "Robot Energy: %3ld", energy); -    XDrawString (ui->dpy, ui->win_buf, ui->gc, 240, ui->map_size->num_rows * TILE_SIZE + 12, status, -        strlen (status)); -  } - -  if (score > -1) { -    g_sprintf (status, "Robot Score: %3ld", score); -    XDrawString (ui->dpy, ui->win_buf, ui->gc, 240, ui->map_size->num_rows * TILE_SIZE + 25, status, -        strlen (status)); -  } - -  if (shields > -1) { -    g_sprintf (status, "Robot Shields: %3ld", shields); -    XDrawString (ui->dpy, ui->win_buf, ui->gc, 480, ui->map_size->num_rows * TILE_SIZE + 12, status, -        strlen (status)); -  } -} - -void user_interface_update_status (UserInterface *ui, -				   const gchar *s, -				   glong energy, -				   glong score, -				   glong shields) -{ -  ui_update_status (ui, s, energy, score, shields); -} - -void user_interface_run(UserInterface* ui) -{ -  XEvent ev; -  XClientMessageEvent* evt; - -  while (TRUE) -  { -    XNextEvent (ui->dpy, &ev); - -    switch (ev.type) -    { -      case KeyPress: -      case KeyRelease: -        switch (XKeycodeToKeysym (ui->dpy, ev.xkey.keycode, 0)) -        { -          case XK_Escape: -            exit (0); -            break; -        } -      case ClientMessage: -        evt = (XClientMessageEvent*)&ev; -        if (evt->message_type == ui->wm_protocols -                && evt->data.l[0] == ui->wm_delete_win) -        { -          g_printf("Exited\n"); -          exit(0); -        } -        break; -      case Expose: -        user_interface_draw(ui); -        break; -    } -  } - -  put_winbuf (ui); -} - -#ifdef USE_MITSHM -static gint -shm_error_handler (UserInterface *ui, Display * d, XErrorEvent * e) -{ -  ui->use_mitshm = 0; -  return 0; -} -#endif - -static void -setup_winbuf (UserInterface *ui) -{ -  XVisualInfo *matches; -  XVisualInfo plate; -  gint count; -  guint depth; -  XGCValues values; -  Visual *vis; - -  vis = DefaultVisualOfScreen (DefaultScreenOfDisplay (ui->dpy)); -  plate.visualid = XVisualIDFromVisual (vis); -  matches = XGetVisualInfo (ui->dpy, VisualIDMask, &plate, &count); -  depth = matches[0].depth; - -#ifdef USE_MITSHM -  ui->use_mitshm = 1; -  ui->shm_info.shmid = shmget (IPC_PRIVATE, win_height * win_width * depth, -      IPC_CREAT | 0777); -  if (ui->shm_info.shmid < 0) { -    g_fprintf (stderr, "shmget failed, looks like I'll have to use XPutImage\n"); -    ui->use_mitshm = 0; -  } else { -    ui->shm_info.shmaddr = (gchar *) shmat (ui->shm_info.shmid, 0, 0); - -    if (!ui->shm_info.shmaddr) { -      g_fprintf (stderr, "shmat failed, looks like I'll have to use XPutImage\n"); -      shmctl (ui->shm_info.shmid, IPC_RMID, 0); -      use_mitshm = 0; -    } else { -      XErrorHandler error_handler = XSetErrorHandler (shm_error_handler); - -      ui->win_bufi = XShmCreateImage (ui->dpy, vis, depth, ZPixmap, ui->shm_info.shmaddr, -          &ui->shm_info, ui->win_width, ui->win_height); -      ui->shm_info.readOnly = False; -      XShmAttach (ui->dpy, &ui->shm_info); -      win_buf = XShmCreatePixmap (ui->dpy, ui->x_win, ui->shm_info.shmaddr, &ui->shm_info, -          ui->win_width, ui->win_height, depth); -      XSync (ui->dpy, False); -      (void) XSetErrorHandler (error_handler); -      if (!use_mitshm) { -        p_fprintf (stderr, -            "XShmAttach failed, looks like I'll have to use XPutImage\n"); -        XFreePixmap (ui->dpy, ui->win_buf); -        XDestroyImage (ui->win_bufi); -        shmdt (ui->shm_info.shmaddr); -        shmctl (ui->shm_info.shmid, IPC_RMID, 0); -      } -    } -  } - -  if (!ui->use_mitshm) { -#endif /* USE_MITSHM */ -    ui->win_buf = XCreatePixmap (ui->dpy, ui->x_win, ui->win_width, ui->win_height, depth); -#ifdef USE_MITSHM -  } else { -    g_printf ("Using MIT Shared Memory Pixmaps. Good.\n", major, minor); -  } -#endif - -  values.font = ui->text; -  values.foreground = WhitePixel (ui->dpy, DefaultScreen (ui->dpy)); - -  ui->buf_gc = XCreateGC (ui->dpy, ui->win_buf, GCFont | GCForeground, &values); -} - -void -create_image (UserInterface *ui, gchar **data, XImage ** image) -{ -  XpmAttributes a; -  gint err; - -  a.valuemask = XpmCloseness | XpmAllocCloseColors; -  a.closeness = 40000;          /* the xpm manual suggests 40000 */ -  a.alloc_close_colors = 1;     /* allocate the colours chosen */ -  err = XpmCreateImageFromData (ui->dpy, data, image, NULL, &a); -  if (err != 0) { -    g_fprintf (stderr, "Cannot create image from xpm: %s\n", -        XpmGetErrorString (err)); -    exit (1); -  } -} - -static void -put_tile (UserInterface *ui, XImage *image, gint x, gint y) -{ -  XPutImage (ui->dpy, ui->win_buf, ui->gc, image, 0, 0, x, y, TILE_SIZE, TILE_SIZE); -} - -static void put_winbuf (UserInterface *ui) -{ -#ifdef USE_MITSHM -  if (use_mitshm) -    XShmPutImage (ui->dpy, ui->x_win, ui->gc, ui->win_bufi, 0, 0, 0, 0, ui->win_width, ui->win_height, -        False); -  else -#endif -    XCopyArea (ui->dpy, ui->win_buf, ui->x_win, ui->gc, 0, 0, ui->win_width, ui->win_height, 0, 0); - -  XSync (ui->dpy, 0); -} diff --git a/ui/Makefile.am b/ui/Makefile.am deleted file mode 100644 index cf01f1b..0000000 --- a/ui/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -## Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> -## -## src/Makefile.am -## -## GNU Robots is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## GNU Robots is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. - -bin_PROGRAMS = uitest - -INCLUDES = $(GTK_CFLAGS) -I$(top_builddir)/ui/ - -uitest_SOURCES = main.c ui-window.c ui-arena.c ui-cmdwin.c -uitest_LDFLAGS = $(GTK_LIBS) diff --git a/ui/design.glade b/ui/design.glade deleted file mode 100644 index b8d6fba..0000000 --- a/ui/design.glade +++ /dev/null @@ -1,317 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Fri May 16 20:44:59 2008 --> -<glade-interface> -  <widget class="GtkWindow" id="window1"> -    <child> -      <widget class="GtkAlignment" id="alignment1"> -        <property name="visible">True</property> -        <property name="left_padding">2</property> -        <property name="right_padding">2</property> -        <child> -          <widget class="GtkVBox" id="vbox1"> -            <property name="visible">True</property> -            <child> -              <widget class="GtkMenuBar" id="menubar1"> -                <property name="visible">True</property> -                <child> -                  <widget class="GtkMenuItem" id="menuitem1"> -                    <property name="visible">True</property> -                    <property name="label" translatable="yes">_File</property> -                    <property name="use_underline">True</property> -                    <child> -                      <widget class="GtkMenu" id="menu1"> -                        <property name="visible">True</property> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem1"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-new</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem2"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-open</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem3"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-save</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem4"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-save-as</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkSeparatorMenuItem" id="separatormenuitem1"> -                            <property name="visible">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem5"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-quit</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                      </widget> -                    </child> -                  </widget> -                </child> -                <child> -                  <widget class="GtkMenuItem" id="menuitem2"> -                    <property name="visible">True</property> -                    <property name="label" translatable="yes">_Edit</property> -                    <property name="use_underline">True</property> -                    <child> -                      <widget class="GtkMenu" id="menu2"> -                        <property name="visible">True</property> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem6"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-cut</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem7"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-copy</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem8"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-paste</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem9"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-delete</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                      </widget> -                    </child> -                  </widget> -                </child> -                <child> -                  <widget class="GtkMenuItem" id="menuitem3"> -                    <property name="visible">True</property> -                    <property name="label" translatable="yes">_View</property> -                    <property name="use_underline">True</property> -                  </widget> -                </child> -                <child> -                  <widget class="GtkMenuItem" id="menuitem4"> -                    <property name="visible">True</property> -                    <property name="label" translatable="yes">_Help</property> -                    <property name="use_underline">True</property> -                    <child> -                      <widget class="GtkMenu" id="menu3"> -                        <property name="visible">True</property> -                        <child> -                          <widget class="GtkImageMenuItem" id="imagemenuitem10"> -                            <property name="visible">True</property> -                            <property name="label" translatable="yes">gtk-about</property> -                            <property name="use_underline">True</property> -                            <property name="use_stock">True</property> -                          </widget> -                        </child> -                      </widget> -                    </child> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="expand">False</property> -              </packing> -            </child> -            <child> -              <widget class="GtkToolbar" id="toolbar1"> -                <property name="visible">True</property> -                <child> -                  <widget class="GtkToolButton" id="toolbutton1"> -                    <property name="visible">True</property> -                    <property name="stock_id">gtk-open</property> -                  </widget> -                  <packing> -                    <property name="expand">False</property> -                  </packing> -                </child> -              </widget> -              <packing> -                <property name="expand">False</property> -                <property name="position">1</property> -              </packing> -            </child> -            <child> -              <widget class="GtkVPaned" id="vpaned1"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <child> -                  <widget class="GtkAlignment" id="alignment2"> -                    <property name="visible">True</property> -                    <property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property> -                    <property name="top_padding">3</property> -                    <property name="bottom_padding">3</property> -                    <child> -                      <widget class="GtkImage" id="image1"> -                        <property name="visible">True</property> -                        <property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property> -                        <property name="stock">gtk-missing-image</property> -                        <property name="icon_size">6</property> -                      </widget> -                    </child> -                  </widget> -                  <packing> -                    <property name="resize">False</property> -                    <property name="shrink">True</property> -                  </packing> -                </child> -                <child> -                  <widget class="GtkVBox" id="vbox2"> -                    <property name="visible">True</property> -                    <child> -                      <widget class="GtkHBox" id="hbox1"> -                        <property name="visible">True</property> -                        <property name="spacing">11</property> -                        <child> -                          <widget class="GtkHBox" id="hbox3"> -                            <property name="visible">True</property> -                            <child> -                              <widget class="GtkButton" id="button1"> -                                <property name="visible">True</property> -                                <property name="can_focus">True</property> -                                <property name="receives_default">True</property> -                                <property name="relief">GTK_RELIEF_NONE</property> -                                <property name="focus_on_click">False</property> -                                <property name="response_id">0</property> -                                <child> -                                  <widget class="GtkImage" id="image2"> -                                    <property name="visible">True</property> -                                    <property name="stock">gtk-media-play</property> -                                  </widget> -                                </child> -                              </widget> -                              <packing> -                                <property name="expand">False</property> -                              </packing> -                            </child> -                            <child> -                              <widget class="GtkButton" id="button2"> -                                <property name="visible">True</property> -                                <property name="can_focus">True</property> -                                <property name="receives_default">True</property> -                                <property name="relief">GTK_RELIEF_NONE</property> -                                <property name="focus_on_click">False</property> -                                <property name="response_id">0</property> -                                <child> -                                  <widget class="GtkImage" id="image3"> -                                    <property name="visible">True</property> -                                    <property name="stock">gtk-media-next</property> -                                  </widget> -                                </child> -                              </widget> -                              <packing> -                                <property name="expand">False</property> -                                <property name="position">1</property> -                              </packing> -                            </child> -                          </widget> -                          <packing> -                            <property name="expand">False</property> -                          </packing> -                        </child> -                        <child> -                          <widget class="GtkHBox" id="hbox4"> -                            <property name="visible">True</property> -                            <property name="spacing">2</property> -                            <child> -                              <widget class="GtkLabel" id="label2"> -                                <property name="visible">True</property> -                                <property name="xalign">1</property> -                                <property name="label" translatable="yes">Speed</property> -                                <property name="justify">GTK_JUSTIFY_RIGHT</property> -                              </widget> -                              <packing> -                                <property name="expand">False</property> -                              </packing> -                            </child> -                            <child> -                              <widget class="GtkHScale" id="hscale1"> -                                <property name="visible">True</property> -                                <property name="can_focus">True</property> -                                <property name="adjustment">0 0 100 1 10 10</property> -                                <property name="value_pos">GTK_POS_RIGHT</property> -                              </widget> -                              <packing> -                                <property name="position">1</property> -                              </packing> -                            </child> -                          </widget> -                          <packing> -                            <property name="position">1</property> -                          </packing> -                        </child> -                      </widget> -                      <packing> -                        <property name="expand">False</property> -                      </packing> -                    </child> -                    <child> -                      <widget class="GtkLabel" id="label3"> -                        <property name="visible">True</property> -                        <property name="label" translatable="yes">Commands/Interaction</property> -                      </widget> -                      <packing> -                        <property name="position">1</property> -                      </packing> -                    </child> -                  </widget> -                  <packing> -                    <property name="resize">False</property> -                    <property name="shrink">True</property> -                  </packing> -                </child> -              </widget> -              <packing> -                <property name="position">2</property> -              </packing> -            </child> -            <child> -              <widget class="GtkStatusbar" id="statusbar1"> -                <property name="visible">True</property> -                <property name="spacing">2</property> -              </widget> -              <packing> -                <property name="expand">False</property> -                <property name="position">3</property> -              </packing> -            </child> -          </widget> -        </child> -      </widget> -    </child> -  </widget> -</glade-interface> diff --git a/ui/main.c b/ui/main.c deleted file mode 100644 index da7e94c..0000000 --- a/ui/main.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots UI Test, main.c. - * - * GNU Robots is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNU Robots is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <gtk/gtkmain.h> - -#include "ui-window.h" - -int main(int argc, char* argv[]) -{ -  GtkWidget* window; - -  gtk_init(&argc, &argv); - -  window = ui_window_new(); - -  gtk_main(); - -  return 0; -} diff --git a/ui/ui-arena.c b/ui/ui-arena.c deleted file mode 100644 index 06c7bcc..0000000 --- a/ui/ui-arena.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots, ui-arena.c - * - * GNU Robots is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GNU Robots is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GNU Robots.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include "ui-arena.h" - -struct _UIArenaPrivate -{ -	int dummy; -}; - -#define UI_ARENA_GET_PRIVATE(obj) \ -    G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_ARENA, UIArenaPrivate) - -G_DEFINE_TYPE(UIArena, ui_arena, GTK_TYPE_DRAWING_AREA) - -GtkWidget *ui_arena_new(void) -{ -	return GTK_WIDGET(g_object_new(UI_TYPE_ARENA, NULL)); -} - -static void ui_arena_init(UIArena *arena) -{ -	gtk_widget_set_size_request(GTK_WIDGET(arena), 40*16,18*16); -} - -static void ui_arena_class_init(UIArenaClass *klass) -{ -	g_type_class_add_private(G_OBJECT_CLASS(klass), -		sizeof(UIArenaPrivate)); -} | 
