aboutsummaryrefslogtreecommitdiff
path: root/engines/glk/alan3
diff options
context:
space:
mode:
Diffstat (limited to 'engines/glk/alan3')
-rw-r--r--engines/glk/alan3/acode.cpp17
-rw-r--r--engines/glk/alan3/instance.cpp3
-rw-r--r--engines/glk/alan3/save.cpp250
3 files changed, 86 insertions, 184 deletions
diff --git a/engines/glk/alan3/acode.cpp b/engines/glk/alan3/acode.cpp
index 3dbfaa5cc0..4d41e0fc43 100644
--- a/engines/glk/alan3/acode.cpp
+++ b/engines/glk/alan3/acode.cpp
@@ -26,9 +26,20 @@ namespace Glk {
namespace Alan3 {
void AttributeEntry::synchronize(Common::Serializer &s) {
- s.syncAsSint32LE(code);
- s.syncAsSint32LE(value);
- s.syncAsSint32LE(id);
+ // We have to do some annoying temporary copy of the fields to get around gcc
+ // errors about getting references to fields of packed structures
+ Aint c = code;
+ Aptr v = value;
+ Aaddr i = id;
+ s.syncAsSint32LE(c);
+ s.syncAsSint32LE(v);
+ s.syncAsSint32LE(i);
+
+ if (s.isLoading()) {
+ code = c;
+ value = v;
+ id = i;
+ }
}
} // End of namespace Alan3
diff --git a/engines/glk/alan3/instance.cpp b/engines/glk/alan3/instance.cpp
index b5220577b3..b738fd6a83 100644
--- a/engines/glk/alan3/instance.cpp
+++ b/engines/glk/alan3/instance.cpp
@@ -630,7 +630,8 @@ static void sayNegative(CONTEXT, int instance) {
} else {
bool flag;
FUNC1(sayInheritedNegativeForm, flag, instances[instance].parent)
- CALL1(sayInstance, instance)
+ if (!flag)
+ CALL1(sayInstance, instance)
}
}
diff --git a/engines/glk/alan3/save.cpp b/engines/glk/alan3/save.cpp
index 6e645d0eb4..da1d5b6ba4 100644
--- a/engines/glk/alan3/save.cpp
+++ b/engines/glk/alan3/save.cpp
@@ -36,212 +36,106 @@
namespace Glk {
namespace Alan3 {
-/*----------------------------------------------------------------------*/
-static void saveStrings(Common::WriteStream *saveFile) {
- StringInitEntry *initEntry;
-
- if (header->stringInitTable != 0)
- for (initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
- !isEndOfArray(initEntry); initEntry++) {
- char *attr = (char *)getInstanceStringAttribute(initEntry->instanceCode, initEntry->attributeCode);
- Aint length = strlen(attr) + 1;
- saveFile->writeUint32LE(length);
- saveFile->write(attr, length);
- }
-}
-
-
-/*----------------------------------------------------------------------*/
-static void saveSets(Common::WriteStream *saveFile) {
- SetInitEntry *initEntry;
-
- if (header->setInitTable != 0)
- for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
- !isEndOfArray(initEntry); initEntry++) {
- Set *attr = (Set *)getInstanceSetAttribute(initEntry->instanceCode, initEntry->attributeCode);
- saveFile->writeUint32LE(attr->size);
- saveFile->write(attr->members, attr->size);
- }
-}
-
-
-/*----------------------------------------------------------------------*/
static void saveGameInfo(Common::WriteStream *saveFile) {
saveFile->writeUint32BE(MKTAG('A', 'S', 'A', 'V'));
saveFile->write(header->version, 4);
saveFile->writeUint32LE(header->uid);
}
+static void verifySaveFile(CONTEXT, Common::SeekableReadStream *saveFile) {
+ if (saveFile->readUint32BE() != MKTAG('A', 'S', 'A', 'V'))
+ error(context, M_NOTASAVEFILE);
+}
+
+static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
+ char savedVersion[4];
-/*----------------------------------------------------------------------*/
-static void saveAdmin(Common::WriteStream *saveFile) {
- Common::Serializer s(nullptr, saveFile);
- for (uint i = 1; i <= header->instanceMax; i++)
- admin[i].synchronize(s);
+ saveFile->read(&savedVersion, 4);
+ if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
+ error(context, M_SAVEVERS);
+}
+
+static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
+ Aword savedUid = saveFile->readUint32LE();
+ if (!ignoreErrorOption && savedUid != header->uid)
+ error(context, M_SAVEVERS);
}
+void syncGame(Common::Serializer &s) {
+ // Current values
+ current.synchronize(s);
-/*----------------------------------------------------------------------*/
-static void saveAttributeArea(Common::WriteStream *saveFile) {
- Common::Serializer s(nullptr, saveFile);
+ // Attributes area
for (Aint i = 0; i < header->attributesAreaSize; ++i)
attributes[i].synchronize(s);
-}
+ // Admin data
+ for (uint i = 1; i <= header->instanceMax; i++)
+ admin[i].synchronize(s);
-/*----------------------------------------------------------------------*/
-static void saveEventQueue(Common::WriteStream *saveFile) {
- Common::Serializer s(nullptr, saveFile);
-
+ // Event queue
s.syncAsSint32LE(eventQueueTop);
for (int i = 0; i < eventQueueTop; ++i)
eventQueue[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void saveCurrentValues(Common::WriteStream *saveFile) {
- Common::Serializer s(nullptr, saveFile);
- current.synchronize(s);
-}
-
-/*----------------------------------------------------------------------*/
-static void saveScores(Common::WriteStream *saveFile) {
+ // Scores
for (Aint i = 0; i < header->scoreCount; ++i)
- saveFile->writeUint32LE(scores[i]);
-}
-
-
-/*----------------------------------------------------------------------*/
-void saveGame(Common::WriteStream *saveFile) {
- /* Save tag, version of interpreter, name and uid of game */
- saveGameInfo(saveFile);
-
- /* Save current values */
- saveCurrentValues(saveFile);
-
- saveAttributeArea(saveFile);
- saveAdmin(saveFile);
-
- saveEventQueue(saveFile);
-
- saveScores(saveFile);
-
- saveStrings(saveFile);
- saveSets(saveFile);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreStrings(Common::SeekableReadStream *saveFile) {
- StringInitEntry *initEntry;
+ s.syncAsUint32LE(scores[i]);
+ // Strings
if (header->stringInitTable != 0)
- for (initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
- !isEndOfArray(initEntry); initEntry++) {
- Aint length = saveFile->readUint32LE();
- char *string = (char *)allocate(length + 1);
+ for (StringInitEntry *initEntry = (StringInitEntry *)pointerTo(header->stringInitTable);
+ !isEndOfArray(initEntry); initEntry++) {
- saveFile->read(string, length);
+ if (s.isSaving()) {
+ char *attr = (char *)getInstanceStringAttribute(initEntry->instanceCode, initEntry->attributeCode);
+ Aint length = strlen(attr) + 1;
+ s.syncAsUint32LE(length);
+ s.syncBytes((byte *)attr, length);
+ } else {
+ Aint length = 0;
+ s.syncAsUint32LE(length);
+ char *string = (char *)allocate(length + 1);
+ s.syncBytes((byte *)string, length);
setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(string));
}
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreSets(Common::SeekableReadStream *saveFile) {
- SetInitEntry *initEntry;
-
- if (header->setInitTable != 0)
- for (initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
- !isEndOfArray(initEntry); initEntry++) {
- Aint setSize = saveFile->readUint32LE();
- Set *set = newSet(setSize);
+ }
- for (int i = 0; i < setSize; i++) {
- Aword member = saveFile->readUint32LE();
- addToSet(set, member);
+ // Sets
+ if (header->setInitTable != 0) {
+ for (SetInitEntry *initEntry = (SetInitEntry *)pointerTo(header->setInitTable);
+ !isEndOfArray(initEntry); initEntry++) {
+
+ if (s.isSaving()) {
+ Set *attr = (Set *)getInstanceSetAttribute(initEntry->instanceCode, initEntry->attributeCode);
+ s.syncAsUint32LE(attr->size);
+ for (int i = 0; i < attr->size; ++i)
+ s.syncAsUint32LE(attr->members[i]);
+
+ } else {
+ Aword setSize = 0, member = 0;
+ s.syncAsUint32BE(setSize);
+ Set *set = newSet(setSize);
+ for (uint i = 0; i < setSize; ++i) {
+ s.syncAsUint32LE(member);
+ addToSet(set, member);
+ }
+
+ setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(set));
}
- setInstanceAttribute(initEntry->instanceCode, initEntry->attributeCode, toAptr(set));
}
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreScores(Common::SeekableReadStream *saveFile) {
- for (Aint i = 0; i < header->scoreCount; ++i)
- scores[i] = saveFile->readUint32LE();
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreEventQueue(Common::SeekableReadStream *saveFile) {
- Common::Serializer s(saveFile, nullptr);
-
- s.syncAsSint32LE(eventQueueTop);
- for (int i = 0; i < eventQueueTop; ++i)
- eventQueue[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreAdmin(Common::SeekableReadStream *saveFile) {
- // Restore admin for instances, remember to reset attribute area pointer
- Common::Serializer s(saveFile, nullptr);
- for (uint i = 1; i <= header->instanceMax; i++) {
- AttributeEntry *currentAttributesArea = admin[i].attributes;
- admin[i].synchronize(s);
- admin[i].attributes = currentAttributesArea;
}
}
+void saveGame(Common::WriteStream *saveFile) {
+ // Save tag, version of interpreter, and unique id of game
+ saveGameInfo(saveFile);
-/*----------------------------------------------------------------------*/
-static void restoreAttributeArea(Common::SeekableReadStream *saveFile) {
- Common::Serializer s(saveFile, nullptr);
- for (Aint i = 0; i < header->attributesAreaSize; ++i)
- attributes[i].synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void restoreCurrentValues(Common::SeekableReadStream *saveFile) {
- Common::Serializer s(saveFile, nullptr);
- current.synchronize(s);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifyGameId(CONTEXT, Common::SeekableReadStream *saveFile) {
- Aword savedUid = saveFile->readUint32LE();
- if (!ignoreErrorOption && savedUid != header->uid)
- error(context, M_SAVEVERS);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifyCompilerVersion(CONTEXT, Common::SeekableReadStream *saveFile) {
- char savedVersion[4];
-
- saveFile->read(&savedVersion, 4);
- if (!ignoreErrorOption && memcmp(savedVersion, header->version, 4))
- error(context, M_SAVEVERS);
-}
-
-
-/*----------------------------------------------------------------------*/
-static void verifySaveFile(CONTEXT, Common::SeekableReadStream *saveFile) {
- char string[5];
- saveFile->read(string, 4);
- string[4] = '\0';
-
- if (strcmp(string, "ASAV") != 0)
- error(context, M_NOTASAVEFILE);
+ // Save game data
+ Common::Serializer s(nullptr, saveFile);
+ syncGame(s);
}
-
-/*----------------------------------------------------------------------*/
bool restoreGame(Common::SeekableReadStream *saveFile) {
Context ctx;
verifySaveFile(ctx, saveFile);
@@ -255,13 +149,9 @@ bool restoreGame(Common::SeekableReadStream *saveFile) {
verifyGameId(ctx, saveFile);
if (ctx._break) return false;
- restoreCurrentValues(saveFile);
- restoreAttributeArea(saveFile);
- restoreAdmin(saveFile);
- restoreEventQueue(saveFile);
- restoreScores(saveFile);
- restoreStrings(saveFile);
- restoreSets(saveFile);
+ // Restore game data
+ Common::Serializer s(saveFile, nullptr);
+ syncGame(s);
return true;
}