aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/detection.cpp40
-rw-r--r--engines/sci/exereader.cpp172
-rw-r--r--engines/sci/exereader.h1
3 files changed, 26 insertions, 187 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 177fc2fbd1..55ea8ee00a 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -260,7 +260,6 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
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 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
// 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 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
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 @@ const ADGameDescription *SciMetaEngine::fallbackDetect(const Common::FSList &fsl
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");
diff --git a/engines/sci/exereader.cpp b/engines/sci/exereader.cpp
index ce6bf184fb..fbeda66b45 100644
--- a/engines/sci/exereader.cpp
+++ b/engines/sci/exereader.cpp
@@ -96,62 +96,6 @@ Common::Platform getGameExePlatform(Common::SeekableReadStream *exeStream) {
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 @@ uint getBit(Common::SeekableReadStream *input) {
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
diff --git a/engines/sci/exereader.h b/engines/sci/exereader.h
index e30d3d90c4..e114c0a3a4 100644
--- a/engines/sci/exereader.h
+++ b/engines/sci/exereader.h
@@ -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