/*
    Spacewar - A hack that hopes to get a game.

*/

#include "math.h"
#include "functions.h"
#include "exec/types.h"
#include "graphics/gfx.h"
#include "graphics/gfxbase.h"
#include "intuition/intuition.h"

#define PI        3.141592654

#define JOY0DAT   0xdff00a
#define JOY1DAT   0xdff00c
#define JOYTEST   0xdff036
#define JOYBUT    0xbfe000

#define JOYUP     0x0100
#define JOYDOWN   0x0001
#define JOYLEFT   0x0200
#define JOYRIGHT  0x0002

#define SP_INVISIBLE 0x0001
#define SP_CRASHES   0x0002
#define SP_LONGSHOTS 0x0008
#define SP_SLOWDOWN  0x0010
#define SP_PLANET    0x0020
#define SP_WALLS     0x0040
#define SP_ASTEROIDS 0x0080
#define SP_BLASTMODE 0x0100
#define SP_SHOTGRAV  0x0200
#define SP_SHIPGRAV  0x0400
#define SP_HITSHIP   0x0800
#define SP_FUTUREX   0x1000
#define SP_FUTUREX2  0x2000
#define SP_FUTUREX3  0x4000

#define XLBORDER  15
#define XRBORDER  625
#define YUBORDER  15
#define YDBORDER  185

#define LXLBORDER  1500
#define LXRBORDER  62500
#define LYUBORDER  1500
#define LYDBORDER  18500

#define YYY       30000.1
#define XXX       15000.1

FLOAT ran();

struct IntuitionBase *IntuitionBase;
struct GfxBase       *GfxBase;
struct Window        *MyWindow,*ReqWindow;
struct Screen        *MyScreen;
struct RastPort      *rp;
struct IntuiMessage  *message;
struct Gadget        *MyGad;

FLOAT x[2],y[2],vx[2],vy[2],h[2],xx[2],yy[2],hh[2];            /* Ships... */
FLOAT sx[10][2],sy[10][2],svx[10][2],svy[10][2];               /* Shots... */

int d1,d2,hit,flp[2],t[10][2],hits[2],gf,ShotNum;
int *jb,*jt,*jd1,*jd2;

FLOAT zs2,zaz,zbz;

long qx,ax[2],ay[2],Gflags;

SHORT sprite[] = { 0,0,0,0,0,0 };

struct NewScreen TheScreen =
{
      0,0,640,200,
      3,          /* 3 Planes = 8 Colors */
      0,1,
      HIRES,
      CUSTOMSCREEN,
      NULL,
      (UBYTE *)"Guido's Space War (c) by Guido Appenzeller in 1987",
      NULL,
      NULL,
};

struct NewWindow Window1 =
{
      0,10,640,190,
      0,1,
      NULL,
      BORDERLESS|BACKDROP,
      NULL,
      NULL,
      NULL,
      NULL,
      NULL,
      0,0,0,0,
      CUSTOMSCREEN
};

/* --- The Options Requester --------------------- */

SHORT Lines1[] = {   0,0,  80,0, 80,20,0,20, 0,0   };
SHORT Lines2[] = {   3,2,  77,2, 77,18,3,18, 3,2   };
SHORT Lines3[] = {   0,0,  11,7, 0,7,  11,0  };
SHORT Lines4[] = {   0,0,  11,0, 11,7, 0,7,  0,0   };
SHORT Lines5[] = {   0,0,  11,0, 11,7, 0,7,  0,0,  11,7, 0,7,  11,0  };

