[Scummvm-git-logs] scummvm master -> 280a4f2d911d10f8199a88805fae6966ac00f44b

dreammaster paulfgilbert at gmail.com
Mon Apr 1 01:37:51 CEST 2019


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
7b4c6d6a35 GLK: Improved detection of Blorb files
280a4f2d91 GLK: Only check the format of a Blorb file if it has a valid file extension


Commit: 7b4c6d6a35f00e46d9021b236393a40aa54e6a6e
    https://github.com/scummvm/scummvm/commit/7b4c6d6a35f00e46d9021b236393a40aa54e6a6e
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2019-03-31T16:37:47-07:00

Commit Message:
GLK: Improved detection of Blorb files

Changed paths:
    engines/glk/blorb.cpp
    engines/glk/blorb.h
    engines/glk/frotz/detection.cpp
    engines/glk/glulxe/detection.cpp
    engines/glk/magnetic/detection.cpp
    engines/glk/scott/detection.cpp
    engines/glk/tads/detection.cpp


diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index ce86dee..ebf5e01 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -24,32 +24,6 @@
 
 namespace Glk {
 
-enum {
-	ID_FORM = MKTAG('F', 'O', 'R', 'M'),
-	ID_IFRS = MKTAG('I', 'F', 'R', 'S'),
-	ID_RIdx = MKTAG('R', 'I', 'd', 'x'),
-
-	ID_Snd = MKTAG('S', 'n', 'd', ' '),
-	ID_Exec = MKTAG('E', 'x', 'e', 'c'),
-	ID_Pict = MKTAG('P', 'i', 'c', 't'),
-	ID_Data = MKTAG('D', 'a', 't', 'a'),
-
-	ID_Copyright = MKTAG('(', 'c', ')', ' '),
-	ID_AUTH = MKTAG('A', 'U', 'T', 'H'),
-	ID_ANNO = MKTAG('A', 'N', 'N', 'O'),
-
-	ID_JPEG = MKTAG('J', 'P', 'E', 'G'),
-	ID_PNG  = MKTAG('P', 'N', 'G', ' '),
-	ID_Rect = MKTAG('R', 'e', 'c', 't'),
-
-	ID_MIDI = MKTAG('M', 'I', 'D', 'I'),
-	ID_MP3 = MKTAG('M', 'P', '3', ' '),
-	ID_WAVE = MKTAG('W', 'A', 'V', 'E'),
-	ID_AIFF = MKTAG('A', 'I', 'F', 'F'),
-	ID_OGG = MKTAG('O', 'G', 'G', ' '),
-	ID_MOD = MKTAG('M', 'O', 'D', ' ')
-};
-
 /*--------------------------------------------------------------------------*/
 
 Blorb::Blorb(const Common::String &filename, InterpreterType interpType) :
@@ -111,39 +85,18 @@ Common::ErrorCode Blorb::load() {
 	// First, chew through the file and index the chunks
 	Common::File f;
 	if ((!_filename.empty() && !f.open(_filename)) ||
-			(_filename.empty() && !f.open(_fileNode)) ||
-			f.size() < 12)
+			(_filename.empty() && !f.open(_fileNode)))
 		return Common::kReadingFailed;
 
-	if (f.readUint32BE() != ID_FORM)
-		return Common::kReadingFailed;
-	f.readUint32BE();
-	if (f.readUint32BE() != ID_IFRS)
-		return Common::kReadingFailed;
-	if (f.readUint32BE() != ID_RIdx)
+	if (!isBlorb(f))
 		return Common::kReadingFailed;
 
-	f.readUint32BE();
-	uint count = f.readUint32BE();
-
-	// First read in the resource index
-	for (uint idx = 0; idx < count; ++idx) {
-		ChunkEntry ce;
-		ce._type = f.readUint32BE();
-		ce._number = f.readUint32BE();
-		ce._offset = f.readUint32BE();
-
-		_chunks.push_back(ce);
-	}
+	if (!readRIdx(f, _chunks))
+		return Common::kReadingFailed;
 
 	// Further iterate through the resources
 	for (uint idx = 0; idx < _chunks.size(); ++idx) {
 		ChunkEntry &ce = _chunks[idx];
-		f.seek(ce._offset);
-		ce._offset += 8;
-
-		ce._id = f.readUint32BE();
-		ce._size = f.readUint32BE();
 
 		if (ce._type == ID_Pict) {
 			ce._filename = Common::String::format("pic%u", ce._number);
@@ -173,22 +126,21 @@ Common::ErrorCode Blorb::load() {
 			ce._filename = Common::String::format("data%u", ce._number);
 
 		} else if (ce._type == ID_Exec) {
-			char buffer[5];
-			WRITE_BE_UINT32(buffer, ce._id);
-			buffer[4] = '\0';
-			Common::String type(buffer);
-
 			if (
-				(_interpType == INTERPRETER_FROTZ && type == "ZCOD") ||
-				(_interpType == INTERPRETER_GLULXE && type == "GLUL") ||
-				(_interpType == INTERPRETER_TADS2 && type == "TAD2") ||
-				(_interpType == INTERPRETER_TADS3 && type == "TAD3") ||
-				(_interpType == INTERPRETER_HUGO && type == "HUGO") ||
-				(_interpType == INTERPRETER_SCOTT && type == "SAAI")
+				(_interpType == INTERPRETER_FROTZ && ce._id == ID_ZCOD) ||
+				(_interpType == INTERPRETER_GLULXE && ce._id == ID_GLUL) ||
+				(_interpType == INTERPRETER_TADS2 && ce._id == ID_TAD2) ||
+				(_interpType == INTERPRETER_TADS3 && ce._id == ID_TAD3) ||
+				(_interpType == INTERPRETER_HUGO && ce._id == ID_HUGO) ||
+				(_interpType == INTERPRETER_SCOTT && ce._id == ID_SAAI)
 			) {
 				// Game executable
 				ce._filename = "game";
 			} else {
+				char buffer[5];
+				WRITE_BE_UINT32(buffer, ce._id);
+				buffer[4] = '\0';
+				Common::String type(buffer);
 				ce._filename = type;
 			}
 		}
@@ -197,9 +149,68 @@ Common::ErrorCode Blorb::load() {
 	return Common::kNoError;
 }
 
-bool Blorb::isBlorb(const Common::String &filename) {
-	return filename.hasSuffixIgnoreCase(".blorb") || filename.hasSuffixIgnoreCase(".zblorb")
-		|| filename.hasSuffixIgnoreCase(".gblorb") || filename.hasSuffixIgnoreCase(".blb");
+bool Blorb::readRIdx(Common::SeekableReadStream &stream, Common::Array<ChunkEntry> &chunks) {
+	if (stream.readUint32BE() != ID_RIdx)
+		return false;
+
+	stream.readUint32BE();
+	uint count = stream.readUint32BE();
+
+	// First read in the resource index
+	for (uint idx = 0; idx < count; ++idx) {
+		ChunkEntry ce;
+		ce._type = stream.readUint32BE();
+		ce._number = stream.readUint32BE();
+		ce._offset = stream.readUint32BE();
+
+		chunks.push_back(ce);
+	}
+
+	// Further iterate through the resources
+	for (uint idx = 0; idx < chunks.size(); ++idx) {
+		ChunkEntry &ce = chunks[idx];
+		stream.seek(ce._offset);
+		ce._offset += 8;
+
+		ce._id = stream.readUint32BE();
+		ce._size = stream.readUint32BE();
+	}
+
+	return true;
+}
+
+bool Blorb::isBlorb(Common::SeekableReadStream &stream, uint32 type) {
+	if (stream.size() < 12)
+		return false;
+	if (stream.readUint32BE() != ID_FORM)
+		return false;
+	stream.readUint32BE();
+	if (stream.readUint32BE() != ID_IFRS)
+		return false;
+
+	if (type == 0)
+		return true;
+
+	Common::Array<ChunkEntry> chunks;
+	if (!readRIdx(stream, chunks))
+		return false;
+
+	// Further iterate through the resources
+	for (uint idx = 0; idx < chunks.size(); ++idx) {
+		ChunkEntry &ce = chunks[idx];
+		if (ce._type == ID_Exec && ce._id == type)
+			return true;
+	}
+
+	return false;
+}
+
+bool Blorb::isBlorb(const Common::String &filename, uint32 type) {
+	Common::File f;
+	if (!filename.empty() && !f.open(filename))
+		return false;
+
+	return isBlorb(f, type);
 }
 
 } // End of namespace Glk
diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h
index 18a84a5..e5dde28 100644
--- a/engines/glk/blorb.h
+++ b/engines/glk/blorb.h
@@ -42,6 +42,39 @@ struct ChunkEntry {
 	Common::String _filename;
 };
 
+enum {
+	ID_FORM = MKTAG('F', 'O', 'R', 'M'),
+	ID_IFRS = MKTAG('I', 'F', 'R', 'S'),
+	ID_RIdx = MKTAG('R', 'I', 'd', 'x'),
+
+	ID_Snd = MKTAG('S', 'n', 'd', ' '),
+	ID_Exec = MKTAG('E', 'x', 'e', 'c'),
+	ID_Pict = MKTAG('P', 'i', 'c', 't'),
+	ID_Data = MKTAG('D', 'a', 't', 'a'),
+
+	ID_Copyright = MKTAG('(', 'c', ')', ' '),
+	ID_AUTH = MKTAG('A', 'U', 'T', 'H'),
+	ID_ANNO = MKTAG('A', 'N', 'N', 'O'),
+
+	ID_ZCOD = MKTAG('Z', 'C', 'O', 'D'),
+	ID_GLUL = MKTAG('G', 'L', 'U', 'L'),
+	ID_TAD2 = MKTAG('T', 'A', 'D', '2'),
+	ID_TAD3 = MKTAG('T', 'A', 'D', '3'),
+	ID_HUGO = MKTAG('H', 'U', 'G', 'O'),
+	ID_SAAI = MKTAG('S', 'A', 'A', 'I'),
+
+	ID_JPEG = MKTAG('J', 'P', 'E', 'G'),
+	ID_PNG  = MKTAG('P', 'N', 'G', ' '),
+	ID_Rect = MKTAG('R', 'e', 'c', 't'),
+
+	ID_MIDI = MKTAG('M', 'I', 'D', 'I'),
+	ID_MP3 = MKTAG('M', 'P', '3', ' '),
+	ID_WAVE = MKTAG('W', 'A', 'V', 'E'),
+	ID_AIFF = MKTAG('A', 'I', 'F', 'F'),
+	ID_OGG = MKTAG('O', 'G', 'G', ' '),
+	ID_MOD = MKTAG('M', 'O', 'D', ' ')
+};
+
 /**
  * Blorb file manager
  */
@@ -95,9 +128,19 @@ public:
 	virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const override;
 
 	/**
+	 * Read the RIdx section from the stream.
+	 */
+	static bool readRIdx(Common::SeekableReadStream &stream, Common::Array<ChunkEntry> &chunks);
+
+	/**
+	 * Returns true if a given file is a Blorb file
+	 */
+	static bool isBlorb(Common::SeekableReadStream &stream, uint32 type = 0);
+
+	/**
 	 * Returns true if a given filename specifies a Blorb file
 	 */
-	static bool isBlorb(const Common::String &filename);
+	static bool isBlorb(const Common::String &filename, uint32 type = 0);
 };
 
 } // End of namespace Glk
diff --git a/engines/glk/frotz/detection.cpp b/engines/glk/frotz/detection.cpp
index 273ca37..4df4fd2 100644
--- a/engines/glk/frotz/detection.cpp
+++ b/engines/glk/frotz/detection.cpp
@@ -57,7 +57,7 @@ GameDescriptor FrotzMetaEngine::findGame(const char *gameId) {
 
 bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
 	const char *const EXTENSIONS[] = { ".z1", ".z2", ".z3", ".z4", ".z5", ".z6", ".z7", ".z8",
-		".zblorb", ".dat", ".zip", nullptr };
+		".dat", ".zip", nullptr };
 
 	// Loop through the files of the folder
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
@@ -65,11 +65,9 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		if (file->isDirectory())
 			continue;
 		Common::String filename = file->getName();
-		bool hasExt = false;
+		bool hasExt = false, isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
-		if (!hasExt)
-			continue;
 
 		// Open up the file and calculate the md5, and get the serial
 		Common::File gameFile;
@@ -79,15 +77,19 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		size_t filesize = gameFile.size();
 		char serial[9] = "";
 		bool emptyBlorb = false;
+		gameFile.seek(0);
+		isBlorb = Blorb::isBlorb(gameFile, ID_ZCOD);
 
-		if (!filename.hasSuffixIgnoreCase(".zblorb")) {
+		if (!isBlorb) {
+			if (!hasExt) {
+				gameFile.close();
+				continue;
+			}
 			gameFile.seek(18);
 			strcpy(&serial[0], "\"");
 			gameFile.read(&serial[1], 6);
 			strcpy(&serial[7], "\"");
-		}
-		gameFile.close();
-		if (filename.hasSuffixIgnoreCase(".zblorb")) {
+		} else {
 			Blorb b(*file, INTERPRETER_FROTZ);
 			Common::SeekableReadStream *f = b.createReadStreamForMember("game");
 			emptyBlorb = f == nullptr;
@@ -100,13 +102,14 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 				delete f;
 			}
 		}
+		gameFile.close();
 
 		// Check for known games. Note that there has been some variation in exact filesizes
 		// for Infocom games due to padding at the end of files. So we match on md5s for the
 		// first 5Kb, and only worry about filesize for more recent Blorb based Zcode games
 		const FrotzGameDescription *p = FROTZ_GAMES;
 		while (p->_gameId && p->_md5 && (md5 != p->_md5 ||
-				(filesize != p->_filesize && filename.hasSuffix(".zblorb"))))
+				(filesize != p->_filesize && isBlorb)))
 			++p;
 
 		DetectedGame gd;
