diff --git a/data/foo_fighter b/data/foo_fighter
index 962546d..4833d0f 100644
--- a/data/foo_fighter
+++ b/data/foo_fighter
@@ -19,11 +19,11 @@ dddededdd
    ddd
 9 2 4 0
  ,-oXo-.
-'   V   `
+'  `V'  `
  ddededd
-d   d   d
+d  ddd  d
 7 2 3 0
  ,oXo.
-/  V  \
+/ `V' \
  deded
-d  d  d
+d ddd d
diff --git a/libee/box.c b/libee/box.c
index 6dc197c..2a4defe 100644
--- a/libee/box.c
+++ b/libee/box.c
@@ -67,7 +67,7 @@ void ee_draw_thin_box(int x1, int y1, int x2, int y2)
         for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++)
             ee_putchar(x, y1, '-');
 
-    if(y2 < ymax)
+    if(y2 <= ymax)
         for(x = x1 < 0 ? 1 : x1 + 1; x < x2 && x < xmax; x++)
             ee_putchar(x, y2, '-');
 
@@ -75,7 +75,7 @@ void ee_draw_thin_box(int x1, int y1, int x2, int y2)
         for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++)
             ee_putchar(x1, y, '|');
 
-    if(x2 < xmax)
+    if(x2 <= xmax)
         for(y = y1 < 0 ? 1 : y1 + 1; y < y2 && y < ymax; y++)
             ee_putchar(x2, y, '|');
 
diff --git a/libee/ee.h b/libee/ee.h
index 38b27ef..a2a1822 100644
--- a/libee/ee.h
+++ b/libee/ee.h
@@ -20,6 +20,14 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+#ifndef __EE_H__
+#define __EE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
 /*
  * Colors
  */
@@ -51,13 +59,16 @@ void ee_end(void);
 
 char ee_get_key(void);
 
-void ee_color(int);
+void ee_set_color(int);
+int ee_get_color(void);
 void ee_putchar(int, int, char);
 void ee_putstr(int, int, char *);
 void ee_clear(void);
 
 void ee_draw_line(int, int, int, int, char);
+void ee_draw_polyline(int[], int[], int, char);
 void ee_draw_thin_line(int, int, int, int);
+void ee_draw_thin_polyline(int[], int[], int);
 
 void ee_draw_circle(int, int, int, char);
 void ee_draw_ellipse(int, int, int, int, char);
@@ -76,8 +87,16 @@ int ee_rand(int, int);
 int ee_sqrt(int);
 
 struct ee_sprite * ee_load_sprite(const char *);
-void ee_set_sprite_frame(struct ee_sprite *, int);
-int ee_get_sprite_frame(struct ee_sprite *);
-void ee_draw_sprite(int, int, struct ee_sprite *);
+int ee_get_sprite_frames(struct ee_sprite *);
+int ee_get_sprite_width(struct ee_sprite *, int);
+int ee_get_sprite_height(struct ee_sprite *, int);
+int ee_get_sprite_dx(struct ee_sprite *, int);
+int ee_get_sprite_dy(struct ee_sprite *, int);
+void ee_draw_sprite(int, int, struct ee_sprite *, int);
 void ee_free_sprite(struct ee_sprite *);
 
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EE_H__ */
diff --git a/libee/graphics.c b/libee/graphics.c
index 58bedc5..3fd0938 100644
--- a/libee/graphics.c
+++ b/libee/graphics.c
@@ -33,8 +33,11 @@
 
 #include "ee.h"
 
-void ee_color(int color)
+static int ee_color = 0;
+
+void ee_set_color(int color)
 {
+    ee_color = color;
 #ifdef USE_SLANG
     SLsmg_set_color(color);
 #elif USE_NCURSES
@@ -44,6 +47,11 @@ void ee_color(int color)
 #endif
 }
 
+int ee_get_color(void)
+{
+    return ee_color;
+}
+
 void ee_putchar(int x, int y, char c)
 {
 #ifdef USE_SLANG
diff --git a/libee/line.c b/libee/line.c
index 49e4418..c2e79f9 100644
--- a/libee/line.c
+++ b/libee/line.c
@@ -68,6 +68,23 @@ void ee_draw_line(int x1, int y1, int x2, int y2, char c)
     clip_line(&s);
 }
 
+void ee_draw_polyline(int x[], int y[], int n, char c)
+{
+    int i;
+    struct line s;
+    s.c = c;
+    s.draw = draw_solid_line;
+
+    for(i = 0; i < n; i++)
+    {
+        s.x1 = x[i];
+        s.y1 = y[i];
+        s.x2 = x[i+1];
+        s.y2 = y[i+1];
+        clip_line(&s);
+    }
+}
+
 /**
  * \brief Draw a thin line on the screen, using ASCII art.
  *
@@ -88,6 +105,22 @@ void ee_draw_thin_line(int x1, int y1, int x2, int y2)
     clip_line(&s);
 }
 
+void ee_draw_thin_polyline(int x[], int y[], int n)
+{
+    int i;
+    struct line s;
+    s.draw = draw_thin_line;
+
+    for(i = 0; i < n; i++)
+    {
+        s.x1 = x[i];
+        s.y1 = y[i];
+        s.x2 = x[i+1];
+        s.y2 = y[i+1];
+        clip_line(&s);
+    }
+}
+
 /*
  * XXX: The following functions are local.
  */
