aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/alan3/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/glk/alan3/main.cpp')
-rw-r--r--engines/glk/alan3/main.cpp1103
1 files changed, 546 insertions, 557 deletions
diff --git a/engines/glk/alan3/main.cpp b/engines/glk/alan3/main.cpp
index e22c5be942..c9612db412 100644
--- a/engines/glk/alan3/main.cpp
+++ b/engines/glk/alan3/main.cpp
@@ -60,7 +60,7 @@ namespace Alan3 {
/* PUBLIC DATA */
/* Amachine structures - Static */
-VerbEntry *vrbs; /* Verb table pointer */
+VerbEntry *vrbs; /* Verb table pointer */
/* PRIVATE DATA */
@@ -74,34 +74,33 @@ VerbEntry *vrbs; /* Verb table pointer */
/*----------------------------------------------------------------------*/
static char *eventName(int event) {
- return stringAt(events[event].id);
+ return stringAt(events[event].id);
}
/*----------------------------------------------------------------------*/
-static void runPendingEvents(void)
-{
- int i;
-
- resetRules();
- while (eventQueueTop != 0 && eventQueue[eventQueueTop-1].after == 0) {
- eventQueueTop--;
- if (isALocation(eventQueue[eventQueueTop].where))
- current.location = eventQueue[eventQueueTop].where;
- else
- current.location = where(eventQueue[eventQueueTop].where, TRANSITIVE);
- if (traceSectionOption) {
- printf("\n<EVENT %s[%d] (at ", eventName(eventQueue[eventQueueTop].event),
- eventQueue[eventQueueTop].event);
- traceSay(current.location);
- printf(" [%d]):>\n", current.location);
- }
- interpret(events[eventQueue[eventQueueTop].event].code);
- evaluateRules(rules);
- }
-
- for (i = 0; i<eventQueueTop; i++)
- eventQueue[i].after--;
+static void runPendingEvents(void) {
+ int i;
+
+ resetRules();
+ while (eventQueueTop != 0 && eventQueue[eventQueueTop - 1].after == 0) {
+ eventQueueTop--;
+ if (isALocation(eventQueue[eventQueueTop].where))
+ current.location = eventQueue[eventQueueTop].where;
+ else
+ current.location = where(eventQueue[eventQueueTop].where, TRANSITIVE);
+ if (traceSectionOption) {
+ printf("\n<EVENT %s[%d] (at ", eventName(eventQueue[eventQueueTop].event),
+ eventQueue[eventQueueTop].event);
+ traceSay(current.location);
+ printf(" [%d]):>\n", current.location);
+ }
+ interpret(events[eventQueue[eventQueueTop].event].code);
+ evaluateRules(rules);
+ }
+
+ for (i = 0; i < eventQueueTop; i++)
+ eventQueue[i].after--;
}
@@ -122,13 +121,13 @@ Common::SeekableReadStream *codfil;
header size for later versions.
*/
static int crcStart(char version[4]) {
- /* Some earlier versions had a shorter header */
- if (isPreAlpha5(version))
- return sizeof(Pre3_0alpha5Header)/sizeof(Aword);
- else if (isPreBeta2(version))
- return sizeof(Pre3_0beta2Header)/sizeof(Aword);
- else
- return sizeof(ACodeHeader)/sizeof(Aword);
+ /* Some earlier versions had a shorter header */
+ if (isPreAlpha5(version))
+ return sizeof(Pre3_0alpha5Header) / sizeof(Aword);
+ else if (isPreBeta2(version))
+ return sizeof(Pre3_0beta2Header) / sizeof(Aword);
+ else
+ return sizeof(ACodeHeader) / sizeof(Aword);
}
@@ -137,47 +136,47 @@ static void readTemporaryHeader(ACodeHeader *tmphdr) {
codfil->seek(0);
codfil->read(tmphdr, sizeof(*tmphdr));
codfil->seek(0);
-
+
if (strncmp((char *)tmphdr, "ALAN", 4) != 0)
- playererr("Not an Alan game file, does not start with \"ALAN\"");
+ playererr("Not an Alan game file, does not start with \"ALAN\"");
}
/*----------------------------------------------------------------------*/
static void reverseMemory() {
- if (littleEndian()) {
- if (debugOption||traceSectionOption||traceInstructionOption)
- output("<Hmm, this is a little-endian machine, fixing byte ordering....");
- reverseACD(); /* Reverse content of the ACD file */
- if (debugOption||traceSectionOption||traceInstructionOption)
- output("OK.>$n");
- }
+ if (littleEndian()) {
+ if (debugOption || traceSectionOption || traceInstructionOption)
+ output("<Hmm, this is a little-endian machine, fixing byte ordering....");
+ reverseACD(); /* Reverse content of the ACD file */
+ if (debugOption || traceSectionOption || traceInstructionOption)
+ output("OK.>$n");
+ }
}
/*----------------------------------------------------------------------*/
static void setupHeader(ACodeHeader tmphdr) {
- if (isPreBeta2(tmphdr.version)) {
- header = (ACodeHeader *)duplicate(&memory[0], sizeof(ACodeHeader));
- if (isPreAlpha5(tmphdr.version)) {
- header->ifids = 0;
- }
- header->prompt = 0;
- } else if (isPreBeta3(tmphdr.version)) {
- header = (ACodeHeader *)pointerTo(0);
- } else {
- header = (ACodeHeader *)pointerTo(0);
- }
+ if (isPreBeta2(tmphdr.version)) {
+ header = (ACodeHeader *)duplicate(&memory[0], sizeof(ACodeHeader));
+ if (isPreAlpha5(tmphdr.version)) {
+ header->ifids = 0;
+ }
+ header->prompt = 0;
+ } else if (isPreBeta3(tmphdr.version)) {
+ header = (ACodeHeader *)pointerTo(0);
+ } else {
+ header = (ACodeHeader *)pointerTo(0);
+ }
}
/*----------------------------------------------------------------------*/
static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
int i;
- /* No memory allocated yet? */
- if (memory == NULL) {
- memory = (Aword *)allocate(tmphdr.size * sizeof(Aword));
- }
+ /* No memory allocated yet? */
+ if (memory == NULL) {
+ memory = (Aword *)allocate(tmphdr.size * sizeof(Aword));
+ }
memTop = tmphdr.size;
if ((int)(sizeof(Aword) * tmphdr.size) > codfil->size())
@@ -186,560 +185,550 @@ static void loadAndCheckMemory(ACodeHeader tmphdr, Aword crc, char err[]) {
for (i = 0; i < (int)tmphdr.size; ++i)
memory[i] = codfil->readUint32LE();
- /* Calculate checksum */
- for (i = crcStart(tmphdr.version); i < memTop; i++) {
- crc += memory[i]&0xff;
- crc += (memory[i]>>8)&0xff;
- crc += (memory[i]>>16)&0xff;
- crc += (memory[i]>>24)&0xff;
- }
- if (crc != tmphdr.acdcrc) {
- sprintf(err, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
- (unsigned long) crc, (unsigned long) tmphdr.acdcrc);
- if (!ignoreErrorOption)
- syserr(err);
- else {
- output("<WARNING! $$");
- output(err);
- output("$$ Ignored, proceed at your own risk.>$n");
- }
- }
+ /* Calculate checksum */
+ for (i = crcStart(tmphdr.version); i < memTop; i++) {
+ crc += memory[i] & 0xff;
+ crc += (memory[i] >> 8) & 0xff;
+ crc += (memory[i] >> 16) & 0xff;
+ crc += (memory[i] >> 24) & 0xff;
+ }
+ if (crc != tmphdr.acdcrc) {
+ sprintf(err, "Checksum error in Acode (.a3c) file (0x%lx instead of 0x%lx).",
+ (unsigned long) crc, (unsigned long) tmphdr.acdcrc);
+ if (!ignoreErrorOption)
+ syserr(err);
+ else {
+ output("<WARNING! $$");
+ output(err);
+ output("$$ Ignored, proceed at your own risk.>$n");
+ }
+ }
}
/*----------------------------------------------------------------------*/
static const char *decodeState(int c) {
- static char state[3] = "\0\0";
- switch (c) {
- case 0: return ".";
- case 'd': return "dev";
- case 'a': return "alpha";
- case 'b': return "beta";
- default:
- state[0] = header->version[3];
- return state;
- }
+ static char state[3] = "\0\0";
+ switch (c) {
+ case 0:
+ return ".";
+ case 'd':
+ return "dev";
+ case 'a':
+ return "alpha";
+ case 'b':
+ return "beta";
+ default:
+ state[0] = header->version[3];
+ return state;
+ }
}
/*======================================================================*/
char *decodedGameVersion(char version[]) {
- static char str[100];
- sprintf(str, "%d.%d%s%d",
- (int)version[3],
- (int)version[2],
- decodeState(version[0]),
- (int)version[1]);
- return str;
+ static char str[100];
+ sprintf(str, "%d.%d%s%d",
+ (int)version[3],
+ (int)version[2],
+ decodeState(version[0]),
+ (int)version[1]);
+ return str;
}
/*----------------------------------------------------------------------*/
static void incompatibleDevelopmentVersion(ACodeHeader *hdr) {
- char str[80];
- sprintf(str, "Incompatible version of ACODE program. Development versions always require exact match. Game is %ld.%ld%s%ld, interpreter %ld.%ld%s%ld!",
- (long)(hdr->version[0]),
- (long)(hdr->version[1]),
- decodeState(hdr->version[3]),
- (long)(hdr->version[2]),
- (long)alan.version.version,
- (long)alan.version.revision,
- alan.version.state,
- (long)alan.version.correction);
- apperr(str);
+ char str[80];
+ sprintf(str, "Incompatible version of ACODE program. Development versions always require exact match. Game is %ld.%ld%s%ld, interpreter %ld.%ld%s%ld!",
+ (long)(hdr->version[0]),
+ (long)(hdr->version[1]),
+ decodeState(hdr->version[3]),
+ (long)(hdr->version[2]),
+ (long)alan.version.version,
+ (long)alan.version.revision,
+ alan.version.state,
+ (long)alan.version.correction);
+ apperr(str);
}
/*----------------------------------------------------------------------*/
static void incompatibleVersion(ACodeHeader *hdr) {
- char str[80];
- sprintf(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
- (long)(hdr->version[0]),
- (long)(hdr->version[1]),
- (long)alan.version.version,
- (long)alan.version.revision);
- apperr(str);
+ char str[80];
+ sprintf(str, "Incompatible version of ACODE program. Game is %ld.%ld, interpreter %ld.%ld.",
+ (long)(hdr->version[0]),
+ (long)(hdr->version[1]),
+ (long)alan.version.version,
+ (long)alan.version.revision);
+ apperr(str);
}
/*----------------------------------------------------------------------*/
static void alphaRunningLaterGame(char gameState) {
- output("<WARNING! You are running an alpha interpreter, but the game is generated by a");
- if (gameState == 'b')
- output("beta");
- else
- output("release");
- output("state compiler which was released later. This might cause the game to not work fully as intended. Look for an upgraded game file.>\n");
+ output("<WARNING! You are running an alpha interpreter, but the game is generated by a");
+ if (gameState == 'b')
+ output("beta");
+ else
+ output("release");
+ output("state compiler which was released later. This might cause the game to not work fully as intended. Look for an upgraded game file.>\n");
}
/*----------------------------------------------------------------------*/
static void nonDevelopmentRunningDevelopmentStateGame(char version[]) {
- char errorMessage[200];
- char versionString[100];
-
- strcpy(errorMessage, "Games generated by a development state compiler");
- sprintf(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
- version[2], decodeState(version[3]));
- strcat(errorMessage, versionString);
- strcat(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
- apperr(errorMessage);
+ char errorMessage[200];
+ char versionString[100];
+
+ strcpy(errorMessage, "Games generated by a development state compiler");
+ sprintf(versionString, "(this game is v%d.%d.%d%s)", version[0], version[1],
+ version[2], decodeState(version[3]));
+ strcat(errorMessage, versionString);
+ strcat(errorMessage, "can only be run with a matching interpreter. Look for a game file generated with an alpha, beta or release state compiler.>\n");
+ apperr(errorMessage);
}
/*======================================================================*/
-void checkVersion(ACodeHeader *hdr)
-{
- /* Strategy for version matching is:
- 1) Development interpreters/games require exact match
- 2) Alpha, Beta and Release interpreters will not run development games
- 3) Alpha interpreters must warn if they run beta or release games
- 4) Beta interpreters may introduce changes which are not alpha compatible,
- if the change is a strict addition (i.e. if not used will not affect
- alpha interpreters, example is introduction of a new opcode if it is
- done at the end of the list)
- 5) Release interpreters should run alpha and beta games without problems
-
- NOTE that we are working with a non-reversed version string/word here.
- */
-
- char interpreterVersion[4];
- bool developmentVersion;
- bool alphaVersion;
- int compareLength;
- char gameState = hdr->version[3];
-
- /* Construct our own version */
- interpreterVersion[0] = alan.version.version;
- interpreterVersion[1] = alan.version.revision;
- interpreterVersion[2] = alan.version.correction;
- interpreterVersion[3] = alan.version.state[0];
-
- /* Check version of .ACD file */
- if (debugOption && !regressionTestOption) {
- printf("<Version of '%s' is %d.%d%s%d!>\n",
- adventureFileName,
- (int)hdr->version[0],
- (int)hdr->version[1],
- decodeState(hdr->version[3]),
- (int)hdr->version[2]);
- newline();
- }
-
- /* Development version require exact match, else only 2 digit match */
- developmentVersion = (strcmp(alan.version.state, "dev") == 0);
- alphaVersion = (strcmp(alan.version.state, "alpha") == 0);
- compareLength = (developmentVersion? 3 : 2);
-
- if (gameState == 'd' && !developmentVersion)
- /* Development state game requires development state interpreter... */
- nonDevelopmentRunningDevelopmentStateGame(hdr->version);
- else {
- /* Compatible if version, revision (and correction if dev state) match... */
- if (memcmp(hdr->version, interpreterVersion, compareLength) != 0) {
- /* Mismatch! */
- if (!ignoreErrorOption) {
- if (developmentVersion)
- incompatibleDevelopmentVersion(hdr);
- else
- incompatibleVersion(hdr);
- } else
- output("<WARNING! Incompatible version of ACODE program.>\n");
- } else if (developmentVersion && gameState != 'd')
- /* ... unless interpreter is development and game not */
- incompatibleDevelopmentVersion(hdr);
- else if (alphaVersion && gameState != 'a') {
- /* If interpreter is alpha version and the game is later, warn! */
- alphaRunningLaterGame(gameState);
- }
- }
+void checkVersion(ACodeHeader *hdr) {
+ /* Strategy for version matching is:
+ 1) Development interpreters/games require exact match
+ 2) Alpha, Beta and Release interpreters will not run development games
+ 3) Alpha interpreters must warn if they run beta or release games
+ 4) Beta interpreters may introduce changes which are not alpha compatible,
+ if the change is a strict addition (i.e. if not used will not affect
+ alpha interpreters, example is introduction of a new opcode if it is
+ done at the end of the list)
+ 5) Release interpreters should run alpha and beta games without problems
+
+ NOTE that we are working with a non-reversed version string/word here.
+ */
+
+ char interpreterVersion[4];
+ bool developmentVersion;
+ bool alphaVersion;
+ int compareLength;
+ char gameState = hdr->version[3];
+
+ /* Construct our own version */
+ interpreterVersion[0] = alan.version.version;
+ interpreterVersion[1] = alan.version.revision;
+ interpreterVersion[2] = alan.version.correction;
+ interpreterVersion[3] = alan.version.state[0];
+
+ /* Check version of .ACD file */
+ if (debugOption && !regressionTestOption) {
+ printf("<Version of '%s' is %d.%d%s%d!>\n",
+ adventureFileName,
+ (int)hdr->version[0],
+ (int)hdr->version[1],
+ decodeState(hdr->version[3]),
+ (int)hdr->version[2]);
+ newline();
+ }
+
+ /* Development version require exact match, else only 2 digit match */
+ developmentVersion = (strcmp(alan.version.state, "dev") == 0);
+ alphaVersion = (strcmp(alan.version.state, "alpha") == 0);
+ compareLength = (developmentVersion ? 3 : 2);
+
+ if (gameState == 'd' && !developmentVersion)
+ /* Development state game requires development state interpreter... */
+ nonDevelopmentRunningDevelopmentStateGame(hdr->version);
+ else {
+ /* Compatible if version, revision (and correction if dev state) match... */
+ if (memcmp(hdr->version, interpreterVersion, compareLength) != 0) {
+ /* Mismatch! */
+ if (!ignoreErrorOption) {
+ if (developmentVersion)
+ incompatibleDevelopmentVersion(hdr);
+ else
+ incompatibleVersion(hdr);
+ } else
+ output("<WARNING! Incompatible version of ACODE program.>\n");
+ } else if (developmentVersion && gameState != 'd')
+ /* ... unless interpreter is development and game not */
+ incompatibleDevelopmentVersion(hdr);
+ else if (alphaVersion && gameState != 'a') {
+ /* If interpreter is alpha version and the game is later, warn! */
+ alphaRunningLaterGame(gameState);
+ }
+ }
}
/*----------------------------------------------------------------------*/
-static void load(void)
-{
- ACodeHeader tmphdr;
- Aword crc = 0;
- char err[100];
+static void load(void) {
+ ACodeHeader tmphdr;
+ Aword crc = 0;
+ char err[100];
- readTemporaryHeader(&tmphdr);
- checkVersion(&tmphdr);
+ readTemporaryHeader(&tmphdr);
+ checkVersion(&tmphdr);
- /* Allocate and load memory */
+ /* Allocate and load memory */
- if (littleEndian())
- reverseHdr(&tmphdr);
+ if (littleEndian())
+ reverseHdr(&tmphdr);
- if (tmphdr.size <= sizeof(ACodeHeader)/sizeof(Aword))
- syserr("Malformed game file. Too small.");
+ if (tmphdr.size <= sizeof(ACodeHeader) / sizeof(Aword))
+ syserr("Malformed game file. Too small.");
- loadAndCheckMemory(tmphdr, crc, err);
+ loadAndCheckMemory(tmphdr, crc, err);
- reverseMemory();
- setupHeader(tmphdr);
+ reverseMemory();
+ setupHeader(tmphdr);
}
/*----------------------------------------------------------------------*/
-static void checkDebug(void)
-{
- /* Make sure he can't debug if not allowed! */
- if (!header->debug) {
- if (debugOption|traceSectionOption|traceInstructionOption) {
- printf("<Sorry, '%s' is not compiled for debug! Exiting.>\n", adventureFileName);
- terminate(0);
- }
- para();
- debugOption = FALSE;
- traceSectionOption = FALSE;
- traceInstructionOption = FALSE;
- tracePushOption = FALSE;
- }
+static void checkDebug(void) {
+ /* Make sure he can't debug if not allowed! */
+ if (!header->debug) {
+ if (debugOption | traceSectionOption | traceInstructionOption) {
+ printf("<Sorry, '%s' is not compiled for debug! Exiting.>\n", adventureFileName);
+ terminate(0);
+ }
+ para();
+ debugOption = FALSE;
+ traceSectionOption = FALSE;
+ traceInstructionOption = FALSE;
+ tracePushOption = FALSE;
+ }
#ifdef TODO
- if (debugOption || regressionTestOption) /* If debugging... */
- srand(1); /* ... use no randomization */
- else
- srand(time(0)); /* Else seed random generator */
+ if (debugOption || regressionTestOption) /* If debugging... */
+ srand(1); /* ... use no randomization */
+ else
+ srand(time(0)); /* Else seed random generator */
#endif
}
/*----------------------------------------------------------------------*/
-static void initStaticData(void)
-{
- /* Dictionary */
- dictionary = (DictionaryEntry *) pointerTo(header->dictionary);
- /* Find out number of entries in dictionary */
- for (dictionarySize = 0; !isEndOfArray(&dictionary[dictionarySize]); dictionarySize++);
-
- /* Scores */
-
-
- /* All addresses to tables indexed by ids are converted to pointers,
- then adjusted to point to the (imaginary) element before the
- actual table so that [0] does not exist. Instead indices goes
- from 1 and we can use [1]. */
-
- if (header->instanceTableAddress == 0)
- syserr("Instance table pointer == 0");
- instances = (InstanceEntry *) pointerTo(header->instanceTableAddress);
- instances--; /* Back up one so that first is no. 1 */
-
-
- if (header->classTableAddress == 0)
- syserr("Class table pointer == 0");
- classes = (ClassEntry *) pointerTo(header->classTableAddress);
- classes--; /* Back up one so that first is no. 1 */
-
- if (header->containerTableAddress != 0) {
- containers = (ContainerEntry *) pointerTo(header->containerTableAddress);
- containers--;
- }
-
- if (header->eventTableAddress != 0) {
- events = (EventEntry *) pointerTo(header->eventTableAddress);
- events--;
- }
-
- /* Scores, if already allocated, copy initial data */
- if (scores == NULL)
- scores = (Aword *)duplicate((Aword *) pointerTo(header->scores), header->scoreCount*sizeof(Aword));
- else
- memcpy(scores, pointerTo(header->scores), header->scoreCount*sizeof(Aword));
-
- if (literals == NULL)
- literals = (LiteralEntry *)allocate(sizeof(Aword)*(MAXPARAMS+1));
-
- stxs = (SyntaxEntry *) pointerTo(header->syntaxTableAddress);
- vrbs = (VerbEntry *) pointerTo(header->verbTableAddress);
- msgs = (MessageEntry *) pointerTo(header->messageTableAddress);
- initRules(header->ruleTableAddress);
-
- if (header->pack)
- freq = (Aword *) pointerTo(header->freq);
+static void initStaticData(void) {
+ /* Dictionary */
+ dictionary = (DictionaryEntry *) pointerTo(header->dictionary);
+ /* Find out number of entries in dictionary */
+ for (dictionarySize = 0; !isEndOfArray(&dictionary[dictionarySize]); dictionarySize++);
+
+ /* Scores */
+
+
+ /* All addresses to tables indexed by ids are converted to pointers,
+ then adjusted to point to the (imaginary) element before the
+ actual table so that [0] does not exist. Instead indices goes
+ from 1 and we can use [1]. */
+
+ if (header->instanceTableAddress == 0)
+ syserr("Instance table pointer == 0");
+ instances = (InstanceEntry *) pointerTo(header->instanceTableAddress);
+ instances--; /* Back up one so that first is no. 1 */
+
+
+ if (header->classTableAddress == 0)
+ syserr("Class table pointer == 0");
+ classes = (ClassEntry *) pointerTo(header->classTableAddress);
+ classes--; /* Back up one so that first is no. 1 */
+
+ if (header->containerTableAddress != 0) {
+ containers = (ContainerEntry *) pointerTo(header->containerTableAddress);
+ containers--;
+ }
+
+ if (header->eventTableAddress != 0) {
+ events = (EventEntry *) pointerTo(header->eventTableAddress);
+ events--;
+ }
+
+ /* Scores, if already allocated, copy initial data */
+ if (scores == NULL)
+ scores = (Aword *)duplicate((Aword *) pointerTo(header->scores), header->scoreCount * sizeof(Aword));
+ else
+ memcpy(scores, pointerTo(header->scores), header->scoreCount * sizeof(Aword));
+
+ if (literals == NULL)
+ literals = (LiteralEntry *)allocate(sizeof(Aword) * (MAXPARAMS + 1));
+
+ stxs = (SyntaxEntry *) pointerTo(header->syntaxTableAddress);
+ vrbs = (VerbEntry *) pointerTo(header->verbTableAddress);
+ msgs = (MessageEntry *) pointerTo(header->messageTableAddress);
+ initRules(header->ruleTableAddress);
+
+ if (header->pack)
+ freq = (Aword *) pointerTo(header->freq);
}
/*----------------------------------------------------------------------*/
-static void initStrings(void)
-{
- StringInitEntry *init;
+static void initStrings(void) {
+ StringInitEntry *init;
- for (init = (StringInitEntry *) pointerTo(header->stringInitTable); !isEndOfArray(init); init++)
- setInstanceAttribute(init->instanceCode, init->attributeCode, toAptr(getStringFromFile(init->fpos, init->len)));
+ for (init = (StringInitEntry *) pointerTo(header->stringInitTable); !isEndOfArray(init); init++)
+ setInstanceAttribute(init->instanceCode, init->attributeCode, toAptr(getStringFromFile(init->fpos, init->len)));
}
/*----------------------------------------------------------------------*/
-static Aint sizeOfAttributeData(void)
-{
- uint i;
- int size = 0;
-
- for (i=1; i<=header->instanceMax; i++) {
- AttributeEntry *attribute = (AttributeEntry *)pointerTo(instances[i].initialAttributes);
- while (!isEndOfArray(attribute)) {
- size += AwordSizeOf(AttributeEntry);
- attribute++;
- }
- size += 1; /* For EOD */
- }
-
- if (size != header->attributesAreaSize
- && (sizeof(AttributeHeaderEntry) == sizeof(AttributeEntry)))
- syserr("Attribute area size calculated wrong.");
- return size;
+static Aint sizeOfAttributeData(void) {
+ uint i;
+ int size = 0;
+
+ for (i = 1; i <= header->instanceMax; i++) {
+ AttributeEntry *attribute = (AttributeEntry *)pointerTo(instances[i].initialAttributes);
+ while (!isEndOfArray(attribute)) {
+ size += AwordSizeOf(AttributeEntry);
+ attribute++;
+ }
+ size += 1; /* For EOD */
+ }
+
+ if (size != header->attributesAreaSize
+ && (sizeof(AttributeHeaderEntry) == sizeof(AttributeEntry)))
+ syserr("Attribute area size calculated wrong.");
+ return size;
}
/*----------------------------------------------------------------------*/
-static AttributeEntry *initializeAttributes(int awordSize)
-{
- Aword *attributeArea = (Aword *)allocate(awordSize*sizeof(Aword));
- Aword *currentAttributeArea = attributeArea;
- uint i;
-
- for (i=1; i<=header->instanceMax; i++) {
- AttributeHeaderEntry *originalAttribute = (AttributeHeaderEntry *)pointerTo(instances[i].initialAttributes);
- admin[i].attributes = (AttributeEntry *)currentAttributeArea;
- while (!isEndOfArray(originalAttribute)) {
- ((AttributeEntry *)currentAttributeArea)->code = originalAttribute->code;
- ((AttributeEntry *)currentAttributeArea)->value = originalAttribute->value;
- ((AttributeEntry *)currentAttributeArea)->id = originalAttribute->id;
- currentAttributeArea += AwordSizeOf(AttributeEntry);
- originalAttribute++;
- }
- *((Aword*)currentAttributeArea) = EOD;
- currentAttributeArea += 1;
- }
-
- return (AttributeEntry *)attributeArea;
+static AttributeEntry *initializeAttributes(int awordSize) {
+ Aword *attributeArea = (Aword *)allocate(awordSize * sizeof(Aword));
+ Aword *currentAttributeArea = attributeArea;
+ uint i;
+
+ for (i = 1; i <= header->instanceMax; i++) {
+ AttributeHeaderEntry *originalAttribute = (AttributeHeaderEntry *)pointerTo(instances[i].initialAttributes);
+ admin[i].attributes = (AttributeEntry *)currentAttributeArea;
+ while (!isEndOfArray(originalAttribute)) {
+ ((AttributeEntry *)currentAttributeArea)->code = originalAttribute->code;
+ ((AttributeEntry *)currentAttributeArea)->value = originalAttribute->value;
+ ((AttributeEntry *)currentAttributeArea)->id = originalAttribute->id;
+ currentAttributeArea += AwordSizeOf(AttributeEntry);
+ originalAttribute++;
+ }
+ *((Aword *)currentAttributeArea) = EOD;
+ currentAttributeArea += 1;
+ }
+
+ return (AttributeEntry *)attributeArea;
}
/*----------------------------------------------------------------------*/
-static void initDynamicData(void)
-{
- uint instanceId;
+static void initDynamicData(void) {
+ uint instanceId;
- /* Allocate for administrative table */
- admin = (AdminEntry *)allocate((header->instanceMax+1)*sizeof(AdminEntry));
+ /* Allocate for administrative table */
+ admin = (AdminEntry *)allocate((header->instanceMax + 1) * sizeof(AdminEntry));
- /* Create game state copy of attributes */
- attributes = initializeAttributes(sizeOfAttributeData());
+ /* Create game state copy of attributes */
+ attributes = initializeAttributes(sizeOfAttributeData());
- /* Initialise string & set attributes */
- initStrings();
- initSets((SetInitEntry*)pointerTo(header->setInitTable));
+ /* Initialise string & set attributes */
+ initStrings();
+ initSets((SetInitEntry *)pointerTo(header->setInitTable));
- /* Set initial locations */
- for (instanceId = 1; instanceId <= header->instanceMax; instanceId++)
- admin[instanceId].location = instances[instanceId].initialLocation;
+ /* Set initial locations */
+ for (instanceId = 1; instanceId <= header->instanceMax; instanceId++)
+ admin[instanceId].location = instances[instanceId].initialLocation;
}
/*----------------------------------------------------------------------*/
static void runInheritedInitialize(Aint theClass) {
- if (theClass == 0) return;
- runInheritedInitialize(classes[theClass].parent);
- if (classes[theClass].initialize)
- interpret(classes[theClass].initialize);
+ if (theClass == 0) return;
+ runInheritedInitialize(classes[theClass].parent);
+ if (classes[theClass].initialize)
+ interpret(classes[theClass].initialize);
}
/*----------------------------------------------------------------------*/
static void runInitialize(Aint theInstance) {
- runInheritedInitialize(instances[theInstance].parent);
- if (instances[theInstance].initialize != 0)
- interpret(instances[theInstance].initialize);
+ runInheritedInitialize(instances[theInstance].parent);
+ if (instances[theInstance].initialize != 0)
+ interpret(instances[theInstance].initialize);
}
/*----------------------------------------------------------------------*/
static void initializeInstances() {
- uint instanceId;
+ uint instanceId;
- /* Set initial locations */
- for (instanceId = 1; instanceId <= header->instanceMax; instanceId++) {
- current.instance = instanceId;
- runInitialize(instanceId);
- }
+ /* Set initial locations */
+ for (instanceId = 1; instanceId <= header->instanceMax; instanceId++) {
+ current.instance = instanceId;
+ runInitialize(instanceId);
+ }
}
/*----------------------------------------------------------------------*/
-static void start(void)
-{
- int startloc;
-
- current.tick = 0;
- current.location = startloc = where(HERO, TRANSITIVE);
- current.actor = HERO;
- current.score = 0;
-
- initializeInstances();
-
- if (traceSectionOption)
- printf("\n<START:>\n");
- interpret(header->start);
- para();
-
- if (where(HERO, TRANSITIVE) == startloc) {
- if (traceSectionOption)
- printf("<CURRENT LOCATION:>");
- look();
- }
- resetAndEvaluateRules(rules, header->version);
+static void start(void) {
+ int startloc;
+
+ current.tick = 0;
+ current.location = startloc = where(HERO, TRANSITIVE);
+ current.actor = HERO;
+ current.score = 0;
+
+ initializeInstances();
+
+ if (traceSectionOption)
+ printf("\n<START:>\n");
+ interpret(header->start);
+ para();
+
+ if (where(HERO, TRANSITIVE) == startloc) {
+ if (traceSectionOption)
+ printf("<CURRENT LOCATION:>");
+ look();
+ }
+ resetAndEvaluateRules(rules, header->version);
}
/*----------------------------------------------------------------------*/
-static void openFiles(void)
-{
- /* If logging open log file */
- if (transcriptOption || logOption) {
- startTranscript();
- }
+static void openFiles(void) {
+ /* If logging open log file */
+ if (transcriptOption || logOption) {
+ startTranscript();
+ }
}
/*----------------------------------------------------------------------*/
-static void init(void)
-{
- int i;
-
- /* Initialise some status */
- eventQueueTop = 0; /* No pending events */
- initStaticData();
- initDynamicData();
- initParsing();
- checkDebug();
-
- getPageSize();
-
- /* Find first conjunction and use that for ',' handling */
- for (i = 0; i < dictionarySize; i++)
- if (isConjunction(i)) {
- conjWord = i;
- break;
- }
-
- /* Start the adventure */
- if (debugOption)
- debug(FALSE, 0, 0);
- else
- clear();
-
- start();
+static void init(void) {
+ int i;
+
+ /* Initialise some status */
+ eventQueueTop = 0; /* No pending events */
+ initStaticData();
+ initDynamicData();
+ initParsing();
+ checkDebug();
+
+ getPageSize();
+
+ /* Find first conjunction and use that for ',' handling */
+ for (i = 0; i < dictionarySize; i++)
+ if (isConjunction(i)) {
+ conjWord = i;
+ break;
+ }
+
+ /* Start the adventure */
+ if (debugOption)
+ debug(FALSE, 0, 0);
+ else
+ clear();
+
+ start();
}
/*----------------------------------------------------------------------*/
-static bool traceActor(int theActor)
-{
- if (traceSectionOption) {
- printf("\n<ACTOR ");
- traceSay(theActor);
- printf("[%d]", theActor);
- if (current.location != 0) {
- printf(" (at ");
- traceSay(current.location);
- } else
- printf(" (nowhere");
- printf("[%d])", current.location);
- }
- return traceSectionOption;
+static bool traceActor(int theActor) {
+ if (traceSectionOption) {
+ printf("\n<ACTOR ");
+ traceSay(theActor);
+ printf("[%d]", theActor);
+ if (current.location != 0) {
+ printf(" (at ");
+ traceSay(current.location);
+ } else
+ printf(" (nowhere");
+ printf("[%d])", current.location);
+ }
+ return traceSectionOption;
}
/*----------------------------------------------------------------------*/
-static char *scriptName(int theActor, int theScript)
-{
- ScriptEntry *scriptEntry = (ScriptEntry *)pointerTo(header->scriptTableAddress);
-
- while (theScript > 1) {
- scriptEntry++;
- theScript--;
- }
- return (char *)pointerTo(scriptEntry->id);
+static char *scriptName(int theActor, int theScript) {
+ ScriptEntry *scriptEntry = (ScriptEntry *)pointerTo(header->scriptTableAddress);
+
+ while (theScript > 1) {
+ scriptEntry++;
+ theScript--;
+ }
+ return (char *)pointerTo(scriptEntry->id);
}
/*----------------------------------------------------------------------*/
-static void moveActor(int theActor)
-{
- ScriptEntry *scr;
- StepEntry *step;
- Aint previousInstance = current.instance;
-
- current.actor = theActor;
- current.instance = theActor;
- current.location = where(theActor, TRANSITIVE);
- if (theActor == (int)HERO) {
+static void moveActor(int theActor) {
+ ScriptEntry *scr;
+ StepEntry *step;
+ Aint previousInstance = current.instance;
+
+ current.actor = theActor;
+ current.instance = theActor;
+ current.location = where(theActor, TRANSITIVE);
+ if (theActor == (int)HERO) {
#ifdef TODO
/* Ask him! */
- if (setjmp(forfeitLabel) == 0) {
- parse();
- capitalize = TRUE;
- fail = FALSE; /* fail only aborts one actor */
- }
+ if (setjmp(forfeitLabel) == 0) {
+ parse();
+ capitalize = TRUE;
+ fail = FALSE; /* fail only aborts one actor */
+ }
#else
::error("TODO: moveActor setjmp");
#endif
- } else if (admin[theActor].script != 0) {
- for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
- if (scr->code == admin[theActor].script) {
- /* Find correct step in the list by indexing */
- step = (StepEntry *) pointerTo(scr->steps);
- step = (StepEntry *) &step[admin[theActor].step];
- /* Now execute it, maybe. First check wait count */
- if (admin[theActor].waitCount > 0) { /* Wait some more ? */
- if (traceActor(theActor))
- printf(", SCRIPT %s[%ld], STEP %ld, Waiting another %ld turns>\n",
- scriptName(theActor, admin[theActor].script),
- (long)admin[theActor].script, (long)admin[theActor].step+1,
- (long)admin[theActor].waitCount);
- admin[theActor].waitCount--;
- break;
- }
- /* Then check possible expression to wait for */
- if (step->exp != 0) {
- if (traceActor(theActor))
- printf(", SCRIPT %s[%ld], STEP %ld, Evaluating:>\n",
- scriptName(theActor, admin[theActor].script),
- (long)admin[theActor].script, (long)admin[theActor].step+1);
- if (!evaluate(step->exp))
- break; /* Break loop, don't execute step*/
- }
- /* OK, so finally let him do his thing */
- admin[theActor].step++; /* Increment step number before executing... */
- if (!isEndOfArray(step+1) && (step+1)->after != 0) {
- admin[theActor].waitCount = evaluate((step+1)->after);
- }
- if (traceActor(theActor))
- printf(", SCRIPT %s[%ld], STEP %ld, Executing:>\n",
- scriptName(theActor, admin[theActor].script),
- (long)admin[theActor].script,
- (long)admin[theActor].step);
- interpret(step->stms);
- step++;
- /* ... so that we can see if he failed or is USEing another script now */
- if (fail || (admin[theActor].step != 0 && isEndOfArray(step)))
- /* No more steps in this script, so stop him */
- admin[theActor].script = 0;
- fail = FALSE; /* fail only aborts one actor */
- break; /* We have executed a script so leave loop */
- }
- }
- if (isEndOfArray(scr))
- syserr("Unknown actor script.");
- } else {
- if (traceActor(theActor)) {
- printf(", Idle>\n");
- }
- }
-
- current.instance = previousInstance;
+ } else if (admin[theActor].script != 0) {
+ for (scr = (ScriptEntry *) pointerTo(header->scriptTableAddress); !isEndOfArray(scr); scr++) {
+ if (scr->code == admin[theActor].script) {
+ /* Find correct step in the list by indexing */
+ step = (StepEntry *) pointerTo(scr->steps);
+ step = (StepEntry *) &step[admin[theActor].step];
+ /* Now execute it, maybe. First check wait count */
+ if (admin[theActor].waitCount > 0) { /* Wait some more ? */
+ if (traceActor(theActor))
+ printf(", SCRIPT %s[%ld], STEP %ld, Waiting another %ld turns>\n",
+ scriptName(theActor, admin[theActor].script),
+ (long)admin[theActor].script, (long)admin[theActor].step + 1,
+ (long)admin[theActor].waitCount);
+ admin[theActor].waitCount--;
+ break;
+ }
+ /* Then check possible expression to wait for */
+ if (step->exp != 0) {
+ if (traceActor(theActor))
+ printf(", SCRIPT %s[%ld], STEP %ld, Evaluating:>\n",
+ scriptName(theActor, admin[theActor].script),
+ (long)admin[theActor].script, (long)admin[theActor].step + 1);
+ if (!evaluate(step->exp))
+ break; /* Break loop, don't execute step*/
+ }
+ /* OK, so finally let him do his thing */
+ admin[theActor].step++; /* Increment step number before executing... */
+ if (!isEndOfArray(step + 1) && (step + 1)->after != 0) {
+ admin[theActor].waitCount = evaluate((step + 1)->after);
+ }
+ if (traceActor(theActor))
+ printf(", SCRIPT %s[%ld], STEP %ld, Executing:>\n",
+ scriptName(theActor, admin[theActor].script),
+ (long)admin[theActor].script,
+ (long)admin[theActor].step);
+ interpret(step->stms);
+ step++;
+ /* ... so that we can see if he failed or is USEing another script now */
+ if (fail || (admin[theActor].step != 0 && isEndOfArray(step)))
+ /* No more steps in this script, so stop him */
+ admin[theActor].script = 0;
+ fail = FALSE; /* fail only aborts one actor */
+ break; /* We have executed a script so leave loop */
+ }
+ }
+ if (isEndOfArray(scr))
+ syserr("Unknown actor script.");
+ } else {
+ if (traceActor(theActor)) {
+ printf(", Idle>\n");
+ }
+ }
+
+ current.instance = previousInstance;
}
#define RESTARTED (setjmp(restartLabel) != NO_JUMP_RETURN)
@@ -747,74 +736,74 @@ static void moveActor(int theActor)
/*======================================================================*/
void run(void) {
- static Stack theStack = NULL; /* Needs to survive longjmp() */
+ static Stack theStack = NULL; /* Needs to survive longjmp() */
- openFiles();
- load(); /* Load program */
+ openFiles();
+ load(); /* Load program */
#ifdef TODO
- if (RESTARTED) {
- deleteStack(theStack);
- }
-
- theStack = createStack(STACKSIZE);
- setInterpreterStack(theStack);
-
- initStateStack();
-
- if (!ERROR_RETURNED) /* Can happen in start section too... */
- init(); /* Initialise and start the adventure */
-
- while (TRUE) {
- if (debugOption)
- debug(FALSE, 0, 0);
-
- if (stackDepth(theStack) != 0)
- syserr("Stack is not empty in main loop");
-
- if (!current.meta)
- runPendingEvents();
-
- /* Return here if error during execution */
- switch (setjmp(returnLabel)) {
- case NO_JUMP_RETURN:
- break;
- case ERROR_RETURN:
- forgetGameState();
- forceNewPlayerInput();
- break;
- case UNDO_RETURN:
- forceNewPlayerInput();
- break;
- default:
- syserr("Unexpected longjmp() return value");
- }
-
- recursionDepth = 0;
-
- /* Move all characters, hero first */
- rememberGameState();
- current.meta = FALSE;
- moveActor(header->theHero);
-
- if (gameStateChanged)
- rememberCommands();
- else
- forgetGameState();
-
- if (!current.meta) {
- current.tick++;
-
- /* Remove this call? Since Eval is done up there after each event... */
- resetAndEvaluateRules(rules, header->version);
-
- /* Then all the other actors... */
- for (uint i = 1; i <= header->instanceMax; i++)
- if (i != header->theHero && isAActor(i)) {
- moveActor(i);
- resetAndEvaluateRules(rules, header->version);
- }
- }
- }
+ if (RESTARTED) {
+ deleteStack(theStack);
+ }
+
+ theStack = createStack(STACKSIZE);
+ setInterpreterStack(theStack);
+
+ initStateStack();
+
+ if (!ERROR_RETURNED) /* Can happen in start section too... */
+ init(); /* Initialise and start the adventure */
+
+ while (TRUE) {
+ if (debugOption)
+ debug(FALSE, 0, 0);
+
+ if (stackDepth(theStack) != 0)
+ syserr("Stack is not empty in main loop");
+
+ if (!current.meta)
+ runPendingEvents();
+
+ /* Return here if error during execution */
+ switch (setjmp(returnLabel)) {
+ case NO_JUMP_RETURN:
+ break;
+ case ERROR_RETURN:
+ forgetGameState();
+ forceNewPlayerInput();
+ break;
+ case UNDO_RETURN:
+ forceNewPlayerInput();
+ break;
+ default:
+ syserr("Unexpected longjmp() return value");
+ }
+
+ recursionDepth = 0;
+
+ /* Move all characters, hero first */
+ rememberGameState();
+ current.meta = FALSE;
+ moveActor(header->theHero);
+
+ if (gameStateChanged)
+ rememberCommands();
+ else
+ forgetGameState();
+
+ if (!current.meta) {
+ current.tick++;
+
+ /* Remove this call? Since Eval is done up there after each event... */
+ resetAndEvaluateRules(rules, header->version);
+
+ /* Then all the other actors... */
+ for (uint i = 1; i <= header->instanceMax; i++)
+ if (i != header->theHero && isAActor(i)) {
+ moveActor(i);
+ resetAndEvaluateRules(rules, header->version);
+ }
+ }
+ }
#endif
}