FULLPIPE: Further work on saving

This commit is contained in:
Eugene Sandulenko 2016-09-18 00:02:11 +02:00
parent 973df9d2fd
commit 83a82a9842
7 changed files with 94 additions and 32 deletions

View File

@ -21,6 +21,7 @@
*/ */
#include "fullpipe/fullpipe.h" #include "fullpipe/fullpipe.h"
#include "common/memstream.h"
#include "graphics/thumbnail.h" #include "graphics/thumbnail.h"
#include "fullpipe/gameloader.h" #include "fullpipe/gameloader.h"
@ -634,8 +635,9 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
header.updateCounter = _updateCounter; header.updateCounter = _updateCounter;
header.unkField = 1; header.unkField = 1;
// open save for reading Common::MemoryWriteStreamDynamic stream;
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(fname);
MfcArchive *archive = new MfcArchive(&stream);
v = _gameVar->getSubVarByName("OBJSTATES"); v = _gameVar->getSubVarByName("OBJSTATES");
@ -649,9 +651,10 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
v->_parentVarObj = 0; v->_parentVarObj = 0;
v->_nextVarObj = 0; v->_nextVarObj = 0;
v->_prevVarObj = 0; v->_prevVarObj = 0;
warning("NULLIFIED");
} }
writeObject(saveFile, v); archive->writeObject(v);
if (v) { if (v) {
v->_parentVarObj = par; v->_parentVarObj = par;
@ -659,15 +662,15 @@ void GameLoader::writeSavegame(Scene *sc, const char *fname) {
v->_prevVarObj = prv; 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++) { 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++) { 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) //if (_savegameCallback)
// _savegameCallback(saveFile, 1); // _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(); saveFile->finalize();
delete saveFile; delete saveFile;

View File

@ -106,12 +106,12 @@ bool Inventory2::loadPartial(MfcArchive &file) { // Inventory2_SerializePartiall
return true; return true;
} }
bool Inventory2::savePartial(Common::WriteStream *saveFile) { bool Inventory2::savePartial(MfcArchive &file) {
saveFile->writeUint32LE(_inventoryItems.size()); file.writeUint32LE(_inventoryItems.size());
for (uint i = 0; i < _inventoryItems.size(); i++) { for (uint i = 0; i < _inventoryItems.size(); i++) {
saveFile->writeUint16LE(_inventoryItems[i]->itemId); file.writeUint16LE(_inventoryItems[i]->itemId);
saveFile->writeUint16LE(_inventoryItems[i]->count); file.writeUint16LE(_inventoryItems[i]->count);
} }
return true; return true;

View File

@ -101,7 +101,7 @@ class Inventory2 : public Inventory {
virtual ~Inventory2(); virtual ~Inventory2();
bool loadPartial(MfcArchive &file); bool loadPartial(MfcArchive &file);
bool savePartial(Common::WriteStream *file); bool savePartial(MfcArchive &file);
void addItem(int itemId, int count); void addItem(int itemId, int count);
void addItem2(StaticANIObject *obj); void addItem2(StaticANIObject *obj);
void removeItem(int itemId, int count); void removeItem(int itemId, int count);

View File

@ -61,7 +61,7 @@ struct PicAniInfo {
int32 someDynamicPhaseIndex; int32 someDynamicPhaseIndex;
bool load(MfcArchive &file); bool load(MfcArchive &file);
bool save(Common::WriteStream *file); void save(MfcArchive &file);
PicAniInfo() { memset(this, 0, sizeof(PicAniInfo)); } PicAniInfo() { memset(this, 0, sizeof(PicAniInfo)); }
}; };
@ -88,6 +88,7 @@ class GameVar : public CObject {
virtual ~GameVar(); virtual ~GameVar();
virtual bool load(MfcArchive &file); virtual bool load(MfcArchive &file);
virtual void save(MfcArchive &file);
GameVar *getSubVarByName(const char *name); GameVar *getSubVarByName(const char *name);
bool setSubVarAsInt(const char *name, int value); bool setSubVarAsInt(const char *name, int value);
int getSubVarAsInt(const char *name); int getSubVarAsInt(const char *name);

View File

@ -26,26 +26,55 @@
namespace Fullpipe { namespace Fullpipe {
bool PicAniInfo::save(Common::WriteStream *file) { void PicAniInfo::save(MfcArchive &file) {
debugC(5, kDebugLoading, "PicAniInfo::save()"); debugC(5, kDebugLoading, "PicAniInfo::save()");
file->writeUint32LE(type); file.writeUint32LE(type);
file->writeUint16LE(objectId); file.writeUint16LE(objectId);
file->writeUint16LE(field_6); file.writeUint16LE(field_6);
file->writeUint32LE(field_8); file.writeUint32LE(field_8);
file->writeUint16LE(sceneId); file.writeUint16LE(sceneId);
file->writeUint16LE(field_E); file.writeUint16LE(field_E);
file->writeSint32LE(ox); file.writeSint32LE(ox);
file->writeSint32LE(oy); file.writeSint32LE(oy);
file->writeUint32LE(priority); file.writeUint32LE(priority);
file->writeUint16LE(staticsId); file.writeUint16LE(staticsId);
file->writeUint16LE(movementId); file.writeUint16LE(movementId);
file->writeUint16LE(dynamicPhaseIndex); file.writeUint16LE(dynamicPhaseIndex);
file->writeUint16LE(flags); file.writeUint16LE(flags);
file->writeUint32LE(field_24); file.writeUint32LE(field_24);
file->writeUint32LE(someDynamicPhaseIndex); file.writeUint32LE(someDynamicPhaseIndex);
}
return true; 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 } // End of namespace Fullpipe

View File

@ -109,6 +109,17 @@ char *MfcArchive::readPascalString(bool twoByte) {
return tmp; 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() { MemoryObject::MemoryObject() {
_memfilename = 0; _memfilename = 0;
_mfield_8 = 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); 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(); int schema = readUint16LE();
debugC(7, kDebugLoading, "parseClass::schema = %d", schema); debugC(7, kDebugLoading, "parseClass::schema = %d", schema);
@ -446,6 +459,13 @@ CObject *MfcArchive::parseClass(bool *isCopyReturned) {
return res; 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 *genFileName(int superId, int sceneId, const char *ext) {
char *s = (char *)calloc(256, 1); char *s = (char *)calloc(256, 1);

View File

@ -34,7 +34,7 @@ class NGIArchive;
typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ClassMap; typedef Common::HashMap<Common::String, int, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ClassMap;
class MfcArchive : public Common::SeekableReadStream, Common::WriteStream { class MfcArchive : public Common::SeekableReadStream, public Common::WriteStream {
ClassMap _classMap; ClassMap _classMap;
Common::Array<CObject *> _objectMap; Common::Array<CObject *> _objectMap;
Common::Array<int> _objectIdMap; Common::Array<int> _objectIdMap;
@ -50,11 +50,14 @@ public:
MfcArchive(Common::WriteStream *file); MfcArchive(Common::WriteStream *file);
char *readPascalString(bool twoByte = false); char *readPascalString(bool twoByte = false);
void writePascalString(char *str, bool twoByte = false);
int readCount(); int readCount();
double readDouble(); double readDouble();
CObject *parseClass(bool *isCopyReturned); CObject *parseClass(bool *isCopyReturned);
CObject *readClass(); CObject *readClass();
void writeObject(CObject *obj);
void incLevel() { _level++; } void incLevel() { _level++; }
void decLevel() { _level--; } void decLevel() { _level--; }
int getLevel() { return _level; } int getLevel() { return _level; }
@ -91,6 +94,7 @@ public:
CObject() : _objtype(kObjTypeDefault) {} CObject() : _objtype(kObjTypeDefault) {}
virtual bool load(MfcArchive &in) { return true; } virtual bool load(MfcArchive &in) { return true; }
virtual void save(MfcArchive &out) { error("Not implemented for obj type: %d", _objtype); }
virtual ~CObject() {} virtual ~CObject() {}
bool loadFile(const char *fname); bool loadFile(const char *fname);