ADL: Implement hires5 savegames
This commit is contained in:
parent
d1905b35d5
commit
0dc67a0a6e
4 changed files with 171 additions and 69 deletions
|
@ -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::Error AdlEngine::loadGameState(int slot) {
|
||||||
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
|
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
|
||||||
Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
|
Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
|
||||||
|
@ -708,47 +751,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
|
||||||
Graphics::skipThumbnail(*inFile);
|
Graphics::skipThumbnail(*inFile);
|
||||||
|
|
||||||
initState();
|
initState();
|
||||||
|
loadState(*inFile);
|
||||||
_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();
|
|
||||||
|
|
||||||
if (inFile->err() || inFile->eos())
|
if (inFile->err() || inFile->eos())
|
||||||
error("Failed to load game '%s'", fileName.c_str());
|
error("Failed to load game '%s'", fileName.c_str());
|
||||||
|
@ -765,6 +768,35 @@ bool AdlEngine::canLoadGameStateCurrently() {
|
||||||
return _canRestoreNow;
|
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::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
|
||||||
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
|
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
|
||||||
Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
|
Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
|
||||||
|
@ -802,34 +834,7 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
|
||||||
outFile->writeUint32BE(playTime);
|
outFile->writeUint32BE(playTime);
|
||||||
|
|
||||||
_display->saveThumbnail(*outFile);
|
_display->saveThumbnail(*outFile);
|
||||||
|
saveState(*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]);
|
|
||||||
|
|
||||||
outFile->finalize();
|
outFile->finalize();
|
||||||
|
|
||||||
if (outFile->err()) {
|
if (outFile->err()) {
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
class ReadStream;
|
class ReadStream;
|
||||||
|
class WriteStream;
|
||||||
class SeekableReadStream;
|
class SeekableReadStream;
|
||||||
class File;
|
class File;
|
||||||
struct Event;
|
struct Event;
|
||||||
|
@ -235,6 +236,8 @@ protected:
|
||||||
Common::Error loadGameState(int slot);
|
Common::Error loadGameState(int slot);
|
||||||
Common::Error saveGameState(int slot, const Common::String &desc);
|
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 readString(Common::ReadStream &stream, byte until = 0) const;
|
||||||
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, 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;
|
void openFile(Common::File &file, const Common::String &name) const;
|
||||||
|
|
|
@ -36,6 +36,98 @@ AdlEngine_v4::~AdlEngine_v4() {
|
||||||
delete _itemPicIndex;
|
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 AdlEngine_v4::loadMessage(uint idx) const {
|
||||||
Common::String str = AdlEngine_v3::loadMessage(idx);
|
Common::String str = AdlEngine_v3::loadMessage(idx);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,8 @@ protected:
|
||||||
AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd);
|
AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd);
|
||||||
|
|
||||||
// AdlEngine
|
// AdlEngine
|
||||||
|
virtual void loadState(Common::ReadStream &stream);
|
||||||
|
virtual void saveState(Common::WriteStream &stream);
|
||||||
virtual Common::String loadMessage(uint idx) const;
|
virtual Common::String loadMessage(uint idx) const;
|
||||||
virtual Common::String getItemDescription(const Item &item) const;
|
virtual Common::String getItemDescription(const Item &item) const;
|
||||||
virtual void switchRegion(byte region);
|
virtual void switchRegion(byte region);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue