Index: /ttyvaders/trunk/explosions.c
===================================================================
--- /ttyvaders/trunk/explosions.c	(revision 15)
+++ /ttyvaders/trunk/explosions.c	(revision 16)
@@ -1,5 +1,4 @@
 
 #include <stdlib.h>
-#include <math.h>
 
 #include "common.h"
@@ -7,5 +6,4 @@
 static void draw_small_explosion( int x, int y, int frame );
 static void draw_big_explosion( int x, int y, int frame );
-static void draw_huge_explosion( int x, int y, int frame );
 
 void init_explosions( game *g, explosions *ex )
@@ -86,7 +84,4 @@
         switch( ex->type[i] )
         {
-            case 2:
-                draw_huge_explosion( ex->x[i], ex->y[i], ex->n[i] );
-                break;
             case 1:
                 draw_big_explosion( ex->x[i], ex->y[i], ex->n[i] );
@@ -309,97 +304,2 @@
 }
 
-static void draw_circle( int x, int y, float r );
-
-static void draw_huge_explosion( int x, int y, int frame )
-{
-    float r = 1.5 * (30 - frame);
-
-    GFX_COLOR( BLUE );
-    draw_circle( x, y, r );
-
-    r += 0.7;
-
-    GFX_COLOR( CYAN );
-    draw_circle( x, y, r );
-
-    r += 0.7;
-
-    GFX_COLOR( WHITE );
-    draw_circle( x, y, r );
-}
-
-static void draw_circle( int x, int y, float r )
-{
-#if 1
-    float c;
-
-    for( c = 0 ; c <= 90 ; c += 1 )
-    {
-        float dx = 0.5 + r * 2.0 * sin( c * M_PI / 180.0 );
-        float dy = 0.5 + r * cos( c * M_PI / 180.0 );
-
-        GFX_GOTO( x + dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x + dx, y - dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y - dy );
-        GFX_WRITE( '#' );
-    }
-#endif
-
-#if 0
-int dx,dy,a2,b2, S, T;
-float a = r*8, b = r*2;
-
- a2 = a*a;
- b2 = b*b;
- dx = 0;
- dy = b;
- S = a2*(1-2*b) + 2*b2;
- T = b2 - 2*a2*(2*b-1);
-        GFX_GOTO( x + dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x + dx, y - dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y - dy );
-        GFX_WRITE( '#' );
-
- do
-   {
-    if (S<0)
-       {
-        S += 2*b2*(2*x+3);
-        T += 4*b2*(x+1);
-        dx++;
-       }
-      else if (T<0)
-          {
-           S += 2*b2*(2*x+3) - 4*a2*(dy-1);
-           T += 4*b2*(x+1) - 2*a2*(2*dy-3);
-           dx++;
-           dy--;
-          }
-         else
-          {
-           S -= 4*a2*(dy-1);
-           T -= 2*a2*(2*dy-3);
-           dy--;
-          }
-        GFX_GOTO( x + dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y + dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x + dx, y - dy );
-        GFX_WRITE( '#' );
-        GFX_GOTO( x - dx, y - dy );
-        GFX_WRITE( '#' );
-   }
- while (dy>0);
-#endif
-
-}
-
Index: /ttyvaders/trunk/main.c
===================================================================
--- /ttyvaders/trunk/main.c	(revision 15)
+++ /ttyvaders/trunk/main.c	(revision 16)
@@ -99,8 +99,8 @@
                     break;
                 case 'j':
-                    //if( p->y < g->h - 2 ) p->y += 1;
+                    if( p->y < g->h - 2 ) p->y += 1;
                     break;
                 case 'k':
-                    //if( p->y > 1 ) p->y -= 1;
+                    if( p->y > 1 ) p->y -= 1;
                     break;
                 case 'l':
@@ -108,5 +108,9 @@
                     break;
                 case '\r':
-                    add_explosion( g, ex, p->x + 2, p->y, 0, 0, 2 );
+                    if( p->nuke == 0 )
+                    {
+                        p->nuke = 40;
+                        add_weapon( g, wp, p->x + 2, p->y, 2 );
+                    }
                     break;
                 case ' ':
@@ -114,6 +118,6 @@
                     {
                         p->weapon = 4;
-                        add_weapon( g, wp, p->x, p->y );
-                        add_weapon( g, wp, p->x + 5, p->y );
+                        add_weapon( g, wp, p->x, p->y, 1 );
+                        add_weapon( g, wp, p->x + 5, p->y, 1 );
                     }
                     break;
Index: /ttyvaders/trunk/collide.c
===================================================================
--- /ttyvaders/trunk/collide.c	(revision 15)
+++ /ttyvaders/trunk/collide.c	(revision 16)
@@ -8,5 +8,5 @@
     int i;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         if( wp->y[i] >= 0 )
