From 6bc59c0bb06e591167124633b06fb6ca9f1d32df Mon Sep 17 00:00:00 2001 From: Julien Templier Date: Tue, 26 Oct 2010 12:10:38 +0000 Subject: LASTEXPRESS: Implement loading of savegame entry headers svn-id: r53847 --- engines/lastexpress/game/savegame.cpp | 51 ++++++++++++++++++++++++----------- engines/lastexpress/game/savegame.h | 10 +++---- 2 files changed, 40 insertions(+), 21 deletions(-) (limited to 'engines/lastexpress/game') diff --git a/engines/lastexpress/game/savegame.cpp b/engines/lastexpress/game/savegame.cpp index 53516b1347..3a0da868ec 100644 --- a/engines/lastexpress/game/savegame.cpp +++ b/engines/lastexpress/game/savegame.cpp @@ -101,7 +101,7 @@ void SaveLoad::create(GameId id) { uint32 SaveLoad::init(GameId id, bool resetHeaders) { initStream(); - // Open savegame + // Open savegame and check size Common::InSaveFile *save = openForLoading(id); if (save->size() < 32) error("SaveLoad::init - Savegame seems to be corrupted (not enough data: %i bytes)", save->size()); @@ -111,7 +111,7 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) { _savegame->writeByte(save->readByte()); _savegame->seek(0); - delete save; + SAFE_DELETE(save); // Load the main header Common::Serializer ser(_savegame, NULL); @@ -131,10 +131,27 @@ uint32 SaveLoad::init(GameId id, bool resetHeaders) { _gameHeaders.push_back(entryHeader); } - warning("SaveLoad::initSavegame: not implemented!"); + // Read the list of entry headers + if (_savegame->size() > 32) { + while (!_savegame->eos() && !_savegame->err()) { + + // Update sound queue while we go through the savegame + getSound()->updateQueue(); + + SavegameEntryHeader *entry = new SavegameEntryHeader(); + entry->saveLoadWithSerializer(ser); + + if (!entry->isValid()) + break; + + _gameHeaders.push_back(entry); + + _savegame->seek(entry->offset, SEEK_CUR); + } + } // return the index to the current save game entry (we store count + 1 entries, so we're good) - return 0; //header.count; + return mainHeader.count; } void SaveLoad::clear() { @@ -314,13 +331,13 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) { header.value = value; // Save position - uint32 pos = _savegame->pos(); + uint32 originalPosition = _savegame->pos(); // Write header Common::Serializer ser(NULL, _savegame); header.saveLoadWithSerializer(ser); - computePadding(); + computeOffset(); // Write game data WRITE_ENTRY("entity index", ser.syncAsUint32LE(entity), 4); @@ -336,21 +353,27 @@ void SaveLoad::writeEntry(SavegameType type, EntityIndex entity, uint32 value) { WRITE_ENTRY("sound", getSound()->saveLoadWithSerializer(ser), 0); WRITE_ENTRY("savepoints", getSavePoints()->saveLoadWithSerializer(ser), 0); - header.padding = computePadding(); + header.offset = computeOffset(originalPosition); + + // Add padding if necessary + while (header.offset & 0xF) { + _savegame->writeByte(0); + header.offset++; + } // Save end position - uint32 endpos = _savegame->pos(); + uint32 endPosition = _savegame->pos(); // Validate entry header if (!header.isValid()) error("SaveLoad::writeEntry: entry header is invalid"); // Save the header with the updated info - _savegame->seek(pos); + _savegame->seek(originalPosition); header.saveLoadWithSerializer(ser); // Move back to the end of the entry - _savegame->seek(endpos); + _savegame->seek(endPosition); } void SaveLoad::readEntry(SavegameType type, EntityIndex entity, uint32 value) { @@ -364,14 +387,10 @@ SaveLoad::SavegameEntryHeader *SaveLoad::getEntry(uint32 index) { return _gameHeaders[index]; } -uint32 SaveLoad::computePadding() { +uint32 SaveLoad::computeOffset(uint32 originalPosition) { warning("SaveLoad::computePadding: not implemented!"); - // Hack - while (_savegame->pos() & 15) - _savegame->writeByte(0); - - return _savegame->pos(); + return (_savegame->pos() - originalPosition - 32); } ////////////////////////////////////////////////////////////////////////// diff --git a/engines/lastexpress/game/savegame.h b/engines/lastexpress/game/savegame.h index 33a1735d61..e5cb940c0b 100644 --- a/engines/lastexpress/game/savegame.h +++ b/engines/lastexpress/game/savegame.h @@ -209,7 +209,7 @@ private: uint32 signature; SavegameType type; TimeValue time; - int padding; + int offset; ChapterIndex chapter; uint32 value; int field_18; @@ -219,7 +219,7 @@ private: signature = SAVEGAME_ENTRY_SIGNATURE; type = kSavegameTypeIndex; time = kTimeNone; - padding = 0; + offset = 0; chapter = kChapterAll; value = 0; field_18 = 0; @@ -230,7 +230,7 @@ private: s.syncAsUint32LE(signature); s.syncAsUint32LE(type); s.syncAsUint32LE(time); - s.syncAsUint32LE(padding); + s.syncAsUint32LE(offset); s.syncAsUint32LE(chapter); s.syncAsUint32LE(value); s.syncAsUint32LE(field_18); @@ -247,7 +247,7 @@ private: if (time < kTimeStartGame || time > kTimeCityConstantinople) return false; - if (padding <= 0 || padding & 15) + if (offset <= 0 || offset & 15) return false; /* No check for < 0, as it cannot happen normaly */ @@ -269,7 +269,7 @@ private: void writeEntry(SavegameType type, EntityIndex entity, uint32 value); void readEntry(SavegameType type, EntityIndex entity, uint32 value); SavegameEntryHeader *getEntry(uint32 index); - uint32 computePadding(); + uint32 computeOffset(uint32 originalPosition = 0); // Opening save files static Common::String getFilename(GameId id); -- cgit v1.2.3