From e6e7222d5a730368ed4e84c2e0f55427460e5230 Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Mon, 21 Jan 2008 00:16:45 +0000 Subject: Imported GNU robots from CVS. Signed-off-by: Bradley Smith --- lib/Makefile.am | 48 +++ lib/cursesplugin.c | 599 ++++++++++++++++++++++++++++++++++ lib/cursesplugin.h | 69 ++++ lib/textplugin.c | 444 +++++++++++++++++++++++++ lib/textplugin.h | 63 ++++ lib/x11plugin.c | 840 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/x11plugin.h | 102 ++++++ lib/xpm/Makefile.am | 31 ++ lib/xpm/baddie.xpm | 28 ++ lib/xpm/food.xpm | 27 ++ lib/xpm/prize.xpm | 31 ++ lib/xpm/robot.xpm | 28 ++ lib/xpm/robot_east.xpm | 28 ++ lib/xpm/robot_north.xpm | 28 ++ lib/xpm/robot_south.xpm | 28 ++ lib/xpm/robot_west.xpm | 28 ++ lib/xpm/space.xpm | 26 ++ lib/xpm/statusbar.xpm | 58 ++++ lib/xpm/wall.xpm | 26 ++ 19 files changed, 2532 insertions(+) create mode 100644 lib/Makefile.am create mode 100644 lib/cursesplugin.c create mode 100644 lib/cursesplugin.h create mode 100644 lib/textplugin.c create mode 100644 lib/textplugin.h create mode 100644 lib/x11plugin.c create mode 100644 lib/x11plugin.h create mode 100644 lib/xpm/Makefile.am create mode 100644 lib/xpm/baddie.xpm create mode 100644 lib/xpm/food.xpm create mode 100644 lib/xpm/prize.xpm create mode 100644 lib/xpm/robot.xpm create mode 100644 lib/xpm/robot_east.xpm create mode 100644 lib/xpm/robot_north.xpm create mode 100644 lib/xpm/robot_south.xpm create mode 100644 lib/xpm/robot_west.xpm create mode 100644 lib/xpm/space.xpm create mode 100644 lib/xpm/statusbar.xpm create mode 100644 lib/xpm/wall.xpm (limited to 'lib') diff --git a/lib/Makefile.am b/lib/Makefile.am new file mode 100644 index 0000000..f3d6283 --- /dev/null +++ b/lib/Makefile.am @@ -0,0 +1,48 @@ +## +## 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 + +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) + +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) + diff --git a/lib/cursesplugin.c b/lib/cursesplugin.c new file mode 100644 index 0000000..a3f08ad --- /dev/null +++ b/lib/cursesplugin.c @@ -0,0 +1,599 @@ +/* $Id: cursesplugin.c,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#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 */ + gint color_pair; + + 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) +{ + 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; + } + + CursesPlugin *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 new file mode 100644 index 0000000..7f72d0e --- /dev/null +++ b/lib/cursesplugin.h @@ -0,0 +1,69 @@ +/* $Id: cursesplugin.h,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CURSES_PLUGIN_H__ +#define __CURSES_PLUGIN_H__ + +#include +#include +#include +#include /* 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 new file mode 100644 index 0000000..32a5a56 --- /dev/null +++ b/lib/textplugin.c @@ -0,0 +1,444 @@ +/* $Id: textplugin.c,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "configs.h" +#include "textplugin.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) +{ + 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; + } + + TextPlugin *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) +{ + fputs (prompt, stdout); + fgets (buff, len, stdin); +} + +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 new file mode 100644 index 0000000..fd9eb7b --- /dev/null +++ b/lib/textplugin.h @@ -0,0 +1,63 @@ +/* $Id: textplugin.h,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __TEXT_PLUGIN_H__ +#define __TEXT_PLUING_H__ + +#include +#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 new file mode 100644 index 0000000..d40efd9 --- /dev/null +++ b/lib/x11plugin.c @@ -0,0 +1,840 @@ +/* $Id: x11plugin.c,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include "configs.h" +#include "x11plugin.h" + +enum +{ + ARG_0, + ARG_MAP +}; + +GType _x11_plugin_type = 0; +static GType _parent_type = 0; + +static void x11_plugin_class_init (X11PluginClass * klass); +static void x11_plugin_init (GObject * object); +static void x11_plugin_interface_init (gpointer g_iface, gpointer iface_data); + +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; + +GType +x11_plugin_get_type (void) +{ + if (!_x11_plugin_type) { + static const GTypeInfo object_info = { + sizeof (X11PluginClass), + NULL, + NULL, + (GClassInitFunc) x11_plugin_class_init, + NULL, + NULL, + sizeof (X11Plugin), + 0, + (GInstanceInitFunc) x11_plugin_init, + NULL + }; + + static const GInterfaceInfo interface_info = { + (GInterfaceInitFunc) x11_plugin_interface_init, + NULL, + NULL + }; + + _x11_plugin_type = + g_type_register_static (G_TYPE_OBJECT, + "X11Plugin", + &object_info, + 0); + + g_type_add_interface_static (_x11_plugin_type, + _parent_type, + &interface_info); + } + + return _x11_plugin_type; +} + +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 (GObject * object) +{ + X11Plugin *x11 = X11_PLUGIN (object); + + 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" + Atom prots[6]; + XClassHint classhint; + XWMHints wmhints; + XGCValues values; + Atom delete_win; + gint x; + + /* Chain up to the parent first */ + object = parent_class->constructor (type, n_construct_properties, construct_properties); + + x11 = X11_PLUGIN (object); + + 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 */ + } + + 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); + + prots[0] = delete_win; + XSetWMProtocols (x11->dpy, x11->x_win, prots, 1); + + 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, + 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_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) +{ + 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; + } + + X11Plugin *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) +{ + /* You want me to write a text-box using xlib? + * You got to be kidding me + * */ + fputs (prompt, stdout); + fgets (buff, len, stdin); +} + +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: %3d", 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: %3d", 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: %3d", 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) +{ + gint x; + XEvent ev; + + x11_update_status (x11, s, energy, score, shields); + + while (XPending (x11->dpy)) { + 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; + } + } + } + + 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) +{ + gint major, minor; + Bool shared; + 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_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 new file mode 100644 index 0000000..0c39fa2 --- /dev/null +++ b/lib/x11plugin.h @@ -0,0 +1,102 @@ +/* $Id: x11plugin.h,v 1.1 2004/10/21 19:24:30 zeenix Exp $ */ + +/* GNU Robots game engine. */ + +/* Copyright (C) 1998 Jim Hall, jhall1@isd.net */ + +/* + This program 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. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __X11_PLUGIN_H__ +#define __X11_PLUGIN_H__ + +#include +#include +#include +#include + +#include +#include "userinterface.h" +#include "map.h" + +G_BEGIN_DECLS + +extern GType _x11_plugin_type; + +typedef struct _X11Plugin X11Plugin; + +struct _X11Plugin { + GObject object; + Map *map; + MapSize *map_size; + gint errors; + + Display *dpy; + Window x_win; + 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; +}; + +typedef struct _X11PluginClass X11PluginClass; + +struct _X11PluginClass { + GObjectClass parent_class; +}; + +#define G_TYPE_X11_PLUGIN (_x11_plugin_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)) + +/* 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/lib/xpm/Makefile.am b/lib/xpm/Makefile.am new file mode 100644 index 0000000..60cb556 --- /dev/null +++ b/lib/xpm/Makefile.am @@ -0,0 +1,31 @@ +## +## xpm/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 +## + +EXTRA_DIST =\ + baddie.xpm\ + food.xpm\ + prize.xpm\ + robot_east.xpm\ + robot_north.xpm\ + robot_south.xpm\ + robot_west.xpm\ + robot.xpm\ + space.xpm\ + statusbar.xpm\ + wall.xpm + diff --git a/lib/xpm/baddie.xpm b/lib/xpm/baddie.xpm new file mode 100644 index 0000000..60c1c6d --- /dev/null +++ b/lib/xpm/baddie.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *baddie_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #ffffff", +"# c #990033", +"a c #c0c0c0", +"b c #808080", +"c c #ffffff", +/* pixels */ +"................", +"................", +"......#...#.....", +".......###......", +".....a#####a....", +".....b#c###b....", +"....b#c###b#b...", +"....##cbab###...", +"...#####a#####..", +"....####a####...", +"...#b###a###b#..", +".....###a###....", +"....#a##a##a#...", +".......#b#......", +"................", +"................" +}; diff --git a/lib/xpm/food.xpm b/lib/xpm/food.xpm new file mode 100644 index 0000000..34558d3 --- /dev/null +++ b/lib/xpm/food.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char *food_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 4 1", +/* colors */ +". c #f83000", +"# c #c8ccc8", +"a c #989898", +"b c #f8fcf8", +/* pixels */ +"bbbbbbbbbbbbbbbb", +"bbbbbbbbbbbbbbbb", +"bbbbbbbbbbbbbbbb", +"bbb#bbbbbb#b#abb", +"bbbbbbbbbbbbbabb", +"bbbbbbbbbbbbbabb", +"bbbbbbbb.bbbbabb", +"bbbbbbbb.bbbbabb", +"bbbbbb.....bbabb", +"bbbbbbbb.bbbbabb", +"bbbbbbbb.bbbbabb", +"bbbbbbbbbbbbbabb", +"bbbbbbbbbbbbbabb", +"bbbaaaaaaaaaaabb", +"bbbbbbbbbbbbbbbb", +"bbbbbbbbbbbbbbbb" +}; diff --git a/lib/xpm/prize.xpm b/lib/xpm/prize.xpm new file mode 100644 index 0000000..96c4dad --- /dev/null +++ b/lib/xpm/prize.xpm @@ -0,0 +1,31 @@ +/* XPM */ +static char *prize_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 8 1", +/* colors */ +". c #303098", +"# c #003098", +"a c #989898", +"b c #c8ccc8", +"c c #606460", +"d c #f8fcf8", +"e c #989800", +"f c #000000", +/* pixels */ +"dddddddddddddddd", +"dddddddddddddddd", +"dddddddddddddddd", +"dddddddddddddddd", +"dddd........dddd", +"dddd#deeeed.dddd", +"dddd#dedded#dddd", +"dddd#dedddd#dddd", +"dddd##.#.###dddd", +"dddd##c#cc##dddd", +"dddd##c#cc#.dddd", +"dddd.#cccc#.dddd", +"dddddddddddddddd", +"dddddddddddddddd", +"dddddddddddddddd", +"dddddddddddddddd" +}; diff --git a/lib/xpm/robot.xpm b/lib/xpm/robot.xpm new file mode 100644 index 0000000..fea60e2 --- /dev/null +++ b/lib/xpm/robot.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *robot_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #bfbfbf", +"# c #000000", +"a c #808080", +"b c #c0c0c0", +"c c #ffffff", +/* pixels */ +"................", +"................", +"................", +"..####...####...", +".#bccb#.#bccb#..", +"#bccccb#bccccb#.", +"#cccccc#cccccc#a", +"#cc##cc#cc##cc#a", +"#cc##cc#cc##cc#a", +"#bccccb#bccccb#a", +".#bccb#a#bccb#aa", +"..####aa.####aa.", +"...aaaa...aaaa..", +"................", +"................", +"................" +}; diff --git a/lib/xpm/robot_east.xpm b/lib/xpm/robot_east.xpm new file mode 100644 index 0000000..14da711 --- /dev/null +++ b/lib/xpm/robot_east.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *robot_east_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #bfbfbf", +"# c #000000", +"a c #808080", +"b c #c0c0c0", +"c c #ffffff", +/* pixels */ +"................", +"................", +"................", +"..####...####...", +".#bccb#.#bccb#..", +"#bccccb#bccccb#.", +"#cccccc#cccccc#a", +"#ccc##c#ccc##c#a", +"#ccc##c#ccc##c#a", +"#bccccb#bccccb#a", +".#bccb#a#bccb#aa", +"..####aa.####aa.", +"...aaaa...aaaa..", +"................", +"................", +"................" +}; diff --git a/lib/xpm/robot_north.xpm b/lib/xpm/robot_north.xpm new file mode 100644 index 0000000..ec7284d --- /dev/null +++ b/lib/xpm/robot_north.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *robot_north_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #bfbfbf", +"# c #000000", +"a c #808080", +"b c #c0c0c0", +"c c #ffffff", +/* pixels */ +"................", +"................", +"................", +"..####...####...", +".#bccb#.#bccb#..", +"#bc##cb#bc##cb#.", +"#cc##cc#cc##cc#a", +"#cccccc#cccccc#a", +"#cccccc#cccccc#a", +"#bccccb#bccccb#a", +".#bccb#a#bccb#aa", +"..####aa.####aa.", +"...aaaa...aaaa..", +"................", +"................", +"................" +}; diff --git a/lib/xpm/robot_south.xpm b/lib/xpm/robot_south.xpm new file mode 100644 index 0000000..b0ffc68 --- /dev/null +++ b/lib/xpm/robot_south.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *robot_south_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #bfbfbf", +"# c #000000", +"a c #808080", +"b c #c0c0c0", +"c c #ffffff", +/* pixels */ +"................", +"................", +"................", +"..####...####...", +".#bccb#.#bccb#..", +"#bccccb#bccccb#.", +"#cccccc#cccccc#a", +"#cccccc#cccccc#a", +"#cc##cc#cc##cc#a", +"#bc##cb#bc##cb#a", +".#bccb#a#bccb#aa", +"..####aa.####aa.", +"...aaaa...aaaa..", +"................", +"................", +"................" +}; diff --git a/lib/xpm/robot_west.xpm b/lib/xpm/robot_west.xpm new file mode 100644 index 0000000..4a5a2af --- /dev/null +++ b/lib/xpm/robot_west.xpm @@ -0,0 +1,28 @@ +/* XPM */ +static char *robot_west_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 5 1", +/* colors */ +". c #bfbfbf", +"# c #000000", +"a c #808080", +"b c #c0c0c0", +"c c #ffffff", +/* pixels */ +"................", +"................", +"................", +"..####...####...", +".#bccb#.#bccb#..", +"#bccccb#bccccb#.", +"#cccccc#cccccc#a", +"#c##ccc#c##ccc#a", +"#c##ccc#c##ccc#a", +"#bccccb#bccccb#a", +".#bccb#a#bccb#aa", +"..####aa.####aa.", +"...aaaa...aaaa..", +"................", +"................", +"................" +}; diff --git a/lib/xpm/space.xpm b/lib/xpm/space.xpm new file mode 100644 index 0000000..bce27fb --- /dev/null +++ b/lib/xpm/space.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *space_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 3 1", +/* colors */ +". c #989898", +"# c #c8ccc8", +"a c #f8fcf8", +/* pixels */ +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa", +"aaaaaaaaaaaaaaaa" +}; diff --git a/lib/xpm/statusbar.xpm b/lib/xpm/statusbar.xpm new file mode 100644 index 0000000..89f5a05 --- /dev/null +++ b/lib/xpm/statusbar.xpm @@ -0,0 +1,58 @@ +/* XPM */ +static char * statusbar_xpm[] = { +"96 32 23 1", +" c None", +". c #323232", +"+ c #343434", +"@ c #363636", +"# c #313131", +"$ c #373737", +"% c #3A3A3A", +"& c #393939", +"* c #2F2F2F", +"= c #262626", +"- c #282828", +"; c #2A2A2A", +"> c #2D2D2D", +", c #1B1B1B", +"' c #1D1D1D", +") c #222222", +"! c #242424", +"~ c #202020", +"{ c #2B2B2B", +"] c #3D3D3D", +"^ c #3C3C3C", +"/ c #3F3F3F", +"( c #191919", +".++@@++.##.$%&*=-;>#..>-,')!=)','~=>#*>;-;{>>*>*#......#=;*$&${~)!-;>>>>**#+++*{{>*#.++..+@&&&$@", +"++@@@.#**>#@&&#{-->*+.>>'~)!!~',''=>##>{-;{>>***##..++..;{*@&@>=!!-{>>>>>**.@+#>>>>#...+#.@$$$$@", +"++@@+#>>>{>+&&+*--{>.+.*!!!!)~''''!{*#*>;;{>>*#....+@++@>>>#@+*;!=;{>>>>>>*#@@+#{>>*##..#.+@@@@+", +"+@@@.*{---{#@&$+;-;>#+++;;-=)~''''!;*#*>{{{>>#.+..++@$$$*>{>*#>{=-;>>>>>>>>*.$@@{>>>>##.##...+.+", +".@@@+*;===;>.@&${;;{*.@@>>{-=)~~'~);>###>>>>>#.@..++@$&&.>;-{>{-=-{>>*>>>{;>#+@@>{{>>>*#***####.", +"#.@$+>;!!=-;>.@&*>-->#+@##*>{-!)~~)->#..*>>>>#+@++++@$&&@#;=-;-!!-{>**>>{;=-{*.+{{{;{>*#**>>>*##", +"*.@@@*{====-{>+$.>;-;>#..++.#>-!))!->*#.##>>>#+$+++@@@$&%+>;--!)!={>##*>{-))=>*#>{;-;>>**>>>>>**", +">#@$@#{-====->.$@#;!->*#.+@$.>;!!!!=>*...#>>>*+$+@++@$$&]$#{;-!~)={>##**{=~~);>>{{;-;{>**>>{{>>*", +";>+&&.>;)-;;-;>.+.#>;;>*##.$%&#;!!)={>##+..*>>.+++$+..&%$&&.;!!!=={*..*>{-)''~!;=-;=!!{*#*>>>>>*", +"-{*+&@*{!={;;;>#+.#>{;>*#**@&&+>-=!={>*#...#>*#.+@@+.#@&&&&+>=!==-;>.+#*{;!~')!-=;;-!!;>.#*>>>**", +"{;;*@&+>=-;;;{>*++.*{{{>**>.$&@.{;--{>>>.+.#**#.+@@+#*#.&^^&*;--;;{>#+++>;=)~~!=-;{;!)-{####*###", +">=!;+%$.=-;;{{>*.++#>{>>>>>*+&&&>{{;>>>>.++.***#@@@+#*>>&^]%@>;-{{{>#@@${;=!))!!-{>;!!!;##....##", +">-~-.&&+;;-;{>>>#.++#>>{>>>>#@&&+#>>>>>>..++####+@@@.*{=@&/]&#{;>>{>#++@;;-=!!)!=;>;=)!-*#++@++.", +">-)-*@$@{;-;>>>>*.@@.*>>{{{>*+$&@+#*>*>>#.+@.##.++@@@#;!*$]/&.>{>>>>#.#*=-==!!!)!-{{=!!->#+@$@+#", +">{;;>#@@>;-->>>{>#@$@#>>;{>>*#@$&@.#***>>.+@+.#.+++$&.>!-#%/%+>{>>>*#*>;!!====))~={{-==;>*+$&@+#", +"#>>{{>.+>;=;>>>{>*@&@.*>>{>>>*.@%&+.##*>>#+@+.....@&&+>!!>&]%@>>>>>##>;=))====!)'!;{-=-;>>+$&@.#", +"=-;>*#**{{-;>>>{>>*+&&.{{{{{>*#+@@$$@+#*>>*+$$+.##+$&&#;=;>+&$.>>>*#.*-~''~=;-!~'~!=--;-{>#@&&@.", +"-=-{#..*>{;;>>>>{;>.$&.>{{{{>*#.@$$$$@..>>*.@$@...+&%&+>-;>.@@.>*>>*.#{!''~=--=~~~)!--;;{>*+&&$+", +"{=!;#$@.>{;{>**>;-{*$$+#>>>>>>**@@$&$$$@>>*.@$$@.#.$%%$.;;>#.+#**{->+@>=''')-;-=~)!=--;->>*+&&&$", +">=~-#&&+>>{{>*##--->.$@.>>>>>>>*+@$&&&&&##*#+@$@.##+&&&+{{>*#.#**;)-#@#;''')=;;-)!!=--;;{>>#@&&$", +">-)=*$&&*>>>*#.#;-!;*++.*>>>>>>>.+@$&&%%+.*#.@$$.*>*+$@.>>>*##*>>!'!>.#>~'''!-;{===--;;;>>{>.$$&", +">;==>.$&+*>>*...>;!={*##>*>>>>>>#.+@$&&%&+#*#+$&+*>>*.#**>*#.#>;=~''=>**!)'')-;;;;-;;;{{*>{{>.++", +">>{-->@^@.*>#...#{=!->*>>>>>>>>>##.+@&&%&$#**+$$&.>{>**>**.++#{-''','!>.;)''~=-{{{{;{{>>*>;-{>*#", +">>>;!>+^$+***.+.+>=)={>>>>>>***>**#.@$&&^&#**.@&%@>{>>>>*#+$@#{!(,'(('{.{=~''!-;>>{{{{>>.>-=-{>>", +">>>{;>*.@+####.@.#>=~~->;{>>>*>*>>*#.+$&&&@#>>#@$$.>{{>*+##+&$*-,'''(')-;-!)');>*>>>>>*##*{-=-;>", +">>>{{{>#++.####.+.#;!)->{>>>>**>>>**.+@$&&$#>{>+&$+#>>*..##+&$#{''~','~=-;=)~!->>*>****#.*>-=-;{", +">>>>{{>*++..***>+@+>-!=;{{>>****>>>*#.++&&$.>;>*$$+#*>#+#**+$&@#)))'''~);;-!))->>*##..+..*>-=-;;", +">>>>>{{>..+.#*>;+@$.>==-{{>>>*#*>>>>**..$&&+>-;{++.#**#.*>>#$&$@--!)~'~);;;-=!-;>*#+@@@++#>-==-;", +"{>**>{{{#.++.>-=*+$$#;=={{{>>**#>>>>>**#+$&+>-=->>**>>*#>>>*.$&&>>;=!!))-{>{---;>*.+@$$&@.>;-=-;", +"{>*#>>{{>#+@.>=~-*$&+>-!;;{{>>*#>>>>>>>**+$@*;==;{>>>>>*>{>>*+$&.*>{;;=!;{>>>{;{>**.@$&&&+*{---;", +"->*#*>{{>*+@+>!'~;@&@*-=;;;;>>**>>>>>>>>{#@@*;==-;>>>>>#>>{{>*+&$+>>>>{=-{***>{>>>**.$&^&$#>---;", +"-{*#*>{{;>+@+>!'(-.&$*;=---;{>***>>>>>>>-*+@#{=!-{>>>>*#>{;-;>.$&@#***>{->*.*>>>*>>>#@&]&$.>;-;{"}; diff --git a/lib/xpm/wall.xpm b/lib/xpm/wall.xpm new file mode 100644 index 0000000..48b6a7c --- /dev/null +++ b/lib/xpm/wall.xpm @@ -0,0 +1,26 @@ +/* XPM */ +static char *wall_xpm[] = { +/* width height num_colors chars_per_pixel */ +" 16 16 3 1", +/* colors */ +". c #cccccc", +"# c #993300", +"a c #cc0033", +/* pixels */ +"...............#", +".aaaaaaaaaaaaaa#", +".aaaaaaaaaaaaaa#", +".aa##########aa#", +".aa#aaaaaaaa.aa#", +".aa#aaaaaaaa.aa#", +".aa#aa...#aa.aa#", +".aa#aa.aa#aa.aa#", +".aa#aa.aa#aa.aa#", +".aa#aa####aa.aa#", +".aa#aaaaaaaa.aa#", +".aa#aaaaaaaa.aa#", +".aa#.........aa#", +".aaaaaaaaaaaaaa#", +".aaaaaaaaaaaaaa#", +"################" +}; -- cgit v1.1