diff --git a/engines/glk/glulxe/detection.cpp b/engines/glk/glulxe/detection.cpp
index 06ce403..64c6eab 100644
--- a/engines/glk/glulxe/detection.cpp
+++ b/engines/glk/glulxe/detection.cpp
@@ -22,6 +22,7 @@
 
 #include "glk/glulxe/detection.h"
 #include "glk/glulxe/detection_tables.h"
+#include "glk/blorb.h"
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/md5.h"
@@ -46,7 +47,7 @@ GameDescriptor GlulxeMetaEngine::findGame(const char *gameId) {
 }
 
 bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
-	const char *const EXTENSIONS[] = { ".ulx", ".blb", ".gblorb", nullptr };
+	const char *const EXTENSIONS[] = { ".ulx", nullptr };
 
 	// Loop through the files of the folder
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
@@ -54,11 +55,9 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 		if (file->isDirectory())
 			continue;
 		Common::String filename = file->getName();
-		bool hasExt = false;
+		bool hasExt = false, isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
-		if (!hasExt)
-			continue;
 
 		// Open up the file and calculate the md5
 		Common::File gameFile;
@@ -66,8 +65,13 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 			continue;
 		Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
 		size_t filesize = gameFile.size();
+		gameFile.seek(0);
+		isBlorb = Blorb::isBlorb(gameFile, ID_GLUL);
 		gameFile.close();
 