diff --git a/libee/sprite.c b/libee/sprite.c
index c613120..3935070 100644
--- a/libee/sprite.c
+++ b/libee/sprite.c
@@ -44,7 +44,6 @@ struct ee_frame
 
 struct ee_sprite
 {
-    int f;
     int nf;
     struct ee_frame *frames;
 };
@@ -60,7 +59,6 @@ struct ee_sprite *ee_load_sprite(const char *file)
         return NULL;
 
     sprite = malloc(sizeof(struct ee_sprite));
-    sprite->f = 0;
     sprite->nf = 0;
     sprite->frames = NULL;
 
@@ -136,34 +134,72 @@ struct ee_sprite *ee_load_sprite(const char *file)
     return sprite;
 }
 
-void ee_set_sprite_frame(struct ee_sprite *sprite, int f)
+int ee_get_sprite_frames(struct ee_sprite *sprite)
 {
     if(sprite == NULL)
-        return;
+        return 0;
+
+    return sprite->nf;
+}
+
+int ee_get_sprite_width(struct ee_sprite *sprite, int f)
+{
+    if(sprite == NULL)
+        return 0;
 
     if(f < 0 || f >= sprite->nf)
-        return;
+        return 0;
+
+    return sprite->frames[f].w;
+}
+
+int ee_get_sprite_height(struct ee_sprite *sprite, int f)
+{
+    if(sprite == NULL)
+        return 0;
+
+    if(f < 0 || f >= sprite->nf)
+        return 0;
 
-    sprite->f = f;
+    return sprite->frames[f].h;
 }
 
-int ee_get_sprite_frame(struct ee_sprite *sprite)
+int ee_get_sprite_dx(struct ee_sprite *sprite, int f)
 {
     if(sprite == NULL)
-        return -1;
+        return 0;
 
-    return sprite->f;
+    if(f < 0 || f >= sprite->nf)
+        return 0;
+
+    return sprite->frames[f].dx;
+}
+
+int ee_get_sprite_dy(struct ee_sprite *sprite, int f)
+{
+    if(sprite == NULL)
+        return 0;
+
+    if(f < 0 || f >= sprite->nf)
+        return 0;
+
+    return sprite->frames[f].dy;
 }
 
-void ee_draw_sprite(int x, int y, struct ee_sprite *sprite)
+void ee_draw_sprite(int x, int y, struct ee_sprite *sprite, int f)
 {
-    int i, j;
+    int i, j, oldcol;
     struct ee_frame *frame;
 
     if(sprite == NULL)
         return;
 
-    frame = &sprite->frames[sprite->f];
+    if(f < 0 || f >= sprite->nf)
+        return;
+
+    frame = &sprite->frames[f];
+
+    oldcol = ee_get_color();
 
     for(j = 0; j < frame->h; j++)
     {
@@ -172,12 +208,14 @@ void ee_draw_sprite(int x, int y, struct ee_sprite *sprite)
             int col = frame->color[frame->w * j + i];
             if(col >= 0)
             {
-                ee_color(col);
+                ee_set_color(col);
                 ee_putchar(x + i - frame->dx, y + j - frame->dy,
                            frame->chars[frame->w * j + i]);
             }
         }
     }
+
+    ee_set_color(oldcol);
 }
 
 void ee_free_sprite(struct ee_sprite *sprite)
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b4fbc2..6c030a4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,7 @@ ttyvaders_SOURCES = \
 	collide.c \
 	common.h \
 	explosions.c \
+	intro.c \
 	main.c \
 	overlay.c \
 	player.c \
diff --git a/src/aliens.c b/src/aliens.c
index 74ebad5..6292796 100644
--- a/src/aliens.c
+++ b/src/aliens.c
@@ -26,10 +26,6 @@
 
 #include "common.h"
 
-static void draw_alien_foo(game *, int, int, int);
-static void draw_alien_bar(game *, int, int, int);
-static void draw_alien_baz(game *, int, int, int);
-
 struct ee_sprite *foo_sprite;
 struct ee_sprite *bar_sprite;
 struct ee_sprite *baz_sprite;
