diff --git a/engines/myst3/archive.cpp b/engines/myst3/archive.cpp index 3e16277847a..62b34692c32 100644 --- a/engines/myst3/archive.cpp +++ b/engines/myst3/archive.cpp @@ -51,12 +51,15 @@ void Archive::_readDirectory() { Common::MemoryReadStream directory(buf.getData(), buf.size()); directory.skip(sizeof(uint32)); - while (directory.pos() < directory.size()) { + while (directory.pos() + 4 < directory.size()) { DirectoryEntry entry(this); - entry.readFromStream(directory); - if (entry.hasSubEntries()) { - _directory.push_back(entry); - } + + if (_multipleRoom) + entry.readFromStream(directory, 0); + else + entry.readFromStream(directory, _roomName); + + _directory.push_back(entry); } } @@ -87,7 +90,14 @@ const DirectorySubEntry *Archive::getDescription(uint16 index, uint16 face, Dire return 0; } -bool Archive::open(const char *fileName) { +bool Archive::open(const char *fileName, const char *room) { + // Copy the room name if provided + // If the room name is not provided, it is assumed that + // we are opening a multi-room archive + _multipleRoom = room == 0; + if (!_multipleRoom) + Common::strlcpy(_roomName, room, sizeof(_roomName)); + if (_file.open(fileName)) { _readDirectory(); return true; diff --git a/engines/myst3/archive.h b/engines/myst3/archive.h index 82f4e6a34dc..8c54c058fee 100644 --- a/engines/myst3/archive.h +++ b/engines/myst3/archive.h @@ -32,6 +32,8 @@ namespace Myst3 { class Archive { private: + bool _multipleRoom; + char _roomName[5]; Common::File _file; Common::Array _directory; @@ -44,7 +46,7 @@ class Archive { void dumpDirectory(); void dumpToFiles(); - bool open(const char *fileName); + bool open(const char *fileName, const char *room); void close(); }; diff --git a/engines/myst3/directoryentry.cpp b/engines/myst3/directoryentry.cpp index 7680c13b80a..d1754c80c75 100644 --- a/engines/myst3/directoryentry.cpp +++ b/engines/myst3/directoryentry.cpp @@ -27,9 +27,15 @@ namespace Myst3 { DirectoryEntry::DirectoryEntry(Archive *archive) : _archive(archive) { + memset(_roomName, 0, sizeof(_roomName)); } -void DirectoryEntry::readFromStream(Common::SeekableReadStream &inStream) { +void DirectoryEntry::readFromStream(Common::SeekableReadStream &inStream, const char *room) { + if (room == 0) + inStream.read(_roomName, 4); + else + Common::strlcpy(_roomName, room, sizeof(_roomName)); + _index = inStream.readUint16LE(); _unk = inStream.readByte(); byte subItemCount = inStream.readByte(); @@ -55,10 +61,6 @@ void DirectoryEntry::dump() { } } -bool DirectoryEntry::hasSubEntries() { - return !_subentries.empty(); -} - void DirectoryEntry::dumpToFiles(Common::SeekableReadStream &inStream) { for (uint i = 0; i < _subentries.size(); i++) { _subentries[i].dumpToFile(inStream, _index); diff --git a/engines/myst3/directoryentry.h b/engines/myst3/directoryentry.h index e799dc29c91..b7c60067b56 100644 --- a/engines/myst3/directoryentry.h +++ b/engines/myst3/directoryentry.h @@ -31,6 +31,7 @@ namespace Myst3 { class DirectoryEntry { private: + char _roomName[5]; uint16 _index; uint8 _unk; Common::Array _subentries; @@ -41,11 +42,10 @@ class DirectoryEntry { DirectoryEntry() {} DirectoryEntry(Archive *archive); - void readFromStream(Common::SeekableReadStream &inStream); + void readFromStream(Common::SeekableReadStream &inStream, const char *room); void dump(); void dumpToFiles(Common::SeekableReadStream &inStream); DirectorySubEntry *getItemDescription(uint16 face, DirectorySubEntry::ResourceType type); - bool hasSubEntries(); uint16 getIndex() { return _index; } }; diff --git a/engines/myst3/myst3.cpp b/engines/myst3/myst3.cpp index 762b49ff726..5a536b3275d 100644 --- a/engines/myst3/myst3.cpp +++ b/engines/myst3/myst3.cpp @@ -107,15 +107,15 @@ Common::Error Myst3Engine::run() { _system->setupScreen(w, h, false, true); _system->showMouse(false); - if (!_archiveLANG->open("ENGLISH.m3t")) { + if (!_archiveLANG->open("ENGLISH.m3t", 0)) { error("Unable to open archive ENGLISH.m3t"); } - if (!_archiveRSRC->open("RSRC.m3r")) { + if (!_archiveRSRC->open("RSRC.m3r", 0)) { error("Unable to open archive RSRC.m3r"); } - if (!_archiveOVER->open("OVER101.m3o")) { + if (!_archiveOVER->open("OVER101.m3o", 0)) { // OVER101 is not required delete _archiveOVER; _archiveOVER = 0; @@ -331,7 +331,7 @@ void Myst3Engine::loadNode(uint16 nodeID, uint32 roomID, uint32 ageID) { Common::String nodeFile = Common::String::format("%snodes.m3a", newRoomName); _archive->close(); - if (!_archive->open(nodeFile.c_str())) { + if (!_archive->open(nodeFile.c_str(), newRoomName)) { error("Unable to open archive %s", nodeFile.c_str()); } }