@@ -60,45 +60,75 @@
     int i, j;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         if( wp->y[i] >= 0 )
         {
             int ok = 0;
+            int r;
 
-            for( j = 0; j < ALIENS; j++ )
+            switch( wp->type[i] )
             {
-                if( wp->x[i] >= al->x[j]
-                     && wp->x[i] <= al->x[j] + 4
-                     && wp->y[i] >= al->y[j]
-                     && wp->y[i] <= al->y[j] + 2 )
+            case 2:
+                /* Big nuke */
+                r = (34 - wp->n[i]) * (34 - wp->n[i]) / 10;
+
+                for( j = 0; j < ALIENS; j++ )
                 {
-                    al->life[j]--;
-                    if( al->life[j] == 0 )
+                    if( al->x[j] < 0 )
                     {
+                        continue;
+                    }
+
+                    if( (al->x[j] - wp->x[i]) * (al->x[j] - wp->x[i])
+                          + 4 * (al->y[j] - wp->y[i]) * (al->y[j] - wp->y[i])
+                        <= r * r )
+                    {
+                        /* Kill alien, not nuke */
+                        add_explosion( g, ex, al->x[j], al->y[j], 0, 0, 1 );
                         al->x[j] = -1;
                         al->y[j] = -1;
-                        add_explosion( g, ex, wp->x[i], wp->y[i], 0, 0, 1 );
                     }
-                    ok = 1;
                 }
-                else if( wp->x[i] >= al->x[j]
-                          && wp->x[i] <= al->x[j] + 4
-                          && wp->y[i]+1 >= al->y[j]
-                          && wp->y[i]+1 <= al->y[j] + 2 )
+                break;
+
+            case 1:
+            default:
+                for( j = 0; j < ALIENS; j++ )
                 {
-                    al->life[j]--;
-                    if( al->life[j] == 0 )
+                    if( wp->x[i] >= al->x[j]
+                         && wp->x[i] <= al->x[j] + 4
+                         && wp->y[i] >= al->y[j]
+                         && wp->y[i] <= al->y[j] + 2 )
                     {
-                        al->x[j] = -1;
-                        al->y[j] = -1;
-                        add_explosion( g, ex, wp->x[i], wp->y[i]+1, 0, 0, 1 );
+                        al->life[j]--;
+                        if( al->life[j] == 0 )
+                        {
+                            al->x[j] = -1;
+                            al->y[j] = -1;
+                            add_explosion( g, ex, wp->x[i], wp->y[i], 0, 0, 1 );
+                        }
+                        ok = 1;
                     }
-                    ok = 1;
+                    else if( wp->x[i] >= al->x[j]
+                              && wp->x[i] <= al->x[j] + 4
+                              && wp->y[i]+1 >= al->y[j]
+                              && wp->y[i]+1 <= al->y[j] + 2 )
+                    {
+                        al->life[j]--;
+                        if( al->life[j] == 0 )
+                        {
+                            al->x[j] = -1;
+                            al->y[j] = -1;
+                            add_explosion( g, ex, wp->x[i], wp->y[i]+1, 0, 0, 1 );
+                        }
+                        ok = 1;
+                    }
                 }
-            }
 
-            if( ok )
-            {
-                wp->y[i] = -1;
+                if( ok )
+                {
+                    wp->y[i] = -1;
+                }
+                break;
             }
         }
Index: /ttyvaders/trunk/player.c
===================================================================
--- /ttyvaders/trunk/player.c	(revision 15)
+++ /ttyvaders/trunk/player.c	(revision 16)
@@ -13,4 +13,5 @@
     p->dir = 0;
     p->weapon = 0;
+    p->nuke = 0;
 
     return p;
@@ -52,4 +53,9 @@
     }
 
+    if( p->nuke )
+    {
+        p->nuke--;
+    }
+
     if( p->dir < 0 )
     {
Index: /ttyvaders/trunk/weapons.c
===================================================================
--- /ttyvaders/trunk/weapons.c	(revision 15)
+++ /ttyvaders/trunk/weapons.c	(revision 16)
@@ -4,13 +4,18 @@
 #include "common.h"
 
+static void draw_nuke( int x, int y, int frame );
+static void draw_circle( int x, int y, int r );
+
 void init_weapons( game *g, weapons *wp )
 {
     int i;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         wp->x[i] = -1;
         wp->y[i] = -1;
         wp->v[i] = 0;
+        wp->n[i] = 0;
+        wp->type[i] = 0;
     }
 }
