aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Montoir2006-11-04 12:00:31 +0000
committerGregory Montoir2006-11-04 12:00:31 +0000
commit5a902f8f7a40f2f2182a0b2149959f8889c468ef (patch)
tree4c388ea299b79dab8b781724f506d50ff6a35246
parentb8ed3bc87f5ddf397959d9ccc266a825f69cc059 (diff)
downloadscummvm-rg350-5a902f8f7a40f2f2182a0b2149959f8889c468ef.tar.gz
scummvm-rg350-5a902f8f7a40f2f2182a0b2149959f8889c468ef.tar.bz2
scummvm-rg350-5a902f8f7a40f2f2182a0b2149959f8889c468ef.zip
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...)
svn-id: r24598
-rw-r--r--engines/queen/debug.cpp4
-rw-r--r--engines/queen/journal.cpp2
-rw-r--r--engines/queen/logic.cpp2
-rw-r--r--engines/queen/queen.cpp77
-rw-r--r--engines/queen/resource.cpp204
-rw-r--r--engines/queen/resource.h94
6 files changed, 191 insertions, 192 deletions
diff --git a/engines/queen/debug.cpp b/engines/queen/debug.cpp
index 8f49753d17..508e6f077d 100644
--- a/engines/queen/debug.cpp
+++ b/engines/queen/debug.cpp
@@ -126,8 +126,8 @@ bool Debugger::Cmd_GameState(int argc, const char **argv) {
}
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;
}
diff --git a/engines/queen/journal.cpp b/engines/queen/journal.cpp
index d763ae486f..b36b4bad31 100644
--- a/engines/queen/journal.cpp
+++ b/engines/queen/journal.cpp
@@ -457,7 +457,7 @@ void Journal::drawConfigPanel() {
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);
diff --git a/engines/queen/logic.cpp b/engines/queen/logic.cpp
index b1675f38b3..91960fd8df 100644
--- a/engines/queen/logic.cpp
+++ b/engines/queen/logic.cpp
@@ -190,7 +190,7 @@ void Logic::initialise() {
_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");
}
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index df7a3ef472..5bada63983 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -48,39 +48,21 @@
#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];
- 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];
+ if (0 == scumm_stricmp(gameid, queenGameDescriptor.gameid)) {
+ return queenGameDescriptor;
}
- return queen_setting[0];
+ return GameDescriptor();
}
DetectedGameList Engine_QUEEN_detectGames(const FSList &fslist) {
@@ -88,32 +70,27 @@ DetectedGameList Engine_QUEEN_detectGames(const FSList &fslist) {
// 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 @@ int QueenEngine::init() {
_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;
diff --git a/engines/queen/resource.cpp b/engines/queen/resource.cpp
index eee279fae5..e51f641287 100644
--- a/engines/queen/resource.cpp
+++ b/engines/queen/resource.cpp
@@ -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 @@ static ResourceEntry *_resourceTablePEM10;
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 @@ static int compareResourceEntry(const void *a, const void *b) {
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 @@ Resource::~Resource() {
ResourceEntry *Resource::resourceEntry(const char *filename) const {
assert(filename[0] && strlen(filename) < 14);
- char entryName[14];
- char *ptr = entryName;
-
- strcpy(entryName, filename);
- do
- *ptr = toupper(*ptr);
- while (*ptr++);
+ Common::String entryName(filename);
+ entryName.toUppercase();
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 @@ uint8 *Resource::loadFile(const char *filename, uint32 skipBytes, uint32 *size,
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;
- }
-
- _compression = COMPRESSION_NONE;
+bool Resource::detectVersion(DetectedGameVersion *ver, Common::File *f) {
+ memset(ver, 0, sizeof(DetectedGameVersion));
- // 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");
+ 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;
+ }
- 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;
+ }
+
+ switch (versionStr[0]) {
+ case 'P':
+ ver->features |= GF_FLOPPY;
+ break;
+ case 'C':
+ ver->features |= GF_TALKIE;
+ break;
}
- return true;
-}
-bool Resource::findCompressedVersion() {
- _resourceFile->open("queen.1c");
- if (!_resourceFile->isOpen()) {
- return false;
+ if (strcmp(versionStr, "PE100") == 0) {
+ ver->features |= GF_DEMO;
+ } else if (strcmp(versionStr, "PEint") == 0) {
+ ver->features |= GF_INTERVIEW;
}
- readTableCompResource();
+
+ strcpy(ver->str, versionStr);
return true;
}
@@ -164,58 +207,32 @@ void Resource::checkJASVersion() {
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);
-}
-
-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;
- }
+ _resourceFile.read(versionStr, 6);
+ if (strcmp(_version.str, versionStr))
+ error("Verifying game version failed! (expected: '%s', found: '%s')", _version.str, versionStr);
}
-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) {
@@ -231,11 +248,10 @@ void Resource::readTableEntries(Common::File *file) {
}
}
-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 @@ Common::File *Resource::giveCompressedSound(const char *filename, uint32 *size)
if (size != NULL) {
*size = re->size;
}
- _resourceFile->seek(re->offset);
- f = _resourceFile;
+ _resourceFile.seek(re->offset);
+ f = &_resourceFile;
}
return f;
}
diff --git a/engines/queen/resource.h b/engines/queen/resource.h
index cb2851d27e..d01dc83859 100644
--- a/engines/queen/resource.h
+++ b/engines/queen/resource.h
@@ -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:
-
- LineReader(char *buffer, uint32 bufsize);
- ~LineReader();
- char *nextLine();
-
-private:
+struct DetectedGameVersion {
+ Common::Language language;
+ uint8 features;
+ uint8 compression;
+ char str[6];
+ uint32 tableOffset;
+};
- char *_buffer;
- uint32 _bufSize;
- int _current;
+struct ResourceEntry {
+ char filename[13];
+ uint8 bundle;
+ uint32 offset;
+ uint32 size;
};
class Resource {
@@ -71,19 +73,22 @@ public:
//! 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 the language of the game
+ Common::Language getLanguage() const { return _version.language; }
- //! returns language of the game
- Common::Language getLanguage() const;
+ //! detect game version
+ static bool detectVersion(DetectedGameVersion *ver, Common::File *f);
enum Version {
VER_ENG_FLOPPY = 0,
@@ -115,25 +120,15 @@ public:
protected:
- Common::File *_resourceFile;
+ Common::File _resourceFile;
- //! compression type for audio files
- uint8 _compression;
-
- //! JAS version string of the game
- char _versionString[6];
+ DetectedGameVersion _version;
//! 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 @@ protected:
ResourceEntry *resourceEntry(const char *filename) const;
//! extarct the resource table for the specified game version
- bool readTableFile(const GameVersion *gameVersion);
-
- //! reads the resource table from a rebuilt datafile (ie. queen.1c)
- void readTableCompResource();
+ void readTableFile(uint32 offset);
//! 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 @@ protected:
#endif
};
+class LineReader {
+public:
+
+ LineReader(char *buffer, uint32 bufsize);
+ ~LineReader();
+ char *nextLine();
+
+private:
+
+ char *_buffer;
+ uint32 _bufSize;
+ int _current;
+};
+
} // End of namespace Queen
#endif