+		if (!hasExt && !isBlorb)
+			continue;
+
 		// Check for known games
 		const GlulxeGameDescription *p = GLULXE_GAMES;
 		while (p->_gameId && (md5 != p->_md5 || filesize != p->_filesize))
@@ -75,9 +79,6 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 
 		DetectedGame gd;
 		if (!p->_gameId) {
-			if (filename.hasSuffixIgnoreCase(".blb"))
-				continue;
-
 			if (gDebugLevel > 0) {
 				// Print an entry suitable for putting into the detection_tables.h, using the
 				// name of the parent folder the game is in as the presumed game Id
diff --git a/engines/glk/magnetic/detection.cpp b/engines/glk/magnetic/detection.cpp
index f702106..cfd0102 100644
--- a/engines/glk/magnetic/detection.cpp
+++ b/engines/glk/magnetic/detection.cpp
@@ -75,9 +75,6 @@ bool MagneticMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames
 
 		DetectedGame gd;
 		if (!p->_gameId) {
-			if (filename.hasSuffixIgnoreCase(".blb"))
-				continue;
-
 			if (gDebugLevel > 0) {
 				// Print an entry suitable for putting into the detection_tables.h, using the
 				// name of the parent folder the game is in as the presumed game Id
diff --git a/engines/glk/scott/detection.cpp b/engines/glk/scott/detection.cpp
index f1c4b9a..0e89b13 100644
--- a/engines/glk/scott/detection.cpp
+++ b/engines/glk/scott/detection.cpp
@@ -22,6 +22,7 @@
 
 #include "glk/scott/detection.h"
 #include "glk/scott/detection_tables.h"
+#include "glk/blorb.h"
 #include "common/file.h"
 #include "common/md5.h"
 #include "engines/game.h"
@@ -44,41 +45,43 @@ GameDescriptor ScottMetaEngine::findGame(const char *gameId) {
 }
 
 bool ScottMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
-	const char *const EXTENSIONS[] = { ".saga", ".dat", ".blb", ".blorb", nullptr };
-	Common::File gameFile;
-	Common::String md5;
+	const char *const EXTENSIONS[] = { ".saga", ".dat", nullptr };
 
 	// Loop through the files of the folder
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
-		Common::String name = file->getName();
+		// Check for a recognised filename
 		if (file->isDirectory())
 			continue;
 
 		Common::String filename = file->getName();
-		bool hasExt = false;
+		bool hasExt = false, isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
-		if (!hasExt)
-			continue;
 
-		if (gameFile.open(*file)) {
-			md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+		Common::File gameFile;
+		if (!gameFile.open(*file))
+			continue;
+		Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
+		int32 filesize = gameFile.size();
+		gameFile.seek(0);
+		isBlorb = Blorb::isBlorb(gameFile, ID_SAAI);
+		gameFile.close();
 
-			// Scan through the Scott game list for a match
-			const ScottGame *p = SCOTT_GAMES;
-			while (p->_md5 && p->_filesize != gameFile.size() && md5 != p->_md5)
-				++p;
+		if (!hasExt && !isBlorb)
+			continue;
 
-			if (p->_filesize) {
-				// Found a match
-				PlainGameDescriptor gameDesc = findGame(p->_gameId);
-				DetectedGame gd(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
-				gd.addExtraEntry("filename", file->getName());
+		// Scan through the Scott game list for a match
+		const ScottGame *p = SCOTT_GAMES;
+		while (p->_md5 && p->_filesize != filesize && md5 != p->_md5)
+			++p;
 
-				gameList.push_back(gd);
-			}
+		if (p->_filesize) {
+			// Found a match
+			PlainGameDescriptor gameDesc = findGame(p->_gameId);
+			DetectedGame gd(p->_gameId, gameDesc.description, Common::EN_ANY, Common::kPlatformUnknown);
+			gd.addExtraEntry("filename", file->getName());
 
-			gameFile.close();
+			gameList.push_back(gd);
 		}
 	}
 
diff --git a/engines/glk/tads/detection.cpp b/engines/glk/tads/detection.cpp
index 9e1eb08..92633da 100644
--- a/engines/glk/tads/detection.cpp
+++ b/engines/glk/tads/detection.cpp
@@ -22,6 +22,7 @@
 
 #include "glk/tads/detection.h"
 #include "glk/tads/detection_tables.h"
+#include "glk/blorb.h"
 #include "common/debug.h"
 #include "common/file.h"
 #include "common/md5.h"
@@ -58,22 +59,32 @@ GameDescriptor TADSMetaEngine::findGame(const char *gameId) {
 }
 
 bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &gameList) {
+	const char *const EXTENSIONS[] = { ".gam", nullptr };
+
 	// Loop through the files of the folder
 	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
 		// Check for a recognised filename
-		Common::String filename = file->getName();
-		if (file->isDirectory() || !(filename.hasSuffixIgnoreCase(".gam")
-				|| filename.hasSuffixIgnoreCase(".blorb")))
+		if (file->isDirectory())
 			continue;
 
+		Common::String filename = file->getName();
+		bool hasExt = false, isBlorb = false;
+		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
+			hasExt = filename.hasSuffixIgnoreCase(*ext);
+
 		// Open up the file and calculate the md5
 		Common::File gameFile;
 		if (!gameFile.open(*file))
 			continue;
 		Common::String md5 = Common::computeStreamMD5AsString(gameFile, 5000);
 		size_t filesize = gameFile.size();
+		gameFile.seek(0);
+		isBlorb = Blorb::isBlorb(gameFile, ID_TAD2) || Blorb::isBlorb(gameFile, ID_TAD3);
 		gameFile.close();
 
+		if (!hasExt && !isBlorb)
+			continue;
+
 		// Check for known games
 		const TADSGameDescription *p = TADS_GAMES;
 		while (p->_gameId && p->_md5 && (md5 != p->_md5 || filesize != p->_filesize))
@@ -81,9 +92,6 @@ bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga
 
 		DetectedGame gd;
 		if (!p->_gameId) {
-			if (!filename.hasSuffixIgnoreCase(".gam"))
-				continue;
-
 			if (gDebugLevel > 0) {
 				// Print an entry suitable for putting into the detection_tables.h, using the
 				Common::String fname = filename;


Commit: 280a4f2d911d10f8199a88805fae6966ac00f44b
    https://github.com/scummvm/scummvm/commit/280a4f2d911d10f8199a88805fae6966ac00f44b
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2019-03-31T16:37:47-07:00

Commit Message:
GLK: Only check the format of a Blorb file if it has a valid file extension

Changed paths:
    engines/glk/blorb.cpp
    engines/glk/blorb.h
    engines/glk/frotz/detection.cpp
    engines/glk/glulxe/detection.cpp
    engines/glk/scott/detection.cpp
    engines/glk/tads/detection.cpp


diff --git a/engines/glk/blorb.cpp b/engines/glk/blorb.cpp
index ebf5e01..03c3dd3 100644
--- a/engines/glk/blorb.cpp
+++ b/engines/glk/blorb.cpp
@@ -213,4 +213,9 @@ bool Blorb::isBlorb(const Common::String &filename, uint32 type) {
 	return isBlorb(f, type);
 }
 
+bool Blorb::hasBlorbExt(const Common::String &filename) {
+	return filename.hasSuffixIgnoreCase(".blorb") || filename.hasSuffixIgnoreCase(".zblorb")
+		|| filename.hasSuffixIgnoreCase(".gblorb") || filename.hasSuffixIgnoreCase(".blb");
+}
+
 } // End of namespace Glk
diff --git a/engines/glk/blorb.h b/engines/glk/blorb.h
index e5dde28..92a5f3f 100644
--- a/engines/glk/blorb.h
+++ b/engines/glk/blorb.h
@@ -141,6 +141,11 @@ public:
 	 * Returns true if a given filename specifies a Blorb file
 	 */
 	static bool isBlorb(const Common::String &filename, uint32 type = 0);
+
+	/**
+	 * Returns true if a given filename has a Blorb file extension
+	 */
+	static bool hasBlorbExt(const Common::String &filename);
 };
 
 } // End of namespace Glk
diff --git a/engines/glk/frotz/detection.cpp b/engines/glk/frotz/detection.cpp
index 4df4fd2..b9d5e10 100644
--- a/engines/glk/frotz/detection.cpp
+++ b/engines/glk/frotz/detection.cpp
@@ -65,9 +65,11 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		if (file->isDirectory())
 			continue;
 		Common::String filename = file->getName();
-		bool hasExt = false, isBlorb = false;
+		bool hasExt = Blorb::hasBlorbExt(filename), isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
+		if (!hasExt)
+			continue;
 
 		// Open up the file and calculate the md5, and get the serial
 		Common::File gameFile;
@@ -81,7 +83,7 @@ bool FrotzMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		isBlorb = Blorb::isBlorb(gameFile, ID_ZCOD);
 
 		if (!isBlorb) {
-			if (!hasExt) {
+			if (Blorb::hasBlorbExt(filename)) {
 				gameFile.close();
 				continue;
 			}
diff --git a/engines/glk/glulxe/detection.cpp b/engines/glk/glulxe/detection.cpp
index 64c6eab..d75f1b7 100644
--- a/engines/glk/glulxe/detection.cpp
+++ b/engines/glk/glulxe/detection.cpp
@@ -55,9 +55,11 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 		if (file->isDirectory())
 			continue;
 		Common::String filename = file->getName();
-		bool hasExt = false, isBlorb = false;
+		bool hasExt = Blorb::hasBlorbExt(filename), isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
+		if (!hasExt)
+			continue;
 
 		// Open up the file and calculate the md5
 		Common::File gameFile;
@@ -69,7 +71,7 @@ bool GlulxeMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &
 		isBlorb = Blorb::isBlorb(gameFile, ID_GLUL);
 		gameFile.close();
 
-		if (!hasExt && !isBlorb)
+		if (!isBlorb && Blorb::hasBlorbExt(filename))
 			continue;
 
 		// Check for known games
diff --git a/engines/glk/scott/detection.cpp b/engines/glk/scott/detection.cpp
index 0e89b13..e2c9872 100644
--- a/engines/glk/scott/detection.cpp
+++ b/engines/glk/scott/detection.cpp
@@ -54,9 +54,11 @@ bool ScottMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 			continue;
 
 		Common::String filename = file->getName();
-		bool hasExt = false, isBlorb = false;
+		bool hasExt = Blorb::hasBlorbExt(filename), isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
+		if (!hasExt)
+			continue;
 
 		Common::File gameFile;
 		if (!gameFile.open(*file))
@@ -67,7 +69,7 @@ bool ScottMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &g
 		isBlorb = Blorb::isBlorb(gameFile, ID_SAAI);
 		gameFile.close();
 
-		if (!hasExt && !isBlorb)
+		if (!isBlorb && Blorb::hasBlorbExt(filename))
 			continue;
 
 		// Scan through the Scott game list for a match
diff --git a/engines/glk/tads/detection.cpp b/engines/glk/tads/detection.cpp
index 92633da..4df6d25 100644
--- a/engines/glk/tads/detection.cpp
+++ b/engines/glk/tads/detection.cpp
@@ -68,9 +68,11 @@ bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga
 			continue;
 
 		Common::String filename = file->getName();
-		bool hasExt = false, isBlorb = false;
+		bool hasExt = Blorb::hasBlorbExt(filename), isBlorb = false;
 		for (const char *const *ext = &EXTENSIONS[0]; *ext && !hasExt; ++ext)
 			hasExt = filename.hasSuffixIgnoreCase(*ext);
+		if (!hasExt)
+			continue;
 
 		// Open up the file and calculate the md5
 		Common::File gameFile;
@@ -82,7 +84,7 @@ bool TADSMetaEngine::detectGames(const Common::FSList &fslist, DetectedGames &ga
 		isBlorb = Blorb::isBlorb(gameFile, ID_TAD2) || Blorb::isBlorb(gameFile, ID_TAD3);
 		gameFile.close();
 
-		if (!hasExt && !isBlorb)
+		if (!isBlorb && Blorb::hasBlorbExt(filename))
 			continue;
 
 		// Check for known games





More information about the Scummvm-git-logs mailing list