diff options
| author | Matthew Hoops | 2012-11-15 10:54:03 -0500 | 
|---|---|---|
| committer | Eugene Sandulenko | 2016-08-03 23:40:36 +0200 | 
| commit | 4a334980e1121d310948fbd497298d24d07011ac (patch) | |
| tree | 4270156d8389385b4b9d90e230e59b0b7c516e1b | |
| parent | 387833ace4c176a5a47acae8e6e6a9764b08f235 (diff) | |
| download | scummvm-rg350-4a334980e1121d310948fbd497298d24d07011ac.tar.gz scummvm-rg350-4a334980e1121d310948fbd497298d24d07011ac.tar.bz2 scummvm-rg350-4a334980e1121d310948fbd497298d24d07011ac.zip | |
DIRECTOR: Add some simple Windows version fallback detection
| -rw-r--r-- | engines/director/detection.cpp | 126 | 
1 files changed, 126 insertions, 0 deletions
| diff --git a/engines/director/detection.cpp b/engines/director/detection.cpp index 3e3d6ca117..63d6b4e685 100644 --- a/engines/director/detection.cpp +++ b/engines/director/detection.cpp @@ -91,6 +91,7 @@ public:  		return "Macromedia Director (C) Macromedia";  	} +	const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;  	virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;  }; @@ -103,6 +104,131 @@ bool DirectorMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD  	return (gd != 0);  } +static Director::DirectorGameDescription s_fallbackDesc = { +	{ +		"director", +		"", +		AD_ENTRY1(0, 0), +		Common::UNK_LANG, +		Common::kPlatformWindows, +		ADGF_NO_FLAGS, +		GUIO0() +	}, +	Director::GID_GENERIC, +	0 +}; + +static char s_fallbackFileNameBuffer[51]; + +const ADGameDescription *DirectorMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const { +	// TODO: Handle Mac fallback + +	// reset fallback description +	Director::DirectorGameDescription *desc = &s_fallbackDesc; +	desc->desc.gameid = "director"; +	desc->desc.extra = ""; +	desc->desc.language = Common::UNK_LANG; +	desc->desc.flags = ADGF_NO_FLAGS; +	desc->desc.platform = Common::kPlatformWindows; +	desc->desc.guioptions = GUIO0(); +	desc->desc.filesDescriptions[0].fileName = 0; +	desc->version = 0; +	desc->gameID = Director::GID_GENERIC; + +	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { +		if (file->isDirectory()) +			continue; + +		Common::String fileName = file->getName(); +		fileName.toLowercase(); +		if (!fileName.hasSuffix(".exe")) +			continue; + +		SearchMan.clear(); +		SearchMan.addDirectory(file->getParent().getName(), file->getParent()); + +		Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember(file->getName()); + +		if (!stream) +			continue; + +		stream->seek(-4, SEEK_END); + +		uint32 offset = stream->readUint32LE(); + +		if (stream->eos() || offset == 0 || offset >= (uint32)(stream->size() - 4)) { +			delete stream; +			continue; +		} + +		stream->seek(offset); + +		uint32 tag = stream->readUint32LE(); + +		switch (tag) { +		case MKTAG('3', '9', 'J', 'P'): +			desc->version = 4; +			break; +		case MKTAG('P', 'J', '9', '5'): +			desc->version = 5; +			break; +		case MKTAG('P', 'J', '0', '0'): +			desc->version = 7; +			break; +		default: +			// Prior to version 4, there was no tag here. So we'll use a bit of a +			// heuristic to detect. The first field is the entry count, of which +			// there should only be one. +			if ((tag & 0xFFFF) != 1) { +				delete stream; +				continue; +			} + +			stream->skip(3); + +			uint32 mmmSize = stream->readUint32LE(); + +			if (stream->eos() || mmmSize == 0) { +				delete stream; +				continue; +			} + +			byte fileNameSize = stream->readByte(); + +			if (stream->eos()) { +				delete stream; +				continue; +			} + +			stream->skip(fileNameSize); +			byte directoryNameSize = stream->readByte(); + +			if (stream->eos()) { +				delete stream; +				continue; +			} + +			stream->skip(directoryNameSize); + +			if ((uint32)stream->pos() != offset) { +				delete stream; +				continue; +			} + +			// Assume v3 at this point (for now at least) +			desc->version = 3; +		} + +		strncpy(s_fallbackFileNameBuffer, fileName.c_str(), 50); +		s_fallbackFileNameBuffer[50] = '\0'; +		desc->desc.filesDescriptions[0].fileName = s_fallbackFileNameBuffer; + +		return (ADGameDescription *)desc; +	} + +	return 0; +} +  #if PLUGIN_ENABLED_DYNAMIC(DIRECTOR)  	REGISTER_PLUGIN_DYNAMIC(DIRECTOR, PLUGIN_TYPE_ENGINE, DirectorMetaEngine);  #else | 
