Index: README
===================================================================
RCS file: /home/cvs/tunneler/tunneler/README,v
retrieving revision 1.1.1.3
retrieving revision 1.5
diff -u -r1.1.1.3 -r1.5
--- README	21 Jan 2005 19:21:06 -0000	1.1.1.3
+++ README	21 Jan 2005 23:32:11 -0000	1.5
@@ -6,7 +6,7 @@
 
 Parametry klienta:
 
-  m - vicerychlostni - 0,5 a z,a snizuje/zvysuje rychlost postupne
+  s - vicerychlostni - 0,5 a z,a snizuje/zvysuje rychlost postupne
 
 Parametry serveru:
 
Index: TODO
===================================================================
RCS file: TODO
diff -N TODO
--- TODO	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1 +0,0 @@
-color v konzoli pri zobrazovani hrace  (ooo)~~
Index: ai.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/ai.c,v
retrieving revision 1.1.1.1
retrieving revision 1.11
diff -u -r1.1.1.1 -r1.11
--- ai.c	21 Jan 2005 19:21:05 -0000	1.1.1.1
+++ ai.c	22 Jan 2005 03:11:18 -0000	1.11
@@ -1,4 +1,5 @@
 #include <assert.h>
+#include <limits.h>
 #include <stdlib.h>
 #include "game.h"
 #include "server.h"
@@ -15,8 +16,6 @@
  * See .h for description of the states.
  *
  * TODO:
- * * Self-preservation instinct - if low on stuff, seek home.
- * * Be active - lay route for playing an explorer, kill enemies on sight.
  * * Getting around larger stone blocks (i.e. home walls).
  * * Difficulty levels - adjusts speed, intelligence, aggressivity
  * * Characters, for that matter - each bot has those attributes laid
@@ -42,23 +41,36 @@
 /* How far to back off. 24 is =~ sqrt(16*16+16*16), 16 is height of one
  * character. */
 #define BACKOFF_DISTANCE    24
+/* How further must be the pursuee than the nearest potential victim before
+ * we retarget. */
+#define RETARGET_RATIO      3
+/* Once per how many ticks are we allowed to change direction when hunting? */
+#define HUNT_TURN_PERIOD    FPS/2
+/* Once per how many ticks are we allowed to change direction when backing off? */
+#define BACKOFF_TURN_PERIOD FPS/4
 
 /* Threshold values before switching to AI_FLEE. */
 #define MIN_NORMAL_ENERGY   MAX_ENERGY/3
-#define MIN_NORMAL_SHIELDS  MAX_SHIELDS/4
+#define MIN_NORMAL_SHIELDS  MAX_SHIELDS/3
 /* How long after being shot last time should the "revenge" last. */
 #define MAX_REVENGE_TICKS   FPS /* 1s */
 /* Threshold values in revenge mode. */
-#define MIN_REVENGE_ENERGY  MAX_ENERGY/6
-#define MIN_REVENGE_SHIELDS MAX_SHIELDS/6
+#define MIN_REVENGE_ENERGY  MAX_ENERGY/4
+#define MIN_REVENGE_SHIELDS MAX_SHIELDS/4
 /* Threshold values before switching to critical mode (slow speed). */
-#define MAX_CRITICAL_ENERGY MAX_ENERGY/8
+#define MAX_CRITICAL_ENERGY MAX_ENERGY/6
 #define MAX_CRITICAL_SHIELDS 0
 
+/* Angle fuzziness - probabily of changing angle by 1 or 2 respectively. */
+#define STUCK_FUZZINESS1    7
+#define STUCK_FUZZINESS2    9
+#define HUNT_FUZZINESS1     FPS /* ... if ever? */
+#define HUNT_FUZZINESS2     FPS*2
+
 
 /* Local utility functions */
 
-#if 1
+#if 0
 #define AIDEBUG(x...) DEBUG("[ai] " x);
 #else
 #define AIDEBUG(x...)
@@ -66,6 +78,8 @@
 
 #define in_revenge(bot_) (bot_->ai.last_shot <= MAX_REVENGE_TICKS)
 
+#define fine_surface(x_,y_) (surface[x_ / XPOINTS_PERCHAR][y_ / YPOINTS_PERCHAR])
+
 /* Returns squared distance. */
 static long
 distance (int x1, int y1, int x2, int y2)
@@ -106,6 +120,43 @@
 	return 1;
 }
 
+/* Scan surface and find the nearest tank there. Returns the player. */
+static plr_t *
+find_nearest_enemy(struct _plr_t *bot)
+{
+	int sx = bot->tank.x/XPOINTS_PERCHAR;
+	int sy = bot->tank.y/YPOINTS_PERCHAR;
+	int minx = sx - VIEWPNT_WIDTH/2;
+	int miny = sy - VIEWPNT_HEIGHT/2;
+	int maxx = sx + VIEWPNT_WIDTH/2;
+	int maxy = sy + VIEWPNT_HEIGHT/2;
+	struct _plr_t *best = NULL;
+	int bestd = INT_MAX;
+	int x, y;
+
+	for (x = minx; x < maxx; x++)
+		for (y = miny; y < maxy; y++) {
+			struct _plr_t *p;
+			int d;
+
+			if (!(surface[x][y] & G_PLAYER))
+				continue;
+
+			d = distance(sx, sy, x, y);
+			if (d >= bestd)
+				continue;
+
+			p = find_player_by_xy(x, y, 1, 1);
+			/* FIXME: Sometimes, p is NULL here. Why?! --pasky */
+			if (!p || p == bot || p->tank.exploding != 0)
+				continue;
+
+			best = p; bestd = d;
+		}
+
+	return best;
+}
+
 /* Determines the proper angle of <from> heading to <target>. */
 static int
 get_angle (int from_x, int from_y, int target_x, int target_y)
@@ -130,11 +181,11 @@
 
 /* Add some randomization to the angle. */
 static int
-fuzzy_angle (int angle)
+fuzzy_angle (int angle, int f1, int f2)
 {
 	return (angle + 8 /* compensate for possible negatives */
-	        + (mkrand(7) == 0 ? mkrand(2) - 1 : 0)
-	        + (mkrand(9) == 0 ? mkrand(4) - 2 : 0)) % 8;
+	        + (mkrand(f1) == 0 ? mkrand(2) - 1 : 0)
+	        + (mkrand(f2) == 0 ? mkrand(4) - 2 : 0)) % 8;
 }
 
 /* Compute difference between two angles. */
