/*
==============================================================================
		      WordUp Graphics Toolkit Version 5.0                     
			     Demonstration Program 61                         
									       
 This program demonstrates use of the sprite library to create a simple       
 SPACE INVADERS game. Mouse movement is used to control the user's ship,  
 and the aliens will follow a predetermined pattern. Alien fire will not     
 damage your ship. This game is incomplete.                                  
									      
 *** PROJECT ***                                                             
 This program requires the WGT5_WC.LIB and WSPR_WC.LIB files to be linked.   
									      
 *** DATA FILES ***                                                          
 INVADE.PAK, INVADER.SPR                                                     
							   WATCOM C++ VERSION 
==============================================================================
*/

#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <ctype.h>
#include <wgt5.h>
#include <wgtspr.h>

block title;

color palette[256];
block sprites[1001];
short x,y,i;
char k;
char ch;
short killed;
short totshoot;
short temp;

// sprites numbers (So you don't get confused)
// 1    = spaceship
// 2    = missile fired
// 3-24 = aliens!
// 25-39= aliens missiles

void gameloop (void);


int timer;

void timer_routine (void)
{
 timer++;
}


void main(void)
{
  if (!vgadetected ())
  {
    printf ("VGA is required to run this program...");
    exit (1);
  }


  printf ("WGT Example #61\n\n");
  printf ("This program demonstrates use of the sprite library to create a simple\n");
  printf ("SPACE INVADERS game. Mouse movement is used to control the user's ship,\n");
  printf ("and the aliens will follow a predetermined pattern. Alien fire will not\n");
  printf ("damage your ship. This game is incomplete.\n");
  printf ("Press q during the game to quit.\n");

  i = minit ();
  if (i == 0)
  { 
    printf ("Mouse not detected.  You need a mouse for this example program\n");
    exit (1);
  }
  else printf ("Mouse with %i buttons detected.\n", i);

  printf ("\nPress any key to begin.\n");
  getch ();

  vga256 ();
  title = wloadpak ("invade.pak");
  wloadsprites (palette, "invader.spr", sprites, 0, 100);
  wsetpalette (0, 255, palette);

  winittimer ();
  wstarttimer (timer_routine, TICKS(60));

  do {
  killed = 0;
  wclip (0, 0, 319, 199);
  maxsprite = 39;                            /* thirty nine sprites on now */
  initialize_sprites (sprites);

  wsetscreen (spritescreen);

  wputblock (0, 0, title, 0);
  wsetcolor (0);
  wbar(0, 0, 319, 140);
  wnormscreen ();
  wcopyscreen(0, 0, 319, 199, spritescreen, 0, 0, NULL);
  wcopyscreen(0, 0, 319, 199, spritescreen, 0, 0, backgroundscreen);

  spriteon(0, 160, 148, 1);

  for (y = 0; y < 3; y++)
    for (x = 1; x < 8; x++)
    {
      temp = (y * 7) + x + 1;
      spriteon(temp, x * 20 + 10, 20 + y * 30, 3);   /* turn alien on */
      animate(temp, "(3,3)(4,3)(5,3)(4,3)R");        /* animate it */
      animon (temp);                                        
      movex (temp, "(1,150,0)(0,30,0)(-1,150,0)(0,30,0)R");   
	/* set up x movement */
      
      movey (temp, "(0,150,0)(1,30,0)(0,150,0)(-1,30,0)R");   
	/* set up y movement */
      movexon (temp);
      moveyon (temp);
    }
    
  msetbounds(0, 148, 319, 148);
  msetxy (160, 148);

  timer = 0;
 
  for (x = 1; x < 15; x++)
    spriteoff (x + 22);

  totshoot = 0;


    do {                                /* Play game until keypress */
      gameloop ();
    } while ((!kbhit ()) && (killed < 21));
    
    if (killed != 21)
      ch = toupper (getch ());
    killed = 0;
    msetbounds (0, 0, 319, 199);
  
    deinitialize_sprites ();            /* Deinit the sprite system */
  } while (ch != 'Q');                  /* Restart game if not Q */

  wstoptimer ();
  wdonetimer ();

  mdeinit ();
  wsetmode (3);
}



void gameloop (void)
{
short checkspr;
int movement_multiplier;
int count;
int openslot;

  //wretrace ();                        /* Time updates to vertical retrace */
  erase_sprites ();

  count = movement_multiplier = timer;
  timer = 0;


  while (count > 0)
    {
     s[0].x = mouse.mx;                /* Set player position */
     s[0].y = mouse.my;

     if ((mouse.but == 1) && (s[1].on == 0))   /* not shooting then */
       {
	sound (600);
	spriteon (1, s[0].x + 3, s[0].y, 2);/* turn on the missile sprite */
	movey (1, "(-2,200,0)");       /* make it move up */
	moveyon (1);                   /* turn the movement on */
       }
    
     for (y = 0; y < 3; y++)           /* loop through all aliens */
       for (x = 1; x < 8; x++)
	 {
	  checkspr = (y * 7) + x + 1;
	  if (s[checkspr].on == 1)     /* if the sprite is still onscreen */
	    {
	     /* Do not shoot more than 14 at once since we can only have 
		sprites */
	     if ((rand () % 50 == 5) && (totshoot < 13))
	       /* 1 in 50 chance of shooting */
	       {       
		openslot = -100;
		i = 1;
		do 
		  {
		   if (s[i + 22].on == 0)  /* find an open slot for missile */
		     { 
		      openslot = i;
		      i = 16;
		     }
		   i++;
		  } while (i < 15);
	  
		if (openslot != -100)
		  {
		   totshoot++;
		   spriteon (openslot + 22, s[checkspr].x + 4, 
			     s[checkspr].y, 2);  /* turn shot on */
		   movey (openslot + 22, "(1,160,0)"); /* move it down */
		   moveyon (openslot + 22);
		  }
	       } 
	
	  if ((overlap (1, checkspr) == 1) && (s[checkspr].num <6))        
	  /* if your missile is hitting it and it isn't already exploding */
	    {
	     sound (200);
	     spriteoff (1);                     /* turn off the missile */
	     animate (checkspr, "(6,5)(7,5)(8,5)(9,5)(10,5)");  
		      /* show explosion */
	     animon (checkspr);                 /* reset animation */
	    }
	  if (s[checkspr].num == 10)            /* if finished animating, */
	    {
	     spriteoff (checkspr);              /* turn off the sprite */
	     killed++;
	    }
	 }
    }
  
  for (y = 1; y < 15; y++)              /* Disable missles when they hit ground */
  {
    if ((s[y + 22].on == 1) && (s[y + 22].y > 154))
      {
       spriteoff (y + 22);
       totshoot--;
      }
  }
  
  if (s[1].y < -10)                     /* User missle off screen? */
    spriteoff (1);
  count--;
 } 
 
  draw_sprites (movement_multiplier);                       
  /* Draw the sprites again */
   
  nosound ();                            /* Stop all sounds */
}