@@ -20,14 +25,23 @@
     int i;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         if( wp->x[i] >= 0 )
         {
-            GFX_COLOR( WHITE );
-            GFX_GOTO( wp->x[i], wp->y[i] );
-            GFX_WRITE( '|' );
-            GFX_COLOR( CYAN );
-            GFX_GOTO( wp->x[i], wp->y[i] + 1 );
-            GFX_WRITE( '|' );
+            switch( wp->type[i] )
+            {
+                case 2:
+                    draw_nuke( wp->x[i], wp->y[i], wp->n[i] );
+                    break;
+                case 1:
+                default:
+                    GFX_COLOR( WHITE );
+                    GFX_GOTO( wp->x[i], wp->y[i] );
+                    GFX_WRITE( '|' );
+                    GFX_COLOR( CYAN );
+                    GFX_GOTO( wp->x[i], wp->y[i] + 1 );
+                    GFX_WRITE( '|' );
+                    break;
+            }
         }
     }
@@ -38,5 +52,5 @@
     int i;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         if( wp->y[i] < 0 )
@@ -47,5 +61,18 @@
         else
         {
-            wp->y[i] += wp->v[i];
+            switch( wp->type[i] )
+            {
+            case 2:
+                wp->n[i]--;
+                if( wp->n[i]-- < 0 )
+                {
+                    wp->y[i] = -1;
+                }
+                break;
+            case 1:
+            default:
+                wp->y[i] += wp->v[i];
+                break;
+            }
 
             /* Check collisions */
@@ -54,9 +81,9 @@
 }
 
-void add_weapon( game *g, weapons *wp, int x, int y )
+void add_weapon( game *g, weapons *wp, int x, int y, int type )
 {
     int i;
 
-    for( i = 0; i < SHOTS; i++ )
+    for( i = 0; i < WEAPONS; i++ )
     {
         if( wp->y[i] < 0 )
@@ -64,5 +91,7 @@
             wp->x[i] = x;
             wp->y[i] = y;
+            wp->type[i] = type;
             wp->v[i] = -2;
+            wp->n[i] = 30;
             break;
         }
@@ -70,2 +99,37 @@
 }
 
+static void draw_nuke( int x, int y, int frame )
+{
+    int r = (34 - frame) * (34 - frame) / 10;
+
+    /* Lots of duplicate pixels, but we don't care */
+    GFX_COLOR( BLUE );
+    draw_circle( x, y, r++ );
+    GFX_COLOR( CYAN );
+    draw_circle( x, y, r++ );
+    GFX_COLOR( WHITE );
+    draw_circle( x, y, r++ );
+    draw_circle( x, y, r++ );
+}
+
+static void draw_circle( int x, int y, int r )
+{
+    int test, dx, dy;
+
+    /* Optimized Bresenham. Kick ass. */
+    for( test = 0, dx = 0, dy = r ; dx <= dy ; dx++ )
+    {
+        GFX_WRITETO( x + dx, y + dy / 2, '#' );
+        GFX_WRITETO( x - dx, y + dy / 2, '#' );
+        GFX_WRITETO( x + dx, y - dy / 2, '#' );
+        GFX_WRITETO( x - dx, y - dy / 2, '#' );
+
+        GFX_WRITETO( x + dy, y + dx / 2, '#' );
+        GFX_WRITETO( x - dy, y + dx / 2, '#' );
+        GFX_WRITETO( x + dy, y - dx / 2, '#' );
+        GFX_WRITETO( x - dy, y - dx / 2, '#' );
+
+        test += test > 0 ? dx - dy-- : dx;
+    }
+}
+
Index: /ttyvaders/trunk/common.h
===================================================================
--- /ttyvaders/trunk/common.h	(revision 15)
+++ /ttyvaders/trunk/common.h	(revision 16)
@@ -1,5 +1,5 @@
 
 #define STARS 50
-#define SHOTS 50
+#define WEAPONS 50
 #define ROCKS 10
 #define ALIENS 10
@@ -17,4 +17,6 @@
 #   define GFX_WRITE(x) addch(x)
 #endif
+
+#define GFX_WRITETO(x,y,c) do{ GFX_GOTO(x,y); GFX_WRITE(c); }while(0)
 
 #define GET_RAND(p,q) ((p)+(int)((1.0*((q)-(p)))*rand()/(RAND_MAX+1.0)))
@@ -55,7 +57,9 @@
 typedef struct
 {
-    int x[SHOTS];
-    int y[SHOTS];
-    int v[SHOTS];
+    int x[WEAPONS];
+    int y[WEAPONS];
+    int v[WEAPONS];
+    int n[WEAPONS];
+    int type[WEAPONS];
 
 } weapons;
@@ -65,5 +69,5 @@
     int x, y;
     int dir;
-    int weapon;
+    int weapon, nuke;
 
 } player;
@@ -113,5 +117,5 @@
 void draw_weapons( game *g, weapons *wp );
 void update_weapons( game *g, weapons *wp );
-void add_weapon( game *g, weapons *wp, int x, int y );
+void add_weapon( game *g, weapons *wp, int x, int y, int type );
 
 void init_starfield( game *g, starfield *s );
