MYST3: Properly read the directory of multiple room archives
This commit is contained in:
parent
4acbdde391
commit
37586bb534
5 changed files with 32 additions and 18 deletions
|
@ -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;
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace Myst3 {
|
|||
|
||||
class Archive {
|
||||
private:
|
||||
bool _multipleRoom;
|
||||
char _roomName[5];
|
||||
Common::File _file;
|
||||
Common::Array<DirectoryEntry> _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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace Myst3 {
|
|||
|
||||
class DirectoryEntry {
|
||||
private:
|
||||
char _roomName[5];
|
||||
uint16 _index;
|
||||
uint8 _unk;
|
||||
Common::Array<DirectorySubEntry> _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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue