[Scummvm-cvs-logs] SF.net SVN: scummvm: [24598] scummvm/trunk/engines/queen

cyx at users.sourceforge.net cyx at users.sourceforge.net
Sat Nov 4 13:00:40 CET 2006


Revision: 24598
          http://svn.sourceforge.net/scummvm/?rev=24598&view=rev
Author:   cyx
Date:     2006-11-04 04:00:31 -0800 (Sat, 04 Nov 2006)

Log Message:
-----------
rewrote FOTAQ game version detection code in a - if I didn't break anything - better way (no more duplicated code, more accurate game description in the launcher...)

Modified Paths:
--------------
    scummvm/trunk/engines/queen/debug.cpp
    scummvm/trunk/engines/queen/journal.cpp
    scummvm/trunk/engines/queen/logic.cpp
    scummvm/trunk/engines/queen/queen.cpp
    scummvm/trunk/engines/queen/resource.cpp
    scummvm/trunk/engines/queen/resource.h

Modified: scummvm/trunk/engines/queen/debug.cpp
===================================================================
--- scummvm/trunk/engines/queen/debug.cpp	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/debug.cpp	2006-11-04 12:00:31 UTC (rev 24598)
@@ -126,8 +126,8 @@
 }
 
 bool Debugger::Cmd_Info(int argc, const char **argv) {
-	DebugPrintf("Version: %s\n", _vm->resource()->JASVersion());
-	DebugPrintf("Audio compression: %d\n", _vm->resource()->compression());
+	DebugPrintf("Version: %s\n", _vm->resource()->getJASVersion());
+	DebugPrintf("Audio compression: %d\n", _vm->resource()->getCompression());
 	return true;
 }
 

Modified: scummvm/trunk/engines/queen/journal.cpp
===================================================================
--- scummvm/trunk/engines/queen/journal.cpp	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/journal.cpp	2006-11-04 12:00:31 UTC (rev 24598)
@@ -457,7 +457,7 @@
 
 void Journal::drawInfoPanel() {
 	showBob(BOB_INFO_BOX, 72, 221, FRAME_INFO_BOX);
-	const char *ver = _vm->resource()->JASVersion();
+	const char *ver = _vm->resource()->getJASVersion();
 	switch (ver[0]) {
 	case 'P':
 		_vm->display()->setTextCentered(132, "PC Hard Drive", false);

Modified: scummvm/trunk/engines/queen/logic.cpp
===================================================================
--- scummvm/trunk/engines/queen/logic.cpp	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/logic.cpp	2006-11-04 12:00:31 UTC (rev 24598)
@@ -190,7 +190,7 @@
 	_currentRoom = _objectData[_entryObj].room;
 	_entryObj = 0;
 
-	if (memcmp(ptr, _vm->resource()->JASVersion(), 5) != 0) {
+	if (memcmp(ptr, _vm->resource()->getJASVersion(), 5) != 0) {
 		warning("Unexpected queen.jas file format");
 	}
 

Modified: scummvm/trunk/engines/queen/queen.cpp
===================================================================
--- scummvm/trunk/engines/queen/queen.cpp	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/queen.cpp	2006-11-04 12:00:31 UTC (rev 24598)
@@ -48,72 +48,49 @@
 
 #include "sound/mididrv.h"
 
-/* Flight of the Amazon Queen */
-static const PlainGameDescriptor queen_setting[] = {
-	{ "queen", "Flight of the Amazon Queen" },
-	{ "queen", "Flight of the Amazon Queen (Demo)" },
-	{ "queen", "Flight of the Amazon Queen (Interview)" },
-	{ 0, 0 }
+static const PlainGameDescriptor queenGameDescriptor = {
+	"queen", "Flight of the Amazon Queen"
 };
 
 GameList Engine_QUEEN_gameIDList() {
 	GameList games;
-	games.push_back(queen_setting[0]);
+	games.push_back(queenGameDescriptor);
 	return games;
 }
 
 GameDescriptor Engine_QUEEN_findGameID(const char *gameid) {
-	if (0 == scumm_stricmp(gameid, queen_setting[0].gameid))
-		return queen_setting[0];
+	if (0 == scumm_stricmp(gameid, queenGameDescriptor.gameid)) {
+		return queenGameDescriptor;
+	}
 	return GameDescriptor();
 }
 
-// FIXME/TODO: it would be nice to re-use the existing code of the
-// Resource class to detect the FOTAQ version.
-static GameDescriptor determineTarget(uint32 size) {
-	switch (size) {
-	case 3724538:	//regular demo
-	case 3732177:
-		return queen_setting[1];
-	case 1915913:   //interview demo
-		return queen_setting[2];
-	default:	//non-demo
-		return queen_setting[0];
-	}
-	return queen_setting[0];
-}
-
 DetectedGameList Engine_QUEEN_detectGames(const FSList &fslist) {
 	DetectedGameList detectedGames;
 
 	// Iterate over all files in the given directory
 	for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
-		if (!file->isDirectory()) {
-			const char *fileName = file->name().c_str();
-
-			if (0 == scumm_stricmp("queen.1", fileName) || 0 == scumm_stricmp("queen.1c", fileName)) {
-				Common::File dataFile;
-				dataFile.open(*file);
-				assert(dataFile.isOpen());
-
-				if (0 == scumm_stricmp("queen.1", fileName)) {	//an unmodified file
-					detectedGames.push_back(determineTarget(dataFile.size()));
-				} else if (0 == scumm_stricmp("queen.1c", fileName)) { //oh joy, it's a rebuilt file
-					char header[9];
-					dataFile.read(header, 9);
-					if (0 == scumm_strnicmp("QTBL", header, 4)) { //check validity
-						uint8 version = 0;	//default to full/normal version
-
-						if (0 == scumm_strnicmp("PE100", header + 4, 5)) //One of the 2 regular demos
-							version = 1;
-						if (0 == scumm_strnicmp("PEint", header + 4, 5)) //Interview demo
-							version = 2;
-
-						detectedGames.push_back(queen_setting[version]);
-					}
+		if (file->isDirectory()) {
+			continue;
+		}
+		if (file->name().equalsIgnoreCase("queen.1") || file->name().equalsIgnoreCase("queen.1c")) {
+			Common::File dataFile;
+			if (!dataFile.open(*file)) {
+				continue;
+			}
+			Queen::DetectedGameVersion version;
+			if (Queen::Resource::detectVersion(&version, &dataFile)) {
+				DetectedGame dg(queenGameDescriptor.gameid, queenGameDescriptor.description, version.language, Common::kPlatformPC);
+				if (version.features & Queen::GF_DEMO) {
+					dg.updateDesc("Demo");
+				} else if (version.features & Queen::GF_INTERVIEW) {
+					dg.updateDesc("Interview");
+				} else if (version.features & Queen::GF_FLOPPY) {
+					dg.updateDesc("Floppy");
+				} else if (version.features & Queen::GF_TALKIE) {
+					dg.updateDesc("Talkie");
 				}
-
-				dataFile.close();
+				detectedGames.push_back(dg);
 				break;
 			}
 		}
@@ -421,7 +398,7 @@
 	_music = new Music(driver, this);
 	_music->hasNativeMT32(native_mt32);
 
-	_sound = Sound::giveSound(_mixer, this, _resource->compression());
+	_sound = Sound::giveSound(_mixer, this, _resource->getCompression());
 	_walk = new Walk(this);
 	//_talkspeedScale = (MAX_TEXT_SPEED - MIN_TEXT_SPEED) / 255.0;
 

Modified: scummvm/trunk/engines/queen/resource.cpp
===================================================================
--- scummvm/trunk/engines/queen/resource.cpp	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/resource.cpp	2006-11-04 12:00:31 UTC (rev 24598)
@@ -21,6 +21,7 @@
  */
 
 #include "common/stdafx.h"
+#include "common/endian.h"
 #include "common/config-manager.h"
 #include "queen/resource.h"
 
@@ -32,7 +33,7 @@
 
 const char *Resource::_tableFilename = "queen.tbl";
 
-const GameVersion Resource::_gameVersions[] = {
+const RetailGameVersion Resource::_gameVersions[] = {
 	{ "PEM10", 0x00000008,  22677657 },
 	{ "CEM10", 0x0000584E, 190787021 },
 	{ "PFM10", 0x0002CD93,  22157304 },
@@ -56,16 +57,29 @@
 
 Resource::Resource()
 	: _resourceEntries(0), _resourceTable(NULL) {
-	_resourceFile = new Common::File();
-	if (!findCompressedVersion() && !findNormalVersion())
-		error("Could not open resource file '%s'", "queen.1");
+	memset(&_version, 0, sizeof(_version));
+
+	if (!_resourceFile.open("queen.1c")) {
+		if (!_resourceFile.open("queen.1")) {
+			error("Could not open resource file 'queen.1[c]'");
+		}
+	}
+	if (!detectVersion(&_version, &_resourceFile)) {
+		error("Unable to detect game version");
+	}
+
+	if (_version.features & GF_REBUILT) {
+		readTableEntries(&_resourceFile);
+	} else {
+		readTableFile(_version.tableOffset);
+	}
+
 	checkJASVersion();
-	debug(5, "Detected game version: %s, which has %d resource entries", _versionString, _resourceEntries);
+	debug(5, "Detected game version: %s, which has %d resource entries", _version.str, _resourceEntries);
 }
 
 Resource::~Resource() {
-	_resourceFile->close();
-	delete _resourceFile;
+	_resourceFile.close();
 
 	if (_resourceTable != _resourceTablePEM10)
 		delete[] _resourceTable;
@@ -74,22 +88,17 @@
 ResourceEntry *Resource::resourceEntry(const char *filename) const {
 	assert(filename[0] && strlen(filename) < 14);
 
-	char entryName[14];
-	char *ptr = entryName;
+	Common::String entryName(filename);
+	entryName.toUppercase();
 
-	strcpy(entryName, filename);
-	do
-		*ptr = toupper(*ptr);
-	while (*ptr++);
-
 	ResourceEntry *re = NULL;
 #ifndef PALMOS_MODE
-	re = (ResourceEntry *)bsearch(entryName, _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry);
+	re = (ResourceEntry *)bsearch(entryName.c_str(), _resourceTable, _resourceEntries, sizeof(ResourceEntry), compareResourceEntry);
 #else
 	// PALMOS FIXME (?) : still doesn't work for me (????) use this instead
 	uint32 cur = 0;
 	do {
-		if (!strcmp(entryName, _resourceTable[cur].filename)) {
+		if (!strcmp(entryName.c_str(), _resourceTable[cur].filename)) {
 			re = &_resourceTable[cur];
 			break;
 		}
@@ -113,44 +122,78 @@
 		dstBuf = new byte[sz];
 	}
 
-	_resourceFile->seek(re->offset + skipBytes);
-	_resourceFile->read(dstBuf, sz);
+	_resourceFile.seek(re->offset + skipBytes);
+	_resourceFile.read(dstBuf, sz);
 	return dstBuf;
 }
 
-bool Resource::findNormalVersion() {
-	_resourceFile->open("queen.1");
-	if (!_resourceFile->isOpen()) {
-		return false;
+bool Resource::detectVersion(DetectedGameVersion *ver, Common::File *f) {
+	memset(ver, 0, sizeof(DetectedGameVersion));
+
+	char versionStr[6];
+	if (f->readUint32BE() == MKID_BE('QTBL')) {
+		f->read(versionStr, 6);
+		f->skip(2);
+		ver->compression = f->readByte();
+		ver->features = GF_REBUILT;
+		ver->tableOffset = 0;
+	} else {
+		const RetailGameVersion *gameVersion = detectGameVersionFromSize(f->size());
+		if (gameVersion == NULL) {
+			warning("Unknown/unsupported FOTAQ version");
+			return false;
+		}
+		strcpy(versionStr, gameVersion->str);
+		ver->compression = COMPRESSION_NONE;
+		ver->features = 0;
+		ver->tableOffset = gameVersion->tableOffset;
 	}
 
-	_compression = COMPRESSION_NONE;
-
-	// detect game version based on resource file size ; we try to
-	// verify that it is indeed the version we think it is later on
-	const GameVersion *gameVersion = detectGameVersion(_resourceFile->size());
-	if (gameVersion == NULL)
-		error("Unknown/unsupported FOTAQ version");
-
-	strcpy(_versionString, gameVersion->versionString);
-	if (!readTableFile(gameVersion)) {
-		// check if it is the english floppy version, for which we have a hardcoded version of the table
-		if (!strcmp(gameVersion->versionString, _gameVersions[VER_ENG_FLOPPY].versionString)) {
-			_resourceEntries = 1076;
-			_resourceTable = _resourceTablePEM10;
+	switch (versionStr[1]) {
+	case 'E':
+		if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS) {
+			ver->language = Common::RU_RUS;
 		} else {
-			error("Could not find tablefile '%s'", _tableFilename);
+			ver->language = Common::EN_ANY;
 		}
+		break;
+	case 'G':
+		ver->language = Common::DE_DEU;
+		break;
+	case 'F':
+		ver->language = Common::FR_FRA;
+		break;
+	case 'I':
+		ver->language = Common::IT_ITA;
+		break;
+	case 'S':
+		ver->language = Common::ES_ESP;
+		break;
+	case 'H':
+		ver->language = Common::HB_ISR;
+		break;
+	default:
+		warning("Unknown language id '%c', defaulting to English", versionStr[1]);
+		ver->language = Common::EN_ANY;
+		break;
 	}
-	return true;
-}
 
-bool Resource::findCompressedVersion() {
-	_resourceFile->open("queen.1c");
-	if (!_resourceFile->isOpen()) {
-		return false;
+	switch (versionStr[0]) {
+	case 'P':
+		ver->features |= GF_FLOPPY;
+		break;
+	case 'C':
+		ver->features |= GF_TALKIE;
+		break;
 	}
-	readTableCompResource();
+
+	if (strcmp(versionStr, "PE100") == 0) {
+		ver->features |= GF_DEMO;
+	} else if (strcmp(versionStr, "PEint") == 0) {
+		ver->features |= GF_INTERVIEW;
+	}
+
+	strcpy(ver->str, versionStr);
 	return true;
 }
 
@@ -164,60 +207,34 @@
 		offset += JAS_VERSION_OFFSET_INTV;
 	else
 		offset += JAS_VERSION_OFFSET_PC;
-	_resourceFile->seek(offset);
+	_resourceFile.seek(offset);
 
 	char versionStr[6];
-	_resourceFile->read(versionStr, 6);
-	if (strcmp(_versionString, versionStr))
-		error("Verifying game version failed! (expected: '%s', found: '%s')", _versionString, versionStr);
+	_resourceFile.read(versionStr, 6);
+	if (strcmp(_version.str, versionStr))
+		error("Verifying game version failed! (expected: '%s', found: '%s')", _version.str, versionStr);
 }
 
-Common::Language Resource::getLanguage() const {
-	switch (_versionString[1]) {
-	case 'E':
-		if (Common::parseLanguage(ConfMan.get("language")) == Common::RU_RUS)
-			return Common::RU_RUS;
-		return Common::EN_ANY;
-	case 'G':
-		return Common::DE_DEU;
-	case 'F':
-		return Common::FR_FRA;
-	case 'I':
-		return Common::IT_ITA;
-	case 'S':
-		return Common::ES_ESP;
-	case 'H':
-		return Common::HB_ISR;
-	default:
-		warning("Unknown language id '%c', defaulting to English", _versionString[1]);
-		return Common::EN_ANY;
-	}
-}
-
-bool Resource::readTableFile(const GameVersion *gameVersion) {
+void Resource::readTableFile(uint32 offset) {
 	Common::File tableFile;
 	tableFile.open(_tableFilename);
-	if (tableFile.isOpen() && tableFile.readUint32BE() == 'QTBL') {
-		if (tableFile.readUint32BE() != CURRENT_TBL_VERSION)
+	if (tableFile.isOpen() && tableFile.readUint32BE() == MKID_BE('QTBL')) {
+		if (tableFile.readUint32BE() != CURRENT_TBL_VERSION) {
 			warning("Incorrect version of queen.tbl, please update it");
-		tableFile.seek(gameVersion->tableOffset);
+		}
+		tableFile.seek(offset);
 		readTableEntries(&tableFile);
-		return true;
+	} else {
+		// check if it is the english floppy version, for which we have a hardcoded version of the table
+		if (strcmp(_version.str, _gameVersions[VER_ENG_FLOPPY].str) == 0) {
+			_resourceEntries = 1076;
+			_resourceTable = _resourceTablePEM10;
+		} else {
+			error("Could not find tablefile '%s'", _tableFilename);
+		}
 	}
-	return false;
 }
 
-void Resource::readTableCompResource() {
-	if (_resourceFile->readUint32BE() != 'QTBL')
-		error("Invalid table header");
-
-	_resourceFile->read(_versionString, 6);
-	_resourceFile->skip(2); // obsolete
-	_compression = _resourceFile->readByte();
-
-	readTableEntries(_resourceFile);
-}
-
 void Resource::readTableEntries(Common::File *file) {
 	_resourceEntries = file->readUint16BE();
 	_resourceTable = new ResourceEntry[_resourceEntries];
@@ -231,11 +248,10 @@
 	}
 }
 
-const GameVersion *Resource::detectGameVersion(uint32 size) const {
-	const GameVersion *pgv = _gameVersions;
-	for (int i = 0; i < VER_COUNT; ++i, ++pgv) {
-		if (pgv->dataFileSize == size) {
-			return pgv;
+const RetailGameVersion *Resource::detectGameVersionFromSize(uint32 size) {
+	for (int i = 0; i < VER_COUNT; ++i) {
+		if (_gameVersions[i].dataFileSize == size) {
+			return &_gameVersions[i];
 		}
  	}
 	return NULL;
@@ -249,8 +265,8 @@
 		if (size != NULL) {
 			*size = re->size;
 		}
-		_resourceFile->seek(re->offset);
-		f = _resourceFile;
+		_resourceFile.seek(re->offset);
+		f = &_resourceFile;
 	}
 	return f;
 }

Modified: scummvm/trunk/engines/queen/resource.h
===================================================================
--- scummvm/trunk/engines/queen/resource.h	2006-11-03 23:22:55 UTC (rev 24597)
+++ scummvm/trunk/engines/queen/resource.h	2006-11-04 12:00:31 UTC (rev 24598)
@@ -29,31 +29,33 @@
 
 namespace Queen {
 
-struct ResourceEntry {
-	char filename[13];
-	uint8 bundle;
-	uint32 offset;
-	uint32 size;
+enum GameFeatures {
+	GF_DEMO      = 1 << 0, // demo
+	GF_TALKIE    = 1 << 1, // equivalent to cdrom version check
+	GF_FLOPPY    = 1 << 2, // floppy, ie. non-talkie version
+	GF_INTERVIEW = 1 << 3, // interview demo
+	GF_REBUILT   = 1 << 4  // version rebuilt with the 'compression_queen' tool
 };
 
-struct GameVersion {
-	char versionString[6];
+struct RetailGameVersion {
+	char str[6];
 	uint32 tableOffset;
 	uint32 dataFileSize;
 };
 
-class LineReader {
-public:
+struct DetectedGameVersion {
+	Common::Language language;
+	uint8 features;
+	uint8 compression;
+	char str[6];
+	uint32 tableOffset;
+};
 
-	LineReader(char *buffer, uint32 bufsize);
-	~LineReader();
-	char *nextLine();
-
-private:
-
-	char *_buffer;
-	uint32 _bufSize;
-	int _current;
+struct ResourceEntry {
+	char filename[13];
+	uint8 bundle;
+	uint32 offset;
+	uint32 size;
 };
 
 class Resource {
@@ -71,20 +73,23 @@
 	//! returns a reference to a sound file
 	Common::File *giveCompressedSound(const char *filename, uint32 *size);
 
-	bool isDemo() const { return !strcmp(_versionString, "PE100"); }
-	bool isInterview() const { return !strcmp(_versionString, "PEint"); }
-	bool isFloppy() const { return _versionString[0] == 'P'; }
-	bool isCD() const { return _versionString[0] == 'C'; }
+	bool isDemo() const { return _version.features & GF_DEMO; }
+	bool isInterview() const { return _version.features & GF_INTERVIEW; }
+	bool isFloppy() const { return _version.features & GF_FLOPPY; }
+	bool isCD() const { return _version.features & GF_TALKIE; }
 
 	//! returns compression type for audio files
-	uint8 compression() const { return _compression; }
+	uint8 getCompression() const { return _version.compression; }
 
 	//! returns JAS version string (contains language, platform and version information)
-	const char *JASVersion() const { return _versionString; }
+	const char *getJASVersion() const { return _version.str; }
 
-	//! returns language of the game
-	Common::Language getLanguage() const;
+	//! returns the language of the game
+	Common::Language getLanguage() const { return _version.language; }
 
+	//! detect game version
+	static bool detectVersion(DetectedGameVersion *ver, Common::File *f);
+
 	enum Version {
 		VER_ENG_FLOPPY   = 0,
 		VER_ENG_TALKIE   = 1,
@@ -115,25 +120,15 @@
 
 protected:
 
-	Common::File *_resourceFile;
+	Common::File _resourceFile;
 
-	//! compression type for audio files
-	uint8 _compression;
+	DetectedGameVersion _version;
 
-	//! JAS version string of the game
-	char _versionString[6];
-
 	//! number of entries in resource table
 	uint32 _resourceEntries;
 
 	ResourceEntry *_resourceTable;
 
-	//! look for a normal queen version (ie. queen.1)
-	bool findNormalVersion();
-
-	//! look for a compressed/rebuilt queen version (ie. queen.1c)
-	bool findCompressedVersion();
-
 	//! verify the version of the selected game
 	void checkJASVersion();
 
@@ -141,22 +136,19 @@
 	ResourceEntry *resourceEntry(const char *filename) const;
 
 	//! extarct the resource table for the specified game version
-	bool readTableFile(const GameVersion *gameVersion);
+	void readTableFile(uint32 offset);
 
-	//! reads the resource table from a rebuilt datafile (ie. queen.1c)
-	void readTableCompResource();
-
 	//! read the resource table from the specified file
 	void readTableEntries(Common::File *file);
 
 	//! detect game version based on queen.1 datafile size
-	const GameVersion *detectGameVersion(uint32 size) const;
+	static const RetailGameVersion *detectGameVersionFromSize(uint32 size);
 
 	//! resource table filename (queen.tbl)
 	static const char *_tableFilename;
 
 	//! known FOTAQ versions
-	static const GameVersion _gameVersions[];
+	static const RetailGameVersion _gameVersions[];
 
 #ifndef PALMOS_68K
 	//! resource table for english floppy version
@@ -164,6 +156,20 @@
 #endif
 };
 
+class LineReader {
+public:
+
+	LineReader(char *buffer, uint32 bufsize);
+	~LineReader();
+	char *nextLine();
+
+private:
+
+	char *_buffer;
+	uint32 _bufSize;
+	int _current;
+};
+
 } // End of namespace Queen
 
 #endif


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