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