[comp.sources.games] v01i093: Asteroids for the Sun, Part02/02

games-request@basser.cs.su.oz.AU (07/16/87)

Submitted by: Rich Burridge <richb@sunk.oz.AU>
Comp.sources.games: Volume 1, Issue 93
Archive-name: asteroids/Part02



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 2)."
# Contents:  ast_main.c
# Wrapped by richb@sunk on Fri May 29 16:20:55 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f ast_main.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"ast_main.c\"
else
echo shar: Extracting \"ast_main.c\" \(36644 characters\)
sed "s/^X//" >ast_main.c <<'END_OF_ast_main.c'
X
X/*  ast_main.c
X *
X *  The game of Asteroids.
X *  Written by Rich Burridge - SUN Microsystems Australia (Melbourne).
X *
X *  Version 3.0.  -  April 1987.
X *
X *  No responsibility is taken for any errors or inaccuracies inherent
X *  either to the comments or the code of this program, but if reported
X *  to me then an attempt will be made to fix them.
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <sys/fcntl.h>
X#include "bltstuff.h"
X#include "asteroids.h"
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X
X#include <sys/types.h>
X#include <sys/timeb.h>
X#include <signal.h>
X
XCanvas canvas ;
XFrame base_frame ;
XPixfont *pf ;
XPixwin *pw ;
X
Xextern etext() ;
X
XNotify_value main_loop() ;
Xvoid event_proc() ;
X
Xshort ast_image[] = {
X#include "asteroids.icon"
X} ;
XDEFINE_ICON_FROM_IMAGE(ast_icon,ast_image) ;
X
Xshort testarea[(BSIZE+1)*4*BYTESPERWORD] ;
Xmpr_static(test_pr,512,4,1,testarea) ;
X
Xshort wrkarea[50*48*BYTESPERWORD] ;
Xmpr_static(wrk_pr,768,50,1,wrkarea) ;
X
Xstruct timeb tlast,tnew,tstartflash,tlastflash ;
X
Xstruct ainfo
X         {
X           struct ainfo *next ;
X           int x,y,dx,dy,xp,yp,sx,sy,wx,wy ;
X           int sizex,sizey,offx,offy,typ ;
X         } ;
X
Xstruct hscore highscore[MAXHS] ;
X
Xint key_stations[3] = {21, 22, 23} ;  /* Station values for function keys R1-R3. */
Xchar old_key_vals[3][MAXLINE] ;       /* Function key string values to save. */
Xchar new_key_vals[3][MAXLINE] =       /* Function key values used by asteroids. */
X     {
X       "g",                  /* Motor on - Function key R1. */
X       "s",                  /* Motor off - Function key R2. */
X       "t"                   /* Hyperspace/teleport - Function key R3. */
X     } ;
X
Xchar path[MAXLINE] ;         /* Full path to the asteroids files. */
Xchar progname[MAXLINE] ;     /* Name of this program. */
Xchar thisscore[MAXLINE] ;    /* User name for new highscore. */
Xchar titlestring[MAXLINE] ;  /* Displayed titleline for this program. */
X
Xint c ;                      /* Value returned by event_proc. */
Xint canvasfd ;               /* File descriptor for canvas subwindow. */
Xint canvasflags ;            /* Used to setup no delay for canvas. */
Xint csi,csj ;                /* Used to put the new highscore value. */
Xint height ;                 /* Height of the asteroids window. */
Xint givehelp ;               /* Set to 0, indicates no initial help. */
Xint orgx ;                   /* X origin of the asteroids window. */
Xint orgy ;                   /* Y origin of the asteroids window. */
Xint scorei ;                 /* Number of characters in highscore user name. */
Xint state = 0 ;              /* Current button state. */
Xint width ;                  /* Width of the asteroids window. */
X
Xint xmax,xmin,ymax,ymin,mindimension ;
Xint score = 0 ;
Xint scorethistank = 0 ;
X
Xint enkey = 01652 ;      /* ENCODE key used in highscore file. */
Xint addbonus = 0 ;
Xint bonus ;              /* what bonus do we give for each set of asteroids */
Xint bonusship = 10000 ;  /* new ship every bonusship points. */
X
Xint flashbonus = 0 ;     /* flag for when to flash message. */
Xint bonusshown = 0 ;
Xint motoron ;
Xint fuel = FULLTANK ;    /* Amount of spaceship fuel left. */
Xint fuelxoffset ;        /* Start of fuel display bar. */
Xint fuelmaxlength ;      /* Maximum length of fuel bar. */
Xint fuellength ;         /* Current length of fuel bar. */
Xint progstate ;          /* State machine for main loop. */
Xint savedstate ;         /* State machine value after Ctrl S. */
X
Xchar bonusstr[80] ;
X
Xstruct ainfo *freeap,*bplist,*waitlist,*aplist ;
Xint basestatus ;
X
Xint ax,ay,bx,by,bdx,bdy,bxp,byp,bxpd,bypd ;
Xint nummove,swcount,ssector,scount ;
Xint basecount,t3count,t1count,waitcount,rr,dummy ;
Xint keys = 0 ;
X
Xextern int sfunc ;           /* Rasterop code used by WRITELN. */
Xchar *malloc() ;
Xextern int rint() ;
X
X
Xcheckscore()
X
X{
X  char buffer[MAXLINE] ;
X
X  SCHRFUNC(RRPL) ;
X  csi = MAXHS - 1 ; 
X  while ((score > highscore[csi].score) && (csi >= 0)) csi-- ;
X
X  if (++csi < MAXHS)
X    {
X      clear_screen() ;
X      SPRINTF(buffer,"Congratulations, you have one of the top %d scores\n",MAXHS) ;
X      WRITELN(100,140,buffer) ;
X      WRITELN(100,200,"Please enter your name : ") ;
X      scorei = 0 ;
X      c = 0 ;
X      thisscore[scorei] = '_' ;
X      thisscore[scorei+1] = '\0' ;
X      WRITELN(370,200,thisscore) ;
X      progstate = NEXTLINE ;
X    }
X  else progstate = DOEND ;
X}
X
X
Xshowhighscore()
X
X{
X  char buffer[MAXLINE] ;
X  int i ;
X
X  clear_screen() ;
X  write_bold(220,200,"High Scores") ;
X  SCHRFUNC(ROR) ;
X  WRITELN(220,201,"___________") ;
X  WRITELN(200,300," Score       Name") ;
X  WRITELN(200,301," _____       ____") ;
X  SCHRFUNC(RRPL) ;
X  for (i = 0; i < MAXHS; i++)
X    {
X      SPRINTF(buffer,"%6d      %s",highscore[i].score,highscore[i].who) ;
X      WRITELN(200,330+i*30,buffer) ;
X    }
X  SPRINTF(buffer,"Your score was %d",score) ;
X  WRITELN(220,500,buffer) ;
X  WRITELN(5,height-40,"Type RETURN to quit") ;
X  progstate = SCORE ;
X}
X
X
Xgethighscore()
X
X{
X  int hsfile,i ;
X  struct hscore nullscore ;
X  char highscname[MAXLINE] ;   /* Full path name of the high score file. */
X
X  SPRINTF(highscname,"%sasteroids.hs",path) ;
X  if ((hsfile = open(highscname,2)) == -1)
X    {
X      if ((hsfile = creat(highscname,0777)) == -1)
X        {
X          PRINTF("\nunable to create highscore file.\n") ;
X          exit(1) ;
X        }
X
X      nullscore.score = 0 ;       /* file should be open. */
X      STRCPY(nullscore.who," ") ;
X      for (i = 0; i < MAXHS; i++)
X        {
X          puths(hsfile,&nullscore) ;
X          STRCPY(highscore[i].who," ") ;
X          highscore[i].score = 0 ;
X        }
X    }
X  else
X    for (i = 0; i < MAXHS; i++) geths(hsfile,&highscore[i]) ;
X  CLOSE(hsfile) ;
X}
X
X
Xputhighscore()
X
X{
X  int hsfile,i ;
X  char highscname[MAXLINE] ;   /* Full path name of the high score file. */ 
X
X  SPRINTF(highscname,"%sasteroids.hs",path) ;
X  if ((hsfile = open(highscname,1)) == -1)
X    PRINTF("Unable to open highscore file.\n") ;
X  else
X    {
X      for (i = 0; i < MAXHS; i++) puths(hsfile,&highscore[i]) ;
X      CLOSE(hsfile) ;
X    }
X}
X
X
Xpuths(where,record)    /* put one hscore record out. */
Xstruct hscore *record ;
Xint where ;
X
X{
X  char buffer[32],valuestr[7] ;
X  int i,value ;
X
X  for (i = 0; i < 16; i++) buffer[i] = record->who[i] ^ enkey ;
X  value = record->score ;
X  SPRINTF(valuestr,"%d",value) ;
X  for (i = 0; i < 7; i++) buffer[i+16] = valuestr[i] ^ enkey ;
X  WRITE(where,buffer,23) ;
X}
X
X
Xgeths(where,record)    /* get one hscore record in. */
Xstruct hscore *record ;
Xint where ;
X
X{
X  char buffer[32],valuestr[7] ;
X  int i ;
X
X  i = read(where,buffer,23) ;
X  for (i = 0; i < 16; i++) record->who[i] = buffer[i] ^ enkey ;
X  for (i = 0; i < 7; i++) valuestr[i] = buffer[i+16] ^ enkey ;
X  record->score = atoi(valuestr) ;
X}
X
X
Xinit()
X
X{
X  int i,j ;
X
X  NICE(-20) ;                  /* High priority activity this game !!! */
X  gethighscore() ;
X  BLT_MEM(&wrk_pr,0,0,768,50,RXOR,&wrk_pr,0,0) ;    /* Clear work area. */
X  rr = 1234 ;
X
X  LINE(&wrk_pr,128,25,128,40,RSET) ;                /* BIG asteroid. */
X  LINE(&wrk_pr,128,40,147,49,RSET) ;
X  LINE(&wrk_pr,147,49,160,49,RSET) ;
X  LINE(&wrk_pr,160,49,173,47,RSET) ;
X  LINE(&wrk_pr,173,47,177,35,RSET) ;
X  LINE(&wrk_pr,177,35,177,19,RSET) ;
X  LINE(&wrk_pr,177,19,174,8,RSET) ;
X  LINE(&wrk_pr,174,8,168,3,RSET) ;
X  LINE(&wrk_pr,168,3,150,0,RSET) ;
X  LINE(&wrk_pr,150,0,144,2,RSET) ;
X  LINE(&wrk_pr,144,2,135,15,RSET) ;
X  LINE(&wrk_pr,135,15,128,25,RSET) ;
X
X  for (i = 1; i <= 48; i++)
X    {
X      j = 128 ;
X      while (BITSET(j,i,48,wrkarea) == 0) j++ ;
X      do
X        j++ ;
X      while (BITSET(j,i,48,wrkarea) != 0) ;
X      while (BITSET(j,i,48,wrkarea) == 0)
X        {
X          if (rint(j-128) < 6) SETON(j,i,48,wrkarea) ;
X                            else SETOFF(j,i,48,wrkarea) ;
X          j++ ;
X        }
X    }
X
X  LINE(&wrk_pr,192,10,192,20,RSET) ;    /* MEDIUM asteroid. */
X  LINE(&wrk_pr,192,20,201,29,RSET) ;
X  LINE(&wrk_pr,201,29,214,29,RSET) ;
X  LINE(&wrk_pr,214,29,221,17,RSET) ;
X  LINE(&wrk_pr,221,17,221,08,RSET) ;
X  LINE(&wrk_pr,221,08,209, 0,RSET) ;
X  LINE(&wrk_pr,209, 0,200, 0,RSET) ;
X  LINE(&wrk_pr,200, 0,192,10,RSET) ;
X
X  for (i = 1; i <= 28; i++)
X    {
X      j = 192 ;
X      while (BITSET(j,i,48,wrkarea) == 0) j++ ;
X      do
X        j++ ;
X      while (BITSET(j,i,48,wrkarea) != 0) ;
X      while (BITSET(j,i,48,wrkarea) == 0)
X        {
X          if (rint(j-192) < 5) SETON(j,i,48,wrkarea) ;
X                            else SETOFF(j,i,48,wrkarea) ;
X          j++ ;
X        }
X    }
X
X  LINE(&wrk_pr,261, 0,270, 0,RSET) ;  /* SMALL asteroid. */
X  LINE(&wrk_pr,270, 0,270, 9,RSET) ;
X  LINE(&wrk_pr,270, 9,263,14,RSET) ;
X  LINE(&wrk_pr,263,14,256,14,RSET) ;
X  LINE(&wrk_pr,256,14,256, 8,RSET) ;
X  LINE(&wrk_pr,256, 8,261, 0,RSET) ;
X  for (i = 1; i <= 13; i++)
X    {
X      j = 256 ;
X      while (BITSET(j,i,48,wrkarea) == 0) j++ ;
X      do
X        j++ ;
X      while (BITSET(j,i,48,wrkarea) != 0) ;
X      while (BITSET(j,i,48,wrkarea) == 0)
X        {
X          if (rint(j-256) < 4) SETON(j,i,48,wrkarea) ;
X          else SETOFF(j,i,48,wrkarea) ;
X          j++ ;
X        }
X    }
X
X  for (i = 0; i <= 3; i++)      /* spaceship */
X    BLT_MEM(&wrk_pr,320+20-i/2,i+10,i+10,1,RXNOR,&wrk_pr,320+20-i/2,i+10) ;
X  for (i = 4; i <= 15; i++)
X    {
X      BLT_MEM(&wrk_pr,320+20-i/2,i+10,4,1,RXNOR,&wrk_pr,320+20-i/2,i+10) ;
X      BLT_MEM(&wrk_pr,320+26+(i+1)/2,i+10,4,1,RXNOR,&wrk_pr,320+26+(i+1)/2,i+10) ;
X    }
X  BLT_MEM(&wrk_pr,320,26,50,4,RXNOR,&wrk_pr,320,26) ;
X  for (i = 0; i <= 3; i++)
X    BLT_MEM(&wrk_pr,320+15-i/2,49-i,i+20,1,RXNOR,&wrk_pr,320+15-i/2,49-i) ;
X  for (i = 4; i <= 19; i++)
X    {
X      BLT_MEM(&wrk_pr,320+15-i/2,49-i,4,1,RXNOR,&wrk_pr,320+15-i/2,49-i) ;
X      BLT_MEM(&wrk_pr,320+31+(i+1)/2,49-i,4,1,RXNOR,&wrk_pr,320+31+(i+1)/2,49-i) ;
X    }
X  BLT_MEM(&wrk_pr,320+18,0,3,3,RXNOR,&wrk_pr,320+18,0) ;
X  BLT_MEM(&wrk_pr,320+30,0,3,3,RXNOR,&wrk_pr,320+30,0) ;
X  LINE(&wrk_pr,320+19,2,320+24,9,RSET) ;
X  LINE(&wrk_pr,320+31,2,320+26,9,RSET) ;
X
X  BLT_MEM(&wrk_pr,256,16,3,3,RXNOR,&wrk_pr,256,16) ;    /* Missiles. */
X
X  aplist = NULL ;
X  bplist = NULL ;
X  freeap = NULL ;
X  waitlist = NULL ;
X  waitcount = rint(100) ;
X
X  xmax = width - 4 ;
X  xmin = 4 ;
X  ymax = height - 4 - FONT_HEIGHT ;
X  ymin = 4 + FONT_HEIGHT ;
X  mindimension = (height < width) ? height : width ;
X 
X/* Calculate bonus payments, smaller window = LARGER bonus. */
X  bonus = 80 - ((mindimension / 100) * 10) ;
X 
X  BLT_SCRN(0,0,width,height,RXOR) ;
X 
X/* Screen black except the border. */
X  FPRINTF(stderr,"%d %d %d %d\n",xmin,ymin,xmax-xmin+1,ymax-ymin+1) ;
X  BLT_SCRN(xmin,ymin,xmax-xmin+1,ymax-ymin+1,RXNOR) ;
X  SCHRFUNC(RRPL) ;
X  WRITELN(xmin+2,height-5,"Fuel : ") ;
X  FPRINTF(stderr,"%d %d\n",xmin+2,height-5) ;
X
X  fuelxoffset = xmin+58 ;
X  fuelmaxlength = (xmax-xmin) - fuelxoffset ;
X  fuellength = fuelmaxlength ;
X 
X  BLT_SCRN(fuelxoffset,height-FONT_HEIGHT,fuellength,FONT_HEIGHT-2,RXNOR) ;
X  addscore(0) ;
X}
X
X
Xcleara(a)
Xstruct ainfo *a ;
X
X{
X  if (a->sizex > 0 && a->sizey > 0)
X    BLT_MEM_TO_SCRN(a->x+a->offx,a->y+a->offy,a->sizex,a->sizey,RXOR,
X                    &wrk_pr,a->wx+a->offx,a->wy+a->offy) ;
X}
X
X
Xupdatea(a)
Xstruct ainfo *a ;
X
X{
X  int res,dx,dy ;
X  int sizex,sizey,offx,offy ;
X
X  res = 1 ;
X  a->dx += a->xp*nummove ;
X  dx = a->dx / AFACTOR ;
X  a->dy += a->yp*nummove ;
X  dy = a->dy / AFACTOR ;
X  if (dx || dy)
X    {
X      sizex = a->sx ;
X      sizey = a->sy ;
X      offx = 0 ;
X      offy = 0 ;
X      a->x += dx ;
X      a->y += dy ;
X      if (a->x < xmin)
X        {
X          offx = xmin - a->x ;
X          sizex -= offx ;
X        }
X      else if (a->x > xmax - a->sx) sizex = xmax - a->x + 1 ;
X      if (a->y < ymin)
X        {
X          offy = ymin - a->y ;
X          sizey -= offy ;
X        }
X      else if (a->y > ymax - a->sy) sizey = ymax - a->y + 1 ;
X      if (sizex > 0 && sizey > 0)
X        BLT_MEM_TO_SCRN(a->x+offx,a->y+offy,sizex,sizey,RXOR,
X                        &wrk_pr,a->wx+offx,a->wy+offy) ;
X      else res = 0 ;
X      if (a->sizex > 0 && a->sizey > 0)
X        BLT_MEM_TO_SCRN(a->x-dx+a->offx,a->y-dy+a->offy,a->sizex,a->sizey,RXOR,
X                        &wrk_pr,a->wx+a->offx,a->wy+a->offy) ;
X      a->sizex = sizex ;
X      a->sizey = sizey ;
X      a->offx = offx ;
X      a->offy = offy ;
X      a->dx -= AFACTOR * dx ;
X      a->dy -= AFACTOR * dy ;
X    }
X  return(res) ;
X}
X
X
Xstarta(plist,typ,x,y,xp,yp)
Xstruct ainfo **plist ;
Xint typ,x,y,xp,yp ;
X
X{
X  struct ainfo *newap ;
X
X  if (freeap == NULL)
X    newap = (struct ainfo *) malloc(sizeof(struct ainfo)) ;
X  else
X    {
X      newap = freeap ;
X      freeap = freeap->next ;
X    }
X  newap->next = *plist ;
X  *plist = newap ;
X  newap->typ = typ ;
X  newap->x = x ;
X  newap->dx = 0 ;
X  newap->xp = xp ;
X  newap->y = y ;
X  newap->dy = 0 ;
X  newap->yp = yp ;
X  switch (typ)
X    {
X      case 0 : newap->sx = 3 ;
X               newap->sy = 3 ;
X               newap->wx = 256 ;
X               newap->wy = 16 ;
X               break ;
X
X      case 1 : newap->sx = 50 ;
X               newap->sy = 50 ;
X               newap->wx = 128 ;
X               newap->wy = 0 ;
X               break ;
X
X      case 2 : newap->sx = 30 ;
X               newap->sy = 30 ;
X               newap->wx = 192 ;
X               newap->wy = 0 ;
X               break ;
X
X      case 3 : newap->sx = 15 ;
X               newap->sy = 15 ;
X               newap->wx = 256 ;
X               newap->wy = 0 ;
X               break ;
X
X      case 5 : newap->sx = 50 ;
X               newap->sy = 50 ;
X               newap->wx = 320 ;
X               newap->wy = 0 ;
X               break ;
X    }
X
X  if (x == xmin) newap->x = xmin - newap->sx + 1 ;
X  if (y == ymin) newap->y = ymin - newap->sy + 1 ;
X  newap->sizex = 0 ;     /* initialise value while off screen. */
X  if (*plist != waitlist)
X    if (updatea(newap)) /* do nothing */ ;
X}
X
X
Xupdatelist(plist)
Xstruct ainfo **plist ;
X
X{
X  struct ainfo *owner,*this,*del ;
X  int nx,ny,s ;
X
X  owner = NULL ;
X  this = *plist ;
X  while (this != NULL)
X    {
X      if (updatea(this))
X        {
X          if (this->typ >= 5)
X            {
X              if (scount > 0) scount -= nummove ;
X              else
X                {
X                  scount = 100 / this->typ ;
X                  scount += rint(scount) ;
X                  ny = rint(71) ;
X                  if (ny > 40) nx = 140 - ny ;
X                  else nx = 100 ;
X                  switch (ssector)
X                    {
X                      case 1 : s = nx ;
X                               nx = ny ;
X                               ny = s ;
X                               break ;
X
X                      case 2 : s = nx ;
X                               nx = (-ny) ;
X                               ny = s ;
X                               break ;
X
X                      case 3 : nx = (-nx) ;
X                               break ;
X
X                      case 4 : nx = (-nx) ;
X                               ny = (-ny) ;
X                               break ;
X
X                      case 5 : s = (-nx) ;
X                               nx = (-ny) ;
X                               ny = s ;
X                               break ;
X
X                      case 6 : s = (-nx) ;
X                               nx = ny ;
X                               ny = s ;
X                               break ;
X
X                      case 7 : ny = (-ny) ;
X                               break ;
X                    }
X                  ssector = (ssector + 1) % 8 ;
X                  starta(plist,0,this->x+20,this->y+20,3*nx,3*ny) ;
X                  if (owner == NULL) owner = *plist ;
X                }
X              this->typ += 1 ;
X            }
X          owner = this ;
X          this = this->next ;
X        }
X      else if ((this->typ == 1 || this->typ == 2 || this->typ == 3)
X                                 && basestatus == BACTIVE)
X        {
X          if (this->xp > 0)
X            {
X              if (this->x >= xmax) this->x = xmin - this->sx + 1 ;
X            }
X          else if (this->x <= xmin - this->sx + 1) this->x = xmax ;
X          if (this->yp > 0)
X            {
X              if (this->y >= ymax) this->y = ymin - this->sy + 1 ;
X            }
X          else if (this->y <= ymin - this->sy + 1) this->y = ymax ;
X          cleara(this) ;
X        }
X      else
X        {
X          del = this ;
X          this = this->next ;
X          if (owner == NULL) *plist = this ;
X          else owner->next = this ;
X          if ((del->typ == 1 || del->typ == 2 || del->typ == 3)
X                               && basestatus != BIDLE)
X            {
X              del->next = waitlist ;
X              waitlist = del ;
X            }
X          else
X            {
X              del->next = freeap ;
X              freeap = del ;
X            }
X        }
X    }
X}
X
X
Xnextangle(cw,x,y,newx,newy)
Xint cw,x,y,*newx,*newy ;
X
X{
X  int inc ;
X
X  if (cw) inc = 1 ;
X  else inc = -1 ;
X  *newx = x ;
X  *newy = y ;
X  if (x + ((y > 0) == cw) > 40) *newy = y - inc ;
X  if (x - ((y < 0) == cw) < -40) *newy = y + inc ;
X  if (y + ((x < 0) == cw) > 40) *newx = x + inc ;
X  if (y - ((x > 0) == cw) < -40) *newx = x - inc ;
X}
X
X
Xdiff()
X
X{
X  if (fuel <= 0) return(0) ;
X  if (state == LEFTDOWN)
X    {
X      fuel -= 1 ;
X      return(MAXDIFF) ;
X    }
X  else if (state == RIGHTDOWN)
X    {
X      fuel -= 1 ;
X      return(-MAXDIFF) ;
X    }
X  else return(0) ;
X}
X
X
Xdrawbase(x,y)
Xint x,y ;
X
X{
X  int t1,t2,i,dbmin,dbmax,ax,ay,bx,by,cx,cy,dx,dy ;
X
X  BLT_MEM(&wrk_pr,0,0,64,BSIZE,RXOR,&wrk_pr,0,0) ;   /* clear work area. */
X  ax = (14 * x + 50) / 100 + BHEIGHT ;
X  ay = (14 * y + 50) / 100 + BHEIGHT ;
X  cx = (-(5 * x + 50)) / 100 + BHEIGHT ;
X  cy = (-(5 * y + 50)) / 100 + BHEIGHT ;
X  t1 = (-10 * x) ;
X  t2 = 6 * y ;
X  bx = (t1 - t2 + 50) / 100 + BHEIGHT ;
X  dx = (t1 + t2 + 50) / 100 + BHEIGHT ;
X  t1 = (-10 * y) ;
X  t2 = 6 * x ;
X  by = (t1 + t2 + 50) / 100 + BHEIGHT ;
X  dy = (t1 - t2 + 50) / 100 + BHEIGHT ;
X
X  LINE(&wrk_pr,ax,ay,bx,by,RSET) ;
X  LINE(&wrk_pr,bx,by,cx,cy,RSET) ;
X  LINE(&wrk_pr,cx,cy,dx,dy,RSET) ;
X  LINE(&wrk_pr,dx,dy,ax,ay,RSET) ;
X  if (abs(x) > abs(y))
X    {
X      if (ay > by)
X        {
X          dbmax = ay ;
X          dbmin = by ;
X        }
X      else
X        {
X          dbmax = by ;
X          dbmin = ay ;
X        } ;
X      if (dy > dbmax) dbmax = dy ;
X      if (dy < dbmin) dbmin = dy ;
X      for (i = dbmin+1; i <= (dbmax-1); i++)
X        {
X          t1 = 0 ;
X          while (BITSET(t1,i,48,wrkarea) == 0) t1++ ;
X          t2 = BSIZE - 1 ;
X          while (BITSET(t2,i,48,wrkarea) == 0) t2-- ;
X          BLT_MEM(&wrk_pr,t1,i,t2-t1,1,RXNOR,&wrk_pr,t1,i) ;
X        }
X    }
X  else
X    {
X      if (ax > bx)
X        {
X          dbmax = ax ;
X          dbmin = bx ;
X        }
X      else
X        {
X          dbmax = bx ;
X          dbmin = ax ;
X        } ;
X      if (dx > dbmax) dbmax = dx ;
X      if (dx < dbmin) dbmin = dx ;
X      for (i = dbmin+1; i <= (dbmax-1); i++)
X        {
X          t1 = 0 ;
X          while (BITSET(i,t1,48,wrkarea) == 0) t1++ ;
X          t2 = BSIZE - 1 ;
X          while (BITSET(i,t2,48,wrkarea) == 0) t2-- ;
X          BLT_MEM(&wrk_pr,i,t1,1,t2-t1,RXNOR,&wrk_pr,i,t1) ;
X        }
X    }
X}
X
X
Xrenewbase(dx,dy)
Xint dx,dy ;
X
X{
X  BLT_MEM_TO_SCRN(bx+dx-BHEIGHT,by+dy-BHEIGHT,BSIZE,BSIZE,RXOR,&wrk_pr,0,0) ;
X  BLT_MEM_TO_SCRN(bx-BHEIGHT,by-BHEIGHT,BSIZE,BSIZE,RXOR,&wrk_pr,64,0) ;
X  bx = bx + dx ;
X  by = by + dy ;
X  BLT_MEM(&wrk_pr,64,0,64,BSIZE,RRPL,&wrk_pr,0,0) ;
X}
X
X
Xstartlist()
X
X{
X  int i,ss,nx ;
X  struct ainfo *ap ;
X
X  t1count = 0 ;
X  t3count = 0 ;
X
X  if (waitlist != NULL)
X    {
X      ap = waitlist ;
X      while (ap->next != NULL) ap = ap->next ;
X      ap->next = freeap ;
X      freeap = waitlist ;
X      waitlist = NULL ;
X    }
X
X  for (i = 1; i <= 6; i++)
X    {
X      ss = (xmax - xmin) / 2 - 50 ;
X      ss = xmin + rint(ss-150) + rint(ss+150) + 50 ;
X      nx = rint(23) + rint(59) - 40 ;
X      switch (rint(12) / 3)
X        {
X          case 0 : starta(&waitlist,1,xmin,ss,100,nx) ;
X                   break ;
X
X          case 1 : starta(&waitlist,1,xmax,ss,-100,nx) ;
X                   break ;
X
X          case 2 : starta(&waitlist,1,ss,ymin,nx,100) ;
X                   break ;
X
X          case 3 : starta(&waitlist,1,ss,ymax,nx,-100) ;
X                   break ;
X        }
X    }
X
X  if (addbonus)
X    {
X      SPRINTF(bonusstr," ** Bonus : %3d **         ",bonus*10) ;
X      startflashbonus() ;
X      addscore(bonus) ;
X    }
X  else addbonus = 1 ;    /* don't add bonus at start. */
X}
X
X
Xmatchlist(plist,test,tx,ty)
Xstruct ainfo **plist,*test ;
Xint tx,ty ;
X
X{
X  struct ainfo *owner,*this ;
X  int nx,ny,s ;
X
X  owner = NULL ;
X  this = *plist ;
X  while (this != NULL)
X    {
X      if (this != test)
X        {
X          if ((tx >= this->x) && (tx < this->x + this->sx)
X                              && (ty >= this->y)
X                              && (ty < this->y + this->sy))
X            if (BITSET(tx - this->x + this->wx,ty - this->y + this->wy,48,wrkarea) != 0)
X              {
X                cleara(this) ;
X                addscore(this->typ) ;
X                if ((scorethistank - REFUEL) >= 0)
X                  {
X                    fuel = FULLTANK ;                      /* refuel */
X                    scorethistank = 0 ;
X                  }
X                if ((this->typ == 1) || (this->typ == 2))
X                  {
X                    nx = (rint(42) + 1) / 2 ;
X                    if (nx > 12) ny = 42 - nx ;
X                    else ny = 30 ;
X                    switch (rint(4))
X                      {
X                        case 1 : ny = (-ny) ;
X                                 break ;
X
X                        case 2 : s = nx ;
X                                 nx = ny ;
X                                 ny = s ;
X                                 break ;
X
X                        case 3 : s = nx ;
X                                 nx = ny ;
X                                 ny = (-s) ;
X                                 break ;
X                      }
X                    if (this->typ == 1) s = 10 ;
X                    else s = 8 ;
X                    starta(plist,this->typ+1,this->x+s,this->y+s,this->xp+nx,this->yp+ny) ;
X                    starta(plist,this->typ+1,this->x+s,this->y+s,this->xp-nx,this->yp-ny) ;
X                    if (owner == NULL) owner = (*plist)->next ;
X                    if (this->typ == 1)
X                      {
X                        t1count++ ;
X                        if (t1count == 6)
X                          {
X                            if (rint(2) == 0)
X                              starta(&waitlist,5,xmin,ymin+1,100,0) ;
X                            else starta(&waitlist,5,xmax,ymin+1,-100,0) ;
X                            scount = 10 ;
X                            ssector = rint(7) ;
X                          }
X                      }
X                  }
X                else if (this->typ == 3)
X                  {
X                    t3count++ ;
X                    if (t3count == 24) startlist() ;
X                  } ;
X                if (owner == NULL) *plist = this->next ;
X                else owner->next = this->next ;
X                this->next = freeap ;
X                freeap = this ;
X                return(1) ;
X              }
X        }
X      owner = this ;
X      this = this->next ;
X    }
X  return(0) ;
X}
X
X
Xcheckhit()
X
X{
X  struct ainfo *owner,*this,*del ;
X  int i,x,y ;
X
X  owner = NULL ;
X  this = bplist ;
X  while (this != NULL)
X    {
X      BLT_MEM(&test_pr,0,0,64,3,RXOR,&test_pr,0,0) ;
X      BLT_SCRN_TO_MEM(&test_pr,0,0,3,3,RRPL,this->x,this->y) ;
X      y = -1 ;
X      for (i = 0; i <= 2; i++)
X        if (testarea[i*4] != 0) y = i ;   /* this checks to see if row <> zeros */
X      if (y < 0)
X        {
X          owner = this ;
X          this = this->next ;
X        }
X      else
X        {
X          x = 0 ;
X          while (BITSET(x,y,4,testarea) == 0) x++ ;
X          x += this->x ;
X          y += this->y ;
X          cleara(this) ;
X          if (!matchlist(&aplist,(struct ainfo *) NULL,x,y))
X            if (!matchlist(&bplist,this,x,y)) /* do nothing */ ;
X          del = this ;
X          this = this->next ;
X          if (owner == NULL) bplist = this ;
X          else
X            {
X              if (owner->next == del) owner->next = this ;
X              else if (bplist == del) bplist = this ;
X              else
X                {
X                  owner = bplist ;
X                  while (owner->next != del) owner = owner->next ;
X                  owner->next = this ;
X                }
X            }
X          del->next = freeap ;
X          freeap = del ;
X        }
X    }
X}
X
X
Xdisintgt(gone)
Xint *gone ;
X
X{
X  int x,y,xx,yy,countdown,gotone ;
X
X  x = 0 ;
X  y = 0 ;
X  gotone = 0 ;
X  countdown = rint(3) ;
X  SETOFF(BHEIGHT,BHEIGHT,48,wrkarea) ;
X  do
X    {
X      if (x > y)
X        if (x > (-y)) y-- ;
X        else x-- ;
X      else if (x < (-y)) y++ ;
X      else x++ ;
X      if (BITSET(x + BHEIGHT,y + BHEIGHT,48,wrkarea) != 0)
X        {
X          gotone = 1 ;
X          if (countdown > 0) countdown-- ;
X          else
X            {
X              countdown = 5 ;
X              xx = x ;
X              yy = y ;
X              if (abs(x) >= abs(y)) xx = xx - (2 * (x > 0) - 1) ;
X              if (abs(x) <= abs(y)) yy = yy - (2 * (y > 0) - 1) ;
X              SETOFF(x+BHEIGHT,y+BHEIGHT,48,wrkarea) ;
X              SETON(xx+BHEIGHT,yy+BHEIGHT,48,wrkarea) ;
X            }
X        }
X    }
X    while (x + y != BHEIGHT + BHEIGHT) ;
X    *gone = !gotone ;
X}
X
X
Xupdatebase()
X
X{
X  int count,d,dd,dx,dy,i,j,newx,newy ;
X  int changed,gone ;
X  struct ainfo *ap ;
X
X  switch (basestatus)
X    {
X      case BWAITING : if ((aplist == NULL) && (bplist == NULL))
X                        {
X                          bx = (xmin + xmax + 1) / 2 ;
X                          by = (ymin + ymax + 1) / 2 ;
X                          ax = 100 ;
X                          ay = 0 ;
X                          bxp = 0 ;
X                          byp = 0 ;
X                          bdx = 0 ;
X                          bdy = 0 ;
X                          bxpd = 0 ;
X                          bypd = 0 ;
X                          motoron = 0 ;
X                          drawbase(ax,ay) ;
X                          renewbase(0,0) ;
X                          swcount = 0 ;
X                          basestatus = BACTIVE ;
X                        }
X                      break ;
X
X      case BACTIVE  : if (waitlist != NULL)
X                        if (waitcount > 0) waitcount-- ;
X                        else
X                          {
X                            ap = waitlist ;
X                            waitlist = ap->next ;
X                            ap->next = aplist ;
X                            aplist = ap ;
X                            waitcount = rint(rint(20) * 10 + 10) + 10 ;
X                          }
X                      d = diff() ;
X                      changed = 0 ;
X                      count = nummove + nummove ;
X                      while ((d != 0) && (count > 0))
X                        {
X                          nextangle((d > 0),ax,ay,&newx,&newy) ;
X                          dd = diff() ;
X                          if ((dd == 0) || ((d > 0) == (dd > 0)) || (abs(dd) < abs(d)))
X                            {
X                              ax = newx ;
X                              ay = newy ;
X                              changed = 1 ;
X                            }
X                          if ((d > 0) != (dd > 0)) d = 0 ;
X                          else d = dd ;
X                          count-- ;
X                        }
X                      if (changed) drawbase(ax,ay) ;
X                      for (count = 1; count <= nummove; count++)
X                        {
X                          if (motoron)
X                            {
X                              fuel -= 10 ;    /* burn some fuel. */
X                              if (fuel <= 0)
X                                {
X                                  fuel = 0 ;
X                                  motoron = 0 ;
X                                }
X                              bxpd += ax ;
X                              bypd += ay ;
X                              dx = bxpd / BFACTOR ;
X                              dy = bypd / BFACTOR ;
X                              bxp += dx ;
X                              byp += dy ;
X                              bxpd -= dx * BFACTOR ;
X                              bypd -= dy * BFACTOR ;
X                            }
X                          bdx += bxp ;
X                          bdy += byp ;
X                        }
X                      dx = bdx / BFACTOR ;
X                      dy = bdy / BFACTOR ;
X                      bdx -= dx * BFACTOR ;
X                      bdy -= dy * BFACTOR ;
X                      if (changed || (dx != 0) || (dy != 0)) renewbase(dx,dy) ;
X                      BLT_MEM(&test_pr,0,0,64,BSIZE,RRPL,&wrk_pr,64,0) ;
X                      BLT_SCRN_TO_MEM(&test_pr,0,0,BSIZE,BSIZE,RXNOR,
X                                      bx-BHEIGHT,by-BHEIGHT) ;
X                      i = 0 ;
X                      do
X                        if ((testarea[i*4]   == 0) &&  /* Is row = zero? */
X                            (testarea[i*4+1] == 0) &&
X                            (testarea[i*4+2] == 0) &&
X                            (testarea[i*4+3] == 0)) i++ ;
X                        else
X                          {
X                            j = 0 ;
X                            while (BITSET(j,i,4,testarea) == 0) j++ ;
X                            i += bx - BHEIGHT ;
X                            j += by - BHEIGHT ;
X                            if (!matchlist(&aplist,(struct ainfo *) NULL,j,i))
X                              if (!matchlist(&bplist,(struct ainfo *) NULL,j,i)) ;
X                            basestatus = BDYING ;
X                            return ;
X                          }
X                      while (i != BSIZE) ;
X                      if (c == BUTMIDDLE)
X                        {
X                          if (swcount > 0) swcount -= nummove ;
X                          else
X                            {
X                              swcount = 20 ;
X                              starta(&bplist,0,bx-1+(17*ax)/100,by-1+(17*ay)/100,ax*5,ay*5) ;
X                            }
X                          c = 0 ;
X                        }
X                      else swcount = 0 ;
X                      break ;
X
X      case BDYING   : disintgt(&gone) ;
X                      renewbase(0,0) ;
X                      if (gone)
X                        {
X                          state = 0 ;             /* Clear previous button state. */
X                          basecount-- ;
X                          addscore(0) ;           /* Correct number of ships left. */
X                          if (basecount == 0) basestatus = BIDLE ;
X                          else
X                            {
X                              basestatus = BWAITING ;
X                              scorethistank = 0 ;
X                              fuel = FULLTANK ;
X                            }
X                        }
X                      break ;
X    }
X}
X
X
Xcheckkey()
X
X{
X  int nx,ny,ss ;
X
X  if (keys)
X    {
X      keys = 0 ;
X      switch (c)
X        {
X          case K_QUIT    : progstate = EXPIRED ;
X                           break ;
X
X          case K_GO      : motoron = ((basestatus == BACTIVE) && (fuel > 0)) ;
X                           break ;
X
X          case K_STOP    : motoron = 0 ;
X                           break ;
X
X          case K_TELEPORT: if (basestatus == BACTIVE)
X                             if (fuel >= (FULLTANK / 5))
X                               {
X                                 fuel -= (FULLTANK / 5) ;  /* 20% loss each hyperspace. */
X                                 ss = (xmax - xmin) / 2 - BSIZE ;
X                                 nx = xmin + BHEIGHT + rint(ss-50) + rint(ss+50) ;
X                                 ny = ymin + BHEIGHT + rint(ss-50) + rint(ss+50) ;
X                                 if (nx < xmin + BHEIGHT) nx = xmin + BHEIGHT ;
X                                 else if (nx > xmax - BHEIGHT) nx = xmax - BHEIGHT ;
X                                 if (ny < ymin + BHEIGHT) ny = ymin + BHEIGHT ;
X                                 else if (ny > ymax - BHEIGHT) ny = ymax - BHEIGHT ;
X                                 renewbase(nx-bx,ny-by) ;
X                               }
X                            break ;
X        }
X    }
X}
X
X
Xnumticks(to,from)
Xstruct timeb *to,*from ;
X
X{
X  return(((to->time - from->time) * 1000 + (to->millitm - from->millitm)) / 16) ;
X}
X
X
Xmain(argc,argv)
Xint argc ;
Xchar *argv[] ;
X
X{
X  get_options(argc,argv) ;          /* Get users command line options. */
X  function_keys(KEY_SET) ;          /* Set asteroid commands function keys. */
X
X  base_frame = window_create(NULL, FRAME,
X                             FRAME_LABEL, titlestring,
X                             FRAME_ICON, &ast_icon,
X                             WIN_X, orgx,
X                             WIN_Y, orgy,
X                             WIN_WIDTH, width,
X                             WIN_HEIGHT, height,
X                             FRAME_ARGS, argc, argv,
X                             0) ;
X  width = width - 10 ;
X  height = height - 25 ;
X
X  canvas = window_create(base_frame, CANVAS,
X                         CANVAS_RETAINED, TRUE,
X                         CANVAS_FAST_MONO, TRUE,
X                         WIN_EVENT_PROC, event_proc,
X                         0) ;
X
X  window_set(canvas, WIN_CONSUME_KBD_EVENTS, WIN_ASCII_EVENTS, 0) ;
X  window_set(canvas, WIN_CONSUME_KBD_EVENTS, WIN_LEFT_KEYS, 0) ;
X
X  pf = pf_default() ;
X  pw = canvas_pixwin(canvas) ;
X
X/* Set up no delay for events within the canvas. */
X  canvasfd = (int) window_get(canvas,WIN_FD) ;
X  canvasflags = fcntl(canvasfd,F_GETFL,0) ;
X  canvasflags |= FNDELAY ;
X  FCNTL(canvasfd,F_SETFL,canvasflags) ;
X
X  sfunc = PIX_SRC ;                 /* Used by WRITELN. */
X  iocursormode(OFFCURSOR) ;
X  progstate = HELP ;
X
X  (void) notify_set_itimer_func(base_frame, main_loop, ITIMER_REAL,
X                        &NOTIFY_POLLING_ITIMER, ((struct itimerval *) 0)) ;
X  window_main_loop(base_frame) ;
X  exit(0) ;
X}
X
X
X/*ARGSUSED*/
Xvoid
Xevent_proc(window,event,arg)
XWindow *window ;
XEvent *event ;
Xcaddr_t arg ;
X
X{
X  if (event_is_button(event))
X    {
X      switch (event_id(event))
X        {
X          case MS_LEFT   : if (event_is_down(event)) c = LEFTDOWN ;
X                           else c = LEFTUP ;
X                           break ;
X          case MS_MIDDLE : if (event_is_down(event)) c = BUTMIDDLE ;
X                           break ;
X          case MS_RIGHT  : if (event_is_down(event)) c = RIGHTDOWN ;
X                           else c = RIGHTUP ;
X        }
X    }
X  else if (event_is_ascii(event)) c = event_id(event) ;
X
X  if (c == CTRLS)
X    {
X      if (progstate != CTRLSHIT) savedstate = progstate ;
X      progstate = CTRLSHIT ;
X      return ;
X    }
X  else if (c == CTRLQ)
X    {
X      progstate = savedstate ;
X      return ;
X    }
X  else if (c > RIGHTDOWN) keys = 1 ;
X  if (c == LEFTDOWN || c == RIGHTDOWN || c == LEFTUP || c == RIGHTUP) state = c ;
X}
X
X
X/*ARGSUSED*/
Xstatic Notify_value
Xmain_loop(client, itimer_type)
XNotify_client client ;
Xint itimer_type ;
X
X{
X  switch (progstate)
X    {
X      case HELP     : clear_screen() ;    /* Clear the asteroids window. */
X                      if (givehelp) do_help_screen() ;  /* Output help screen. */
X                      progstate = GETRET ;
X                      break ;
X      case GETRET   : if (c == RETURN) progstate = STARTUP ;
X                      break ;
X      case STARTUP  : clear_screen() ;   /* White background, before inversion. */
X                      basecount = 3 ;
X                      init() ;
X                      startlist() ;
X                      basestatus = BWAITING ;
X                      ftime(&tlast) ;
X                      nummove = 1 ;
X                      progstate = UPDATE ;
X                      break ;
X      case UPDATE   : update() ;
X                      break ;
X      case EXPIRED  : function_keys(KEY_RESET) ;
X                      BLT_SCRN(0,0,width,height,RXOR) ;
X                      checkscore() ;
X      case NEXTLINE : getnewscore(365,200) ;
X                      break ;
X      case DOEND    : showhighscore() ;
X                      break ;
X      case SCORE    : if (c == RETURN) exit(0) ;
X                      break ;
X      case CTRLSHIT : break ;
X    }
X}
X
X
Xupdate()
X
X{
X  updatelist(&aplist) ;
X  updatelist(&bplist) ;
X  updatebase() ;
X  checkhit() ;
X  checkkey() ;
X  showfuel() ;
X  if (flashbonus) doflashbonus() ;
X  do
X    {
X      dummy = rint(2) ;
X      ftime(&tnew) ;
X    } 
X  while (tnew.millitm == tlast.millitm) ;
X  nummove = numticks(&tnew,&tlast) ;
X  if (nummove > 20) nummove = 20 ;
X  tlast.time = tnew.time ;
X  tlast.millitm = tnew.millitm ;
X  if ((basestatus == BIDLE) && (aplist == NULL) && (bplist == NULL))
X    progstate = EXPIRED ;
X}
END_OF_ast_main.c
if test 36644 -ne `wc -c <ast_main.c`; then
    echo shar: \"ast_main.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archiveSubj0) r