diff options
author | Paul Gilbert | 2015-01-11 16:01:10 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-01-11 16:01:10 -0500 |
commit | edccbe63f24e26944dcd7cd3da59b6842cb36b46 (patch) | |
tree | 090430845d07b3ba3d55c4c8a6e42565c8f40f50 | |
parent | 3b1edcdf36fc7a207a70cb28e7dcf7879ea9b7e5 (diff) | |
download | scummvm-rg350-edccbe63f24e26944dcd7cd3da59b6842cb36b46.tar.gz scummvm-rg350-edccbe63f24e26944dcd7cd3da59b6842cb36b46.tar.bz2 scummvm-rg350-edccbe63f24e26944dcd7cd3da59b6842cb36b46.zip |
XEEN: Added saving of maze monster/object data
-rw-r--r-- | engines/xeen/files.h | 15 | ||||
-rw-r--r-- | engines/xeen/interface.cpp | 1 | ||||
-rw-r--r-- | engines/xeen/map.cpp | 201 | ||||
-rw-r--r-- | engines/xeen/map.h | 5 |
4 files changed, 147 insertions, 75 deletions
diff --git a/engines/xeen/files.h b/engines/xeen/files.h index 7c0817a850..a8343c1653 100644 --- a/engines/xeen/files.h +++ b/engines/xeen/files.h @@ -34,6 +34,19 @@ namespace Xeen { class XeenEngine; +#define SYNC_AS(SUFFIX,STREAM,TYPE,SIZE) \ + template<typename T> \ + void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \ + if (_version < minVersion || _version > maxVersion) \ + return; \ + if (_loadStream) \ + val = static_cast<TYPE>(_loadStream->read ## STREAM()); \ + else { \ + TYPE tmp = (TYPE)val; \ + _saveStream->write ## STREAM(tmp); \ + } \ + _bytesSynced += SIZE; \ + } /* * Main resource manager */ @@ -69,6 +82,8 @@ public: XeenSerializer(Common::SeekableReadStream *in, Common::WriteStream *out) : Common::Serializer(in, out), _in(in) {} + SYNC_AS(Sint8, Byte, int8, 1) + bool finished() const { return _in != nullptr && _in->pos() >= _in->size(); } }; diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index f952425d05..c2c907b898 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -883,7 +883,6 @@ void Interface::setIndoorsMonsters() { void Interface::setIndoorObjects() { Common::Point mazePos = _vm->_party._mazePosition; _objNumber = 0; - int objIndx = 0; const int8 *posOffset = &SCREEN_POSITIONING[_vm->_party._mazeDirection * 48]; Common::Point pt; diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp index d65e09d5d7..c70b0cfe6d 100644 --- a/engines/xeen/map.cpp +++ b/engines/xeen/map.cpp @@ -611,11 +611,11 @@ MobStruct::MobStruct() { _direction = DIR_NORTH; } -bool MobStruct::synchronize(Common::SeekableReadStream &s) { - _pos.x = (int8)s.readByte(); - _pos.y = (int8)s.readByte(); - _id = s.readByte(); - _direction = (Direction)s.readByte(); +bool MobStruct::synchronize(XeenSerializer &s) { + s.syncAsSint8(_pos.x); + s.syncAsSint8(_pos.y); + s.syncAsByte(_id); + s.syncAsByte(_direction); return _id != 0xff || _pos.x != -1 || _pos.y != -1; } @@ -658,85 +658,134 @@ MazeWallItem::MazeWallItem() { MonsterObjectData::MonsterObjectData(XeenEngine *vm): _vm(vm) { } -void MonsterObjectData::synchronize(Common::SeekableReadStream &s, - bool isOutdoors, MonsterData monsterData) { - _objectSprites.clear(); - _monsterSprites.clear(); - _monsterAttackSprites.clear(); - _wallItemSprites.clear(); - _objects.clear(); - _monsters.clear(); - _wallItems.clear(); - +void MonsterObjectData::synchronize(XeenSerializer &s, MonsterData monsterData) { Common::Array<MobStruct> mobStructs; + MobStruct mobStruct; byte b; - for (int i = 0; i < 16; ++i) { - if ((b = s.readByte()) != 0xff) + if (s.isLoading()) { + _objectSprites.clear(); + _monsterSprites.clear(); + _monsterAttackSprites.clear(); + _wallItemSprites.clear(); + _objects.clear(); + _monsters.clear(); + _wallItems.clear(); + } + + for (uint i = 0; i < 16; ++i) { + b = (i >= _objectSprites.size()) ? 0xff : _objectSprites[i]._spriteId; + s.syncAsByte(b); + if (b != 0xff) _objectSprites.push_back(SpriteResourceEntry(b)); } - for (int i = 0; i < 16; ++i) { - if ((b = s.readByte()) != 0xff) + for (uint i = 0; i < 16; ++i) { + b = (i >= _monsterSprites.size()) ? 0xff : _monsterSprites[i]._spriteId; + s.syncAsByte(b); + if (b != 0xff) _monsterSprites.push_back(SpriteResourceEntry(b)); } - for (int i = 0; i < 16; ++i) { - if ((b = s.readByte()) != 0xff) + for (uint i = 0; i < 16; ++i) { + b = (i >= _wallItemSprites.size()) ? 0xff : _wallItemSprites[i]._spriteId; + s.syncAsByte(b); + if (b != 0xff) _wallItemSprites.push_back(SpriteResourceEntry(b)); } - // Merge together object data - MobStruct mobStruct; - mobStruct.synchronize(s); - do { - MazeObject obj; - obj._position = mobStruct._pos; - obj._id = mobStruct._id; - obj._direction = mobStruct._direction; - obj._frame = 100; - obj._spriteId = _objectSprites[obj._id]._spriteId; - obj._sprites = &_objectSprites[obj._id]._sprites; - - _objects.push_back(obj); + if (s.isSaving()) { + // Save objects + for (uint i = 0; i < _objects.size(); ++i) { + mobStruct._pos = _objects[i]._position; + mobStruct._id = _objects[i]._id; + mobStruct._direction = _objects[i]._direction; + mobStruct.synchronize(s); + } + mobStruct._pos.x = mobStruct._pos.y = -1; + mobStruct._id = 0xff; mobStruct.synchronize(s); - } while (mobStruct._id != 255 || mobStruct._pos.x != -1); - - // Merge together monster data - mobStruct.synchronize(s); - do { - MazeMonster mon; - mon._position = mobStruct._pos; - mon._id = mobStruct._id; - mon._spriteId = _monsterSprites[mon._id]._spriteId; - mon._sprites = &_monsterSprites[mon._id]._sprites; - mon._attackSprites = &_monsterSprites[mon._id]._attackSprites; - - MonsterStruct &md = monsterData[mon._spriteId]; - mon._hp = md._hp; - mon._frame = _vm->getRandomNumber(7); - mon._effect1 = mon._effect2 = md._animationEffect; - if (md._animationEffect) - mon._effect3 = _vm->getRandomNumber(7); - - _monsters.push_back(mon); + + // Save monsters + for (uint i = 0; i < _monsters.size(); ++i) { + mobStruct._pos = _monsters[i]._position; + mobStruct._id = _monsters[i]._id; + mobStruct._direction = DIR_NORTH; + mobStruct.synchronize(s); + } + mobStruct._pos.x = mobStruct._pos.y = -1; + mobStruct._id = 0xff; mobStruct.synchronize(s); - } while (mobStruct._id != 255 || mobStruct._pos.x != -1); - - // Merge together wall item data - mobStruct.synchronize(s); - do { - if (mobStruct._id < (int)_wallItemSprites.size()) { - MazeWallItem wi; - wi._position = mobStruct._pos; - wi._id = mobStruct._id; - wi._direction = mobStruct._direction; - wi._spriteId = _wallItemSprites[wi._id]._spriteId; - wi._sprites = &_wallItemSprites[wi._id]._sprites; - - _wallItems.push_back(wi); + + // Save wall items + if (_wallItems.size() == 0) { + MobStruct nullStruct; + nullStruct.synchronize(s); + } else { + for (uint i = 0; i < _wallItems.size(); ++i) { + mobStruct._pos = _wallItems[i]._position; + mobStruct._id = _wallItems[i]._id; + mobStruct._direction = _wallItems[i]._direction; + mobStruct.synchronize(s); + } } + mobStruct._pos.x = mobStruct._pos.y = -1; + mobStruct._id = 0xff; + mobStruct.synchronize(s); + } else { + // Load monster/obbject data and merge together with sprite Ids + // Merge together object data + mobStruct.synchronize(s); + do { + MazeObject obj; + obj._position = mobStruct._pos; + obj._id = mobStruct._id; + obj._direction = mobStruct._direction; + obj._frame = 100; + obj._spriteId = _objectSprites[obj._id]._spriteId; + obj._sprites = &_objectSprites[obj._id]._sprites; + + _objects.push_back(obj); + mobStruct.synchronize(s); + } while (mobStruct._id != 255 || mobStruct._pos.x != -1); + + // Merge together monster data mobStruct.synchronize(s); - } while (mobStruct._id != 255 || mobStruct._pos.x != -1); + do { + MazeMonster mon; + mon._position = mobStruct._pos; + mon._id = mobStruct._id; + mon._spriteId = _monsterSprites[mon._id]._spriteId; + mon._sprites = &_monsterSprites[mon._id]._sprites; + mon._attackSprites = &_monsterSprites[mon._id]._attackSprites; + + MonsterStruct &md = monsterData[mon._spriteId]; + mon._hp = md._hp; + mon._frame = _vm->getRandomNumber(7); + mon._effect1 = mon._effect2 = md._animationEffect; + if (md._animationEffect) + mon._effect3 = _vm->getRandomNumber(7); + + _monsters.push_back(mon); + mobStruct.synchronize(s); + } while (mobStruct._id != 255 || mobStruct._pos.x != -1); + + // Merge together wall item data + mobStruct.synchronize(s); + do { + if (mobStruct._id < (int)_wallItemSprites.size()) { + MazeWallItem wi; + wi._position = mobStruct._pos; + wi._id = mobStruct._id; + wi._direction = mobStruct._direction; + wi._spriteId = _wallItemSprites[wi._id]._spriteId; + wi._sprites = &_wallItemSprites[wi._id]._sprites; + + _wallItems.push_back(wi); + } + + mobStruct.synchronize(s); + } while (mobStruct._id != 255 || mobStruct._pos.x != -1); + } } /*------------------------------------------------------------------------*/ @@ -888,7 +937,8 @@ void Map::load(int mapId) { Common::String mobName = Common::String::format("maze%c%03d.mob", (mapId >= 100) ? 'x' : '0', mapId); File mobFile(mobName); - _mobData.synchronize(mobFile, _isOutdoors, _monsterData); + XeenSerializer sMob(&mobFile, nullptr); + _mobData.synchronize(sMob, _monsterData); mobFile.close(); Common::String headName = Common::String::format("aaze%c%03d.hed", @@ -925,7 +975,8 @@ void Map::load(int mapId) { Common::String filename = Common::String::format("maze%c%03d.mob", (_vm->_party._mazeId >= 100) ? 'x' : '0', _vm->_party._mazeId); File mobFile(filename, *_vm->_saves); - _mobData.synchronize(mobFile, _isOutdoors, _monsterData); + XeenSerializer sMob(&mobFile, nullptr); + _mobData.synchronize(sMob, _monsterData); mobFile.close(); // Load sprites for the objects @@ -1068,6 +1119,14 @@ void Map::saveMaze() { XeenSerializer sEvents(nullptr, &fEvents); _events.synchronize(sEvents); fEvents.finalize(); + + // Save the maze MOB file + filename = Common::String::format("maze%c%03d.mob", + (mazeNum >= 100) ? 'x' : '0', mazeNum); + OutFile fMob(_vm, filename); + XeenSerializer sMob(nullptr, &fEvents); + _mobData.synchronize(sMob, _monsterData); + fEvents.finalize(); } void Map::cellFlagLookup(const Common::Point &pt) { diff --git a/engines/xeen/map.h b/engines/xeen/map.h index c23b214736..d26dffff82 100644 --- a/engines/xeen/map.h +++ b/engines/xeen/map.h @@ -228,7 +228,7 @@ public: public: MobStruct(); - bool synchronize(Common::SeekableReadStream &s); + bool synchronize(XeenSerializer &s); }; struct MazeObject { @@ -295,8 +295,7 @@ public: public: MonsterObjectData(XeenEngine *vm); - void synchronize(Common::SeekableReadStream &s, bool isOutdoors, - MonsterData monsterData); + void synchronize(XeenSerializer &s, MonsterData monsterData); }; class HeadData { |