diff options
author | Filippos Karapetis | 2009-08-24 08:10:29 +0000 |
---|---|---|
committer | Filippos Karapetis | 2009-08-24 08:10:29 +0000 |
commit | 4c62b6ac86d28d5701dd2563eb030bf5cfa0d036 (patch) | |
tree | e4106d1b9d788c58a08677791ff4802dbdf0e5c5 | |
parent | 030665f90b5f172b7bafe730abcbc6f2a818ad6d (diff) | |
download | scummvm-rg350-4c62b6ac86d28d5701dd2563eb030bf5cfa0d036.tar.gz scummvm-rg350-4c62b6ac86d28d5701dd2563eb030bf5cfa0d036.tar.bz2 scummvm-rg350-4c62b6ac86d28d5701dd2563eb030bf5cfa0d036.zip |
- 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
svn-id: r43683
-rw-r--r-- | engines/sci/detection.cpp | 40 | ||||
-rw-r--r-- | engines/sci/exereader.cpp | 172 | ||||
-rw-r--r-- | engines/sci/exereader.h | 1 |
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 |