From 370d065544a764881c1fd729d54ded6c52269f12 Mon Sep 17 00:00:00 2001 From: Peje Nilsson Date: Fri, 9 Jun 2017 15:16:44 +0200 Subject: [PATCH] Refactor suspend & resume --- actions.c | 287 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 148 insertions(+), 139 deletions(-) diff --git a/actions.c b/actions.c index b4ce9ec..283c19f 100644 --- a/actions.c +++ b/actions.c @@ -114,7 +114,7 @@ static int bigwords(long foo) game.foobar=k; if (k != 4) return(2009); game.foobar=0; - if (game.place[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && game.loc == PLAC[EGGS])) + if (game.place[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && game.loc == PLAC[EGGS])) return(2011); /* Bring back troll if we steal the eggs back from him before * crossing. */ @@ -554,7 +554,7 @@ static int fly(token_t obj) RSPEAK(SPK); return(2); } - + static int inven(token_t obj) /* Inventory. If object, treat same as find. Else report on current burden. */ { @@ -598,7 +598,7 @@ int light(token_t obj) RSPEAK(39); if (game.wzdark) return(2000); return(2012); - } + } } static int listen(void) @@ -638,7 +638,7 @@ static int lock(token_t verb, token_t obj) if (HERE(CHAIN))obj=CHAIN; if (obj == 0) return(2011); } - + /* Lock, unlock object. Special stuff for opening clam/oyster * and for chain. */ if (obj == CLAM || obj == OYSTER) @@ -716,7 +716,7 @@ static int read(FILE *input, token_t obj) } if (obj > NOBJECTS || obj == 0 || DARK(0)) return(8000); } - + if (DARK(0)) { SETPRM(1,WD1,WD1X); RSPEAK(256); @@ -889,6 +889,81 @@ static int wave(token_t obj) } } +static int suspend_resume_common(long kk) +{ +/* This next part is shared with the "resume" code. The two cases are + * distinguished by the value of kk (-1 for suspend, +1 for resume). */ + + DATIME(&I,&K); + K=I+650*K; + SAVWRD(kk,K); + K=VRSION; + SAVWRD(0,K); + if(K != VRSION) { + SETPRM(1,K/10,MOD(K,10)); + SETPRM(3,VRSION/10,MOD(VRSION,10)); + RSPEAK(269); + return(2000); + } +/* Herewith are all the variables whose values can change during a game, + * omitting a few (such as I, J, ATTACK) whose values between turns are + * irrelevant and some whose values when a game is + * suspended or resumed are guaranteed to match. If unsure whether a value + * needs to be saved, include it. Overkill can't hurt. Pad the last savwds + * with junk variables to bring it up to 7 values. */ + SAVWDS(game.abbnum,game.blklin,game.bonus,game.clock1,game.clock2,game.closed,game.closng); + SAVWDS(game.detail,game.dflag,game.dkill,game.dtotal,game.foobar,game.holdng,game.iwest); + SAVWDS(game.knfloc,game.limit,K,game.lmwarn,game.loc,game.newloc,game.numdie); + SAVWDS(K,game.oldlc2,game.oldloc,game.oldobj,game.panic,game.saved,game.setup); + SAVWDS(SPK,game.tally,game.thresh,game.trndex,game.trnluz,game.turns,OBJTXT[OYSTER]); + SAVWDS(K,WD1,WD1X,WD2,game.wzdark,game.zzword,OBJSND[BIRD]); + SAVWDS(OBJTXT[SIGN],game.clshnt,game.novice,K,K,K,K); + SAVARR(game.abbrev,LOCSIZ); + SAVARR(game.atloc,LOCSIZ); + SAVARR(game.dloc,NDWARVES); + SAVARR(game.dseen,NDWARVES); + SAVARR(game.fixed,NOBJECTS); + SAVARR(game.hinted,HNTSIZ); + SAVARR(game.hintlc,HNTSIZ); + SAVARR(game.link,NOBJECTS*2); + SAVARR(game.odloc,NDWARVES); + SAVARR(game.place,NOBJECTS); + SAVARR(game.prop,NOBJECTS); + SAVWRD(kk,K); + if(K != 0) { + RSPEAK(270); + exit(0); + } + K=NUL; + game.zzword=RNDVOC(3,game.zzword); + if(kk > 0) return(8); + RSPEAK(266); + exit(0); +} + +static int suspend(FILE *input) +/* Suspend. Offer to save things in a file, but charging some points (so + * can't win by using saved games to retry battles or to start over after + * learning zzword). */ +{ + SPK=201; + RSPEAK(260); + if(!YES(input,200,54,54)) return(2012); + game.saved=game.saved+5; + return suspend_resume_common(-1); +} + +static int resume(FILE *input) +/* Resume. Read a suspended game back from a file. */ +{ + + if(game.loc != 1 || game.abbrev[1] != 1) { + RSPEAK(268); + if(!YES(input,200,54,54)) return(2012); + } + return suspend_resume_common(1); +} + /* This stuff was broken off as part of an effort to get the main program * to compile without running out of memory. We're called with a number * that says what label the caller wanted to "goto", and we return a @@ -908,7 +983,7 @@ int action(FILE *input, long STARTAT, long verb, long obj) } BUG(99); -L4000: +L4000: SPK=ACTSPK[verb]; if (WD2 > 0 && verb != SAY) return(2800); if (verb == SAY)obj=WD2; @@ -918,79 +993,79 @@ L4000: switch (verb-1) { case 0: /* CARRY */ return carry(INTRANSITIVE); - case 1: /* DROP */ return(8000); - case 2: /* SAY */ return(8000); - case 3: /* UNLOC */ return lock(verb, INTRANSITIVE); - case 4: /* NOTHI */ return(2009); - case 5: /* LOCK */ return lock(verb, INTRANSITIVE); - case 6: /* LIGHT */ return light(INTRANSITIVE); - case 7: /* EXTIN */ return extinguish(INTRANSITIVE); - case 8: /* WAVE */ return(8000); - case 9: /* CALM */ return(8000); - case 10: /* WALK */ return(2011); - case 11: /* ATTAC */ return attack(input, verb, obj); - case 12: /* POUR */ return pour(obj); - case 13: /* EAT */ return eat(INTRANSITIVE); - case 14: /* DRINK */ return drink(obj); - case 15: /* RUB */ return(8000); - case 16: /* TOSS */ return(8000); - case 17: /* QUIT */ return quit(input); - case 18: /* FIND */ return(8000); - case 19: /* INVEN */ return inven(obj); - case 20: /* FEED */ return(8000); - case 21: /* FILL */ return fill(obj); - case 22: /* BLAST */ return blast(); - case 23: /* SCOR */ return vscore(); - case 24: /* FOO */ return bigwords(WD1); - case 25: /* BRIEF */ return brief(); - case 26: /* READ */ return read(input, INTRANSITIVE); - case 27: /* BREAK */ return(8000); - case 28: /* WAKE */ return(8000); - case 29: /* SUSP */ goto L8300; - case 30: /* RESU */ goto L8310; - case 31: /* FLY */ return fly(INTRANSITIVE); - case 32: /* LISTE */ return listen(); - case 33: /* ZZZZ */ return reservoir(); + case 1: /* DROP */ return(8000); + case 2: /* SAY */ return(8000); + case 3: /* UNLOC */ return lock(verb, INTRANSITIVE); + case 4: /* NOTHI */ return(2009); + case 5: /* LOCK */ return lock(verb, INTRANSITIVE); + case 6: /* LIGHT */ return light(INTRANSITIVE); + case 7: /* EXTIN */ return extinguish(INTRANSITIVE); + case 8: /* WAVE */ return(8000); + case 9: /* CALM */ return(8000); + case 10: /* WALK */ return(2011); + case 11: /* ATTAC */ return attack(input, verb, obj); + case 12: /* POUR */ return pour(obj); + case 13: /* EAT */ return eat(INTRANSITIVE); + case 14: /* DRINK */ return drink(obj); + case 15: /* RUB */ return(8000); + case 16: /* TOSS */ return(8000); + case 17: /* QUIT */ return quit(input); + case 18: /* FIND */ return(8000); + case 19: /* INVEN */ return inven(obj); + case 20: /* FEED */ return(8000); + case 21: /* FILL */ return fill(obj); + case 22: /* BLAST */ return blast(); + case 23: /* SCOR */ return vscore(); + case 24: /* FOO */ return bigwords(WD1); + case 25: /* BRIEF */ return brief(); + case 26: /* READ */ return read(input, INTRANSITIVE); + case 27: /* BREAK */ return(8000); + case 28: /* WAKE */ return(8000); + case 29: /* SUSP */ return suspend(input); + case 30: /* RESU */ return resume(input); + case 31: /* FLY */ return fly(INTRANSITIVE); + case 32: /* LISTE */ return listen(); + case 33: /* ZZZZ */ return reservoir(); } BUG(23); /* Analyse a transitive verb. */ L4090: switch (verb-1) { - case 0: /* CARRY */ return carry(obj); - case 1: /* DROP */ return discard(obj, false); - case 2: /* SAY */ return say(); - case 3: /* UNLOC */ return lock(verb, obj); - case 4: /* NOTHI */ return(2009); - case 5: /* LOCK */ return lock(verb, obj); - case 6: /* LIGHT */ return light(obj); - case 7: /* EXTI */ return extinguish(obj); - case 8: /* WAVE */ return wave(obj); - case 9: /* CALM */ return(2011); - case 10: /* WALK */ return(2011); - case 11: /* ATTAC */ return attack(input, verb, obj); - case 12: /* POUR */ return pour(obj); - case 13: /* EAT */ return eat(obj); - case 14: /* DRINK */ return drink(obj); - case 15: /* RUB */ return rub(obj); - case 16: /* TOSS */ return throw(input, verb, obj); - case 17: /* QUIT */ return(2011); - case 18: /* FIND */ return find(obj); - case 19: /* INVEN */ return find(obj); - case 20: /* FEED */ return feed(obj); - case 21: /* FILL */ return fill(obj); - case 22: /* BLAST */ return blast(); - case 23: /* SCOR */ return(2011); - case 24: /* FOO */ return(2011); - case 25: /* BRIEF */ return(2011); - case 26: /* READ */ return read(input, obj); - case 27: /* BREAK */ return vbreak(obj); - case 28: /* WAKE */ return wake(obj); - case 29: /* SUSP */ return(2011); - case 30: /* RESU */ return(2011); - case 31: /* FLY */ return fly(obj); - case 32: /* LISTE */ return(2011); - case 33: /* ZZZZ */ return reservoir(); + case 0: /* CARRY */ return carry(obj); + case 1: /* DROP */ return discard(obj, false); + case 2: /* SAY */ return say(); + case 3: /* UNLOC */ return lock(verb, obj); + case 4: /* NOTHI */ return(2009); + case 5: /* LOCK */ return lock(verb, obj); + case 6: /* LIGHT */ return light(obj); + case 7: /* EXTI */ return extinguish(obj); + case 8: /* WAVE */ return wave(obj); + case 9: /* CALM */ return(2011); + case 10: /* WALK */ return(2011); + case 11: /* ATTAC */ return attack(input, verb, obj); + case 12: /* POUR */ return pour(obj); + case 13: /* EAT */ return eat(obj); + case 14: /* DRINK */ return drink(obj); + case 15: /* RUB */ return rub(obj); + case 16: /* TOSS */ return throw(input, verb, obj); + case 17: /* QUIT */ return(2011); + case 18: /* FIND */ return find(obj); + case 19: /* INVEN */ return find(obj); + case 20: /* FEED */ return feed(obj); + case 21: /* FILL */ return fill(obj); + case 22: /* BLAST */ return blast(); + case 23: /* SCOR */ return(2011); + case 24: /* FOO */ return(2011); + case 25: /* BRIEF */ return(2011); + case 26: /* READ */ return read(input, obj); + case 27: /* BREAK */ return vbreak(obj); + case 28: /* WAKE */ return wake(obj); + case 29: /* SUSP */ return(2011); + case 30: /* RESU */ return(2011); + case 31: /* FLY */ return fly(obj); + case 32: /* LISTE */ return(2011); + case 33: /* ZZZZ */ return reservoir(); } BUG(24); @@ -1037,70 +1112,4 @@ L5190: if ((verb == FIND || verb == INVENT) && WD2 <= 0) goto L5010; * transitive, plus ten times the verb number. Many intransitive verbs use the * transitive code, and some verbs use code for other verbs, as noted below. */ -/* Suspend. Offer to save things in a file, but charging some points (so - * can't win by using saved games to retry battles or to start over after - * learning zzword). */ - -L8300: SPK=201; - RSPEAK(260); - if (!YES(input,200,54,54)) return(2012); - game.saved=game.saved+5; - kk= -1; - -/* This next part is shared with the "resume" code. The two cases are - * distinguished by the value of kk (-1 for suspend, +1 for resume). */ - -L8305: DATIME(&I,&K); - K=I+650*K; - SAVWRD(kk,K); - K=VRSION; - SAVWRD(0,K); - if (K != VRSION) goto L8312; -/* Herewith are all the variables whose values can change during a game, - * omitting a few (such as I, J, ATTACK) whose values between turns are - * irrelevant and some whose values when a game is - * suspended or resumed are guaranteed to match. If unsure whether a value - * needs to be saved, include it. Overkill can't hurt. Pad the last savwds - * with junk variables to bring it up to 7 values. */ - SAVWDS(game.abbnum,game.blklin,game.bonus,game.clock1,game.clock2,game.closed,game.closng); - SAVWDS(game.detail,game.dflag,game.dkill,game.dtotal,game.foobar,game.holdng,game.iwest); - SAVWDS(game.knfloc,game.limit,K,game.lmwarn,game.loc,game.newloc,game.numdie); - SAVWDS(K,game.oldlc2,game.oldloc,game.oldobj,game.panic,game.saved,game.setup); - SAVWDS(SPK,game.tally,game.thresh,game.trndex,game.trnluz,game.turns,OBJTXT[OYSTER]); - SAVWDS(K,WD1,WD1X,WD2,game.wzdark,game.zzword,OBJSND[BIRD]); - SAVWDS(OBJTXT[SIGN],game.clshnt,game.novice,K,K,K,K); - SAVARR(game.abbrev,LOCSIZ); - SAVARR(game.atloc,LOCSIZ); - SAVARR(game.dloc,NDWARVES); - SAVARR(game.dseen,NDWARVES); - SAVARR(game.fixed,NOBJECTS); - SAVARR(game.hinted,HNTSIZ); - SAVARR(game.hintlc,HNTSIZ); - SAVARR(game.link,NOBJECTS*2); - SAVARR(game.odloc,NDWARVES); - SAVARR(game.place,NOBJECTS); - SAVARR(game.prop,NOBJECTS); - SAVWRD(kk,K); - if (K != 0) goto L8318; - K=NUL; - game.zzword=RNDVOC(3,game.zzword); - if (kk > 0) return(8); - RSPEAK(266); - exit(0); - -/* Resume. Read a suspended game back from a file. */ - -L8310: kk=1; - if (game.loc == 1 && game.abbrev[1] == 1) goto L8305; - RSPEAK(268); - if (!YES(input,200,54,54)) return(2012); - goto L8305; - -L8312: SETPRM(1,K/10,MOD(K,10)); - SETPRM(3,VRSION/10,MOD(VRSION,10)); - RSPEAK(269); - return(2000); - -L8318: RSPEAK(270); - exit(0); }