diff options
author | Walter van Niftrik | 2016-12-23 20:56:56 +0100 |
---|---|---|
committer | Walter van Niftrik | 2016-12-23 20:59:02 +0100 |
commit | 0dc67a0a6e37446ed63e777712d6d239b4090d11 (patch) | |
tree | a1afcdfa6b6414a3a39ba5493e4e71e059c68ec0 /engines/adl | |
parent | d1905b35d5028c7dbb8d8922cf1e5c6c3178cd56 (diff) | |
download | scummvm-rg350-0dc67a0a6e37446ed63e777712d6d239b4090d11.tar.gz scummvm-rg350-0dc67a0a6e37446ed63e777712d6d239b4090d11.tar.bz2 scummvm-rg350-0dc67a0a6e37446ed63e777712d6d239b4090d11.zip |
ADL: Implement hires5 savegames
Diffstat (limited to 'engines/adl')
-rw-r--r-- | engines/adl/adl.cpp | 143 | ||||
-rw-r--r-- | engines/adl/adl.h | 3 | ||||
-rw-r--r-- | engines/adl/adl_v4.cpp | 92 | ||||
-rw-r--r-- | engines/adl/adl_v4.h | 2 |
4 files changed, 171 insertions, 69 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index 81950450ab..e223fea606 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -676,6 +676,49 @@ bool AdlEngine::hasFeature(EngineFeature f) const { } } +void AdlEngine::loadState(Common::ReadStream &stream) { + _state.room = stream.readByte(); + _state.moves = stream.readByte(); + _state.isDark = stream.readByte(); + _state.time.hours = stream.readByte(); + _state.time.minutes = stream.readByte(); + + uint32 size = stream.readUint32BE(); + if (size != _state.rooms.size()) + error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size); + + for (uint i = 0; i < size; ++i) { + _state.rooms[i].picture = stream.readByte(); + _state.rooms[i].curPicture = stream.readByte(); + _state.rooms[i].isFirstTime = stream.readByte(); + } + + // NOTE: _state.curPicture is part of the save state in the original engine. We + // reconstruct it instead. This is believed to be safe for at least hires 0-2, but + // this may need to be re-evaluated for later games. + _state.curPicture = getCurRoom().curPicture; + + size = stream.readUint32BE(); + if (size != _state.items.size()) + error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); + + Common::List<Item>::iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + item->room = stream.readByte(); + item->picture = stream.readByte(); + item->position.x = stream.readByte(); + item->position.y = stream.readByte(); + item->state = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != _state.vars.size()) + error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size); + + for (uint i = 0; i < size; ++i) + _state.vars[i] = stream.readByte(); +} + Common::Error AdlEngine::loadGameState(int slot) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName); @@ -708,47 +751,7 @@ Common::Error AdlEngine::loadGameState(int slot) { Graphics::skipThumbnail(*inFile); initState(); - - _state.room = inFile->readByte(); - _state.moves = inFile->readByte(); - _state.isDark = inFile->readByte(); - _state.time.hours = inFile->readByte(); - _state.time.minutes = inFile->readByte(); - - uint32 size = inFile->readUint32BE(); - if (size != _state.rooms.size()) - error("Room count mismatch (expected %i; found %i)", _state.rooms.size(), size); - - for (uint i = 0; i < size; ++i) { - _state.rooms[i].picture = inFile->readByte(); - _state.rooms[i].curPicture = inFile->readByte(); - _state.rooms[i].isFirstTime = inFile->readByte(); - } - - // NOTE: _state.curPicture is part of the save state in the original engine. We - // reconstruct it instead. This is believed to be safe for at least hires 0-2, but - // this may need to be re-evaluated for later games. - _state.curPicture = getCurRoom().curPicture; - - size = inFile->readUint32BE(); - if (size != _state.items.size()) - error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); - - Common::List<Item>::iterator item; - for (item = _state.items.begin(); item != _state.items.end(); ++item) { - item->room = inFile->readByte(); - item->picture = inFile->readByte(); - item->position.x = inFile->readByte(); - item->position.y = inFile->readByte(); - item->state = inFile->readByte(); - } - - size = inFile->readUint32BE(); - if (size != _state.vars.size()) - error("Variable count mismatch (expected %i; found %i)", _state.vars.size(), size); - - for (uint i = 0; i < size; ++i) - _state.vars[i] = inFile->readByte(); + loadState(*inFile); if (inFile->err() || inFile->eos()) error("Failed to load game '%s'", fileName.c_str()); @@ -765,6 +768,35 @@ bool AdlEngine::canLoadGameStateCurrently() { return _canRestoreNow; } +void AdlEngine::saveState(Common::WriteStream &stream) { + stream.writeByte(_state.room); + stream.writeByte(_state.moves); + stream.writeByte(_state.isDark); + stream.writeByte(_state.time.hours); + stream.writeByte(_state.time.minutes); + + stream.writeUint32BE(_state.rooms.size()); + for (uint i = 0; i < _state.rooms.size(); ++i) { + stream.writeByte(_state.rooms[i].picture); + stream.writeByte(_state.rooms[i].curPicture); + stream.writeByte(_state.rooms[i].isFirstTime); + } + + stream.writeUint32BE(_state.items.size()); + Common::List<Item>::const_iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + stream.writeByte(item->room); + stream.writeByte(item->picture); + stream.writeByte(item->position.x); + stream.writeByte(item->position.y); + stream.writeByte(item->state); + } + + stream.writeUint32BE(_state.vars.size()); + for (uint i = 0; i < _state.vars.size(); ++i) + stream.writeByte(_state.vars[i]); +} + Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot); Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName); @@ -802,34 +834,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) { outFile->writeUint32BE(playTime); _display->saveThumbnail(*outFile); - - outFile->writeByte(_state.room); - outFile->writeByte(_state.moves); - outFile->writeByte(_state.isDark); - outFile->writeByte(_state.time.hours); - outFile->writeByte(_state.time.minutes); - - outFile->writeUint32BE(_state.rooms.size()); - for (uint i = 0; i < _state.rooms.size(); ++i) { - outFile->writeByte(_state.rooms[i].picture); - outFile->writeByte(_state.rooms[i].curPicture); - outFile->writeByte(_state.rooms[i].isFirstTime); - } - - outFile->writeUint32BE(_state.items.size()); - Common::List<Item>::const_iterator item; - for (item = _state.items.begin(); item != _state.items.end(); ++item) { - outFile->writeByte(item->room); - outFile->writeByte(item->picture); - outFile->writeByte(item->position.x); - outFile->writeByte(item->position.y); - outFile->writeByte(item->state); - } - - outFile->writeUint32BE(_state.vars.size()); - for (uint i = 0; i < _state.vars.size(); ++i) - outFile->writeByte(_state.vars[i]); - + saveState(*outFile); outFile->finalize(); if (outFile->err()) { diff --git a/engines/adl/adl.h b/engines/adl/adl.h index dcc8f44a20..4b644ccbf4 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -42,6 +42,7 @@ namespace Common { class ReadStream; +class WriteStream; class SeekableReadStream; class File; struct Event; @@ -235,6 +236,8 @@ protected: Common::Error loadGameState(int slot); Common::Error saveGameState(int slot, const Common::String &desc); + virtual void loadState(Common::ReadStream &stream); + virtual void saveState(Common::WriteStream &stream); Common::String readString(Common::ReadStream &stream, byte until = 0) const; Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const; void openFile(Common::File &file, const Common::String &name) const; diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp index 613ffd8832..2ab784f3aa 100644 --- a/engines/adl/adl_v4.cpp +++ b/engines/adl/adl_v4.cpp @@ -36,6 +36,98 @@ AdlEngine_v4::~AdlEngine_v4() { delete _itemPicIndex; } +void AdlEngine_v4::loadState(Common::ReadStream &stream) { + _state.room = stream.readByte(); + _state.region = stream.readByte(); + _state.prevRegion = stream.readByte(); + + uint32 size = stream.readUint32BE(); + if (size != _state.regions.size()) + error("Region count mismatch (expected %i; found %i)", _state.regions.size(), size); + + Common::Array<Region>::iterator region; + for (region = _state.regions.begin(); region != _state.regions.end(); ++region) { + size = stream.readUint32BE(); + if (size != region->rooms.size()) + error("Room count mismatch (expected %i; found %i)", region->rooms.size(), size); + + Common::Array<RoomState>::iterator room; + for (room = region->rooms.begin(); room != region->rooms.end(); ++room) { + room->picture = stream.readByte(); + room->isFirstTime = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != region->vars.size()) + error("Variable count mismatch (expected %i; found %i)", region->vars.size(), size); + + for (uint i = 0; i < region->vars.size(); ++i) + region->vars[i] = stream.readByte(); + } + + size = stream.readUint32BE(); + if (size != _state.items.size()) + error("Item count mismatch (expected %i; found %i)", _state.items.size(), size); + + Common::List<Item>::iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + item->room = stream.readByte(); + item->region = stream.readByte(); + item->state = stream.readByte(); + } + + size = stream.readUint32BE(); + const uint expectedSize = _state.vars.size() - getRegion(1).vars.size(); + if (size != expectedSize) + error("Variable count mismatch (expected %i; found %i)", expectedSize, size); + + for (uint i = getRegion(1).vars.size(); i < size; ++i) + _state.vars[i] = stream.readByte(); + + if (stream.err() || stream.eos()) + return; + + loadRegion(_state.region); + restoreRoomState(_state.room); + _roomOnScreen = _picOnScreen = 0; +} + +void AdlEngine_v4::saveState(Common::WriteStream &stream) { + backupVars(); + backupRoomState(_state.room); + + stream.writeByte(_state.room); + stream.writeByte(_state.region); + stream.writeByte(_state.prevRegion); + + stream.writeUint32BE(_state.regions.size()); + Common::Array<Region>::const_iterator region; + for (region = _state.regions.begin(); region != _state.regions.end(); ++region) { + stream.writeUint32BE(region->rooms.size()); + Common::Array<RoomState>::const_iterator room; + for (room = region->rooms.begin(); room != region->rooms.end(); ++room) { + stream.writeByte(room->picture); + stream.writeByte(room->isFirstTime); + } + + stream.writeUint32BE(region->vars.size()); + for (uint i = 0; i < region->vars.size(); ++i) + stream.writeByte(region->vars[i]); + } + + stream.writeUint32BE(_state.items.size()); + Common::List<Item>::const_iterator item; + for (item = _state.items.begin(); item != _state.items.end(); ++item) { + stream.writeByte(item->room); + stream.writeByte(item->region); + stream.writeByte(item->state); + } + + stream.writeUint32BE(_state.vars.size() - getRegion(1).vars.size()); + for (uint i = getRegion(1).vars.size(); i < _state.vars.size(); ++i) + stream.writeByte(_state.vars[i]); +} + Common::String AdlEngine_v4::loadMessage(uint idx) const { Common::String str = AdlEngine_v3::loadMessage(idx); diff --git a/engines/adl/adl_v4.h b/engines/adl/adl_v4.h index 1fd0a72b1d..c1f9bfbd73 100644 --- a/engines/adl/adl_v4.h +++ b/engines/adl/adl_v4.h @@ -49,6 +49,8 @@ protected: AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd); // AdlEngine + virtual void loadState(Common::ReadStream &stream); + virtual void saveState(Common::WriteStream &stream); virtual Common::String loadMessage(uint idx) const; virtual Common::String getItemDescription(const Item &item) const; virtual void switchRegion(byte region); |