@@ -57,13 +53,13 @@ void draw_aliens(game *g, aliens *al)
         switch(al->type[i])
         {
             case ALIEN_FOO:
-                draw_alien_foo(g, al->x[i], al->y[i], al->img[i] % 8);
+                ee_draw_sprite(al->x[i], al->y[i], foo_sprite, al->img[i] % 8);
                 break;
             case ALIEN_BAR:
-                draw_alien_bar(g, al->x[i], al->y[i], al->img[i] % 2);
+                ee_draw_sprite(al->x[i], al->y[i], bar_sprite, al->img[i] % 2);
                 break;
             case ALIEN_BAZ:
-                draw_alien_baz(g, al->x[i], al->y[i], al->img[i] % 6);
+                ee_draw_sprite(al->x[i], al->y[i], baz_sprite, al->img[i] % 6);
                 break;
             case ALIEN_NONE:
                 break;
@@ -138,22 +134,3 @@ void add_alien(game *g, aliens *al, int x, int y, int type)
     }
 }
 
-static void draw_alien_bar(game *g, int x, int y, int frame)
-{
-    ee_set_sprite_frame(bar_sprite, frame);
-    ee_draw_sprite(x, y, bar_sprite);
-}
-
-static void draw_alien_baz(game *g, int x, int y, int frame)
-{
-    ee_set_sprite_frame(baz_sprite, frame);
-    ee_draw_sprite(x, y, baz_sprite);
-}
-
-static void draw_alien_foo(game *g, int x, int y, int frame)
-{
-    ee_set_sprite_frame(foo_sprite, frame);
-    ee_draw_sprite(x, y, foo_sprite);
-}
-
-
diff --git a/src/bonus.c b/src/bonus.c
index 75d3178..8b9b6c2 100644
--- a/src/bonus.c
+++ b/src/bonus.c
@@ -51,12 +51,12 @@ void draw_bonus(game *g, bonus *bo)
         switch(bo->type[i])
         {
             case BONUS_GREEN:
-                ee_set_sprite_frame(gem_sprite, (bo->n[i]/2 % 3) ? 0 : 1);
-                ee_draw_sprite(bo->x[i], bo->y[i], gem_sprite);
+                ee_draw_sprite(bo->x[i], bo->y[i], gem_sprite,
+                               (bo->n[i]/2 % 3) ? 0 : 1);
                 break;
             case BONUS_LIFE:
-                ee_set_sprite_frame(heart_sprite, (bo->n[i] % 3) ? 0 : 1);
-                ee_draw_sprite(bo->x[i], bo->y[i], heart_sprite);
+                ee_draw_sprite(bo->x[i], bo->y[i], heart_sprite,
+                               (bo->n[i] % 3) ? 0 : 1);
                 break;
             case BONUS_NONE:
                 break;
diff --git a/src/box.c b/src/box.c
index c6be773..8b38e94 100644
--- a/src/box.c
+++ b/src/box.c
@@ -43,7 +43,7 @@ void draw_box(game *g, box *b)
 {
     int j, frame;
 
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
 
     /* Draw the thin horizontal line */
     if(b->frame < 8)
@@ -66,7 +66,7 @@ void draw_box(game *g, box *b)
     ee_draw_line(b->x + b->w / 2 - 1, b->y - b->h * (frame - 8) / 8,
                  b->x + b->w / 2 - 1, b->y + b->h * (frame - 8) / 8 - 1, 'X');
 
-    ee_color(EE_BLACK);
+    ee_set_color(EE_BLACK);
 
     for(j = b->y - b->h * (frame - 8) / 8 + 1;
          j < b->y + b->h * (frame - 8) / 8;
@@ -82,7 +82,7 @@ void draw_box(game *g, box *b)
     }
 
     /* Draw the text inside the frame */
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
 
     /* FIXME: use a font */
     ee_putstr(b->x - b->w / 2 + 12, b->y - b->h / 2 + 2,
diff --git a/src/common.h b/src/common.h
index 0b7d1cb..19d6691 100644
--- a/src/common.h
+++ b/src/common.h
@@ -20,6 +20,8 @@
  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
+void intro(void);
+
 /*
  * Compile-time limits
  */
diff --git a/src/explosions.c b/src/explosions.c
index 9081f25..09c5af7 100644
--- a/src/explosions.c
+++ b/src/explosions.c
@@ -26,9 +26,6 @@
 
 #include "common.h"
 
-static void draw_small_explosion(int x, int y, int frame);
-static void draw_medium_explosion(int x, int y, int frame);
-
 struct ee_sprite *medium_sprite;
 struct ee_sprite *small_sprite;
 
@@ -79,7 +76,7 @@ void draw_explosions(game *g, explosions *ex)
     for(i = 0; i < EXPLOSIONS; i++)
     {
 #if 0
-        ee_color(GREEN);
+        ee_set_color(GREEN);
         ee_goto(ex->x[i] + 3, ex->y[i]);
         switch(ee_rand(0,2))
         {
@@ -106,10 +103,12 @@ void draw_explosions(game *g, explosions *ex)
         switch(ex->type[i])
         {
             case EXPLOSION_MEDIUM:
-                draw_medium_explosion(ex->x[i], ex->y[i], ex->n[i]);
+                ee_draw_sprite(ex->x[i], ex->y[i], medium_sprite,
+                               10 - ex->n[i]);
                 break;
             case EXPLOSION_SMALL:
-                draw_small_explosion(ex->x[i], ex->y[i], ex->n[i]);
+                ee_draw_sprite(ex->x[i], ex->y[i], small_sprite,
+                               6 - ex->n[i]);
                 break;
             case EXPLOSION_NONE:
                 break;
@@ -141,15 +140,3 @@ void update_explosions(game *g, explosions *ex)
     }
 }
 
-static void draw_small_explosion(int x, int y, int frame)
-{
-    ee_set_sprite_frame(small_sprite, 6 - frame);
-    ee_draw_sprite(x, y, small_sprite);
-}
-
-static void draw_medium_explosion(int x, int y, int frame)
-{
-    ee_set_sprite_frame(medium_sprite, 10 - frame);
-    ee_draw_sprite(x, y, medium_sprite);
-}
-
diff --git a/src/intro.c b/src/intro.c
new file mode 100644
index 0000000..9beb148
--- /dev/null
+++ b/src/intro.c
@@ -0,0 +1,77 @@
+/*
+ *   ttyvaders     Textmode shoot'em up
+ *   Copyright (c) 2002 Sam Hocevar <sam@zoy.org>
+ *                 All Rights Reserved
+ *
+ *   $Id$
+ *
+ *   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 "config.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+
+#include "common.h"
+
+void intro(void)
+{
+    struct ee_sprite *foo_sprite = ee_load_sprite("data/foo_fighter");
+    struct ee_sprite *bar_sprite = ee_load_sprite("data/bar_fighter");
+    struct ee_sprite *baz_sprite = ee_load_sprite("data/baz_fighter");
+
+    int frame = 0;
+
+    while(ee_get_key() == 0)
+    {
+        int i, xo, yo, x[5], y[5];
+
+        frame++;
+
+        ee_clear();
+
+        xo = ee_get_width() / 2;
+        yo = ee_get_height() / 2;
+
+        ee_set_color(EE_RED);
+        ee_fill_ellipse(xo, yo, 16, 8, '#');
+        ee_set_color(EE_GREEN);
+        ee_draw_thin_ellipse(xo, yo, 16, 8);
+
+        for(i = 0; i < 4; i ++)
+        {
+            x[i] = xo + 0.5 + 12 * cos(0.05 * frame + i * M_PI / 2);
+            y[i] = yo + 0.5 + 6 * sin(0.05 * frame + i * M_PI / 2);
+        }
+        x[4] = x[0];
+        y[4] = y[0];
+
+        ee_set_color(EE_BLACK);
+        ee_fill_triangle(x[0], y[0], x[1], y[1], x[2], y[2], '#');
+        ee_fill_triangle(x[0], y[0], x[3], y[3], x[2], y[2], '#');
+        ee_draw_line(x[0], y[0], x[2], y[2], '#');
+        ee_set_color(EE_GREEN);
+        ee_draw_thin_polyline(x, y, 4);
+
+        ee_draw_sprite(xo, yo, foo_sprite, frame % 5);
+
+        ee_refresh();
+
+        usleep(40000);
+    }
+}
+
diff --git a/src/main.c b/src/main.c
index ad474b7..11afcb5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -48,6 +48,8 @@ int main (int argc, char **argv)
     g->w = ee_get_width();
     g->h = ee_get_height();
 
+intro();
+
     /* Go ! */
     start_game(g);
 
diff --git a/src/overlay.c b/src/overlay.c
index 8deefbf..0fad04d 100644
--- a/src/overlay.c
+++ b/src/overlay.c
@@ -32,49 +32,49 @@ void draw_status(game *g)
     static char dashes30[] = "==============================";
 
     /* Draw life jauge */
-    ee_color(EE_GRAY);
+    ee_set_color(EE_GRAY);
     ee_putstr(4, 1, dots30);
 
     if(g->p->life > MAX_LIFE * 7 / 10)
     {
-        ee_color(EE_GREEN);
+        ee_set_color(EE_GREEN);
     }
     else if(g->p->life > MAX_LIFE * 3 / 10)
     {
-        ee_color(EE_YELLOW);
+        ee_set_color(EE_YELLOW);
     }
     else
     {
-        ee_color(EE_RED);
+        ee_set_color(EE_RED);
     }
 
     ee_putstr(4, 1, dashes30 + (MAX_LIFE - g->p->life) * 30 / MAX_LIFE);
 
-    ee_color(EE_WHITE);
+    ee_set_color(EE_WHITE);
     ee_putstr(1, 1, "L |");
     ee_putstr(34, 1, "|");
 
     /* Draw weapon jauge */
-    ee_color(EE_GRAY);
+    ee_set_color(EE_GRAY);
     ee_putstr(42, 1, dots30 + 10);
 
     if(g->p->special > MAX_SPECIAL * 9 / 10)
     {
-        ee_color(EE_WHITE);
+        ee_set_color(EE_WHITE);
     }
     else if(g->p->special > MAX_SPECIAL * 3 / 10)
     {
-        ee_color(EE_CYAN);
+        ee_set_color(EE_CYAN);
     }
     else
     {
-        ee_color(EE_BLUE);
+        ee_set_color(EE_BLUE);
     }
 
     ee_putstr(42, 1, dashes30 + 10
                        + (MAX_SPECIAL - g->p->special) * 20 / MAX_SPECIAL);
 
-    ee_color(EE_WHITE);
+    ee_set_color(EE_WHITE);
     ee_putstr(39, 1, "S |");
     ee_putstr(62, 1, "|");
 }
diff --git a/src/player.c b/src/player.c
index 601ae2b..948feef 100644
--- a/src/player.c
+++ b/src/player.c
@@ -57,7 +57,7 @@ void draw_player(game *g, player *p)
     if(p->dead)
         return;
 
-    ee_draw_sprite(p->x, p->y, ship_sprite);
+    ee_draw_sprite(p->x, p->y, ship_sprite, 0);
 }
 
 void update_player(game *g, player *p)
diff --git a/src/starfield.c b/src/starfield.c
index b4a3348..5c5b787 100644
--- a/src/starfield.c
+++ b/src/starfield.c
@@ -53,7 +53,7 @@ void draw_starfield(game *g, starfield *s)
     {
         if(s[i].x >= 0)
         {
-            ee_color(s[i].c);
+            ee_set_color(s[i].c);
             ee_putchar(s[i].x, s[i].y, s[i].ch);
         }
     }
diff --git a/src/tunnel.c b/src/tunnel.c
index 9cd17a1..b6f4c31 100644
--- a/src/tunnel.c
+++ b/src/tunnel.c
@@ -71,7 +71,7 @@ void draw_tunnel(game *g, tunnel *t)
     int i, j;
     char c;
 
-    ee_color(EE_GREEN);
+    ee_set_color(EE_GREEN);
 
     /* Left border */
     for(i = 0; i < g->h ; i++)
@@ -109,7 +109,7 @@ void draw_tunnel(game *g, tunnel *t)
         ee_putchar(t->right[i] - 1, i, c);
     }
 
-    ee_color(EE_RED);
+    ee_set_color(EE_RED);
 
     /* Left concrete */
     for(i = 0; i < g->h ; i++)
diff --git a/src/weapons.c b/src/weapons.c
index b5c12a8..0d68ae9 100644
--- a/src/weapons.c
+++ b/src/weapons.c
@@ -56,20 +56,20 @@ void draw_weapons(game *g, weapons *wp)
         switch(wp->type[i])
         {
             case WEAPON_LASER:
-                ee_color(EE_WHITE);
+                ee_set_color(EE_WHITE);
                 ee_putchar(wp->x[i] >> 4, wp->y[i] >> 4, '|');
-                ee_color(EE_CYAN);
+                ee_set_color(EE_CYAN);
                 ee_putchar(wp->x[i] >> 4, (wp->y[i] >> 4) + 1, '|');
                 break;
             case WEAPON_SEEKER:
-                ee_color(EE_CYAN);
+                ee_set_color(EE_CYAN);
                 ee_putchar(wp->x3[i] >> 4, wp->y3[i] >> 4, '.');
                 ee_putchar(wp->x2[i] >> 4, wp->y2[i] >> 4, 'o');
-                ee_color(EE_WHITE);
+                ee_set_color(EE_WHITE);
                 ee_putchar(wp->x[i] >> 4, wp->y[i] >> 4, '@');
                 break;
             case WEAPON_BOMB:
-                ee_color(EE_GRAY);
+                ee_set_color(EE_GRAY);
                 ee_putchar((wp->x[i] - wp->vx[i]) >> 4, (wp->y[i] - wp->vy[i]) >> 4, '.');
                 ee_putchar((wp->x3[i] - wp->vx[i]) >> 4, (wp->y3[i] - wp->vy[i]) >> 4, '.');
                 ee_putchar((wp->x2[i] - wp->vx[i]) >> 4, (wp->y2[i] - wp->vy[i]) >> 4, '.');
@@ -333,19 +333,16 @@ static void draw_bomb(int x, int y, int vx, int vy)
         }
     }
 
