From d5009ee5c17b92ded3717428733b0d64654dd55d Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Mon, 29 Aug 2016 18:13:23 +0200 Subject: DIRECTOR: Put all archive parsing methods into archive.cpp --- engines/director/archive.cpp | 239 ++++++++++++++++++++++++++++++++++++++++++ engines/director/director.cpp | 210 +------------------------------------ engines/director/director.h | 2 + engines/director/module.mk | 1 + 4 files changed, 246 insertions(+), 206 deletions(-) create mode 100644 engines/director/archive.cpp (limited to 'engines') diff --git a/engines/director/archive.cpp b/engines/director/archive.cpp new file mode 100644 index 0000000000..6266ce386a --- /dev/null +++ b/engines/director/archive.cpp @@ -0,0 +1,239 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/macresman.h" + +#include "director/director.h" +#include "director/resource.h" +#include "director/lingo/lingo.h" + +namespace Director { + +Archive *DirectorEngine::createArchive() { + if (getVersion() < 4) { + return new RIFFArchive(); + } else { + return new RIFXArchive(); + } +} + +void DirectorEngine::loadMainArchive() { + if (getPlatform() == Common::kPlatformWindows) + loadEXE(); + else + loadMac(); +} + +void DirectorEngine::cleanupMainArchive() { + delete _mainArchive; + delete _macBinary; +} + +void DirectorEngine::loadEXE() { + Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName()); + if (!exeStream) + error("Failed to open EXE '%s'", getEXEName().c_str()); + + _lingo->processEvent(kEventStart, 0); + + exeStream->seek(-4, SEEK_END); + exeStream->seek(exeStream->readUint32LE()); + + switch (getVersion()) { + case 3: + loadEXEv3(exeStream); + break; + case 4: + loadEXEv4(exeStream); + break; + case 5: + loadEXEv5(exeStream); + break; + case 7: + loadEXEv7(exeStream); + break; + default: + error("Unhandled Windows EXE version %d", getVersion()); + } +} + +void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) { + uint16 entryCount = stream->readUint16LE(); + if (entryCount != 1) + error("Unhandled multiple entry v3 EXE"); + + stream->skip(5); // unknown + + stream->readUint32LE(); // Main MMM size + Common::String mmmFileName = readPascalString(*stream); + Common::String directoryName = readPascalString(*stream); + + debugC(1, kDebugLoading, "Main MMM: '%s'", mmmFileName.c_str()); + debugC(1, kDebugLoading, "Directory Name: '%s'", directoryName.c_str()); + + _mainArchive = new RIFFArchive(); + + if (!_mainArchive->openFile(mmmFileName)) + error("Could not open '%s'", mmmFileName.c_str()); + + delete stream; +} + +void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) { + if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3')) + error("Invalid projector tag found in v4 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + /* uint32 fontMapOffset = */ stream->readUint32LE(); + /* uint32 resourceForkOffset1 = */ stream->readUint32LE(); + /* uint32 resourceForkOffset2 = */ stream->readUint32LE(); + stream->readUint32LE(); // graphics DLL offset + stream->readUint32LE(); // sound DLL offset + /* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) { + if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5')) + error("Invalid projector tag found in v5 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + /* uint16 screenWidth = */ stream->readUint16LE(); + /* uint16 screenHeight = */ stream->readUint16LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + /* uint32 fontMapOffset = */ stream->readUint32LE(); + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) { + if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0')) + error("Invalid projector tag found in v7 EXE"); + + uint32 rifxOffset = stream->readUint32LE(); + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // unknown + stream->readUint32LE(); // some DLL offset + + loadEXERIFX(stream, rifxOffset); +} + +void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) { + _mainArchive = new RIFXArchive(); + + if (!_mainArchive->openStream(stream, offset)) + error("Failed to load RIFX from EXE"); +} + +void DirectorEngine::loadMac() { + if (getVersion() < 4) { + // The data is part of the resource fork of the executable + _mainArchive = new MacArchive(); + + if (!_mainArchive->openFile(getEXEName())) + error("Failed to open Mac binary '%s'", getEXEName().c_str()); + } else { + // The RIFX is located in the data fork of the executable + _macBinary = new Common::MacResManager(); + + if (!_macBinary->open(getEXEName()) || !_macBinary->hasDataFork()) + error("Failed to open Mac binary '%s'", getEXEName().c_str()); + + Common::SeekableReadStream *dataFork = _macBinary->getDataFork(); + _mainArchive = new RIFXArchive(); + + // First we need to detect PPC vs. 68k + + uint32 tag = dataFork->readUint32BE(); + uint32 startOffset; + + if (SWAP_BYTES_32(tag) == MKTAG('P', 'J', '9', '3') || tag == MKTAG('P', 'J', '9', '5') || tag == MKTAG('P', 'J', '0', '0')) { + // PPC: The RIFX shares the data fork with the binary + startOffset = dataFork->readUint32BE(); + } else { + // 68k: The RIFX is the only thing in the data fork + startOffset = 0; + } + + if (!_mainArchive->openStream(dataFork, startOffset)) + error("Failed to load RIFX from Mac binary"); + } +} + +void DirectorEngine::loadSharedCastsFrom(Common::String filename) { + Archive *shardcst = createArchive(); + + shardcst->openFile(filename); + + Score *castScore = new Score(this); + Common::SeekableSubReadStreamEndian *castStream = shardcst->getResource(MKTAG('V','W','C','R'), 1024); + + castScore->loadCastData(*castStream); + *_sharedCasts = castScore->_casts; + + Common::Array dib = shardcst->getResourceIDList(MKTAG('D','I','B',' ')); + + if (dib.size() != 0) { + Common::Array::iterator iterator; + for (iterator = dib.begin(); iterator != dib.end(); ++iterator) { + debugC(3, kDebugLoading, "Shared DIB %d", *iterator); + _sharedDIB->setVal(*iterator, shardcst->getResource(MKTAG('D','I','B',' '), *iterator)); + } + } + + Common::Array stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T')); + + if (stxt.size() != 0) { + Common::Array::iterator iterator; + for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) { + debugC(3, kDebugLoading, "Shared STXT %d", *iterator); + _sharedSTXT->setVal(*iterator, shardcst->getResource(MKTAG('S','T','X','T'), *iterator)); + } + } + + Common::Array bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D')); + + if (bmp.size() != 0) { + Common::Array::iterator iterator; + for (iterator = bmp.begin(); iterator != bmp.end(); ++iterator) { + _sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator)); + } + } + + Common::Array sound = shardcst->getResourceIDList(MKTAG('S','N','D',' ')); + + if (stxt.size() != 0) { + Common::Array::iterator iterator; + for (iterator = sound.begin(); iterator != sound.end(); ++iterator) { + _sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator)); + } + } +} + +} // End of namespace Director diff --git a/engines/director/director.cpp b/engines/director/director.cpp index 44275f73b6..5adfbf3f02 100644 --- a/engines/director/director.cpp +++ b/engines/director/director.cpp @@ -23,14 +23,11 @@ #include "common/config-manager.h" #include "common/debug-channels.h" #include "common/error.h" -#include "common/macresman.h" #include "graphics/macgui/macwindowmanager.h" #include "director/director.h" -#include "director/images.h" #include "director/resource.h" -#include "director/score.h" #include "director/sound.h" #include "director/lingo/lingo.h" @@ -81,8 +78,9 @@ DirectorEngine::~DirectorEngine() { delete _sharedDIB; delete _currentScore; - delete _mainArchive; - delete _macBinary; + + cleanupMainArchive(); + delete _soundManager; delete _lingo; } @@ -114,11 +112,7 @@ Common::Error DirectorEngine::run() { //_mainArchive->openFile("bookshelf_example.mmm"); loadMMMNames(ConfMan.get("path")); - - if (getPlatform() == Common::kPlatformWindows) - loadEXE(); - else - loadMac(); + loadMainArchive(); _currentScore = new Score(this); debug(0, "Score name %s", _currentScore->getMacName().c_str()); @@ -163,152 +157,6 @@ Common::HashMap DirectorEngine::loadMMMNames(Common::St return nameMap; } -Archive *DirectorEngine::createArchive() { - if (getVersion() < 4) { - return new RIFFArchive(); - } else { - return new RIFXArchive(); - } -} - -void DirectorEngine::loadEXE() { - Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName()); - if (!exeStream) - error("Failed to open EXE '%s'", getEXEName().c_str()); - - _lingo->processEvent(kEventStart, 0); - - exeStream->seek(-4, SEEK_END); - exeStream->seek(exeStream->readUint32LE()); - - switch (getVersion()) { - case 3: - loadEXEv3(exeStream); - break; - case 4: - loadEXEv4(exeStream); - break; - case 5: - loadEXEv5(exeStream); - break; - case 7: - loadEXEv7(exeStream); - break; - default: - error("Unhandled Windows EXE version %d", getVersion()); - } -} - -void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) { - uint16 entryCount = stream->readUint16LE(); - if (entryCount != 1) - error("Unhandled multiple entry v3 EXE"); - - stream->skip(5); // unknown - - stream->readUint32LE(); // Main MMM size - Common::String mmmFileName = readPascalString(*stream); - Common::String directoryName = readPascalString(*stream); - - debugC(1, kDebugLoading, "Main MMM: '%s'", mmmFileName.c_str()); - debugC(1, kDebugLoading, "Directory Name: '%s'", directoryName.c_str()); - - _mainArchive = new RIFFArchive(); - - if (!_mainArchive->openFile(mmmFileName)) - error("Could not open '%s'", mmmFileName.c_str()); - - delete stream; -} - -void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) { - if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3')) - error("Invalid projector tag found in v4 EXE"); - - uint32 rifxOffset = stream->readUint32LE(); - /* uint32 fontMapOffset = */ stream->readUint32LE(); - /* uint32 resourceForkOffset1 = */ stream->readUint32LE(); - /* uint32 resourceForkOffset2 = */ stream->readUint32LE(); - stream->readUint32LE(); // graphics DLL offset - stream->readUint32LE(); // sound DLL offset - /* uint32 rifxOffsetAlt = */ stream->readUint32LE(); // equivalent to rifxOffset - - loadEXERIFX(stream, rifxOffset); -} - -void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) { - if (stream->readUint32LE() != MKTAG('P', 'J', '9', '5')) - error("Invalid projector tag found in v5 EXE"); - - uint32 rifxOffset = stream->readUint32LE(); - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - /* uint16 screenWidth = */ stream->readUint16LE(); - /* uint16 screenHeight = */ stream->readUint16LE(); - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - /* uint32 fontMapOffset = */ stream->readUint32LE(); - - loadEXERIFX(stream, rifxOffset); -} - -void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) { - if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0')) - error("Invalid projector tag found in v7 EXE"); - - uint32 rifxOffset = stream->readUint32LE(); - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - stream->readUint32LE(); // unknown - stream->readUint32LE(); // some DLL offset - - loadEXERIFX(stream, rifxOffset); -} - -void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) { - _mainArchive = new RIFXArchive(); - - if (!_mainArchive->openStream(stream, offset)) - error("Failed to load RIFX from EXE"); -} - -void DirectorEngine::loadMac() { - if (getVersion() < 4) { - // The data is part of the resource fork of the executable - _mainArchive = new MacArchive(); - - if (!_mainArchive->openFile(getEXEName())) - error("Failed to open Mac binary '%s'", getEXEName().c_str()); - } else { - // The RIFX is located in the data fork of the executable - _macBinary = new Common::MacResManager(); - - if (!_macBinary->open(getEXEName()) || !_macBinary->hasDataFork()) - error("Failed to open Mac binary '%s'", getEXEName().c_str()); - - Common::SeekableReadStream *dataFork = _macBinary->getDataFork(); - _mainArchive = new RIFXArchive(); - - // First we need to detect PPC vs. 68k - - uint32 tag = dataFork->readUint32BE(); - uint32 startOffset; - - if (SWAP_BYTES_32(tag) == MKTAG('P', 'J', '9', '3') || tag == MKTAG('P', 'J', '9', '5') || tag == MKTAG('P', 'J', '0', '0')) { - // PPC: The RIFX shares the data fork with the binary - startOffset = dataFork->readUint32BE(); - } else { - // 68k: The RIFX is the only thing in the data fork - startOffset = 0; - } - - if (!_mainArchive->openStream(dataFork, startOffset)) - error("Failed to load RIFX from Mac binary"); - } -} - Common::String DirectorEngine::readPascalString(Common::SeekableReadStream &stream) { byte length = stream.readByte(); Common::String x; @@ -324,54 +172,4 @@ void DirectorEngine::setPalette(byte *palette, uint16 count) { _currentPaletteLength = count; } -void DirectorEngine::loadSharedCastsFrom(Common::String filename) { - Archive *shardcst = createArchive(); - - shardcst->openFile(filename); - - Score *castScore = new Score(this); - Common::SeekableSubReadStreamEndian *castStream = shardcst->getResource(MKTAG('V','W','C','R'), 1024); - - castScore->loadCastData(*castStream); - *_sharedCasts = castScore->_casts; - - Common::Array dib = shardcst->getResourceIDList(MKTAG('D','I','B',' ')); - - if (dib.size() != 0) { - Common::Array::iterator iterator; - for (iterator = dib.begin(); iterator != dib.end(); ++iterator) { - debugC(3, kDebugLoading, "Shared DIB %d", *iterator); - _sharedDIB->setVal(*iterator, shardcst->getResource(MKTAG('D','I','B',' '), *iterator)); - } - } - - Common::Array stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T')); - - if (stxt.size() != 0) { - Common::Array::iterator iterator; - for (iterator = stxt.begin(); iterator != stxt.end(); ++iterator) { - debugC(3, kDebugLoading, "Shared STXT %d", *iterator); - _sharedSTXT->setVal(*iterator, shardcst->getResource(MKTAG('S','T','X','T'), *iterator)); - } - } - - Common::Array bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D')); - - if (bmp.size() != 0) { - Common::Array::iterator iterator; - for (iterator = bmp.begin(); iterator != bmp.end(); ++iterator) { - _sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator)); - } - } - - Common::Array sound = shardcst->getResourceIDList(MKTAG('S','N','D',' ')); - - if (stxt.size() != 0) { - Common::Array::iterator iterator; - for (iterator = sound.begin(); iterator != sound.end(); ++iterator) { - _sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator)); - } - } -} - } // End of namespace Director diff --git a/engines/director/director.h b/engines/director/director.h index 05ce34e7ca..4cb8640d5b 100644 --- a/engines/director/director.h +++ b/engines/director/director.h @@ -81,7 +81,9 @@ public: uint16 getPaletteColorCount() const { return _currentPaletteLength; } void loadSharedCastsFrom(Common::String filename); + void loadMainArchive(); Archive *createArchive(); + void cleanupMainArchive(); Common::HashMap *getSharedDIB() const { return _sharedDIB; } Common::HashMap *getSharedBMP() const { return _sharedBMP; } diff --git a/engines/director/module.mk b/engines/director/module.mk index c37e9d9b9b..1ea361590a 100644 --- a/engines/director/module.mk +++ b/engines/director/module.mk @@ -1,6 +1,7 @@ MODULE := engines/director MODULE_OBJS = \ + archive.o \ detection.o \ director.o \ frame.o \ -- cgit v1.2.3