struct IntuiText Text17= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Future Exp.",NULL };
struct IntuiText Text16= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Future Exp.",NULL };
struct IntuiText Text15= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Future Exp",NULL };
struct IntuiText Text14= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Int. Shots",NULL };
struct IntuiText Text13= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Ship Grav.",NULL };
struct IntuiText Text12= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Shot Grav.",NULL };
struct IntuiText Text11= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Blast Mode",NULL };
struct IntuiText Text10= { 1,0,JAM1,-90,0,NULL,(TEXT *)"Asteroids ",NULL };
struct IntuiText Text9 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Walls     ",NULL };
struct IntuiText Text8 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Planet    ",NULL };
struct IntuiText Text7 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Slow down ",NULL };
struct IntuiText Text6 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Long shots",NULL };
struct IntuiText Text5 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"5/10 shots",NULL };
struct IntuiText Text4 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Crashes   ",NULL };
struct IntuiText Text3 = { 1,0,JAM1,-90,0,NULL,(TEXT *)"Invisible ",NULL };
struct IntuiText Text2 = { 1,0,JAM1,13,7,NULL,(TEXT *)" QUIT! ",NULL };
struct IntuiText Text1 = { 1,0,JAM1,9,7,NULL,(TEXT *)"PLAY IT!",NULL };

struct Border Border5 = { 0,0,1,0,JAM1,8,(SHORT *)&Lines5,NULL };
struct Border Border4 = { 0,0,1,0,JAM1,5,(SHORT *)&Lines4,NULL };
struct Border Border3 = { 0,0,0,0,JAM1,5,(SHORT *)&Lines3,&Border4 };
struct Border Border2 = { 0,0,1,0,JAM1,5,(SHORT *)&Lines2,NULL };
struct Border Border1 = { 0,0,1,0,JAM1,5,(SHORT *)&Lines1,&Border2 };

struct Gadget Gadget17= {NULL,340,52,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text17,NULL,NULL,12,NULL };

struct Gadget Gadget16= {&Gadget17,340,42,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text16,NULL,NULL,12,NULL };

struct Gadget Gadget15= {&Gadget16,340,32,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text15,NULL,NULL,12,NULL };

struct Gadget Gadget14= {&Gadget15,340,22,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text14,NULL,NULL,12,NULL };

struct Gadget Gadget13= {&Gadget14,340,12,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text13,NULL,NULL,12,NULL };

struct Gadget Gadget12= {&Gadget13,220,52,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text12,NULL,NULL,12,NULL };

struct Gadget Gadget11= {&Gadget12,220,42,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text11,NULL,NULL,12,NULL };

struct Gadget Gadget10= {&Gadget11,220,32,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text10,NULL,NULL,12,NULL };

struct Gadget Gadget9 = {&Gadget10,220,22,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text9,NULL,NULL,11,NULL };

struct Gadget Gadget8 = {&Gadget9,220,12,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text8,NULL,NULL,10,NULL };

struct Gadget Gadget7 = {&Gadget8,100,52,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text7,NULL,NULL,07,NULL };

struct Gadget Gadget6 = {&Gadget7,100,42,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text6,NULL,NULL,06,NULL };

struct Gadget Gadget5 = {&Gadget6,100,32,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text5,NULL,NULL,05,NULL };

struct Gadget Gadget4 = {&Gadget5,100,22,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text4,NULL,NULL,04,NULL };

struct Gadget Gadget3 = {&Gadget4,100,12,12,8,GADGHIMAGE,RELVERIFY|TOGGLESELECT,
          BOOLGADGET,(APTR)&Border3,(APTR)&Border5,&Text3,NULL,NULL,03,NULL };

struct Gadget Gadget2 = {&Gadget3,10,74,81,21,GADGHCOMP,RELVERIFY,BOOLGADGET,
                           (APTR)&Border1,NULL,&Text2,NULL,NULL,02,NULL };

struct Gadget Gadget1 = {&Gadget2,270,74,81,21,GADGHCOMP,RELVERIFY,BOOLGADGET,
                           (APTR)&Border1,NULL,&Text1,NULL,NULL,01,NULL };

struct NewWindow ReqWindow1 =
{
      140,50,360,100,
      0,1,
      GADGETUP,
      ACTIVATE,
      &Gadget1,
      NULL,
      (UBYTE*)"      * * * Guido's Space War * * *",
      NULL,
      NULL,
      0,0,0,0,
      CUSTOMSCREEN
};

