diff options
author | Matthew Hoops | 2012-11-14 11:16:35 -0500 |
---|---|---|
committer | Eugene Sandulenko | 2016-08-03 23:40:36 +0200 |
commit | eb16a726e90133592f0ea0bde2bb94dab99d3911 (patch) | |
tree | bdf2a95e0173a5163c033e2067ab16a81b6c0faa /engines/director/director.cpp | |
parent | a24668ff797675039135c4aeb2b4b78c800abe3e (diff) | |
download | scummvm-rg350-eb16a726e90133592f0ea0bde2bb94dab99d3911.tar.gz scummvm-rg350-eb16a726e90133592f0ea0bde2bb94dab99d3911.tar.bz2 scummvm-rg350-eb16a726e90133592f0ea0bde2bb94dab99d3911.zip |
DIRECTOR: Add basic v3-5 exe parsing
Diffstat (limited to 'engines/director/director.cpp')
-rw-r--r-- | engines/director/director.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/engines/director/director.cpp b/engines/director/director.cpp index 840692ae7f..7fe0c6966a 100644 --- a/engines/director/director.cpp +++ b/engines/director/director.cpp @@ -22,12 +22,15 @@ #include "audio/mixer.h" +#include "common/debug.h" #include "common/scummsys.h" #include "common/error.h" +#include "common/stream.h" #include "common/system.h" #include "common/textconsole.h" #include "director/director.h" +#include "director/resource.h" namespace Director { @@ -37,13 +40,111 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam // Setup mixer syncSoundSettings(); + + _mainArchive = 0; } DirectorEngine::~DirectorEngine() { + delete _mainArchive; } Common::Error DirectorEngine::run() { + debug("Starting v%d Director game", getVersion()); + + if (getPlatform() == Common::kPlatformWindows) + loadEXE(); + return Common::kNoError; } +void DirectorEngine::loadEXE() { + Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName()); + if (!exeStream) + error("Failed to open EXE '%s'", getEXEName().c_str()); + + 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; + } +} + +void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) { + stream->readUint32LE(); // unknown + stream->readUint16LE(); // unknown + stream->readUint32LE(); // Main MMM size + stream->readByte(); // zero + Common::String mmmFileName = readPascalString(*stream); + Common::String directoryName = readPascalString(*stream); + + debug("Main MMM: '%s'", mmmFileName.c_str()); + debug("Directory Name: '%s'", directoryName.c_str()); + + _mainArchive = new RIFFArchive(); + + // TODO: Convert MMM name and load + + 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::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) { + stream->seek(offset); + + _mainArchive = new RIFXArchive(); + + if (!_mainArchive->openStream(stream)) + error("Failed to load RIFX from EXE"); +} + +Common::String DirectorEngine::readPascalString(Common::SeekableReadStream &stream) { + byte length = stream.readByte(); + Common::String x; + + while (length--) + x += (char)stream.readByte(); + + return x; +} + } // End of namespace Director |