page%rishathra@Sun.COM (Bob Page) (04/26/89)
Submitted-by: mab@druwy.att.com (Alan Bland)
Posting-number: Volume 89, Issue 95
Archive-name: fun/wand22.2
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# ami-pw.menus.h
# ami-pw.palette.h
# ami-sounds.c
# ami-sounds.h
# display.c
# edit.c
# encrypt.c
# fall.c
# game.c
# This is archive 2 of a 3-part kit.
# This archive created: Tue Apr 25 00:28:06 1989
echo "extracting ami-pw.menus.h"
sed 's/^X//' << \SHAR_EOF > ami-pw.menus.h
X
Xstruct IntuiText IText1 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Instructions HELP",
X NULL
X};
X
Xstruct MenuItem MenuItem5 = {
X NULL,
X 0,36,
X 192,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText1,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText2 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Show map F10",
X NULL
X};
X
Xstruct MenuItem MenuItem4 = {
X &MenuItem5,
X 0,27,
X 192,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText2,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText3 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Move to center F3",
X NULL
X};
X
Xstruct MenuItem MenuItem3 = {
X &MenuItem4,
X 0,18,
X 192,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText3,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText4 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Toggle map mode F2",
X NULL
X};
X
Xstruct MenuItem MenuItem2 = {
X &MenuItem3,
X 0,9,
X 192,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText4,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText5 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Jump to next level F1",
X NULL
X};
X
Xstruct MenuItem MenuItem1 = {
X &MenuItem2,
X 0,0,
X 192,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText5,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct Menu Menu2 = {
X NULL,
X 82,0,
X 66,0,
X MENUENABLED,
X "Wander",
X &MenuItem1
X};
X
Xstruct IntuiText IText6 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Quit Game q",
X NULL
X};
X
Xstruct MenuItem MenuItem11 = {
X NULL,
X 0,45,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText6,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText7 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Credits c",
X NULL
X};
X
Xstruct MenuItem MenuItem10 = {
X &MenuItem11,
X 0,36,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText7,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText8 = {
X 3,1,JAM1,
X 0,0,
X NULL,
X "",
X NULL
X};
X
Xstruct MenuItem SubItem6 = {
X NULL,
X 161,32,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText8,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText9 = {
X 9,1,JAM1,
X 0,0,
X NULL,
X "Edit an existing screen: wanderer -e screenfilename",
X NULL
X};
X
Xstruct MenuItem SubItem5 = {
X &SubItem6,
X 161,24,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText9,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText10 = {
X 9,1,JAM1,
X 0,0,
X NULL,
X " Create a new screen: wanderer -e",
X NULL
X};
X
Xstruct MenuItem SubItem4 = {
X &SubItem5,
X 161,16,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText10,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText11 = {
X 3,1,JAM1,
X 0,0,
X NULL,
X "",
X NULL
X};
X
Xstruct MenuItem SubItem3 = {
X &SubItem4,
X 161,8,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText11,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText12 = {
X 3,1,JAM1,
X 0,0,
X NULL,
X "from the CLI as follows:",
X NULL
X};
X
Xstruct MenuItem SubItem2 = {
X &SubItem3,
X 161,0,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText12,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText13 = {
X 3,1,JAM1,
X 0,0,
X NULL,
X "To edit a screen, exit the game and run wanderer",
X NULL
X};
X
Xstruct MenuItem SubItem1 = {
X &SubItem2,
X 161,-8,
X 416,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP+HIGHBOX,
X 0,
X (APTR)&IText13,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText14 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Edit Screen",
X NULL
X};
X
Xstruct MenuItem MenuItem9 = {
X &MenuItem10,
X 0,27,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText14,
X NULL,
X NULL,
X &SubItem1,
X MENUNULL
X};
X
Xstruct IntuiText IText15 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Restore Game F7",
X NULL
X};
X
Xstruct MenuItem MenuItem8 = {
X &MenuItem9,
X 0,18,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText15,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText16 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Save Game F6",
X NULL
X};
X
Xstruct MenuItem MenuItem7 = {
X &MenuItem8,
X 0,9,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText16,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct IntuiText IText17 = {
X 3,1,COMPLEMENT,
X 0,0,
X NULL,
X "Redraw Screen shift-W",
X NULL
X};
X
Xstruct MenuItem MenuItem6 = {
X &MenuItem7,
X 0,0,
X 176,8,
X ITEMTEXT+ITEMENABLED+HIGHCOMP,
X 0,
X (APTR)&IText17,
X NULL,
X NULL,
X NULL,
X MENUNULL
X};
X
Xstruct Menu Menu1 = {
X &Menu2,
X 0,0,
X 75,0,
X MENUENABLED,
X "Project",
X &MenuItem6
X};
X
X#define MenuList1 Menu1
SHAR_EOF
echo "extracting ami-pw.palette.h"
sed 's/^X//' << \SHAR_EOF > ami-pw.palette.h
X
XUSHORT Palette[] = {
X 0x0000, /* color #0 */
X 0x0ECA, /* color #1 */
X 0x0C00, /* color #2 */
X 0x0E22, /* color #3 */
X 0x0E77, /* color #4 */
X 0x0070, /* color #5 */
X 0x0090, /* color #6 */
X 0x00B0, /* color #7 */
X 0x0DC0, /* color #8 */
X 0x035F, /* color #9 */
X 0x07AF, /* color #10 */
X 0x0F60, /* color #11 */
X 0x0A60, /* color #12 */
X 0x0BBB, /* color #13 */
X 0x0888, /* color #14 */
X 0x0444 /* color #15 */
X#define PaletteColorCount 16
X};
X
X#define PALETTE Palette
SHAR_EOF
echo "extracting ami-sounds.c"
sed 's/^X//' << \SHAR_EOF > ami-sounds.c
X#ifdef AMIGA
X
X/**************************** Sound.c *********************************
X
X Sound is copyright (c) 1988 by Richard Lee Stockton, 21305 60th Ave W.,
XMountlake Terrace, Washington 98043, 206/776-1253(voice), but may be freely
Xdistributed as long as no profit is made from its distribution or sale
Xwithout my written permission. I call this concept 'FreeWare', you can
Xcall it whatcha want.
X
XHacked to death by Alan Bland, bears little resemblance to the original
Xsound.c.
X
X**************************************************************************/
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <libraries/dosextens.h>
X#include <devices/audio.h>
X#include <string.h>
X#include "sounds.h"
X
X/* We'll need 4 buffers in CHIP memory, all else in FAST, if ya got it */
X
X#define BUFSIZE 1024L
X
X/* This array defines all the possible sounds */
X
Xstruct SoundData {
X long sps;
X BOOL stereo;
X long sactual;
X char *sbuffer;
X} sdata[MAX_SOUNDS];
X
Xstruct IOAudio *sound[4]={NULL,NULL,NULL,NULL};
XUBYTE sunit[4]={12,10,5,3};
Xlong templength;
Xchar *tempbuffer=NULL, *cbuf[4]={NULL,NULL,NULL,NULL};
X
X/*********** quit, give-up, go home, finish... Neatness counts! ******/
X
Xvoid freeSounds(string)
Xchar *string;
X{
X short k;
X
X if(sound[0]) /* This cleans up the audio device stuff */
X {
X for(k=3;k>(-1);k--) if(sound[k]) AbortIO(sound[k]);
X if(sound[0]->ioa_Request.io_Device) CloseDevice(sound[0]);
X for(k=3;k>(-1);k--)
X {
X if(sound[k]->ioa_Request.io_Message.mn_ReplyPort)
X DeletePort(sound[k]->ioa_Request.io_Message.mn_ReplyPort);
X }
X for(k=3;k>(-1);k--)
X {
X if(sound[k]) FreeMem(sound[k],(long)sizeof(struct IOAudio));
X if(cbuf[k]) FreeMem(cbuf[k],BUFSIZE);
X }
X sound[0]=NULL;
X }
X
X if (string != NULL)
X {
X fatal(string);
X }
X
X/* Get rid of all the sound data */
X for(k=0; k<MAX_SOUNDS; k++)
X {
X if (sdata[k].sbuffer)
X FreeMem(sdata[k].sbuffer, sdata[k].sactual);
X }
X
X/* Clean up everything else */
X
X if(tempbuffer) FreeMem(tempbuffer,templength);
X
X/* and return, caller will exit */
X}
X
X
X/* Don't Allocate if Low Mem - by Bryce Nesbitt */
X/* Aberations by RLS. 4096 should be fudge enough */
X
Xchar *SafeAllocMem(size,flags)
Xlong size, flags;
X{
X register char *p;
X
X if(p=(char *)AllocMem(size,flags))
X if(AvailMem(MEMF_CHIP)<4096L)
X { FreeMem(p,size); return(NULL); }
X return(p);
X}
X
X
X/******** Load SoundFile 'sPath' ********/
X
Xvoid loadSound(sPath, sd)
Xchar *sPath;
Xstruct SoundData *sd;
X{
X struct FileHandle *sFile=NULL;
X struct FileInfoBlock *finfo=NULL;
X struct FileLock *lock=NULL;
X long i, j, sstart;
X char string[5];
X
X/* Set defaults if not found in IFF file */
X sd->stereo = FALSE;
X sd->sactual = 0L;
X
X/* Allocate 256 bytes as work memory */
X
X if(!(tempbuffer=SafeAllocMem(256L,MEMF_CLEAR|MEMF_PUBLIC)))
X freeSounds("No Work Memory!");
X
X/* Check for and parse IFF data in first 256 bytes of file */
X
X if(!(sFile=(struct FileHandle *)Open(sPath,MODE_OLDFILE)))
X {
X/*
X char errmsg[80];
X templength=256L;
X strcpy(errmsg, "Can't open ");
X strcat(errmsg, sPath);
X freeSounds(errmsg);
X*/
X /* ignore if sound file not found */
X sd->sbuffer = NULL;
X FreeMem(tempbuffer,256L); tempbuffer=NULL;
X return;
X }
X Read(sFile,tempbuffer,256L); /* load the 1st 256 bytes */
X for(sstart=0L, sd->sps=0L, i=0L; i<252L; i+=4L)
X {
X strncpy(string,tempbuffer+i,4); string[4]=NULL;
X if(!(strcmp(string,"VHDR"))) /* get samples per second */
X {
X for(j=0;j<(long)((UBYTE)tempbuffer[i+20]);j++) sd->sps+=256L;
X sd->sps += ((UBYTE)tempbuffer[i+21L]);
X }
X if(!(strcmp(string,"CHAN"))) /* Channel Assignment */
X {
X if((tempbuffer[i+7]==6)||(tempbuffer[i+11]==6)) sd->stereo=TRUE;
X }
X if(!(strcmp(string,"BODY"))) /* get size of sound data */
X {
X for(j=0;j<4;j++) sd->sactual+=(((UBYTE)tempbuffer[i+7L-j])<<(8*j));
X sstart = i+8L; i=252L;
X }
X }
X
X/* if not in IFF format, get filesize from FileInfoBlock */
X
X if(!sd->sactual)
X {
X
X/* Allocate a file info block, get size from it, and de-allocate */
X
X if((!(finfo=(struct FileInfoBlock *)
X SafeAllocMem((long)sizeof(struct FileInfoBlock),MEMF_CLEAR)))
X ||(!(lock=(struct FileLock *)Lock(sPath,ACCESS_READ)))||(!(Examine(lock,finfo))) )
X freeSounds("FileInfoBlock Problem!");
X sd->sactual = finfo->fib_Size; if(lock) UnLock(lock);
X if(finfo) FreeMem(finfo,(long)sizeof(struct FileInfoBlock));
X
X/* default for non-IFF sample */
X sd->sps = 20000L;
X }
X
X/* clean up work area */
X
X FreeMem(tempbuffer,256L); tempbuffer=NULL;
X
X/* Allocate _contiguous_ memory for SOUND data. */
X/* We'll transfer in BUFSIZE chunks to CHIP memory a little later. */
X/* We have to do the contiguity(?) check since AllocMem() does not. */
X
X if((AvailMem(MEMF_LARGEST) < sd->sactual) ||
X (!(sd->sbuffer=SafeAllocMem(sd->sactual,MEMF_CLEAR|MEMF_PUBLIC))))
X { Close(sFile); freeSounds("Need Contiguous Memory!"); }
X
X/* Load the data into sbuffer */
X
X Seek(sFile,sstart,OFFSET_BEGINNING);
X if((Read(sFile,sd->sbuffer,sd->sactual)) == -1L)
X { Close(sFile); freeSounds("Read Error!");}
X Close(sFile);
X}
X
Xvoid initSoundMem()
X{
X short k;
X
X/* Allocate sound data buffers from CHIP memory. Ports and */
X/* Audio Request Structures do NOT require CHIP memory */
X
X for(k=0;k<4;k++)
X {
X if(!(cbuf[k]=SafeAllocMem(BUFSIZE,
X MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))) freeSounds("No CHIP Memory!");
X if(!(sound[k]=(struct IOAudio *)SafeAllocMem((long)sizeof(struct IOAudio),
X MEMF_CLEAR|MEMF_PUBLIC))) freeSounds("No IOA Memory!");
X }
X if( (!(sound[0]->ioa_Request.io_Message.mn_ReplyPort =
X (struct MsgPort *) CreatePort("Sound0",0L))) ||
X (!(sound[1]->ioa_Request.io_Message.mn_ReplyPort =
X (struct MsgPort *) CreatePort("Sound1",0L))) ||
X (!(sound[2]->ioa_Request.io_Message.mn_ReplyPort =
X (struct MsgPort *) CreatePort("Sound2",0L))) ||
X (!(sound[3]->ioa_Request.io_Message.mn_ReplyPort =
X (struct MsgPort *) CreatePort("Sound3",0L))) )
X freeSounds("No Port Memory!");
X
X
X/* Open Audio using the first IOAudio as the 'initializer' request */
X
X sound[0]->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
X sound[0]->ioa_Data = &sunit[0];
X sound[0]->ioa_Length = 4L;
X if((OpenDevice(AUDIONAME,0L,sound[0],0L))!=NULL)
X freeSounds("No Audio Device!");
X
X/* Set all IOAudios. */
X
X for(k=0;k<4;k++)
X {
X sound[k]->ioa_Request.io_Message.mn_Node.ln_Pri = 20;
X sound[k]->ioa_Request.io_Command = CMD_WRITE;
X sound[k]->ioa_Request.io_Flags = ADIOF_PERVOL;
X
X/* Note copies of Device & AllocKey from initializer. */
X
X sound[k]->ioa_Request.io_Device = sound[0]->ioa_Request.io_Device;
X sound[k]->ioa_AllocKey = sound[0]->ioa_AllocKey;
X
X/* Each IOAudio has its own CHIP buffer, Port, and Unit (left/right) */
X
X sound[k]->ioa_Data = (UBYTE *)cbuf[k];
X
X/* One time through this BUFSIZE (or smaller) part of the whole */
X
X sound[k]->ioa_Cycles = 1L;
X }
X
X/* The compiler wants 'Unit' to be a structure, we just want to mask */
X/* into the allocated left/right channels. left=1 or 8, right=2 or 4 */
X/* ...zap! You're a Unit structure! Feel any different? */
X
X for(k=2;k>(-1);k-=2)
X {
X sound[k+1]->ioa_Request.io_Unit = (struct Unit *)
X ((ULONG)(sound[0]->ioa_Request.io_Unit)&6L);
X sound[k]->ioa_Request.io_Unit = (struct Unit *)
X ((ULONG)(sound[0]->ioa_Request.io_Unit)&9L);
X }
X
X}
X
X/***************** make a noise ******************/
X
Xvoid playSound(snum)
Xint snum;
X{
X LONG dactual, dlength, remaining;
X USHORT count;
X short k;
X long cycles = 1;
X
X/* don't do sound if not loaded */
X if (sdata[snum].sbuffer == NULL) return;
X
X for (k=0; k<4; k++)
X {
X
X/* 3579547 divided by 55 = 65083, nearly the maximum Period (65535) */
X
X sound[k]->ioa_Period = 3579547L/sdata[snum].sps;
X
X/* As LOUD as possible. Use your monitor/stereo volume. Rock 'n Roll! */
X
X sound[k]->ioa_Volume = 64L;
X }
X
X/* If in STEREO, split file. If in MONO, 'b' buffers use 'a' data */
X
X if(sdata[snum].stereo) remaining=(sdata[snum].sactual/2L)-(sdata[snum].sactual&1L);
X else
X {
X remaining=sdata[snum].sactual;
X sound[1]->ioa_Data = (UBYTE *)cbuf[0];
X sound[3]->ioa_Data = (UBYTE *)cbuf[2];
X }
X
X/* dactual is the length of one channel's complete data */
X
X dactual=remaining; k=count=0;
X
X/* we be doing loops here */
X
X do
X {
X
X/* be CERTAIN ioa_Length is an even number & set datalength */
X
X if(remaining>BUFSIZE) dlength=BUFSIZE;
X else { dlength=remaining; dlength-=(dlength&1L); }
X
X/* Move the data into the proper CHIP buffer of BUFSIZE */
X
X movmem(sdata[snum].sbuffer+(dactual-remaining),cbuf[k],(int)dlength);
X
X/* Don't load or use the right CHIP buffers if MONO. Saves time. */
X
X if(sdata[snum].stereo) movmem(sdata[snum].sbuffer+(sdata[snum].sactual-remaining),
X cbuf[k+1],(int)dlength);
X
X/* Data has been moved, so adjust 'remaining' */
X
X remaining-=dlength;
X
X/* Left and Right Lengths are the same, no matter what! */
X
X sound[k]->ioa_Length = sound[k+1]->ioa_Length = dlength;
X
X/* Start one set of Left/Right Channels. */
X BeginIO(sound[k]); BeginIO(sound[k+1]);
X
X/* Is this the last time AND the last cycle? If yes & no, reset. */
X
X if(remaining<2L) if(--cycles!=0L)
X { remaining=dactual; dlength=BUFSIZE; }
X
X/* Is this the last time, or what? */
X
X if(remaining<2L) WaitIO(sound[k+1]); /* wait for LAST request */
X else
X {
X if(k) k=0; else k=2; /* switch buffers & wait for PREVIOUS */
X if(count++) WaitIO(sound[k+1]);
X }
X
X/* Keep going until we run out of data */
X
X } while(remaining>1L); /* End of Loop */
X}
X
X/******** initialize everything ********/
X
Xvoid initSounds()
X{
X
X/* Load 'em up! */
X
X loadSound("sounds/death", &sdata[DEATH_SOUND]);
X loadSound("sounds/arrow", &sdata[ARROW_SOUND]);
X loadSound("sounds/boulder", &sdata[BOULDER_SOUND]);
X loadSound("sounds/clock", &sdata[CLOCK_SOUND]);
X loadSound("sounds/diamond", &sdata[DIAMOND_SOUND]);
X loadSound("sounds/deadmonster", &sdata[DEADMONSTER_SOUND]);
X loadSound("sounds/kaboom", &sdata[KABOOM_SOUND]);
X loadSound("sounds/exit", &sdata[EXIT_SOUND]);
X loadSound("sounds/teleport",&sdata[TELEPORT_SOUND]);
X loadSound("sounds/munch", &sdata[MUNCH_SOUND]);
X loadSound("sounds/step", &sdata[STEP_SOUND]);
X loadSound("sounds/cage", &sdata[CAGE_SOUND]);
X loadSound("sounds/push", &sdata[PUSH_SOUND]);
X
X/* Setup chip buffers and I/O structures */
X
X initSoundMem();
X}
X
X#endif
SHAR_EOF
echo "extracting ami-sounds.h"
sed 's/^X//' << \SHAR_EOF > ami-sounds.h
X#ifdef AMIGA
X
X#define DEATH_SOUND 0
X#define ARROW_SOUND 1
X#define BOULDER_SOUND 2
X#define CLOCK_SOUND 3
X#define DIAMOND_SOUND 4
X#define DEADMONSTER_SOUND 5
X#define KABOOM_SOUND 6
X#define EXIT_SOUND 7
X#define TELEPORT_SOUND 8
X#define MUNCH_SOUND 9
X#define STEP_SOUND 10
X#define CAGE_SOUND 11
X#define PUSH_SOUND 12
X#define MAX_SOUNDS 13 /* one higher than last one */
X
X#endif
SHAR_EOF
echo "extracting display.c"
sed 's/^X//' << \SHAR_EOF > display.c
X#include "wand_head.h"
X
Xextern int debug_disp;
X
X/* This function is used to draw a symbol on the map, and when running
X * in full-screen display mode. Added by Alan Bland for the AMIGA to
X * allow the map characters to use a color graphics font.
X */
Xvoid draw_map_symbol(ch)
Xint ch;
X{
X#ifdef AMIGA
X int color;
X switch (ch)
X {
X case 'M': color = BLUE; break;
X case 'S': color = ORANGE; break;
X case ' ': color = DK_GREEN; break;
X case '#': color = DK_GRAY; break;
X case '<': color = ORANGE; break;
X case '>': color = ORANGE; break;
X case 'O': color = DK_GRAY; break;
X case ':': color = BROWN; break;
X case '/': color = BROWN; break;
X case '\\': color = BROWN; break;
X case '*': color = WHITE; break;
X case '=': color = DK_GRAY; break;
X case '@': color = RED; break;
X case 'T': color = YELLOW; break;
X case 'X': color = RED; break;
X case '!': color = BLACK; break;
X case 'C': color = LT_GRAY; break;
X case '+': color = LT_BLUE; break;
X case 'A': color = RED; break;
X case '^': color = ORANGE; break;
X default: ch='?';color = DK_GRAY; break;
X }
X set_map_font(1);
X setcolor(color, DK_GREEN);
X addch(ch);
X setcolor(TEXT_COLOR, BACK_COLOR);
X set_map_font(0);
X#else
X addch(ch);
X#endif
X}
X
X/* draw a box at the specified row,column,width,height */
Xvoid draw_box(r,c,w,h)
Xint r,c,w,h;
X{
X#ifdef AMIGA
X /* white rectangle with dark green interior */
X /* note: coordinates are text coords, must adjust for graphics */
X int x1=c*8+8;
X int y1=r*8+8;
X int x2=x1+(w-2)*8;
X int y2=y1+(h-2)*8;
X
X SetAPen(R, DK_GREEN);
X RectFill(R, x1, y1, x2, y2);
X SetAPen(R, WHITE);
X Move(R, x1-1, y1-1);
X Draw(R, x1-1, y2+1);
X Draw(R, x2+1, y2+1);
X Draw(R, x2+1, y1-1);
X Draw(R, x1-1, y1-1);
X
X SetAPen(R, TEXT_COLOR);
X#else
X char buf1[80], buf2[80];
X int x,y;
X buf1[0] = '+';
X buf2[0] = '|';
X for (x=1;x<w-1;++x) {
X buf1[x] = '-';
X buf2[x] = ' ';
X }
X buf1[x] = '+';
X buf2[x] = '|';
X buf1[x+1] = '\0';
X buf2[x+1] = '\0';
X
X move(r,c);
X addstr(buf1);
X for (y=1;y<h-1;++y) {
X move(r+y,c);
X addstr(buf2);
X }
X move(r+h-1,c);
X addstr(buf1);
X#endif
X}
X
Xvoid map(row_ptr)
Xchar (*row_ptr)[ROWLEN+1];
X{
Xint x,y;
Xint ch;
Xdraw_box(0,0,ROWLEN+2,NOOFROWS+2);
Xfor(y = 0;y < NOOFROWS; y++)
X {
X for(x = 0; x < ROWLEN; x++)
X {
X ch = (*row_ptr)[x];
X if(!debug_disp)
X {
X if((ch == 'M')||(ch == 'S'))
X ch = ' ';
X }
X else
X {
X if( !(ch==' '||ch=='#'||ch=='<'||ch=='>'||ch=='O'||ch==':'||
X ch=='/'||ch=='\\'||ch=='*'||ch=='='||ch=='@'||ch=='T'||
X ch=='X'||ch=='!'||ch=='M'||ch=='S'||ch=='C'||ch=='+'||
X ch=='A'||ch=='^') )
X ch = '"';
X }
X /* don't bother drawing spaces - speeds up non-smart curses */
X if (ch != ' ')
X {
X move(y+1,x+1);
X draw_map_symbol(ch);
X }
X }
X row_ptr++;
X }
Xif(!debug_disp)
X {
X move(18,0);
X addstr("Press any key to return to the game.");
X refresh();
X (void) getchar();
X for(y=0;y<=(NOOFROWS+2);y++)
X {
X move(y,0);
X addstr(" ");
X }
X }
Xelse
X refresh();
X}
X
X/* called by scroll() and display() to actually draw the game display */
Xvoid rdisplay(cx,cy,row_ptr,score)
Xchar (*row_ptr)[ROWLEN+1];
Xint cx,cy,score;
X{
X int x,y = 0,
X x_coord,y_coord;
X char ch;
X while(y<(cy-3))
X {
X y++;
X row_ptr++;
X };
X for(y=(cy-3);y<=(cy+3);y++)
X {
X y_coord = (y+3-cy)*2;
X if ((y<0) || (y>=NOOFROWS))
X {
X#ifdef AMIGA
X /* this makes sure graphics are done right */
X int i, ax;
X for (ax=0,i=0; i<11; ax+=3,++i)
X {
X draw_symbol(ax,y_coord,'#');
X }
X#else
X move(y_coord+1,1);
X addstr("#################################");
X move(y_coord+2,1);
X addstr("#################################");
X#endif
X }
X else
X {
X for(x=(cx-5);x<=(cx+5);x++)
X {
X x_coord = (x+5-cx)*3;
X if ((x<0) || (x>ROWLEN-1))
X draw_symbol(x_coord,y_coord,'#');
X else
X {
X ch = (*row_ptr)[x];
X draw_symbol(x_coord,y_coord,ch);
X }
X };
X row_ptr++;
X } /* end if */
X } /* end y loop */
X move(16,0);
X refresh();
X}
X
X/* draw the game display, doing intelligent scrolling if possible */
X/* actually, all this does is draw the display contents without */
X/* erasing the previous contents or redrawing the border */
X/* (looks better on machines that don't have intelligent curses) */
X/* should be possible to do nifty scrolling routines here at some point */
Xvoid scroll(cx,cy,row_ptr,score)
Xchar (*row_ptr)[ROWLEN+1];
Xint cx,cy,score;
X{
X /* assume border is there, just draw game display contents */
X rdisplay(cx,cy,row_ptr,score);
X}
X
X/* draw the game display, erasing the current contents first */
Xvoid display(cx,cy,row_ptr,score)
Xchar (*row_ptr)[ROWLEN+1];
Xint cx,cy,score;
X{
X /* draw the border and erase current contents of display region */
X draw_box(0,0,35,16);
X /* now do the actual display */
X rdisplay(cx,cy,row_ptr,score);
X}
X
Xvoid redraw_screen(maxmoves,num,score,nf,diamonds,mx,sx,sy,frow)
Xint maxmoves,num,score,nf,diamonds,mx,sx,sy;
Xchar **frow;
X{
Xchar buffer[50];
Xclear();
Xmove(0,48);
X(void) addstr("Score\t Diamonds");
Xmove(1,48);
X(void) addstr("\tFound\tTotal");
Xmove(3,48);
X(void) sprintf(buffer,"%d\t %d\t %d ",score,nf,diamonds);
X(void) addstr(buffer);
Xmove(6,48);
X(void) sprintf(buffer,"Current screen %d",num);
X(void) addstr(buffer);
Xif(maxmoves != 0)
X(void) sprintf(buffer,"Moves remaining = %d ",maxmoves);
Xelse
X{
X (void) strcpy(buffer," Unlimited moves ");
X maxmoves = -1;
X};
Xmove(15,48);
X(void) addstr(buffer);
Xshow_monster(mx != -1); /* tell player if monster exists */
X
Xif(!debug_disp)
X display(sx,sy,frow,score);
Xelse
X map(frow);
X}
SHAR_EOF
echo "extracting edit.c"
sed 's/^X//' << \SHAR_EOF > edit.c
X#include "wand_head.h"
X
Xextern char *playscreen();
X
Xextern int debug_disp;
Xextern char *edit_screen;
Xextern char screen[NOOFROWS][ROWLEN+1];
X
Xstatic char *inst[] = { "O Boulder",
X "< > Arrows",
X "^ Balloon",
X ": Earth",
X "! Landmine",
X "* Treasure",
X "/ \\ Deflectors",
X "+ Cage",
X "= # Rock",
X "T Teleport",
X "A Arrival (1 max)",
X "X Exit (always 1)",
X "@ Start (always 1)",
X "M Big Monster (1 max)",
X "S Baby Monster",
X "- Alternative space",
X "C Time Capsule",
X NULL };
X/* Print instructions around the screen */
Xvoid instruct()
X{
Xint loop;
Xfor(loop = 0; inst[loop] ; loop++)
X {
X move(loop+1,55);
X addstr(inst[loop]);
X }
Xmove(20,0);
Xaddstr("Use wanderer keys to move. m = change no. of moves, p = play game\n");
Xaddstr("n = play game with full screen, q = quit, x = quit without save.");
X}
X
Xvoid noins()
X{
Xint loop;
Xfor(loop =0; inst[loop] ; loop++)
X {
X move(loop+1,55);
X addstr(" ");
X }
Xmove(20,0);
Xaddstr(" \n");
Xaddstr(" ");
X}
X
X/* Actual edit function */
X
Xvoid editscreen(num,score,bell,maxmoves,keys)
Xint num, maxmoves,
X *bell,
X *score;
Xchar keys[10];
X{
Xint x,y,sx=0,sy=0,quit=0,nx,ny,nosave =0;
Xchar (*frow)[ROWLEN+1] = screen,
X ch;
Xchar buffer[50];
Xchar *howdead;
X
Xfor(x=0;x<=ROWLEN;x++)
X for(y=0;y<NOOFROWS;y++)
X {
X if(screen[y][x] == '@')
X {
X sx = x;
X sy = y;
X }
X if(screen[y][x] == '-')
X screen[y][x] = ' ';
X };
Xx=sx;
Xy=sy;
Xif(maxmoves != 0)
X(void) sprintf(buffer,"Moves remaining = %d ",maxmoves);
Xelse
X(void) strcpy(buffer," Unlimited moves ");
Xdebug_disp=1;
Xmap(frow);
Xmove(18,0);
Xaddstr(buffer);
X
X/* ACTUAL EDIT FUNCTION */
X
Xinstruct();
Xwhile(!quit)
X{
Xmove(y+1,x+1);
Xrefresh();
Xcursor(1);
Xch = (char)getchar();
Xcursor(0);
X
Xnx=x;
Xny=y;
X
Xif(ch == keys[3]||ch == keys[2]||ch == keys[1]||ch == keys[0])
X {
X if(ch == keys[3])
X nx++;
X if(ch == keys[2])
X nx--;
X if(ch == keys[1])
X ny++;
X if(ch == keys[0])
X ny--;
X }
Xelse if(ch == 'q')
X {
X noins();
X break;
X }
Xelse if(ch == 'x')
X {
X noins();
X move(20,0);
X addstr("You will lose any changes made this session - are you sure? (y/n)");
X refresh();
X ch = getch();
X if(ch != 'y')
X {
X noins();
X instruct();
X refresh();
X }
X else
X {
X nosave = 1;
X addstr("\n");
X refresh();
X break;
X }
X }
Xelse if(ch == 'm') /* change to number of moves for the screen */
X {
X move(19,0);
X addstr("How many moves for this screen? :");
X refresh();echo();
X gets(buffer);
X noecho();
X maxmoves = atoi(buffer);
X if(maxmoves < 0 ) maxmoves = 0;
X move(19,0);
X addstr(" ");
X if(maxmoves != 0)
X (void) sprintf(buffer,"Moves remaining = %d ",maxmoves);
X else
X (void) strcpy(buffer," Unlimited moves ");
X move(18,0);
X addstr(buffer);
X refresh(); /* for some reason, this seems to add a '.' to */
X /* the map... Ive no idea why yet... */
X }
Xelse if(ch == 'p' || ch == 'n') /* play the game (test) */
X {
X noins();
X wscreen(num,maxmoves);
X if(ch == 'p')
X {
X debug_disp = 0;
X clear();
X }
X *score = 0;
X howdead = playscreen(&num,score,bell,maxmoves,keys);
X move(20,0);
X if(howdead!=0)
X addstr(howdead);
X else
X addstr("DONE!");
X printw("; hit any key to continue\n");
X refresh();
X ch = (char)getchar();
X clear();
X rscreen(num,&maxmoves);
X debug_disp = 1;
X map(frow);
X instruct();
X }
Xelse
X {
X if(ch >= 'a' && ch <= 'z') ch = ch - 'a' + 'A';
X if(ch < ' ' || ch == (char)127) ch = '.'; /* no ctrl codes, thankyou */
X if(ch == '"') ch = (char)getchar();
X screen[y][x] = ch;
X move(y+1,x+1);
X draw_map_symbol(ch);
X nx++;
X }
Xif(nx < 0)
X {
X nx = ROWLEN-1;
X ny--;
X }
Xif(nx >= ROWLEN)
X {
X nx = 0;
X ny++;
X }
Xif(ny < 0) ny = NOOFROWS-1;
Xif(ny >= NOOFROWS) ny = 0;
Xmove(ny+1,nx+1);
Xx=nx;
Xy=ny;
X}
X
Xif(! nosave)
X {
X for(y = 0; y<=NOOFROWS;y++) /* certain editors - eg ded - have a */
X /* habit of truncating trailing spaces*/
X /* so this should stop them! */
X if(screen[y][ROWLEN-1] == ' ')
X screen[y][ROWLEN-1] = '-';
X wscreen(num,maxmoves);
X }
Xnoins();
Xmove(20,0);
Xrefresh();
X}
X
SHAR_EOF
echo "extracting encrypt.c"
sed 's/^X//' << \SHAR_EOF > encrypt.c
X#include "wand_head.h"
X
X/* Uses seeded random xor to encrypt because setkey doesnt work on our
X system. */
X
X/* this is the randon number seed */
X#define BLURFL 32451 /* the word blurfl is used for historical reasons */
X /* but it can be any nuber */
Xcrypt_file(name)
Xchar *name;
X{
Xchar buffer[1024];
Xint fd,length,loop;
X
Xif((fd = open(name,O_RDONLY)) == -1) {
X endwin();
X sprintf(buffer,"Wanderer: cannot open %s",name);
X perror(buffer);
X exit(1);
X}
Xif((length = read(fd,buffer,1024)) < 1) {
X endwin();
X sprintf(buffer,"Wanderer: read error on %s",name);
X perror(buffer);
X exit(1);
X}
Xclose(fd);
X
X/* Right, got it in here, now to encrypt the stuff */
X
Xaddstr("Running crypt routine...\n");
Xrefresh();
X
Xsrand(BLURFL);
Xfor(loop=0;loop<length;loop++)
X buffer[loop]^=rand();
X
Xif((fd = open(name,O_WRONLY|O_TRUNC))== -1) {
X endwin();
X sprintf(buffer,"Wanderer: cannot write to %s",name);
X perror(buffer);
X exit(1);
X}
Xif(write(fd,buffer,length)!=length) {
X endwin();
X sprintf(buffer,"Wanderer: write error on %s",name);
X perror(buffer);
X exit(1);
X}
Xclose(fd);
X
X/* ok, file now contains encrypted/decrypted game. */
X/* lets go back home... */
X}
SHAR_EOF
echo "extracting fall.c"
sed 's/^X//' << \SHAR_EOF > fall.c
X#include "wand_head.h"
X
Xextern void draw_symbol();
Xextern int debug_disp;
Xextern char screen[NOOFROWS][ROWLEN+1];
X
Xint check(mx,my,x,y,dx,dy,sx,sy,howdead)
X/* check for any falling caused by something moving out of x,y along
X vector dx,dy. All the others are constant and should really have
X been global... */
Xint x,y,sx,sy,dx,dy, *mx, *my;
Xchar howdead[25];
X{
Xint ret=0;
Xret+=fall(mx,my,x,y,sx,sy,howdead);
Xret+=fall(mx,my,x-dx,y-dy,sx,sy,howdead);
Xret+=fall(mx,my,x-dy,y-dx,sx,sy,howdead);
Xret+=fall(mx,my,x+dy,y+dx,sx,sy,howdead);
Xret+=fall(mx,my,x-dx-dy,y-dy-dx,sx,sy,howdead);
Xret+=fall(mx,my,x-dx+dy,y-dy+dx,sx,sy,howdead);
Xreturn ret;
X}
X
Xint fall(mx,my,x,y,sx,sy,howdead) /* recursive function for falling */
X /* boulders and arrows */
Xint x,y,sx,sy, *mx, *my;
Xchar howdead[25];
X{
Xint nx = x,nxu = x,nyl = y,nyr = y,retval = 0, makesound = 0;
Xif ((y>(NOOFROWS-1))||(y<0)||(x<0)||(x>(ROWLEN-1)))
X return(0);
Xif((screen[y][x] != 'O') && (screen[y][x] != ' ') && (screen[y][x] != 'M') &&
X (screen[y][x] !='\\') && (screen[y][x] != '/') && (screen[y][x] != '@') &&
X (screen[y][x] != '^'))
X return(0);
Xif(screen[y][x] == 'O')
X {
X if((screen[y][x-1] == ' ') && (screen[y-1][x-1] == ' '))
X nx--;
X else
X {
X if((screen[y][x+1] == ' ') && (screen[y-1][x+1] == ' '))
X nx++;
X else
X nx = -1;
X }
X if((screen[y][x-1] == ' ') && (screen[y+1][x-1] == ' '))
X nxu--;
X else
X {
X if((screen[y][x+1] == ' ') && (screen[y+1][x+1] == ' '))
X nxu++;
X else
X nxu = -1;
X }
X if((screen[y-1][x] == ' ') && (screen[y-1][x+1] == ' '))
X nyr--;
X else
X {
X if((screen[y+1][x] == ' ') && (screen[y+1][x+1] == ' '))
X nyr++;
X else
X nyr = -1;
X }
X if((screen[y-1][x] == ' ') && (screen[y-1][x-1] == ' '))
X nyl--;
X else
X {
X if((screen[y+1][x] == ' ') && (screen[y+1][x-1] == ' '))
X nyl++;
X else
X nyl = -1;
X }
X }
Xif(screen[y][x] == '\\')
X {
X if(screen[y-1][++nx] != ' ')
X nx = -1;
X if(screen[y+1][--nxu] != ' ')
X nxu = -1;
X if(screen[--nyr][x+1] != ' ')
X nyr = -1;
X if(screen[++nyl][x-1] != ' ')
X nyl = -1;
X }
Xif(screen[y][x] == '/')
X {
X if(screen[y-1][--nx] != ' ')
X nx = -1;
X if(screen[y+1][++nxu] != ' ')
X nxu = -1;
X if(screen[++nyr][x+1] != ' ')
X nyr = -1;
X if(screen[--nyl][x-1] != ' ')
X nyl = -1;
X }
Xif((screen[y][nx] != ' ') && (screen[y][nx] != 'M'))
X nx = -1;
Xif((screen[y-1][x] == 'O') && (nx >= 0) && (y > 0) &&
X (screen[y][nx] != '^')) /* boulder falls ? */
X {
X screen[y-1][x] = ' ';
X if(screen[y][nx] == '@')
X {
X makesound = 1;
X strcpy(howdead,"a falling boulder");
X retval=1;
X }
X if(screen[y][nx] == 'M')
X {
X makesound = 1;
X *mx = *my = -2;
X screen[y][nx] = ' ';
X }
X screen[y][nx] = 'O';
X if(!debug_disp)
X {
X if((y<(sy+5)) && (y>(sy-3)) && (x>(sx-6)) && (x<(sx+6)))
X draw_symbol((x-sx+5)*3,(y-sy+2)*2,' ');
X if((y<(sy+4)) && (y>(sy-4)) && (nx>(sx-6)) && (nx<(sx+6)))
X draw_symbol((nx-sx+5)*3,(y-sy+3)*2,'O');
X }
X else
X {
X move(y,x+1);
X draw_map_symbol(' ');
X move(y+1,nx+1);
X draw_map_symbol('O');
X }
X refresh();
X
X#ifdef BOULDER_SOUND
X {
X int w,e,s,sw,se;
X
X /* try to predict if boulder has stopped falling */
X /* so we know when to trigger the sound */
X w = screen[y][nx-1];
X e = screen[y][nx+1];
X s = screen[y+1][nx];
X sw = screen[y+1][nx-1];
X se = screen[y+1][nx+1];
X
X if (s != ' ' && s != '/' && s != '\\' && s != 'O')
X makesound = 1;
X else if (s == 'O')
X {
X if (w != ' ' && e != ' ')
X makesound = 1;
X else if (w != ' ' && e == ' ' && se != ' ')
X makesound = 1;
X else if (w == ' ' && e != ' ' && sw != ' ')
X makesound = 1;
X else if (w == ' ' && sw != ' ' && e == ' ' && se != ' ')
X makesound = 1;
X }
X else if (s == '/' && sw != ' ')
X makesound = 1;
X else if (s == '\\' && se != ' ')
X makesound = 1;
X
X if (makesound) playSound(BOULDER_SOUND);
X }
X#endif
X
X retval+=fall(mx,my,nx ,y+1,sx,sy,howdead);
X retval+=check(mx,my,x,y-1,0,1,sx,sy,howdead);
X if(screen[y+1][nx] == '@')
X {
X if (!makesound) playSound(BOULDER_SOUND);
X strcpy(howdead,"a falling boulder");
X return(1);
X }
X if(screen[y+1][nx] == 'M')
X {
X if (!makesound) playSound(BOULDER_SOUND);
X *mx = *my = -2;
X screen[y+1][nx] = ' ';
X }
X }
Xif((screen[nyr][x] != '^')&&(screen[nyr][x] != ' ')&&(screen[nyr][x] != 'M'))
X nyr = -1;
Xif((screen[y][x+1] == '<')&&(nyr>=0)&&(x+1<ROWLEN)) /* arrow moves ( < ) ? */
X {
X screen[y][x+1] = ' ';
X if(screen[nyr][x] == '@')
X {
X playSound(ARROW_SOUND);
X strcpy(howdead,"a speeding arrow");
X retval = 1;
X }
X if(screen[nyr][x] == 'M')
X {
X playSound(ARROW_SOUND);
X *mx = *my = -2;
X screen[nyr][x] = ' ';
X }
X screen[nyr][x] = '<';
X if(!debug_disp)
X {
X if((y<(sy+4)) && (y>(sy-4)) && (x<(sx+5)) && (x>(sx-7)))
X draw_symbol((x-sx+6)*3,(y-sy+3)*2,' ');
X if((nyr<(sy+4)) && (nyr>(sy-4)) && (x<(sx+6)) && (x>(sx-6)))
X draw_symbol((x-sx+5)*3,(nyr-sy+3)*2,'<');
X }
X else
X {
X move(y+1,x+2);
X draw_map_symbol(' ');
X move(nyr+1,x+1);
X draw_map_symbol('<');
X }
X refresh();
X retval+=fall(mx,my,x-1,nyr,sx,sy,howdead);
X retval+=check(mx,my,x+1,y,-1,0,sx,sy,howdead);
X if(screen[nyr][x-1] == '@')
X {
X playSound(ARROW_SOUND);
X strcpy(howdead,"a speeding arrow");
X return(1);
X }
X if(screen[nyr][x-1] == 'M')
X {
X playSound(ARROW_SOUND);
X *mx = *my = -2;
X screen[nyr][x-1] = ' ';
X }
X }
Xif((screen[nyl][x] != ' ')&&(screen[nyl][x] != '^')&&(screen[nyl][x] != 'M'))
X nyl = -1;
Xif((screen[y][x-1] == '>')&&(nyl>=0)&&(x>0)) /* arrow moves ( > ) ? */
X {
X screen[y][x-1] = ' ';
X if(screen[nyl][x] == '@')
X {
X playSound(ARROW_SOUND);
X strcpy(howdead,"a speeding arrow");
X retval = 1;
X }
X if(screen[nyl][x] == 'M')
X {
X playSound(ARROW_SOUND);
X *mx = *my = -2;
X screen[nyl][x] = ' ';
X }
X screen[nyl][x] = '>';
X if(!debug_disp)
X {
X if((y<(sy+4)) && (y>(sy-4)) && (x<(sx+7)) && (x>(sx-5)))
X draw_symbol((x-sx+4)*3,(y-sy+3)*2,' ');
X if((nyl<(sy+4)) && (nyl>(sy-4)) && (x<(sx+6)) && (x>(sx-6)))
X draw_symbol((x-sx+5)*3,(nyl-sy+3)*2,'>');
X }
X else
X {
X move(y+1,x);
X draw_map_symbol(' ');
X move(nyl+1,x+1);
X draw_map_symbol('>');
X }
X refresh();
X retval+=fall(mx,my,x+1,nyl,sx,sy,howdead);
X retval+=check(mx,my,x-1,y,1,0,sx,sy,howdead);
X if(screen[nyl][x+1] == '@')
X {
X playSound(ARROW_SOUND);
X strcpy(howdead,"a speeding arrow");
X return(1);
X }
X if(screen[nyl][x+1] == 'M')
X {
X playSound(ARROW_SOUND);
X *mx = *my = -2;
X screen[nyl][x+1] = ' ';
X }
X }
Xif(screen[y][nxu] != ' ')
X nxu = -1;
Xif((screen[y+1][x] == '^') && (nxu >= 0) && (y < NOOFROWS) &&
X (screen[y][x] != '^')) /* balloon rises? */
X {
X screen[y+1][x] = ' ';
X screen[y][nxu] = '^';
X if(!debug_disp)
X {
X if((y<(sy+3)) && (y>(sy-5)) && (x>(sx-6)) && (x<(sx+6)))
X draw_symbol((x-sx+5)*3,(y-sy+4)*2,' ');
X if((y<(sy+4)) && (y>(sy-4)) && (nxu>(sx-6)) && (nxu<(sx+6)))
X draw_symbol((nxu-sx+5)*3,(y-sy+3)*2,'^');
X }
X else
X {
X move(y+2,x+1);
X draw_map_symbol(' ');
X move(y+1,nxu+1);
X draw_map_symbol('^');
X }
X refresh();
X retval+=fall(mx,my,nxu ,y-1,sx,sy,howdead);
X retval+=check(mx,my,x,y+1,0,-1,sx,sy,howdead);
X }
Xif(retval>0)
X return(1);
Xreturn(0);
X}
SHAR_EOF
echo "extracting game.c"
sed 's/^X//' << \SHAR_EOF > game.c
X#include "wand_head.h"
X
X#define viable(x,y) (((screen[y][x] == ' ') || (screen[y][x] == ':') ||\
X (screen[y][x] == '@') || (screen[y][x] == '+') ||\
X (screen[y][x] == 'S')) && (y >= 0) &&\
X (x >= 0) && (y < NOOFROWS) && (x < ROWLEN))
X
X/* typedef struct mon_rec *//* M002 struct mon_rec moved */
X/* { *//* to header file because it */
X/* int x,y,mx,my; *//* is needed by save.c */
X/* char under; */
X/* struct mon_rec *next,*prev; */
X/* }; */
X
Xtypedef struct { int d[2]; } direction;
X
X#ifdef LINT_ARGS /* M001 */
Xdirection new_direction(int, int, int, int);
X#else
Xdirection new_direction();
X#endif
X
Xextern int jumpscreen();
X
Xextern int check();
X
Xextern void showpass();
X
Xextern void draw_symbol();
X
Xextern void display();
X
Xextern int fall();
X
Xextern void map();
X
Xextern void redraw_screen();
Xextern int debug_disp;
Xextern int edit_mode;
Xextern int saved_game;
Xextern char screen[NOOFROWS][ROWLEN+1];
X
X/* Add a spirit to the chain */
X/* Maintain a doubly linked list to make reuse possible.
X tail_of_list is *NOT* the last monster allocated, but
X the last monster alloted to a screen. start_of_list
X is a dummy entry to ease processing. last_of_list
X is the last entry allocated. */
Xstatic struct mon_rec start_of_list = {0,0,0,0,0,NULL,NULL};
X
Xstruct mon_rec *tail_of_list;
Xstruct mon_rec *last_of_list;
X
Xstruct mon_rec *make_monster(x,y)
Xint x,y;
X{
Xchar *malloc();
X#define MALLOC (struct mon_rec *)malloc(sizeof(struct mon_rec))
Xstruct mon_rec *monster;
Xif(tail_of_list->next == NULL)
X {
X if((last_of_list = MALLOC) == NULL)
X return NULL;
X tail_of_list->next = last_of_list;
X last_of_list->prev = tail_of_list;
X last_of_list->next = NULL;
X }
Xmonster = tail_of_list = tail_of_list->next;
Xmonster->x = x;
Xmonster->y = y;
Xmonster->mx = 1; /* always start moving RIGHT. (fix later) */
Xmonster->my = 0;
Xmonster->under = ' ';
Xreturn monster;
X}
X
X/* 'follow lefthand wall' algorithm for baby monsters */
X
Xdirection new_direction(x,y,bx,by)
Xint x,y,bx,by;
X{
Xdirection out;
Xif(viable((x+by),(y-bx)))
X {
X out.d[0] = by;
X out.d[1] = -bx;
X return out;
X }
Xif(viable((x+bx),(y+by)))
X {
X out.d[0] = bx;
X out.d[1] = by;
X return out;
X }
Xif(viable((x-by),(y+bx)))
X {
X out.d[0] = -by;
X out.d[1] = bx;
X return out;
X }
Xif(viable((x-bx),(y-by)))
X {
X out.d[0] = -bx;
X out.d[1] = -by;
X return out;
X }
Xout.d[0] = -bx;
Xout.d[1] = -by;
Xreturn out;
X}
X
X/* tell player if monster exists */
Xshow_monster(yes)
Xint yes;
X{
Xif(yes)
X draw_symbol(48,10,'M');
Xelse
X {
X move(48,10);
X addstr(" ");
X move(48,11);
X addstr(" ");
X }
X}
X
X/* Actual game function - Calls fall() to move
X boulders and arrows recursively */
X/* Variable explaination :
X All the var names make sense to ME, but some people think them a bit confusing... :-) So heres an explanation.
X x,y : where you are
X nx,ny : where you're trying to move to
X sx,sy : where the screen window on the playing area is
X mx,my : where the monster is
X tx,ty : teleport arrival
X bx,by : baby monster position
X nbx,nby : where it wants to be
X lx,ly : the place you left when teleporting
X nf : how many diamonds youve got so far
X new_disp : the vector the baby monster is trying
X*/
X
Xchar *playscreen(num,score,bell,maxmoves,keys)
Xint *num, maxmoves,
X *bell,
X *score;
Xchar keys[10];
X{
Xint x,y,nx,ny,deadyet =0,
X sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1,
X bx, by, nbx, nby, tmpx,tmpy,
X newnum,
X max_score = 250,
X diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection;
Xchar (*frow)[ROWLEN+1] = screen,
X ch,
X buffer[25];
Xstatic char howdead[25]; /* M001 can't use auto var for return value */
Xdirection new_disp;
Xstruct mon_rec *monster,*current;
X
Xtail_of_list = &start_of_list;
X
Xfor(x=0;x<=ROWLEN;x++)
X for(y=0;y<NOOFROWS;y++)
X {
X if((screen[y][x] == '*')||(screen[y][x] == '+'))
X {
X diamonds++;
X max_score += 10;
X if(screen[y][x] == '+')
X max_score += 20;
X }
X if(screen[y][x] == 'A') /* note teleport arrival point & */
X { /* replace with space */
X tx = x;
X ty = y;
X screen[y][x] = ' ';
X }
X if(screen[y][x] == '@')
X {
X sx = x;
X sy = y;
X }
X if(screen[y][x] == 'M') /* Put megamonster in */
X {
X mx = x;
X my = y;
X }
X if(screen[y][x] == 'S') /* link small monster to pointer chain */
X {
X if((monster = make_monster(x,y)) == NULL)
X {
X strcpy(howdead,"running out of memory");
X return howdead;
X }
X if(!viable(x,y-1)) /* make sure its running in the correct */
X { /* direction.. */
X monster->mx = 1;
X monster->my = 0;
X }
X else if(!viable(x+1,y))
X {
X monster->mx = 0;
X monster->my = 1;
X }
X else if(!viable(x,y+1))
X {
X monster->mx = -1;
X monster->my = 0;
X }
X else if(!viable(x-1,y))
X {
X monster->mx = 0;
X monster->my = -1;
X }
X }
X if(screen[y][x] == '-')
X screen[y][x] = ' ';
X };
Xx=sx;
Xy=sy;
Xif((x == -1)&&(y == -1)) /* no start position in screen ? */
X {
X strcpy(howdead,"a screen design error");
X return(howdead);
X }
X
Xupdate_game: /* M002 restored game restarts here */
X
Xmove(0,48);
X(void) addstr("Score\t Diamonds");
Xmove(1,48);
X(void) addstr("\tFound\tTotal");
Xmove(3,48);
X(void) sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X(void) addstr(buffer);
Xmove(6,48);
X(void) sprintf(buffer,"Current screen %d",*num);
X(void) addstr(buffer);
Xif(maxmoves != 0)
X(void) sprintf(buffer,"Moves remaining = %d ",maxmoves);
Xelse
X{
X (void) strcpy(buffer," Unlimited moves ");
X maxmoves = -1;
X};
Xmove(15,48);
X(void) addstr(buffer);
Xshow_monster(mx != -1); /* tell player if monster exists */
X
Xif(!debug_disp)
X display(sx,sy,frow,*score);
Xelse
X map(frow);
X
X/* ACTUAL GAME FUNCTION - Returns method of death in string */
X
Xwhile(deadyet == 0)
X{
X#ifdef MOUSE
X/* get next keyboard character or mouse click (AMIGA) */
Xif ((ch = mouseorkey()) == MOUSE) {
X int mouserow, mousecol, deltax, deltay;
X#define UP keys[0]
X#define DOWN keys[1]
X#define LEFT keys[2]
X#define RIGHT keys[3]
X /* convert mouse coordinates to the keystroke in that direction */
X getmouse(&mouserow, &mousecol);
X /* adjust mouse coordinates to the game window */
X if (debug_disp) {
X --mouserow;
X --mousecol;
X } else {
X mouserow = mouserow/2+sy-3;
X mousecol = mousecol/3+sx-5;
X }
X deltax = mousecol - x;
X deltay = mouserow - y;
X if (deltax == 0 && deltay == 0) {
X ch = ' '; /* no change */
X } else if (deltax >= 0 && deltay >= 0) {
X if (deltax > deltay) ch = RIGHT; else ch = DOWN;
X } else if (deltax >= 0 && deltay <= 0) {
X if (deltax > abs(deltay)) ch = RIGHT; else ch = UP;
X } else if (deltax <= 0 && deltay >= 0) {
X if (abs(deltax) > deltay) ch = LEFT; else ch = DOWN;
X } else {
X if (abs(deltax) > abs(deltay)) ch = LEFT; else ch = UP;
X }
X}
X#else
X/* get next keyboard character */
Xch = getch();
X#endif
X
Xnx=x;
Xny=y;
X
Xif((ch == keys[3]) && (x <(ROWLEN-1))) /* move about - but thats obvious */
X nx++;
Xif((ch == keys[2]) && (x > 0))
X nx--;
Xif((ch == keys[1]) && (y <(NOOFROWS-1)))
X ny++;
Xif((ch == keys[0]) && (y > 0))
X ny--;
X#ifndef AMIGA
Xif(ch == '1') /* Add or get rid of that awful sound */
X {
X move(10,45);
X *bell = 1;
X (void) addstr("Bell ON ");
X move(16,0);
X refresh();
X continue;
X }
Xif(ch == '0')
X {
X *bell = 0;
X move(10,45);
X (void) addstr("Bell OFF");
X move(16,0);
X refresh();
X continue;
X }
X#endif
Xif(ch == '~') /* level jump */
X {
X if((newnum = jumpscreen(*num)) == 0)
X {
X strcpy(howdead,"a jump error.");
X return howdead;
X }
X if(newnum != *num)
X { /* Sorry Greg, no points for free */
X sprintf(howdead,"~%c",newnum);
X return howdead;
X }
X continue;
X }
Xif(ch == '!') /* look at the map */
X {
X if(debug_disp)
X continue;
X map(frow);
X display(sx,sy,frow,*score);
X continue;
X }
Xif(ch == 'q')
X {
X strcpy(howdead,"quitting the game");
X return howdead;
X }
Xif(ch == '?')
X {
X helpme();
X if(debug_disp)
X map(frow);
X else
X display(sx,sy,frow,*score);
X continue;
X }
Xif (ch == 'c')
X {
X credits();
X redraw_screen(maxmoves,*num,*score,nf,diamonds,mx,sx,sy,frow);
X continue;
X }
Xif((ch == '@')&&(!debug_disp))
X {
X sx = x;
X sy = y;
X display(sx,sy,frow,*score);
X continue;
X }
Xif(ch == '#')
X {
X debug_disp = 1 - debug_disp;
X if(debug_disp)
X map(frow);
X else
X {
X for(tmpy=0;tmpy<=(NOOFROWS+1);tmpy++)
X {
X move(tmpy,0);
X addstr(" ");
X }
X sx = x; sy = y;
X display(sx,sy,frow,*score);
X }
X continue;
X }
Xif(ch == 'W')
X {
X redraw_screen(maxmoves,*num,*score,nf,diamonds,mx,sx,sy,frow);
X continue;
X }
X
X/* M002 Added save/restore game feature. Gregory H. Margo */
Xif(ch == 'S') /* save game */
X {
X extern struct save_vars zz;
X
X /* stuff away important local variables to be saved */
X /* so the game state may be acurately restored */
X zz.z_x = x;
X zz.z_y = y;
X zz.z_nx = nx;
X zz.z_ny = ny;
X zz.z_sx = sx;
X zz.z_sy = sy;
X zz.z_tx = tx;
X zz.z_ty = ty;
X zz.z_lx = lx;
X zz.z_ly = ly;
X zz.z_mx = mx;
X zz.z_my = my;
X zz.z_bx = bx;
X zz.z_by = by;
X zz.z_nbx = nbx;
X zz.z_nby = nby;
X zz.z_max_score = max_score;
X zz.z_diamonds = diamonds;
X zz.z_nf = nf;
X zz.z_hd = hd;
X zz.z_vd = vd;
X zz.z_xdirection = xdirection;
X zz.z_ydirection = ydirection;
X
X save_game(*num, score, bell, maxmoves, &start_of_list, tail_of_list);
X /* if save fails, we come back here */
X redraw_screen(maxmoves,*num,*score,nf,diamonds,mx,sx,sy,frow);
X continue;
X }
Xif(ch == 'R') /* restore game */
X {
X extern struct save_vars zz;
X
X restore_game(num, score, bell, &maxmoves, &start_of_list, &tail_of_list);
X
X /* recover important local variables */
X x = zz.z_x;
X y = zz.z_y;
X nx = zz.z_nx;
X ny = zz.z_ny;
X sx = zz.z_sx;
X sy = zz.z_sy;
X tx = zz.z_tx;
X ty = zz.z_ty;
X lx = zz.z_lx;
X ly = zz.z_ly;
X mx = zz.z_mx;
X my = zz.z_my;
X bx = zz.z_bx;
X by = zz.z_by;
X nbx = zz.z_nbx;
X nby = zz.z_nby;
X max_score = zz.z_max_score;
X diamonds = zz.z_diamonds;
X nf = zz.z_nf;
X hd = zz.z_hd;
X vd = zz.z_vd;
X xdirection = zz.z_xdirection;
X ydirection = zz.z_ydirection;
X
X if (maxmoves == -1)
X maxmoves = 0; /* to get the "unlimited moves" message */
X
X goto update_game; /* the dreaded goto */
X }
X
Xif(screen[ny][nx] == 'C')
X {
X playSound(CLOCK_SOUND);
X screen[ny][nx] = ':';
X *score+=4;
X if(maxmoves != -1)
X maxmoves+=250;
X }
Xswitch(screen[ny][nx])
X {
X case '@': break;
X case '*': *score+=9;
X max_score -= 10;
X nf++;
X playSound(DIAMOND_SOUND);
X case ':': *score+=1;
X move(3,48);
X sprintf(buffer,"%d\t %d",*score,nf);
X (void) addstr(buffer);
X case ' ':
X if (screen[ny][nx] != '*') playSound(STEP_SOUND);
X screen[y][x] = ' ';
X screen[ny][nx] = '@';
X if(!debug_disp)
X {
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X }
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X move(ny+1,nx+1);
X draw_map_symbol('@');
X }
X deadyet += check(&mx,&my,x,y,nx-x,ny-y,sx,sy,howdead);
X move(16,0);
X refresh();
X y = ny;
X x = nx;
X break;
X case 'O':
X if(screen[y][nx*2-x] == 'M')
X {
X screen[y][nx*2-x] = ' ';
X mx = my = -1;
X *score+=100;
X move(3,48);
X sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X (void) addstr(buffer);
X playSound(DEADMONSTER_SOUND);
X show_monster(0);
X move(16,0);
X refresh();
X }
X if(screen[y][nx*2-x] == ' ')
X {
X playSound(PUSH_SOUND);
X screen[y][nx*2-x] = 'O';
X screen[y][x] = ' ';
X screen[ny][nx] = '@';
X if(!debug_disp)
X {
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X if(nx*2-x>sx-6&&nx*2-x<sx+6)
X draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O');
X }
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X move(ny+1,nx+1);
X draw_map_symbol('@');
X move(y+1,nx*2-x+1);
X draw_map_symbol('O');
X }
X deadyet += fall(&mx,&my,nx*2-x,y+1,sx,sy,howdead);
X deadyet += fall(&mx,&my,x*2-nx,y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y-1,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y+1,sx,sy,howdead);
X move(16,0);
X refresh();
X y = ny;
X x = nx;
X }
X break;
X case '^':
X if(screen[y][nx*2-x] == ' ')
X {
X screen[y][nx*2-x] = '^';
X screen[y][x] = ' ';
X screen[ny][nx] = '@';
X if(!debug_disp)
X {
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X if(nx*2-x>sx-6&&nx*2-x<sx+6)
X draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'^');
X }
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X move(ny+1,nx+1);
X draw_map_symbol('@');
X move(y+1,nx*2-x+1);
X draw_map_symbol('^');
X }
X deadyet += fall(&mx,&my,nx*2-x,y-1,sx,sy,howdead);
X deadyet += fall(&mx,&my,x*2-nx,y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y+1,sx,sy,howdead);
X deadyet += fall(&mx,&my,x,y-1,sx,sy,howdead);
X move(16,0);
X refresh();
X y = ny;
X x = nx;
X }
X break;
X case '<':
X case '>':
X if(screen[ny*2-y][x] == 'M')
X {
X screen[ny*2-y][x] = ' ';
X mx = my = -1;
X *score+=100;
X move(3,48);
X sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X (void) addstr(buffer);
X playSound(DEADMONSTER_SOUND);
X show_monster(0);
X move(16,0);
X refresh();
X }
X if(screen[ny*2-y][x] == ' ')
X {
X screen[ny*2-y][x] = screen[ny][nx];
X screen[y][x] = ' ';
X screen[ny][nx] = '@';
X if(!debug_disp)
X {
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X if(ny*2-y>sy-4&&ny*2-y<sy+4)
X draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]);
X }
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X move(ny+1,nx+1);
X draw_map_symbol('@');
X move(ny*2-y+1,x+1);
X draw_map_symbol(screen[ny*2-y][x]);
X }
X deadyet += fall(&mx,&my,x,y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,howdead);
X deadyet += fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,howdead);
X deadyet += fall(&mx,&my,x-1,ny*2-y,sx,sy,howdead);
X deadyet += fall(&mx,&my,x+1,ny*2-y,sx,sy,howdead);
X move(16,0);
X refresh();
X y = ny;
X x = nx;
X }
X break;
X case '!':
X strcpy(howdead,"an exploding landmine");
X deadyet = 1;
X if(!debug_disp)
X {
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@');
X }
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X move(ny+1,nx+1);
X draw_map_symbol('@');
X }
X move(16,0);
X refresh();
X playSound(KABOOM_SOUND);
X break;
X case 'X':
X if(nf == diamonds)
X {
X playSound(EXIT_SOUND);
X *score+=250;
X showpass(*num);
X return NULL;
X }
X break;
X case 'T':
X if(tx > -1)
X {
X playSound(TELEPORT_SOUND);
X screen[ny][nx] = ' ';
X screen[y][x] = ' ';
X lx = x;
X ly = y;
X y = ty;
X x = tx;
X screen[y][x] = '@';
X sx = x;
X sy = y;
X *score += 20;
X move(3,48);
X sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X (void) addstr(buffer);
X if(!debug_disp)
X display(sx,sy,frow,*score);
X else
X map(frow);
X deadyet = fall(&mx,&my,nx,ny,sx,sy,howdead);
X if(deadyet == 0)
X deadyet = fall(&mx,&my,lx,ly,sx,sy,howdead);
X if(deadyet == 0)
X deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,howdead);
X if(deadyet == 0)
X deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,howdead);
X if(deadyet == 0)
X deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,howdead);
X if(deadyet == 0)
X deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,howdead);
X move(16,0);
X refresh();
X }
X else
X {
X screen[ny][nx] = ' ';
X move(16,0);
X addstr("Teleport out of order");
X refresh();
X }
X break;
X case 'M':
X playSound(MUNCH_SOUND);
X strcpy(howdead,"a hungry monster");
X deadyet = 1;
X if(!debug_disp)
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X }
X move(16,0);
X refresh();
X break;
X case 'S':
X playSound(MUNCH_SOUND);
X strcpy(howdead,"walking into a monster");
X deadyet = 1;
X if(!debug_disp)
X draw_symbol((x-sx+5)*3,(y-sy+3)*2,' ');
X else
X {
X move(y+1,x+1);
X draw_map_symbol(' ');
X }
X move(16,0);
X refresh();
X break;
X default:
X break;
X }
Xif((y == ny) && (x == nx) && (maxmoves>0))
X {
X (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves);
X move(15,48);
X (void) addstr(buffer);
X }
Xif(maxmoves == 0)
X {
X strcpy(howdead,"running out of time");
X return(howdead);
X }
Xif(!debug_disp)
X {
X if ((x<(sx-3))&& (deadyet ==0)) /* screen scrolling if necessary */
X {
X sx-=6;
X if(sx < 4)
X sx = 4;
X scroll(sx,sy,frow,*score);
X }
X if ((y<(sy-2))&& (deadyet == 0))
X {
X sy-=5;
X if(sy < 2)
X sy = 2;
X scroll(sx,sy,frow,*score);
X }
X if ((x>(sx+3)) && (deadyet == 0))
X {
X sx+=6;
X if(sx>(ROWLEN -5))
X sx = ROWLEN -5;
X scroll(sx,sy,frow,*score);
X }
X if ((y>(sy+2))&& (deadyet ==0))
X {
X sy+=5;
X if(sy > (NOOFROWS-3))
X sy = NOOFROWS -3;
X scroll(sx,sy,frow,*score);
X }
X }
X
X /* MONSTER SECTION */
X
X/* big monster first */
Xif(mx == -2) /* has the monster been killed ? */
X {
X playSound(DEADMONSTER_SOUND);
X *score+=100;
X mx = my = -1;
X move(3,48);
X sprintf(buffer,"%d\t %d\t",*score,nf);
X (void) addstr(buffer);
X show_monster(0);
X move(16,0);
X refresh();
X } /* if monster still alive */
Xif(mx != -1) /* then move that monster ! */
X {
X screen[my][mx] = ' ';
X if(mx>x)
X xdirection = -1;
X else
X xdirection = 1;
X if(!debug_disp)
X {
X if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' ');
X }
X else
X {
X move(my+1,mx+1);
X draw_map_symbol(' ');
X }
X if((hd = (mx-x))<0)
X hd = -hd;
X if((vd = (my-y))<0)
X vd = -vd;
X if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')))
X mx+=xdirection;
X else
X {
X if(my>y)
X ydirection = -1;
X else
X ydirection = 1;
X if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@'))
X my+=ydirection;
X else
X if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))
X mx+=xdirection;
X }
X if(!debug_disp)
X {
X if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6)))
X draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M');
X }
X else
X {
X move(my+1,mx+1);
X draw_map_symbol('M');
X }
X if(screen[my][mx] == '@') /* ha! gottim! */
X {
X playSound(MUNCH_SOUND);
X strcpy(howdead,"a hungry monster");
X move(16,0);
X refresh();
X return(howdead);
X }
X screen[my][mx] = 'M';
X move(16,0);
X refresh();
X }
X
Xcurrent = &start_of_list; /* baby monsters now */
Xwhile((current != tail_of_list)&&(!deadyet))
X /* deal with those little monsters */
X {
X monster = current->next;
X new_disp = new_direction( monster->x, monster->y, monster->mx, monster->my );
X if(monster->under!='S') /* if on top of another baby */
X {
X screen[monster->y][monster->x] = monster->under;
X if(!debug_disp)
X {
X if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under);
X }
X else
X {
X move(monster->y+1,monster->x+1);
X draw_map_symbol(monster->under);
X }
X if(monster->under == ' ')
X deadyet+=check(&mx,&my,monster->x,monster->y,new_disp.d[0],new_disp.d[1],sx,sy,howdead);
X }
X else
X monster->under=' ';
X monster->mx = new_disp.d[0];
X monster->my = new_disp.d[1];
X monster->x += monster->mx;
X monster->y += monster->my;
X monster->under = screen[monster->y][monster->x];
X screen[monster->y][monster->x] = 'S'; /* move into new space */
X if(!debug_disp)
X {
X if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S');
X }
X else
X {
X move(monster->y+1,monster->x+1);
X draw_map_symbol('S');
X }
X if(monster->under == '@') /* monster hit you? */
X {
X playSound(MUNCH_SOUND);
X strcpy(howdead,"the little monsters");
X move(16,0);
X refresh();
X return(howdead);
X }
X if(monster->under == '+') /* monster hit cage? */
X {
X playSound(CAGE_SOUND);
X *score +=20;
X max_score -= 20;
X move(3,48);
X sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds);
X (void) addstr(buffer);
X /* remove from chain, and insert at the end (at last_of_list) */
X if(monster == tail_of_list)
X tail_of_list = tail_of_list->prev;
X else
X {
X current->next = monster-> next;
X current->next->prev = current;
X monster->next = NULL;
X monster->prev = last_of_list;
X last_of_list->next = monster;
X last_of_list = monster;
X }
X screen[monster->y][monster->x] = '*';
X if(!debug_disp)
X {
X if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6)))
X draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*');
X }
X else
X {
X move(monster->y+1,monster->x+1);
X draw_map_symbol('*');
X }
X }
X else
X current = monster;
X move(16,0);
X refresh();
X }
X
Xif((edit_mode)&&(deadyet)) { /* stop death if testing */
X if(!debug_disp)
X move(18,0);
X else
X move(20,0);
X addstr("You were killed by ");
X addstr(howdead);
X addstr("\nPress 'c' to continue.");
X refresh();
X ch=getch();
X if(ch == 'c')
X deadyet = 0;
X if(!debug_disp)
X move(18,0);
X else
X move(20,0);
X addstr(" ");
X addstr("\n ");
X refresh();
X }
X
X}
Xreturn(howdead);
X}
SHAR_EOF
echo "End of archive 2 (of 3)"
# if you want to concatenate archives, remove anything after this line
exit