/* --- Open Everything, no Error-Checking yet --- */

Openstuff()
{

if((IntuitionBase = (struct IntuitionBase *)
                  OpenLibrary("intuition.library",0L)) == NULL )
{  printf("Where's Intuition man !\n");
   exit(FALSE);           }

if((GfxBase = (struct GfxBase *)
                  OpenLibrary("graphics.library",0L)) == NULL )
{  printf("Where's the Grafix-Library !\n");
   CloseLibrary(IntuitionBase);
   exit(FALSE);           }

/* Open Screen & Window --------------------------*/

MyScreen       = OpenScreen(&TheScreen);
Window1.Screen = MyScreen;
ReqWindow1.Screen = MyScreen;
MyWindow       = OpenWindow(&Window1);

/* Colors (sometimes crashes the system) */

SetRGB4(&(MyScreen->ViewPort),0L,0L,0L,0L);
SetRGB4(&(MyScreen->ViewPort),1L,15L,15L,15L);
SetRGB4(&(MyScreen->ViewPort),2L,7L,7L,7L);
SetRGB4(&(MyScreen->ViewPort),3L,11L,11L,11L);
SetRGB4(&(MyScreen->ViewPort),4L,13L,13L,13L);
SetRGB4(&(MyScreen->ViewPort),5L,15L,15L,15L);
SetRGB4(&(MyScreen->ViewPort),6L,15L,0L,0L);
SetRGB4(&(MyScreen->ViewPort),7L,9L,9L,15L);

}

Closestuff()
{

CloseWindow(MyWindow);
CloseScreen(MyScreen);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);

exit(TRUE);

}

Ship(x,y,h,c)
FLOAT x,y,h;
long c;
{
   long  ex,ey,dx,dy,x1,y1;
   float c1,c2;
   int rr;

   SetAPen(rp,c);

   rr=0;
   c1=sin(h);c2=cos(h);
   dx=c2*8   ; dy=c1*5;
   ex=c1*6   ; ey=c2*4;
   x1=x+dx   ; y1=y-dy    ;rr=rr+ReadPixel(rp,x1,y1);Move(rp,x1,y1);
   x1=x-dx-ex; y1=y+dy-ey ;rr=rr+ReadPixel(rp,x1,y1);Draw(rp,x1,y1);
   x1=x      ; y1=y       ;rr=rr+ReadPixel(rp,x1,y1);Draw(rp,x1,y1);
   x1=x-dx+ex; y1=y+dy+ey ;rr=rr+ReadPixel(rp,x1,y1);Draw(rp,x1,y1);
   x1=x+dx   ; y1=y-dy    ;Draw(rp,x1,y1);
   if(rr>4) rr=0;
   return(rr);
}

PlayGame()
{
   BYTE  pth,ptw;
   int gt;

   Move(rp,0L,0L);ClearScreen(rp);
   SetPointer(MyWindow,&sprite,1L,1L,0L,0L);
   SetUP();

   x[0]=150;y[0]=100;vx[0]=0;vy[0]=0;h[0]=-PI/2;flp[0]=0;
   x[1]=510;y[1]=100;vx[1]=0;vy[1]=0;h[1]=PI/2;flp[1]=0;
   hit = 0;hits[1]=10;hits[0]=10;qx = 0;
   Score();

   while( hit == 0 )
    {
      Direct1();
      MoveShip(1);
      Ship(xx[1],yy[1],hh[1],0L);
      if( Ship(x[1] ,y[1] ,h[1] ,6L) > 0 ) { hh[1]=0;hit=5; }
      Shots(1);
      Direct0();
      MoveShip(0);
      Ship(xx[0],yy[0],hh[0],0L);
      if( Ship(x[0] ,y[0] ,h[0] ,7L) > 0 ) { hh[0]=0;hit=6; }
      Shots(0);
    }
   SetRGB4(&(MyScreen->ViewPort),6L,15L,0L,0L);
   SetRGB4(&(MyScreen->ViewPort),7L,9L,9L,15L);
   Ship(x[1],y[1],h[1],0L);
   Ship(x[0],y[0],h[0],0L);
   if( hit <7 && hit >4 ) BlastShip(6-hit);
   for(gt=0;gt<ShotNum;gt++){t[gt][0]=0;t[gt][1]=0;}
}

