[Scummvm-cvs-logs] SF.net SVN: scummvm:[43683] scummvm/trunk/engines/sci

thebluegr at users.sourceforge.net thebluegr at users.sourceforge.net
Mon Aug 24 10:10:29 CEST 2009


Revision: 43683
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43683&view=rev
Author:   thebluegr
Date:     2009-08-24 08:10:29 +0000 (Mon, 24 Aug 2009)

Log Message:
-----------
- Removed the code which reads the SCI version string from the game executable in the fallback detector. We no longer use the actual SCI version string, and we can auto-detect a lot of features from the game resources now. The EXE version string was only used to display the detected SCI version in the console, which isn't very useful to us anymore.
- Added detection for PC and Amiga versions based on the game's detected view types. Still need to do detection for Mac and Atari ST versions

Modified Paths:
--------------
    scummvm/trunk/engines/sci/detection.cpp
    scummvm/trunk/engines/sci/exereader.cpp
    scummvm/trunk/engines/sci/exereader.h

Modified: scummvm/trunk/engines/sci/detection.cpp
===================================================================
--- scummvm/trunk/engines/sci/detection.cpp	2009-08-24 07:57:04 UTC (rev 43682)
+++ scummvm/trunk/engines/sci/detection.cpp	2009-08-24 08:10:29 UTC (rev 43683)
@@ -260,7 +260,6 @@
 	bool foundResMap = false;
 	bool foundRes000 = false;
 	Common::Platform exePlatform = Common::kPlatformUnknown;
-	Common::String exeVersionString;
 
 	// First grab all filenames
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
@@ -293,22 +292,15 @@
 
 		// Check if it's a known executable name
 		// Note: "sier" matches "sier.exe", "sierra.exe", "sierw.exe" and "sierw5.exe"
+		// TODO: Try to remove this code, and base platform detection on game resources
+		// instead of the executable itself
 		if (filename.contains("scidhuv") || filename.contains("sciduv") ||
 			filename.contains("sciv") || filename.contains("sciw") ||
 			filename.contains("prog") || filename.contains("sier")) {
 
-			// We already found a valid exe, no need to check this one.
-			if (!exeVersionString.empty())
-				continue;
-
 			// Is it really an executable file?
 			Common::SeekableReadStream *fileStream = file->createReadStream();
 			exePlatform = getGameExePlatform(fileStream);
-
-			// It's a valid exe, read the interpreter version string
-			if (exePlatform != Common::kPlatformUnknown)
-				exeVersionString = readSciVersionFromExe(fileStream, exePlatform);
-
 			delete fileStream;
 		}
 	}
@@ -319,19 +311,40 @@
 		return 0;
 	}
 
+	ResourceManager *resMgr = new ResourceManager(fslist);
+	SciVersion version = resMgr->sciVersion();
+	SegManager *segManager = new SegManager(resMgr, version);
+
 	// Set some defaults
 	s_fallbackDesc.desc.extra = "";
 	s_fallbackDesc.desc.language = Common::UNK_LANG;
+	if (exePlatform == Common::kPlatformUnknown) {
+		// Try to determine the platform from game resources
+		ViewType gameViews = resMgr->getViewType();
+		if (gameViews == kViewEga || gameViews == kViewVga ||
+			gameViews == kViewVga11) {
+			// Must be PC or Mac, set to PC for now
+			// TODO: Is there a reliable way to determine the game
+			// platform from the resources? So far, I've noticed
+			// that Mac versions have a different signature for
+			// kGetEvent and kNewWindow. I'm unsure about Atari ST
+			// versions. Could we base detection on this?
+			exePlatform = Common::kPlatformPC;
+		} else if (gameViews == kViewAmiga) {
+			exePlatform = Common::kPlatformAmiga;
+		}
+		// TODO: detection for Mac and Atari ST
+	}
+
 	s_fallbackDesc.desc.platform = exePlatform;
 	s_fallbackDesc.desc.flags = ADGF_NO_FLAGS;
 
 	// Determine the game id
-	ResourceManager *resMgr = new ResourceManager(fslist);
-	SciVersion version = resMgr->sciVersion();
-	SegManager *segManager = new SegManager(resMgr, version);
 	if (!script_instantiate(resMgr, segManager, version, 0)) {
 		warning("fallbackDetect(): Could not instantiate script 0");
 		SearchMan.remove("SCI_detection");
+		delete segManager;
+		delete resMgr;
 		return 0;
 	}
 	reg_t game_obj = script_lookup_export(segManager, 0, 0);
@@ -345,7 +358,6 @@
 	printf("If this is *NOT* a fan-modified version (in particular, not a fan-made\n");
 	printf("translation), please, report the data above, including the following\n");
 	printf("version number, from the game's executable:\n");
-	printf("Version: %s\n\n", exeVersionString.empty() ? "not found" : exeVersionString.c_str());
 
 	SearchMan.remove("SCI_detection");
 

Modified: scummvm/trunk/engines/sci/exereader.cpp
===================================================================
--- scummvm/trunk/engines/sci/exereader.cpp	2009-08-24 07:57:04 UTC (rev 43682)
+++ scummvm/trunk/engines/sci/exereader.cpp	2009-08-24 08:10:29 UTC (rev 43683)
@@ -96,62 +96,6 @@
 	return Common::kPlatformUnknown;
 }
 
