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