Direct1()
{
   static int zzz;
   FLOAT c1,c2;

   zzz = zzz -1;
   hh[1]=h[1];
   if (MyScreen->MouseX == 0) hit=1;
   *jt = 0;
   if ( (*jd2 & JOYLEFT)  > 0 ) h[1]=h[1]+.1;
   if ( (*jd2 & JOYRIGHT) > 0 ) h[1]=h[1]-.1;
   if ( (*jd2 & 0x300 )>0 && (*jd2 & 0x300)!=0x300 )
      {
         vx[1]=vx[1]+cos(h[1])/3.3; if(vx[1]>4) vx[1]=4;
                                    if(vx[1]<-4) vx[1]=-4;
         vy[1]=vy[1]-sin(h[1])/5;   if(vy[1]>2.5) vy[1]=2.5;
                                    if(vy[1]<-2.5) vy[1]=-2.5;
      }
   if ( ((*jb & 0x80) == 0) && (t[flp[1]][1] == 0) && (zzz < 0) )
      {
         c1 = sin( h[1] ); c2 = cos( h[1] );

         zzz = 5;
         t[flp[1]][1]   = 200;
         svx[flp[1]][1] = c2*5;
         svy[flp[1]][1] = -c1*3.3;
         sx[flp[1]][1]  = x[1]+c2*4;
         sy[flp[1]][1]  = y[1]-c1*2.5;
         flp[1] = flp[1] + 1; if (flp[1] > (ShotNum-1)) flp[1]=0;
      }
   if( (Gflags & SP_INVISIBLE )>0 )
      {
         if((*jd2 & 0x03 )>0 && (*jd2 & 0x03)!=0x03)
              SetRGB4(&(MyScreen->ViewPort),6L,0L,0L,0L );
         else SetRGB4(&(MyScreen->ViewPort),6L,15L,0L,0L);
      }
}

Direct0()
{
   static int zzz;
   FLOAT c1,c2;

   zzz = zzz -1;
   hh[0]=h[0];
   if (MyScreen->MouseX == 0) hit=1;
   *jt = 0;
   if ( (*jd1 & JOYLEFT)  > 0 ) h[0]=h[0]+.1;
   if ( (*jd1 & JOYRIGHT) > 0 ) h[0]=h[0]-.1;
   if ( (*jd1 & 0x300 )>0 && (*jd1 & 0x300)!=0x300 )
      {
         vx[0]=vx[0]+cos(h[0])/3.3; if(vx[0]>4) vx[0]=4;
                                    if(vx[0]<-4) vx[0]=-4;
         vy[0]=vy[0]-sin(h[0])/5;   if(vy[0]>2.5) vy[0]=2.5;
                                    if(vy[0]<-2.5) vy[0]=-2.5;
      }
   if ( ((*jb & 0x40) == 0) && (t[flp[0]][0] == 0) && (zzz < 0) )
      {
         c1 = sin( h[0] ); c2 = cos( h[0] );

         zzz = 5;
         t[flp[0]][0]   = 200;
         svx[flp[0]][0] = c2*5;
         svy[flp[0]][0] = -c1*3.3;
         sx[flp[0]][0]  = x[0]+c2*4;
         sy[flp[0]][0]  = y[0]-c1*2.5;
         flp[0] = flp[0] + 1; if (flp[0] > (ShotNum-1)) flp[0]=0;
      }
   if( (Gflags & SP_INVISIBLE )>0 )
      {
         if((*jd1 & 0x03 )>0 && (*jd1 & 0x03)!=0x03)
              SetRGB4(&(MyScreen->ViewPort),7L,0L,0L,0L );
         else SetRGB4(&(MyScreen->ViewPort),7L,9L,9L,15L);
      }
}