-    ee_set_sprite_frame(bomb_sprite, frame);
-    ee_draw_sprite(x, y, bomb_sprite);
+    ee_draw_sprite(x, y, bomb_sprite, frame);
 }
 
 static void draw_fragbomb(int x, int y, int frame)
 {
     /* Draw the head */
-    ee_set_sprite_frame(fragbomb_sprite, frame & 1);
-    ee_draw_sprite(x, y, fragbomb_sprite);
+    ee_draw_sprite(x, y, fragbomb_sprite, frame & 1);
 
     /* Draw the tail */
-    ee_set_sprite_frame(fragbomb_sprite, 2 + (frame % 4));
-    ee_draw_sprite(x, y, fragbomb_sprite);
+    ee_draw_sprite(x, y, fragbomb_sprite, 2 + (frame % 4));
 }
 
 static void draw_beam(int x, int y, int frame)
@@ -356,84 +353,84 @@ static void draw_beam(int x, int y, int frame)
     switch(frame)
     {
         case 24:
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x, y-3, "__");
             ee_putchar(x-1, y-2, '\'');
             ee_putchar(x+2, y-2, '`');
             break;
         case 23:
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putstr(x, y-3, "__");
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x-2, y-2, "-'");
             ee_putstr(x+2, y-2, "`-");
             break;
         case 22:
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putstr(x, y-3, "__");
             ee_putchar(x-1, y-2, '\'');
             ee_putchar(x+2, y-2, '`');
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x-3, y-2, ",-");
             ee_putstr(x+3, y-2, "-.");
             break;
         case 21:
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putstr(x-1, y-3, "____");
             ee_putchar(x-2, y-2, '\'');
             ee_putchar(x+3, y-2, '`');
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x-4, y-2, ",-");
             ee_putstr(x+4, y-2, "-.");
             break;
         case 20:
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x, y-3, "%%");
             ee_putchar(x-4, y-2, ',');
             ee_putchar(x+5, y-2, '.');
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putchar(x-1, y-3, ':');
             ee_putchar(x+2, y-3, ':');
             ee_putstr(x-3, y-2, "-'");
             ee_putstr(x+3, y-2, "`-");
             break;
         case 19:
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x, y-4, "%%");
             ee_putstr(x, y-3, "##");
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putchar(x-1, y-4, ':');
             ee_putchar(x+2, y-4, ':');
             ee_putchar(x-1, y-3, '%');
             ee_putchar(x+2, y-3, '%');
             ee_putstr(x-4, y-2, ",-'");
             ee_putstr(x+3, y-2, "`-.");
