richb@yarra.OZ (Rich Burridge) (12/04/86)
This is the game of asteroids for the Sun. Please read the README just a little further on in this posting. Suggestions, improvements, bugs (there's got to be at least a couple of these) and flames to me. Regards Rich. Rich Burridge ISD: +61 3 267-6222 Sun Australia STD: (03) 267-6222 14 Queens Rd, ARPA: richb%yarra.oz@seismo.css.gov Melbourne, VIC 3004. UUCP: seismo!munnari!yarra.oz!richb AUSTRALIA. ACS: richb@yarra.oz ---------CUT HERE----------CUT HERE-------------CUT HERE------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Makefile # asteroids.h # asteroids.help # asteroids.icon # ast_main.c # ast_stuff.c # ast_sun.c # This archive created: Thu Dec 4 12:36:03 1986 # By: Rich Burridge (Sun Computer Australia (Melbourne)) export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' ASTEROIDS. ---------- This is the game of Asteroids for the Sun. The original version was written in Pascal on an ICL Perq, by persons unknown, somewhere in the North of England in 1982. This version is based on the conversion of that program to C by Brian Rippon and Graham Underwood for the ICL Perq PNX O/S in 1983. This should work on a Sun 2, but I didn't have one, so perhaps someone can let me know what changes if any were needed. This has been put together for a release for Christmas. There are still a couple of things which could be improved, but it is still a very workable game. These are: (1) You can be killed for no apparent reason. (2) Needs a restart handler. This is currently handled poorly. **YOU MUST NOT ALTER THE ASTEROIDS WINDOW ONCE YOU'VE STARTED** Hopefully these will be "fixed" in the next version. Just type "asteroids", to start the game. There are three command line switches: -h - Don't display the initial help message. -xnnn - Initial width of the asteroids window (default 768). -ynnn - Initial height of the asteroids window (default 900). The smaller the window the higher the bonus scores. Suggestions, flames, bugs, fixes and improvements to me. Regards Rich. SHAR_EOF fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' # # Makefile for the asteroids game. # Written by Rich Burridge - Sun Australia (Melbourne) - December 1986. # # Version 2.0. # # No responsibility is taken for any errors inherent either in the comments # or the code of this program, but if reported to me then an attempt will # be made to fix them. # BINARIES = asteroids BINDIR = . CFLAGS = -O LDFLAGS = OBJS = ast_main.o ast_stuff.o ast_sun.o SRCS = ast_main.c ast_stuff.c ast_sun.c LIBS = -lsuntool -lsunwindow -lpixrect HDRS = asteroids.h # # The following commands are declared: # all: $(BINARIES) backup: cp ast_main.c ast_main.c~ cp ast_stuff.c ast_stuff.c~ cp ast_sun.c ast_sun.c~ lint: lint $(SRCS) -lpixrect clean: rm -f *.o core # # General Makefile stuff. # asteroids: $(OBJS) cc $(LDFLAGS) -o asteroids $(OBJS) $(LIBS) ast_main.o: ast_main.c $(HDRS) ast_stuff.o: ast_stuff.c $(HDRS) ast_sun.o: ast_sun.c $(HDRS) SHAR_EOF fi if test -f 'asteroids.h' then echo shar: "will not over-write existing file 'asteroids.h'" else cat << \SHAR_EOF > 'asteroids.h' /* asteroids.h * * Definitions used by the asteroids game. * Written by Rich Burridge - SUN Australia (Melbourne) - December 1986. * * Version 2.0. * * No responsibility is taken for any errors inherent either to the code * or the comments of this program, but if reported to me then an attempt * will be made to fix them. */ #include <pixrect/pixrect_hs.h> #include <suntool/gfx_hs.h> #include <setjmp.h> #define MAXEXLV 5 /* Maximum number of nested exceptions. */ typedef struct { int cl ; jmp_buf jb[ MAXEXLV ] ; } exceptn ; #define exception(x) exceptn x = { 0 } ; #define exexception(x) extern exceptn x ; /* x is of type exception */ #define when(x) switch(setjmp(x.jb[x.cl++])) { \ default : (void) fprintf(stderr,"Unexpected exception raised") ; \ exit(1) ; \ case 0 : break ; /* x is of type integer */ #define etype(x) case x : #define endwhen } #define forget(x) x.cl-- /* x is of type exception and y is an integer */ #define raise(x,y) longjmp(x.jb[x.cl - 1],y) extern struct gfxsubwindow *gfx ; /* Pointer to asteroids tool window. */ extern char *sprintf() ; #define BIND (void) bind /* To make lint happy. */ #define CLOSE (void) close #define CONNECT (void) connect #define FCLOSE (void) fclose #define FPRINTF (void) fprintf #define KILL (void) kill #define LISTEN (void) listen #define NICE (void) nice #define PRINTF (void) printf #define READ (void) read #define SCANF (void) scanf #define SELECT (void) select #define SIGNAL (void) signal #define SPRINTF (void) sprintf #define STRCPY (void) strcpy #define UNLINK (void) unlink #define WRITE (void) write #define RRPL PIX_SRC /* RASTEROP codes. */ #define ROR PIX_SRC | PIX_DST #define RXOR PIX_SRC ^ PIX_DST #define RCLR PIX_CLR #define RSET PIX_SET #define RINV PIX_NOT(PIX_DST) #define RXNOR PIX_SRC ^ PIX_NOT(PIX_DST) #define RORNOT PIX_NOT(PIX_SRC) | PIX_DST #define RANDNOT PIX_NOT(PIX_SRC) & PIX_DST #define MAXLINE 80 /* Maximum string length. */ #ifndef CTRLQ #define CTRLQ 17 /* Used to restart the asteroids game. */ #endif #ifndef CTRLS #define CTRLS 19 /* Used to halt the asteroids game. */ #endif #define ESC '\033' /* Definitions of valid asteroid keys. */ #define DEL '\177' #define BACKSPACE '\010' #define FLASHTIME 4 /* Seconds */ #define FLICKERTIME 20 /* Jiffies */ #define FONT_HEIGHT 16 /* Height of font within asteroids. */ #define FONT_WIDTH 8 /* Width of standard character font. */ #define FULLTANK 50000 /* Full fuel tanks */ #define HELPNAME "asteroids.help" /* Name of the initial help file. */ #define RETURN 13 /* Certain useful ASCII constants. */ #define SOCKNAME "/tmp/astsocket" /* Asteroids socket name. */ #define OFFCURSOR 0 /* Modes for the mouse cursor. */ #define TRACKCURSOR 1 /* Asteroid event values. */ #define LEFTUP 1 /* Left mouse button up. */ #define LEFTDOWN 2 /* Left mouse button down. */ #define BUTMIDDLE 3 /* Middle mouse button. */ #define RIGHTUP 4 /* Right mouse button up. */ #define RIGHTDOWN 5 /* Right mouse button down. */ #define WIN_DAMAGED 6 /* Value returned on window damage. */ #define SWIDTH 768 /* Maximum screen width. */ #define SHEIGHT 900 /* Maximum screen height. */ #define MASTER 0 /* Server version of SID tool. */ #define SLAVE 1 /* Client version of SID tool. */ /* Set the function to be used for characters. */ #define SCHRFUNC(f) (sfunc = f) /* Machine independent rasterop calls. */ /* Manipulate a portion of the screen with itself. */ #define BLT_SCRN(sx,sy,w,h,op) \ (pw_writebackground(gfx->gfx_pixwin,sx,sy,w,h,op)) /* Move a screen raster to an offscreen area. */ #define BLT_SCRN_TO_MEM(mem,mx,my,w,h,op,sx,sy) \ (pw_read(mem,mx,my,w,h,op,gfx->gfx_pixwin,sx,sy)) /* Move an offscreen raster area to the screen. */ #define BLT_MEM_TO_SCRN(sx,sy,w,h,op,mem,mx,my) \ (pw_write(gfx->gfx_pixwin,sx,sy,w,h,op,mem,mx,my)) /* Move an offscreen raster area to another offscreen raster area. */ #define BLT_MEM(mem1,mx1,my1,w,h,op,mem2,mx2,my2) \ (pr_rop(mem1,mx1,my1,w,h,op,mem2,mx2,my2)) /* Draw a line of type op,in a raster area. */ #define LINE(area,x1,y1,x2,y2,op) \ (pr_vector(area,x1,y1,x2,y2,op,1)) SHAR_EOF fi if test -f 'asteroids.help' then echo shar: "will not over-write existing file 'asteroids.help'" else cat << \SHAR_EOF > 'asteroids.help' WELCOME TO THE GAME OF ASTEROIDS. The object of the game, is to destroy the asteroids before they destroy you. You control the spaceship which initially starts in the centre of the window. Holding down the LEFT button of the mouse rotates the spaceship anticlockwise. Holding down the RIGHT button of the mouse rotates the spaceship clockwise. Pressing the MIDDLE button will fire a missile out of the front of the spaceship. You can enter hyperspace by pressing the BACKSPACE key. This will return you to the screen in a random position. You can turn your rocket motors on by pressing the ESC key. Pressing the DELETE key will turn your rocket motors off. To quit the game at any time, just press the q key. Rotating the shapeship, moving or entering hyperspace uses up fuel. Running out of fuel will eventually render you helpless. Fuel tanks are refilled every 6000 points scored per spaceship, and for each new spaceship. You get a new spaceship every 10000 points. There are bonus points for each set of asteroids you destroy. Also the smaller your window, the more bonus you get. You have three spaceships to start with. Good luck!! Hit RETURN to start the game. SHAR_EOF fi if test -f 'asteroids.icon' then echo shar: "will not over-write existing file 'asteroids.icon'" else cat << \SHAR_EOF > 'asteroids.icon' /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 */ 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFF7F,0xFEFF,0xFFFD, 0xBFFF,0xFE3F,0xFC7F,0xFF3D,0xBFFF,0xFF7F,0xFEFF,0xFF3D, 0xB3FF,0xFFBF,0xFDFF,0xFFFD,0xB3FF,0xFFDF,0xFBFF,0xFFFD, 0xBFFF,0xFFDF,0xFBFF,0xFF3D,0xBFFF,0xFFEF,0xF7FF,0xFF3D, 0xBFFF,0xFFEF,0xF7FF,0xFFFD,0xBFFF,0xFFF7,0xEFFF,0xFFFD, 0xBFFF,0xFFC0,0x03FF,0xFFFD,0xBFFF,0xFF80,0x01FF,0xFFFD, 0xBFFF,0xFF8F,0xF1FF,0xFFFD,0xBFFF,0xFF1F,0xF8FF,0xFFFD, 0xBFFF,0xFF1F,0xF8FF,0xFFFD,0xBFFF,0xFE3F,0xFC7F,0xFFCD, 0xBFFF,0xFE3F,0xFC7F,0xFFCD,0xBFFF,0x0000,0x0000,0xFFFD, 0xB3FF,0x0000,0x0000,0xFFFD,0xB3FF,0x0000,0x0000,0xFFFD, 0xBFFF,0xC7FF,0xFFE3,0xFFFD,0xBFFF,0xE3FF,0xFFC7,0xFFFD, 0xBFFF,0xE3FF,0xFFC7,0xFFFD,0xBFFF,0xF1FF,0xFF8F,0xFFFD, 0xBFFF,0xF1FF,0xFF8F,0xFFFD,0xBFFF,0xF8FF,0xFF1F,0xFFFD, 0xBFFF,0xF8FF,0xFF1F,0xFFFD,0xBFFF,0xFC7F,0xFE3F,0xFFFD, 0xBFFF,0xFC7F,0xFE3F,0xFFFD,0xBFFF,0xFE3F,0xFC7F,0xFFFD, 0xBFFF,0xFE3F,0xFC7F,0xFFFD,0xBFFF,0xFF1F,0xF8FF,0xFFFD, 0xBFFF,0xFF00,0x00FF,0xFFFD,0xBFFF,0xFF00,0x00FF,0xFFFD, 0xBFFF,0xFF80,0x01FF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xF9FD, 0xBFCF,0xFFFF,0xFFFF,0xF9FD,0xBFCF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFF3F,0xFFFD, 0xBFF9,0xFFFF,0xFF3F,0xFFFD,0xBFF9,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xF9FD,0xBFFF,0xFFFF,0xFFFF,0xF9FD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0xBFFF,0xFFFF,0xF9FF,0xFFFD,0xBFFF,0xFFFF,0xF9FF,0xFFFD, 0xBFFF,0xFFFF,0xFFFF,0xFFFD,0xBFFF,0xFFFF,0xFFFF,0xFFFD, 0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF SHAR_EOF fi if test -f 'ast_main.c' then echo shar: "will not over-write existing file 'ast_main.c'" else cat << \SHAR_EOF > 'ast_main.c' /* ast_main.c * * The game of Asteroids. * Written by Rich Burridge - SUN Australia (Melbourne) - December 1986. * * Version 2.0. * * No responsibility is taken for any errors or inaccuracies inherent * either to the comments or the code of this program, but if reported * to me then an attempt will be made to fix them. */ #include <stdio.h> #include <strings.h> #include <sys/types.h> #include <sys/timeb.h> #include <signal.h> #include "asteroids.h" extern etext() ; exception(god) ; /* Raised to create the slave asteroids process. */ #define BYTESPERWORD 2 #define bheight 15 #define bsize 2*bheight+1 /* * Macros to test and set bits. * i,j are the x,y offsets from pointer. * scan is the scan length of the area pointed at. */ #define SETON(i,j,scan,ptr) (*(ptr+(scan*(j))+(i)/16) |= (1 << (017 - ((i) & 017)))) #define SETOFF(i,j,scan,ptr) (*(ptr+(scan*(j))+(i)/16) &= ~(1 << (017 - ((i) & 017)))) #define BITSET(i,j,scan,ptr) (((*(ptr+(scan*(j))+(i)/16)) &(1 << (017 - ((i) & 017)))) ? (1):(0)) #define BIDLE 0 #define BWAITING 1 #define BACTIVE 2 #define BDYING 3 #define MAXHS 5 /* Max records held in high score file. */ #define AFACTOR 120 #define BFACTOR 256 #define REFUEL 6000 /* fill up tanks every REFUEL points scored per ship */ #define MAXDIFF 15000 short testarea[(bsize+1)*4*BYTESPERWORD] ; mpr_static(test_pr,512,4,1,testarea) ; short wrkarea[50*48*BYTESPERWORD] ; mpr_static(wrk_pr,768,50,1,wrkarea) ; struct timeb tlast,tnew,tstartflash,tlastflash ; struct ainfo { struct ainfo *next ; int x,y,dx,dy,xp,yp,sx,sy,wx,wy ; int sizex,sizey,offx,offy,typ ; } ; struct hscore { char who[MAXLINE] ; int score ; } ; struct hscore highscore[MAXHS] ; char progname[MAXLINE] ; /* Name of this program. */ char titlestring[MAXLINE] ; int c ; /* Value returned by wgread. */ int firsttime = 0 ; /* Used for redrawing a damaged screen. */ int height ; /* Height of the asteroids window. */ int givehelp ; /* Set to 0, indicates no initial help. */ int prog_type ; /* Whether program is server or client. */ int orgx = 0 ; /* X origin of the asteroids window. */ int orgy = 0 ; /* Y origin of the asteroids window. */ int state = 0 ; /* Current button state. */ int width ; /* Width of the asteroids window. */ int xmax,xmin,ymax,ymin,mindimension ; int score = 0 ; int scorethistank = 0 ; int enkey = 01652 ; /* ENCODE key used in highscore file. */ int addbonus = 0 ; int bonus ; /* what bonus do we give for each set of asteroids */ int bonusship = 10000 ; /* new ship every bonusship points. */ int flashbonus = 0 ; /* flag for when to flash message. */ int bonusshown = 0 ; int motoron ; int fuel = FULLTANK ; /* Amount of spaceship fuel left. */ int fuelxoffset ; /* Start of fuel display bar. */ int fuelmaxlength ; /* Maximum length of fuel bar. */ int fuellength ; /* Current length of fuel bar. */ char bonusstr[80] ; struct ainfo *freeap,*bplist,*waitlist,*aplist ; int basestatus ; int ax,ay,bx,by,bdx,bdy,bxp,byp,bxpd,bypd ; int nummove,swcount,ssector,scount ; int basecount,t3count,t1count,waitcount,rr,dummy ; int keys = 0 ; extern int sfunc ; /* Rasterop code used by writeln. */ char *malloc() ; extern int closedown(),rint() ; checkscore() { char buffer[MAXLINE] ; char me[MAXLINE] ; int i,j,len ; SCHRFUNC(RRPL) ; i = MAXHS - 1 ; while ((score > highscore[i].score) && (i >= 0)) i-- ; if (++i < MAXHS) { clear_screen() ; SPRINTF(buffer,"Congratulations, you have one of the top %d scores\n",MAXHS) ; writeln(100,140,buffer) ; do { len = 1 ; writeln(100,200,"Please enter your name : ") ; if (!(len = getline(me,365,200))) writeln(100,220," ** No name given. **") ; } while (!len) ; j = MAXHS - 1 ; while (--j >= i) { highscore[j+1].score = highscore[j].score ; STRCPY(highscore[j+1].who,highscore[j].who) ; } highscore[i].score = score ; STRCPY(highscore[i].who,me) ; puthighscore() ; } } showhighscore() { char buffer[MAXLINE] ; int i ; clear_screen() ; write_bold(220,200,"High Scores") ; SCHRFUNC(ROR) ; writeln(220,201,"___________") ; writeln(200,300," Score Name") ; writeln(200,301," _____ ____") ; SCHRFUNC(RRPL) ; for (i = 0; i < MAXHS; i++) { SPRINTF(buffer,"%6d %s",highscore[i].score,highscore[i].who) ; writeln(200,330+i*30,buffer) ; } SPRINTF(buffer,"Your score was %d",score) ; writeln(220,500,buffer) ; writeln(5,height-40,"Type RETURN to quit") ; while (wgread() != RETURN) ; } gethighscore() { int hsfile,i ; struct hscore nullscore ; if ((hsfile = open("asteroids.hs",2)) == -1) { if ((hsfile = creat("asteroids.hs",0777)) == -1) { PRINTF("\nunable to create highscore file.\n") ; exit(1) ; } nullscore.score = 0 ; /* file should be open. */ STRCPY(nullscore.who," ") ; for (i = 0; i < MAXHS; i++) { puths(hsfile,&nullscore) ; STRCPY(highscore[i].who," ") ; highscore[i].score = 0 ; } } else for (i = 0; i < MAXHS; i++) geths(hsfile,&highscore[i]) ; CLOSE(hsfile) ; } puthighscore() { int hsfile,i ; if ((hsfile = open("asteroids.hs",1)) == -1) PRINTF("Unable to open highscore file.\n") ; else { for (i = 0; i < MAXHS; i++) puths(hsfile,&highscore[i]) ; CLOSE(hsfile) ; } } puths(where,record) /* put one hscore record out. */ struct hscore *record ; int where ; { char buffer[32],valuestr[7] ; int i,value ; for (i = 0; i < 16; i++) buffer[i] = record->who[i] ^ enkey ; value = record->score ; SPRINTF(valuestr,"%d",value) ; for (i = 0; i < 7; i++) buffer[i+16] = valuestr[i] ^ enkey ; WRITE(where,buffer,23) ; } geths(where,record) /* get one hscore record in. */ struct hscore *record ; int where ; { char buffer[32],valuestr[7] ; int i ; i = read(where,buffer,23) ; for (i = 0; i < 16; i++) record->who[i] = buffer[i] ^ enkey ; for (i = 0; i < 7; i++) valuestr[i] = buffer[i+16] ^ enkey ; record->score = atoi(valuestr) ; } init() { int i,j ; NICE(-20) ; /* High priority activity this game !!! */ SIGNAL(SIGQUIT,closedown) ; SIGNAL(SIGHUP,closedown) ; SIGNAL(SIGINT,closedown) ; gethighscore() ; BLT_MEM(&wrk_pr,0,0,768,50,RXOR,&wrk_pr,0,0) ; /* Clear work area. */ rr = 1234 ; LINE(&wrk_pr,128,25,128,40,RSET) ; /* BIG asteroid. */ LINE(&wrk_pr,128,40,147,49,RSET) ; LINE(&wrk_pr,147,49,160,49,RSET) ; LINE(&wrk_pr,160,49,173,47,RSET) ; LINE(&wrk_pr,173,47,177,35,RSET) ; LINE(&wrk_pr,177,35,177,19,RSET) ; LINE(&wrk_pr,177,19,174,8,RSET) ; LINE(&wrk_pr,174,8,168,3,RSET) ; LINE(&wrk_pr,168,3,150,0,RSET) ; LINE(&wrk_pr,150,0,144,2,RSET) ; LINE(&wrk_pr,144,2,135,15,RSET) ; LINE(&wrk_pr,135,15,128,25,RSET) ; for (i = 1; i <= 48; i++) { j = 128 ; while (BITSET(j,i,48,wrkarea) == 0) j++ ; do j++ ; while (BITSET(j,i,48,wrkarea) != 0) ; while (BITSET(j,i,48,wrkarea) == 0) { if (rint(j-128) < 6) SETON(j,i,48,wrkarea) ; else SETOFF(j,i,48,wrkarea) ; j++ ; } } LINE(&wrk_pr,192,10,192,20,RSET) ; /* MEDIUM asteroid. */ LINE(&wrk_pr,192,20,201,29,RSET) ; LINE(&wrk_pr,201,29,214,29,RSET) ; LINE(&wrk_pr,214,29,221,17,RSET) ; LINE(&wrk_pr,221,17,221,08,RSET) ; LINE(&wrk_pr,221,08,209, 0,RSET) ; LINE(&wrk_pr,209, 0,200, 0,RSET) ; LINE(&wrk_pr,200, 0,192,10,RSET) ; for (i = 1; i <= 28; i++) { j = 192 ; while (BITSET(j,i,48,wrkarea) == 0) j++ ; do j++ ; while (BITSET(j,i,48,wrkarea) != 0) ; while (BITSET(j,i,48,wrkarea) == 0) { if (rint(j-192) < 5) SETON(j,i,48,wrkarea) ; else SETOFF(j,i,48,wrkarea) ; j++ ; } } LINE(&wrk_pr,261, 0,270, 0,RSET) ; /* SMALL asteroid. */ LINE(&wrk_pr,270, 0,270, 9,RSET) ; LINE(&wrk_pr,270, 9,263,14,RSET) ; LINE(&wrk_pr,263,14,256,14,RSET) ; LINE(&wrk_pr,256,14,256, 8,RSET) ; LINE(&wrk_pr,256, 8,261, 0,RSET) ; for (i = 1; i <= 13; i++) { j = 256 ; while (BITSET(j,i,48,wrkarea) == 0) j++ ; do j++ ; while (BITSET(j,i,48,wrkarea) != 0) ; while (BITSET(j,i,48,wrkarea) == 0) { if (rint(j-256) < 4) SETON(j,i,48,wrkarea) ; else SETOFF(j,i,48,wrkarea) ; j++ ; } } for (i = 0; i <= 3; i++) /* spaceship */ BLT_MEM(&wrk_pr,320+20-i/2,i+10,i+10,1,RXNOR,&wrk_pr,320+20-i/2,i+10) ; for (i = 4; i <= 15; i++) { BLT_MEM(&wrk_pr,320+20-i/2,i+10,4,1,RXNOR,&wrk_pr,320+20-i/2,i+10) ; BLT_MEM(&wrk_pr,320+26+(i+1)/2,i+10,4,1,RXNOR,&wrk_pr,320+26+(i+1)/2,i+10) ; } BLT_MEM(&wrk_pr,320,26,50,4,RXNOR,&wrk_pr,320,26) ; for (i = 0; i <= 3; i++) BLT_MEM(&wrk_pr,320+15-i/2,49-i,i+20,1,RXNOR,&wrk_pr,320+15-i/2,49-i) ; for (i = 4; i <= 19; i++) { BLT_MEM(&wrk_pr,320+15-i/2,49-i,4,1,RXNOR,&wrk_pr,320+15-i/2,49-i) ; BLT_MEM(&wrk_pr,320+31+(i+1)/2,49-i,4,1,RXNOR,&wrk_pr,320+31+(i+1)/2,49-i) ; } BLT_MEM(&wrk_pr,320+18,0,3,3,RXNOR,&wrk_pr,320+18,0) ; BLT_MEM(&wrk_pr,320+30,0,3,3,RXNOR,&wrk_pr,320+30,0) ; LINE(&wrk_pr,320+19,2,320+24,9,RSET) ; LINE(&wrk_pr,320+31,2,320+26,9,RSET) ; BLT_MEM(&wrk_pr,256,16,3,3,RXNOR,&wrk_pr,256,16) ; /* Missiles. */ aplist = NULL ; bplist = NULL ; freeap = NULL ; waitlist = NULL ; waitcount = rint(100) ; xmax = width - 4 ; xmin = 4 ; ymax = height - 4 - FONT_HEIGHT ; ymin = 4 + FONT_HEIGHT ; mindimension = (height < width) ? height : width ; /* Calculate bonus payments, smaller window = LARGER bonus. */ bonus = 80 - ((mindimension / 100) * 10) ; BLT_SCRN(0,0,width,height,RXOR) ; /* Screen black except the border. */ BLT_SCRN(xmin,ymin,xmax-xmin+1,ymax-ymin+1,RXNOR) ; SCHRFUNC(RRPL) ; writeln(xmin+2,height-5,"Fuel : ") ; fuelxoffset = xmin+58 ; fuelmaxlength = (xmax-xmin) - fuelxoffset ; fuellength = fuelmaxlength ; BLT_SCRN(fuelxoffset,height-FONT_HEIGHT,fuellength,FONT_HEIGHT-2,RXNOR) ; addscore(0) ; } cleara(a) struct ainfo *a ; { if (a->sizex > 0 && a->sizey > 0) BLT_MEM_TO_SCRN(a->x+a->offx,a->y+a->offy,a->sizex,a->sizey,RXOR, &wrk_pr,a->wx+a->offx,a->wy+a->offy) ; } updatea(a) struct ainfo *a ; { int res,dx,dy ; int sizex,sizey,offx,offy ; res = 1 ; a->dx += a->xp*nummove ; dx = a->dx / AFACTOR ; a->dy += a->yp*nummove ; dy = a->dy / AFACTOR ; if (dx || dy) { sizex = a->sx ; sizey = a->sy ; offx = 0 ; offy = 0 ; a->x += dx ; a->y += dy ; if (a->x < xmin) { offx = xmin - a->x ; sizex -= offx ; } else if (a->x > xmax - a->sx) sizex = xmax - a->x + 1 ; if (a->y < ymin) { offy = ymin - a->y ; sizey -= offy ; } else if (a->y > ymax - a->sy) sizey = ymax - a->y + 1 ; if (sizex > 0 && sizey > 0) BLT_MEM_TO_SCRN(a->x+offx,a->y+offy,sizex,sizey,RXOR, &wrk_pr,a->wx+offx,a->wy+offy) ; else res = 0 ; if (a->sizex > 0 && a->sizey > 0) BLT_MEM_TO_SCRN(a->x-dx+a->offx,a->y-dy+a->offy,a->sizex,a->sizey,RXOR, &wrk_pr,a->wx+a->offx,a->wy+a->offy) ; a->sizex = sizex ; a->sizey = sizey ; a->offx = offx ; a->offy = offy ; a->dx -= AFACTOR * dx ; a->dy -= AFACTOR * dy ; } return(res) ; } starta(plist,typ,x,y,xp,yp) struct ainfo **plist ; int typ,x,y,xp,yp ; { struct ainfo *newap ; if (freeap == NULL) newap = (struct ainfo *) malloc(sizeof(struct ainfo)) ; else { newap = freeap ; freeap = freeap->next ; } newap->next = *plist ; *plist = newap ; newap->typ = typ ; newap->x = x ; newap->dx = 0 ; newap->xp = xp ; newap->y = y ; newap->dy = 0 ; newap->yp = yp ; switch (typ) { case 0 : newap->sx = 3 ; newap->sy = 3 ; newap->wx = 256 ; newap->wy = 16 ; break ; case 1 : newap->sx = 50 ; newap->sy = 50 ; newap->wx = 128 ; newap->wy = 0 ; break ; case 2 : newap->sx = 30 ; newap->sy = 30 ; newap->wx = 192 ; newap->wy = 0 ; break ; case 3 : newap->sx = 15 ; newap->sy = 15 ; newap->wx = 256 ; newap->wy = 0 ; break ; case 5 : newap->sx = 50 ; newap->sy = 50 ; newap->wx = 320 ; newap->wy = 0 ; break ; } if (x == xmin) newap->x = xmin - newap->sx + 1 ; if (y == ymin) newap->y = ymin - newap->sy + 1 ; newap->sizex = 0 ; /* initialise value while off screen. */ if (*plist != waitlist) if (updatea(newap)) /* do nothing */ ; } updatelist(plist) struct ainfo **plist ; { struct ainfo *owner,*this,*del ; int nx,ny,s ; owner = NULL ; this = *plist ; while (this != NULL) { if (updatea(this)) { if (this->typ >= 5) { if (scount > 0) scount -= nummove ; else { scount = 100 / this->typ ; scount += rint(scount) ; ny = rint(71) ; if (ny > 40) nx = 140 - ny ; else nx = 100 ; switch (ssector) { case 1 : s = nx ; nx = ny ; ny = s ; break ; case 2 : s = nx ; nx = (-ny) ; ny = s ; break ; case 3 : nx = (-nx) ; break ; case 4 : nx = (-nx) ; ny = (-ny) ; break ; case 5 : s = (-nx) ; nx = (-ny) ; ny = s ; break ; case 6 : s = (-nx) ; nx = ny ; ny = s ; break ; case 7 : ny = (-ny) ; break ; } ssector = (ssector + 1) % 8 ; starta(plist,0,this->x+20,this->y+20,3*nx,3*ny) ; if (owner == NULL) owner = *plist ; } this->typ += 1 ; } owner = this ; this = this->next ; } else if ((this->typ == 1 || this->typ == 2 || this->typ == 3) && basestatus == BACTIVE) { if (this->xp > 0) { if (this->x >= xmax) this->x = xmin - this->sx + 1 ; } else if (this->x <= xmin - this->sx + 1) this->x = xmax ; if (this->yp > 0) { if (this->y >= ymax) this->y = ymin - this->sy + 1 ; } else if (this->y <= ymin - this->sy + 1) this->y = ymax ; cleara(this) ; } else { del = this ; this = this->next ; if (owner == NULL) *plist = this ; else owner->next = this ; if ((del->typ == 1 || del->typ == 2 || del->typ == 3) && basestatus != BIDLE) { del->next = waitlist ; waitlist = del ; } else { del->next = freeap ; freeap = del ; } } } } nextangle(cw,x,y,newx,newy) int cw,x,y,*newx,*newy ; { int inc ; if (cw) inc = 1 ; else inc = -1 ; *newx = x ; *newy = y ; if (x + ((y > 0) == cw) > 40) *newy = y - inc ; if (x - ((y < 0) == cw) < -40) *newy = y + inc ; if (y + ((x < 0) == cw) > 40) *newx = x + inc ; if (y - ((x > 0) == cw) < -40) *newx = x - inc ; } restore_screen() /* Restore screen after window damage. */ { /* * Due to the inherent design of the game, it would appear not to * be easily possible to restore a damaged screen. This is where it * would be done if a neat way was found. * * If you do find a way, please send your answer to the author for * netwide distribution. Yes, this is a challenge!! */ c = 0 ; if (++firsttime == 1) return ; exit(1) ; } diff() { c = wgread() ; if (fuel <= 0) return(0) ; if (c == CTRLS) { do { c = wgread() ; if (c == WIN_DAMAGED) restore_screen() ; } while (c != CTRLQ) ; c = 0 ; } if (c == WIN_DAMAGED) restore_screen() ; if (c > WIN_DAMAGED) keys = 1 ; if (c == LEFTDOWN || c == RIGHTDOWN || c == LEFTUP || c == RIGHTUP) state = c ; if (state == LEFTDOWN) { fuel -= 1 ; return(MAXDIFF) ; } else if (state == RIGHTDOWN) { fuel -= 1 ; return(-MAXDIFF) ; } else return(0) ; } drawbase(x,y) int x,y ; { int t1,t2,i,dbmin,dbmax,ax,ay,bx,by,cx,cy,dx,dy ; BLT_MEM(&wrk_pr,0,0,64,bsize,RXOR,&wrk_pr,0,0) ; /* clear work area. */ ax = (14 * x + 50) / 100 + bheight ; ay = (14 * y + 50) / 100 + bheight ; cx = (-(5 * x + 50)) / 100 + bheight ; cy = (-(5 * y + 50)) / 100 + bheight ; t1 = (-10 * x) ; t2 = 6 * y ; bx = (t1 - t2 + 50) / 100 + bheight ; dx = (t1 + t2 + 50) / 100 + bheight ; t1 = (-10 * y) ; t2 = 6 * x ; by = (t1 + t2 + 50) / 100 + bheight ; dy = (t1 - t2 + 50) / 100 + bheight ; LINE(&wrk_pr,ax,ay,bx,by,RSET) ; LINE(&wrk_pr,bx,by,cx,cy,RSET) ; LINE(&wrk_pr,cx,cy,dx,dy,RSET) ; LINE(&wrk_pr,dx,dy,ax,ay,RSET) ; if (abs(x) > abs(y)) { if (ay > by) { dbmax = ay ; dbmin = by ; } else { dbmax = by ; dbmin = ay ; } ; if (dy > dbmax) dbmax = dy ; if (dy < dbmin) dbmin = dy ; for (i = dbmin+1; i <= (dbmax-1); i++) { t1 = 0 ; while (BITSET(t1,i,48,wrkarea) == 0) t1++ ; t2 = bsize - 1 ; while (BITSET(t2,i,48,wrkarea) == 0) t2-- ; BLT_MEM(&wrk_pr,t1,i,t2-t1,1,RXNOR,&wrk_pr,t1,i) ; } } else { if (ax > bx) { dbmax = ax ; dbmin = bx ; } else { dbmax = bx ; dbmin = ax ; } ; if (dx > dbmax) dbmax = dx ; if (dx < dbmin) dbmin = dx ; for (i = dbmin+1; i <= (dbmax-1); i++) { t1 = 0 ; while (BITSET(i,t1,48,wrkarea) == 0) t1++ ; t2 = bsize - 1 ; while (BITSET(i,t2,48,wrkarea) == 0) t2-- ; BLT_MEM(&wrk_pr,i,t1,1,t2-t1,RXNOR,&wrk_pr,i,t1) ; } } } renewbase(dx,dy) int dx,dy ; { BLT_MEM_TO_SCRN(bx+dx-bheight,by+dy-bheight,bsize,bsize,RXOR,&wrk_pr,0,0) ; BLT_MEM_TO_SCRN(bx-bheight,by-bheight,bsize,bsize,RXOR,&wrk_pr,64,0) ; bx = bx + dx ; by = by + dy ; BLT_MEM(&wrk_pr,64,0,64,bsize,RRPL,&wrk_pr,0,0) ; } startlist() { int i,ss,nx ; struct ainfo *ap ; t1count = 0 ; t3count = 0 ; if (waitlist != NULL) { ap = waitlist ; while (ap->next != NULL) ap = ap->next ; ap->next = freeap ; freeap = waitlist ; waitlist = NULL ; } for (i = 1; i <= 6; i++) { ss = (xmax - xmin) / 2 - 50 ; ss = xmin + rint(ss-150) + rint(ss+150) + 50 ; nx = rint(23) + rint(59) - 40 ; switch (rint(12) / 3) { case 0 : starta(&waitlist,1,xmin,ss,100,nx) ; break ; case 1 : starta(&waitlist,1,xmax,ss,-100,nx) ; break ; case 2 : starta(&waitlist,1,ss,ymin,nx,100) ; break ; case 3 : starta(&waitlist,1,ss,ymax,nx,-100) ; break ; } } if (addbonus) { SPRINTF(bonusstr," ** Bonus : %3d ** ",bonus*10) ; startflashbonus() ; addscore(bonus) ; } else addbonus = 1 ; /* don't add bonus at start. */ } matchlist(plist,test,tx,ty) struct ainfo **plist,*test ; int tx,ty ; { struct ainfo *owner,*this ; int nx,ny,s ; owner = NULL ; this = *plist ; while (this != NULL) { if (this != test) { if ((tx >= this->x) && (tx < this->x + this->sx) && (ty >= this->y) && (ty < this->y + this->sy)) if (BITSET(tx - this->x + this->wx,ty - this->y + this->wy,48,wrkarea) != 0) { cleara(this) ; addscore(this->typ) ; if ((scorethistank - REFUEL) >= 0) { fuel = FULLTANK ; /* refuel */ scorethistank = 0 ; } if ((this->typ == 1) || (this->typ == 2)) { nx = (rint(42) + 1) / 2 ; if (nx > 12) ny = 42 - nx ; else ny = 30 ; switch (rint(4)) { case 1 : ny = (-ny) ; break ; case 2 : s = nx ; nx = ny ; ny = s ; break ; case 3 : s = nx ; nx = ny ; ny = (-s) ; break ; } if (this->typ == 1) s = 10 ; else s = 8 ; starta(plist,this->typ+1,this->x+s,this->y+s,this->xp+nx,this->yp+ny) ; starta(plist,this->typ+1,this->x+s,this->y+s,this->xp-nx,this->yp-ny) ; if (owner == NULL) owner = (*plist)->next ; if (this->typ == 1) { t1count++ ; if (t1count == 6) { if (rint(2) == 0) starta(&waitlist,5,xmin,ymin+1,100,0) ; else starta(&waitlist,5,xmax,ymin+1,-100,0) ; scount = 10 ; ssector = rint(7) ; } } } else if (this->typ == 3) { t3count++ ; if (t3count == 24) startlist() ; } ; if (owner == NULL) *plist = this->next ; else owner->next = this->next ; this->next = freeap ; freeap = this ; return(1) ; } } owner = this ; this = this->next ; } return(0) ; } checkhit() { struct ainfo *owner,*this,*del ; int i,x,y ; owner = NULL ; this = bplist ; while (this != NULL) { BLT_MEM(&test_pr,0,0,64,3,RXOR,&test_pr,0,0) ; BLT_SCRN_TO_MEM(&test_pr,0,0,3,3,RRPL,this->x,this->y) ; y = -1 ; for (i = 0; i <= 2; i++) if (testarea[i*4] != 0) y = i ; /* this checks to see if row <> zeros */ if (y < 0) { owner = this ; this = this->next ; } else { x = 0 ; while (BITSET(x,y,4,testarea) == 0) x++ ; x += this->x ; y += this->y ; cleara(this) ; if (!matchlist(&aplist,(struct ainfo *) NULL,x,y)) if (!matchlist(&bplist,this,x,y)) /* do nothing */ ; del = this ; this = this->next ; if (owner == NULL) bplist = this ; else { if (owner->next == del) owner->next = this ; else if (bplist == del) bplist = this ; else { owner = bplist ; while (owner->next != del) owner = owner->next ; owner->next = this ; } } del->next = freeap ; freeap = del ; } } } disintgt(gone) int *gone ; { int x,y,xx,yy,countdown,gotone ; x = 0 ; y = 0 ; gotone = 0 ; countdown = rint(3) ; SETOFF(bheight,bheight,48,wrkarea) ; do { if (x > y) if (x > (-y)) y-- ; else x-- ; else if (x < (-y)) y++ ; else x++ ; if (BITSET(x + bheight,y + bheight,48,wrkarea) != 0) { gotone = 1 ; if (countdown > 0) countdown-- ; else { countdown = 5 ; xx = x ; yy = y ; if (abs(x) >= abs(y)) xx = xx - (2 * (x > 0) - 1) ; if (abs(x) <= abs(y)) yy = yy - (2 * (y > 0) - 1) ; SETOFF(x+bheight,y+bheight,48,wrkarea) ; SETON(xx+bheight,yy+bheight,48,wrkarea) ; } } } while (x + y != bheight + bheight) ; *gone = !gotone ; } updatebase() { int count,d,dd,dx,dy,i,j,newx,newy ; int changed,gone ; struct ainfo *ap ; switch (basestatus) { case BWAITING : if ((aplist == NULL) && (bplist == NULL)) { bx = (xmin + xmax + 1) / 2 ; by = (ymin + ymax + 1) / 2 ; ax = 100 ; ay = 0 ; bxp = 0 ; byp = 0 ; bdx = 0 ; bdy = 0 ; bxpd = 0 ; bypd = 0 ; motoron = 0 ; drawbase(ax,ay) ; renewbase(0,0) ; swcount = 0 ; basestatus = BACTIVE ; } break ; case BACTIVE : if (waitlist != NULL) if (waitcount > 0) waitcount-- ; else { ap = waitlist ; waitlist = ap->next ; ap->next = aplist ; aplist = ap ; waitcount = rint(rint(20) * 10 + 10) + 10 ; } d = diff() ; changed = 0 ; count = nummove + nummove ; while ((d != 0) && (count > 0)) { nextangle((d > 0),ax,ay,&newx,&newy) ; dd = diff() ; if ((dd == 0) || ((d > 0) == (dd > 0)) || (abs(dd) < abs(d))) { ax = newx ; ay = newy ; changed = 1 ; } if ((d > 0) != (dd > 0)) d = 0 ; else d = dd ; count-- ; } if (changed) drawbase(ax,ay) ; for (count = 1; count <= nummove; count++) { if (motoron) { fuel -= 10 ; /* burn some fuel. */ if (fuel <= 0) { fuel = 0 ; motoron = 0 ; } bxpd += ax ; bypd += ay ; dx = bxpd / BFACTOR ; dy = bypd / BFACTOR ; bxp += dx ; byp += dy ; bxpd -= dx * BFACTOR ; bypd -= dy * BFACTOR ; } bdx += bxp ; bdy += byp ; } dx = bdx / BFACTOR ; dy = bdy / BFACTOR ; bdx -= dx * BFACTOR ; bdy -= dy * BFACTOR ; if (changed || (dx != 0) || (dy != 0)) renewbase(dx,dy) ; BLT_MEM(&test_pr,0,0,64,bsize,RRPL,&wrk_pr,64,0) ; BLT_SCRN_TO_MEM(&test_pr,0,0,bsize,bsize,RXNOR, bx-bheight,by-bheight) ; i = 0 ; do if ((testarea[i*4] == 0) && /* Is row = zero? */ (testarea[i*4+1] == 0) && (testarea[i*4+2] == 0) && (testarea[i*4+3] == 0)) i++ ; else { j = 0 ; while (BITSET(j,i,4,testarea) == 0) j++ ; i += bx - bheight ; j += by - bheight ; if (!matchlist(&aplist,(struct ainfo *) NULL,j,i)) if (!matchlist(&bplist,(struct ainfo *) NULL,j,i)) ; basestatus = BDYING ; return ; } while (i != bsize) ; if (c == BUTMIDDLE) if (swcount > 0) swcount -= nummove ; else { swcount = 20 ; starta(&bplist,0,bx-1+(17*ax)/100,by-1+(17*ay)/100,ax*5,ay*5) ; } else swcount = 0 ; break ; case BDYING : disintgt(&gone) ; renewbase(0,0) ; if (gone) { while (wgread() != 0) ; /* Flush some output. */ state = 0 ; /* Clear previous button state. */ basecount-- ; if (basecount == 0) basestatus = BIDLE ; else { basestatus = BWAITING ; scorethistank = 0 ; fuel = FULLTANK ; } } break ; } } checkkey() { int nx,ny,ss ; if (keys) { keys = 0 ; switch (c) { case 'q' : case 'Q' : closedown() ; break ; case ESC : motoron = ((basestatus == BACTIVE) && (fuel > 0)) ; break ; case DEL : motoron = 0 ; break ; case BACKSPACE : if (basestatus == BACTIVE) if (fuel >= (FULLTANK / 5)) { fuel -= (FULLTANK / 5) ; /* 20% loss each hyperspace. */ ss = (xmax - xmin) / 2 - bsize ; nx = xmin + bheight + rint(ss-50) + rint(ss+50) ; ny = ymin + bheight + rint(ss-50) + rint(ss+50) ; if (nx < xmin + bheight) nx = xmin + bheight ; else if (nx > xmax - bheight) nx = xmax - bheight ; if (ny < ymin + bheight) ny = ymin + bheight ; else if (ny > ymax - bheight) ny = ymax - bheight ; renewbase(nx-bx,ny-by) ; } break ; } } } numticks(to,from) struct timeb *to,*from ; { return(((to->time - from->time) * 1000 + (to->millitm - from->millitm)) / 16) ; } /*ARGSUSED*/ main(argc,argv) int argc ; char *argv[] ; { STRCPY(progname,argv[0]) ; prog_type = MASTER ; when(god) etype(1) prog_type = SLAVE ; break ; endwhen ; get_options(argc,argv) ; /* Get users command line options. */ STRCPY(titlestring,"Asteroids V2.0.") ; if (prog_type == MASTER) { starttool(orgx,orgy,width,height,titlestring) ; exit(0) ; /* Slave is dead, master suicides. */ } startup() ; clear_screen() ; /* Clear the asteroids window. */ if (givehelp) do_help_screen() ; /* Output initial help/start screen. */ clear_screen() ; /* White background, before inversion. */ init() ; basecount = 3 ; startlist() ; basestatus = BWAITING ; ftime(&tlast) ; nummove = 1 ; do { updatelist(&aplist) ; updatelist(&bplist) ; updatebase() ; checkhit() ; checkkey() ; showfuel() ; if (flashbonus) doflashbonus() ; do { dummy = rint(2) ; ftime(&tnew) ; } while (tnew.millitm == tlast.millitm) ; nummove = numticks(&tnew,&tlast) ; if (nummove > 20) nummove = 20 ; tlast.time = tnew.time ; tlast.millitm = tnew.millitm ; } while ((basestatus != BIDLE) || (aplist != NULL) || (bplist != NULL)) ; closedown() ; } SHAR_EOF fi if test -f 'ast_stuff.c' then echo shar: "will not over-write existing file 'ast_stuff.c'" else cat << \SHAR_EOF > 'ast_stuff.c' /* ast_stuff.c * * Various functions and procedures used by the asteroids game. * Written by Rich Burridge - SUN Australia (Melbourne) - December 1986. * * Version 2.0. * * Routines: * * addscore - Add up current total score. * clear_screen - Clear the asteroid tool window. * closedown - Output high scores and exit cleanly. * do_help_screen - Output initial help/start screen. * doflashbonus - Display bonus message. * draw_frame - Create popup window for help message. * getline - Get characters from player until RETURN pressed. * get_options - Get user command line options. * rint - Pseudo random number generator. * showfuel - Show how much fuel is left. * showtitle - Display titlestring or bonus message. * startflashbonus - Start bonus message flashing. * * No responsibility is taken for any errors inherent either to the code * or the comments of this program, but if reported to me then an attempt * will be made to fix them. */ #include <stdio.h> #include <strings.h> #include "asteroids.h" #include <sys/timeb.h> extern char bonusstr[MAXLINE] ; /* Bonus message. */ extern char progname[MAXLINE] ; /* Name of this program. */ extern char titlestring[MAXLINE] ; /* Title string for asteroids window. */ extern struct timeb tstartflash,tlastflash ; extern int basecount ; /* Number of spaceships left. */ extern int bonusship ; /* New ship every bonusship points. */ extern int bonusshown ; /* Set if bonus message to be displayed. */ extern int flashbonus ; /* Flag for when to flash message. */ extern int fuel ; /* Amount of spaceship fuel left. */ extern int fuellength ; /* Current length of fuel bar. */ extern int fuelmaxlength ; /* Maximum length of fuel bar. */ extern int fuelxoffset ; /* Start of fuel display bar. */ extern int givehelp ; /* Set to 0, no initial help given. */ extern int height ; /* Window height. */ extern int orgx ; /* Window X origin. */ extern int orgy ; /* Window Y origin. */ extern int rr ; /* Used by rint for random numbers. */ extern int score ; /* Current score. */ extern int scorethistank ; /* Score this spaceship. */ extern int sfunc ; /* Rasterop function used by writeln. */ extern int width ; /* Window width. */ addscore(s) /* Add up current total score. */ int s ; { int s10 ; s10 = s*10 ; score += s10 ; scorethistank += s10 ; if (score > bonusship) { SPRINTF(bonusstr," ** Bonus Spaceship ** ") ; startflashbonus() ; basecount += 1 ; bonusship *= 2 ; /* double it. */ } SPRINTF(titlestring," Score : %6d",score) ; showtitle() ; } clear_screen() { getwindowparms(&orgx,&orgy,&width,&height) ; BLT_SCRN(orgx,orgy,width,height,RCLR) ; } closedown() /* Output high scores and exit cleanly. */ { BLT_SCRN(0,0,width,height,RXOR) ; checkscore() ; showhighscore() ; exit(0) ; } do_help_screen() { int x,y ; int length = 0 ; /* Length of longest help line. */ int nolines = 0 ; /* Number of lines in help file. */ char line[MAXLINE] ; /* Current line read from help file. */ FILE *tf ; /* File descripter for help file. */ int texty = 20 ; /* Initial y coordinate for help message. */ if ((tf = fopen(HELPNAME,"r")) == NULL) { FPRINTF(stderr,"%s: can't open %s for help information.\n", progname,HELPNAME) ; return ; } while (fgets(line,MAXLINE,tf) != NULL) { if (strlen(line) > length) length = strlen(line) ; nolines++ ; } FCLOSE(tf) ; x = (width - length*FONT_WIDTH - 20) / 2 ; y = (height - nolines*15+texty) / 2 ; draw_frame(x,y,length*FONT_WIDTH+20,nolines*15+texty) ; tf = fopen(HELPNAME,"r") ; while (fgets(line,MAXLINE,tf) != NULL) { line[strlen(line)-1] = '\0' ; SCHRFUNC(PIX_SRC) ; writeln(x+10,y+texty,line) ; texty += 15 ; } FCLOSE(tf) ; while (wgread() != RETURN) ; } doflashbonus() { struct timeb tnow ; ftime(&tnow) ; if (numticks(&tnow,&tlastflash) > FLICKERTIME) { bonusshown = !bonusshown ; /* on off on off every second. */ SCHRFUNC(RXOR) ; writeln(orgx+6,orgy+FONT_HEIGHT-2,bonusstr) ; tlastflash.time = tnow.time ; tlastflash.millitm = tnow.millitm ; } /* See if time out, if so stop flash */ if (((tnow.time - tstartflash.time) > FLASHTIME) && !bonusshown) { flashbonus = 0 ; addscore(0) ; /* to put score back on screen. */ } } draw_frame(x,y,fr_width,fr_height) int x,y,fr_width,fr_height ; { BLT_SCRN(x,y,fr_width,fr_height,RSET) ; BLT_SCRN(x+1,y+1,fr_width-2,fr_height-2,RCLR) ; BLT_SCRN(x+3,y+3,fr_width-6,fr_height-6,RSET) ; BLT_SCRN(x+5,y+5,fr_width-10,fr_height-10,RCLR) ; } getline(s,x,y) /* Get characters from user until a RETURN. */ char s[MAXLINE] ; int x,y ; { int c,i ; SCHRFUNC(RRPL) ; i = 0 ; for (;;) { s[i] = '_' ; s[i+1] = '\0' ; writeln(x,y,s) ; do c = wgread() ; while (!c) ; switch (c) { case BACKSPACE : case DEL : if (i) { s[i] = ' ' ; s[i+1] = '\0' ; i-- ; writeln(x,y,s) ; } break ; case RETURN : s[i] = '\0' ; return(i) ; default : s[i++] = c ; } } } get_options(argc,argv) int argc ; char *argv[] ; { char *arg ; char *p ; /* Pointer to string following argument flag. */ width = SWIDTH ; height = SHEIGHT ; givehelp = 1 ; while (argc > 1 && (arg = argv[1])[0] == '-') { p = arg + 2 ; switch (arg[1]) { case 'h' : givehelp = 0 ; /* Don't display help message. */ break ; case 'x' : width = atoi(p) ; /* Width of asteroids window. */ if (width < 500) width = 500 ; break ; case 'y' : height = atoi(p) ; /* Height of asteroids window. */ if (height < 500) height = 500 ; break ; default : FPRINTF(stderr,"sidtool: USAGE %s [-d]\n",argv[0]) ; exit(1) ; } argc-- ; argv++ ; } } rint(r) int r ; { rr = ((rr*4705 + 1) & 32767) ; if (!r) r = 1 ; return(rr % r) ; } showfuel() /* Show how much fuel is left. */ { int howmuch ; howmuch = (int)(fuelmaxlength * ((double)fuel / (double)FULLTANK)) ; if (howmuch != fuellength) { BLT_SCRN(fuelxoffset,height-FONT_HEIGHT,fuelmaxlength,FONT_HEIGHT-2,RCLR) ; fuellength = howmuch ; BLT_SCRN(fuelxoffset,height-FONT_HEIGHT,fuellength,FONT_HEIGHT-2,RXNOR) ; } } showtitle() /* Display titlestring or bonus message. */ { if (!flashbonus) { SCHRFUNC(RRPL) ; writeln(orgx+6,orgy+FONT_HEIGHT-2,titlestring) ; } } startflashbonus() /* start bonus flashing. */ { flashbonus = 1 ; bonusshown = 1 ; SCHRFUNC(RRPL) ; writeln(orgx+6,orgy+FONT_HEIGHT-2,bonusstr) ; /* Don't XOR the first one. */ ftime(&tstartflash) ; /* Get the time start. */ tlastflash.time = tstartflash.time ; tlastflash.millitm = tstartflash.millitm ; } SHAR_EOF fi if test -f 'ast_sun.c' then echo shar: "will not over-write existing file 'ast_sun.c'" else cat << \SHAR_EOF > 'ast_sun.c' /* ast_sun.c * * SUN dependent functions and procedures used by the asteroids game. * Written by Rich Burridge - SUN Australia (Melbourne) - December 1986. * * Version 2.0. * * Routines. * --------- * * lose * sigwinched * sigchild * toolsw_selected * toolsw_sighandler * starttool * startup * write_bold - Output text item in pseudo bold.* writeln * getwindowparms - Return window dimensions. * wgread - Check for button or key pressed. * * No responsibility is taken for any errors inherent either to the code * or the comments of this program, but if reported to me then an attempt * will be made to fix them. */ #include <stdio.h> #include <strings.h> #include "asteroids.h" #include <sys/timeb.h> #include <suntool/tool_hs.h> #include <suntool/emptysw.h> #include <sys/socket.h> #include <sys/file.h> #include <sys/ioctl.h> #include <sys/un.h> #include <signal.h> #include <errno.h> exexception(god) ; extern int errno ; struct pixwin *pixwin ; struct tool *tool ; struct toolsw *emptysw ; struct inputevent ie ; struct inputmask im ; sigwinched(),sigchild() ; toolsw_selected(),toolsw_sighandler() ; int pid ; /* Process id of slave program. */ int finished = 0 ; /* 1 -> socket no longer available. */ int sfunc ; extern int c ; /* Used by wgread for mouse and keyboard interaction. */ extern int width,height ; /* Dimensions of the SID tool window. */ static short ast_image[256] = { #include "asteroids.icon" } ; mpr_static(ast_mpr,64,64,1,ast_image) ; static struct icon icon = { 64,64,(struct pixrect *)NULL,0,0,64,64, &ast_mpr,0,0,0,0,NULL,(struct pixfont *)NULL, ICON_BKGRDCLR } ; extern struct pixfont *pw_pfsysopen() ; /* GFX stuff. */ static struct pixfont *pixfont ; struct gfxsubwindow *gfx ; char name[WIN_NAMESIZE] ; static struct cursor nullcur,syscur ; /* Cursor stuff. */ static short nullicon[CUR_MAXIMAGEWORDS],sysicon[CUR_MAXIMAGEWORDS] ; mpr_static(nullpix,8*sizeof(nullicon[0]), sizeof(nullicon)/sizeof(nullicon[0]),1,nullicon) ; mpr_static(syscurpix,8*sizeof(sysicon[0]), sizeof(sysicon)/sizeof(sysicon[0]),1,sysicon) ; #define TUNIT 0 /* Socket stuff. */ static struct timeval timeout = {TUNIT,TUNIT} ; static struct sockaddr_un client,server ; static int mask,sin,sout,snew,slen ; lose(str) char *str ; { FPRINTF(stderr,str) ; exit(1) ; } static sigwinched() { tool_sigwinch(tool) ; } static sigchild() { finished = 1 ; tool_sigchld(tool) ; } /*ARGSUSED*/ static toolsw_selected(sw,ibits,obits,ebits,timer) caddr_t sw ; int *ibits,*obits,*ebits ; struct timeval **timer ; { char c = '\0' ; if (*ibits & (1 << emptysw->ts_windowfd)) { input_readevent(emptysw->ts_windowfd,&ie) ; switch (ie.ie_code) { case MS_LEFT : if (ie.ie_flags & IE_NEGEVENT) c = LEFTUP ; else if (!(ie.ie_flags & IE_NEGEVENT)) c = LEFTDOWN ; break ; case MS_MIDDLE : if (!(ie.ie_flags & IE_NEGEVENT)) c = BUTMIDDLE ; break ; case MS_RIGHT : if (ie.ie_flags & IE_NEGEVENT) c = RIGHTUP ; else if (!(ie.ie_flags & IE_NEGEVENT)) c = RIGHTDOWN ; } if ((ie.ie_code >= ASCII_FIRST) && (ie.ie_code <= ASCII_LAST)) c = (char) ie.ie_code ; WRITE(snew,&c,1) ; } *ibits = 0 ; } static toolsw_sighandler() { char c ; if (!finished) { c = WIN_DAMAGED ; WRITE(snew,&c,1) ; pw_damaged(pixwin) ; pw_donedamaged(pixwin) ; } } starttool(orgx,orgy,width,height,toolname) int orgx,orgy,width,height ; char *toolname ; { char **tool_attrs = NULL ; UNLINK(SOCKNAME) ; sout = socket(AF_UNIX,SOCK_STREAM,0) ; /* Create server socket. */ server.sun_family = AF_UNIX ; STRCPY(server.sun_path,SOCKNAME) ; BIND(sout,(struct sockaddr *) &server,strlen(SOCKNAME)+2) ; LISTEN(sout,5) ; tool = tool_make(WIN_LABEL, toolname, WIN_ICON, &icon, WIN_LEFT, orgx, WIN_TOP, orgy, WIN_WIDTH, width, WIN_HEIGHT, height, WIN_ATTR_LIST, tool_attrs, 0) ; if (tool == (struct tool *)NULL) lose("Couldn't create tool") ; tool_free_attribute_list(tool_attrs) ; emptysw = esw_createtoolsubwindow(tool,"",TOOL_SWEXTENDTOEDGE,TOOL_SWEXTENDTOEDGE) ; if (emptysw == (struct toolsw *)NULL) lose("Couldn't create empty subwindow") ; pixwin = pw_open(emptysw->ts_windowfd) ; if (pixwin == (struct pixwin *)NULL) lose("Couldn't create pixwin.") ; emptysw->ts_io.tio_handlesigwinch = toolsw_sighandler ; emptysw->ts_io.tio_selected = toolsw_selected ; input_imnull(&im) ; im.im_flags |= IM_ASCII ; im.im_flags |= IM_NEGEVENT ; win_setinputcodebit(&im,MS_LEFT) ; win_setinputcodebit(&im,MS_MIDDLE) ; win_setinputcodebit(&im,MS_RIGHT) ; win_setinputmask(emptysw->ts_windowfd,&im,(struct inputmask *)NULL,WIN_NULLLINK) ; (void) signal(SIGWINCH,sigwinched) ; tool_install(tool) ; /* Install the tool. */ win_fdtoname(emptysw->ts_windowfd,name) ; /* Make GFX window name. */ we_setgfxwindow(name) ; if ((pid = fork()) == NULL) raise(god,1) ; /* Fork graphics program. */ slen = sizeof(server) ; snew = accept(sout,(struct sockaddr *) &server,&slen) ; /* Accept client socket. */ (void) signal(SIGCHLD,sigchild) ; tool_select(tool,1) ; /* Notification loop. */ tool_destroy(tool) ; /* Die gracefully. */ KILL(pid,SIGKILL) ; /* Murder the child !! */ CLOSE(snew) ; CLOSE(sout) ; } startup() { sfunc = PIX_SRC ; /* Used by writeln */ sin = socket(AF_UNIX,SOCK_STREAM,0) ; /* Create client socket. */ client.sun_family = AF_UNIX ; STRCPY(client.sun_path,SOCKNAME) ; CONNECT(sin,(struct sockaddr *) &client,strlen(client.sun_path)+2) ; gfx = gfxsw_init(0,0) ; if (gfx == (struct gfxsubwindow *)NULL) lose("Couldn't create graphics window.") ; pixfont = pw_pfsysopen() ; if (pixfont == (struct pixfont *)NULL) lose("Couldn't create default font.") ; syscur.cur_shape = &syscurpix ; win_getcursor(gfx->gfx_windowfd,&syscur) ; syscur.cur_function = RXOR ; nullcur.cur_shape = &nullpix ; win_getcursor(gfx->gfx_windowfd,&nullcur) ; nullcur.cur_xhot = nullcur.cur_yhot = 0 ; nullcur.cur_function = RXOR ; nullcur.cur_shape->pr_size.x = 0 ; nullcur.cur_shape->pr_size.y = 0 ; } write_bold(x,y,text) int x,y ; char text[MAXLINE] ; { pw_text(gfx->gfx_pixwin,x,y,ROR,pixfont,text) ; pw_text(gfx->gfx_pixwin,x+1,y,ROR,pixfont,text) ; } writeln(x,y,text) /* Write a line of text to the screen at x,y. */ int x,y ; char *text ; { pw_text(gfx->gfx_pixwin,x,y,sfunc,pixfont,text) ; } getwindowparms(orgx,orgy,width,height) /* Return window dimensions. */ int *orgx,*orgy,*width,*height ; { struct rect rect ; win_getsize(gfx->gfx_windowfd,&rect) ; *orgx = rect.r_left ; *orgy = rect.r_top ; *width = rect.r_width ; *height = rect.r_height ; } wgread() /* Check for button or key pressed. */ { char c ; c = '\0' ; mask = 1 << sin ; SELECT(32,&mask,(int *) 0,(int *) 0,&timeout) ; if (mask & (1 << sin)) READ(sin,&c,1) ; return((int) c) ; } SHAR_EOF fi exit 0 # End of shell archive D D