Shots(z)
int z;
{
   int q,pix,n2;

   n2 = 1-z;

   for(q=0;q<ShotNum;q++)
      {
         if (t[q][z] != 0)
            {
               SetAPen(rp,0L);
               WritePixel(rp,(long)sx[q][z],(long)sy[q][z]);
               t[q][z] = t[q][z] -1;
               if( ( Gflags & SP_HITSHIP ) > 0 ){
                  if( x[n2]>sx[q][z] ) sx[q][z]=sx[q][z]+3.5;
                  else sx[q][z]=sx[q][z]-3.5;
                  if( y[n2]>sy[q][z] ) sy[q][z]=sy[q][z]+1;
                  else sy[q][z]=sy[q][z]-1; }

               else {
                  sx[q][z]=sx[q][z]+svx[q][z];
                  sy[q][z]=sy[q][z]+svy[q][z];

               if( ( Gflags & SP_SHOTGRAV ) > 0 )
               {
                  zaz = sx[q][z] - 320.0 ; zbz = sy[q][z] - 100.0;
                  zs2 = 1/( fabs(zaz) + fabs(zbz) );
                  svx[q][z] = svx[q][z] - zaz*zs2/4;
                  svy[q][z] = svy[q][z] - zbz*zs2/8;
               }    }

               pix=ReadPixel(rp,(long)sx[q][z],(long)sy[q][z]);
               if(pix >0 && pix <6)
                  {
                     t[q][z]=0;
                     if(( Gflags & SP_BLASTMODE)>0 )
                       RectFill(rp,(long)(sx[q][z]-5),(long)(sy[q][z]-3),(long)(sx[q][z]+5),(long)(sy[q][z]+3) );
                  }
               if(sy[q][z]<YUBORDER)  {sy[q][z]=YDBORDER;
                                 if ((Gflags & SP_LONGSHOTS)==0) t[q][z]=5*(t>5);}
               if(sy[q][z]>YDBORDER)  {sy[q][z]=YUBORDER;
                                 if ((Gflags & SP_LONGSHOTS)==0) t[q][z]=5*(t>5);}
               if(sx[q][z]>XRBORDER)  {sx[q][z]=XLBORDER;
                                 if ((Gflags & SP_LONGSHOTS)==0) t[q][z]=5*(t>5);}
               if(sx[q][z]<XLBORDER)  {sx[q][z]=XRBORDER;
                                 if ((Gflags & SP_LONGSHOTS)==0) t[q][z]=5*(t>5);}

               if(t[q][z] != 0) {
               if(qx == 0)
               if( pix==6+z)
                  {
                     DisplayBeep(MyScreen);
                     hits[n2]=hits[n2]-1;
                     if (hits[n2] == 0) hit = 5+z;
                     Score();
                  }
               SetAPen(rp,5L);
               WritePixel(rp,(long)sx[q][z],(long)sy[q][z]); }
            }
      }
}

Score()
{
   long sm;

   SetAPen(rp,0L);
   RectFill(rp,30L,3L,90L,7L);
   RectFill(rp,120L,3L,180L,7L);

   SetAPen(rp,6L);
   sm = hits[1]*6+30;
   RectFill(rp,30L,3L,sm,7L);

   SetAPen(rp,7L);
   sm = hits[0]*6+120;
   RectFill(rp,120L,3L,sm,7L);
}

