diff options
Diffstat (limited to 'engines/glk/alan3')
-rw-r--r-- | engines/glk/alan3/acode.cpp | 17 | ||||
-rw-r--r-- | engines/glk/alan3/instance.cpp | 3 | ||||
-rw-r--r-- | engines/glk/alan3/save.cpp | 250 |
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; } |