/* SAVE- SAVE GAME STATE */ /*COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142*/ /* ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED */ /* WRITTEN BY R. M. SUPNIK */ #include #include "funcs.h" #include "vars.h" /* DECLARATIONS */ static integer cxappl_ P((integer)); void savegm_() { /* Local variables */ integer i; FILE *e; prsvec_1.prswon = FALSE_; /* !DISABLE GAME. */ /* Note: save file format is different for PDP vs. non-PDP versions */ if ((e = fopen("dsave.dat", BINWRITE)) == NULL) goto L100; gttime_(&i); /* !GET TIME. */ #define do_uio(i, zbuf, cbytes) \ (void) fwrite((const char *)(zbuf), (cbytes), (i), e) do_uio(1, &vers_1.vmaj, sizeof(integer)); do_uio(1, &vers_1.vmin, sizeof(integer)); do_uio(1, &vers_1.vedit, sizeof(integer)); do_uio(1, &play_1.winner, sizeof(integer)); do_uio(1, &play_1.here, sizeof(integer)); do_uio(1, &hack_1.thfpos, sizeof(integer)); do_uio(1, &play_1.telflg, sizeof(logical)); do_uio(1, &hack_1.thfflg, sizeof(logical)); do_uio(1, &hack_1.thfact, sizeof(logical)); do_uio(1, &hack_1.swdact, sizeof(logical)); do_uio(1, &hack_1.swdsta, sizeof(integer)); do_uio(64, &puzzle_1.cpvec[0], sizeof(integer)); do_uio(1, &i, sizeof(integer)); do_uio(1, &state_1.moves, sizeof(integer)); do_uio(1, &state_1.deaths, sizeof(integer)); do_uio(1, &state_1.rwscor, sizeof(integer)); do_uio(1, &state_1.egscor, sizeof(integer)); do_uio(1, &state_1.mxload, sizeof(integer)); do_uio(1, &state_1.ltshft, sizeof(integer)); do_uio(1, &state_1.bloc, sizeof(integer)); do_uio(1, &state_1.mungrm, sizeof(integer)); do_uio(1, &state_1.hs, sizeof(integer)); do_uio(1, &screen_1.fromdr, sizeof(integer)); do_uio(1, &screen_1.scolrm, sizeof(integer)); do_uio(1, &screen_1.scolac, sizeof(integer)); do_uio(220, &objcts_1.odesc1[0], sizeof(integer)); do_uio(220, &objcts_1.odesc2[0], sizeof(integer)); do_uio(220, &objcts_1.oflag1[0], sizeof(integer)); do_uio(220, &objcts_1.oflag2[0], sizeof(integer)); do_uio(220, &objcts_1.ofval[0], sizeof(integer)); do_uio(220, &objcts_1.otval[0], sizeof(integer)); do_uio(220, &objcts_1.osize[0], sizeof(integer)); do_uio(220, &objcts_1.ocapac[0], sizeof(integer)); do_uio(220, &objcts_1.oroom[0], sizeof(integer)); do_uio(220, &objcts_1.oadv[0], sizeof(integer)); do_uio(220, &objcts_1.ocan[0], sizeof(integer)); do_uio(200, &rooms_1.rval[0], sizeof(integer)); do_uio(200, &rooms_1.rflag[0], sizeof(integer)); do_uio(4, &advs_1.aroom[0], sizeof(integer)); do_uio(4, &advs_1.ascore[0], sizeof(integer)); do_uio(4, &advs_1.avehic[0], sizeof(integer)); do_uio(4, &advs_1.astren[0], sizeof(integer)); do_uio(4, &advs_1.aflag[0], sizeof(integer)); do_uio(46, &flags[0], sizeof(logical)); do_uio(22, &switch_[0], sizeof(integer)); do_uio(4, &vill_1.vprob[0], sizeof(integer)); do_uio(25, &cevent_1.cflag[0], sizeof(logical)); do_uio(25, &cevent_1.ctick[0], sizeof(integer)); #undef do_uio if (fclose(e) == EOF) goto L100; rspeak_(597); return; L100: rspeak_(598); /* !CANT DO IT. */ } /* savegm_ */ /* RESTORE- RESTORE GAME STATE */ /* DECLARATIONS */ void rstrgm_() { /* Local variables */ integer i, j, k; FILE *e; prsvec_1.prswon = FALSE_; /* !DISABLE GAME. */ /* Note: save file format is different for PDP vs. non-PDP versions */ if ((e = fopen("dsave.dat", BINREAD)) == NULL) goto L100; #define do_uio(i, zbuf, cbytes) \ (void)fread((char *)(zbuf), (cbytes), (i), e) do_uio(1, &i, sizeof(integer)); do_uio(1, &j, sizeof(integer)); do_uio(1, &k, sizeof(integer)); if (i != vers_1.vmaj | j != vers_1.vmin) { goto L200; } do_uio(1, &play_1.winner, sizeof(integer)); do_uio(1, &play_1.here, sizeof(integer)); do_uio(1, &hack_1.thfpos, sizeof(integer)); do_uio(1, &play_1.telflg, sizeof(logical)); do_uio(1, &hack_1.thfflg, sizeof(logical)); do_uio(1, &hack_1.thfact, sizeof(logical)); do_uio(1, &hack_1.swdact, sizeof(logical)); do_uio(1, &hack_1.swdsta, sizeof(integer)); do_uio(64, &puzzle_1.cpvec[0], sizeof(integer)); do_uio(1, &time_1.pltime, sizeof(integer)); do_uio(1, &state_1.moves, sizeof(integer)); do_uio(1, &state_1.deaths, sizeof(integer)); do_uio(1, &state_1.rwscor, sizeof(integer)); do_uio(1, &state_1.egscor, sizeof(integer)); do_uio(1, &state_1.mxload, sizeof(integer)); do_uio(1, &state_1.ltshft, sizeof(integer)); do_uio(1, &state_1.bloc, sizeof(integer)); do_uio(1, &state_1.mungrm, sizeof(integer)); do_uio(1, &state_1.hs, sizeof(integer)); do_uio(1, &screen_1.fromdr, sizeof(integer)); do_uio(1, &screen_1.scolrm, sizeof(integer)); do_uio(1, &screen_1.scolac, sizeof(integer)); do_uio(220, &objcts_1.odesc1[0], sizeof(integer)); do_uio(220, &objcts_1.odesc2[0], sizeof(integer)); do_uio(220, &objcts_1.oflag1[0], sizeof(integer)); do_uio(220, &objcts_1.oflag2[0], sizeof(integer)); do_uio(220, &objcts_1.ofval[0], sizeof(integer)); do_uio(220, &objcts_1.otval[0], sizeof(integer)); do_uio(220, &objcts_1.osize[0], sizeof(integer)); do_uio(220, &objcts_1.ocapac[0], sizeof(integer)); do_uio(220, &objcts_1.oroom[0], sizeof(integer)); do_uio(220, &objcts_1.oadv[0], sizeof(integer)); do_uio(220, &objcts_1.ocan[0], sizeof(integer)); do_uio(200, &rooms_1.rval[0], sizeof(integer)); do_uio(200, &rooms_1.rflag[0], sizeof(integer)); do_uio(4, &advs_1.aroom[0], sizeof(integer)); do_uio(4, &advs_1.ascore[0], sizeof(integer)); do_uio(4, &advs_1.avehic[0], sizeof(integer)); do_uio(4, &advs_1.astren[0], sizeof(integer)); do_uio(4, &advs_1.aflag[0], sizeof(integer)); do_uio(46, &flags[0], sizeof(logical)); do_uio(22, &switch_[0], sizeof(integer)); do_uio(4, &vill_1.vprob[0], sizeof(integer)); do_uio(25, &cevent_1.cflag[0], sizeof(logical)); do_uio(25, &cevent_1.ctick[0], sizeof(integer)); (void)fclose(e); rspeak_(599); return; L100: rspeak_(598); /* !CANT DO IT. */ return; L200: rspeak_(600); /* !OBSOLETE VERSION */ (void)fclose(e); } /* rstrgm_ */ /* WALK- MOVE IN SPECIFIED DIRECTION */ /* DECLARATIONS */ logical walk_() { /* System generated locals */ logical ret_val; ret_val = TRUE_; /* !ASSUME WINS. */ if (play_1.winner != aindex_1.player || lit_(play_1.here) || prob_(25, 25)) { goto L500; } if (! findxt_(prsvec_1.prso, play_1.here)) { goto L450; } /* !INVALID EXIT? GRUE */ /* ! */ switch (curxt_1.xtype) { case 1: goto L400; case 2: goto L200; case 3: goto L100; case 4: goto L300; } /* !DECODE EXIT TYPE. */ bug_(9, curxt_1.xtype); L100: if (cxappl_(curxt_1.xactio) != 0) { goto L400; } /* !CEXIT... RETURNED ROOM? */ if (flags[*xflag - 1]) { goto L400; } /* !NO, FLAG ON? */ L200: jigsup_(523); /* !BAD EXIT, GRUE */ /* ! */ return ret_val; L300: if (cxappl_(curxt_1.xactio) != 0) { goto L400; } /* !DOOR... RETURNED ROOM? */ if ((objcts_1.oflag2[curxt_1.xobj - 1] & OPENBT) != 0) { goto L400; } /* !NO, DOOR OPEN? */ jigsup_(523); /* !BAD EXIT, GRUE */ /* ! */ return ret_val; L400: if (lit_(curxt_1.xroom1)) { goto L900; } /* !VALID ROOM, IS IT LIT? */ L450: jigsup_(522); /* !NO, GRUE */ /* ! */ return ret_val; /* ROOM IS LIT, OR WINNER IS NOT PLAYER (NO GRUE). */ L500: if (findxt_(prsvec_1.prso, play_1.here)) { goto L550; } /* !EXIT EXIST? */ L525: curxt_1.xstrng = 678; /* !ASSUME WALL. */ if (prsvec_1.prso == xsrch_1.xup) { curxt_1.xstrng = 679; } /* !IF UP, CANT. */ if (prsvec_1.prso == xsrch_1.xdown) { curxt_1.xstrng = 680; } /* !IF DOWN, CANT. */ if ((rooms_1.rflag[play_1.here - 1] & RNWALL) != 0) { curxt_1.xstrng = 524; } rspeak_(curxt_1.xstrng); prsvec_1.prscon = 1; /* !STOP CMD STREAM. */ return ret_val; L550: switch (curxt_1.xtype) { case 1: goto L900; case 2: goto L600; case 3: goto L700; case 4: goto L800; } /* !BRANCH ON EXIT TYPE. */ bug_(9, curxt_1.xtype); L700: if (cxappl_(curxt_1.xactio) != 0) { goto L900; } /* !CEXIT... RETURNED ROOM? */ if (flags[*xflag - 1]) { goto L900; } /* !NO, FLAG ON? */ L600: if (curxt_1.xstrng == 0) { goto L525; } /* !IF NO REASON, USE STD. */ rspeak_(curxt_1.xstrng); /* !DENY EXIT. */ prsvec_1.prscon = 1; /* !STOP CMD STREAM. */ return ret_val; L800: if (cxappl_(curxt_1.xactio) != 0) { goto L900; } /* !DOOR... RETURNED ROOM? */ if ((objcts_1.oflag2[curxt_1.xobj - 1] & OPENBT) != 0) { goto L900; } /* !NO, DOOR OPEN? */ if (curxt_1.xstrng == 0) { curxt_1.xstrng = 525; } /* !IF NO REASON, USE STD. */ rspsub_(curxt_1.xstrng, objcts_1.odesc2[curxt_1.xobj - 1]); prsvec_1.prscon = 1; /* !STOP CMD STREAM. */ return ret_val; L900: ret_val = moveto_(curxt_1.xroom1, play_1.winner); /* !MOVE TO ROOM. */ if (ret_val) { ret_val = rmdesc_(0); } /* !DESCRIBE ROOM. */ return ret_val; } /* walk_ */ /* CXAPPL- CONDITIONAL EXIT PROCESSORS */ /* DECLARATIONS */ static integer cxappl_(ri) integer ri; { /* System generated locals */ integer ret_val, i__1; /* Local variables */ integer i, j, k; integer nxt; integer ldir; ret_val = 0; /* !NO RETURN. */ if (ri == 0) { return ret_val; } /* !IF NO ACTION, DONE. */ switch (ri) { case 1: goto L1000; case 2: goto L2000; case 3: goto L3000; case 4: goto L4000; case 5: goto L5000; case 6: goto L6000; case 7: goto L7000; case 8: goto L8000; case 9: goto L9000; case 10: goto L10000; case 11: goto L11000; case 12: goto L12000; case 13: goto L13000; case 14: goto L14000; } bug_(5, ri); /* C1- COFFIN-CURE */ L1000: findex_1.egyptf = objcts_1.oadv[oindex_1.coffi - 1] != play_1.winner; /* !T IF NO COFFIN. */ return ret_val; /* C2- CAROUSEL EXIT */ /* C5- CAROUSEL OUT */ L2000: if (findex_1.caroff) { return ret_val; } /* !IF FLIPPED, NOTHING. */ L2500: rspeak_(121); /* !SPIN THE COMPASS. */ L5000: i = xpars_1.xelnt[xpars_1.xcond - 1] * rnd_(8); /* !CHOOSE RANDOM EXIT. */ curxt_1.xroom1 = exits_1.travel[rooms_1.rexit[play_1.here - 1] + i - 1] & xpars_1.xrmask; ret_val = curxt_1.xroom1; /* !RETURN EXIT. */ return ret_val; /* C3- CHIMNEY FUNCTION */ L3000: findex_1.litldf = FALSE_; /* !ASSUME HEAVY LOAD. */ j = 0; i__1 = objcts_1.olnt; for (i = 1; i <= i__1; ++i) { /* !COUNT OBJECTS. */ if (objcts_1.oadv[i - 1] == play_1.winner) { ++j; } /* L3100: */ } if (j > 2) { return ret_val; } /* !CARRYING TOO MUCH? */ curxt_1.xstrng = 446; /* !ASSUME NO LAMP. */ if (objcts_1.oadv[oindex_1.lamp - 1] != play_1.winner) { return ret_val; } /* !NO LAMP? */ findex_1.litldf = TRUE_; /* !HE CAN DO IT. */ if ((objcts_1.oflag2[oindex_1.door - 1] & OPENBT) == 0) { objcts_1.oflag2[oindex_1.door - 1] &= ~ TCHBT; } return ret_val; /* C4- FROBOZZ FLAG (MAGNET ROOM, FAKE EXIT) */ /* C6- FROBOZZ FLAG (MAGNET ROOM, REAL EXIT) */ L4000: if (findex_1.caroff) { goto L2500; } /* !IF FLIPPED, GO SPIN. */ findex_1.frobzf = FALSE_; /* !OTHERWISE, NOT AN EXIT. */ return ret_val; L6000: if (findex_1.caroff) { goto L2500; } /* !IF FLIPPED, GO SPIN. */ findex_1.frobzf = TRUE_; /* !OTHERWISE, AN EXIT. */ return ret_val; /* C7- FROBOZZ FLAG (BANK ALARM) */ L7000: findex_1.frobzf = objcts_1.oroom[oindex_1.bills - 1] != 0 & objcts_1.oroom[oindex_1.portr - 1] != 0; return ret_val; /* CXAPPL, PAGE 3 */ /* C8- FROBOZZ FLAG (MRGO) */ L8000: findex_1.frobzf = FALSE_; /* !ASSUME CANT MOVE. */ if (findex_1.mloc != curxt_1.xroom1) { goto L8100; } /* !MIRROR IN WAY? */ if (prsvec_1.prso == xsrch_1.xnorth || prsvec_1.prso == xsrch_1.xsouth) { goto L8200; } if (findex_1.mdir % 180 != 0) { goto L8300; } /* !MIRROR MUST BE N-S. */ curxt_1.xroom1 = (curxt_1.xroom1 - rindex_1.mra << 1) + rindex_1.mrae; /* !CALC EAST ROOM. */ if (prsvec_1.prso > xsrch_1.xsouth) { ++curxt_1.xroom1; } /* !IF SW/NW, CALC WEST. */ L8100: ret_val = curxt_1.xroom1; return ret_val; L8200: curxt_1.xstrng = 814; /* !ASSUME STRUC BLOCKS. */ if (findex_1.mdir % 180 == 0) { return ret_val; } /* !IF MIRROR N-S, DONE. */ L8300: ldir = findex_1.mdir; /* !SEE WHICH MIRROR. */ if (prsvec_1.prso == xsrch_1.xsouth) { ldir = 180; } curxt_1.xstrng = 815; /* !MIRROR BLOCKS. */ if (ldir > 180 && ! findex_1.mr1f || ldir < 180 && ! findex_1.mr2f) { curxt_1.xstrng = 816; } return ret_val; /* C9- FROBOZZ FLAG (MIRIN) */ L9000: if (mrhere_(play_1.here) != 1) { goto L9100; } /* !MIRROR 1 HERE? */ if (findex_1.mr1f) { curxt_1.xstrng = 805; } /* !SEE IF BROKEN. */ findex_1.frobzf = findex_1.mropnf; /* !ENTER IF OPEN. */ return ret_val; L9100: findex_1.frobzf = FALSE_; /* !NOT HERE, */ curxt_1.xstrng = 817; /* !LOSE. */ return ret_val; /* CXAPPL, PAGE 4 */ /* C10- FROBOZZ FLAG (MIRROR EXIT) */ L10000: findex_1.frobzf = FALSE_; /* !ASSUME CANT. */ ldir = (prsvec_1.prso - xsrch_1.xnorth) / xsrch_1.xnorth * 45; /* !XLATE DIR TO DEGREES. */ if (! findex_1.mropnf || (findex_1.mdir + 270) % 360 != ldir && prsvec_1.prso != xsrch_1.xexit) { goto L10200; } curxt_1.xroom1 = (findex_1.mloc - rindex_1.mra << 1) + rindex_1.mrae + 1 - findex_1.mdir / 180; /* !ASSUME E-W EXIT. */ if (findex_1.mdir % 180 == 0) { goto L10100; } /* !IF N-S, OK. */ curxt_1.xroom1 = findex_1.mloc + 1; /* !ASSUME N EXIT. */ if (findex_1.mdir > 180) { curxt_1.xroom1 = findex_1.mloc - 1; } /* !IF SOUTH. */ L10100: ret_val = curxt_1.xroom1; return ret_val; L10200: if (! findex_1.wdopnf || (findex_1.mdir + 180) % 360 != ldir && prsvec_1.prso != xsrch_1.xexit) { return ret_val; } curxt_1.xroom1 = findex_1.mloc + 1; /* !ASSUME N. */ if (findex_1.mdir == 0) { curxt_1.xroom1 = findex_1.mloc - 1; } /* !IF S. */ rspeak_(818); /* !CLOSE DOOR. */ findex_1.wdopnf = FALSE_; ret_val = curxt_1.xroom1; return ret_val; /* C11- MAYBE DOOR. NORMAL MESSAGE IS THAT DOOR IS CLOSED. */ /* BUT IF LCELL.NE.4, DOOR ISNT THERE. */ L11000: if (findex_1.lcell != 4) { curxt_1.xstrng = 678; } /* !SET UP MSG. */ return ret_val; /* C12- FROBZF (PUZZLE ROOM MAIN ENTRANCE) */ L12000: findex_1.frobzf = TRUE_; /* !ALWAYS ENTER. */ findex_1.cphere = 10; /* !SET SUBSTATE. */ return ret_val; /* C13- CPOUTF (PUZZLE ROOM SIZE ENTRANCE) */ L13000: findex_1.cphere = 52; /* !SET SUBSTATE. */ return ret_val; /* CXAPPL, PAGE 5 */ /* C14- FROBZF (PUZZLE ROOM TRANSITIONS) */ L14000: findex_1.frobzf = FALSE_; /* !ASSSUME LOSE. */ if (prsvec_1.prso != xsrch_1.xup) { goto L14100; } /* !UP? */ if (findex_1.cphere != 10) { return ret_val; } /* !AT EXIT? */ curxt_1.xstrng = 881; /* !ASSUME NO LADDER. */ if (puzzle_1.cpvec[findex_1.cphere] != -2) { return ret_val; } /* !LADDER HERE? */ rspeak_(882); /* !YOU WIN. */ findex_1.frobzf = TRUE_; /* !LET HIM OUT. */ return ret_val; L14100: if (findex_1.cphere != 52 || prsvec_1.prso != xsrch_1.xwest || ! findex_1.cpoutf) { goto L14200; } findex_1.frobzf = TRUE_; /* !YES, LET HIM OUT. */ return ret_val; L14200: for (i = 1; i <= 16; i += 2) { /* !LOCATE EXIT. */ if (prsvec_1.prso == puzzle_1.cpdr[i - 1]) { goto L14400; } /* L14300: */ } return ret_val; /* !NO SUCH EXIT. */ L14400: j = puzzle_1.cpdr[i]; /* !GET DIRECTIONAL OFFSET. */ nxt = findex_1.cphere + j; /* !GET NEXT STATE. */ k = 8; /* !GET ORTHOGONAL DIR. */ if (j < 0) { k = -8; } if ((abs(j) == 1 || abs(j) == 8 || (puzzle_1.cpvec[findex_1.cphere + k - 1] == 0 || puzzle_1.cpvec[nxt - k - 1] == 0)) && puzzle_1.cpvec[ nxt - 1] == 0) { goto L14500; } return ret_val; L14500: cpgoto_(nxt); /* !MOVE TO STATE. */ curxt_1.xroom1 = rindex_1.cpuzz; /* !STAY IN ROOM. */ ret_val = curxt_1.xroom1; return ret_val; } /* cxappl_ */