DIRECTOR: Add basic v3-5 exe parsing

This commit is contained in:
Matthew Hoops 2012-11-14 11:16:35 -05:00 committed by Eugene Sandulenko
parent a24668ff79
commit eb16a726e9
3 changed files with 117 additions and 0 deletions

View File

@ -54,6 +54,10 @@ Common::Language DirectorEngine::getLanguage() const {
return _gameDescription->desc.language;
}
Common::String DirectorEngine::getEXEName() const {
return _gameDescription->desc.filesDescriptions[0].fileName;
}
bool DirectorEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsRTL);

View File

@ -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

View File

@ -35,6 +35,7 @@ enum DirectorGameID {
GID_GENERIC
};
class Archive;
struct DirectorGameDescription;
class DirectorEngine : public ::Engine {
@ -48,6 +49,7 @@ public:
uint16 getVersion() const;
Common::Platform getPlatform() const;
Common::Language getLanguage() const;
Common::String getEXEName() const;
bool hasFeature(EngineFeature f) const;
@ -56,6 +58,16 @@ protected:
private:
const DirectorGameDescription *_gameDescription;
void loadEXE();
void loadEXEv3(Common::SeekableReadStream *stream);
void loadEXEv4(Common::SeekableReadStream *stream);
void loadEXEv5(Common::SeekableReadStream *stream);
void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
Common::String readPascalString(Common::SeekableReadStream &stream);
Archive *_mainArchive;
};
} // End of namespace Director