-            ee_color(EE_BLUE);
+            ee_set_color(EE_BLUE);
             ee_putchar(x-2, y-3, ':');
             ee_putchar(x+3, y-3, ':');
             break;
         case 18:
         default:
             r = (18 - frame) * (18 - frame);
-            ee_color(EE_WHITE);
+            ee_set_color(EE_WHITE);
             ee_putstr(x-1, y-5-r, ":%%:");
             ee_putstr(x-1, y-4-r, "%##%");
-            ee_color(EE_CYAN);
+            ee_set_color(EE_CYAN);
             ee_putchar(x-2, y-4-r, ':');
             ee_putchar(x+3, y-4-r, ':');
             ee_putchar(x-2, y-2, '\'');
             ee_putchar(x+3, y-2, '`');
-            ee_color(EE_BLUE);
+            ee_set_color(EE_BLUE);
             ee_putchar(x-3, y-2, ':');
             ee_putchar(x+4, y-2, ':');
             for(i = 0; i <= r; i++)
             {
-                ee_color(EE_WHITE);
+                ee_set_color(EE_WHITE);
                 ee_putstr(x-1, y-3-i, ((i+frame) % 5) ? "####" : "%%%%");
-                ee_color(EE_CYAN);
+                ee_set_color(EE_CYAN);
                 ee_putchar(x-2, y-3-i, '%');
                 ee_putchar(x+3, y-3-i, '%');
-                ee_color(EE_BLUE);
+                ee_set_color(EE_BLUE);
                 ee_putchar(x-3, y-3-i, ':');
                 ee_putchar(x+4, y-3-i, ':');
             }
