Refactor tokenization to save raw tokens and use static buffer space...
[open-adventure.git] / main.c
diff --git a/main.c b/main.c
index 7eb21dab571a9be8d7c381f89ddac3d67eafb91a..c2c4daa79a5029c26dfe06705b1cba99403d17a8 100644 (file)
--- a/main.c
+++ b/main.c
@@ -185,7 +185,7 @@ static void checkhints(void)
                     game.hintlc[hint] = 0;
                     return;
                 case 4:        /* dark */
-                    if (game.prop[EMERALD] != NOT_YET_FOUND && game.prop[PYRAMID] == NOT_YET_FOUND)
+                    if (game.prop[EMERALD] != STATE_NOTFOUND && game.prop[PYRAMID] == STATE_NOTFOUND)
                         break;
                     game.hintlc[hint] = 0;
                     return;
@@ -245,7 +245,8 @@ static bool spotted_by_pirate(int i)
      *  that game.place[CHEST] = LOC_NOWHERE might mean that he's thrown
      *  it to the troll, but in that case he's seen the chest
      *  (game.prop=0). */
-    if (game.loc == game.chloc || game.prop[CHEST] >= 0)
+    if (game.loc == game.chloc ||
+        game.prop[CHEST] >= 0)
         return true;
     int snarfed = 0;
     bool movechest = false, robplayer = false;
@@ -254,10 +255,12 @@ static bool spotted_by_pirate(int i)
             continue;
         /*  Pirate won't take pyramid from plover room or dark
          *  room (too easy!). */
-        if (treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac)) {
+        if (treasure == PYRAMID && (game.loc == objects[PYRAMID].plac ||
+                                    game.loc == objects[EMERALD].plac)) {
             continue;
         }
-        if (TOTING(treasure) || HERE(treasure))
+        if (TOTING(treasure) ||
+            HERE(treasure))
             ++snarfed;
         if (TOTING(treasure)) {
             movechest = true;
@@ -288,7 +291,8 @@ static bool spotted_by_pirate(int i)
         for (int treasure = 1; treasure <= NOBJECTS; treasure++) {
             if (!objects[treasure].is_treasure)
                 continue;
-            if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac || game.loc == objects[EMERALD].plac))) {
+            if (!(treasure == PYRAMID && (game.loc == objects[PYRAMID].plac ||
+                                          game.loc == objects[EMERALD].plac))) {
                 if (AT(treasure) && game.fixed[treasure] == 0)
                     carry(treasure, game.loc);
                 if (TOTING(treasure))
@@ -319,7 +323,9 @@ static bool dwarfmove(void)
      *  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 (game.loc == 0 || FORCED(game.loc) || CNDBIT(game.newloc, COND_NOARRR))
+    if (game.loc == 0 ||
+        FORCED(game.loc) ||
+        CNDBIT(game.newloc, COND_NOARRR))
         return true;
 
     /* Dwarf activity level ratchets up */
@@ -333,7 +339,9 @@ static bool dwarfmove(void)
      *  the 5 dwarves.  If any of the survivors is at loc,
      *  replace him with the alternate. */
     if (game.dflag == 1) {
-        if (!INDEEP(game.loc) || (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) || PCT(85))))
+        if (!INDEEP(game.loc) ||
+            (PCT(95) && (!CNDBIT(game.loc, COND_NOBACK) ||
+                         PCT(85))))
             return true;
         game.dflag = 2;
         for (int i = 1; i <= 2; i++) {
@@ -400,7 +408,9 @@ static bool dwarfmove(void)
         j = 1 + randrange(j);
         game.odloc[i] = game.dloc[i];
         game.dloc[i] = tk[j];
-        game.dseen[i] = (game.dseen[i] && INDEEP(game.loc)) || (game.dloc[i] == game.loc || game.odloc[i] == game.loc);
+        game.dseen[i] = (game.dseen[i] && INDEEP(game.loc)) ||
+                        (game.dloc[i] == game.loc ||
+                         game.odloc[i] == game.loc);
         if (!game.dseen[i])
             continue;
         game.dloc[i] = game.loc;
@@ -471,7 +481,8 @@ static void croak(void)
          *  death and exit. */
         rspeak(DEATH_CLOSING);
         terminate(endgame);
-    } else if (game.numdie == NDEATHS || !yes(query, yes_response, arbitrary_messages[OK_MAN]))
+    } else if (game.numdie == NDEATHS ||
+               !yes(query, yes_response, arbitrary_messages[OK_MAN]))
         terminate(endgame);
     else {
         game.place[WATER] = game.place[OIL] = LOC_NOWHERE;
@@ -504,14 +515,14 @@ static bool traveleq(long a, long b)
  *  him, so we need game.oldlc2, which is the last place he was
  *  safe.) */
 
