Begin gathering saveable game state into a structure. Not yet complete.
authorEric S. Raymond <esr@thyrsus.com>
Tue, 23 May 2017 22:47:04 +0000 (18:47 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Tue, 23 May 2017 22:47:04 +0000 (18:47 -0400)
No logic changes.  A bunch of globals turn into fields (with the same names
except for lowercasing) in struct game_t.

Eventually this will allow drastic simplification of the save/load logic.

COPYING
actions1.c
actions2.c
adventure.text
funcs.h
init.c
main.c
main.h
misc.c
score.c
share.h

diff --git a/COPYING b/COPYING
index 1c5f1a415fac569378e13fdea5642115bb6fd59f..e86ca35c53347eb59e355d52176051a408b85808 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -16,11 +16,11 @@ documentation and/or other materials provided with the distribution.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+game.limitED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+game.limitED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
index 66bad5e89017bb127e544326673eac0a61f04bb6..702e14c40416968f27b060456f426375b4f1508c 100644 (file)
@@ -94,8 +94,8 @@ L5110:        if(K == DWARF && ATDWRF(LOC) > 0) goto L5010;
 L5120: if(OBJ != PLANT || !AT(PLANT2) || PROP[PLANT2] == 0) goto L5130;
        OBJ=PLANT2;
         goto L5010;
-L5130: if(OBJ != KNIFE || KNFLOC != LOC) goto L5140;
-       KNFLOC= -1;
+L5130: if(OBJ != KNIFE || game.knfloc != LOC) goto L5140;
+       game.knfloc= -1;
        SPK=116;
         return(2011);
 L5140: if(OBJ != ROD || !HERE(ROD2)) goto L5190;
@@ -160,9 +160,9 @@ L9040:      if(OBJ == CLAM || OBJ == OYSTER) goto L9046;
        if(OBJ == GRATE || OBJ == CHAIN)SPK=31;
        if(SPK != 31 || !HERE(KEYS)) return(2011);
        if(OBJ == CHAIN) goto L9048;
-       if(!CLOSNG) goto L9043;
+       if(!game.closng) goto L9043;
        K=130;
-       if(!PANIC)CLOCK2=15;
+       if(!PANIC)game.clock2=15;
        PANIC=true;
         return(2010);
 
@@ -208,17 +208,17 @@ L9049:    SPK=172;
 
 /*  Light.  Applicable only to lamp and urn. */
 
-L8070: if(HERE(LAMP) && PROP[LAMP] == 0 && LIMIT >= 0)OBJ=LAMP;
+L8070: if(HERE(LAMP) && PROP[LAMP] == 0 && game.limit >= 0)OBJ=LAMP;
        if(HERE(URN) && PROP[URN] == 1)OBJ=OBJ*100+URN;
        if(OBJ == 0 || OBJ > 100) return(8000);
 
 L9070: if(OBJ == URN) goto L9073;
        if(OBJ != LAMP) return(2011);
        SPK=184;
-       if(LIMIT < 0) return(2011);
+       if(game.limit < 0) return(2011);
        PROP[LAMP]=1;
        RSPEAK(39);
-       if(WZDARK) return(2000);
+       if(game.wzdark) return(2000);
         return(2012);
 
 L9073: SPK=38;
@@ -250,12 +250,12 @@ L9086:    PROP[LAMP]=0;
 /*  Wave.  No effect unless waving rod at fissure or at bird. */
 
 L9090: if((!TOTING(OBJ)) && (OBJ != ROD || !TOTING(ROD2)))SPK=29;
-       if(OBJ != ROD || !TOTING(OBJ) || (!HERE(BIRD) && (CLOSNG || !AT(FISSUR))))
+       if(OBJ != ROD || !TOTING(OBJ) || (!HERE(BIRD) && (game.closng || !AT(FISSUR))))
                return(2011);
        if(HERE(BIRD))SPK=206+MOD(PROP[BIRD],2);
        if(SPK == 206 && LOC == PLACE[STEPS] && PROP[JADE] < 0) goto L9094;
-       if(CLOSED) return(18999);
-       if(CLOSNG || !AT(FISSUR)) return(2011);
+       if(game.closed) return(18999);
+       if(game.closng || !AT(FISSUR)) return(2011);
        if(HERE(BIRD))RSPEAK(SPK);
        PROP[FISSUR]=1-PROP[FISSUR];
        PSPEAK(FISSUR,2-PROP[FISSUR]);
@@ -360,7 +360,7 @@ L8180:      if(YES(input,22,54,54)) score(1);
 
 L9190: if(AT(OBJ) || (LIQ(0) == OBJ && AT(BOTTLE)) || K == LIQLOC(LOC) || (OBJ ==
                DWARF && ATDWRF(LOC) > 0))SPK=94;
-       if(CLOSED)SPK=138;
+       if(game.closed)SPK=138;
        if(TOTING(OBJ))SPK=24;
         return(2011);
 
@@ -370,9 +370,9 @@ L8200:      SPK=98;
        /* 8201 */ for (I=1; I<=100; I++) {
        if(I == BEAR || !TOTING(I)) goto L8201;
        if(SPK == 98)RSPEAK(99);
-       BLKLIN=false;
+       game.blklin=false;
        PSPEAK(I,-1);
-       BLKLIN=true;
+       game.blklin=true;
        SPK=0;
 L8201: /*etc*/ ;
        } /* end loop */
@@ -386,11 +386,11 @@ L9220:    return(fill());
 
 /*  Blast.  No effect unless you've got dynamite, which is a neat trick! */
 
-L9230: if(PROP[ROD2] < 0 || !CLOSED) return(2011);
-       BONUS=133;
-       if(LOC == 115)BONUS=134;
-       if(HERE(ROD2))BONUS=135;
-       RSPEAK(BONUS);
+L9230: if(PROP[ROD2] < 0 || !game.closed) return(2011);
+       game.bonus=133;
+       if(LOC == 115)game.bonus=134;
+       if(HERE(ROD2))game.bonus=135;
+       RSPEAK(game.bonus);
         score(0);
 
 /*  Score.  Call scoring routine but tell it to return. */
@@ -407,13 +407,13 @@ L8240:    score(-1);
 
 L8250: K=VOCAB(WD1,3);
        SPK=42;
-       if(FOOBAR == 1-K) goto L8252;
-       if(FOOBAR != 0)SPK=151;
+       if(game.foobar == 1-K) goto L8252;
+       if(game.foobar != 0)SPK=151;
         return(2011);
 
-L8252: FOOBAR=K;
+L8252: game.foobar=K;
        if(K != 4) return(2009);
-       FOOBAR=0;
+       game.foobar=0;
        if(PLACE[EGGS] == PLAC[EGGS] || (TOTING(EGGS) && LOC == PLAC[EGGS])) 
                return(2011);
 /*  Bring back troll if we steal the eggs back from him before crossing. */
@@ -429,8 +429,8 @@ L8252:      FOOBAR=K;
 /*  Brief.  Intransitive only.  Suppress long descriptions after first time. */
 
 L8260: SPK=156;
-       ABBNUM=10000;
-       DETAIL=3;
+       game.abbnum=10000;
+       game.detail=3;
         return(2011);
 
 /*  Read.  Print stuff based on objtxt.  Oyster (?) is special case. */
@@ -453,7 +453,7 @@ L9275:      CLSHNT=YES(input,192,193,54);
 
 L9280: if(OBJ == MIRROR)SPK=148;
        if(OBJ == VASE && PROP[VASE] == 0) goto L9282;
-       if(OBJ != MIRROR || !CLOSED) return(2011);
+       if(OBJ != MIRROR || !game.closed) return(2011);
        SPK=197;
         return(18999);
 
@@ -465,7 +465,7 @@ L9282:      SPK=198;
 
 /*  Wake.  Only use is to disturb the dwarves. */
 
-L9290: if(OBJ != DWARF || !CLOSED) return(2011);
+L9290: if(OBJ != DWARF || !game.closed) return(2011);
        SPK=199;
         return(18999);
 
@@ -494,12 +494,12 @@ L8305:    DATIME(I,K);
  *  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(ABBNUM,BLKLIN,BONUS,CLOCK1,CLOCK2,CLOSED,CLOSNG);
-       SAVWDS(DETAIL,DFLAG,DKILL,DTOTAL,FOOBAR,HOLDNG,IWEST);
-       SAVWDS(KNFLOC,LIMIT,LL,LMWARN,LOC,NEWLOC,NUMDIE);
+       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,LL,game.lmwarn,LOC,game.newloc,game.numdie);
        SAVWDS(OBJ,OLDLC2,OLDLOC,OLDOBJ,PANIC,SAVED,SETUP);
        SAVWDS(SPK,TALLY,THRESH,TRNDEX,TRNLUZ,TURNS,OBJTXT[OYSTER]);