MoveShip(z)
int z;
{
   xx[z]=x[z];yy[z]=y[z];

   x[z]=x[z]+vx[z];
   y[z]=y[z]+vy[z];

   if(y[z]<YUBORDER)  y[z]=YDBORDER;
   if(y[z]>YDBORDER)  y[z]=YUBORDER;
   if(x[z]>XRBORDER)  x[z]=XLBORDER;
   if(x[z]<XLBORDER)  x[z]=XRBORDER;

   if( ( Gflags & SP_SHIPGRAV ) > 0 )
      {
          zaz = x[z] - 320.0 ; zbz = y[z] - 100.0;
          zs2 = 1/( fabs(zaz) + fabs(zbz) );
          vx[z] = vx[z] - zaz*zs2/8;
          vy[z] = vy[z] - zbz*zs2/16;
      }

   if((Gflags & SP_SLOWDOWN) > 0)
      {
         vx[z]=vx[z]*.99;
         vy[z]=vy[z]*.99;
      }

   if((Gflags & SP_CRASHES) > 0)
      {
         if( ReadPixel(rp,(long)x[z],(long)y[z]) == 6+z )
            {
               DisplayBeep(MyScreen);
               hits[0]=hits[0]-1;
               hits[1]=hits[1]-1;
               if((hits[1] == 0) && (hits[0] == 0)) hits[1]=hits[0]=1;
               if(hits[0]==0) hit=6;
               if(hits[1]==0) hit=5;
               Score();
            }
      }

}

SetUP()
{
   int fflag;

   FLOAT al,c1,c2;
   long pp,a1,a2,a3,a4;
   SetAPen(rp,1L);
   Move(rp,10L,8L);
   Text(rp,"E:",2L);
   Move(rp,100L,8L);
   Text(rp,"E:",2L);

   for(pp=0;pp<11;pp++)
      {
         WritePixel(rp,(long)30+pp*6,2L);
         WritePixel(rp,(long)30+pp*6,8L);
         WritePixel(rp,(long)120+pp*6,2L);
         WritePixel(rp,(long)120+pp*6,8L);
      }
   if(Gflags & SP_PLANET)
      {
         for(al=0;al<PI;al=al+.01)
            {
               SetAPen(rp,(long)rand()/6000L);
               c1=sin(al);c2=cos(al);
               Move(rp,(long)(320+c1*70),(long)(100-c2*40));
               Draw(rp,(long)(320-c1*70),(long)(100-c2*40));
            }

      }
   if(Gflags & SP_WALLS)
      {
         for(al=0;al<11;al++)
            {
               SetAPen(rp,(long)al/2);
               Move(rp,(long)(al*2),(long)(15+al));
               Draw(rp,(long)(639-al*2),(long)(15+al));
               Draw(rp,(long)(639-al*2),(long)(189-al));
               Draw(rp,(long)(al*2),(long)(189-al));
               Draw(rp,(long)(al*2),(long)(15+al));
               Draw(rp,(long)(al*2+1),(long)(15+al));
               Draw(rp,(long)(al*2+1),(long)(189-al));
               Draw(rp,(long)(638-al*2),(long)(189-al));
               Draw(rp,(long)(638-al*2),(long)(15+al));
            }
      }
   if(Gflags & SP_ASTEROIDS)
      {
         for(al=0;al<5;al++)
            {
               do {
               a1 = 50+rand()/61; a2 = 35+rand()/253;
               Move(rp,a1,a2); fflag = 0;
               if( ((150-a1)>-5) && ((150-a1)<75) && ((100-a2)>-5) && ((100-a2)<45) ) fflag =1;
               if( ((510-a1)>-5) && ((510-a1)<75) && ((100-a2)>-5) && ((100-a2)<45) ) fflag =1;
               } while(fflag == 1);
               for(pp=0;pp<150;pp++)
                {
                  SetAPen(rp,(long)rand()/6000L);
                  a3 = rand()/469-35; a4 = rand()/820-20;
                  if( (a3*a3+a4*a4*3.24) < 1225)
                  Draw(rp, (long)a1+a3 , (long)a2+a4 );
                }
            }
      }


}

