aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-07 22:11:18 -0500
committerPaul Gilbert2015-01-07 22:11:18 -0500
commit96d086ab9cc28a2145072487b60036f916b28774 (patch)
tree93b880f20ecb1d2730c90cbe3b684ecaf3d07845
parentcd7c00ca8c93258d7b6c3ef92fc32452df1052cb (diff)
downloadscummvm-rg350-96d086ab9cc28a2145072487b60036f916b28774.tar.gz
scummvm-rg350-96d086ab9cc28a2145072487b60036f916b28774.tar.bz2
scummvm-rg350-96d086ab9cc28a2145072487b60036f916b28774.zip
XEEN: Add prefix support to CC files, initial save state fixes
-rw-r--r--engines/xeen/files.cpp48
-rw-r--r--engines/xeen/files.h12
-rw-r--r--engines/xeen/map.cpp4
-rw-r--r--engines/xeen/saves.cpp33
4 files changed, 87 insertions, 10 deletions
diff --git a/engines/xeen/files.cpp b/engines/xeen/files.cpp
index b1358d4cdc..79387f2e24 100644
--- a/engines/xeen/files.cpp
+++ b/engines/xeen/files.cpp
@@ -39,6 +39,14 @@ uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) const
Common::String name = resourceName;
name.toUppercase();
+ // Check if a resource number is being directly specified
+ if (name.size() == 4) {
+ char *endPtr;
+ uint16 num = (uint16)strtol(name.c_str(), &endPtr, 16);
+ if (!*endPtr)
+ return num;
+ }
+
const byte *msgP = (const byte *)name.c_str();
int total = *msgP++;
for (; *msgP; total += *msgP++) {
@@ -121,7 +129,15 @@ int BaseCCArchive::listMembers(Common::ArchiveMemberList &list) const {
/*------------------------------------------------------------------------*/
CCArchive::CCArchive(const Common::String &filename, bool encoded):
- _filename(filename), _encoded(encoded) {
+ BaseCCArchive(), _filename(filename), _encoded(encoded) {
+ File f(filename);
+ loadIndex(&f);
+}
+
+CCArchive::CCArchive(const Common::String &filename, const Common::String &prefix,
+ bool encoded): BaseCCArchive(), _filename(filename),
+ _prefix(prefix), _encoded(encoded) {
+ _prefix.toLowercase();
File f(filename);
loadIndex(&f);
}
@@ -129,6 +145,25 @@ CCArchive::CCArchive(const Common::String &filename, bool encoded):
CCArchive::~CCArchive() {
}
+bool CCArchive::getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const {
+ Common::String resName = resourceName;
+
+ if (!_prefix.empty() && resName.contains('|')) {
+ resName.toLowercase();
+ Common::String prefix = _prefix + "|";
+
+ if (!strncmp(resName.c_str(), prefix.c_str(), prefix.size()))
+ // Matching CC prefix, so strip it off and allow processing to
+ // continue onto the base getHeaderEntry method
+ resName = Common::String(resName.c_str() + prefix.size());
+ else
+ // Not matching prefix, so don't allow a match
+ return false;
+ }
+
+ return BaseCCArchive::getHeaderEntry(resName, ccEntry);
+}
+
Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::String &name) const {
CCEntry ccEntry;
@@ -166,9 +201,9 @@ FileManager::FileManager(XeenEngine *vm) {
_isDarkCc = vm->getGameID() != GType_Clouds;
if (_isDarkCc)
- SearchMan.add("dark", new CCArchive("dark.cc"));
- SearchMan.add("xeen", new CCArchive("xeen.cc"));
- SearchMan.add("intro", new CCArchive("intro.cc"));
+ SearchMan.add("dark", new CCArchive("dark.cc", "dark", true));
+ SearchMan.add("xeen", new CCArchive("xeen.cc", "xeen", true));
+ SearchMan.add("intro", new CCArchive("intro.cc", "intro", true));
}
/*------------------------------------------------------------------------*/
@@ -181,4 +216,9 @@ void File::openFile(const Common::String &filename) {
error("Could not open file - %s", filename.c_str());
}
+void File::openFile(const Common::String &filename, Common::Archive &archive) {
+ if (!Common::File::open(filename, archive))
+ error("Could not open file - %s", filename.c_str());
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/files.h b/engines/xeen/files.h
index 6e560ca334..343aea1e74 100644
--- a/engines/xeen/files.h
+++ b/engines/xeen/files.h
@@ -52,9 +52,13 @@ class File : public Common::File {
public:
File() : Common::File() {}
File(const Common::String &filename) { openFile(filename); }
+ File(const Common::String &filename, Common::Archive &archive) {
+ openFile(filename, archive);
+ }
virtual ~File() {}
void openFile(const Common::String &filename);
+ void openFile(const Common::String &filename, Common::Archive &archive);
};
/**
@@ -82,7 +86,7 @@ protected:
void loadIndex(Common::SeekableReadStream *stream);
- bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
+ virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
public:
BaseCCArchive() {}
@@ -98,9 +102,13 @@ public:
class CCArchive : public BaseCCArchive {
private:
Common::String _filename;
+ Common::String _prefix;
bool _encoded;
+protected:
+ virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
public:
- CCArchive(const Common::String &filename, bool encoded = true);
+ CCArchive(const Common::String &filename, bool encoded);
+ CCArchive(const Common::String &filename, const Common::String &prefix, bool encoded);
virtual ~CCArchive();
// Archive implementation
diff --git a/engines/xeen/map.cpp b/engines/xeen/map.cpp
index 15c696bf94..a3a4063ee9 100644
--- a/engines/xeen/map.cpp
+++ b/engines/xeen/map.cpp
@@ -714,7 +714,7 @@ void MonsterObjectData::synchronize(Common::SeekableReadStream &s,
}
// Merge up wall items
- _wallItems.clear();
+ _wallItems.resize(1);
for (uint i = 0; i < wallItemData.size(); ++i) {
MazeWallItem &dest = _wallItems[i];
dest._position = wallItemData[i]._pos;
@@ -897,7 +897,7 @@ void Map::load(int mapId) {
// Reload the monster data for the main maze that we're loading
Common::String filename = Common::String::format("maze%c%03u.mob",
(_vm->_party._mazeId >= 100) ? 'x' : '0', _vm->_party._mazeId);
- File mobFile(filename);
+ File mobFile(filename, *_vm->_saves);
_mobData.synchronize(mobFile, _isOutdoors, _monsterData);
mobFile.close();
diff --git a/engines/xeen/saves.cpp b/engines/xeen/saves.cpp
index ae29dd1149..36bb7bda1a 100644
--- a/engines/xeen/saves.cpp
+++ b/engines/xeen/saves.cpp
@@ -99,10 +99,39 @@ void SavesManager::load(Common::SeekableReadStream *stream) {
* Sets up the dynamic data for the game for a new game
*/
void SavesManager::reset() {
- Common::String name(_vm->getGameID() == GType_Clouds ? "xeen.cur" : "dark.cur");
- File f(name);
+ Common::String prefix = _vm->getGameID() == GType_Clouds ? "xeen|" : "dark|";
+ Common::MemoryWriteStreamDynamic saveFile(DisposeAfterUse::YES);
+ Common::File fIn;
+
+ for (int i = 0; i <= 5; ++i) {
+ Common::String filename = prefix + Common::String::format("2A%dC", i);
+ if (fIn.exists(filename)) {
+ // Read in the next resource
+ fIn.open(filename);
+ byte *data = new byte[fIn.size()];
+ fIn.read(data, fIn.size());
+
+ // Copy it to the combined savefile resource
+ saveFile.write(data, fIn.size());
+ delete[] data;
+ fIn.close();
+ }
+ }
+ Common::MemoryReadStream f(saveFile.getData(), saveFile.size());
load(&f);
+
+ // Set up the party and characters from dark.cur
+ CCArchive gameCur("xeen.cur", false);
+ File fParty("maze.pty", gameCur);
+ Common::Serializer sParty(&fParty, nullptr);
+ _party.synchronize(sParty);
+ fParty.close();
+
+ File fChar("maze.chr", gameCur);
+ Common::Serializer sChar(&fChar, nullptr);
+ _roster.synchronize(sChar);
+ fChar.close();
}
void SavesManager::readCharFile() {