[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