RequestIt()
{
   int c;

   ReqWindow = OpenWindow(&ReqWindow1);
   rp = ReqWindow->RPort;

   SetAPen(rp,1L);
   Move(rp,140L,78L);Text(rp,"Last Score",10L);
   Move(rp,172L,90L);Text(rp,"to",2L);
   Move(rp,0L,65L);Draw(rp,359L,65L);

   Ship(116.0,87.0,1.0,7L);
   while(hits[1]<10)
      {
         Move(rp,(long)138+hits[1]*3,83L);
         Draw(rp,(long)138+hits[1]*3,91L);hits[1]++;
      }

   Ship(244.0,87.0,2.0,6L);
   while(hits[0]<10)
      {
         Move(rp,(long)222L-hits[0]*3,83L);
         Draw(rp,(long)222L-hits[0]*3,91L);hits[0]++;
      }

   c = 0;
   while(c != 1)
      {
         WaitPort(ReqWindow->UserPort);
         message = (struct IntuiMessage *)GetMsg(ReqWindow->UserPort);
         MyGad = (struct Gadget *) message->IAddress;
         c = MyGad->GadgetID;

         if(c == 2) { c = 1; gf = 1; }

         ReplyMsg(message);
      }

   Gflags = 0;
   if((Gadget3.Flags & SELECTED)>0) Gflags = Gflags + SP_INVISIBLE;
   if((Gadget7.Flags & SELECTED)>0) Gflags = Gflags + SP_SLOWDOWN;
   if((Gadget4.Flags & SELECTED)>0) Gflags = Gflags + SP_CRASHES;
   if((Gadget6.Flags & SELECTED)>0) Gflags = Gflags + SP_LONGSHOTS;
   if((Gadget8.Flags & SELECTED)>0) Gflags = Gflags + SP_PLANET;
   if((Gadget10.Flags & SELECTED)>0) Gflags = Gflags + SP_ASTEROIDS;
   if((Gadget11.Flags & SELECTED)>0) Gflags = Gflags + SP_BLASTMODE;
   if((Gadget12.Flags & SELECTED)>0) Gflags = Gflags + SP_SHOTGRAV;
   if((Gadget13.Flags & SELECTED)>0) Gflags = Gflags + SP_SHIPGRAV;
   if((Gadget14.Flags & SELECTED)>0) Gflags = Gflags + SP_HITSHIP;
   if((Gadget9.Flags & SELECTED)>0) Gflags = Gflags + SP_WALLS;
   if((Gadget5.Flags & SELECTED)>0) ShotNum = 10;
   else ShotNum = 5;

   CloseWindow(ReqWindow);
   rp = MyWindow->RPort;

}