@@ -446,14 +443,14 @@ static void draw_nuke(int x, int y, int frame)
     int r = (29 - frame) * (29 - frame) / 8;
 
     /* Lots of duplicate pixels, but we don't care */
-    ee_color(EE_BLUE);
+    ee_set_color(EE_BLUE);
     ee_draw_ellipse(x, y, r, r / 2, ':');
     ee_draw_ellipse(x, y, r + 1, r / 2, ':');
     ee_draw_ellipse(x, y, r + 2, r / 2, ':');
-    ee_color(EE_CYAN);
+    ee_set_color(EE_CYAN);
     ee_draw_ellipse(x, y, r + 2, r / 2 + 1, '%');
     ee_draw_ellipse(x, y, r + 3, r / 2 + 1, '%');
-    ee_color(EE_WHITE);
+    ee_set_color(EE_WHITE);
     ee_draw_ellipse(x, y, r + 3, r / 2 + 2, '#');
     ee_draw_ellipse(x, y, r + 4, r / 2 + 2, '#');
     ee_draw_ellipse(x, y, r + 4, r / 2 + 3, '#');
diff --git a/test/demo.c b/test/demo.c
index ae9d7f3..d040700 100644
--- a/test/demo.c
+++ b/test/demo.c
@@ -142,7 +142,7 @@ static void display_menu(void)
     int yo = ee_get_height() - 2;
 
     ee_clear();
