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