BlastShip(z)
int z;
{
   long  bx[16],by[16],bvx[8],bvy[8];
   long  px[40],py[40],pvx[40],pvy[40];
   FLOAT q1,q2,dx,dy,ex,ey;
   int gt,dt;

   q1=sin(h[z]);q2=cos(h[z]);
   dx=q2*800   ; dy=q1*500;
   ex=q1*600   ; ey=q2*400;
   for(gt=0;gt<16;gt=gt+8){
   bx[0+gt]=bx[7+gt]=x[z]*100+dx;    by[0+gt]=by[7+gt]=y[z]*100-dy;
   bx[2+gt]=bx[1+gt]=x[z]*100-dx-ex; by[2+gt]=by[1+gt]=y[z]*100+dy-ey;
   bx[4+gt]=bx[3+gt]=x[z]*100;       by[4+gt]=by[3+gt]=y[z]*100;
   bx[6+gt]=bx[5+gt]=x[z]*100-dx+ex; by[6+gt]=by[5+gt]=y[z]*100+dy+ey;}

   for(gt=0;gt<8;gt++)
      {
         bvx[gt]=(1-rand()/XXX) *200+vx[z]*50;
         bvy[gt]=(.5-rand()/YYY)*200+vy[z]*50;
      }

   for(gt=0;gt<40;gt++){ px[gt]=x[z]*100;py[gt]=y[z]*100;
                         pvx[gt]=( 1-rand()/XXX)*200+vx[z]*50;
                         pvy[gt]=(.5-rand()/YYY)*200+vy[z]*50;   }

   qx = 1;

   for(gt = 0;gt<50;gt++)
    {
      x[1-z]=x[1-z]+vx[1-z]*2;
      y[1-z]=y[1-z]+vy[1-z]*2;

      vx[1-z]=vx[1-z]*.95;
      vy[1-z]=vy[1-z]*.95;

      if(y[1-z]<YUBORDER)  y[1-z]=YDBORDER;
      if(y[1-z]>YDBORDER)  y[1-z]=YUBORDER;
      if(x[1-z]>XRBORDER)  x[1-z]=XLBORDER;
      if(x[1-z]<XLBORDER)  x[1-z]=XRBORDER;

      Ship(xx[1-z],yy[1-z],hh[1-z],0L);
      Ship(x[1-z] ,y[1-z] ,h[1-z] ,(long)6+z);
      xx[1-z]=x[1-z];yy[1-z]=y[1-z];hh[1-z]=h[1-z];
      Shots(1);
      Shots(0);

      for(dt=0;dt<40;dt++)
         {
            SetAPen(rp,0L);
            WritePixel(rp,(long)px[dt]/100,(long)py[dt]/100);
            px[dt]=px[dt]+pvx[dt];
            py[dt]=py[dt]+pvy[dt];
            if(py[dt]<LYUBORDER) py[dt] =LYDBORDER;
            if(py[dt]>LYDBORDER) py[dt] =LYUBORDER;
            if(px[dt]<LXLBORDER) px[dt] =LXRBORDER;
            if(px[dt]>LXRBORDER) px[dt] =LXLBORDER;
            SetAPen(rp,(long)7-z);
            WritePixel(rp,(long)px[dt]/100,(long)py[dt]/100);
         }

      Shots(1);
      Shots(0);

      for(dt=0;dt<8;dt++)
         {
            SetAPen(rp,0L);
            Move(rp,(long)bx[ dt*2 ]/100,(long)by[ dt*2 ]/100);
            Draw(rp,(long)bx[dt*2+1]/100,(long)by[dt*2+1]/100);
            bx[ dt*2 ]=bx[ dt*2 ]+bvx[dt];by[ dt*2 ]=by[ dt*2 ]+bvy[dt];
            bx[dt*2+1]=bx[dt*2+1]+bvx[dt];by[dt*2+1]=by[dt*2+1]+bvy[dt];

            if( by[dt*2] < 1500 ) { by[ dt*2 ]=by[ dt*2 ]+16000;
                                  by[dt*2+1]=by[dt*2+1]+16000; }
            if( by[dt*2] > 17500) { by[ dt*2 ]=by[ dt*2 ]-16000;
                                  by[dt*2+1]=by[dt*2+1]-16000; }

            if( bx[dt*2] < 2000 ) { bx[ dt*2 ]=bx[ dt*2 ]+60000;
                                  bx[dt*2+1]=bx[dt*2+1]+60000; }
            if( bx[dt*2] > 62000) { bx[ dt*2 ]=bx[ dt*2 ]-60000;
                                  bx[dt*2+1]=bx[dt*2+1]-60000; }

            SetAPen(rp,(long)7-z);
            Move(rp,(long)bx[ dt*2 ]/100,(long)by[ dt*2 ]/100);
            Draw(rp,(long)bx[dt*2+1]/100,(long)by[dt*2+1]/100);
         }
    }
}

/* ------------------ The main() part ---------------------- */

main()
{

jt  = JOYTEST;
jd1 = JOY0DAT;
jd2 = JOY1DAT;
jb  = JOYBUT;

gf = 0;

Openstuff();
rp = MyWindow->RPort;

SetUP();

while( gf == 0)
{

   RequestIt();

   if (gf == 0) PlayGame();

}

Closestuff();

}
