diff options
author | Paul Gilbert | 2015-01-07 22:11:18 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-01-07 22:11:18 -0500 |
commit | 96d086ab9cc28a2145072487b60036f916b28774 (patch) | |
tree | 93b880f20ecb1d2730c90cbe3b684ecaf3d07845 | |
parent | cd7c00ca8c93258d7b6c3ef92fc32452df1052cb (diff) | |
download | scummvm-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.cpp | 48 | ||||
-rw-r--r-- | engines/xeen/files.h | 12 | ||||
-rw-r--r-- | engines/xeen/map.cpp | 4 | ||||
-rw-r--r-- | engines/xeen/saves.cpp | 33 |
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() { |