page%rishathra@Sun.COM (Bob Page) (04/26/89)
Submitted-by: mab@druwy.att.com (Alan Bland) Posting-number: Volume 89, Issue 96 Archive-name: fun/wand22.3 # 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: # help.c # icon.c # jump.c # m.c # read.c # save.c # scores.c # wand_head.h # This is archive 3 of a 3-part kit. # This archive created: Tue Apr 25 00:28:08 1989 echo "extracting help.c" sed 's/^X//' << \SHAR_EOF > help.c X/* From jason@uucp.aeras */ X X#include "wand_head.h" X X/* this help text structure allows graphic icons to be displayed along X * with the help text. if your machine doesn't do graphics, it still X * works ok with the text representation. X */ Xstruct { X char *text; /* text for this line */ X short col; /* column position for graphic icon, -1 for none */ X short offrow; /* row offset, fakes multiple icons per row */ X char icon; /* icon character to display */ X} help[]={ X" ** W A N D E R E R ** ", -1,0,0, /* 0 */ X" =========================== ", -1,0,0, /* 1 */ X" by Steven Shipway ", -1,0,0, /* 2 */ X"How to play: ", -1,0,0, /* 3 */ X" Collect all the treasure: ", 30,0,'*',/* 4 */ X" ", -1,0,0, /* 5 */ X" Then go through the exit: ", 30,0,'X',/* 6 */ X" ", -1,0,0, /* 7 */ X#ifdef AMIGA X" Use mouse, cursor keys or ", -1,0,0, /* 8 */ X" h,j,k,l keys move around. ", -1,0,0, /* 9 */ X" ESC Quit game ", -1,0,0, /* 10 */ X" F10 Look at map ", -1,0,0, /* 11 */ X" F6 Save game F7 Restore Game ", -1,0,0, /* 12 */ X" HELP Help mode F3 Center screen", -1,0,0, /* 13 */ X" F1 Jump level F2 Switch mode ", -1,0,0, /* 14 */ X#else X" h Left j Down ", -1,0,0, /* 8 */ X" k Up l Right ", -1,0,0, /* 9 */ X" 1 Loud q Quit game ", -1,0,0, /* 10 */ X" 0 Quiet ! Look at map ", -1,0,0, /* 11 */ X" S Save game R Restore Game ", -1,0,0, /* 12 */ X" ? Help mode @ Center screen ", -1,0,0, /* 13 */ X" ~ Jump level # Switch mode ", -1,0,0, /* 14 */ X#endif X" nb: No level bonus for jumping. ", -1,0,0, /* 15 */ X X#ifdef AMIGA X"This is you: ", -1,0,0, /* 0 */ X" ", 5,0,'@', /* 1 */ X" ", -1,0,0, /* 2 */ X#else X"This is you: You are a spider. ", -1,0,0, /* 0 */ X" (At least, that's ", 5,0,'@', /* 1 */ X" what you look like) ", -1,0,0, /* 2 */ X#endif X" ", -1,0,0, /* 3 */ X"The other items you will find are: ", -1,0,0, /* 4 */ X" ", -1,0,0, /* 5 */ X" ", 1,0,'#', /* 6 */ X" and Solid rock ", 10,-1,'=',/* 7 */ X" ", -1,0,0, /* 8 */ X" Time capsule (5 points, ", 2,0,'C', /* 9 */ X" +250 extra moves) ", -1,0,0, /* 10 */ X" ", -1,0,0, /* 11 */ X" Passable earth (one point) ", 2,0,':', /* 12 */ X" ", -1,0,0, /* 13 */ X" Teleport (50 points for ", 1,0,'T', /* 14 */ X" using it) ", -1,0,0, /* 15 */ X X" Boulder (falls down, other ", 2,0,'O', /* 0 */ X" boulders and arrows fall ", -1,0,0, /* 1 */ X" off of it) ", -1,0,0, /* 2 */ X" ", -1,0,0, /* 3 */ X" Arrows ", 1,0,'<', /* 4 */ X" and (run left and right)", 10,-1,'>',/* 5 */ X" ", -1,0,0, /* 6 */ X" Cage - holds baby monsters ", 2,0,'=', /* 7 */ X" and changes into diamonds ", -1,0,0, /* 8 */ X" ", -1,0,0, /* 9 */ X" (10 points) ", 2,0,'*', /* 10 */ X" Money (collect it) ", -1,0,0, /* 11 */ X" ", -1,0,0, /* 12 */ X" Baby monster (kills you) ", 2,0,'S', /* 13 */ X" ", -1,0,0, /* 14 */ X" ", -1,0,0, /* 15 */ X X"When a baby monster hits a cage it ", -1,0,0, /* 0 */ X"is captured and you get 50 points. ", -1,0,0, /* 1 */ X"The cage also becomes a diamond. ", -1,0,0, /* 2 */ X" ", -1,0,0, /* 3 */ X" Instant annihilation ", 1,0,'!', /* 4 */ X" ", -1,0,0, /* 5 */ X" ", -1,0,0, /* 6 */ X" Slopes (boulders ", 1,0,'\\',/* 7 */ X" and and etc slide off) ", 9,-1,'/',/* 8 */ X" ", -1,0,0, /* 9 */ X" Monster (eats you up whole. ", 1,0,'M', /* 10 */ X" Yum Yum yum..) (100 points) ", -1,0,0, /* 11 */ X" (kill with a rock or arrow) ", -1,0,0, /* 12 */ X" ", -1,0,0, /* 13 */ X" Exit -- Must Collect all the ", 1,0,'X', /* 14 */ X" treasure first. (250 bonus) ", -1,0,0, /* 15 */ X X" A new addition for version ", 1,0,'^', /* 0 */ X" 2.2M . The balloon rises, ", -1,0,0, /* 1 */ X" and is popped by arrows. It ", -1,0,0, /* 2 */ X" does *not* kill you. ", -1,0,0, /* 3 */ X" ", -1,0,0, /* 4 */ X" Unrecognised symbol in map. ", 1,0,'-', /* 5 */ X" This is probably a **bug** ! ", -1,0,0, /* 6 */ X" ", -1,0,0, /* 7 */ X" ENVIRONMENT VARIABLES: ", -1,0,0, /* 8 */ X" ", -1,0,0, /* 9 */ X" NEWNAME,NAME : Checked in that ", -1,0,0, /* 10 */ X" order for the hiscore table ", -1,0,0, /* 11 */ X" NEWKEYS : Redefine movement keys", -1,0,0, /* 12 */ X" eg- 'hlkj' for default ", -1,0,0, /* 13 */ X" SAVENAME : File used for saved ", -1,0,0, /* 14 */ X" games. ", -1,0,0 /* 15 */ X}; X X X Xvoid Xhelpme() /* routine to show help menu. */ X{ X int i = 0, i1 = 0, i2 = 0; /* loop counters */ X char ch; X X draw_box(0,0,43,19); X for(i1 = 0; i1 < 5; i1++) /* times to show loop. */ X { X setcolor(WHITE, DK_GREEN); X for(i = 0; i < 16; i++) /* show one menu. */ X { X move(i+1,1); /* move to start of line. */ X addstr(help[i2+i].text); X } X /* now go back and draw any icon images */ X for(i = 0; i < 16; i++) /* show one menu. */ X { X if (help[i2+i].col >= 0) X { X /* draw the beastie */ X draw_symbol(help[i2+i].col+1,i+help[i2+i].offrow,help[i2+i].icon); X } X } X X i2 += 16; X X move(i+1,1); /* move to start of line. */ X setcolor(YELLOW, DK_GREEN); X addstr("<return> to continue, <space> to exit"); X refresh(); /* show on screen. */ X ch = (char) getchar(); /* just for now, get anything. */ X if(ch == ' ') /* if return or what ever.. */ X break; /* exit routine now. */ X } X setcolor(TEXT_COLOR, BACK_COLOR); X for (i=0; i<19; i++) X { X move(i,0); /* move to start of line. */ X addstr(" "); X } X} X Xcredits() X{ X char buffer[512]; X FILE *fp; X int i; X clear(); X sprintf(buffer,"%s/credits",SCREENPATH); X if((fp = fopen(buffer,"r")) == NULL) { X addstr(" Sorry - credits unavailable!\n"); X } X else { X i = 0; X while(fgets(buffer,512,fp) != NULL) { X addstr(buffer); X if (++i == LINES-2) { X addstr("Press any key."); X refresh(); X getch(); X i = 0; X clear(); X } X } X } X addstr("Press any key."); X refresh(); X getch(); X} SHAR_EOF echo "extracting icon.c" sed 's/^X//' << \SHAR_EOF > icon.c X#include "wand_head.h" X X#ifdef AMIGA X#include "pw.images.h" /* AMIGA image bitmaps */ X#endif X Xvoid draw_symbol(x,y,ch) /* this is where the pretty graphics are */ X /* all defined - change them if you want.. */ Xint x,y; Xchar ch; X{ X#ifdef AMIGA X /* show graphics images on the AMIGA */ X struct Image *image; X switch(ch) X { X case ' ': /* space */ X image = &grassimage; X break; X case '#': /* rock */ X image = &rockimage; X break; X case '<': /* arrows */ X image = &leftarrowimage; X break; X case '>': X image = &rightarrowimage; X break; X case 'O': /* boulder */ X image = &boulderimage; X break; X case ':': /* earth */ X image = &earthimage; X break; X case '/': /* slopes */ X image = &leftslopeimage; X break; X case '\\': X image = &rightslopeimage; X break; X case '*': /* diamond */ X image = &diamondimage; X break; X case '=': /* rock */ X image = &rock2image; X break; X case '@': /* YOU!!! */ X image = &youimage; X break; X case 'T': /* teleport */ X image = &teleportimage; X break; X case 'X': /* exits */ X image = &exitimage; X break; X case '!': /* landmine */ X image = &bang1image; X break; X case 'M': /* big monster */ X image = &monsterimage; X break; X case 'S': /* baby monster */ X image = &babymonsterimage; X break; X case '^': /* balloon */ X image = &balloonimage; X break; X case 'C': /* time capsule */ X image = &timecapsuleimage; X break; X case '+': /* cage */ X image = &cageimage; X break; X default: /* this is what it uses if it doesnt */ X /* recognise the character */ X image = &unknownimage; X break; X } X DrawImage(R, image, x*8 + 8, y*8 + 8); X X#else X char icon[2][4], X (*iconrow)[4] = icon; X X switch(ch) X { X case ' ': /* space */ X strcpy(*iconrow++," "); X strcpy(*iconrow, " "); X break; X case '#': /* rock */ X strcpy(*iconrow++,"###"); X strcpy(*iconrow, "###"); X break; X case '<': /* arrows */ X strcpy(*iconrow++,"<--"); X strcpy(*iconrow, "<--"); X break; X case '>': X strcpy(*iconrow++,"-->"); X strcpy(*iconrow, "-->"); X break; X case 'O': /* boulder */ X strcpy(*iconrow++,"/^\\"); X strcpy(*iconrow, "\\_/"); X break; X case ':': /* earth */ X strcpy(*iconrow++,". ."); X strcpy(*iconrow, " . "); X break; X case '/': /* slopes */ X strcpy(*iconrow++," _/"); X strcpy(*iconrow, "/ "); X break; X case '\\': X strcpy(*iconrow++,"\\_ "); X strcpy(*iconrow, " \\"); X break; X case '*': /* diamond */ X strcpy(*iconrow++,"/$\\"); X strcpy(*iconrow, "\\$/"); X break; X case '=': /* rock */ X strcpy(*iconrow++,"=-="); X strcpy(*iconrow, "-=-"); X break; X case '@': /* YOU!!! */ X strcpy(*iconrow++," o "); X strcpy(*iconrow, "<|>"); X break; X case 'T': /* teleport */ X strcpy(*iconrow++,"(*)"); X strcpy(*iconrow, "(*)"); X break; X case 'X': /* exits */ X strcpy(*iconrow++,"Way"); X strcpy(*iconrow, "Out"); X break; X case '!': /* landmine */ X strcpy(*iconrow++," I "); X strcpy(*iconrow, " o "); X break; X case 'M': /* big monster */ X strcpy(*iconrow++,"}o{"); X strcpy(*iconrow, "/^\\"); X break; X case 'S': /* baby monster */ X strcpy(*iconrow++,"-o-"); X strcpy(*iconrow, "/*\\"); X break; X case '^': /* balloon */ X strcpy(*iconrow++,"/~\\"); X strcpy(*iconrow, "\\_X"); X break; X case 'C': /* time capsule */ X strcpy(*iconrow++," "); X strcpy(*iconrow, "<O>"); X break; X case '+': /* cage */ X strcpy(*iconrow++,"TTT"); X strcpy(*iconrow, "III"); X break; X default: /* this is what it uses if it doesnt */ X /* recognise the character */ X strcpy(*iconrow++,"OOO"); X strcpy(*iconrow, "OOO"); X break; X }; X move(y+1,x+1); X iconrow--; X addstr(*iconrow++); X move(y+2,x+1); X addstr(*iconrow); X#endif X} SHAR_EOF echo "extracting jump.c" sed 's/^X//' << \SHAR_EOF > jump.c X#include "wand_head.h" X Xextern int debug_disp; Xextern int no_passwords; Xextern int maxscreens; X X#ifndef DICTIONARY X /* use this stuff if no dictionary file is defined */ X /* feel free to change the words, but don't change how many there are */ X Xchar *dictionary[] = { /* 8 per line, total 128 (16 lines) */ X"zero","frog","insanity","hack","stardust","whimpy","lost","rattlesnake", X"panic","crisis","centipede","zaxxon","birdbrain","feeble","juggler","eunuchs", X"unix","amigoid","squirrel","moose","natasha","gyroscope","relax","superstar", X"winner","cheater","liberal","quail","insignificant","oxen","leap","orange", X"troll","zipper","drum","nuke","waste","want","secretword","wyrm", X"english","allegro","treefrog","bullfrog","dump","lunch","donut","lemon", X"helpme","fly","swim","joystick","rambo","leaf","horrible","unknown", X"high","mountain","mispeled","valley","zappa","glass","crunch","sdi", X"squiggly","worms","hint","wanderer","rogue","people","veggie","barf", X"exhausted","raygun","butcher","reebok","gnu","bicycle","fish","boulder", X"repeat","crisis","centipede","birdbrain","lost","rattler","snake","oops", X"squirrel","panic","zero","insanity","whimpy","nifty","crunch","oops", X"paperclip","keynote","keystone","vail","aspen","fall","short","dwarf", X"oboe","bazooka","bassoon","torpedo","risky","bored","cat","music", X"tinker","thunk","liver","onions","tastey","uggh","badnews","whynot", X"because","monster","quest","griffin","gomf","shoe","serpent","tammy" X}; X#endif X Xint scrn_passwd(num, passwd) /* reads password num into passwd */ Xint num; Xchar *passwd; X{ X#ifdef DICTIONARY X long position; X FILE *fp; X X position = PASSWD; X while(position > 200000) X position -= 200000; X if((fp = fopen(DICTIONARY,"r")) == NULL) X return 0; X fseek(fp,position,ftell(fp)); X while(fgetc(fp) != '\n'); X fscanf(fp,"%s\n",passwd); X /* read a word into passwd */ X fclose(fp); X return (1); X#else X static int firsttime = 1; X if (firsttime) X { X /* first time thru, shuffle the passwords in memory */ X /* this thwarts the disk browsers */ X register int i; X register char *temp; X X firsttime = 0; X for (i=0; i<64; i+=2) X { X temp = dictionary[i]; X dictionary[i] = dictionary[i+64]; X dictionary[i+64] = temp; X } X for (i=0; i<123; i+=3) X { X temp = dictionary[i]; X dictionary[i] = dictionary[i+2]; X dictionary[i+2] = dictionary[i+1]; X dictionary[i+1] = temp; X } X } X strcpy(passwd, dictionary[num&127]); X return (1); X#endif X} X Xvoid showpass(num) Xint num; X{ Xchar correct[20]; Xchar buffer[100]; Xchar ch; Xint passline; Xif(no_passwords) X return; Xif(!debug_disp) X passline = 18; Xelse X passline = 20; Xmove(passline,0); X Xif(!scrn_passwd(num,correct)) X return; X(void) sprintf(buffer,"The password to jump to level %d ( using ~ ) is : %s \n",(num+1),correct); Xaddstr(buffer); Xaddstr("PRESS ANY KEY TO REMOVE IT AND CONTINUE \n"); Xrefresh(); Xch = getch(); Xmove(passline,0); Xaddstr(" \n"); Xaddstr(" "); Xmove(passline,0); Xrefresh(); X} X Xint jumpscreen(num) Xint num; X{ Xchar word[20], X buffer[100], X correct[20]; Xint index=0; Xint scrn; Xint passline; X Xif (!debug_disp) X passline = 16; Xelse X passline = 18; X Xif(no_passwords == 1) { X move(passline,0); X addstr("Enter number of desired level.\n"); X refresh(); X scrn = getnum(); X if(scrn > num) { X move(passline,0); X addstr(" "); X return scrn; X } X move(passline,0); X addstr("No way, Jose! Back-jumping is prohibited!"); X refresh(); X return num; X } X Xmove(passline,0); Xaddstr("Please enter password of screen to jump to:"); Xrefresh(); Xwhile(((word[index++] = getch()) != '\n')&&(index < 19)) X { X addch('*'); X refresh(); X } Xword[--index]='\0'; Xmove(passline,0); Xaddstr("Validating... \n"); Xrefresh(); X Xif(strcmp(word,MASTERPASSWORD) == 0) X { X move(passline,0); X addstr("Enter number of desired level."); X refresh(); X num = getnum(); X (void) scrn_passwd(num-1,correct); X sprintf(buffer,"Certainly master, but the correct word is %s. \n",correct); X move(passline,0); X addstr(buffer); X addstr("PRESS ANY KEY TO REMOVE IT AND CONTINUE \n"); X refresh(); X getchar(); X move(passline,0); X addstr(" "); X move(passline+1,0); X addstr(" "); X move(passline,0); X refresh(); X return num; X } X Xfor(scrn = num;scrn < maxscreens;scrn++) { X if(!scrn_passwd(scrn,correct)) X break; X if(strcmp(correct,word) == 0) X { X move(passline,0); X addstr("Password Validated..... Jumping to desired screen. "); X refresh(); X return ++scrn; X } X } X Xmove(passline,0); Xaddstr("PASSWORD NOT RECOGNISED! Press any key... "); Xrefresh(); Xgetchar(); Xmove(passline,0); Xaddstr(" "); Xrefresh(); X Xreturn num; X} X Xint getnum() X{ Xchar ch; Xint num = 0; X for(ch = getch(),addch(ch),refresh(); ch >= '0' && ch <= '9'; ch = getch(),addch(ch),refresh()) X { X num = num * 10 + ch - '0'; X } X return num; X} SHAR_EOF echo "extracting m.c" sed 's/^X//' << \SHAR_EOF > m.c X#include "wand_head.h" X Xextern char *playscreen(); X Xextern int rscreen(); X Xextern int savescore(); X Xint debug_disp = 0; Xint no_passwords = 0; Xint maxscreens; Xchar screen[NOOFROWS][ROWLEN+1]; Xint edit_mode = 0; Xint saved_game = 0; Xchar *edit_screen; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ Xchar (*frow)[ROWLEN+1] = screen; Xint num,score,bell = 0,maxmoves,fp,x,y; Xchar howdead[25],buffer[100], X *name,*keys,*dead,ch; Xchar *malloc(); X Xif(argc == 2) X { X if(!strcmp(argv[1], "-e")) X { X edit_mode = 1; X edit_screen = NULL; X } X else if(!strcmp(argv[1], "-m")) X { X initscr(); X erase_scores(); X endwin(); X exit(0); X } X else if(!strcmp(argv[1], "-c")) X { X /* show credits */ X initscr(); X credits(); X endwin(); X exit(0); X } X else if(!strcmp(argv[1], "-s")) X { X initscr(); X savescore("-",0,0,"-"); X addstr("press any key"); X getch(); X endwin(); X exit(0); X } X else if(!strcmp(argv[1], "-f")) X { X debug_disp = 1; X } X else X { X fprintf(stderr,"Usage: %s [ -e [ file ] | -m | -c | -s | -f ]\n",argv[0]); X exit(1); X } X } Xif(argc > 2) X { X if(!strcmp(argv[1],"-e")) X { X edit_mode = 1; X edit_screen = argv[2]; X } X else X { X fprintf(stderr,"Usage: %s [ -e [ file ] | -m | -c | -s | -f ]\n",argv[0]); X exit(1); X } X } X X/* check for passwords - if file no_pws is in screen dir no pws! */ Xsprintf(buffer,"%s/no_pws",SCREENPATH); Xif((fp = open(buffer,O_RDONLY)) != -1) { X close(fp); X no_passwords = 1; X} X X/* count available screens */ Xfor(maxscreens = 0;;maxscreens++) { X sprintf(buffer,"%s/screen.%d",SCREENPATH,(maxscreens+1)); X if((fp = open(buffer, O_RDONLY)) == -1 ) X break; X close(fp); X} X Xinitscr(); X Xif((name = (char *)getenv("NEWNAME")) == NULL) X if((name = (char *)getenv("NAME")) == NULL) X if((name = (char *)getenv("FULLNAME")) == NULL) X if((name = (char *)getenv("USER")) == NULL) X if((name = (char *)getenv("LOGNAME")) == NULL) X#ifdef ASKNAME /* M001 */ X { X name = malloc(80); X if (name == NULL) { X addstr("malloc error\n"); X refresh(); X endwin(); X exit(1); X } X X draw_box(3,10,40,5); X move(5,12); X setcolor(YELLOW, DK_GREEN); X addstr("What is your name? "); X refresh(); X echo(); CBOFF; X gets(name); X noecho(); CBON; X setcolor(TEXT_COLOR, BACK_COLOR); X if (name[0] == '\0') X name = "noname"; X } X#else X name = "noname"; X#endif X Xif((keys = (char *)getenv("NEWKEYS")) == NULL) X { X keys = "kjhl"; X } X X/* MAIN PROGRAM HERE */ X XCBON; noecho(); X Xwhile (1) X{ X num = 1; X score = 0; X maxmoves = 0; X clear(); X if(!edit_mode) { X for (;;) { X if (rscreen(num,&maxmoves)) { X strcpy(howdead,"a non-existant screen"); X break; X }; X dead = playscreen(&num,&score,&bell,maxmoves,keys); X if ((dead != NULL) && (*dead == '~')) { X num = (int)(dead[1]) - 1; X dead = NULL; X } X if (dead != NULL) X { X strcpy(howdead,dead); X break; X } X num++; X } X X playSound(DEATH_SOUND); X clear(); X setcolor(RED, BLACK); X sprintf(buffer,"%s killed by %s with a score of %d on level %d.\n",name,howdead,score,num); X addstr(buffer); X } X else X { X if(rscreen(num,&maxmoves)) X { X for(x=0;x<ROWLEN;x++) X for(y=0;y<NOOFROWS;y++) X screen[y][x] = ' '; X } X editscreen(num,&score,&bell,maxmoves,keys); X } X /* END OF MAIN PROGRAM */ X X /* SAVE ROUTINES FOR SCORES */ X X if(!edit_mode) X { X setcolor(WHITE, BLACK); X if((savescore(howdead,score,num,name) == 0)&&(score != 0)) X addstr("\nWARNING: score not saved!\n\n"); X } X setcolor(RED, BLACK); X addstr("WANDERER (C)1988 S. Shipway."); X#ifdef AMIGA X addstr(" AMIGA version by Alan Bland."); X#endif X X /* ask if they want to play again - save loading time on floppy-based systems */ X setcolor(LT_GREEN, BLACK); X addstr("\nDo you want to try again? "); X refresh(); X while ((ch = getch()) != 'y' && ch != 'n') {} X if (ch == 'n') break; X} X Xecho(); XCBOFF; Xendwin(); Xexit(0); X} SHAR_EOF echo "extracting read.c" sed 's/^X//' << \SHAR_EOF > read.c X#include "wand_head.h" X Xextern int edit_mode; Xextern char *edit_screen; Xextern char screen[NOOFROWS][ROWLEN+1]; X Xint rscreen(num,maxmoves) Xint *maxmoves, num; X{ Xint y,ch; XFILE *fp; Xchar name[50], buffer[80]; Xchar (*row_ptr)[ROWLEN+1] = screen; Xif(!edit_mode) X sprintf(name,"%s/screen.%d",SCREENPATH,num); Xelse X { X if(!edit_screen) X sprintf(name,"screen"); X else X sprintf(name,"%s",edit_screen); X } Xfp = fopen(name,"r"); Xif(fp == NULL) X { X if(edit_mode) X sprintf(buffer,"\nCannot find file %s.\n\n",name); X else X sprintf(buffer,"\nFile for screen %d unavailable.\n\n",num) ; X addstr(buffer); X } Xelse X { X for(y = 0;y<NOOFROWS;y++) X { X fgets((*row_ptr++),ROWLEN + 1,fp); X#ifndef AMIGA X /* for some reason Amiga Lattice C behaves differently here */ X /* Amiga already removed the newline character */ X fgetc(fp); /* remove newline char*/ X#endif X } X /* skip over final line, then read number of moves permitted */ X while ( (ch = fgetc(fp)) != '\n' && ch != EOF) {} X if(fscanf(fp,"%d",maxmoves) != 1) X *maxmoves=0; X fclose(fp); X } Xreturn (fp == NULL); X} X Xint wscreen(num,maxmoves) Xint maxmoves, num; X{ Xint y,x; XFILE *fp; Xchar name[50]; Xchar (*row_ptr)[ROWLEN+1] = screen; Xif(!edit_screen) X sprintf(name,"screen"); Xelse X sprintf(name,"%s",edit_screen); Xfp = fopen(name,"w"); Xif(fp == NULL) X { X#ifdef AMIGA X strcpy(name, "ram:screenfile"); X#else X sprintf(name,"/tmp/screen.%d",getpid()); X#endif X fp = fopen(name,"w"); X move(21,0); X addstr("Written file is "); X addstr(name); X refresh(); X } Xif(fp == NULL) X addstr("\nFile for screen cannot be written.\n\n") ; Xelse X { X for(y = 0;y<NOOFROWS;y++) X { X for(x = 0;x<ROWLEN;x++) X fputc(row_ptr[y][x],fp); X fputc('\n',fp); X }; X for(x = 0; x<ROWLEN;x++) X fputc('#',fp); X fputc('\n',fp); X if(maxmoves != 0) X fprintf(fp,"%d\n",maxmoves); X fclose(fp); X }; Xreturn (fp == NULL); X} SHAR_EOF echo "extracting save.c" sed 's/^X//' << \SHAR_EOF > save.c X#include "wand_head.h" X#include <errno.h> X Xextern char screen[NOOFROWS][ROWLEN+1]; Xextern int saved_game; X Xextern void crypt_file(); Xstruct saved_game { X short num; X short score; X short bell; X short maxmoves; X short num_monsters; X}; X Xstruct save_vars zz; X X/* save game and exit - if trouble occurs, return to game */ Xvoid Xsave_game(num, score, bell, maxmoves, start_of_list, tail_of_list) Xint num, *score, *bell, maxmoves; Xstruct mon_rec *start_of_list, *tail_of_list; X{ X char fname[128], *fp, buffer[40]; X FILE *fo; X struct saved_game s; X extern char *getenv(); X struct mon_rec *mp; X X clear(); X X if ((char *)NULL == (fp = getenv("SAVENAME"))) { X addstr("Saving game.... Filename ? "); X refresh(); X fp = fname; X echo(); CBOFF; X gets(fp); X CBON; noecho(); X } X if ((FILE *)NULL == (fo = fopen(fp, W_BIN))) { X addstr("\nUnable to save game, press any key."); X refresh(); X getch(); X return; X } X X s.num = num; X s.score = *score; X s.bell = *bell; X s.maxmoves = maxmoves; X s.num_monsters = 0; X X mp = start_of_list; /* first entry is dummy */ X while (mp != tail_of_list) { X mp = mp->next; X s.num_monsters++; /* count them monsters */ X } X X if ( (1 != fwrite((char *)&s, sizeof(s), 1, fo)) || X (1 != fwrite((char *)screen, sizeof(screen), 1, fo)) || X (1 != fwrite((char *)&zz, sizeof(zz), 1, fo)) ) X { X goto file_error; X } X X mp = start_of_list; X while (mp != tail_of_list) { X /* save them monsters */ X mp = mp->next; X if (1 != fwrite((char *)mp, sizeof(struct mon_rec), 1, fo)) { Xfile_error: X sprintf(buffer, "Write error on '%s', press any key.", fname); X addstr(buffer); X refresh(); X fclose(fo); X unlink(fname); X getch(); X return; X } X } X X fclose(fo); X#ifndef NO_ENCRYPTION X crypt_file(fp,0); /* encrpyt the saved game */ X#endif X echo(); X CBOFF; X endwin(); X exit(0); X} X Xvoid Xrestore_game(num, score, bell, maxmoves, start_of_list, tail_of_list) Xint *num, *score, *bell, *maxmoves; Xstruct mon_rec *start_of_list, **tail_of_list; X{ X FILE *fi; X struct saved_game s; X struct mon_rec *mp, *tmp, tmp_monst; X char fname[128], *fp, buffer[80]; X FILE *fo; X extern char *getenv(); X X if ((char *)NULL == (fp = getenv("SAVENAME"))) { X move((LINES-1),0); X addstr("Restore Filename ? "); X refresh(); X echo(); CBOFF; X fp = fname; X gets(fp); X CBON; noecho(); X } X clear(); X refresh(); X#ifndef NO_ENCRYPTION X crypt_file(fp,1); /*decrypt it*/ X#endif X if ((FILE *)NULL == (fi = fopen(fp, R_BIN))) { X sprintf(buffer, "Open error on '%s'\n", fp); X addstr(buffer); X goto cant_restore; X } X if ( (1 != fread((char *)&s, sizeof(s), 1, fi)) || X (1 != fread((char *)screen, sizeof(screen), 1, fi)) || X (1 != fread((char *)&zz, sizeof(zz), 1, fi)) ) { X sprintf(buffer, "Read error on '%s'\n", fp); X addstr(buffer); X fclose(fi); X goto cant_restore; X } X X *num = s.num; X *score = s.score; X *bell = s.bell; X *maxmoves = s.maxmoves; X X /* free any monsters already on chain, to start clean */ X mp = start_of_list->next; X while ((mp != NULL) && (mp != start_of_list)) { X /* free them monsters */ X tmp = mp; X mp = mp->next; X free(tmp); X } X X /* re-initialize the monster list */ X /* *start_of_list = {0,0,0,0,0,NULL,NULL}; */ X start_of_list->x = 0; X start_of_list->y = 0; X start_of_list->mx = 0; X start_of_list->my = 0; X start_of_list->under = 0; X start_of_list->next = (struct mon_rec *)NULL; X start_of_list->prev = (struct mon_rec *)NULL; X X *tail_of_list = start_of_list; X X while (s.num_monsters--) { X /* use make_monster to allocate the monster structures */ X /* to get all the linking right without even trying */ X if ((struct mon_rec *)NULL == (mp = make_monster(0, 0))) { X sprintf(buffer,"Monster alloc error on '%s'\n", fp); X addstr(buffer); X addstr("Try again - it might work.\nBut then,pigs might fly...\n"); X fclose(fi); X goto cant_restore; X } X if (1 != fread((char *)&tmp_monst, sizeof(struct mon_rec), 1, fi)) { X sprintf(buffer,"Monster read error on '%s'\n", fp); X addstr(buffer); X fclose(fi); Xcant_restore: X addstr("Cannot restore game --- sorry.\n"); X addstr("Press any key..."); X refresh(); X getch(); X endwin(); X exit(1); X } X /* copy info without trashing links */ X mp->x = tmp_monst.x; X mp->y = tmp_monst.y; X mp->mx = tmp_monst.mx; X mp->my = tmp_monst.my; X mp->under = tmp_monst.under; X } X X fclose(fi); X unlink(fp); X saved_game = 1; X} SHAR_EOF echo "extracting scores.c" sed 's/^X//' << \SHAR_EOF > scores.c X#include "wand_head.h" X X#if MSDOS | AMIGA /* M001 */ X#define LOCK X#define UNLOCK X#else X#define LOCK while((lock = creat(LOCKPATH,0)) < 0) X#define UNLOCK (void) unlink(LOCKPATH) X#endif X X#define ENTRIES 15 X X#if MSDOS | AMIGA /* M001 */ X#define getuid() 0 X#else Xextern int getuid(); X#endif X Xextern int saved_game; /* prevent recording of hiscore if */ X /* NO_RESTORED_GAME_HISCORES is #def'd */ X Xtypedef struct X { X char howdead[25]; X char name[20]; X int score; X int level; X int uid; X } score_entry; X X#ifdef LINT_ARGS /* M001 */ Xvoid show_scores(score_entry *,int ); Xint readtable(score_entry *); X#else Xvoid show_scores(); Xint readtable(); X#endif X Xvoid show_scores(table,num) Xscore_entry *table; Xint num; X{ Xint tot = num; X X/* only show the top ten */ Xif (num > 10) num = tot = 10; X Xaddstr("\nNo. Score Level Names How they died\n"); Xaddstr("=============================================================================\n"); Xwhile(num > 0) X { X char buffer[80]; X num--; X sprintf(buffer,"%2d %5d %3d %-20s killed by %-s\n",(tot - num),table->score,table->level,table->name,table->howdead); X addstr(buffer); X table++; X } Xaddstr("\n"); X} X Xint readtable(table_ptr) Xscore_entry *table_ptr; X{ XFILE *fp; Xint numread; Xif((fp = fopen(HISCOREPATH,R_BIN)) == NULL) X { X numread = 0; X } Xelse X { X numread = fread( VOIDSTAR table_ptr, sizeof(score_entry), ENTRIES, fp); X fclose(fp); X } Xreturn numread; X} X Xint savescore(howdead,score,level,name) Xchar *howdead, *name; Xint score,level; X{ Xscore_entry table[ENTRIES + 2], X *table_ptr = table,new_entry,temp_entry; Xint numread,index = 1, numsaved, lock, already = 0, output_value = 1, X user_id; XFILE *fp; X#ifdef NO_RESTORED_GAME_HISCORES Xif(saved_game) { X addstr("No hiscores recorded from restored games.\n"); X addstr("\nWanderer (C) 1988 S.Shipway.\n\n"); X return 1; X} X#endif Xuser_id = getuid(); Xstrncpy(new_entry.howdead,howdead,25); Xnew_entry.howdead[24] = '\0'; /* M002 strncpy does not null terminate */ Xstrncpy(new_entry.name,name,20); Xnew_entry.name[19] = '\0'; /* M002 strncpy does not null terminate */ Xnew_entry.score = score; Xnew_entry.level = level; Xnew_entry.uid = user_id; XLOCK; Xnumread = readtable(table_ptr); Xif (numread > 0) X if(table[numread-1].score > 99999) /* stop system errors messing it up*/ X { X numread--; X addstr("Erasing spurious entry in table.\n"); X } Xif(score == 0) X { X show_scores(table,numread); X UNLOCK; X return 0; X } Xif (numread > 0) X { X numread++; /* scan through until correct insertion point */ X /* pass table entries with higher scores */ X while((table_ptr->score > score)&&(index < numread)) X { X#ifdef COMPARE_BY_NAME X#define SAMEUSER(p) (strcmp((p)->name, name) == 0) X#else X#define SAMEUSER(p) ((p)->uid == user_id) X#endif X if(SAMEUSER(table_ptr)) X { X already = 1; X break; X } X table_ptr++; X index++; X } X /* pass table entries with equal score but higher or equal level */ X while((table_ptr->level>=level)&&(index<numread)&&(table_ptr->score==score)) X { X if(SAMEUSER(table_ptr)) X { X already = 1; X break; X } X table_ptr++; X index++; X } X /* if already found: done */ X if(already == 1) X { X numread--; X show_scores(table,numread); X UNLOCK; X return numread; X } X /* shift down score list */ X while(index < numread) X { X /* swap *table_ptr and new_entry */ X temp_entry = *table_ptr; X *table_ptr = new_entry; X new_entry = temp_entry; X if(SAMEUSER(&new_entry)) X { X already = 1; X numread--; /* an older entry found */ X break; X } X table_ptr++; X index++; X } X /* if all shifted without finding an older entry */ X if(already==0) X *table_ptr = new_entry; X } Xelse X { X addstr("\nCreating new hiscore table.\n\n"); X *table_ptr = new_entry; X numread++; X } Xnumread = ( (numread > ENTRIES) ? ENTRIES : numread ); Xif ((fp = fopen(HISCOREPATH,W_BIN)) == NULL) X { X UNLOCK; X return 0; X } Xtable_ptr = table; Xnumsaved = fwrite( VOIDSTAR table_ptr, sizeof(score_entry), numread, fp); Xchmod(HISCOREPATH,0666); Xif(numsaved < numread) X { X output_value = 0; X } Xfclose(fp); XUNLOCK; Xshow_scores(table,numsaved); Xreturn output_value; X} X Xvoid delete_entry(num) Xint num; X{ Xscore_entry table[ENTRIES + 22], X *table_ptr = table; Xint numread,index = 1, numsaved, lock, output_value = 1; XFILE *fp; XLOCK; Xnumread = readtable(table_ptr); Xif (numread == 0) { X addstr("Missing or unreadable hiscore table.\n\n"); X UNLOCK; X exit(1); X} Xif (num > numread) { X addstr("Invalid entry, choose again\n"); X UNLOCK; X return; X} Xwhile(index < num) X { X index++; X table_ptr++; X } Xwhile(index < numread) X { X index++; X *table_ptr = *(table_ptr+1); X table_ptr++; X } Xnumread--; Xfp = fopen(HISCOREPATH,W_BIN); Xtable_ptr = table; Xnumsaved = fwrite( VOIDSTAR table_ptr, sizeof(score_entry), numread, fp); Xchmod(HISCOREPATH,0666); Xif(numsaved < numread) X { X output_value = 0; X } Xfclose(fp); XUNLOCK; Xshow_scores(table,numsaved); X} X Xerase_scores() X{ Xint erasenum,numread,index = 0; Xchar correct[20],c,buffer[20]; Xscore_entry table[ENTRIES + 2], X *table_ptr = table; Xaddstr("Please enter password:"); Xwhile((c = getchar()) != '\n' && index <19) { X correct[index++] = c; X } Xcorrect[index] = 0; Xif(strcmp(correct,MASTERPASSWORD)) X { X addstr("\nFoo, charlatan!\n"); X return 0; X } Xnumread = readtable(table_ptr); Xshow_scores(table,numread); Xaddstr("\n"); Xfor(;;) X{ Xaddstr("Number to erase (0 to exit): "); Xgets(buffer); Xerasenum = atoi(buffer); Xaddstr("\n"); Xif(erasenum == 0) X break; Xdelete_entry(erasenum); Xaddstr("\n"); X} Xaddstr("Byee!\n"); X} SHAR_EOF echo "extracting wand_head.h" sed 's/^X//' << \SHAR_EOF > wand_head.h X#include <stdio.h> X#include <curses.h> X#include <string.h> X#include <fcntl.h> X X/* I wouldnt change these if I were you - it wont give you a bigger screen */ X#define ROWLEN 40 X#define NOOFROWS 16 X X/* Change these to the necessary directories or files */ X#define SCREENPATH "/usr/games/lib/wand/screens" X#define HISCOREPATH "/usr/games/lib/wand/hiscore" X#define LOCKPATH "/tmp/wanderer.lock" /* hiscore lock file */ X#define DICTIONARY "/usr/dict/words" X X/* change this to anything, but dont forget what */ X#define MASTERPASSWORD "squiggly worms" X X/* change the numbers in this as well, but keep it in the same form */ X#define PASSWD (num * num * 4373 + num * 16927 + 39) X X/* To disable the recording of hiscores from games restored from saves */ X/* #define NO_RESTORED_GAME_HISCORES */ X/* #define COMPARE_BY_NAME define this to compare by name, not uid */ X#define GUESTUID 0 /* guestuid always compared by name */ X/* #define NO_ENCRYPTION define this to disable the savefile encryptor */ X/* cbreak switching via curses package. */ X/* on some Ultrix systems you may need to use crmode() and nocrmode() */ X/* if so, just change the #defs to the necessary. I also know that Xenix */ X/* systems have to use crmode, so.. */ X#ifdef XENIX X#define CBON crmode() X#define CBOFF nocrmode() X#else X#define CBON cbreak() X#define CBOFF nocbreak() X#endif X X/* AMIGA version supports color and sound. for other versions */ X/* the following macros expand to nothing. */ X#ifndef AMIGA X#define setcolor(forecolor, backcolor) X#define playSound(whichone) X#define cursor(state) X#endif X X/* MSDOS modifications (M001) by Gregory H. Margo */ X#ifdef MSDOS X#define R_BIN "rb" /* binary mode for non-text files */ X#define W_BIN "wb" X# ifdef VOIDPTR X# define VOIDSTAR (void *) X# else X# define VOIDSTAR (char *) X# endif X#define ASKNAME /* ask user's name if not in environment */ X#define COMPARE_BY_NAME /* compare users with name, not uid */ X#undef getchar /* remove stdio's definition to use curses' */ X#define getchar() getch() /* use curse's definition instead */ X X#else /* not MSDOS */ X#define R_BIN "r" X#define W_BIN "w" X#define VOIDSTAR X#endif X X/* AMIGA modifications by Alan Bland */ X#ifdef AMIGA X#undef SCREENPATH X#undef HISCOREPATH X#undef DICTIONARY X#define SCREENPATH "screens" X#define HISCOREPATH "hiscore" X#define ASKNAME /* ask user's name if not in environment */ X#define COMPARE_BY_NAME /* compare users with name, not uid */ X#define NO_ENCRYPTION /* define this to disable the savefile encryptor */ X#define LINT_ARGS /* Lattice compiler uses ANSI prototypes */ X#undef VOIDSTAR X#define VOIDSTAR (void *) X#undef getchar /* remove stdio's definition to use curses' */ X#define getchar() getch() /* use curse's definition instead */ X#define gets(s) getstr(s) /* curses version */ X#include "sounds.h" /* index into sound table */ X#endif X X/* Save and Restore game additions (M002) by Gregory H. Margo */ X/* mon_rec structure needed by save.c */ Xstruct mon_rec X { X int x,y,mx,my; X char under; X struct mon_rec *next,*prev; X }; X X Xstruct save_vars { X int z_x, z_y, X z_nx, z_ny, X z_sx, z_sy, X z_tx, z_ty, X z_lx, z_ly, X z_mx, z_my, X z_bx, z_by, X z_nbx, z_nby, X z_max_score, X z_diamonds, X z_nf, X z_hd, X z_vd, X z_xdirection, X z_ydirection; X}; X X/* prototypes added by Gregory H. Margo */ X#ifdef LINT_ARGS /* M001 */ X/* DISPLAY.c */ Xextern void map(char (*)[ROWLEN+1]); Xextern void display(int ,int ,char (*)[ROWLEN+1],int ); X X/* EDIT.C */ Xextern void instruct(void); Xextern void noins(void); Xextern void editscreen(int ,int *,int *,int ,char *); X X/* FALL.C */ Xextern int check(int *,int *,int ,int ,int ,int ,int ,int ,char *); Xextern int fall(int *,int *,int ,int ,int ,int ,char *); X X/* GAME.C */ Xextern struct mon_rec *make_monster(int ,int ); Xextern char *playscreen(int *,int *,int *,int ,char *); X X/* ICON.C */ Xextern void draw_symbol(int ,int ,char ); X X/* JUMP.C */ Xextern int scrn_passwd(int ,char *); Xextern void showpass(int ); Xextern int jumpscreen(int ); Xextern int getnum(void); X X/* READ.C */ Xextern int rscreen(int ,int *); Xextern int wscreen(int ,int ); X X/* SAVE.C */ Xextern void save_game(int ,int *,int *,int ,struct mon_rec *,struct mon_rec *); Xextern void restore_game(int *,int *,int *,int *,struct mon_rec *,struct mon_rec **); X X/* SCORES.C */ Xextern int savescore(char *,int ,int ,char *); Xextern void delete_entry(int ); Xextern int erase_scores(void); X X#else X X/* DISPLAY.c */ Xextern void map(); Xextern void display(); X X/* EDIT.C */ Xextern void instruct(); Xextern void noins(); Xextern void editscreen(); X X/* FALL.C */ Xextern int check(); Xextern int fall(); X X/* GAME.C */ Xextern struct mon_rec *make_monster(); Xextern char *playscreen(); X X/* ICON.C */ Xextern void draw_symbol(); X X/* JUMP.C */ Xextern int scrn_passwd(); Xextern void showpass(); Xextern int jumpscreen(); Xextern int getnum(); X X/* READ.C */ Xextern int rscreen(); Xextern int wscreen(); X X/* SAVE.C */ Xextern void save_game(); Xextern void restore_game(); X X/* SCORES.C */ Xextern int savescore(); Xextern void delete_entry(); Xextern int erase_scores(); X X#endif SHAR_EOF echo "End of archive 3 (of 3)" # if you want to concatenate archives, remove anything after this line exit