[Scummvm-cvs-logs] SF.net SVN: scummvm:[46025] scummvm/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Fri Nov 20 22:25:36 CET 2009


Revision: 46025
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46025&view=rev
Author:   lordhoto
Date:     2009-11-20 21:25:36 +0000 (Fri, 20 Nov 2009)

Log Message:
-----------
Changed kyra.dat to use a global "INDEX" file instead of INDEX files for every game variant.

Modified Paths:
--------------
    scummvm/trunk/dists/engine-data/kyra.dat
    scummvm/trunk/engines/kyra/staticres.cpp
    scummvm/trunk/tools/create_kyradat/create_kyradat.cpp

Modified: scummvm/trunk/dists/engine-data/kyra.dat
===================================================================
(Binary files differ)

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2009-11-20 21:25:01 UTC (rev 46024)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2009-11-20 21:25:36 UTC (rev 46025)
@@ -45,7 +45,7 @@
 
 namespace Kyra {
 
-#define RESFILE_VERSION 64
+#define RESFILE_VERSION 65
 
 namespace {
 bool checkKyraDat(Common::SeekableReadStream *file) {
@@ -68,75 +68,86 @@
 			return false;
 	return true;
 }
-} // end of anonymous namespace
 
-// used for the KYRA.DAT file which still uses
-// the old flag system, we just convert it, which
-// is less work than to change KYRA.DAT again
-enum {
-	GF_FLOPPY	= 1 <<  0,
-	GF_TALKIE	= 1 <<  1,
-	GF_FMTOWNS	= 1 <<  2,
-	GF_DEMO		= 1 <<  3,
-	GF_ENGLISH	= 1 <<  4,
-	GF_FRENCH	= 1 <<  5,
-	GF_GERMAN	= 1 <<  6,
-	GF_SPANISH	= 1 <<  7,
-	GF_ITALIAN	= 1 <<  8,
-	GF_JAPANESE = 1 <<  9,
-	// other languages here
-	GF_LNGUNK	= 1 << 16,	// also used for multi language in kyra3
-	GF_AMIGA	= 1 << 17
+struct LanguageTypes {
+	Common::Language lang;
+	const char *ext;
 };
 
-#define GAME_FLAGS (GF_FLOPPY | GF_TALKIE | GF_DEMO | GF_FMTOWNS | GF_AMIGA)
-#define LANGUAGE_FLAGS (GF_ENGLISH | GF_FRENCH | GF_GERMAN | GF_SPANISH | GF_ITALIAN | GF_JAPANESE | GF_LNGUNK)
+const LanguageTypes languages[] = {
+	{ Common::EN_ANY, "ENG" },
+	{ Common::FR_FRA, "FRE" },
+	{ Common::DE_DEU, "GER" },
+	{ Common::ES_ESP, "SPA" },
+	{ Common::IT_ITA, "ITA" },
+	{ Common::JA_JPN, "JPN" },
+	{ Common::UNK_LANG, 0 }
+};
 
-uint32 createFeatures(const GameFlags &flags) {
-	if (flags.isTalkie && flags.isDemo)
-		return GF_TALKIE | GF_DEMO;
-	if (flags.isTalkie)
-		return GF_TALKIE;
-	if (flags.isDemo)
-		return GF_DEMO;
-	if (flags.platform == Common::kPlatformFMTowns || flags.platform == Common::kPlatformPC98)
-		return GF_FMTOWNS;
-	if (flags.platform == Common::kPlatformAmiga)
-		return GF_AMIGA;
-	return GF_FLOPPY;
-}
+struct IndexTable {
+	int type;
+	int value;
 
-uint32 createLanguage(const GameFlags &flags) {
-	if (flags.lang == Common::EN_ANY)
-		return GF_ENGLISH;
-	if (flags.lang == Common::DE_DEU)
-		return GF_GERMAN;
-	if (flags.lang == Common::FR_FRA)
-		return GF_FRENCH;
-	if (flags.lang == Common::ES_ESP)
-		return GF_SPANISH;
-	if (flags.lang == Common::IT_ITA)
-		return GF_ITALIAN;
-	if (flags.lang == Common::JA_JPN)
-		return GF_JAPANESE;
-	return GF_LNGUNK;
+	bool operator==(int t) const {
+		return (type == t);
+	}
+};
+
+const IndexTable iGameTable[] = {
+	{ GI_KYRA1, 0 },
+	{ GI_KYRA2, 1 },
+	{ GI_KYRA3, 2 },
+	{ GI_LOL, 3 },
+	{ -1, -1 }
+};
+
+byte getGameID(const GameFlags &flags) {
+	return Common::find(iGameTable, iGameTable + ARRAYSIZE(iGameTable) - 1, flags.gameID)->value;
 }
 
-struct LanguageTypes {
-	uint32 flags;
-	const char *ext;
+/*const IndexTable iLanguageTable[] = {
+	{ Common::EN_ANY, 0 },
+	{ Common::FR_FRA, 1 },
+	{ Common::DE_DEU, 2 },
+	{ Common::ES_ESP, 3 },
+	{ Common::IT_ITA, 4 },
+	{ Common::JA_JPN, 5 },
+	{ -1, -1 }
 };
 
-static const LanguageTypes languages[] = {
-	{ GF_ENGLISH, "ENG" },	// this is the default language
-	{ GF_FRENCH, "FRE" },
-	{ GF_GERMAN, "GER" },
-	{ GF_SPANISH, "SPA" },
-	{ GF_ITALIAN, "ITA" },
-	{ GF_JAPANESE, "JPN" },
-	{ 0, 0 }
+byte getLanguageID(const GameFlags &flags) {
+	return Common::find(iLanguageTable, iLanguageTable + ARRAYSIZE(iLanguageTable) - 1, flags.lang)->value;
+}*/
+
+const IndexTable iPlatformTable[] = {
+	{ Common::kPlatformPC, 0 },
+	{ Common::kPlatformAmiga, 1 },
+	{ Common::kPlatformFMTowns, 2 },
+	{ Common::kPlatformPC98, 3 },
+	{ Common::kPlatformMacintosh, 0 }, // HACK: Should be type "4", but as long as we can't extract Macintosh data, we need to use DOS data.
+	{ -1, -1 }
 };
 
+byte getPlatformID(const GameFlags &flags) {
+	// HACK: Gross hack to support Kyra2 PC98, till there's data for it in kyra.dat
+	if (flags.gameID == GI_KYRA2 && flags.platform == Common::kPlatformPC98)
+		return 3;
+	return Common::find(iPlatformTable, iPlatformTable + ARRAYSIZE(iPlatformTable) - 1, flags.platform)->value;
+}
+
+byte getSpecialID(const GameFlags &flags) {
+	if (flags.isDemo && flags.isTalkie)
+		return 3;
+	else if (flags.isDemo)
+		return 2;
+	else if (flags.isTalkie)
+		return 1;
+	else
+		return 0;
+}
+
+} // end of anonymous namespace
+
 bool StaticResource::loadStaticResourceFile() {
 	Resource *res = _vm->resource();
 
@@ -178,32 +189,42 @@
 }
 
 bool StaticResource::tryKyraDatLoad() {
-	Common::SeekableReadStream *index = getFile("INDEX");
+	Common::SeekableReadStream *index = _vm->resource()->createReadStream("INDEX");
 	if (!index)
 		return false;
 
-	if (index->size() != 3*4) {
+	const uint32 version = index->readUint32BE();
+
+	if (version != RESFILE_VERSION) {
 		delete index;
 		return false;
 	}
 
-	uint32 version = index->readUint32BE();
-	uint32 gameID = index->readUint32BE();
-	uint32 featuresValue = index->readUint32BE();
+	const uint32 includedGames = index->readUint32BE();
 
+	if (includedGames * 2 + 8 != (uint32)index->size()) {
+		delete index;
+		return false;
+	}
+
+	const uint16 gameDef = ((getGameID(_vm->gameFlags()) & 0xF) << 12) |
+	                       ((getPlatformID(_vm->gameFlags()) & 0xF) << 8) |
+	                       ((getSpecialID(_vm->gameFlags()) & 0xF) << 4);
+
+	bool found = false;
+	for (uint32 i = 0; i < includedGames; ++i) {
+		if (index->readUint16BE() == gameDef) {
+			found = true;
+			break;
+		}
+	}
+
 	delete index;
 	index = 0;
 
-	if (version != RESFILE_VERSION)
+	if (!found)
 		return false;
 
-	if (gameID != _vm->game())
-		return false;
-
-	uint32 gameFeatures = createFeatures(_vm->gameFlags());
-	if ((featuresValue & GAME_FLAGS) != gameFeatures)
-		return false;
-
 	// load all tables for now
 	if (!prefetchId(-1))
 		return false;
@@ -705,7 +726,7 @@
 bool StaticResource::loadLanguageTable(const char *filename, void *&ptr, int &size) {
 	static Common::String file;
 	for (int i = 0; languages[i].ext; ++i) {
-		if (languages[i].flags != createLanguage(_vm->gameFlags()))
+		if (languages[i].lang != _vm->gameFlags().lang)
 			continue;
 
 		file = filename;
@@ -714,17 +735,6 @@
 			return true;
 	}
 
-	file = filename;
-	file += languages[0].ext;
-	if (loadStringTable(file.c_str(), ptr, size)) {
-		static bool warned = false;
-		if (!warned) {
-			warned = true;
-			warning("couldn't find specific language table for your version, using English now");
-		}
-		return true;
-	}
-
 	return false;
 }
 

Modified: scummvm/trunk/tools/create_kyradat/create_kyradat.cpp
===================================================================
--- scummvm/trunk/tools/create_kyradat/create_kyradat.cpp	2009-11-20 21:25:01 UTC (rev 46024)
+++ scummvm/trunk/tools/create_kyradat/create_kyradat.cpp	2009-11-20 21:25:36 UTC (rev 46025)
@@ -38,10 +38,10 @@
 
 #include <string>
 #include <map>
+#include <algorithm>
 
 enum {
-	kKyraDatVersion = 64,
-	kIndexSize = 12
+	kKyraDatVersion = 65
 };
 
 const ExtractFilename extractFilenames[] = {
@@ -353,126 +353,160 @@
 
 // index generation
 
-enum {
-	GF_FLOPPY	= 1 <<  0,
-	GF_TALKIE	= 1 <<  1,
-	GF_FMTOWNS	= 1 <<  2,
-	GF_DEMO		= 1 <<  3,
-	GF_ENGLISH	= 1 <<  4,
-	GF_FRENCH	= 1 <<  5,
-	GF_GERMAN	= 1 <<  6,
-	GF_SPANISH	= 1 <<  7,
-	GF_ITALIAN	= 1 <<  8,
-	GF_JAPANESE = 1 <<  9,
-	// ...
-	GF_LNGUNK	= 1 << 16,
-	GF_AMIGA	= 1 << 17
+struct IndexTable {
+	int type;
+	int value;
+
+	bool operator==(int t) const {
+		return (type == t);
+	}
 };
 
-uint32 getFeatures(const Game *g) {
-	uint32 features = 0;
+const IndexTable iGameTable[] = {
+	{ kKyra1, 0 },
+	{ kKyra2, 1 },
+	{ kKyra3, 2 },
+	{ kLol, 3 },
+	{ -1, -1 }
+};
 
-	if (g->special == kTalkieVersion)
-		features |= GF_TALKIE;
-	else if (g->special == kDemoVersion)
-		features |= GF_DEMO;
-	else if (g->special == kTalkieDemoVersion)
-		features |= (GF_DEMO | GF_TALKIE);
-	else if (g->platform == kPlatformFMTowns || g->platform == kPlatformPC98)	// HACK
-		features |= GF_FMTOWNS;
-	else if (g->platform == kPlatformAmiga)
-		features |= GF_AMIGA;
-	else
-		features |= GF_FLOPPY;
+byte getGameID(int game) {
+	return std::find(iGameTable, iGameTable + ARRAYSIZE(iGameTable) - 1, game)->value;
+}
 
-	if (g->lang == EN_ANY)
-		features |= GF_ENGLISH;
-	else if (g->lang == DE_DEU)
-		features |= GF_GERMAN;
-	else if (g->lang == FR_FRA)
-		features |= GF_FRENCH;
-	else if (g->lang == ES_ESP)
-		features |= GF_SPANISH;
-	else if (g->lang == IT_ITA)
-		features |= GF_ITALIAN;
-	else if (g->lang == JA_JPN)
-		features |= GF_JAPANESE;
-	else
-		features |= GF_LNGUNK;
+/*const IndexTable iLanguageTable[] = {
+	{ EN_ANY, 0 },
+	{ FR_FRA, 1 },
+	{ DE_DEU, 2 },
+	{ ES_ESP, 3 },
+	{ IT_ITA, 4 },
+	{ JA_JPN, 5 },
+	{ -1, -1 }
+};
 
-	return features;
+byte getLanguageID(int lang) {
+	return std::find(iLanguageTable, iLanguageTable + ARRAYSIZE(iLanguageTable) - 1, lang)->value;
+}*/
+
+const IndexTable iPlatformTable[] = {
+	{ kPlatformPC, 0 },
+	{ kPlatformAmiga, 1 },
+	{ kPlatformFMTowns, 2 },
+	{ kPlatformPC98, 3 },
+	{ kPlatformMacintosh, 4 },
+	{ -1, -1 }
+};
+
+byte getPlatformID(int platform) {
+	return std::find(iPlatformTable, iPlatformTable + ARRAYSIZE(iPlatformTable) - 1, platform)->value;
 }
 
-bool updateIndex(byte *dst, const int dstSize, const Game *g) {
-	if ((size_t)dstSize < kIndexSize)
-		return false;
+const IndexTable iSpecialTable[] = {
+	{ kNoSpecial, 0 },
+	{ kTalkieVersion, 1 },
+	{ kDemoVersion, 2 },
+	{ kTalkieDemoVersion, 3 },
+	{ -1, -1 }
+};
 
-	WRITE_BE_UINT32(dst, kKyraDatVersion); dst += 4;
-	WRITE_BE_UINT32(dst, g->game); dst += 4;
-	uint32 features = READ_BE_UINT32(dst);
-	features |= getFeatures(g);
-	WRITE_BE_UINT32(dst, features); dst += 4;
-
-	return true;
+byte getSpecialID(int special) {
+	return std::find(iSpecialTable, iSpecialTable + ARRAYSIZE(iSpecialTable) - 1, special)->value;
 }
 
-bool checkIndex(const byte *s, const int srcSize) {
-	if ((size_t)srcSize < sizeof(uint32))
-		return false;
-	uint32 version = READ_BE_UINT32(s);
-	return (version == kKyraDatVersion);
+typedef uint16 GameDef;
+
+GameDef createGameDef(const Game *g) {
+	return ((getGameID(g->game) & 0xF) << 12) |
+	       ((getPlatformID(g->platform) & 0xF) << 8) |
+	       ((getSpecialID(g->special) & 0xF) << 4);
 }
 
-bool updateIndex(PAKFile &out, const Game *g) {
-	char filename[32];
-	ExtractInformation extractInfo;
-	extractInfo.game = g->game;
-	extractInfo.lang = -1;
-	extractInfo.platform = g->platform;
-	extractInfo.special = g->special;
+struct Index {
+	Index() : version(0), includedGames(0), gameList() {}
 
-	createFilename(filename, &extractInfo, "INDEX");
+	uint32 version;
+	uint32 includedGames;
 
-	byte *index = new byte[kIndexSize];
-	assert(index);
-	memset(index, 0, kIndexSize);
+	typedef std::list<GameDef> GameList;
+	GameList gameList;
+};
 
+Index parseIndex(const uint8 *data, uint32 size) {
+	Index result;
+
+	if (size < 8)
+		return result;
+
+	result.version = READ_BE_UINT32(data); data += 4;
+	result.includedGames = READ_BE_UINT32(data); data += 4;
+
+	if (result.includedGames * 2 + 8 != size) {
+		result.version = result.includedGames = 0;
+		return result;
+	}
+
+	for (uint32 i = 0; i < result.includedGames; ++i) {
+		GameDef game = READ_BE_UINT16(data); data += 2;
+		result.gameList.push_back(game);
+	}
+
+	return result;
+}
+
+bool updateIndex(PAKFile &out, const Game *g) {
 	uint32 size = 0;
-	const uint8 *data = out.getFileData(filename, &size);
+	const uint8 *data = out.getFileData("INDEX", &size);
+
+	Index index;
 	if (data)
-		memcpy(index, data, size);
+		index = parseIndex(data, size);
 
-	if (!updateIndex(index, kIndexSize, g)) {
-		delete[] index;
-		return false;
+	GameDef gameDef = createGameDef(g);
+	if (index.version == kKyraDatVersion) {
+		if (std::find(index.gameList.begin(), index.gameList.end(), gameDef) == index.gameList.end()) {
+			++index.includedGames;
+			index.gameList.push_back(gameDef);
+		}
+	} else {
+		index.version = kKyraDatVersion;
+		index.includedGames = 1;
+		index.gameList.push_back(gameDef);
 	}
 
-	out.removeFile(filename);
-	if (!out.addFile(filename, index, kIndexSize)) {
-		fprintf(stderr, "ERROR: couldn't update %s file\n", filename);
-		delete[] index;
+	const uint32 indexBufferSize = 8 + index.includedGames * 2;
+	uint8 *indexBuffer = new uint8[indexBufferSize];
+	assert(indexBuffer);
+	uint8 *dst = indexBuffer;
+	WRITE_BE_UINT32(dst, index.version); dst += 4;
+	WRITE_BE_UINT32(dst, index.includedGames); dst += 4;
+	for (Index::GameList::const_iterator i = index.gameList.begin(); i != index.gameList.end(); ++i) {
+		WRITE_BE_UINT16(dst, *i); dst += 2;
+	}
+
+	out.removeFile("INDEX");
+	if (!out.addFile("INDEX", indexBuffer, indexBufferSize)) {
+		fprintf(stderr, "ERROR: couldn't update kyra.dat INDEX\n");
+		delete[] indexBuffer;
 		return false;
 	}
 
 	return true;
 }
 
-bool checkIndex(PAKFile &out, const Game *g) {
-	char filename[32];
-	ExtractInformation extractInfo;
-	extractInfo.game = g->game;
-	extractInfo.lang = -1;
-	extractInfo.platform = g->platform;
-	extractInfo.special = g->special;
-
-	createFilename(filename, &extractInfo, "INDEX");
-
+bool checkIndex(PAKFile &file) {
 	uint32 size = 0;
-	const uint8 *data = out.getFileData(filename, &size);
+	const uint8 *data = file.getFileData("INDEX", &size);
 	if (!data)
-		return true;
+		return false;
 
-	return checkIndex(data, size);
+	Index index = parseIndex(data, size);
+
+	if (index.version != kKyraDatVersion)
+		return false;
+	if (index.includedGames * 2 + 8 != size)
+		return false;
+
+	return true;
 }
 
 // main processing
@@ -548,6 +582,11 @@
 	PAKFile out;
 	out.loadFile(argv[1], false);
 
+	// When the output file is no valid kyra.dat file, we will delete
+	// all the output.
+	if (!checkIndex(out))
+		out.clearFile();
+
 	MD5Map inputFiles = createMD5Sums(argc - 2, &argv[2]);
 
 	GameMap games = createGameMap(inputFiles);
@@ -1134,11 +1173,6 @@
 	extractInfo.platform = g->platform;
 	extractInfo.special = g->special;
 
-	if (!checkIndex(out, g)) {
-		fprintf(stderr, "ERROR: corrupted INDEX file\n");
-		return false;
-	}
-
 	Search search(data, size);
 	IdMap ids;
 


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