aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-11 14:21:57 -0500
committerPaul Gilbert2015-01-11 14:21:57 -0500
commit3b1edcdf36fc7a207a70cb28e7dcf7879ea9b7e5 (patch)
tree8eabf36d7aeaa2fd790c3f1aa3125b348e708a41
parent0b5f79afb7dbf0d2bcf3cb14747f93f348b1aaa5 (diff)
downloadscummvm-rg350-3b1edcdf36fc7a207a70cb28e7dcf7879ea9b7e5.tar.gz
scummvm-rg350-3b1edcdf36fc7a207a70cb28e7dcf7879ea9b7e5.tar.bz2
scummvm-rg350-3b1edcdf36fc7a207a70cb28e7dcf7879ea9b7e5.zip
XEEN: Implemented code for 'saving' resources to the loaded savefile
-rw-r--r--engines/xeen/files.cpp2
-rw-r--r--engines/xeen/files.h15
-rw-r--r--engines/xeen/map.cpp21
-rw-r--r--engines/xeen/map.h2
-rw-r--r--engines/xeen/saves.cpp25
-rw-r--r--engines/xeen/saves.h16
-rw-r--r--engines/xeen/scripts.cpp40
-rw-r--r--engines/xeen/scripts.h7
8 files changed, 103 insertions, 25 deletions
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index 79387f2e24..8ab1f35fcb 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -32,7 +32,7 @@ namespace Xeen {
/**
* Hash a given filename to produce the Id that represents it
*/
-uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) const {
+uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) {
if (resourceName.empty())
return 0xffff;
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index 343aea1e74..7c0817a850 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "common/file.h"
+#include "common/serializer.h"
#include "graphics/surface.h"
#include "xeen/xsurface.h"
@@ -61,6 +62,16 @@ public:
void openFile(const Common::String &filename, Common::Archive &archive);
};
+class XeenSerializer : public Common::Serializer {
+private:
+ Common::SeekableReadStream *_in;
+public:
+ XeenSerializer(Common::SeekableReadStream *in, Common::WriteStream *out) :
+ Common::Serializer(in, out), _in(in) {}
+
+ bool finished() const { return _in != nullptr && _in->pos() >= _in->size(); }
+};
+
/**
* Details of a single entry in a CC file index
*/
@@ -79,8 +90,6 @@ struct CCEntry {
* Base Xeen CC file implementation
*/
class BaseCCArchive : public Common::Archive {
-private:
- uint16 convertNameToId(const Common::String &resourceName) const;
protected:
Common::Array<CCEntry> _index;
@@ -88,6 +97,8 @@ protected:
virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
public:
+ static uint16 convertNameToId(const Common::String &resourceName);
+public:
BaseCCArchive() {}
// Archive implementation
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index d07ca2d363..d65e09d5d7 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -1042,8 +1042,9 @@ void Map::loadEvents(int mapId) {
// Load events
Common::String filename = Common::String::format("maze%c%03d.evt",
(mapId >= 100) ? 'x' : '0', mapId);
- File fEvents(filename);
- _events.synchronize(fEvents);
+ File fEvents(filename, *_vm->_saves);
+ XeenSerializer sEvents(&fEvents, nullptr);
+ _events.synchronize(sEvents);
fEvents.close();
// Load text data
@@ -1052,11 +1053,23 @@ void Map::loadEvents(int mapId) {
File fText(filename);
_events._text.resize(fText.size());
fText.read(&_events._text[0], fText.size());
-
- _events.synchronize(fText);
fText.close();
}
+void Map::saveMaze() {
+ int mazeNum = _mazeData[0]._mazeNumber;
+ if (!mazeNum || (mazeNum == 85 && !_vm->_files->_isDarkCc))
+ return;
+
+ // Save the event data
+ Common::String filename = Common::String::format("maze%c%03d.evt",
+ (mazeNum >= 100) ? 'x' : '0', mazeNum);
+ OutFile fEvents(_vm, filename);
+ XeenSerializer sEvents(nullptr, &fEvents);
+ _events.synchronize(sEvents);
+ fEvents.finalize();
+}
+
void Map::cellFlagLookup(const Common::Point &pt) {
Common::Point pos = pt;
int mapId = _vm->_party._mazeId;
diff --git a/engines/xeen/map.h b/engines/xeen/map.h
index bc1b0245b9..c23b214736 100644
--- a/engines/xeen/map.h
+++ b/engines/xeen/map.h
@@ -350,6 +350,8 @@ public:
int mazeLookup(const Common::Point &pt, int directionLayerIndex);
void setCellSurfaceFlags(const Common::Point &pt, int bits);
+
+ void saveMaze();
};
} // End of namespace Xeen
diff --git a/engines/xeen/saves.cpp b/engines/xeen/saves.cpp
index e6bfa80e09..c2b15106eb 100644
--- a/engines/xeen/saves.cpp
+++ b/engines/xeen/saves.cpp
@@ -29,6 +29,22 @@
namespace Xeen {
+OutFile::OutFile(XeenEngine *vm, const Common::String filename) :
+ _vm(vm), _filename(filename) {
+}
+
+void OutFile::finalize() {
+ uint16 id = BaseCCArchive::convertNameToId(_filename);
+
+ if (!_vm->_saves->_newData.contains(id))
+ _vm->_saves->_newData[id] = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
+
+ Common::MemoryWriteStreamDynamic &out = _vm->_saves->_newData[id];
+ out.write(getData(), size());
+}
+
+/*------------------------------------------------------------------------*/
+
SavesManager::SavesManager(XeenEngine *vm, Party &party, Roster &roster) :
BaseCCArchive(), _vm(vm), _party(party), _roster(roster) {
SearchMan.add("saves", this, 0, false);
@@ -67,6 +83,15 @@ void SavesManager::syncBitFlags(Common::Serializer &s, bool *startP, bool *endP)
Common::SeekableReadStream *SavesManager::createReadStreamForMember(const Common::String &name) const {
CCEntry ccEntry;
+ // If the given resource has already been perviously "written" to the
+ // save manager, then return that new resource
+ uint16 id = BaseCCArchive::convertNameToId(name);
+ if (_newData.contains(id)) {
+ Common::MemoryWriteStreamDynamic stream = _newData[id];
+ return new Common::MemoryReadStream(stream.getData(), stream.size());
+ }
+
+ // Retrieve the resource from the loaded savefile
if (getHeaderEntry(name, ccEntry)) {
// Open the correct CC entry
return new Common::MemoryReadStream(_data + ccEntry._offset, ccEntry._size);
diff --git a/engines/xeen/saves.h b/engines/xeen/saves.h
index ed4b80b29d..6b73625c61 100644
--- a/engines/xeen/saves.h
+++ b/engines/xeen/saves.h
@@ -24,6 +24,7 @@
#define XEEN_SAVES_H
#include "common/scummsys.h"
+#include "common/memstream.h"
#include "common/savefile.h"
#include "graphics/surface.h"
#include "xeen/party.h"
@@ -40,12 +41,27 @@ struct XeenSavegameHeader {
int _totalFrames;
};
+class XeenEngine;
+class SavesManager;
+
+class OutFile : public Common::MemoryWriteStreamDynamic {
+private:
+ XeenEngine *_vm;
+ Common::String _filename;
+public:
+ OutFile(XeenEngine *vm, const Common::String filename);
+
+ void finalize();
+};
+
class SavesManager: public BaseCCArchive {
+ friend class OutFile;
private:
XeenEngine *_vm;
Party &_party;
Roster &_roster;
byte *_data;
+ Common::HashMap<uint16, Common::MemoryWriteStreamDynamic > _newData;
void load(Common::SeekableReadStream *stream);
public:
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index ee804317ec..0a864aa2cb 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -27,27 +27,37 @@ namespace Xeen {
MazeEvent::MazeEvent() : _direction(DIR_ALL), _line(-1), _opcode(OP_None) {
}
-void MazeEvent::synchronize(Common::SeekableReadStream &s) {
- int len = s.readByte();
- _position.x = s.readByte();
- _position.y = s.readByte();
- _direction = (Direction)s.readByte();
- _line = s.readByte();
- _opcode = (Opcode)s.readByte();
-
- for (int i = 0; i < (len - 5); ++i)
- _parameters.push_back(s.readByte());
+void MazeEvent::synchronize(Common::Serializer &s) {
+ int len = 5 + _parameters.size();
+ s.syncAsByte(len);
+
+ s.syncAsByte(_position.x);
+ s.syncAsByte(_position.y);
+ s.syncAsByte(_direction);
+ s.syncAsByte(_line);
+ s.syncAsByte(_opcode);
+
+ len -= 5;
+ if (s.isLoading())
+ _parameters.resize(len);
+ for (int i = 0; i < len; ++i)
+ s.syncAsByte(_parameters[i]);
}
/*------------------------------------------------------------------------*/
-void MazeEvents::synchronize(Common::SeekableReadStream &s) {
+void MazeEvents::synchronize(XeenSerializer &s) {
MazeEvent e;
- clear();
- while (!s.eos()) {
- e.synchronize(s);
- push_back(e);
+ if (s.isLoading()) {
+ clear();
+ while (!s.finished()) {
+ e.synchronize(s);
+ push_back(e);
+ }
+ } else {
+ for (uint i = 0; i < size(); ++i)
+ (*this).operator[](i).synchronize(s);
}
}
diff --git a/engines/xeen/scripts.h b/engines/xeen/scripts.h
index 1ab08faa7e..727d37f681 100644
--- a/engines/xeen/scripts.h
+++ b/engines/xeen/scripts.h
@@ -25,7 +25,8 @@
#include "common/scummsys.h"
#include "common/system.h"
-#include "common/stream.h"
+#include "common/serializer.h"
+#include "xeen/files.h"
#include "xeen/party.h"
namespace Xeen {
@@ -104,14 +105,14 @@ public:
public:
MazeEvent();
- void synchronize(Common::SeekableReadStream &s);
+ void synchronize(Common::Serializer &s);
};
class MazeEvents : public Common::Array<MazeEvent> {
public:
Common::Array<byte> _text;
public:
- void synchronize(Common::SeekableReadStream &s);
+ void synchronize(XeenSerializer &s);
};
} // End of namespace Xeen