-bool isLZEXECompressed(Common::SeekableReadStream *exeStream) {
-	uint32 filepos = 0;
-
-	exeStream->seek(0, SEEK_SET);
-
-	// First 2 bytes should be "MZ" (0x5A4D)
-	if (exeStream->readUint16LE() != 0x5A4D)	// at pos 0, +2
-		return false;
-
-	exeStream->skip(6);
-
-	// Header size should be 2
-	filepos = exeStream->readUint16LE();
-	if (filepos != 2)							// at pos 8, +2
-		return false;
-
-	exeStream->skip(12);
-
-	// Calculate code segment offset in exe file
-	filepos += exeStream->readUint16LE();		// at pos 22, +2
-	filepos <<= 4;
-
-	// First relocation item offset should be 0x1c
-	if (exeStream->readUint16LE() != 0x1c)		// at pos 24, +2
-		return false;
-
-	// Number of overlays should be 0
-	if (exeStream->readUint16LE() != 0)			// at pos 26, +2
-		return false;
-
-	// Look for LZEXE signature
-	byte magic[4];
-	exeStream->read(magic, 4);
-
-	if (memcmp(magic, "LZ09", 4) && memcmp(magic, "LZ91", 4))
-		return false;
-
-	// Seek to offset 8 of info table at start of code segment
-	exeStream->seek(filepos + 8, SEEK_SET);
-	if (exeStream->err())
-		return false;
-
-	// Read size of compressed data in paragraphs
-	uint16 size = exeStream->readUint16LE();
-
-	// Move file pointer to start of compressed data
-	filepos -= size << 4;
-	exeStream->seek(filepos, SEEK_SET);
-	if (exeStream->err())
-		return false;
-
-	// All conditions met, this is an LZEXE packed file
-	// We are currently at the start of the compressed file data
-	return true;
-}
-
 uint getBit(Common::SeekableReadStream *input) {
 	uint bit = _bits & 1;
 	_bitCount--;
@@ -172,120 +116,4 @@
 	return bit;
 }
 
-Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream, Common::Platform platform) {
-	int len = exeStream->size();
-	unsigned char *buffer = NULL;
-
-	// Read the executable
-	bool isLZEXE = isLZEXECompressed(exeStream);
-
-	if (!isLZEXE) {
-		buffer = new unsigned char[exeStream->size()];
-
-		exeStream->seek(0, SEEK_SET);
-		exeStream->read(buffer, exeStream->size());
-	} else {
-		buffer = new unsigned char[exeStream->size() * 3];
-		_bitCount = 0;
-
-		// Skip LZEXE header
-		exeStream->seek(32, SEEK_SET);
-
-		int pos = 0;
-		int repeat;
-		short offset;
-
-		while (1) {
-			if (exeStream->ioFailed()) {
-				warning("Error reading from input file");
-				delete[] buffer;
-				return NULL;
-			}
-
-			if (getBit(exeStream)) {
-				buffer[pos++] = exeStream->readByte();
-			} else {
-				if (getBit(exeStream)) {
-					byte tmp[2];
-					exeStream->read(tmp, 2);
-					repeat = (tmp[1] & 0x07);
-					offset = ((tmp[1] & ~0x07) << 5) | tmp[0] | 0xE000;
-
-					if (repeat == 0) {
-						repeat = exeStream->readByte();
-
-						if (repeat == 0) {
-							len = pos;
-							break;
-						}
-						else if (repeat == 1)
-							continue;
-						else
-							repeat++;
-					} else
-						repeat += 2;
-				} else {
-					repeat = getBit(exeStream) << 1;
-					repeat += getBit(exeStream) + 2;
-					offset = exeStream->readByte() | 0xFF00;
-				}
-
-				while (repeat > 0) {
-					buffer[pos] = buffer[pos + offset];
-					pos++;
-					repeat--;
-				}
-			}
-		}
-	}
-
-	// Find SCI version number
-
-	int state = 0;
-	/* 'state' encodes how far we have matched the version pattern
-	**   "n.nnn.nnn"
-	**
-	**   n.nnn.nnn
-	**  0123456789
-	**
-	** Since we cannot be certain that the pattern does not begin with an
-	** alphanumeric character, some states are ambiguous.
-	** The pattern is expected to be terminated with a non-alphanumeric
-	** character.
-	*/
-
-
-	int accept;
-	unsigned char *buf = buffer;
-
-	// String-encoded result, copied from buffer
-	char currentString[10];
-
-	for (int i = 0; i < len; i++) {
-		unsigned char ch = *buf++;
-		// By default, we don't like this character
-		accept = 0;
-
-		if (isalnum(ch)) {
-			accept = (state != 1 && state != 5 && state != 9);
-		} else if (ch == '.') {
-			accept = (state == 1 || state == 5);
-		} else if (state == 9) {
-			// Terminate string
-			currentString[9] = 0;
-
-			// Return the current string
-			return currentString;
-		}
-
-		if (accept)
-			currentString[state++] = ch;
-		else
-			state = 0;
-	}
-
-	delete[] buffer;
-	return "unknown";
-}
-
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/exereader.h
===================================================================
--- scummvm/trunk/engines/sci/exereader.h	2009-08-24 07:57:04 UTC (rev 43682)
+++ scummvm/trunk/engines/sci/exereader.h	2009-08-24 08:10:29 UTC (rev 43683)
@@ -32,7 +32,6 @@
 namespace Sci {
 
 Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream);
-Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream, Common::Platform platform);
 
 } // End of namespace Sci
 


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list