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

jvprat at users.sourceforge.net jvprat at users.sourceforge.net
Fri Feb 20 15:45:29 CET 2009


Revision: 38589
          http://scummvm.svn.sourceforge.net/scummvm/?rev=38589&view=rev
Author:   jvprat
Date:     2009-02-20 14:45:28 +0000 (Fri, 20 Feb 2009)

Log Message:
-----------
- Moved SciEngine code to sci.cpp
- Fill the platform on fallback detection
- Report unparseable version strings
- Map known non-numeric version strings to their numeric counterparts
- Fix a crash caused by uninitialized LZEXE data

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

Modified: scummvm/trunk/engines/sci/detection.cpp
===================================================================
--- scummvm/trunk/engines/sci/detection.cpp	2009-02-20 12:32:48 UTC (rev 38588)
+++ scummvm/trunk/engines/sci/detection.cpp	2009-02-20 14:45:28 UTC (rev 38589)
@@ -30,6 +30,8 @@
 #include "sci/exereader.h"
 #include "sci/include/versions.h"
 
+namespace Sci {
+
 // Titles of the games
 static const PlainGameDescriptor SciGameTitles[] = {
 	{"sci",             "Unknown SCI Game"},
@@ -90,26 +92,6 @@
 	{0, 0}
 };
 
-const char* SciEngine::getGameID() const {
-	return _gameDescription->desc.gameid;
-}
-
-Common::Platform SciEngine::getPlatform() const {
-	return _gameDescription->desc.platform;
-}
-
-Common::Language SciEngine::getLanguage() const {
-	return _gameDescription->desc.language;
-}
-
-uint32 SciEngine::getFlags() const {
-	return _gameDescription->desc.flags;
-}
-
-int SciEngine::getVersion() const {
-	return _gameDescription->version;
-}
-
 /*
 	// Missing - from FreeSCI
 	{ 0x980CEAD3, SCI_VERSION(0, 000, 629), "Demo Quest" },
@@ -154,7 +136,7 @@
 		{},
 		SCI_VERSION(1, 000, 510)
 	},
-	
+
 	// Castle of Dr. Brain - English DOS Demo
 	{{"castlebrain", "Demo", {
 		{"resource.map", 0, "467bb5e3224bb54640c3280032aebff5", 633},
@@ -332,7 +314,7 @@
 		SCI_VERSION(0, 000, 000)	// FIXME: add version here
 	},
 #endif
-  
+
 	// Freddy Pharkas - English DOS CD Demo
 	{{"freddypharkas", "CD Demo", {
 		{"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918},
@@ -1681,7 +1663,7 @@
 		{},
 		SCI_VERSION(2, 100, 2)
 	},
-		
+
 	// Torin's Passage - Spanish Windows
 	{{"torin", "", {
 		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
@@ -1690,7 +1672,7 @@
 		{},
 		SCI_VERSION(2, 100, 2)
 	},
-	
+
 	// Torin's Passage - French Windows
 	{{"torin", "", {
 		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
@@ -1699,7 +1681,7 @@
 		{},
 		SCI_VERSION(2, 100, 2)
 	},
-		
+
 	// Torin's Passage - German Windows
 	{{"torin", "", {
 		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
@@ -1708,7 +1690,7 @@
 		{},
 		SCI_VERSION(2, 100, 2)
 	},
-	
+
 	// Torin's Passage - Italian Windows CD (from glorifindel)
 	{{"torin", "", {
 		{"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799},
@@ -1776,20 +1758,22 @@
 
 
 const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fslist) const {
-	int exeVersion = 0;
 	bool foundResMap = false;
 	bool foundRes000 = false;
-	bool foundExe = 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) {
-		if (file->isDirectory()) continue;
+		if (file->isDirectory())
+			continue;
+
 		Common::String filename = file->getName();
 		filename.toLowercase();
-		
+
 		if (filename.contains("resource.map") || filename.contains("resmap.000"))
 			foundResMap = true;
-		
+
 		if (filename.contains("resource.000") || filename.contains("resource.001")
 			|| filename.contains("ressci.000") || filename.contains("ressci.001"))
 			foundRes000 = true;
@@ -1798,47 +1782,56 @@
 		if (filename.contains("scidhuv") || filename.contains("sciv") ||
 			filename.contains("sierra") || filename.contains("sciw") ||
 			filename.contains("prog")) {
-			
-			if (foundExe) // We already found a valid exe, no need to check this one.
+
+			// We already found a valid exe, no need to check this one.
+			if (exeVersionString.size())
 				continue;
-			
+
 			// Is it really an executable file?
 			Common::SeekableReadStream *fileStream = file->createReadStream();
-			bool isExe = isGameExe(fileStream);
+			exePlatform = getGameExePlatform(fileStream);
 
-			if (isExe && readSciVersionFromExe(fileStream, &exeVersion)) // All ok, we got the version from the executable successfully	
-				foundExe = true;
-				
+			// It's a valid exe, read the interpreter version string
+			if (exePlatform != Common::kPlatformUnknown)
+				exeVersionString = readSciVersionFromExe(fileStream);
+
 			delete fileStream;
 		}
-
 	}
-	
-	if (!foundExe)
+
+	if (exePlatform == Common::kPlatformUnknown)
 		return 0;
 
 	// If these files aren't found, it can't be SCI
 	if (!foundResMap && !foundRes000)
 		return 0;
-		
+
 	// Set some defaults
 	g_fallbackDesc.desc.gameid = "sci";
 	g_fallbackDesc.desc.extra = "";
 	g_fallbackDesc.desc.language = Common::UNK_LANG;
-	g_fallbackDesc.desc.platform = Common::kPlatformPC;
+	g_fallbackDesc.desc.platform = exePlatform;
 	g_fallbackDesc.desc.flags = ADGF_NO_FLAGS;
-	g_fallbackDesc.version = exeVersion;
+	g_fallbackDesc.version = SCI_VERSION(0, 0, 0);
 
 	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("Interpreter version: %d.%03d.%03d (by executable scan)\n",
-			SCI_VERSION_MAJOR(exeVersion),
- 			SCI_VERSION_MINOR(exeVersion),
- 			SCI_VERSION_PATCHLEVEL(exeVersion));
-		
-	return (const ADGameDescription *)&g_fallbackDesc;
+	// Try to parse the executable version
+	if (getSciVersionFromString(exeVersionString, &g_fallbackDesc.version)) {
+		printf("Interpreter version: %d.%03d.%03d (got %s by executable scan)\n",
+			SCI_VERSION_MAJOR(g_fallbackDesc.version),
+			SCI_VERSION_MINOR(g_fallbackDesc.version),
+			SCI_VERSION_PATCHLEVEL(g_fallbackDesc.version),
+			exeVersionString.c_str());
+
+		return (const ADGameDescription *)&g_fallbackDesc;
+	} else {
+		printf("Couldn't parse the interpreter version: %s (by executable scan)\n",
+			exeVersionString.c_str());
+		return NULL;
+	}
 }
 
 bool SciMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
@@ -1849,8 +1842,10 @@
 	return true;
 }
 
+} // End of namespace Sci
+
 #if PLUGIN_ENABLED_DYNAMIC(SCI)
-	REGISTER_PLUGIN_DYNAMIC(SCI, PLUGIN_TYPE_ENGINE, SciMetaEngine);
+	REGISTER_PLUGIN_DYNAMIC(SCI, PLUGIN_TYPE_ENGINE, Sci::SciMetaEngine);
 #else
-	REGISTER_PLUGIN_STATIC(SCI, PLUGIN_TYPE_ENGINE, SciMetaEngine);
+	REGISTER_PLUGIN_STATIC(SCI, PLUGIN_TYPE_ENGINE, Sci::SciMetaEngine);
 #endif

Modified: scummvm/trunk/engines/sci/exereader.cpp
===================================================================
--- scummvm/trunk/engines/sci/exereader.cpp	2009-02-20 12:32:48 UTC (rev 38588)
+++ scummvm/trunk/engines/sci/exereader.cpp	2009-02-20 14:45:28 UTC (rev 38589)
@@ -24,21 +24,20 @@
  */
 
 #include "common/endian.h"
-#include "common/util.h"
 
 #include "sci/exereader.h"
 #include "sci/include/versions.h"
 
-//namespace Sci {
+namespace Sci {
 
 int _bitCount;
 uint16 _bits;
 
-bool isGameExe(Common::SeekableReadStream *exeStream) {
+Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream) {
 	byte magic[4];
 	// Make sure that the executable is at least 4KB big
 	if (exeStream->size() < 4096)
-		return false;
+		return Common::kPlatformUnknown;
 
 	// Read exe header
 	exeStream->read(magic, 4);
@@ -48,18 +47,18 @@
 	// Information obtained from http://magicdb.org/magic.db
 	// Check if it's a DOS executable
 	if (magic[0] == 'M' && magic[1] == 'Z') {
-		return true;
+		return Common::kPlatformPC;
 	}
 
 	// Check if it's an Amiga executable
 	if ((magic[2] == 0x03 && magic[3] == 0xF3) ||
 		(magic[0] == 0x7F && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F')) {
-		return true;
+		return Common::kPlatformAmiga;
 	}
 
 	// Check if it's an Atari executable
 	if ((magic[0] == 0x60 && magic[1] == 0x1A))
-		return true;
+		return Common::kPlatformAtariST;
 
 	// Check if it's a Mac exe
 
@@ -67,7 +66,7 @@
 	int32 offset = (int32)READ_BE_UINT32(magic);
 	offset += 28;
 	if (exeStream->size() <= offset)
-		return false;
+		return Common::kPlatformUnknown;
 
 	// Skip number of types in map
 	exeStream->skip(2);
@@ -77,23 +76,23 @@
 	while (!exeStream->eos()) {
 		exeStream->skip(4);
 		if (exeStream->eos())
-			return false;
+			return Common::kPlatformUnknown;
 
 		exeStream->read(magic, 4);
 		if (exeStream->eos())
-			return false;
+			return Common::kPlatformUnknown;
 
 		if (!memcmp(magic, "CODE", 4)) {
-			return true;
+			return Common::kPlatformMacintosh;
 		}
 		// Skip to the next list entry
 		exeStream->skip(4);
 		if (exeStream->eos())
-			return false;
+			return Common::kPlatformUnknown;
 	}
 
 	// If we've reached here, the file type is unknown
-	return false;
+	return Common::kPlatformUnknown;
 }
 
 bool isLZEXECompressed(Common::SeekableReadStream *exeStream) {
@@ -172,10 +171,10 @@
 	return bit;
 }
 
-bool readSciVersionFromExe(Common::SeekableReadStream *exeStream, int *version) {
+Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream) {
 	int len = exeStream->size();
 	unsigned char *buffer = NULL;
-	char result_string[10]; /* string-encoded result, copied from buf */
+
 	// Read the executable
 	bool isLZEXE = isLZEXECompressed(exeStream);
 
@@ -186,6 +185,7 @@
 		exeStream->read(buffer, exeStream->size());
 	} else {
 		buffer = new unsigned char[exeStream->size() * 3];
+		_bitCount = 0;
 
 		// Skip LZEXE header
 		exeStream->seek(32, SEEK_SET);
@@ -198,7 +198,7 @@
 			if (exeStream->ioFailed()) {
 				warning("Error reading from input file");
 				delete[] buffer;
-				return false;
+				return NULL;
 			}
 
 			if (getBit(exeStream)) {
@@ -257,9 +257,14 @@
 	int accept;
 	unsigned char *buf = buffer;
 
+	// String-encoded result, copied from buffer
+	char currentString[10];
+	Common::String resultString;
+
 	for (int i = 0; i < len; i++) {
 		unsigned char ch = *buf++;
-		accept = 0; // By default, we don't like this character
+		// By default, we don't like this character
+		accept = 0;
 
 		if (isalnum(ch)) {
 			accept = (state != 1
@@ -269,24 +274,63 @@
 			accept = (state == 1
 			          || state == 5);
 		} else if (state == 9) {
-			result_string[9] = 0; /* terminate string */
+			// Terminate string
+			currentString[9] = 0;
 
-			if (!version_parse(result_string, version)) {
+			// Return the current string if it's parseable
+			int version;
+			if (getSciVersionFromString(currentString, &version)) {
 				delete[] buffer;
-				return true;	// success
+				return currentString;
 			}
 
-			// Continue searching
+			// Save the found string and continue searching
+			resultString = currentString;
 		}
 
 		if (accept)
-			result_string[state++] = ch;
+			currentString[state++] = ch;
 		else
 			state = 0;
 	}
 
 	delete[] buffer;
-	return false; // failure
+	return resultString;
 }
 
-//} // End of namespace Sci
+bool getSciVersionFromString(Common::String versionString, int *version) {
+	// Map non-numeric versions to their numeric counterparts
+	Common::String mappedVersion = versionString;
+	if (versionString.hasPrefix("S.old.")) {
+		// SCI 01
+		mappedVersion = "0.001.";
+		mappedVersion += versionString.c_str() + 6;
+	} else if (versionString.hasPrefix("1.ECO.")
+		|| versionString.hasPrefix("1.SQ1.")
+		|| versionString.hasPrefix("1.SQ4.")
+		|| versionString.hasPrefix("1.LS5.")
+		|| versionString.hasPrefix("1.pq3.")
+		|| versionString.hasPrefix("FAIRY.")) {
+		// SCI 1.0
+		mappedVersion = "1.000.";
+		mappedVersion += versionString.c_str() + 6;
+	} else if (versionString.hasPrefix("T.A00.")) {
+		mappedVersion = "1.000.510";
+	} else if (versionString.hasPrefix("L.rry.")
+		|| versionString.hasPrefix("l.cfs.")) {
+		// SCI 1.1
+		mappedVersion = "1.001.";
+		mappedVersion += versionString.c_str() + 6;
+	} else if (versionString == "x.yyy.yyy") {
+		// How to map it?
+	}
+
+	// Parse to a version number
+	if (!version_parse(mappedVersion.c_str(), version)) {
+		return true;
+	} else {
+		return false;
+	}
+}
+
+} // End of namespace Sci

Modified: scummvm/trunk/engines/sci/exereader.h
===================================================================
--- scummvm/trunk/engines/sci/exereader.h	2009-02-20 12:32:48 UTC (rev 38588)
+++ scummvm/trunk/engines/sci/exereader.h	2009-02-20 14:45:28 UTC (rev 38589)
@@ -26,14 +26,15 @@
 #ifndef EXEREADER_H
 #define EXEREADER_H
 
-#include "common/file.h"
-#include "common/str.h"
+#include "common/stream.h"
+#include "common/util.h"
 
-//namespace Sci {
+namespace Sci {
 
-bool isGameExe(Common::SeekableReadStream *exeStream);
-bool readSciVersionFromExe(Common::SeekableReadStream *exeStream, int *version);
+Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream);
+Common::String readSciVersionFromExe(Common::SeekableReadStream *exeStream);
+bool getSciVersionFromString(Common::String versionString, int *version);
 
-//} // End of namespace Sci
+} // End of namespace Sci
 
 #endif // SCI_H

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-02-20 12:32:48 UTC (rev 38588)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-02-20 14:45:28 UTC (rev 38589)
@@ -31,10 +31,10 @@
 #include "sci/sci.h"
 #include "sci/include/engine.h"
 
-//namespace Sci {
-
 extern gfx_driver_t gfx_driver_scummvm;
 
+namespace Sci {
+
 int
 c_quit(state_t *s) {
 	script_abort_flag = 1; /* Terminate VM */
@@ -309,4 +309,24 @@
 	return Common::kNoError;
 }
 
-//} // End of namespace Sci
+const char* SciEngine::getGameID() const {
+	return _gameDescription->desc.gameid;
+}
+
+int SciEngine::getVersion() const {
+	return _gameDescription->version;
+}
+
+Common::Language SciEngine::getLanguage() const {
+	return _gameDescription->desc.language;
+}
+
+Common::Platform SciEngine::getPlatform() const {
+	return _gameDescription->desc.platform;
+}
+
+uint32 SciEngine::getFlags() const {
+	return _gameDescription->desc.flags;
+}
+
+} // End of namespace Sci

Modified: scummvm/trunk/engines/sci/sci.h
===================================================================
--- scummvm/trunk/engines/sci/sci.h	2009-02-20 12:32:48 UTC (rev 38588)
+++ scummvm/trunk/engines/sci/sci.h	2009-02-20 14:45:28 UTC (rev 38589)
@@ -29,7 +29,7 @@
 #include "engines/engine.h"
 #include "gui/debugger.h"
 
-//namespace Sci {
+namespace Sci {
 
 // our engine debug levels
 enum {
@@ -62,7 +62,6 @@
 	virtual Common::Error init(void);
 	virtual Common::Error go(void);
 
-	const SciGameDescription *_gameDescription;
 	const char* getGameID() const;
 	int getVersion() const;
 	Common::Language getLanguage() const;
@@ -70,6 +69,7 @@
 	uint32 getFlags() const;
 
 private:
+	const SciGameDescription *_gameDescription;
 	//Console *_console;
 };
 
@@ -82,6 +82,6 @@
 };
 */
 
-//} // End of namespace Sci
+} // End of namespace Sci
 
 #endif // SCI_H


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