ri...@sunk.uucp
unread,Apr 12, 1987, 2:12:51 AM4/12/87You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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