diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | include/userinterface.h | 169 | ||||
-rw-r--r-- | lib/Makefile.am | 52 | ||||
-rw-r--r-- | lib/cursesplugin.c | 596 | ||||
-rw-r--r-- | lib/cursesplugin.h | 67 | ||||
-rw-r--r-- | lib/textplugin.c | 460 | ||||
-rw-r--r-- | lib/textplugin.h | 61 | ||||
-rw-r--r-- | lib/x11plugin.c | 834 | ||||
-rw-r--r-- | lib/x11plugin.h | 104 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/main.c | 112 | ||||
-rw-r--r-- | src/userinterface.c | 796 | ||||
-rw-r--r-- | xpm/Makefile.am (renamed from lib/xpm/Makefile.am) | 0 | ||||
-rw-r--r-- | xpm/baddie.xpm (renamed from lib/xpm/baddie.xpm) | 0 | ||||
-rw-r--r-- | xpm/food.xpm (renamed from lib/xpm/food.xpm) | 0 | ||||
-rw-r--r-- | xpm/prize.xpm (renamed from lib/xpm/prize.xpm) | 0 | ||||
-rw-r--r-- | xpm/robot.xpm (renamed from lib/xpm/robot.xpm) | 0 | ||||
-rw-r--r-- | xpm/robot_east.xpm (renamed from lib/xpm/robot_east.xpm) | 0 | ||||
-rw-r--r-- | xpm/robot_north.xpm (renamed from lib/xpm/robot_north.xpm) | 0 | ||||
-rw-r--r-- | xpm/robot_south.xpm (renamed from lib/xpm/robot_south.xpm) | 0 | ||||
-rw-r--r-- | xpm/robot_west.xpm (renamed from lib/xpm/robot_west.xpm) | 0 | ||||
-rw-r--r-- | xpm/space.xpm (renamed from lib/xpm/space.xpm) | 0 | ||||
-rw-r--r-- | xpm/statusbar.xpm (renamed from lib/xpm/statusbar.xpm) | 0 | ||||
-rw-r--r-- | xpm/wall.xpm (renamed from lib/xpm/wall.xpm) | 0 |
26 files changed, 749 insertions, 2519 deletions
@@ -1,3 +1,9 @@ +2008-05-05 Bradley Smith <brad@brad-smith.co.uk> + + * lib/* include/userinterface.h src/userinterface src/main.c + configure.ac src/Makefile.am: + Scrap plug-able interfaces in preparation for GTK GUI. + 2008-03-09 Bradley Smith <brad@brad-smith.co.uk> * src/api.c: diff --git a/Makefile.am b/Makefile.am index 6c0ec25..c40dc2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -17,7 +17,7 @@ ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA AUTOMAKE_OPTIONS = 1.8.5 -SUBDIRS = contrib doc include lib maps scheme src +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 a4714e7..0cc4ab0 100644 --- a/configure.ac +++ b/configure.ac @@ -169,8 +169,7 @@ AC_CONFIG_FILES([Makefile contrib/Makefile doc/Makefile include/Makefile - lib/Makefile - lib/xpm/Makefile + xpm/Makefile maps/Makefile scheme/Makefile src/Makefile diff --git a/include/userinterface.h b/include/userinterface.h index c67d364..e8c7665 100644 --- a/include/userinterface.h +++ b/include/userinterface.h @@ -1,11 +1,11 @@ /* Copyright (C) 1998 Jim Hall <jhall1@isd.net> * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> * - * GNU Robots game engine. This is the header file for user_interface module + * GNU Robots game engine. * - * GNU Robots is free software: you can redistribute it and/or modify + * 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 + * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GNU Robots is distributed in the hope that it will be useful, @@ -21,121 +21,87 @@ #ifndef __USER_INTERFACE_H__ #define __USER_INTERFACE_H__ +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/xpm.h> +#include <X11/keysym.h> + #include <glib-object.h> +/*#include "userinterface.h"*/ #include "map.h" G_BEGIN_DECLS -#define G_TYPE_USER_INTERFACE \ - user_interface_get_type() -#define G_IS_USER_INTERFACE(obj) \ - G_TYPE_CHECK_INSTANCE_TYPE(obj, G_TYPE_USER_INTERFACE) -#define G_IS_USER_INTERFACE_CLASS(klass)\ - G_TYPE_CHECK_CLASS_TYPE(klass, G_TYPE_USER_INTERFACE) -#define USER_INTERFACE_GET_CLASS(obj) \ - G_TYPE_INSTANCE_GET_INTERFACE(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) +#define G_TYPE_USER_INTERFACE user_interface_get_type() +#define G_IS_USER_INTERFACE(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + G_TYPE_USER_INTERFACE) +#define G_IS_USER_INTERFACE_CLASS(klass) G_TYPE_CHECK_CLASS_TYPE ((klass), \ + G_TYPE_USER_INTERFACE) +#define USER_INTERFACE_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS ((obj), \ + G_TYPE_USER_INTERFACE, \ + UserInterfaceClass) +#define USER_INTERFACE(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + G_TYPE_USER_INTERFACE, UserInterface) +#define USER_INTERFACE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST ((klass), \ + G_TYPE_USER_INTERFACE, \ + UserInterfaceClass) typedef struct _UserInterface UserInterface; typedef struct _UserInterfaceClass UserInterfaceClass; +struct _UserInterface { + GObject object; + Map *map; + MapSize *map_size; + + Display *dpy; + Window x_win; + Atom wm_delete_win; + Atom wm_protocols; + GC gc; + GC buf_gc; + Font text; + +#ifdef USE_MITSHM +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/extensions/XShm.h> + XShmSegmentInfo shm_info; + guchar use_mitshm = 1; +#endif + + gint win_width; + gint win_height; + + Pixmap win_buf; + + XImage *win_bufi; + XImage *statusbar; + XImage *space; + XImage *food; + XImage *wall; + XImage *prize; + XImage *baddie; + XImage *robotDirs[4]; + XImage *robotPix; +}; + struct _UserInterfaceClass { - GTypeInterface parent; - - 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); + GObjectClass parent_class; }; /* normal GObject stuff */ -GType user_interface_get_type (void); +GType user_interface_get_type (void); + +UserInterface* user_interface_new (Map* map); -/* functions we want implemented by the implementers of our interface */ 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, @@ -207,10 +173,9 @@ void user_interface_get_string (UserInterface *ui, gchar *buff, gint len); -typedef UserInterface * (* UserInterfaceInitFunc) (Map *map, - GType parent_type); -#define USER_INTERFACE_INIT_FUNCTION "user_interface_new" +/* 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__*/ +#endif /* __USER_INTERFACE_H__ */ diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index 0712921..0000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -## Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> -## -## lib/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 2 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, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -SUBDIRS = xpm - -if USE_CURSES -CURSES_PLUGIN=libgrobots-curses.la -else -CURSES_PLUGIN= -endif - -if USE_X11 -X11_PLUGIN=libgrobots-x11.la -else -X11_PLUGIN= -endif - -INCLUDES = $(GLIB2_CFLAGS) $(CURSES_CFLAGS) $(X_FLAGS) -I$(top_builddir)/include $(READLINE_CFLAGS) - -pkglib_LTLIBRARIES = libgrobots-text.la $(CURSES_PLUGIN) $(X11_PLUGIN) - -libgrobots_text_la_SOURCES = textplugin.c -libgrobots_text_la_LDFLAGS = -module -avoid-version -libgrobots_text_la_LIBADD = $(GLIB2_LIBS) $(READLINE_LIBS) - -libgrobots_curses_la_SOURCES = cursesplugin.c -libgrobots_curses_la_LDFLAGS = -module -avoid-version -libgrobots_curses_la_LIBADD = $(GLIB2_LIBS) $(CURSES_LIBS) - -libgrobots_x11_la_SOURCES = x11plugin.c -libgrobots_x11_la_LDFLAGS = -module -avoid-version -libgrobots_x11_la_LIBADD = $(GLIB2_LIBS) $(X_LIBS) $(READLINE_LIBS) - -EXTRA_DIST =\ - cursesplugin.h \ - textplugin.h \ - x11plugin.h diff --git a/lib/cursesplugin.c b/lib/cursesplugin.c deleted file mode 100644 index 3fb6e47..0000000 --- a/lib/cursesplugin.c +++ /dev/null @@ -1,596 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <glib.h> -#include <stdio.h> -#include "configs.h" -#include "cursesplugin.h" - -enum -{ - ARG_0, - ARG_MAP -}; - -GType _curses_plugin_type = 0; -static GType _parent_type = 0; - -static void curses_plugin_class_init (CursesPluginClass * klass); -static void curses_plugin_init (GObject * object); -static void curses_plugin_interface_init (gpointer g_iface, gpointer iface_data); - -static GObject * curses_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); - -static void curses_plugin_finalize (GObject * object); -static void curses_plugin_dispose (GObject * object); - -static void curses_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void curses_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -inline void curses_plugin_update_status (CursesPlugin *curses, - const gchar *s, - glong energy, - glong score, - glong shields); - -static GObjectClass *parent_class = NULL; - -GType -curses_plugin_get_type (void) -{ - if (!_curses_plugin_type) { - static const GTypeInfo object_info = { - sizeof (CursesPluginClass), - NULL, - NULL, - (GClassInitFunc) curses_plugin_class_init, - NULL, - NULL, - sizeof (CursesPlugin), - 0, - (GInstanceInitFunc) curses_plugin_init, - NULL - }; - - static const GInterfaceInfo interface_info = { - (GInterfaceInitFunc) curses_plugin_interface_init, - NULL, - NULL - }; - - _curses_plugin_type = - g_type_register_static (G_TYPE_OBJECT, - "CursesPlugin", - &object_info, - 0); - - g_type_add_interface_static (_curses_plugin_type, - _parent_type, - &interface_info); - } - - return _curses_plugin_type; -} - -static void -curses_plugin_class_init (CursesPluginClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - gobject_class->constructor = curses_plugin_constructor; - gobject_class->set_property = curses_plugin_set_property; - gobject_class->get_property = curses_plugin_get_property; - gobject_class->dispose = curses_plugin_dispose; - gobject_class->finalize = curses_plugin_finalize; - - g_object_class_override_property (gobject_class, ARG_MAP, "map"); -} - -static void -curses_plugin_init (GObject * object) -{ - CursesPlugin *curses = CURSES_PLUGIN (object); - - curses->map = NULL; - curses->map_size = NULL; -} - -static GObject * -curses_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GObject *object; - CursesPlugin *curses; - - /* Chain up to the parent first */ - object = parent_class->constructor (type, n_construct_properties, construct_properties); - - curses = CURSES_PLUGIN (object); - - /* Initialize curses mode */ - curses->win = initscr (); - - cbreak (); - noecho (); - - scrollok (curses->win, TRUE); /* Put scrolling on */ - setscrreg (LINES - 2, LINES - 1); /* Where to scroll */ - - /* clearok (stdscr, TRUE); */ - nonl (); - intrflush (stdscr, FALSE); - keypad (stdscr, TRUE); - - if (has_colors()) { - start_color(); - - /* - * Simple color assignment, often all we need. - **/ - init_pair (COLOR_BLACK, COLOR_BLACK, COLOR_BLACK); - init_pair (COLOR_GREEN, COLOR_GREEN, COLOR_BLACK); - init_pair (COLOR_RED, COLOR_RED, COLOR_BLACK); - init_pair (COLOR_CYAN, COLOR_CYAN, COLOR_BLACK); - init_pair (COLOR_WHITE, COLOR_WHITE, COLOR_BLACK); - init_pair (COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK); - init_pair (COLOR_BLUE, COLOR_BLUE, COLOR_BLACK); - init_pair (COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK); - } - - clear (); - refresh (); - curses->errors = 0; - - return object; -} - -static void -curses_plugin_dispose (GObject * object) -{ - CursesPlugin *curses = CURSES_PLUGIN (object); - - if (curses->map != NULL) { - g_object_unref (G_OBJECT (curses->map)); - - if (curses->map_size != NULL) { - g_free (curses->map_size); - } - } - - parent_class->dispose (object); -} - -/* finalize is called when the object has to free its resources */ -static void -curses_plugin_finalize (GObject * object) -{ - /* End curses mode */ - endwin (); - - parent_class->finalize (object); -} - -static void -curses_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - CursesPlugin *curses; - GObject *obj; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_CURSES_PLUGIN (object)); - - curses = CURSES_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - obj = g_value_get_object (value); - g_return_if_fail (obj != NULL); - - if (curses->map != NULL) { - g_object_unref (curses->map); - } - - curses->map = MAP (g_object_ref (obj)); - - if (curses->map_size != NULL) { - g_free (curses->map_size); - } - - g_object_get (G_OBJECT (curses->map), - "size", &curses->map_size, - NULL); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -curses_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - CursesPlugin *curses; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_CURSES_PLUGIN (object)); - - curses = CURSES_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - g_value_set_object (value, g_object_ref (G_OBJECT (curses->map))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -UserInterface * -user_interface_new (Map *map, GType parent_type) -{ - CursesPlugin *curses; - - g_return_val_if_fail (map != NULL, NULL); - g_return_val_if_fail (_parent_type != 0 || parent_type != 0, NULL); - - if (!_parent_type) { - _parent_type = parent_type; - } - - curses = CURSES_PLUGIN (g_object_new (curses_plugin_get_type (), - "map", map, - NULL)); - if (curses->errors) { - g_object_unref (G_OBJECT (curses)); - return NULL; - } - - return USER_INTERFACE (curses); -} - -inline void curses_plugin_add_thing (CursesPlugin *curses, - gint x, - gint y, - gint thing) -{ - gshort color; - - /* Highlight the unusual chars */ - if (thing == '?') { - standout (); - } - - switch (thing) { - case SPACE: - color = COLOR_PAIR (COLOR_BLACK); - break; - case FOOD: - color = COLOR_PAIR (COLOR_GREEN); - break; - case PRIZE: - color = COLOR_PAIR (COLOR_YELLOW); - break; - case WALL: - color = COLOR_PAIR (COLOR_WHITE); - break; - case BADDIE: - color = COLOR_PAIR (COLOR_RED); - break; - case ROBOT: - color = COLOR_PAIR (COLOR_BLUE); - break; - default: - /* What here? */ - color = COLOR_PAIR (COLOR_BLACK); - } - - mvaddch (y, x, thing | color); - - if (thing == '?') { - standend (); - } - - redrawwin (curses->win); -} - -inline void curses_plugin_draw (CursesPlugin *curses) -{ - gshort color; - gint i, j; - - /* Draw the map for the GNU Robots game. */ - - for (j = 0; j < curses->map_size->num_rows; j++) { - for (i = 0; i < curses->map_size->num_cols; i++) { - /* Special cases */ - - switch (MAP_GET_OBJECT (curses->map, i, j)) { - case '\0': - /* Highlight the unusual chars */ - if (MAP_GET_OBJECT (curses->map, i, j) == '?') { - standout (); - } - color = COLOR_PAIR (COLOR_BLACK); - break; - case SPACE: - color = COLOR_PAIR (COLOR_BLACK); - break; - case FOOD: - color = COLOR_PAIR (COLOR_GREEN); - break; - case PRIZE: - color = COLOR_PAIR (COLOR_YELLOW); - break; - case WALL: - color = COLOR_PAIR (COLOR_WHITE); - break; - case BADDIE: - color = COLOR_PAIR (COLOR_RED); - break; - case ROBOT: - color = COLOR_PAIR (COLOR_BLUE); - break; - default: - /* What here? */ - color = COLOR_PAIR (COLOR_BLACK); - break; - } /* switch */ - - mvaddch (j, i, MAP_GET_OBJECT (curses->map, i, j) | color); - - if (MAP_GET_OBJECT (curses->map, i, j) == '?') { - standend (); - } - } /* for i */ - } /* for j */ - - redrawwin (curses->win); -} - -inline void curses_plugin_move_robot (CursesPlugin *curses, - gint from_x, - gint from_y, - gint to_x, - gint to_y, - gint cdir, - glong energy, - glong score, - glong shields) -{ - /* Clear previous tile */ - - mvaddch (from_y, from_x, ' ' | COLOR_PAIR (COLOR_BLACK)); - - standout (); - switch (cdir) { - case NORTH: - mvaddch (to_y, to_x, '^' | COLOR_PAIR (COLOR_BLUE)); - break; - case EAST: - mvaddch (to_y, to_x, '>' | COLOR_PAIR (COLOR_BLUE)); - break; - case SOUTH: - mvaddch (to_y, to_x, 'v' | COLOR_PAIR (COLOR_BLUE)); - break; - case WEST: - mvaddch (to_y, to_x, '<' | COLOR_PAIR (COLOR_BLUE)); - break; - } - - standend (); - refresh (); - - g_usleep (USLEEP_TIME); -} - -/* function to animate the robot */ -inline void curses_plugin_robot_smell (CursesPlugin *curses, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields) -{ - curses_plugin_update_status (curses, "robot smells...", energy, score, shields); -} - -inline void curses_plugin_robot_zap (CursesPlugin *curses, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - curses_plugin_update_status (curses, "robot fires his little gun...", energy, score, shields); -} - -inline void curses_plugin_robot_feel (CursesPlugin *curses, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - curses_plugin_update_status (curses, "robot feels for a thing...", energy, score, shields); -} - -inline void curses_plugin_robot_grab (CursesPlugin *curses, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - curses_plugin_update_status (curses, "robot grabs thing...", energy, score, shields); -} - -inline void curses_plugin_robot_look (CursesPlugin *curses, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - curses_plugin_update_status (curses, "robot looks for a thing...", energy, score, shields); -} - -/* function to get data from user */ -inline void curses_plugin_get_string (CursesPlugin *curses, - gchar *prompt, - gchar *buff, - gint len) -{ - mvaddstr (LINES - 2, 0, prompt); - refresh (); - - echo (); - getnstr (buff, len); - noecho (); - - move (LINES - 2, 0); - clrtoeol (); - refresh (); -} - -inline void curses_plugin_update_status (CursesPlugin *curses, - const gchar *s, - glong energy, - glong score, - glong shields) -{ - /* print on mode line (y=LINES-1) */ - mvaddstr (LINES - 1, 1, s); - refresh (); - - /* Sleep, then erase it */ - napms (SLEEP_TIME); - - move (LINES - 1, 1); - clrtoeol (); - refresh (); -} - -static void curses_plugin_interface_init (gpointer g_iface, gpointer iface_data) -{ - UserInterfaceClass *klass = (UserInterfaceClass *)g_iface; - - klass->user_interface_add_thing = (void (*) (UserInterface *ui, - gint x, - gint y, - gint thing)) - curses_plugin_add_thing; - - klass->user_interface_draw = (void (*) (UserInterface *ui)) curses_plugin_draw; - klass->user_interface_update_status = (void (*) (UserInterface *ui, - const gchar *s, - glong energy, - glong score, - glong shields)) - curses_plugin_update_status; - klass->user_interface_move_robot = (void (*) (UserInterface *ui, - gint from_x, - gint from_y, - gint to_x, - gint to_y, - gint cdir, - glong energy, - glong score, - glong shields)) - curses_plugin_move_robot; - klass->user_interface_robot_smell = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields)) - curses_plugin_robot_smell; - klass->user_interface_robot_zap = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - curses_plugin_robot_zap; - klass->user_interface_robot_feel = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - curses_plugin_robot_grab; - klass->user_interface_robot_grab = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - curses_plugin_robot_grab; - klass->user_interface_robot_look = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - curses_plugin_robot_look; - klass->user_interface_get_string = (void (*) (UserInterface *ui, - gchar *prompt, - gchar *buff, - gint len)) - curses_plugin_get_string; -} diff --git a/lib/cursesplugin.h b/lib/cursesplugin.h deleted file mode 100644 index 3f6beba..0000000 --- a/lib/cursesplugin.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __CURSES_PLUGIN_H__ -#define __CURSES_PLUGIN_H__ - -#include <glib-object.h> -#include <curses.h> -#include <stdio.h> -#include <stdlib.h> /* for sleep */ -#include "configs.h" -#include "userinterface.h" -#include "map.h" - -G_BEGIN_DECLS - -extern GType _curses_plugin_type; - -typedef struct _CursesPlugin CursesPlugin; - -struct _CursesPlugin { - GObject object; - Map *map; - MapSize *map_size; - gint errors; - - WINDOW *win; -}; - -typedef struct _CursesPluginClass CursesPluginClass; - -struct _CursesPluginClass { - GObjectClass parent_class; -}; - -#define G_TYPE_CURSES_PLUGIN (_curses_plugin_type) -#define G_IS_CURSES_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_CURSES_PLUGIN)) -#define G_IS_CURSES_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_CURSES_PLUGIN)) -#define CURSES_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_CURSES_PLUGIN, CursesPluginClass)) -#define CURSES_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_CURSES_PLUGIN, CursesPlugin)) -#define CURSES_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_CURSES_PLUGIN, CursesPluginClass)) - -/* normal GObject stuff */ -GType curses_plugin_get_type (void); - -CursesPlugin* curses_plugin_new (void); - -G_END_DECLS - -#endif /* __CURSES_PLUGIN_H__*/ diff --git a/lib/textplugin.c b/lib/textplugin.c deleted file mode 100644 index 75a6800..0000000 --- a/lib/textplugin.c +++ /dev/null @@ -1,460 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <glib.h> -#include <glib/gprintf.h> -#include <stdio.h> -#include <stdlib.h> -#include "configs.h" -#include "textplugin.h" - -#include <readline.h> -#include <history.h> - -enum -{ - ARG_0, - ARG_MAP -}; - -GType _text_plugin_type = 0; -static GType _parent_type = 0; - -static void text_plugin_class_init (TextPluginClass * klass); -static void text_plugin_init (GObject * object); -static void text_plugin_interface_init (gpointer g_iface, gpointer iface_data); - -static GObject * text_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); - -static void text_plugin_finalize (GObject * object); -static void text_plugin_dispose (GObject * object); - -static void text_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void text_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -inline void text_plugin_update_status (TextPlugin *text, - const gchar *s, - glong energy, - glong score, - glong shields); - -static GObjectClass *parent_class = NULL; - -/* For translation of directions to strings */ -static gchar *str_dir[] = { "North", "East", "South", "West" }; - -GType -text_plugin_get_type (void) -{ - if (!_text_plugin_type) { - static const GTypeInfo object_info = { - sizeof (TextPluginClass), - NULL, - NULL, - (GClassInitFunc) text_plugin_class_init, - NULL, - NULL, - sizeof (TextPlugin), - 0, - (GInstanceInitFunc) text_plugin_init, - NULL - }; - - static const GInterfaceInfo interface_info = { - (GInterfaceInitFunc) text_plugin_interface_init, - NULL, - NULL - }; - - _text_plugin_type = - g_type_register_static (G_TYPE_OBJECT, - "TextPlugin", - &object_info, - 0); - - g_type_add_interface_static (_text_plugin_type, - _parent_type, - &interface_info); - } - - return _text_plugin_type; -} - -static void -text_plugin_class_init (TextPluginClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - gobject_class->constructor = text_plugin_constructor; - gobject_class->set_property = text_plugin_set_property; - gobject_class->get_property = text_plugin_get_property; - gobject_class->dispose = text_plugin_dispose; - gobject_class->finalize = text_plugin_finalize; - - g_object_class_override_property (gobject_class, ARG_MAP, "map"); -} - -static void -text_plugin_init (GObject * object) -{ - TextPlugin *text = TEXT_PLUGIN (object); - - text->map = NULL; - text->map_size = NULL; -} - -static GObject * -text_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GObject *object; - - /* Chain up to the parent first */ - object = parent_class->constructor (type, n_construct_properties, construct_properties); - - g_printf ("GNU Robots starting..\n"); - - return object; -} - -static void -text_plugin_dispose (GObject * object) -{ - TextPlugin *text = TEXT_PLUGIN (object); - - if (text->map != NULL) { - g_object_unref (G_OBJECT (text->map)); - - if (text->map_size != NULL) { - g_free (text->map_size); - } - } - - parent_class->dispose (object); -} - -/* finalize is called when the object has to free its resources */ -static void -text_plugin_finalize (GObject * object) -{ - g_printf ("GNU Robots done.\n"); - - parent_class->finalize (object); -} - -static void -text_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - TextPlugin *text; - GObject *obj; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_TEXT_PLUGIN (object)); - - text = TEXT_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - obj = g_value_get_object (value); - g_return_if_fail (obj != NULL); - - if (text->map != NULL) { - g_object_unref (text->map); - } - - text->map = MAP (g_object_ref (obj)); - - if (text->map_size != NULL) { - g_free (text->map_size); - } - - g_object_get (G_OBJECT (text->map), - "size", &text->map_size, - NULL); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -text_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - TextPlugin *text; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_TEXT_PLUGIN (object)); - - text = TEXT_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - g_value_set_object (value, g_object_ref (G_OBJECT (text->map))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -UserInterface * -user_interface_new (Map *map, GType parent_type) -{ - TextPlugin *text; - - g_return_val_if_fail (map != NULL, NULL); - g_return_val_if_fail (_parent_type != 0 || parent_type != 0, NULL); - - if (!_parent_type) { - _parent_type = parent_type; - } - - text = TEXT_PLUGIN (g_object_new (text_plugin_get_type (), - "map", map, - NULL)); - if (text->errors) { - g_object_unref (G_OBJECT (text)); - return NULL; - } - - return USER_INTERFACE (text); -} - -inline void text_plugin_add_thing (TextPlugin *text, - gint x, - gint y, - gint thing) -{ - g_printf ("thing `%c' added at %d,%d\n", thing, x, y); -} - -inline void text_plugin_draw (TextPlugin *text) -{ - gint i, j; - - for (j = 0; j < text->map_size->num_rows; j++) { - for (i = 0; i < text->map_size->num_cols; i++) { - g_printf ("thing `%c' added at %d,%d\n", MAP_GET_OBJECT (text->map, i, j), i, j); - } - } -} - -inline void text_plugin_move_robot (TextPlugin *text, - gint from_x, - gint from_y, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields) -{ - g_printf ("robot now at %d,%d facing %s\n", x, y, str_dir[cdir]); -} - -/* function to animate the robot */ -inline void text_plugin_robot_smell (TextPlugin *text, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields) -{ - g_printf ("the robot sniffs..\n"); -} - -inline void text_plugin_robot_zap (TextPlugin *text, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - g_printf ("robot fires gun at space %d,%d\n", x_to, y_to); -} - -inline void text_plugin_robot_feel (TextPlugin *text, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - g_printf ("robot feels space %d,%d\n", x_to, y_to); -} - -inline void text_plugin_robot_grab (TextPlugin *text, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - g_printf ("robot grabs for space %d,%d\n", x_to, y_to); -} - -inline void text_plugin_robot_look (TextPlugin *text, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - g_printf ("robot looks towards %s from %d,%d\n", str_dir[cdir], x, y); -} - -/* function to get data from user */ -inline void text_plugin_get_string (TextPlugin *text, - 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); -} - -inline void text_plugin_update_status (TextPlugin *text, - const gchar *s, - glong energy, - glong score, - glong shields) -{ - puts (s); -} - -static void text_plugin_interface_init (gpointer g_iface, gpointer iface_data) -{ - UserInterfaceClass *klass = (UserInterfaceClass *)g_iface; - - klass->user_interface_add_thing = (void (*) (UserInterface *ui, - gint x, - gint y, - gint thing)) - text_plugin_add_thing; - - klass->user_interface_draw = (void (*) (UserInterface *ui)) text_plugin_draw; - klass->user_interface_update_status = (void (*) (UserInterface *ui, - const gchar *s, - glong energy, - glong score, - glong shields)) - text_plugin_update_status; - klass->user_interface_move_robot = (void (*) (UserInterface *ui, - gint from_x, - gint from_y, - gint to_x, - gint to_y, - gint cdir, - glong energy, - glong score, - glong shields)) - text_plugin_move_robot; - klass->user_interface_robot_smell = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields)) - text_plugin_robot_smell; - klass->user_interface_robot_zap = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - text_plugin_robot_zap; - klass->user_interface_robot_feel = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - text_plugin_robot_grab; - klass->user_interface_robot_grab = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - text_plugin_robot_grab; - klass->user_interface_robot_look = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - text_plugin_robot_look; - klass->user_interface_get_string = (void (*) (UserInterface *ui, - gchar *prompt, - gchar *buff, - gint len)) - text_plugin_get_string; -} diff --git a/lib/textplugin.h b/lib/textplugin.h deleted file mode 100644 index f720b2a..0000000 --- a/lib/textplugin.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __TEXT_PLUGIN_H__ -#define __TEXT_PLUING_H__ - -#include <glib-object.h> -#include "userinterface.h" -#include "map.h" - -G_BEGIN_DECLS - -extern GType _text_plugin_type; - -typedef struct _TextPlugin TextPlugin; - -struct _TextPlugin { - GObject object; - Map *map; - MapSize *map_size; - gint errors; -}; - -typedef struct _TextPluginClass TextPluginClass; - -struct _TextPluginClass { - GObjectClass parent_class; -}; - -#define G_TYPE_TEXT_PLUGIN (_text_plugin_type) -#define G_IS_TEXT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_TEXT_PLUGIN)) -#define G_IS_TEXT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_TEXT_PLUGIN)) -#define TEXT_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_TEXT_PLUGIN, TextPluginClass)) -#define TEXT_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_TEXT_PLUGIN, TextPlugin)) -#define TEXT_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_TEXT_PLUGIN, TextPluginClass)) - -/* normal GObject stuff */ -GType text_plugin_get_type (void); - -TextPlugin* text_plugin_new (void); - -G_END_DECLS - -#endif /* __TEXT_PLUGIN_H__*/ diff --git a/lib/x11plugin.c b/lib/x11plugin.c deleted file mode 100644 index b46b5cd..0000000 --- a/lib/x11plugin.c +++ /dev/null @@ -1,834 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <glib.h> -#include <glib/gprintf.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "configs.h" -#include "x11plugin.h" - -#include <readline.h> -#include <history.h> - -static GType _parent_type = 0; -static void x11_plugin_interface_init(gpointer g_iface, - gpointer iface_data); - -G_DEFINE_TYPE_WITH_CODE(X11Plugin, x11_plugin, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(_parent_type, x11_plugin_interface_init)) - -enum -{ - ARG_0, - ARG_MAP -}; - -static GObject * x11_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties); - -static void x11_plugin_finalize (GObject * object); -static void x11_plugin_dispose (GObject * object); - -static void x11_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void x11_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static void put_tile (X11Plugin *x11, XImage *image, gint x, gint y); -static void put_winbuf (X11Plugin *x11); -static void setup_winbuf (X11Plugin *x11); -void create_image (X11Plugin *x11, gchar **data, XImage ** image); -inline void x11_plugin_update_status (X11Plugin *x11, const gchar *s, - glong energy, glong score, glong shields); - -static GObjectClass *parent_class = NULL; - -static void -x11_plugin_class_init (X11PluginClass * klass) -{ - GObjectClass *gobject_class; - - gobject_class = (GObjectClass *) klass; - - parent_class = g_type_class_ref (G_TYPE_OBJECT); - - gobject_class->constructor = x11_plugin_constructor; - gobject_class->set_property = x11_plugin_set_property; - gobject_class->get_property = x11_plugin_get_property; - gobject_class->dispose = x11_plugin_dispose; - gobject_class->finalize = x11_plugin_finalize; - - g_object_class_override_property (gobject_class, ARG_MAP, "map"); -} - -static void -x11_plugin_init (X11Plugin* x11) -{ - x11->map = NULL; - x11->map_size = NULL; -} - -static GObject * -x11_plugin_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - /* Initialize X11 */ - GObject *object; - X11Plugin *x11; -#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); - - x11 = X11_PLUGIN (object); - - XInitThreads(); - - if ((x11->dpy = XOpenDisplay ("")) == NULL) { - g_printf ("Couldn't open the X Server Display!\n"); - exit (1); /* Exit nicely isn't needed yet, and causes segfault */ - } - - x11->wm_delete_win = XInternAtom (x11->dpy, "WM_DELETE_WINDOW", False); - - x11->win_width = x11->map_size->num_cols * TILE_SIZE; - x11->win_height = x11->map_size->num_rows * TILE_SIZE + 32; - x11->x_win = XCreateSimpleWindow (x11->dpy, DefaultRootWindow (x11->dpy), - 0, 0, x11->win_width, x11->win_height, 0, 0, 0); - - XSetWMProtocols (x11->dpy, x11->x_win, &(x11->wm_delete_win), 1); - - x11->wm_protocols = XInternAtom(x11->dpy, "WM_PROTOCOLS", False); - - XStoreName (x11->dpy, x11->x_win, "GNU Robots"); - - classhint.res_name = "robots"; - classhint.res_class = "Robots"; - XSetClassHint (x11->dpy, x11->x_win, &classhint); - - /* XSetCommand() seems to segfault... */ - - wmhints.input = True; - wmhints.flags = InputHint; - XSetWMHints (x11->dpy, x11->x_win, &wmhints); - - XSelectInput (x11->dpy, x11->x_win, - ExposureMask | KeyPressMask | KeyReleaseMask | StructureNotifyMask - | FocusChangeMask); - - XMapWindow (x11->dpy, x11->x_win); - - x11->text = XLoadFont (x11->dpy, - "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*"); - values.font = x11->text; - values.foreground = WhitePixel (x11->dpy, DefaultScreen (x11->dpy)); - - x11->gc = XCreateGC (x11->dpy, x11->x_win, - GCFont | GCForeground, &values); - - create_image (x11, statusbar_xpm, &x11->statusbar); - create_image (x11, space_xpm, &x11->space); - create_image (x11, food_xpm, &x11->food); - create_image (x11, wall_xpm, &x11->wall); - create_image (x11, prize_xpm, &x11->prize); - create_image (x11, baddie_xpm, &x11->baddie); - create_image (x11, robot_north_xpm, &x11->robotDirs[0]); - create_image (x11, robot_east_xpm, &x11->robotDirs[1]); - create_image (x11, robot_south_xpm, &x11->robotDirs[2]); - create_image (x11, robot_west_xpm, &x11->robotDirs[3]); - create_image (x11, robot_xpm, &x11->robotPix); - - setup_winbuf (x11); - - /* update_status ("Welcome to GNU Robots"); */ - x11->errors = 0; - - return object; -} - -static void -x11_plugin_dispose (GObject * object) -{ - X11Plugin *x11; - x11 = X11_PLUGIN (object); - - if (x11->map != NULL) { - g_object_unref (G_OBJECT (x11->map)); - - if (x11->map_size != NULL) { - g_free (x11->map_size); - } - } - - parent_class->dispose (object); -} - -/* finalize is called when the object has to free its resources */ -static void -x11_plugin_finalize (GObject * object) -{ - X11Plugin *x11 = X11_PLUGIN (object); - - /* End X11 mode */ -#ifdef USE_MITSHM - if (use_mitshm) { - XShmDetach (x11->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 (x11->dpy, x11->x_win); - XUnloadFont (x11->dpy, x11->text); - - parent_class->finalize (object); -} - -static void -x11_plugin_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - X11Plugin *x11; - GObject *obj; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_X11_PLUGIN (object)); - - x11 = X11_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - obj = g_value_get_object (value); - g_return_if_fail (obj != NULL); - - if (x11->map != NULL) { - g_object_unref (x11->map); - } - - x11->map = MAP (g_object_ref (obj)); - - if (x11->map_size != NULL) { - g_free (x11->map_size); - } - - g_object_get (G_OBJECT (x11->map), - "size", &x11->map_size, - NULL); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -x11_plugin_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - X11Plugin *x11; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (G_IS_X11_PLUGIN (object)); - - x11 = X11_PLUGIN (object); - - switch (prop_id) { - case ARG_MAP: - g_value_set_object (value, g_object_ref (G_OBJECT (x11->map))); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -UserInterface * -user_interface_new (Map *map, GType parent_type) -{ - X11Plugin *x11; - - g_return_val_if_fail (map != NULL, NULL); - g_return_val_if_fail (_parent_type != 0 || parent_type != 0, NULL); - - if (!_parent_type) { - _parent_type = parent_type; - } - - x11 = X11_PLUGIN (g_object_new (x11_plugin_get_type (), - "map", map, - NULL)); - if (x11->errors) { - g_object_unref (G_OBJECT (x11)); - return NULL; - } - - return USER_INTERFACE (x11); -} - -/* note that hook_delete_thing(x,y) is the same as - hook_add_thing(x,y,space) */ -inline void x11_plugin_add_thing (X11Plugin *x11, - 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 (x11, x11->space, w_x, w_y); - break; - case FOOD: - put_tile (x11, x11->food, w_x, w_y); - break; - case PRIZE: - put_tile (x11, x11->prize, w_x, w_y); - break; - case WALL: - put_tile (x11, x11->wall, w_x, w_y); - break; - case BADDIE: - put_tile (x11, x11->baddie, w_x, w_y); - break; - case ROBOT: - put_tile (x11, x11->robotPix, w_x, w_y); - break; - default: - put_tile (x11, x11->wall, w_x, w_y); - break; - } - - put_winbuf (x11); - XFlush (x11->dpy); -} - -inline void x11_plugin_draw (X11Plugin *x11) -{ - gint i, j; - - /* Draw the map for the GNU Robots game. */ - for (j = 0; j < x11->map_size->num_rows; j++) { - for (i = 0; i < x11->map_size->num_cols; i++) { - /* Special cases */ - switch (MAP_GET_OBJECT (x11->map, i, j)) { - /* Add something for the ROBOT?? */ - case '\0': - put_tile (x11, x11->wall, i * TILE_SIZE, j * TILE_SIZE); - break; - case SPACE: - put_tile (x11, x11->space, i * TILE_SIZE, j * TILE_SIZE); - break; - case FOOD: - put_tile (x11, x11->food, i * TILE_SIZE, j * TILE_SIZE); - break; - case PRIZE: - put_tile (x11, x11->prize, i * TILE_SIZE, j * TILE_SIZE); - break; - case WALL: - put_tile (x11, x11->wall, i * TILE_SIZE, j * TILE_SIZE); - break; - case BADDIE: - put_tile (x11, x11->baddie, i * TILE_SIZE, j * TILE_SIZE); - break; - case ROBOT: - put_tile (x11, x11->robotPix, i * TILE_SIZE, j * TILE_SIZE); - break; - default: - put_tile (x11, x11->wall, i * TILE_SIZE, j * TILE_SIZE); - break; - } /* switch */ - } /* for i */ - } /* for j */ - - put_winbuf (x11); - XSync (x11->dpy, FALSE); -} - -inline void x11_plugin_move_robot (X11Plugin *x11, - 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); - - x11_plugin_update_status (x11, "robot moves..", energy, score, shields); - - /* Check if robot is moving withing a single box */ - if (distance == 0) { - put_tile (x11, x11->space, from_x * TILE_SIZE, from_y * TILE_SIZE); - put_tile (x11, x11->robotDirs[cdir], to_x * TILE_SIZE, to_y * TILE_SIZE); - - put_winbuf (x11); - XSync (x11->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 (x11, x11->space, from_x, from_y); - put_tile (x11, x11->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 (x11); - XSync (x11->dpy, False); - g_usleep (USLEEP_TIME / 16); - if (!ok) - break; - } - - g_usleep (USLEEP_TIME); -} - -/* hooks to animate the robot */ -inline void x11_plugin_robot_smell (X11Plugin *x11, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields) -{ - /* If we want to change the pic, do it here */ - x11_plugin_update_status (x11, "robot sniffs...", energy, score, shields); - g_usleep (USLEEP_TIME); -} - -inline void x11_plugin_robot_zap (X11Plugin *x11, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - x11_plugin_update_status (x11, "robot fires his little gun...", energy, score, shields); - g_usleep (USLEEP_TIME); -} - -inline void x11_plugin_robot_feel (X11Plugin *x11, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - x11_plugin_update_status (x11, "robot feels for a thing...", energy, score, shields); - g_usleep (USLEEP_TIME); -} - -inline void x11_plugin_robot_grab (X11Plugin *x11, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - x11_plugin_update_status (x11, "robot grabs thing...", energy, score, shields); - g_usleep (USLEEP_TIME); -} - -inline void x11_plugin_robot_look (X11Plugin *x11, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields) -{ - x11_plugin_update_status (x11, "robot looks for a thing...", energy, score, shields); - g_usleep (USLEEP_TIME); -} - -/* hooks to get/display data from/to user */ -inline void x11_plugin_get_string (X11Plugin *x11, - 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); -} - -inline void x11_update_status (X11Plugin *x11, - const gchar *s, - glong energy, - glong score, - glong shields) -{ - gchar status[20]; - gint x = 0; - - while (x < x11->win_width) { - XPutImage (x11->dpy, x11->win_buf, x11->buf_gc, x11->statusbar, 0, 0, x, x11->map_size->num_rows * TILE_SIZE, 96, - 32); - x = x + 96; - } - - XDrawString (x11->dpy, x11->win_buf, x11->gc, 3, x11->map_size->num_rows * TILE_SIZE + 16, s, strlen (s)); - - if (energy > -1) { - g_sprintf (status, "Robot Energy: %3ld", energy); - XDrawString (x11->dpy, x11->win_buf, x11->gc, 240, x11->map_size->num_rows * TILE_SIZE + 12, status, - strlen (status)); - } - - if (score > -1) { - g_sprintf (status, "Robot Score: %3ld", score); - XDrawString (x11->dpy, x11->win_buf, x11->gc, 240, x11->map_size->num_rows * TILE_SIZE + 25, status, - strlen (status)); - } - - if (shields > -1) { - g_sprintf (status, "Robot Shields: %3ld", shields); - XDrawString (x11->dpy, x11->win_buf, x11->gc, 480, x11->map_size->num_rows * TILE_SIZE + 12, status, - strlen (status)); - } -} - -inline void x11_plugin_update_status (X11Plugin *x11, - const gchar *s, - glong energy, - glong score, - glong shields) -{ - x11_update_status (x11, s, energy, score, shields); -} - -inline void x11_plugin_run(X11Plugin* x11) -{ - XEvent ev; - XClientMessageEvent* evt; - - while (TRUE) - { - XNextEvent (x11->dpy, &ev); - - switch (ev.type) - { - case KeyPress: - case KeyRelease: - switch (XKeycodeToKeysym (x11->dpy, ev.xkey.keycode, 0)) - { - case XK_Escape: - exit (0); - break; - } - case ClientMessage: - evt = (XClientMessageEvent*)&ev; - if (evt->message_type == x11->wm_protocols - && evt->data.l[0] == x11->wm_delete_win) - { - g_printf("Exited\n"); - exit(0); - } - break; - case Expose: - x11_plugin_draw(x11); - break; - } - } - - put_winbuf (x11); -} - -#ifdef USE_MITSHM -inline gint -shm_error_handler (X11Plugin *x11, Display * d, XErrorEvent * e) -{ - x11->use_mitshm = 0; - return 0; -} -#endif - -static void -setup_winbuf (X11Plugin *x11) -{ - XVisualInfo *matches; - XVisualInfo plate; - gint count; - guint depth; - XGCValues values; - Visual *vis; - - vis = DefaultVisualOfScreen (DefaultScreenOfDisplay (x11->dpy)); - plate.visualid = XVisualIDFromVisual (vis); - matches = XGetVisualInfo (x11->dpy, VisualIDMask, &plate, &count); - depth = matches[0].depth; - -#ifdef USE_MITSHM - x11->use_mitshm = 1; - x11->shm_info.shmid = shmget (IPC_PRIVATE, win_height * win_width * depth, - IPC_CREAT | 0777); - if (x11->shm_info.shmid < 0) { - g_fprintf (stderr, "shmget failed, looks like I'll have to use XPutImage\n"); - x11->use_mitshm = 0; - } else { - x11->shm_info.shmaddr = (gchar *) shmat (x11->shm_info.shmid, 0, 0); - - if (!x11->shm_info.shmaddr) { - g_fprintf (stderr, "shmat failed, looks like I'll have to use XPutImage\n"); - shmctl (x11->shm_info.shmid, IPC_RMID, 0); - use_mitshm = 0; - } else { - XErrorHandler error_handler = XSetErrorHandler (shm_error_handler); - - x11->win_bufi = XShmCreateImage (x11->dpy, vis, depth, ZPixmap, x11->shm_info.shmaddr, - &x11->shm_info, x11->win_width, x11->win_height); - x11->shm_info.readOnly = False; - XShmAttach (x11->dpy, &x11->shm_info); - win_buf = XShmCreatePixmap (x11->dpy, x11->x_win, x11->shm_info.shmaddr, &x11->shm_info, - x11->win_width, x11->win_height, depth); - XSync (x11->dpy, False); - (void) XSetErrorHandler (error_handler); - if (!use_mitshm) { - p_fprintf (stderr, - "XShmAttach failed, looks like I'll have to use XPutImage\n"); - XFreePixmap (x11->dpy, x11->win_buf); - XDestroyImage (x11->win_bufi); - shmdt (x11->shm_info.shmaddr); - shmctl (x11->shm_info.shmid, IPC_RMID, 0); - } - } - } - - if (!x11->use_mitshm) { -#endif /* USE_MITSHM */ - x11->win_buf = XCreatePixmap (x11->dpy, x11->x_win, x11->win_width, x11->win_height, depth); -#ifdef USE_MITSHM - } else { - g_printf ("Using MIT Shared Memory Pixmaps. Good.\n", major, minor); - } -#endif - - values.font = x11->text; - values.foreground = WhitePixel (x11->dpy, DefaultScreen (x11->dpy)); - - x11->buf_gc = XCreateGC (x11->dpy, x11->win_buf, GCFont | GCForeground, &values); -} - -void -create_image (X11Plugin *x11, 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 (x11->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 (X11Plugin *x11, XImage *image, gint x, gint y) -{ - XPutImage (x11->dpy, x11->win_buf, x11->gc, image, 0, 0, x, y, TILE_SIZE, TILE_SIZE); -} - -static void put_winbuf (X11Plugin *x11) -{ -#ifdef USE_MITSHM - if (use_mitshm) - XShmPutImage (x11->dpy, x11->x_win, x11->gc, x11->win_bufi, 0, 0, 0, 0, x11->win_width, x11->win_height, - False); - else -#endif - XCopyArea (x11->dpy, x11->win_buf, x11->x_win, x11->gc, 0, 0, x11->win_width, x11->win_height, 0, 0); - - XSync (x11->dpy, 0); -} - -static void x11_plugin_interface_init (gpointer g_iface, gpointer iface_data) -{ - UserInterfaceClass *klass = (UserInterfaceClass *)g_iface; - - klass->user_interface_add_thing = (void (*) (UserInterface *ui, - gint x, - gint y, - gint thing)) - x11_plugin_add_thing; - - klass->user_interface_run = (void(*)(UserInterface *ui)) x11_plugin_run; - klass->user_interface_draw = (void (*) (UserInterface *ui)) x11_plugin_draw; - klass->user_interface_update_status = (void (*) (UserInterface *ui, - const gchar *s, - glong energy, - glong score, - glong shields)) - x11_plugin_update_status; - klass->user_interface_move_robot = (void (*) (UserInterface *ui, - gint from_x, - gint from_y, - gint to_x, - gint to_y, - gint cdir, - glong energy, - glong score, - glong shields)) - x11_plugin_move_robot; - klass->user_interface_robot_smell = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - glong energy, - glong score, - glong shields)) - x11_plugin_robot_smell; - klass->user_interface_robot_zap = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - x11_plugin_robot_zap; - klass->user_interface_robot_feel = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - x11_plugin_robot_grab; - klass->user_interface_robot_grab = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - x11_plugin_robot_grab; - klass->user_interface_robot_look = (void (*) (UserInterface *ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - glong energy, - glong score, - glong shields)) - x11_plugin_robot_look; - klass->user_interface_get_string = (void (*) (UserInterface *ui, - gchar *prompt, - gchar *buff, - gint len)) - x11_plugin_get_string; -} diff --git a/lib/x11plugin.h b/lib/x11plugin.h deleted file mode 100644 index 05be8c2..0000000 --- a/lib/x11plugin.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (C) 1998 Jim Hall <jhall1@isd.net> - * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> - * - * GNU Robots game engine. - * - * GNU Robots is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __X11_PLUGIN_H__ -#define __X11_PLUGIN_H__ - -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/xpm.h> -#include <X11/keysym.h> - -#include <glib-object.h> -#include "userinterface.h" -#include "map.h" - -G_BEGIN_DECLS - -#define G_TYPE_X11_PLUGIN x11_plugin_get_type() -#define G_IS_X11_PLUGIN(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - G_TYPE_X11_PLUGIN) -#define G_IS_X11_PLUGIN_CLASS(klass) G_TYPE_CHECK_CLASS_TYPE ((klass), \ - G_TYPE_X11_PLUGIN) -#define X11_PLUGIN_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS ((obj), \ - G_TYPE_X11_PLUGIN, \ - X11PluginClass) -#define X11_PLUGIN(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - G_TYPE_X11_PLUGIN, X11Plugin) -#define X11_PLUGIN_CLASS(klass) G_TYPE_CHECK_CLASS_CAST ((klass), \ - G_TYPE_X11_PLUGIN, \ - X11PluginClass) - -typedef struct _X11Plugin X11Plugin; -typedef struct _X11PluginClass X11PluginClass; - -struct _X11Plugin { - GObject object; - Map *map; - MapSize *map_size; - gint errors; - - Display *dpy; - Window x_win; - Atom wm_delete_win; - Atom wm_protocols; - GC gc; - GC buf_gc; - Font text; - -#ifdef USE_MITSHM -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/extensions/XShm.h> - XShmSegmentInfo shm_info; - guchar use_mitshm = 1; -#endif - - gint win_width; - gint win_height; - - Pixmap win_buf; - - XImage *win_bufi; - XImage *statusbar; - XImage *space; - XImage *food; - XImage *wall; - XImage *prize; - XImage *baddie; - XImage *robotDirs[4]; - XImage *robotPix; -}; - -struct _X11PluginClass { - GObjectClass parent_class; -}; - -/* normal GObject stuff */ -GType x11_plugin_get_type (void); - -X11Plugin* x11_plugin_new (void); - -/* 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 /* __X11_PLUGIN_H__ */ diff --git a/src/Makefile.am b/src/Makefile.am index 8cdb716..fc510f8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,8 @@ bin_PROGRAMS = gnurobots -INCLUDES = $(GLIB2_CFLAGS) $(GUILE_CFLAGS) -I$(top_builddir)/include \ +INCLUDES = $(GLIB2_CFLAGS) $(GUILE_CFLAGS) $(READLINE_CFLAGS) $(X_FLAGS) \ + -I$(top_builddir)/include \ -DPKGLIBDIR=\"$(pkglibdir)\" \ -DABS_TOP_BUILDDIR=\"$(abs_top_builddir)\" \ -DPKGDATADIR=\"$(pkgdatadir)\" \ @@ -26,4 +27,5 @@ INCLUDES = $(GLIB2_CFLAGS) $(GUILE_CFLAGS) -I$(top_builddir)/include \ -DSCRIPTS_PATH=\"$(schemedir)\" gnurobots_SOURCES = main.c api.c map.c grobot.c userinterface.c -gnurobots_LDFLAGS = $(GLIB2_LIBS) $(GUILE_LDFLAGS) -lltdl -lgthread-2.0 +gnurobots_LDFLAGS = $(GLIB2_LIBS) $(GUILE_LDFLAGS) $(READLINE_LIBS) \ + $(X_LIBS) -lltdl -lgthread-2.0 @@ -25,12 +25,10 @@ #include <glib.h> #include <glib/gprintf.h> -#include <gmodule.h> #include <libguile.h> #include <getopt.h> /* for GNU getopt_long */ -#include <ltdl.h> /* For loading our ui plugins */ #include "grobot.h" /* the robot structure, and robot manipulation routines */ @@ -43,22 +41,13 @@ #include "main.h" /* for this source file */ #define BUFF_LEN 1024 -#define MODULE_PREFIX "grobots-" -#define MODULE_PATH_MAX 256 -#define MODULE_NAME_MAX 256 - -/* Plugins we should know about STATICALLY */ -#define X11_MODULE "x11" -#define CURSES_MODULE "curses" /* Globals (share with api.c) */ GList *robots = NULL; GRobot *robot = NULL; /* The current robot */ UserInterface *ui; Map *map; -GModule *plugin; -UserInterface *load_ui_module (gchar *module_name, Map *map); gpointer callback(gpointer data); SCM catch_handler (void *data, SCM tag, SCM throw_args); gint is_file_readable (const gchar *filename); @@ -89,7 +78,6 @@ main (gint argc, gchar *argv[]) {"map-file", 1, NULL, 'f'}, {"shields", 1, NULL, 's'}, {"energy", 1, NULL, 'e'}, - {"plugin", 1, NULL, 'p'}, {NULL, 0, NULL, 0} }; @@ -154,11 +142,6 @@ main (gint argc, gchar *argv[]) robot->energy = (glong) atol (optarg); break; - case 'p': - /* Set plugin */ - main_argv[3] = optarg; /* pointer assignment */ - break; - default: /* invalid option */ usage (argv[0]); @@ -299,7 +282,6 @@ main_prog (void *closure, gint argc, gchar *argv[]) { gchar *map_file = argv[1]; gchar *robot_program = argv[2]; - gchar *module = argv[3]; api_init (); @@ -317,7 +299,7 @@ main_prog (void *closure, gint argc, gchar *argv[]) G_ROBOT_POSITION_Y (robot), G_ROBOT_POSITION_X (robot), ROBOT); - ui = load_ui_module (module, map); + ui = user_interface_new (map); if (ui == NULL) { @@ -332,7 +314,10 @@ main_prog (void *closure, gint argc, gchar *argv[]) /* draw the map */ user_interface_draw (ui); - user_interface_update_status (ui, "", -1, -1, -1); + user_interface_update_status (ui, "Welcome to GNU Robots", -1,-1, -1); + + g_thread_init(NULL); + g_thread_create(callback, NULL, FALSE, NULL); if (strlen (robot_program) != 0) { @@ -345,12 +330,8 @@ main_prog (void *closure, gint argc, gchar *argv[]) { gchar buff[BUFF_LEN]; - g_thread_init(NULL); - g_printf("Robot program not specified. Entering interactive mode..\n"); - g_thread_create(callback, NULL, FALSE, NULL); - while(1) { user_interface_get_string (ui, "guile> ", buff, BUFF_LEN); @@ -411,82 +392,6 @@ death (GRobot *robot) exit_nicely (); } -UserInterface * -load_ui_module (gchar *module_name, Map *map) -{ - UserInterface *ui = NULL; - UserInterfaceInitFunc user_interface_new = NULL; - gchar module_full_name[MODULE_NAME_MAX]; - gchar module_path[MODULE_PATH_MAX]; - gchar *module_full_path; - const char *path = getenv (MODULE_PATH_ENV); - - if (!g_module_supported ()) - { - g_printf ("load_ui_module: %s\n", g_module_error ()); - return NULL; - } - - if (path != NULL) - { - g_strlcpy (module_path, path, MODULE_PATH_MAX); - } - - else - { - g_strlcpy (module_path, MODULE_PATH, MODULE_PATH_MAX); - } - - /* Load the module. */ - g_strlcpy (module_full_name, MODULE_PREFIX, MODULE_NAME_MAX); - - if (module_name != NULL) - { - g_strlcat (module_full_name, module_name, MODULE_NAME_MAX); - } - - else - { - if (getenv ("DISPLAY") != NULL) - { - /* Yuppi! we have x */ - g_strlcat (module_full_name, X11_MODULE, MODULE_NAME_MAX); - } - - else - { - g_strlcat (module_full_name, CURSES_MODULE, MODULE_NAME_MAX); - } - } - - module_full_path = g_module_build_path (module_path, module_full_name); - plugin = g_module_open (module_full_path, 0); - g_free (module_full_path); - - /* Find our handles. */ - if (plugin) - { - if (!(g_module_symbol (plugin, USER_INTERFACE_INIT_FUNCTION, - (gpointer) & user_interface_new))) - { - g_printf ("load_ui_module: %s\n", g_module_error ()); - g_module_close (plugin); - plugin = NULL; - } - else - { - ui = user_interface_new (map, user_interface_get_type ()); - } - } - else - { - g_printf ("error loading module '%s': %s\n", module_name, - g_module_error ()); - } - - return ui; -} - /************************************************************************ * void exit_nicely() * * * @@ -519,12 +424,6 @@ exit_nicely () g_list_foreach (robots, (GFunc)g_object_unref, NULL); g_list_free (robots); - /* unload the plugin */ - if (plugin != NULL) - { - g_module_close (plugin); - } - g_printf ("\n-----------------------STATISTICS-----------------------\n"); g_printf ("Shields: %ld\n", (shields < 0 ? 0 : shields)); g_printf ("Energy: %ld\n", (energy < 0 ? 0 : energy)); @@ -567,7 +466,6 @@ usage (const gchar *argv0) g_printf ("Usage: %s [OPTION]... [FILE]\n\n", argv0); g_printf (" -f, --map-file=FILE Load map file (this option is required)\n"); - g_printf (" -p, --plugin=PLUGIN Use plugin PLUGIN\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"); diff --git a/src/userinterface.c b/src/userinterface.c index f31591f..577cb7a 100644 --- a/src/userinterface.c +++ b/src/userinterface.c @@ -1,7 +1,7 @@ /* Copyright (C) 1998 Jim Hall <jhall1@isd.net> * Copyright (C) 2008 Bradley Smith <brad@brad-smith.co.uk> * - * GNU Robots game engine. This is the User Interface module + * 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 @@ -19,185 +19,719 @@ */ #include <glib.h> - +#include <glib/gprintf.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include "configs.h" #include "userinterface.h" -/*enum +#include <readline.h> +#include <history.h> + +G_DEFINE_TYPE(UserInterface, user_interface, G_TYPE_OBJECT) + +enum { ARG_0, ARG_MAP -};*/ +}; + +static GObject * user_interface_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties); + +static void user_interface_finalize (GObject * object); +static void user_interface_dispose (GObject * object); -static void user_interface_base_init (UserInterfaceClass * klass); +static void user_interface_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); -GType -user_interface_get_type (void) +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) { - static GType _user_interface_type = 0; + GObjectClass *gobject_class; - if (!_user_interface_type) - { - static const GTypeInfo interface_info = { - sizeof (UserInterfaceClass), - (GBaseInitFunc) user_interface_base_init, - NULL, - NULL, - NULL, - NULL, - 0, - 0, - NULL, - NULL - }; + 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; - _user_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "UserInterface", - &interface_info, 0); + /* 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 */ } - return _user_interface_type; + 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, + "-*-helvetica-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_base_init (UserInterfaceClass * klass) +user_interface_dispose (GObject * object) { - static gboolean initialized = FALSE; + UserInterface *ui; + ui = USER_INTERFACE (object); - if (!initialized) - { - /*GObjectClass *gobject_class = - g_type_class_peek (((GTypeInterface *) klass)->g_instance_type); + if (ui->map != NULL) { + g_object_unref (G_OBJECT (ui->map)); - g_object_class_install_property (gobject_class, ARG_MAP, */ - g_object_interface_install_property (klass, - g_param_spec_object ("map", - "Map", - "Reference to the Game Map object", - G_TYPE_MAP, - G_PARAM_READWRITE - | - G_PARAM_CONSTRUCT)); - initialized = TRUE; + if (ui->map_size != NULL) { + g_free (ui->map_size); + } } + + parent_class->dispose (object); } -void -user_interface_add_thing (UserInterface * ui, gint x, gint y, gint thing) +/* finalize is called when the object has to free its resources */ +static void +user_interface_finalize (GObject * object) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_add_thing (ui, x, y, thing); + 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); } -void user_interface_run(UserInterface* ui) +static void +user_interface_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) { - USER_INTERFACE_GET_CLASS(ui)->user_interface_run(ui); + 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; + } } -void -user_interface_draw (UserInterface * ui) +static void +user_interface_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_draw (ui); + 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; + } } -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) -{ - USER_INTERFACE_GET_CLASS (ui)->user_interface_move_robot (ui, from_x, - from_y, to_x, - to_y, cdir, - energy, score, - shields); -} - -/* user_interfaces to animate the robot */ -void -user_interface_robot_smell (UserInterface * ui, - gint x, - gint y, - gint cdir, - glong energy, glong score, glong shields) +UserInterface * +user_interface_new (Map *map) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_robot_smell (ui, x, y, cdir, - energy, score, - shields); + 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); } -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) +/* 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) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_robot_zap (ui, x, y, cdir, - x_to, y_to, energy, - score, shields); + 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_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_draw (UserInterface *ui) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_robot_feel (ui, x, y, cdir, - x_to, y_to, - energy, score, - shields); + 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_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_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) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_robot_grab (ui, x, y, cdir, - x_to, y_to, - energy, score, - 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_look (UserInterface * ui, - gint x, - gint y, - gint cdir, - gint x_to, - gint y_to, - 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) { - USER_INTERFACE_GET_CLASS (ui)->user_interface_robot_look (ui, x, y, cdir, - x_to, y_to, - energy, score, - shields); + user_interface_update_status (ui, "robot fires his little gun...", energy, score, shields); + g_usleep (USLEEP_TIME); } -void -user_interface_get_string (UserInterface *ui, gchar *prompt, gchar *buff, - gint len) +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) { - USER_INTERFACE_GET_CLASS(ui)->user_interface_get_string(ui, prompt, buff, - len); + 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 -user_interface_update_status (UserInterface * ui, const gchar * s, - glong energy, glong score, glong shields) +create_image (UserInterface *ui, gchar **data, XImage ** image) { - USER_INTERFACE_GET_CLASS(ui)->user_interface_update_status(ui, s, energy, - score, shields); + 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/lib/xpm/Makefile.am b/xpm/Makefile.am index 069cada..069cada 100644 --- a/lib/xpm/Makefile.am +++ b/xpm/Makefile.am diff --git a/lib/xpm/baddie.xpm b/xpm/baddie.xpm index 60c1c6d..60c1c6d 100644 --- a/lib/xpm/baddie.xpm +++ b/xpm/baddie.xpm diff --git a/lib/xpm/food.xpm b/xpm/food.xpm index 34558d3..34558d3 100644 --- a/lib/xpm/food.xpm +++ b/xpm/food.xpm diff --git a/lib/xpm/prize.xpm b/xpm/prize.xpm index 96c4dad..96c4dad 100644 --- a/lib/xpm/prize.xpm +++ b/xpm/prize.xpm diff --git a/lib/xpm/robot.xpm b/xpm/robot.xpm index fea60e2..fea60e2 100644 --- a/lib/xpm/robot.xpm +++ b/xpm/robot.xpm diff --git a/lib/xpm/robot_east.xpm b/xpm/robot_east.xpm index 14da711..14da711 100644 --- a/lib/xpm/robot_east.xpm +++ b/xpm/robot_east.xpm diff --git a/lib/xpm/robot_north.xpm b/xpm/robot_north.xpm index ec7284d..ec7284d 100644 --- a/lib/xpm/robot_north.xpm +++ b/xpm/robot_north.xpm diff --git a/lib/xpm/robot_south.xpm b/xpm/robot_south.xpm index b0ffc68..b0ffc68 100644 --- a/lib/xpm/robot_south.xpm +++ b/xpm/robot_south.xpm diff --git a/lib/xpm/robot_west.xpm b/xpm/robot_west.xpm index 4a5a2af..4a5a2af 100644 --- a/lib/xpm/robot_west.xpm +++ b/xpm/robot_west.xpm diff --git a/lib/xpm/space.xpm b/xpm/space.xpm index bce27fb..bce27fb 100644 --- a/lib/xpm/space.xpm +++ b/xpm/space.xpm diff --git a/lib/xpm/statusbar.xpm b/xpm/statusbar.xpm index 89f5a05..89f5a05 100644 --- a/lib/xpm/statusbar.xpm +++ b/xpm/statusbar.xpm diff --git a/lib/xpm/wall.xpm b/xpm/wall.xpm index 48b6a7c..48b6a7c 100644 --- a/lib/xpm/wall.xpm +++ b/xpm/wall.xpm |