Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sid Tool (Pacman) Part 4 of 5.

4 views
Skip to first unread message

ri...@sunk.uucp

unread,
Apr 12, 1987, 2:12:51 AM4/12/87
to
---------CUT HERE----------CUT HERE--------
#! /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 4 (of 5)."
# Contents: sid_blt.c sid_stuff.c
# Wrapped by richb@sunk on Sun Apr 12 15:19:49 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f sid_blt.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"sid_blt.c\"
else
echo shar: Extracting \"sid_blt.c\" \(21194 characters\)
sed "s/^X//" >sid_blt.c <<'END_OF_sid_blt.c'
X
X/* sid_blt.c
X *
X * Various routines that do "rasterop" type graphics used by sidtool.
X *
X * Written by Rich Burridge - SUN Microsystems Australia (Melbourne).
X *
X * Version 2.1. - April 1987.
X *
X * No responsibility is taken for any errors inherent either to the code
X * or the comments of this program, but if reported to me then an attempt
X * will be made to fix them.
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <setjmp.h>
X#include "bltstuff.h"
X#include "sidtool.h"
X#include <sys/types.h>
X#include <sys/timeb.h>
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X
Xextern jmp_buf exception ;
Xextern int val ;
X
Xextern Pixfont *pf ;
Xextern Pixwin *pw ;
X
X/* For descriptions of these variables, see sid_main.c */
X
Xextern BOOLEAN autoplay,demomode,remove ;
X
Xextern char a_name[MAXLINE],buffer[MAXLINE],but_names[7][8],h_name[MAXLINE] ;
Xextern char m_name[MAXLINE],maze[XSIZE+2][YSIZE+2],names[4][MAXLINE],sc ;
Xextern char titlestring[MAXLINE] ;
X
Xextern int autoscore,blueblink,blueincblink,boxx,boxy,button,c,circatchup ;
Xextern int cirmx,cirmy,cirx,ciry,count,credits,curbluetime[MAXNUMPLAYERS+1] ;
Xextern int curdir,dots[MAXNUMPLAYERS+1][XSIZE+4][YSIZE+2],dotx,doty ;
Xextern int fruitchances[MAXNUMPLAYERS+1],fruiton,fruittime,fruitx,fruity ;
Xextern int fruitmaze[MAXNUMPLAYERS+1],g,gamestate,height,highplayer ;
Xextern int highscore,inc,movei,movej,movex,newdir,numcir[MAXNUMPLAYERS+1] ;
Xextern int numdots[MAXNUMPLAYERS+1],nx,ny,oldcurdir,oldcx,oldcy,orgx,orgy ;
Xextern int pausetime,player,posx,posy,progstate,score[MAXNUMPLAYERS+1] ;
Xextern int sfunc,skilllevel,speed,tunnel[XSIZE+4][YSIZE+2],walls[XSIZE+6][YSIZE+1] ;
Xextern int width,x,y ;
X
Xextern Pixrect *load_picture() ;
Xextern long random() ;
X
Xextern Pixrect *bigdot,*bluebug[2],*bluepics[2],*bugpics[4][2],*circleexplode[9] ;
Xextern Pixrect *circles[4][4],*corner[4],*curcircle,*eyes[4],*fruitpics[9] ;
Xextern Pixrect *smalldot ;
X
Xextern struct bugrec bugs[4] ; /* The bad guys. */
Xextern struct scorerec allhighscores[11] ;
Xextern struct startrec startpos[4] ;
X
X
Xclear_screen()
X
X{
X BLT_SCRN(orgx,orgy,width,height,RCLR) ;
X
X/* To get over displaying the last cursor incorrectly after a cleared screen,
X * the old cursor position is forced off the screen.
X */
X
X oldcx = 1000 ;
X oldcy = 1000 ;
X}
X
X
Xddrawline(mx,my,dir)
Xint mx,my,dir ;
X
X/* Draw a maze line from mx,my in the direction dir.
X * Parameters: dir should be d,u,l,r, (or R for a thin line).
X */
X
X{
X int x,y ;
X
X TRANSPT(mx,my,x,y) ;
X switch (dir)
X {
X case 'd' :
X case 'u' : BLT_SCRN(x+SQUARE/2,y,2,SQUARE,RSET) ;
X break ;
X case 'l' :
X case 'r' : BLT_SCRN(x,y+SQUARE/2,SQUARE,2,RSET) ;
X break ;
X case 'R' : BLT_SCRN(x,y+SQUARE/2,SQUARE,1,RSET) ;
X }
X}
X
X
Xdrawbug(g)
Xregister struct bugrec *g ;
X
X{
X int inc,winc ;
X
X inc = g->scrx - GOFFSET ;
X winc = 0 ;
X
X if (inc < 0)
X if (inc <= 45) return ;
X else winc = inc ;
X else if (inc > SWIDTH-45)
X if (inc > SWIDTH - 1) return ;
X else
X {
X winc = SWIDTH-45-inc ;
X inc = 0 ;
X }
X else inc = 0 ;
X
X if (g->eyesonly)
X {
X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET,
X 45+winc,21,RXOR,eyes[g->dir],-inc,0) ;
X/* Fake BLT to get speed same. */
X BLT_MEM(bugpics[GIND(g)][g->pic],0,0,45+winc,21,RRPL,
X bugpics[GIND(g)][g->pic],0,0) ;
X }
X else if (g->bluetime > 0)
X {
X if ((g->bluetime < blueblink) &&
X (g->bluetime % blueincblink > blueincblink / 2))
X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET,
X 45+winc,45,RXOR,bluepics[g->pic],-inc,0) ;
X else
X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET,
X 45+winc,45,RXOR,bluebug[g->pic],-inc,0) ;
X/* Fake BLT to get speed same. */
X BLT_MEM(eyes[g->dir],0,0,45+winc,21,RRPL,eyes[g->dir],0,0) ;
X }
X else
X {
X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET,
X 45+winc,45,RXOR,bugpics[GIND(g)][g->pic],-inc,0) ;
X BLT_MEM_TO_SCRN(g->scrx-GOFFSET-inc,g->scry-GOFFSET,
X 45+winc,21,RXOR,eyes[g->dir],-inc,0) ;
X }
X}
X
X
Xdrawcir(p,x,y) /* Draw the specified screen on the screen. */
Xint x,y ;
XPixrect *p ;
X
X{
X if (x < 0) return ; /* Fully off left side. */
X else if (x > SWIDTH+1) return ; /* Fully off right side. */
X
X if (!(oldcx == x && oldcy == y))
X {
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X curcircle = p ;
X BLT_MEM_TO_SCRN(x-GOFFSET+5,y-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X oldcx = x ;
X oldcy = y ;
X }
X}
X
X
Xdrawcorner(mx,my,dir)
Xint dir,mx,my ;
X
X/* Draw a corner at MAZE position mx,my turning the direction dir. */
X
X{
X int x,y ;
X
X TRANSPT(mx,my,x,y) ;
X BLT_MEM_TO_SCRN(x,y,SQUARE,SQUARE,RRPL,corner[dir],0,0) ;
X}
X
X
Xdrawdot(mx,my,size) /* XORS a dot at the maze position mx,my. */
Xint mx,my,size ;
X
X{
X TRANSPT(mx,my,mx,my) ;
X if (size == BIGDOT) BLT_MEM_TO_SCRN(mx,my,24,24,RXOR,bigdot,0,0) ;
X else if (size == SMALLDOT) BLT_MEM_TO_SCRN(mx+9,my+9,7,7,RXOR,smalldot,9,9) ;
X}
X
X
Xdrawmaze() /* Draw the maze,the dots,the scores, etc on the screen. */
X
X{
X int x,y ;
X
X clear_screen() ;
X for (y = 0; y <= YSIZE+1; y++)
X {
X walls[1][y] = 1 ;
X walls[0][y] = 1 ;
X walls[XSIZE+4][y] = 1 ;
X walls[XSIZE+5][y] = 1 ;
X for (x = 0; x <= XSIZE+1; x++) walls[x+2][y] = 0 ;
X }
X
X for (y = 0; y <= YSIZE+1; y++)
X for (x = 0; x <= XSIZE+1; x++)
X if ((maze[x][y] == 's') || (maze[x][y] == 'S') || (maze[x][y] == 'T'))
X drawbox(x,y) ;
X else if (maze[x][y] == 'x') walls[x+2][y] = 1 ; /* Borders. */
X
X PPAUSE(pausetime*30) ;
X BLT_SCRN(XBASE-(SQUARE/2)-2,YBASE-(SQUARE/2)-2,
X SQUARE*(XSIZE+1)+6,SQUARE*(YSIZE+1)+6,RINV) ;
X fixexits() ;
X
X for (y = 1; y <= YSIZE; y++)
X for (x = 1; x <= XSIZE; x++)
X if (dots[player][x+1][y] == SMALLDOT)
X {
X PPAUSE(pausetime*5) ;
X drawdot(x,y,SMALLDOT) ;
X }
X else if (dots[player][x+1][y] == BIGDOT)
X {
X PPAUSE(pausetime*5) ;
X drawdot(x,y,BIGDOT) ;
X }
X
X for (x = 1; x <= 4; x++) showplayerscore(x) ;
X
X SPRINTF(buffer,"High Score (%1d)",skilllevel) ;
X WRITELN(310,20,buffer) ;
X if (!highscore) WRITELN(348,35,"0") ;
X else
X {
X SPRINTF(buffer,"%1d0",highscore) ;
X WRITELN(348,35,buffer) ;
X }
X
X for (x = 1; x <= numcir[player]; x++)
X {
X PPAUSE(pausetime*30) ;
X BLT_MEM_TO_SCRN(30+(x-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ;
X }
X
X BLT_MEM_TO_SCRN(705,25,45,45,RRPL,fruitpics[fruitmaze[player]],0,0) ;
X BLT_SCRN(700,20,55,55,RINV) ;
X SPRINTF(buffer,"%1d0",fruitscore(fruitmaze[player])) ;
X WRITELN(710,15,buffer) ;
X
X if (autoplay && (!demomode))
X {
X SCHRFUNC(RXOR) ;
X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ;
X SCHRFUNC(RRPL) ;
X WRITELN(300,65,"Type DEL to begin") ;
X WRITELN(480,50,"Auto Score") ;
X WRITELN(489,65,"0") ;
X }
X}
X
X
Xdocredits()
X
X{
X int g,x,y,i,j ;
X
X credits = 1 ;
X clear_screen() ;
X dohelp() ;
X WRITELN(5,860,"Type DEL to begin") ;
X for (i = 0; i < 100; i++) LONGPAUSE() ;
X
X newbugs(0) ;
X UNTRANSPT(130,350,dotx,doty) ;
X UNTRANSPT(860,350,x,y) ;
X TRANSPT(x,y,i,ciry) ;
X BLT_SCRN(3,ciry-37,762,100,RINV) ;
X
X for (g = POKEY; g <= SHADOW; g++)
X {
X bugs[g].mx = x + g * 2 ;
X bugs[g].my = doty ;
X bugs[g].dir = g ;
X TRANSPT(bugs[g].mx,bugs[g].my,bugs[g].scrx,bugs[g].scry) ;
X drawbug(&bugs[g]) ; /* Should be invisible. */
X }
X drawdot(dotx,doty,BIGDOT) ;
X cirx = 720 ;
X inc = 0 ;
X movei = 1 ;
X progstate = MOVELEFT ;
X}
X
X
Xmove_left() /* Animate screen and bugs left. */
X
X{
X int g ;
X
X if (movei % 8) cirx-- ;
X drawcir(circles[LEFT][inc],cirx,ciry) ;
X if (movei % 4 == 0) inc = (inc + 1) % 4 ;
X for (g = POKEY; g <= SHADOW; g++)
X {
X drawbug(&bugs[g]) ; /* Erase old. */
X bugs[g].scrx-- ;
X if (movei % 13 == 0) bugs[g].pic = (bugs[g].pic + 1) % 2 ;
X if (movei % 18 == 0) bugs[g].dir = (bugs[g].dir + 1) % 4 ;
X drawbug(&bugs[g]) ; /* Draw new. */
X }
X if (++movei > 662)
X {
X credits = 2 ;
X drawdot(dotx,doty,BIGDOT) ;
X for (g = POKEY; g <= SHADOW; g++)
X {
X drawbug(&bugs[g]) ; /* Erase old. */
X bugs[g].bluetime = 32000 ;
X drawbug(&bugs[g]) ; /* Draw new as blue. */
X }
X SCHRFUNC(RXOR) ;
X movej = 200 ;
X movex = 1 ;
X movei = 1 ;
X progstate = MOVERIGHT ;
X }
X}
X
X
Xmove_right() /* Animate eating screen and bugs right. */
X
X{
X int g,i ;
X
X PPAUSE(8*movex) ;
X if (movei % 26) cirx++ ;
X drawcir(circles[RIGHT][inc],cirx,ciry) ;
X if (movei % 4 == 0) inc = (inc + 1) % 4 ;
X for (g = POKEY; g <= SHADOW; g++)
X if (!bugs[g].eyesonly)
X {
X drawbug(&bugs[g]) ; /* Erase old. */
X if (movei % 2) bugs[g].scrx++ ;
X if (movei % 13 == 0) bugs[g].pic = (bugs[g].pic + 1) % 2 ;
X if (cirx >= bugs[g].scrx-20)
X {
X bugs[g].eyesonly = 1 ;
X SPRINTF(buffer,"%1d",movej) ;
X WRITELN(bugs[g].scrx-20,440,buffer) ;
X for (i = 0; i < 60; i++) LONGPAUSE() ;
X SPRINTF(buffer,"%1d",movej) ;
X WRITELN(bugs[g].scrx-20,440,buffer) ;
X movej *= 2 ;
X movex++ ;
X }
X else drawbug(&bugs[g]) ; /* Draw new. */
X }
X if (++movei > 665)
X {
X SCHRFUNC(RRPL) ;
X for (i = 0; i < 100; i++) LONGPAUSE() ;
X credits = 0 ;
X progstate = INITGAME ;
X }
X}
X
X
Xdohelp()
X
X{
X int g,i,x,y ;
X char line[MAXLINE] ;
X FILE *fn ;
X
X write_bold(105,100,titlestring) ;
X WRITELN(105,120,"Original version by Brad A. Myers with pictures of fruit by Terry Vavra.") ;
X
X for (g = POKEY; g <= SHADOW; g++)
X {
X if (g > 1) y = YBASE + 130 ;
X else y = YBASE + 50 ;
X x = (g % 2) ? 384 : 100 ;
X
X BLT_MEM_TO_SCRN(x,y,45,45,RRPL,bugpics[g][0],0,0) ;
X BLT_MEM_TO_SCRN(x,y,45,21,RXOR,eyes[g],0,0) ;
X for (i = 0; i < 40; i++) LONGPAUSE() ;
X SPRINTF(buffer,"- %s",names[g]) ;
X WRITELN(x+60,y+25,buffer) ;
X for (i = 0; i < 40; i++) LONGPAUSE() ;
X }
X
X if ((fn = fopen(h_name,"r")) == NULL)
X {
X FPRINTF(stderr,"\nsidtool: can't open %s\n",h_name) ;
X exit(-1) ;
X }
X x = 105 ;
X y = 465 ;
X i = 0 ;
X while (get_string(fn,line) != -1)
X {
X WRITELN(x,i*15+y,line) ;
X i++ ;
X }
X if (!autoplay) make_control_panel() ;
X if (!autoplay) display_settings() ;
X}
X
X
Xdoplay()
X
X{
X if (remove) /* Jump here if have been eaten or starting new game. */
X {
X removecircle() ;
X numcir[player]-- ;
X }
X curdir = LEFT ; /* Jump here if got all dots. */
X fruiton = 0 ;
X sc = ' ' ;
X inc = 0 ;
X count = 1 ;
X posx = (SWIDTH / 2) - 11 ;
X posy = YBASE + SQUARE * 21 ;
X fruittime = randomrange(1000,2500) ;
X UNTRANSPT(posx,posy,cirmx,cirmy) ;
X drawcir(circles[curdir][inc],posx,posy) ;
X newbugs(1) ;
X if (demomode || !autoplay)
X {
X SCHRFUNC(RXOR) ;
X WRITELN(357,YBASE+SQUARE*16,"READY!") ;
X blinkpause() ;
X SCHRFUNC(RXOR) ;
X WRITELN(357,YBASE+SQUARE*16,"READY!") ;
X SCHRFUNC(RRPL) ;
X }
X}
X
X
Xmake_play() /* Perform next movement of each sid tool object. */
X
X{
X updatebugs() ;
X if (checkcollision(cirmx,cirmy,&g)) handlecollision(&bugs[g]) ;
X if (fruittime != -1)
X {
X fruittime-- ;
X if (!fruittime) updatefruit() ;
X }
X newdir = curdir ;
X if (GCENTERED(posx,posy))
X {
X if (autoplay)
X newdir = dorandomdir(curdir,posx,posy,cirmx,cirmy,&x,&y,&nx,&ny,1) ;
X else
X switch (curdir)
X {
X case UP : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ;
X else if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ;
X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ;
X break ;
X
X case DOWN : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ;
X else if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ;
X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ;
X break ;
X
X case RIGHT : if (sc == 'l' && !walls[cirmx+1][cirmy]) newdir = LEFT ;
X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ;
X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ;
X break ;
X
X case LEFT : if (sc == 'r' && !walls[cirmx+3][cirmy]) newdir = RIGHT ;
X else if (sc == 'u' && !walls[cirmx+2][cirmy-1]) newdir = UP ;
X else if (sc == 'd' && !walls[cirmx+2][cirmy+1]) newdir = DOWN ;
X break ;
X }
X }
X if (doinc(newdir,posx,posy,cirmx,cirmy,&x,&y,&nx,&ny)) doupdate() ;
X else
X {
X if (!GCENTERED(posx,posy)) doupdate() ; /* Until centered. */
X else
X {
X if (oldcurdir != curdir)
X {
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,
X 45,45,RXOR,curcircle,0,0) ;
X curcircle = circles[curdir][0] ;
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,
X 45,45,RXOR,curcircle,0,0) ;
X oldcurdir = curdir ;
X }
X }
X }
X if (checkcollision(cirmx,cirmy,&g)) handlecollision(&bugs[g]) ;
X}
X
X
Xdoupdate()
X
X{
X count++ ;
X if (count % circatchup == 0) return ; /* Go slower than bugs. */
X drawcir(circles[newdir][inc],x,y) ;
X if (count % 4 == 0) inc = (inc + 1) % 4 ;
X if (fruiton)
X if ((nx == FRUITMX) && (ny == FRUITMY)) destroyfruit() ;
X if (dots[player][nx+1][ny] != NODOT)
X {
X if (dots[player][nx+1][ny] == SMALLDOT) updatescore(1) ;
X else
X {
X changebugs() ;
X updatescore(5) ;
X }
X numdots[player]-- ;
X drawdot(nx,ny,dots[player][nx+1][ny]) ;
X dots[player][nx+1][ny] = NODOT ;
X if (!numdots[player])
X {
X resetmaze() ;
X gamestate = FALSE ;
X progstate = RESETGAME ;
X longjmp(exception,val) ;
X }
X }
X curdir = newdir ;
X posx = x ;
X posy = y ;
X cirmx = nx ;
X cirmy = ny ;
X}
X
X
Xexplodecircle(posx,posy)
Xint posx,posy ;
X
X{
X int i ;
X
X for (i = 0; i <= 8; i++)
X {
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X curcircle = circleexplode[i] ;
X BLT_MEM_TO_SCRN(posx-GOFFSET+5,posy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X oldcx = posx ;
X oldcy = posy ;
X PPAUSE(pausetime*70) ;
X }
X for (i = 0; i < 80; i++) LONGPAUSE() ;
X}
X
X
Xfixexits()
X
X/* Look for tunnels on the borders. For each, show the area as black
X * on the screen and set the walls and tunnel global variables to
X * reflect the presence of the tunnel.
X */
X
X{
X int x,y,t ;
X
X PPAUSE(pausetime*30) ;
X for (y = 1; y <= YSIZE; y++)
X if (maze[0][y] == ' ')
X {
X walls[1][y] = 0 ;
X walls[0][y] = 0 ;
X x = -1 ;
X do
X {
X x++ ;
X tunnel[x][y] = 1 ;
X }
X while (maze[x][y] == ' ') ;
X TRANSPT(0,y,x,t) ;
X BLT_SCRN(3,t-2-SQUARE/2,XBASE-(SQUARE/2)-5,SQUARE*2+6,RINV) ;
X }
X
X PPAUSE(pausetime*30) ;
X for (y = 1; y <= YSIZE; y++)
X if (maze[XSIZE+1][y] == ' ')
X {
X walls[XSIZE+4][y] = 0 ;
X walls[XSIZE+5][y] = 0 ;
X x = XSIZE+1 ;
X do
X {
X x-- ;
X tunnel[x][y] = 1 ;
X }
X while (maze[x][y] == ' ') ;
X TRANSPT(0,y,x,t) ;
X BLT_SCRN(XBASE-(SQUARE/2)+SQUARE*(XSIZE+1)+4,t-2-SQUARE/2,
X XBASE-(SQUARE/2)-5,SQUARE*2+6,RINV) ;
X }
X}
X
X
Xget_button_option()
X
X{
X if (!c) return ;
X else if (c >= BUT_AUTO+2 && c <= BUT_START+2)
X {
X BLT_SCRN(SQUARE/2+100*(c-2)+BUTXOFF,SQUARE/2+BUTYOFF,70,SQUARE,RINV) ;
X PPAUSE(pausetime*100) ;
X BLT_SCRN(SQUARE/2+100*(c-2)+BUTXOFF,SQUARE/2+BUTYOFF,70,SQUARE,RINV) ;
X progstate = MAKESEL ;
X button = c - 2 ;
X c = 0 ;
X }
X}
X
X
Xinitialize()
X
X{
X int fd,i,j,g,x,y ;
X struct timeb tp ;
X FILE *fn ;
X
X ftime(&tp) ;
X for (x = 1; x < tp.millitm % 10; x++) y = (int) random() ; /* Randomize start. */
X
X if (!demomode) FPRINTF(stdout," Random") ;
X if (!demomode) FPRINTF(stdout," Memory") ;
X
X if ((fd = open(a_name,0)) == -1)
X {
X FPRINTF(stderr,"sidtool: unable to open %s.\n",a_name) ;
X exit(-1) ;
X }
X
X for (i = UR; i <= LU; i++) corner[i] = load_picture(fd) ;
X
X bigdot = load_picture(fd) ;
X smalldot = load_picture(fd) ;
X
X for (i = RIGHT; i <= DOWN; i++)
X for (j = 0; j <= 3; j++) circles[i][j] = load_picture(fd) ;
X for (i = POKEY; i <= SHADOW; i++)
X for (j = 0; j <= 1; j++) bugpics[i][j] = load_picture(fd) ;
X
X for (i = 0; i <= 1; i++) bluebug[i] = load_picture(fd) ;
X for (i = 0; i <= 1; i++) bluepics[i] = load_picture(fd) ;
X for (i = 0; i <= 3; i++) eyes[i] = load_picture(fd) ;
X for (i = 0; i <= 8; i++) circleexplode[i] = load_picture(fd) ;
X for (i = 1; i <= 8; i++) fruitpics[i] = load_picture(fd) ;
X
X CLOSE(fd) ;
X
X if (!demomode) FPRINTF(stdout," File") ;
X
X if ((fn = fopen(m_name,"r")) == NULL)
X {
X FPRINTF(stderr,"\nsidtool: can't open %s\n",m_name) ;
X exit(-1) ;
X }
X
X for (y = 0; y <= YSIZE+1; y++)
X {
X FGETS(buffer,MAXLINE,fn) ;
X for (x = 0; x <= XSIZE+1; x++) maze[x][y] = buffer[x] ;
X }
X FCLOSE(fn) ;
X
X if (!demomode) FPRINTF(stdout," Maze") ;
X
X TRANSPT(FRUITMX,FRUITMY,fruitx,fruity) ;
X readallhighscores() ;
X highscore = allhighscores[skilllevel].score ;
X if (!demomode) FPRINTF(stdout," HighScore") ;
X
X g = POKEY ;
X for (y = 1; y <= YSIZE; y++)
X for (x = 1; x <= XSIZE; x++)
X if ((maze[x][y] >= '0') && (maze[x][y] <= '9'))
X {
X startpos[g].x = x ;
X startpos[g].y = y ;
X startpos[g].time = maze[x][y] - '0' ;
X if (g < SHADOW) g++ ;
X if (maze[x][y] == '0')
X {
X boxx = x ;
X boxy = y ;
X }
X }
X
X if (!demomode) FPRINTF(stdout," Starting\n") ;
X for (x = 0; x < XSIZE+3; x++)
X for (y = 0; y < YSIZE; y++) tunnel[x][y] = 0 ;
X}
X
X
Xmake_button(x,y,but_name)
Xint x,y ;
Xchar but_name[MAXLINE] ;
X
X{
X int len ;
X
X len = strlen(but_name) * 10 ;
X BLT_MEM_TO_SCRN(x,y,SQUARE,SQUARE,RRPL,corner[UR],0,0) ;
X BLT_MEM_TO_SCRN(x,y+SQUARE,SQUARE,SQUARE,RRPL,corner[LU],0,0) ;
X
X BLT_SCRN(x+SQUARE,y+SQUARE/2,len,2,RSET) ;
X BLT_SCRN(x+SQUARE,y+SQUARE*3/2,len,2,RSET) ;
X
X BLT_MEM_TO_SCRN(x+len,y,SQUARE,SQUARE,RRPL,corner[RD],0,0) ;
X BLT_MEM_TO_SCRN(x+len,y+SQUARE,SQUARE,SQUARE,RRPL,corner[DL],0,0) ;
X write_bold(x+SQUARE-5,y+SQUARE*3/2-10,but_name) ;
X}
X
X
Xmake_control_panel()
X
X{
X int i ;
X
X BLT_SCRN(0,0,width,YBASE-20,RCLR) ; /* Clear panel area. */
X for (i = BUT_AUTO; i <= BUT_START; i++)
X make_button(100*i+BUTXOFF,BUTYOFF,but_names[i]) ; /* Make option buttons. */
X}
X
X
Xremovecircle()
X
X{
X BLT_MEM_TO_SCRN(30+(numcir[player]-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ;
X}
X
X
Xresetmaze()
X
X{
X int i,j ;
X
X erasebugs() ;
X LONGPAUSE() ;
X for (i = 1; i <= 20; i++)
X {
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X for (j = 0; j < 10; j++) LONGPAUSE() ;
X }
X LONGPAUSE() ;
X if (fruitmaze[player] < 8) fruitmaze[player]++ ;
X fruitchances[player] = 0 ;
X setdots(player) ;
X drawmaze() ;
X if (curbluetime[player] > 1) curbluetime[player] -= 60 ;
X}
X
X
Xupdatefruit()
X
X{
X Pixrect *p ;
X
X p = fruitpics[fruitmaze[player]] ;
X BLT_MEM_TO_SCRN(fruitx-GOFFSET,fruity-GOFFSET,45,45,RXOR,p,0,0) ;
X if (fruiton) /* Turning fruit off. */
X {
X fruitchances[player]++ ;
X if (fruitchances[player] > 2) fruittime = -1 ; /* Already had 2 chances. */
X else fruittime = randomrange(1000,2500) ;
X }
X else fruittime = randomrange(500,1000) ; /* Turning fruit on. */
X fruiton = !fruiton ;
X}
X
X
Xupdatescore(amt)
Xint amt ;
X
X{
X int i,temp,x,y ;
X
X if (autoplay)
X if (!demomode)
X {
X autoscore += amt ;
X SPRINTF(buffer,"%1d0",autoscore) ;
X WRITELN(489,65,buffer) ;
X return ;
X }
X temp = score[player] + amt ;
X if (temp >= 1000)
X if (score[player] < 1000)
X {
X for (i = 1; i < 7; i++)
X {
X BLT_MEM_TO_SCRN(oldcx-GOFFSET+5,oldcy-GOFFSET+5,45,45,RXOR,curcircle,0,0) ;
X for (i = 0; i < 10; i++) LONGPAUSE() ;
X }
X numcir[player]++ ;
X BLT_MEM_TO_SCRN(30+(numcir[player]-1)*60,20,50,50,RXOR,circles[RIGHT][0],0,0) ;
X }
X score[player] = temp ;
X x = (player % 2) ? 217 : 597 ;
X y = (player < 3) ? 40 : 80 ;
X SPRINTF(buffer,"%1d0",score[player]) ;
X WRITELN(x,y,buffer) ;
X if (score[player] > highscore)
X {
X highplayer = player ;
X highscore = score[player] ;
X SPRINTF(buffer,"%1d0",highscore) ;
X WRITELN(348,35,buffer) ;
X }
X}
END_OF_sid_blt.c
if test 21194 -ne `wc -c <sid_blt.c`; then
echo shar: \"sid_blt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f sid_stuff.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"sid_stuff.c\"
else
echo shar: Extracting \"sid_stuff.c\" \(13593 characters\)
sed "s/^X//" >sid_stuff.c <<'END_OF_sid_stuff.c'
X
X/* sid_stuff.c
X *
X * Various functions and procedures used by Sid Tool.
X *
X * Written by Rich Burridge - SUN Microsystems Australia (Melbourne).
X *
X * Version 2.1. - April 1987.
X *
X * No responsibility is taken for any errors inherent either to the code
X * or the comments of this program, but if reported to me then an attempt
X * will be made to fix them.
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <setjmp.h>
X#include "bltstuff.h"
X#include "sidtool.h"
X#include <suntool/sunview.h>
X#include <suntool/canvas.h>
X
Xextern Pixfont *pf ;
Xextern Pixrect *circles[4][4] ;
Xextern Pixwin *pw ;
X
Xextern jmp_buf exception ;
Xextern int val ;
X
Xextern long random() ;
Xextern char *getenv() ;
X
X/* For descriptions of these external variables, see sid_main.c */
X
Xextern BOOLEAN autoplay,changed,demomode,gamestate,remove ;
X
Xextern char a_name[MAXLINE],buffer[MAXLINE],h_name[MAXLINE] ;
Xextern char m_name[MAXLINE], new_key_vals[9][MAXLINE] ;
Xextern char old_key_vals[9][MAXLINE],s_name[MAXLINE],titlestring[MAXLINE] ;
X
Xextern int blueblink,blueincblink,button,c,cirx,ciry,credits ;
Xextern int curbluetime[MAXNUMPLAYERS+1],curdir,dotx,doty ;
Xextern int fruitmaze[MAXNUMPLAYERS+1],fruiton,fruitsgotten[MAXNUMPLAYERS+1][9] ;
Xextern int fruitx,fruity,bugssincedot,height,highscore,inc,key_stations[9] ;
Xextern int lastnumplayers,numcir[MAXNUMPLAYERS+1],numplayers ;
Xextern int orgx,orgy,player,posx,posy,progstate,redraw,sfunc,skilllevel,speed ;
Xextern int started,walls[XSIZE+6][YSIZE+1],width ;
X
Xextern struct bugrec bugs[4] ;
Xextern struct scorerec allhighscores[11] ;
Xextern struct startrec startpos[4] ;
X
X
Xchangebugs()
X
X{
X register struct bugrec *p ;
X
X bugssincedot = 0 ;
X for (p = &bugs[POKEY]; p <= &bugs[SHADOW]; p++)
X if (!p->eyesonly)
X {
X drawbug(p) ;
X p->bluetime = curbluetime[player] ;
X if ((!p->boxtime) && (!p->inbox))
X p->dir = REVERSEDIR(p->dir) ;
X drawbug(p) ; /* Will be blue now. */
X }
X}
X
X
Xchangeplayers(startgame)
Xint startgame ;
X
X{
X int cnt,i ;
X
X if (numplayers == 1)
X {
X if (fruiton) updatefruit() ;
X gamestate = TRUE ;
X progstate = RESETGAME ;
X longjmp(exception,val) ;
X }
X cnt = 0 ;
X do
X {
X cnt++ ;
X player = 1 + (player % numplayers) ;
X if (cnt > 5) /* Game all over. */
X {
X progstate = DOLEAVE ;
X longjmp(exception,val) ;
X }
X }
X while (!numcir[player]) ;
X clear_screen() ;
X SPRINTF(buffer,"Player %1d",player) ;
X write_bold(348,500,buffer) ;
X for (i = 0; i < 100; i++) LONGPAUSE() ;
X drawmaze() ;
X blinkpause() ;
X if (!startgame)
X {
X gamestate = TRUE ;
X progstate = RESETGAME ;
X longjmp(exception,val) ;
X }
X}
X
X
Xcheckcollision(nx,ny,g)
Xregister int nx,ny ;
Xint *g ;
X
X{
X register struct bugrec *tg ;
X
X for (tg = &bugs[POKEY]; tg <= &bugs[SHADOW]; tg++)
X if (tg->mx == nx)
X if (tg->my == ny)
X if (!tg->eyesonly)
X {
X *g = GIND(tg) ;
X return(1) ;
X }
X return(0) ;
X}
X
X
Xcheckinc(dir,mx,my)
Xint dir,mx,my ;
X
X{
X switch (dir)
X {
X case UP : return(!walls[mx+2][my-1]) ;
X case RIGHT : return(!walls[mx+3][my]) ;
X case DOWN : return(!walls[mx+2][my+1]) ;
X case LEFT : return(!walls[mx+1][my]) ;
X }
X return(0) ;
X}
X
X
Xdestroyblue(g)
Xregister struct bugrec *g ;
X
X{
X int i,inc,x ;
X
X drawbug(g) ; /* Turn off. */
X g->eyesonly = 1 ;
X g->bluetime = 0 ;
X inc = 20 ;
X for (i = 1; i <= bugssincedot; i++) inc *= 2 ;
X bugssincedot++ ;
X x = g->scrx + 10 ;
X if (x > 740) x = 740 ;
X else if (x < 5) x = 5 ;
X SCHRFUNC(RXOR) ;
X SPRINTF(buffer,"%1d0",inc) ;
X WRITELN(x,g->scry+10,buffer) ;
X for (i = 0; i < 10; i++) LONGPAUSE() ;
X SPRINTF(buffer,"%1d0",inc) ;
X WRITELN(x,g->scry+10,buffer) ;
X SCHRFUNC(RRPL) ;
X drawbug(g) ; /* Turn on as eyesonly. */
X updatescore(inc) ;
X}
X
X
Xdestroyfruit()
X
X{
X int i,inc ;
X
X fruitsgotten[player][fruitmaze[player]]++ ;
X updatefruit() ; /* Turn fruit off. */
X inc = fruitscore(fruitmaze[player]) ;
X updatescore(inc) ;
X SCHRFUNC(RXOR) ;
X SPRINTF(buffer,"%1d0",inc) ;
X WRITELN(fruitx+10,fruity+10,buffer) ;
X for (i = 0; i < 10; i++) LONGPAUSE() ;
X SPRINTF(buffer,"%1d0",inc) ;
X WRITELN(fruitx+10,fruity+10,buffer) ;
X SCHRFUNC(RRPL) ;
X}
X
X
Xdisplay_settings() /* Display current skill level and number of players. */
X
X{
X int x,y ;
X char buffer[MAXLINE] ;
X
X x = 50 ;
X y = 70 ;
X write_bold(x,y,"Current skill level:") ;
X SPRINTF(buffer,"%1d ",skilllevel) ;
X WRITELN(x+190,y,buffer) ;
X
X x = 430 ;
X write_bold(x,y,"Number of players:") ;
X SPRINTF(buffer,"%1d ",numplayers) ;
X WRITELN(x+180,y,buffer) ;
X}
X
X
Xdohighscores() /* Display high scores on the screen. */
X
X{
X char skillc ;
X int level ;
X
X clear_screen() ;
X write_bold(334,200,"High Scores") ;
X SCHRFUNC(ROR) ;
X WRITELN(334,201,"___________") ;
X WRITELN(200,300,"Skill level Score Who") ;
X WRITELN(200,301,"___________ _____ ___");
X SCHRFUNC(RRPL) ;
X for (level = 1; level <= 10; level++)
X {
X skillc = (level == skilllevel) ? '*' : ' ' ;
X if (allhighscores[level].score)
X SPRINTF(buffer,"%c %2d = %5d0 %s",
X skillc,level,allhighscores[level].score,allhighscores[level].who) ;
X else
X SPRINTF(buffer,"%c %2d = - %s",
X skillc,level,allhighscores[level].who) ;
X WRITELN(200,330+level*30,buffer) ;
X }
X if (!autoplay) make_control_panel() ;
X if (!autoplay) display_settings() ;
X}
X
X
Xmake_selection() /* Get user selection after DEL press. */
X
X{
X switch (button)
X {
X case BUT_AUTO : numplayers = 1 ;
X autoplay = TRUE ;
X started = TRUE ;
X iocursormode(OFFCURSOR) ;
X break ;
X case BUT_HELP : clear_screen() ;
X dohelp() ;
X break ;
X case BUT_LEVEL : skilllevel = skilllevel % 10 + 1 ;
X display_settings() ;
X highscore = allhighscores[skilllevel].score ;
X break ;
X case BUT_PLAYERS : numplayers = numplayers % 4 + 1 ;
X display_settings() ;
X break ;
X case BUT_QUIT : exit(0) ;
X case BUT_SCORES : dohighscores() ;
X break ;
X case BUT_START : autoplay = FALSE ;
X started = TRUE ;
X iocursormode(OFFCURSOR) ;
X lastnumplayers = numplayers ;
X }
X if (button == BUT_AUTO || button == BUT_START) progstate = INITGAME ;
X else progstate = GETBUT ;
X}
X
X
Xrestore_screen() /* Called when window needs to be drawn. */
X
X{
X int g ;
X
X if (!redraw++) return ;
X clear_screen() ;
X if (!started)
X {
X iocursormode(TRACKCURSOR) ;
X make_control_panel() ;
X display_settings() ;
X dohelp() ;
X }
X else if (credits)
X {
X dohelp() ;
X BLT_SCRN(3,ciry-37,762,100,RSET) ;
X if (credits == 1)
X {
X drawdot(dotx,doty,BIGDOT) ;
X drawcir(circles[LEFT][inc],cirx,ciry) ;
X }
X else drawcir(circles[RIGHT][inc],cirx,ciry) ;
X for (g = POKEY; g <= SHADOW; g++)
X if (!bugs[g].eyesonly) drawbug(&bugs[g]) ;
X }
X else
X {
X iocursormode(OFFCURSOR) ;
X drawmaze() ;
X for (g = POKEY; g <= SHADOW; g++) drawbug(&bugs[g]) ;
X drawcir(circles[curdir][inc],posx,posy) ;
X }
X}
X
X
Xerasebugs() /* Erase all bugs from the screen. */
X
X{
X int g ;
X
X for (g = POKEY; g <= SHADOW; g++)
X drawbug(&bugs[g]) ; /* Erase all bugs. */
X}
X
X
Xfruitscore(fruit) /* Returns the score for the fruit specified. */
Xint fruit ;
X
X{
X switch (fruit)
X {
X case 1 : return(10) ;
X case 2 : return(30) ;
X case 3 : return(50) ;
X case 4 : return(70) ;
X case 5 : return(100) ;
X case 6 : return(200) ;
X case 7 : return(300) ;
X case 8 : return(500) ;
X }
X return(0) ;
X}
X
X
Xgeths(fd,record) /* Get one high score record in. */
Xstruct scorerec *record ;
Xint fd ;
X
X{
X char buffer[32],valuestr[7] ;
X int i ;
X
X i = read(fd,buffer,23) ;
X for (i = 0; i < 16; i++) record->who[i] = buffer[i] ^ ENKEY ;
X record->who[i] = '\0' ;
X for (i = 0; i < 7; i++) valuestr[i] = buffer[i+16] ^ ENKEY ;
X record->score = atoi(valuestr) ;
X}
X
X
Xget_options(argc,argv)
Xint argc ;
Xchar *argv[] ;
X
X{
X char *arg,*env ;
X char *p ; /* Pointer to string following argument flag. */
X
X orgx = 0 ; /* X origin of SUN SID window. */
X orgy = 0 ; /* Y origin of SUN SID window. */
X width = SWIDTH ; /* Width of SUN SID window. */
X height = SHEIGHT ; /* Height of SUN SID window. */
X speed = SPEED ; /* Default speed of Sun machine that this game is on.*/
X STRCPY(titlestring,"sidtool - Sun Interactive Debugger V2.1. Rich Burridge") ;
X STRCPY(m_name,M_NAME) ; /* Default sidtool maze filename. */
X STRCPY(a_name,A_NAME) ; /* Default sidtool animate filename. */
X STRCPY(s_name,S_NAME) ; /* Default sidtool highscore filename. */
X STRCPY(h_name,H_NAME) ; /* Default sidtool help filename. */
X demomode = FALSE ;
X
X if ((env = getenv("SID_MAZE")) != NULL) STRCPY(m_name,env) ;
X if ((env = getenv("SID_ANIMATE")) != NULL) STRCPY(a_name,env) ;
X if ((env = getenv("SID_SCORE")) != NULL) STRCPY(s_name,env) ;
X if ((env = getenv("SID_HELP")) != NULL) STRCPY(h_name,env) ;
X
X while (argc > 1 && (arg = argv[1])[0] == '-')
X {
X p = arg + 2 ;
X switch (arg[1])
X {
X case 'a' : STRCPY(a_name,p) ; /* New animate filename. */
X break ;
X case 'c' : speed = atoi(p) ; /* New class (speed) of machine. */
X break ;
X case 'd' : demomode = TRUE ; /* Run in self demonstration mode. */
X break ;
X case 'h' : STRCPY(h_name,p) ; /* New help filename. */
X break ;
X case 'm' : STRCPY(m_name,p) ; /* New maze filename. */
X break ;
X case 's' : STRCPY(s_name,p) ; /* New high score filename. */
X }
X argc-- ;
X argv++ ;
X }
X}
X
X
Xget_string(fd,s) /* Get next line from specified file. */
XFILE *fd ;
Xchar s[MAXLINE] ;
X
X{
X int c,i ;
X
X i = 0 ;
X while (i < MAXLINE-1 && (c = getc(fd)) != EOF && c != '\n')
X if (c != '\0') s[i++] = c ;
X
X if (c == EOF) return(-1) ;
X s[i] = '\0' ;
X return(i) ;
X}
X
X
Xhandlecollision(g)
Xregister struct bugrec *g ;
X
X{
X int i ;
X struct bugrec *tg ;
X
X if (g->bluetime > 0) destroyblue(g) ;
X else
X {
X drawbug(g) ; /* Erase one that ate screen. */
X explodecircle(posx,posy) ;
X for (tg = &bugs[POKEY]; tg <= &bugs[SHADOW]; tg++)
X if (tg != g) drawbug(tg) ;
X if (autoplay)
X {
X progstate = DOLEAVE ;
X longjmp(exception,val) ;
X }
X else if (!numcir[player])
X {
X SCHRFUNC(RXOR) ;
X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ;
X for (i = 0; i < 80; i++) LONGPAUSE() ;
X WRITELN(339,YBASE+SQUARE*16,"GAME OVER!") ;
X SCHRFUNC(RRPL) ;
X if (numplayers == 1)
X {
X progstate = DOLEAVE ;
X longjmp(exception,val) ;
X }
X }
X else for (i = 0; i < 50; i++) LONGPAUSE() ;
X changeplayers(0) ;
X }
X}
X
X
Xnewbugs(drawthem)
Xint drawthem ;
X
X{
X register struct bugrec *p ;
X
X for (p = &bugs[POKEY]; p <= &bugs[SHADOW]; p++)
X {
X p->dir = UP ;
X p->mx = startpos[GIND(p)].x ;
X p->my = startpos[GIND(p)].y ;
X TRANSPT(p->mx,p->my,p->scrx,p->scry) ;
X p->bluetime = 0 ;
X p->eyesonly = 0 ;
X p->boxtime = ((-2*skilllevel+25) / 5) * startpos[GIND(p)].time ;
X if (!p->boxtime) p->inbox = 0 ;
X else p->inbox = 1 ;
X p->enteringbox = 0 ;
X p->count = 0 ;
X p->delay = 5 ;
X p->pic = GIND(p) % 2 ;
X p->intunnel = 0 ;
X if (drawthem) drawbug(p) ;
X }
X}
X
X
Xplay() /* Initialise for next player to play. */
X
X{
X fruiton = 0 ;
X blueblink = 200 ;
X blueincblink = 25 ;
X if (numplayers == 1)
X {
X player = 1 ;
X drawmaze() ;
X blinkpause() ;
X }
X else
X {
X player = numplayers ;
X changeplayers(1) ;
X }
X remove = TRUE ;
X}
X
X
Xpuths(fd,record) /* Put one high score record out. */
Xstruct scorerec record ;
Xint fd ;
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(fd,buffer,23) ;
X}
X
X
Xrandomrange(low,high) /* Return a random number between low and high. */
Xint low,high ;
X
X{
X return((((int) random() & 077777) % (high-low+1)) + low) ;
X}
X
X
Xfunction_keys(state) /* Set or reset the function keys. */
Xint state ;
X
X{
X int count = 176 ; /* 0xB0 -- the starting entry for strings. */
X int fd,i ;
X
X if ((fd = open("/dev/kbd",0,0)) < 0)
X {
X FPRINTF(stderr,"sidtool: can't open /dev/kbd\n") ;
X exit(1) ;
X }
X for (i = 0; i < 9; i++) /* Set up function keys R7-R15, saving old values. */
X {
X if (state == KEY_SET) get_key(fd,key_stations[i],old_key_vals[i],count) ;
X set_key(fd,key_stations[i],new_key_vals[i],count++) ;
X }
X CLOSE(fd) ;
X}
END_OF_sid_stuff.c
if test 13593 -ne `wc -c <sid_stuff.c`; then
echo shar: \"sid_stuff.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
D
D
D
0 new messages