aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authoruruk2014-07-03 01:19:30 +0200
committeruruk2014-07-04 13:01:28 +0200
commitf155546ecb03e0a308cdb6b2308ab01c992e71ce (patch)
tree304d6669cafb68a31bc90f36a59d5b78948b2c1f /engines
parentaeaac02332a8faa32a7f6c534309b71432dd3a2b (diff)
downloadscummvm-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')
-rw-r--r--engines/cge2/cge2.h2
-rw-r--r--engines/cge2/cge2_main.cpp3
-rw-r--r--engines/cge2/saveload.cpp110
-rw-r--r--engines/cge2/spare.cpp25
-rw-r--r--engines/cge2/spare.h2
-rw-r--r--engines/cge2/vga13h.cpp28
-rw-r--r--engines/cge2/vga13h.h3
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 {