-    ee_color(EE_WHITE);
+    ee_set_color(EE_WHITE);
     ee_draw_line(xo, yo, 1, yo, '.');
     ee_draw_line(1, yo, 1, 1, ':');
     ee_draw_line(xo, 1, xo, yo, ':');
@@ -178,7 +178,7 @@ static void demo_all(void)
     ee_clear();
 
     /* Draw the sun */
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
     xo = ee_get_width() / 4;
     yo = ee_get_height() / 4 + 5 * sin(0.03*i);
 
@@ -190,9 +190,9 @@ static void demo_all(void)
     }
 
     j = 15 + sin(0.03*i) * 8;
-    ee_color(EE_WHITE);
+    ee_set_color(EE_WHITE);
     ee_fill_ellipse(xo, yo, j, j / 2, '#');
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
     ee_draw_ellipse(xo, yo, j, j / 2, '#');
 
     /* Draw the pyramid */
@@ -208,19 +208,19 @@ static void demo_all(void)
     x3 = ee_get_width() / 4 - sin(0.02*i) * 5;
     y3 = ee_get_height() * 3 / 4 + cos(0.02*i) * 5;
 
-    ee_color(EE_GREEN);
+    ee_set_color(EE_GREEN);
     ee_fill_triangle(xo, yo, x2, y2, x1, y1, '%');
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
     ee_draw_thin_triangle(xo, yo, x2, y2, x1, y1);
 
-    ee_color(EE_RED);
+    ee_set_color(EE_RED);
     ee_fill_triangle(x1, y1, x2, y2, x3, y3, '#');
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
     ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3);
 
-    ee_color(EE_BLUE);
+    ee_set_color(EE_BLUE);
     ee_fill_triangle(xo, yo, x2, y2, x3, y3, '%');
-    ee_color(EE_YELLOW);
+    ee_set_color(EE_YELLOW);
     ee_draw_thin_triangle(xo, yo, x2, y2, x3, y3);
 
     /* Draw a background triangle */
@@ -233,7 +233,7 @@ static void demo_all(void)
     x3 = ee_get_width() / 3;
     y3 = ee_get_height() - 3;
 
-    ee_color(EE_CYAN);
+    ee_set_color(EE_CYAN);
     ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3);
 
     xo = ee_get_width() / 2 + cos(0.027*i) * ee_get_width() / 3;
@@ -244,13 +244,13 @@ static void demo_all(void)
     ee_draw_thin_line(x3, y3, xo, yo);
 
     /* Draw a sprite on the pyramid */
-    ee_draw_sprite(xo, yo, sprite);
+    ee_draw_sprite(xo, yo, sprite, 0);
 
     /* Draw a trail behind the foreground sprite */
     for(j = i - 60; j < i; j++)
     {
         int delta = ee_rand(-5, 5);
-        ee_color(ee_rand(1, 10));
+        ee_set_color(ee_rand(1, 10));
         ee_putchar(ee_get_width() / 2
                     + cos(0.02*j) * (delta + ee_get_width() / 4),
                    ee_get_height() / 2
@@ -261,7 +261,7 @@ static void demo_all(void)
     /* Draw foreground sprite */
     ee_draw_sprite(ee_get_width() / 2 + cos(0.02*i) * ee_get_width() / 4,
                    ee_get_height() / 2 + sin(0.02*i) * ee_get_height() / 3,
-                   sprite);
+                   sprite, 0);
 
     ee_refresh();
 }
@@ -275,7 +275,7 @@ static void demo_dots(void)
     for(i = 1000; i--;)
     {
         /* Putpixel */
-        ee_color(ee_rand(1, 10));
+        ee_set_color(ee_rand(1, 10));
         ee_putchar(ee_rand(0, xmax), ee_rand(0, ymax), '#');
     }
     ee_refresh();
@@ -298,7 +298,7 @@ static void demo_lines(void)
         x2 = ee_rand(0, w - 1); y2 = ee_rand(0, h - 1);
     }
 
-    ee_color(ee_rand(1, 10));
+    ee_set_color(ee_rand(1, 10));
     if(thin)
         ee_draw_thin_line(x1, y1, x2, y2);
     else
@@ -324,12 +324,12 @@ static void demo_boxes(void)
         x2 = ee_rand(0, w - 1); y2 = ee_rand(0, h - 1);
     }
 
