First step in game state encapsulation: the dwarf & pirate locations.
[open-adventure.git] / misc.c
diff --git a/misc.c b/misc.c
index 365d7c88eb21ffba77f6e4f715195c6c7820d81f..5c71c744d7067f4806e5664e2878324c8ce82ff0 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -12,7 +12,7 @@
 
 /*  I/O routines (SPEAK, PSPEAK, RSPEAK, SETPRM, GETIN, YES) */
 
-void SPEAK(long N) {
+void SPEAK(vocab_t 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
@@ -22,7 +22,7 @@ long BLANK, CASE, I, K, L, NEG, NPARMS, PARM, PRMTYP, STATE;
        BLANK=BLKLIN;
        K=N;
        NPARMS=1;
-L10:   L=IABS(LINES[K])-1;
+L10:   L=labs(LINES[K])-1;
        K=K+1;
        LNLENG=0;
        LNPOSN=1;
@@ -52,7 +52,7 @@ L32:  if(LNPOSN > LNLENG) goto L40;
        if(PRMTYP < 1 || PRMTYP > 9) goto L30;
        SHFTXT(LNPOSN+2,PRMTYP-2);
        LNPOSN=LNPOSN+PRMTYP;
-       PARM=IABS(PARMS[NPARMS]);
+       PARM=labs(PARMS[NPARMS]);
        NEG=0;
        if(PARMS[NPARMS] < 0)NEG=9;
        /* 390 */ for (I=1; I<=PRMTYP; I++) {
@@ -111,7 +111,7 @@ L40:        if(BLANK)TYPE0();
        return;
 }
 
-void PSPEAK(long MSG,long SKIP) {
+void PSPEAK(vocab_t MSG,int SKIP) {
 long I, M;
 
 /*  Find the skip+1st message from msg and print it.  MSG should be the index of
@@ -121,7 +121,7 @@ long I, M;
        M=PTEXT[MSG];
        if(SKIP < 0) goto L9;
        for (I=0; I<=SKIP; I++) {
-L1:    M=IABS(LINES[M]);
+L1:    M=labs(LINES[M]);
        if(LINES[M] >= 0) goto L1;
        /*etc*/ ;
        } /* end loop */
@@ -129,7 +129,7 @@ L9: SPEAK(M);
        return;
 }
 
-void RSPEAK(long I) {
+void RSPEAK(vocab_t I) {
 
 /*  Print the I-TH "random" message (section 6 of database). */
 
@@ -194,8 +194,8 @@ L22:        JUNK=GETTXT(false,true,true);
 #undef WORD2X
 #define GETIN(SRC,WORD1,WORD1X,WORD2,WORD2X) fGETIN(SRC,&WORD1,&WORD1X,&WORD2,&WORD2X)
 
-long YES(FILE *input, long X, long Y, long Z) {
-long YEAH, REPLY, JUNK1, JUNK2, JUNK3;
+long YES(FILE *input, vocab_t X, vocab_t Y, vocab_t Z) {
+token_t YEAH, REPLY, JUNK1, JUNK2, JUNK3;
 
 /*  Print message X, wait for yes/no answer.  If yes, print Y and return true;
  *  if no, print Z and return false. */
@@ -215,7 +215,7 @@ L20:        YEAH=false;
 }
 
 
-/*  Line-parsing routines (GETNUM, GETTXT, MAKEWD, PUTTXT, SHFTXT, TYPE0)
+/*  Line-parsing routines (GETTXT, MAKEWD, PUTTXT, SHFTXT, TYPE0)
                */
 /*  The routines on this page handle all the stuff that would normally be
  *  taken care of by format statements.  We do it this way instead so that
@@ -223,81 +223,56 @@ L20:      YEAH=false;
  *  machine dependent i/o stuff is on the following page.  See that page
  *  for a description of MAPCOM's inline array. */
 
-long GETNUM(FILE *source) {
-long DIGIT, NUMBER, SIGN;
-
-/*  Obtain the next integer from an input line.  If K>0, we first read a
- *  new input line from a file; if K<0, we read a line from the keyboard;
- *  if K=0 we use a line that has already been read (and perhaps partially
- *  scanned).  If we're at the end of the line or encounter an illegal
- *  character (not a digit, hyphen, or blank), we return 0. */
-
-
-       if(source != NULL)MAPLIN(source);
-       NUMBER=0;
-L10:   if(LNPOSN > LNLENG)return(NUMBER);
-       if(INLINE[LNPOSN] != 0) goto L20;
-       LNPOSN=LNPOSN+1;
-        goto L10;
-
-L20:   SIGN=1;
-       if(INLINE[LNPOSN] != 9) goto L32;
-       SIGN= -1;
-L30:   LNPOSN=LNPOSN+1;
-L32:   if(LNPOSN > LNLENG || INLINE[LNPOSN] == 0) goto L42;
-       DIGIT=INLINE[LNPOSN]-64;
-       if(DIGIT < 0 || DIGIT > 9) goto L40;
-       NUMBER=NUMBER*10+DIGIT;
-        goto L30;
-
-L40:   NUMBER=0;
-L42:   NUMBER=NUMBER*SIGN;
-       LNPOSN=LNPOSN+1;
-       return(NUMBER);
-}
-
-long GETTXT(long SKIP,long ONEWRD, long UPPER) {
-long CHAR, TEXT, I; static long SPLITTING = -1;
-
+long GETTXT(bool SKIP,bool ONEWRD, bool UPPER) {
 /*  Take characters from an input line and pack them into 30-bit words.
  *  Skip says to skip leading blanks.  ONEWRD says stop if we come to a
  *  blank.  UPPER says to map all letters to uppercase.  If we reach the
  *  end of the line, the word is filled up with blanks (which encode as 0's).
  *  If we're already at end of line when TEXT is called, we return -1. */
 
-       if(LNPOSN != SPLITTING)SPLITTING = -1;
-       TEXT= -1;
-L10:   if(LNPOSN > LNLENG)return(TEXT);
-       if((!SKIP) || INLINE[LNPOSN] != 0) goto L11;
-       LNPOSN=LNPOSN+1;
-        goto L10;
-
-L11:   TEXT=0;
-       /* 15 */ for (I=1; I<=5; I++) {
-       TEXT=TEXT*64;
-       if(LNPOSN > LNLENG || (ONEWRD && INLINE[LNPOSN] == 0)) goto L15;
-       CHAR=INLINE[LNPOSN];
-       if(CHAR >= 63) goto L12;
-       SPLITTING = -1;
-       if(UPPER && CHAR >= 37)CHAR=CHAR-26;
-       TEXT=TEXT+CHAR;
-        goto L14;
-
-L12:   if(SPLITTING == LNPOSN) goto L13;
-       TEXT=TEXT+63;
-       SPLITTING = LNPOSN;
-        goto L15;
-
-L13:   TEXT=TEXT+CHAR-63;
-       SPLITTING = -1;
-L14:   LNPOSN=LNPOSN+1;
-L15:   /*etc*/ ;
-       } /* end loop */
-
-       return(TEXT);
-}
-
-long MAKEWD(long LETTRS) {
+  long TEXT;
+  static long SPLITTING = -1;
+
+  if(LNPOSN != SPLITTING)
+    SPLITTING = -1;
+  TEXT= -1;
+  while (true) {
+    if(LNPOSN > LNLENG)
+      return(TEXT);
+    if((!SKIP) || INLINE[LNPOSN] != 0)
+      break;
+    LNPOSN=LNPOSN+1;
+  }
+
+  TEXT=0;
+  for (int I=1; I<=5; I++) {
+    TEXT=TEXT*64;
+    if(LNPOSN > LNLENG || (ONEWRD && INLINE[LNPOSN] == 0))
+      continue;
+    char current=INLINE[LNPOSN];
+    if(current < 63) {
+      SPLITTING = -1;
+      if(UPPER && current >= 37)
+        current=current-26;
+      TEXT=TEXT+current;
+      LNPOSN=LNPOSN+1;
+      continue;
+    }
+    if(SPLITTING != LNPOSN) {
+      TEXT=TEXT+63;
+      SPLITTING = LNPOSN;
+      continue;
+    }
+
+    TEXT=TEXT+current-63;
+    SPLITTING = -1;
+    LNPOSN=LNPOSN+1;
+  }
+
+  return(TEXT);
+}
+
+token_t MAKEWD(long LETTRS) {
 long I, L, WORD;
 
 /*  Combine five uppercase letters (represented by pairs of decimal digits
@@ -307,15 +282,13 @@ long I, L, WORD;
  *  kludgey workaround, you can increment a letter by 5 by adding 50 to
  *  the next pair of digits. */
 
-
        WORD=0;
        I=1;
-       L=LETTRS;
-L10:   WORD=WORD+I*(MOD(L,50)+10);
-       I=I*64;
-       if(MOD(L,100) > 50)WORD=WORD+I*5;
-       L=L/100;
-       if(L != 0) goto L10;
+       for (L=LETTRS; L != 0; L=L/100) {
+               WORD=WORD+I*(MOD(L,50)+10);
+               I=I*64;
+               if(MOD(L,100) > 50)WORD=WORD+I*5;
+       }
        I=64L*64L*64L*64L*64L/I;
        WORD=WORD*I;
        return(WORD);
@@ -323,7 +296,7 @@ L10:        WORD=WORD+I*(MOD(L,50)+10);
 
 
 #define STATE (*sTATE)
-void fPUTTXT(long WORD, long *sTATE, long CASE) {
+void fPUTTXT(token_t WORD, long *sTATE, long CASE) {
 long ALPH1, ALPH2, BYTE, DIV, I, W;
 
 /*  Unpack the 30-bit value in word to obtain up to 5 integer-encoded chars,
@@ -338,13 +311,13 @@ long ALPH1, ALPH2, BYTE, DIV, I, W;
 
 
        ALPH1=13*CASE+24;
-       ALPH2=26*IABS(CASE)+ALPH1;
-       if(IABS(CASE) > 1)ALPH1=ALPH2;
+       ALPH2=26*labs(CASE)+ALPH1;
+       if(labs(CASE) > 1)ALPH1=ALPH2;
 /*  ALPH1&2 DEFINE RANGE OF WRONG-CASE CHARS, 11-36 OR 37-62 OR EMPTY. */
        DIV=64L*64L*64L*64L;
        W=WORD;
        /* 18 */ for (I=1; I<=5; I++) {
-       if(W <= 0 && STATE == 0 && IABS(CASE) <= 1)return;
+       if(W <= 0 && STATE == 0 && labs(CASE) <= 1)return;
        BYTE=W/DIV;
        if(STATE != 0 || BYTE != 63) goto L12;
        STATE=63;
@@ -536,7 +509,7 @@ long I, J;
        I=PLACE[OBJECT];
        J=FIXED[OBJECT];
        MOVE(OBJECT,I);
-       MOVE(OBJECT+100,J);
+       MOVE(OBJECT+NOBJECTS,J);
        return;
 }
 
@@ -548,10 +521,10 @@ long FROM;
  *  are not at any loc, since carry wants to remove objects from ATLOC chains. */
 
 
-       if(OBJECT > 100) goto L1;
+       if(OBJECT > NOBJECTS) goto L1;
        FROM=PLACE[OBJECT];
         goto L2;
-L1:    {long x = OBJECT-100; FROM=FIXED[x];}
+L1:    {long x = OBJECT-NOBJECTS; FROM=FIXED[x];}
 L2:    if(FROM > 0 && FROM <= 300)CARRY(OBJECT,FROM);
        DROP(OBJECT,WHERE);
        return;
@@ -572,10 +545,10 @@ void CARRY(long OBJECT, long WHERE) {
 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
+ *  location.  Incr holdng unless it was already being toted.  If OBJECT>NOBJECTS
  *  (moving "fixed" second loc), don't change PLACE or HOLDNG. */
 
-       if(OBJECT > 100) goto L5;
+       if(OBJECT > NOBJECTS) goto L5;
        if(PLACE[OBJECT] == -1)return;
        PLACE[OBJECT]= -1;
        HOLDNG=HOLDNG+1;
@@ -594,11 +567,11 @@ void DROP(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. */
 
-       if(OBJECT > 100) goto L1;
+       if(OBJECT > NOBJECTS) goto L1;
        if(PLACE[OBJECT] == -1)HOLDNG=HOLDNG-1;
        PLACE[OBJECT]=WHERE;
         goto L2;
-L1:    {long x = OBJECT-100; FIXED[x]=WHERE;}
+L1:    {long x = OBJECT-NOBJECTS; FIXED[x]=WHERE;}
 L2:    if(WHERE <= 0)return;
        LINK[OBJECT]=ATLOC[WHERE];
        ATLOC[WHERE]=OBJECT;
@@ -618,9 +591,9 @@ long AT, I;
        AT=0;
        if(DFLAG < 2)return(AT);
        AT= -1;
-       for (I=1; I<=5; I++) {
-       if(DLOC[I] == WHERE) goto L2;
-       if(DLOC[I] != 0)AT=0;
+       for (I=1; I<=NDWARVES-1; I++) {
+       if(game.dloc[I] == WHERE) goto L2;
+       if(game.dloc[I] != 0)AT=0;
        } /* end loop */
        return(AT);
 
@@ -631,26 +604,14 @@ L2:       AT=I;
 /*  Utility routines (SETBIT, TSTBIT, set_seed, get_next_lcg_value,
  *  randrange, RNDVOC, BUG) */
 
-long SETBIT(long BIT) {
-long I, IND;
-
+long SETBIT(long bit) {
 /*  Returns 2**bit for use in constructing bit-masks. */
-
-       IND=1;
-       if(BIT <= 0)return(IND);
-       for (I=1; I<=BIT; I++) {
-       IND=IND+IND;
-       } /* end loop */
-       return(IND);
+    return(2 << bit);
 }
 
-
-
-long TSTBIT(long MASK, long BIT) {
-
+bool TSTBIT(long mask, int bit) {
 /*  Returns true if the specified bit is set in the mask. */
-
-       return(MOD(MASK/SETBIT(BIT),2) != 0);
+    return((mask & (1 << bit)) != 0);
 }
 
 void set_seed(long seedval)
@@ -772,7 +733,7 @@ long I, VAL;
 
        if(MAP2[1] == 0)MPINIT();
 
-       if (!oldstyle && SETUP && OPENED == stdin)
+       if (!oldstyle && OPENED == stdin)
                fputs("> ", stdout);
        do {
                IGNORE(fgets(rawbuf,sizeof(rawbuf)-1,OPENED));
@@ -889,5 +850,4 @@ void DATIME(long* D, long* T) {
   *T = (long) tv.tv_usec;
 }
 
-long IABS(N)long N; {return(N<0? -N : N);}
 long MOD(N,M)long N, M; {return(N%M);}