From 83a82a98420423f2aa27b7e7eedce13b03ec34b2 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Sun, 18 Sep 2016 00:02:11 +0200 Subject: FULLPIPE: Further work on saving --- engines/fullpipe/gameloader.cpp | 22 +++++++++----- engines/fullpipe/inventory.cpp | 8 ++--- engines/fullpipe/inventory.h | 2 +- engines/fullpipe/objects.h | 3 +- engines/fullpipe/statesaver.cpp | 65 +++++++++++++++++++++++++++++------------ engines/fullpipe/utils.cpp | 22 +++++++++++++- engines/fullpipe/utils.h | 6 +++- 7 files changed, 95 insertions(+), 33 deletions(-) (limited to 'engines/fullpipe') diff --git a/engines/fullpipe/gameloader.cpp b/engines/fullpipe/gameloader.cpp index 83da25dbf3..5d204bf0cd 100644 --- a/engines/fullpipe/gameloader.cpp +++ b/engines/fullpipe/gameloader.cpp @@ -21,6 +21,7 @@ */ #include "fullpipe/fullpipe.h" +#include "common/memstream.h" #include "graphics/thumbnail.h" #include "fullpipe/gameloader.h" @@ -634,8 +635,9 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) { header.updateCounter = _updateCounter; header.unkField = 1; - // open save for reading - Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname); + Common::MemoryWriteStreamDynamic stream; + + MfcArchive *archive = new MfcArchive(&stream); v = _gameVar->getSubVarByName("OBJSTATES"); @@ -649,9 +651,10 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) { v->_parentVarObj = 0; v->_nextVarObj = 0; v->_prevVarObj = 0; + warning("NULLIFIED"); } - writeObject(saveFile, v); + archive->writeObject(v); if (v) { v->_parentVarObj = par; @@ -659,15 +662,15 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) { v->_prevVarObj = prv; } - getGameLoaderInventory()->savePartial(saveFile); + getGameLoaderInventory()->savePartial(*archive); - saveFile->writeUint32LE(_sc2array.size()); + archive->writeUint32LE(_sc2array.size()); for (uint i = 0; i < _sc2array.size(); i++) { - saveFile->writeUint32LE(_sc2array[i]._picAniInfosCount); + archive->writeUint32LE(_sc2array[i]._picAniInfosCount); for (uint j = 0; j < _sc2array[i]._picAniInfosCount; j++) { - _sc2array[i]._picAniInfos[j]->save(saveFile); + _sc2array[i]._picAniInfos[j]->save(*archive); } } @@ -677,6 +680,11 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) { //if (_savegameCallback) // _savegameCallback(saveFile, 1); + // Now dump it into save file + Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname); + + saveFile->write(stream.getData(), stream.size()); + saveFile->finalize(); delete saveFile; diff --git a/engines/fullpipe/inventory.cpp b/engines/fullpipe/inventory.cpp index 335635c6e8..8424e7e976 100644 --- a/engines/fullpipe/inventory.cpp +++ b/engines/fullpipe/inventory.cpp @@ -106,12 +106,12 @@ bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartiall return true; } -bool Inventory2::savePartial(Common::WriteStream *saveFile) { - saveFile->writeUint32LE(_inventoryItems.size()); +bool Inventory2::savePartial(MfcArchive &file) { + file.writeUint32LE(_inventoryItems.size()); for (uint i = 0; i < _inventoryItems.size(); i++) { - saveFile->writeUint16LE(_inventoryItems[i]->itemId); - saveFile->writeUint16LE(_inventoryItems[i]->count); + file.writeUint16LE(_inventoryItems[i]->itemId); + file.writeUint16LE(_inventoryItems[i]->count); } return true; diff --git a/engines/fullpipe/inventory.h b/engines/fullpipe/inventory.h index e619f7d0e1..9f9b9961c6 100644 --- a/engines/fullpipe/inventory.h +++ b/engines/fullpipe/inventory.h @@ -101,7 +101,7 @@ class Inventory2 : public Inventory { virtual ~Inventory2(); bool loadPartial(MfcArchive &file); - bool savePartial(Common::WriteStream *file); + bool savePartial(MfcArchive &file); void addItem(int itemId, int count); void addItem2(StaticANIObject *obj); void removeItem(int itemId, int count); diff --git a/engines/fullpipe/objects.h b/engines/fullpipe/objects.h index a138fe811a..9f0ccf18de 100644 --- a/engines/fullpipe/objects.h +++ b/engines/fullpipe/objects.h @@ -61,7 +61,7 @@ struct PicAniInfo { int32 someDynamicPhaseIndex; bool load(MfcArchive &file); - bool save(Common::WriteStream *file); + void save(MfcArchive &file); PicAniInfo() { memset(this, 0, sizeof(PicAniInfo)); } }; @@ -88,6 +88,7 @@ class GameVar : public CObject { virtual ~GameVar(); virtual bool load(MfcArchive &file); + virtual void save(MfcArchive &file); GameVar *getSubVarByName(const char *name); bool setSubVarAsInt(const char *name, int value); int getSubVarAsInt(const char *name); diff --git a/engines/fullpipe/statesaver.cpp b/engines/fullpipe/statesaver.cpp index 8ffdc1513d..a889707474 100644 --- a/engines/fullpipe/statesaver.cpp +++ b/engines/fullpipe/statesaver.cpp @@ -26,26 +26,55 @@ namespace Fullpipe { -bool PicAniInfo::save(Common::WriteStream *file) { +void PicAniInfo::save(MfcArchive &file) { debugC(5, kDebugLoading, "PicAniInfo::save()"); - file->writeUint32LE(type); - file->writeUint16LE(objectId); - file->writeUint16LE(field_6); - file->writeUint32LE(field_8); - file->writeUint16LE(sceneId); - file->writeUint16LE(field_E); - file->writeSint32LE(ox); - file->writeSint32LE(oy); - file->writeUint32LE(priority); - file->writeUint16LE(staticsId); - file->writeUint16LE(movementId); - file->writeUint16LE(dynamicPhaseIndex); - file->writeUint16LE(flags); - file->writeUint32LE(field_24); - file->writeUint32LE(someDynamicPhaseIndex); - - return true; + file.writeUint32LE(type); + file.writeUint16LE(objectId); + file.writeUint16LE(field_6); + file.writeUint32LE(field_8); + file.writeUint16LE(sceneId); + file.writeUint16LE(field_E); + file.writeSint32LE(ox); + file.writeSint32LE(oy); + file.writeUint32LE(priority); + file.writeUint16LE(staticsId); + file.writeUint16LE(movementId); + file.writeUint16LE(dynamicPhaseIndex); + file.writeUint16LE(flags); + file.writeUint32LE(field_24); + file.writeUint32LE(someDynamicPhaseIndex); +} + +void GameVar::save(MfcArchive &file) { + warning("Saving: %s", transCyrillic((byte *)_varName)); + file.writePascalString(_varName); + file.writeUint32LE(_varType); + + switch (_varType) { + case 0: + file.writeUint32LE(_value.intValue); + break; + case 1: + file.writeUint32LE(_value.intValue); // FIXME + break; + case 2: + file.writePascalString(_value.stringValue); + break; + default: + error("Unknown var type: %d (0x%x)", _varType, _varType); + } + + warning("Saving: %s, _parent", transCyrillic((byte *)_varName)); + file.writeObject(_parentVarObj); + warning("Saving: %s, _prev", transCyrillic((byte *)_varName)); + file.writeObject(_prevVarObj); + warning("Saving: %s, _next", transCyrillic((byte *)_varName)); + file.writeObject(_nextVarObj); + warning("Saving: %s, _field", transCyrillic((byte *)_varName)); + file.writeObject(_field_14); + warning("Saving: %s, _subs", transCyrillic((byte *)_varName)); + file.writeObject(_subVars); } } // End of namespace Fullpipe diff --git a/engines/fullpipe/utils.cpp b/engines/fullpipe/utils.cpp index 32503764d3..fff2dad15b 100644 --- a/engines/fullpipe/utils.cpp +++ b/engines/fullpipe/utils.cpp @@ -109,6 +109,17 @@ char *MfcArchive::readPascalString(bool twoByte) { return tmp; } +void MfcArchive::writePascalString(char *str, bool twoByte) { + int len = strlen(str); + + if (twoByte) + writeUint16LE(len); + else + writeByte(len); + + write(str, len); +} + MemoryObject::MemoryObject() { _memfilename = 0; _mfield_8 = 0; @@ -391,7 +402,9 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { debugC(7, kDebugLoading, "parseClass::obTag = %d (%04x) at 0x%08x", obTag, obTag, pos() - 2); - if (obTag == 0xffff) { + if (obTag == 0x0000) { + return NULL; + } else if (obTag == 0xffff) { int schema = readUint16LE(); debugC(7, kDebugLoading, "parseClass::schema = %d", schema); @@ -446,6 +459,13 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) { return res; } +void MfcArchive::writeObject(CObject *obj) { + if (obj == NULL) + writeUint16LE(0); + else + obj->save(*this); +} + char *genFileName(int superId, int sceneId, const char *ext) { char *s = (char *)calloc(256, 1); diff --git a/engines/fullpipe/utils.h b/engines/fullpipe/utils.h index 3741b4ae0e..5de919d383 100644 --- a/engines/fullpipe/utils.h +++ b/engines/fullpipe/utils.h @@ -34,7 +34,7 @@ class NGIArchive; typedef Common::HashMap ClassMap; -class MfcArchive : public Common::SeekableReadStream, Common::WriteStream { +class MfcArchive : public Common::SeekableReadStream, public Common::WriteStream { ClassMap _classMap; Common::Array _objectMap; Common::Array _objectIdMap; @@ -50,11 +50,14 @@ public: MfcArchive(Common::WriteStream *file); char *readPascalString(bool twoByte = false); + void writePascalString(char *str, bool twoByte = false); int readCount(); double readDouble(); CObject *parseClass(bool *isCopyReturned); CObject *readClass(); + void writeObject(CObject *obj); + void incLevel() { _level++; } void decLevel() { _level--; } int getLevel() { return _level; } @@ -91,6 +94,7 @@ public: CObject() : _objtype(kObjTypeDefault) {} virtual bool load(MfcArchive &in) { return true; } + virtual void save(MfcArchive &out) { error("Not implemented for obj type: %d", _objtype); } virtual ~CObject() {} bool loadFile(const char *fname); -- cgit v1.2.3