-    ee_color(ee_rand(1, 10));
+    ee_set_color(ee_rand(1, 10));
     ee_fill_box(x1, y1, x2, y2, '#');
 
     if(outline)
     {
-        ee_color(ee_rand(1, 10));
+        ee_set_color(ee_rand(1, 10));
         ee_draw_thin_box(x1, y1, x2, y2);
     }
 
@@ -357,12 +357,12 @@ static void demo_ellipses(void)
         } while(x - a < 0 || x + a >= w || y - b < 0 || y + b >= h);
     }
 
-    ee_color(ee_rand(1, 10));
+    ee_set_color(ee_rand(1, 10));
     ee_fill_ellipse(x, y, a, b, '#');
 
     if(outline)
     {
-        ee_color(ee_rand(1, 10));
+        ee_set_color(ee_rand(1, 10));
         ee_draw_thin_ellipse(x, y, a, b);
     }
 
@@ -389,12 +389,12 @@ static void demo_triangles(void)
         x3 = ee_rand(0, w - 1); y3 = ee_rand(0, h - 1);
     }
 
-    ee_color(ee_rand(1, 10));
+    ee_set_color(ee_rand(1, 10));
     ee_fill_triangle(x1, y1, x2, y2, x3, y3, '#');
 
     if(outline)
     {
-        ee_color(ee_rand(1, 10));
+        ee_set_color(ee_rand(1, 10));
         ee_draw_thin_triangle(x1, y1, x2, y2, x3, y3);
     }
 
@@ -404,7 +404,7 @@ static void demo_triangles(void)
 static void demo_sprites(void)
 {
     ee_draw_sprite(ee_rand(0, ee_get_width() - 1),
-                   ee_rand(0, ee_get_height() - 1), sprite);
+                   ee_rand(0, ee_get_height() - 1), sprite, 0);
     ee_refresh();
 }
 
diff --git a/test/spritedit.c b/test/spritedit.c
index e86f6f5..492ed44 100644
--- a/test/spritedit.c
+++ b/test/spritedit.c
@@ -22,32 +22,89 @@
 
 #include "config.h"
 
-#include <math.h>
-#include <string.h>
+#include <stdio.h>
 
 #include "ee.h"
 
 int main(int argc, char **argv)
 {
     int quit = 0;
+    struct ee_sprite *sprite;
+    int frame = 0;
+
+    if(argc < 2)
+    {
+        fprintf(stderr, "%s: missing argument (filename).\n", argv[0]);
+        return 1;
+    }
 
     if(ee_init())
+        return 1;
+
+    sprite = ee_load_sprite(argv[1]);
+
+    if(!sprite)
     {
+        ee_end();
+        fprintf(stderr, "%s: could not open `%s'.\n", argv[0], argv[1]);
         return 1;
     }
 
     /* Go ! */
     while(!quit)
     {
-        char key = ee_get_key();
-        switch(key)
+        int xa, ya, xb, yb;
+        char buf[BUFSIZ];
+
+        switch(ee_get_key())
         {
         case 0:
             break;
         case 'q':
             quit = 1;
             break;
+        case '-':
+            if(frame > 0)
+                frame--;
+            break;
+        case '+':
+            if(frame < ee_get_sprite_frames(sprite) - 1)
+                frame++;
+            break;
         }
+
+        ee_clear();
+
+        ee_set_color(EE_WHITE);
+        ee_draw_thin_box(0, 0, ee_get_width() - 1, ee_get_height() - 1);
+
+        ee_putstr(3, 0, "[ Sprite editor for libee ]");
+
+        sprintf(buf, "sprite `%s'", argv[1]);
+        ee_putstr(3, 2, buf);
+        sprintf(buf, "frame %i/%i", frame, ee_get_sprite_frames(sprite) - 1);
+        ee_putstr(3, 3, buf);
+
+        /* Crosshair */
+        ee_draw_thin_line(57, 2, 57, 18);
+        ee_draw_thin_line(37, 10, 77, 10);
+        ee_putchar(57, 10, '+');
+
+        /* Boxed sprite */
+        xa = -1 - ee_get_sprite_dx(sprite, frame);
+        ya = -1 - ee_get_sprite_dy(sprite, frame);
+        xb = xa + 1 + ee_get_sprite_width(sprite, frame);
+        yb = ya + 1 + ee_get_sprite_height(sprite, frame);
+        ee_set_color(EE_BLACK);
+        ee_fill_box(57 + xa, 10 + ya, 57 + xb, 10 + yb, ' ');
+        ee_set_color(EE_WHITE);
+        ee_draw_thin_box(57 + xa, 10 + ya, 57 + xb, 10 + yb);
+        ee_draw_sprite(57, 10, sprite, frame);
+
+        /* Free sprite */
+        ee_draw_sprite(20, 10, sprite, frame);
+
+        ee_refresh();
     }
 
     /* Clean up */