From ae3a780491b700be0258b1c2243c86cf10729fcc Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Sun, 3 Aug 2008 16:22:59 +0100 Subject: Add Gtk interface. Using a Vte for guile input. Signed-off-by: Bradley Smith --- Makefile.am | 2 +- configure.ac | 52 +- include/Makefile.am | 16 +- include/grobot.h | 6 +- include/ui-arena.h | 83 +++ include/ui-cmdwin.h | 60 ++ include/ui-window-private.h | 32 + include/ui-window.h | 61 ++ include/userinterface.h | 180 ------ src/Makefile.am | 20 +- src/grobot.c | 1449 +++++++++++++++++++++---------------------- src/main.c | 737 +++++++++++----------- src/ui-arena.c | 466 ++++++++++++++ src/ui-cmdwin.c | 87 +++ src/ui-window.c | 88 +++ src/userinterface.c | 736 ---------------------- ui/Makefile.am | 23 - ui/design.glade | 317 ---------- ui/main.c | 34 - ui/ui-arena.c | 45 -- ui/ui-arena.h | 58 -- ui/ui-cmdwin.c | 45 -- ui/ui-cmdwin.h | 58 -- ui/ui-window-private.h | 32 - ui/ui-window.c | 80 --- ui/ui-window.h | 58 -- 26 files changed, 1998 insertions(+), 2827 deletions(-) create mode 100644 include/ui-arena.h create mode 100644 include/ui-cmdwin.h create mode 100644 include/ui-window-private.h create mode 100644 include/ui-window.h delete mode 100644 include/userinterface.h create mode 100644 src/ui-arena.c create mode 100644 src/ui-cmdwin.c create mode 100644 src/ui-window.c delete mode 100644 src/userinterface.c delete mode 100644 ui/Makefile.am delete mode 100644 ui/design.glade delete mode 100644 ui/main.c delete mode 100644 ui/ui-arena.c delete mode 100644 ui/ui-arena.h delete mode 100644 ui/ui-cmdwin.c delete mode 100644 ui/ui-cmdwin.h delete mode 100644 ui/ui-window-private.h delete mode 100644 ui/ui-window.c delete mode 100644 ui/ui-window.h 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 . 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 . -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 #include -#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/include/ui-arena.h b/include/ui-arena.h new file mode 100644 index 0000000..2fee88f --- /dev/null +++ b/include/ui-arena.h @@ -0,0 +1,83 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots, ui-arena.h + * + * 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 . + */ + +#ifndef __UI_ARENA_H__ +#define __UI_ARENA_H__ + +#include + +#include "map.h" + +G_BEGIN_DECLS + +#define UI_TYPE_ARENA \ + ui_arena_get_type() +#define UI_ARENA(obj) \ + G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_ARENA, UIArena) +#define UI_ARENA_CLASS(klass) \ + G_TYPE_CHECK_CLASS_CAST(klass, UI_ARENA_TYPE, UIArenaClass) +#define IS_UI_ARENA(obj) \ + G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_ARENA) +#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; + +struct _UIArena +{ + GtkDrawingArea widget; + UIArenaPrivate* priv; +}; + +struct _UIArenaClass +{ + GtkDrawingAreaClass parent_class; +}; + +GType ui_arena_get_type(void) G_GNUC_CONST; + +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 + +#endif diff --git a/include/ui-cmdwin.h b/include/ui-cmdwin.h new file mode 100644 index 0000000..1c6196d --- /dev/null +++ b/include/ui-cmdwin.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots, ui-cmdwin.h + * + * 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 . + */ + +#ifndef __UI_CMDWIN_H__ +#define __UI_CMDWIN_H__ + +#include + +G_BEGIN_DECLS + +#define UI_TYPE_CMDWIN \ + ui_cmdwin_get_type() +#define UI_CMDWIN(obj) \ + G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_CMDWIN, UICmdWin) +#define UI_CMDWIN_CLASS(klass) \ + G_TYPE_CHECK_CLASS_CAST(klass, UI_CMDWIN_TYPE, UICmdWinClass) +#define IS_UI_CMDWIN(obj) \ + G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_CMDWIN) +#define IS_UI_CMDWIN_CLASS(klass) \ + G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_CMDWIN) + +typedef struct _UICmdWin UICmdWin; +typedef struct _UICmdWinClass UICmdWinClass; +typedef struct _UICmdWinPrivate UICmdWinPrivate; + +struct _UICmdWin +{ + GtkVBox widget; + UICmdWinPrivate* priv; +}; + +struct _UICmdWinClass +{ + GtkVBoxClass parent_class; +}; + +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 + +#endif diff --git a/include/ui-window-private.h b/include/ui-window-private.h new file mode 100644 index 0000000..cfb8b63 --- /dev/null +++ b/include/ui-window-private.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots UI Test, ui-window-private.h. + * + * 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 . + */ + +#ifndef __UI_WINDOW_PRIVATE_H__ +#define __UI_WINDOW_PRIVATE_H__ + +G_BEGIN_DECLS + +struct _UIWindowPrivate +{ + GtkWidget *cmdwin; + GtkWidget *arena; +}; + +G_END_DECLS + +#endif /* __UI_WINDOW_PRIVATE_H__ */ diff --git a/include/ui-window.h b/include/ui-window.h new file mode 100644 index 0000000..7b6c06f --- /dev/null +++ b/include/ui-window.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots UI Test, ui-window.h. + * + * 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 . + */ + +#ifndef __UI_WINDOW_H__ +#define __UI_WINDOW_H__ + +#include "map.h" + +#include + +G_BEGIN_DECLS + +#define UI_TYPE_WINDOW \ + ui_window_get_type() +#define UI_WINDOW(obj) \ + G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_WINDOW, UIWindow) +#define UI_WINDOW_CLASS(klass) \ + G_TYPE_CHECK_CLASS_CAST(klass, UI_WINDOW_TYPE, UIWindowClass) +#define IS_UI_WINDOW(obj) \ + G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_WINDOW) +#define IS_UI_WINDOW_CLASS(klass) \ + G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_WINDOW) + +typedef struct _UIWindow UIWindow; +typedef struct _UIWindowClass UIWindowClass; +typedef struct _UIWindowPrivate UIWindowPrivate; + +struct _UIWindow +{ + GtkWindow widget; + UIWindowPrivate* priv; +}; + +struct _UIWindowClass +{ + GtkWindowClass parent_class; +}; + +GType ui_window_get_type(void) G_GNUC_CONST; + +GtkWidget *ui_window_new(); +void ui_window_postinit(UIWindow *window, Map* map); + +G_END_DECLS + +#endif /* __UI_WINDOW_H__ */ 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 - * Copyright (C) 2008 Bradley Smith - * - * 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 . - */ - -#ifndef __USER_INTERFACE_H__ -#define __USER_INTERFACE_H__ - -#include -#include -#include -#include - -#include -/*#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 -#include -#include - 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 #include #include @@ -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; } diff --git a/src/main.c b/src/main.c index 16dfaf1..3e24e78 100644 --- a/src/main.c +++ b/src/main.c @@ -19,254 +19,255 @@ */ #include -#include /* for getopt */ -#include /* for strdup */ +#include /* for getopt */ +#include /* for strdup */ #include #include #include -#include /* for GNU getopt_long */ +#include /* 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 .\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 .\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 + * + * 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 . + */ + +#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 + +#include + +#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/src/ui-cmdwin.c b/src/ui-cmdwin.c new file mode 100644 index 0000000..71f7b53 --- /dev/null +++ b/src/ui-cmdwin.c @@ -0,0 +1,87 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots, ui-cmdwin.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 . + */ + +#include "ui-cmdwin.h" + +#include +#include + +#include +#include +#include + +struct _UICmdWinPrivate +{ + GtkWidget *vte; +}; + +#define UI_CMDWIN_GET_PRIVATE(obj) \ + G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_CMDWIN, UICmdWinPrivate) + +G_DEFINE_TYPE(UICmdWin, ui_cmdwin, GTK_TYPE_VBOX) + +GtkWidget *ui_cmdwin_new(void) +{ + return GTK_WIDGET(g_object_new(UI_TYPE_CMDWIN, NULL)); +} + +static void ui_cmdwin_init(UICmdWin *cmdwin) +{ + 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) +{ + 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/src/ui-window.c b/src/ui-window.c new file mode 100644 index 0000000..8758c64 --- /dev/null +++ b/src/ui-window.c @@ -0,0 +1,88 @@ +/* Copyright (C) 2008 Bradley Smith + * + * GNU Robots UI Test, ui-window.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 . + */ + +#include "ui-window.h" +#include "ui-window-private.h" + +#include "ui-cmdwin.h" +#include "ui-arena.h" + +#include "main.h" +#include "map.h" +#include "configs.h" + +#include + +#define UI_WINDOW_GET_PRIVATE(obj) \ + G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_WINDOW, UIWindowPrivate) + +G_DEFINE_TYPE(UIWindow, ui_window, GTK_TYPE_WINDOW) + +static void on_ui_window_destroy(GtkWidget *widget, gpointer data); + +GtkWidget *ui_window_new() +{ + return GTK_WIDGET(g_object_new(UI_TYPE_WINDOW, NULL)); +} + +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) +{ + window->priv = UI_WINDOW_GET_PRIVATE(window); + + 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(); + ui_arena_set_map(UI_ARENA(window->priv->arena), map); + + /* TODO: Add menu first etc */ + 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); + + gtk_widget_show(window->priv->cmdwin); + gtk_widget_show(window->priv->arena); + 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) +{ + g_type_class_add_private(G_OBJECT_CLASS(klass), + sizeof(UIWindowPrivate)); +} 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 - * Copyright (C) 2008 Bradley Smith - * - * 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 . - */ - -#include -#include -#include -#include -#include -#include "configs.h" -#include "userinterface.h" - -#include -#include - -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 -## -## 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 . - -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 @@ - - - - - - - - True - 2 - 2 - - - True - - - True - - - True - _File - True - - - True - - - True - gtk-new - True - True - - - - - True - gtk-open - True - True - - - - - True - gtk-save - True - True - - - - - True - gtk-save-as - True - True - - - - - True - - - - - True - gtk-quit - True - True - - - - - - - - - True - _Edit - True - - - True - - - True - gtk-cut - True - True - - - - - True - gtk-copy - True - True - - - - - True - gtk-paste - True - True - - - - - True - gtk-delete - True - True - - - - - - - - - True - _View - True - - - - - True - _Help - True - - - True - - - True - gtk-about - True - True - - - - - - - - - False - - - - - True - - - True - gtk-open - - - False - - - - - False - 1 - - - - - True - True - - - True - GDK_EXTENSION_EVENTS_ALL - 3 - 3 - - - True - GDK_EXTENSION_EVENTS_ALL - gtk-missing-image - 6 - - - - - False - True - - - - - True - - - True - 11 - - - True - - - True - True - True - GTK_RELIEF_NONE - False - 0 - - - True - gtk-media-play - - - - - False - - - - - True - True - True - GTK_RELIEF_NONE - False - 0 - - - True - gtk-media-next - - - - - False - 1 - - - - - False - - - - - True - 2 - - - True - 1 - Speed - GTK_JUSTIFY_RIGHT - - - False - - - - - True - True - 0 0 100 1 10 10 - GTK_POS_RIGHT - - - 1 - - - - - 1 - - - - - False - - - - - True - Commands/Interaction - - - 1 - - - - - False - True - - - - - 2 - - - - - True - 2 - - - False - 3 - - - - - - - - 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 - * - * 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 . - */ - -#include - -#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 - * - * 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 . - */ - -#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)); -} diff --git a/ui/ui-arena.h b/ui/ui-arena.h deleted file mode 100644 index 5277f54..0000000 --- a/ui/ui-arena.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots, ui-arena.h - * - * 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 . - */ - -#ifndef __UI_ARENA_H__ -#define __UI_ARENA_H__ - -#include - -G_BEGIN_DECLS - -#define UI_TYPE_ARENA \ - ui_arena_get_type() -#define UI_ARENA(obj) \ - G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_ARENA, UIArena) -#define UI_ARENA_CLASS(klass) \ - G_TYPE_CHECK_CLASS_CAST(klass, UI_ARENA_TYPE, UIArenaClass) -#define IS_UI_ARENA(obj) \ - G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_ARENA) -#define IS_UI_ARENA_CLASS(klass) \ - G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_ARENA) - -typedef struct _UIArena UIArena; -typedef struct _UIArenaClass UIArenaClass; -typedef struct _UIArenaPrivate UIArenaPrivate; - -struct _UIArena -{ - GtkDrawingArea widget; - UIArenaPrivate* priv; -}; - -struct _UIArenaClass -{ - GtkDrawingAreaClass parent_class; -}; - -GType ui_arena_get_type(void) G_GNUC_CONST; - -GtkWidget *ui_arena_new(void); - -G_END_DECLS - -#endif diff --git a/ui/ui-cmdwin.c b/ui/ui-cmdwin.c deleted file mode 100644 index b743687..0000000 --- a/ui/ui-cmdwin.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots, ui-cmdwin.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 . - */ - -#include "ui-cmdwin.h" - -struct _UICmdWinPrivate -{ - int dummy; -}; - -#define UI_CMDWIN_GET_PRIVATE(obj) \ - G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_CMDWIN, UICmdWinPrivate) - -G_DEFINE_TYPE(UICmdWin, ui_cmdwin, GTK_TYPE_VBOX) - -GtkWidget *ui_cmdwin_new(void) -{ - return GTK_WIDGET(g_object_new(UI_TYPE_CMDWIN, NULL)); -} - -static void ui_cmdwin_init(UICmdWin *cmdwin) -{ - gtk_widget_set_size_request(GTK_WIDGET(cmdwin), 40*16,200); -} - -static void ui_cmdwin_class_init(UICmdWinClass *klass) -{ - g_type_class_add_private(G_OBJECT_CLASS(klass), - sizeof(UICmdWinPrivate)); -} diff --git a/ui/ui-cmdwin.h b/ui/ui-cmdwin.h deleted file mode 100644 index c3bcf8a..0000000 --- a/ui/ui-cmdwin.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots, ui-cmdwin.h - * - * 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 . - */ - -#ifndef __UI_CMDWIN_H__ -#define __UI_CMDWIN_H__ - -#include - -G_BEGIN_DECLS - -#define UI_TYPE_CMDWIN \ - ui_cmdwin_get_type() -#define UI_CMDWIN(obj) \ - G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_CMDWIN, UICmdWin) -#define UI_CMDWIN_CLASS(klass) \ - G_TYPE_CHECK_CLASS_CAST(klass, UI_CMDWIN_TYPE, UICmdWinClass) -#define IS_UI_CMDWIN(obj) \ - G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_CMDWIN) -#define IS_UI_CMDWIN_CLASS(klass) \ - G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_CMDWIN) - -typedef struct _UICmdWin UICmdWin; -typedef struct _UICmdWinClass UICmdWinClass; -typedef struct _UICmdWinPrivate UICmdWinPrivate; - -struct _UICmdWin -{ - GtkVBox widget; - UICmdWinPrivate* priv; -}; - -struct _UICmdWinClass -{ - GtkVBoxClass parent_class; -}; - -GType ui_cmdwin_get_type(void) G_GNUC_CONST; - -GtkWidget *ui_cmdwin_new(void); - -G_END_DECLS - -#endif diff --git a/ui/ui-window-private.h b/ui/ui-window-private.h deleted file mode 100644 index cfb8b63..0000000 --- a/ui/ui-window-private.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots UI Test, ui-window-private.h. - * - * 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 . - */ - -#ifndef __UI_WINDOW_PRIVATE_H__ -#define __UI_WINDOW_PRIVATE_H__ - -G_BEGIN_DECLS - -struct _UIWindowPrivate -{ - GtkWidget *cmdwin; - GtkWidget *arena; -}; - -G_END_DECLS - -#endif /* __UI_WINDOW_PRIVATE_H__ */ diff --git a/ui/ui-window.c b/ui/ui-window.c deleted file mode 100644 index 27c49e9..0000000 --- a/ui/ui-window.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots UI Test, ui-window.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 . - */ - -#include "ui-window.h" -#include "ui-window-private.h" - -#include "ui-cmdwin.h" -#include "ui-arena.h" - -#include - -#define UI_WINDOW_GET_PRIVATE(obj) \ - G_TYPE_INSTANCE_GET_PRIVATE(obj, UI_TYPE_WINDOW, UIWindowPrivate) - -G_DEFINE_TYPE(UIWindow, ui_window, GTK_TYPE_WINDOW) - -static void on_ui_window_destroy(GtkWidget *widget, gpointer data); - -GtkWidget *ui_window_new(void) -{ - return GTK_WIDGET(g_object_new(UI_TYPE_WINDOW, NULL)); -} - -static void on_ui_window_destroy(GtkWidget *widget, gpointer data) -{ - gtk_widget_hide(widget); - gtk_main_quit(); -} - -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(); - 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); - - /* TODO: Add menu first etc */ - gtk_box_pack_start(GTK_BOX(vbox), vpaned, 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)); -} - -static void ui_window_class_init(UIWindowClass *klass) -{ - g_type_class_add_private(G_OBJECT_CLASS(klass), - sizeof(UIWindowPrivate)); -} diff --git a/ui/ui-window.h b/ui/ui-window.h deleted file mode 100644 index 450223b..0000000 --- a/ui/ui-window.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2008 Bradley Smith - * - * GNU Robots UI Test, ui-window.h. - * - * 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 . - */ - -#ifndef __UI_WINDOW_H__ -#define __UI_WINDOW_H__ - -#include - -G_BEGIN_DECLS - -#define UI_TYPE_WINDOW \ - ui_window_get_type() -#define UI_WINDOW(obj) \ - G_TYPE_CHECK_INSTANCE_CAST(obj, UI_TYPE_WINDOW, UIWindow) -#define UI_WINDOW_CLASS(klass) \ - G_TYPE_CHECK_CLASS_CAST(klass, UI_WINDOW_TYPE, UIWindowClass) -#define IS_UI_WINDOW(obj) \ - G_TYPE_CHECK_INSTANCE_TYPE(obj, UI_TYPE_WINDOW) -#define IS_UI_WINDOW_CLASS(klass) \ - G_TYPE_CHECK_CLASS_TYPE(klass, UI_TYPE_WINDOW) - -typedef struct _UIWindow UIWindow; -typedef struct _UIWindowClass UIWindowClass; -typedef struct _UIWindowPrivate UIWindowPrivate; - -struct _UIWindow -{ - GtkWindow widget; - UIWindowPrivate* priv; -}; - -struct _UIWindowClass -{ - GtkWindowClass parent_class; -}; - -GType ui_window_get_type(void) G_GNUC_CONST; - -GtkWidget *ui_window_new(void); - -G_END_DECLS - -#endif /* __UI_WINDOW_H__ */ -- cgit v1.1