-static bool playermove( int motion)
+static void playermove( int motion)
 {
     int scratchloc, travel_entry = tkey[game.loc];
     game.newloc = game.loc;
     if (travel_entry == 0)
         BUG(LOCATION_HAS_NO_TRAVEL_ENTRIES); // LCOV_EXCL_LINE
     if (motion == NUL)
-        return true;
+        return;
     else if (motion == BACK) {
         /*  Handle "go back".  Look for verb which goes from game.loc to
          *  game.oldloc, or to game.oldlc2 If game.oldloc has forced-motion.
@@ -543,7 +554,7 @@ static bool playermove( int motion)
                     travel_entry = te_tmp;
                     if (travel_entry == 0) {
                         rspeak(NOT_CONNECTED);
-                        return true;
+                        return;
                     }
                 }
 
@@ -553,7 +564,7 @@ static bool playermove( int motion)
             }
         } else {
             rspeak(spk);
-            return true;
+            return;
         }
     } else if (motion == LOOK) {
         /*  Look.  Can't give more detail.  Pretend it wasn't dark
@@ -564,11 +575,11 @@ static bool playermove( int motion)
         ++game.detail;
         game.wzdark = false;
         game.abbrev[game.loc] = 0;
-        return true;
+        return;
     } else if (motion == CAVE) {
         /*  Cave.  Different messages depending on whether above ground. */
         rspeak((OUTSID(game.loc) && game.loc != LOC_GRATE) ? FOLLOW_STREAM : NEED_DETAIL);
-        return true;
+        return;
     } else {
         /* none of the specials */
         game.oldlc2 = game.oldloc;
@@ -578,7 +589,8 @@ static bool playermove( int motion)
     /* Look for a way to fulfil the motion verb passed in - travel_entry indexes
      * the beginning of the motion entries for here (game.loc). */
     for (;;) {
-        if (T_TERMINATE(travel[travel_entry]) || travel[travel_entry].motion == motion)
+        if (T_TERMINATE(travel[travel_entry]) ||
+            travel[travel_entry].motion == motion)
             break;
         if (travel[travel_entry].stop) {
             /*  Couldn't find an entry matching the motion word passed
@@ -586,18 +598,23 @@ static bool playermove( int motion)
             int spk = CANT_APPLY;
             if (motion >= EAST && motion <= NW)
                 spk = BAD_DIRECTION;
-            if (motion == UP || motion == DOWN)
+            if (motion == UP ||
+                motion == DOWN)
                 spk = BAD_DIRECTION;
-            if (motion == FORWARD || motion == LEFT || motion == RIGHT)
+            if (motion == FORWARD ||
+                motion == LEFT ||
+                motion == RIGHT)
                 spk = UNSURE_FACING;
-            if (motion == OUTSIDE || motion == INSIDE)
+            if (motion == OUTSIDE ||
+                motion == INSIDE)
                 spk = NO_INOUT_HERE;
-            if (motion == XYZZY || motion == PLUGH)
+            if (motion == XYZZY ||
+                motion == PLUGH)
                 spk = NOTHING_HAPPENS;
             if (motion == CRAWL)
                 spk = WHICH_WAY;
             rspeak(spk);
-            return true;
+            return;
         }
         ++travel_entry;
     }
@@ -614,12 +631,14 @@ static bool playermove( int motion)
                 if (!SPECIAL(cond)) {
                     /* YAML N and [pct N] conditionals */
                     if (cond <= 100) {
-                        if (cond == 0 || PCT(cond))
+                        if (cond == 0 ||
+                            PCT(cond))
                             break;
                         /* else fall through */
                     }
                     /* YAML [with OBJ] clause */
-                    if (TOTING(arg) || (cond > 200 && AT(arg)))
+                    if (TOTING(arg) ||
+                        (cond > 200 && AT(arg)))
                         break;
                     /* else fall through to check [not OBJ STATE] */
                 } else if (game.prop[arg] != cond / 100 - 3)
@@ -640,13 +659,13 @@ static bool playermove( int motion)
             /* Found an eligible rule, now execute it */
             game.newloc = travel[travel_entry].dest;
             if (!SPECIAL(game.newloc))
-                return true;
+                return;
 
             if (game.newloc > 500) {
                 /* Execute a speak rule */
                 rspeak(L_SPEAK(game.newloc));
                 game.newloc = game.loc;
-                return true;
+                return;
             } else {
                 game.newloc -= SPECIALBASE;
                 switch (game.newloc) {
@@ -657,11 +676,12 @@ static bool playermove( int motion)
                      * for actual motion, but can be spotted by "go back". */
                     /* FIXME: Arithmetic on location numbers */
                     game.newloc = 99 + 100 - game.loc;
-                    if (game.holdng > 1 || (game.holdng == 1 && !TOTING(EMERALD))) {
+                    if (game.holdng > 1 ||
+                        (game.holdng == 1 && !TOTING(EMERALD))) {
                         game.newloc = game.loc;
                         rspeak(MUST_DROP);
                     }
-                    return true;
+                    return;
                 case 2:
                     /* Travel 302.  Plover transport.  Drop the
                      * emerald (only use special travel if toting
@@ -689,7 +709,7 @@ static bool playermove( int motion)
                      * entries check for game.prop(TROLL)=0.)  Special
                      * stuff for bear. */
                     if (game.prop[TROLL] == TROLL_PAIDONCE) {
-                        pspeak(TROLL, look, TROLL_PAIDONCE);
+                        pspeak(TROLL, look, TROLL_PAIDONCE, true);
                         game.prop[TROLL] = TROLL_UNPAID;
                         move(TROLL2, 0);
                         move(TROLL2 + NOBJECTS, 0);
@@ -697,13 +717,13 @@ static bool playermove( int motion)
                         move(TROLL + NOBJECTS, objects[TROLL].fixd);
                         juggle(CHASM);
                         game.newloc = game.loc;
-                        return true;
+                        return;
                     } else {
                         game.newloc = objects[TROLL].plac + objects[TROLL].fixd - game.loc;
                         if (game.prop[TROLL] == TROLL_UNPAID)
                             game.prop[TROLL] = TROLL_PAIDONCE;
                         if (!TOTING(BEAR))
-                            return true;
+                            return;
                         rspeak(BRIDGE_COLLAPSE);
                         game.prop[CHASM] = BRIDGE_WRECKED;
                         game.prop[TROLL] = TROLL_GONE;
@@ -712,7 +732,7 @@ static bool playermove( int motion)
                         game.prop[BEAR] = BEAR_DEAD;
                         game.oldlc2 = game.newloc;
                         croak();
-                        return true;
+                        return;
                     }
                 default:
                     BUG(SPECIAL_TRAVEL_500_GT_L_GT_300_EXCEEDS_GOTO_LIST); // LCOV_EXCL_LINE
@@ -917,7 +937,7 @@ static void listobjects(void)
             int kk = game.prop[obj];
             if (obj == STEPS && game.loc == game.fixed[STEPS])
                 kk = 1;
-            pspeak(obj, look, kk);
+            pspeak(obj, look, kk, true);
         }
     }
 }
@@ -964,7 +984,8 @@ static bool do_command()
         if (game.loc == 0)
             croak();
         const char* msg = locations[game.loc].description.small;
-        if (MOD(game.abbrev[game.loc], game.abbnum) == 0 || msg == 0)
+        if (MOD(game.abbrev[game.loc], game.abbnum) == 0 ||
+            msg == 0)
             msg = locations[game.loc].description.big;
         if (!FORCED(game.loc) && DARK(game.loc)) {
             /*  The easiest way to get killed is to fall into a pit in
@@ -981,10 +1002,8 @@ static bool do_command()
             rspeak(TAME_BEAR);
         speak(msg);
         if (FORCED(game.loc)) {
-            if (playermove(HERE))
-                return true;
-            else
-                continue;      /* back to top of main interpreter loop */
+            playermove(HERE);
+           return true;
         }
         if (game.loc == LOC_Y2 && PCT(25) && !game.closng)
             rspeak(SAYS_PLUGH);
@@ -1006,7 +1025,7 @@ L2600:
          *  tick game.clock1 unless well into cave (and not at Y2). */
         if (game.closed) {
             if (game.prop[OYSTER] < 0 && TOTING(OYSTER))
-                pspeak(OYSTER, look, 1);
+                pspeak(OYSTER, look, 1, true);
             for (size_t i = 1; i <= NOBJECTS; i++) {
                 if (TOTING(i) && game.prop[i] < 0)
                     game.prop[i] = -1 - game.prop[i];
@@ -1035,12 +1054,7 @@ L2600:
         strncpy(inputbuf, input, LINESIZE - 1);
         free(input);
 
-        long tokens[4];
-        tokenize(inputbuf, tokens);
-        command.wd1 = tokens[0];
-        command.wd1x = tokens[1];
-        command.wd2 = tokens[2];
-        command.wd2x = tokens[3];
+        tokenize(inputbuf, &command);
 
         /*  Every input, check "game.foobar" flag.  If zero, nothing's
          *  going on.  If pos, make neg.  If neg, he skipped a word,
@@ -1070,13 +1084,14 @@ L2607:
         } else
             lampcheck();
 
-        char word1[6];
-        char word2[6];
+        char word1[TOKLEN+1];
+        char word2[TOKLEN+1];
         packed_to_token(command.wd1, word1);
         packed_to_token(command.wd2, word2);
         V1 = get_vocab_id(word1);
         V2 = get_vocab_id(word2);
-        if (V1 == ENTER && (V2 == STREAM || V2 == 1000 + WATER)) {
+        if (V1 == ENTER && (V2 == STREAM ||
+                            V2 == PROMOTE_WORD(WATER))) {
             if (LIQLOC(game.loc) == WATER) {
                 rspeak(FEET_WET);
             } else {
@@ -1122,10 +1137,8 @@ Lookup:
         kmod = MOD(defn, 1000);
         switch (defn / 1000) {
         case 0:
-            if (playermove(kmod))
-                return true;
-            else
-                continue;      /* back to top of main interpreter loop */
+            playermove(kmod);
+           return true;
         case 1:
             command.part = unknown;
             command.obj = kmod;