@@ -151,19 +202,22 @@
 void    reset_ai (AI *ai)
 {
 	ai->state = AI_IDLE;
-	ai->idle.tick_count = 0;
+	ai->idle.tick_count = 2 * FPS;
 	ai->backing_off = 0;
 	ai->last_shot = 100000;
+	ai->last_turnaround = 100000;
 }
 
 void    stop_ai_pursue (plr_t *p)
 {
 	plr_t *bot;
 
-	/* Turn the pursuers to confused schizo-bots on lunch. */
+	/* Let the pursuers mind their own bussiness. */
 	foreach (bot, players)
-		if (bot->ai.state == AI_HUNT && bot->ai.hunt.pursuing == p)
-			reset_ai(&bot->ai);
+		if (bot->ai.state == AI_HUNT && bot->ai.hunt.pursuing == p) {
+			bot->ai.state = AI_EXPLORE;
+			bot->ai.explore.tick_count = 0;
+		}
 }
 
 
@@ -191,6 +245,16 @@
 	    && good_shot(&victim->tank, &victim->ai.hunt.pursuing->tank))
 		return;
 
+	if (victim->ai.last_turnaround <= BACKOFF_TURN_PERIOD)
+		return;
+	victim->ai.last_turnaround = 0;
+
+	/* Don't back off if exploring - let us just go in another direction. */
+	if (victim->ai.state == AI_EXPLORE) {
+		victim->ai.explore.tick_count = 0;
+		return;
+	}
+
 	if (!victim->ai.backing_off) {
 		AIDEBUG("[%d] gonna back off...", victim->id);
 		victim->ai.backoff_x = victim->tank.x;
@@ -205,7 +269,8 @@
 	 * of directions if we are consistently getting stuck in
 	 * one place. */
 	victim->tank.next_angle = fuzzy_angle((mkrand(2) ? 3 : 5)
-	                                      + victim->tank.next_angle);
+	                                      + victim->tank.next_angle,
+					      STUCK_FUZZINESS1, STUCK_FUZZINESS2);
 	AIDEBUG("[%d] backoff new angle %d", victim->id,
 		victim->tank.next_angle);
 }
@@ -224,8 +289,8 @@
 	/* TODO: If home wall in the way, set the target to the home
 	 * corner first. --pasky */
 	bot->ai.flee.home_x = x = bot->tank.home_x;
-	y1 = bot->tank.home_y - gfx_home->sprites[0]->center_y*YPOINTS_PERCHAR;
-	y2 = bot->tank.home_y + gfx_home->sprites[0]->center_y*YPOINTS_PERCHAR;
+	y1 = bot->tank.home_y - gfx_home->directions[0]->frames[0]->center_y*YPOINTS_PERCHAR;
+	y2 = bot->tank.home_y + gfx_home->directions[0]->frames[0]->center_y*YPOINTS_PERCHAR;
 	if (distance(bot->tank.x, bot->tank.y, x, y1)
 	    < distance(bot->tank.x, bot->tank.y, x, y2))
 		bot->ai.flee.home_y = y1;
@@ -237,33 +302,101 @@
 /* State bot_update handlers */
 
 typedef void (*state_hook)(struct _plr_t *bot);
+void bot_idle(struct _plr_t *bot);
+void bot_explore(struct _plr_t *bot);
+void bot_hunt(struct _plr_t *bot);
+void bot_flee(struct _plr_t *bot);
 
 void    bot_idle (struct _plr_t *bot)
 {
-	/* TODO: Switch to AI_EXPLORE when tick_count is zero. */
+	AIDEBUG("[%d] idle.", bot->id);
 	/* *Yawn*. Make sure we aren't madly running around or something. */
 	bot->tank.speed = 0;
 	bot->tank.fire = 0;
-	AIDEBUG("[%d] idle.", bot->id);
+
+	if (--bot->ai.idle.tick_count < 0
+	    && (!surface_calc_collision(&bot->tank.current_pos, G_HOME)
+	        || (bot->tank.energy >= MAX_ENERGY
+	            && bot->tank.shields >= MAX_SHIELDS))) {
+		bot->ai.state = AI_EXPLORE;
+		bot->ai.explore.tick_count = 0;
+	}
+}
+
+void    bot_explore (struct _plr_t *bot)
+{
+	struct _plr_t *enemy;
+	int speed = TANK_SPEED;
+
+	AIDEBUG("[%d] Exploring [%d,%d]->[%d]...", bot->id,
+	        bot->tank.x, bot->tank.y, bot->tank.angle);
+
+	bot->ai.explore.tick_count--;
+
+	/* We are in the middle of our home - get us out! */
+	if (bot->ai.explore.tick_count < 0
+	    && abs(bot->tank.x - bot->tank.home_x) <= 2*XPOINTS_PERCHAR
+	    && abs(bot->tank.y - bot->tank.home_y) <= 1*YPOINTS_PERCHAR) {
+		bot->tank.next_angle = 4 * mkrand(2);
+		bot->ai.explore.tick_count = FPS / 2; /* ?more intelligence! */
+		return;
+	}
+
+	/* Look for an enemy, if not inside home. */
+	if (!(fine_surface(bot->tank.x, bot->tank.y) & G_HOME)) {
+		enemy = find_nearest_enemy(bot);
+		if (enemy) {
+			bot->ai.state = AI_HUNT;
+			bot->ai.hunt.pursuing = enemy;
+			bot_hunt(bot);
+			return;
+		}
+	}
+
+	/* TODO: The exploring routine is quite trivial. We should chose one
+	 * of the already known homes and sometimes head to it. We should
+	 * also make use of already empty space. --pasky */
+
+	if (--bot->ai.explore.tick_count < 0) {
+		bot->ai.explore.tick_count = FPS * (mkrand(40) + 1) / 4;
+
+		bot->tank.next_angle = mkrand(8);
+		/* Try to make the AI less deadly - slow down when turning
+		 * around. */
+		speed /= delta_angle(bot->tank.next_angle, bot->tank.angle) + 1;
+	}
+
+	/* Bhum dhum... */
+	bot->tank.speed = speed;
 }
 
 void    bot_hunt (struct _plr_t *bot)
 {
-	plr_t *victim = bot->ai.hunt.pursuing;
+	plr_t *victim = bot->ai.hunt.pursuing, *victim2;
 	int angle;
 	int speed = TANK_SPEED;
 
 	assert(victim);
 
+	/* Make sure there isn't a much better victim. */
+	victim2 = find_nearest_enemy(bot);
+	if (victim2
+	    && distance(bot->tank.x, bot->tank.y, victim2->tank.x, victim2->tank.y) * RETARGET_RATIO
+	       < distance(bot->tank.x, bot->tank.y, victim->tank.x, victim->tank.y)) {
+		victim = bot->ai.hunt.pursuing = victim2;
+	}
+
 	/* Set the right angle if we didn't yet.
 	 * Possibly change it a bit randomly. */
 	angle = fuzzy_angle(get_angle(bot->tank.x, bot->tank.y,
-	                              victim->tank.x, victim->tank.y));
-	if (angle != bot->tank.angle) {
+	                              victim->tank.x, victim->tank.y),
+	                    HUNT_FUZZINESS1, HUNT_FUZZINESS2);
+	if (angle != bot->tank.angle && bot->ai.last_turnaround > HUNT_TURN_PERIOD) {
 		/* Try to make the AI less deadly - slow down when turning
 		 * around. */
 		speed /= delta_angle(angle, bot->tank.angle) + 1;
 		bot->tank.next_angle = angle;
+		bot->ai.last_turnaround = 0;
 	}
 
 	/* Shooting angle? (We can sometimes hit the tank's corner even from
@@ -347,12 +480,13 @@
 {
 	static const state_hook states[] = {
 		bot_idle,
-		/* bot_explore, */
+		bot_explore,
 		bot_hunt,
 		bot_flee,
 	};
 
 	bot->ai.last_shot++;
