DIRECTOR: Use KEY* mappings instead of taking the first resource to load chunks

This commit is contained in:
Pragyansh Chaturvedi 2022-07-28 01:05:05 +05:30 committed by Debby Servilla
parent 8f9da662cc
commit dbe1ae48d5
4 changed files with 43 additions and 38 deletions

View File

@ -171,6 +171,18 @@ Common::String Archive::getName(uint32 tag, uint16 id) const {
return resMap[id].name;
}
Common::SeekableReadStreamEndian *Archive::getMovieResourceIfPresent(uint32 tag) {
if (g_director->getVersion() >= 400 && (_movieChunks.contains(tag) && hasResource(tag, _movieChunks[tag])))
return getResource(tag, _movieChunks[tag]);
if (hasResource(tag, -1)) {
warning("Archive::getMovieResourceIfPresent(): KEY* to reference tag %d not found, returning first occurence of this resource", tag);
return getFirstResource(tag);
}
return nullptr;
}
Common::Array<uint32> Archive::getResourceTypeList() const {
Common::Array<uint32> typeList;
@ -593,12 +605,7 @@ bool RIFXArchive::openStream(Common::SeekableReadStream *stream, uint32 startOff
}
// Parse the CAS*, if present
if (hasResource(MKTAG('C', 'A', 'S', '*'), -1)) {
Common::SeekableReadStreamEndian *casStream = nullptr;
if (_movieChunks.contains(MKTAG('C', 'A', 'S', '*')))
casStream = getResource(MKTAG('C', 'A', 'S', '*'), _movieChunks[MKTAG('C', 'A', 'S', '*')]);
else
casStream = getFirstResource(MKTAG('C', 'A', 'S', '*'));
if (Common::SeekableReadStreamEndian *casStream = getMovieResourceIfPresent(MKTAG('C', 'A', 'S', '*'))) {
readCast(*casStream);
delete casStream;
}

View File

@ -69,6 +69,7 @@ public:
uint32 getOffset(uint32 tag, uint16 id) const;
uint16 findResourceID(uint32 tag, const Common::String &resName, bool ignoreCase = false) const;
Common::String getName(uint32 tag, uint16 id) const;
Common::SeekableReadStreamEndian *getMovieResourceIfPresent(uint32 tag);
Common::Array<uint32> getResourceTypeList() const;
Common::Array<uint16> getResourceIDList(uint32 type) const;
@ -80,9 +81,9 @@ protected:
Common::SeekableReadStream *_stream;
typedef Common::HashMap<uint16, Resource> ResourceMap;
typedef Common::HashMap<uint32, ResourceMap> TypeMap;
typedef Common::HashMap<uint32, uint32> MovieMap;
typedef Common::HashMap<uint32, uint32> MovieChunkMap;
TypeMap _types;
MovieMap _movieChunks;
MovieChunkMap _movieChunks;
Common::String _pathName;
};

View File

@ -238,7 +238,9 @@ bool Cast::loadConfig() {
return false;
}
Common::SeekableReadStreamEndian *stream = _castArchive->getFirstResource(MKTAG('V', 'W', 'C', 'F'));
Common::SeekableReadStreamEndian *stream = nullptr;
stream = _castArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'C', 'F'));
debugC(1, kDebugLoading, "****** Loading Config VWCF");
@ -489,26 +491,26 @@ void Cast::loadCast() {
}
// Font Mapping
if (_castArchive->hasResource(MKTAG('V', 'W', 'F', 'M'), -1)) {
loadFontMap(*(r = _castArchive->getFirstResource(MKTAG('V', 'W', 'F', 'M'))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'F', 'M'))) {
loadFontMap(*r);
delete r;
}
// Cross-Platform Font Mapping
if (_castArchive->hasResource(MKTAG('F', 'X', 'm', 'p'), -1)) {
loadFXmp(*(r = _castArchive->getFirstResource(MKTAG('F', 'X', 'm', 'p'))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('F', 'X', 'm', 'p'))) {
loadFXmp(*r);
delete r;
}
// Font Mapping V4
if (_castArchive->hasResource(MKTAG('F', 'm', 'a', 'p'), -1)) {
loadFontMapV4(*(r = _castArchive->getFirstResource(MKTAG('F', 'm', 'a', 'p'))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('F', 'm', 'a', 'p'))) {
loadFontMapV4(*r);
delete r;
}
// Pattern Tiles
if (_castArchive->hasResource(MKTAG('V', 'W', 'T', 'L'), -1)) {
loadVWTL(*(r = _castArchive->getFirstResource(MKTAG('V', 'W', 'T', 'L'))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'T', 'L'))) {
loadVWTL(*r);
delete r;
}
@ -525,8 +527,8 @@ void Cast::loadCast() {
}
// External sound files
if (_castArchive->hasResource(MKTAG('S', 'T', 'R', ' '), -1)) {
loadExternalSound(*(r = _castArchive->getFirstResource(MKTAG('S', 'T', 'R', ' '))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('S', 'T', 'R', ' '))) {
loadExternalSound(*r);
delete r;
}
@ -558,14 +560,9 @@ void Cast::loadCast() {
// For D4+ we may request to force Lingo scripts and skip precompiled bytecode
if (_version >= kFileVer400 && !debugChannelSet(-1, kDebugNoBytecode)) {
// Try to load script context
Common::Array<uint16> lctx = _castArchive->getResourceIDList(MKTAG('L','c','t','x'));
if (lctx.size() > 0) {
debugC(2, kDebugLoading, "****** Loading %d Lctx resources", lctx.size());
for (Common::Array<uint16>::iterator iterator = lctx.begin(); iterator != lctx.end(); ++iterator) {
loadLingoContext(*(r = _castArchive->getResource(MKTAG('L','c','t','x'), *iterator)));
delete r;
}
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('L', 'c', 't', 'x'))) {
loadLingoContext(*r);
delete r;
}
}
@ -580,8 +577,8 @@ void Cast::loadCast() {
}
// Score Order List resources
if (_castArchive->hasResource(MKTAG('S', 'o', 'r', 'd'), -1)) {
loadSord(*(r = _castArchive->getFirstResource(MKTAG('S', 'o', 'r', 'd'))));
if (r = _castArchive->getMovieResourceIfPresent(MKTAG('S', 'o', 'r', 'd'))) {
loadSord(*r);
delete r;
}

View File

@ -111,9 +111,8 @@ void Movie::setArchive(Archive *archive) {
_cast->setArchive(archive);
// Frame Labels
if (archive->hasResource(MKTAG('V', 'W', 'L', 'B'), -1)) {
Common::SeekableReadStreamEndian *r;
_score->loadLabels(*(r = archive->getFirstResource(MKTAG('V', 'W', 'L', 'B'))));
if (Common::SeekableReadStreamEndian *r = archive->getMovieResourceIfPresent(MKTAG('V', 'W', 'L', 'B'))) {
_score->loadLabels(*r);
delete r;
}
}
@ -131,8 +130,8 @@ bool Movie::loadArchive() {
// Wait to handle _stageColor until palette is loaded in loadCast...
// File Info
if (_movieArchive->hasResource(MKTAG('V', 'W', 'F', 'I'), -1)) {
loadFileInfo(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'F', 'I'))));
if (r = _movieArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'F', 'I'))) {
loadFileInfo(*r);
delete r;
}
@ -166,16 +165,17 @@ bool Movie::loadArchive() {
_window->setStageColor(_stageColor, true);
// Score
if (!_movieArchive->hasResource(MKTAG('V', 'W', 'S', 'C'), -1)) {
if (!(r = _movieArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'S', 'C')))) {
warning("Movie::loadArchive(): Wrong movie format. VWSC resource missing");
return false;
}
_score->loadFrames(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'S', 'C'))), _version);
_score->loadFrames(*r, _version);
delete r;
// Action list
if (_movieArchive->hasResource(MKTAG('V', 'W', 'A', 'C'), -1)) {
_score->loadActions(*(r = _movieArchive->getFirstResource(MKTAG('V', 'W', 'A', 'C'))));
if (r = _movieArchive->getMovieResourceIfPresent(MKTAG('V', 'W', 'A', 'C'))) {
_score->loadActions(*r);
delete r;
}