-       SAVWDS(VERB,WD1,WD1X,WD2,WZDARK,ZZWORD,OBJSND[BIRD]);
+       SAVWDS(VERB,WD1,WD1X,WD2,game.wzdark,ZZWORD,OBJSND[BIRD]);
        SAVWDS(OBJTXT[SIGN],CLSHNT,NOVICE,K,K,K,K);
        SAVARR(ABB,LOCSIZ);
        SAVARR(ATLOC,LOCSIZ);
@@ -548,7 +548,7 @@ L9320:      if(OBJ != RUG) return(2011);
        if(PROP[RUG] != 2) return(2011);
        OLDLC2=OLDLOC;
        OLDLOC=LOC;
-       NEWLOC=PLACE[RUG]+FIXED[RUG]-LOC;
+       game.newloc=PLACE[RUG]+FIXED[RUG]-LOC;
        SPK=226;
        if(PROP[SAPPH] >= 0)SPK=227;
        RSPEAK(SPK);
@@ -579,7 +579,7 @@ L8340:      if(!AT(RESER) && LOC != FIXED[RESER]-1) return(2011);
        PROP[RESER]=1-PROP[RESER];
        if(AT(RESER)) return(2012);
        OLDLC2=LOC;
-       NEWLOC=0;
+       game.newloc=0;
        RSPEAK(241);
         return(2);
 
index dcc649da04b43856bcace8eab25df80c5168c3f0..698319f4c70fba4e6f0b4cc70388ed4d02997335 100644 (file)
@@ -31,7 +31,7 @@ L9011:        if(FIXED[OBJ] != 0) return(2011);
        if(!TOTING(BOTTLE))SPK=104;
         return(2011);
 L9017: SPK=92;
-       if(HOLDNG >= 7) return(2011);
+       if(game.holdng >= 7) return(2011);
        if(OBJ != BIRD || PROP[BIRD] == 1 || -1-PROP[BIRD] == 1) goto L9014;
        if(PROP[BIRD] == 2) goto L9015;
        if(!TOTING(CAGE))SPK=27;
@@ -63,7 +63,7 @@ int discard(bool just_do_it) {
        if(!TOTING(OBJ)) return(2011);
        if(OBJ != BIRD || !HERE(SNAKE)) goto L9023;
        RSPEAK(30);
-       if(CLOSED) return(19000);
+       if(game.closed) return(19000);
        DSTROY(SNAKE);
 /*  SET PROP FOR USE BY TRAVEL OPTIONS */
        PROP[SNAKE]=1;
@@ -150,7 +150,7 @@ int attack(FILE *input) {
        if(OBJ > 100) return(8000);
 L9124: if(OBJ != BIRD) goto L9125;
        SPK=137;
-       if(CLOSED) return(2011);
+       if(game.closed) return(2011);
        DSTROY(BIRD);
        PROP[BIRD]=0;
        SPK=45;
@@ -163,7 +163,7 @@ L9126:      if(OBJ == 0)SPK=44;
        if(OBJ == CLAM || OBJ == OYSTER)SPK=150;
        if(OBJ == SNAKE)SPK=46;
        if(OBJ == DWARF)SPK=49;
-       if(OBJ == DWARF && CLOSED) return(19000);
+       if(OBJ == DWARF && game.closed) return(19000);
        if(OBJ == DRAGON)SPK=167;
        if(OBJ == TROLL)SPK=157;
        if(OBJ == OGRE)SPK=203;
@@ -233,12 +233,12 @@ int throw(FILE *cmdin) {
        return(attack(cmdin));
 
 L9172: SPK=48;
-       if(RAN(7) < DFLAG) goto L9175;
+       if(RAN(7) < game.dflag) goto L9175;
        DSEEN[I]=false;
        DLOC[I]=0;
        SPK=47;
-       DKILL=DKILL+1;
-       if(DKILL == 1)SPK=149;
+       game.dkill=game.dkill+1;
+       if(game.dkill == 1)SPK=149;
 L9175: RSPEAK(SPK);
        DROP(AXE,LOC);
        K=NUL;
@@ -279,7 +279,7 @@ L9212:      if(OBJ != SNAKE && OBJ != DRAGON && OBJ != TROLL) goto L9213;
        SPK=102;
        if(OBJ == DRAGON && PROP[DRAGON] != 0)SPK=110;
        if(OBJ == TROLL)SPK=182;
-       if(OBJ != SNAKE || CLOSED || !HERE(BIRD)) return(2011);
+       if(OBJ != SNAKE || game.closed || !HERE(BIRD)) return(2011);
        SPK=101;
        DSTROY(BIRD);
        PROP[BIRD]=0;
@@ -288,7 +288,7 @@ L9212:      if(OBJ != SNAKE && OBJ != DRAGON && OBJ != TROLL) goto L9213;
 L9213: if(OBJ != DWARF) goto L9214;
        if(!HERE(FOOD)) return(2011);
        SPK=103;
-       DFLAG=DFLAG+2;
+       game.dflag=game.dflag+2;
         return(2011);
 
 L9214: if(OBJ != BEAR) goto L9215;
index 5ec4034e22935c6cac8c229b1506d9c6757951d8..fe8e9831d2de076776180663896afb149c072278 100644 (file)
 142    though you get partial credit just for locating it.  You lose points
 142    for getting killed, or for quitting, though the former costs you more.
 142    There are also points based on how much (if any) of the cave you've
-142    managed to explore; in particular, there is a large bonus just for
+142    managed to explore; in particular, there is a large game.bonus just for
 142    getting in (to distinguish the beginners from the rest of the pack),
 142    and there are other ways to determine whether you've been through some
 142    of the more harrowing sections.  If you think you've found all the
 142    treasures, just keep exploring for a while.  If nothing interesting
 142    happens, you haven't found them all yet.  If something interesting
 142    *DOES* happen (incidentally, there *ARE* ways to hasten things along),
-142    it means you're getting a bonus and have an opportunity to garner many
+142    it means you're getting a game.bonus and have an opportunity to garner many
 142    more points in the Master's section.  I may occasionally offer hints
 142    if you seem to be having trouble.  If I do, I'll warn you in advance
 142    how much it will affect your score to accept the hints.  Finally, to
diff --git a/funcs.h b/funcs.h
index 455de2d6b78360ae63c24aaf9528feb70b969410..e0cec9060b0668afdd247e4a3f0d4f86917735cf 100644 (file)
--- a/funcs.h
+++ b/funcs.h
@@ -28,7 +28,7 @@
 #define FOREST(LOC)    ((LOC) >= 145 && (LOC) <= 166)
 #define VOCWRD(LETTRS,SECT)    (VOCAB(MAKEWD(LETTRS),SECT))
 
-/*  The following two functions were added to fix a bug (CLOCK1 decremented
+/*  The following two functions were added to fix a bug (game.clock1 decremented
  *  while in forest).  They should probably be replaced by using another
  *  "cond" bit.  For now, however, a quick fix...  OUTSID(LOC) is true if
  *  LOC is outside, INDEEP(LOC) is true if LOC is "deep" in the cave (hall
diff --git a/init.c b/init.c
index a74dd86b67acae6c208c78fa77942ec745e6028c..240ad92f001e52514ee84e89a2fed9662f03eaa2 100644 (file)
--- a/init.c
+++ b/init.c
@@ -278,20 +278,20 @@ L1014:    TRNVLS=TRNVLS+1;
 
 /*  The stuff for section 3 is encoded here.  Each "from-location" gets a
  *  contiguous section of the "TRAVEL" array.  Each entry in travel is
- *  NEWLOC*1000 + KEYWORD (from section 4, motion verbs), and is negated if
+ *  game.newloc*1000 + KEYWORD (from section 4, motion verbs), and is negated if
  *  this is the last entry for this location.  KEY(N) is the index in travel
  *  of the first option at location N. */
 
 L1030: LOC=GETNUM(OPENED);
        if(LOC == -1) goto L1002;
-       NEWLOC=GETNUM(NULL);
+       game.newloc=GETNUM(NULL);
        if(KEY[LOC] != 0) goto L1033;
        KEY[LOC]=TRVS;
         goto L1035;
 L1033: TRVS--; TRAVEL[TRVS]= -TRAVEL[TRVS]; TRVS++;
 L1035: L=GETNUM(NULL);
        if(L == 0) goto L1039;
-       TRAVEL[TRVS]=NEWLOC*1000+L;
+       TRAVEL[TRVS]=game.newloc*1000+L;
        TRVS=TRVS+1;
        if(TRVS == TRVSIZ)BUG(3);
         goto L1035;
@@ -519,7 +519,7 @@ L1106:      /*etc*/ ;
  *  prior loc of each dwarf, initially garbage.  DALTLC is alternate initial loc
  *  for dwarf, in case one of them starts out on top of the adventurer.  (No 2
  *  of the 5 initial locs are adjacent.)  DSEEN is true if dwarf has seen him.
- *  DFLAG controls the level of activation of all this:
+ *  game.dflag controls the level of activation of all this:
  *     0       No dwarf stuff yet (wait until reaches Hall Of Mists)
  *     1       Reached Hall Of Mists, but hasn't met first dwarf
  *     2       Met first dwarf, others start moving, no knives thrown yet
@@ -534,7 +534,7 @@ L1106:      /*etc*/ ;
        for (I=1; I<=6; I++) {
        DSEEN[I]=false;
        } /* end loop */
-       DFLAG=0;
+       game.dflag=0;
        DLOC[1]=19;
        DLOC[2]=27;
        DLOC[3]=33;
@@ -544,21 +544,21 @@ L1106:    /*etc*/ ;
        DALTLC=18;
 
 /*  Other random flags and counters, as follows:
- *     ABBNUM  How often we should print non-abbreviated descriptions
- *     BONUS   Used to determine amount of bonus if he reaches closing
- *     CLOCK1  Number of turns from finding last treasure till closing
- *     CLOCK2  Number of turns from first warning till blinding flash
+ *     game.abbnum     How often we should print non-abbreviated descriptions
+ *     game.bonus      Used to determine amount of bonus if he reaches closing
+ *     game.clock1     Number of turns from finding last treasure till closing
+ *     game.clock2     Number of turns from first warning till blinding flash
  *     CONDS   Min value for cond(loc) if loc has any hints
- *     DETAIL  How often we've said "not allowed to give more detail"
- *     DKILL   Number of dwarves killed (unused in scoring, needed for msg)
- *     FOOBAR  Current progress in saying "FEE FIE FOE FOO".
- *     HOLDNG  Number of objects being carried
+ *     game.detail     How often we've said "not allowed to give more detail"
+ *     game.dkill      Number of dwarves killed (unused in scoring, needed for msg)
+ *     game.foobar     Current progress in saying "FEE FIE FOE FOO".
+ *     game.holdng     Number of objects being carried
  *     IGO     How many times he's said "go XXX" instead of "XXX"
- *     IWEST   How many times he's said "west" instead of "w"
- *     KNFLOC  0 if no knife here, loc if knife here, -1 after caveat
- *     LIMIT   Lifetime of lamp (not set here)
+ *     game.iwest      How many times he's said "west" instead of "w"
+ *     game.knfloc     0 if no knife here, loc if knife here, -1 after caveat
+ *     game.limit      Lifetime of lamp (not set here)
  *     MAXDIE  Number of reincarnation messages available (up to 5)
- *     NUMDIE  Number of times killed so far
+ *     game.numdie     Number of times killed so far
  *     THRESH  Next #turns threshhold (-1 if none)
  *     TRNDEX  Index in TRNVAL of next threshhold (section 14 of database)
  *     TRNLUZ  # points lost so far due to number of turns used
@@ -570,27 +570,27 @@ L1106:    /*etc*/ ;
        THRESH= -1;
        if(TRNVLS > 0)THRESH=MOD(TRNVAL[1],100000)+1;
        TRNLUZ=0;
-       LMWARN=false;
+       game.lmwarn=false;
        IGO=0;
-       IWEST=0;
-       KNFLOC=0;
-       DETAIL=0;
-       ABBNUM=5;
+       game.iwest=0;
+       game.knfloc=0;
+       game.detail=0;
+       game.abbnum=5;
        for (I=0; I<=4; I++) {
        {long x = 2*I+81; if(RTEXT[x] != 0)MAXDIE=I+1;}
        } /* end loop */
-       NUMDIE=0;
-       HOLDNG=0;
-       DKILL=0;
-       FOOBAR=0;
-       BONUS=0;
-       CLOCK1=30;
-       CLOCK2=50;
+       game.numdie=0;
+       game.holdng=0;
+       game.dkill=0;
+       game.foobar=0;
+       game.bonus=0;
+       game.clock1=30;
+       game.clock2=50;
        CONDS=SETBIT(11);
        SAVED=0;
-       CLOSNG=false;
+       game.closng=false;
        PANIC=false;
-       CLOSED=false;
+       game.closed=false;
        CLSHNT=false;
        NOVICE=false;
        SETUP=1;
diff --git a/main.c b/main.c
index de25b32a388cf642e4c34af86cc5886df7dfecd3..6f59f7d347f53c3227cb046de53a5a5e11a2a6dd 100644 (file)
--- a/main.c
+++ b/main.c
 
 #include "misc.h"
 
-long ABB[186], ATAB[331], ATLOC[186], BLKLIN = true, DFLAG,
-               DLOC[7], FIXED[101], HOLDNG,
+long ABB[186], ATAB[331], ATLOC[186],
+               DLOC[7], FIXED[101],
                KTAB[331], *LINES, LINK[201], LNLENG, LNPOSN,
                PARMS[26], PLACE[101], PTEXT[101], RTEXT[278],
                SETUP = 0, TABSIZ = 330;
 signed char INLINE[LINESIZE+1], MAP1[129], MAP2[129];
 
-long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BONUS,
+long ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD,
                 BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2,
-               CLAM, CLOCK1, CLOCK2, CLOSED, CLOSNG, CLSHNT, CLSMAX = 12, CLSSES,
-               COINS, COND[186], CONDS, CTEXT[13], CVAL[13], DALTLC, DETAIL,
-                DKILL, DOOR, DPRSSN, DRAGON, DSEEN[7], DTOTAL, DWARF, EGGS,
-               EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[101], FOOBAR, FOOD,
+               CLAM, CLSHNT, CLSMAX = 12, CLSSES,
+               COINS, COND[186], CONDS, CTEXT[13], CVAL[13], DALTLC,
+               DOOR, DPRSSN, DRAGON, DSEEN[7], DWARF, EGGS,
+               EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[101], FOOD,
                GRATE, HINT, HINTED[21], HINTLC[21], HINTS[21][5], HNTMAX,
-               HNTSIZ = 20, I, INVENT, IGO, IWEST, J, JADE, K, K2, KEY[186], KEYS, KK,
-               KNFLOC, KNIFE, KQ, L, LAMP, LIMIT, LINSIZ = 12500, LINUSE, LL,
-               LMWARN, LOC, LOCK, LOCSIZ = 185, LOCSND[186], LOOK, LTEXT[186],
+               HNTSIZ = 20, I, INVENT, IGO, J, JADE, K, K2, KEY[186], KEYS, KK,
+               KNIFE, KQ, L, LAMP, LINSIZ = 12500, LINUSE, LL,
+               LOC, LOCK, LOCSIZ = 185, LOCSND[186], LOOK, LTEXT[186],
                MAGZIN, MAXDIE, MAXTRS, MESH = 123456789,
                MESSAG, MIRROR, MXSCOR,
-               NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ, OBJSND[101],
+               NOVICE, NUGGET, NUL, OBJ, OBJSND[101],
                OBJTXT[101], ODLOC[7], OGRE, OIL, OLDLC2, OLDLOC, OLDOBJ, OYSTER,
                PANIC, PEARL, PILLOW, PLAC[101], PLANT, PLANT2, PROP[101], PYRAM,
                RESER, ROD, ROD2, RTXSIZ = 277, RUBY, RUG, SAPPH, SAVED, SAY,
@@ -39,7 +39,8 @@ long ABBNUM, ACTSPK[36], AMBER, ATTACK, AXE, BACK, BATTER, BEAR, BIRD, BLOOD, BO
                TRNDEX, TRNLUZ, TRNSIZ = 5, TRNVAL[6], TRNVLS, TROLL, TROLL2, TRVS,
                 TRVSIZ = 885, TTEXT[6], TURNS, URN, V1, V2, VASE, VEND, VERB,
                VOLCAN, VRBSIZ = 35, VRSION = 25, WATER, WD1, WD1X, WD2, WD2X,
-               WZDARK = false, ZZWORD;
+               ZZWORD;
+struct game_t game = {.blklin = true};
 FILE  *logfp;
 bool oldstyle = false;
 
@@ -83,13 +84,13 @@ int main(int argc, char *argv[]) {
 
 /* Logical variables:
  *
- *  CLOSED says whether we're all the way closed
- *  CLOSNG says whether it's closing time yet
+ *  game.closed says whether we're all the way closed
+ *  game.closng says whether it's closing time yet
  *  CLSHNT says whether he's read the clue in the endgame
- *  LMWARN says whether he's been warned about lamp going dim
+ *  game.lmwarn says whether he's been warned about lamp going dim
  *  NOVICE says whether he asked for instructions at start-up
  *  PANIC says whether he's found out he's trapped in the cave
- *  WZDARK says whether the loc he's leaving was dark */
+ *  game.wzdark says whether the loc he's leaving was dark */
 
 #include "funcs.h"
 
@@ -119,10 +120,10 @@ L1:       SETUP= -1;
        I=RAN(-1);
        ZZWORD=RNDVOC(3,0)+MESH*2;
        NOVICE=YES(stdin, 65,1,0);
-       NEWLOC=1;
+       game.newloc=1;
        LOC=1;
-       LIMIT=330;
-       if(NOVICE)LIMIT=1000;
+       game.limit=330;
+       if(NOVICE)game.limit=1000;
 
        for (;;) {
            do_command(stdin);
@@ -133,47 +134,47 @@ static void do_command(FILE *cmdin) {
 
 /*  Can't leave cave once it's closing (except by main office). */
 
-L2:    if(!OUTSID(NEWLOC) || NEWLOC == 0 || !CLOSNG) goto L71;
+L2:    if(!OUTSID(game.newloc) || game.newloc == 0 || !game.closng) goto L71;
        RSPEAK(130);
-       NEWLOC=LOC;
-       if(!PANIC)CLOCK2=15;
+       game.newloc=LOC;
+       if(!PANIC)game.clock2=15;
        PANIC=true;
 
 /*  See if a dwarf has seen him and has come from where he wants to go.  If so,
  *  the dwarf's blocking his way.  If coming from place forbidden to pirate
  *  (dwarves rooted in place) let him get out (and attacked). */
 
-L71:   if(NEWLOC == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74;
+L71:   if(game.newloc == LOC || FORCED(LOC) || CNDBIT(LOC,3)) goto L74;
        /* 73 */ for (I=1; I<=5; I++) {
-       if(ODLOC[I] != NEWLOC || !DSEEN[I]) goto L73;
-       NEWLOC=LOC;
+       if(ODLOC[I] != game.newloc || !DSEEN[I]) goto L73;
+       game.newloc=LOC;
        RSPEAK(2);
         goto L74;
 L73:   /*etc*/ ;
        } /* end loop */
-L74:   LOC=NEWLOC;
+L74:   LOC=game.newloc;
 
 /*  Dwarf stuff.  See earlier comments for description of variables.  Remember
  *  sixth dwarf is pirate and is thus very different except for motion rules. */
 
 /*  First off, don't let the dwarves follow him into a pit or a wall.  Activate
  *  the whole mess the first time he gets as far as the hall of mists (loc 15).
- *  If NEWLOC is forbidden to pirate (in particular, if it's beyond the troll
+ *  If game.newloc is forbidden to pirate (in particular, if it's beyond the troll
  *  bridge), bypass dwarf stuff.  That way pirate can't steal return toll, and
  *  dwarves can't meet the bear.  Also means dwarves won't follow him into dead
  *  end in maze, but c'est la vie.  They'll wait for him outside the dead end. */
 
-       if(LOC == 0 || FORCED(LOC) || CNDBIT(NEWLOC,3)) goto L2000;
-       if(DFLAG != 0) goto L6000;
-       if(INDEEP(LOC))DFLAG=1;
+       if(LOC == 0 || FORCED(LOC) || CNDBIT(game.newloc,3)) goto L2000;
+       if(game.dflag != 0) goto L6000;
+       if(INDEEP(LOC))game.dflag=1;
         goto L2000;
 
 /*  When we encounter the first dwarf, we kill 0, 1, or 2 of the 5 dwarves.  If
  *  any of the survivors is at loc, replace him with the alternate. */
 
-L6000: if(DFLAG != 1) goto L6010;
+L6000: if(game.dflag != 1) goto L6010;
        if(!INDEEP(LOC) || (PCT(95) && (!CNDBIT(LOC,4) || PCT(85)))) goto L2000;
-       DFLAG=2;
+       game.dflag=2;
        for (I=1; I<=2; I++) {
        J=1+RAN(5);
        if(PCT(50))DLOC[J]=0;
@@ -191,7 +192,7 @@ L6000:      if(DFLAG != 1) goto L6010;
  *  they don't back up unless there's no alternative.  If they don't have to
  *  move, they attack.  And, of course, dead dwarves don't do much of anything. */
 
-L6010: DTOTAL=0;
+L6010: game.dtotal=0;
        ATTACK=0;
        STICK=0;
        /* 6030 */ for (I=1; I<=6; I++) {
@@ -201,13 +202,13 @@ L6010:    DTOTAL=0;
        KK=DLOC[I];
        KK=KEY[KK];
        if(KK == 0) goto L6016;
-L6012: NEWLOC=MOD(IABS(TRAVEL[KK])/1000,1000);
+L6012: game.newloc=MOD(IABS(TRAVEL[KK])/1000,1000);
        {long x = J-1;
-       if(NEWLOC > 300 || !INDEEP(NEWLOC) || NEWLOC == ODLOC[I] || (J > 1 &&
-               NEWLOC == TK[x]) || J >= 20 || NEWLOC == DLOC[I] ||
-               FORCED(NEWLOC) || (I == 6 && CNDBIT(NEWLOC,3)) ||
+       if(game.newloc > 300 || !INDEEP(game.newloc) || game.newloc == ODLOC[I] || (J > 1 &&
+               game.newloc == TK[x]) || J >= 20 || game.newloc == DLOC[I] ||
+               FORCED(game.newloc) || (I == 6 && CNDBIT(game.newloc,3)) ||
                IABS(TRAVEL[KK])/1000000 == 100) goto L6014;}
-       TK[J]=NEWLOC;
+       TK[J]=game.newloc;
        J=J+1;
 L6014: KK=KK+1;
        {long x = KK-1; if(TRAVEL[x] >= 0) goto L6012;}
@@ -262,11 +263,11 @@ L6025:    RSPEAK(186);
 
 /*  This threatening little dwarf is in the room with him! */
 
-L6027: DTOTAL=DTOTAL+1;
+L6027: game.dtotal=game.dtotal+1;
        if(ODLOC[I] != DLOC[I]) goto L6030;
        ATTACK=ATTACK+1;
-       if(KNFLOC >= 0)KNFLOC=LOC;
-       if(RAN(1000) < 95*(DFLAG-2))STICK=STICK+1;
+       if(game.knfloc >= 0)game.knfloc=LOC;
+       if(RAN(1000) < 95*(game.dflag-2))STICK=STICK+1;
 L6030: /*etc*/ ;
        } /* end loop */
 
@@ -274,11 +275,11 @@ L6030:    /*etc*/ ;
  *  Note that various of the "knife" messages must have specific relative
  *  positions in the RSPEAK database. */
 
-       if(DTOTAL == 0) goto L2000;
-       SETPRM(1,DTOTAL,0);
-       RSPEAK(4+1/DTOTAL);
+       if(game.dtotal == 0) goto L2000;
+       SETPRM(1,game.dtotal,0);
+       RSPEAK(4+1/game.dtotal);
        if(ATTACK == 0) goto L2000;
-       if(DFLAG == 2)DFLAG=3;
+       if(game.dflag == 2)game.dflag=3;
        SETPRM(1,ATTACK,0);
        K=6;
        if(ATTACK > 1)K=250;
@@ -300,15 +301,15 @@ L6030:    /*etc*/ ;
 
 L2000: if(LOC == 0) goto L99;
        KK=STEXT[LOC];
-       if(MOD(ABB[LOC],ABBNUM) == 0 || KK == 0)KK=LTEXT[LOC];
+       if(MOD(ABB[LOC],game.abbnum) == 0 || KK == 0)KK=LTEXT[LOC];
        if(FORCED(LOC) || !DARK(0)) goto L2001;
-       if(WZDARK && PCT(35)) goto L90;
+       if(game.wzdark && PCT(35)) goto L90;
        KK=RTEXT[16];
 L2001: if(TOTING(BEAR))RSPEAK(141);
        SPEAK(KK);
        K=1;
        if(FORCED(LOC)) goto L8;
-       if(LOC == 33 && PCT(25) && !CLOSNG)RSPEAK(7);
+       if(LOC == 33 && PCT(25) && !game.closng)RSPEAK(7);
 
 /*  Print out descriptions of objects at this location.  If not closing and
  *  property value is negative, tally off another treasure.  Rug is special
@@ -324,7 +325,7 @@ L2004:      if(I == 0) goto L2012;
        if(OBJ > 100)OBJ=OBJ-100;
        if(OBJ == STEPS && TOTING(NUGGET)) goto L2008;
        if(PROP[OBJ] >= 0) goto L2006;
-       if(CLOSED) goto L2008;
+       if(game.closed) goto L2008;
        PROP[OBJ]=0;
        if(OBJ == RUG || OBJ == CHAIN)PROP[OBJ]=1;
        TALLY=TALLY-1;
@@ -371,22 +372,22 @@ L2602:    /*etc*/ ;
  *  if closing time, check for any objects being toted with PROP < 0 and set
  *  the prop to -1-PROP.  This way objects won't be described until they've
  *  been picked up and put down separate from their respective piles.  Don't
- *  tick CLOCK1 unless well into cave (and not at Y2). */
+ *  tick game.clock1 unless well into cave (and not at Y2). */
 
-L2603: if(!CLOSED) goto L2605;
+L2603: if(!game.closed) goto L2605;
        if(PROP[OYSTER] < 0 && TOTING(OYSTER))PSPEAK(OYSTER,1);
        for (I=1; I<=100; I++) {
        if(TOTING(I) && PROP[I] < 0)PROP[I]= -1-PROP[I];
        } /* end loop */
-L2605: WZDARK=DARK(0);
-       if(KNFLOC > 0 && KNFLOC != LOC)KNFLOC=0;
+L2605: game.wzdark=DARK(0);
+       if(game.knfloc > 0 && game.knfloc != LOC)game.knfloc=0;
        I=RAN(1);
        GETIN(cmdin, WD1,WD1X,WD2,WD2X);
 
-/*  Every input, check "FOOBAR" flag.  If zero, nothing's going on.  If pos,
+/*  Every input, check "game.foobar" flag.  If zero, nothing's going on.  If pos,
  *  make neg.  If neg, he skipped a word, so make it zero. */
 
-L2607: FOOBAR=(FOOBAR>0 ? -FOOBAR : 0);
+L2607: game.foobar=(game.foobar>0 ? -game.foobar : 0);
        TURNS=TURNS+1;
        if(TURNS != THRESH) goto L2608;
        SPEAK(TTEXT[TRNDEX]);
@@ -396,15 +397,15 @@ L2607:    FOOBAR=(FOOBAR>0 ? -FOOBAR : 0);
        if(TRNDEX <= TRNVLS)THRESH=MOD(TRNVAL[TRNDEX],100000)+1;
 L2608: if(VERB == SAY && WD2 > 0)VERB=0;
        if(VERB == SAY) goto L4090;
-       if(TALLY == 0 && INDEEP(LOC) && LOC != 33)CLOCK1=CLOCK1-1;
-       if(CLOCK1 == 0) goto L10000;
-       if(CLOCK1 < 0)CLOCK2=CLOCK2-1;
-       if(CLOCK2 == 0) goto L11000;
-       if(PROP[LAMP] == 1)LIMIT=LIMIT-1;
-       if(LIMIT <= 30 && HERE(BATTER) && PROP[BATTER] == 0 && HERE(LAMP)) goto
+       if(TALLY == 0 && INDEEP(LOC) && LOC != 33)game.clock1=game.clock1-1;
+       if(game.clock1 == 0) goto L10000;
+       if(game.clock1 < 0)game.clock2=game.clock2-1;
+       if(game.clock2 == 0) goto L11000;
+       if(PROP[LAMP] == 1)game.limit=game.limit-1;
+       if(game.limit <= 30 && HERE(BATTER) && PROP[BATTER] == 0 && HERE(LAMP)) goto
                L12000;
-       if(LIMIT == 0) goto L12400;
-       if(LIMIT <= 30) goto L12200;
+       if(game.limit == 0) goto L12400;
+       if(game.limit <= 30) goto L12200;
 L19999: K=43;
        if(LIQLOC(LOC) == WATER)K=70;
        V1=VOCAB(WD1,-1);
@@ -417,8 +418,8 @@ L19999: K=43;
 L2610: if(V1 == 1000+CAGE && V2 == 1000+BIRD && HERE(CAGE) &&
                HERE(BIRD))WD1=MAKEWD(301200308);
 L2620: if(WD1 != MAKEWD(23051920)) goto L2625;
-       IWEST=IWEST+1;
-       if(IWEST == 10)RSPEAK(17);
+       game.iwest=game.iwest+1;
+       if(game.iwest == 10)RSPEAK(17);
 L2625: if(WD1 != MAKEWD( 715) || WD2 == 0) goto L2630;
        IGO=IGO+1;
        if(IGO == 10)RSPEAK(276);
@@ -478,13 +479,13 @@ L8000:    SETPRM(1,WD1,WD1X);
 /*  Figure out the new location
  *
  *  Given the current location in "LOC", and a motion verb number in "K", put
- *  the new location in "NEWLOC".  The current loc is saved in "OLDLOC" in case
+ *  the new location in "game.newloc".  The current loc is saved in "OLDLOC" in case
  *  he wants to retreat.  The current OLDLOC is saved in OLDLC2, in case he
- *  dies.  (if he does, NEWLOC will be limbo, and OLDLOC will be what killed
+ *  dies.  (if he does, game.newloc will be limbo, and OLDLOC will be what killed
  *  him, so we need OLDLC2, which is the last place he was safe.) */
 
 L8:    KK=KEY[LOC];
-       NEWLOC=LOC;
+       game.newloc=LOC;
        if(KK == 0)BUG(26);
        if(K == NUL) return;
        if(K == BACK) goto L20;
@@ -500,34 +501,34 @@ L9:       LL=IABS(TRAVEL[KK]);
         goto L9;
 
 L10:   LL=LL/1000;
-L11:   NEWLOC=LL/1000;
-       K=MOD(NEWLOC,100);
-       if(NEWLOC <= 300) goto L13;
-       if(PROP[K] != NEWLOC/100-3) goto L16;
+L11:   game.newloc=LL/1000;
+       K=MOD(game.newloc,100);
+       if(game.newloc <= 300) goto L13;
+       if(PROP[K] != game.newloc/100-3) goto L16;
 L12:   if(TRAVEL[KK] < 0)BUG(25);
        KK=KK+1;
-       NEWLOC=IABS(TRAVEL[KK])/1000;
-       if(NEWLOC == LL) goto L12;
-       LL=NEWLOC;
+       game.newloc=IABS(TRAVEL[KK])/1000;
+       if(game.newloc == LL) goto L12;
+       LL=game.newloc;
         goto L11;
 
-L13:   if(NEWLOC <= 100) goto L14;
-       if(TOTING(K) || (NEWLOC > 200 && AT(K))) goto L16;
+L13:   if(game.newloc <= 100) goto L14;
+       if(TOTING(K) || (game.newloc > 200 && AT(K))) goto L16;
         goto L12;
 
-L14:   if(NEWLOC != 0 && !PCT(NEWLOC)) goto L12;
-L16:   NEWLOC=MOD(LL,1000);
-       if(NEWLOC <= 300) return;
-       if(NEWLOC <= 500) goto L30000;
-       RSPEAK(NEWLOC-500);
-       NEWLOC=LOC;
+L14:   if(game.newloc != 0 && !PCT(game.newloc)) goto L12;
+L16:   game.newloc=MOD(LL,1000);
+       if(game.newloc <= 300) return;
+       if(game.newloc <= 500) goto L30000;
+       RSPEAK(game.newloc-500);
+       game.newloc=LOC;
         return;
 
 /*  Special motions come here.  Labelling convention: statement numbers NNNXX
  *  (XX=00-99) are used for special case number NNN (NNN=301-500). */
 
-L30000: NEWLOC=NEWLOC-300;
-        switch (NEWLOC) { case 1: goto L30100; case 2: goto L30200; case 3: goto
+L30000: game.newloc=game.newloc-300;
+        switch (game.newloc) { case 1: goto L30100; case 2: goto L30200; case 3: goto
                L30300; }
        BUG(20);
 
@@ -535,9 +536,9 @@ L30000: NEWLOC=NEWLOC-300;
  *  table must include "useless" entries going through passage, which can never
  *  be used for actual motion, but can be spotted by "go back". */
 
-L30100: NEWLOC=99+100-LOC;
-       if(HOLDNG == 0 || (HOLDNG == 1 && TOTING(EMRALD))) return;
-       NEWLOC=LOC;
+L30100: game.newloc=99+100-LOC;
+       if(game.holdng == 0 || (game.holdng == 1 && TOTING(EMRALD))) return;
+       game.newloc=LOC;
        RSPEAK(117);
         return;
 
@@ -562,19 +563,19 @@ L30300: if(PROP[TROLL] != 1) goto L30310;
        MOVE(TROLL,PLAC[TROLL]);
        MOVE(TROLL+100,FIXD[TROLL]);
        JUGGLE(CHASM);
-       NEWLOC=LOC;
+       game.newloc=LOC;
         return;
 
-L30310: NEWLOC=PLAC[TROLL]+FIXD[TROLL]-LOC;
+L30310: game.newloc=PLAC[TROLL]+FIXD[TROLL]-LOC;
        if(PROP[TROLL] == 0)PROP[TROLL]=1;
        if(!TOTING(BEAR)) return;
        RSPEAK(162);
        PROP[CHASM]=1;
        PROP[TROLL]=2;
-       DROP(BEAR,NEWLOC);
+       DROP(BEAR,game.newloc);
        FIXED[BEAR]= -1;
        PROP[BEAR]=3;
-       OLDLC2=NEWLOC;
+       OLDLC2=game.newloc;
         goto L99;
 
 /*  End of specials. */
@@ -614,9 +615,9 @@ L25:        K=MOD(IABS(TRAVEL[KK]),1000);
 /*  Look.  Can't give more detail.  Pretend it wasn't dark (though it may "now"
  *  be dark) so he won't fall into a pit while staring into the gloom. */
 
-L30:   if(DETAIL < 3)RSPEAK(15);
-       DETAIL=DETAIL+1;
-       WZDARK=false;
+L30:   if(game.detail < 3)RSPEAK(15);
+       game.detail=game.detail+1;
+       game.wzdark=false;
        ABB[LOC]=0;
         return;
 
@@ -668,10 +669,10 @@ L90:      RSPEAK(23);
 
 /*  Okay, he's dead.  Let's get on with it. */
 
-L99:   if(CLOSNG) goto L95;
-       NUMDIE=NUMDIE+1;
-       if(!YES(cmdin,79+NUMDIE*2,80+NUMDIE*2,54)) score(0);
-       if(NUMDIE == MAXDIE) score(0);
+L99:   if(game.closng) goto L95;
+       game.numdie=game.numdie+1;
+       if(!YES(cmdin,79+game.numdie*2,80+game.numdie*2,54)) score(0);
+       if(game.numdie == MAXDIE) score(0);
        PLACE[WATER]=0;
        PLACE[OIL]=0;
        if(TOTING(LAMP))PROP[LAMP]=0;
@@ -690,7 +691,7 @@ L98:        /*etc*/ ;
 /*  He died during closing time.  No resurrection.  Tally up a death and exit. */
 
 L95:   RSPEAK(131);
-       NUMDIE=NUMDIE+1;
+       game.numdie=game.numdie+1;
         score(0);
 
 
@@ -717,7 +718,7 @@ L40010: HINTLC[HINT]=0;
        SETPRM(1,HINTS[HINT][2],HINTS[HINT][2]);
        RSPEAK(261);
        HINTED[HINT]=YES(cmdin,175,HINTS[HINT][4],54);
-       if(HINTED[HINT] && LIMIT > 30)LIMIT=LIMIT+30*HINTS[HINT][2];
+       if(HINTED[HINT] && game.limit > 30)game.limit=game.limit+30*HINTS[HINT][2];
 L40020: HINTLC[HINT]=0;
 L40030:  goto L2602;
 
@@ -732,7 +733,7 @@ L40200: if(PLACE[BIRD] == LOC && TOTING(ROD) && OLDOBJ == BIRD) goto L40010;
 L40300: if(HERE(SNAKE) && !HERE(BIRD)) goto L40010;
         goto L40020;
 
-L40400: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0 && HOLDNG >
+L40400: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0 && game.holdng >
                1) goto L40010;
         goto L40020;
 
@@ -741,7 +742,7 @@ L40500: if(PROP[EMRALD] != -1 && PROP[PYRAM] == -1) goto L40010;
 
 L40600:  goto L40010;
 
-L40700: if(DFLAG == 0) goto L40010;
+L40700: if(game.dflag == 0) goto L40010;
         goto L40020;
 
 L40800: if(ATLOC[LOC] == 0 && ATLOC[OLDLOC] == 0 && ATLOC[OLDLC2] == 0) goto
@@ -763,15 +764,15 @@ L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010;
 /*  Cave closing and scoring */
 
 
-/*  These sections handle the closing of the cave.  The cave closes "CLOCK1"
+/*  These sections handle the closing of the cave.  The cave closes "game.clock1"
  *  turns after the last treasure has been located (including the pirate's
  *  chest, which may of course never show up).  Note that the treasures need not
- *  have been taken yet, just located.  Hence CLOCK1 must be large enough to get
+ *  have been taken yet, just located.  Hence game.clock1 must be large enough to get
  *  out of the cave (it only ticks while inside the cave).  When it hits zero,
  *  we branch to 10000 to start closing the cave, and then sit back and wait for
- *  him to try to get out.  If he doesn't within CLOCK2 turns, we close the
+ *  him to try to get out.  If he doesn't within game.clock2 turns, we close the
  *  cave; if he does try, we assume he panics, and give him a few additional
- *  turns to get frantic before we close.  When CLOCK2 hits zero, we branch to
+ *  turns to get frantic before we close.  When game.clock2 hits zero, we branch to
  *  11000 to transport him into the final puzzle.  Note that the puzzle depends
  *  upon all sorts of random things.  For instance, there must be no water or
  *  oil, since there are beanstalks which we don't want to be able to water,
@@ -783,8 +784,8 @@ L41000: if(TALLY == 1 && PROP[JADE] < 0) goto L40010;
 
 /*  When the first warning comes, we lock the grate, destroy the bridge, kill
  *  all the dwarves (and the pirate), remove the troll and bear (unless dead),
- *  and set "CLOSNG" to true.  Leave the dragon; too much trouble to move it.
- *  from now until CLOCK2 runs out, he cannot unlock the grate, move to any
+ *  and set "game.closng" to true.  Leave the dragon; too much trouble to move it.
+ *  from now until game.clock2 runs out, he cannot unlock the grate, move to any
  *  location outside the cave, or create the bridge.  Nor can he be
  *  resurrected if he dies.  Note that the snake is already gone, since he got
  *  to the treasure accessible only via the hall of the mountain king. Also, he's
@@ -809,11 +810,11 @@ L10000: PROP[GRATE]=0;
        PROP[AXE]=0;
        FIXED[AXE]=0;
        RSPEAK(129);
-       CLOCK1= -1;
-       CLOSNG=true;
+       game.clock1= -1;
+       game.closng=true;
         goto L19999;
 
-/*  ONCE HE'S PANICKED, AND CLOCK2 HAS RUN OUT, WE COME HERE TO SET UP THE
+/*  ONCE HE'S PANICKED, AND game.clock2 HAS RUN OUT, WE COME HERE TO SET UP THE
  *  STORAGE ROOM.  THE ROOM HAS TWO LOCS, HARDWIRED AS 115 (NE) AND 116 (SW).
  *  AT THE NE END, WE PLACE EMPTY BOTTLES, A NURSERY OF PLANTS, A BED OF
  *  OYSTERS, A PILE OF LAMPS, RODS WITH STARS, SLEEPING DWARVES, AND HIM.  AT
@@ -834,7 +835,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
        PROP[DWARF]=PUT(DWARF,115,0);
        LOC=115;
        OLDLOC=115;
-       NEWLOC=115;
+       game.newloc=115;
 
 /*  Leave the grate with normal (non-negative) property.  Reuse sign. */
 
@@ -855,7 +856,7 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
        } /* end loop */
 
        RSPEAK(132);
-       CLOSED=true;
+       game.closed=true;
         return;
 
 /*  Another way we can force an end to things is by having the lamp give out.
@@ -867,19 +868,19 @@ L11000: PROP[BOTTLE]=PUT(BOTTLE,115,1);
 L12000: RSPEAK(188);
        PROP[BATTER]=1;
        if(TOTING(BATTER))DROP(BATTER,LOC);
-       LIMIT=LIMIT+2500;
-       LMWARN=false;
+       game.limit=game.limit+2500;
+       game.lmwarn=false;
         goto L19999;
 
-L12200: if(LMWARN || !HERE(LAMP)) goto L19999;
-       LMWARN=true;
+L12200: if(game.lmwarn || !HERE(LAMP)) goto L19999;
+       game.lmwarn=true;
        SPK=187;
        if(PLACE[BATTER] == 0)SPK=183;
        if(PROP[BATTER] == 1)SPK=189;
        RSPEAK(SPK);
         goto L19999;
 
-L12400: LIMIT= -1;
+L12400: game.limit= -1;
        PROP[LAMP]=0;
        if(HERE(LAMP))RSPEAK(184);
         goto L19999;
diff --git a/main.h b/main.h
index fa87d627ec8847e720f844ca471bcd41cea47872..dfc27bd2cec358e6497ec0eecbccd22b348589bd 100644 (file)
--- a/main.h
+++ b/main.h
@@ -2,9 +2,38 @@
 
 #define LINESIZE       100
 
-extern long ABB[], ATAB[], ATLOC[], BLKLIN, DFLAG, DLOC[], FIXED[], HOLDNG,
+extern long ABB[], ATAB[], ATLOC[], DLOC[], FIXED[],
                KTAB[], *LINES, LINK[], LNLENG, LNPOSN,
                PARMS[], PLACE[], PTEXT[], RTEXT[], TABSIZ;
 extern signed char INLINE[LINESIZE+1], MAP1[], MAP2[];
 extern FILE *logfp;
 extern bool oldstyle;
+
+struct game_t  {
+    /* These members are in the save order of the individual variables
+     * in the 2.5 code. */
+    long abbnum;
+    long blklin;
+    long bonus;
+    long clock1;
+    long clock2;
+    long closed;
+    long closng;
+    long detail;
+    long dflag;
+    long dkill;
+    long dtotal;
+    long foobar;
+    long holdng;
+    long iwest;
+    long knfloc;
+    long limit;
+    /* LL may go here */
+    long lmwarn;
+    /* LOC will go here */
+    long newloc;
+    long numdie;
+    /* more state will go here */
+    long wzdark;
+};
+extern struct game_t game;
diff --git a/misc.c b/misc.c
index 63052ced47351603e80fccdd31da28c47ca90cca..8d5a296d61e2068ae19deafc228c35547da46d35 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -15,11 +15,11 @@ void fSPEAK(long N) {
 long BLANK, CASE, I, K, L, NEG, NPARMS, PARM, PRMTYP, STATE;
 
 /*  Print the message which starts at LINES(N).  Precede it with a blank line
- *  unless BLKLIN is false. */
+ *  unless game.blklin is false. */
 
 
        if(N == 0)return;
-       BLANK=BLKLIN;
+       BLANK=game.blklin;
        K=N;
        NPARMS=1;
 L10:   L=IABS(LINES[K])-1;
@@ -182,11 +182,11 @@ long JUNK;
  *  WORD2 (chars 6 thru 10 in WORD2X), else WORD2 is -1. */
 
 
-L10:   if(BLKLIN)TYPE0();
+L10:   if(game.blklin)TYPE0();
        MAPLIN(input);
        if(input == stdin && feof(stdin)) score(1);
        WORD1=GETTXT(true,true,true,0);
-       if(BLKLIN && WORD1 < 0) goto L10;
+       if(game.blklin && WORD1 < 0) goto L10;
        WORD1X=GETTXT(false,true,true,0);
 L12:   JUNK=GETTXT(false,true,true,0);
        if(JUNK > 0) goto L12;
@@ -650,13 +650,13 @@ long TEMP;
 
 /*  Start toting an object, removing it from the list of things at its former
  *  location.  Incr holdng unless it was already being toted.  If OBJECT>100
- *  (moving "fixed" second loc), don't change PLACE or HOLDNG. */
+ *  (moving "fixed" second loc), don't change PLACE or game.holdng. */
 
 
        if(OBJECT > 100) goto L5;
        if(PLACE[OBJECT] == -1)return;
        PLACE[OBJECT]= -1;
-       HOLDNG=HOLDNG+1;
+       game.holdng=game.holdng+1;
 L5:    if(ATLOC[WHERE] != OBJECT) goto L6;
        ATLOC[WHERE]=LINK[OBJECT];
        return;
@@ -676,11 +676,11 @@ void fDROP(long OBJECT, long WHERE) {
 ;
 
 /*  Place an object at a given loc, prefixing it onto the ATLOC list.  Decr
- *  HOLDNG if the object was being toted. */
+ *  game.holdng if the object was being toted. */
 
 
        if(OBJECT > 100) goto L1;
-       if(PLACE[OBJECT] == -1)HOLDNG=HOLDNG-1;
+       if(PLACE[OBJECT] == -1)game.holdng=game.holdng-1;
        PLACE[OBJECT]=WHERE;
         goto L2;
 L1:    {long x = OBJECT-100; FIXED[x]=WHERE;}
@@ -703,7 +703,7 @@ long ATDWRF, I;
 
 
        ATDWRF=0;
-       if(DFLAG < 2)return(ATDWRF);
+       if(game.dflag < 2)return(ATDWRF);
        ATDWRF= -1;
        for (I=1; I<=5; I++) {
        if(DLOC[I] == WHERE) goto L2;
diff --git a/score.c b/score.c
index 162cc5d9dfb49d9f97103833e298143c19ccea59..484a9e7097ddef22996bc15823e5c214893b70b2 100644 (file)
--- a/score.c
+++ b/score.c
@@ -18,7 +18,7 @@ void score(long MODE) {
  *  Each treasure > chest    16                   224
  *  Surviving             (MAX-NUM)*10             30
  *  Not quitting              4                     4
- *  Reaching "CLOSNG"        25                    25
+ *  Reaching "game.closng"        25                    25
  *  "Closed": Quit/Killed    10
  *            Klutzed        25
  *            Wrong way      30
@@ -46,26 +46,26 @@ void score(long MODE) {
 L20010: /*etc*/ ;
        } /* end loop */
 
-/*  Now look at how he finished and how far he got.  MAXDIE and NUMDIE tell us
- *  how well he survived.  DFLAG will
- *  tell us if he ever got suitably deep into the cave.  CLOSNG still indicates
+/*  Now look at how he finished and how far he got.  MAXDIE and game.numdie tell us
+ *  how well he survived.  game.dflag will
+ *  tell us if he ever got suitably deep into the cave.  game.closng still indicates
  *  whether he reached the endgame.  And if he got as far as "cave closed"
- *  (indicated by "CLOSED"), then bonus is zero for mundane exits or 133, 134,
+ *  (indicated by "game.closed"), then game.bonus is zero for mundane exits or 133, 134,
  *  135 if he blew it (so to speak). */
 
-       SCORE=SCORE+(MAXDIE-NUMDIE)*10;
+       SCORE=SCORE+(MAXDIE-game.numdie)*10;
        MXSCOR=MXSCOR+MAXDIE*10;
        if(MODE == 0)SCORE=SCORE+4;
        MXSCOR=MXSCOR+4;
-       if(DFLAG != 0)SCORE=SCORE+25;
+       if(game.dflag != 0)SCORE=SCORE+25;
        MXSCOR=MXSCOR+25;
-       if(CLOSNG)SCORE=SCORE+25;
+       if(game.closng)SCORE=SCORE+25;
        MXSCOR=MXSCOR+25;
-       if(!CLOSED) goto L20020;
-       if(BONUS == 0)SCORE=SCORE+10;
-       if(BONUS == 135)SCORE=SCORE+25;
-       if(BONUS == 134)SCORE=SCORE+30;
-       if(BONUS == 133)SCORE=SCORE+45;
+       if(!game.closed) goto L20020;
+       if(game.bonus == 0)SCORE=SCORE+10;
+       if(game.bonus == 135)SCORE=SCORE+25;
+       if(game.bonus == 134)SCORE=SCORE+30;
+       if(game.bonus == 133)SCORE=SCORE+45;
 L20020: MXSCOR=MXSCOR+45;
 
 /*  Did he come to Witt's End as he should? */
diff --git a/share.h b/share.h
index ff4252b3c56afe840e7f8ca62bc6021b6e6e91ce..7beee36d986a18c64ea6c67fd184361ad8f1ac09 100644 (file)
--- a/share.h
+++ b/share.h
@@ -1,17 +1,17 @@
 extern void score(long);
-extern long ABBNUM, ACTSPK[], AMBER, ATTACK, AXE, BACK, BATTER, BEAR,
-   BIRD, BLOOD, BONUS,
+extern long ACTSPK[], AMBER, ATTACK, AXE, BACK, BATTER, BEAR,
+   BIRD, BLOOD,
    BOTTLE, CAGE, CAVE, CAVITY, CHAIN, CHASM, CHEST, CHLOC, CHLOC2,
-   CLAM, CLOCK1, CLOCK2, CLOSED, CLOSNG, CLSHNT, CLSMAX, CLSSES,
-   COINS, COND[], CONDS, CTEXT[], CVAL[], DALTLC, DETAIL,
-   DKILL, DOOR, DPRSSN, DRAGON, DSEEN[], DTOTAL, DWARF, EGGS,
-   EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[], FOOBAR, FOOD,
+   CLAM, CLSHNT, CLSMAX, CLSSES,
+   COINS, COND[], CONDS, CTEXT[], CVAL[], DALTLC,
+   DOOR, DPRSSN, DRAGON, DSEEN[], DWARF, EGGS,
+   EMRALD, ENTER, ENTRNC, FIND, FISSUR, FIXD[], FOOD,
    GRATE, HINT, HINTED[], HINTLC[], HINTS[][5], HNTMAX,
-   HNTSIZ, I, INVENT, IGO, IWEST, J, JADE, K, K2, KEY[], KEYS, KK,
-   KNFLOC, KNIFE, KQ, L, LAMP, LIMIT, LINSIZ, LINUSE, LL,
-   LMWARN, LOC, LOCK, LOCSIZ, LOCSND[], LOOK, LTEXT[],
+   HNTSIZ, I, INVENT, IGO, J, JADE, K, K2, KEY[], KEYS, KK,
+   KNIFE, KQ, L, LAMP, LINSIZ, LINUSE, LL,
+   LOC, LOCK, LOCSIZ, LOCSND[], LOOK, LTEXT[],
    MAGZIN, MAXDIE, MAXTRS, MESH, MESSAG, MIRROR, MXSCOR,
-   NEWLOC, NOVICE, NUGGET, NUL, NUMDIE, OBJ, OBJSND[],
+   NOVICE, NUGGET, NUL, OBJ, OBJSND[],
    OBJTXT[], ODLOC[], OGRE, OIL, OLDLC2, OLDLOC, OLDOBJ, OYSTER,
    PANIC, PEARL, PILLOW, PLAC[], PLANT, PLANT2, PROP[], PYRAM,
    RESER, ROD, ROD2, RTXSIZ, RUBY, RUG, SAPPH, SAVED, SAY,
@@ -20,5 +20,4 @@ extern long ABBNUM, ACTSPK[], AMBER, ATTACK, AXE, BACK, BATTER, BEAR,
    TRNDEX, TRNLUZ, TRNSIZ, TRNVAL[], TRNVLS, TROLL, TROLL2, TRVS,
    TRVSIZ, TTEXT[], TURNS, URN, V1, V2, VASE, VEND, VERB,
    VOLCAN, VRBSIZ, VRSION, WATER, WD1, WD1X, WD2, WD2X,
-   WZDARK, ZZWORD;
-
+   ZZWORD;