+	bot->ai.last_turnaround++;
 
 	if (bot->ai.state != AI_FLEE
 	    && (bot->tank.energy < (in_revenge(bot) ? MIN_REVENGE_ENERGY : MIN_NORMAL_ENERGY)
Index: ai.h
===================================================================
RCS file: /home/cvs/tunneler/tunneler/ai.h,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -r1.1.1.1 -r1.5
--- ai.h	21 Jan 2005 19:21:05 -0000	1.1.1.1
+++ ai.h	21 Jan 2005 22:24:30 -0000	1.5
@@ -9,18 +9,15 @@
  * AI_IDLE:    The bot has nothing to do, staying on a single spot.
  *             It does so until idle_count is zero (it relaxes a little
  *             after it kills an enemy, more realistic) and then
- *             <TODO:>
  *             until it has full energy if it finds inself in a home
  *             and until it has full shields if it finds itself in
  *             own home. Then it switches to the AI_EXPLORE state.
- * AI_EXPLORE: <TODO:>
- *             The bot plays an explorer. It follows either randomly
+ * AI_EXPLORE: The bot plays an explorer. It follows either randomly
  *             laid route or already digged paths, until it sees
  *             any enemy (->AI_HUNT).
  * AI_HUNT:    The bot pursues a chosen enemy and fires at will,
  *             until it kills the victim (->AI_IDLE for a short period).
- * AI_FLEE:    <TODO:>
- *             The bot got to low energy and/or shields.
+ * AI_FLEE:    The bot got to low energy and/or shields.
  *             It heads to the nearest home (if energy) or to its own
  *             home (if shields). Then it goes to AI_IDLE.
  */
@@ -28,16 +25,19 @@
 typedef struct _ai_t {
 	enum ai_state {
 		AI_IDLE,
-		/* AI_EXPLORE, */
+		AI_EXPLORE,
 		AI_HUNT,
 		AI_FLEE,
-		AI_BACKOFF,
 	} state;
 	union {
 		struct {
 			int tick_count;
 		} idle;
 		struct {
+			/* How long to hold direction. */
+			int tick_count;
+		} explore;
+		struct {
 			struct _plr_t *pursuing;
 		} hunt;
 		struct {
@@ -61,6 +61,8 @@
 
 	/* How many ticks ago did we get shot the last time? */
 	long last_shot;
+	/* How many ticks ago did we change angle the last time? */
+	long last_turnaround;
 } AI;
 
 void    hit_ai_hook (struct _plr_t *victim, struct _plr_t *trespasser);
Index: client.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/client.c,v
retrieving revision 1.1.1.3
retrieving revision 1.8
diff -u -r1.1.1.3 -r1.8
--- client.c	21 Jan 2005 19:21:05 -0000	1.1.1.3
+++ client.c	22 Jan 2005 03:11:18 -0000	1.8
@@ -136,14 +136,16 @@
 		exit(EX_UNAVAILABLE);
 	}
 
-	for (lineno = 0; fgets(line, 128, f); lineno++) {
+	for (lineno = 1; fgets(line, 128, f); lineno++) {
 		/* <char><sep><..action..> (<sep> can be anything, usually \t) */
 		/* /^##/ is a comment; blank lines permitted */
 		unsigned char key = *line, *action = line + 2;
 		enum key_action i;
 
-		if (line[0] == '\0') continue; /* blank line */
-		if (line[0] == '#' && line[1] == '#') continue; /* comment */
+		if (line[0] == '\n' || line[0] == '\0' || line[1] == '\0')
+			continue; /* blank line */
+		if (line[0] == '#' && line[1] == '#')
+			continue; /* comment */
 
 		action[strlen(action) - 1] = 0; /* chop */
 		for (i = 0; i < ACT_MAX; i++) {
@@ -358,10 +360,10 @@
 
 	load_kbdbind();
 
-	gfx_obj[0] = load_gfxobj("tank", 8);
-	gfx_obj[1] = load_gfxobj("explosion", 8);
-	gfx_obj[2] = load_gfxobj("bullet", 8);
-	gfx_obj[3] = load_gfxobj("home", 2);
+	gfx_obj[0] = load_gfxobj("tank");
+	gfx_obj[1] = load_gfxobj("explosion");
+	gfx_obj[2] = load_gfxobj("bullet");
+	gfx_obj[3] = load_gfxobj("home");
 
 	uport = atoi(argv[2]);
 	tport = atoi(argv[3]);
Index: game.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/game.c,v
retrieving revision 1.1.1.3
retrieving revision 1.8
diff -u -r1.1.1.3 -r1.8
--- game.c	21 Jan 2005 19:21:06 -0000	1.1.1.3
+++ game.c	22 Jan 2005 03:11:18 -0000	1.8
@@ -59,7 +59,7 @@
 {
 	SPRITE *s;
 
-	s = g->sprites[angle%8];
+	s = g->directions[angle%8]->frames[0];
 	p->sx = x/XPOINTS_PERCHAR - s->center_x;
 	p->sy = y/YPOINTS_PERCHAR - s->center_y;
 	p->angle = angle;
@@ -115,7 +115,7 @@
 
 #define FECHAR(i,j,s) for (j=0; j<s->height; j++) 		\
 			for (i=0; i<s->width; i++) 		\
-			  if (s->sprite[j*s->width+i]&128)
+			  if (!sprite_char_transparent(s->sprite[j*s->width+i]))
 
 _u16	surface_calc_collision(SPOS *s, _u8 flags)
 {
@@ -508,6 +508,31 @@
 
 /****************************************************************************/
 
+void    init_rocks (void)
+{
+#define MAX_RADIUS 8
+	int i;
+
+	for (i = 0; i < 500; i++) {
+		int rx, ry, x, y;
+		int xradius = mkrand(MAX_RADIUS), yradius = mkrand(MAX_RADIUS);
+
+		x = mkrand(SURFACE_WIDTH); y = mkrand(SURFACE_HEIGHT);
+		for (ry = -yradius; ry < yradius; ry++) {
+			for (rx = -xradius; rx < xradius; rx++) {
+				xradius += mkrand(3) - 1; yradius += mkrand(3) - 1;
+				rx += mkrand(3) - 1; ry += mkrand(3) - 1;
+
+				if ((abs(rx*ry) < abs(xradius*yradius))
+				    && (x+rx > 0) && (x+ry > 0)
+				    && (x+rx < SURFACE_WIDTH) && (y+ry < SURFACE_HEIGHT))
+					surface[x+rx][y+ry] = G_STONE;
+			}
+		}
+	}
+#undef MAX_RADIUS
+}
+
 void	init_surface (void)
 {
 	_u16 i, j,n;
@@ -547,6 +572,7 @@
 			surface[SURFACE_WIDTH-j][i] = G_STONE;
 		}
 	}
+	init_rocks();
 	init_list(bullets);
 	init_list(sprites);
 }
Index: game.h
===================================================================
RCS file: /home/cvs/tunneler/tunneler/game.h,v
retrieving revision 1.1.1.2
retrieving revision 1.6
diff -u -r1.1.1.2 -r1.6
--- game.h	21 Jan 2005 19:21:06 -0000	1.1.1.2
+++ game.h	21 Jan 2005 22:24:30 -0000	1.6
@@ -88,6 +88,7 @@
 _u32	mkrand(long max);
 void    tankborder(SPRITE *s, _u16 angle, int *sx, int *sy);
 int     tank_in_region(TANK *tank, int x, int y, int wx, int wy);
+struct _plr_t *find_player_by_xy (_u16 x, _u16 y, _u16 wx, _u16 wy);
 void	conv_angle(_u16 angle, _s16 add, int *ax, int *ay);
 void	conv_coords(int x, int y, int angle, GFXOBJ *g, SPOS *p);
 _u16	surface_calc_collision(SPOS *s, _u8 flags);
Index: server.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/server.c,v
retrieving revision 1.1.1.3
retrieving revision 1.7
diff -u -r1.1.1.3 -r1.7
--- server.c	21 Jan 2005 19:21:06 -0000	1.1.1.3
+++ server.c	22 Jan 2005 03:11:18 -0000	1.7
@@ -398,10 +398,10 @@
 		printf("tunneler server -- 2005, ment\nusage: %s <udp_port> <tcp_port> [opts]\n", argv[0]);
 		exit(1);
 	}
-	gfx_tank = load_gfxobj("tank", 8);
-	gfx_bullet = load_gfxobj("bullet", 8);
-	gfx_explosion = load_gfxobj("explosion", 8);
-	gfx_home = load_gfxobj("home", 2);
+	gfx_tank = load_gfxobj("tank");
+	gfx_bullet = load_gfxobj("bullet");
+	gfx_explosion = load_gfxobj("explosion");
+	gfx_home = load_gfxobj("home");
 
 	srandom(time(NULL));
 
Index: sprite.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/sprite.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- sprite.c	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ sprite.c	22 Jan 2005 03:11:18 -0000	1.2
@@ -1,71 +1,171 @@
+#include <ctype.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
 #include "types.h"
 #include "sprite.h"
 #include "debug.h"
 #include "xmalloc.h"
 
-SPRITE 	*load_sprite(char *filename)
+void	dump_gfx(GFXOBJ *g);
+
+
+#define SKIP_NEWLINES do { char c; while ((c = getc(fr)) == '\n') (*lineno)++; ungetc(c, fr); } while (0)
+
+static SPRITE *
+load_sprite(FILE *fr, unsigned char *fname, int *lineno)
 {
-	FILE 	*fr;
-	char	line[128], *p, c, transchar;
-	int	width, height, cx, cy, lc=0;
+	char	line[128], imglist[9] = "ta", *i, c;
+	int	width = -1, height = -1, cx = -1, cy = -1, x, y;
 	SPRITE 	*s;
 
-	fr = fopen(filename, "r");
-	if (fr == NULL) {
-		printf("cannot open sprite: %s", filename);
-		exit(1);
+	fscanf(fr, "%d %d %d %d", &width, &height, &cx, &cy);
+	while ((c = getc(fr)) == ' ' || c == '\t');
+	if (c && isalpha(c) && c != '\n') {
+		i = imglist;
+		do {
+			*(i++) = c;
+		} while (isalpha(c = getc(fr)) && (i - imglist) < 9);
+		*i = '\0';
+		ungetc(c, fr);
 	}
+	(*lineno)++;
 
-	fscanf(fr, "%c %d %d %d %d", &transchar, &width, &height, &cx, &cy);
-	DEBUG("nacitam sprajt %d*%d center %d*%d transparentni %c", width, height, cx, cy, transchar);
-	while((c=getc(fr)) == '\n');
-	ungetc(c, fr);
+	DEBUG("nacitam sprajt %d*%d center %d*%d, imidze %s", width, height, cx, cy, imglist);
+	if (width < 0 || height < 0 || cx < 0 || cy < 0) {
+		fprintf(stderr, "%s:%d: Parse error.\n", fname, (*lineno) - 1);
+		exit(1);
+	}
 
-	s = (SPRITE *) ALLOC(sizeof(SPRITE)-1+width*height);
+	s = (SPRITE *) ALLOC(sizeof(SPRITE)-1+(width*height)*sizeof(struct sprite_char));
 	s->width = width;
 	s->height = height;
 	s->center_x = cx;
 	s->center_y = cy;
-	while(fgets(line, 127, fr) && height--) {
-		for (p = line; *p; p++)
-			if (*p != transchar)
-				*p |= 128;
-		strncpy(s->sprite+(lc++)*width, line, width);
+
+	for (i = imglist; *i; i++) {
+		SKIP_NEWLINES;
+		for (y = 0; y < s->height && fgets(line, 127, fr); y++) {
+			int l = strlen(line) - 1;
+
+			(*lineno)++;
+			//DEBUG("[%c]-> %s", *i, line);
+
+			/* TODO: Optimizable. */
+			for (x = 0; x < s->width; x++) {
+				struct sprite_char *c = &s->sprite[width * y + x];
+
+				switch (*i) {
+				case 't':
+					if (x >= l)
+						c->text = ' ';
+					else
+						c->text = line[x];
+					break;
+
+				case 'a':
+					if (x >= l)
+						c->attr = SCA_TRANSPARENT;
+					else
+						switch (line[x]) {
+						case '|': c->attr = SCA_NORMAL; break;
+						case '#': c->attr = SCA_STANDOUT; break;
+						case '.': c->attr = SCA_TRANSPARENT; break;
+						case ':': c->attr = SCA_TRANSLUCENT; break;
+						default:  c->attr = isupper(line[x]) ? SCA_BRIGHTCOLOR : SCA_DARKCOLOR;
+							switch (tolower(line[x])) {
+							case 'k': c->color = 0; break;
+							case 'r': c->color = 1; break;
+							case 'g': c->color = 2; break;
+							case 'y': c->color = 3; break;
+							case 'b': c->color = 4; break;
+							case 'm': c->color = 5; break;
+							case 'c': c->color = 6; break;
+							case 'h': c->color = 7; break;
+							default:
+								fprintf(stderr, "%s:%d: Invalid attribute '%c'.\n",
+								        fname, *lineno, line[x]);
+								exit(1);
+							}
+						}
+					break;
+
+				default:
+					fprintf(stderr, "%s:%d: Invalid image type '%c'.\n", fname, *lineno, *i);
+					exit(1);
+				}
+			}
+		}
 	}
 
-	fclose(fr);
 	return s;
 }
 
-GFXOBJ	*load_gfxobj(char *name, _u16 n)
+static SPRITESET *
+load_spritegroup(FILE *fr, unsigned char *fname, int *lineno)
 {
-	GFXOBJ 	*g = (GFXOBJ *) ALLOC(sizeof(GFXOBJ)+(n-1)*sizeof(SPRITE *));
-	char 	filename[256];
-	int 	i;
+	SPRITESET *sg;
+	int 	n, i;
+
+	fscanf(fr, "%d %*s", &n); (*lineno)++;
+	SKIP_NEWLINES;
 
-	DEBUG("loading gfx obj named '%s' with %d pictures", name, n);
+	sg = ALLOC(sizeof(SPRITESET) + (n - 1) * sizeof(SPRITE *));
+	sg->n = n;
 	for (i=0; i<n; i++) {
-		snprintf(filename, 255, "sprites/%s.%d", name, i);
-		g->sprites[i] = load_sprite(filename);
+		sg->frames[i] = load_sprite(fr, fname, lineno);
+	}
+	return sg;
+}
+
+GFXOBJ	*load_gfxobj(char *name)
+{
+	FILE 	*fr;
+	GFXOBJ 	*g;
+	char 	filename[256];
+	int 	n, i;
+	int     lno = 1;
+	int     *lineno = &lno;
+
+	snprintf(filename, 255, "sprites/%s", name);
+	fr = fopen(filename, "r");
+	if (fr == NULL) {
+		perror(filename);
+		exit(1);
 	}
+
+	DEBUG("loading gfx obj named '%s'", name);
+	fscanf(fr, "%d %*s", &n); (*lineno)++;
+	SKIP_NEWLINES;
+
+	g = ALLOC(sizeof(GFXOBJ) + (n - 1) * sizeof(SPRITESET *));
 	g->n = n;
+	for (i=0; i<n; i++) {
+		g->directions[i] = load_spritegroup(fr, name, lineno);
+	}
+	fclose(fr);
+	/* dump_gfx(g); */
 	return g;
 }
 
+
+
+#if 0
+
 void	dump_sprite(SPRITE *s)
 {
 	int i, j;
-	char c;
 	for (j=0; j<s->height; j++) {
 		for (i=0; i<s->width; i++) {
-			c = s->sprite[s->width*j+i];
-			if (c&128) 
-				printf("%c", c&127);
+			struct sprite_char c = s->sprite[s->width*j+i];
+			static const char cc[] = "krgybmch";
+			printf("%c", c.text);
+			if (c.attr == SCA_DARKCOLOR)
+				printf("[%c]", cc[(int) c.color]);
+			else if (c.attr == SCA_BRIGHTCOLOR)
+				printf("[%c]", toupper(cc[(int) c.color]));
 			else
-				printf(".");
+				printf("[%d]", c.attr);
 		}
 		putchar('\n');
 	}
@@ -74,11 +174,17 @@
 void	dump_gfx(GFXOBJ *g)
 {
 	int i;
-	DEBUG("dumping gfx obj with %d sprites", g->n);
+	DEBUG("dumping gfx obj with %d directions", g->n);
 	for (i=0; i<g->n; i++) {
-		printf("-- sprite %d\n", i);
-		dump_sprite(g->sprites[i]);
+		int j;
+
+		printf("-- direction %d\n", i);
+		for (j=0; j<g->directions[i]->n; j++) {
+			printf("-- frame %d\n", i);
+			dump_sprite(g->directions[i]->frames[j]);
+		}
 	}
 	printf("-- end of dump\n");
 }
 
+#endif
Index: sprite.h
===================================================================
RCS file: /home/cvs/tunneler/tunneler/sprite.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- sprite.h	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ sprite.h	22 Jan 2005 03:11:18 -0000	1.2
@@ -2,18 +2,40 @@
 #define __INCLUDED_SPRITE_H
 #include "types.h"
 
+struct sprite_char {
+	char text;
+	enum {
+		SCA_NORMAL,
+		SCA_STANDOUT,
+		SCA_TRANSPARENT,
+		SCA_TRANSLUCENT,
+		SCA_DARKCOLOR,
+		SCA_BRIGHTCOLOR,
+	} attr:3;
+	/* As in the escape sequence: black,red,green,brown,blue,magenta,cyan,white. */
+	unsigned char color:3;
+};
+
+#define sprite_char_transparent(c) (c.attr == SCA_TRANSPARENT || c.attr == SCA_TRANSLUCENT)
+
 typedef struct {
 	_u16	width, height;	
 	_u16	center_x, center_y;
-	_u8	sprite[1];
+	struct sprite_char sprite[1];
 } SPRITE;
 
 typedef struct {
+	_u16    n;
+	/* XXX: Only single frame per direction supported for now. */
+	SPRITE  *frames[1];
+} SPRITESET;
+
+typedef struct {
 	_u16	n;
-	SPRITE	*sprites[1];
+	SPRITESET *directions[1];
 } GFXOBJ;
 
 extern	GFXOBJ	*gfx_tank, *gfx_bullet, *gfx_explosion, *gfx_home;
-GFXOBJ	*load_gfxobj(char *name, _u16 n);
+GFXOBJ	*load_gfxobj(char *name);
 
 #endif
Index: term.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/term.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- term.c	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ term.c	22 Jan 2005 00:08:53 -0000	1.2
@@ -14,10 +14,12 @@
 	newflags.c_lflag &= ~(ICANON | ECHO);
 	newflags.c_iflag &= ~(IXON | IXOFF);
 	tcsetattr(0, TCSAFLUSH, &newflags);
+	printf("\0337"); /* Save terminal. */
 }
 
 void	cleanup_term(void)
 {
+	printf("\0338"); /* Restore terminal. */
 	tcsetattr(0, TCSAFLUSH, &oldflags);
 }
 
Index: virtual.c
===================================================================
RCS file: /home/cvs/tunneler/tunneler/virtual.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- virtual.c	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ virtual.c	22 Jan 2005 03:11:18 -0000	1.2
@@ -16,24 +16,31 @@
 {
 	SPRITE *s;
 	_u16 	i, j;
-	_u8 	c;
+	struct sprite_char c;
 
-	s = sprite->sprites[state];
+	s = sprite->directions[state]->frames[0];
 	//DEBUG("draw x:%d y:%d state:%d h:%d", sx, sy, state, s->height);
 	for (j=0; j<s->height; j++) {
 		//DEBUG("j %d s %d V %d", j, sy, VIEWPNT_HEIGHT);
 		if (j+sy < 0 || j+sy >= VIEWPNT_HEIGHT)
 			continue;
 		for (i=0; i<s->width; i++) {
+			int vsx = (j+sy)*VIEWPNT_WIDTH+i+sx;
+
 			if (i+sx < 0 || i+sx >= VIEWPNT_WIDTH)
 				continue;
 			c = s->sprite[j*s->width+i];
-			//DEBUG("%x", c);
-			if (c&128) {
-				virtual_screen[(j+sy)*VIEWPNT_WIDTH+i+sx][0] = c&127;
-				virtual_screen[(j+sy)*VIEWPNT_WIDTH+i+sx][1] = color;
+			//DEBUG("%c/%d/%d", c.text, c.attr, c.color);
+			if (!sprite_char_transparent(c))
+				virtual_screen[vsx][0] = c.text;
+			switch (c.attr) {
+				case SCA_NORMAL:      virtual_screen[vsx][1] = color; break;
+				case SCA_STANDOUT:    virtual_screen[vsx][1] = color^8; break;
+				case SCA_TRANSPARENT: break;
+				case SCA_TRANSLUCENT: virtual_screen[vsx][1] &= ~8; break;
+				case SCA_DARKCOLOR:   virtual_screen[vsx][1] = c.color; break;
+				case SCA_BRIGHTCOLOR: virtual_screen[vsx][1] = c.color|8; break;
 			}
-
 		}
 	}
 }
Index: sprites/README
===================================================================
RCS file: sprites/README
diff -N sprites/README
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sprites/README	22 Jan 2005 03:11:18 -0000	1.1
@@ -0,0 +1,40 @@
+Here comes description of the sprites format:
+
+<anything> ... really anything up to the end of line
+<num:> ....... decimal number
+<str:images> . list of images to follow, one per character, in that order:
+               't' - text              'a' - attr
+               'b' - background (TODO)
+               Default is "ta" if unspecified.
+<img:text> ... text to be displayed, verbatim (missing chars = ' ')
+<img:attr> ... attributes corresponding to the given position
+               (missing chars = '|'):
+               '.' - transparent       ':' - translucent (darkening)
+               '|' - current color normal
+               '#' - current color standout (opposite intensity)
+               Dark colors:
+               'r' - red               'c' - cyan
+               'g' - green             'm' - magenta
+               'b' - blue              'y' - yellow
+               'h' - grey              'k' - black
+               Equivalent bright colors:
+               'RGBHCMYK'
+
+Blank lines are permitted except inside of images.
+
+
+The file:
+
+<num:directions> <anything>
+Nx<direction>
+
+<direction>:
+
+<num:frames> <anything>
+Nx<frame>
+
+<frame>:
+
+<num:width> <num:height> <num:center_x> <num:center_y> [<str:images>]
+<img:text>
+<img:attr>
Index: sprites/bullet
===================================================================
RCS file: sprites/bullet
diff -N sprites/bullet
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sprites/bullet	22 Jan 2005 03:11:18 -0000	1.1
@@ -0,0 +1,47 @@
+8 directions
+
+1 frame
+1 2 0 1 t
+|
+^
+
+1 frame
+2 2 0 1
+ /
+'
+.|
+|.
+
+1 frame
+3 1 0 0 t
+>--
+
+1 frame
+2 2 0 0
+.
+ \
+|.
+.|
+
+1 frame
+1 2 0 0 t
+v
+|
+
+1 frame
+2 2 1 0
+ .
+/
+.|
+|.
+
+1 frame
+3 1 2 0 t
+--<
+
+1 frame
+2 2 1 1
+\
+ `
+|.
+.|
Index: sprites/bullet.0
===================================================================
RCS file: sprites/bullet.0
diff -N sprites/bullet.0
--- sprites/bullet.0	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 1 2 0 1
-|
-^
Index: sprites/bullet.1
===================================================================
RCS file: sprites/bullet.1
diff -N sprites/bullet.1
--- sprites/bullet.1	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 2 2 0 1
-x/ 
-'x  
Index: sprites/bullet.2
===================================================================
RCS file: sprites/bullet.2
diff -N sprites/bullet.2
--- sprites/bullet.2	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2 +0,0 @@
-x 3 1 0 0
->--
Index: sprites/bullet.3
===================================================================
RCS file: sprites/bullet.3
diff -N sprites/bullet.3
--- sprites/bullet.3	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 2 2 0 0
-.x 
-x\
Index: sprites/bullet.4
===================================================================
RCS file: sprites/bullet.4
diff -N sprites/bullet.4
--- sprites/bullet.4	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 1 2 0 0
-v
-|
Index: sprites/bullet.5
===================================================================
RCS file: sprites/bullet.5
diff -N sprites/bullet.5
--- sprites/bullet.5	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 2 2 1 0
-x.
-/x
Index: sprites/bullet.6
===================================================================
RCS file: sprites/bullet.6
diff -N sprites/bullet.6
--- sprites/bullet.6	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2 +0,0 @@
-x 3 1 2 0
---<
Index: sprites/bullet.7
===================================================================
RCS file: sprites/bullet.7
diff -N sprites/bullet.7
--- sprites/bullet.7	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,3 +0,0 @@
-x 2 2 1 1
-\x  
-x`
Index: sprites/explosion
===================================================================
RCS file: sprites/explosion
diff -N sprites/explosion
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sprites/explosion	22 Jan 2005 03:11:18 -0000	1.1
@@ -0,0 +1,119 @@
+8 directions
+
+1 frame
+6 4 2 1
+ $(## 
+*( )$@
+!&#$4#
+ !(%& 
+.rrRr.
+rR.rRr
+RrRYrR
+.rrRr.
+
+1 frame
+6 4 2 1
+ $(* !
+*( )# 
+ &$*(#
+)!( & 
+.rRr.R
+Rr.YR.
+.RrRRr
+rrR.r.
+
+1 frame
+8 6 3 2
+  ____  
+ #$@#%% 
+ -#$ $%@
+-@#$^@^-
+ )!($-% 
+  ~  ~  
+..RrRr..
+.rRrrRr.
+.rRR.rRr
+rRrRrRrR
+.rRrRrr.
+..r..y..
+
+1 frame
+8 6 3 2
+ ~-_~_~ 
+( $(  !(
+)  @ # )
+(!~  (#(
+) !($  )
+ ~~_-~~ 
+.RryrRy.
+r.Rr..rR
+R..r.R.r
+rRr..rYR
+r.rRR..r
+.rRyRyr.
+
+1 frame
+9 5 3 2
+ zzzzzzz 
+z %z Qzzz
+zzQzz5zQ 
+ z#z%zQzz
+ zzz z z 
+.yyryrRy.
+y.rR.RryR
+ryRrRrrR.
+.RrrRrRry
+.ryR.r.y.
+
+1 frame
+12 6 5 3
+   .z q.z
+ zqz.zq z..
+. qz zz zqqz
+zz zqz z zq.
+ .qzz zqz z
+   z qz..
+...ry.ryh
+.hyryry.ryr
+y.ry.Rr.yrry
+ry.Ryr.R.yyr
+.rryr.Rry.h
+...h.ryyr
+
+1 frame
+15 8 7 4
+  .. ,,.. .,   
+ ...   ..  ... 
+.,,''..'.'  ...
+..,, .'..,'....
+,  ..'','  '  .
+...''...,..'.. 
+  ..,'.  '..'' 
+   ...'''...   
+..hr.yryy.ry...
+.yry...yr..rrh.
+hryrrryryr..yrh
+ryry.|rRrryrryy
+y..rRrRRr..y..h
+rhyyrRrrRryrry.
+..ryryr..yryhy.
+...hyrhhyhyr...
+
+1 frame
+15 8 7 3
+   ...   ...   
+ ............. 
+.....   .. ..  
+..   ..........
+........    ...
+..  ... ..... .
+ .....    .... 
+   ....... .   
+...hhy...hyh...
+.hhyhryhryhyhh.
+hryhr...yh.rh..
+hh...yhryhyhyhh
+yhyryhyr....yrh
+hh..yrh.yhyrh.h
+.hhrhy....rhyh.
+...yhhyhhr.h...
Index: sprites/explosion.0
===================================================================
RCS file: sprites/explosion.0
diff -N sprites/explosion.0
--- sprites/explosion.0	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-| 6 4 2 1
-|$(##|
-*(|)$@
-!&#$4#
-|!(%&|
Index: sprites/explosion.1
===================================================================
RCS file: sprites/explosion.1
diff -N sprites/explosion.1
--- sprites/explosion.1	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-| 6 4 2 1
-|$(*|!
-*(|)#|
-|&$*(#
-)!(|&|
Index: sprites/explosion.2
===================================================================
RCS file: sprites/explosion.2
diff -N sprites/explosion.2
--- sprites/explosion.2	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,7 +0,0 @@
-| 8 6 3 2
-||____||
-|#$@#%%|
-|-#$|$%@
--@#$^@^-
-|)!($-%|
-||~||~||
Index: sprites/explosion.3
===================================================================
RCS file: sprites/explosion.3
diff -N sprites/explosion.3
--- sprites/explosion.3	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,7 +0,0 @@
-| 8 6 3 2
-|~-_~_~|
-(|$(||!(
-)||@|#|)
-(!~||(#(
-)|!($||)
-|~~_-~~|
Index: sprites/explosion.4
===================================================================
RCS file: sprites/explosion.4
diff -N sprites/explosion.4
--- sprites/explosion.4	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,6 +0,0 @@
-| 9 5 3 2
-|zzzzzzz|
-z|%z|Qzzz
-zzQzz5zQ|
-|z#z%zQzz
-|zzz|z|z|
Index: sprites/explosion.5
===================================================================
RCS file: sprites/explosion.5
diff -N sprites/explosion.5
--- sprites/explosion.5	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,6 +0,0 @@
-| 9 5 3 2
-|z||zzzz|
-zzzzq|zzz
-z|qzzzzqz
-zzzzq|zzz
-|zz|z|zz|
Index: sprites/explosion.6
===================================================================
RCS file: sprites/explosion.6
diff -N sprites/explosion.6
--- sprites/explosion.6	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,9 +0,0 @@
-| 15 8 7 3
-||..|,,..|.,|||
-|...|||..||...|
-.,,''..'.'||...
-..,,|.'..,'....
-,||..'','||'||.
-...''...,..'..|
-||..,'.||'..''|
-|||...'''...|||
Index: sprites/explosion.7
===================================================================
RCS file: sprites/explosion.7
diff -N sprites/explosion.7
--- sprites/explosion.7	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,9 +0,0 @@
-| 15 8 7 3
-|||...|||...|||
-|.............|
-.....|||..|..||
-..|||..........
-........||||...
-..||...|.....|.
-|.....||||....|
-|||.......|.|||
Index: sprites/home
===================================================================
RCS file: sprites/home
diff -N sprites/home
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sprites/home	22 Jan 2005 03:11:18 -0000	1.1
@@ -0,0 +1,43 @@
+2 directions
+
+1 frame
+27 14 14 6
+.-------.:::::::::.-------.
+| x   __|:::::::::|__   x |
+|   /':::::::::::::::`\   |
+| /':::::::::::::::::::`\ |
+||:::::::::::::::::::::::||
+||:::::::::::::::::::::::||
+||:::::::::::::::::::::::||
+||:::::::::::::::::::::::||
+||:::::::::::::::::::::::||
+||:::::::::::::::::::::::||
+| \:::::::::::::::::::::/'|
+|  `\:::::::::::::::::/'  |
+| x  `~~|:::::::::|~~'  x |
+`-------':::::::::`-------'
+|||||||||.........|||||||||
+||#||||||.........||||||#||
+||||||...............||||||
+||||...................||||
+||.......................||
+||.......................||
+||.......................||
+||.......................||
+||.......................||
+||.......................||
+|||.....................|||
+|||||.................|||||
+||#||||||.........||||||#||
+|||||||||.........|||||||||
+
+1 frame
+9 4 4 1
+.-------.
+:ferda:::
+:zametac:
+`-------'
+|||||||||
+|#####|||
+|#######|
+|||||||||
Index: sprites/home.0
===================================================================
RCS file: sprites/home.0
diff -N sprites/home.0
--- sprites/home.0	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,15 +0,0 @@
-: 27 14 14 6
-.-------.:::::::::.-------.
-|     __|:::::::::|__     |
-|   /':::::::::::::::`\   |
-| /':::::::::::::::::::`\ |
-||:::::::::::::::::::::::||
-||:::::::::::::::::::::::||
-||:::::::::::::::::::::::||
-||:::::::::::::::::::::::||
-||:::::::::::::::::::::::||
-||:::::::::::::::::::::::||
-| \:::::::::::::::::::::/'|
-|  `\:::::::::::::::::/'  |
-|    `~~|:::::::::|~~'    |
-`-------':::::::::`-------'
Index: sprites/home.1
===================================================================
RCS file: sprites/home.1
diff -N sprites/home.1
--- sprites/home.1	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 9 4 4 1
-.-------.
-:ferda:::
-:zametac:
-`-------'
Index: sprites/tank
===================================================================
RCS file: sprites/tank
diff -N sprites/tank
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ sprites/tank	22 Jan 2005 03:11:18 -0000	1.1
@@ -0,0 +1,85 @@
+8 directions
+
+1 frame
+5 4 2 2
+ _|_
+| | |
+|[o]|
+`---'
+.|||.
+|||||
+||#||
+|||||
+
+1 frame
+6 4 2 2
+  /\ /
+/' /`\
+\ ~ /'
+ `-'
+..||.|
+||||||
+||#|||
+.|||..
+
+1 frame
+7 3 2 1
+.----.
+|[o]---
+`----'
+||||||.
+||#||||
+||||||.
+
+1 frame
+7 4 3 2
+  /\
+/`  `\
+`\ ~\/'
+  `-'`\
+..||...
+||||||.
+|||#|||
+..|||||
+
+1 frame
+5 4 2 1
+.---.
+|[o]|
+| | |
+ ~|~
+|||||
+||#||
+|||||
+.|||.
+
+1 frame
+7 4 3 2
+   /\
+ /'  `\
+`\/~ /'
+/'`-'
+...||..
+.||||||
+|||#|||
+|||||..
+
+1 frame
+7 3 4 1
+ .----.
+---[o]|
+ `----'
+.||||||
+||||#||
+.||||||
+
+1 frame
+7 4 3 2
+\ /\
+/`\ `\
+`\ ~ /'
+  `-'
+|.||...
+||||||.
+|||#|||
+..|||..
Index: sprites/tank.0
===================================================================
RCS file: sprites/tank.0
diff -N sprites/tank.0
--- sprites/tank.0	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 5 4 2 2
-x_|_x     
-| | |
-|[o]|
-`---'
Index: sprites/tank.1
===================================================================
RCS file: sprites/tank.1
diff -N sprites/tank.1
--- sprites/tank.1	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 6 4 2 2
-xx/\ / 
-/' /`\ 
-\ ~ /'  
-x`-'xx  
Index: sprites/tank.2
===================================================================
RCS file: sprites/tank.2
diff -N sprites/tank.2
--- sprites/tank.2	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,4 +0,0 @@
-x 7 3 2 1
-.----.x 
-|[o]---
-`----'x
Index: sprites/tank.3
===================================================================
RCS file: sprites/tank.3
diff -N sprites/tank.3
--- sprites/tank.3	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 7 4 3 2
-xx/\xxx
-/`  `\x 
-`\ ~\/' 
-xx`-'`\    
Index: sprites/tank.4
===================================================================
RCS file: sprites/tank.4
diff -N sprites/tank.4
--- sprites/tank.4	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 5 4 2 1
-.---.
-|[o]|
-| | |
-x~|~x   
Index: sprites/tank.5
===================================================================
RCS file: sprites/tank.5
diff -N sprites/tank.5
--- sprites/tank.5	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 7 4 3 2
-xxx/\xx  
-x/'  `\ 
-`\/~ /'  
-/'`-'xx   
Index: sprites/tank.6
===================================================================
RCS file: sprites/tank.6
diff -N sprites/tank.6
--- sprites/tank.6	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,4 +0,0 @@
-x 7 3 4 1
-x.----.
----[o]|
-x`----'
Index: sprites/tank.7
===================================================================
RCS file: sprites/tank.7
diff -N sprites/tank.7
--- sprites/tank.7	20 Jan 2005 17:39:53 -0000	1.1.1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,5 +0,0 @@
-x 7 4 3 2
-\ /\xxx  
-/`\ `\x  
-`\ ~ /' 
-xx`-'xx    
