diff options
author | uruk | 2014-07-03 01:19:30 +0200 |
---|---|---|
committer | uruk | 2014-07-04 13:01:28 +0200 |
commit | f155546ecb03e0a308cdb6b2308ab01c992e71ce (patch) | |
tree | 304d6669cafb68a31bc90f36a59d5b78948b2c1f /engines/cge2 | |
parent | aeaac02332a8faa32a7f6c534309b71432dd3a2b (diff) | |
download | scummvm-rg350-f155546ecb03e0a308cdb6b2308ab01c992e71ce.tar.gz scummvm-rg350-f155546ecb03e0a308cdb6b2308ab01c992e71ce.tar.bz2 scummvm-rg350-f155546ecb03e0a308cdb6b2308ab01c992e71ce.zip |
CGE2: Partially working save/load system.
There's a mayor bug which blocks the toolbar from interaction after loading. To be investigated during the upcoming days.
Diffstat (limited to 'engines/cge2')
-rw-r--r-- | engines/cge2/cge2.h | 2 | ||||
-rw-r--r-- | engines/cge2/cge2_main.cpp | 3 | ||||
-rw-r--r-- | engines/cge2/saveload.cpp | 110 | ||||
-rw-r--r-- | engines/cge2/spare.cpp | 25 | ||||
-rw-r--r-- | engines/cge2/spare.h | 2 | ||||
-rw-r--r-- | engines/cge2/vga13h.cpp | 28 | ||||
-rw-r--r-- | engines/cge2/vga13h.h | 3 |
7 files changed, 131 insertions, 42 deletions
diff --git a/engines/cge2/cge2.h b/engines/cge2/cge2.h index af16311ab2..aade31f2b8 100644 --- a/engines/cge2/cge2.h +++ b/engines/cge2/cge2.h @@ -131,6 +131,8 @@ private: void writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header); void syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream); void syncHeader(Common::Serializer &s); + bool loadGame(int slotNumber); + void resetGame(); public: CGE2Engine(OSystem *syst, const ADGameDescription *gameDescription); virtual bool hasFeature(EngineFeature f) const; diff --git a/engines/cge2/cge2_main.cpp b/engines/cge2/cge2_main.cpp index 5a4b2c1443..071340508c 100644 --- a/engines/cge2/cge2_main.cpp +++ b/engines/cge2/cge2_main.cpp @@ -729,6 +729,7 @@ void CGE2Engine::loadUser() { // Missing loading from file. TODO: Implement it with the saving/loading! loadScript("CGE.INI"); loadHeroes(); + loadPos(); } void CGE2Engine::loadHeroes() { // Original name: loadGame() @@ -771,8 +772,6 @@ void CGE2Engine::loadHeroes() { // Original name: loadGame() //--- start! switchHero(_sex); - - loadPos(); } void CGE2Engine::loadPos() { diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp index 971b044e35..8d0237e702 100644 --- a/engines/cge2/saveload.cpp +++ b/engines/cge2/saveload.cpp @@ -37,6 +37,7 @@ #include "cge2/snail.h" #include "cge2/hero.h" #include "cge2/text.h" +#include "cge2/sound.h" namespace CGE2 { @@ -195,7 +196,10 @@ Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) { writeSavegameHeader(saveFile, header); // Write out the data of the savegame - syncGame(NULL, saveFile); + saveHeroPos(); + sceneDown(); + syncGame(nullptr, saveFile); + sceneUp(_now); // Finish writing out game data saveFile->finalize(); @@ -249,13 +253,11 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS // Synchronise header data syncHeader(s); - if (s.isSaving()) { - for (int i = 0; i < kSceneMax; i++) - _eyeTab[i]->sync(s); - - _spare->sync(s); + // Synchronise _spare and mingled with it, the sprites of the heroes' + _spare->sync(s, _heroTab); - // The references of the items in the heroes pockets: + if (s.isSaving()) { + // Save the references of the items in the heroes pockets: for (int i = 0; i < 2; i++) { for (int j = 0; j < kPocketMax; j++) { Sprite *spr = _heroTab[i]->_pocket[j]; @@ -263,11 +265,23 @@ void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteS s.syncAsSint16LE(ref); } } - - for (int i = 0; i < kMaxPoint; i++) - _point[i]->sync(s); } else { - // Loading game + // Load items to the pockets + for (int i = 0; i < 2; i++) { + for (int j = 0; j < kPocketMax; j++) { + int ref = 0; + s.syncAsSint16LE(ref); + _heroTab[i]->_pocket[j] = _spare->locate(ref); + } + } + } + + // Heroes' _posTabs + for (int i = 0; i < 2; i++) { + for (int j = 0; j < kSceneMax; j++) { + s.syncAsSint16LE(_heroTab[i]->_posTab[j]->x); + s.syncAsSint16LE(_heroTab[i]->_posTab[j]->y); + } } } @@ -282,11 +296,6 @@ void CGE2Engine::syncHeader(Common::Serializer &s) { for (int i = 0; i < 4; i++) s.syncAsUint16LE(_flag[i]); - if (s.isLoading()) { - // Reset scene values - //initSceneValues(); - } - if (s.isSaving()) { // Write checksum int checksum = kSavegameCheckSum; @@ -301,8 +310,75 @@ void CGE2Engine::syncHeader(Common::Serializer &s) { } Common::Error CGE2Engine::loadGameState(int slot) { - warning("STUB: CGE2Engine::loadGameState()"); + // Clear current game activity + sceneDown(); + resetGame(); + // If music is playing, kill it. + if (_music) + _midiPlayer->killMidi(); + + if (!loadGame(slot)) + return Common::kReadingFailed; + + loadHeroes(); + + sceneUp(_now); + + _busyPtr = _vga->_showQ->locate(kBusyRef); + + _vol[0] = _vga->_showQ->locate(kDvolRef); + _vol[1] = _vga->_showQ->locate(kMvolRef); + return Common::kNoError; } +void CGE2Engine::resetGame() { + _busyPtr = nullptr; + busy(false); + _spare->clear(); + _vga->_showQ->clear(); + _commandHandler->reset(); +} + +bool CGE2Engine::loadGame(int slotNumber) { + Common::MemoryReadStream *readStream; + + // Open up the savegame file + Common::String slotName = generateSaveName(slotNumber); + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(slotName); + + // Read the data into a data buffer + int size = saveFile->size(); + byte *dataBuffer = (byte *)malloc(size); + saveFile->read(dataBuffer, size); + readStream = new Common::MemoryReadStream(dataBuffer, size, DisposeAfterUse::YES); + delete saveFile; + + // Check to see if it's a ScummVM savegame or not + char buffer[kSavegameStrSize + 1]; + readStream->read(buffer, kSavegameStrSize + 1); + + if (strncmp(buffer, kSavegameStr, kSavegameStrSize + 1) != 0) { + delete readStream; + return false; + } else { + SavegameHeader saveHeader; + + if (!readSavegameHeader(readStream, saveHeader)) { + delete readStream; + return false; + } + + // Delete the thumbnail + saveHeader.thumbnail->free(); + delete saveHeader.thumbnail; + } + + // Get in the savegame + syncGame(readStream, nullptr); + + delete readStream; + return true; +} + } // End of namespace CGE2 diff --git a/engines/cge2/spare.cpp b/engines/cge2/spare.cpp index 5db4772fc7..4bc4a5f9d8 100644 --- a/engines/cge2/spare.cpp +++ b/engines/cge2/spare.cpp @@ -29,13 +29,30 @@ namespace CGE2 { -void Spare::sync(Common::Serializer &s) { - for (uint i = 0; i < _container.size(); i++) - _container[i]->sync(s); +void Spare::sync(Common::Serializer &s, HeroTab *heroTab[2]) { + if (s.isSaving()) { + int size = 0; + for (uint i = 0; i < _container.size(); i++) + if (_container[i]->_ref >= 141) + size++; + s.syncAsSint16LE(size); + + for (uint i = 0; i < _container.size(); i++) + if (_container[i]->_ref >= 141) + _container[i]->sync(s); + } else { + int size; + s.syncAsSint16LE(size); + + for (int i = 0; i < size; i++) { + Sprite *sprite = new Sprite(_vm); + sprite->sync(s); + store(sprite); + } + } } void Spare::clear() { - for (int i = 0; i < _container.size(); i++) for (uint i = 0; i < _container.size(); i++) delete _container[i]; diff --git a/engines/cge2/spare.h b/engines/cge2/spare.h index 7dc6ce60f5..d34ca4855e 100644 --- a/engines/cge2/spare.h +++ b/engines/cge2/spare.h @@ -46,7 +46,7 @@ public: void dispose(Sprite *spr); void dispose(int ref); void dispose(); - void sync(Common::Serializer &s); + void sync(Common::Serializer &s, HeroTab *heroTab[2]); uint16 count() { return _container.size(); } void clear(); }; diff --git a/engines/cge2/vga13h.cpp b/engines/cge2/vga13h.cpp index 3ce690ed6a..f40c84ebfc 100644 --- a/engines/cge2/vga13h.cpp +++ b/engines/cge2/vga13h.cpp @@ -40,22 +40,14 @@ namespace CGE2 { void V3D::sync(Common::Serializer &s) { - int pos = 0; - if (s.isLoading()) { - s.syncAsSint16LE(pos); - _x = FXP(pos); - s.syncAsSint16LE(pos); - _y = FXP(pos); - s.syncAsSint16LE(pos); - _z = FXP(pos); - } else { - pos = _x.trunc(); - s.syncAsUint16LE(pos); - pos = _y.trunc(); - s.syncAsUint16LE(pos); - pos = _z.trunc(); - s.syncAsByte(pos); - } + _x.sync(s); + _y.sync(s); + _z.sync(s); +} + +void FXP::sync(Common::Serializer &s) { + s.syncAsUint16LE(f); + s.syncAsSint16LE(i); } Seq *getConstantSeq(bool seqFlag) { @@ -748,8 +740,8 @@ void Sprite::sync(Common::Serializer &s) { s.syncAsUint16LE(_time); for (int i = 0; i < kActions; i++){ - s.syncAsSint16LE(_actionCtrl->_ptr); - s.syncAsSint16LE(_actionCtrl->_cnt); + s.syncAsByte(_actionCtrl[i]._ptr); + s.syncAsByte(_actionCtrl[i]._cnt); } s.syncAsSint16LE(_seqPtr); s.syncAsSint16LE(_seqCnt); diff --git a/engines/cge2/vga13h.h b/engines/cge2/vga13h.h index ce914ce2c8..7dd7933302 100644 --- a/engines/cge2/vga13h.h +++ b/engines/cge2/vga13h.h @@ -115,6 +115,7 @@ public: int trunc(void) const { return i; } int round(void) const { return i + (f > 0x7FFF); } bool empty() const { return i == 0 && f == 0; } + void sync(Common::Serializer &s); }; // From CGETYPE.H: @@ -274,6 +275,7 @@ public: virtual void tick(); virtual void setScene(int c); void clrHide() { if (_ext) _ext->_b0 = NULL; } + void sync(Common::Serializer &s); static void (*notify) (); @@ -297,6 +299,7 @@ public: } Sprite *locate(int ref); bool locate(Sprite *spr); + void clear() { _head = _tail = nullptr; } }; class Vga { |