+#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "main.h"
+#include "share.h" /* for SETUP */
#include "misc.h"
#include "funcs.h"
LNLENG=0;
LNPOSN=1;
STATE=0;
- /* 20 */ for (I=K; I<=L; I++) {
-L20: PUTTXT(LINES[I],STATE,2,I);
+ for (I=K; I<=L; I++) {
+ PUTTXT(LINES[I],STATE,2,I);
} /* end loop */
LNPOSN=0;
L30: LNPOSN=LNPOSN+1;
L360: PRMTYP=PARMS[NPARMS];
SHFTXT(LNPOSN+2,PRMTYP-2);
if(PRMTYP == 0) goto L395;
- /* 365 */ for (I=1; I<=PRMTYP; I++) {
+ for (I=1; I<=PRMTYP; I++) {
INLINE[LNPOSN]=0;
-L365: LNPOSN=LNPOSN+1;
+ LNPOSN=LNPOSN+1;
} /* end loop */
goto L395;
M=PTEXT[MSG];
if(SKIP < 0) goto L9;
- /* 3 */ for (I=0; I<=SKIP; I++) {
+ for (I=0; I<=SKIP; I++) {
L1: M=IABS(LINES[M]);
if(LINES[M] >= 0) goto L1;
-L3: /*etc*/ ;
+ /*etc*/ ;
} /* end loop */
L9: SPEAK(M);
return;
#define WORD1X (*wORD1X)
#define WORD2 (*wORD2)
#define WORD2X (*wORD2X)
-void fGETIN(long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) {
+void fGETIN(FILE *input, long *wORD1, long *wORD1X, long *wORD2, long *wORD2X) {
long JUNK;
-/* Get a command from the adventurer. snarf out the first word, pad it with
+/* Get a command from the adventurer. Snarf out the first word, pad it with
* blanks, and return it in WORD1. Chars 6 thru 10 are returned in WORD1X, in
* case we need to print out the whole word in an error message. Any number of
* blanks may follow the word. If a second word appears, it is returned in
L10: if(BLKLIN)TYPE0();
- MAPLIN(false);
+ MAPLIN(input);
+ if(input == stdin && feof(stdin)) score(1);
WORD1=GETTXT(true,true,true,0);
if(BLKLIN && WORD1 < 0) goto L10;
WORD1X=GETTXT(false,true,true,0);
#undef WORD1X
#undef WORD2
#undef WORD2X
-#define GETIN(WORD1,WORD1X,WORD2,WORD2X) fGETIN(&WORD1,&WORD1X,&WORD2,&WORD2X)
+#define GETIN(SRC,WORD1,WORD1X,WORD2,WORD2X) fGETIN(SRC,&WORD1,&WORD1X,&WORD2,&WORD2X)
#undef YES
-long fYES(long X, long Y, long Z) {
+long fYES(FILE *input, long X, long Y, long Z) {
long YES, REPLY, JUNK1, JUNK2, JUNK3;
* if no, print Z and return false. */
L1: RSPEAK(X);
- GETIN(REPLY,JUNK1,JUNK2,JUNK3);
+ GETIN(input, REPLY,JUNK1,JUNK2,JUNK3);
if(REPLY == MAKEWD(250519) || REPLY == MAKEWD(25)) goto L10;
if(REPLY == MAKEWD(1415) || REPLY == MAKEWD(14)) goto L20;
RSPEAK(185);
#define YES(X,Y,Z) fYES(X,Y,Z)
#undef GETNUM
-long fGETNUM(long K) {
+long fGETNUM(FILE *source) {
long DIGIT, GETNUM, SIGN;
/* Obtain the next integer from an input line. If K>0, we first read a
* character (not a digit, hyphen, or blank), we return 0. */
- if(K != 0)MAPLIN(K > 0);
+ if(source != NULL)MAPLIN(source);
GETNUM=0;
L10: if(LNPOSN > LNLENG)return(GETNUM);
if(INLINE[LNPOSN] != 0) goto L20;
if(LNLENG < FROM || DELTA == 0) goto L2;
- /* 1 */ for (I=FROM; I<=LNLENG; I++) {
+ for (I=FROM; I<=LNLENG; I++) {
II=I;
if(DELTA > 0)II=FROM+LNLENG-I;
JJ=II+DELTA;
-L1: INLINE[JJ]=INLINE[II];
+ INLINE[JJ]=INLINE[II];
} /* end loop */
L2: LNLENG=LNLENG+DELTA;
return;
/* Write or read an array of N words. See SAVWRD. */
- /* 1 */ for (I=1; I<=N; I++) {
-L1: SAVWRD(0,ARR[I]);
+ for (I=1; I<=N; I++) {
+ SAVWRD(0,ARR[I]);
} /* end loop */
return;
}
#define DSTROY(OBJECT) fDSTROY(OBJECT)
#undef JUGGLE
-void fJUGGLE(OBJECT)long OBJECT; {
+void fJUGGLE(long OBJECT) {
long I, J;
/* Juggle an object by picking it up and putting it down again, the purpose
#define JUGGLE(OBJECT) fJUGGLE(OBJECT)
#undef MOVE
-void fMOVE(OBJECT,WHERE)long OBJECT, WHERE; {
+void fMOVE(long OBJECT, long WHERE) {
long FROM;
/* Place any object anywhere by picking it up and dropping it. May already be
#define MOVE(OBJECT,WHERE) fMOVE(OBJECT,WHERE)
#undef PUT
-long fPUT(OBJECT,WHERE,PVAL)long OBJECT, PVAL, WHERE; {
+long fPUT(long OBJECT, long WHERE, long PVAL) {
long PUT;
/* PUT is the same as MOVE, except it returns a value used to set up the
#define PUT(OBJECT,WHERE,PVAL) fPUT(OBJECT,WHERE,PVAL)
#undef CARRY
-void fCARRY(OBJECT,WHERE)long OBJECT, WHERE; {
+void fCARRY(long OBJECT, long WHERE) {
long TEMP;
/* Start toting an object, removing it from the list of things at its former
#define CARRY(OBJECT,WHERE) fCARRY(OBJECT,WHERE)
#undef DROP
-void fDROP(OBJECT,WHERE)long OBJECT, WHERE; {
+void fDROP(long OBJECT, long WHERE) {
;
/* Place an object at a given loc, prefixing it onto the ATLOC list. Decr
#define DROP(OBJECT,WHERE) fDROP(OBJECT,WHERE)
#undef ATDWRF
-long fATDWRF(WHERE)long WHERE; {
+long fATDWRF(long WHERE) {
long ATDWRF, I;
/* Return the index of first dwarf at the given location, zero if no dwarf is
ATDWRF=0;
if(DFLAG < 2)return(ATDWRF);
ATDWRF= -1;
- /* 1 */ for (I=1; I<=5; I++) {
+ for (I=1; I<=5; I++) {
if(DLOC[I] == WHERE) goto L2;
-L1: if(DLOC[I] != 0)ATDWRF=0;
+ if(DLOC[I] != 0)ATDWRF=0;
} /* end loop */
return(ATDWRF);
-/* Utility routines (SETBIT, TSTBIT, RAN, RNDVOC, BUG) */
+/* Utility routines (SETBIT, TSTBIT, set_seed_from_time, get_next_lcg_value, randrange, RNDVOC, BUG) */
#undef SETBIT
-long fSETBIT(BIT)long BIT; {
+long fSETBIT(long BIT) {
long I, SETBIT;
/* Returns 2**bit for use in constructing bit-masks. */
SETBIT=1;
if(BIT <= 0)return(SETBIT);
- /* 1 */ for (I=1; I<=BIT; I++) {
-L1: SETBIT=SETBIT+SETBIT;
+ for (I=1; I<=BIT; I++) {
+ SETBIT=SETBIT+SETBIT;
} /* end loop */
return(SETBIT);
}
#define SETBIT(BIT) fSETBIT(BIT)
#undef TSTBIT
-long fTSTBIT(MASK,BIT)long BIT, MASK; {
+long fTSTBIT(long MASK, long BIT) {
long TSTBIT;
/* Returns true if the specified bit is set in the mask. */
#define TSTBIT(MASK,BIT) fTSTBIT(MASK,BIT)
-#undef RAN
-long fRAN(RANGE)long RANGE; {
-static long D, R = 0, RAN, T;
-
-/* Since the ran function in LIB40 seems to be a real lose, we'll use one of
- * our own. It's been run through many of the tests in Knuth vol. 2 and
- * seems to be quite reliable. RAN returns a value uniformly selected
- * between 0 and range-1. */
-
-
- D=1;
- if(R != 0 && RANGE >= 0) goto L1;
- DATIME(D,T);
- R=MOD(T+5,1048576L);
- D=1000+MOD(D,1000);
-L1: /* 2 */ for (T=1; T<=D; T++) {
-L2: R=MOD(R*1093L+221587L,1048576L);
- } /* end loop */
- RAN=(RANGE*R)/1048576;
- return(RAN);
+
+void set_seed_from_time(void)
+{
+ /* Use the current system time to get seed the ISO rand() function, from which we get a seed for the LCG. */
+ srand(time(NULL));
+ lcgstate.x = (unsigned long) rand() % lcgstate.m;
}
+unsigned long get_next_lcg_value(void)
+{
+ /* Return the LCG's current value, and then iterate it. */
+ unsigned long old_x = lcgstate.x;
+ lcgstate.x = (lcgstate.a * lcgstate.x + lcgstate.c) % lcgstate.m;
+ return(old_x);
+}
+long randrange(long range)
+{
+ /* Return a random integer from [0, range). */
+ long result = range * get_next_lcg_value() / lcgstate.m;
+ return(result);
+}
-#define RAN(RANGE) fRAN(RANGE)
#undef RNDVOC
-long fRNDVOC(CHAR,FORCE)long CHAR, FORCE; {
+long fRNDVOC(long CHAR, long FORCE) {
long DIV, I, J, RNDVOC;
/* Searches the vocabulary for a word whose second character is char, and
RNDVOC=FORCE;
if(RNDVOC != 0) goto L3;
- /* 1 */ for (I=1; I<=5; I++) {
- J=11+RAN(26);
+ for (I=1; I<=5; I++) {
+ J=11+randrange(26);
if(I == 2)J=CHAR;
-L1: RNDVOC=RNDVOC*64+J;
+ RNDVOC=RNDVOC*64+J;
} /* end loop */
L3: J=10000;
DIV=64L*64L*64L;
- /* 5 */ for (I=1; I<=TABSIZ; I++) {
+ for (I=1; I<=TABSIZ; I++) {
J=J+7;
if(MOD((ATAB[I]-J*J)/DIV,64L) == CHAR) goto L8;
-L5: /*etc*/ ;
+ /*etc*/ ;
} /* end loop */
BUG(5);
#define RNDVOC(CHAR,FORCE) fRNDVOC(CHAR,FORCE)
#undef BUG
-void fBUG(NUM)long NUM; {
+void fBUG(long NUM) {
/* The following conditions are currently considered fatal bugs. Numbers < 20
* are detected while reading the database; the others occur at "run time".
#define BUG(NUM) fBUG(NUM)
#undef MAPLIN
-void fMAPLIN(FIL)long FIL; {
-long I, VAL; static FILE *OPENED = NULL;
+void fMAPLIN(FILE *OPENED) {
+long I, VAL;
-/* Read a line of input, either from a file (if FIL=true) or from the
- * keyboard, translate the chars to integers in the range 0-126 and store
+/* Read a line of input, from the specified input source,
+ * translate the chars to integers in the range 0-126 and store
* them in the common array "INLINE". Integer values are as follows:
* 0 = space [ASCII CODE 40 octal, 32 decimal]
* 1-2 = !" [ASCII 41-42 octal, 33-34 decimal]
* This procedure may use the map1,map2 arrays to maintain static data for
* the mapping. MAP2(1) is set to 0 when the program starts
* and is not changed thereafter unless the routines on this page choose
- * to do so.
- *
- * Note that MAPLIN is expected to open the file the first time it is
- * asked to read a line from it. that is, there is no other place where
- * the data file is opened. */
-
+ * to do so. */
if(MAP2[1] == 0)MPINIT();
- if(FIL) goto L15;
- IGNORE(fgets(INLINE+1, sizeof(INLINE)-1, stdin));
- if(feof(stdin)) score(1);
- goto L20;
-
-L15: if(!OPENED){
- OPENED=fopen("adventure.text","r" /* NOT binary */);
- if(!OPENED){printf("Can't read adventure.text!\n"); exit(0);}
- }
- IGNORE(fgets(INLINE+1,100,OPENED));
-
-L20: LNLENG=0;
- /* 25 */ for (I=1; I<=100 && INLINE[I]!=0; I++) {
- VAL=INLINE[I]+1;
- INLINE[I]=MAP1[VAL];
-L25: if(INLINE[I] != 0)LNLENG=I;
- } /* end loop */
- LNPOSN=1;
- if(FIL && LNLENG == 0) goto L15;
-/* Above is to get around an F40 compiler bug wherein it reads a blank
- * line whenever a crlf is broken across a record boundary. */
- return;
+ if (!oldstyle && SETUP)
+ fputs("> ", stdout);
+ IGNORE(fgets(INLINE+1,sizeof(INLINE)-1,OPENED));
+ if (feof(OPENED)) {
+ if (logfp)
+ fclose(logfp);
+ } else {
+ if (logfp)
+ IGNORE(fputs(INLINE+1, logfp));
+ else if (!isatty(0))
+ IGNORE(fputs(INLINE+1, stdout));
+ LNLENG=0;
+ for (I=1; I<=sizeof(INLINE) && INLINE[I]!=0; I++) {
+ VAL=INLINE[I]+1;
+ INLINE[I]=MAP1[VAL];
+ if(INLINE[I] != 0)LNLENG=I;
+ } /* end loop */
+ LNPOSN=1;
+ }
}
-
-
-
#define MAPLIN(FIL) fMAPLIN(FIL)
+
#undef TYPE
-void fTYPE() {
+void fTYPE(void) {
long I, VAL;
/* Type the first "LNLENG" characters stored in inline, mapping them
return;
L10: if(MAP2[1] == 0)MPINIT();
- /* 20 */ for (I=1; I<=LNLENG; I++) {
+ for (I=1; I<=LNLENG; I++) {
VAL=INLINE[I];
-L20: {long x = VAL+1; INLINE[I]=MAP2[x];}
+ {long x = VAL+1; INLINE[I]=MAP2[x];}
} /* end loop */
{long x = LNLENG+1; INLINE[x]=0;}
printf("%s\n",INLINE+1);
#define TYPE() fTYPE()
#undef MPINIT
-void fMPINIT() {
+void fMPINIT(void) {
long FIRST, I, J, LAST, VAL;
static long RUNS[7][2] = {32,34, 39,46, 65,90, 97,122, 37,37, 48,57, 0,126};
- /* 10 */ for (I=1; I<=128; I++) {
-L10: MAP1[I]= -1;
+ for (I=1; I<=128; I++) {
+ MAP1[I]= -1;
} /* end loop */
VAL=0;
- /* 20 */ for (I=0; I<7; I++) {
+ for (I=0; I<7; I++) {
FIRST=RUNS[I][0];
LAST=RUNS[I][1];
/* 22 */ for (J=FIRST; J<=LAST; J++) {
VAL=VAL+1;
L22: J--;
} /* end loop */
-L20: /*etc*/ ;
+ /*etc*/ ;
} /* end loop */
MAP1[128]=MAP1[10];
/* For this version, tab (9) maps to space (32), so del (127) uses tab's value */
MAP1[10]=MAP1[33];
MAP1[11]=MAP1[33];
- /* 30 */ for (I=0; I<=126; I++) {
+ for (I=0; I<=126; I++) {
I++; VAL=MAP1[I]+1; I--;
MAP2[VAL]=I*('B'-'A');
-L30: if(I >= 64)MAP2[VAL]=(I-64)*('B'-'A')+'@';
+ if(I >= 64)MAP2[VAL]=(I-64)*('B'-'A')+'@';
} /* end loop */
return;
#define MPINIT() fMPINIT()
#undef SAVEIO
-void fSAVEIO(OP,IN,ARR)long ARR[], IN, OP; {
+void fSAVEIO(long OP, long IN, long ARR[]) {
static FILE *F; char NAME[50];
/* If OP=0, ask for a file name and open a file. (If IN=true, the file is for